From 53776a31779e4c52d345ef29a4de4f44dfc04b9f Mon Sep 17 00:00:00 2001 From: Oba Date: Mon, 30 Sep 2024 17:34:35 +0200 Subject: [PATCH 01/56] chore: import ssj --- .github/workflows/kakarot-ssj/build.yml | 32 + .github/workflows/kakarot-ssj/ci.yml | 82 + .github/workflows/kakarot-ssj/ef-tests.yml | 129 + .github/workflows/kakarot-ssj/release.yml | 28 + .github/workflows/kakarot-ssj/test.yml | 26 + .github/workflows/kakarot-ssj/tests-unit.yml | 26 + .../workflows/kakarot-ssj/trunk-check.yaml | 24 + .../{ => workflows/kakarot0}/actionlint.yaml | 0 .github/workflows/{ => kakarot0}/ci.yml | 0 .../{ => kakarot0}/nightly-fuzzing.yml | 0 .github/workflows/{ => kakarot0}/release.yml | 0 .../workflows/{ => kakarot0}/trunk-check.yaml | 0 .../workflows/{ => kakarot0}/update-rpc.yml | 0 kakarot-ssj/.all-contributorsrc | 189 + kakarot-ssj/.codespellrc | 2 + kakarot-ssj/.devcontainer/devcontainer.json | 10 + kakarot-ssj/.env.example | 5 + kakarot-ssj/.github/CODEOWNERS | 3 + .../.github/ISSUE_TEMPLATE/01_BUG_REPORT.md | 40 + .../ISSUE_TEMPLATE/02_FEATURE_REQUEST.md | 23 + .../ISSUE_TEMPLATE/03_CODEBASE_IMPROVEMENT.md | 9 + kakarot-ssj/.github/ISSUE_TEMPLATE/config.yml | 6 + kakarot-ssj/.github/PULL_REQUEST_TEMPLATE.md | 39 + kakarot-ssj/.github/workflows/build.yml | 32 + kakarot-ssj/.github/workflows/ci.yml | 82 + kakarot-ssj/.github/workflows/ef-tests.yml | 129 + kakarot-ssj/.github/workflows/release.yml | 28 + kakarot-ssj/.github/workflows/test.yml | 26 + kakarot-ssj/.github/workflows/tests-unit.yml | 26 + .../.github/workflows/trunk-check.yaml | 24 + kakarot-ssj/.gitignore | 10 + kakarot-ssj/.markdownlint.json | 8 + kakarot-ssj/.prettierrc.json | 3 + kakarot-ssj/.tool-versions | 2 + kakarot-ssj/.trunk/.gitignore | 9 + kakarot-ssj/.trunk/configs/.isort.cfg | 2 + kakarot-ssj/.trunk/configs/.shellcheckrc | 7 + kakarot-ssj/.trunk/configs/.yamllint.yaml | 10 + kakarot-ssj/.trunk/configs/ruff.toml | 5 + kakarot-ssj/.trunk/trunk.yaml | 74 + kakarot-ssj/LICENSE | 21 + kakarot-ssj/Makefile | 19 + kakarot-ssj/README.md | 247 + kakarot-ssj/Scarb.lock | 74 + kakarot-ssj/Scarb.toml | 17 + kakarot-ssj/blockchain-tests-skip.yml | 8730 +++++++++++++++++ kakarot-ssj/bun.lockb | Bin 0 -> 48666 bytes .../alexandria_data_structures/.gitignore | 1 + .../alexandria_data_structures/Scarb.toml | 15 + .../alexandria_data_structures/src/lib.cairo | 1 + .../alexandria_data_structures/src/vec.cairo | 167 + kakarot-ssj/crates/contracts/Scarb.toml | 32 + .../contracts/src/account_contract.cairo | 283 + .../crates/contracts/src/cairo1_helpers.cairo | 233 + .../crates/contracts/src/components.cairo | 2 + .../contracts/src/components/ownable.cairo | 91 + .../src/components/upgradeable.cairo | 40 + kakarot-ssj/crates/contracts/src/errors.cairo | 49 + .../crates/contracts/src/kakarot_core.cairo | 8 + .../contracts/src/kakarot_core/eth_rpc.cairo | 305 + .../src/kakarot_core/interface.cairo | 122 + .../contracts/src/kakarot_core/kakarot.cairo | 230 + kakarot-ssj/crates/contracts/src/lib.cairo | 37 + .../src/mocks/cairo1_helpers_fixture.cairo | 15 + .../crates/contracts/src/storage.cairo | 199 + .../src/test_contracts/test_upgradeable.cairo | 102 + .../crates/contracts/src/test_data.cairo | 1781 ++++ .../crates/contracts/src/test_utils.cairo | 148 + .../contracts/src/uninitialized_account.cairo | 66 + kakarot-ssj/crates/contracts/tests/lib.cairo | 8 + .../tests/test_account_contract.cairo | 148 + .../contracts/tests/test_cairo1_helpers.cairo | 20 + .../tests/test_execution_from_outside.cairo | 545 + .../contracts/tests/test_kakarot_core.cairo | 383 + .../crates/contracts/tests/test_ownable.cairo | 210 + kakarot-ssj/crates/evm/.gitignore | 1 + kakarot-ssj/crates/evm/Scarb.toml | 25 + kakarot-ssj/crates/evm/src/backend.cairo | 2 + .../evm/src/backend/starknet_backend.cairo | 517 + .../crates/evm/src/backend/validation.cairo | 322 + kakarot-ssj/crates/evm/src/call_helpers.cairo | 129 + .../crates/evm/src/create_helpers.cairo | 186 + kakarot-ssj/crates/evm/src/errors.cairo | 112 + kakarot-ssj/crates/evm/src/gas.cairo | 402 + kakarot-ssj/crates/evm/src/instructions.cairo | 34 + .../src/instructions/block_information.cairo | 368 + .../instructions/comparison_operations.cairo | 1980 ++++ .../instructions/duplication_operations.cairo | 556 ++ .../environmental_information.cairo | 1153 +++ .../instructions/exchange_operations.cairo | 439 + .../src/instructions/logging_operations.cairo | 400 + .../src/instructions/memory_operations.cairo | 1069 ++ .../src/instructions/push_operations.cairo | 751 ++ .../crates/evm/src/instructions/sha3.cairo | 600 ++ .../stop_and_arithmetic_operations.cairo | 740 ++ .../src/instructions/system_operations.cairo | 1180 +++ kakarot-ssj/crates/evm/src/interpreter.cairo | 1115 +++ kakarot-ssj/crates/evm/src/lib.cairo | 40 + kakarot-ssj/crates/evm/src/memory.cairo | 1199 +++ kakarot-ssj/crates/evm/src/model.cairo | 365 + .../crates/evm/src/model/account.cairo | 467 + kakarot-ssj/crates/evm/src/model/vm.cairo | 311 + kakarot-ssj/crates/evm/src/precompiles.cairo | 155 + .../crates/evm/src/precompiles/blake2f.cairo | 212 + .../evm/src/precompiles/ec_operations.cairo | 107 + .../precompiles/ec_operations/ec_add.cairo | 185 + .../precompiles/ec_operations/ec_mul.cairo | 142 + .../evm/src/precompiles/ec_recover.cairo | 150 + .../crates/evm/src/precompiles/identity.cairo | 71 + .../crates/evm/src/precompiles/modexp.cairo | 302 + .../evm/src/precompiles/p256verify.cairo | 251 + .../crates/evm/src/precompiles/sha256.cairo | 171 + kakarot-ssj/crates/evm/src/stack.cairo | 635 ++ kakarot-ssj/crates/evm/src/state.cairo | 784 ++ kakarot-ssj/crates/evm/src/test_data.cairo | 2 + .../evm/src/test_data/test_data_blake2f.cairo | 1533 +++ .../evm/src/test_data/test_data_modexp.cairo | 1553 +++ kakarot-ssj/crates/evm/src/test_utils.cairo | 298 + kakarot-ssj/crates/openzeppelin/Scarb.toml | 32 + kakarot-ssj/crates/openzeppelin/src/lib.cairo | 1 + .../crates/openzeppelin/src/token.cairo | 1 + .../crates/openzeppelin/src/token/erc20.cairo | 6 + .../openzeppelin/src/token/erc20/erc20.cairo | 259 + .../src/token/erc20/interface.cairo | 90 + kakarot-ssj/crates/snforge_utils/.gitignore | 2 + kakarot-ssj/crates/snforge_utils/Scarb.toml | 26 + .../crates/snforge_utils/src/contracts.cairo | 51 + .../crates/snforge_utils/src/lib.cairo | 319 + kakarot-ssj/crates/utils/.gitignore | 1 + kakarot-ssj/crates/utils/Scarb.toml | 25 + kakarot-ssj/crates/utils/src/address.cairo | 100 + kakarot-ssj/crates/utils/src/constants.cairo | 232 + kakarot-ssj/crates/utils/src/crypto.cairo | 2 + .../utils/src/crypto/blake2_compress.cairo | 170 + .../crates/utils/src/crypto/modexp.cairo | 3 + .../utils/src/crypto/modexp/arith.cairo | 2524 +++++ .../crates/utils/src/crypto/modexp/lib.cairo | 19 + .../utils/src/crypto/modexp/mpnat.cairo | 1034 ++ kakarot-ssj/crates/utils/src/errors.cairo | 69 + .../crates/utils/src/eth_transaction.cairo | 68 + .../utils/src/eth_transaction/common.cairo | 51 + .../utils/src/eth_transaction/eip1559.cairo | 144 + .../utils/src/eth_transaction/eip2930.cairo | 128 + .../utils/src/eth_transaction/legacy.cairo | 39 + .../src/eth_transaction/transaction.cairo | 532 + .../utils/src/eth_transaction/tx_type.cairo | 23 + kakarot-ssj/crates/utils/src/felt_vec.cairo | 785 ++ kakarot-ssj/crates/utils/src/fmt.cairo | 50 + kakarot-ssj/crates/utils/src/helpers.cairo | 282 + kakarot-ssj/crates/utils/src/i256.cairo | 535 + kakarot-ssj/crates/utils/src/lib.cairo | 16 + kakarot-ssj/crates/utils/src/math.cairo | 724 ++ kakarot-ssj/crates/utils/src/rlp.cairo | 2766 ++++++ .../crates/utils/src/serialization.cairo | 301 + kakarot-ssj/crates/utils/src/set.cairo | 281 + kakarot-ssj/crates/utils/src/test_data.cairo | 421 + kakarot-ssj/crates/utils/src/traits.cairo | 162 + .../crates/utils/src/traits/array.cairo | 143 + .../crates/utils/src/traits/bytes.cairo | 820 ++ .../crates/utils/src/traits/eth_address.cairo | 147 + .../crates/utils/src/traits/integer.cairo | 671 ++ kakarot-ssj/crates/utils/src/utils.cairo | 309 + kakarot-ssj/docs/CODE_OF_CONDUCT.md | 78 + kakarot-ssj/docs/CONTRIBUTING.md | 128 + kakarot-ssj/docs/SECURITY.md | 23 + kakarot-ssj/docs/general/account_state.png | Bin 0 -> 132360 bytes kakarot-ssj/docs/general/contract_bytecode.md | 230 + kakarot-ssj/docs/general/contract_storage.md | 274 + kakarot-ssj/docs/general/local_state.md | 177 + kakarot-ssj/docs/general/machine.md | 242 + kakarot-ssj/docs/general/volition.png | Bin 0 -> 192376 bytes .../docs/img/kakarot_github_banner.png | Bin 0 -> 68625 bytes kakarot-ssj/package-lock.json | 434 + kakarot-ssj/package.json | 24 + kakarot-ssj/rust-toolchain | 1 + kakarot-ssj/scripts/compare_snapshot.py | 166 + kakarot-ssj/scripts/compute_create_address.ts | 60 + kakarot-ssj/scripts/compute_rlp_encoding.ts | 160 + .../scripts/compute_starknet_address.ts | 48 + .../scripts/data/input_access_list_tx.json | 18 + .../data/input_eip1559_y_parity_false.json | 11 + .../data/input_eip_2930_counter_inc_tx.json | 10 + kakarot-ssj/scripts/data/input_fee_tx.json | 19 + .../scripts/data/input_legacy_deploy_tx.json | 9 + kakarot-ssj/scripts/data/input_legacy_tx.json | 9 + kakarot-ssj/scripts/filter_tests.py | 50 + kakarot-ssj/scripts/find_selectory.py | 30 + kakarot-ssj/scripts/gas_debug_call.py | 38 + kakarot-ssj/scripts/gen_snapshot.py | 22 + kakarot-ssj/scripts/install_hook.sh | 35 + kakarot-ssj/scripts/run_filtered_tests.py | 73 + kakarot-ssj/scripts/setup_cairo_native.sh | 185 + kakarot-ssj/tsconfig.json | 22 + 193 files changed, 53453 insertions(+) create mode 100644 .github/workflows/kakarot-ssj/build.yml create mode 100644 .github/workflows/kakarot-ssj/ci.yml create mode 100644 .github/workflows/kakarot-ssj/ef-tests.yml create mode 100644 .github/workflows/kakarot-ssj/release.yml create mode 100644 .github/workflows/kakarot-ssj/test.yml create mode 100644 .github/workflows/kakarot-ssj/tests-unit.yml create mode 100644 .github/workflows/kakarot-ssj/trunk-check.yaml rename .github/{ => workflows/kakarot0}/actionlint.yaml (100%) rename .github/workflows/{ => kakarot0}/ci.yml (100%) rename .github/workflows/{ => kakarot0}/nightly-fuzzing.yml (100%) rename .github/workflows/{ => kakarot0}/release.yml (100%) rename .github/workflows/{ => kakarot0}/trunk-check.yaml (100%) rename .github/workflows/{ => kakarot0}/update-rpc.yml (100%) create mode 100644 kakarot-ssj/.all-contributorsrc create mode 100644 kakarot-ssj/.codespellrc create mode 100644 kakarot-ssj/.devcontainer/devcontainer.json create mode 100644 kakarot-ssj/.env.example create mode 100644 kakarot-ssj/.github/CODEOWNERS create mode 100644 kakarot-ssj/.github/ISSUE_TEMPLATE/01_BUG_REPORT.md create mode 100644 kakarot-ssj/.github/ISSUE_TEMPLATE/02_FEATURE_REQUEST.md create mode 100644 kakarot-ssj/.github/ISSUE_TEMPLATE/03_CODEBASE_IMPROVEMENT.md create mode 100644 kakarot-ssj/.github/ISSUE_TEMPLATE/config.yml create mode 100644 kakarot-ssj/.github/PULL_REQUEST_TEMPLATE.md create mode 100644 kakarot-ssj/.github/workflows/build.yml create mode 100644 kakarot-ssj/.github/workflows/ci.yml create mode 100644 kakarot-ssj/.github/workflows/ef-tests.yml create mode 100644 kakarot-ssj/.github/workflows/release.yml create mode 100644 kakarot-ssj/.github/workflows/test.yml create mode 100644 kakarot-ssj/.github/workflows/tests-unit.yml create mode 100644 kakarot-ssj/.github/workflows/trunk-check.yaml create mode 100644 kakarot-ssj/.gitignore create mode 100644 kakarot-ssj/.markdownlint.json create mode 100644 kakarot-ssj/.prettierrc.json create mode 100644 kakarot-ssj/.tool-versions create mode 100644 kakarot-ssj/.trunk/.gitignore create mode 100644 kakarot-ssj/.trunk/configs/.isort.cfg create mode 100644 kakarot-ssj/.trunk/configs/.shellcheckrc create mode 100644 kakarot-ssj/.trunk/configs/.yamllint.yaml create mode 100644 kakarot-ssj/.trunk/configs/ruff.toml create mode 100644 kakarot-ssj/.trunk/trunk.yaml create mode 100644 kakarot-ssj/LICENSE create mode 100644 kakarot-ssj/Makefile create mode 100644 kakarot-ssj/README.md create mode 100644 kakarot-ssj/Scarb.lock create mode 100644 kakarot-ssj/Scarb.toml create mode 100644 kakarot-ssj/blockchain-tests-skip.yml create mode 100755 kakarot-ssj/bun.lockb create mode 100644 kakarot-ssj/crates/alexandria_data_structures/.gitignore create mode 100644 kakarot-ssj/crates/alexandria_data_structures/Scarb.toml create mode 100644 kakarot-ssj/crates/alexandria_data_structures/src/lib.cairo create mode 100644 kakarot-ssj/crates/alexandria_data_structures/src/vec.cairo create mode 100644 kakarot-ssj/crates/contracts/Scarb.toml create mode 100644 kakarot-ssj/crates/contracts/src/account_contract.cairo create mode 100644 kakarot-ssj/crates/contracts/src/cairo1_helpers.cairo create mode 100644 kakarot-ssj/crates/contracts/src/components.cairo create mode 100644 kakarot-ssj/crates/contracts/src/components/ownable.cairo create mode 100644 kakarot-ssj/crates/contracts/src/components/upgradeable.cairo create mode 100644 kakarot-ssj/crates/contracts/src/errors.cairo create mode 100644 kakarot-ssj/crates/contracts/src/kakarot_core.cairo create mode 100644 kakarot-ssj/crates/contracts/src/kakarot_core/eth_rpc.cairo create mode 100644 kakarot-ssj/crates/contracts/src/kakarot_core/interface.cairo create mode 100644 kakarot-ssj/crates/contracts/src/kakarot_core/kakarot.cairo create mode 100644 kakarot-ssj/crates/contracts/src/lib.cairo create mode 100644 kakarot-ssj/crates/contracts/src/mocks/cairo1_helpers_fixture.cairo create mode 100644 kakarot-ssj/crates/contracts/src/storage.cairo create mode 100644 kakarot-ssj/crates/contracts/src/test_contracts/test_upgradeable.cairo create mode 100644 kakarot-ssj/crates/contracts/src/test_data.cairo create mode 100644 kakarot-ssj/crates/contracts/src/test_utils.cairo create mode 100644 kakarot-ssj/crates/contracts/src/uninitialized_account.cairo create mode 100644 kakarot-ssj/crates/contracts/tests/lib.cairo create mode 100644 kakarot-ssj/crates/contracts/tests/test_account_contract.cairo create mode 100644 kakarot-ssj/crates/contracts/tests/test_cairo1_helpers.cairo create mode 100644 kakarot-ssj/crates/contracts/tests/test_execution_from_outside.cairo create mode 100644 kakarot-ssj/crates/contracts/tests/test_kakarot_core.cairo create mode 100644 kakarot-ssj/crates/contracts/tests/test_ownable.cairo create mode 100644 kakarot-ssj/crates/evm/.gitignore create mode 100644 kakarot-ssj/crates/evm/Scarb.toml create mode 100644 kakarot-ssj/crates/evm/src/backend.cairo create mode 100644 kakarot-ssj/crates/evm/src/backend/starknet_backend.cairo create mode 100644 kakarot-ssj/crates/evm/src/backend/validation.cairo create mode 100644 kakarot-ssj/crates/evm/src/call_helpers.cairo create mode 100644 kakarot-ssj/crates/evm/src/create_helpers.cairo create mode 100644 kakarot-ssj/crates/evm/src/errors.cairo create mode 100644 kakarot-ssj/crates/evm/src/gas.cairo create mode 100644 kakarot-ssj/crates/evm/src/instructions.cairo create mode 100644 kakarot-ssj/crates/evm/src/instructions/block_information.cairo create mode 100644 kakarot-ssj/crates/evm/src/instructions/comparison_operations.cairo create mode 100644 kakarot-ssj/crates/evm/src/instructions/duplication_operations.cairo create mode 100644 kakarot-ssj/crates/evm/src/instructions/environmental_information.cairo create mode 100644 kakarot-ssj/crates/evm/src/instructions/exchange_operations.cairo create mode 100644 kakarot-ssj/crates/evm/src/instructions/logging_operations.cairo create mode 100644 kakarot-ssj/crates/evm/src/instructions/memory_operations.cairo create mode 100644 kakarot-ssj/crates/evm/src/instructions/push_operations.cairo create mode 100644 kakarot-ssj/crates/evm/src/instructions/sha3.cairo create mode 100644 kakarot-ssj/crates/evm/src/instructions/stop_and_arithmetic_operations.cairo create mode 100644 kakarot-ssj/crates/evm/src/instructions/system_operations.cairo create mode 100644 kakarot-ssj/crates/evm/src/interpreter.cairo create mode 100644 kakarot-ssj/crates/evm/src/lib.cairo create mode 100644 kakarot-ssj/crates/evm/src/memory.cairo create mode 100644 kakarot-ssj/crates/evm/src/model.cairo create mode 100644 kakarot-ssj/crates/evm/src/model/account.cairo create mode 100644 kakarot-ssj/crates/evm/src/model/vm.cairo create mode 100644 kakarot-ssj/crates/evm/src/precompiles.cairo create mode 100644 kakarot-ssj/crates/evm/src/precompiles/blake2f.cairo create mode 100644 kakarot-ssj/crates/evm/src/precompiles/ec_operations.cairo create mode 100644 kakarot-ssj/crates/evm/src/precompiles/ec_operations/ec_add.cairo create mode 100644 kakarot-ssj/crates/evm/src/precompiles/ec_operations/ec_mul.cairo create mode 100644 kakarot-ssj/crates/evm/src/precompiles/ec_recover.cairo create mode 100644 kakarot-ssj/crates/evm/src/precompiles/identity.cairo create mode 100644 kakarot-ssj/crates/evm/src/precompiles/modexp.cairo create mode 100644 kakarot-ssj/crates/evm/src/precompiles/p256verify.cairo create mode 100644 kakarot-ssj/crates/evm/src/precompiles/sha256.cairo create mode 100644 kakarot-ssj/crates/evm/src/stack.cairo create mode 100644 kakarot-ssj/crates/evm/src/state.cairo create mode 100644 kakarot-ssj/crates/evm/src/test_data.cairo create mode 100644 kakarot-ssj/crates/evm/src/test_data/test_data_blake2f.cairo create mode 100644 kakarot-ssj/crates/evm/src/test_data/test_data_modexp.cairo create mode 100644 kakarot-ssj/crates/evm/src/test_utils.cairo create mode 100644 kakarot-ssj/crates/openzeppelin/Scarb.toml create mode 100644 kakarot-ssj/crates/openzeppelin/src/lib.cairo create mode 100644 kakarot-ssj/crates/openzeppelin/src/token.cairo create mode 100644 kakarot-ssj/crates/openzeppelin/src/token/erc20.cairo create mode 100644 kakarot-ssj/crates/openzeppelin/src/token/erc20/erc20.cairo create mode 100644 kakarot-ssj/crates/openzeppelin/src/token/erc20/interface.cairo create mode 100644 kakarot-ssj/crates/snforge_utils/.gitignore create mode 100644 kakarot-ssj/crates/snforge_utils/Scarb.toml create mode 100644 kakarot-ssj/crates/snforge_utils/src/contracts.cairo create mode 100644 kakarot-ssj/crates/snforge_utils/src/lib.cairo create mode 100644 kakarot-ssj/crates/utils/.gitignore create mode 100644 kakarot-ssj/crates/utils/Scarb.toml create mode 100644 kakarot-ssj/crates/utils/src/address.cairo create mode 100644 kakarot-ssj/crates/utils/src/constants.cairo create mode 100644 kakarot-ssj/crates/utils/src/crypto.cairo create mode 100644 kakarot-ssj/crates/utils/src/crypto/blake2_compress.cairo create mode 100644 kakarot-ssj/crates/utils/src/crypto/modexp.cairo create mode 100644 kakarot-ssj/crates/utils/src/crypto/modexp/arith.cairo create mode 100644 kakarot-ssj/crates/utils/src/crypto/modexp/lib.cairo create mode 100644 kakarot-ssj/crates/utils/src/crypto/modexp/mpnat.cairo create mode 100644 kakarot-ssj/crates/utils/src/errors.cairo create mode 100644 kakarot-ssj/crates/utils/src/eth_transaction.cairo create mode 100644 kakarot-ssj/crates/utils/src/eth_transaction/common.cairo create mode 100644 kakarot-ssj/crates/utils/src/eth_transaction/eip1559.cairo create mode 100644 kakarot-ssj/crates/utils/src/eth_transaction/eip2930.cairo create mode 100644 kakarot-ssj/crates/utils/src/eth_transaction/legacy.cairo create mode 100644 kakarot-ssj/crates/utils/src/eth_transaction/transaction.cairo create mode 100644 kakarot-ssj/crates/utils/src/eth_transaction/tx_type.cairo create mode 100644 kakarot-ssj/crates/utils/src/felt_vec.cairo create mode 100644 kakarot-ssj/crates/utils/src/fmt.cairo create mode 100644 kakarot-ssj/crates/utils/src/helpers.cairo create mode 100644 kakarot-ssj/crates/utils/src/i256.cairo create mode 100644 kakarot-ssj/crates/utils/src/lib.cairo create mode 100644 kakarot-ssj/crates/utils/src/math.cairo create mode 100644 kakarot-ssj/crates/utils/src/rlp.cairo create mode 100644 kakarot-ssj/crates/utils/src/serialization.cairo create mode 100644 kakarot-ssj/crates/utils/src/set.cairo create mode 100644 kakarot-ssj/crates/utils/src/test_data.cairo create mode 100644 kakarot-ssj/crates/utils/src/traits.cairo create mode 100644 kakarot-ssj/crates/utils/src/traits/array.cairo create mode 100644 kakarot-ssj/crates/utils/src/traits/bytes.cairo create mode 100644 kakarot-ssj/crates/utils/src/traits/eth_address.cairo create mode 100644 kakarot-ssj/crates/utils/src/traits/integer.cairo create mode 100644 kakarot-ssj/crates/utils/src/utils.cairo create mode 100644 kakarot-ssj/docs/CODE_OF_CONDUCT.md create mode 100644 kakarot-ssj/docs/CONTRIBUTING.md create mode 100644 kakarot-ssj/docs/SECURITY.md create mode 100644 kakarot-ssj/docs/general/account_state.png create mode 100644 kakarot-ssj/docs/general/contract_bytecode.md create mode 100644 kakarot-ssj/docs/general/contract_storage.md create mode 100644 kakarot-ssj/docs/general/local_state.md create mode 100644 kakarot-ssj/docs/general/machine.md create mode 100644 kakarot-ssj/docs/general/volition.png create mode 100644 kakarot-ssj/docs/img/kakarot_github_banner.png create mode 100644 kakarot-ssj/package-lock.json create mode 100644 kakarot-ssj/package.json create mode 100644 kakarot-ssj/rust-toolchain create mode 100644 kakarot-ssj/scripts/compare_snapshot.py create mode 100644 kakarot-ssj/scripts/compute_create_address.ts create mode 100644 kakarot-ssj/scripts/compute_rlp_encoding.ts create mode 100644 kakarot-ssj/scripts/compute_starknet_address.ts create mode 100644 kakarot-ssj/scripts/data/input_access_list_tx.json create mode 100644 kakarot-ssj/scripts/data/input_eip1559_y_parity_false.json create mode 100644 kakarot-ssj/scripts/data/input_eip_2930_counter_inc_tx.json create mode 100644 kakarot-ssj/scripts/data/input_fee_tx.json create mode 100644 kakarot-ssj/scripts/data/input_legacy_deploy_tx.json create mode 100644 kakarot-ssj/scripts/data/input_legacy_tx.json create mode 100644 kakarot-ssj/scripts/filter_tests.py create mode 100644 kakarot-ssj/scripts/find_selectory.py create mode 100644 kakarot-ssj/scripts/gas_debug_call.py create mode 100644 kakarot-ssj/scripts/gen_snapshot.py create mode 100644 kakarot-ssj/scripts/install_hook.sh create mode 100644 kakarot-ssj/scripts/run_filtered_tests.py create mode 100755 kakarot-ssj/scripts/setup_cairo_native.sh create mode 100644 kakarot-ssj/tsconfig.json diff --git a/.github/workflows/kakarot-ssj/build.yml b/.github/workflows/kakarot-ssj/build.yml new file mode 100644 index 000000000..7cca4d20d --- /dev/null +++ b/.github/workflows/kakarot-ssj/build.yml @@ -0,0 +1,32 @@ +name: Reusable Build Workflow + +on: + workflow_call: + inputs: + artifact-name: + required: true + type: string + +permissions: read-all + +jobs: + build: + runs-on: ubuntu-latest + env: + CI_COMMIT_MESSAGE: CI Formatting Auto Commit + CI_COMMIT_AUTHOR: ${{ github.event.repository.name }} CI + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Scarb + uses: software-mansion/setup-scarb@v1 + + - name: Build contracts + run: scarb build -p contracts + + - name: Upload artifacts + uses: actions/upload-artifact@v3 + with: + name: ${{ inputs.artifact-name }} + path: target/dev diff --git a/.github/workflows/kakarot-ssj/ci.yml b/.github/workflows/kakarot-ssj/ci.yml new file mode 100644 index 000000000..b99ecd358 --- /dev/null +++ b/.github/workflows/kakarot-ssj/ci.yml @@ -0,0 +1,82 @@ +name: CI + +on: + push: + branches: + - main + +env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: read-all + +jobs: + build: + uses: ./.github/workflows/build.yml + with: + artifact-name: kakarot-ssj-build + + tests-unit: + uses: ./.github/workflows/tests-unit.yml + with: + run-fmt-check: false + + ef-tests: + uses: ./.github/workflows/ef-tests.yml + needs: [build] + with: + artifact-name: kakarot-ssj-build + + resources: + runs-on: ubuntu-latest + needs: [ef-tests] + steps: + - uses: actions/checkout@v4 + + - name: Set up Python 3.10.14 + uses: actions/setup-python@v4 + with: + python-version: 3.10.14 + + - name: Load cached Poetry installation + id: cached-poetry + uses: actions/cache@v4 + with: + path: ~/.local + key: poetry-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }} + + - name: Install Poetry + if: steps.cached-poetry.outputs.cache-hit != 'true' + uses: snok/install-poetry@v1 + with: + virtualenvs-create: true + virtualenvs-in-project: true + installer-parallel: true + + - run: poetry config installer.modern-installation false + + - name: Load cached venv + id: cached-poetry-dependencies + uses: actions/cache@v4 + with: + path: .venv + key: venv-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }} + + - name: Install dependencies + if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true' + run: make setup + + - name: Load performance artifacts + uses: actions/download-artifact@v3 + with: + path: resources + name: resources + + - name: Check resources evolution + run: | + result=$(GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }} make check-resources 2>&1) + echo "$result" >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/kakarot-ssj/ef-tests.yml b/.github/workflows/kakarot-ssj/ef-tests.yml new file mode 100644 index 000000000..5957d20fc --- /dev/null +++ b/.github/workflows/kakarot-ssj/ef-tests.yml @@ -0,0 +1,129 @@ +name: EF-Tests + +on: + workflow_call: + inputs: + artifact-name: + required: true + type: string + +permissions: read-all + +jobs: + ef-tests: + # trunk-ignore(actionlint/runner-label) + runs-on: ubuntu-latest-16-cores + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Cache cairo-native setup + id: cache-cairo-native + uses: actions/cache@v3 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + ./libcairo_native_runtime.a + key: + ${{ runner.os }}-cairo-native-${{ hashFiles('**/Cargo.lock', + 'scripts/setup_cairo_native.sh') }} + + - name: Make setup script executable + run: chmod +x ./scripts/setup_cairo_native.sh + + - name: Setup Cairo Native + run: | + if [[ "${{ steps.cache-cairo-native.outputs.cache-hit }}" == 'true' ]]; then + sudo ./scripts/setup_cairo_native.sh -s + else + sudo ./scripts/setup_cairo_native.sh + fi + + - name: Set Environment Variables + run: | + echo "MLIR_SYS_190_PREFIX=/usr/lib/llvm-19/" >> $GITHUB_ENV + echo "LLVM_SYS_191_PREFIX=/usr/lib/llvm-19/" >> $GITHUB_ENV + echo "TABLEGEN_190_PREFIX=/usr/lib/llvm-19/" >> $GITHUB_ENV + echo "CAIRO_NATIVE_RUNTIME_LIBRARY=$(pwd)/libcairo_native_runtime.a" >> $GITHUB_ENV + + - name: Checkout ef-tests + uses: actions/checkout@v4 + with: + repository: kkrt-labs/ef-tests + ref: feat/cairo-native + path: ef-tests # Check out to a subdirectory to avoid cleaning the kakarot-ssj directory + + - name: Checkout local skip file + uses: actions/checkout@v4 + with: + sparse-checkout: | + blockchain-tests-skip.yml + sparse-checkout-cone-mode: false + path: skip-file + + - name: Setup ef-tests + run: | + mv skip-file/blockchain-tests-skip.yml ef-tests/blockchain-tests-skip.yml + cd ef-tests + mkdir -p build/common + make setup setup-kakarot-v0 + + - name: Install nextest + uses: taiki-e/install-action@nextest + + - name: Download Kakarot-SSJ build artifacts in v1 + uses: actions/download-artifact@v3 + with: + name: ${{ inputs.artifact-name }} + path: ef-tests/build/v1 + + - name: Move Cairo1Helpers + run: | + mv ef-tests/build/v1/contracts_Cairo1Helpers.compiled_contract_class.json \ + ef-tests/build/common/cairo1_helpers.json + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: 3.10.14 + + # Add this step to verify the file exists + - name: Verify libcairo_native_runtime.a + run: | + echo $CAIRO_NATIVE_RUNTIME_LIBRARY + ls -l $CAIRO_NATIVE_RUNTIME_LIBRARY + + - name: Run tests + working-directory: ef-tests + run: | + set -o pipefail + RUST_MIN_STACK=1342177280 make ef-test-v1-native | tee data.txt + set +o pipefail + + - name: Retrieve ef-tests execution resources + working-directory: ef-tests + run: python scripts/compute_resources.py + env: + KAKAROT_VERSION: v1 + + - name: Upload resources + uses: actions/upload-artifact@v3 + with: + path: ef-tests/resources + name: resources + + - name: Generate blockchain-tests-skip.yml file + if: github.event_name == 'workflow_dispatch' + working-directory: ef-tests + run: make generate-skip-file + + - name: Upload skip file + if: github.event_name == 'workflow_dispatch' + uses: actions/upload-artifact@v3 + with: + path: ef-tests/blockchain-tests-skip.yml + name: blockchain-tests-skip diff --git a/.github/workflows/kakarot-ssj/release.yml b/.github/workflows/kakarot-ssj/release.yml new file mode 100644 index 000000000..122c07080 --- /dev/null +++ b/.github/workflows/kakarot-ssj/release.yml @@ -0,0 +1,28 @@ +# trunk-ignore-all(checkov/CKV2_GHA_1) +name: Release + +on: + release: + types: [published] + +jobs: + build-and-upload: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Set up Scarb + uses: software-mansion/setup-scarb@v1 + - name: Build contracts + run: | + scarb build -p contracts + - name: Zip dev artifacts + run: zip -rj kakarot-ssj-build.zip target/dev + - name: Upload artifacts to release + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: kakarot-ssj-build.zip + asset_name: kakarot-ssj-build.zip + tag: ${{ github.ref_name }} + overwrite: true diff --git a/.github/workflows/kakarot-ssj/test.yml b/.github/workflows/kakarot-ssj/test.yml new file mode 100644 index 000000000..cc095668a --- /dev/null +++ b/.github/workflows/kakarot-ssj/test.yml @@ -0,0 +1,26 @@ +name: CI + +permissions: read-all + +on: [pull_request] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + uses: ./.github/workflows/build.yml + with: + artifact-name: kakarot-ssj-build + + tests-unit: + uses: ./.github/workflows/tests-unit.yml + with: + run-fmt-check: true + + ef-tests: + uses: ./.github/workflows/ef-tests.yml + needs: [build] + with: + artifact-name: kakarot-ssj-build diff --git a/.github/workflows/kakarot-ssj/tests-unit.yml b/.github/workflows/kakarot-ssj/tests-unit.yml new file mode 100644 index 000000000..2ff0ef28d --- /dev/null +++ b/.github/workflows/kakarot-ssj/tests-unit.yml @@ -0,0 +1,26 @@ +name: Reusable Unit Tests Workflow + +on: + workflow_call: + inputs: + run-fmt-check: + type: boolean + default: false + required: false + +permissions: read-all + +jobs: + unit-tests: + runs-on: ubuntu-latest-16-cores # trunk-ignore(actionlint/runner-label) + steps: + - uses: actions/checkout@v4 + - uses: foundry-rs/setup-snfoundry@v3 + - uses: software-mansion/setup-scarb@v1 + + - name: Run format check + if: inputs.run-fmt-check + run: scarb fmt --check + + - name: Run tests + run: scarb test diff --git a/.github/workflows/kakarot-ssj/trunk-check.yaml b/.github/workflows/kakarot-ssj/trunk-check.yaml new file mode 100644 index 000000000..2e0216311 --- /dev/null +++ b/.github/workflows/kakarot-ssj/trunk-check.yaml @@ -0,0 +1,24 @@ +name: Trunk + +on: [pull_request] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: read-all + +jobs: + trunk_check: + name: Trunk Check Runner + runs-on: ubuntu-latest + permissions: + checks: write # For trunk to post annotations + contents: read # For repo checkout + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Trunk Check + uses: trunk-io/trunk-action@v1 diff --git a/.github/actionlint.yaml b/.github/workflows/kakarot0/actionlint.yaml similarity index 100% rename from .github/actionlint.yaml rename to .github/workflows/kakarot0/actionlint.yaml diff --git a/.github/workflows/ci.yml b/.github/workflows/kakarot0/ci.yml similarity index 100% rename from .github/workflows/ci.yml rename to .github/workflows/kakarot0/ci.yml diff --git a/.github/workflows/nightly-fuzzing.yml b/.github/workflows/kakarot0/nightly-fuzzing.yml similarity index 100% rename from .github/workflows/nightly-fuzzing.yml rename to .github/workflows/kakarot0/nightly-fuzzing.yml diff --git a/.github/workflows/release.yml b/.github/workflows/kakarot0/release.yml similarity index 100% rename from .github/workflows/release.yml rename to .github/workflows/kakarot0/release.yml diff --git a/.github/workflows/trunk-check.yaml b/.github/workflows/kakarot0/trunk-check.yaml similarity index 100% rename from .github/workflows/trunk-check.yaml rename to .github/workflows/kakarot0/trunk-check.yaml diff --git a/.github/workflows/update-rpc.yml b/.github/workflows/kakarot0/update-rpc.yml similarity index 100% rename from .github/workflows/update-rpc.yml rename to .github/workflows/kakarot0/update-rpc.yml diff --git a/kakarot-ssj/.all-contributorsrc b/kakarot-ssj/.all-contributorsrc new file mode 100644 index 000000000..5ab9a148a --- /dev/null +++ b/kakarot-ssj/.all-contributorsrc @@ -0,0 +1,189 @@ +{ + "projectName": "kakarot-ssj", + "projectOwner": "sayajin-labs", + "repoType": "github", + "repoHost": "https://github.com", + "files": ["README.md"], + "imageSize": 100, + "commit": true, + "commitConvention": "gitmoji", + "contributors": [ + { + "login": "abdelhamidbakhta", + "name": "Abdel @ StarkWare ", + "avatar_url": "https://avatars.githubusercontent.com/u/45264458?v=4", + "profile": "https://github.com/abdelhamidbakhta", + "contributions": ["code"] + }, + { + "login": "jobez", + "name": "johann bestowrous", + "avatar_url": "https://avatars.githubusercontent.com/u/615197?v=4", + "profile": "https://github.com/jobez", + "contributions": ["code"] + }, + { + "login": "Eikix", + "name": "Elias Tazartes", + "avatar_url": "https://avatars.githubusercontent.com/u/66871571?v=4", + "profile": "https://github.com/Eikix", + "contributions": ["review", "tutorial", "talk"] + }, + { + "login": "enitrat", + "name": "Mathieu", + "avatar_url": "https://avatars.githubusercontent.com/u/60658558?v=4", + "profile": "https://github.com/enitrat", + "contributions": ["code", "test", "doc"] + }, + { + "login": "khaeljy", + "name": "khaeljy", + "avatar_url": "https://avatars.githubusercontent.com/u/1810456?v=4", + "profile": "https://github.com/khaeljy", + "contributions": ["code"] + }, + { + "login": "ClementWalter", + "name": "Clément Walter", + "avatar_url": "https://avatars.githubusercontent.com/u/18620296?v=4", + "profile": "https://www.linkedin.com/in/clementwalter/", + "contributions": ["code"] + }, + { + "login": "LucasLvy", + "name": "Lucas @ StarkWare", + "avatar_url": "https://avatars.githubusercontent.com/u/70894690?v=4", + "profile": "https://github.com/LucasLvy", + "contributions": ["code"] + }, + { + "login": "lambda-0x", + "name": "lambda-0x", + "avatar_url": "https://avatars.githubusercontent.com/u/87354252?v=4", + "profile": "https://github.com/lambda-0x", + "contributions": ["code"] + }, + { + "login": "danilowhk", + "name": "danilowhk", + "avatar_url": "https://avatars.githubusercontent.com/u/12735159?v=4", + "profile": "https://github.com/danilowhk", + "contributions": ["code"] + }, + { + "login": "TAdev0", + "name": "Tristan", + "avatar_url": "https://avatars.githubusercontent.com/u/122918260?v=4", + "profile": "https://github.com/TAdev0", + "contributions": ["code"] + }, + { + "login": "Quentash", + "name": "Quentash", + "avatar_url": "https://avatars.githubusercontent.com/u/100387965?v=4", + "profile": "https://github.com/Quentash", + "contributions": ["code"] + }, + { + "login": "ftupas", + "name": "ftupas", + "avatar_url": "https://avatars.githubusercontent.com/u/35031356?v=4", + "profile": "https://github.com/ftupas", + "contributions": ["code"] + }, + { + "login": "aniketpr01", + "name": "Aniket Prajapati", + "avatar_url": "https://avatars.githubusercontent.com/u/46114123?v=4", + "profile": "https://aniketpr01.github.io/", + "contributions": ["code"] + }, + { + "login": "dbejarano820", + "name": "Daniel Bejarano", + "avatar_url": "https://avatars.githubusercontent.com/u/58019353?v=4", + "profile": "https://github.com/dbejarano820", + "contributions": ["code"] + }, + { + "login": "Noeljarillo", + "name": "Noeljarillo", + "avatar_url": "https://avatars.githubusercontent.com/u/77942794?v=4", + "profile": "https://github.com/Noeljarillo", + "contributions": ["code"] + }, + { + "login": "trbutler4", + "name": "Thomas Butler", + "avatar_url": "https://avatars.githubusercontent.com/u/58192340?v=4", + "profile": "https://github.com/trbutler4", + "contributions": ["code"] + }, + { + "login": "kariy", + "name": "Ammar Arif", + "avatar_url": "https://avatars.githubusercontent.com/u/26515232?v=4", + "profile": "https://github.com/kariy", + "contributions": ["doc"] + }, + { + "login": "greged93", + "name": "greged93", + "avatar_url": "https://avatars.githubusercontent.com/u/82421016?v=4", + "profile": "https://github.com/greged93", + "contributions": ["code"] + }, + { + "login": "chachaleo", + "name": "Charlotte", + "avatar_url": "https://avatars.githubusercontent.com/u/49371958?v=4", + "profile": "https://github.com/chachaleo", + "contributions": ["code"] + }, + { + "login": "akhercha", + "name": "akhercha", + "avatar_url": "https://avatars.githubusercontent.com/u/22559023?v=4", + "profile": "https://t.me/notaihe", + "contributions": ["code"] + }, + { + "login": "alextnetto", + "name": "Alexandro T. Netto", + "avatar_url": "https://avatars.githubusercontent.com/u/56097505?v=4", + "profile": "https://github.com/alextnetto", + "contributions": ["code"] + }, + { + "login": "edisontim", + "name": "tedison", + "avatar_url": "https://avatars.githubusercontent.com/u/76473430?v=4", + "profile": "https://github.com/edisontim", + "contributions": ["code"] + }, + { + "login": "rkdud007", + "name": "Pia", + "avatar_url": "https://avatars.githubusercontent.com/u/76558220?v=4", + "profile": "https://github.com/rkdud007", + "contributions": ["code"] + }, + { + "login": "glihm", + "name": "glihm", + "avatar_url": "https://avatars.githubusercontent.com/u/7962849?v=4", + "profile": "https://github.com/glihm", + "contributions": ["code"] + }, + { + "login": "bajpai244", + "name": "Harsh Bajpai", + "avatar_url": "https://avatars.githubusercontent.com/u/41180869?v=4", + "profile": "https://github.com/bajpai244", + "contributions": ["code"] + } + ], + "contributorsPerLine": 7, + "linkToUsage": true +} diff --git a/kakarot-ssj/.codespellrc b/kakarot-ssj/.codespellrc new file mode 100644 index 000000000..8511d3f6f --- /dev/null +++ b/kakarot-ssj/.codespellrc @@ -0,0 +1,2 @@ +[codespell] +ignore-words-list = crate diff --git a/kakarot-ssj/.devcontainer/devcontainer.json b/kakarot-ssj/.devcontainer/devcontainer.json new file mode 100644 index 000000000..8ce21e6b3 --- /dev/null +++ b/kakarot-ssj/.devcontainer/devcontainer.json @@ -0,0 +1,10 @@ +{ + "name": "Kakarot SSJ", + "image": "mcr.microsoft.com/devcontainers/base:jammy", + "customizations": { + "vscode": { + "extensions": ["starkware.cairo1"] + } + }, + "postCreateCommand": "curl --proto '=https' --tlsv1.2 -sSf https://docs.swmansion.com/scarb/install.sh | sh" +} diff --git a/kakarot-ssj/.env.example b/kakarot-ssj/.env.example new file mode 100644 index 000000000..0cf3d0a25 --- /dev/null +++ b/kakarot-ssj/.env.example @@ -0,0 +1,5 @@ +# A Github token to download the CI artifacts +GITHUB_TOKEN= +# Private key to sign transactions for RLP scripts/compute_rlp_encoding.ts +# Warning: Do not use this key in production systems +PRIVATE_KEY=0x6be0067ba259624aa28f796b703e7d095925a470b17786767bd09aaa3fc2ceea diff --git a/kakarot-ssj/.github/CODEOWNERS b/kakarot-ssj/.github/CODEOWNERS new file mode 100644 index 000000000..f5bcd1a3b --- /dev/null +++ b/kakarot-ssj/.github/CODEOWNERS @@ -0,0 +1,3 @@ +* @abdelhamidbakhta +* @Eikix +* @ClementWalter diff --git a/kakarot-ssj/.github/ISSUE_TEMPLATE/01_BUG_REPORT.md b/kakarot-ssj/.github/ISSUE_TEMPLATE/01_BUG_REPORT.md new file mode 100644 index 000000000..350367dfd --- /dev/null +++ b/kakarot-ssj/.github/ISSUE_TEMPLATE/01_BUG_REPORT.md @@ -0,0 +1,40 @@ +--- +name: Bug Report +about: Create a report to help Kakarot to improve +title: "bug: " +labels: "bug" +assignees: "" +--- + +## Bug Report + +**Kakarot version:** + + + +**Current behavior:** + + + +**Expected behavior:** + + + +**Steps to reproduce:** + + + +**Related code:** + + + +```bash +insert short code snippets here +``` + +**Other information:** + + diff --git a/kakarot-ssj/.github/ISSUE_TEMPLATE/02_FEATURE_REQUEST.md b/kakarot-ssj/.github/ISSUE_TEMPLATE/02_FEATURE_REQUEST.md new file mode 100644 index 000000000..44ad3de06 --- /dev/null +++ b/kakarot-ssj/.github/ISSUE_TEMPLATE/02_FEATURE_REQUEST.md @@ -0,0 +1,23 @@ +--- +name: Feature Request +about: Suggest an idea for this project +title: "feat: " +labels: "enhancement" +assignees: "" +--- + +## Feature Request + +### Describe the Feature Request + +### Describe Preferred Solution + +### Related Code + +### Additional Context + +**If the feature request is approved, would you be willing to submit a PR?** +_(Help can be provided if you need assistance submitting a PR)_ + +- [ ] Yes +- [ ] No diff --git a/kakarot-ssj/.github/ISSUE_TEMPLATE/03_CODEBASE_IMPROVEMENT.md b/kakarot-ssj/.github/ISSUE_TEMPLATE/03_CODEBASE_IMPROVEMENT.md new file mode 100644 index 000000000..5f0050e39 --- /dev/null +++ b/kakarot-ssj/.github/ISSUE_TEMPLATE/03_CODEBASE_IMPROVEMENT.md @@ -0,0 +1,9 @@ +--- +name: Codebase improvement +about: + Provide your feedback for the existing codebase. Suggest a better solution for + algorithms, development tools, etc. +title: "dev: " +labels: "enhancement" +assignees: "" +--- diff --git a/kakarot-ssj/.github/ISSUE_TEMPLATE/config.yml b/kakarot-ssj/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 000000000..6a42160f5 --- /dev/null +++ b/kakarot-ssj/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,6 @@ +--- +blank_issues_enabled: false +contact_links: + - name: Kakarot Community Support + url: https://github.com/sayajin-labs/kakarot-ssj/discussions + about: Please ask and answer questions here. diff --git a/kakarot-ssj/.github/PULL_REQUEST_TEMPLATE.md b/kakarot-ssj/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..77cf20ce2 --- /dev/null +++ b/kakarot-ssj/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,39 @@ + + +## Pull Request type + + + +Please check the type of change your PR introduces: + +- [ ] Bugfix +- [ ] Feature +- [ ] Code style update (formatting, renaming) +- [ ] Refactoring (no functional changes, no API changes) +- [ ] Build-related changes +- [ ] Documentation content changes +- [ ] Other (please describe): + +## What is the current behavior? + + + +Resolves: # + +## What is the new behavior? + + + +- +- +- + +## Does this introduce a breaking change? + +- [ ] Yes +- [ ] No + + diff --git a/kakarot-ssj/.github/workflows/build.yml b/kakarot-ssj/.github/workflows/build.yml new file mode 100644 index 000000000..7cca4d20d --- /dev/null +++ b/kakarot-ssj/.github/workflows/build.yml @@ -0,0 +1,32 @@ +name: Reusable Build Workflow + +on: + workflow_call: + inputs: + artifact-name: + required: true + type: string + +permissions: read-all + +jobs: + build: + runs-on: ubuntu-latest + env: + CI_COMMIT_MESSAGE: CI Formatting Auto Commit + CI_COMMIT_AUTHOR: ${{ github.event.repository.name }} CI + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Scarb + uses: software-mansion/setup-scarb@v1 + + - name: Build contracts + run: scarb build -p contracts + + - name: Upload artifacts + uses: actions/upload-artifact@v3 + with: + name: ${{ inputs.artifact-name }} + path: target/dev diff --git a/kakarot-ssj/.github/workflows/ci.yml b/kakarot-ssj/.github/workflows/ci.yml new file mode 100644 index 000000000..b99ecd358 --- /dev/null +++ b/kakarot-ssj/.github/workflows/ci.yml @@ -0,0 +1,82 @@ +name: CI + +on: + push: + branches: + - main + +env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: read-all + +jobs: + build: + uses: ./.github/workflows/build.yml + with: + artifact-name: kakarot-ssj-build + + tests-unit: + uses: ./.github/workflows/tests-unit.yml + with: + run-fmt-check: false + + ef-tests: + uses: ./.github/workflows/ef-tests.yml + needs: [build] + with: + artifact-name: kakarot-ssj-build + + resources: + runs-on: ubuntu-latest + needs: [ef-tests] + steps: + - uses: actions/checkout@v4 + + - name: Set up Python 3.10.14 + uses: actions/setup-python@v4 + with: + python-version: 3.10.14 + + - name: Load cached Poetry installation + id: cached-poetry + uses: actions/cache@v4 + with: + path: ~/.local + key: poetry-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }} + + - name: Install Poetry + if: steps.cached-poetry.outputs.cache-hit != 'true' + uses: snok/install-poetry@v1 + with: + virtualenvs-create: true + virtualenvs-in-project: true + installer-parallel: true + + - run: poetry config installer.modern-installation false + + - name: Load cached venv + id: cached-poetry-dependencies + uses: actions/cache@v4 + with: + path: .venv + key: venv-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }} + + - name: Install dependencies + if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true' + run: make setup + + - name: Load performance artifacts + uses: actions/download-artifact@v3 + with: + path: resources + name: resources + + - name: Check resources evolution + run: | + result=$(GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }} make check-resources 2>&1) + echo "$result" >> "$GITHUB_STEP_SUMMARY" diff --git a/kakarot-ssj/.github/workflows/ef-tests.yml b/kakarot-ssj/.github/workflows/ef-tests.yml new file mode 100644 index 000000000..5957d20fc --- /dev/null +++ b/kakarot-ssj/.github/workflows/ef-tests.yml @@ -0,0 +1,129 @@ +name: EF-Tests + +on: + workflow_call: + inputs: + artifact-name: + required: true + type: string + +permissions: read-all + +jobs: + ef-tests: + # trunk-ignore(actionlint/runner-label) + runs-on: ubuntu-latest-16-cores + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Cache cairo-native setup + id: cache-cairo-native + uses: actions/cache@v3 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + ./libcairo_native_runtime.a + key: + ${{ runner.os }}-cairo-native-${{ hashFiles('**/Cargo.lock', + 'scripts/setup_cairo_native.sh') }} + + - name: Make setup script executable + run: chmod +x ./scripts/setup_cairo_native.sh + + - name: Setup Cairo Native + run: | + if [[ "${{ steps.cache-cairo-native.outputs.cache-hit }}" == 'true' ]]; then + sudo ./scripts/setup_cairo_native.sh -s + else + sudo ./scripts/setup_cairo_native.sh + fi + + - name: Set Environment Variables + run: | + echo "MLIR_SYS_190_PREFIX=/usr/lib/llvm-19/" >> $GITHUB_ENV + echo "LLVM_SYS_191_PREFIX=/usr/lib/llvm-19/" >> $GITHUB_ENV + echo "TABLEGEN_190_PREFIX=/usr/lib/llvm-19/" >> $GITHUB_ENV + echo "CAIRO_NATIVE_RUNTIME_LIBRARY=$(pwd)/libcairo_native_runtime.a" >> $GITHUB_ENV + + - name: Checkout ef-tests + uses: actions/checkout@v4 + with: + repository: kkrt-labs/ef-tests + ref: feat/cairo-native + path: ef-tests # Check out to a subdirectory to avoid cleaning the kakarot-ssj directory + + - name: Checkout local skip file + uses: actions/checkout@v4 + with: + sparse-checkout: | + blockchain-tests-skip.yml + sparse-checkout-cone-mode: false + path: skip-file + + - name: Setup ef-tests + run: | + mv skip-file/blockchain-tests-skip.yml ef-tests/blockchain-tests-skip.yml + cd ef-tests + mkdir -p build/common + make setup setup-kakarot-v0 + + - name: Install nextest + uses: taiki-e/install-action@nextest + + - name: Download Kakarot-SSJ build artifacts in v1 + uses: actions/download-artifact@v3 + with: + name: ${{ inputs.artifact-name }} + path: ef-tests/build/v1 + + - name: Move Cairo1Helpers + run: | + mv ef-tests/build/v1/contracts_Cairo1Helpers.compiled_contract_class.json \ + ef-tests/build/common/cairo1_helpers.json + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: 3.10.14 + + # Add this step to verify the file exists + - name: Verify libcairo_native_runtime.a + run: | + echo $CAIRO_NATIVE_RUNTIME_LIBRARY + ls -l $CAIRO_NATIVE_RUNTIME_LIBRARY + + - name: Run tests + working-directory: ef-tests + run: | + set -o pipefail + RUST_MIN_STACK=1342177280 make ef-test-v1-native | tee data.txt + set +o pipefail + + - name: Retrieve ef-tests execution resources + working-directory: ef-tests + run: python scripts/compute_resources.py + env: + KAKAROT_VERSION: v1 + + - name: Upload resources + uses: actions/upload-artifact@v3 + with: + path: ef-tests/resources + name: resources + + - name: Generate blockchain-tests-skip.yml file + if: github.event_name == 'workflow_dispatch' + working-directory: ef-tests + run: make generate-skip-file + + - name: Upload skip file + if: github.event_name == 'workflow_dispatch' + uses: actions/upload-artifact@v3 + with: + path: ef-tests/blockchain-tests-skip.yml + name: blockchain-tests-skip diff --git a/kakarot-ssj/.github/workflows/release.yml b/kakarot-ssj/.github/workflows/release.yml new file mode 100644 index 000000000..122c07080 --- /dev/null +++ b/kakarot-ssj/.github/workflows/release.yml @@ -0,0 +1,28 @@ +# trunk-ignore-all(checkov/CKV2_GHA_1) +name: Release + +on: + release: + types: [published] + +jobs: + build-and-upload: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Set up Scarb + uses: software-mansion/setup-scarb@v1 + - name: Build contracts + run: | + scarb build -p contracts + - name: Zip dev artifacts + run: zip -rj kakarot-ssj-build.zip target/dev + - name: Upload artifacts to release + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: kakarot-ssj-build.zip + asset_name: kakarot-ssj-build.zip + tag: ${{ github.ref_name }} + overwrite: true diff --git a/kakarot-ssj/.github/workflows/test.yml b/kakarot-ssj/.github/workflows/test.yml new file mode 100644 index 000000000..cc095668a --- /dev/null +++ b/kakarot-ssj/.github/workflows/test.yml @@ -0,0 +1,26 @@ +name: CI + +permissions: read-all + +on: [pull_request] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + uses: ./.github/workflows/build.yml + with: + artifact-name: kakarot-ssj-build + + tests-unit: + uses: ./.github/workflows/tests-unit.yml + with: + run-fmt-check: true + + ef-tests: + uses: ./.github/workflows/ef-tests.yml + needs: [build] + with: + artifact-name: kakarot-ssj-build diff --git a/kakarot-ssj/.github/workflows/tests-unit.yml b/kakarot-ssj/.github/workflows/tests-unit.yml new file mode 100644 index 000000000..2ff0ef28d --- /dev/null +++ b/kakarot-ssj/.github/workflows/tests-unit.yml @@ -0,0 +1,26 @@ +name: Reusable Unit Tests Workflow + +on: + workflow_call: + inputs: + run-fmt-check: + type: boolean + default: false + required: false + +permissions: read-all + +jobs: + unit-tests: + runs-on: ubuntu-latest-16-cores # trunk-ignore(actionlint/runner-label) + steps: + - uses: actions/checkout@v4 + - uses: foundry-rs/setup-snfoundry@v3 + - uses: software-mansion/setup-scarb@v1 + + - name: Run format check + if: inputs.run-fmt-check + run: scarb fmt --check + + - name: Run tests + run: scarb test diff --git a/kakarot-ssj/.github/workflows/trunk-check.yaml b/kakarot-ssj/.github/workflows/trunk-check.yaml new file mode 100644 index 000000000..2e0216311 --- /dev/null +++ b/kakarot-ssj/.github/workflows/trunk-check.yaml @@ -0,0 +1,24 @@ +name: Trunk + +on: [pull_request] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: read-all + +jobs: + trunk_check: + name: Trunk Check Runner + runs-on: ubuntu-latest + permissions: + checks: write # For trunk to post annotations + contents: read # For repo checkout + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Trunk Check + uses: trunk-io/trunk-action@v1 diff --git a/kakarot-ssj/.gitignore b/kakarot-ssj/.gitignore new file mode 100644 index 000000000..1fa41de69 --- /dev/null +++ b/kakarot-ssj/.gitignore @@ -0,0 +1,10 @@ +.DS_Store +.env +target +.idea/ +node_modules/ +*.snfoundry_cache +cache/ + +scripts/libcairo_native_runtime.a +scripts/__pycache__ diff --git a/kakarot-ssj/.markdownlint.json b/kakarot-ssj/.markdownlint.json new file mode 100644 index 000000000..73c09417e --- /dev/null +++ b/kakarot-ssj/.markdownlint.json @@ -0,0 +1,8 @@ +{ + "MD033": false, + "MD041": false, + "MD045": false, + "MD013": { + "code_blocks": false + } +} diff --git a/kakarot-ssj/.prettierrc.json b/kakarot-ssj/.prettierrc.json new file mode 100644 index 000000000..5b5bd9933 --- /dev/null +++ b/kakarot-ssj/.prettierrc.json @@ -0,0 +1,3 @@ +{ + "proseWrap": "always" +} diff --git a/kakarot-ssj/.tool-versions b/kakarot-ssj/.tool-versions new file mode 100644 index 000000000..5248f18a0 --- /dev/null +++ b/kakarot-ssj/.tool-versions @@ -0,0 +1,2 @@ +scarb 2.8.3 +starknet-foundry 0.31.0 diff --git a/kakarot-ssj/.trunk/.gitignore b/kakarot-ssj/.trunk/.gitignore new file mode 100644 index 000000000..15966d087 --- /dev/null +++ b/kakarot-ssj/.trunk/.gitignore @@ -0,0 +1,9 @@ +*out +*logs +*actions +*notifications +*tools +plugins +user_trunk.yaml +user.yaml +tmp diff --git a/kakarot-ssj/.trunk/configs/.isort.cfg b/kakarot-ssj/.trunk/configs/.isort.cfg new file mode 100644 index 000000000..b9fb3f3e8 --- /dev/null +++ b/kakarot-ssj/.trunk/configs/.isort.cfg @@ -0,0 +1,2 @@ +[settings] +profile=black diff --git a/kakarot-ssj/.trunk/configs/.shellcheckrc b/kakarot-ssj/.trunk/configs/.shellcheckrc new file mode 100644 index 000000000..8c7b1ada8 --- /dev/null +++ b/kakarot-ssj/.trunk/configs/.shellcheckrc @@ -0,0 +1,7 @@ +enable=all +source-path=SCRIPTDIR +disable=SC2154 + +# If you're having issues with shellcheck following source, disable the errors via: +# disable=SC1090 +# disable=SC1091 diff --git a/kakarot-ssj/.trunk/configs/.yamllint.yaml b/kakarot-ssj/.trunk/configs/.yamllint.yaml new file mode 100644 index 000000000..4d444662d --- /dev/null +++ b/kakarot-ssj/.trunk/configs/.yamllint.yaml @@ -0,0 +1,10 @@ +rules: + quoted-strings: + required: only-when-needed + extra-allowed: ["{|}"] + empty-values: + forbid-in-block-mappings: true + forbid-in-flow-mappings: true + key-duplicates: {} + octal-values: + forbid-implicit-octal: true diff --git a/kakarot-ssj/.trunk/configs/ruff.toml b/kakarot-ssj/.trunk/configs/ruff.toml new file mode 100644 index 000000000..346b1d9aa --- /dev/null +++ b/kakarot-ssj/.trunk/configs/ruff.toml @@ -0,0 +1,5 @@ +# Generic, formatter-friendly config. +select = ["B", "D3", "D4", "E", "F"] + +# Never enforce `E501` (line length violations). This should be handled by formatters. +ignore = ["E501"] diff --git a/kakarot-ssj/.trunk/trunk.yaml b/kakarot-ssj/.trunk/trunk.yaml new file mode 100644 index 000000000..420b66299 --- /dev/null +++ b/kakarot-ssj/.trunk/trunk.yaml @@ -0,0 +1,74 @@ +# This file controls the behavior of Trunk: https://docs.trunk.io/cli +# To learn more about the format of this file, see https://docs.trunk.io/reference/trunk-yaml +version: 0.1 +cli: + version: 1.19.0 +plugins: + sources: + - id: trunk + ref: v1.4.2 + uri: https://github.com/trunk-io/plugins +runtimes: + enabled: + - go@1.21.0 + - node@18.12.1 + - python@3.10.8 +lint: + files: + - name: cairo + extensions: + - cairo + - name: solidity + extensions: + - sol + definitions: + # - name: cairo + # files: [cairo] + # commands: + # - output: rewrite + # success_codes: [1] + # formatter: true + # run: scarb fmt -e stdout + # read_output_from: stdout + # run_linter_from: workspace + - name: solidity + files: [solidity] + commands: + - output: rewrite + success_codes: [0, 1] + formatter: true + run: forge fmt ${target} --check -r + read_output_from: stdout + run_linter_from: workspace + enabled: + - osv-scanner@1.6.2 + - trivy@0.49.0 + # DISABLED: https://github.com/software-mansion/scarb/issues/1534 + # - cairo@SYSTEM + - solidity@SYSTEM + - actionlint@1.6.26 + - black@24.1.1 + - checkov@3.2.5 + - codespell@2.2.6 + - git-diff-check + - hadolint@2.12.0 + - isort@5.13.2 + - markdownlint@0.39.0 + - oxipng@9.0.0 + - prettier@3.2.5 + - ruff@0.2.1 + - shellcheck@0.9.0 + - shfmt@3.6.0 + - taplo@0.8.1 + - yamllint@1.33.0 + disabled: + - trufflehog + - bandit + - terrascan +actions: + disabled: + - trunk-announce + - trunk-fmt-pre-commit + enabled: + - trunk-check-pre-push + - trunk-upgrade-available diff --git a/kakarot-ssj/LICENSE b/kakarot-ssj/LICENSE new file mode 100644 index 000000000..92c70adad --- /dev/null +++ b/kakarot-ssj/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022, Abdelhamid Bakhta + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/kakarot-ssj/Makefile b/kakarot-ssj/Makefile new file mode 100644 index 000000000..c69fc0ec1 --- /dev/null +++ b/kakarot-ssj/Makefile @@ -0,0 +1,19 @@ +install: + bash scripts/install_hook.sh + +test-unit: + @PACKAGE="$(word 2,$(MAKECMDGOALS))" && \ + FILTER="$(word 3,$(MAKECMDGOALS))" && \ + if [ -z "$$PACKAGE" ] && [ -z "$$FILTER" ]; then \ + scarb test; \ + elif [ -n "$$PACKAGE" ] && [ -z "$$FILTER" ]; then \ + scarb test -p $$PACKAGE; \ + elif [ -n "$$PACKAGE" ] && [ -n "$$FILTER" ]; then \ + uv run scripts/run_filtered_tests.py $$PACKAGE $$FILTER; \ + else \ + echo "Usage: make test-unit [PACKAGE] [FILTER]"; \ + exit 1; \ + fi + +%: + @: diff --git a/kakarot-ssj/README.md b/kakarot-ssj/README.md new file mode 100644 index 000000000..28016b6ce --- /dev/null +++ b/kakarot-ssj/README.md @@ -0,0 +1,247 @@ +

+ +

+
+

+ Kakarot, the zkEVM written in Cairo. +

+
+ +
+
+ +![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/kkrt-labs/kakarot-ssj/test.yml?branch=main) +![GitHub](https://img.shields.io/github/license/kkrt-labs/kakarot-ssj?style=flat-square&logo=github) +![GitHub contributors](https://img.shields.io/github/contributors/kkrt-labs/kakarot-ssj?logo=github&style=flat-square) +![GitHub top language](https://img.shields.io/github/languages/top/kkrt-labs/kakarot-ssj?style=flat-square) +[![Telegram](https://img.shields.io/badge/telegram-Kakarot-yellow.svg?logo=telegram)](https://t.me/KakarotZkEvm) +![Contributions welcome](https://img.shields.io/badge/contributions-welcome-orange.svg) +[![Read FAQ](https://img.shields.io/badge/Ask%20Question-Read%20FAQ-000000)](https://www.newton.so/view?tags=kakarot) +![GitHub Repo stars](https://img.shields.io/github/stars/kkrt-labs/kakarot-ssj?style=social) +[![Twitter Follow](https://img.shields.io/twitter/follow/KakarotZkEvm?style=social)](https://x.com/KakarotZkEvm) + +
+ +
+Table of Contents + +- [About](#about) +- [Getting Started](#getting-started) + - [Installation](#installation) +- [Usage](#usage) + - [Build](#build) + - [Test](#test) + - [Format](#format) +- [Roadmap](#roadmap) +- [Support](#support) +- [Project assistance](#project-assistance) +- [Contributing](#contributing) +- [Authors \& contributors](#authors--contributors) +- [Security](#security) +- [License](#license) +- [Acknowledgements](#acknowledgements) +- [Contributors ✨](#contributors-) + +
+ +--- + +## About + +Kakarot is an (zk)-Ethereum Virtual Machine implementation written in Cairo. +Kakarot is Ethereum compatible, i.e. all existing smart contracts, developer +tools and wallets work out-of-the-box on Kakarot. It's been open source from day +one. Soon available on Starknet L2 and Appchains. + +🚧 It is a work in progress, and it is not ready for production. + +## Getting Started + +This repository is a Cairo rewrite of +[the CairoZero version of Kakarot zkEVM](https://github.com/kkrt-labs/kakarot). + +### Installation + +- Install [Scarb](https://docs.swmansion.com/scarb). To make sure your version + always matches the one used by Kakarot, you can install Scarb + [via asdf](https://docs.swmansion.com/scarb/download#install-via-asdf). + +- Install + [Starknet Foundry](https://foundry-rs.github.io/starknet-foundry/getting-started/installation.html?highlight=asdf#installation-via-asdf). + We also recommend installing it via asdf. + +- Install the + [Cairo Profiler](https://github.com/software-mansion/cairo-profiler) to + profile your Cairo code. + +- Install [Bun](https://bun.sh/docs/installation) to run the JavaScript scripts. + +- [Fork](https://docs.github.com/en/get-started/quickstart/fork-a-repo) the + repository and clone your fork + (`git clone https://github.com//kakarot-ssj`) + +- Run `make install` to install the git hooks. +- Add your environment variables to `.env` (see `.env.example` for an example). + - Get your Github token [here](https://github.com/settings/tokens?type=beta) + +## Usage + +### Build + +```bash +scarb build +``` + +### Test + +```bash +scarb test +``` + +### Format + +The project uses [trunk](https://trunk.io/) for everything except cairo files. If you +don't have it installed already, you can do: + +```bash +curl https://get.trunk.io -fsSL | bash +``` + +then + +```bash +trunk check --fix +``` + +VS Code users, don't miss the +[VS Code trunk plugin](https://marketplace.visualstudio.com/items?itemName=Trunk.io). + +For cairo files, run: + +```bash +scarb fmt +``` + +## Roadmap + +See the [open issues](https://github.com/kkrt-labs/kakarot-ssj/issues) for a +list of proposed features (and known issues). + +- [Top Feature Requests](https://github.com/kkrt-labs/kakarot-ssj/issues?q=label%3Aenhancement+is%3Aopen+sort%3Areactions-%2B1-desc) + (Add your votes using the 👍 reaction) +- [Top Bugs](https://github.com/kkrt-labs/kakarot-ssj/issues?q=is%3Aissue+is%3Aopen+label%3Abug+sort%3Areactions-%2B1-desc) + (Add your votes using the 👍 reaction) +- [Newest Bugs](https://github.com/kkrt-labs/kakarot-ssj/issues?q=is%3Aopen+is%3Aissue+label%3Abug) + +## Support + +Reach out to the maintainer at one of the following places: + +- [GitHub Discussions](https://github.com/kkrt-labs/kakarot-ssj/discussions) +- [Telegram group](https://t.me/KakarotZkEvm) + +## Project assistance + +If you want to say **thank you** or/and support active development of Kakarot: + +- Add a [GitHub Star](https://github.com/kkrt-labs/kakarot-ssj) to the project. +- Tweet about [Kakarot](https://twitter.com/KakarotZkEvm). +- Write interesting articles about the project on [Dev.to](https://dev.to/), + [Medium](https://medium.com/), [Mirror](https://mirror.xyz/) or your personal + blog. + +Together, we can make Kakarot **better**! + +## Contributing + +First off, thanks for taking the time to contribute! Contributions are what make +the open-source community such an amazing place to learn, inspire, and create. +Any contribution you make will benefit everybody else and is **greatly +appreciated**. + +Please read [our contribution guidelines](docs/CONTRIBUTING.md), and thank you +for being involved! + +## Authors & contributors + +For a full list of all authors and contributors, see +[the contributors page](https://github.com/kkrt-labs/kakarot-ssj/contributors). + +## Security + +Kakarot follows good practices of security, but 100% security cannot be assured. +Kakarot is provided **"as is"** without any **warranty**. Use at your own risk. + +_For more information and to report security issues, please refer to our +[security documentation](docs/SECURITY.md)._ + +## License + +This project is licensed under the **MIT license**. + +See [LICENSE](LICENSE) for more information. + +## Acknowledgements + +## Contributors ✨ + +Thanks goes to these wonderful people +([emoji key](https://allcontributors.org/docs/en/emoji-key)): + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Abdel @ StarkWare
Abdel @ StarkWare

💻
johann bestowrous
johann bestowrous

💻
Elias Tazartes
Elias Tazartes

👀 📢
Mathieu
Mathieu

💻 ⚠️ 📖
khaeljy
khaeljy

💻
Clément Walter
Clément Walter

💻
Lucas @ StarkWare
Lucas @ StarkWare

💻
lambda-0x
lambda-0x

💻
danilowhk
danilowhk

💻
Tristan
Tristan

💻
Quentash
Quentash

💻
ftupas
ftupas

💻
Aniket Prajapati
Aniket Prajapati

💻
Daniel Bejarano
Daniel Bejarano

💻
Noeljarillo
Noeljarillo

💻
Thomas Butler
Thomas Butler

💻
Ammar Arif
Ammar Arif

📖
greged93
greged93

💻
Charlotte
Charlotte

💻
akhercha
akhercha

💻
Alexandro T. Netto
Alexandro T. Netto

💻
tedison
tedison

💻
Pia
Pia

💻
glihm
glihm

💻
+ + Add your contributions + +
+ + + + + + +This project follows the +[all-contributors](https://github.com/all-contributors/all-contributors) +specification. Contributions of any kind welcome! diff --git a/kakarot-ssj/Scarb.lock b/kakarot-ssj/Scarb.lock new file mode 100644 index 000000000..8a345708d --- /dev/null +++ b/kakarot-ssj/Scarb.lock @@ -0,0 +1,74 @@ +# Code generated by scarb DO NOT EDIT. +version = 1 + +[[package]] +name = "alexandria_data_structures" +version = "0.1.0" +dependencies = [ + "snforge_std", +] + +[[package]] +name = "contracts" +version = "0.1.0" +dependencies = [ + "evm", + "openzeppelin", + "snforge_std", + "snforge_utils", + "utils", +] + +[[package]] +name = "evm" +version = "0.1.0" +dependencies = [ + "contracts", + "garaga", + "openzeppelin", + "snforge_std", + "snforge_utils", + "utils", +] + +[[package]] +name = "garaga" +version = "0.1.0" +source = "git+https://github.com/keep-starknet-strange/garaga.git#933784eee3811334cf1a5b83d9ffcc9cfda3be8c" + +[[package]] +name = "openzeppelin" +version = "0.1.0" +dependencies = [ + "snforge_std", +] + +[[package]] +name = "snforge_scarb_plugin" +version = "0.31.0" +source = "git+https://github.com/foundry-rs/starknet-foundry.git?tag=v0.31.0#249f1e9960b7ee07d80e12b585ac57b644f9e4c0" + +[[package]] +name = "snforge_std" +version = "0.31.0" +source = "git+https://github.com/foundry-rs/starknet-foundry.git?tag=v0.31.0#249f1e9960b7ee07d80e12b585ac57b644f9e4c0" +dependencies = [ + "snforge_scarb_plugin", +] + +[[package]] +name = "snforge_utils" +version = "0.1.0" +dependencies = [ + "evm", + "snforge_std", +] + +[[package]] +name = "utils" +version = "0.1.0" +dependencies = [ + "alexandria_data_structures", + "evm", + "snforge_std", +] diff --git a/kakarot-ssj/Scarb.toml b/kakarot-ssj/Scarb.toml new file mode 100644 index 000000000..b0d420965 --- /dev/null +++ b/kakarot-ssj/Scarb.toml @@ -0,0 +1,17 @@ +[workspace] +members = ["crates/*"] + +[workspace.package] +description = "Kakarot is an (zk)-Ethereum Virtual Machine implementation written in Cairo." +documentation = "https://www.kakarot.org/" +cairo-version = "2.8.2" +version = "0.1.0" +readme = "README.md" +repository = "https://github.com/kkrt-labs/kakarot-ssj/" +license-file = "LICENSE" + +[workspace.dependencies] +starknet = "2.8.2" + +[workspace.tool.fmt] +sort-module-level-items = true diff --git a/kakarot-ssj/blockchain-tests-skip.yml b/kakarot-ssj/blockchain-tests-skip.yml new file mode 100644 index 000000000..2cabb317a --- /dev/null +++ b/kakarot-ssj/blockchain-tests-skip.yml @@ -0,0 +1,8730 @@ +# List of test directories to completely skip +# trunk-ignore(yamllint/empty-values) +directories: + +# List of file names to be skipped +# The first level corresponds to the directory, the second to the list of file names to ignore. +# trunk-ignore(yamllint/empty-values) +filename: + +# Keeping some skipped tests because of a probable memory leak somewhere +# causing cargo test to just crash at some point +regex: + eip4895_withdrawals: + - .* + eip4844_blobs: + - .* + eip4788_beacon_root: + - .* + eip7516_blobgasfee: + - .* + stEIP4844-blobtransactions: + - .* + stMemoryStressTest: + - mload32bitBound_return.* # ef-tests #565 + - CREATE_Bounds.* # ef-tests #565 + - CREATE2_Bounds.* # ef-tests #565 + - CALL_Bounds.* # ef-tests #565 + - CALLCODE_Bounds.* # ef-tests #565 + - DELEGATECALL_Bounds.* # ef-tests #565 + - static_CALL_Bounds.* # ef-tests #565 + stZeroKnowledge: + - .*ecmul.* + stZeroKnowledge2: + - .*ecadd.* + - .*ecmul.* + +testname: + vmIOandFlowOperations: + - gas_d0g0v0_Shanghai + - pc_d0g0v0_Shanghai + - pc_d1g0v0_Shanghai + - jump_d5g0v0_Shanghai + - jumpi_d9g0v0_Shanghai + stEIP3860-limitmeterinitcode: + - create2InitCodeSizeLimit_d1g0v0_Shanghai + - create2InitCodeSizeLimit_d0g0v0_Shanghai + - createInitCodeSizeLimit_d0g0v0_Shanghai + - creationTxInitCodeSizeLimit_d0g0v0_Shanghai + vmTests: + - blockInfo_d0g0v0_Shanghai + - blockInfo_d1g0v0_Shanghai + - blockInfo_d2g0v0_Shanghai + - blockInfo_d3g0v0_Shanghai + - blockInfo_d4g0v0_Shanghai + - calldatasize_d0g0v0_Shanghai + - calldatasize_d10g0v0_Shanghai + - calldatasize_d11g0v0_Shanghai + - calldatasize_d12g0v0_Shanghai + - calldatasize_d13g0v0_Shanghai + - calldatasize_d14g0v0_Shanghai + - calldatasize_d15g0v0_Shanghai + - calldatasize_d16g0v0_Shanghai + - calldatasize_d17g0v0_Shanghai + - calldatasize_d18g0v0_Shanghai + - calldatasize_d19g0v0_Shanghai + - calldatasize_d1g0v0_Shanghai + - calldatasize_d2g0v0_Shanghai + - calldatasize_d3g0v0_Shanghai + - calldatasize_d4g0v0_Shanghai + - calldatasize_d5g0v0_Shanghai + - calldatasize_d6g0v0_Shanghai + - calldatasize_d7g0v0_Shanghai + - calldatasize_d8g0v0_Shanghai + - calldatasize_d9g0v0_Shanghai + - envInfo_d0g0v0_Shanghai + - envInfo_d1g0v0_Shanghai + - envInfo_d2g0v0_Shanghai + - envInfo_d3g0v0_Shanghai + - envInfo_d4g0v0_Shanghai + - envInfo_d5g0v0_Shanghai + - envInfo_d6g0v0_Shanghai + - envInfo_d7g0v0_Shanghai + - envInfo_d8g0v0_Shanghai + - envInfo_d9g0v0_Shanghai + - random_d4g0v0_Shanghai + - random_d3g0v0_Shanghai + - sha3_d0g0v0_Shanghai + - sha3_d10g0v0_Shanghai + - sha3_d11g0v0_Shanghai + - sha3_d12g0v0_Shanghai + - sha3_d13g0v0_Shanghai + - sha3_d15g0v0_Shanghai + - sha3_d14g0v0_Shanghai + - sha3_d16g0v0_Shanghai + - sha3_d1g0v0_Shanghai + - sha3_d2g0v0_Shanghai + - sha3_d3g0v0_Shanghai + - sha3_d4g0v0_Shanghai + - sha3_d5g0v0_Shanghai + - sha3_d6g0v0_Shanghai + - sha3_d7g0v0_Shanghai + - sha3_d8g0v0_Shanghai + - sha3_d9g0v0_Shanghai + stEIP3855-push0: + - push0_d2g0v0_Shanghai + - push0_d1g0v0_Shanghai + vmArithmeticTest: + - expPower256_d0g0v0_Shanghai + - expPower256Of256_d0g0v0_Shanghai + - twoOps_d0g0v0_Shanghai + stArgsZeroOneBalance: + - callNonConst_d0g0v1_Shanghai + - calldatacopyNonConst_d0g0v1_Shanghai + - expNonConst_d0g0v0_Shanghai + - sha3NonConst_d0g0v0_Shanghai + - sha3NonConst_d0g0v1_Shanghai + vmPerformance: + - loopExp_d10g0v0_Shanghai + - loopExp_d2g0v0_Shanghai + - loopExp_d11g0v0_Shanghai + - loopExp_d0g0v0_Shanghai + - loopExp_d1g0v0_Shanghai + - loopExp_d14g0v0_Shanghai + - loopExp_d3g0v0_Shanghai + - loopExp_d4g0v0_Shanghai + - loopExp_d9g0v0_Shanghai + - loopExp_d5g0v0_Shanghai + - loopMul_d0g0v0_Shanghai + - loopMul_d2g0v0_Shanghai + - loopMul_d1g0v0_Shanghai + - performanceTester_d1g0v0_Shanghai + - performanceTester_d0g0v0_Shanghai + - performanceTester_d3g0v0_Shanghai + - performanceTester_d2g0v0_Shanghai + - performanceTester_d4g0v0_Shanghai + stBadOpcode: + - badOpcodes_d110g0v0_Shanghai + - invalidAddr_d41g0v0_Shanghai + - invalidAddr_d43g0v0_Shanghai + - invalidAddr_d45g0v0_Shanghai + - invalidAddr_d47g0v0_Shanghai + - invalidAddr_d49g0v0_Shanghai + - invalidDiffPlaces_d0g0v0_Shanghai + - invalidDiffPlaces_d10g0v0_Shanghai + - invalidDiffPlaces_d11g0v0_Shanghai + - invalidDiffPlaces_d12g0v0_Shanghai + - invalidDiffPlaces_d13g0v0_Shanghai + - invalidDiffPlaces_d14g0v0_Shanghai + - invalidDiffPlaces_d15g0v0_Shanghai + - invalidAddr_d71g0v0_Shanghai + - invalidAddr_d73g0v0_Shanghai + - invalidAddr_d75g0v0_Shanghai + - invalidAddr_d77g0v0_Shanghai + - invalidAddr_d79g0v0_Shanghai + - invalidDiffPlaces_d16g0v0_Shanghai + - invalidDiffPlaces_d1g0v0_Shanghai + - invalidDiffPlaces_d17g0v0_Shanghai + - invalidDiffPlaces_d18g0v0_Shanghai + - invalidDiffPlaces_d2g0v0_Shanghai + - invalidDiffPlaces_d3g0v0_Shanghai + - invalidDiffPlaces_d4g0v0_Shanghai + - invalidDiffPlaces_d19g0v0_Shanghai + - invalidDiffPlaces_d21g0v0_Shanghai + - invalidDiffPlaces_d5g0v0_Shanghai + - invalidDiffPlaces_d20g0v0_Shanghai + - invalidDiffPlaces_d22g0v0_Shanghai + - invalidDiffPlaces_d6g0v0_Shanghai + - invalidDiffPlaces_d23g0v0_Shanghai + - measureGas_d1g0v0_Shanghai + - invalidDiffPlaces_d7g0v0_Shanghai + - invalidDiffPlaces_d8g0v0_Shanghai + - invalidDiffPlaces_d9g0v0_Shanghai + - measureGas_d6g0v0_Shanghai + - measureGas_d7g0v0_Shanghai + - opc0CDiffPlaces_d0g0v0_Shanghai + - measureGas_d8g0v0_Shanghai + - invalidDiffPlaces_d24g0v0_Shanghai + - measureGas_d0g0v0_Shanghai + - measureGas_d9g0v0_Shanghai + - invalidDiffPlaces_d25g0v0_Shanghai + - invalidDiffPlaces_d26g0v0_Shanghai + - invalidDiffPlaces_d28g0v0_Shanghai + - invalidDiffPlaces_d27g0v0_Shanghai + - invalidDiffPlaces_d29g0v0_Shanghai + - invalidDiffPlaces_d30g0v0_Shanghai + - opc0CDiffPlaces_d1g0v0_Shanghai + - invalidDiffPlaces_d31g0v0_Shanghai + - invalidDiffPlaces_d32g0v0_Shanghai + - opc0CDiffPlaces_d10g0v0_Shanghai + - opc0CDiffPlaces_d11g0v0_Shanghai + - invalidDiffPlaces_d33g0v0_Shanghai + - opc0CDiffPlaces_d2g0v0_Shanghai + - opc0CDiffPlaces_d12g0v0_Shanghai + - opc0CDiffPlaces_d14g0v0_Shanghai + - opc0CDiffPlaces_d13g0v0_Shanghai + - invalidDiffPlaces_d34g0v0_Shanghai + - opc0CDiffPlaces_d15g0v0_Shanghai + - opc0DDiffPlaces_d0g0v0_Shanghai + - opc0CDiffPlaces_d16g0v0_Shanghai + - opc0CDiffPlaces_d3g0v0_Shanghai + - opc0CDiffPlaces_d17g0v0_Shanghai + - opc0CDiffPlaces_d4g0v0_Shanghai + - opc0CDiffPlaces_d18g0v0_Shanghai + - opc0CDiffPlaces_d19g0v0_Shanghai + - opc0CDiffPlaces_d5g0v0_Shanghai + - opc0CDiffPlaces_d21g0v0_Shanghai + - opc0CDiffPlaces_d6g0v0_Shanghai + - opc0CDiffPlaces_d8g0v0_Shanghai + - opc0CDiffPlaces_d20g0v0_Shanghai + - opc0CDiffPlaces_d7g0v0_Shanghai + - opc0CDiffPlaces_d22g0v0_Shanghai + - opc0DDiffPlaces_d10g0v0_Shanghai + - opc0CDiffPlaces_d23g0v0_Shanghai + - opc0CDiffPlaces_d9g0v0_Shanghai + - opc0CDiffPlaces_d24g0v0_Shanghai + - opc0DDiffPlaces_d12g0v0_Shanghai + - opc0DDiffPlaces_d1g0v0_Shanghai + - opc0DDiffPlaces_d11g0v0_Shanghai + - opc0CDiffPlaces_d25g0v0_Shanghai + - opc0CDiffPlaces_d26g0v0_Shanghai + - opc0CDiffPlaces_d32g0v0_Shanghai + - opc0DDiffPlaces_d13g0v0_Shanghai + - opc0CDiffPlaces_d29g0v0_Shanghai + - opc0CDiffPlaces_d27g0v0_Shanghai + - opc0CDiffPlaces_d28g0v0_Shanghai + - opc0CDiffPlaces_d30g0v0_Shanghai + - opc0CDiffPlaces_d31g0v0_Shanghai + - opc0DDiffPlaces_d14g0v0_Shanghai + - opc0DDiffPlaces_d15g0v0_Shanghai + - opc0DDiffPlaces_d2g0v0_Shanghai + - opc0CDiffPlaces_d33g0v0_Shanghai + - opc0DDiffPlaces_d16g0v0_Shanghai + - opc0CDiffPlaces_d34g0v0_Shanghai + - opc0DDiffPlaces_d17g0v0_Shanghai + - opc0EDiffPlaces_d0g0v0_Shanghai + - opc0DDiffPlaces_d18g0v0_Shanghai + - opc0DDiffPlaces_d3g0v0_Shanghai + - opc0DDiffPlaces_d19g0v0_Shanghai + - opc0DDiffPlaces_d4g0v0_Shanghai + - opc0DDiffPlaces_d20g0v0_Shanghai + - opc0DDiffPlaces_d5g0v0_Shanghai + - opc0DDiffPlaces_d21g0v0_Shanghai + - opc0DDiffPlaces_d6g0v0_Shanghai + - opc0DDiffPlaces_d22g0v0_Shanghai + - opc0DDiffPlaces_d7g0v0_Shanghai + - opc0DDiffPlaces_d23g0v0_Shanghai + - opc0DDiffPlaces_d8g0v0_Shanghai + - opc0DDiffPlaces_d9g0v0_Shanghai + - opc0EDiffPlaces_d10g0v0_Shanghai + - opc0EDiffPlaces_d11g0v0_Shanghai + - opc0EDiffPlaces_d1g0v0_Shanghai + - opc0DDiffPlaces_d24g0v0_Shanghai + - opc0EDiffPlaces_d12g0v0_Shanghai + - opc0DDiffPlaces_d26g0v0_Shanghai + - opc0DDiffPlaces_d25g0v0_Shanghai + - opc0DDiffPlaces_d28g0v0_Shanghai + - opc0EDiffPlaces_d13g0v0_Shanghai + - opc0DDiffPlaces_d27g0v0_Shanghai + - opc0EDiffPlaces_d14g0v0_Shanghai + - opc0DDiffPlaces_d29g0v0_Shanghai + - opc0EDiffPlaces_d15g0v0_Shanghai + - opc0DDiffPlaces_d30g0v0_Shanghai + - opc0EDiffPlaces_d16g0v0_Shanghai + - opc0DDiffPlaces_d31g0v0_Shanghai + - opc0DDiffPlaces_d32g0v0_Shanghai + - opc0EDiffPlaces_d2g0v0_Shanghai + - opc0DDiffPlaces_d33g0v0_Shanghai + - opc0DDiffPlaces_d34g0v0_Shanghai + - opc0EDiffPlaces_d17g0v0_Shanghai + - opc0EDiffPlaces_d18g0v0_Shanghai + - opc0EDiffPlaces_d19g0v0_Shanghai + - opc0EDiffPlaces_d3g0v0_Shanghai + - opc0EDiffPlaces_d21g0v0_Shanghai + - opc0FDiffPlaces_d0g0v0_Shanghai + - opc0EDiffPlaces_d20g0v0_Shanghai + - opc0EDiffPlaces_d4g0v0_Shanghai + - opc0EDiffPlaces_d5g0v0_Shanghai + - opc0EDiffPlaces_d22g0v0_Shanghai + - opc0EDiffPlaces_d6g0v0_Shanghai + - opc0EDiffPlaces_d23g0v0_Shanghai + - opc0EDiffPlaces_d7g0v0_Shanghai + - opc0EDiffPlaces_d8g0v0_Shanghai + - opc0EDiffPlaces_d9g0v0_Shanghai + - opc0FDiffPlaces_d1g0v0_Shanghai + - opc0EDiffPlaces_d24g0v0_Shanghai + - opc0FDiffPlaces_d10g0v0_Shanghai + - opc0FDiffPlaces_d11g0v0_Shanghai + - opc0EDiffPlaces_d26g0v0_Shanghai + - opc0EDiffPlaces_d25g0v0_Shanghai + - opc0EDiffPlaces_d28g0v0_Shanghai + - opc0FDiffPlaces_d12g0v0_Shanghai + - opc0EDiffPlaces_d27g0v0_Shanghai + - opc0FDiffPlaces_d13g0v0_Shanghai + - opc0EDiffPlaces_d29g0v0_Shanghai + - opc0FDiffPlaces_d14g0v0_Shanghai + - opc0EDiffPlaces_d32g0v0_Shanghai + - opc0FDiffPlaces_d15g0v0_Shanghai + - opc0EDiffPlaces_d30g0v0_Shanghai + - opc0EDiffPlaces_d31g0v0_Shanghai + - opc0EDiffPlaces_d33g0v0_Shanghai + - opc0FDiffPlaces_d2g0v0_Shanghai + - opc0FDiffPlaces_d16g0v0_Shanghai + - opc0EDiffPlaces_d34g0v0_Shanghai + - opc0FDiffPlaces_d17g0v0_Shanghai + - opc0FDiffPlaces_d18g0v0_Shanghai + - opc0FDiffPlaces_d3g0v0_Shanghai + - opc0FDiffPlaces_d19g0v0_Shanghai + - opc0FDiffPlaces_d20g0v0_Shanghai + - opc0FDiffPlaces_d4g0v0_Shanghai + - opc0FDiffPlaces_d21g0v0_Shanghai + - opc1EDiffPlaces_d0g0v0_Shanghai + - opc0FDiffPlaces_d22g0v0_Shanghai + - opc0FDiffPlaces_d23g0v0_Shanghai + - opc0FDiffPlaces_d5g0v0_Shanghai + - opc0FDiffPlaces_d6g0v0_Shanghai + - opc0FDiffPlaces_d7g0v0_Shanghai + - opc0FDiffPlaces_d8g0v0_Shanghai + - opc0FDiffPlaces_d24g0v0_Shanghai + - opc1EDiffPlaces_d1g0v0_Shanghai + - opc0FDiffPlaces_d9g0v0_Shanghai + - opc1EDiffPlaces_d10g0v0_Shanghai + - opc0FDiffPlaces_d25g0v0_Shanghai + - opc1EDiffPlaces_d11g0v0_Shanghai + - opc0FDiffPlaces_d26g0v0_Shanghai + - opc1EDiffPlaces_d12g0v0_Shanghai + - opc0FDiffPlaces_d27g0v0_Shanghai + - opc1EDiffPlaces_d13g0v0_Shanghai + - opc0FDiffPlaces_d28g0v0_Shanghai + - opc1EDiffPlaces_d14g0v0_Shanghai + - opc1EDiffPlaces_d15g0v0_Shanghai + - opc0FDiffPlaces_d30g0v0_Shanghai + - opc0FDiffPlaces_d29g0v0_Shanghai + - opc0FDiffPlaces_d33g0v0_Shanghai + - opc0FDiffPlaces_d32g0v0_Shanghai + - opc1EDiffPlaces_d2g0v0_Shanghai + - opc0FDiffPlaces_d31g0v0_Shanghai + - opc1EDiffPlaces_d16g0v0_Shanghai + - opc0FDiffPlaces_d34g0v0_Shanghai + - opc1EDiffPlaces_d17g0v0_Shanghai + - opc1EDiffPlaces_d18g0v0_Shanghai + - opc1EDiffPlaces_d21g0v0_Shanghai + - opc1EDiffPlaces_d19g0v0_Shanghai + - opc1EDiffPlaces_d3g0v0_Shanghai + - opc1EDiffPlaces_d20g0v0_Shanghai + - opc1FDiffPlaces_d0g0v0_Shanghai + - opc1EDiffPlaces_d23g0v0_Shanghai + - opc1EDiffPlaces_d4g0v0_Shanghai + - opc1EDiffPlaces_d22g0v0_Shanghai + - opc1EDiffPlaces_d5g0v0_Shanghai + - opc1EDiffPlaces_d6g0v0_Shanghai + - opc1EDiffPlaces_d7g0v0_Shanghai + - opc1EDiffPlaces_d8g0v0_Shanghai + - opc1EDiffPlaces_d24g0v0_Shanghai + - opc1EDiffPlaces_d9g0v0_Shanghai + - opc1FDiffPlaces_d1g0v0_Shanghai + - opc1EDiffPlaces_d25g0v0_Shanghai + - opc1FDiffPlaces_d10g0v0_Shanghai + - opc1FDiffPlaces_d11g0v0_Shanghai + - opc1EDiffPlaces_d26g0v0_Shanghai + - opc1FDiffPlaces_d12g0v0_Shanghai + - opc1EDiffPlaces_d27g0v0_Shanghai + - opc1FDiffPlaces_d13g0v0_Shanghai + - opc1FDiffPlaces_d14g0v0_Shanghai + - opc1EDiffPlaces_d28g0v0_Shanghai + - opc1FDiffPlaces_d15g0v0_Shanghai + - opc1EDiffPlaces_d30g0v0_Shanghai + - opc1EDiffPlaces_d29g0v0_Shanghai + - opc1EDiffPlaces_d31g0v0_Shanghai + - opc1EDiffPlaces_d32g0v0_Shanghai + - opc1FDiffPlaces_d16g0v0_Shanghai + - opc1FDiffPlaces_d2g0v0_Shanghai + - opc1FDiffPlaces_d17g0v0_Shanghai + - opc1EDiffPlaces_d33g0v0_Shanghai + - opc1EDiffPlaces_d34g0v0_Shanghai + - opc1FDiffPlaces_d18g0v0_Shanghai + - opc1FDiffPlaces_d19g0v0_Shanghai + - opc1FDiffPlaces_d20g0v0_Shanghai + - opc1FDiffPlaces_d3g0v0_Shanghai + - opc1FDiffPlaces_d21g0v0_Shanghai + - opc21DiffPlaces_d0g0v0_Shanghai + - opc1FDiffPlaces_d22g0v0_Shanghai + - opc1FDiffPlaces_d4g0v0_Shanghai + - opc1FDiffPlaces_d23g0v0_Shanghai + - opc1FDiffPlaces_d5g0v0_Shanghai + - opc1FDiffPlaces_d6g0v0_Shanghai + - opc1FDiffPlaces_d7g0v0_Shanghai + - opc1FDiffPlaces_d24g0v0_Shanghai + - opc1FDiffPlaces_d8g0v0_Shanghai + - opc1FDiffPlaces_d9g0v0_Shanghai + - opc21DiffPlaces_d1g0v0_Shanghai + - opc1FDiffPlaces_d25g0v0_Shanghai + - opc21DiffPlaces_d10g0v0_Shanghai + - opc21DiffPlaces_d11g0v0_Shanghai + - opc1FDiffPlaces_d26g0v0_Shanghai + - opc21DiffPlaces_d12g0v0_Shanghai + - opc21DiffPlaces_d13g0v0_Shanghai + - opc1FDiffPlaces_d27g0v0_Shanghai + - opc21DiffPlaces_d14g0v0_Shanghai + - opc1FDiffPlaces_d29g0v0_Shanghai + - opc1FDiffPlaces_d28g0v0_Shanghai + - opc21DiffPlaces_d15g0v0_Shanghai + - opc21DiffPlaces_d16g0v0_Shanghai + - opc1FDiffPlaces_d30g0v0_Shanghai + - opc1FDiffPlaces_d31g0v0_Shanghai + - opc1FDiffPlaces_d32g0v0_Shanghai + - opc21DiffPlaces_d2g0v0_Shanghai + - opc1FDiffPlaces_d33g0v0_Shanghai + - opc21DiffPlaces_d17g0v0_Shanghai + - opc1FDiffPlaces_d34g0v0_Shanghai + - opc21DiffPlaces_d18g0v0_Shanghai + - opc21DiffPlaces_d3g0v0_Shanghai + - opc21DiffPlaces_d19g0v0_Shanghai + - opc22DiffPlaces_d0g0v0_Shanghai + - opc21DiffPlaces_d21g0v0_Shanghai + - opc21DiffPlaces_d22g0v0_Shanghai + - opc21DiffPlaces_d4g0v0_Shanghai + - opc21DiffPlaces_d20g0v0_Shanghai + - opc21DiffPlaces_d23g0v0_Shanghai + - opc21DiffPlaces_d5g0v0_Shanghai + - opc21DiffPlaces_d6g0v0_Shanghai + - opc21DiffPlaces_d7g0v0_Shanghai + - opc21DiffPlaces_d8g0v0_Shanghai + - opc21DiffPlaces_d24g0v0_Shanghai + - opc21DiffPlaces_d9g0v0_Shanghai + - opc22DiffPlaces_d1g0v0_Shanghai + - opc22DiffPlaces_d10g0v0_Shanghai + - opc21DiffPlaces_d25g0v0_Shanghai + - opc21DiffPlaces_d26g0v0_Shanghai + - opc22DiffPlaces_d11g0v0_Shanghai + - opc22DiffPlaces_d12g0v0_Shanghai + - opc22DiffPlaces_d13g0v0_Shanghai + - opc22DiffPlaces_d14g0v0_Shanghai + - opc21DiffPlaces_d27g0v0_Shanghai + - opc21DiffPlaces_d28g0v0_Shanghai + - opc22DiffPlaces_d15g0v0_Shanghai + - opc21DiffPlaces_d29g0v0_Shanghai + - opc21DiffPlaces_d30g0v0_Shanghai + - opc21DiffPlaces_d31g0v0_Shanghai + - opc21DiffPlaces_d32g0v0_Shanghai + - opc22DiffPlaces_d2g0v0_Shanghai + - opc22DiffPlaces_d16g0v0_Shanghai + - opc21DiffPlaces_d33g0v0_Shanghai + - opc21DiffPlaces_d34g0v0_Shanghai + - opc22DiffPlaces_d17g0v0_Shanghai + - opc22DiffPlaces_d18g0v0_Shanghai + - opc22DiffPlaces_d19g0v0_Shanghai + - opc22DiffPlaces_d3g0v0_Shanghai + - opc23DiffPlaces_d0g0v0_Shanghai + - opc22DiffPlaces_d21g0v0_Shanghai + - opc22DiffPlaces_d22g0v0_Shanghai + - opc22DiffPlaces_d4g0v0_Shanghai + - opc22DiffPlaces_d20g0v0_Shanghai + - opc22DiffPlaces_d23g0v0_Shanghai + - opc22DiffPlaces_d5g0v0_Shanghai + - opc22DiffPlaces_d6g0v0_Shanghai + - opc22DiffPlaces_d7g0v0_Shanghai + - opc22DiffPlaces_d8g0v0_Shanghai + - opc22DiffPlaces_d24g0v0_Shanghai + - opc22DiffPlaces_d9g0v0_Shanghai + - opc23DiffPlaces_d1g0v0_Shanghai + - opc23DiffPlaces_d10g0v0_Shanghai + - opc22DiffPlaces_d25g0v0_Shanghai + - opc23DiffPlaces_d11g0v0_Shanghai + - opc22DiffPlaces_d26g0v0_Shanghai + - opc23DiffPlaces_d12g0v0_Shanghai + - opc23DiffPlaces_d13g0v0_Shanghai + - opc22DiffPlaces_d27g0v0_Shanghai + - opc22DiffPlaces_d28g0v0_Shanghai + - opc23DiffPlaces_d14g0v0_Shanghai + - opc22DiffPlaces_d29g0v0_Shanghai + - opc23DiffPlaces_d15g0v0_Shanghai + - opc22DiffPlaces_d30g0v0_Shanghai + - opc22DiffPlaces_d31g0v0_Shanghai + - opc22DiffPlaces_d32g0v0_Shanghai + - opc23DiffPlaces_d16g0v0_Shanghai + - opc23DiffPlaces_d2g0v0_Shanghai + - opc22DiffPlaces_d34g0v0_Shanghai + - opc22DiffPlaces_d33g0v0_Shanghai + - opc23DiffPlaces_d17g0v0_Shanghai + - opc23DiffPlaces_d18g0v0_Shanghai + - opc23DiffPlaces_d19g0v0_Shanghai + - opc23DiffPlaces_d3g0v0_Shanghai + - opc24DiffPlaces_d0g0v0_Shanghai + - opc23DiffPlaces_d20g0v0_Shanghai + - opc23DiffPlaces_d4g0v0_Shanghai + - opc23DiffPlaces_d21g0v0_Shanghai + - opc23DiffPlaces_d22g0v0_Shanghai + - opc23DiffPlaces_d23g0v0_Shanghai + - opc23DiffPlaces_d5g0v0_Shanghai + - opc23DiffPlaces_d6g0v0_Shanghai + - opc23DiffPlaces_d7g0v0_Shanghai + - opc23DiffPlaces_d8g0v0_Shanghai + - opc23DiffPlaces_d24g0v0_Shanghai + - opc23DiffPlaces_d9g0v0_Shanghai + - opc24DiffPlaces_d1g0v0_Shanghai + - opc24DiffPlaces_d10g0v0_Shanghai + - opc23DiffPlaces_d25g0v0_Shanghai + - opc23DiffPlaces_d26g0v0_Shanghai + - opc24DiffPlaces_d11g0v0_Shanghai + - opc24DiffPlaces_d12g0v0_Shanghai + - opc23DiffPlaces_d27g0v0_Shanghai + - opc24DiffPlaces_d13g0v0_Shanghai + - opc23DiffPlaces_d28g0v0_Shanghai + - opc24DiffPlaces_d14g0v0_Shanghai + - opc24DiffPlaces_d15g0v0_Shanghai + - opc23DiffPlaces_d29g0v0_Shanghai + - opc23DiffPlaces_d30g0v0_Shanghai + - opc24DiffPlaces_d16g0v0_Shanghai + - opc23DiffPlaces_d32g0v0_Shanghai + - opc24DiffPlaces_d2g0v0_Shanghai + - opc23DiffPlaces_d31g0v0_Shanghai + - opc23DiffPlaces_d33g0v0_Shanghai + - opc23DiffPlaces_d34g0v0_Shanghai + - opc24DiffPlaces_d17g0v0_Shanghai + - opc24DiffPlaces_d18g0v0_Shanghai + - opc24DiffPlaces_d19g0v0_Shanghai + - opc24DiffPlaces_d3g0v0_Shanghai + - opc25DiffPlaces_d0g0v0_Shanghai + - opc24DiffPlaces_d21g0v0_Shanghai + - opc24DiffPlaces_d4g0v0_Shanghai + - opc24DiffPlaces_d20g0v0_Shanghai + - opc24DiffPlaces_d22g0v0_Shanghai + - opc24DiffPlaces_d23g0v0_Shanghai + - opc24DiffPlaces_d5g0v0_Shanghai + - opc24DiffPlaces_d6g0v0_Shanghai + - opc24DiffPlaces_d7g0v0_Shanghai + - opc24DiffPlaces_d8g0v0_Shanghai + - opc24DiffPlaces_d24g0v0_Shanghai + - opc24DiffPlaces_d9g0v0_Shanghai + - opc24DiffPlaces_d25g0v0_Shanghai + - opc25DiffPlaces_d1g0v0_Shanghai + - opc25DiffPlaces_d10g0v0_Shanghai + - opc24DiffPlaces_d26g0v0_Shanghai + - opc25DiffPlaces_d11g0v0_Shanghai + - opc25DiffPlaces_d12g0v0_Shanghai + - opc24DiffPlaces_d27g0v0_Shanghai + - opc25DiffPlaces_d13g0v0_Shanghai + - opc24DiffPlaces_d28g0v0_Shanghai + - opc25DiffPlaces_d14g0v0_Shanghai + - opc24DiffPlaces_d29g0v0_Shanghai + - opc25DiffPlaces_d15g0v0_Shanghai + - opc25DiffPlaces_d16g0v0_Shanghai + - opc24DiffPlaces_d30g0v0_Shanghai + - opc24DiffPlaces_d31g0v0_Shanghai + - opc24DiffPlaces_d32g0v0_Shanghai + - opc25DiffPlaces_d2g0v0_Shanghai + - opc24DiffPlaces_d33g0v0_Shanghai + - opc25DiffPlaces_d17g0v0_Shanghai + - opc24DiffPlaces_d34g0v0_Shanghai + - opc25DiffPlaces_d18g0v0_Shanghai + - opc25DiffPlaces_d3g0v0_Shanghai + - opc26DiffPlaces_d0g0v0_Shanghai + - opc25DiffPlaces_d19g0v0_Shanghai + - opc25DiffPlaces_d21g0v0_Shanghai + - opc25DiffPlaces_d4g0v0_Shanghai + - opc25DiffPlaces_d20g0v0_Shanghai + - opc25DiffPlaces_d22g0v0_Shanghai + - opc25DiffPlaces_d5g0v0_Shanghai + - opc25DiffPlaces_d23g0v0_Shanghai + - opc25DiffPlaces_d6g0v0_Shanghai + - opc25DiffPlaces_d7g0v0_Shanghai + - opc25DiffPlaces_d8g0v0_Shanghai + - opc25DiffPlaces_d9g0v0_Shanghai + - opc25DiffPlaces_d24g0v0_Shanghai + - opc26DiffPlaces_d1g0v0_Shanghai + - opc26DiffPlaces_d10g0v0_Shanghai + - opc25DiffPlaces_d25g0v0_Shanghai + - opc26DiffPlaces_d11g0v0_Shanghai + - opc25DiffPlaces_d26g0v0_Shanghai + - opc26DiffPlaces_d12g0v0_Shanghai + - opc25DiffPlaces_d27g0v0_Shanghai + - opc26DiffPlaces_d13g0v0_Shanghai + - opc25DiffPlaces_d28g0v0_Shanghai + - opc26DiffPlaces_d14g0v0_Shanghai + - opc26DiffPlaces_d15g0v0_Shanghai + - opc25DiffPlaces_d29g0v0_Shanghai + - opc26DiffPlaces_d16g0v0_Shanghai + - opc25DiffPlaces_d30g0v0_Shanghai + - opc25DiffPlaces_d31g0v0_Shanghai + - opc25DiffPlaces_d32g0v0_Shanghai + - opc26DiffPlaces_d2g0v0_Shanghai + - opc25DiffPlaces_d33g0v0_Shanghai + - opc25DiffPlaces_d34g0v0_Shanghai + - opc26DiffPlaces_d17g0v0_Shanghai + - opc26DiffPlaces_d18g0v0_Shanghai + - opc26DiffPlaces_d19g0v0_Shanghai + - opc26DiffPlaces_d3g0v0_Shanghai + - opc27DiffPlaces_d0g0v0_Shanghai + - opc26DiffPlaces_d21g0v0_Shanghai + - opc26DiffPlaces_d4g0v0_Shanghai + - opc26DiffPlaces_d20g0v0_Shanghai + - opc26DiffPlaces_d22g0v0_Shanghai + - opc26DiffPlaces_d23g0v0_Shanghai + - opc26DiffPlaces_d5g0v0_Shanghai + - opc26DiffPlaces_d6g0v0_Shanghai + - opc26DiffPlaces_d7g0v0_Shanghai + - opc26DiffPlaces_d8g0v0_Shanghai + - opc26DiffPlaces_d24g0v0_Shanghai + - opc26DiffPlaces_d9g0v0_Shanghai + - opc27DiffPlaces_d1g0v0_Shanghai + - opc26DiffPlaces_d25g0v0_Shanghai + - opc27DiffPlaces_d10g0v0_Shanghai + - opc26DiffPlaces_d26g0v0_Shanghai + - opc27DiffPlaces_d11g0v0_Shanghai + - opc27DiffPlaces_d12g0v0_Shanghai + - opc26DiffPlaces_d27g0v0_Shanghai + - opc27DiffPlaces_d13g0v0_Shanghai + - opc26DiffPlaces_d28g0v0_Shanghai + - opc27DiffPlaces_d14g0v0_Shanghai + - opc26DiffPlaces_d29g0v0_Shanghai + - opc27DiffPlaces_d15g0v0_Shanghai + - opc27DiffPlaces_d16g0v0_Shanghai + - opc26DiffPlaces_d30g0v0_Shanghai + - opc26DiffPlaces_d31g0v0_Shanghai + - opc27DiffPlaces_d2g0v0_Shanghai + - opc26DiffPlaces_d33g0v0_Shanghai + - opc26DiffPlaces_d32g0v0_Shanghai + - opc26DiffPlaces_d34g0v0_Shanghai + - opc27DiffPlaces_d17g0v0_Shanghai + - opc27DiffPlaces_d18g0v0_Shanghai + - opc27DiffPlaces_d19g0v0_Shanghai + - opc27DiffPlaces_d3g0v0_Shanghai + - opc28DiffPlaces_d0g0v0_Shanghai + - opc27DiffPlaces_d21g0v0_Shanghai + - opc27DiffPlaces_d4g0v0_Shanghai + - opc27DiffPlaces_d20g0v0_Shanghai + - opc27DiffPlaces_d22g0v0_Shanghai + - opc27DiffPlaces_d5g0v0_Shanghai + - opc27DiffPlaces_d23g0v0_Shanghai + - opc27DiffPlaces_d6g0v0_Shanghai + - opc27DiffPlaces_d7g0v0_Shanghai + - opc27DiffPlaces_d8g0v0_Shanghai + - opc27DiffPlaces_d9g0v0_Shanghai + - opc27DiffPlaces_d24g0v0_Shanghai + - opc28DiffPlaces_d1g0v0_Shanghai + - opc27DiffPlaces_d25g0v0_Shanghai + - opc28DiffPlaces_d10g0v0_Shanghai + - opc28DiffPlaces_d11g0v0_Shanghai + - opc27DiffPlaces_d26g0v0_Shanghai + - opc28DiffPlaces_d12g0v0_Shanghai + - opc27DiffPlaces_d27g0v0_Shanghai + - opc28DiffPlaces_d13g0v0_Shanghai + - opc28DiffPlaces_d14g0v0_Shanghai + - opc27DiffPlaces_d28g0v0_Shanghai + - opc28DiffPlaces_d15g0v0_Shanghai + - opc27DiffPlaces_d29g0v0_Shanghai + - opc27DiffPlaces_d30g0v0_Shanghai + - opc28DiffPlaces_d16g0v0_Shanghai + - opc27DiffPlaces_d31g0v0_Shanghai + - opc28DiffPlaces_d2g0v0_Shanghai + - opc27DiffPlaces_d32g0v0_Shanghai + - opc27DiffPlaces_d33g0v0_Shanghai + - opc27DiffPlaces_d34g0v0_Shanghai + - opc28DiffPlaces_d17g0v0_Shanghai + - opc28DiffPlaces_d18g0v0_Shanghai + - opc28DiffPlaces_d19g0v0_Shanghai + - opc28DiffPlaces_d3g0v0_Shanghai + - opc28DiffPlaces_d21g0v0_Shanghai + - opc29DiffPlaces_d0g0v0_Shanghai + - opc28DiffPlaces_d20g0v0_Shanghai + - opc28DiffPlaces_d22g0v0_Shanghai + - opc28DiffPlaces_d4g0v0_Shanghai + - opc28DiffPlaces_d23g0v0_Shanghai + - opc28DiffPlaces_d5g0v0_Shanghai + - opc28DiffPlaces_d6g0v0_Shanghai + - opc28DiffPlaces_d7g0v0_Shanghai + - opc28DiffPlaces_d8g0v0_Shanghai + - opc28DiffPlaces_d24g0v0_Shanghai + - opc28DiffPlaces_d9g0v0_Shanghai + - opc29DiffPlaces_d1g0v0_Shanghai + - opc28DiffPlaces_d25g0v0_Shanghai + - opc29DiffPlaces_d10g0v0_Shanghai + - opc28DiffPlaces_d26g0v0_Shanghai + - opc29DiffPlaces_d11g0v0_Shanghai + - opc29DiffPlaces_d12g0v0_Shanghai + - opc28DiffPlaces_d27g0v0_Shanghai + - opc29DiffPlaces_d13g0v0_Shanghai + - opc28DiffPlaces_d28g0v0_Shanghai + - opc29DiffPlaces_d14g0v0_Shanghai + - opc28DiffPlaces_d29g0v0_Shanghai + - opc29DiffPlaces_d15g0v0_Shanghai + - opc29DiffPlaces_d16g0v0_Shanghai + - opc28DiffPlaces_d30g0v0_Shanghai + - opc29DiffPlaces_d2g0v0_Shanghai + - opc28DiffPlaces_d31g0v0_Shanghai + - opc28DiffPlaces_d32g0v0_Shanghai + - opc28DiffPlaces_d33g0v0_Shanghai + - opc28DiffPlaces_d34g0v0_Shanghai + - opc29DiffPlaces_d17g0v0_Shanghai + - opc29DiffPlaces_d18g0v0_Shanghai + - opc29DiffPlaces_d3g0v0_Shanghai + - opc29DiffPlaces_d19g0v0_Shanghai + - opc29DiffPlaces_d21g0v0_Shanghai + - opc29DiffPlaces_d4g0v0_Shanghai + - opc2ADiffPlaces_d0g0v0_Shanghai + - opc29DiffPlaces_d20g0v0_Shanghai + - opc29DiffPlaces_d22g0v0_Shanghai + - opc29DiffPlaces_d5g0v0_Shanghai + - opc29DiffPlaces_d23g0v0_Shanghai + - opc29DiffPlaces_d6g0v0_Shanghai + - opc29DiffPlaces_d7g0v0_Shanghai + - opc29DiffPlaces_d8g0v0_Shanghai + - opc29DiffPlaces_d24g0v0_Shanghai + - opc29DiffPlaces_d9g0v0_Shanghai + - opc2ADiffPlaces_d1g0v0_Shanghai + - opc29DiffPlaces_d25g0v0_Shanghai + - opc2ADiffPlaces_d10g0v0_Shanghai + - opc29DiffPlaces_d26g0v0_Shanghai + - opc2ADiffPlaces_d11g0v0_Shanghai + - opc2ADiffPlaces_d12g0v0_Shanghai + - opc29DiffPlaces_d27g0v0_Shanghai + - opc2ADiffPlaces_d13g0v0_Shanghai + - opc29DiffPlaces_d28g0v0_Shanghai + - opc2ADiffPlaces_d14g0v0_Shanghai + - opc29DiffPlaces_d29g0v0_Shanghai + - opc2ADiffPlaces_d15g0v0_Shanghai + - opc29DiffPlaces_d30g0v0_Shanghai + - opc2ADiffPlaces_d16g0v0_Shanghai + - opc2ADiffPlaces_d2g0v0_Shanghai + - opc29DiffPlaces_d31g0v0_Shanghai + - opc29DiffPlaces_d33g0v0_Shanghai + - opc29DiffPlaces_d32g0v0_Shanghai + - opc29DiffPlaces_d34g0v0_Shanghai + - opc2ADiffPlaces_d17g0v0_Shanghai + - opc2ADiffPlaces_d18g0v0_Shanghai + - opc2ADiffPlaces_d19g0v0_Shanghai + - opc2ADiffPlaces_d3g0v0_Shanghai + - opc2ADiffPlaces_d21g0v0_Shanghai + - opc2BDiffPlaces_d0g0v0_Shanghai + - opc2ADiffPlaces_d4g0v0_Shanghai + - opc2ADiffPlaces_d20g0v0_Shanghai + - opc2ADiffPlaces_d22g0v0_Shanghai + - opc2ADiffPlaces_d23g0v0_Shanghai + - opc2ADiffPlaces_d5g0v0_Shanghai + - opc2ADiffPlaces_d6g0v0_Shanghai + - opc2ADiffPlaces_d7g0v0_Shanghai + - opc2ADiffPlaces_d8g0v0_Shanghai + - opc2ADiffPlaces_d24g0v0_Shanghai + - opc2ADiffPlaces_d9g0v0_Shanghai + - opc2ADiffPlaces_d25g0v0_Shanghai + - opc2BDiffPlaces_d1g0v0_Shanghai + - opc2BDiffPlaces_d10g0v0_Shanghai + - opc2ADiffPlaces_d26g0v0_Shanghai + - opc2BDiffPlaces_d11g0v0_Shanghai + - opc2BDiffPlaces_d12g0v0_Shanghai + - opc2ADiffPlaces_d27g0v0_Shanghai + - opc2BDiffPlaces_d13g0v0_Shanghai + - opc2ADiffPlaces_d28g0v0_Shanghai + - opc2BDiffPlaces_d14g0v0_Shanghai + - opc2ADiffPlaces_d29g0v0_Shanghai + - opc2BDiffPlaces_d15g0v0_Shanghai + - opc2ADiffPlaces_d31g0v0_Shanghai + - opc2BDiffPlaces_d16g0v0_Shanghai + - opc2ADiffPlaces_d30g0v0_Shanghai + - opc2BDiffPlaces_d2g0v0_Shanghai + - opc2ADiffPlaces_d32g0v0_Shanghai + - opc2ADiffPlaces_d33g0v0_Shanghai + - opc2ADiffPlaces_d34g0v0_Shanghai + - opc2BDiffPlaces_d17g0v0_Shanghai + - opc2BDiffPlaces_d18g0v0_Shanghai + - opc2BDiffPlaces_d3g0v0_Shanghai + - opc2BDiffPlaces_d19g0v0_Shanghai + - opc2BDiffPlaces_d21g0v0_Shanghai + - opc2BDiffPlaces_d4g0v0_Shanghai + - opc2CDiffPlaces_d0g0v0_Shanghai + - opc2BDiffPlaces_d22g0v0_Shanghai + - opc2BDiffPlaces_d20g0v0_Shanghai + - opc2BDiffPlaces_d23g0v0_Shanghai + - opc2BDiffPlaces_d5g0v0_Shanghai + - opc2BDiffPlaces_d6g0v0_Shanghai + - opc2BDiffPlaces_d7g0v0_Shanghai + - opc2BDiffPlaces_d8g0v0_Shanghai + - opc2BDiffPlaces_d24g0v0_Shanghai + - opc2BDiffPlaces_d9g0v0_Shanghai + - opc2CDiffPlaces_d1g0v0_Shanghai + - opc2BDiffPlaces_d25g0v0_Shanghai + - opc2CDiffPlaces_d10g0v0_Shanghai + - opc2CDiffPlaces_d11g0v0_Shanghai + - opc2BDiffPlaces_d26g0v0_Shanghai + - opc2CDiffPlaces_d12g0v0_Shanghai + - opc2BDiffPlaces_d27g0v0_Shanghai + - opc2CDiffPlaces_d13g0v0_Shanghai + - opc2BDiffPlaces_d28g0v0_Shanghai + - opc2CDiffPlaces_d14g0v0_Shanghai + - opc2BDiffPlaces_d29g0v0_Shanghai + - opc2CDiffPlaces_d15g0v0_Shanghai + - opc2BDiffPlaces_d30g0v0_Shanghai + - opc2CDiffPlaces_d16g0v0_Shanghai + - opc2BDiffPlaces_d31g0v0_Shanghai + - opc2CDiffPlaces_d2g0v0_Shanghai + - opc2BDiffPlaces_d32g0v0_Shanghai + - opc2BDiffPlaces_d33g0v0_Shanghai + - opc2BDiffPlaces_d34g0v0_Shanghai + - opc2CDiffPlaces_d17g0v0_Shanghai + - opc2CDiffPlaces_d18g0v0_Shanghai + - opc2CDiffPlaces_d19g0v0_Shanghai + - opc2CDiffPlaces_d3g0v0_Shanghai + - opc2CDiffPlaces_d21g0v0_Shanghai + - opc2DDiffPlaces_d0g0v0_Shanghai + - opc2CDiffPlaces_d20g0v0_Shanghai + - opc2CDiffPlaces_d22g0v0_Shanghai + - opc2CDiffPlaces_d4g0v0_Shanghai + - opc2CDiffPlaces_d23g0v0_Shanghai + - opc2CDiffPlaces_d5g0v0_Shanghai + - opc2CDiffPlaces_d6g0v0_Shanghai + - opc2CDiffPlaces_d7g0v0_Shanghai + - opc2CDiffPlaces_d8g0v0_Shanghai + - opc2CDiffPlaces_d24g0v0_Shanghai + - opc2CDiffPlaces_d9g0v0_Shanghai + - opc2DDiffPlaces_d1g0v0_Shanghai + - opc2CDiffPlaces_d25g0v0_Shanghai + - opc2DDiffPlaces_d10g0v0_Shanghai + - opc2CDiffPlaces_d26g0v0_Shanghai + - opc2DDiffPlaces_d11g0v0_Shanghai + - opc2DDiffPlaces_d12g0v0_Shanghai + - opc2CDiffPlaces_d27g0v0_Shanghai + - opc2DDiffPlaces_d13g0v0_Shanghai + - opc2CDiffPlaces_d28g0v0_Shanghai + - opc2DDiffPlaces_d14g0v0_Shanghai + - opc2DDiffPlaces_d15g0v0_Shanghai + - opc2CDiffPlaces_d29g0v0_Shanghai + - opc2DDiffPlaces_d16g0v0_Shanghai + - opc2CDiffPlaces_d30g0v0_Shanghai + - opc2CDiffPlaces_d31g0v0_Shanghai + - opc2DDiffPlaces_d2g0v0_Shanghai + - opc2CDiffPlaces_d32g0v0_Shanghai + - opc2CDiffPlaces_d33g0v0_Shanghai + - opc2CDiffPlaces_d34g0v0_Shanghai + - opc2DDiffPlaces_d17g0v0_Shanghai + - opc2DDiffPlaces_d18g0v0_Shanghai + - opc2DDiffPlaces_d3g0v0_Shanghai + - opc2DDiffPlaces_d19g0v0_Shanghai + - opc2EDiffPlaces_d0g0v0_Shanghai + - opc2DDiffPlaces_d21g0v0_Shanghai + - opc2DDiffPlaces_d4g0v0_Shanghai + - opc2DDiffPlaces_d20g0v0_Shanghai + - opc2DDiffPlaces_d22g0v0_Shanghai + - opc2DDiffPlaces_d5g0v0_Shanghai + - opc2DDiffPlaces_d23g0v0_Shanghai + - opc2DDiffPlaces_d6g0v0_Shanghai + - opc2DDiffPlaces_d7g0v0_Shanghai + - opc2DDiffPlaces_d8g0v0_Shanghai + - opc2DDiffPlaces_d24g0v0_Shanghai + - opc2DDiffPlaces_d9g0v0_Shanghai + - opc2EDiffPlaces_d1g0v0_Shanghai + - opc2DDiffPlaces_d25g0v0_Shanghai + - opc2EDiffPlaces_d10g0v0_Shanghai + - opc2DDiffPlaces_d26g0v0_Shanghai + - opc2EDiffPlaces_d11g0v0_Shanghai + - opc2EDiffPlaces_d12g0v0_Shanghai + - opc2DDiffPlaces_d27g0v0_Shanghai + - opc2EDiffPlaces_d13g0v0_Shanghai + - opc2DDiffPlaces_d28g0v0_Shanghai + - opc2EDiffPlaces_d14g0v0_Shanghai + - opc2DDiffPlaces_d29g0v0_Shanghai + - opc2EDiffPlaces_d15g0v0_Shanghai + - opc2DDiffPlaces_d30g0v0_Shanghai + - opc2DDiffPlaces_d31g0v0_Shanghai + - opc2EDiffPlaces_d16g0v0_Shanghai + - opc2DDiffPlaces_d32g0v0_Shanghai + - opc2EDiffPlaces_d2g0v0_Shanghai + - opc2DDiffPlaces_d33g0v0_Shanghai + - opc2DDiffPlaces_d34g0v0_Shanghai + - opc2EDiffPlaces_d17g0v0_Shanghai + - opc2EDiffPlaces_d18g0v0_Shanghai + - opc2EDiffPlaces_d19g0v0_Shanghai + - opc2EDiffPlaces_d3g0v0_Shanghai + - opc2EDiffPlaces_d21g0v0_Shanghai + - opc2FDiffPlaces_d0g0v0_Shanghai + - opc2EDiffPlaces_d20g0v0_Shanghai + - opc2EDiffPlaces_d22g0v0_Shanghai + - opc2EDiffPlaces_d4g0v0_Shanghai + - opc2EDiffPlaces_d23g0v0_Shanghai + - opc2EDiffPlaces_d5g0v0_Shanghai + - opc2EDiffPlaces_d6g0v0_Shanghai + - opc2EDiffPlaces_d7g0v0_Shanghai + - opc2EDiffPlaces_d8g0v0_Shanghai + - opc2EDiffPlaces_d24g0v0_Shanghai + - opc2EDiffPlaces_d9g0v0_Shanghai + - opc2EDiffPlaces_d25g0v0_Shanghai + - opc2FDiffPlaces_d1g0v0_Shanghai + - opc2FDiffPlaces_d10g0v0_Shanghai + - opc2EDiffPlaces_d26g0v0_Shanghai + - opc2FDiffPlaces_d11g0v0_Shanghai + - opc2FDiffPlaces_d12g0v0_Shanghai + - opc2EDiffPlaces_d27g0v0_Shanghai + - opc2FDiffPlaces_d13g0v0_Shanghai + - opc2FDiffPlaces_d14g0v0_Shanghai + - opc2EDiffPlaces_d28g0v0_Shanghai + - opc2EDiffPlaces_d29g0v0_Shanghai + - opc2FDiffPlaces_d15g0v0_Shanghai + - opc2EDiffPlaces_d30g0v0_Shanghai + - opc2EDiffPlaces_d31g0v0_Shanghai + - opc2FDiffPlaces_d16g0v0_Shanghai + - opc2EDiffPlaces_d32g0v0_Shanghai + - opc2EDiffPlaces_d33g0v0_Shanghai + - opc2FDiffPlaces_d2g0v0_Shanghai + - opc2EDiffPlaces_d34g0v0_Shanghai + - opc2FDiffPlaces_d17g0v0_Shanghai + - opc2FDiffPlaces_d18g0v0_Shanghai + - opc2FDiffPlaces_d3g0v0_Shanghai + - opc2FDiffPlaces_d19g0v0_Shanghai + - opc2FDiffPlaces_d4g0v0_Shanghai + - opc2FDiffPlaces_d21g0v0_Shanghai + - opc49DiffPlaces_d0g0v0_Shanghai + - opc2FDiffPlaces_d20g0v0_Shanghai + - opc2FDiffPlaces_d22g0v0_Shanghai + - opc2FDiffPlaces_d23g0v0_Shanghai + - opc2FDiffPlaces_d5g0v0_Shanghai + - opc2FDiffPlaces_d6g0v0_Shanghai + - opc2FDiffPlaces_d7g0v0_Shanghai + - opc2FDiffPlaces_d8g0v0_Shanghai + - opc2FDiffPlaces_d24g0v0_Shanghai + - opc2FDiffPlaces_d9g0v0_Shanghai + - opc2FDiffPlaces_d25g0v0_Shanghai + - opc49DiffPlaces_d1g0v0_Shanghai + - opc49DiffPlaces_d10g0v0_Shanghai + - opc2FDiffPlaces_d26g0v0_Shanghai + - opc49DiffPlaces_d11g0v0_Shanghai + - opc49DiffPlaces_d12g0v0_Shanghai + - opc2FDiffPlaces_d27g0v0_Shanghai + - opc49DiffPlaces_d13g0v0_Shanghai + - opc2FDiffPlaces_d28g0v0_Shanghai + - opc2FDiffPlaces_d29g0v0_Shanghai + - opc49DiffPlaces_d14g0v0_Shanghai + - opc49DiffPlaces_d15g0v0_Shanghai + - opc2FDiffPlaces_d30g0v0_Shanghai + - opc2FDiffPlaces_d31g0v0_Shanghai + - opc49DiffPlaces_d2g0v0_Shanghai + - opc49DiffPlaces_d16g0v0_Shanghai + - opc2FDiffPlaces_d33g0v0_Shanghai + - opc2FDiffPlaces_d32g0v0_Shanghai + - opc2FDiffPlaces_d34g0v0_Shanghai + - opc49DiffPlaces_d17g0v0_Shanghai + - opc49DiffPlaces_d18g0v0_Shanghai + - opc49DiffPlaces_d19g0v0_Shanghai + - opc49DiffPlaces_d3g0v0_Shanghai + - opc49DiffPlaces_d21g0v0_Shanghai + - opc4ADiffPlaces_d0g0v0_Shanghai + - opc49DiffPlaces_d4g0v0_Shanghai + - opc49DiffPlaces_d20g0v0_Shanghai + - opc49DiffPlaces_d22g0v0_Shanghai + - opc49DiffPlaces_d23g0v0_Shanghai + - opc49DiffPlaces_d5g0v0_Shanghai + - opc49DiffPlaces_d6g0v0_Shanghai + - opc49DiffPlaces_d7g0v0_Shanghai + - opc49DiffPlaces_d8g0v0_Shanghai + - opc49DiffPlaces_d24g0v0_Shanghai + - opc49DiffPlaces_d9g0v0_Shanghai + - opc49DiffPlaces_d25g0v0_Shanghai + - opc4ADiffPlaces_d1g0v0_Shanghai + - opc4ADiffPlaces_d10g0v0_Shanghai + - opc4ADiffPlaces_d11g0v0_Shanghai + - opc49DiffPlaces_d26g0v0_Shanghai + - opc4ADiffPlaces_d12g0v0_Shanghai + - opc49DiffPlaces_d27g0v0_Shanghai + - opc4ADiffPlaces_d13g0v0_Shanghai + - opc49DiffPlaces_d28g0v0_Shanghai + - opc4ADiffPlaces_d14g0v0_Shanghai + - opc49DiffPlaces_d29g0v0_Shanghai + - opc4ADiffPlaces_d15g0v0_Shanghai + - opc49DiffPlaces_d30g0v0_Shanghai + - opc4ADiffPlaces_d16g0v0_Shanghai + - opc49DiffPlaces_d31g0v0_Shanghai + - opc4ADiffPlaces_d2g0v0_Shanghai + - opc49DiffPlaces_d32g0v0_Shanghai + - opc49DiffPlaces_d33g0v0_Shanghai + - opc49DiffPlaces_d34g0v0_Shanghai + - opc4ADiffPlaces_d17g0v0_Shanghai + - opc4ADiffPlaces_d18g0v0_Shanghai + - opc4ADiffPlaces_d3g0v0_Shanghai + - opc4ADiffPlaces_d19g0v0_Shanghai + - opc4ADiffPlaces_d21g0v0_Shanghai + - opc4BDiffPlaces_d0g0v0_Shanghai + - opc4ADiffPlaces_d20g0v0_Shanghai + - opc4ADiffPlaces_d4g0v0_Shanghai + - opc4ADiffPlaces_d22g0v0_Shanghai + - opc4ADiffPlaces_d23g0v0_Shanghai + - opc4ADiffPlaces_d5g0v0_Shanghai + - opc4ADiffPlaces_d6g0v0_Shanghai + - opc4ADiffPlaces_d7g0v0_Shanghai + - opc4ADiffPlaces_d8g0v0_Shanghai + - opc4ADiffPlaces_d9g0v0_Shanghai + - opc4ADiffPlaces_d24g0v0_Shanghai + - opc4BDiffPlaces_d1g0v0_Shanghai + - opc4ADiffPlaces_d25g0v0_Shanghai + - opc4BDiffPlaces_d10g0v0_Shanghai + - opc4BDiffPlaces_d11g0v0_Shanghai + - opc4ADiffPlaces_d26g0v0_Shanghai + - opc4BDiffPlaces_d12g0v0_Shanghai + - opc4BDiffPlaces_d13g0v0_Shanghai + - opc4ADiffPlaces_d27g0v0_Shanghai + - opc4BDiffPlaces_d14g0v0_Shanghai + - opc4ADiffPlaces_d28g0v0_Shanghai + - opc4ADiffPlaces_d29g0v0_Shanghai + - opc4BDiffPlaces_d15g0v0_Shanghai + - opc4BDiffPlaces_d16g0v0_Shanghai + - opc4ADiffPlaces_d30g0v0_Shanghai + - opc4ADiffPlaces_d31g0v0_Shanghai + - opc4BDiffPlaces_d2g0v0_Shanghai + - opc4ADiffPlaces_d32g0v0_Shanghai + - opc4ADiffPlaces_d33g0v0_Shanghai + - opc4ADiffPlaces_d34g0v0_Shanghai + - opc4BDiffPlaces_d17g0v0_Shanghai + - opc4BDiffPlaces_d18g0v0_Shanghai + - opc4BDiffPlaces_d19g0v0_Shanghai + - opc4BDiffPlaces_d3g0v0_Shanghai + - opc4BDiffPlaces_d21g0v0_Shanghai + - opc4CDiffPlaces_d0g0v0_Shanghai + - opc4BDiffPlaces_d20g0v0_Shanghai + - opc4BDiffPlaces_d4g0v0_Shanghai + - opc4BDiffPlaces_d22g0v0_Shanghai + - opc4BDiffPlaces_d5g0v0_Shanghai + - opc4BDiffPlaces_d23g0v0_Shanghai + - opc4BDiffPlaces_d6g0v0_Shanghai + - opc4BDiffPlaces_d7g0v0_Shanghai + - opc4BDiffPlaces_d8g0v0_Shanghai + - opc4BDiffPlaces_d24g0v0_Shanghai + - opc4BDiffPlaces_d9g0v0_Shanghai + - opc4BDiffPlaces_d25g0v0_Shanghai + - opc4CDiffPlaces_d1g0v0_Shanghai + - opc4CDiffPlaces_d10g0v0_Shanghai + - opc4CDiffPlaces_d11g0v0_Shanghai + - opc4BDiffPlaces_d26g0v0_Shanghai + - opc4BDiffPlaces_d27g0v0_Shanghai + - opc4CDiffPlaces_d12g0v0_Shanghai + - opc4CDiffPlaces_d13g0v0_Shanghai + - opc4BDiffPlaces_d28g0v0_Shanghai + - opc4CDiffPlaces_d14g0v0_Shanghai + - opc4CDiffPlaces_d15g0v0_Shanghai + - opc4BDiffPlaces_d29g0v0_Shanghai + - opc4CDiffPlaces_d16g0v0_Shanghai + - opc4BDiffPlaces_d30g0v0_Shanghai + - opc4BDiffPlaces_d31g0v0_Shanghai + - opc4BDiffPlaces_d32g0v0_Shanghai + - opc4BDiffPlaces_d33g0v0_Shanghai + - opc4CDiffPlaces_d2g0v0_Shanghai + - opc4BDiffPlaces_d34g0v0_Shanghai + - opc4CDiffPlaces_d17g0v0_Shanghai + - opc4CDiffPlaces_d18g0v0_Shanghai + - opc4CDiffPlaces_d19g0v0_Shanghai + - opc4CDiffPlaces_d3g0v0_Shanghai + - opc4CDiffPlaces_d4g0v0_Shanghai + - opc4DDiffPlaces_d0g0v0_Shanghai + - opc4CDiffPlaces_d21g0v0_Shanghai + - opc4CDiffPlaces_d20g0v0_Shanghai + - opc4CDiffPlaces_d22g0v0_Shanghai + - opc4CDiffPlaces_d23g0v0_Shanghai + - opc4CDiffPlaces_d5g0v0_Shanghai + - opc4CDiffPlaces_d6g0v0_Shanghai + - opc4CDiffPlaces_d7g0v0_Shanghai + - opc4CDiffPlaces_d8g0v0_Shanghai + - opc4CDiffPlaces_d24g0v0_Shanghai + - opc4CDiffPlaces_d9g0v0_Shanghai + - opc4DDiffPlaces_d1g0v0_Shanghai + - opc4CDiffPlaces_d25g0v0_Shanghai + - opc4DDiffPlaces_d10g0v0_Shanghai + - opc4CDiffPlaces_d26g0v0_Shanghai + - opc4DDiffPlaces_d11g0v0_Shanghai + - opc4DDiffPlaces_d12g0v0_Shanghai + - opc4CDiffPlaces_d27g0v0_Shanghai + - opc4DDiffPlaces_d13g0v0_Shanghai + - opc4CDiffPlaces_d28g0v0_Shanghai + - opc4DDiffPlaces_d14g0v0_Shanghai + - opc4CDiffPlaces_d29g0v0_Shanghai + - opc4DDiffPlaces_d15g0v0_Shanghai + - opc4DDiffPlaces_d16g0v0_Shanghai + - opc4CDiffPlaces_d30g0v0_Shanghai + - opc4CDiffPlaces_d31g0v0_Shanghai + - opc4DDiffPlaces_d2g0v0_Shanghai + - opc4CDiffPlaces_d32g0v0_Shanghai + - opc4CDiffPlaces_d33g0v0_Shanghai + - opc4CDiffPlaces_d34g0v0_Shanghai + - opc4DDiffPlaces_d17g0v0_Shanghai + - opc4DDiffPlaces_d18g0v0_Shanghai + - opc4DDiffPlaces_d19g0v0_Shanghai + - opc4DDiffPlaces_d3g0v0_Shanghai + - opc4DDiffPlaces_d21g0v0_Shanghai + - opc4EDiffPlaces_d0g0v0_Shanghai + - opc4DDiffPlaces_d20g0v0_Shanghai + - opc4DDiffPlaces_d4g0v0_Shanghai + - opc4DDiffPlaces_d22g0v0_Shanghai + - opc4DDiffPlaces_d23g0v0_Shanghai + - opc4DDiffPlaces_d5g0v0_Shanghai + - opc4DDiffPlaces_d6g0v0_Shanghai + - opc4DDiffPlaces_d7g0v0_Shanghai + - opc4DDiffPlaces_d8g0v0_Shanghai + - opc4DDiffPlaces_d24g0v0_Shanghai + - opc4DDiffPlaces_d9g0v0_Shanghai + - opc4DDiffPlaces_d25g0v0_Shanghai + - opc4EDiffPlaces_d1g0v0_Shanghai + - opc4EDiffPlaces_d10g0v0_Shanghai + - opc4DDiffPlaces_d26g0v0_Shanghai + - opc4EDiffPlaces_d11g0v0_Shanghai + - opc4EDiffPlaces_d12g0v0_Shanghai + - opc4DDiffPlaces_d27g0v0_Shanghai + - opc4EDiffPlaces_d13g0v0_Shanghai + - opc4DDiffPlaces_d28g0v0_Shanghai + - opc4EDiffPlaces_d14g0v0_Shanghai + - opc4DDiffPlaces_d29g0v0_Shanghai + - opc4EDiffPlaces_d15g0v0_Shanghai + - opc4EDiffPlaces_d16g0v0_Shanghai + - opc4DDiffPlaces_d30g0v0_Shanghai + - opc4DDiffPlaces_d31g0v0_Shanghai + - opc4EDiffPlaces_d2g0v0_Shanghai + - opc4DDiffPlaces_d32g0v0_Shanghai + - opc4DDiffPlaces_d33g0v0_Shanghai + - opc4DDiffPlaces_d34g0v0_Shanghai + - opc4EDiffPlaces_d17g0v0_Shanghai + - opc4EDiffPlaces_d18g0v0_Shanghai + - opc4EDiffPlaces_d19g0v0_Shanghai + - opc4EDiffPlaces_d3g0v0_Shanghai + - opc4FDiffPlaces_d0g0v0_Shanghai + - opc4EDiffPlaces_d21g0v0_Shanghai + - opc4EDiffPlaces_d20g0v0_Shanghai + - opc4EDiffPlaces_d4g0v0_Shanghai + - opc4EDiffPlaces_d22g0v0_Shanghai + - opc4EDiffPlaces_d23g0v0_Shanghai + - opc4EDiffPlaces_d5g0v0_Shanghai + - opc4EDiffPlaces_d6g0v0_Shanghai + - opc4EDiffPlaces_d7g0v0_Shanghai + - opc4EDiffPlaces_d8g0v0_Shanghai + - opc4EDiffPlaces_d9g0v0_Shanghai + - opc4EDiffPlaces_d24g0v0_Shanghai + - opc4FDiffPlaces_d1g0v0_Shanghai + - opc4EDiffPlaces_d25g0v0_Shanghai + - opc4FDiffPlaces_d10g0v0_Shanghai + - opc4FDiffPlaces_d11g0v0_Shanghai + - opc4EDiffPlaces_d26g0v0_Shanghai + - opc4FDiffPlaces_d12g0v0_Shanghai + - opc4EDiffPlaces_d27g0v0_Shanghai + - opc4FDiffPlaces_d13g0v0_Shanghai + - opc4EDiffPlaces_d28g0v0_Shanghai + - opc4FDiffPlaces_d14g0v0_Shanghai + - opc4EDiffPlaces_d29g0v0_Shanghai + - opc4FDiffPlaces_d15g0v0_Shanghai + - opc4EDiffPlaces_d30g0v0_Shanghai + - opc4EDiffPlaces_d31g0v0_Shanghai + - opc4FDiffPlaces_d16g0v0_Shanghai + - opc4EDiffPlaces_d32g0v0_Shanghai + - opc4FDiffPlaces_d2g0v0_Shanghai + - opc4EDiffPlaces_d33g0v0_Shanghai + - opc4EDiffPlaces_d34g0v0_Shanghai + - opc4FDiffPlaces_d17g0v0_Shanghai + - opc4FDiffPlaces_d18g0v0_Shanghai + - opc4FDiffPlaces_d19g0v0_Shanghai + - opc4FDiffPlaces_d3g0v0_Shanghai + - opc4FDiffPlaces_d21g0v0_Shanghai + - opc5CDiffPlaces_d0g0v0_Shanghai + - opc4FDiffPlaces_d20g0v0_Shanghai + - opc4FDiffPlaces_d4g0v0_Shanghai + - opc4FDiffPlaces_d22g0v0_Shanghai + - opc4FDiffPlaces_d5g0v0_Shanghai + - opc4FDiffPlaces_d23g0v0_Shanghai + - opc4FDiffPlaces_d6g0v0_Shanghai + - opc4FDiffPlaces_d7g0v0_Shanghai + - opc4FDiffPlaces_d8g0v0_Shanghai + - opc4FDiffPlaces_d24g0v0_Shanghai + - opc4FDiffPlaces_d9g0v0_Shanghai + - opc5CDiffPlaces_d1g0v0_Shanghai + - opc4FDiffPlaces_d25g0v0_Shanghai + - opc5CDiffPlaces_d10g0v0_Shanghai + - opc5CDiffPlaces_d11g0v0_Shanghai + - opc4FDiffPlaces_d26g0v0_Shanghai + - opc5CDiffPlaces_d12g0v0_Shanghai + - opc4FDiffPlaces_d27g0v0_Shanghai + - opc5CDiffPlaces_d13g0v0_Shanghai + - opc4FDiffPlaces_d28g0v0_Shanghai + - opc5CDiffPlaces_d14g0v0_Shanghai + - opc5CDiffPlaces_d15g0v0_Shanghai + - opc4FDiffPlaces_d29g0v0_Shanghai + - opc4FDiffPlaces_d30g0v0_Shanghai + - opc5CDiffPlaces_d16g0v0_Shanghai + - opc4FDiffPlaces_d31g0v0_Shanghai + - opc5CDiffPlaces_d2g0v0_Shanghai + - opc4FDiffPlaces_d32g0v0_Shanghai + - opc4FDiffPlaces_d33g0v0_Shanghai + - opc4FDiffPlaces_d34g0v0_Shanghai + - opc5CDiffPlaces_d17g0v0_Shanghai + - opc5CDiffPlaces_d18g0v0_Shanghai + - opc5CDiffPlaces_d19g0v0_Shanghai + - opc5CDiffPlaces_d3g0v0_Shanghai + - opc5DDiffPlaces_d0g0v0_Shanghai + - opc5CDiffPlaces_d21g0v0_Shanghai + - opc5CDiffPlaces_d4g0v0_Shanghai + - opc5CDiffPlaces_d20g0v0_Shanghai + - opc5CDiffPlaces_d22g0v0_Shanghai + - opc5CDiffPlaces_d5g0v0_Shanghai + - opc5CDiffPlaces_d23g0v0_Shanghai + - opc5CDiffPlaces_d6g0v0_Shanghai + - opc5CDiffPlaces_d7g0v0_Shanghai + - opc5CDiffPlaces_d8g0v0_Shanghai + - opc5CDiffPlaces_d9g0v0_Shanghai + - opc5CDiffPlaces_d24g0v0_Shanghai + - opc5DDiffPlaces_d1g0v0_Shanghai + - opc5DDiffPlaces_d10g0v0_Shanghai + - opc5CDiffPlaces_d26g0v0_Shanghai + - opc5CDiffPlaces_d25g0v0_Shanghai + - opc5DDiffPlaces_d11g0v0_Shanghai + - opc5DDiffPlaces_d12g0v0_Shanghai + - opc5DDiffPlaces_d13g0v0_Shanghai + - opc5CDiffPlaces_d27g0v0_Shanghai + - opc5CDiffPlaces_d28g0v0_Shanghai + - opc5DDiffPlaces_d14g0v0_Shanghai + - opc5CDiffPlaces_d29g0v0_Shanghai + - opc5DDiffPlaces_d15g0v0_Shanghai + - opc5DDiffPlaces_d16g0v0_Shanghai + - opc5CDiffPlaces_d30g0v0_Shanghai + - opc5DDiffPlaces_d2g0v0_Shanghai + - opc5CDiffPlaces_d32g0v0_Shanghai + - opc5CDiffPlaces_d31g0v0_Shanghai + - opc5CDiffPlaces_d33g0v0_Shanghai + - opc5CDiffPlaces_d34g0v0_Shanghai + - opc5DDiffPlaces_d17g0v0_Shanghai + - opc5DDiffPlaces_d18g0v0_Shanghai + - opc5DDiffPlaces_d19g0v0_Shanghai + - opc5DDiffPlaces_d3g0v0_Shanghai + - opc5EDiffPlaces_d0g0v0_Shanghai + - opc5DDiffPlaces_d21g0v0_Shanghai + - opc5DDiffPlaces_d20g0v0_Shanghai + - opc5DDiffPlaces_d4g0v0_Shanghai + - opc5DDiffPlaces_d22g0v0_Shanghai + - opc5DDiffPlaces_d5g0v0_Shanghai + - opc5DDiffPlaces_d23g0v0_Shanghai + - opc5DDiffPlaces_d6g0v0_Shanghai + - opc5DDiffPlaces_d7g0v0_Shanghai + - opc5DDiffPlaces_d8g0v0_Shanghai + - opc5DDiffPlaces_d24g0v0_Shanghai + - opc5DDiffPlaces_d9g0v0_Shanghai + - opc5DDiffPlaces_d25g0v0_Shanghai + - opc5EDiffPlaces_d1g0v0_Shanghai + - opc5EDiffPlaces_d10g0v0_Shanghai + - opc5DDiffPlaces_d26g0v0_Shanghai + - opc5EDiffPlaces_d11g0v0_Shanghai + - opc5EDiffPlaces_d12g0v0_Shanghai + - opc5DDiffPlaces_d27g0v0_Shanghai + - opc5EDiffPlaces_d13g0v0_Shanghai + - opc5DDiffPlaces_d28g0v0_Shanghai + - opc5EDiffPlaces_d14g0v0_Shanghai + - opc5EDiffPlaces_d15g0v0_Shanghai + - opc5DDiffPlaces_d29g0v0_Shanghai + - opc5EDiffPlaces_d16g0v0_Shanghai + - opc5DDiffPlaces_d30g0v0_Shanghai + - opc5DDiffPlaces_d31g0v0_Shanghai + - opc5EDiffPlaces_d2g0v0_Shanghai + - opc5DDiffPlaces_d32g0v0_Shanghai + - opc5DDiffPlaces_d34g0v0_Shanghai + - opc5DDiffPlaces_d33g0v0_Shanghai + - opc5EDiffPlaces_d17g0v0_Shanghai + - opc5EDiffPlaces_d18g0v0_Shanghai + - opc5EDiffPlaces_d19g0v0_Shanghai + - opc5EDiffPlaces_d3g0v0_Shanghai + - opc5EDiffPlaces_d4g0v0_Shanghai + - opc5EDiffPlaces_d21g0v0_Shanghai + - opcA5DiffPlaces_d0g0v0_Shanghai + - opc5EDiffPlaces_d20g0v0_Shanghai + - opc5EDiffPlaces_d22g0v0_Shanghai + - opc5EDiffPlaces_d5g0v0_Shanghai + - opc5EDiffPlaces_d23g0v0_Shanghai + - opc5EDiffPlaces_d6g0v0_Shanghai + - opc5EDiffPlaces_d7g0v0_Shanghai + - opc5EDiffPlaces_d8g0v0_Shanghai + - opc5EDiffPlaces_d24g0v0_Shanghai + - opc5EDiffPlaces_d9g0v0_Shanghai + - opc5EDiffPlaces_d25g0v0_Shanghai + - opcA5DiffPlaces_d1g0v0_Shanghai + - opcA5DiffPlaces_d10g0v0_Shanghai + - opcA5DiffPlaces_d11g0v0_Shanghai + - opc5EDiffPlaces_d26g0v0_Shanghai + - opcA5DiffPlaces_d12g0v0_Shanghai + - opc5EDiffPlaces_d27g0v0_Shanghai + - opcA5DiffPlaces_d13g0v0_Shanghai + - opc5EDiffPlaces_d28g0v0_Shanghai + - opcA5DiffPlaces_d14g0v0_Shanghai + - opc5EDiffPlaces_d29g0v0_Shanghai + - opcA5DiffPlaces_d15g0v0_Shanghai + - opc5EDiffPlaces_d30g0v0_Shanghai + - opcA5DiffPlaces_d16g0v0_Shanghai + - opc5EDiffPlaces_d31g0v0_Shanghai + - opcA5DiffPlaces_d2g0v0_Shanghai + - opc5EDiffPlaces_d32g0v0_Shanghai + - opc5EDiffPlaces_d33g0v0_Shanghai + - opc5EDiffPlaces_d34g0v0_Shanghai + - opcA5DiffPlaces_d17g0v0_Shanghai + - opcA5DiffPlaces_d18g0v0_Shanghai + - opcA5DiffPlaces_d19g0v0_Shanghai + - opcA5DiffPlaces_d3g0v0_Shanghai + - opcA5DiffPlaces_d21g0v0_Shanghai + - opcA6DiffPlaces_d0g0v0_Shanghai + - opcA5DiffPlaces_d20g0v0_Shanghai + - opcA5DiffPlaces_d4g0v0_Shanghai + - opcA5DiffPlaces_d22g0v0_Shanghai + - opcA5DiffPlaces_d23g0v0_Shanghai + - opcA5DiffPlaces_d5g0v0_Shanghai + - opcA5DiffPlaces_d6g0v0_Shanghai + - opcA5DiffPlaces_d7g0v0_Shanghai + - opcA5DiffPlaces_d8g0v0_Shanghai + - opcA5DiffPlaces_d24g0v0_Shanghai + - opcA5DiffPlaces_d9g0v0_Shanghai + - opcA6DiffPlaces_d1g0v0_Shanghai + - opcA5DiffPlaces_d25g0v0_Shanghai + - opcA6DiffPlaces_d10g0v0_Shanghai + - opcA6DiffPlaces_d11g0v0_Shanghai + - opcA5DiffPlaces_d26g0v0_Shanghai + - opcA6DiffPlaces_d12g0v0_Shanghai + - opcA5DiffPlaces_d27g0v0_Shanghai + - opcA6DiffPlaces_d13g0v0_Shanghai + - opcA5DiffPlaces_d28g0v0_Shanghai + - opcA6DiffPlaces_d14g0v0_Shanghai + - opcA5DiffPlaces_d29g0v0_Shanghai + - opcA6DiffPlaces_d15g0v0_Shanghai + - opcA6DiffPlaces_d16g0v0_Shanghai + - opcA5DiffPlaces_d30g0v0_Shanghai + - opcA5DiffPlaces_d31g0v0_Shanghai + - opcA5DiffPlaces_d32g0v0_Shanghai + - opcA6DiffPlaces_d2g0v0_Shanghai + - opcA5DiffPlaces_d34g0v0_Shanghai + - opcA5DiffPlaces_d33g0v0_Shanghai + - opcA6DiffPlaces_d17g0v0_Shanghai + - opcA6DiffPlaces_d18g0v0_Shanghai + - opcA6DiffPlaces_d19g0v0_Shanghai + - opcA6DiffPlaces_d3g0v0_Shanghai + - opcA7DiffPlaces_d0g0v0_Shanghai + - opcA6DiffPlaces_d21g0v0_Shanghai + - opcA6DiffPlaces_d20g0v0_Shanghai + - opcA6DiffPlaces_d4g0v0_Shanghai + - opcA6DiffPlaces_d22g0v0_Shanghai + - opcA6DiffPlaces_d23g0v0_Shanghai + - opcA6DiffPlaces_d5g0v0_Shanghai + - opcA6DiffPlaces_d6g0v0_Shanghai + - opcA6DiffPlaces_d7g0v0_Shanghai + - opcA6DiffPlaces_d8g0v0_Shanghai + - opcA6DiffPlaces_d9g0v0_Shanghai + - opcA6DiffPlaces_d24g0v0_Shanghai + - opcA7DiffPlaces_d1g0v0_Shanghai + - opcA6DiffPlaces_d25g0v0_Shanghai + - opcA7DiffPlaces_d10g0v0_Shanghai + - opcA7DiffPlaces_d11g0v0_Shanghai + - opcA6DiffPlaces_d26g0v0_Shanghai + - opcA7DiffPlaces_d12g0v0_Shanghai + - opcA6DiffPlaces_d27g0v0_Shanghai + - opcA7DiffPlaces_d13g0v0_Shanghai + - opcA6DiffPlaces_d28g0v0_Shanghai + - opcA7DiffPlaces_d14g0v0_Shanghai + - opcA6DiffPlaces_d29g0v0_Shanghai + - opcA7DiffPlaces_d15g0v0_Shanghai + - opcA6DiffPlaces_d30g0v0_Shanghai + - opcA7DiffPlaces_d16g0v0_Shanghai + - opcA6DiffPlaces_d31g0v0_Shanghai + - opcA7DiffPlaces_d2g0v0_Shanghai + - opcA6DiffPlaces_d32g0v0_Shanghai + - opcA6DiffPlaces_d33g0v0_Shanghai + - opcA6DiffPlaces_d34g0v0_Shanghai + - opcA7DiffPlaces_d17g0v0_Shanghai + - opcA7DiffPlaces_d18g0v0_Shanghai + - opcA7DiffPlaces_d19g0v0_Shanghai + - opcA7DiffPlaces_d3g0v0_Shanghai + - opcA7DiffPlaces_d21g0v0_Shanghai + - opcA8DiffPlaces_d0g0v0_Shanghai + - opcA7DiffPlaces_d4g0v0_Shanghai + - opcA7DiffPlaces_d20g0v0_Shanghai + - opcA7DiffPlaces_d22g0v0_Shanghai + - opcA7DiffPlaces_d23g0v0_Shanghai + - opcA7DiffPlaces_d5g0v0_Shanghai + - opcA7DiffPlaces_d6g0v0_Shanghai + - opcA7DiffPlaces_d7g0v0_Shanghai + - opcA7DiffPlaces_d8g0v0_Shanghai + - opcA7DiffPlaces_d24g0v0_Shanghai + - opcA7DiffPlaces_d9g0v0_Shanghai + - opcA8DiffPlaces_d1g0v0_Shanghai + - opcA7DiffPlaces_d25g0v0_Shanghai + - opcA8DiffPlaces_d10g0v0_Shanghai + - opcA8DiffPlaces_d11g0v0_Shanghai + - opcA7DiffPlaces_d26g0v0_Shanghai + - opcA8DiffPlaces_d12g0v0_Shanghai + - opcA7DiffPlaces_d27g0v0_Shanghai + - opcA8DiffPlaces_d13g0v0_Shanghai + - opcA7DiffPlaces_d28g0v0_Shanghai + - opcA8DiffPlaces_d14g0v0_Shanghai + - opcA7DiffPlaces_d29g0v0_Shanghai + - opcA8DiffPlaces_d15g0v0_Shanghai + - opcA8DiffPlaces_d16g0v0_Shanghai + - opcA7DiffPlaces_d30g0v0_Shanghai + - opcA7DiffPlaces_d31g0v0_Shanghai + - opcA8DiffPlaces_d2g0v0_Shanghai + - opcA7DiffPlaces_d32g0v0_Shanghai + - opcA7DiffPlaces_d33g0v0_Shanghai + - opcA7DiffPlaces_d34g0v0_Shanghai + - opcA8DiffPlaces_d17g0v0_Shanghai + - opcA8DiffPlaces_d18g0v0_Shanghai + - opcA8DiffPlaces_d3g0v0_Shanghai + - opcA8DiffPlaces_d19g0v0_Shanghai + - opcA8DiffPlaces_d21g0v0_Shanghai + - opcA9DiffPlaces_d0g0v0_Shanghai + - opcA8DiffPlaces_d4g0v0_Shanghai + - opcA8DiffPlaces_d20g0v0_Shanghai + - opcA8DiffPlaces_d22g0v0_Shanghai + - opcA8DiffPlaces_d5g0v0_Shanghai + - opcA8DiffPlaces_d23g0v0_Shanghai + - opcA8DiffPlaces_d6g0v0_Shanghai + - opcA8DiffPlaces_d7g0v0_Shanghai + - opcA8DiffPlaces_d8g0v0_Shanghai + - opcA8DiffPlaces_d9g0v0_Shanghai + - opcA8DiffPlaces_d24g0v0_Shanghai + - opcA9DiffPlaces_d1g0v0_Shanghai + - opcA8DiffPlaces_d25g0v0_Shanghai + - opcA9DiffPlaces_d10g0v0_Shanghai + - opcA8DiffPlaces_d26g0v0_Shanghai + - opcA9DiffPlaces_d11g0v0_Shanghai + - opcA9DiffPlaces_d12g0v0_Shanghai + - opcA8DiffPlaces_d27g0v0_Shanghai + - opcA9DiffPlaces_d13g0v0_Shanghai + - opcA9DiffPlaces_d14g0v0_Shanghai + - opcA8DiffPlaces_d28g0v0_Shanghai + - opcA9DiffPlaces_d15g0v0_Shanghai + - opcA8DiffPlaces_d29g0v0_Shanghai + - opcA9DiffPlaces_d16g0v0_Shanghai + - opcA8DiffPlaces_d30g0v0_Shanghai + - opcA8DiffPlaces_d31g0v0_Shanghai + - opcA8DiffPlaces_d32g0v0_Shanghai + - opcA9DiffPlaces_d2g0v0_Shanghai + - opcA8DiffPlaces_d33g0v0_Shanghai + - opcA8DiffPlaces_d34g0v0_Shanghai + - opcA9DiffPlaces_d17g0v0_Shanghai + - opcA9DiffPlaces_d18g0v0_Shanghai + - opcA9DiffPlaces_d19g0v0_Shanghai + - opcA9DiffPlaces_d3g0v0_Shanghai + - opcA9DiffPlaces_d21g0v0_Shanghai + - opcA9DiffPlaces_d20g0v0_Shanghai + - opcAADiffPlaces_d0g0v0_Shanghai + - opcA9DiffPlaces_d4g0v0_Shanghai + - opcA9DiffPlaces_d22g0v0_Shanghai + - opcA9DiffPlaces_d23g0v0_Shanghai + - opcA9DiffPlaces_d5g0v0_Shanghai + - opcA9DiffPlaces_d6g0v0_Shanghai + - opcA9DiffPlaces_d7g0v0_Shanghai + - opcA9DiffPlaces_d8g0v0_Shanghai + - opcA9DiffPlaces_d9g0v0_Shanghai + - opcA9DiffPlaces_d24g0v0_Shanghai + - opcAADiffPlaces_d1g0v0_Shanghai + - opcA9DiffPlaces_d25g0v0_Shanghai + - opcAADiffPlaces_d10g0v0_Shanghai + - opcA9DiffPlaces_d26g0v0_Shanghai + - opcAADiffPlaces_d11g0v0_Shanghai + - opcAADiffPlaces_d12g0v0_Shanghai + - opcA9DiffPlaces_d27g0v0_Shanghai + - opcAADiffPlaces_d13g0v0_Shanghai + - opcA9DiffPlaces_d28g0v0_Shanghai + - opcAADiffPlaces_d14g0v0_Shanghai + - opcA9DiffPlaces_d29g0v0_Shanghai + - opcAADiffPlaces_d15g0v0_Shanghai + - opcAADiffPlaces_d16g0v0_Shanghai + - opcA9DiffPlaces_d30g0v0_Shanghai + - opcA9DiffPlaces_d32g0v0_Shanghai + - opcAADiffPlaces_d2g0v0_Shanghai + - opcA9DiffPlaces_d31g0v0_Shanghai + - opcA9DiffPlaces_d33g0v0_Shanghai + - opcA9DiffPlaces_d34g0v0_Shanghai + - opcAADiffPlaces_d17g0v0_Shanghai + - opcAADiffPlaces_d18g0v0_Shanghai + - opcAADiffPlaces_d19g0v0_Shanghai + - opcAADiffPlaces_d3g0v0_Shanghai + - opcAADiffPlaces_d21g0v0_Shanghai + - opcABDiffPlaces_d0g0v0_Shanghai + - opcAADiffPlaces_d4g0v0_Shanghai + - opcAADiffPlaces_d22g0v0_Shanghai + - opcAADiffPlaces_d20g0v0_Shanghai + - opcAADiffPlaces_d5g0v0_Shanghai + - opcAADiffPlaces_d23g0v0_Shanghai + - opcAADiffPlaces_d6g0v0_Shanghai + - opcAADiffPlaces_d7g0v0_Shanghai + - opcAADiffPlaces_d8g0v0_Shanghai + - opcAADiffPlaces_d9g0v0_Shanghai + - opcAADiffPlaces_d24g0v0_Shanghai + - opcABDiffPlaces_d1g0v0_Shanghai + - opcAADiffPlaces_d25g0v0_Shanghai + - opcABDiffPlaces_d10g0v0_Shanghai + - opcAADiffPlaces_d26g0v0_Shanghai + - opcABDiffPlaces_d11g0v0_Shanghai + - opcABDiffPlaces_d12g0v0_Shanghai + - opcAADiffPlaces_d27g0v0_Shanghai + - opcABDiffPlaces_d13g0v0_Shanghai + - opcAADiffPlaces_d28g0v0_Shanghai + - opcABDiffPlaces_d14g0v0_Shanghai + - opcAADiffPlaces_d29g0v0_Shanghai + - opcABDiffPlaces_d15g0v0_Shanghai + - opcAADiffPlaces_d30g0v0_Shanghai + - opcAADiffPlaces_d31g0v0_Shanghai + - opcABDiffPlaces_d16g0v0_Shanghai + - opcABDiffPlaces_d2g0v0_Shanghai + - opcAADiffPlaces_d32g0v0_Shanghai + - opcAADiffPlaces_d33g0v0_Shanghai + - opcAADiffPlaces_d34g0v0_Shanghai + - opcABDiffPlaces_d17g0v0_Shanghai + - opcABDiffPlaces_d18g0v0_Shanghai + - opcABDiffPlaces_d19g0v0_Shanghai + - opcABDiffPlaces_d3g0v0_Shanghai + - opcABDiffPlaces_d21g0v0_Shanghai + - opcACDiffPlaces_d0g0v0_Shanghai + - opcABDiffPlaces_d4g0v0_Shanghai + - opcABDiffPlaces_d20g0v0_Shanghai + - opcABDiffPlaces_d22g0v0_Shanghai + - opcABDiffPlaces_d23g0v0_Shanghai + - opcABDiffPlaces_d5g0v0_Shanghai + - opcABDiffPlaces_d6g0v0_Shanghai + - opcABDiffPlaces_d7g0v0_Shanghai + - opcABDiffPlaces_d8g0v0_Shanghai + - opcABDiffPlaces_d9g0v0_Shanghai + - opcABDiffPlaces_d24g0v0_Shanghai + - opcACDiffPlaces_d1g0v0_Shanghai + - opcABDiffPlaces_d25g0v0_Shanghai + - opcACDiffPlaces_d10g0v0_Shanghai + - opcACDiffPlaces_d11g0v0_Shanghai + - opcABDiffPlaces_d26g0v0_Shanghai + - opcACDiffPlaces_d12g0v0_Shanghai + - opcABDiffPlaces_d27g0v0_Shanghai + - opcACDiffPlaces_d13g0v0_Shanghai + - opcABDiffPlaces_d28g0v0_Shanghai + - opcACDiffPlaces_d14g0v0_Shanghai + - opcABDiffPlaces_d29g0v0_Shanghai + - opcACDiffPlaces_d15g0v0_Shanghai + - opcACDiffPlaces_d16g0v0_Shanghai + - opcABDiffPlaces_d30g0v0_Shanghai + - opcABDiffPlaces_d31g0v0_Shanghai + - opcACDiffPlaces_d2g0v0_Shanghai + - opcABDiffPlaces_d32g0v0_Shanghai + - opcABDiffPlaces_d33g0v0_Shanghai + - opcABDiffPlaces_d34g0v0_Shanghai + - opcACDiffPlaces_d17g0v0_Shanghai + - opcACDiffPlaces_d18g0v0_Shanghai + - opcACDiffPlaces_d19g0v0_Shanghai + - opcACDiffPlaces_d3g0v0_Shanghai + - opcADDiffPlaces_d0g0v0_Shanghai + - opcACDiffPlaces_d21g0v0_Shanghai + - opcACDiffPlaces_d4g0v0_Shanghai + - opcACDiffPlaces_d20g0v0_Shanghai + - opcACDiffPlaces_d22g0v0_Shanghai + - opcACDiffPlaces_d5g0v0_Shanghai + - opcACDiffPlaces_d23g0v0_Shanghai + - opcACDiffPlaces_d6g0v0_Shanghai + - opcACDiffPlaces_d7g0v0_Shanghai + - opcACDiffPlaces_d8g0v0_Shanghai + - opcACDiffPlaces_d24g0v0_Shanghai + - opcACDiffPlaces_d9g0v0_Shanghai + - opcADDiffPlaces_d1g0v0_Shanghai + - opcACDiffPlaces_d25g0v0_Shanghai + - opcADDiffPlaces_d10g0v0_Shanghai + - opcACDiffPlaces_d26g0v0_Shanghai + - opcADDiffPlaces_d11g0v0_Shanghai + - opcADDiffPlaces_d12g0v0_Shanghai + - opcACDiffPlaces_d27g0v0_Shanghai + - opcADDiffPlaces_d13g0v0_Shanghai + - opcACDiffPlaces_d28g0v0_Shanghai + - opcADDiffPlaces_d14g0v0_Shanghai + - opcACDiffPlaces_d29g0v0_Shanghai + - opcADDiffPlaces_d15g0v0_Shanghai + - opcADDiffPlaces_d16g0v0_Shanghai + - opcACDiffPlaces_d30g0v0_Shanghai + - opcACDiffPlaces_d31g0v0_Shanghai + - opcACDiffPlaces_d32g0v0_Shanghai + - opcADDiffPlaces_d2g0v0_Shanghai + - opcACDiffPlaces_d33g0v0_Shanghai + - opcACDiffPlaces_d34g0v0_Shanghai + - opcADDiffPlaces_d17g0v0_Shanghai + - opcADDiffPlaces_d18g0v0_Shanghai + - opcADDiffPlaces_d19g0v0_Shanghai + - opcADDiffPlaces_d3g0v0_Shanghai + - opcAEDiffPlaces_d0g0v0_Shanghai + - opcADDiffPlaces_d21g0v0_Shanghai + - opcADDiffPlaces_d4g0v0_Shanghai + - opcADDiffPlaces_d20g0v0_Shanghai + - opcADDiffPlaces_d22g0v0_Shanghai + - opcADDiffPlaces_d5g0v0_Shanghai + - opcADDiffPlaces_d23g0v0_Shanghai + - opcADDiffPlaces_d6g0v0_Shanghai + - opcADDiffPlaces_d7g0v0_Shanghai + - opcADDiffPlaces_d8g0v0_Shanghai + - opcADDiffPlaces_d24g0v0_Shanghai + - opcADDiffPlaces_d9g0v0_Shanghai + - opcADDiffPlaces_d25g0v0_Shanghai + - opcAEDiffPlaces_d1g0v0_Shanghai + - opcAEDiffPlaces_d10g0v0_Shanghai + - opcADDiffPlaces_d26g0v0_Shanghai + - opcAEDiffPlaces_d11g0v0_Shanghai + - opcAEDiffPlaces_d12g0v0_Shanghai + - opcADDiffPlaces_d27g0v0_Shanghai + - opcAEDiffPlaces_d13g0v0_Shanghai + - opcADDiffPlaces_d28g0v0_Shanghai + - opcAEDiffPlaces_d14g0v0_Shanghai + - opcADDiffPlaces_d29g0v0_Shanghai + - opcAEDiffPlaces_d15g0v0_Shanghai + - opcAEDiffPlaces_d16g0v0_Shanghai + - opcADDiffPlaces_d30g0v0_Shanghai + - opcAEDiffPlaces_d2g0v0_Shanghai + - opcADDiffPlaces_d32g0v0_Shanghai + - opcADDiffPlaces_d31g0v0_Shanghai + - opcADDiffPlaces_d33g0v0_Shanghai + - opcADDiffPlaces_d34g0v0_Shanghai + - opcAEDiffPlaces_d17g0v0_Shanghai + - opcAEDiffPlaces_d18g0v0_Shanghai + - opcAEDiffPlaces_d19g0v0_Shanghai + - opcAEDiffPlaces_d3g0v0_Shanghai + - opcAEDiffPlaces_d21g0v0_Shanghai + - opcAFDiffPlaces_d0g0v0_Shanghai + - opcAEDiffPlaces_d4g0v0_Shanghai + - opcAEDiffPlaces_d20g0v0_Shanghai + - opcAEDiffPlaces_d22g0v0_Shanghai + - opcAEDiffPlaces_d5g0v0_Shanghai + - opcAEDiffPlaces_d23g0v0_Shanghai + - opcAEDiffPlaces_d6g0v0_Shanghai + - opcAEDiffPlaces_d7g0v0_Shanghai + - opcAEDiffPlaces_d8g0v0_Shanghai + - opcAEDiffPlaces_d24g0v0_Shanghai + - opcAEDiffPlaces_d9g0v0_Shanghai + - opcAEDiffPlaces_d25g0v0_Shanghai + - opcAFDiffPlaces_d1g0v0_Shanghai + - opcAFDiffPlaces_d10g0v0_Shanghai + - opcAEDiffPlaces_d26g0v0_Shanghai + - opcAFDiffPlaces_d11g0v0_Shanghai + - opcAFDiffPlaces_d12g0v0_Shanghai + - opcAFDiffPlaces_d13g0v0_Shanghai + - opcAEDiffPlaces_d27g0v0_Shanghai + - opcAEDiffPlaces_d28g0v0_Shanghai + - opcAFDiffPlaces_d14g0v0_Shanghai + - opcAEDiffPlaces_d29g0v0_Shanghai + - opcAFDiffPlaces_d15g0v0_Shanghai + - opcAEDiffPlaces_d30g0v0_Shanghai + - opcAFDiffPlaces_d16g0v0_Shanghai + - opcAEDiffPlaces_d31g0v0_Shanghai + - opcAFDiffPlaces_d2g0v0_Shanghai + - opcAEDiffPlaces_d32g0v0_Shanghai + - opcAEDiffPlaces_d33g0v0_Shanghai + - opcAEDiffPlaces_d34g0v0_Shanghai + - opcAFDiffPlaces_d17g0v0_Shanghai + - opcAFDiffPlaces_d18g0v0_Shanghai + - opcAFDiffPlaces_d19g0v0_Shanghai + - opcAFDiffPlaces_d3g0v0_Shanghai + - opcAFDiffPlaces_d21g0v0_Shanghai + - opcB0DiffPlaces_d0g0v0_Shanghai + - opcAFDiffPlaces_d4g0v0_Shanghai + - opcAFDiffPlaces_d20g0v0_Shanghai + - opcAFDiffPlaces_d22g0v0_Shanghai + - opcAFDiffPlaces_d23g0v0_Shanghai + - opcAFDiffPlaces_d5g0v0_Shanghai + - opcAFDiffPlaces_d6g0v0_Shanghai + - opcAFDiffPlaces_d7g0v0_Shanghai + - opcAFDiffPlaces_d8g0v0_Shanghai + - opcAFDiffPlaces_d9g0v0_Shanghai + - opcAFDiffPlaces_d24g0v0_Shanghai + - opcAFDiffPlaces_d25g0v0_Shanghai + - opcB0DiffPlaces_d1g0v0_Shanghai + - opcB0DiffPlaces_d10g0v0_Shanghai + - opcB0DiffPlaces_d11g0v0_Shanghai + - opcAFDiffPlaces_d26g0v0_Shanghai + - opcB0DiffPlaces_d12g0v0_Shanghai + - opcB0DiffPlaces_d13g0v0_Shanghai + - opcAFDiffPlaces_d27g0v0_Shanghai + - opcAFDiffPlaces_d28g0v0_Shanghai + - opcB0DiffPlaces_d14g0v0_Shanghai + - opcAFDiffPlaces_d29g0v0_Shanghai + - opcB0DiffPlaces_d15g0v0_Shanghai + - opcAFDiffPlaces_d30g0v0_Shanghai + - opcB0DiffPlaces_d16g0v0_Shanghai + - opcAFDiffPlaces_d31g0v0_Shanghai + - opcB0DiffPlaces_d2g0v0_Shanghai + - opcAFDiffPlaces_d32g0v0_Shanghai + - opcAFDiffPlaces_d33g0v0_Shanghai + - opcAFDiffPlaces_d34g0v0_Shanghai + - opcB0DiffPlaces_d17g0v0_Shanghai + - opcB0DiffPlaces_d18g0v0_Shanghai + - opcB0DiffPlaces_d3g0v0_Shanghai + - opcB0DiffPlaces_d19g0v0_Shanghai + - opcB1DiffPlaces_d0g0v0_Shanghai + - opcB0DiffPlaces_d21g0v0_Shanghai + - opcB0DiffPlaces_d20g0v0_Shanghai + - opcB0DiffPlaces_d4g0v0_Shanghai + - opcB0DiffPlaces_d22g0v0_Shanghai + - opcB0DiffPlaces_d5g0v0_Shanghai + - opcB0DiffPlaces_d23g0v0_Shanghai + - opcB0DiffPlaces_d6g0v0_Shanghai + - opcB0DiffPlaces_d7g0v0_Shanghai + - opcB0DiffPlaces_d8g0v0_Shanghai + - opcB0DiffPlaces_d24g0v0_Shanghai + - opcB0DiffPlaces_d9g0v0_Shanghai + - opcB0DiffPlaces_d25g0v0_Shanghai + - opcB1DiffPlaces_d1g0v0_Shanghai + - opcB1DiffPlaces_d10g0v0_Shanghai + - opcB1DiffPlaces_d11g0v0_Shanghai + - opcB0DiffPlaces_d26g0v0_Shanghai + - opcB1DiffPlaces_d12g0v0_Shanghai + - opcB0DiffPlaces_d27g0v0_Shanghai + - opcB1DiffPlaces_d13g0v0_Shanghai + - opcB0DiffPlaces_d28g0v0_Shanghai + - opcB1DiffPlaces_d14g0v0_Shanghai + - opcB0DiffPlaces_d29g0v0_Shanghai + - opcB1DiffPlaces_d15g0v0_Shanghai + - opcB1DiffPlaces_d16g0v0_Shanghai + - opcB0DiffPlaces_d30g0v0_Shanghai + - opcB0DiffPlaces_d31g0v0_Shanghai + - opcB0DiffPlaces_d32g0v0_Shanghai + - opcB1DiffPlaces_d2g0v0_Shanghai + - opcB0DiffPlaces_d33g0v0_Shanghai + - opcB0DiffPlaces_d34g0v0_Shanghai + - opcB1DiffPlaces_d17g0v0_Shanghai + - opcB1DiffPlaces_d18g0v0_Shanghai + - opcB1DiffPlaces_d19g0v0_Shanghai + - opcB1DiffPlaces_d3g0v0_Shanghai + - opcB1DiffPlaces_d21g0v0_Shanghai + - opcB1DiffPlaces_d4g0v0_Shanghai + - opcB2DiffPlaces_d0g0v0_Shanghai + - opcB1DiffPlaces_d22g0v0_Shanghai + - opcB1DiffPlaces_d20g0v0_Shanghai + - opcB1DiffPlaces_d5g0v0_Shanghai + - opcB1DiffPlaces_d23g0v0_Shanghai + - opcB1DiffPlaces_d6g0v0_Shanghai + - opcB1DiffPlaces_d7g0v0_Shanghai + - opcB1DiffPlaces_d8g0v0_Shanghai + - opcB1DiffPlaces_d24g0v0_Shanghai + - opcB1DiffPlaces_d9g0v0_Shanghai + - opcB1DiffPlaces_d25g0v0_Shanghai + - opcB2DiffPlaces_d1g0v0_Shanghai + - opcB2DiffPlaces_d10g0v0_Shanghai + - opcB2DiffPlaces_d11g0v0_Shanghai + - opcB1DiffPlaces_d26g0v0_Shanghai + - opcB2DiffPlaces_d12g0v0_Shanghai + - opcB1DiffPlaces_d27g0v0_Shanghai + - opcB2DiffPlaces_d13g0v0_Shanghai + - opcB1DiffPlaces_d28g0v0_Shanghai + - opcB2DiffPlaces_d14g0v0_Shanghai + - opcB1DiffPlaces_d29g0v0_Shanghai + - opcB2DiffPlaces_d15g0v0_Shanghai + - opcB1DiffPlaces_d30g0v0_Shanghai + - opcB2DiffPlaces_d16g0v0_Shanghai + - opcB1DiffPlaces_d31g0v0_Shanghai + - opcB1DiffPlaces_d32g0v0_Shanghai + - opcB2DiffPlaces_d2g0v0_Shanghai + - opcB1DiffPlaces_d33g0v0_Shanghai + - opcB1DiffPlaces_d34g0v0_Shanghai + - opcB2DiffPlaces_d17g0v0_Shanghai + - opcB2DiffPlaces_d18g0v0_Shanghai + - opcB2DiffPlaces_d19g0v0_Shanghai + - opcB2DiffPlaces_d3g0v0_Shanghai + - opcB2DiffPlaces_d21g0v0_Shanghai + - opcB3DiffPlaces_d0g0v0_Shanghai + - opcB2DiffPlaces_d20g0v0_Shanghai + - opcB2DiffPlaces_d4g0v0_Shanghai + - opcB2DiffPlaces_d22g0v0_Shanghai + - opcB2DiffPlaces_d23g0v0_Shanghai + - opcB2DiffPlaces_d5g0v0_Shanghai + - opcB2DiffPlaces_d6g0v0_Shanghai + - opcB2DiffPlaces_d7g0v0_Shanghai + - opcB2DiffPlaces_d8g0v0_Shanghai + - opcB2DiffPlaces_d24g0v0_Shanghai + - opcB2DiffPlaces_d9g0v0_Shanghai + - opcB3DiffPlaces_d1g0v0_Shanghai + - opcB2DiffPlaces_d25g0v0_Shanghai + - opcB3DiffPlaces_d10g0v0_Shanghai + - opcB2DiffPlaces_d26g0v0_Shanghai + - opcB3DiffPlaces_d11g0v0_Shanghai + - opcB3DiffPlaces_d12g0v0_Shanghai + - opcB2DiffPlaces_d27g0v0_Shanghai + - opcB3DiffPlaces_d13g0v0_Shanghai + - opcB2DiffPlaces_d28g0v0_Shanghai + - opcB3DiffPlaces_d14g0v0_Shanghai + - opcB3DiffPlaces_d15g0v0_Shanghai + - opcB2DiffPlaces_d29g0v0_Shanghai + - opcB2DiffPlaces_d30g0v0_Shanghai + - opcB2DiffPlaces_d31g0v0_Shanghai + - opcB3DiffPlaces_d16g0v0_Shanghai + - opcB2DiffPlaces_d32g0v0_Shanghai + - opcB3DiffPlaces_d2g0v0_Shanghai + - opcB2DiffPlaces_d33g0v0_Shanghai + - opcB2DiffPlaces_d34g0v0_Shanghai + - opcB3DiffPlaces_d17g0v0_Shanghai + - opcB3DiffPlaces_d18g0v0_Shanghai + - opcB3DiffPlaces_d19g0v0_Shanghai + - opcB3DiffPlaces_d3g0v0_Shanghai + - opcB3DiffPlaces_d21g0v0_Shanghai + - opcB4DiffPlaces_d0g0v0_Shanghai + - opcB3DiffPlaces_d4g0v0_Shanghai + - opcB3DiffPlaces_d20g0v0_Shanghai + - opcB3DiffPlaces_d22g0v0_Shanghai + - opcB3DiffPlaces_d5g0v0_Shanghai + - opcB3DiffPlaces_d23g0v0_Shanghai + - opcB3DiffPlaces_d6g0v0_Shanghai + - opcB3DiffPlaces_d7g0v0_Shanghai + - opcB3DiffPlaces_d8g0v0_Shanghai + - opcB3DiffPlaces_d9g0v0_Shanghai + - opcB3DiffPlaces_d24g0v0_Shanghai + - opcB4DiffPlaces_d1g0v0_Shanghai + - opcB3DiffPlaces_d25g0v0_Shanghai + - opcB4DiffPlaces_d10g0v0_Shanghai + - opcB4DiffPlaces_d11g0v0_Shanghai + - opcB3DiffPlaces_d26g0v0_Shanghai + - opcB4DiffPlaces_d12g0v0_Shanghai + - opcB3DiffPlaces_d27g0v0_Shanghai + - opcB4DiffPlaces_d13g0v0_Shanghai + - opcB4DiffPlaces_d14g0v0_Shanghai + - opcB3DiffPlaces_d28g0v0_Shanghai + - opcB4DiffPlaces_d15g0v0_Shanghai + - opcB3DiffPlaces_d29g0v0_Shanghai + - opcB3DiffPlaces_d30g0v0_Shanghai + - opcB4DiffPlaces_d16g0v0_Shanghai + - opcB3DiffPlaces_d31g0v0_Shanghai + - opcB4DiffPlaces_d2g0v0_Shanghai + - opcB3DiffPlaces_d32g0v0_Shanghai + - opcB3DiffPlaces_d33g0v0_Shanghai + - opcB3DiffPlaces_d34g0v0_Shanghai + - opcB4DiffPlaces_d17g0v0_Shanghai + - opcB4DiffPlaces_d18g0v0_Shanghai + - opcB4DiffPlaces_d19g0v0_Shanghai + - opcB4DiffPlaces_d3g0v0_Shanghai + - opcB5DiffPlaces_d0g0v0_Shanghai + - opcB4DiffPlaces_d21g0v0_Shanghai + - opcB4DiffPlaces_d20g0v0_Shanghai + - opcB4DiffPlaces_d4g0v0_Shanghai + - opcB4DiffPlaces_d22g0v0_Shanghai + - opcB4DiffPlaces_d5g0v0_Shanghai + - opcB4DiffPlaces_d23g0v0_Shanghai + - opcB4DiffPlaces_d6g0v0_Shanghai + - opcB4DiffPlaces_d7g0v0_Shanghai + - opcB4DiffPlaces_d8g0v0_Shanghai + - opcB4DiffPlaces_d24g0v0_Shanghai + - opcB4DiffPlaces_d9g0v0_Shanghai + - opcB4DiffPlaces_d25g0v0_Shanghai + - opcB5DiffPlaces_d1g0v0_Shanghai + - opcB5DiffPlaces_d10g0v0_Shanghai + - opcB5DiffPlaces_d11g0v0_Shanghai + - opcB4DiffPlaces_d26g0v0_Shanghai + - opcB5DiffPlaces_d12g0v0_Shanghai + - opcB4DiffPlaces_d27g0v0_Shanghai + - opcB5DiffPlaces_d13g0v0_Shanghai + - opcB4DiffPlaces_d28g0v0_Shanghai + - opcB5DiffPlaces_d14g0v0_Shanghai + - opcB4DiffPlaces_d29g0v0_Shanghai + - opcB5DiffPlaces_d15g0v0_Shanghai + - opcB4DiffPlaces_d30g0v0_Shanghai + - opcB5DiffPlaces_d16g0v0_Shanghai + - opcB4DiffPlaces_d31g0v0_Shanghai + - opcB4DiffPlaces_d32g0v0_Shanghai + - opcB5DiffPlaces_d2g0v0_Shanghai + - opcB4DiffPlaces_d33g0v0_Shanghai + - opcB4DiffPlaces_d34g0v0_Shanghai + - opcB5DiffPlaces_d17g0v0_Shanghai + - opcB5DiffPlaces_d18g0v0_Shanghai + - opcB5DiffPlaces_d19g0v0_Shanghai + - opcB5DiffPlaces_d3g0v0_Shanghai + - opcB6DiffPlaces_d0g0v0_Shanghai + - opcB5DiffPlaces_d21g0v0_Shanghai + - opcB5DiffPlaces_d4g0v0_Shanghai + - opcB5DiffPlaces_d20g0v0_Shanghai + - opcB5DiffPlaces_d22g0v0_Shanghai + - opcB5DiffPlaces_d5g0v0_Shanghai + - opcB5DiffPlaces_d23g0v0_Shanghai + - opcB5DiffPlaces_d6g0v0_Shanghai + - opcB5DiffPlaces_d7g0v0_Shanghai + - opcB5DiffPlaces_d8g0v0_Shanghai + - opcB5DiffPlaces_d24g0v0_Shanghai + - opcB5DiffPlaces_d9g0v0_Shanghai + - opcB5DiffPlaces_d25g0v0_Shanghai + - opcB6DiffPlaces_d1g0v0_Shanghai + - opcB6DiffPlaces_d10g0v0_Shanghai + - opcB6DiffPlaces_d11g0v0_Shanghai + - opcB5DiffPlaces_d26g0v0_Shanghai + - opcB6DiffPlaces_d12g0v0_Shanghai + - opcB5DiffPlaces_d27g0v0_Shanghai + - opcB6DiffPlaces_d13g0v0_Shanghai + - opcB5DiffPlaces_d28g0v0_Shanghai + - opcB6DiffPlaces_d14g0v0_Shanghai + - opcB5DiffPlaces_d29g0v0_Shanghai + - opcB6DiffPlaces_d15g0v0_Shanghai + - opcB5DiffPlaces_d30g0v0_Shanghai + - opcB5DiffPlaces_d31g0v0_Shanghai + - opcB6DiffPlaces_d16g0v0_Shanghai + - opcB6DiffPlaces_d2g0v0_Shanghai + - opcB5DiffPlaces_d32g0v0_Shanghai + - opcB5DiffPlaces_d33g0v0_Shanghai + - opcB5DiffPlaces_d34g0v0_Shanghai + - opcB6DiffPlaces_d17g0v0_Shanghai + - opcB6DiffPlaces_d18g0v0_Shanghai + - opcB6DiffPlaces_d19g0v0_Shanghai + - opcB6DiffPlaces_d3g0v0_Shanghai + - opcB6DiffPlaces_d21g0v0_Shanghai + - opcB7DiffPlaces_d0g0v0_Shanghai + - opcB6DiffPlaces_d4g0v0_Shanghai + - opcB6DiffPlaces_d22g0v0_Shanghai + - opcB6DiffPlaces_d20g0v0_Shanghai + - opcB6DiffPlaces_d5g0v0_Shanghai + - opcB6DiffPlaces_d23g0v0_Shanghai + - opcB6DiffPlaces_d6g0v0_Shanghai + - opcB6DiffPlaces_d7g0v0_Shanghai + - opcB6DiffPlaces_d8g0v0_Shanghai + - opcB6DiffPlaces_d9g0v0_Shanghai + - opcB6DiffPlaces_d24g0v0_Shanghai + - opcB6DiffPlaces_d25g0v0_Shanghai + - opcB7DiffPlaces_d1g0v0_Shanghai + - opcB7DiffPlaces_d10g0v0_Shanghai + - opcB6DiffPlaces_d26g0v0_Shanghai + - opcB7DiffPlaces_d11g0v0_Shanghai + - opcB7DiffPlaces_d12g0v0_Shanghai + - opcB6DiffPlaces_d27g0v0_Shanghai + - opcB7DiffPlaces_d13g0v0_Shanghai + - opcB6DiffPlaces_d28g0v0_Shanghai + - opcB7DiffPlaces_d14g0v0_Shanghai + - opcB6DiffPlaces_d29g0v0_Shanghai + - opcB7DiffPlaces_d15g0v0_Shanghai + - opcB6DiffPlaces_d30g0v0_Shanghai + - opcB7DiffPlaces_d16g0v0_Shanghai + - opcB6DiffPlaces_d31g0v0_Shanghai + - opcB7DiffPlaces_d2g0v0_Shanghai + - opcB6DiffPlaces_d32g0v0_Shanghai + - opcB6DiffPlaces_d33g0v0_Shanghai + - opcB6DiffPlaces_d34g0v0_Shanghai + - opcB7DiffPlaces_d17g0v0_Shanghai + - opcB7DiffPlaces_d18g0v0_Shanghai + - opcB7DiffPlaces_d19g0v0_Shanghai + - opcB7DiffPlaces_d3g0v0_Shanghai + - opcB7DiffPlaces_d21g0v0_Shanghai + - opcB7DiffPlaces_d4g0v0_Shanghai + - opcB8DiffPlaces_d0g0v0_Shanghai + - opcB7DiffPlaces_d20g0v0_Shanghai + - opcB7DiffPlaces_d22g0v0_Shanghai + - opcB7DiffPlaces_d5g0v0_Shanghai + - opcB7DiffPlaces_d23g0v0_Shanghai + - opcB7DiffPlaces_d6g0v0_Shanghai + - opcB7DiffPlaces_d7g0v0_Shanghai + - opcB7DiffPlaces_d8g0v0_Shanghai + - opcB7DiffPlaces_d24g0v0_Shanghai + - opcB7DiffPlaces_d9g0v0_Shanghai + - opcB7DiffPlaces_d25g0v0_Shanghai + - opcB8DiffPlaces_d1g0v0_Shanghai + - opcB8DiffPlaces_d10g0v0_Shanghai + - opcB7DiffPlaces_d26g0v0_Shanghai + - opcB8DiffPlaces_d11g0v0_Shanghai + - opcB8DiffPlaces_d12g0v0_Shanghai + - opcB7DiffPlaces_d27g0v0_Shanghai + - opcB8DiffPlaces_d13g0v0_Shanghai + - opcB7DiffPlaces_d28g0v0_Shanghai + - opcB8DiffPlaces_d14g0v0_Shanghai + - opcB7DiffPlaces_d29g0v0_Shanghai + - opcB8DiffPlaces_d15g0v0_Shanghai + - opcB8DiffPlaces_d16g0v0_Shanghai + - opcB7DiffPlaces_d30g0v0_Shanghai + - opcB7DiffPlaces_d31g0v0_Shanghai + - opcB8DiffPlaces_d2g0v0_Shanghai + - opcB7DiffPlaces_d32g0v0_Shanghai + - opcB7DiffPlaces_d33g0v0_Shanghai + - opcB7DiffPlaces_d34g0v0_Shanghai + - opcB8DiffPlaces_d17g0v0_Shanghai + - opcB8DiffPlaces_d18g0v0_Shanghai + - opcB8DiffPlaces_d19g0v0_Shanghai + - opcB8DiffPlaces_d3g0v0_Shanghai + - opcB8DiffPlaces_d21g0v0_Shanghai + - opcB9DiffPlaces_d0g0v0_Shanghai + - opcB8DiffPlaces_d4g0v0_Shanghai + - opcB8DiffPlaces_d20g0v0_Shanghai + - opcB8DiffPlaces_d22g0v0_Shanghai + - opcB8DiffPlaces_d23g0v0_Shanghai + - opcB8DiffPlaces_d5g0v0_Shanghai + - opcB8DiffPlaces_d6g0v0_Shanghai + - opcB8DiffPlaces_d7g0v0_Shanghai + - opcB8DiffPlaces_d8g0v0_Shanghai + - opcB8DiffPlaces_d24g0v0_Shanghai + - opcB8DiffPlaces_d9g0v0_Shanghai + - opcB8DiffPlaces_d25g0v0_Shanghai + - opcB9DiffPlaces_d1g0v0_Shanghai + - opcB9DiffPlaces_d10g0v0_Shanghai + - opcB9DiffPlaces_d11g0v0_Shanghai + - opcB8DiffPlaces_d26g0v0_Shanghai + - opcB9DiffPlaces_d12g0v0_Shanghai + - opcB8DiffPlaces_d27g0v0_Shanghai + - opcB9DiffPlaces_d13g0v0_Shanghai + - opcB8DiffPlaces_d28g0v0_Shanghai + - opcB9DiffPlaces_d14g0v0_Shanghai + - opcB8DiffPlaces_d29g0v0_Shanghai + - opcB9DiffPlaces_d15g0v0_Shanghai + - opcB9DiffPlaces_d16g0v0_Shanghai + - opcB8DiffPlaces_d30g0v0_Shanghai + - opcB8DiffPlaces_d31g0v0_Shanghai + - opcB9DiffPlaces_d2g0v0_Shanghai + - opcB8DiffPlaces_d32g0v0_Shanghai + - opcB8DiffPlaces_d33g0v0_Shanghai + - opcB8DiffPlaces_d34g0v0_Shanghai + - opcB9DiffPlaces_d17g0v0_Shanghai + - opcB9DiffPlaces_d18g0v0_Shanghai + - opcB9DiffPlaces_d19g0v0_Shanghai + - opcB9DiffPlaces_d3g0v0_Shanghai + - opcB9DiffPlaces_d21g0v0_Shanghai + - opcBADiffPlaces_d0g0v0_Shanghai + - opcB9DiffPlaces_d20g0v0_Shanghai + - opcB9DiffPlaces_d4g0v0_Shanghai + - opcB9DiffPlaces_d22g0v0_Shanghai + - opcB9DiffPlaces_d23g0v0_Shanghai + - opcB9DiffPlaces_d5g0v0_Shanghai + - opcB9DiffPlaces_d6g0v0_Shanghai + - opcB9DiffPlaces_d7g0v0_Shanghai + - opcB9DiffPlaces_d8g0v0_Shanghai + - opcB9DiffPlaces_d24g0v0_Shanghai + - opcB9DiffPlaces_d9g0v0_Shanghai + - opcBADiffPlaces_d1g0v0_Shanghai + - opcB9DiffPlaces_d25g0v0_Shanghai + - opcBADiffPlaces_d10g0v0_Shanghai + - opcBADiffPlaces_d11g0v0_Shanghai + - opcB9DiffPlaces_d26g0v0_Shanghai + - opcBADiffPlaces_d12g0v0_Shanghai + - opcBADiffPlaces_d13g0v0_Shanghai + - opcB9DiffPlaces_d27g0v0_Shanghai + - opcB9DiffPlaces_d28g0v0_Shanghai + - opcBADiffPlaces_d14g0v0_Shanghai + - opcB9DiffPlaces_d29g0v0_Shanghai + - opcBADiffPlaces_d15g0v0_Shanghai + - opcBADiffPlaces_d16g0v0_Shanghai + - opcB9DiffPlaces_d30g0v0_Shanghai + - opcB9DiffPlaces_d31g0v0_Shanghai + - opcBADiffPlaces_d2g0v0_Shanghai + - opcB9DiffPlaces_d32g0v0_Shanghai + - opcB9DiffPlaces_d33g0v0_Shanghai + - opcB9DiffPlaces_d34g0v0_Shanghai + - opcBADiffPlaces_d17g0v0_Shanghai + - opcBADiffPlaces_d18g0v0_Shanghai + - opcBADiffPlaces_d19g0v0_Shanghai + - opcBADiffPlaces_d3g0v0_Shanghai + - opcBBDiffPlaces_d0g0v0_Shanghai + - opcBADiffPlaces_d21g0v0_Shanghai + - opcBADiffPlaces_d20g0v0_Shanghai + - opcBADiffPlaces_d4g0v0_Shanghai + - opcBADiffPlaces_d22g0v0_Shanghai + - opcBADiffPlaces_d23g0v0_Shanghai + - opcBADiffPlaces_d5g0v0_Shanghai + - opcBADiffPlaces_d6g0v0_Shanghai + - opcBADiffPlaces_d7g0v0_Shanghai + - opcBADiffPlaces_d8g0v0_Shanghai + - opcBADiffPlaces_d9g0v0_Shanghai + - opcBADiffPlaces_d24g0v0_Shanghai + - opcBADiffPlaces_d25g0v0_Shanghai + - opcBBDiffPlaces_d1g0v0_Shanghai + - opcBBDiffPlaces_d10g0v0_Shanghai + - opcBBDiffPlaces_d11g0v0_Shanghai + - opcBADiffPlaces_d26g0v0_Shanghai + - opcBBDiffPlaces_d12g0v0_Shanghai + - opcBADiffPlaces_d27g0v0_Shanghai + - opcBBDiffPlaces_d13g0v0_Shanghai + - opcBADiffPlaces_d28g0v0_Shanghai + - opcBBDiffPlaces_d14g0v0_Shanghai + - opcBBDiffPlaces_d15g0v0_Shanghai + - opcBADiffPlaces_d29g0v0_Shanghai + - opcBBDiffPlaces_d16g0v0_Shanghai + - opcBADiffPlaces_d30g0v0_Shanghai + - opcBBDiffPlaces_d2g0v0_Shanghai + - opcBADiffPlaces_d31g0v0_Shanghai + - opcBADiffPlaces_d32g0v0_Shanghai + - opcBADiffPlaces_d33g0v0_Shanghai + - opcBADiffPlaces_d34g0v0_Shanghai + - opcBBDiffPlaces_d17g0v0_Shanghai + - opcBBDiffPlaces_d18g0v0_Shanghai + - opcBBDiffPlaces_d19g0v0_Shanghai + - opcBBDiffPlaces_d3g0v0_Shanghai + - opcBCDiffPlaces_d0g0v0_Shanghai + - opcBBDiffPlaces_d21g0v0_Shanghai + - opcBBDiffPlaces_d20g0v0_Shanghai + - opcBBDiffPlaces_d4g0v0_Shanghai + - opcBBDiffPlaces_d22g0v0_Shanghai + - opcBBDiffPlaces_d5g0v0_Shanghai + - opcBBDiffPlaces_d23g0v0_Shanghai + - opcBBDiffPlaces_d6g0v0_Shanghai + - opcBBDiffPlaces_d7g0v0_Shanghai + - opcBBDiffPlaces_d8g0v0_Shanghai + - opcBBDiffPlaces_d9g0v0_Shanghai + - opcBBDiffPlaces_d24g0v0_Shanghai + - opcBCDiffPlaces_d1g0v0_Shanghai + - opcBBDiffPlaces_d25g0v0_Shanghai + - opcBCDiffPlaces_d10g0v0_Shanghai + - opcBCDiffPlaces_d11g0v0_Shanghai + - opcBBDiffPlaces_d26g0v0_Shanghai + - opcBCDiffPlaces_d12g0v0_Shanghai + - opcBBDiffPlaces_d27g0v0_Shanghai + - opcBCDiffPlaces_d13g0v0_Shanghai + - opcBBDiffPlaces_d28g0v0_Shanghai + - opcBCDiffPlaces_d14g0v0_Shanghai + - opcBBDiffPlaces_d29g0v0_Shanghai + - opcBCDiffPlaces_d15g0v0_Shanghai + - opcBBDiffPlaces_d30g0v0_Shanghai + - opcBBDiffPlaces_d31g0v0_Shanghai + - opcBCDiffPlaces_d16g0v0_Shanghai + - opcBBDiffPlaces_d32g0v0_Shanghai + - opcBCDiffPlaces_d2g0v0_Shanghai + - opcBBDiffPlaces_d33g0v0_Shanghai + - opcBBDiffPlaces_d34g0v0_Shanghai + - opcBCDiffPlaces_d17g0v0_Shanghai + - opcBCDiffPlaces_d18g0v0_Shanghai + - opcBCDiffPlaces_d3g0v0_Shanghai + - opcBCDiffPlaces_d19g0v0_Shanghai + - opcBCDiffPlaces_d21g0v0_Shanghai + - opcBDDiffPlaces_d0g0v0_Shanghai + - opcBCDiffPlaces_d4g0v0_Shanghai + - opcBCDiffPlaces_d22g0v0_Shanghai + - opcBCDiffPlaces_d20g0v0_Shanghai + - opcBCDiffPlaces_d23g0v0_Shanghai + - opcBCDiffPlaces_d5g0v0_Shanghai + - opcBCDiffPlaces_d6g0v0_Shanghai + - opcBCDiffPlaces_d7g0v0_Shanghai + - opcBCDiffPlaces_d8g0v0_Shanghai + - opcBCDiffPlaces_d24g0v0_Shanghai + - opcBCDiffPlaces_d9g0v0_Shanghai + - opcBCDiffPlaces_d25g0v0_Shanghai + - opcBDDiffPlaces_d1g0v0_Shanghai + - opcBDDiffPlaces_d10g0v0_Shanghai + - opcBCDiffPlaces_d26g0v0_Shanghai + - opcBDDiffPlaces_d11g0v0_Shanghai + - opcBDDiffPlaces_d12g0v0_Shanghai + - opcBCDiffPlaces_d27g0v0_Shanghai + - opcBDDiffPlaces_d13g0v0_Shanghai + - opcBCDiffPlaces_d28g0v0_Shanghai + - opcBDDiffPlaces_d14g0v0_Shanghai + - opcBCDiffPlaces_d29g0v0_Shanghai + - opcBDDiffPlaces_d15g0v0_Shanghai + - opcBCDiffPlaces_d30g0v0_Shanghai + - opcBCDiffPlaces_d31g0v0_Shanghai + - opcBDDiffPlaces_d16g0v0_Shanghai + - opcBDDiffPlaces_d2g0v0_Shanghai + - opcBCDiffPlaces_d32g0v0_Shanghai + - opcBCDiffPlaces_d33g0v0_Shanghai + - opcBCDiffPlaces_d34g0v0_Shanghai + - opcBDDiffPlaces_d17g0v0_Shanghai + - opcBDDiffPlaces_d18g0v0_Shanghai + - opcBDDiffPlaces_d19g0v0_Shanghai + - opcBDDiffPlaces_d3g0v0_Shanghai + - opcBDDiffPlaces_d21g0v0_Shanghai + - opcBEDiffPlaces_d0g0v0_Shanghai + - opcBDDiffPlaces_d4g0v0_Shanghai + - opcBDDiffPlaces_d20g0v0_Shanghai + - opcBDDiffPlaces_d22g0v0_Shanghai + - opcBDDiffPlaces_d5g0v0_Shanghai + - opcBDDiffPlaces_d23g0v0_Shanghai + - opcBDDiffPlaces_d6g0v0_Shanghai + - opcBDDiffPlaces_d7g0v0_Shanghai + - opcBDDiffPlaces_d8g0v0_Shanghai + - opcBDDiffPlaces_d24g0v0_Shanghai + - opcBDDiffPlaces_d9g0v0_Shanghai + - opcBEDiffPlaces_d1g0v0_Shanghai + - opcBDDiffPlaces_d25g0v0_Shanghai + - opcBEDiffPlaces_d10g0v0_Shanghai + - opcBDDiffPlaces_d26g0v0_Shanghai + - opcBEDiffPlaces_d11g0v0_Shanghai + - opcBEDiffPlaces_d12g0v0_Shanghai + - opcBDDiffPlaces_d27g0v0_Shanghai + - opcBEDiffPlaces_d13g0v0_Shanghai + - opcBDDiffPlaces_d28g0v0_Shanghai + - opcBEDiffPlaces_d14g0v0_Shanghai + - opcBDDiffPlaces_d29g0v0_Shanghai + - opcBEDiffPlaces_d15g0v0_Shanghai + - opcBEDiffPlaces_d16g0v0_Shanghai + - opcBDDiffPlaces_d30g0v0_Shanghai + - opcBDDiffPlaces_d31g0v0_Shanghai + - opcBDDiffPlaces_d32g0v0_Shanghai + - opcBEDiffPlaces_d2g0v0_Shanghai + - opcBDDiffPlaces_d33g0v0_Shanghai + - opcBDDiffPlaces_d34g0v0_Shanghai + - opcBEDiffPlaces_d17g0v0_Shanghai + - opcBEDiffPlaces_d18g0v0_Shanghai + - opcBEDiffPlaces_d19g0v0_Shanghai + - opcBEDiffPlaces_d3g0v0_Shanghai + - opcBEDiffPlaces_d21g0v0_Shanghai + - opcBFDiffPlaces_d0g0v0_Shanghai + - opcBEDiffPlaces_d4g0v0_Shanghai + - opcBEDiffPlaces_d20g0v0_Shanghai + - opcBEDiffPlaces_d22g0v0_Shanghai + - opcBEDiffPlaces_d5g0v0_Shanghai + - opcBEDiffPlaces_d23g0v0_Shanghai + - opcBEDiffPlaces_d6g0v0_Shanghai + - opcBEDiffPlaces_d7g0v0_Shanghai + - opcBEDiffPlaces_d8g0v0_Shanghai + - opcBEDiffPlaces_d24g0v0_Shanghai + - opcBEDiffPlaces_d9g0v0_Shanghai + - opcBEDiffPlaces_d25g0v0_Shanghai + - opcBFDiffPlaces_d1g0v0_Shanghai + - opcBFDiffPlaces_d10g0v0_Shanghai + - opcBFDiffPlaces_d11g0v0_Shanghai + - opcBEDiffPlaces_d26g0v0_Shanghai + - opcBFDiffPlaces_d12g0v0_Shanghai + - opcBEDiffPlaces_d27g0v0_Shanghai + - opcBFDiffPlaces_d13g0v0_Shanghai + - opcBEDiffPlaces_d28g0v0_Shanghai + - opcBFDiffPlaces_d14g0v0_Shanghai + - opcBFDiffPlaces_d15g0v0_Shanghai + - opcBEDiffPlaces_d29g0v0_Shanghai + - opcBEDiffPlaces_d30g0v0_Shanghai + - opcBFDiffPlaces_d16g0v0_Shanghai + - opcBEDiffPlaces_d31g0v0_Shanghai + - opcBEDiffPlaces_d32g0v0_Shanghai + - opcBFDiffPlaces_d2g0v0_Shanghai + - opcBEDiffPlaces_d33g0v0_Shanghai + - opcBEDiffPlaces_d34g0v0_Shanghai + - opcBFDiffPlaces_d17g0v0_Shanghai + - opcBFDiffPlaces_d18g0v0_Shanghai + - opcBFDiffPlaces_d19g0v0_Shanghai + - opcBFDiffPlaces_d3g0v0_Shanghai + - opcBFDiffPlaces_d21g0v0_Shanghai + - opcC0DiffPlaces_d0g0v0_Shanghai + - opcBFDiffPlaces_d4g0v0_Shanghai + - opcBFDiffPlaces_d20g0v0_Shanghai + - opcBFDiffPlaces_d22g0v0_Shanghai + - opcBFDiffPlaces_d5g0v0_Shanghai + - opcBFDiffPlaces_d23g0v0_Shanghai + - opcBFDiffPlaces_d6g0v0_Shanghai + - opcBFDiffPlaces_d7g0v0_Shanghai + - opcBFDiffPlaces_d8g0v0_Shanghai + - opcBFDiffPlaces_d24g0v0_Shanghai + - opcBFDiffPlaces_d9g0v0_Shanghai + - opcBFDiffPlaces_d25g0v0_Shanghai + - opcC0DiffPlaces_d1g0v0_Shanghai + - opcC0DiffPlaces_d10g0v0_Shanghai + - opcBFDiffPlaces_d26g0v0_Shanghai + - opcC0DiffPlaces_d11g0v0_Shanghai + - opcC0DiffPlaces_d12g0v0_Shanghai + - opcBFDiffPlaces_d27g0v0_Shanghai + - opcC0DiffPlaces_d13g0v0_Shanghai + - opcBFDiffPlaces_d28g0v0_Shanghai + - opcC0DiffPlaces_d14g0v0_Shanghai + - opcBFDiffPlaces_d29g0v0_Shanghai + - opcC0DiffPlaces_d15g0v0_Shanghai + - opcC0DiffPlaces_d16g0v0_Shanghai + - opcBFDiffPlaces_d31g0v0_Shanghai + - opcBFDiffPlaces_d30g0v0_Shanghai + - opcBFDiffPlaces_d32g0v0_Shanghai + - opcC0DiffPlaces_d2g0v0_Shanghai + - opcBFDiffPlaces_d34g0v0_Shanghai + - opcBFDiffPlaces_d33g0v0_Shanghai + - opcC0DiffPlaces_d17g0v0_Shanghai + - opcC0DiffPlaces_d18g0v0_Shanghai + - opcC0DiffPlaces_d19g0v0_Shanghai + - opcC0DiffPlaces_d3g0v0_Shanghai + - opcC0DiffPlaces_d21g0v0_Shanghai + - opcC1DiffPlaces_d0g0v0_Shanghai + - opcC0DiffPlaces_d4g0v0_Shanghai + - opcC0DiffPlaces_d20g0v0_Shanghai + - opcC0DiffPlaces_d22g0v0_Shanghai + - opcC0DiffPlaces_d5g0v0_Shanghai + - opcC0DiffPlaces_d23g0v0_Shanghai + - opcC0DiffPlaces_d6g0v0_Shanghai + - opcC0DiffPlaces_d7g0v0_Shanghai + - opcC0DiffPlaces_d8g0v0_Shanghai + - opcC0DiffPlaces_d24g0v0_Shanghai + - opcC0DiffPlaces_d9g0v0_Shanghai + - opcC1DiffPlaces_d1g0v0_Shanghai + - opcC0DiffPlaces_d25g0v0_Shanghai + - opcC1DiffPlaces_d10g0v0_Shanghai + - opcC1DiffPlaces_d11g0v0_Shanghai + - opcC0DiffPlaces_d26g0v0_Shanghai + - opcC1DiffPlaces_d12g0v0_Shanghai + - opcC0DiffPlaces_d27g0v0_Shanghai + - opcC1DiffPlaces_d13g0v0_Shanghai + - opcC0DiffPlaces_d28g0v0_Shanghai + - opcC1DiffPlaces_d14g0v0_Shanghai + - opcC0DiffPlaces_d29g0v0_Shanghai + - opcC1DiffPlaces_d15g0v0_Shanghai + - opcC0DiffPlaces_d30g0v0_Shanghai + - opcC0DiffPlaces_d31g0v0_Shanghai + - opcC1DiffPlaces_d16g0v0_Shanghai + - opcC1DiffPlaces_d2g0v0_Shanghai + - opcC0DiffPlaces_d32g0v0_Shanghai + - opcC0DiffPlaces_d33g0v0_Shanghai + - opcC0DiffPlaces_d34g0v0_Shanghai + - opcC1DiffPlaces_d17g0v0_Shanghai + - opcC1DiffPlaces_d18g0v0_Shanghai + - opcC1DiffPlaces_d19g0v0_Shanghai + - opcC1DiffPlaces_d3g0v0_Shanghai + - opcC1DiffPlaces_d21g0v0_Shanghai + - opcC1DiffPlaces_d4g0v0_Shanghai + - opcC2DiffPlaces_d0g0v0_Shanghai + - opcC1DiffPlaces_d20g0v0_Shanghai + - opcC1DiffPlaces_d22g0v0_Shanghai + - opcC1DiffPlaces_d23g0v0_Shanghai + - opcC1DiffPlaces_d5g0v0_Shanghai + - opcC1DiffPlaces_d6g0v0_Shanghai + - opcC1DiffPlaces_d7g0v0_Shanghai + - opcC1DiffPlaces_d8g0v0_Shanghai + - opcC1DiffPlaces_d9g0v0_Shanghai + - opcC1DiffPlaces_d24g0v0_Shanghai + - opcC2DiffPlaces_d1g0v0_Shanghai + - opcC1DiffPlaces_d25g0v0_Shanghai + - opcC2DiffPlaces_d10g0v0_Shanghai + - opcC2DiffPlaces_d11g0v0_Shanghai + - opcC1DiffPlaces_d26g0v0_Shanghai + - opcC2DiffPlaces_d12g0v0_Shanghai + - opcC1DiffPlaces_d27g0v0_Shanghai + - opcC2DiffPlaces_d13g0v0_Shanghai + - opcC2DiffPlaces_d14g0v0_Shanghai + - opcC1DiffPlaces_d28g0v0_Shanghai + - opcC2DiffPlaces_d15g0v0_Shanghai + - opcC1DiffPlaces_d29g0v0_Shanghai + - opcC1DiffPlaces_d30g0v0_Shanghai + - opcC2DiffPlaces_d16g0v0_Shanghai + - opcC1DiffPlaces_d31g0v0_Shanghai + - opcC2DiffPlaces_d2g0v0_Shanghai + - opcC1DiffPlaces_d32g0v0_Shanghai + - opcC1DiffPlaces_d33g0v0_Shanghai + - opcC1DiffPlaces_d34g0v0_Shanghai + - opcC2DiffPlaces_d17g0v0_Shanghai + - opcC2DiffPlaces_d18g0v0_Shanghai + - opcC2DiffPlaces_d19g0v0_Shanghai + - opcC2DiffPlaces_d3g0v0_Shanghai + - opcC2DiffPlaces_d21g0v0_Shanghai + - opcC3DiffPlaces_d0g0v0_Shanghai + - opcC2DiffPlaces_d4g0v0_Shanghai + - opcC2DiffPlaces_d20g0v0_Shanghai + - opcC2DiffPlaces_d22g0v0_Shanghai + - opcC2DiffPlaces_d23g0v0_Shanghai + - opcC2DiffPlaces_d5g0v0_Shanghai + - opcC2DiffPlaces_d6g0v0_Shanghai + - opcC2DiffPlaces_d7g0v0_Shanghai + - opcC2DiffPlaces_d8g0v0_Shanghai + - opcC2DiffPlaces_d24g0v0_Shanghai + - opcC2DiffPlaces_d9g0v0_Shanghai + - opcC3DiffPlaces_d1g0v0_Shanghai + - opcC2DiffPlaces_d25g0v0_Shanghai + - opcC3DiffPlaces_d10g0v0_Shanghai + - opcC3DiffPlaces_d11g0v0_Shanghai + - opcC2DiffPlaces_d26g0v0_Shanghai + - opcC3DiffPlaces_d12g0v0_Shanghai + - opcC2DiffPlaces_d27g0v0_Shanghai + - opcC3DiffPlaces_d13g0v0_Shanghai + - opcC2DiffPlaces_d28g0v0_Shanghai + - opcC3DiffPlaces_d14g0v0_Shanghai + - opcC3DiffPlaces_d15g0v0_Shanghai + - opcC2DiffPlaces_d29g0v0_Shanghai + - opcC2DiffPlaces_d30g0v0_Shanghai + - opcC3DiffPlaces_d16g0v0_Shanghai + - opcC2DiffPlaces_d31g0v0_Shanghai + - opcC2DiffPlaces_d32g0v0_Shanghai + - opcC3DiffPlaces_d2g0v0_Shanghai + - opcC2DiffPlaces_d33g0v0_Shanghai + - opcC2DiffPlaces_d34g0v0_Shanghai + - opcC3DiffPlaces_d17g0v0_Shanghai + - opcC3DiffPlaces_d18g0v0_Shanghai + - opcC3DiffPlaces_d3g0v0_Shanghai + - opcC3DiffPlaces_d19g0v0_Shanghai + - opcC4DiffPlaces_d0g0v0_Shanghai + - opcC3DiffPlaces_d21g0v0_Shanghai + - opcC3DiffPlaces_d4g0v0_Shanghai + - opcC3DiffPlaces_d20g0v0_Shanghai + - opcC3DiffPlaces_d22g0v0_Shanghai + - opcC3DiffPlaces_d5g0v0_Shanghai + - opcC3DiffPlaces_d23g0v0_Shanghai + - opcC3DiffPlaces_d6g0v0_Shanghai + - opcC3DiffPlaces_d7g0v0_Shanghai + - opcC3DiffPlaces_d8g0v0_Shanghai + - opcC3DiffPlaces_d9g0v0_Shanghai + - opcC3DiffPlaces_d24g0v0_Shanghai + - opcC3DiffPlaces_d25g0v0_Shanghai + - opcC4DiffPlaces_d1g0v0_Shanghai + - opcC4DiffPlaces_d10g0v0_Shanghai + - opcC4DiffPlaces_d11g0v0_Shanghai + - opcC3DiffPlaces_d26g0v0_Shanghai + - opcC4DiffPlaces_d12g0v0_Shanghai + - opcC3DiffPlaces_d27g0v0_Shanghai + - opcC4DiffPlaces_d13g0v0_Shanghai + - opcC3DiffPlaces_d28g0v0_Shanghai + - opcC4DiffPlaces_d14g0v0_Shanghai + - opcC3DiffPlaces_d29g0v0_Shanghai + - opcC4DiffPlaces_d15g0v0_Shanghai + - opcC3DiffPlaces_d30g0v0_Shanghai + - opcC4DiffPlaces_d16g0v0_Shanghai + - opcC3DiffPlaces_d31g0v0_Shanghai + - opcC4DiffPlaces_d2g0v0_Shanghai + - opcC3DiffPlaces_d32g0v0_Shanghai + - opcC3DiffPlaces_d33g0v0_Shanghai + - opcC3DiffPlaces_d34g0v0_Shanghai + - opcC4DiffPlaces_d17g0v0_Shanghai + - opcC4DiffPlaces_d18g0v0_Shanghai + - opcC4DiffPlaces_d19g0v0_Shanghai + - opcC4DiffPlaces_d3g0v0_Shanghai + - opcC4DiffPlaces_d21g0v0_Shanghai + - opcC5DiffPlaces_d0g0v0_Shanghai + - opcC4DiffPlaces_d4g0v0_Shanghai + - opcC4DiffPlaces_d20g0v0_Shanghai + - opcC4DiffPlaces_d22g0v0_Shanghai + - opcC4DiffPlaces_d5g0v0_Shanghai + - opcC4DiffPlaces_d23g0v0_Shanghai + - opcC4DiffPlaces_d6g0v0_Shanghai + - opcC4DiffPlaces_d7g0v0_Shanghai + - opcC4DiffPlaces_d8g0v0_Shanghai + - opcC4DiffPlaces_d24g0v0_Shanghai + - opcC4DiffPlaces_d9g0v0_Shanghai + - opcC4DiffPlaces_d25g0v0_Shanghai + - opcC5DiffPlaces_d1g0v0_Shanghai + - opcC5DiffPlaces_d10g0v0_Shanghai + - opcC5DiffPlaces_d11g0v0_Shanghai + - opcC4DiffPlaces_d26g0v0_Shanghai + - opcC5DiffPlaces_d12g0v0_Shanghai + - opcC4DiffPlaces_d27g0v0_Shanghai + - opcC5DiffPlaces_d13g0v0_Shanghai + - opcC4DiffPlaces_d28g0v0_Shanghai + - opcC5DiffPlaces_d14g0v0_Shanghai + - opcC4DiffPlaces_d29g0v0_Shanghai + - opcC5DiffPlaces_d15g0v0_Shanghai + - opcC5DiffPlaces_d16g0v0_Shanghai + - opcC4DiffPlaces_d31g0v0_Shanghai + - opcC4DiffPlaces_d30g0v0_Shanghai + - opcC5DiffPlaces_d2g0v0_Shanghai + - opcC4DiffPlaces_d32g0v0_Shanghai + - opcC4DiffPlaces_d33g0v0_Shanghai + - opcC4DiffPlaces_d34g0v0_Shanghai + - opcC5DiffPlaces_d17g0v0_Shanghai + - opcC5DiffPlaces_d18g0v0_Shanghai + - opcC5DiffPlaces_d3g0v0_Shanghai + - opcC5DiffPlaces_d19g0v0_Shanghai + - opcC5DiffPlaces_d21g0v0_Shanghai + - opcC6DiffPlaces_d0g0v0_Shanghai + - opcC5DiffPlaces_d20g0v0_Shanghai + - opcC5DiffPlaces_d4g0v0_Shanghai + - opcC5DiffPlaces_d22g0v0_Shanghai + - opcC5DiffPlaces_d5g0v0_Shanghai + - opcC5DiffPlaces_d23g0v0_Shanghai + - opcC5DiffPlaces_d6g0v0_Shanghai + - opcC5DiffPlaces_d7g0v0_Shanghai + - opcC5DiffPlaces_d8g0v0_Shanghai + - opcC5DiffPlaces_d24g0v0_Shanghai + - opcC5DiffPlaces_d9g0v0_Shanghai + - opcC5DiffPlaces_d25g0v0_Shanghai + - opcC6DiffPlaces_d1g0v0_Shanghai + - opcC6DiffPlaces_d10g0v0_Shanghai + - opcC6DiffPlaces_d11g0v0_Shanghai + - opcC5DiffPlaces_d26g0v0_Shanghai + - opcC6DiffPlaces_d12g0v0_Shanghai + - opcC6DiffPlaces_d13g0v0_Shanghai + - opcC5DiffPlaces_d27g0v0_Shanghai + - opcC5DiffPlaces_d28g0v0_Shanghai + - opcC6DiffPlaces_d14g0v0_Shanghai + - opcC5DiffPlaces_d29g0v0_Shanghai + - opcC6DiffPlaces_d15g0v0_Shanghai + - opcC5DiffPlaces_d31g0v0_Shanghai + - opcC5DiffPlaces_d30g0v0_Shanghai + - opcC6DiffPlaces_d16g0v0_Shanghai + - opcC5DiffPlaces_d32g0v0_Shanghai + - opcC6DiffPlaces_d2g0v0_Shanghai + - opcC5DiffPlaces_d33g0v0_Shanghai + - opcC5DiffPlaces_d34g0v0_Shanghai + - opcC6DiffPlaces_d17g0v0_Shanghai + - opcC6DiffPlaces_d18g0v0_Shanghai + - opcC6DiffPlaces_d19g0v0_Shanghai + - opcC6DiffPlaces_d3g0v0_Shanghai + - opcC6DiffPlaces_d21g0v0_Shanghai + - opcC7DiffPlaces_d0g0v0_Shanghai + - opcC6DiffPlaces_d20g0v0_Shanghai + - opcC6DiffPlaces_d4g0v0_Shanghai + - opcC6DiffPlaces_d22g0v0_Shanghai + - opcC6DiffPlaces_d5g0v0_Shanghai + - opcC6DiffPlaces_d23g0v0_Shanghai + - opcC6DiffPlaces_d6g0v0_Shanghai + - opcC6DiffPlaces_d7g0v0_Shanghai + - opcC6DiffPlaces_d8g0v0_Shanghai + - opcC6DiffPlaces_d9g0v0_Shanghai + - opcC6DiffPlaces_d24g0v0_Shanghai + - opcC6DiffPlaces_d25g0v0_Shanghai + - opcC7DiffPlaces_d1g0v0_Shanghai + - opcC7DiffPlaces_d10g0v0_Shanghai + - opcC6DiffPlaces_d26g0v0_Shanghai + - opcC7DiffPlaces_d11g0v0_Shanghai + - opcC7DiffPlaces_d12g0v0_Shanghai + - opcC6DiffPlaces_d27g0v0_Shanghai + - opcC7DiffPlaces_d13g0v0_Shanghai + - opcC6DiffPlaces_d28g0v0_Shanghai + - opcC7DiffPlaces_d14g0v0_Shanghai + - opcC7DiffPlaces_d15g0v0_Shanghai + - opcC6DiffPlaces_d29g0v0_Shanghai + - opcC6DiffPlaces_d30g0v0_Shanghai + - opcC7DiffPlaces_d16g0v0_Shanghai + - opcC6DiffPlaces_d31g0v0_Shanghai + - opcC7DiffPlaces_d2g0v0_Shanghai + - opcC6DiffPlaces_d32g0v0_Shanghai + - opcC6DiffPlaces_d33g0v0_Shanghai + - opcC6DiffPlaces_d34g0v0_Shanghai + - opcC7DiffPlaces_d17g0v0_Shanghai + - opcC7DiffPlaces_d18g0v0_Shanghai + - opcC7DiffPlaces_d19g0v0_Shanghai + - opcC7DiffPlaces_d3g0v0_Shanghai + - opcC7DiffPlaces_d21g0v0_Shanghai + - opcC8DiffPlaces_d0g0v0_Shanghai + - opcC7DiffPlaces_d20g0v0_Shanghai + - opcC7DiffPlaces_d4g0v0_Shanghai + - opcC7DiffPlaces_d22g0v0_Shanghai + - opcC7DiffPlaces_d23g0v0_Shanghai + - opcC7DiffPlaces_d5g0v0_Shanghai + - opcC7DiffPlaces_d6g0v0_Shanghai + - opcC7DiffPlaces_d7g0v0_Shanghai + - opcC7DiffPlaces_d8g0v0_Shanghai + - opcC7DiffPlaces_d9g0v0_Shanghai + - opcC7DiffPlaces_d24g0v0_Shanghai + - opcC7DiffPlaces_d25g0v0_Shanghai + - opcC8DiffPlaces_d1g0v0_Shanghai + - opcC8DiffPlaces_d10g0v0_Shanghai + - opcC7DiffPlaces_d26g0v0_Shanghai + - opcC8DiffPlaces_d11g0v0_Shanghai + - opcC8DiffPlaces_d12g0v0_Shanghai + - opcC7DiffPlaces_d27g0v0_Shanghai + - opcC8DiffPlaces_d13g0v0_Shanghai + - opcC7DiffPlaces_d28g0v0_Shanghai + - opcC8DiffPlaces_d14g0v0_Shanghai + - opcC7DiffPlaces_d29g0v0_Shanghai + - opcC8DiffPlaces_d15g0v0_Shanghai + - opcC8DiffPlaces_d16g0v0_Shanghai + - opcC7DiffPlaces_d31g0v0_Shanghai + - opcC7DiffPlaces_d30g0v0_Shanghai + - opcC8DiffPlaces_d2g0v0_Shanghai + - opcC7DiffPlaces_d32g0v0_Shanghai + - opcC7DiffPlaces_d33g0v0_Shanghai + - opcC7DiffPlaces_d34g0v0_Shanghai + - opcC8DiffPlaces_d17g0v0_Shanghai + - opcC8DiffPlaces_d18g0v0_Shanghai + - opcC8DiffPlaces_d19g0v0_Shanghai + - opcC8DiffPlaces_d3g0v0_Shanghai + - opcC8DiffPlaces_d21g0v0_Shanghai + - opcC8DiffPlaces_d4g0v0_Shanghai + - opcC9DiffPlaces_d0g0v0_Shanghai + - opcC8DiffPlaces_d20g0v0_Shanghai + - opcC8DiffPlaces_d22g0v0_Shanghai + - opcC8DiffPlaces_d5g0v0_Shanghai + - opcC8DiffPlaces_d23g0v0_Shanghai + - opcC8DiffPlaces_d6g0v0_Shanghai + - opcC8DiffPlaces_d7g0v0_Shanghai + - opcC8DiffPlaces_d8g0v0_Shanghai + - opcC8DiffPlaces_d24g0v0_Shanghai + - opcC8DiffPlaces_d9g0v0_Shanghai + - opcC8DiffPlaces_d25g0v0_Shanghai + - opcC9DiffPlaces_d1g0v0_Shanghai + - opcC9DiffPlaces_d10g0v0_Shanghai + - opcC9DiffPlaces_d11g0v0_Shanghai + - opcC8DiffPlaces_d26g0v0_Shanghai + - opcC9DiffPlaces_d12g0v0_Shanghai + - opcC8DiffPlaces_d27g0v0_Shanghai + - opcC9DiffPlaces_d13g0v0_Shanghai + - opcC8DiffPlaces_d28g0v0_Shanghai + - opcC9DiffPlaces_d14g0v0_Shanghai + - opcC9DiffPlaces_d15g0v0_Shanghai + - opcC8DiffPlaces_d29g0v0_Shanghai + - opcC9DiffPlaces_d16g0v0_Shanghai + - opcC8DiffPlaces_d30g0v0_Shanghai + - opcC8DiffPlaces_d31g0v0_Shanghai + - opcC8DiffPlaces_d32g0v0_Shanghai + - opcC9DiffPlaces_d2g0v0_Shanghai + - opcC8DiffPlaces_d33g0v0_Shanghai + - opcC8DiffPlaces_d34g0v0_Shanghai + - opcC9DiffPlaces_d17g0v0_Shanghai + - opcC9DiffPlaces_d18g0v0_Shanghai + - opcC9DiffPlaces_d3g0v0_Shanghai + - opcC9DiffPlaces_d19g0v0_Shanghai + - opcC9DiffPlaces_d21g0v0_Shanghai + - opcCADiffPlaces_d0g0v0_Shanghai + - opcC9DiffPlaces_d4g0v0_Shanghai + - opcC9DiffPlaces_d20g0v0_Shanghai + - opcC9DiffPlaces_d22g0v0_Shanghai + - opcC9DiffPlaces_d5g0v0_Shanghai + - opcC9DiffPlaces_d23g0v0_Shanghai + - opcC9DiffPlaces_d6g0v0_Shanghai + - opcC9DiffPlaces_d7g0v0_Shanghai + - opcC9DiffPlaces_d8g0v0_Shanghai + - opcC9DiffPlaces_d24g0v0_Shanghai + - opcC9DiffPlaces_d9g0v0_Shanghai + - opcC9DiffPlaces_d25g0v0_Shanghai + - opcCADiffPlaces_d1g0v0_Shanghai + - opcCADiffPlaces_d10g0v0_Shanghai + - opcC9DiffPlaces_d26g0v0_Shanghai + - opcCADiffPlaces_d11g0v0_Shanghai + - opcCADiffPlaces_d12g0v0_Shanghai + - opcC9DiffPlaces_d27g0v0_Shanghai + - opcCADiffPlaces_d13g0v0_Shanghai + - opcC9DiffPlaces_d28g0v0_Shanghai + - opcCADiffPlaces_d14g0v0_Shanghai + - opcC9DiffPlaces_d29g0v0_Shanghai + - opcCADiffPlaces_d15g0v0_Shanghai + - opcCADiffPlaces_d16g0v0_Shanghai + - opcC9DiffPlaces_d30g0v0_Shanghai + - opcC9DiffPlaces_d31g0v0_Shanghai + - opcCADiffPlaces_d2g0v0_Shanghai + - opcC9DiffPlaces_d32g0v0_Shanghai + - opcC9DiffPlaces_d33g0v0_Shanghai + - opcC9DiffPlaces_d34g0v0_Shanghai + - opcCADiffPlaces_d17g0v0_Shanghai + - opcCADiffPlaces_d18g0v0_Shanghai + - opcCADiffPlaces_d19g0v0_Shanghai + - opcCADiffPlaces_d3g0v0_Shanghai + - opcCADiffPlaces_d21g0v0_Shanghai + - opcCBDiffPlaces_d0g0v0_Shanghai + - opcCADiffPlaces_d20g0v0_Shanghai + - opcCADiffPlaces_d22g0v0_Shanghai + - opcCADiffPlaces_d4g0v0_Shanghai + - opcCADiffPlaces_d23g0v0_Shanghai + - opcCADiffPlaces_d5g0v0_Shanghai + - opcCADiffPlaces_d6g0v0_Shanghai + - opcCADiffPlaces_d7g0v0_Shanghai + - opcCADiffPlaces_d8g0v0_Shanghai + - opcCADiffPlaces_d24g0v0_Shanghai + - opcCADiffPlaces_d9g0v0_Shanghai + - opcCADiffPlaces_d25g0v0_Shanghai + - opcCBDiffPlaces_d1g0v0_Shanghai + - opcCBDiffPlaces_d10g0v0_Shanghai + - opcCBDiffPlaces_d11g0v0_Shanghai + - opcCADiffPlaces_d26g0v0_Shanghai + - opcCBDiffPlaces_d12g0v0_Shanghai + - opcCADiffPlaces_d27g0v0_Shanghai + - opcCBDiffPlaces_d13g0v0_Shanghai + - opcCADiffPlaces_d28g0v0_Shanghai + - opcCBDiffPlaces_d14g0v0_Shanghai + - opcCADiffPlaces_d29g0v0_Shanghai + - opcCBDiffPlaces_d15g0v0_Shanghai + - opcCADiffPlaces_d30g0v0_Shanghai + - opcCADiffPlaces_d31g0v0_Shanghai + - opcCBDiffPlaces_d16g0v0_Shanghai + - opcCBDiffPlaces_d2g0v0_Shanghai + - opcCADiffPlaces_d32g0v0_Shanghai + - opcCADiffPlaces_d34g0v0_Shanghai + - opcCADiffPlaces_d33g0v0_Shanghai + - opcCBDiffPlaces_d17g0v0_Shanghai + - opcCBDiffPlaces_d18g0v0_Shanghai + - opcCBDiffPlaces_d3g0v0_Shanghai + - opcCBDiffPlaces_d19g0v0_Shanghai + - opcCBDiffPlaces_d21g0v0_Shanghai + - opcCCDiffPlaces_d0g0v0_Shanghai + - opcCBDiffPlaces_d4g0v0_Shanghai + - opcCBDiffPlaces_d20g0v0_Shanghai + - opcCBDiffPlaces_d22g0v0_Shanghai + - opcCBDiffPlaces_d5g0v0_Shanghai + - opcCBDiffPlaces_d23g0v0_Shanghai + - opcCBDiffPlaces_d6g0v0_Shanghai + - opcCBDiffPlaces_d7g0v0_Shanghai + - opcCBDiffPlaces_d8g0v0_Shanghai + - opcCBDiffPlaces_d9g0v0_Shanghai + - opcCBDiffPlaces_d24g0v0_Shanghai + - opcCCDiffPlaces_d1g0v0_Shanghai + - opcCBDiffPlaces_d25g0v0_Shanghai + - opcCCDiffPlaces_d10g0v0_Shanghai + - opcCCDiffPlaces_d11g0v0_Shanghai + - opcCBDiffPlaces_d26g0v0_Shanghai + - opcCCDiffPlaces_d12g0v0_Shanghai + - opcCBDiffPlaces_d27g0v0_Shanghai + - opcCCDiffPlaces_d13g0v0_Shanghai + - opcCBDiffPlaces_d28g0v0_Shanghai + - opcCCDiffPlaces_d14g0v0_Shanghai + - opcCBDiffPlaces_d29g0v0_Shanghai + - opcCCDiffPlaces_d15g0v0_Shanghai + - opcCCDiffPlaces_d16g0v0_Shanghai + - opcCBDiffPlaces_d30g0v0_Shanghai + - opcCBDiffPlaces_d31g0v0_Shanghai + - opcCCDiffPlaces_d2g0v0_Shanghai + - opcCBDiffPlaces_d32g0v0_Shanghai + - opcCBDiffPlaces_d33g0v0_Shanghai + - opcCBDiffPlaces_d34g0v0_Shanghai + - opcCCDiffPlaces_d17g0v0_Shanghai + - opcCCDiffPlaces_d18g0v0_Shanghai + - opcCCDiffPlaces_d19g0v0_Shanghai + - opcCCDiffPlaces_d3g0v0_Shanghai + - opcCCDiffPlaces_d21g0v0_Shanghai + - opcCDDiffPlaces_d0g0v0_Shanghai + - opcCCDiffPlaces_d4g0v0_Shanghai + - opcCCDiffPlaces_d20g0v0_Shanghai + - opcCCDiffPlaces_d22g0v0_Shanghai + - opcCCDiffPlaces_d5g0v0_Shanghai + - opcCCDiffPlaces_d23g0v0_Shanghai + - opcCCDiffPlaces_d6g0v0_Shanghai + - opcCCDiffPlaces_d7g0v0_Shanghai + - opcCCDiffPlaces_d8g0v0_Shanghai + - opcCCDiffPlaces_d24g0v0_Shanghai + - opcCCDiffPlaces_d9g0v0_Shanghai + - opcCDDiffPlaces_d1g0v0_Shanghai + - opcCCDiffPlaces_d25g0v0_Shanghai + - opcCDDiffPlaces_d10g0v0_Shanghai + - opcCDDiffPlaces_d11g0v0_Shanghai + - opcCCDiffPlaces_d26g0v0_Shanghai + - opcCDDiffPlaces_d12g0v0_Shanghai + - opcCCDiffPlaces_d27g0v0_Shanghai + - opcCDDiffPlaces_d13g0v0_Shanghai + - opcCCDiffPlaces_d28g0v0_Shanghai + - opcCDDiffPlaces_d14g0v0_Shanghai + - opcCCDiffPlaces_d29g0v0_Shanghai + - opcCDDiffPlaces_d15g0v0_Shanghai + - opcCDDiffPlaces_d16g0v0_Shanghai + - opcCCDiffPlaces_d30g0v0_Shanghai + - opcCDDiffPlaces_d2g0v0_Shanghai + - opcCCDiffPlaces_d31g0v0_Shanghai + - opcCCDiffPlaces_d32g0v0_Shanghai + - opcCCDiffPlaces_d33g0v0_Shanghai + - opcCCDiffPlaces_d34g0v0_Shanghai + - opcCDDiffPlaces_d17g0v0_Shanghai + - opcCDDiffPlaces_d18g0v0_Shanghai + - opcCDDiffPlaces_d19g0v0_Shanghai + - opcCDDiffPlaces_d3g0v0_Shanghai + - opcCDDiffPlaces_d21g0v0_Shanghai + - opcCEDiffPlaces_d0g0v0_Shanghai + - opcCDDiffPlaces_d4g0v0_Shanghai + - opcCDDiffPlaces_d20g0v0_Shanghai + - opcCDDiffPlaces_d22g0v0_Shanghai + - opcCDDiffPlaces_d23g0v0_Shanghai + - opcCDDiffPlaces_d5g0v0_Shanghai + - opcCDDiffPlaces_d6g0v0_Shanghai + - opcCDDiffPlaces_d7g0v0_Shanghai + - opcCDDiffPlaces_d8g0v0_Shanghai + - opcCDDiffPlaces_d24g0v0_Shanghai + - opcCDDiffPlaces_d9g0v0_Shanghai + - opcCDDiffPlaces_d25g0v0_Shanghai + - opcCEDiffPlaces_d1g0v0_Shanghai + - opcCEDiffPlaces_d10g0v0_Shanghai + - opcCDDiffPlaces_d26g0v0_Shanghai + - opcCEDiffPlaces_d11g0v0_Shanghai + - opcCEDiffPlaces_d12g0v0_Shanghai + - opcCDDiffPlaces_d27g0v0_Shanghai + - opcCEDiffPlaces_d13g0v0_Shanghai + - opcCDDiffPlaces_d28g0v0_Shanghai + - opcCEDiffPlaces_d14g0v0_Shanghai + - opcCDDiffPlaces_d29g0v0_Shanghai + - opcCEDiffPlaces_d15g0v0_Shanghai + - opcCDDiffPlaces_d30g0v0_Shanghai + - opcCEDiffPlaces_d16g0v0_Shanghai + - opcCDDiffPlaces_d31g0v0_Shanghai + - opcCEDiffPlaces_d2g0v0_Shanghai + - opcCDDiffPlaces_d32g0v0_Shanghai + - opcCDDiffPlaces_d33g0v0_Shanghai + - opcCDDiffPlaces_d34g0v0_Shanghai + - opcCEDiffPlaces_d17g0v0_Shanghai + - opcCEDiffPlaces_d18g0v0_Shanghai + - opcCEDiffPlaces_d19g0v0_Shanghai + - opcCEDiffPlaces_d3g0v0_Shanghai + - opcCEDiffPlaces_d21g0v0_Shanghai + - opcCFDiffPlaces_d0g0v0_Shanghai + - opcCEDiffPlaces_d4g0v0_Shanghai + - opcCEDiffPlaces_d20g0v0_Shanghai + - opcCEDiffPlaces_d22g0v0_Shanghai + - opcCEDiffPlaces_d5g0v0_Shanghai + - opcCEDiffPlaces_d23g0v0_Shanghai + - opcCEDiffPlaces_d6g0v0_Shanghai + - opcCEDiffPlaces_d7g0v0_Shanghai + - opcCEDiffPlaces_d8g0v0_Shanghai + - opcCEDiffPlaces_d24g0v0_Shanghai + - opcCEDiffPlaces_d9g0v0_Shanghai + - opcCEDiffPlaces_d25g0v0_Shanghai + - opcCFDiffPlaces_d1g0v0_Shanghai + - opcCFDiffPlaces_d10g0v0_Shanghai + - opcCEDiffPlaces_d26g0v0_Shanghai + - opcCFDiffPlaces_d11g0v0_Shanghai + - opcCFDiffPlaces_d12g0v0_Shanghai + - opcCEDiffPlaces_d27g0v0_Shanghai + - opcCFDiffPlaces_d13g0v0_Shanghai + - opcCEDiffPlaces_d28g0v0_Shanghai + - opcCFDiffPlaces_d14g0v0_Shanghai + - opcCEDiffPlaces_d29g0v0_Shanghai + - opcCFDiffPlaces_d15g0v0_Shanghai + - opcCFDiffPlaces_d16g0v0_Shanghai + - opcCEDiffPlaces_d30g0v0_Shanghai + - opcCEDiffPlaces_d31g0v0_Shanghai + - opcCFDiffPlaces_d2g0v0_Shanghai + - opcCEDiffPlaces_d32g0v0_Shanghai + - opcCEDiffPlaces_d33g0v0_Shanghai + - opcCEDiffPlaces_d34g0v0_Shanghai + - opcCFDiffPlaces_d17g0v0_Shanghai + - opcCFDiffPlaces_d18g0v0_Shanghai + - opcCFDiffPlaces_d19g0v0_Shanghai + - opcCFDiffPlaces_d3g0v0_Shanghai + - opcD0DiffPlaces_d0g0v0_Shanghai + - opcCFDiffPlaces_d21g0v0_Shanghai + - opcCFDiffPlaces_d4g0v0_Shanghai + - opcCFDiffPlaces_d20g0v0_Shanghai + - opcCFDiffPlaces_d22g0v0_Shanghai + - opcCFDiffPlaces_d5g0v0_Shanghai + - opcCFDiffPlaces_d23g0v0_Shanghai + - opcCFDiffPlaces_d6g0v0_Shanghai + - opcCFDiffPlaces_d7g0v0_Shanghai + - opcCFDiffPlaces_d8g0v0_Shanghai + - opcCFDiffPlaces_d24g0v0_Shanghai + - opcCFDiffPlaces_d9g0v0_Shanghai + - opcCFDiffPlaces_d25g0v0_Shanghai + - opcD0DiffPlaces_d1g0v0_Shanghai + - opcD0DiffPlaces_d10g0v0_Shanghai + - opcD0DiffPlaces_d11g0v0_Shanghai + - opcCFDiffPlaces_d26g0v0_Shanghai + - opcD0DiffPlaces_d12g0v0_Shanghai + - opcCFDiffPlaces_d27g0v0_Shanghai + - opcD0DiffPlaces_d13g0v0_Shanghai + - opcCFDiffPlaces_d28g0v0_Shanghai + - opcD0DiffPlaces_d14g0v0_Shanghai + - opcCFDiffPlaces_d29g0v0_Shanghai + - opcD0DiffPlaces_d15g0v0_Shanghai + - opcD0DiffPlaces_d16g0v0_Shanghai + - opcCFDiffPlaces_d30g0v0_Shanghai + - opcCFDiffPlaces_d31g0v0_Shanghai + - opcD0DiffPlaces_d2g0v0_Shanghai + - opcCFDiffPlaces_d32g0v0_Shanghai + - opcCFDiffPlaces_d33g0v0_Shanghai + - opcCFDiffPlaces_d34g0v0_Shanghai + - opcD0DiffPlaces_d17g0v0_Shanghai + - opcD0DiffPlaces_d18g0v0_Shanghai + - opcD0DiffPlaces_d19g0v0_Shanghai + - opcD0DiffPlaces_d3g0v0_Shanghai + - opcD1DiffPlaces_d0g0v0_Shanghai + - opcD0DiffPlaces_d21g0v0_Shanghai + - opcD0DiffPlaces_d4g0v0_Shanghai + - opcD0DiffPlaces_d20g0v0_Shanghai + - opcD0DiffPlaces_d22g0v0_Shanghai + - opcD0DiffPlaces_d5g0v0_Shanghai + - opcD0DiffPlaces_d23g0v0_Shanghai + - opcD0DiffPlaces_d6g0v0_Shanghai + - opcD0DiffPlaces_d7g0v0_Shanghai + - opcD0DiffPlaces_d8g0v0_Shanghai + - opcD0DiffPlaces_d9g0v0_Shanghai + - opcD0DiffPlaces_d24g0v0_Shanghai + - opcD1DiffPlaces_d1g0v0_Shanghai + - opcD0DiffPlaces_d25g0v0_Shanghai + - opcD1DiffPlaces_d10g0v0_Shanghai + - opcD1DiffPlaces_d11g0v0_Shanghai + - opcD0DiffPlaces_d26g0v0_Shanghai + - opcD1DiffPlaces_d12g0v0_Shanghai + - opcD0DiffPlaces_d27g0v0_Shanghai + - opcD1DiffPlaces_d13g0v0_Shanghai + - opcD0DiffPlaces_d28g0v0_Shanghai + - opcD1DiffPlaces_d14g0v0_Shanghai + - opcD0DiffPlaces_d29g0v0_Shanghai + - opcD1DiffPlaces_d15g0v0_Shanghai + - opcD0DiffPlaces_d30g0v0_Shanghai + - opcD1DiffPlaces_d16g0v0_Shanghai + - opcD0DiffPlaces_d31g0v0_Shanghai + - opcD1DiffPlaces_d2g0v0_Shanghai + - opcD0DiffPlaces_d32g0v0_Shanghai + - opcD0DiffPlaces_d33g0v0_Shanghai + - opcD0DiffPlaces_d34g0v0_Shanghai + - opcD1DiffPlaces_d17g0v0_Shanghai + - opcD1DiffPlaces_d18g0v0_Shanghai + - opcD1DiffPlaces_d19g0v0_Shanghai + - opcD1DiffPlaces_d3g0v0_Shanghai + - opcD1DiffPlaces_d21g0v0_Shanghai + - opcD2DiffPlaces_d0g0v0_Shanghai + - opcD1DiffPlaces_d4g0v0_Shanghai + - opcD1DiffPlaces_d20g0v0_Shanghai + - opcD1DiffPlaces_d22g0v0_Shanghai + - opcD1DiffPlaces_d5g0v0_Shanghai + - opcD1DiffPlaces_d23g0v0_Shanghai + - opcD1DiffPlaces_d6g0v0_Shanghai + - opcD1DiffPlaces_d7g0v0_Shanghai + - opcD1DiffPlaces_d8g0v0_Shanghai + - opcD1DiffPlaces_d9g0v0_Shanghai + - opcD1DiffPlaces_d24g0v0_Shanghai + - opcD1DiffPlaces_d25g0v0_Shanghai + - opcD2DiffPlaces_d1g0v0_Shanghai + - opcD2DiffPlaces_d10g0v0_Shanghai + - opcD1DiffPlaces_d26g0v0_Shanghai + - opcD2DiffPlaces_d11g0v0_Shanghai + - opcD2DiffPlaces_d12g0v0_Shanghai + - opcD1DiffPlaces_d27g0v0_Shanghai + - opcD2DiffPlaces_d13g0v0_Shanghai + - opcD1DiffPlaces_d28g0v0_Shanghai + - opcD2DiffPlaces_d14g0v0_Shanghai + - opcD1DiffPlaces_d29g0v0_Shanghai + - opcD2DiffPlaces_d15g0v0_Shanghai + - opcD1DiffPlaces_d30g0v0_Shanghai + - opcD2DiffPlaces_d16g0v0_Shanghai + - opcD1DiffPlaces_d31g0v0_Shanghai + - opcD2DiffPlaces_d2g0v0_Shanghai + - opcD1DiffPlaces_d32g0v0_Shanghai + - opcD1DiffPlaces_d33g0v0_Shanghai + - opcD1DiffPlaces_d34g0v0_Shanghai + - opcD2DiffPlaces_d17g0v0_Shanghai + - opcD2DiffPlaces_d18g0v0_Shanghai + - opcD2DiffPlaces_d19g0v0_Shanghai + - opcD2DiffPlaces_d3g0v0_Shanghai + - opcD2DiffPlaces_d21g0v0_Shanghai + - opcD3DiffPlaces_d0g0v0_Shanghai + - opcD2DiffPlaces_d4g0v0_Shanghai + - opcD2DiffPlaces_d20g0v0_Shanghai + - opcD2DiffPlaces_d22g0v0_Shanghai + - opcD2DiffPlaces_d23g0v0_Shanghai + - opcD2DiffPlaces_d5g0v0_Shanghai + - opcD2DiffPlaces_d6g0v0_Shanghai + - opcD2DiffPlaces_d7g0v0_Shanghai + - opcD2DiffPlaces_d8g0v0_Shanghai + - opcD2DiffPlaces_d24g0v0_Shanghai + - opcD2DiffPlaces_d9g0v0_Shanghai + - opcD2DiffPlaces_d25g0v0_Shanghai + - opcD3DiffPlaces_d1g0v0_Shanghai + - opcD3DiffPlaces_d10g0v0_Shanghai + - opcD3DiffPlaces_d11g0v0_Shanghai + - opcD2DiffPlaces_d26g0v0_Shanghai + - opcD3DiffPlaces_d12g0v0_Shanghai + - opcD2DiffPlaces_d27g0v0_Shanghai + - opcD3DiffPlaces_d13g0v0_Shanghai + - opcD2DiffPlaces_d28g0v0_Shanghai + - opcD3DiffPlaces_d14g0v0_Shanghai + - opcD3DiffPlaces_d15g0v0_Shanghai + - opcD2DiffPlaces_d29g0v0_Shanghai + - opcD3DiffPlaces_d16g0v0_Shanghai + - opcD2DiffPlaces_d30g0v0_Shanghai + - opcD2DiffPlaces_d31g0v0_Shanghai + - opcD3DiffPlaces_d2g0v0_Shanghai + - opcD2DiffPlaces_d32g0v0_Shanghai + - opcD2DiffPlaces_d33g0v0_Shanghai + - opcD2DiffPlaces_d34g0v0_Shanghai + - opcD3DiffPlaces_d17g0v0_Shanghai + - opcD3DiffPlaces_d18g0v0_Shanghai + - opcD3DiffPlaces_d19g0v0_Shanghai + - opcD3DiffPlaces_d3g0v0_Shanghai + - opcD3DiffPlaces_d21g0v0_Shanghai + - opcD4DiffPlaces_d0g0v0_Shanghai + - opcD3DiffPlaces_d20g0v0_Shanghai + - opcD3DiffPlaces_d4g0v0_Shanghai + - opcD3DiffPlaces_d22g0v0_Shanghai + - opcD3DiffPlaces_d23g0v0_Shanghai + - opcD3DiffPlaces_d5g0v0_Shanghai + - opcD3DiffPlaces_d6g0v0_Shanghai + - opcD3DiffPlaces_d7g0v0_Shanghai + - opcD3DiffPlaces_d8g0v0_Shanghai + - opcD3DiffPlaces_d24g0v0_Shanghai + - opcD3DiffPlaces_d9g0v0_Shanghai + - opcD3DiffPlaces_d25g0v0_Shanghai + - opcD4DiffPlaces_d1g0v0_Shanghai + - opcD4DiffPlaces_d10g0v0_Shanghai + - opcD4DiffPlaces_d11g0v0_Shanghai + - opcD3DiffPlaces_d26g0v0_Shanghai + - opcD4DiffPlaces_d12g0v0_Shanghai + - opcD3DiffPlaces_d27g0v0_Shanghai + - opcD4DiffPlaces_d13g0v0_Shanghai + - opcD3DiffPlaces_d28g0v0_Shanghai + - opcD4DiffPlaces_d14g0v0_Shanghai + - opcD4DiffPlaces_d15g0v0_Shanghai + - opcD3DiffPlaces_d29g0v0_Shanghai + - opcD3DiffPlaces_d30g0v0_Shanghai + - opcD4DiffPlaces_d16g0v0_Shanghai + - opcD3DiffPlaces_d31g0v0_Shanghai + - opcD4DiffPlaces_d2g0v0_Shanghai + - opcD3DiffPlaces_d32g0v0_Shanghai + - opcD3DiffPlaces_d33g0v0_Shanghai + - opcD3DiffPlaces_d34g0v0_Shanghai + - opcD4DiffPlaces_d17g0v0_Shanghai + - opcD4DiffPlaces_d18g0v0_Shanghai + - opcD4DiffPlaces_d19g0v0_Shanghai + - opcD4DiffPlaces_d3g0v0_Shanghai + - opcD5DiffPlaces_d0g0v0_Shanghai + - opcD4DiffPlaces_d21g0v0_Shanghai + - opcD4DiffPlaces_d4g0v0_Shanghai + - opcD4DiffPlaces_d20g0v0_Shanghai + - opcD4DiffPlaces_d22g0v0_Shanghai + - opcD4DiffPlaces_d5g0v0_Shanghai + - opcD4DiffPlaces_d23g0v0_Shanghai + - opcD4DiffPlaces_d6g0v0_Shanghai + - opcD4DiffPlaces_d7g0v0_Shanghai + - opcD4DiffPlaces_d8g0v0_Shanghai + - opcD4DiffPlaces_d9g0v0_Shanghai + - opcD4DiffPlaces_d24g0v0_Shanghai + - opcD5DiffPlaces_d1g0v0_Shanghai + - opcD4DiffPlaces_d25g0v0_Shanghai + - opcD5DiffPlaces_d10g0v0_Shanghai + - opcD5DiffPlaces_d11g0v0_Shanghai + - opcD4DiffPlaces_d26g0v0_Shanghai + - opcD5DiffPlaces_d12g0v0_Shanghai + - opcD4DiffPlaces_d27g0v0_Shanghai + - opcD5DiffPlaces_d13g0v0_Shanghai + - opcD4DiffPlaces_d28g0v0_Shanghai + - opcD5DiffPlaces_d14g0v0_Shanghai + - opcD4DiffPlaces_d29g0v0_Shanghai + - opcD5DiffPlaces_d15g0v0_Shanghai + - opcD4DiffPlaces_d30g0v0_Shanghai + - opcD5DiffPlaces_d16g0v0_Shanghai + - opcD4DiffPlaces_d31g0v0_Shanghai + - opcD5DiffPlaces_d2g0v0_Shanghai + - opcD4DiffPlaces_d32g0v0_Shanghai + - opcD4DiffPlaces_d33g0v0_Shanghai + - opcD4DiffPlaces_d34g0v0_Shanghai + - opcD5DiffPlaces_d17g0v0_Shanghai + - opcD5DiffPlaces_d18g0v0_Shanghai + - opcD5DiffPlaces_d19g0v0_Shanghai + - opcD5DiffPlaces_d3g0v0_Shanghai + - opcD6DiffPlaces_d0g0v0_Shanghai + - opcD5DiffPlaces_d21g0v0_Shanghai + - opcD5DiffPlaces_d4g0v0_Shanghai + - opcD5DiffPlaces_d20g0v0_Shanghai + - opcD5DiffPlaces_d22g0v0_Shanghai + - opcD5DiffPlaces_d23g0v0_Shanghai + - opcD5DiffPlaces_d5g0v0_Shanghai + - opcD5DiffPlaces_d6g0v0_Shanghai + - opcD5DiffPlaces_d7g0v0_Shanghai + - opcD5DiffPlaces_d8g0v0_Shanghai + - opcD5DiffPlaces_d24g0v0_Shanghai + - opcD5DiffPlaces_d9g0v0_Shanghai + - opcD5DiffPlaces_d25g0v0_Shanghai + - opcD6DiffPlaces_d1g0v0_Shanghai + - opcD6DiffPlaces_d10g0v0_Shanghai + - opcD6DiffPlaces_d11g0v0_Shanghai + - opcD5DiffPlaces_d26g0v0_Shanghai + - opcD6DiffPlaces_d12g0v0_Shanghai + - opcD5DiffPlaces_d27g0v0_Shanghai + - opcD6DiffPlaces_d13g0v0_Shanghai + - opcD5DiffPlaces_d28g0v0_Shanghai + - opcD6DiffPlaces_d14g0v0_Shanghai + - opcD5DiffPlaces_d29g0v0_Shanghai + - opcD6DiffPlaces_d15g0v0_Shanghai + - opcD6DiffPlaces_d16g0v0_Shanghai + - opcD5DiffPlaces_d30g0v0_Shanghai + - opcD5DiffPlaces_d31g0v0_Shanghai + - opcD6DiffPlaces_d2g0v0_Shanghai + - opcD5DiffPlaces_d32g0v0_Shanghai + - opcD5DiffPlaces_d33g0v0_Shanghai + - opcD5DiffPlaces_d34g0v0_Shanghai + - opcD6DiffPlaces_d17g0v0_Shanghai + - opcD6DiffPlaces_d18g0v0_Shanghai + - opcD6DiffPlaces_d3g0v0_Shanghai + - opcD6DiffPlaces_d19g0v0_Shanghai + - opcD6DiffPlaces_d21g0v0_Shanghai + - opcD6DiffPlaces_d4g0v0_Shanghai + - opcD7DiffPlaces_d0g0v0_Shanghai + - opcD6DiffPlaces_d20g0v0_Shanghai + - opcD6DiffPlaces_d22g0v0_Shanghai + - opcD6DiffPlaces_d5g0v0_Shanghai + - opcD6DiffPlaces_d23g0v0_Shanghai + - opcD6DiffPlaces_d6g0v0_Shanghai + - opcD6DiffPlaces_d7g0v0_Shanghai + - opcD6DiffPlaces_d8g0v0_Shanghai + - opcD6DiffPlaces_d24g0v0_Shanghai + - opcD6DiffPlaces_d9g0v0_Shanghai + - opcD7DiffPlaces_d1g0v0_Shanghai + - opcD6DiffPlaces_d25g0v0_Shanghai + - opcD7DiffPlaces_d10g0v0_Shanghai + - opcD7DiffPlaces_d11g0v0_Shanghai + - opcD6DiffPlaces_d26g0v0_Shanghai + - opcD7DiffPlaces_d12g0v0_Shanghai + - opcD7DiffPlaces_d13g0v0_Shanghai + - opcD6DiffPlaces_d27g0v0_Shanghai + - opcD6DiffPlaces_d28g0v0_Shanghai + - opcD7DiffPlaces_d14g0v0_Shanghai + - opcD7DiffPlaces_d15g0v0_Shanghai + - opcD6DiffPlaces_d29g0v0_Shanghai + - opcD6DiffPlaces_d30g0v0_Shanghai + - opcD6DiffPlaces_d31g0v0_Shanghai + - opcD7DiffPlaces_d16g0v0_Shanghai + - opcD7DiffPlaces_d2g0v0_Shanghai + - opcD6DiffPlaces_d32g0v0_Shanghai + - opcD6DiffPlaces_d33g0v0_Shanghai + - opcD6DiffPlaces_d34g0v0_Shanghai + - opcD7DiffPlaces_d17g0v0_Shanghai + - opcD7DiffPlaces_d18g0v0_Shanghai + - opcD7DiffPlaces_d19g0v0_Shanghai + - opcD7DiffPlaces_d3g0v0_Shanghai + - opcD7DiffPlaces_d21g0v0_Shanghai + - opcD8DiffPlaces_d0g0v0_Shanghai + - opcD7DiffPlaces_d4g0v0_Shanghai + - opcD7DiffPlaces_d20g0v0_Shanghai + - opcD7DiffPlaces_d22g0v0_Shanghai + - opcD7DiffPlaces_d5g0v0_Shanghai + - opcD7DiffPlaces_d23g0v0_Shanghai + - opcD7DiffPlaces_d6g0v0_Shanghai + - opcD7DiffPlaces_d7g0v0_Shanghai + - opcD7DiffPlaces_d8g0v0_Shanghai + - opcD7DiffPlaces_d24g0v0_Shanghai + - opcD7DiffPlaces_d9g0v0_Shanghai + - opcD8DiffPlaces_d1g0v0_Shanghai + - opcD7DiffPlaces_d25g0v0_Shanghai + - opcD8DiffPlaces_d10g0v0_Shanghai + - opcD8DiffPlaces_d11g0v0_Shanghai + - opcD7DiffPlaces_d26g0v0_Shanghai + - opcD8DiffPlaces_d12g0v0_Shanghai + - opcD7DiffPlaces_d27g0v0_Shanghai + - opcD8DiffPlaces_d13g0v0_Shanghai + - opcD7DiffPlaces_d28g0v0_Shanghai + - opcD8DiffPlaces_d14g0v0_Shanghai + - opcD7DiffPlaces_d29g0v0_Shanghai + - opcD8DiffPlaces_d15g0v0_Shanghai + - opcD8DiffPlaces_d16g0v0_Shanghai + - opcD7DiffPlaces_d30g0v0_Shanghai + - opcD7DiffPlaces_d31g0v0_Shanghai + - opcD8DiffPlaces_d2g0v0_Shanghai + - opcD7DiffPlaces_d32g0v0_Shanghai + - opcD7DiffPlaces_d33g0v0_Shanghai + - opcD7DiffPlaces_d34g0v0_Shanghai + - opcD8DiffPlaces_d17g0v0_Shanghai + - opcD8DiffPlaces_d18g0v0_Shanghai + - opcD8DiffPlaces_d19g0v0_Shanghai + - opcD8DiffPlaces_d3g0v0_Shanghai + - opcD8DiffPlaces_d21g0v0_Shanghai + - opcD9DiffPlaces_d0g0v0_Shanghai + - opcD8DiffPlaces_d4g0v0_Shanghai + - opcD8DiffPlaces_d20g0v0_Shanghai + - opcD8DiffPlaces_d22g0v0_Shanghai + - opcD8DiffPlaces_d5g0v0_Shanghai + - opcD8DiffPlaces_d23g0v0_Shanghai + - opcD8DiffPlaces_d6g0v0_Shanghai + - opcD8DiffPlaces_d7g0v0_Shanghai + - opcD8DiffPlaces_d8g0v0_Shanghai + - opcD8DiffPlaces_d24g0v0_Shanghai + - opcD8DiffPlaces_d9g0v0_Shanghai + - opcD8DiffPlaces_d25g0v0_Shanghai + - opcD9DiffPlaces_d1g0v0_Shanghai + - opcD9DiffPlaces_d10g0v0_Shanghai + - opcD8DiffPlaces_d26g0v0_Shanghai + - opcD9DiffPlaces_d11g0v0_Shanghai + - opcD9DiffPlaces_d12g0v0_Shanghai + - opcD8DiffPlaces_d27g0v0_Shanghai + - opcD9DiffPlaces_d13g0v0_Shanghai + - opcD8DiffPlaces_d28g0v0_Shanghai + - opcD9DiffPlaces_d14g0v0_Shanghai + - opcD8DiffPlaces_d29g0v0_Shanghai + - opcD9DiffPlaces_d15g0v0_Shanghai + - opcD8DiffPlaces_d30g0v0_Shanghai + - opcD9DiffPlaces_d16g0v0_Shanghai + - opcD8DiffPlaces_d31g0v0_Shanghai + - opcD9DiffPlaces_d2g0v0_Shanghai + - opcD8DiffPlaces_d32g0v0_Shanghai + - opcD8DiffPlaces_d33g0v0_Shanghai + - opcD8DiffPlaces_d34g0v0_Shanghai + - opcD9DiffPlaces_d17g0v0_Shanghai + - opcD9DiffPlaces_d18g0v0_Shanghai + - opcD9DiffPlaces_d19g0v0_Shanghai + - opcD9DiffPlaces_d3g0v0_Shanghai + - opcD9DiffPlaces_d21g0v0_Shanghai + - opcDADiffPlaces_d0g0v0_Shanghai + - opcD9DiffPlaces_d4g0v0_Shanghai + - opcD9DiffPlaces_d20g0v0_Shanghai + - opcD9DiffPlaces_d22g0v0_Shanghai + - opcD9DiffPlaces_d5g0v0_Shanghai + - opcD9DiffPlaces_d23g0v0_Shanghai + - opcD9DiffPlaces_d6g0v0_Shanghai + - opcD9DiffPlaces_d7g0v0_Shanghai + - opcD9DiffPlaces_d8g0v0_Shanghai + - opcD9DiffPlaces_d9g0v0_Shanghai + - opcD9DiffPlaces_d24g0v0_Shanghai + - opcD9DiffPlaces_d25g0v0_Shanghai + - opcDADiffPlaces_d1g0v0_Shanghai + - opcDADiffPlaces_d10g0v0_Shanghai + - opcDADiffPlaces_d11g0v0_Shanghai + - opcD9DiffPlaces_d26g0v0_Shanghai + - opcDADiffPlaces_d12g0v0_Shanghai + - opcD9DiffPlaces_d27g0v0_Shanghai + - opcDADiffPlaces_d13g0v0_Shanghai + - opcD9DiffPlaces_d28g0v0_Shanghai + - opcDADiffPlaces_d14g0v0_Shanghai + - opcD9DiffPlaces_d29g0v0_Shanghai + - opcDADiffPlaces_d15g0v0_Shanghai + - opcD9DiffPlaces_d30g0v0_Shanghai + - opcDADiffPlaces_d16g0v0_Shanghai + - opcD9DiffPlaces_d31g0v0_Shanghai + - opcD9DiffPlaces_d32g0v0_Shanghai + - opcDADiffPlaces_d2g0v0_Shanghai + - opcD9DiffPlaces_d33g0v0_Shanghai + - opcD9DiffPlaces_d34g0v0_Shanghai + - opcDADiffPlaces_d17g0v0_Shanghai + - opcDADiffPlaces_d18g0v0_Shanghai + - opcDADiffPlaces_d19g0v0_Shanghai + - opcDADiffPlaces_d3g0v0_Shanghai + - opcDADiffPlaces_d21g0v0_Shanghai + - opcDBDiffPlaces_d0g0v0_Shanghai + - opcDADiffPlaces_d20g0v0_Shanghai + - opcDADiffPlaces_d4g0v0_Shanghai + - opcDADiffPlaces_d22g0v0_Shanghai + - opcDADiffPlaces_d5g0v0_Shanghai + - opcDADiffPlaces_d23g0v0_Shanghai + - opcDADiffPlaces_d6g0v0_Shanghai + - opcDADiffPlaces_d7g0v0_Shanghai + - opcDADiffPlaces_d8g0v0_Shanghai + - opcDADiffPlaces_d9g0v0_Shanghai + - opcDADiffPlaces_d24g0v0_Shanghai + - opcDADiffPlaces_d25g0v0_Shanghai + - opcDBDiffPlaces_d1g0v0_Shanghai + - opcDBDiffPlaces_d10g0v0_Shanghai + - opcDADiffPlaces_d26g0v0_Shanghai + - opcDBDiffPlaces_d11g0v0_Shanghai + - opcDBDiffPlaces_d12g0v0_Shanghai + - opcDBDiffPlaces_d13g0v0_Shanghai + - opcDADiffPlaces_d27g0v0_Shanghai + - opcDADiffPlaces_d28g0v0_Shanghai + - opcDBDiffPlaces_d14g0v0_Shanghai + - opcDADiffPlaces_d29g0v0_Shanghai + - opcDBDiffPlaces_d15g0v0_Shanghai + - opcDADiffPlaces_d30g0v0_Shanghai + - opcDADiffPlaces_d31g0v0_Shanghai + - opcDBDiffPlaces_d16g0v0_Shanghai + - opcDBDiffPlaces_d2g0v0_Shanghai + - opcDADiffPlaces_d32g0v0_Shanghai + - opcDADiffPlaces_d33g0v0_Shanghai + - opcDADiffPlaces_d34g0v0_Shanghai + - opcDBDiffPlaces_d17g0v0_Shanghai + - opcDBDiffPlaces_d18g0v0_Shanghai + - opcDBDiffPlaces_d19g0v0_Shanghai + - opcDBDiffPlaces_d3g0v0_Shanghai + - opcDBDiffPlaces_d21g0v0_Shanghai + - opcDCDiffPlaces_d0g0v0_Shanghai + - opcDBDiffPlaces_d20g0v0_Shanghai + - opcDBDiffPlaces_d4g0v0_Shanghai + - opcDBDiffPlaces_d22g0v0_Shanghai + - opcDBDiffPlaces_d5g0v0_Shanghai + - opcDBDiffPlaces_d23g0v0_Shanghai + - opcDBDiffPlaces_d6g0v0_Shanghai + - opcDBDiffPlaces_d7g0v0_Shanghai + - opcDBDiffPlaces_d8g0v0_Shanghai + - opcDBDiffPlaces_d24g0v0_Shanghai + - opcDBDiffPlaces_d9g0v0_Shanghai + - opcDBDiffPlaces_d25g0v0_Shanghai + - opcDCDiffPlaces_d1g0v0_Shanghai + - opcDCDiffPlaces_d10g0v0_Shanghai + - opcDCDiffPlaces_d11g0v0_Shanghai + - opcDBDiffPlaces_d26g0v0_Shanghai + - opcDCDiffPlaces_d12g0v0_Shanghai + - opcDBDiffPlaces_d27g0v0_Shanghai + - opcDCDiffPlaces_d13g0v0_Shanghai + - opcDBDiffPlaces_d28g0v0_Shanghai + - opcDCDiffPlaces_d14g0v0_Shanghai + - opcDBDiffPlaces_d29g0v0_Shanghai + - opcDCDiffPlaces_d15g0v0_Shanghai + - opcDBDiffPlaces_d31g0v0_Shanghai + - opcDBDiffPlaces_d30g0v0_Shanghai + - opcDCDiffPlaces_d16g0v0_Shanghai + - opcDBDiffPlaces_d32g0v0_Shanghai + - opcDCDiffPlaces_d2g0v0_Shanghai + - opcDBDiffPlaces_d33g0v0_Shanghai + - opcDBDiffPlaces_d34g0v0_Shanghai + - opcDCDiffPlaces_d17g0v0_Shanghai + - opcDCDiffPlaces_d18g0v0_Shanghai + - opcDCDiffPlaces_d19g0v0_Shanghai + - opcDCDiffPlaces_d3g0v0_Shanghai + - opcDCDiffPlaces_d21g0v0_Shanghai + - opcDDDiffPlaces_d0g0v0_Shanghai + - opcDCDiffPlaces_d4g0v0_Shanghai + - opcDCDiffPlaces_d20g0v0_Shanghai + - opcDCDiffPlaces_d22g0v0_Shanghai + - opcDCDiffPlaces_d5g0v0_Shanghai + - opcDCDiffPlaces_d23g0v0_Shanghai + - opcDCDiffPlaces_d6g0v0_Shanghai + - opcDCDiffPlaces_d7g0v0_Shanghai + - opcDCDiffPlaces_d8g0v0_Shanghai + - opcDCDiffPlaces_d9g0v0_Shanghai + - opcDCDiffPlaces_d24g0v0_Shanghai + - opcDCDiffPlaces_d25g0v0_Shanghai + - opcDDDiffPlaces_d1g0v0_Shanghai + - opcDDDiffPlaces_d10g0v0_Shanghai + - opcDDDiffPlaces_d11g0v0_Shanghai + - opcDCDiffPlaces_d26g0v0_Shanghai + - opcDDDiffPlaces_d12g0v0_Shanghai + - opcDCDiffPlaces_d27g0v0_Shanghai + - opcDDDiffPlaces_d13g0v0_Shanghai + - opcDCDiffPlaces_d28g0v0_Shanghai + - opcDDDiffPlaces_d14g0v0_Shanghai + - opcDCDiffPlaces_d29g0v0_Shanghai + - opcDDDiffPlaces_d15g0v0_Shanghai + - opcDCDiffPlaces_d30g0v0_Shanghai + - opcDDDiffPlaces_d16g0v0_Shanghai + - opcDCDiffPlaces_d31g0v0_Shanghai + - opcDDDiffPlaces_d2g0v0_Shanghai + - opcDCDiffPlaces_d32g0v0_Shanghai + - opcDCDiffPlaces_d33g0v0_Shanghai + - opcDCDiffPlaces_d34g0v0_Shanghai + - opcDDDiffPlaces_d17g0v0_Shanghai + - opcDDDiffPlaces_d18g0v0_Shanghai + - opcDDDiffPlaces_d19g0v0_Shanghai + - opcDDDiffPlaces_d3g0v0_Shanghai + - opcDEDiffPlaces_d0g0v0_Shanghai + - opcDDDiffPlaces_d21g0v0_Shanghai + - opcDDDiffPlaces_d4g0v0_Shanghai + - opcDDDiffPlaces_d20g0v0_Shanghai + - opcDDDiffPlaces_d22g0v0_Shanghai + - opcDDDiffPlaces_d5g0v0_Shanghai + - opcDDDiffPlaces_d23g0v0_Shanghai + - opcDDDiffPlaces_d6g0v0_Shanghai + - opcDDDiffPlaces_d7g0v0_Shanghai + - opcDDDiffPlaces_d8g0v0_Shanghai + - opcDDDiffPlaces_d24g0v0_Shanghai + - opcDDDiffPlaces_d9g0v0_Shanghai + - opcDDDiffPlaces_d25g0v0_Shanghai + - opcDEDiffPlaces_d1g0v0_Shanghai + - opcDEDiffPlaces_d10g0v0_Shanghai + - opcDEDiffPlaces_d11g0v0_Shanghai + - opcDDDiffPlaces_d26g0v0_Shanghai + - opcDEDiffPlaces_d12g0v0_Shanghai + - opcDDDiffPlaces_d27g0v0_Shanghai + - opcDEDiffPlaces_d13g0v0_Shanghai + - opcDDDiffPlaces_d28g0v0_Shanghai + - opcDEDiffPlaces_d14g0v0_Shanghai + - opcDDDiffPlaces_d29g0v0_Shanghai + - opcDEDiffPlaces_d15g0v0_Shanghai + - opcDDDiffPlaces_d30g0v0_Shanghai + - opcDEDiffPlaces_d16g0v0_Shanghai + - opcDDDiffPlaces_d31g0v0_Shanghai + - opcDEDiffPlaces_d2g0v0_Shanghai + - opcDDDiffPlaces_d32g0v0_Shanghai + - opcDDDiffPlaces_d33g0v0_Shanghai + - opcDDDiffPlaces_d34g0v0_Shanghai + - opcDEDiffPlaces_d17g0v0_Shanghai + - opcDEDiffPlaces_d18g0v0_Shanghai + - opcDEDiffPlaces_d19g0v0_Shanghai + - opcDEDiffPlaces_d3g0v0_Shanghai + - opcDEDiffPlaces_d21g0v0_Shanghai + - opcDFDiffPlaces_d0g0v0_Shanghai + - opcDEDiffPlaces_d20g0v0_Shanghai + - opcDEDiffPlaces_d4g0v0_Shanghai + - opcDEDiffPlaces_d22g0v0_Shanghai + - opcDEDiffPlaces_d5g0v0_Shanghai + - opcDEDiffPlaces_d23g0v0_Shanghai + - opcDEDiffPlaces_d6g0v0_Shanghai + - opcDEDiffPlaces_d7g0v0_Shanghai + - opcDEDiffPlaces_d8g0v0_Shanghai + - opcDEDiffPlaces_d24g0v0_Shanghai + - opcDEDiffPlaces_d9g0v0_Shanghai + - opcDEDiffPlaces_d25g0v0_Shanghai + - opcDFDiffPlaces_d1g0v0_Shanghai + - opcDFDiffPlaces_d10g0v0_Shanghai + - opcDFDiffPlaces_d11g0v0_Shanghai + - opcDEDiffPlaces_d26g0v0_Shanghai + - opcDFDiffPlaces_d12g0v0_Shanghai + - opcDEDiffPlaces_d27g0v0_Shanghai + - opcDFDiffPlaces_d13g0v0_Shanghai + - opcDEDiffPlaces_d28g0v0_Shanghai + - opcDFDiffPlaces_d14g0v0_Shanghai + - opcDEDiffPlaces_d29g0v0_Shanghai + - opcDFDiffPlaces_d15g0v0_Shanghai + - opcDEDiffPlaces_d30g0v0_Shanghai + - opcDFDiffPlaces_d16g0v0_Shanghai + - opcDEDiffPlaces_d31g0v0_Shanghai + - opcDEDiffPlaces_d32g0v0_Shanghai + - opcDFDiffPlaces_d2g0v0_Shanghai + - opcDEDiffPlaces_d33g0v0_Shanghai + - opcDEDiffPlaces_d34g0v0_Shanghai + - opcDFDiffPlaces_d17g0v0_Shanghai + - opcDFDiffPlaces_d18g0v0_Shanghai + - opcDFDiffPlaces_d19g0v0_Shanghai + - opcDFDiffPlaces_d3g0v0_Shanghai + - opcDFDiffPlaces_d21g0v0_Shanghai + - opcE0DiffPlaces_d0g0v0_Shanghai + - opcDFDiffPlaces_d4g0v0_Shanghai + - opcDFDiffPlaces_d20g0v0_Shanghai + - opcDFDiffPlaces_d22g0v0_Shanghai + - opcDFDiffPlaces_d5g0v0_Shanghai + - opcDFDiffPlaces_d23g0v0_Shanghai + - opcDFDiffPlaces_d6g0v0_Shanghai + - opcDFDiffPlaces_d7g0v0_Shanghai + - opcDFDiffPlaces_d8g0v0_Shanghai + - opcDFDiffPlaces_d9g0v0_Shanghai + - opcDFDiffPlaces_d24g0v0_Shanghai + - opcDFDiffPlaces_d25g0v0_Shanghai + - opcE0DiffPlaces_d1g0v0_Shanghai + - opcE0DiffPlaces_d10g0v0_Shanghai + - opcE0DiffPlaces_d11g0v0_Shanghai + - opcDFDiffPlaces_d26g0v0_Shanghai + - opcE0DiffPlaces_d12g0v0_Shanghai + - opcDFDiffPlaces_d27g0v0_Shanghai + - opcE0DiffPlaces_d13g0v0_Shanghai + - opcDFDiffPlaces_d28g0v0_Shanghai + - opcE0DiffPlaces_d14g0v0_Shanghai + - opcDFDiffPlaces_d29g0v0_Shanghai + - opcE0DiffPlaces_d15g0v0_Shanghai + - opcE0DiffPlaces_d16g0v0_Shanghai + - opcDFDiffPlaces_d30g0v0_Shanghai + - opcDFDiffPlaces_d31g0v0_Shanghai + - opcE0DiffPlaces_d2g0v0_Shanghai + - opcDFDiffPlaces_d32g0v0_Shanghai + - opcDFDiffPlaces_d33g0v0_Shanghai + - opcDFDiffPlaces_d34g0v0_Shanghai + - opcE0DiffPlaces_d17g0v0_Shanghai + - opcE0DiffPlaces_d18g0v0_Shanghai + - opcE0DiffPlaces_d19g0v0_Shanghai + - opcE0DiffPlaces_d3g0v0_Shanghai + - opcE0DiffPlaces_d21g0v0_Shanghai + - opcE1DiffPlaces_d0g0v0_Shanghai + - opcE0DiffPlaces_d4g0v0_Shanghai + - opcE0DiffPlaces_d20g0v0_Shanghai + - opcE0DiffPlaces_d22g0v0_Shanghai + - opcE0DiffPlaces_d5g0v0_Shanghai + - opcE0DiffPlaces_d23g0v0_Shanghai + - opcE0DiffPlaces_d6g0v0_Shanghai + - opcE0DiffPlaces_d7g0v0_Shanghai + - opcE0DiffPlaces_d8g0v0_Shanghai + - opcE0DiffPlaces_d24g0v0_Shanghai + - opcE0DiffPlaces_d9g0v0_Shanghai + - opcE0DiffPlaces_d25g0v0_Shanghai + - opcE1DiffPlaces_d1g0v0_Shanghai + - opcE1DiffPlaces_d10g0v0_Shanghai + - opcE0DiffPlaces_d26g0v0_Shanghai + - opcE1DiffPlaces_d11g0v0_Shanghai + - opcE1DiffPlaces_d12g0v0_Shanghai + - opcE0DiffPlaces_d27g0v0_Shanghai + - opcE1DiffPlaces_d13g0v0_Shanghai + - opcE0DiffPlaces_d28g0v0_Shanghai + - opcE1DiffPlaces_d14g0v0_Shanghai + - opcE0DiffPlaces_d29g0v0_Shanghai + - opcE1DiffPlaces_d15g0v0_Shanghai + - opcE0DiffPlaces_d30g0v0_Shanghai + - opcE0DiffPlaces_d31g0v0_Shanghai + - opcE1DiffPlaces_d16g0v0_Shanghai + - opcE0DiffPlaces_d32g0v0_Shanghai + - opcE1DiffPlaces_d2g0v0_Shanghai + - opcE0DiffPlaces_d33g0v0_Shanghai + - opcE0DiffPlaces_d34g0v0_Shanghai + - opcE1DiffPlaces_d17g0v0_Shanghai + - opcE1DiffPlaces_d18g0v0_Shanghai + - opcE1DiffPlaces_d19g0v0_Shanghai + - opcE1DiffPlaces_d3g0v0_Shanghai + - opcE1DiffPlaces_d21g0v0_Shanghai + - opcE2DiffPlaces_d0g0v0_Shanghai + - opcE1DiffPlaces_d4g0v0_Shanghai + - opcE1DiffPlaces_d20g0v0_Shanghai + - opcE1DiffPlaces_d22g0v0_Shanghai + - opcE1DiffPlaces_d5g0v0_Shanghai + - opcE1DiffPlaces_d23g0v0_Shanghai + - opcE1DiffPlaces_d6g0v0_Shanghai + - opcE1DiffPlaces_d7g0v0_Shanghai + - opcE1DiffPlaces_d8g0v0_Shanghai + - opcE1DiffPlaces_d9g0v0_Shanghai + - opcE1DiffPlaces_d24g0v0_Shanghai + - opcE1DiffPlaces_d25g0v0_Shanghai + - opcE2DiffPlaces_d1g0v0_Shanghai + - opcE2DiffPlaces_d10g0v0_Shanghai + - opcE2DiffPlaces_d11g0v0_Shanghai + - opcE1DiffPlaces_d26g0v0_Shanghai + - opcE2DiffPlaces_d12g0v0_Shanghai + - opcE1DiffPlaces_d27g0v0_Shanghai + - opcE2DiffPlaces_d13g0v0_Shanghai + - opcE1DiffPlaces_d28g0v0_Shanghai + - opcE2DiffPlaces_d14g0v0_Shanghai + - opcE1DiffPlaces_d29g0v0_Shanghai + - opcE2DiffPlaces_d15g0v0_Shanghai + - opcE1DiffPlaces_d30g0v0_Shanghai + - opcE1DiffPlaces_d31g0v0_Shanghai + - opcE2DiffPlaces_d16g0v0_Shanghai + - opcE2DiffPlaces_d2g0v0_Shanghai + - opcE1DiffPlaces_d32g0v0_Shanghai + - opcE1DiffPlaces_d33g0v0_Shanghai + - opcE1DiffPlaces_d34g0v0_Shanghai + - opcE2DiffPlaces_d17g0v0_Shanghai + - opcE2DiffPlaces_d18g0v0_Shanghai + - opcE2DiffPlaces_d19g0v0_Shanghai + - opcE2DiffPlaces_d3g0v0_Shanghai + - opcE2DiffPlaces_d21g0v0_Shanghai + - opcE3DiffPlaces_d0g0v0_Shanghai + - opcE2DiffPlaces_d4g0v0_Shanghai + - opcE2DiffPlaces_d20g0v0_Shanghai + - opcE2DiffPlaces_d22g0v0_Shanghai + - opcE2DiffPlaces_d5g0v0_Shanghai + - opcE2DiffPlaces_d23g0v0_Shanghai + - opcE2DiffPlaces_d6g0v0_Shanghai + - opcE2DiffPlaces_d7g0v0_Shanghai + - opcE2DiffPlaces_d8g0v0_Shanghai + - opcE2DiffPlaces_d24g0v0_Shanghai + - opcE2DiffPlaces_d9g0v0_Shanghai + - opcE3DiffPlaces_d1g0v0_Shanghai + - opcE2DiffPlaces_d25g0v0_Shanghai + - opcE3DiffPlaces_d10g0v0_Shanghai + - opcE2DiffPlaces_d26g0v0_Shanghai + - opcE3DiffPlaces_d11g0v0_Shanghai + - opcE3DiffPlaces_d12g0v0_Shanghai + - opcE2DiffPlaces_d27g0v0_Shanghai + - opcE3DiffPlaces_d13g0v0_Shanghai + - opcE2DiffPlaces_d28g0v0_Shanghai + - opcE3DiffPlaces_d14g0v0_Shanghai + - opcE2DiffPlaces_d29g0v0_Shanghai + - opcE3DiffPlaces_d15g0v0_Shanghai + - opcE3DiffPlaces_d16g0v0_Shanghai + - opcE2DiffPlaces_d30g0v0_Shanghai + - opcE2DiffPlaces_d31g0v0_Shanghai + - opcE2DiffPlaces_d32g0v0_Shanghai + - opcE3DiffPlaces_d2g0v0_Shanghai + - opcE2DiffPlaces_d33g0v0_Shanghai + - opcE2DiffPlaces_d34g0v0_Shanghai + - opcE3DiffPlaces_d17g0v0_Shanghai + - opcE3DiffPlaces_d18g0v0_Shanghai + - opcE3DiffPlaces_d19g0v0_Shanghai + - opcE3DiffPlaces_d3g0v0_Shanghai + - opcE4DiffPlaces_d0g0v0_Shanghai + - opcE3DiffPlaces_d21g0v0_Shanghai + - opcE3DiffPlaces_d20g0v0_Shanghai + - opcE3DiffPlaces_d4g0v0_Shanghai + - opcE3DiffPlaces_d22g0v0_Shanghai + - opcE3DiffPlaces_d5g0v0_Shanghai + - opcE3DiffPlaces_d23g0v0_Shanghai + - opcE3DiffPlaces_d6g0v0_Shanghai + - opcE3DiffPlaces_d7g0v0_Shanghai + - opcE3DiffPlaces_d8g0v0_Shanghai + - opcE3DiffPlaces_d9g0v0_Shanghai + - opcE3DiffPlaces_d24g0v0_Shanghai + - opcE3DiffPlaces_d25g0v0_Shanghai + - opcE4DiffPlaces_d1g0v0_Shanghai + - opcE4DiffPlaces_d10g0v0_Shanghai + - opcE4DiffPlaces_d11g0v0_Shanghai + - opcE3DiffPlaces_d26g0v0_Shanghai + - opcE4DiffPlaces_d12g0v0_Shanghai + - opcE3DiffPlaces_d27g0v0_Shanghai + - opcE4DiffPlaces_d13g0v0_Shanghai + - opcE3DiffPlaces_d28g0v0_Shanghai + - opcE4DiffPlaces_d14g0v0_Shanghai + - opcE3DiffPlaces_d29g0v0_Shanghai + - opcE4DiffPlaces_d15g0v0_Shanghai + - opcE3DiffPlaces_d30g0v0_Shanghai + - opcE4DiffPlaces_d16g0v0_Shanghai + - opcE3DiffPlaces_d31g0v0_Shanghai + - opcE4DiffPlaces_d2g0v0_Shanghai + - opcE3DiffPlaces_d32g0v0_Shanghai + - opcE3DiffPlaces_d33g0v0_Shanghai + - opcE3DiffPlaces_d34g0v0_Shanghai + - opcE4DiffPlaces_d17g0v0_Shanghai + - opcE4DiffPlaces_d18g0v0_Shanghai + - opcE4DiffPlaces_d19g0v0_Shanghai + - opcE4DiffPlaces_d3g0v0_Shanghai + - opcE4DiffPlaces_d21g0v0_Shanghai + - opcE5DiffPlaces_d0g0v0_Shanghai + - opcE4DiffPlaces_d20g0v0_Shanghai + - opcE4DiffPlaces_d4g0v0_Shanghai + - opcE4DiffPlaces_d22g0v0_Shanghai + - opcE4DiffPlaces_d23g0v0_Shanghai + - opcE4DiffPlaces_d5g0v0_Shanghai + - opcE4DiffPlaces_d6g0v0_Shanghai + - opcE4DiffPlaces_d7g0v0_Shanghai + - opcE4DiffPlaces_d8g0v0_Shanghai + - opcE4DiffPlaces_d24g0v0_Shanghai + - opcE4DiffPlaces_d9g0v0_Shanghai + - opcE4DiffPlaces_d25g0v0_Shanghai + - opcE5DiffPlaces_d1g0v0_Shanghai + - opcE5DiffPlaces_d10g0v0_Shanghai + - opcE5DiffPlaces_d11g0v0_Shanghai + - opcE4DiffPlaces_d26g0v0_Shanghai + - opcE5DiffPlaces_d12g0v0_Shanghai + - opcE4DiffPlaces_d27g0v0_Shanghai + - opcE5DiffPlaces_d13g0v0_Shanghai + - opcE4DiffPlaces_d28g0v0_Shanghai + - opcE5DiffPlaces_d14g0v0_Shanghai + - opcE4DiffPlaces_d29g0v0_Shanghai + - opcE5DiffPlaces_d15g0v0_Shanghai + - opcE5DiffPlaces_d16g0v0_Shanghai + - opcE4DiffPlaces_d31g0v0_Shanghai + - opcE4DiffPlaces_d30g0v0_Shanghai + - opcE4DiffPlaces_d32g0v0_Shanghai + - opcE5DiffPlaces_d2g0v0_Shanghai + - opcE4DiffPlaces_d33g0v0_Shanghai + - opcE4DiffPlaces_d34g0v0_Shanghai + - opcE5DiffPlaces_d17g0v0_Shanghai + - opcE5DiffPlaces_d18g0v0_Shanghai + - opcE5DiffPlaces_d19g0v0_Shanghai + - opcE5DiffPlaces_d3g0v0_Shanghai + - opcE6DiffPlaces_d0g0v0_Shanghai + - opcE5DiffPlaces_d21g0v0_Shanghai + - opcE5DiffPlaces_d4g0v0_Shanghai + - opcE5DiffPlaces_d20g0v0_Shanghai + - opcE5DiffPlaces_d22g0v0_Shanghai + - opcE5DiffPlaces_d5g0v0_Shanghai + - opcE5DiffPlaces_d23g0v0_Shanghai + - opcE5DiffPlaces_d6g0v0_Shanghai + - opcE5DiffPlaces_d7g0v0_Shanghai + - opcE5DiffPlaces_d8g0v0_Shanghai + - opcE5DiffPlaces_d24g0v0_Shanghai + - opcE5DiffPlaces_d9g0v0_Shanghai + - opcE5DiffPlaces_d25g0v0_Shanghai + - opcE6DiffPlaces_d1g0v0_Shanghai + - opcE6DiffPlaces_d10g0v0_Shanghai + - opcE6DiffPlaces_d11g0v0_Shanghai + - opcE5DiffPlaces_d26g0v0_Shanghai + - opcE6DiffPlaces_d12g0v0_Shanghai + - opcE6DiffPlaces_d13g0v0_Shanghai + - opcE5DiffPlaces_d27g0v0_Shanghai + - opcE5DiffPlaces_d28g0v0_Shanghai + - opcE6DiffPlaces_d14g0v0_Shanghai + - opcE5DiffPlaces_d29g0v0_Shanghai + - opcE6DiffPlaces_d15g0v0_Shanghai + - opcE5DiffPlaces_d30g0v0_Shanghai + - opcE6DiffPlaces_d16g0v0_Shanghai + - opcE5DiffPlaces_d31g0v0_Shanghai + - opcE6DiffPlaces_d2g0v0_Shanghai + - opcE5DiffPlaces_d32g0v0_Shanghai + - opcE5DiffPlaces_d33g0v0_Shanghai + - opcE5DiffPlaces_d34g0v0_Shanghai + - opcE6DiffPlaces_d17g0v0_Shanghai + - opcE6DiffPlaces_d18g0v0_Shanghai + - opcE6DiffPlaces_d19g0v0_Shanghai + - opcE6DiffPlaces_d3g0v0_Shanghai + - opcE6DiffPlaces_d21g0v0_Shanghai + - opcE7DiffPlaces_d0g0v0_Shanghai + - opcE6DiffPlaces_d20g0v0_Shanghai + - opcE6DiffPlaces_d4g0v0_Shanghai + - opcE6DiffPlaces_d22g0v0_Shanghai + - opcE6DiffPlaces_d23g0v0_Shanghai + - opcE6DiffPlaces_d5g0v0_Shanghai + - opcE6DiffPlaces_d6g0v0_Shanghai + - opcE6DiffPlaces_d7g0v0_Shanghai + - opcE6DiffPlaces_d8g0v0_Shanghai + - opcE6DiffPlaces_d24g0v0_Shanghai + - opcE6DiffPlaces_d9g0v0_Shanghai + - opcE6DiffPlaces_d25g0v0_Shanghai + - opcE7DiffPlaces_d1g0v0_Shanghai + - opcE7DiffPlaces_d10g0v0_Shanghai + - opcE7DiffPlaces_d11g0v0_Shanghai + - opcE6DiffPlaces_d26g0v0_Shanghai + - opcE7DiffPlaces_d12g0v0_Shanghai + - opcE6DiffPlaces_d27g0v0_Shanghai + - opcE7DiffPlaces_d13g0v0_Shanghai + - opcE6DiffPlaces_d28g0v0_Shanghai + - opcE7DiffPlaces_d14g0v0_Shanghai + - opcE6DiffPlaces_d29g0v0_Shanghai + - opcE7DiffPlaces_d15g0v0_Shanghai + - opcE7DiffPlaces_d16g0v0_Shanghai + - opcE6DiffPlaces_d30g0v0_Shanghai + - opcE6DiffPlaces_d31g0v0_Shanghai + - opcE6DiffPlaces_d32g0v0_Shanghai + - opcE7DiffPlaces_d2g0v0_Shanghai + - opcE6DiffPlaces_d33g0v0_Shanghai + - opcE6DiffPlaces_d34g0v0_Shanghai + - opcE7DiffPlaces_d17g0v0_Shanghai + - opcE7DiffPlaces_d18g0v0_Shanghai + - opcE7DiffPlaces_d19g0v0_Shanghai + - opcE7DiffPlaces_d3g0v0_Shanghai + - opcE7DiffPlaces_d21g0v0_Shanghai + - opcE8DiffPlaces_d0g0v0_Shanghai + - opcE7DiffPlaces_d4g0v0_Shanghai + - opcE7DiffPlaces_d20g0v0_Shanghai + - opcE7DiffPlaces_d22g0v0_Shanghai + - opcE7DiffPlaces_d5g0v0_Shanghai + - opcE7DiffPlaces_d23g0v0_Shanghai + - opcE7DiffPlaces_d6g0v0_Shanghai + - opcE7DiffPlaces_d7g0v0_Shanghai + - opcE7DiffPlaces_d8g0v0_Shanghai + - opcE7DiffPlaces_d24g0v0_Shanghai + - opcE7DiffPlaces_d9g0v0_Shanghai + - opcE8DiffPlaces_d1g0v0_Shanghai + - opcE7DiffPlaces_d25g0v0_Shanghai + - opcE8DiffPlaces_d10g0v0_Shanghai + - opcE8DiffPlaces_d11g0v0_Shanghai + - opcE7DiffPlaces_d26g0v0_Shanghai + - opcE8DiffPlaces_d12g0v0_Shanghai + - opcE7DiffPlaces_d27g0v0_Shanghai + - opcE8DiffPlaces_d13g0v0_Shanghai + - opcE7DiffPlaces_d28g0v0_Shanghai + - opcE8DiffPlaces_d14g0v0_Shanghai + - opcE8DiffPlaces_d15g0v0_Shanghai + - opcE7DiffPlaces_d29g0v0_Shanghai + - opcE7DiffPlaces_d30g0v0_Shanghai + - opcE8DiffPlaces_d16g0v0_Shanghai + - opcE7DiffPlaces_d31g0v0_Shanghai + - opcE8DiffPlaces_d2g0v0_Shanghai + - opcE7DiffPlaces_d32g0v0_Shanghai + - opcE7DiffPlaces_d33g0v0_Shanghai + - opcE7DiffPlaces_d34g0v0_Shanghai + - opcE8DiffPlaces_d17g0v0_Shanghai + - opcE8DiffPlaces_d18g0v0_Shanghai + - opcE8DiffPlaces_d19g0v0_Shanghai + - opcE8DiffPlaces_d3g0v0_Shanghai + - opcE9DiffPlaces_d0g0v0_Shanghai + - opcE8DiffPlaces_d21g0v0_Shanghai + - opcE8DiffPlaces_d20g0v0_Shanghai + - opcE8DiffPlaces_d4g0v0_Shanghai + - opcE8DiffPlaces_d22g0v0_Shanghai + - opcE8DiffPlaces_d5g0v0_Shanghai + - opcE8DiffPlaces_d23g0v0_Shanghai + - opcE8DiffPlaces_d6g0v0_Shanghai + - opcE8DiffPlaces_d7g0v0_Shanghai + - opcE8DiffPlaces_d8g0v0_Shanghai + - opcE8DiffPlaces_d9g0v0_Shanghai + - opcE8DiffPlaces_d24g0v0_Shanghai + - opcE8DiffPlaces_d25g0v0_Shanghai + - opcE9DiffPlaces_d1g0v0_Shanghai + - opcE9DiffPlaces_d10g0v0_Shanghai + - opcE9DiffPlaces_d11g0v0_Shanghai + - opcE8DiffPlaces_d26g0v0_Shanghai + - opcE9DiffPlaces_d12g0v0_Shanghai + - opcE8DiffPlaces_d27g0v0_Shanghai + - opcE9DiffPlaces_d13g0v0_Shanghai + - opcE8DiffPlaces_d28g0v0_Shanghai + - opcE9DiffPlaces_d14g0v0_Shanghai + - opcE8DiffPlaces_d29g0v0_Shanghai + - opcE9DiffPlaces_d15g0v0_Shanghai + - opcE8DiffPlaces_d30g0v0_Shanghai + - opcE9DiffPlaces_d16g0v0_Shanghai + - opcE8DiffPlaces_d31g0v0_Shanghai + - opcE9DiffPlaces_d2g0v0_Shanghai + - opcE8DiffPlaces_d32g0v0_Shanghai + - opcE8DiffPlaces_d33g0v0_Shanghai + - opcE8DiffPlaces_d34g0v0_Shanghai + - opcE9DiffPlaces_d17g0v0_Shanghai + - opcE9DiffPlaces_d18g0v0_Shanghai + - opcE9DiffPlaces_d19g0v0_Shanghai + - opcE9DiffPlaces_d3g0v0_Shanghai + - opcE9DiffPlaces_d21g0v0_Shanghai + - opcEADiffPlaces_d0g0v0_Shanghai + - opcE9DiffPlaces_d4g0v0_Shanghai + - opcE9DiffPlaces_d20g0v0_Shanghai + - opcE9DiffPlaces_d22g0v0_Shanghai + - opcE9DiffPlaces_d5g0v0_Shanghai + - opcE9DiffPlaces_d23g0v0_Shanghai + - opcE9DiffPlaces_d6g0v0_Shanghai + - opcE9DiffPlaces_d7g0v0_Shanghai + - opcE9DiffPlaces_d8g0v0_Shanghai + - opcE9DiffPlaces_d24g0v0_Shanghai + - opcE9DiffPlaces_d9g0v0_Shanghai + - opcE9DiffPlaces_d25g0v0_Shanghai + - opcEADiffPlaces_d1g0v0_Shanghai + - opcEADiffPlaces_d10g0v0_Shanghai + - opcEADiffPlaces_d11g0v0_Shanghai + - opcE9DiffPlaces_d26g0v0_Shanghai + - opcEADiffPlaces_d12g0v0_Shanghai + - opcE9DiffPlaces_d27g0v0_Shanghai + - opcEADiffPlaces_d13g0v0_Shanghai + - opcE9DiffPlaces_d28g0v0_Shanghai + - opcEADiffPlaces_d14g0v0_Shanghai + - opcE9DiffPlaces_d29g0v0_Shanghai + - opcEADiffPlaces_d15g0v0_Shanghai + - opcE9DiffPlaces_d30g0v0_Shanghai + - opcEADiffPlaces_d16g0v0_Shanghai + - opcE9DiffPlaces_d32g0v0_Shanghai + - opcE9DiffPlaces_d31g0v0_Shanghai + - opcEADiffPlaces_d2g0v0_Shanghai + - opcE9DiffPlaces_d33g0v0_Shanghai + - opcE9DiffPlaces_d34g0v0_Shanghai + - opcEADiffPlaces_d17g0v0_Shanghai + - opcEADiffPlaces_d18g0v0_Shanghai + - opcEADiffPlaces_d19g0v0_Shanghai + - opcEADiffPlaces_d3g0v0_Shanghai + - opcEADiffPlaces_d21g0v0_Shanghai + - opcEADiffPlaces_d4g0v0_Shanghai + - opcEBDiffPlaces_d0g0v0_Shanghai + - opcEADiffPlaces_d20g0v0_Shanghai + - opcEADiffPlaces_d22g0v0_Shanghai + - opcEADiffPlaces_d5g0v0_Shanghai + - opcEADiffPlaces_d23g0v0_Shanghai + - opcEADiffPlaces_d6g0v0_Shanghai + - opcEADiffPlaces_d7g0v0_Shanghai + - opcEADiffPlaces_d8g0v0_Shanghai + - opcEADiffPlaces_d24g0v0_Shanghai + - opcEADiffPlaces_d9g0v0_Shanghai + - opcEADiffPlaces_d25g0v0_Shanghai + - opcEBDiffPlaces_d1g0v0_Shanghai + - opcEBDiffPlaces_d10g0v0_Shanghai + - opcEADiffPlaces_d26g0v0_Shanghai + - opcEBDiffPlaces_d11g0v0_Shanghai + - opcEBDiffPlaces_d12g0v0_Shanghai + - opcEADiffPlaces_d27g0v0_Shanghai + - opcEBDiffPlaces_d13g0v0_Shanghai + - opcEADiffPlaces_d28g0v0_Shanghai + - opcEBDiffPlaces_d14g0v0_Shanghai + - opcEADiffPlaces_d29g0v0_Shanghai + - opcEBDiffPlaces_d15g0v0_Shanghai + - opcEADiffPlaces_d30g0v0_Shanghai + - opcEADiffPlaces_d31g0v0_Shanghai + - opcEBDiffPlaces_d16g0v0_Shanghai + - opcEBDiffPlaces_d2g0v0_Shanghai + - opcEADiffPlaces_d32g0v0_Shanghai + - opcEADiffPlaces_d34g0v0_Shanghai + - opcEADiffPlaces_d33g0v0_Shanghai + - opcEBDiffPlaces_d17g0v0_Shanghai + - opcEBDiffPlaces_d18g0v0_Shanghai + - opcEBDiffPlaces_d19g0v0_Shanghai + - opcEBDiffPlaces_d3g0v0_Shanghai + - opcEBDiffPlaces_d21g0v0_Shanghai + - opcECDiffPlaces_d0g0v0_Shanghai + - opcEBDiffPlaces_d4g0v0_Shanghai + - opcEBDiffPlaces_d20g0v0_Shanghai + - opcEBDiffPlaces_d22g0v0_Shanghai + - opcEBDiffPlaces_d5g0v0_Shanghai + - opcEBDiffPlaces_d23g0v0_Shanghai + - opcEBDiffPlaces_d6g0v0_Shanghai + - opcEBDiffPlaces_d7g0v0_Shanghai + - opcEBDiffPlaces_d8g0v0_Shanghai + - opcEBDiffPlaces_d24g0v0_Shanghai + - opcEBDiffPlaces_d9g0v0_Shanghai + - opcEBDiffPlaces_d25g0v0_Shanghai + - opcECDiffPlaces_d1g0v0_Shanghai + - opcECDiffPlaces_d10g0v0_Shanghai + - opcEBDiffPlaces_d26g0v0_Shanghai + - opcECDiffPlaces_d11g0v0_Shanghai + - opcECDiffPlaces_d12g0v0_Shanghai + - opcEBDiffPlaces_d27g0v0_Shanghai + - opcECDiffPlaces_d13g0v0_Shanghai + - opcEBDiffPlaces_d28g0v0_Shanghai + - opcECDiffPlaces_d14g0v0_Shanghai + - opcEBDiffPlaces_d29g0v0_Shanghai + - opcECDiffPlaces_d15g0v0_Shanghai + - opcECDiffPlaces_d16g0v0_Shanghai + - opcEBDiffPlaces_d30g0v0_Shanghai + - opcEBDiffPlaces_d31g0v0_Shanghai + - opcEBDiffPlaces_d32g0v0_Shanghai + - opcECDiffPlaces_d2g0v0_Shanghai + - opcEBDiffPlaces_d33g0v0_Shanghai + - opcEBDiffPlaces_d34g0v0_Shanghai + - opcECDiffPlaces_d17g0v0_Shanghai + - opcECDiffPlaces_d18g0v0_Shanghai + - opcECDiffPlaces_d19g0v0_Shanghai + - opcECDiffPlaces_d3g0v0_Shanghai + - opcECDiffPlaces_d21g0v0_Shanghai + - opcEDDiffPlaces_d0g0v0_Shanghai + - opcECDiffPlaces_d4g0v0_Shanghai + - opcECDiffPlaces_d20g0v0_Shanghai + - opcECDiffPlaces_d22g0v0_Shanghai + - opcECDiffPlaces_d5g0v0_Shanghai + - opcECDiffPlaces_d23g0v0_Shanghai + - opcECDiffPlaces_d6g0v0_Shanghai + - opcECDiffPlaces_d7g0v0_Shanghai + - opcECDiffPlaces_d8g0v0_Shanghai + - opcECDiffPlaces_d24g0v0_Shanghai + - opcECDiffPlaces_d9g0v0_Shanghai + - opcEDDiffPlaces_d1g0v0_Shanghai + - opcECDiffPlaces_d25g0v0_Shanghai + - opcEDDiffPlaces_d10g0v0_Shanghai + - opcEDDiffPlaces_d11g0v0_Shanghai + - opcECDiffPlaces_d26g0v0_Shanghai + - opcEDDiffPlaces_d12g0v0_Shanghai + - opcECDiffPlaces_d27g0v0_Shanghai + - opcEDDiffPlaces_d13g0v0_Shanghai + - opcECDiffPlaces_d28g0v0_Shanghai + - opcEDDiffPlaces_d14g0v0_Shanghai + - opcECDiffPlaces_d29g0v0_Shanghai + - opcEDDiffPlaces_d15g0v0_Shanghai + - opcEDDiffPlaces_d16g0v0_Shanghai + - opcECDiffPlaces_d31g0v0_Shanghai + - opcECDiffPlaces_d30g0v0_Shanghai + - opcEDDiffPlaces_d2g0v0_Shanghai + - opcECDiffPlaces_d32g0v0_Shanghai + - opcECDiffPlaces_d33g0v0_Shanghai + - opcECDiffPlaces_d34g0v0_Shanghai + - opcEDDiffPlaces_d17g0v0_Shanghai + - opcEDDiffPlaces_d18g0v0_Shanghai + - opcEDDiffPlaces_d19g0v0_Shanghai + - opcEDDiffPlaces_d3g0v0_Shanghai + - opcEDDiffPlaces_d21g0v0_Shanghai + - opcEEDiffPlaces_d0g0v0_Shanghai + - opcEDDiffPlaces_d4g0v0_Shanghai + - opcEDDiffPlaces_d20g0v0_Shanghai + - opcEDDiffPlaces_d22g0v0_Shanghai + - opcEDDiffPlaces_d5g0v0_Shanghai + - opcEDDiffPlaces_d23g0v0_Shanghai + - opcEDDiffPlaces_d6g0v0_Shanghai + - opcEDDiffPlaces_d7g0v0_Shanghai + - opcEDDiffPlaces_d8g0v0_Shanghai + - opcEDDiffPlaces_d9g0v0_Shanghai + - opcEDDiffPlaces_d24g0v0_Shanghai + - opcEDDiffPlaces_d25g0v0_Shanghai + - opcEEDiffPlaces_d1g0v0_Shanghai + - opcEEDiffPlaces_d10g0v0_Shanghai + - opcEDDiffPlaces_d26g0v0_Shanghai + - opcEEDiffPlaces_d11g0v0_Shanghai + - opcEEDiffPlaces_d12g0v0_Shanghai + - opcEDDiffPlaces_d27g0v0_Shanghai + - opcEEDiffPlaces_d13g0v0_Shanghai + - opcEDDiffPlaces_d28g0v0_Shanghai + - opcEEDiffPlaces_d14g0v0_Shanghai + - opcEDDiffPlaces_d29g0v0_Shanghai + - opcEEDiffPlaces_d15g0v0_Shanghai + - opcEEDiffPlaces_d16g0v0_Shanghai + - opcEDDiffPlaces_d30g0v0_Shanghai + - opcEDDiffPlaces_d31g0v0_Shanghai + - opcEEDiffPlaces_d2g0v0_Shanghai + - opcEDDiffPlaces_d32g0v0_Shanghai + - opcEDDiffPlaces_d33g0v0_Shanghai + - opcEDDiffPlaces_d34g0v0_Shanghai + - opcEEDiffPlaces_d17g0v0_Shanghai + - opcEEDiffPlaces_d18g0v0_Shanghai + - opcEEDiffPlaces_d3g0v0_Shanghai + - opcEEDiffPlaces_d19g0v0_Shanghai + - opcEEDiffPlaces_d21g0v0_Shanghai + - opcEFDiffPlaces_d0g0v0_Shanghai + - opcEEDiffPlaces_d20g0v0_Shanghai + - opcEEDiffPlaces_d4g0v0_Shanghai + - opcEEDiffPlaces_d22g0v0_Shanghai + - opcEEDiffPlaces_d5g0v0_Shanghai + - opcEEDiffPlaces_d23g0v0_Shanghai + - opcEEDiffPlaces_d6g0v0_Shanghai + - opcEEDiffPlaces_d7g0v0_Shanghai + - opcEEDiffPlaces_d8g0v0_Shanghai + - opcEEDiffPlaces_d24g0v0_Shanghai + - opcEEDiffPlaces_d9g0v0_Shanghai + - opcEFDiffPlaces_d1g0v0_Shanghai + - opcEEDiffPlaces_d25g0v0_Shanghai + - opcEFDiffPlaces_d10g0v0_Shanghai + - opcEFDiffPlaces_d11g0v0_Shanghai + - opcEEDiffPlaces_d26g0v0_Shanghai + - opcEFDiffPlaces_d12g0v0_Shanghai + - opcEEDiffPlaces_d27g0v0_Shanghai + - opcEFDiffPlaces_d13g0v0_Shanghai + - opcEEDiffPlaces_d28g0v0_Shanghai + - opcEFDiffPlaces_d14g0v0_Shanghai + - opcEEDiffPlaces_d29g0v0_Shanghai + - opcEFDiffPlaces_d15g0v0_Shanghai + - opcEFDiffPlaces_d16g0v0_Shanghai + - opcEEDiffPlaces_d30g0v0_Shanghai + - opcEEDiffPlaces_d31g0v0_Shanghai + - opcEFDiffPlaces_d2g0v0_Shanghai + - opcEEDiffPlaces_d32g0v0_Shanghai + - opcEEDiffPlaces_d33g0v0_Shanghai + - opcEEDiffPlaces_d34g0v0_Shanghai + - opcEFDiffPlaces_d17g0v0_Shanghai + - opcEFDiffPlaces_d18g0v0_Shanghai + - opcEFDiffPlaces_d19g0v0_Shanghai + - opcEFDiffPlaces_d3g0v0_Shanghai + - opcEFDiffPlaces_d21g0v0_Shanghai + - opcF6DiffPlaces_d0g0v0_Shanghai + - opcEFDiffPlaces_d4g0v0_Shanghai + - opcEFDiffPlaces_d20g0v0_Shanghai + - opcEFDiffPlaces_d22g0v0_Shanghai + - opcEFDiffPlaces_d23g0v0_Shanghai + - opcEFDiffPlaces_d5g0v0_Shanghai + - opcEFDiffPlaces_d6g0v0_Shanghai + - opcEFDiffPlaces_d7g0v0_Shanghai + - opcEFDiffPlaces_d8g0v0_Shanghai + - opcEFDiffPlaces_d24g0v0_Shanghai + - opcEFDiffPlaces_d9g0v0_Shanghai + - opcF6DiffPlaces_d1g0v0_Shanghai + - opcEFDiffPlaces_d25g0v0_Shanghai + - opcF6DiffPlaces_d10g0v0_Shanghai + - opcF6DiffPlaces_d11g0v0_Shanghai + - opcEFDiffPlaces_d26g0v0_Shanghai + - opcF6DiffPlaces_d12g0v0_Shanghai + - opcF6DiffPlaces_d13g0v0_Shanghai + - opcEFDiffPlaces_d27g0v0_Shanghai + - opcEFDiffPlaces_d28g0v0_Shanghai + - opcF6DiffPlaces_d14g0v0_Shanghai + - opcF6DiffPlaces_d15g0v0_Shanghai + - opcEFDiffPlaces_d29g0v0_Shanghai + - opcF6DiffPlaces_d16g0v0_Shanghai + - opcEFDiffPlaces_d30g0v0_Shanghai + - opcEFDiffPlaces_d31g0v0_Shanghai + - opcF6DiffPlaces_d2g0v0_Shanghai + - opcEFDiffPlaces_d32g0v0_Shanghai + - opcEFDiffPlaces_d33g0v0_Shanghai + - opcEFDiffPlaces_d34g0v0_Shanghai + - opcF6DiffPlaces_d17g0v0_Shanghai + - opcF6DiffPlaces_d18g0v0_Shanghai + - opcF6DiffPlaces_d19g0v0_Shanghai + - opcF6DiffPlaces_d3g0v0_Shanghai + - opcF7DiffPlaces_d0g0v0_Shanghai + - opcF6DiffPlaces_d21g0v0_Shanghai + - opcF6DiffPlaces_d20g0v0_Shanghai + - opcF6DiffPlaces_d4g0v0_Shanghai + - opcF6DiffPlaces_d22g0v0_Shanghai + - opcF6DiffPlaces_d5g0v0_Shanghai + - opcF6DiffPlaces_d23g0v0_Shanghai + - opcF6DiffPlaces_d6g0v0_Shanghai + - opcF6DiffPlaces_d7g0v0_Shanghai + - opcF6DiffPlaces_d8g0v0_Shanghai + - opcF6DiffPlaces_d24g0v0_Shanghai + - opcF6DiffPlaces_d9g0v0_Shanghai + - opcF6DiffPlaces_d25g0v0_Shanghai + - opcF7DiffPlaces_d1g0v0_Shanghai + - opcF7DiffPlaces_d10g0v0_Shanghai + - opcF7DiffPlaces_d11g0v0_Shanghai + - opcF6DiffPlaces_d26g0v0_Shanghai + - opcF7DiffPlaces_d12g0v0_Shanghai + - opcF6DiffPlaces_d27g0v0_Shanghai + - opcF7DiffPlaces_d13g0v0_Shanghai + - opcF6DiffPlaces_d28g0v0_Shanghai + - opcF7DiffPlaces_d14g0v0_Shanghai + - opcF6DiffPlaces_d29g0v0_Shanghai + - opcF7DiffPlaces_d15g0v0_Shanghai + - opcF6DiffPlaces_d30g0v0_Shanghai + - opcF6DiffPlaces_d31g0v0_Shanghai + - opcF7DiffPlaces_d16g0v0_Shanghai + - opcF7DiffPlaces_d2g0v0_Shanghai + - opcF6DiffPlaces_d32g0v0_Shanghai + - opcF6DiffPlaces_d33g0v0_Shanghai + - opcF6DiffPlaces_d34g0v0_Shanghai + - opcF7DiffPlaces_d17g0v0_Shanghai + - opcF7DiffPlaces_d18g0v0_Shanghai + - opcF7DiffPlaces_d19g0v0_Shanghai + - opcF7DiffPlaces_d3g0v0_Shanghai + - opcF7DiffPlaces_d21g0v0_Shanghai + - opcF8DiffPlaces_d0g0v0_Shanghai + - opcF7DiffPlaces_d20g0v0_Shanghai + - opcF7DiffPlaces_d4g0v0_Shanghai + - opcF7DiffPlaces_d22g0v0_Shanghai + - opcF7DiffPlaces_d5g0v0_Shanghai + - opcF7DiffPlaces_d23g0v0_Shanghai + - opcF7DiffPlaces_d6g0v0_Shanghai + - opcF7DiffPlaces_d7g0v0_Shanghai + - opcF7DiffPlaces_d8g0v0_Shanghai + - opcF7DiffPlaces_d24g0v0_Shanghai + - opcF7DiffPlaces_d9g0v0_Shanghai + - opcF7DiffPlaces_d25g0v0_Shanghai + - opcF8DiffPlaces_d1g0v0_Shanghai + - opcF8DiffPlaces_d10g0v0_Shanghai + - opcF7DiffPlaces_d26g0v0_Shanghai + - opcF8DiffPlaces_d11g0v0_Shanghai + - opcF8DiffPlaces_d12g0v0_Shanghai + - opcF7DiffPlaces_d27g0v0_Shanghai + - opcF8DiffPlaces_d13g0v0_Shanghai + - opcF7DiffPlaces_d28g0v0_Shanghai + - opcF8DiffPlaces_d14g0v0_Shanghai + - opcF7DiffPlaces_d29g0v0_Shanghai + - opcF8DiffPlaces_d15g0v0_Shanghai + - opcF7DiffPlaces_d30g0v0_Shanghai + - opcF7DiffPlaces_d31g0v0_Shanghai + - opcF8DiffPlaces_d16g0v0_Shanghai + - opcF7DiffPlaces_d32g0v0_Shanghai + - opcF8DiffPlaces_d2g0v0_Shanghai + - opcF7DiffPlaces_d33g0v0_Shanghai + - opcF7DiffPlaces_d34g0v0_Shanghai + - opcF8DiffPlaces_d17g0v0_Shanghai + - opcF8DiffPlaces_d18g0v0_Shanghai + - opcF8DiffPlaces_d19g0v0_Shanghai + - opcF8DiffPlaces_d3g0v0_Shanghai + - opcF8DiffPlaces_d21g0v0_Shanghai + - opcF9DiffPlaces_d0g0v0_Shanghai + - opcF8DiffPlaces_d4g0v0_Shanghai + - opcF8DiffPlaces_d20g0v0_Shanghai + - opcF8DiffPlaces_d22g0v0_Shanghai + - opcF8DiffPlaces_d5g0v0_Shanghai + - opcF8DiffPlaces_d23g0v0_Shanghai + - opcF8DiffPlaces_d6g0v0_Shanghai + - opcF8DiffPlaces_d7g0v0_Shanghai + - opcF8DiffPlaces_d8g0v0_Shanghai + - opcF8DiffPlaces_d9g0v0_Shanghai + - opcF8DiffPlaces_d24g0v0_Shanghai + - opcF9DiffPlaces_d1g0v0_Shanghai + - opcF8DiffPlaces_d25g0v0_Shanghai + - opcF9DiffPlaces_d10g0v0_Shanghai + - opcF9DiffPlaces_d11g0v0_Shanghai + - opcF8DiffPlaces_d26g0v0_Shanghai + - opcF9DiffPlaces_d12g0v0_Shanghai + - opcF8DiffPlaces_d27g0v0_Shanghai + - opcF9DiffPlaces_d13g0v0_Shanghai + - opcF8DiffPlaces_d28g0v0_Shanghai + - opcF9DiffPlaces_d14g0v0_Shanghai + - opcF8DiffPlaces_d29g0v0_Shanghai + - opcF9DiffPlaces_d15g0v0_Shanghai + - opcF8DiffPlaces_d30g0v0_Shanghai + - opcF9DiffPlaces_d16g0v0_Shanghai + - opcF8DiffPlaces_d31g0v0_Shanghai + - opcF9DiffPlaces_d2g0v0_Shanghai + - opcF8DiffPlaces_d32g0v0_Shanghai + - opcF8DiffPlaces_d33g0v0_Shanghai + - opcF8DiffPlaces_d34g0v0_Shanghai + - opcF9DiffPlaces_d17g0v0_Shanghai + - opcF9DiffPlaces_d18g0v0_Shanghai + - opcF9DiffPlaces_d19g0v0_Shanghai + - opcF9DiffPlaces_d3g0v0_Shanghai + - opcFBDiffPlaces_d0g0v0_Shanghai + - opcF9DiffPlaces_d21g0v0_Shanghai + - opcF9DiffPlaces_d20g0v0_Shanghai + - opcF9DiffPlaces_d4g0v0_Shanghai + - opcF9DiffPlaces_d22g0v0_Shanghai + - opcF9DiffPlaces_d5g0v0_Shanghai + - opcF9DiffPlaces_d23g0v0_Shanghai + - opcF9DiffPlaces_d6g0v0_Shanghai + - opcF9DiffPlaces_d7g0v0_Shanghai + - opcF9DiffPlaces_d8g0v0_Shanghai + - opcF9DiffPlaces_d24g0v0_Shanghai + - opcF9DiffPlaces_d9g0v0_Shanghai + - opcF9DiffPlaces_d25g0v0_Shanghai + - opcFBDiffPlaces_d1g0v0_Shanghai + - opcFBDiffPlaces_d10g0v0_Shanghai + - opcFBDiffPlaces_d11g0v0_Shanghai + - opcF9DiffPlaces_d26g0v0_Shanghai + - opcFBDiffPlaces_d12g0v0_Shanghai + - opcF9DiffPlaces_d27g0v0_Shanghai + - opcFBDiffPlaces_d13g0v0_Shanghai + - opcF9DiffPlaces_d28g0v0_Shanghai + - opcFBDiffPlaces_d14g0v0_Shanghai + - opcF9DiffPlaces_d29g0v0_Shanghai + - opcFBDiffPlaces_d15g0v0_Shanghai + - opcF9DiffPlaces_d30g0v0_Shanghai + - opcFBDiffPlaces_d16g0v0_Shanghai + - opcF9DiffPlaces_d31g0v0_Shanghai + - opcFBDiffPlaces_d2g0v0_Shanghai + - opcF9DiffPlaces_d32g0v0_Shanghai + - opcF9DiffPlaces_d33g0v0_Shanghai + - opcF9DiffPlaces_d34g0v0_Shanghai + - opcFBDiffPlaces_d17g0v0_Shanghai + - opcFBDiffPlaces_d18g0v0_Shanghai + - opcFBDiffPlaces_d19g0v0_Shanghai + - opcFBDiffPlaces_d3g0v0_Shanghai + - opcFBDiffPlaces_d21g0v0_Shanghai + - opcFCDiffPlaces_d0g0v0_Shanghai + - opcFBDiffPlaces_d4g0v0_Shanghai + - opcFBDiffPlaces_d20g0v0_Shanghai + - opcFBDiffPlaces_d22g0v0_Shanghai + - opcFBDiffPlaces_d23g0v0_Shanghai + - opcFBDiffPlaces_d5g0v0_Shanghai + - opcFBDiffPlaces_d6g0v0_Shanghai + - opcFBDiffPlaces_d7g0v0_Shanghai + - opcFBDiffPlaces_d8g0v0_Shanghai + - opcFBDiffPlaces_d24g0v0_Shanghai + - opcFBDiffPlaces_d9g0v0_Shanghai + - opcFCDiffPlaces_d1g0v0_Shanghai + - opcFBDiffPlaces_d25g0v0_Shanghai + - opcFCDiffPlaces_d10g0v0_Shanghai + - opcFBDiffPlaces_d26g0v0_Shanghai + - opcFCDiffPlaces_d11g0v0_Shanghai + - opcFCDiffPlaces_d12g0v0_Shanghai + - opcFBDiffPlaces_d27g0v0_Shanghai + - opcFCDiffPlaces_d13g0v0_Shanghai + - opcFBDiffPlaces_d28g0v0_Shanghai + - opcFCDiffPlaces_d14g0v0_Shanghai + - opcFBDiffPlaces_d29g0v0_Shanghai + - opcFCDiffPlaces_d15g0v0_Shanghai + - opcFBDiffPlaces_d30g0v0_Shanghai + - opcFCDiffPlaces_d16g0v0_Shanghai + - opcFBDiffPlaces_d31g0v0_Shanghai + - opcFCDiffPlaces_d2g0v0_Shanghai + - opcFBDiffPlaces_d32g0v0_Shanghai + - opcFBDiffPlaces_d33g0v0_Shanghai + - opcFBDiffPlaces_d34g0v0_Shanghai + - opcFCDiffPlaces_d17g0v0_Shanghai + - opcFCDiffPlaces_d18g0v0_Shanghai + - opcFCDiffPlaces_d19g0v0_Shanghai + - opcFCDiffPlaces_d3g0v0_Shanghai + - opcFCDiffPlaces_d21g0v0_Shanghai + - opcFEDiffPlaces_d0g0v0_Shanghai + - opcFCDiffPlaces_d4g0v0_Shanghai + - opcFCDiffPlaces_d20g0v0_Shanghai + - opcFCDiffPlaces_d22g0v0_Shanghai + - opcFCDiffPlaces_d5g0v0_Shanghai + - opcFCDiffPlaces_d23g0v0_Shanghai + - opcFCDiffPlaces_d6g0v0_Shanghai + - opcFCDiffPlaces_d7g0v0_Shanghai + - opcFCDiffPlaces_d8g0v0_Shanghai + - opcFCDiffPlaces_d24g0v0_Shanghai + - opcFCDiffPlaces_d9g0v0_Shanghai + - opcFEDiffPlaces_d1g0v0_Shanghai + - opcFCDiffPlaces_d25g0v0_Shanghai + - opcFEDiffPlaces_d10g0v0_Shanghai + - opcFCDiffPlaces_d26g0v0_Shanghai + - opcFEDiffPlaces_d11g0v0_Shanghai + - opcFEDiffPlaces_d12g0v0_Shanghai + - opcFEDiffPlaces_d13g0v0_Shanghai + - opcFCDiffPlaces_d27g0v0_Shanghai + - opcFCDiffPlaces_d28g0v0_Shanghai + - opcFEDiffPlaces_d14g0v0_Shanghai + - opcFCDiffPlaces_d29g0v0_Shanghai + - opcFEDiffPlaces_d15g0v0_Shanghai + - opcFEDiffPlaces_d16g0v0_Shanghai + - opcFCDiffPlaces_d30g0v0_Shanghai + - opcFCDiffPlaces_d31g0v0_Shanghai + - opcFEDiffPlaces_d2g0v0_Shanghai + - opcFCDiffPlaces_d32g0v0_Shanghai + - opcFCDiffPlaces_d33g0v0_Shanghai + - opcFCDiffPlaces_d34g0v0_Shanghai + - opcFEDiffPlaces_d17g0v0_Shanghai + - opcFEDiffPlaces_d18g0v0_Shanghai + - opcFEDiffPlaces_d19g0v0_Shanghai + - opcFEDiffPlaces_d3g0v0_Shanghai + - opcFEDiffPlaces_d21g0v0_Shanghai + - opcFEDiffPlaces_d20g0v0_Shanghai + - opcFEDiffPlaces_d4g0v0_Shanghai + - opcFEDiffPlaces_d22g0v0_Shanghai + - opcFEDiffPlaces_d5g0v0_Shanghai + - opcFEDiffPlaces_d23g0v0_Shanghai + - opcFEDiffPlaces_d6g0v0_Shanghai + - opcFEDiffPlaces_d7g0v0_Shanghai + - opcFEDiffPlaces_d8g0v0_Shanghai + - opcFEDiffPlaces_d24g0v0_Shanghai + - opcFEDiffPlaces_d9g0v0_Shanghai + - opcFEDiffPlaces_d25g0v0_Shanghai + - opcFEDiffPlaces_d26g0v0_Shanghai + - opcFEDiffPlaces_d27g0v0_Shanghai + - opcFEDiffPlaces_d28g0v0_Shanghai + - opcFEDiffPlaces_d29g0v0_Shanghai + - opcFEDiffPlaces_d30g0v0_Shanghai + - opcFEDiffPlaces_d31g0v0_Shanghai + - opcFEDiffPlaces_d32g0v0_Shanghai + - opcFEDiffPlaces_d33g0v0_Shanghai + - opcFEDiffPlaces_d34g0v0_Shanghai + - operationDiffGas_d6g0v0_Shanghai + - operationDiffGas_d1g0v0_Shanghai + - operationDiffGas_d0g0v0_Shanghai + - operationDiffGas_d7g0v0_Shanghai + - operationDiffGas_d8g0v0_Shanghai + - operationDiffGas_d9g0v0_Shanghai + stAttackTest: + - CrashingTransaction_d0g0v0_Shanghai + - ContractCreationSpam_d0g0v0_Shanghai + stBugs: + - randomStatetestDEFAULT_minus_Tue_07_58_41_minus_15153_minus_575192_d0g0v0_Shanghai + stCallCodes: + - callcode_checkPC_d0g0v0_Shanghai + - callcodeDynamicCode_d2g0v0_Shanghai + - callcodeDynamicCode_d3g0v0_Shanghai + - callcallcall_ABCB_RECURSIVE_d0g0v0_Shanghai + - callcallcallcode_ABCB_RECURSIVE_d0g0v0_Shanghai + - callcallcodecall_ABCB_RECURSIVE_d0g0v0_Shanghai + - callcallcodecallcode_ABCB_RECURSIVE_d0g0v0_Shanghai + - callcodecallcall_ABCB_RECURSIVE_d0g0v0_Shanghai + - callcodecallcallcode_ABCB_RECURSIVE_d0g0v0_Shanghai + - callcodecallcodecall_ABCB_RECURSIVE_d0g0v0_Shanghai + - callcodecallcodecallcode_ABCB_RECURSIVE_d0g0v0_Shanghai + stCallCreateCallCodeTest: + - callOutput3Fail_d0g0v0_Shanghai + - callOutput3partialFail_d0g0v0_Shanghai + - callcodeOutput3Fail_d0g0v0_Shanghai + - callcodeOutput3partialFail_d0g0v0_Shanghai + - contractCreationMakeCallThatAskMoreGasThenTransactionProvided_d0g1v0_Shanghai + - createNameRegistratorPreStore1NotEnoughGas_d0g0v0_Shanghai + - createInitFailUndefinedInstruction_d0g0v0_Shanghai + - createJS_NoCollision_d0g0v0_Shanghai + - CallRecursiveBombPreCall_d0g0v0_Shanghai + - Call1024BalanceTooLow_d0g0v0_Shanghai + - Callcode1024BalanceTooLow_d0g0v0_Shanghai + - Call1024OOG_d0g2v0_Shanghai + - Call1024OOG_d0g0v0_Shanghai + - Call1024OOG_d0g1v0_Shanghai + - Call1024OOG_d0g3v0_Shanghai + - Callcode1024OOG_d0g0v0_Shanghai + - Callcode1024OOG_d0g1v0_Shanghai + - createInitFailStackSizeLargerThan1024_d0g0v0_Shanghai + - Call1024PreCalls_d0g1v0_Shanghai + - Call1024PreCalls_d0g0v0_Shanghai + stChainId: + - chainId_d0g0v0_Shanghai + stCreate2: + - CREATE2_Suicide_d0g0v0_Shanghai + - CREATE2_Suicide_d10g0v0_Shanghai + - CREATE2_Suicide_d11g0v0_Shanghai + - CREATE2_Suicide_d2g0v0_Shanghai + - CREATE2_Suicide_d1g0v0_Shanghai + - CREATE2_Suicide_d4g0v0_Shanghai + - CREATE2_Suicide_d3g0v0_Shanghai + - CREATE2_Suicide_d6g0v0_Shanghai + - CREATE2_Suicide_d5g0v0_Shanghai + - CREATE2_Suicide_d7g0v0_Shanghai + - CREATE2_Suicide_d8g0v0_Shanghai + - CREATE2_Suicide_d9g0v0_Shanghai + - Create2OOGFromCallRefunds_d18g0v0_Shanghai + - Create2OOGafterInitCodeReturndataSize_d0g0v0_Shanghai + - Create2OOGFromCallRefunds_d21g0v0_Shanghai + - Create2OOGafterInitCode_d0g0v0_Shanghai + - Create2OOGafterInitCode_d0g1v0_Shanghai + - Create2OOGafterInitCodeRevert2_d0g0v0_Shanghai + - Create2OOGafterInitCodeRevert_d0g0v0_Shanghai + - CreateMessageRevertedOOGInInit_d0g0v0_Shanghai + - CreateMessageReverted_d0g0v0_Shanghai + - CreateMessageRevertedOOGInInit_d0g1v0_Shanghai + - create2InitCodes_d0g0v0_Shanghai + - RevertInCreateInInitCreate2_d0g0v0_Shanghai + - create2InitCodes_d1g0v0_Shanghai + - create2InitCodes_d3g0v0_Shanghai + - create2InitCodes_d2g0v0_Shanghai + - create2InitCodes_d4g0v0_Shanghai + - create2InitCodes_d7g0v0_Shanghai + - create2InitCodes_d5g0v0_Shanghai + - create2InitCodes_d8g0v0_Shanghai + - create2InitCodes_d6g0v0_Shanghai + - create2callPrecompiles_d1g0v0_Shanghai + - create2callPrecompiles_d2g0v0_Shanghai + - create2callPrecompiles_d3g0v0_Shanghai + - create2callPrecompiles_d5g0v0_Shanghai + - create2callPrecompiles_d0g0v0_Shanghai + - create2collisionBalance_d0g0v0_Shanghai + - create2collisionBalance_d3g0v0_Shanghai + - create2collisionBalance_d1g0v0_Shanghai + - create2collisionBalance_d2g0v0_Shanghai + - create2callPrecompiles_d4g0v0_Shanghai + - create2collisionCode2_d0g0v0_Shanghai + - create2collisionCode2_d1g0v0_Shanghai + - create2checkFieldsInInitcode_d7g0v0_Shanghai + - create2collisionCode_d0g0v0_Shanghai + - create2collisionCode_d1g0v0_Shanghai + - create2collisionCode_d2g0v0_Shanghai + - create2collisionNonce_d0g0v0_Shanghai + - create2callPrecompiles_d6g0v0_Shanghai + - create2collisionNonce_d1g0v0_Shanghai + - create2collisionNonce_d2g0v0_Shanghai + - create2checkFieldsInInitcode_d6g0v0_Shanghai + - create2collisionSelfdestructed2_d0g0v0_Shanghai + - create2checkFieldsInInitcode_d5g0v0_Shanghai + - create2noCash_d2g0v0_Shanghai + - create2collisionSelfdestructedOOG_d0g0v0_Shanghai + - create2collisionSelfdestructed2_d1g0v0_Shanghai + - create2collisionSelfdestructedOOG_d1g0v0_Shanghai + - create2collisionSelfdestructedOOG_d2g0v0_Shanghai + - create2collisionStorage_d0g0v0_Shanghai + - create2collisionSelfdestructed_d0g0v0_Shanghai + - create2collisionSelfdestructed_d1g0v0_Shanghai + - create2collisionStorage_d1g0v0_Shanghai + - create2collisionSelfdestructed_d2g0v0_Shanghai + - create2callPrecompiles_d7g0v0_Shanghai + - create2collisionStorage_d2g0v0_Shanghai + - Create2OnDepth1023_d0g0v0_Shanghai + - Create2OnDepth1024_d0g0v0_Shanghai + stCallDelegateCodesCallCodeHomestead: + - callcallcallcode_ABCB_RECURSIVE_d0g0v0_Shanghai + - callcallcodecall_ABCB_RECURSIVE_d0g0v0_Shanghai + - callcallcodecallcode_ABCB_RECURSIVE_d0g0v0_Shanghai + - callcodecallcall_ABCB_RECURSIVE_d0g0v0_Shanghai + - callcodecallcallcode_ABCB_RECURSIVE_d0g0v0_Shanghai + - callcodecallcodecall_ABCB_RECURSIVE_d0g0v0_Shanghai + - callcodecallcodecallcode_ABCB_RECURSIVE_d0g0v0_Shanghai + stCallDelegateCodesHomestead: + - callcallcallcode_ABCB_RECURSIVE_d0g0v0_Shanghai + - callcallcodecall_ABCB_RECURSIVE_d0g0v0_Shanghai + - callcallcodecallcode_ABCB_RECURSIVE_d0g0v0_Shanghai + - callcodecallcall_ABCB_RECURSIVE_d0g0v0_Shanghai + - callcodecallcallcode_ABCB_RECURSIVE_d0g0v0_Shanghai + - callcodecallcodecall_ABCB_RECURSIVE_d0g0v0_Shanghai + - callcodecallcodecallcode_ABCB_RECURSIVE_d0g0v0_Shanghai + stCreateTest: + - CREATE_EContractCreateEContractInInit_Tr_d0g0v0_Shanghai + - CREATE_EContractCreateNEContractInInitOOG_Tr_d0g0v0_Shanghai + - CREATE_EmptyContractWithBalance_d0g0v0_Shanghai + - CREATE_EContractCreateNEContractInInit_Tr_d0g0v0_Shanghai + - CREATE_EmptyContractAndCallIt_0wei_d0g0v0_Shanghai + - CREATE_EmptyContractAndCallIt_1wei_d0g0v0_Shanghai + - CREATE_EContract_ThenCALLToNonExistentAcc_d0g0v0_Shanghai + - CREATE_EmptyContract_d0g0v0_Shanghai + - CREATE_EmptyContractWithStorage_d0g0v0_Shanghai + - CREATE_empty000CreateinInitCode_Transaction_d0g0v0_Shanghai + - CREATE_EmptyContractWithStorageAndCallIt_0wei_d0g0v0_Shanghai + - CREATE_EmptyContractWithStorageAndCallIt_1wei_d0g0v0_Shanghai + - CodeInConstructor_d0g0v0_Shanghai + - CodeInConstructor_d1g0v0_Shanghai + - CreateCollisionToEmpty_d0g0v0_Shanghai + - CreateCollisionToEmpty_d0g0v1_Shanghai + - CreateCollisionToEmpty_d1g0v0_Shanghai + - CreateCollisionToEmpty_d1g0v1_Shanghai + - CreateCollisionToEmpty_d2g0v0_Shanghai + - CreateCollisionToEmpty_d2g0v1_Shanghai + - CreateCollisionResults_d0g0v0_Shanghai + - CreateOOGFromCallRefunds_d18g0v0_Shanghai + - CreateCollisionResults_d1g0v0_Shanghai + - CreateOOGFromCallRefunds_d21g0v0_Shanghai + - CreateOOGFromEOARefunds_d18g0v0_Shanghai + - CreateOOGFromEOARefunds_d21g0v0_Shanghai + - CreateOOGafterInitCodeReturndata2_d0g0v0_Shanghai + - CreateOOGafterInitCodeRevert2_d1g0v0_Shanghai + - CreateAddressWarmAfterFail_d7g0v0_Shanghai + - CreateTransactionHighNonce_d0g0v0_Shanghai + - CreateTransactionHighNonce_d0g0v1_Shanghai + - TransactionCollisionToEmpty_d0g0v0_Shanghai + - TransactionCollisionToEmpty_d0g0v1_Shanghai + - CreateAddressWarmAfterFail_d7g0v1_Shanghai + - CreateResults_d10g0v0_Shanghai + - CreateResults_d12g0v0_Shanghai + - CreateResults_d14g0v0_Shanghai + - CreateResults_d16g0v0_Shanghai + - CreateResults_d11g0v0_Shanghai + - CreateResults_d13g0v0_Shanghai + - CreateResults_d15g0v0_Shanghai + - CreateResults_d0g0v0_Shanghai + - CreateResults_d17g0v0_Shanghai + - createLargeResult_d0g0v0_Shanghai + - CreateResults_d1g0v0_Shanghai + - CreateResults_d2g0v0_Shanghai + - CreateResults_d3g0v0_Shanghai + - createLargeResult_d2g0v0_Shanghai + - CreateResults_d4g0v0_Shanghai + - createLargeResult_d1g0v0_Shanghai + - createLargeResult_d3g0v0_Shanghai + - CreateResults_d8g0v0_Shanghai + - CreateResults_d9g0v0_Shanghai + - CreateOOGafterMaxCodesize_d2g0v0_Shanghai + - CreateResults_d5g0v0_Shanghai + - CreateOOGafterMaxCodesize_d0g0v0_Shanghai + - CreateOOGafterMaxCodesize_d5g0v0_Shanghai + - CreateResults_d6g0v0_Shanghai + - CreateOOGafterMaxCodesize_d1g0v0_Shanghai + - CreateOOGafterMaxCodesize_d3g0v0_Shanghai + - CreateResults_d7g0v0_Shanghai + - createLargeResult_d8g0v0_Shanghai + - createLargeResult_d9g0v0_Shanghai + - createLargeResult_d10g0v0_Shanghai + - createLargeResult_d11g0v0_Shanghai + - createLargeResult_d6g0v0_Shanghai + - createLargeResult_d12g0v0_Shanghai + - createLargeResult_d7g0v0_Shanghai + - createLargeResult_d13g0v0_Shanghai + - createLargeResult_d14g0v0_Shanghai + - createLargeResult_d15g0v0_Shanghai + - createLargeResult_d4g0v0_Shanghai + - createLargeResult_d5g0v0_Shanghai + stDelegatecallTestHomestead: + - callOutput3partialFail_d0g0v0_Shanghai + - delegatecodeDynamicCode_d0g0v0_Shanghai + - Call1024BalanceTooLow_d0g0v0_Shanghai + - CallRecursiveBombPreCall_d0g0v0_Shanghai + - Call1024OOG_d0g0v0_Shanghai + - Call1024OOG_d0g1v0_Shanghai + - Delegatecall1024_d0g0v0_Shanghai + - Delegatecall1024OOG_d0g0v0_Shanghai + - Call1024PreCalls_d0g1v0_Shanghai + - Call1024PreCalls_d0g2v0_Shanghai + stEIP150Specific: + - CreateAndGasInsideCreate_d0g0v0_Shanghai + - SuicideToExistingContract_d0g0v0_Shanghai + - SuicideToNotExistingContract_d0g0v0_Shanghai + - Transaction64Rule_integerBoundaries_d10g0v0_Shanghai + - Transaction64Rule_integerBoundaries_d11g0v0_Shanghai + - NewGasPriceForCodes_d0g0v0_Shanghai + stEIP150singleCodeGasPrices: + - RawCallGasValueTransferAsk_d0g0v0_Shanghai + - RawCallGasValueTransfer_d0g0v0_Shanghai + - RawCallCodeGasMemoryAsk_d0g0v0_Shanghai + - RawCallCodeGasMemory_d0g0v0_Shanghai + - RawCallCodeGasValueTransferMemory_d0g0v0_Shanghai + - RawCallCodeGasValueTransferMemoryAsk_d0g0v0_Shanghai + - RawCreateGasValueTransfer_d0g0v0_Shanghai + - RawCreateGas_d0g0v0_Shanghai + - RawCallGasValueTransferMemory_d0g0v0_Shanghai + - RawCallGasValueTransferMemoryAsk_d0g0v0_Shanghai + - RawCallMemoryGasAsk_d0g0v0_Shanghai + - RawCallMemoryGas_d0g0v0_Shanghai + - RawExtCodeCopyGas_d0g0v0_Shanghai + - RawCreateFailGasValueTransfer2_d0g0v0_Shanghai + - eip2929OOG_d0g0v0_Shanghai + - RawCreateGasMemory_d0g0v0_Shanghai + - RawCreateGasValueTransferMemory_d0g0v0_Shanghai + - RawExtCodeCopyMemoryGas_d0g0v0_Shanghai + - RawDelegateCallGasMemoryAsk_d0g0v0_Shanghai + - RawDelegateCallGasMemory_d0g0v0_Shanghai + - eip2929_d0g0v0_Shanghai + - eip2929_d10g0v0_Shanghai + - eip2929_d11g0v0_Shanghai + - eip2929_d12g0v0_Shanghai + - eip2929_d14g0v0_Shanghai + - eip2929_d13g0v0_Shanghai + - eip2929_d15g0v0_Shanghai + - eip2929_d16g0v0_Shanghai + - eip2929_d17g0v0_Shanghai + - eip2929_d18g0v0_Shanghai + - eip2929_d19g0v0_Shanghai + - eip2929_d1g0v0_Shanghai + - eip2929_d21g0v0_Shanghai + - eip2929_d20g0v0_Shanghai + - eip2929_d22g0v0_Shanghai + - eip2929_d23g0v0_Shanghai + - eip2929_d24g0v0_Shanghai + - eip2929_d25g0v0_Shanghai + - eip2929_d26g0v0_Shanghai + - eip2929_d27g0v0_Shanghai + - eip2929_d28g0v0_Shanghai + - eip2929_d29g0v0_Shanghai + - eip2929_d2g0v0_Shanghai + - eip2929_d30g0v0_Shanghai + - eip2929_minus_ff_d0g0v0_Shanghai + - eip2929_minus_ff_d2g0v0_Shanghai + - eip2929_minus_ff_d1g0v0_Shanghai + - eip2929_minus_ff_d4g0v0_Shanghai + - eip2929_minus_ff_d3g0v0_Shanghai + - eip2929_d31g0v0_Shanghai + - eip2929_minus_ff_d5g0v0_Shanghai + - eip2929_d33g0v0_Shanghai + - eip2929_minus_ff_d6g0v0_Shanghai + - eip2929_d32g0v0_Shanghai + - eip2929_minus_ff_d7g0v0_Shanghai + - eip2929_minus_ff_d8g0v0_Shanghai + - eip2929_d34g0v0_Shanghai + - eip2929_d35g0v0_Shanghai + - eip2929_d36g0v0_Shanghai + - eip2929_d37g0v0_Shanghai + - eip2929_d3g0v0_Shanghai + - eip2929_d4g0v0_Shanghai + - eip2929_d5g0v0_Shanghai + - eip2929_d7g0v0_Shanghai + - eip2929_d6g0v0_Shanghai + - eip2929_d8g0v0_Shanghai + - eip2929_d9g0v0_Shanghai + - gasCostBerlin_d0g0v0_Shanghai + - gasCostBerlin_d100g0v0_Shanghai + - gasCostBerlin_d101g0v0_Shanghai + - gasCostBerlin_d102g0v0_Shanghai + - gasCostBerlin_d103g0v0_Shanghai + - gasCostBerlin_d104g0v0_Shanghai + - gasCostBerlin_d105g0v0_Shanghai + - gasCostBerlin_d106g0v0_Shanghai + - gasCostBerlin_d107g0v0_Shanghai + - gasCostBerlin_d108g0v0_Shanghai + - gasCostBerlin_d109g0v0_Shanghai + - gasCostBerlin_d10g0v0_Shanghai + - gasCostBerlin_d11g0v0_Shanghai + - gasCostBerlin_d12g0v0_Shanghai + - gasCostBerlin_d13g0v0_Shanghai + - gasCostBerlin_d14g0v0_Shanghai + - gasCostBerlin_d15g0v0_Shanghai + - gasCostBerlin_d17g0v0_Shanghai + - gasCostBerlin_d18g0v0_Shanghai + - gasCostBerlin_d16g0v0_Shanghai + - gasCostBerlin_d19g0v0_Shanghai + - gasCostBerlin_d1g0v0_Shanghai + - gasCostBerlin_d20g0v0_Shanghai + - gasCostBerlin_d21g0v0_Shanghai + - gasCostBerlin_d22g0v0_Shanghai + - gasCostBerlin_d23g0v0_Shanghai + - gasCostBerlin_d24g0v0_Shanghai + - gasCostBerlin_d25g0v0_Shanghai + - gasCostBerlin_d26g0v0_Shanghai + - gasCostBerlin_d27g0v0_Shanghai + - gasCostBerlin_d29g0v0_Shanghai + - gasCostBerlin_d28g0v0_Shanghai + - gasCostBerlin_d2g0v0_Shanghai + - gasCostBerlin_d30g0v0_Shanghai + - gasCostBerlin_d31g0v0_Shanghai + - gasCostBerlin_d32g0v0_Shanghai + - gasCostBerlin_d33g0v0_Shanghai + - gasCostBerlin_d34g0v0_Shanghai + - gasCostBerlin_d35g0v0_Shanghai + - gasCostBerlin_d36g0v0_Shanghai + - gasCostBerlin_d37g0v0_Shanghai + - gasCostBerlin_d38g0v0_Shanghai + - gasCostBerlin_d39g0v0_Shanghai + - gasCostBerlin_d3g0v0_Shanghai + - gasCostBerlin_d40g0v0_Shanghai + - gasCostBerlin_d41g0v0_Shanghai + - gasCostBerlin_d42g0v0_Shanghai + - gasCostBerlin_d44g0v0_Shanghai + - gasCostBerlin_d43g0v0_Shanghai + - gasCostBerlin_d45g0v0_Shanghai + - gasCostBerlin_d46g0v0_Shanghai + - gasCostBerlin_d47g0v0_Shanghai + - gasCostBerlin_d48g0v0_Shanghai + - gasCostBerlin_d49g0v0_Shanghai + - gasCostBerlin_d4g0v0_Shanghai + - gasCostBerlin_d50g0v0_Shanghai + - gasCostBerlin_d51g0v0_Shanghai + - gasCostBerlin_d52g0v0_Shanghai + - gasCostBerlin_d53g0v0_Shanghai + - gasCostBerlin_d54g0v0_Shanghai + - gasCostBerlin_d55g0v0_Shanghai + - gasCostBerlin_d57g0v0_Shanghai + - gasCostBerlin_d56g0v0_Shanghai + - gasCostBerlin_d58g0v0_Shanghai + - gasCostBerlin_d59g0v0_Shanghai + - gasCostBerlin_d5g0v0_Shanghai + - gasCostBerlin_d60g0v0_Shanghai + - gasCostBerlin_d61g0v0_Shanghai + - gasCostBerlin_d62g0v0_Shanghai + - gasCostBerlin_d63g0v0_Shanghai + - gasCostBerlin_d64g0v0_Shanghai + - gasCostBerlin_d66g0v0_Shanghai + - gasCostBerlin_d67g0v0_Shanghai + - gasCostBerlin_d65g0v0_Shanghai + - gasCostBerlin_d69g0v0_Shanghai + - gasCostBerlin_d6g0v0_Shanghai + - gasCostBerlin_d68g0v0_Shanghai + - gasCostBerlin_d70g0v0_Shanghai + - gasCostBerlin_d71g0v0_Shanghai + - gasCostBerlin_d72g0v0_Shanghai + - gasCostBerlin_d74g0v0_Shanghai + - gasCostBerlin_d76g0v0_Shanghai + - gasCostBerlin_d73g0v0_Shanghai + - gasCostBerlin_d77g0v0_Shanghai + - gasCostBerlin_d75g0v0_Shanghai + - gasCostExp_d0g0v0_Shanghai + - gasCostBerlin_d78g0v0_Shanghai + - gasCostExp_d1g0v0_Shanghai + - gasCostExp_d2g0v0_Shanghai + - gasCostBerlin_d79g0v0_Shanghai + - gasCostExp_d3g0v0_Shanghai + - gasCostExp_d4g0v0_Shanghai + - gasCostExp_d5g0v0_Shanghai + - gasCostExp_d6g0v0_Shanghai + - gasCostExp_d7g0v0_Shanghai + - gasCostExp_d8g0v0_Shanghai + - gasCostBerlin_d7g0v0_Shanghai + - gasCostMemSeg_d0g0v0_Shanghai + - gasCostJump_d0g0v0_Shanghai + - gasCostJump_d1g0v0_Shanghai + - gasCostJump_d2g0v0_Shanghai + - gasCostBerlin_d80g0v0_Shanghai + - gasCostMemSeg_d10g0v0_Shanghai + - gasCostMemSeg_d11g0v0_Shanghai + - gasCostMemSeg_d12g0v0_Shanghai + - gasCostMemSeg_d13g0v0_Shanghai + - gasCostMemSeg_d14g0v0_Shanghai + - gasCostMemSeg_d15g0v0_Shanghai + - gasCostBerlin_d81g0v0_Shanghai + - gasCostMemSeg_d1g0v0_Shanghai + - gasCostMemSeg_d16g0v0_Shanghai + - gasCostMemSeg_d17g0v0_Shanghai + - gasCostMemSeg_d18g0v0_Shanghai + - gasCostMemSeg_d19g0v0_Shanghai + - gasCostMemSeg_d2g0v0_Shanghai + - gasCostMemSeg_d20g0v0_Shanghai + - gasCostMemSeg_d21g0v0_Shanghai + - gasCostMemSeg_d22g0v0_Shanghai + - gasCostMemSeg_d23g0v0_Shanghai + - gasCostMemSeg_d24g0v0_Shanghai + - gasCostMemSeg_d25g0v0_Shanghai + - gasCostMemSeg_d26g0v0_Shanghai + - gasCostMemSeg_d27g0v0_Shanghai + - gasCostMemSeg_d28g0v0_Shanghai + - gasCostMemSeg_d29g0v0_Shanghai + - gasCostMemSeg_d3g0v0_Shanghai + - gasCostMemSeg_d31g0v0_Shanghai + - gasCostMemSeg_d32g0v0_Shanghai + - gasCostMemSeg_d33g0v0_Shanghai + - gasCostMemSeg_d34g0v0_Shanghai + - gasCostMemSeg_d36g0v0_Shanghai + - gasCostMemSeg_d37g0v0_Shanghai + - gasCostMemSeg_d38g0v0_Shanghai + - gasCostMemSeg_d39g0v0_Shanghai + - gasCostMemSeg_d41g0v0_Shanghai + - gasCostMemSeg_d4g0v0_Shanghai + - gasCostMemSeg_d42g0v0_Shanghai + - gasCostMemSeg_d43g0v0_Shanghai + - gasCostMemSeg_d44g0v0_Shanghai + - gasCostMemSeg_d46g0v0_Shanghai + - gasCostMemSeg_d47g0v0_Shanghai + - gasCostMemSeg_d48g0v0_Shanghai + - gasCostMemSeg_d49g0v0_Shanghai + - gasCostMemSeg_d5g0v0_Shanghai + - gasCostBerlin_d83g0v0_Shanghai + - gasCostBerlin_d82g0v0_Shanghai + - gasCostBerlin_d84g0v0_Shanghai + - gasCostMemSeg_d6g0v0_Shanghai + - gasCostMemSeg_d7g0v0_Shanghai + - gasCostMemSeg_d8g0v0_Shanghai + - gasCostBerlin_d85g0v0_Shanghai + - gasCostMemSeg_d9g0v0_Shanghai + - gasCostBerlin_d86g0v0_Shanghai + - gasCostMemSeg_d51g0v0_Shanghai + - gasCostBerlin_d87g0v0_Shanghai + - gasCostMemSeg_d52g0v0_Shanghai + - gasCostMemSeg_d53g0v0_Shanghai + - gasCostBerlin_d88g0v0_Shanghai + - gasCostBerlin_d89g0v0_Shanghai + - gasCostMemSeg_d54g0v0_Shanghai + - gasCostBerlin_d8g0v0_Shanghai + - gasCostBerlin_d90g0v0_Shanghai + - gasCostBerlin_d91g0v0_Shanghai + - gasCostBerlin_d92g0v0_Shanghai + - gasCostBerlin_d93g0v0_Shanghai + - gasCostBerlin_d94g0v0_Shanghai + - gasCostBerlin_d95g0v0_Shanghai + - gasCostBerlin_d98g0v0_Shanghai + - gasCostBerlin_d96g0v0_Shanghai + - gasCostBerlin_d97g0v0_Shanghai + - gasCostMemory_d0g0v0_Shanghai + - gasCostBerlin_d9g0v0_Shanghai + - gasCostBerlin_d99g0v0_Shanghai + - gasCostMemory_d10g0v0_Shanghai + - gasCostMemory_d11g0v0_Shanghai + - gasCostMemory_d14g0v0_Shanghai + - gasCostMemory_d12g0v0_Shanghai + - gasCostMemory_d13g0v0_Shanghai + - gasCostMemory_d15g0v0_Shanghai + - gasCostMemory_d17g0v0_Shanghai + - gasCostMemory_d16g0v0_Shanghai + - gasCostMemory_d19g0v0_Shanghai + - gasCostMemory_d18g0v0_Shanghai + - gasCostMemory_d1g0v0_Shanghai + - gasCostMemory_d20g0v0_Shanghai + - gasCostMemory_d23g0v0_Shanghai + - gasCostMemory_d21g0v0_Shanghai + - gasCostMemory_d22g0v0_Shanghai + - gasCostMemory_d24g0v0_Shanghai + - gasCostMemory_d25g0v0_Shanghai + - gasCostMemory_d26g0v0_Shanghai + - gasCostMemory_d27g0v0_Shanghai + - gasCostMemory_d28g0v0_Shanghai + - gasCostMemory_d29g0v0_Shanghai + - gasCostMemory_d2g0v0_Shanghai + - gasCostMemory_d30g0v0_Shanghai + - gasCostMemory_d31g0v0_Shanghai + - gasCostMemory_d32g0v0_Shanghai + - gasCostMemory_d33g0v0_Shanghai + - gasCostMemory_d34g0v0_Shanghai + - gasCostMemory_d35g0v0_Shanghai + - gasCostMemory_d3g0v0_Shanghai + - gasCostMemory_d36g0v0_Shanghai + - gasCostMemory_d37g0v0_Shanghai + - gasCostMemory_d38g0v0_Shanghai + - gasCostMemory_d39g0v0_Shanghai + - gasCostMemory_d40g0v0_Shanghai + - gasCostMemory_d41g0v0_Shanghai + - gasCostMemory_d42g0v0_Shanghai + - gasCostMemory_d43g0v0_Shanghai + - gasCostMemory_d44g0v0_Shanghai + - gasCostMemory_d45g0v0_Shanghai + - gasCostMemory_d47g0v0_Shanghai + - gasCostMemory_d46g0v0_Shanghai + - gasCostMemory_d4g0v0_Shanghai + - gasCostMemory_d48g0v0_Shanghai + - gasCostReturn_d0g0v0_Shanghai + - gasCostMemory_d49g0v0_Shanghai + - gasCostMemory_d50g0v0_Shanghai + - gasCostMemory_d51g0v0_Shanghai + - gasCostMemory_d52g0v0_Shanghai + - gasCostMemory_d53g0v0_Shanghai + - gasCostMemory_d5g0v0_Shanghai + - gasCostMemory_d54g0v0_Shanghai + - gasCostMemory_d55g0v0_Shanghai + - gasCostMemory_d56g0v0_Shanghai + - gasCostMemory_d57g0v0_Shanghai + - gasCostMemory_d58g0v0_Shanghai + - gasCostMemory_d59g0v0_Shanghai + - gasCostMemory_d60g0v0_Shanghai + - gasCostMemory_d6g0v0_Shanghai + - gasCostMemory_d61g0v0_Shanghai + - gasCostMemory_d62g0v0_Shanghai + - gasCostMemory_d63g0v0_Shanghai + - gasCostMemory_d64g0v0_Shanghai + - gasCostMemory_d65g0v0_Shanghai + - gasCostMemory_d8g0v0_Shanghai + - gasCostMemory_d7g0v0_Shanghai + - gasCostMemory_d9g0v0_Shanghai + - gasCostMemory_d66g0v0_Shanghai + - gasCostMemory_d67g0v0_Shanghai + - gasCostMemory_d68g0v0_Shanghai + - gasCostMemory_d69g0v0_Shanghai + - gasCostMemory_d70g0v0_Shanghai + - gasCostMemory_d71g0v0_Shanghai + - gasCostMemory_d72g0v0_Shanghai + - gasCostMemory_d73g0v0_Shanghai + - gasCostMemory_d74g0v0_Shanghai + stEIP1559: + - baseFeeDiffPlaces_d0g0v0_Shanghai + - baseFeeDiffPlaces_d1g0v0_Shanghai + - baseFeeDiffPlaces_d10g0v0_Shanghai + - baseFeeDiffPlaces_d2g0v0_Shanghai + - baseFeeDiffPlaces_d11g0v0_Shanghai + - baseFeeDiffPlaces_d12g0v0_Shanghai + - baseFeeDiffPlaces_d3g0v0_Shanghai + - baseFeeDiffPlaces_d13g0v0_Shanghai + - baseFeeDiffPlaces_d4g0v0_Shanghai + - baseFeeDiffPlaces_d14g0v0_Shanghai + - baseFeeDiffPlaces_d15g0v0_Shanghai + - baseFeeDiffPlaces_d5g0v0_Shanghai + - baseFeeDiffPlaces_d6g0v0_Shanghai + - baseFeeDiffPlaces_d16g0v0_Shanghai + - baseFeeDiffPlaces_d7g0v0_Shanghai + - baseFeeDiffPlaces_d17g0v0_Shanghai + - baseFeeDiffPlaces_d18g0v0_Shanghai + - baseFeeDiffPlaces_d19g0v0_Shanghai + - gasPriceDiffPlaces_d0g0v0_Shanghai + - baseFeeDiffPlaces_d20g0v0_Shanghai + - baseFeeDiffPlaces_d8g0v0_Shanghai + - baseFeeDiffPlaces_d21g0v0_Shanghai + - baseFeeDiffPlaces_d9g0v0_Shanghai + - baseFeeDiffPlaces_d22g0v0_Shanghai + - gasPriceDiffPlaces_d1g0v0_Shanghai + - baseFeeDiffPlaces_d24g0v0_Shanghai + - baseFeeDiffPlaces_d23g0v0_Shanghai + - gasPriceDiffPlaces_d10g0v0_Shanghai + - baseFeeDiffPlaces_d25g0v0_Shanghai + - baseFeeDiffPlaces_d26g0v0_Shanghai + - gasPriceDiffPlaces_d11g0v0_Shanghai + - gasPriceDiffPlaces_d12g0v0_Shanghai + - baseFeeDiffPlaces_d28g0v0_Shanghai + - baseFeeDiffPlaces_d27g0v0_Shanghai + - baseFeeDiffPlaces_d29g0v0_Shanghai + - baseFeeDiffPlaces_d30g0v0_Shanghai + - gasPriceDiffPlaces_d13g0v0_Shanghai + - baseFeeDiffPlaces_d32g0v0_Shanghai + - baseFeeDiffPlaces_d31g0v0_Shanghai + - baseFeeDiffPlaces_d33g0v0_Shanghai + - intrinsic_d0g0v0_Shanghai + - intrinsic_d0g10v0_Shanghai + - gasPriceDiffPlaces_d14g0v0_Shanghai + - baseFeeDiffPlaces_d34g0v0_Shanghai + - intrinsic_d0g11v0_Shanghai + - intrinsic_d0g12v0_Shanghai + - intrinsic_d0g13v0_Shanghai + - intrinsic_d0g14v0_Shanghai + - gasPriceDiffPlaces_d15g0v0_Shanghai + - intrinsic_d0g15v0_Shanghai + - intrinsic_d0g16v0_Shanghai + - intrinsic_d0g17v0_Shanghai + - intrinsic_d0g18v0_Shanghai + - intrinsic_d0g19v0_Shanghai + - intrinsic_d0g1v0_Shanghai + - intrinsic_d0g20v0_Shanghai + - intrinsic_d0g21v0_Shanghai + - intrinsic_d0g22v0_Shanghai + - intrinsic_d0g23v0_Shanghai + - intrinsic_d0g24v0_Shanghai + - intrinsic_d0g25v0_Shanghai + - gasPriceDiffPlaces_d16g0v0_Shanghai + - intrinsic_d0g26v0_Shanghai + - intrinsic_d0g27v0_Shanghai + - intrinsic_d0g29v0_Shanghai + - intrinsic_d0g28v0_Shanghai + - intrinsic_d0g2v0_Shanghai + - intrinsic_d0g30v0_Shanghai + - intrinsic_d0g31v0_Shanghai + - intrinsic_d0g32v0_Shanghai + - intrinsic_d0g33v0_Shanghai + - intrinsic_d0g34v0_Shanghai + - gasPriceDiffPlaces_d17g0v0_Shanghai + - intrinsic_d0g35v0_Shanghai + - intrinsic_d0g36v0_Shanghai + - intrinsic_d0g37v0_Shanghai + - intrinsic_d0g38v0_Shanghai + - intrinsic_d0g39v0_Shanghai + - intrinsic_d0g3v0_Shanghai + - intrinsic_d0g40v0_Shanghai + - intrinsic_d0g41v0_Shanghai + - intrinsic_d0g42v0_Shanghai + - intrinsic_d0g43v0_Shanghai + - intrinsic_d0g44v0_Shanghai + - intrinsic_d0g45v0_Shanghai + - intrinsic_d0g46v0_Shanghai + - intrinsic_d0g47v0_Shanghai + - intrinsic_d0g48v0_Shanghai + - gasPriceDiffPlaces_d2g0v0_Shanghai + - intrinsic_d0g49v0_Shanghai + - intrinsic_d0g4v0_Shanghai + - gasPriceDiffPlaces_d18g0v0_Shanghai + - intrinsic_d0g50v0_Shanghai + - intrinsic_d0g51v0_Shanghai + - intrinsic_d0g52v0_Shanghai + - intrinsic_d0g53v0_Shanghai + - intrinsic_d0g54v0_Shanghai + - intrinsic_d0g55v0_Shanghai + - intrinsic_d0g56v0_Shanghai + - intrinsic_d0g5v0_Shanghai + - intrinsic_d0g57v0_Shanghai + - gasPriceDiffPlaces_d19g0v0_Shanghai + - intrinsic_d0g6v0_Shanghai + - intrinsic_d0g7v0_Shanghai + - intrinsic_d0g8v0_Shanghai + - intrinsic_d10g0v0_Shanghai + - intrinsic_d0g9v0_Shanghai + - intrinsic_d10g10v0_Shanghai + - intrinsic_d10g11v0_Shanghai + - intrinsic_d10g12v0_Shanghai + - intrinsic_d10g13v0_Shanghai + - intrinsic_d10g14v0_Shanghai + - intrinsic_d10g15v0_Shanghai + - intrinsic_d10g16v0_Shanghai + - intrinsic_d10g17v0_Shanghai + - intrinsic_d10g18v0_Shanghai + - intrinsic_d10g19v0_Shanghai + - intrinsic_d10g1v0_Shanghai + - intrinsic_d10g20v0_Shanghai + - intrinsic_d10g21v0_Shanghai + - intrinsic_d10g22v0_Shanghai + - intrinsic_d10g23v0_Shanghai + - intrinsic_d10g24v0_Shanghai + - intrinsic_d10g25v0_Shanghai + - intrinsic_d10g26v0_Shanghai + - intrinsic_d10g29v0_Shanghai + - intrinsic_d10g27v0_Shanghai + - intrinsic_d10g28v0_Shanghai + - gasPriceDiffPlaces_d20g0v0_Shanghai + - intrinsic_d10g2v0_Shanghai + - intrinsic_d10g30v0_Shanghai + - intrinsic_d10g31v0_Shanghai + - intrinsic_d10g32v0_Shanghai + - intrinsic_d10g33v0_Shanghai + - intrinsic_d10g34v0_Shanghai + - intrinsic_d10g35v0_Shanghai + - intrinsic_d10g36v0_Shanghai + - intrinsic_d10g39v0_Shanghai + - intrinsic_d10g37v0_Shanghai + - intrinsic_d10g38v0_Shanghai + - intrinsic_d10g3v0_Shanghai + - intrinsic_d10g40v0_Shanghai + - intrinsic_d10g41v0_Shanghai + - intrinsic_d10g42v0_Shanghai + - intrinsic_d10g43v0_Shanghai + - intrinsic_d10g44v0_Shanghai + - intrinsic_d10g45v0_Shanghai + - intrinsic_d10g46v0_Shanghai + - intrinsic_d10g48v0_Shanghai + - intrinsic_d10g47v0_Shanghai + - intrinsic_d10g49v0_Shanghai + - intrinsic_d10g50v0_Shanghai + - intrinsic_d10g4v0_Shanghai + - intrinsic_d10g51v0_Shanghai + - intrinsic_d10g52v0_Shanghai + - intrinsic_d10g53v0_Shanghai + - intrinsic_d10g54v0_Shanghai + - intrinsic_d10g55v0_Shanghai + - gasPriceDiffPlaces_d3g0v0_Shanghai + - intrinsic_d10g5v0_Shanghai + - intrinsic_d10g56v0_Shanghai + - intrinsic_d10g57v0_Shanghai + - intrinsic_d10g6v0_Shanghai + - intrinsic_d10g7v0_Shanghai + - intrinsic_d10g8v0_Shanghai + - intrinsic_d10g9v0_Shanghai + - intrinsic_d11g0v0_Shanghai + - intrinsic_d11g10v0_Shanghai + - intrinsic_d11g11v0_Shanghai + - intrinsic_d11g12v0_Shanghai + - intrinsic_d11g13v0_Shanghai + - intrinsic_d11g14v0_Shanghai + - intrinsic_d11g15v0_Shanghai + - intrinsic_d11g16v0_Shanghai + - intrinsic_d11g17v0_Shanghai + - intrinsic_d11g18v0_Shanghai + - intrinsic_d11g19v0_Shanghai + - intrinsic_d11g1v0_Shanghai + - gasPriceDiffPlaces_d4g0v0_Shanghai + - intrinsic_d11g20v0_Shanghai + - intrinsic_d11g21v0_Shanghai + - intrinsic_d11g22v0_Shanghai + - intrinsic_d11g23v0_Shanghai + - intrinsic_d11g24v0_Shanghai + - intrinsic_d11g25v0_Shanghai + - intrinsic_d11g26v0_Shanghai + - intrinsic_d11g27v0_Shanghai + - intrinsic_d11g29v0_Shanghai + - intrinsic_d11g28v0_Shanghai + - intrinsic_d11g30v0_Shanghai + - intrinsic_d11g2v0_Shanghai + - intrinsic_d11g31v0_Shanghai + - intrinsic_d11g32v0_Shanghai + - gasPriceDiffPlaces_d5g0v0_Shanghai + - intrinsic_d11g33v0_Shanghai + - gasPriceDiffPlaces_d21g0v0_Shanghai + - intrinsic_d11g34v0_Shanghai + - intrinsic_d11g36v0_Shanghai + - intrinsic_d11g35v0_Shanghai + - intrinsic_d11g37v0_Shanghai + - intrinsic_d11g39v0_Shanghai + - intrinsic_d11g38v0_Shanghai + - intrinsic_d11g3v0_Shanghai + - intrinsic_d11g40v0_Shanghai + - intrinsic_d11g41v0_Shanghai + - intrinsic_d11g42v0_Shanghai + - intrinsic_d11g43v0_Shanghai + - intrinsic_d11g44v0_Shanghai + - intrinsic_d11g45v0_Shanghai + - intrinsic_d11g46v0_Shanghai + - intrinsic_d11g47v0_Shanghai + - intrinsic_d11g48v0_Shanghai + - intrinsic_d11g49v0_Shanghai + - gasPriceDiffPlaces_d22g0v0_Shanghai + - intrinsic_d11g4v0_Shanghai + - intrinsic_d11g54v0_Shanghai + - gasPriceDiffPlaces_d6g0v0_Shanghai + - intrinsic_d11g50v0_Shanghai + - intrinsic_d11g51v0_Shanghai + - intrinsic_d11g52v0_Shanghai + - intrinsic_d11g53v0_Shanghai + - intrinsic_d11g55v0_Shanghai + - intrinsic_d11g56v0_Shanghai + - intrinsic_d11g5v0_Shanghai + - intrinsic_d11g57v0_Shanghai + - intrinsic_d11g6v0_Shanghai + - intrinsic_d11g7v0_Shanghai + - gasPriceDiffPlaces_d7g0v0_Shanghai + - intrinsic_d11g8v0_Shanghai + - intrinsic_d11g9v0_Shanghai + - intrinsic_d12g0v0_Shanghai + - intrinsic_d12g10v0_Shanghai + - intrinsic_d12g13v0_Shanghai + - intrinsic_d12g12v0_Shanghai + - intrinsic_d12g11v0_Shanghai + - intrinsic_d12g15v0_Shanghai + - intrinsic_d12g14v0_Shanghai + - intrinsic_d12g16v0_Shanghai + - intrinsic_d12g17v0_Shanghai + - intrinsic_d12g18v0_Shanghai + - intrinsic_d12g19v0_Shanghai + - intrinsic_d12g1v0_Shanghai + - intrinsic_d12g20v0_Shanghai + - intrinsic_d12g21v0_Shanghai + - intrinsic_d12g22v0_Shanghai + - gasPriceDiffPlaces_d8g0v0_Shanghai + - intrinsic_d12g23v0_Shanghai + - intrinsic_d12g24v0_Shanghai + - intrinsic_d12g25v0_Shanghai + - gasPriceDiffPlaces_d24g0v0_Shanghai + - intrinsic_d12g26v0_Shanghai + - intrinsic_d12g29v0_Shanghai + - gasPriceDiffPlaces_d23g0v0_Shanghai + - intrinsic_d12g28v0_Shanghai + - intrinsic_d12g27v0_Shanghai + - intrinsic_d12g2v0_Shanghai + - intrinsic_d12g30v0_Shanghai + - intrinsic_d12g33v0_Shanghai + - intrinsic_d12g31v0_Shanghai + - intrinsic_d12g32v0_Shanghai + - intrinsic_d12g34v0_Shanghai + - intrinsic_d12g35v0_Shanghai + - intrinsic_d12g36v0_Shanghai + - intrinsic_d12g37v0_Shanghai + - intrinsic_d12g38v0_Shanghai + - intrinsic_d12g39v0_Shanghai + - intrinsic_d12g3v0_Shanghai + - gasPriceDiffPlaces_d9g0v0_Shanghai + - intrinsic_d12g40v0_Shanghai + - intrinsic_d12g41v0_Shanghai + - intrinsic_d12g42v0_Shanghai + - intrinsic_d12g43v0_Shanghai + - intrinsic_d12g44v0_Shanghai + - intrinsic_d12g45v0_Shanghai + - intrinsic_d12g46v0_Shanghai + - intrinsic_d12g47v0_Shanghai + - intrinsic_d12g48v0_Shanghai + - intrinsic_d12g49v0_Shanghai + - intrinsic_d12g4v0_Shanghai + - intrinsic_d12g50v0_Shanghai + - intrinsic_d12g51v0_Shanghai + - intrinsic_d12g52v0_Shanghai + - intrinsic_d12g53v0_Shanghai + - intrinsic_d12g54v0_Shanghai + - intrinsic_d12g55v0_Shanghai + - intrinsic_d12g56v0_Shanghai + - intrinsic_d12g57v0_Shanghai + - intrinsic_d12g5v0_Shanghai + - intrinsic_d12g6v0_Shanghai + - intrinsic_d12g8v0_Shanghai + - intrinsic_d12g7v0_Shanghai + - intrinsic_d12g9v0_Shanghai + - intrinsic_d13g0v0_Shanghai + - intrinsic_d13g10v0_Shanghai + - intrinsic_d13g11v0_Shanghai + - intrinsic_d13g13v0_Shanghai + - intrinsic_d13g14v0_Shanghai + - intrinsic_d13g12v0_Shanghai + - intrinsic_d13g15v0_Shanghai + - intrinsic_d13g1v0_Shanghai + - gasPriceDiffPlaces_d25g0v0_Shanghai + - intrinsic_d13g16v0_Shanghai + - intrinsic_d13g17v0_Shanghai + - intrinsic_d13g20v0_Shanghai + - intrinsic_d13g19v0_Shanghai + - intrinsic_d13g18v0_Shanghai + - intrinsic_d13g21v0_Shanghai + - intrinsic_d13g22v0_Shanghai + - intrinsic_d13g23v0_Shanghai + - intrinsic_d13g24v0_Shanghai + - intrinsic_d13g25v0_Shanghai + - intrinsic_d13g26v0_Shanghai + - intrinsic_d13g27v0_Shanghai + - intrinsic_d13g28v0_Shanghai + - intrinsic_d13g29v0_Shanghai + - intrinsic_d13g2v0_Shanghai + - intrinsic_d13g30v0_Shanghai + - intrinsic_d13g31v0_Shanghai + - intrinsic_d13g34v0_Shanghai + - intrinsic_d13g32v0_Shanghai + - intrinsic_d13g33v0_Shanghai + - intrinsic_d13g35v0_Shanghai + - intrinsic_d13g36v0_Shanghai + - intrinsic_d13g39v0_Shanghai + - intrinsic_d13g37v0_Shanghai + - intrinsic_d13g38v0_Shanghai + - intrinsic_d13g3v0_Shanghai + - intrinsic_d13g40v0_Shanghai + - intrinsic_d13g41v0_Shanghai + - intrinsic_d13g42v0_Shanghai + - intrinsic_d13g43v0_Shanghai + - intrinsic_d13g44v0_Shanghai + - intrinsic_d13g45v0_Shanghai + - intrinsic_d13g46v0_Shanghai + - intrinsic_d13g47v0_Shanghai + - intrinsic_d13g48v0_Shanghai + - intrinsic_d13g49v0_Shanghai + - intrinsic_d13g4v0_Shanghai + - intrinsic_d13g50v0_Shanghai + - intrinsic_d13g52v0_Shanghai + - intrinsic_d13g51v0_Shanghai + - intrinsic_d13g53v0_Shanghai + - intrinsic_d13g54v0_Shanghai + - intrinsic_d13g55v0_Shanghai + - intrinsic_d13g56v0_Shanghai + - intrinsic_d13g5v0_Shanghai + - intrinsic_d13g57v0_Shanghai + - intrinsic_d13g6v0_Shanghai + - intrinsic_d13g8v0_Shanghai + - intrinsic_d13g7v0_Shanghai + - intrinsic_d13g9v0_Shanghai + - intrinsic_d14g0v0_Shanghai + - intrinsic_d14g10v0_Shanghai + - intrinsic_d14g11v0_Shanghai + - intrinsic_d14g12v0_Shanghai + - intrinsic_d14g13v0_Shanghai + - intrinsic_d14g14v0_Shanghai + - intrinsic_d14g15v0_Shanghai + - intrinsic_d14g16v0_Shanghai + - gasPriceDiffPlaces_d26g0v0_Shanghai + - intrinsic_d14g17v0_Shanghai + - intrinsic_d14g18v0_Shanghai + - intrinsic_d14g19v0_Shanghai + - intrinsic_d14g1v0_Shanghai + - intrinsic_d14g20v0_Shanghai + - intrinsic_d14g21v0_Shanghai + - intrinsic_d14g22v0_Shanghai + - intrinsic_d14g23v0_Shanghai + - intrinsic_d14g24v0_Shanghai + - intrinsic_d14g25v0_Shanghai + - intrinsic_d14g2v0_Shanghai + - intrinsic_d14g26v0_Shanghai + - intrinsic_d14g29v0_Shanghai + - intrinsic_d14g27v0_Shanghai + - intrinsic_d14g28v0_Shanghai + - intrinsic_d14g30v0_Shanghai + - intrinsic_d14g31v0_Shanghai + - intrinsic_d14g32v0_Shanghai + - intrinsic_d14g34v0_Shanghai + - intrinsic_d14g33v0_Shanghai + - intrinsic_d14g35v0_Shanghai + - intrinsic_d14g36v0_Shanghai + - intrinsic_d14g39v0_Shanghai + - intrinsic_d14g38v0_Shanghai + - intrinsic_d14g37v0_Shanghai + - intrinsic_d14g3v0_Shanghai + - intrinsic_d14g40v0_Shanghai + - intrinsic_d14g41v0_Shanghai + - intrinsic_d14g44v0_Shanghai + - intrinsic_d14g42v0_Shanghai + - intrinsic_d14g43v0_Shanghai + - intrinsic_d14g45v0_Shanghai + - intrinsic_d14g46v0_Shanghai + - intrinsic_d14g49v0_Shanghai + - intrinsic_d14g48v0_Shanghai + - intrinsic_d14g47v0_Shanghai + - intrinsic_d14g50v0_Shanghai + - intrinsic_d14g4v0_Shanghai + - intrinsic_d14g51v0_Shanghai + - intrinsic_d15g0v0_Shanghai + - intrinsic_d15g10v0_Shanghai + - intrinsic_d15g11v0_Shanghai + - intrinsic_d15g12v0_Shanghai + - intrinsic_d15g13v0_Shanghai + - intrinsic_d14g52v0_Shanghai + - intrinsic_d15g14v0_Shanghai + - intrinsic_d15g15v0_Shanghai + - intrinsic_d15g16v0_Shanghai + - intrinsic_d15g17v0_Shanghai + - intrinsic_d15g18v0_Shanghai + - intrinsic_d15g19v0_Shanghai + - intrinsic_d15g1v0_Shanghai + - intrinsic_d15g20v0_Shanghai + - intrinsic_d14g53v0_Shanghai + - intrinsic_d14g54v0_Shanghai + - intrinsic_d14g55v0_Shanghai + - intrinsic_d14g57v0_Shanghai + - intrinsic_d14g56v0_Shanghai + - intrinsic_d14g5v0_Shanghai + - intrinsic_d15g21v0_Shanghai + - intrinsic_d15g22v0_Shanghai + - intrinsic_d14g7v0_Shanghai + - intrinsic_d15g23v0_Shanghai + - intrinsic_d15g25v0_Shanghai + - intrinsic_d14g6v0_Shanghai + - intrinsic_d15g24v0_Shanghai + - intrinsic_d15g29v0_Shanghai + - intrinsic_d15g26v0_Shanghai + - intrinsic_d15g27v0_Shanghai + - intrinsic_d14g9v0_Shanghai + - intrinsic_d15g28v0_Shanghai + - intrinsic_d14g8v0_Shanghai + - gasPriceDiffPlaces_d27g0v0_Shanghai + - intrinsic_d15g2v0_Shanghai + - intrinsic_d15g30v0_Shanghai + - intrinsic_d15g34v0_Shanghai + - intrinsic_d15g31v0_Shanghai + - intrinsic_d15g33v0_Shanghai + - intrinsic_d15g32v0_Shanghai + - gasPriceDiffPlaces_d28g0v0_Shanghai + - intrinsic_d15g35v0_Shanghai + - intrinsic_d15g36v0_Shanghai + - intrinsic_d15g39v0_Shanghai + - intrinsic_d15g37v0_Shanghai + - intrinsic_d15g3v0_Shanghai + - intrinsic_d15g38v0_Shanghai + - intrinsic_d15g40v0_Shanghai + - intrinsic_d15g44v0_Shanghai + - intrinsic_d15g41v0_Shanghai + - intrinsic_d15g42v0_Shanghai + - intrinsic_d15g43v0_Shanghai + - intrinsic_d15g48v0_Shanghai + - intrinsic_d15g46v0_Shanghai + - intrinsic_d15g49v0_Shanghai + - intrinsic_d15g47v0_Shanghai + - intrinsic_d15g45v0_Shanghai + - intrinsic_d15g4v0_Shanghai + - intrinsic_d15g50v0_Shanghai + - intrinsic_d15g51v0_Shanghai + - intrinsic_d15g52v0_Shanghai + - intrinsic_d15g54v0_Shanghai + - intrinsic_d15g53v0_Shanghai + - intrinsic_d15g55v0_Shanghai + - intrinsic_d15g56v0_Shanghai + - intrinsic_d15g5v0_Shanghai + - intrinsic_d15g57v0_Shanghai + - intrinsic_d15g6v0_Shanghai + - intrinsic_d15g7v0_Shanghai + - intrinsic_d15g8v0_Shanghai + - intrinsic_d15g9v0_Shanghai + - gasPriceDiffPlaces_d29g0v0_Shanghai + - intrinsic_d16g0v0_Shanghai + - intrinsic_d16g10v0_Shanghai + - intrinsic_d16g11v0_Shanghai + - intrinsic_d16g12v0_Shanghai + - intrinsic_d16g13v0_Shanghai + - intrinsic_d16g14v0_Shanghai + - intrinsic_d16g15v0_Shanghai + - intrinsic_d16g16v0_Shanghai + - intrinsic_d16g17v0_Shanghai + - intrinsic_d16g19v0_Shanghai + - intrinsic_d16g1v0_Shanghai + - intrinsic_d16g20v0_Shanghai + - intrinsic_d16g18v0_Shanghai + - intrinsic_d16g22v0_Shanghai + - intrinsic_d16g21v0_Shanghai + - intrinsic_d16g29v0_Shanghai + - intrinsic_d16g23v0_Shanghai + - gasPriceDiffPlaces_d30g0v0_Shanghai + - intrinsic_d16g24v0_Shanghai + - intrinsic_d16g25v0_Shanghai + - intrinsic_d16g26v0_Shanghai + - intrinsic_d16g27v0_Shanghai + - intrinsic_d16g28v0_Shanghai + - intrinsic_d16g2v0_Shanghai + - intrinsic_d16g30v0_Shanghai + - intrinsic_d16g31v0_Shanghai + - intrinsic_d16g32v0_Shanghai + - intrinsic_d16g33v0_Shanghai + - intrinsic_d16g34v0_Shanghai + - intrinsic_d16g35v0_Shanghai + - intrinsic_d16g36v0_Shanghai + - intrinsic_d16g37v0_Shanghai + - intrinsic_d16g39v0_Shanghai + - intrinsic_d16g44v0_Shanghai + - intrinsic_d16g38v0_Shanghai + - intrinsic_d16g40v0_Shanghai + - intrinsic_d16g3v0_Shanghai + - intrinsic_d16g41v0_Shanghai + - intrinsic_d16g42v0_Shanghai + - intrinsic_d16g43v0_Shanghai + - intrinsic_d16g45v0_Shanghai + - intrinsic_d16g46v0_Shanghai + - intrinsic_d16g49v0_Shanghai + - intrinsic_d16g47v0_Shanghai + - intrinsic_d16g48v0_Shanghai + - intrinsic_d16g4v0_Shanghai + - intrinsic_d16g50v0_Shanghai + - intrinsic_d16g52v0_Shanghai + - intrinsic_d16g51v0_Shanghai + - intrinsic_d16g54v0_Shanghai + - intrinsic_d16g53v0_Shanghai + - gasPriceDiffPlaces_d31g0v0_Shanghai + - intrinsic_d16g55v0_Shanghai + - intrinsic_d16g5v0_Shanghai + - intrinsic_d16g56v0_Shanghai + - intrinsic_d16g57v0_Shanghai + - intrinsic_d16g6v0_Shanghai + - intrinsic_d16g7v0_Shanghai + - gasPriceDiffPlaces_d32g0v0_Shanghai + - intrinsic_d16g8v0_Shanghai + - intrinsic_d16g9v0_Shanghai + - intrinsic_d17g0v0_Shanghai + - intrinsic_d17g10v0_Shanghai + - intrinsic_d17g11v0_Shanghai + - intrinsic_d17g12v0_Shanghai + - intrinsic_d17g15v0_Shanghai + - intrinsic_d17g14v0_Shanghai + - intrinsic_d17g13v0_Shanghai + - intrinsic_d17g16v0_Shanghai + - intrinsic_d17g20v0_Shanghai + - intrinsic_d17g18v0_Shanghai + - intrinsic_d17g17v0_Shanghai + - intrinsic_d17g19v0_Shanghai + - intrinsic_d17g1v0_Shanghai + - intrinsic_d17g25v0_Shanghai + - intrinsic_d17g21v0_Shanghai + - intrinsic_d17g22v0_Shanghai + - intrinsic_d17g23v0_Shanghai + - intrinsic_d17g24v0_Shanghai + - intrinsic_d17g26v0_Shanghai + - intrinsic_d17g27v0_Shanghai + - gasPriceDiffPlaces_d33g0v0_Shanghai + - intrinsic_d17g29v0_Shanghai + - intrinsic_d17g28v0_Shanghai + - intrinsic_d17g2v0_Shanghai + - intrinsic_d17g30v0_Shanghai + - intrinsic_d17g31v0_Shanghai + - gasPriceDiffPlaces_d34g0v0_Shanghai + - intrinsic_d17g32v0_Shanghai + - intrinsic_d17g34v0_Shanghai + - intrinsic_d17g33v0_Shanghai + - intrinsic_d17g35v0_Shanghai + - intrinsic_d17g36v0_Shanghai + - intrinsic_d17g37v0_Shanghai + - intrinsic_d17g38v0_Shanghai + - intrinsic_d17g39v0_Shanghai + - intrinsic_d17g44v0_Shanghai + - intrinsic_d17g3v0_Shanghai + - intrinsic_d17g40v0_Shanghai + - intrinsic_d17g41v0_Shanghai + - intrinsic_d17g42v0_Shanghai + - intrinsic_d17g43v0_Shanghai + - intrinsic_d17g45v0_Shanghai + - intrinsic_d17g46v0_Shanghai + - intrinsic_d17g47v0_Shanghai + - intrinsic_d17g48v0_Shanghai + - intrinsic_d17g49v0_Shanghai + - intrinsic_d17g4v0_Shanghai + - intrinsic_d17g52v0_Shanghai + - intrinsic_d17g50v0_Shanghai + - intrinsic_d17g51v0_Shanghai + - intrinsic_d17g54v0_Shanghai + - intrinsic_d17g53v0_Shanghai + - intrinsic_d17g55v0_Shanghai + - intrinsic_d17g56v0_Shanghai + - intrinsic_d17g5v0_Shanghai + - intrinsic_d17g57v0_Shanghai + - intrinsic_d17g6v0_Shanghai + - intrinsic_d17g7v0_Shanghai + - intrinsic_d17g8v0_Shanghai + - intrinsic_d17g9v0_Shanghai + - intrinsic_d18g0v0_Shanghai + - intrinsic_d18g10v0_Shanghai + - intrinsic_d18g11v0_Shanghai + - intrinsic_d18g13v0_Shanghai + - intrinsic_d18g12v0_Shanghai + - intrinsic_d18g14v0_Shanghai + - intrinsic_d18g15v0_Shanghai + - intrinsic_d18g16v0_Shanghai + - intrinsic_d18g17v0_Shanghai + - intrinsic_d18g19v0_Shanghai + - intrinsic_d18g18v0_Shanghai + - intrinsic_d18g1v0_Shanghai + - intrinsic_d18g20v0_Shanghai + - intrinsic_d18g21v0_Shanghai + - intrinsic_d18g22v0_Shanghai + - intrinsic_d18g25v0_Shanghai + - intrinsic_d18g24v0_Shanghai + - intrinsic_d18g23v0_Shanghai + - intrinsic_d18g29v0_Shanghai + - intrinsic_d18g26v0_Shanghai + - intrinsic_d18g27v0_Shanghai + - intrinsic_d18g28v0_Shanghai + - intrinsic_d18g2v0_Shanghai + - intrinsic_d18g30v0_Shanghai + - intrinsic_d18g31v0_Shanghai + - intrinsic_d18g34v0_Shanghai + - intrinsic_d18g32v0_Shanghai + - intrinsic_d18g33v0_Shanghai + - intrinsic_d18g35v0_Shanghai + - intrinsic_d18g36v0_Shanghai + - intrinsic_d18g37v0_Shanghai + - intrinsic_d18g38v0_Shanghai + - intrinsic_d18g39v0_Shanghai + - intrinsic_d18g3v0_Shanghai + - intrinsic_d18g40v0_Shanghai + - intrinsic_d18g44v0_Shanghai + - intrinsic_d18g41v0_Shanghai + - intrinsic_d18g42v0_Shanghai + - intrinsic_d18g43v0_Shanghai + - intrinsic_d18g45v0_Shanghai + - intrinsic_d18g47v0_Shanghai + - intrinsic_d18g46v0_Shanghai + - intrinsic_d18g48v0_Shanghai + - intrinsic_d18g49v0_Shanghai + - intrinsic_d18g4v0_Shanghai + - intrinsic_d18g50v0_Shanghai + - intrinsic_d18g51v0_Shanghai + - intrinsic_d18g52v0_Shanghai + - intrinsic_d18g54v0_Shanghai + - intrinsic_d18g53v0_Shanghai + - intrinsic_d18g55v0_Shanghai + - intrinsic_d18g5v0_Shanghai + - intrinsic_d18g57v0_Shanghai + - intrinsic_d18g56v0_Shanghai + - intrinsic_d18g6v0_Shanghai + - intrinsic_d18g7v0_Shanghai + - intrinsic_d18g8v0_Shanghai + - intrinsic_d18g9v0_Shanghai + - intrinsic_d19g0v0_Shanghai + - intrinsic_d19g10v0_Shanghai + - intrinsic_d19g12v0_Shanghai + - intrinsic_d19g11v0_Shanghai + - intrinsic_d19g13v0_Shanghai + - intrinsic_d19g14v0_Shanghai + - intrinsic_d19g15v0_Shanghai + - intrinsic_d19g16v0_Shanghai + - intrinsic_d19g17v0_Shanghai + - intrinsic_d19g18v0_Shanghai + - intrinsic_d19g20v0_Shanghai + - intrinsic_d19g19v0_Shanghai + - intrinsic_d19g1v0_Shanghai + - intrinsic_d19g21v0_Shanghai + - intrinsic_d19g22v0_Shanghai + - intrinsic_d19g23v0_Shanghai + - intrinsic_d19g25v0_Shanghai + - intrinsic_d19g24v0_Shanghai + - intrinsic_d19g29v0_Shanghai + - intrinsic_d19g27v0_Shanghai + - intrinsic_d19g26v0_Shanghai + - intrinsic_d19g28v0_Shanghai + - intrinsic_d19g2v0_Shanghai + - intrinsic_d19g30v0_Shanghai + - intrinsic_d19g34v0_Shanghai + - intrinsic_d19g31v0_Shanghai + - intrinsic_d19g32v0_Shanghai + - intrinsic_d19g33v0_Shanghai + - intrinsic_d19g35v0_Shanghai + - intrinsic_d19g36v0_Shanghai + - intrinsic_d19g37v0_Shanghai + - intrinsic_d19g38v0_Shanghai + - intrinsic_d19g39v0_Shanghai + - intrinsic_d19g3v0_Shanghai + - intrinsic_d19g40v0_Shanghai + - intrinsic_d19g41v0_Shanghai + - intrinsic_d19g42v0_Shanghai + - intrinsic_d19g43v0_Shanghai + - intrinsic_d1g0v0_Shanghai + - intrinsic_d1g10v0_Shanghai + - intrinsic_d1g11v0_Shanghai + - intrinsic_d1g12v0_Shanghai + - intrinsic_d1g13v0_Shanghai + - intrinsic_d1g14v0_Shanghai + - intrinsic_d19g44v0_Shanghai + - intrinsic_d19g45v0_Shanghai + - intrinsic_d1g15v0_Shanghai + - intrinsic_d19g46v0_Shanghai + - intrinsic_d1g16v0_Shanghai + - intrinsic_d19g47v0_Shanghai + - intrinsic_d19g48v0_Shanghai + - intrinsic_d19g49v0_Shanghai + - intrinsic_d19g4v0_Shanghai + - intrinsic_d1g17v0_Shanghai + - intrinsic_d1g18v0_Shanghai + - intrinsic_d1g19v0_Shanghai + - intrinsic_d19g50v0_Shanghai + - intrinsic_d19g51v0_Shanghai + - intrinsic_d19g55v0_Shanghai + - intrinsic_d19g53v0_Shanghai + - intrinsic_d19g54v0_Shanghai + - intrinsic_d19g5v0_Shanghai + - intrinsic_d19g52v0_Shanghai + - intrinsic_d19g56v0_Shanghai + - intrinsic_d19g57v0_Shanghai + - intrinsic_d1g1v0_Shanghai + - intrinsic_d1g20v0_Shanghai + - intrinsic_d19g6v0_Shanghai + - intrinsic_d1g21v0_Shanghai + - intrinsic_d19g8v0_Shanghai + - intrinsic_d19g7v0_Shanghai + - intrinsic_d1g22v0_Shanghai + - intrinsic_d19g9v0_Shanghai + - intrinsic_d1g23v0_Shanghai + - intrinsic_d1g25v0_Shanghai + - intrinsic_d1g24v0_Shanghai + - intrinsic_d1g26v0_Shanghai + - intrinsic_d1g27v0_Shanghai + - intrinsic_d1g29v0_Shanghai + - intrinsic_d1g28v0_Shanghai + - intrinsic_d1g2v0_Shanghai + - intrinsic_d1g30v0_Shanghai + - intrinsic_d1g31v0_Shanghai + - intrinsic_d1g32v0_Shanghai + - intrinsic_d1g33v0_Shanghai + - intrinsic_d1g34v0_Shanghai + - intrinsic_d1g35v0_Shanghai + - intrinsic_d1g36v0_Shanghai + - intrinsic_d1g37v0_Shanghai + - intrinsic_d1g38v0_Shanghai + - intrinsic_d1g39v0_Shanghai + - intrinsic_d1g40v0_Shanghai + - intrinsic_d1g44v0_Shanghai + - intrinsic_d1g3v0_Shanghai + - intrinsic_d1g43v0_Shanghai + - intrinsic_d1g41v0_Shanghai + - intrinsic_d1g42v0_Shanghai + - intrinsic_d1g45v0_Shanghai + - intrinsic_d1g46v0_Shanghai + - intrinsic_d1g47v0_Shanghai + - intrinsic_d1g48v0_Shanghai + - intrinsic_d1g4v0_Shanghai + - intrinsic_d1g49v0_Shanghai + - intrinsic_d1g50v0_Shanghai + - intrinsic_d1g51v0_Shanghai + - intrinsic_d1g54v0_Shanghai + - intrinsic_d1g52v0_Shanghai + - intrinsic_d1g53v0_Shanghai + - intrinsic_d1g55v0_Shanghai + - intrinsic_d1g56v0_Shanghai + - intrinsic_d1g57v0_Shanghai + - intrinsic_d20g0v0_Shanghai + - intrinsic_d20g10v0_Shanghai + - intrinsic_d1g5v0_Shanghai + - intrinsic_d20g11v0_Shanghai + - intrinsic_d20g12v0_Shanghai + - intrinsic_d1g6v0_Shanghai + - intrinsic_d20g15v0_Shanghai + - intrinsic_d20g13v0_Shanghai + - intrinsic_d20g14v0_Shanghai + - intrinsic_d20g16v0_Shanghai + - intrinsic_d1g7v0_Shanghai + - intrinsic_d20g20v0_Shanghai + - intrinsic_d20g17v0_Shanghai + - intrinsic_d20g18v0_Shanghai + - intrinsic_d1g8v0_Shanghai + - intrinsic_d20g25v0_Shanghai + - intrinsic_d20g1v0_Shanghai + - intrinsic_d20g19v0_Shanghai + - intrinsic_d1g9v0_Shanghai + - intrinsic_d20g21v0_Shanghai + - intrinsic_d20g23v0_Shanghai + - intrinsic_d20g22v0_Shanghai + - intrinsic_d20g24v0_Shanghai + - intrinsic_d20g29v0_Shanghai + - intrinsic_d20g26v0_Shanghai + - intrinsic_d20g27v0_Shanghai + - intrinsic_d20g28v0_Shanghai + - intrinsic_d20g30v0_Shanghai + - intrinsic_d20g2v0_Shanghai + - intrinsic_d20g31v0_Shanghai + - intrinsic_d20g32v0_Shanghai + - intrinsic_d20g34v0_Shanghai + - intrinsic_d20g33v0_Shanghai + - intrinsic_d20g35v0_Shanghai + - intrinsic_d20g36v0_Shanghai + - intrinsic_d20g39v0_Shanghai + - intrinsic_d20g37v0_Shanghai + - intrinsic_d20g38v0_Shanghai + - intrinsic_d20g3v0_Shanghai + - intrinsic_d20g40v0_Shanghai + - intrinsic_d20g44v0_Shanghai + - intrinsic_d20g49v0_Shanghai + - intrinsic_d20g41v0_Shanghai + - intrinsic_d20g42v0_Shanghai + - intrinsic_d20g45v0_Shanghai + - intrinsic_d20g43v0_Shanghai + - intrinsic_d20g46v0_Shanghai + - intrinsic_d20g54v0_Shanghai + - intrinsic_d20g48v0_Shanghai + - intrinsic_d20g47v0_Shanghai + - intrinsic_d20g50v0_Shanghai + - intrinsic_d20g4v0_Shanghai + - intrinsic_d20g52v0_Shanghai + - intrinsic_d20g51v0_Shanghai + - intrinsic_d20g53v0_Shanghai + - intrinsic_d20g5v0_Shanghai + - intrinsic_d20g55v0_Shanghai + - intrinsic_d20g56v0_Shanghai + - intrinsic_d20g57v0_Shanghai + - intrinsic_d20g6v0_Shanghai + - intrinsic_d20g7v0_Shanghai + - intrinsic_d20g8v0_Shanghai + - intrinsic_d20g9v0_Shanghai + - intrinsic_d21g0v0_Shanghai + - intrinsic_d21g10v0_Shanghai + - intrinsic_d21g11v0_Shanghai + - intrinsic_d21g12v0_Shanghai + - intrinsic_d21g15v0_Shanghai + - intrinsic_d21g13v0_Shanghai + - intrinsic_d21g14v0_Shanghai + - intrinsic_d21g16v0_Shanghai + - intrinsic_d21g25v0_Shanghai + - intrinsic_d21g17v0_Shanghai + - intrinsic_d21g18v0_Shanghai + - intrinsic_d21g19v0_Shanghai + - intrinsic_d21g20v0_Shanghai + - intrinsic_d21g1v0_Shanghai + - intrinsic_d21g29v0_Shanghai + - intrinsic_d21g22v0_Shanghai + - intrinsic_d21g23v0_Shanghai + - intrinsic_d21g21v0_Shanghai + - intrinsic_d21g26v0_Shanghai + - intrinsic_d21g27v0_Shanghai + - intrinsic_d21g24v0_Shanghai + - intrinsic_d21g28v0_Shanghai + - intrinsic_d21g34v0_Shanghai + - intrinsic_d21g2v0_Shanghai + - intrinsic_d21g30v0_Shanghai + - intrinsic_d21g31v0_Shanghai + - intrinsic_d21g32v0_Shanghai + - intrinsic_d21g33v0_Shanghai + - intrinsic_d21g35v0_Shanghai + - intrinsic_d21g36v0_Shanghai + - intrinsic_d21g37v0_Shanghai + - intrinsic_d21g38v0_Shanghai + - intrinsic_d21g39v0_Shanghai + - intrinsic_d21g3v0_Shanghai + - intrinsic_d21g40v0_Shanghai + - intrinsic_d21g44v0_Shanghai + - intrinsic_d21g41v0_Shanghai + - intrinsic_d21g42v0_Shanghai + - intrinsic_d21g43v0_Shanghai + - intrinsic_d21g49v0_Shanghai + - intrinsic_d21g45v0_Shanghai + - intrinsic_d21g54v0_Shanghai + - intrinsic_d21g48v0_Shanghai + - intrinsic_d21g46v0_Shanghai + - intrinsic_d21g47v0_Shanghai + - intrinsic_d21g4v0_Shanghai + - intrinsic_d21g51v0_Shanghai + - intrinsic_d21g50v0_Shanghai + - intrinsic_d21g5v0_Shanghai + - intrinsic_d21g52v0_Shanghai + - intrinsic_d21g53v0_Shanghai + - intrinsic_d21g56v0_Shanghai + - intrinsic_d21g55v0_Shanghai + - intrinsic_d21g57v0_Shanghai + - intrinsic_d21g6v0_Shanghai + - intrinsic_d21g8v0_Shanghai + - intrinsic_d21g7v0_Shanghai + - intrinsic_d22g0v0_Shanghai + - intrinsic_d21g9v0_Shanghai + - intrinsic_d22g10v0_Shanghai + - intrinsic_d22g11v0_Shanghai + - intrinsic_d22g12v0_Shanghai + - intrinsic_d22g13v0_Shanghai + - intrinsic_d22g14v0_Shanghai + - intrinsic_d22g15v0_Shanghai + - intrinsic_d22g16v0_Shanghai + - intrinsic_d22g17v0_Shanghai + - intrinsic_d22g18v0_Shanghai + - intrinsic_d22g19v0_Shanghai + - intrinsic_d22g1v0_Shanghai + - intrinsic_d22g20v0_Shanghai + - intrinsic_d22g25v0_Shanghai + - intrinsic_d22g29v0_Shanghai + - intrinsic_d22g21v0_Shanghai + - intrinsic_d22g22v0_Shanghai + - intrinsic_d22g23v0_Shanghai + - intrinsic_d22g24v0_Shanghai + - intrinsic_d22g28v0_Shanghai + - intrinsic_d22g26v0_Shanghai + - intrinsic_d22g34v0_Shanghai + - intrinsic_d22g27v0_Shanghai + - intrinsic_d22g2v0_Shanghai + - intrinsic_d22g30v0_Shanghai + - intrinsic_d22g31v0_Shanghai + - intrinsic_d22g39v0_Shanghai + - intrinsic_d22g32v0_Shanghai + - intrinsic_d22g33v0_Shanghai + - intrinsic_d22g35v0_Shanghai + - intrinsic_d22g36v0_Shanghai + - intrinsic_d22g37v0_Shanghai + - intrinsic_d22g38v0_Shanghai + - intrinsic_d22g3v0_Shanghai + - intrinsic_d22g40v0_Shanghai + - intrinsic_d22g41v0_Shanghai + - intrinsic_d22g42v0_Shanghai + - intrinsic_d22g43v0_Shanghai + - intrinsic_d22g44v0_Shanghai + - intrinsic_d22g45v0_Shanghai + - intrinsic_d22g49v0_Shanghai + - intrinsic_d22g46v0_Shanghai + - intrinsic_d22g48v0_Shanghai + - intrinsic_d22g47v0_Shanghai + - intrinsic_d22g4v0_Shanghai + - intrinsic_d22g54v0_Shanghai + - intrinsic_d22g52v0_Shanghai + - intrinsic_d22g50v0_Shanghai + - intrinsic_d22g51v0_Shanghai + - intrinsic_d22g5v0_Shanghai + - intrinsic_d22g53v0_Shanghai + - intrinsic_d22g55v0_Shanghai + - intrinsic_d22g56v0_Shanghai + - intrinsic_d22g6v0_Shanghai + - intrinsic_d22g7v0_Shanghai + - intrinsic_d22g57v0_Shanghai + - intrinsic_d22g8v0_Shanghai + - intrinsic_d22g9v0_Shanghai + - intrinsic_d23g0v0_Shanghai + - intrinsic_d23g10v0_Shanghai + - intrinsic_d23g11v0_Shanghai + - intrinsic_d23g15v0_Shanghai + - intrinsic_d23g12v0_Shanghai + - intrinsic_d23g13v0_Shanghai + - intrinsic_d23g14v0_Shanghai + - intrinsic_d23g16v0_Shanghai + - intrinsic_d23g17v0_Shanghai + - intrinsic_d23g18v0_Shanghai + - intrinsic_d23g19v0_Shanghai + - intrinsic_d23g1v0_Shanghai + - intrinsic_d23g20v0_Shanghai + - intrinsic_d23g21v0_Shanghai + - intrinsic_d23g22v0_Shanghai + - intrinsic_d23g25v0_Shanghai + - intrinsic_d23g23v0_Shanghai + - intrinsic_d23g29v0_Shanghai + - intrinsic_d23g26v0_Shanghai + - intrinsic_d23g24v0_Shanghai + - intrinsic_d23g27v0_Shanghai + - intrinsic_d23g2v0_Shanghai + - intrinsic_d23g28v0_Shanghai + - intrinsic_d23g30v0_Shanghai + - intrinsic_d23g34v0_Shanghai + - intrinsic_d23g31v0_Shanghai + - intrinsic_d23g32v0_Shanghai + - intrinsic_d23g33v0_Shanghai + - intrinsic_d23g35v0_Shanghai + - intrinsic_d23g38v0_Shanghai + - intrinsic_d23g36v0_Shanghai + - intrinsic_d23g37v0_Shanghai + - intrinsic_d23g39v0_Shanghai + - intrinsic_d23g3v0_Shanghai + - intrinsic_d23g40v0_Shanghai + - intrinsic_d23g41v0_Shanghai + - intrinsic_d23g44v0_Shanghai + - intrinsic_d23g42v0_Shanghai + - intrinsic_d23g45v0_Shanghai + - intrinsic_d23g43v0_Shanghai + - intrinsic_d23g46v0_Shanghai + - intrinsic_d23g47v0_Shanghai + - intrinsic_d23g48v0_Shanghai + - intrinsic_d23g49v0_Shanghai + - intrinsic_d23g4v0_Shanghai + - intrinsic_d23g50v0_Shanghai + - intrinsic_d23g52v0_Shanghai + - intrinsic_d23g54v0_Shanghai + - intrinsic_d23g51v0_Shanghai + - intrinsic_d23g53v0_Shanghai + - intrinsic_d23g5v0_Shanghai + - intrinsic_d23g55v0_Shanghai + - intrinsic_d23g56v0_Shanghai + - intrinsic_d23g6v0_Shanghai + - intrinsic_d23g57v0_Shanghai + - intrinsic_d23g7v0_Shanghai + - intrinsic_d23g8v0_Shanghai + - intrinsic_d23g9v0_Shanghai + - intrinsic_d24g0v0_Shanghai + - intrinsic_d24g10v0_Shanghai + - intrinsic_d24g11v0_Shanghai + - intrinsic_d24g12v0_Shanghai + - intrinsic_d24g14v0_Shanghai + - intrinsic_d24g13v0_Shanghai + - intrinsic_d24g15v0_Shanghai + - intrinsic_d24g16v0_Shanghai + - intrinsic_d24g17v0_Shanghai + - intrinsic_d24g18v0_Shanghai + - intrinsic_d24g1v0_Shanghai + - intrinsic_d24g19v0_Shanghai + - intrinsic_d24g20v0_Shanghai + - intrinsic_d24g21v0_Shanghai + - intrinsic_d24g22v0_Shanghai + - intrinsic_d24g23v0_Shanghai + - intrinsic_d24g24v0_Shanghai + - intrinsic_d24g25v0_Shanghai + - intrinsic_d24g26v0_Shanghai + - intrinsic_d24g27v0_Shanghai + - intrinsic_d24g29v0_Shanghai + - intrinsic_d24g28v0_Shanghai + - intrinsic_d24g30v0_Shanghai + - intrinsic_d24g2v0_Shanghai + - intrinsic_d24g34v0_Shanghai + - intrinsic_d24g31v0_Shanghai + - intrinsic_d24g32v0_Shanghai + - intrinsic_d24g33v0_Shanghai + - intrinsic_d24g36v0_Shanghai + - intrinsic_d24g35v0_Shanghai + - intrinsic_d24g37v0_Shanghai + - intrinsic_d24g38v0_Shanghai + - intrinsic_d24g39v0_Shanghai + - intrinsic_d24g3v0_Shanghai + - intrinsic_d24g40v0_Shanghai + - intrinsic_d25g0v0_Shanghai + - intrinsic_d24g41v0_Shanghai + - intrinsic_d24g42v0_Shanghai + - intrinsic_d24g43v0_Shanghai + - intrinsic_d25g10v0_Shanghai + - intrinsic_d25g11v0_Shanghai + - intrinsic_d25g13v0_Shanghai + - intrinsic_d25g12v0_Shanghai + - intrinsic_d24g44v0_Shanghai + - intrinsic_d25g14v0_Shanghai + - intrinsic_d24g45v0_Shanghai + - intrinsic_d24g46v0_Shanghai + - intrinsic_d24g49v0_Shanghai + - intrinsic_d24g47v0_Shanghai + - intrinsic_d24g48v0_Shanghai + - intrinsic_d24g4v0_Shanghai + - intrinsic_d25g15v0_Shanghai + - intrinsic_d24g50v0_Shanghai + - intrinsic_d24g51v0_Shanghai + - intrinsic_d25g16v0_Shanghai + - intrinsic_d24g54v0_Shanghai + - intrinsic_d24g52v0_Shanghai + - intrinsic_d24g53v0_Shanghai + - intrinsic_d25g17v0_Shanghai + - intrinsic_d25g19v0_Shanghai + - intrinsic_d25g18v0_Shanghai + - intrinsic_d25g1v0_Shanghai + - intrinsic_d25g20v0_Shanghai + - intrinsic_d25g22v0_Shanghai + - intrinsic_d25g21v0_Shanghai + - intrinsic_d25g23v0_Shanghai + - intrinsic_d25g25v0_Shanghai + - intrinsic_d25g24v0_Shanghai + - intrinsic_d24g55v0_Shanghai + - intrinsic_d25g26v0_Shanghai + - intrinsic_d25g29v0_Shanghai + - intrinsic_d25g27v0_Shanghai + - intrinsic_d25g28v0_Shanghai + - intrinsic_d24g56v0_Shanghai + - intrinsic_d25g2v0_Shanghai + - intrinsic_d25g30v0_Shanghai + - intrinsic_d24g57v0_Shanghai + - intrinsic_d24g5v0_Shanghai + - intrinsic_d25g31v0_Shanghai + - intrinsic_d25g32v0_Shanghai + - intrinsic_d24g6v0_Shanghai + - intrinsic_d25g33v0_Shanghai + - intrinsic_d25g34v0_Shanghai + - intrinsic_d24g7v0_Shanghai + - intrinsic_d24g8v0_Shanghai + - intrinsic_d24g9v0_Shanghai + - intrinsic_d25g39v0_Shanghai + - intrinsic_d25g35v0_Shanghai + - intrinsic_d25g36v0_Shanghai + - intrinsic_d25g37v0_Shanghai + - intrinsic_d25g38v0_Shanghai + - intrinsic_d25g40v0_Shanghai + - intrinsic_d25g3v0_Shanghai + - intrinsic_d25g41v0_Shanghai + - intrinsic_d25g42v0_Shanghai + - intrinsic_d25g44v0_Shanghai + - intrinsic_d25g43v0_Shanghai + - intrinsic_d25g45v0_Shanghai + - intrinsic_d25g46v0_Shanghai + - intrinsic_d25g47v0_Shanghai + - intrinsic_d25g48v0_Shanghai + - intrinsic_d25g49v0_Shanghai + - intrinsic_d25g4v0_Shanghai + - intrinsic_d25g50v0_Shanghai + - intrinsic_d25g51v0_Shanghai + - intrinsic_d25g54v0_Shanghai + - intrinsic_d25g5v0_Shanghai + - intrinsic_d25g52v0_Shanghai + - intrinsic_d25g53v0_Shanghai + - intrinsic_d25g55v0_Shanghai + - intrinsic_d25g57v0_Shanghai + - intrinsic_d25g56v0_Shanghai + - intrinsic_d25g6v0_Shanghai + - intrinsic_d25g7v0_Shanghai + - intrinsic_d25g9v0_Shanghai + - intrinsic_d25g8v0_Shanghai + - intrinsic_d26g0v0_Shanghai + - intrinsic_d26g10v0_Shanghai + - intrinsic_d26g11v0_Shanghai + - intrinsic_d26g15v0_Shanghai + - intrinsic_d26g12v0_Shanghai + - intrinsic_d26g13v0_Shanghai + - intrinsic_d26g14v0_Shanghai + - intrinsic_d26g16v0_Shanghai + - intrinsic_d26g17v0_Shanghai + - intrinsic_d26g18v0_Shanghai + - intrinsic_d26g19v0_Shanghai + - intrinsic_d26g1v0_Shanghai + - intrinsic_d26g20v0_Shanghai + - intrinsic_d26g21v0_Shanghai + - intrinsic_d26g22v0_Shanghai + - intrinsic_d26g25v0_Shanghai + - intrinsic_d26g24v0_Shanghai + - intrinsic_d26g23v0_Shanghai + - intrinsic_d26g29v0_Shanghai + - intrinsic_d26g26v0_Shanghai + - intrinsic_d26g27v0_Shanghai + - intrinsic_d26g28v0_Shanghai + - intrinsic_d26g34v0_Shanghai + - intrinsic_d26g30v0_Shanghai + - intrinsic_d26g2v0_Shanghai + - intrinsic_d26g31v0_Shanghai + - intrinsic_d26g32v0_Shanghai + - intrinsic_d26g35v0_Shanghai + - intrinsic_d26g33v0_Shanghai + - intrinsic_d26g36v0_Shanghai + - intrinsic_d26g37v0_Shanghai + - intrinsic_d26g38v0_Shanghai + - intrinsic_d26g39v0_Shanghai + - intrinsic_d26g3v0_Shanghai + - intrinsic_d26g44v0_Shanghai + - intrinsic_d26g40v0_Shanghai + - intrinsic_d26g41v0_Shanghai + - intrinsic_d26g43v0_Shanghai + - intrinsic_d26g42v0_Shanghai + - intrinsic_d26g45v0_Shanghai + - intrinsic_d26g46v0_Shanghai + - intrinsic_d26g47v0_Shanghai + - intrinsic_d26g48v0_Shanghai + - intrinsic_d26g49v0_Shanghai + - intrinsic_d26g4v0_Shanghai + - intrinsic_d26g50v0_Shanghai + - intrinsic_d26g51v0_Shanghai + - intrinsic_d26g54v0_Shanghai + - intrinsic_d26g52v0_Shanghai + - intrinsic_d26g53v0_Shanghai + - intrinsic_d26g5v0_Shanghai + - intrinsic_d26g55v0_Shanghai + - intrinsic_d26g56v0_Shanghai + - intrinsic_d26g57v0_Shanghai + - intrinsic_d26g6v0_Shanghai + - intrinsic_d26g8v0_Shanghai + - intrinsic_d26g7v0_Shanghai + - intrinsic_d26g9v0_Shanghai + - intrinsic_d27g0v0_Shanghai + - intrinsic_d27g10v0_Shanghai + - intrinsic_d27g11v0_Shanghai + - intrinsic_d27g12v0_Shanghai + - intrinsic_d27g13v0_Shanghai + - intrinsic_d27g14v0_Shanghai + - intrinsic_d27g15v0_Shanghai + - intrinsic_d27g16v0_Shanghai + - intrinsic_d27g17v0_Shanghai + - intrinsic_d27g18v0_Shanghai + - intrinsic_d27g1v0_Shanghai + - intrinsic_d27g19v0_Shanghai + - intrinsic_d27g20v0_Shanghai + - intrinsic_d27g21v0_Shanghai + - intrinsic_d27g22v0_Shanghai + - intrinsic_d27g23v0_Shanghai + - intrinsic_d27g25v0_Shanghai + - intrinsic_d27g24v0_Shanghai + - intrinsic_d27g29v0_Shanghai + - intrinsic_d27g28v0_Shanghai + - intrinsic_d27g26v0_Shanghai + - intrinsic_d27g27v0_Shanghai + - intrinsic_d27g2v0_Shanghai + - intrinsic_d27g30v0_Shanghai + - intrinsic_d27g31v0_Shanghai + - intrinsic_d27g34v0_Shanghai + - intrinsic_d27g32v0_Shanghai + - intrinsic_d27g33v0_Shanghai + - intrinsic_d27g39v0_Shanghai + - intrinsic_d27g35v0_Shanghai + - intrinsic_d27g36v0_Shanghai + - intrinsic_d27g38v0_Shanghai + - intrinsic_d27g3v0_Shanghai + - intrinsic_d27g37v0_Shanghai + - intrinsic_d27g40v0_Shanghai + - intrinsic_d27g41v0_Shanghai + - intrinsic_d27g42v0_Shanghai + - intrinsic_d27g43v0_Shanghai + - intrinsic_d27g44v0_Shanghai + - intrinsic_d27g45v0_Shanghai + - intrinsic_d27g46v0_Shanghai + - intrinsic_d27g47v0_Shanghai + - intrinsic_d27g48v0_Shanghai + - intrinsic_d27g49v0_Shanghai + - intrinsic_d27g4v0_Shanghai + - intrinsic_d27g54v0_Shanghai + - intrinsic_d27g50v0_Shanghai + - intrinsic_d27g51v0_Shanghai + - intrinsic_d27g52v0_Shanghai + - intrinsic_d27g53v0_Shanghai + - intrinsic_d27g55v0_Shanghai + - intrinsic_d27g5v0_Shanghai + - intrinsic_d27g57v0_Shanghai + - intrinsic_d27g56v0_Shanghai + - intrinsic_d27g6v0_Shanghai + - intrinsic_d27g7v0_Shanghai + - intrinsic_d27g8v0_Shanghai + - intrinsic_d27g9v0_Shanghai + - intrinsic_d28g0v0_Shanghai + - intrinsic_d28g10v0_Shanghai + - intrinsic_d28g11v0_Shanghai + - intrinsic_d28g15v0_Shanghai + - intrinsic_d28g12v0_Shanghai + - intrinsic_d28g14v0_Shanghai + - intrinsic_d28g16v0_Shanghai + - intrinsic_d28g13v0_Shanghai + - intrinsic_d28g17v0_Shanghai + - intrinsic_d28g18v0_Shanghai + - intrinsic_d28g19v0_Shanghai + - intrinsic_d28g20v0_Shanghai + - intrinsic_d28g1v0_Shanghai + - intrinsic_d28g21v0_Shanghai + - intrinsic_d28g22v0_Shanghai + - intrinsic_d28g23v0_Shanghai + - intrinsic_d28g24v0_Shanghai + - intrinsic_d28g25v0_Shanghai + - intrinsic_d28g29v0_Shanghai + - intrinsic_d28g26v0_Shanghai + - intrinsic_d28g27v0_Shanghai + - intrinsic_d28g28v0_Shanghai + - intrinsic_d28g30v0_Shanghai + - intrinsic_d28g2v0_Shanghai + - intrinsic_d28g31v0_Shanghai + - intrinsic_d28g32v0_Shanghai + - intrinsic_d28g34v0_Shanghai + - intrinsic_d28g33v0_Shanghai + - intrinsic_d28g35v0_Shanghai + - intrinsic_d28g36v0_Shanghai + - intrinsic_d28g37v0_Shanghai + - intrinsic_d28g38v0_Shanghai + - intrinsic_d28g39v0_Shanghai + - intrinsic_d28g3v0_Shanghai + - intrinsic_d28g40v0_Shanghai + - intrinsic_d28g44v0_Shanghai + - intrinsic_d28g41v0_Shanghai + - intrinsic_d28g42v0_Shanghai + - intrinsic_d28g43v0_Shanghai + - intrinsic_d28g45v0_Shanghai + - intrinsic_d28g46v0_Shanghai + - intrinsic_d28g49v0_Shanghai + - intrinsic_d28g47v0_Shanghai + - intrinsic_d28g48v0_Shanghai + - intrinsic_d28g4v0_Shanghai + - intrinsic_d28g50v0_Shanghai + - intrinsic_d28g54v0_Shanghai + - intrinsic_d28g51v0_Shanghai + - intrinsic_d28g53v0_Shanghai + - intrinsic_d28g52v0_Shanghai + - intrinsic_d28g55v0_Shanghai + - intrinsic_d28g56v0_Shanghai + - intrinsic_d28g5v0_Shanghai + - intrinsic_d28g57v0_Shanghai + - intrinsic_d28g6v0_Shanghai + - intrinsic_d28g7v0_Shanghai + - intrinsic_d28g8v0_Shanghai + - intrinsic_d28g9v0_Shanghai + - intrinsic_d29g0v0_Shanghai + - intrinsic_d29g10v0_Shanghai + - intrinsic_d29g11v0_Shanghai + - intrinsic_d29g12v0_Shanghai + - intrinsic_d29g13v0_Shanghai + - intrinsic_d29g14v0_Shanghai + - intrinsic_d29g15v0_Shanghai + - intrinsic_d29g16v0_Shanghai + - intrinsic_d29g17v0_Shanghai + - intrinsic_d29g18v0_Shanghai + - intrinsic_d29g19v0_Shanghai + - intrinsic_d29g1v0_Shanghai + - intrinsic_d29g20v0_Shanghai + - intrinsic_d29g21v0_Shanghai + - intrinsic_d29g22v0_Shanghai + - intrinsic_d29g25v0_Shanghai + - intrinsic_d29g23v0_Shanghai + - intrinsic_d29g24v0_Shanghai + - intrinsic_d29g26v0_Shanghai + - intrinsic_d29g27v0_Shanghai + - intrinsic_d29g29v0_Shanghai + - intrinsic_d29g28v0_Shanghai + - intrinsic_d29g2v0_Shanghai + - intrinsic_d29g30v0_Shanghai + - intrinsic_d29g34v0_Shanghai + - intrinsic_d29g31v0_Shanghai + - intrinsic_d29g32v0_Shanghai + - intrinsic_d29g33v0_Shanghai + - intrinsic_d29g35v0_Shanghai + - intrinsic_d29g36v0_Shanghai + - intrinsic_d29g38v0_Shanghai + - intrinsic_d29g37v0_Shanghai + - intrinsic_d29g39v0_Shanghai + - intrinsic_d29g3v0_Shanghai + - intrinsic_d29g40v0_Shanghai + - intrinsic_d29g41v0_Shanghai + - intrinsic_d29g43v0_Shanghai + - intrinsic_d29g42v0_Shanghai + - intrinsic_d2g0v0_Shanghai + - intrinsic_d2g10v0_Shanghai + - intrinsic_d2g11v0_Shanghai + - intrinsic_d2g12v0_Shanghai + - intrinsic_d2g13v0_Shanghai + - intrinsic_d29g44v0_Shanghai + - intrinsic_d2g14v0_Shanghai + - intrinsic_d29g45v0_Shanghai + - intrinsic_d29g46v0_Shanghai + - intrinsic_d29g47v0_Shanghai + - intrinsic_d29g49v0_Shanghai + - intrinsic_d29g48v0_Shanghai + - intrinsic_d29g4v0_Shanghai + - intrinsic_d29g50v0_Shanghai + - intrinsic_d2g15v0_Shanghai + - intrinsic_d29g51v0_Shanghai + - intrinsic_d29g54v0_Shanghai + - intrinsic_d29g52v0_Shanghai + - intrinsic_d29g53v0_Shanghai + - intrinsic_d2g16v0_Shanghai + - intrinsic_d29g55v0_Shanghai + - intrinsic_d2g17v0_Shanghai + - intrinsic_d2g18v0_Shanghai + - intrinsic_d29g5v0_Shanghai + - intrinsic_d29g56v0_Shanghai + - intrinsic_d29g57v0_Shanghai + - intrinsic_d29g6v0_Shanghai + - intrinsic_d2g19v0_Shanghai + - intrinsic_d2g1v0_Shanghai + - intrinsic_d29g7v0_Shanghai + - intrinsic_d2g20v0_Shanghai + - intrinsic_d29g8v0_Shanghai + - intrinsic_d2g21v0_Shanghai + - intrinsic_d29g9v0_Shanghai + - intrinsic_d2g22v0_Shanghai + - intrinsic_d2g25v0_Shanghai + - intrinsic_d2g24v0_Shanghai + - intrinsic_d2g23v0_Shanghai + - intrinsic_d2g26v0_Shanghai + - intrinsic_d2g27v0_Shanghai + - intrinsic_d2g29v0_Shanghai + - intrinsic_d2g28v0_Shanghai + - intrinsic_d2g2v0_Shanghai + - intrinsic_d2g30v0_Shanghai + - intrinsic_d2g31v0_Shanghai + - intrinsic_d2g32v0_Shanghai + - intrinsic_d2g33v0_Shanghai + - intrinsic_d2g34v0_Shanghai + - intrinsic_d2g35v0_Shanghai + - intrinsic_d2g37v0_Shanghai + - intrinsic_d2g36v0_Shanghai + - intrinsic_d2g38v0_Shanghai + - intrinsic_d2g39v0_Shanghai + - intrinsic_d2g3v0_Shanghai + - intrinsic_d2g40v0_Shanghai + - intrinsic_d2g41v0_Shanghai + - intrinsic_d2g42v0_Shanghai + - intrinsic_d2g43v0_Shanghai + - intrinsic_d2g44v0_Shanghai + - intrinsic_d2g46v0_Shanghai + - intrinsic_d2g45v0_Shanghai + - intrinsic_d2g47v0_Shanghai + - intrinsic_d2g49v0_Shanghai + - intrinsic_d2g48v0_Shanghai + - intrinsic_d2g50v0_Shanghai + - intrinsic_d2g4v0_Shanghai + - intrinsic_d2g51v0_Shanghai + - intrinsic_d2g52v0_Shanghai + - intrinsic_d2g53v0_Shanghai + - intrinsic_d2g54v0_Shanghai + - intrinsic_d2g55v0_Shanghai + - intrinsic_d2g56v0_Shanghai + - intrinsic_d2g5v0_Shanghai + - intrinsic_d2g57v0_Shanghai + - intrinsic_d2g6v0_Shanghai + - intrinsic_d2g8v0_Shanghai + - intrinsic_d2g7v0_Shanghai + - intrinsic_d2g9v0_Shanghai + - intrinsic_d3g0v0_Shanghai + - intrinsic_d3g10v0_Shanghai + - intrinsic_d3g11v0_Shanghai + - intrinsic_d3g13v0_Shanghai + - intrinsic_d3g12v0_Shanghai + - intrinsic_d3g14v0_Shanghai + - intrinsic_d3g15v0_Shanghai + - intrinsic_d3g16v0_Shanghai + - intrinsic_d3g17v0_Shanghai + - intrinsic_d3g18v0_Shanghai + - intrinsic_d3g19v0_Shanghai + - intrinsic_d3g1v0_Shanghai + - intrinsic_d3g20v0_Shanghai + - intrinsic_d3g21v0_Shanghai + - intrinsic_d3g22v0_Shanghai + - intrinsic_d3g25v0_Shanghai + - intrinsic_d3g23v0_Shanghai + - intrinsic_d3g24v0_Shanghai + - intrinsic_d3g27v0_Shanghai + - intrinsic_d3g26v0_Shanghai + - intrinsic_d3g29v0_Shanghai + - intrinsic_d3g28v0_Shanghai + - intrinsic_d3g30v0_Shanghai + - intrinsic_d3g2v0_Shanghai + - intrinsic_d3g31v0_Shanghai + - intrinsic_d3g32v0_Shanghai + - intrinsic_d3g33v0_Shanghai + - intrinsic_d3g34v0_Shanghai + - intrinsic_d3g35v0_Shanghai + - intrinsic_d3g36v0_Shanghai + - intrinsic_d3g37v0_Shanghai + - intrinsic_d3g38v0_Shanghai + - intrinsic_d3g39v0_Shanghai + - intrinsic_d3g3v0_Shanghai + - intrinsic_d3g40v0_Shanghai + - intrinsic_d3g41v0_Shanghai + - intrinsic_d3g42v0_Shanghai + - intrinsic_d3g43v0_Shanghai + - intrinsic_d3g44v0_Shanghai + - intrinsic_d3g45v0_Shanghai + - intrinsic_d3g46v0_Shanghai + - intrinsic_d3g47v0_Shanghai + - intrinsic_d3g49v0_Shanghai + - intrinsic_d3g48v0_Shanghai + - intrinsic_d3g4v0_Shanghai + - intrinsic_d3g50v0_Shanghai + - intrinsic_d3g51v0_Shanghai + - intrinsic_d3g52v0_Shanghai + - intrinsic_d3g54v0_Shanghai + - intrinsic_d3g53v0_Shanghai + - intrinsic_d3g55v0_Shanghai + - intrinsic_d3g56v0_Shanghai + - intrinsic_d3g57v0_Shanghai + - intrinsic_d3g5v0_Shanghai + - intrinsic_d3g6v0_Shanghai + - intrinsic_d3g7v0_Shanghai + - intrinsic_d3g8v0_Shanghai + - intrinsic_d3g9v0_Shanghai + - intrinsic_d4g0v0_Shanghai + - intrinsic_d4g10v0_Shanghai + - intrinsic_d4g11v0_Shanghai + - intrinsic_d4g12v0_Shanghai + - intrinsic_d4g13v0_Shanghai + - intrinsic_d4g14v0_Shanghai + - intrinsic_d4g15v0_Shanghai + - intrinsic_d4g16v0_Shanghai + - intrinsic_d4g17v0_Shanghai + - intrinsic_d4g18v0_Shanghai + - intrinsic_d4g19v0_Shanghai + - intrinsic_d4g1v0_Shanghai + - intrinsic_d4g20v0_Shanghai + - intrinsic_d4g21v0_Shanghai + - intrinsic_d4g22v0_Shanghai + - intrinsic_d4g23v0_Shanghai + - intrinsic_d4g25v0_Shanghai + - intrinsic_d4g24v0_Shanghai + - intrinsic_d4g29v0_Shanghai + - intrinsic_d4g26v0_Shanghai + - intrinsic_d4g27v0_Shanghai + - intrinsic_d4g28v0_Shanghai + - intrinsic_d4g2v0_Shanghai + - intrinsic_d4g30v0_Shanghai + - intrinsic_d4g32v0_Shanghai + - intrinsic_d4g31v0_Shanghai + - intrinsic_d4g34v0_Shanghai + - intrinsic_d4g33v0_Shanghai + - intrinsic_d4g35v0_Shanghai + - intrinsic_d4g36v0_Shanghai + - intrinsic_d4g37v0_Shanghai + - intrinsic_d4g38v0_Shanghai + - intrinsic_d5g0v0_Shanghai + - intrinsic_d5g10v0_Shanghai + - intrinsic_d4g39v0_Shanghai + - intrinsic_d5g11v0_Shanghai + - intrinsic_d5g12v0_Shanghai + - intrinsic_d4g3v0_Shanghai + - intrinsic_d5g13v0_Shanghai + - intrinsic_d4g40v0_Shanghai + - intrinsic_d4g41v0_Shanghai + - intrinsic_d5g14v0_Shanghai + - intrinsic_d4g42v0_Shanghai + - intrinsic_d4g43v0_Shanghai + - intrinsic_d5g15v0_Shanghai + - intrinsic_d4g44v0_Shanghai + - intrinsic_d5g16v0_Shanghai + - intrinsic_d4g45v0_Shanghai + - intrinsic_d4g46v0_Shanghai + - intrinsic_d5g17v0_Shanghai + - intrinsic_d5g18v0_Shanghai + - intrinsic_d5g1v0_Shanghai + - intrinsic_d5g19v0_Shanghai + - intrinsic_d5g20v0_Shanghai + - intrinsic_d4g48v0_Shanghai + - intrinsic_d4g47v0_Shanghai + - intrinsic_d4g49v0_Shanghai + - intrinsic_d4g4v0_Shanghai + - intrinsic_d5g21v0_Shanghai + - intrinsic_d4g50v0_Shanghai + - intrinsic_d5g22v0_Shanghai + - intrinsic_d5g23v0_Shanghai + - intrinsic_d5g25v0_Shanghai + - intrinsic_d5g24v0_Shanghai + - intrinsic_d4g51v0_Shanghai + - intrinsic_d4g54v0_Shanghai + - intrinsic_d4g52v0_Shanghai + - intrinsic_d4g53v0_Shanghai + - intrinsic_d4g5v0_Shanghai + - intrinsic_d4g56v0_Shanghai + - intrinsic_d4g55v0_Shanghai + - intrinsic_d4g57v0_Shanghai + - intrinsic_d4g6v0_Shanghai + - intrinsic_d4g7v0_Shanghai + - intrinsic_d4g8v0_Shanghai + - intrinsic_d5g26v0_Shanghai + - intrinsic_d4g9v0_Shanghai + - intrinsic_d5g29v0_Shanghai + - intrinsic_d5g27v0_Shanghai + - intrinsic_d5g28v0_Shanghai + - intrinsic_d5g34v0_Shanghai + - intrinsic_d5g30v0_Shanghai + - intrinsic_d5g2v0_Shanghai + - intrinsic_d5g31v0_Shanghai + - intrinsic_d5g32v0_Shanghai + - intrinsic_d5g33v0_Shanghai + - intrinsic_d5g36v0_Shanghai + - intrinsic_d5g35v0_Shanghai + - intrinsic_d5g37v0_Shanghai + - intrinsic_d5g39v0_Shanghai + - intrinsic_d5g38v0_Shanghai + - intrinsic_d5g3v0_Shanghai + - intrinsic_d5g41v0_Shanghai + - intrinsic_d5g40v0_Shanghai + - intrinsic_d5g42v0_Shanghai + - intrinsic_d5g43v0_Shanghai + - intrinsic_d5g44v0_Shanghai + - intrinsic_d5g45v0_Shanghai + - intrinsic_d5g47v0_Shanghai + - intrinsic_d5g46v0_Shanghai + - intrinsic_d5g48v0_Shanghai + - intrinsic_d5g49v0_Shanghai + - intrinsic_d5g4v0_Shanghai + - intrinsic_d5g50v0_Shanghai + - intrinsic_d5g51v0_Shanghai + - intrinsic_d5g52v0_Shanghai + - intrinsic_d5g53v0_Shanghai + - intrinsic_d5g54v0_Shanghai + - intrinsic_d5g55v0_Shanghai + - intrinsic_d5g57v0_Shanghai + - intrinsic_d5g5v0_Shanghai + - intrinsic_d5g56v0_Shanghai + - intrinsic_d5g6v0_Shanghai + - intrinsic_d5g7v0_Shanghai + - intrinsic_d5g8v0_Shanghai + - intrinsic_d5g9v0_Shanghai + - intrinsic_d6g0v0_Shanghai + - intrinsic_d6g10v0_Shanghai + - intrinsic_d6g11v0_Shanghai + - intrinsic_d6g12v0_Shanghai + - intrinsic_d6g13v0_Shanghai + - intrinsic_d6g15v0_Shanghai + - intrinsic_d6g14v0_Shanghai + - intrinsic_d6g16v0_Shanghai + - intrinsic_d6g17v0_Shanghai + - intrinsic_d6g18v0_Shanghai + - intrinsic_d6g19v0_Shanghai + - intrinsic_d6g20v0_Shanghai + - intrinsic_d6g1v0_Shanghai + - intrinsic_d6g21v0_Shanghai + - intrinsic_d6g22v0_Shanghai + - intrinsic_d6g23v0_Shanghai + - intrinsic_d6g25v0_Shanghai + - intrinsic_d6g24v0_Shanghai + - intrinsic_d6g29v0_Shanghai + - intrinsic_d6g27v0_Shanghai + - intrinsic_d6g26v0_Shanghai + - intrinsic_d6g28v0_Shanghai + - intrinsic_d6g2v0_Shanghai + - intrinsic_d6g30v0_Shanghai + - intrinsic_d6g31v0_Shanghai + - intrinsic_d6g34v0_Shanghai + - intrinsic_d6g32v0_Shanghai + - intrinsic_d6g33v0_Shanghai + - intrinsic_d6g35v0_Shanghai + - intrinsic_d6g36v0_Shanghai + - intrinsic_d6g37v0_Shanghai + - intrinsic_d6g38v0_Shanghai + - intrinsic_d6g39v0_Shanghai + - intrinsic_d6g3v0_Shanghai + - intrinsic_d6g40v0_Shanghai + - intrinsic_d6g41v0_Shanghai + - intrinsic_d6g42v0_Shanghai + - intrinsic_d6g44v0_Shanghai + - intrinsic_d6g43v0_Shanghai + - intrinsic_d6g46v0_Shanghai + - intrinsic_d6g45v0_Shanghai + - intrinsic_d6g47v0_Shanghai + - intrinsic_d6g48v0_Shanghai + - intrinsic_d6g49v0_Shanghai + - intrinsic_d6g4v0_Shanghai + - intrinsic_d6g50v0_Shanghai + - intrinsic_d6g51v0_Shanghai + - intrinsic_d6g54v0_Shanghai + - intrinsic_d6g53v0_Shanghai + - intrinsic_d6g52v0_Shanghai + - intrinsic_d6g55v0_Shanghai + - intrinsic_d6g56v0_Shanghai + - intrinsic_d6g57v0_Shanghai + - intrinsic_d6g5v0_Shanghai + - intrinsic_d6g6v0_Shanghai + - intrinsic_d6g7v0_Shanghai + - intrinsic_d6g8v0_Shanghai + - intrinsic_d6g9v0_Shanghai + - intrinsic_d7g0v0_Shanghai + - intrinsic_d7g10v0_Shanghai + - intrinsic_d7g11v0_Shanghai + - intrinsic_d7g12v0_Shanghai + - intrinsic_d7g13v0_Shanghai + - intrinsic_d7g14v0_Shanghai + - intrinsic_d7g15v0_Shanghai + - intrinsic_d7g16v0_Shanghai + - intrinsic_d7g18v0_Shanghai + - intrinsic_d7g17v0_Shanghai + - intrinsic_d7g19v0_Shanghai + - intrinsic_d7g20v0_Shanghai + - intrinsic_d7g1v0_Shanghai + - intrinsic_d7g21v0_Shanghai + - intrinsic_d7g23v0_Shanghai + - intrinsic_d7g22v0_Shanghai + - intrinsic_d7g24v0_Shanghai + - intrinsic_d7g25v0_Shanghai + - intrinsic_d7g26v0_Shanghai + - intrinsic_d7g29v0_Shanghai + - intrinsic_d7g27v0_Shanghai + - intrinsic_d7g28v0_Shanghai + - intrinsic_d7g2v0_Shanghai + - intrinsic_d7g34v0_Shanghai + - intrinsic_d7g30v0_Shanghai + - intrinsic_d7g31v0_Shanghai + - intrinsic_d7g32v0_Shanghai + - intrinsic_d7g33v0_Shanghai + - intrinsic_d7g35v0_Shanghai + - intrinsic_d7g36v0_Shanghai + - intrinsic_d7g38v0_Shanghai + - intrinsic_d7g37v0_Shanghai + - intrinsic_d7g39v0_Shanghai + - intrinsic_d7g3v0_Shanghai + - intrinsic_d7g40v0_Shanghai + - intrinsic_d7g41v0_Shanghai + - intrinsic_d7g42v0_Shanghai + - intrinsic_d7g43v0_Shanghai + - intrinsic_d7g44v0_Shanghai + - intrinsic_d7g45v0_Shanghai + - intrinsic_d7g46v0_Shanghai + - intrinsic_d7g47v0_Shanghai + - intrinsic_d7g48v0_Shanghai + - intrinsic_d7g49v0_Shanghai + - intrinsic_d7g4v0_Shanghai + - intrinsic_d7g50v0_Shanghai + - intrinsic_d7g51v0_Shanghai + - intrinsic_d7g52v0_Shanghai + - intrinsic_d7g54v0_Shanghai + - intrinsic_d7g53v0_Shanghai + - intrinsic_d7g55v0_Shanghai + - intrinsic_d7g56v0_Shanghai + - intrinsic_d7g5v0_Shanghai + - intrinsic_d7g57v0_Shanghai + - intrinsic_d7g6v0_Shanghai + - intrinsic_d7g7v0_Shanghai + - intrinsic_d7g8v0_Shanghai + - intrinsic_d7g9v0_Shanghai + - intrinsic_d8g0v0_Shanghai + - intrinsic_d8g10v0_Shanghai + - intrinsic_d8g11v0_Shanghai + - intrinsic_d8g12v0_Shanghai + - intrinsic_d8g15v0_Shanghai + - intrinsic_d8g13v0_Shanghai + - intrinsic_d8g14v0_Shanghai + - intrinsic_d8g16v0_Shanghai + - intrinsic_d8g17v0_Shanghai + - intrinsic_d8g18v0_Shanghai + - intrinsic_d8g19v0_Shanghai + - intrinsic_d8g1v0_Shanghai + - intrinsic_d8g20v0_Shanghai + - intrinsic_d8g21v0_Shanghai + - intrinsic_d8g22v0_Shanghai + - intrinsic_d8g25v0_Shanghai + - intrinsic_d8g24v0_Shanghai + - intrinsic_d8g23v0_Shanghai + - intrinsic_d8g29v0_Shanghai + - intrinsic_d8g26v0_Shanghai + - intrinsic_d8g27v0_Shanghai + - intrinsic_d8g28v0_Shanghai + - intrinsic_d8g2v0_Shanghai + - intrinsic_d8g30v0_Shanghai + - intrinsic_d8g32v0_Shanghai + - intrinsic_d8g34v0_Shanghai + - intrinsic_d8g31v0_Shanghai + - intrinsic_d8g33v0_Shanghai + - intrinsic_d8g35v0_Shanghai + - intrinsic_d8g36v0_Shanghai + - intrinsic_d8g37v0_Shanghai + - intrinsic_d8g38v0_Shanghai + - intrinsic_d8g39v0_Shanghai + - intrinsic_d8g3v0_Shanghai + - intrinsic_d8g40v0_Shanghai + - intrinsic_d8g41v0_Shanghai + - intrinsic_d8g42v0_Shanghai + - intrinsic_d8g44v0_Shanghai + - intrinsic_d8g43v0_Shanghai + - intrinsic_d8g45v0_Shanghai + - intrinsic_d8g46v0_Shanghai + - intrinsic_d8g47v0_Shanghai + - intrinsic_d8g48v0_Shanghai + - intrinsic_d8g49v0_Shanghai + - intrinsic_d8g4v0_Shanghai + - intrinsic_d8g50v0_Shanghai + - intrinsic_d8g51v0_Shanghai + - intrinsic_d8g54v0_Shanghai + - intrinsic_d8g52v0_Shanghai + - intrinsic_d8g53v0_Shanghai + - intrinsic_d8g5v0_Shanghai + - intrinsic_d8g57v0_Shanghai + - intrinsic_d8g56v0_Shanghai + - intrinsic_d8g55v0_Shanghai + - intrinsic_d8g6v0_Shanghai + - intrinsic_d8g7v0_Shanghai + - intrinsic_d8g8v0_Shanghai + - intrinsic_d8g9v0_Shanghai + - intrinsic_d9g0v0_Shanghai + - intrinsic_d9g10v0_Shanghai + - intrinsic_d9g11v0_Shanghai + - intrinsic_d9g12v0_Shanghai + - intrinsic_d9g13v0_Shanghai + - intrinsic_d9g14v0_Shanghai + - intrinsic_d9g15v0_Shanghai + - intrinsic_d9g16v0_Shanghai + - intrinsic_d9g17v0_Shanghai + - intrinsic_d9g18v0_Shanghai + - intrinsic_d9g19v0_Shanghai + - intrinsic_d9g20v0_Shanghai + - intrinsic_d9g1v0_Shanghai + - intrinsic_d9g21v0_Shanghai + - intrinsic_d9g22v0_Shanghai + - intrinsic_d9g23v0_Shanghai + - intrinsic_d9g24v0_Shanghai + - intrinsic_d9g25v0_Shanghai + - intrinsic_d9g26v0_Shanghai + - intrinsic_d9g29v0_Shanghai + - intrinsic_d9g27v0_Shanghai + - intrinsic_d9g28v0_Shanghai + - intrinsic_d9g30v0_Shanghai + - intrinsic_d9g2v0_Shanghai + - intrinsic_d9g34v0_Shanghai + - intrinsic_d9g31v0_Shanghai + - intrinsic_d9g32v0_Shanghai + - intrinsic_d9g33v0_Shanghai + - intrinsic_d9g35v0_Shanghai + - intrinsic_d9g37v0_Shanghai + - intrinsic_d9g36v0_Shanghai + - intrinsic_d9g38v0_Shanghai + - intrinsic_d9g39v0_Shanghai + - lowGasLimit_d0g0v0_Shanghai + - lowFeeCap_d0g0v0_Shanghai + - intrinsic_d9g3v0_Shanghai + - intrinsic_d9g40v0_Shanghai + - lowGasLimit_d0g3v0_Shanghai + - lowGasLimit_d0g1v0_Shanghai + - intrinsic_d9g41v0_Shanghai + - intrinsic_d9g42v0_Shanghai + - lowGasPriceOldTypes_d0g0v0_Shanghai + - lowGasLimit_d0g2v0_Shanghai + - intrinsic_d9g43v0_Shanghai + - intrinsic_d9g44v0_Shanghai + - intrinsic_d9g45v0_Shanghai + - lowGasPriceOldTypes_d1g0v0_Shanghai + - intrinsic_d9g46v0_Shanghai + - intrinsic_d9g49v0_Shanghai + - intrinsic_d9g48v0_Shanghai + - intrinsic_d9g47v0_Shanghai + - outOfFundsOldTypes_d0g0v0_Shanghai + - intrinsic_d9g4v0_Shanghai + - outOfFundsOldTypes_d0g1v0_Shanghai + - outOfFundsOldTypes_d1g1v0_Shanghai + - outOfFundsOldTypes_d0g0v1_Shanghai + - outOfFundsOldTypes_d1g0v0_Shanghai + - intrinsic_d9g50v0_Shanghai + - intrinsic_d9g52v0_Shanghai + - intrinsic_d9g51v0_Shanghai + - outOfFundsOldTypes_d0g1v1_Shanghai + - intrinsic_d9g53v0_Shanghai + - outOfFundsOldTypes_d1g0v1_Shanghai + - outOfFunds_d0g1v0_Shanghai + - outOfFundsOldTypes_d1g1v1_Shanghai + - outOfFunds_d0g0v0_Shanghai + - intrinsic_d9g54v0_Shanghai + - outOfFunds_d0g0v1_Shanghai + - intrinsic_d9g55v0_Shanghai + - intrinsic_d9g56v0_Shanghai + - senderBalance_d0g0v0_Shanghai + - intrinsic_d9g5v0_Shanghai + - intrinsic_d9g57v0_Shanghai + - intrinsic_d9g6v0_Shanghai + - intrinsic_d9g7v0_Shanghai + - intrinsic_d9g8v0_Shanghai + - tipTooHigh_d0g0v0_Shanghai + - outOfFunds_d0g1v1_Shanghai + - intrinsic_d9g9v0_Shanghai + - transactionIntinsicBug_d0g0v0_Shanghai + - typeTwoBerlin_d0g0v0_Shanghai + - valCausesOOF_d0g0v1_Shanghai + - valCausesOOF_d0g2v0_Shanghai + - valCausesOOF_d0g2v1_Shanghai + - valCausesOOF_d1g0v1_Shanghai + - valCausesOOF_d0g0v0_Shanghai + - valCausesOOF_d0g1v0_Shanghai + - valCausesOOF_d0g1v1_Shanghai + - valCausesOOF_d1g2v1_Shanghai + - valCausesOOF_d1g2v0_Shanghai + - valCausesOOF_d1g0v0_Shanghai + - valCausesOOF_d1g1v0_Shanghai + - valCausesOOF_d1g1v1_Shanghai + stEIP158Specific: + - CALL_OneVCallSuicide_d0g0v0_Shanghai + - CALL_ZeroVCallSuicide_d0g0v0_Shanghai + - EXP_Empty_d0g0v0_Shanghai + - vitalikTransactionTest_d0g0v0_Shanghai + stEIP2930: + - addressOpcodes_d11g0v0_Shanghai + - addressOpcodes_d14g0v0_Shanghai + - addressOpcodes_d19g0v0_Shanghai + - addressOpcodes_d17g0v0_Shanghai + - addressOpcodes_d21g0v0_Shanghai + - addressOpcodes_d13g0v0_Shanghai + - addressOpcodes_d23g0v0_Shanghai + - addressOpcodes_d29g0v0_Shanghai + - addressOpcodes_d26g0v0_Shanghai + - addressOpcodes_d2g0v0_Shanghai + - addressOpcodes_d1g0v0_Shanghai + - addressOpcodes_d35g0v0_Shanghai + - addressOpcodes_d31g0v0_Shanghai + - addressOpcodes_d25g0v0_Shanghai + - addressOpcodes_d10g0v0_Shanghai + - addressOpcodes_d0g0v0_Shanghai + - addressOpcodes_d12g0v0_Shanghai + - addressOpcodes_d18g0v0_Shanghai + - addressOpcodes_d15g0v0_Shanghai + - addressOpcodes_d16g0v0_Shanghai + - addressOpcodes_d20g0v0_Shanghai + - addressOpcodes_d22g0v0_Shanghai + - addressOpcodes_d24g0v0_Shanghai + - addressOpcodes_d28g0v0_Shanghai + - addressOpcodes_d33g0v0_Shanghai + - addressOpcodes_d27g0v0_Shanghai + - addressOpcodes_d30g0v0_Shanghai + - addressOpcodes_d34g0v0_Shanghai + - coinbaseT01_d0g0v0_Shanghai + - addressOpcodes_d36g0v0_Shanghai + - coinbaseT01_d2g0v0_Shanghai + - coinbaseT01_d1g0v0_Shanghai + - coinbaseT2_d0g0v0_Shanghai + - coinbaseT2_d1g0v0_Shanghai + - addressOpcodes_d32g0v0_Shanghai + - manualCreate_d2g0v0_Shanghai + - storageCosts_d0g0v0_Shanghai + - addressOpcodes_d37g0v0_Shanghai + - storageCosts_d10g0v0_Shanghai + - storageCosts_d11g0v0_Shanghai + - addressOpcodes_d38g0v0_Shanghai + - storageCosts_d18g0v0_Shanghai + - storageCosts_d12g0v0_Shanghai + - storageCosts_d19g0v0_Shanghai + - storageCosts_d13g0v0_Shanghai + - storageCosts_d14g0v0_Shanghai + - storageCosts_d20g0v0_Shanghai + - storageCosts_d21g0v0_Shanghai + - storageCosts_d15g0v0_Shanghai + - storageCosts_d16g0v0_Shanghai + - storageCosts_d17g0v0_Shanghai + - storageCosts_d1g0v0_Shanghai + - storageCosts_d23g0v0_Shanghai + - storageCosts_d22g0v0_Shanghai + - storageCosts_d24g0v0_Shanghai + - storageCosts_d26g0v0_Shanghai + - storageCosts_d25g0v0_Shanghai + - storageCosts_d27g0v0_Shanghai + - storageCosts_d28g0v0_Shanghai + - storageCosts_d29g0v0_Shanghai + - storageCosts_d2g0v0_Shanghai + - storageCosts_d30g0v0_Shanghai + - storageCosts_d31g0v0_Shanghai + - storageCosts_d3g0v0_Shanghai + - storageCosts_d4g0v0_Shanghai + - storageCosts_d5g0v0_Shanghai + - addressOpcodes_d41g0v0_Shanghai + - addressOpcodes_d5g0v0_Shanghai + - addressOpcodes_d43g0v0_Shanghai + - addressOpcodes_d7g0v0_Shanghai + - storageCosts_d32g0v0_Shanghai + - addressOpcodes_d45g0v0_Shanghai + - addressOpcodes_d47g0v0_Shanghai + - storageCosts_d34g0v0_Shanghai + - storageCosts_d33g0v0_Shanghai + - addressOpcodes_d9g0v0_Shanghai + - storageCosts_d6g0v0_Shanghai + - addressOpcodes_d3g0v0_Shanghai + - storageCosts_d7g0v0_Shanghai + - storageCosts_d9g0v0_Shanghai + - storageCosts_d8g0v0_Shanghai + - addressOpcodes_d39g0v0_Shanghai + - addressOpcodes_d4g0v0_Shanghai + - addressOpcodes_d40g0v0_Shanghai + - addressOpcodes_d42g0v0_Shanghai + - addressOpcodes_d44g0v0_Shanghai + - addressOpcodes_d6g0v0_Shanghai + - addressOpcodes_d46g0v0_Shanghai + - storageCosts_d35g0v0_Shanghai + - addressOpcodes_d8g0v0_Shanghai + - variedContext_d11g0v0_Shanghai + - variedContext_d10g0v0_Shanghai + - variedContext_d16g0v0_Shanghai + - variedContext_d13g0v0_Shanghai + - variedContext_d12g0v0_Shanghai + - variedContext_d18g0v0_Shanghai + - variedContext_d14g0v0_Shanghai + - variedContext_d15g0v0_Shanghai + - variedContext_d0g0v0_Shanghai + - variedContext_d1g0v0_Shanghai + - variedContext_d34g0v0_Shanghai + - variedContext_d2g0v0_Shanghai + - variedContext_d22g0v0_Shanghai + - variedContext_d3g0v0_Shanghai + - variedContext_d4g0v0_Shanghai + - variedContext_d26g0v0_Shanghai + - variedContext_d6g0v0_Shanghai + - variedContext_d7g0v0_Shanghai + - variedContext_d8g0v0_Shanghai + - variedContext_d5g0v0_Shanghai + - variedContext_d9g0v0_Shanghai + - variedContext_d30g0v0_Shanghai + - variedContext_d24g0v0_Shanghai + - variedContext_d28g0v0_Shanghai + - variedContext_d32g0v0_Shanghai + - variedContext_d21g0v0_Shanghai + - variedContext_d20g0v0_Shanghai + stExample: + - invalidTr_d0g0v0_Shanghai + - eip1559_d0g0v0_Shanghai + - basefeeExample_d0g0v0_Shanghai + - mergeTest_d0g0v0_Shanghai + - solidityExample_d0g0v0_Shanghai + stExtCodeHash: + - extCodeCopyBounds_d0g0v0_Shanghai + - extCodeHashDynamicArgument_d1g0v0_Shanghai + - extCodeHashInInitCode_d1g0v0_Shanghai + - dynamicAccountOverwriteEmpty_d0g0v0_Shanghai + - extCodeHashSubcallSuicide_d0g0v0_Shanghai + - extcodehashEmpty_d0g0v0_Shanghai + - extcodehashEmpty_d2g0v0_Shanghai + - extcodehashEmpty_d1g0v0_Shanghai + - extcodehashEmpty_d3g0v0_Shanghai + - extcodehashEmpty_d4g0v0_Shanghai + - extcodehashEmpty_d5g0v0_Shanghai + - extcodehashEmpty_d6g0v0_Shanghai + - extcodehashEmpty_d7g0v0_Shanghai + - extcodehashEmpty_d8g0v0_Shanghai + - extCodeHashSubcallOOG_d4g0v0_Shanghai + - extcodehashEmpty_d9g0v0_Shanghai + - extCodeHashMaxCodeSize_d0g0v0_Shanghai + stInitCodeTest: + - CallContractToCreateContractWhichWouldCreateContractInInitCode_d0g0v0_Shanghai + - OutOfGasPrefundedContractCreation_d0g0v0_Shanghai + - OutOfGasPrefundedContractCreation_d0g2v0_Shanghai + - CallRecursiveContract_d0g0v0_Shanghai + stMemExpandingEIP150Calls: + - CreateAndGasInsideCreateWithMemExpandingCalls_d0g0v0_Shanghai + - CallGoesOOGOnSecondLevelWithMemExpandingCalls_d0g0v0_Shanghai + - NewGasPriceForCodesWithMemExpandingCalls_d0g0v0_Shanghai + stMemoryStressTest: + - RETURN_Bounds_d0g1v0_Shanghai + - RETURN_Bounds_d0g2v0_Shanghai + - DUP_Bounds_d0g0v0_Shanghai + - DUP_Bounds_d0g1v0_Shanghai + - DUP_Bounds_d0g2v0_Shanghai + stMemoryTest: + - bufferSrcOffset_d10g0v0_Shanghai + - bufferSrcOffset_d12g0v0_Shanghai + - bufferSrcOffset_d18g0v0_Shanghai + - bufferSrcOffset_d16g0v0_Shanghai + - bufferSrcOffset_d17g0v0_Shanghai + - bufferSrcOffset_d13g0v0_Shanghai + - bufferSrcOffset_d14g0v0_Shanghai + - bufferSrcOffset_d19g0v0_Shanghai + - bufferSrcOffset_d20g0v0_Shanghai + - bufferSrcOffset_d21g0v0_Shanghai + - bufferSrcOffset_d22g0v0_Shanghai + - bufferSrcOffset_d23g0v0_Shanghai + - bufferSrcOffset_d36g0v0_Shanghai + - bufferSrcOffset_d37g0v0_Shanghai + - bufferSrcOffset_d38g0v0_Shanghai + - bufferSrcOffset_d43g0v0_Shanghai + - bufferSrcOffset_d45g0v0_Shanghai + - bufferSrcOffset_d44g0v0_Shanghai + - bufferSrcOffset_d46g0v0_Shanghai + - bufferSrcOffset_d47g0v0_Shanghai + - bufferSrcOffset_d60g0v0_Shanghai + - bufferSrcOffset_d61g0v0_Shanghai + - bufferSrcOffset_d62g0v0_Shanghai + - bufferSrcOffset_d67g0v0_Shanghai + - bufferSrcOffset_d68g0v0_Shanghai + - bufferSrcOffset_d70g0v0_Shanghai + - bufferSrcOffset_d69g0v0_Shanghai + - bufferSrcOffset_d71g0v0_Shanghai + - bufferSrcOffset_d8g0v0_Shanghai + - bufferSrcOffset_d9g0v0_Shanghai + - buffer_d0g0v0_Shanghai + - buffer_d108g0v0_Shanghai + - buffer_d109g0v0_Shanghai + - buffer_d111g0v0_Shanghai + - buffer_d112g0v0_Shanghai + - buffer_d123g0v0_Shanghai + - buffer_d124g0v0_Shanghai + - buffer_d126g0v0_Shanghai + - buffer_d127g0v0_Shanghai + - buffer_d138g0v0_Shanghai + - buffer_d139g0v0_Shanghai + - buffer_d142g0v0_Shanghai + - buffer_d141g0v0_Shanghai + - buffer_d153g0v0_Shanghai + - buffer_d154g0v0_Shanghai + - buffer_d156g0v0_Shanghai + - buffer_d157g0v0_Shanghai + - buffer_d168g0v0_Shanghai + - buffer_d169g0v0_Shanghai + - buffer_d16g0v0_Shanghai + - buffer_d171g0v0_Shanghai + - buffer_d172g0v0_Shanghai + - buffer_d17g0v0_Shanghai + - buffer_d183g0v0_Shanghai + - buffer_d184g0v0_Shanghai + - buffer_d186g0v0_Shanghai + - buffer_d187g0v0_Shanghai + - buffer_d198g0v0_Shanghai + - buffer_d1g0v0_Shanghai + - buffer_d199g0v0_Shanghai + - buffer_d19g0v0_Shanghai + - buffer_d202g0v0_Shanghai + - buffer_d201g0v0_Shanghai + - buffer_d20g0v0_Shanghai + - buffer_d213g0v0_Shanghai + - buffer_d214g0v0_Shanghai + - buffer_d216g0v0_Shanghai + - buffer_d217g0v0_Shanghai + - buffer_d228g0v0_Shanghai + - buffer_d229g0v0_Shanghai + - buffer_d231g0v0_Shanghai + - buffer_d232g0v0_Shanghai + - buffer_d243g0v0_Shanghai + - buffer_d244g0v0_Shanghai + - buffer_d246g0v0_Shanghai + - buffer_d247g0v0_Shanghai + - buffer_d258g0v0_Shanghai + - buffer_d259g0v0_Shanghai + - buffer_d261g0v0_Shanghai + - buffer_d262g0v0_Shanghai + - buffer_d273g0v0_Shanghai + - buffer_d274g0v0_Shanghai + - buffer_d276g0v0_Shanghai + - buffer_d277g0v0_Shanghai + - buffer_d288g0v0_Shanghai + - buffer_d289g0v0_Shanghai + - buffer_d291g0v0_Shanghai + - buffer_d292g0v0_Shanghai + - buffer_d303g0v0_Shanghai + - buffer_d304g0v0_Shanghai + - buffer_d306g0v0_Shanghai + - buffer_d307g0v0_Shanghai + - buffer_d318g0v0_Shanghai + - buffer_d319g0v0_Shanghai + - buffer_d31g0v0_Shanghai + - buffer_d320g0v0_Shanghai + - buffer_d321g0v0_Shanghai + - buffer_d322g0v0_Shanghai + - buffer_d323g0v0_Shanghai + - buffer_d324g0v0_Shanghai + - buffer_d325g0v0_Shanghai + - buffer_d326g0v0_Shanghai + - buffer_d327g0v0_Shanghai + - buffer_d328g0v0_Shanghai + - buffer_d329g0v0_Shanghai + - buffer_d32g0v0_Shanghai + - buffer_d330g0v0_Shanghai + - buffer_d331g0v0_Shanghai + - buffer_d332g0v0_Shanghai + - buffer_d333g0v0_Shanghai + - buffer_d334g0v0_Shanghai + - buffer_d335g0v0_Shanghai + - buffer_d336g0v0_Shanghai + - buffer_d337g0v0_Shanghai + - buffer_d338g0v0_Shanghai + - buffer_d339g0v0_Shanghai + - buffer_d340g0v0_Shanghai + - buffer_d341g0v0_Shanghai + - buffer_d342g0v0_Shanghai + - buffer_d343g0v0_Shanghai + - buffer_d344g0v0_Shanghai + - buffer_d345g0v0_Shanghai + - buffer_d346g0v0_Shanghai + - buffer_d347g0v0_Shanghai + - buffer_d35g0v0_Shanghai + - buffer_d34g0v0_Shanghai + - buffer_d3g0v0_Shanghai + - buffer_d46g0v0_Shanghai + - buffer_d47g0v0_Shanghai + - buffer_d4g0v0_Shanghai + - buffer_d49g0v0_Shanghai + - buffer_d50g0v0_Shanghai + - buffer_d62g0v0_Shanghai + - buffer_d65g0v0_Shanghai + - buffer_d6g0v0_Shanghai + - callDataCopyOffset_d0g0v0_Shanghai + - codecopy_dejavu2_d0g0v0_Shanghai + - oog_d0g0v0_Shanghai + - buffer_d76g0v0_Shanghai + - memCopySelf_d0g0v0_Shanghai + - buffer_d77g0v0_Shanghai + - buffer_d79g0v0_Shanghai + - oog_d30g0v0_Shanghai + - buffer_d80g0v0_Shanghai + - oog_d9g0v0_Shanghai + - buffer_d93g0v0_Shanghai + - buffer_d94g0v0_Shanghai + - buffer_d96g0v0_Shanghai + - buffer_d97g0v0_Shanghai + - stackLimitGas_1023_d0g0v0_Shanghai + - stackLimitGas_1024_d0g0v0_Shanghai + - stackLimitPush31_1024_d0g0v0_Shanghai + - stackLimitPush31_1023_d0g0v0_Shanghai + - stackLimitPush32_1023_d0g0v0_Shanghai + - stackLimitPush32_1024_d0g0v0_Shanghai + stNonZeroCallsTest: + - NonZeroValue_CALL_ToNonNonZeroBalance_d0g0v0_Shanghai + stPreCompiledContracts2: + - CALLBlake2f_d4g0v0_Shanghai + - CALLBlake2f_d4g1v0_Shanghai + - CALLBlake2f_d4g2v0_Shanghai + - CALLBlake2f_d5g0v0_Shanghai + - CALLBlake2f_d4g3v0_Shanghai + - CALLBlake2f_d5g2v0_Shanghai + - CALLBlake2f_d5g1v0_Shanghai + - CALLBlake2f_d6g1v0_Shanghai + - CALLBlake2f_d5g3v0_Shanghai + - CALLBlake2f_d6g0v0_Shanghai + - CALLBlake2f_d6g2v0_Shanghai + - CALLBlake2f_d6g3v0_Shanghai + - CALLBlake2f_d7g0v0_Shanghai + - CALLBlake2f_d7g1v0_Shanghai + - CALLBlake2f_d7g2v0_Shanghai + - CALLBlake2f_d7g3v0_Shanghai + - CALLBlake2f_d8g0v0_Shanghai + - CALLBlake2f_d8g2v0_Shanghai + - CALLBlake2f_d8g1v0_Shanghai + - CALLBlake2f_d8g3v0_Shanghai + - CALLBlake2f_d9g0v0_Shanghai + - CALLCODEBlake2f_d4g0v0_Shanghai + - CALLCODEBlake2f_d4g1v0_Shanghai + - CALLCODEBlake2f_d4g2v0_Shanghai + - CALLCODEBlake2f_d4g3v0_Shanghai + - CALLCODEBlake2f_d5g0v0_Shanghai + - CALLCODEBlake2f_d5g1v0_Shanghai + - CALLCODEBlake2f_d5g2v0_Shanghai + - CALLCODEBlake2f_d5g3v0_Shanghai + - CALLCODEBlake2f_d6g0v0_Shanghai + - CALLCODEBlake2f_d6g1v0_Shanghai + - CALLCODEBlake2f_d6g2v0_Shanghai + - CALLCODEBlake2f_d6g3v0_Shanghai + - CALLCODEBlake2f_d7g0v0_Shanghai + - CALLCODEBlake2f_d7g1v0_Shanghai + - CALLCODEBlake2f_d7g3v0_Shanghai + - CALLCODEBlake2f_d7g2v0_Shanghai + - CALLCODEBlake2f_d8g0v0_Shanghai + - CALLCODEBlake2f_d8g1v0_Shanghai + - CALLCODEBlake2f_d8g3v0_Shanghai + - CALLCODEBlake2f_d8g2v0_Shanghai + - CALLCODEBlake2f_d9g0v0_Shanghai + - CALLCODEEcrecover0_completeReturnValue_d0g0v0_Shanghai + - CALLCODEEcrecover0_NoGas_d0g0v0_Shanghai + - CALLCODEEcrecover0_d0g0v0_Shanghai + - CALLCODEEcrecover0_gas3000_d0g0v0_Shanghai + - CALLCODEEcrecover0_overlappingInputOutput_d0g0v0_Shanghai + - CALLCODEEcrecover3_d0g0v0_Shanghai + - CALLCODEEcrecoverH_prefixed0_d0g0v0_Shanghai + - CALLCODEEcrecoverS_prefixed0_d0g0v0_Shanghai + - CALLCODEEcrecoverV_prefixed0_d0g0v0_Shanghai + - CALLCODERipemd160_1_d0g0v0_Shanghai + - CALLCODERipemd160_2_d0g0v0_Shanghai + - CALLCODERipemd160_3_postfixed0_d0g0v0_Shanghai + - CALLCODERipemd160_3_d0g0v0_Shanghai + - CALLCODERipemd160_3_prefixed0_d0g0v0_Shanghai + - CALLCODESha256_0_d0g0v0_Shanghai + - CALLCODESha256_1_d0g0v0_Shanghai + - CALLCODERipemd160_4_d0g0v0_Shanghai + - CALLCODESha256_1_nonzeroValue_d0g0v0_Shanghai + - CALLCODESha256_2_d0g0v0_Shanghai + - CALLCODESha256_3_d0g0v0_Shanghai + - CALLCODESha256_3_postfix0_d0g0v0_Shanghai + - CALLCODESha256_3_prefix0_d0g0v0_Shanghai + - CALLCODESha256_4_d0g0v0_Shanghai + - CALLCODESha256_4_gas99_d0g0v0_Shanghai + - CallEcrecover0_0input_d0g0v0_Shanghai + - CallEcrecover0_completeReturnValue_d0g0v0_Shanghai + - CallEcrecover0_Gas2999_d0g0v0_Shanghai + - CallEcrecover0_d0g0v0_Shanghai + - CallEcrecover0_NoGas_d0g0v0_Shanghai + - CallEcrecover0_gas3000_d0g0v0_Shanghai + - CallEcrecover0_overlappingInputOutput_d0g0v0_Shanghai + - CallEcrecover1_d0g0v0_Shanghai + - CallEcrecoverInvalidSignature_d0g0v0_Shanghai + - CallEcrecover2_d0g0v0_Shanghai + - CallEcrecover80_d0g0v0_Shanghai + - CallEcrecover3_d0g0v0_Shanghai + - CallEcrecoverH_prefixed0_d0g0v0_Shanghai + - CallEcrecoverCheckLengthWrongV_d0g0v0_Shanghai + - CallEcrecoverCheckLength_d0g0v0_Shanghai + - CallEcrecoverR_prefixed0_d0g0v0_Shanghai + - CallEcrecoverS_prefixed0_d0g0v0_Shanghai + - CallEcrecoverUnrecoverableKey_d0g0v0_Shanghai + - CallEcrecoverV_prefixed0_d0g0v0_Shanghai + - CallEcrecover_Overflow_d0g0v0_Shanghai + - CallEcrecover_Overflow_d1g0v0_Shanghai + - CallIdentitiy_1_d0g0v0_Shanghai + - CallIdentitiy_0_d0g0v0_Shanghai + - CallIdentity_1_nonzeroValue_d0g0v0_Shanghai + - CallIdentity_2_d0g0v0_Shanghai + - CallIdentity_3_d0g0v0_Shanghai + - CallIdentity_4_d0g0v0_Shanghai + - CallEcrecover_Overflow_d2g0v0_Shanghai + - CallIdentity_4_gas18_d0g0v0_Shanghai + - CallIdentity_4_gas17_d0g0v0_Shanghai + - CallEcrecover_Overflow_d3g0v0_Shanghai + - CallEcrecover_Overflow_d4g0v0_Shanghai + - CallRipemd160_0_d0g0v0_Shanghai + - CallEcrecover_Overflow_d5g0v0_Shanghai + - CallIdentity_6_inputShorterThanOutput_d0g0v0_Shanghai + - CallRipemd160_1_d0g0v0_Shanghai + - CallEcrecover_Overflow_d6g0v0_Shanghai + - CallEcrecover_Overflow_d7g0v0_Shanghai + - CallRipemd160_2_d0g0v0_Shanghai + - CallRipemd160_3_d0g0v0_Shanghai + - CallRipemd160_3_postfixed0_d0g0v0_Shanghai + - CallRipemd160_3_prefixed0_d0g0v0_Shanghai + - CallRipemd160_4_d0g0v0_Shanghai + - CallRipemd160_4_gas719_d0g0v0_Shanghai + - CallSha256_1_d0g0v0_Shanghai + - CallSha256_0_d0g0v0_Shanghai + - CallSha256_1_nonzeroValue_d0g0v0_Shanghai + - CallSha256_2_d0g0v0_Shanghai + - CallSha256_3_d0g0v0_Shanghai + - CallSha256_3_postfix0_d0g0v0_Shanghai + - CallSha256_3_prefix0_d0g0v0_Shanghai + - CallSha256_4_d0g0v0_Shanghai + - CallSha256_4_gas99_d0g0v0_Shanghai + - ecrecoverWeirdV_d0g0v0_Shanghai + - ecrecoverWeirdV_d10g0v0_Shanghai + - ecrecoverWeirdV_d11g0v0_Shanghai + - ecrecoverWeirdV_d12g0v0_Shanghai + - ecrecoverWeirdV_d13g0v0_Shanghai + - ecrecoverWeirdV_d14g0v0_Shanghai + - ecrecoverWeirdV_d15g0v0_Shanghai + - ecrecoverWeirdV_d18g0v0_Shanghai + - ecrecoverWeirdV_d16g0v0_Shanghai + - ecrecoverWeirdV_d17g0v0_Shanghai + - ecrecoverWeirdV_d19g0v0_Shanghai + - ecrecoverWeirdV_d1g0v0_Shanghai + - ecrecoverWeirdV_d20g0v0_Shanghai + - ecrecoverWeirdV_d21g0v0_Shanghai + - ecrecoverWeirdV_d22g0v0_Shanghai + - ecrecoverWeirdV_d23g0v0_Shanghai + - ecrecoverWeirdV_d24g0v0_Shanghai + - ecrecoverWeirdV_d25g0v0_Shanghai + - ecrecoverWeirdV_d26g0v0_Shanghai + - ecrecoverWeirdV_d28g0v0_Shanghai + - ecrecoverWeirdV_d27g0v0_Shanghai + - ecrecoverWeirdV_d2g0v0_Shanghai + - ecrecoverWeirdV_d29g0v0_Shanghai + - ecrecoverWeirdV_d30g0v0_Shanghai + - ecrecoverWeirdV_d32g0v0_Shanghai + - ecrecoverWeirdV_d31g0v0_Shanghai + - ecrecoverWeirdV_d33g0v0_Shanghai + - ecrecoverWeirdV_d35g0v0_Shanghai + - ecrecoverWeirdV_d34g0v0_Shanghai + - ecrecoverWeirdV_d3g0v0_Shanghai + - ecrecoverWeirdV_d4g0v0_Shanghai + - ecrecoverWeirdV_d5g0v0_Shanghai + - ecrecoverWeirdV_d6g0v0_Shanghai + - ecrecoverWeirdV_d8g0v0_Shanghai + - ecrecoverWeirdV_d7g0v0_Shanghai + - ecrecoverWeirdV_d9g0v0_Shanghai + - modexp_0_0_0_20500_d0g1v0_Shanghai + - modexp_0_0_0_20500_d0g2v0_Shanghai + - modexp_0_0_0_20500_d0g3v0_Shanghai + - modexp_0_0_0_22000_d0g0v0_Shanghai + - modexp_0_0_0_22000_d0g2v0_Shanghai + - modexp_0_0_0_22000_d0g1v0_Shanghai + - modexp_0_0_0_25000_d0g3v0_Shanghai + - modexp_0_0_0_22000_d0g3v0_Shanghai + - modexp_0_0_0_25000_d0g0v0_Shanghai + - modexp_0_0_0_25000_d0g1v0_Shanghai + - modexp_0_0_0_25000_d0g2v0_Shanghai + - modexp_0_0_0_35000_d0g0v0_Shanghai + - modexp_0_0_0_35000_d0g1v0_Shanghai + - modexp_0_0_0_35000_d0g3v0_Shanghai + - modexp_0_0_0_35000_d0g2v0_Shanghai + - CALLCODEIdentity_5_d0g0v0_Shanghai + - CALLCODERipemd160_5_d0g0v0_Shanghai + - CALLCODESha256_5_d0g0v0_Shanghai + - CallIdentity_5_d0g0v0_Shanghai + - CallRipemd160_5_d0g0v0_Shanghai + - CallSha256_5_d0g0v0_Shanghai + - ecrecoverShortBuff_d0g0v0_Shanghai + stPreCompiledContracts: + - blake2B_d0g0v0_Shanghai + - blake2B_d1g0v0_Shanghai + - blake2B_d2g0v0_Shanghai + - delegatecall09Undefined_d0g0v0_Shanghai + - blake2B_d3g0v0_Shanghai + - blake2B_d4g0v0_Shanghai + - blake2B_d5g0v0_Shanghai + - idPrecomps_d0g0v0_Shanghai + - blake2B_d6g0v0_Shanghai + - blake2B_d10g0v0_Shanghai + - blake2B_d11g0v0_Shanghai + - blake2B_d7g0v0_Shanghai + - blake2B_d8g0v0_Shanghai + - blake2B_d12g0v0_Shanghai + - blake2B_d13g0v0_Shanghai + - blake2B_d14g0v0_Shanghai + - blake2B_d15g0v0_Shanghai + - blake2B_d9g0v0_Shanghai + - idPrecomps_d1g0v0_Shanghai + - blake2B_d17g0v0_Shanghai + - blake2B_d18g0v0_Shanghai + - blake2B_d19g0v0_Shanghai + - blake2B_d23g0v0_Shanghai + - blake2B_d21g0v0_Shanghai + - blake2B_d16g0v0_Shanghai + - blake2B_d20g0v0_Shanghai + - blake2B_d24g0v0_Shanghai + - blake2B_d25g0v0_Shanghai + - blake2B_d22g0v0_Shanghai + - idPrecomps_d2g0v0_Shanghai + - idPrecomps_d3g0v0_Shanghai + - idPrecomps_d4g0v0_Shanghai + - idPrecomps_d5g0v0_Shanghai + - idPrecomps_d6g0v0_Shanghai + - idPrecomps_d7g0v0_Shanghai + - idPrecomps_d8g0v0_Shanghai + - identity_to_bigger_d0g0v0_Shanghai + - identity_to_smaller_d0g0v0_Shanghai + - modexpTests_d0g0v0_Shanghai + - modexpTests_d100g0v0_Shanghai + - modexpTests_d101g0v0_Shanghai + - modexpTests_d102g0v0_Shanghai + - modexpTests_d103g0v0_Shanghai + - modexpTests_d104g0v0_Shanghai + - modexpTests_d106g0v0_Shanghai + - modexpTests_d105g0v0_Shanghai + - modexpTests_d107g0v0_Shanghai + - modexpTests_d108g0v0_Shanghai + - modexpTests_d109g0v0_Shanghai + - modexpTests_d10g0v0_Shanghai + - modexpTests_d110g0v0_Shanghai + - modexpTests_d111g0v0_Shanghai + - modexpTests_d112g0v0_Shanghai + - modexpTests_d113g0v0_Shanghai + - modexpTests_d114g0v0_Shanghai + - modexpTests_d115g0v0_Shanghai + - modexpTests_d116g0v0_Shanghai + - modexpTests_d117g0v0_Shanghai + - modexpTests_d118g0v0_Shanghai + - modexpTests_d11g0v0_Shanghai + - modexpTests_d120g0v0_Shanghai + - modexpTests_d119g0v0_Shanghai + - modexpTests_d121g0v0_Shanghai + - modexpTests_d122g0v0_Shanghai + - modexpTests_d123g0v0_Shanghai + - modexpTests_d124g0v0_Shanghai + - modexpTests_d125g0v0_Shanghai + - modexpTests_d126g0v0_Shanghai + - modexpTests_d12g0v0_Shanghai + - modexpTests_d13g0v0_Shanghai + - modexpTests_d14g0v0_Shanghai + - modexpTests_d15g0v0_Shanghai + - modexpTests_d16g0v0_Shanghai + - modexpTests_d18g0v0_Shanghai + - modexpTests_d17g0v0_Shanghai + - modexpTests_d19g0v0_Shanghai + - modexpTests_d1g0v0_Shanghai + - modexpTests_d20g0v0_Shanghai + - modexpTests_d21g0v0_Shanghai + - modexpTests_d22g0v0_Shanghai + - modexpTests_d24g0v0_Shanghai + - modexpTests_d23g0v0_Shanghai + - modexpTests_d25g0v0_Shanghai + - modexpTests_d26g0v0_Shanghai + - modexpTests_d27g0v0_Shanghai + - modexpTests_d29g0v0_Shanghai + - modexpTests_d28g0v0_Shanghai + - modexpTests_d2g0v0_Shanghai + - modexpTests_d30g0v0_Shanghai + - modexpTests_d31g0v0_Shanghai + - modexpTests_d32g0v0_Shanghai + - modexpTests_d33g0v0_Shanghai + - modexpTests_d34g0v0_Shanghai + - modexpTests_d36g0v0_Shanghai + - modexpTests_d35g0v0_Shanghai + - modexpTests_d38g0v0_Shanghai + - modexpTests_d37g0v0_Shanghai + - modexpTests_d39g0v0_Shanghai + - modexpTests_d3g0v0_Shanghai + - modexpTests_d40g0v0_Shanghai + - modexpTests_d41g0v0_Shanghai + - modexpTests_d42g0v0_Shanghai + - modexpTests_d43g0v0_Shanghai + - modexpTests_d44g0v0_Shanghai + - modexpTests_d45g0v0_Shanghai + - modexpTests_d46g0v0_Shanghai + - modexpTests_d47g0v0_Shanghai + - modexpTests_d48g0v0_Shanghai + - modexpTests_d49g0v0_Shanghai + - modexpTests_d4g0v0_Shanghai + - modexpTests_d50g0v0_Shanghai + - modexpTests_d51g0v0_Shanghai + - modexpTests_d52g0v0_Shanghai + - modexpTests_d53g0v0_Shanghai + - modexpTests_d54g0v0_Shanghai + - modexpTests_d55g0v0_Shanghai + - modexpTests_d56g0v0_Shanghai + - modexpTests_d57g0v0_Shanghai + - modexpTests_d59g0v0_Shanghai + - modexpTests_d58g0v0_Shanghai + - modexpTests_d5g0v0_Shanghai + - modexpTests_d60g0v0_Shanghai + - modexpTests_d61g0v0_Shanghai + - modexpTests_d62g0v0_Shanghai + - modexpTests_d64g0v0_Shanghai + - modexpTests_d63g0v0_Shanghai + - modexpTests_d65g0v0_Shanghai + - modexpTests_d66g0v0_Shanghai + - modexpTests_d67g0v0_Shanghai + - modexpTests_d68g0v0_Shanghai + - modexpTests_d69g0v0_Shanghai + - modexpTests_d6g0v0_Shanghai + - modexpTests_d70g0v0_Shanghai + - modexpTests_d71g0v0_Shanghai + - modexpTests_d72g0v0_Shanghai + - modexpTests_d73g0v0_Shanghai + - modexpTests_d74g0v0_Shanghai + - modexpTests_d75g0v0_Shanghai + - modexpTests_d76g0v0_Shanghai + - modexpTests_d77g0v0_Shanghai + - modexpTests_d78g0v0_Shanghai + - modexpTests_d79g0v0_Shanghai + - modexpTests_d7g0v0_Shanghai + - modexpTests_d81g0v0_Shanghai + - modexpTests_d80g0v0_Shanghai + - modexpTests_d82g0v0_Shanghai + - modexpTests_d83g0v0_Shanghai + - modexpTests_d84g0v0_Shanghai + - modexpTests_d86g0v0_Shanghai + - modexpTests_d85g0v0_Shanghai + - modexpTests_d87g0v0_Shanghai + - modexpTests_d88g0v0_Shanghai + - modexpTests_d89g0v0_Shanghai + - modexpTests_d8g0v0_Shanghai + - modexpTests_d90g0v0_Shanghai + - modexpTests_d91g0v0_Shanghai + - modexpTests_d93g0v0_Shanghai + - modexpTests_d92g0v0_Shanghai + - modexpTests_d94g0v0_Shanghai + - modexpTests_d95g0v0_Shanghai + - modexpTests_d96g0v0_Shanghai + - modexpTests_d97g0v0_Shanghai + - modexpTests_d98g0v0_Shanghai + - modexpTests_d99g0v0_Shanghai + - modexp_d0g0v0_Shanghai + - modexpTests_d9g0v0_Shanghai + - modexp_d0g1v0_Shanghai + - modexp_d0g2v0_Shanghai + - modexp_d0g3v0_Shanghai + - modexp_d11g0v0_Shanghai + - modexp_d11g1v0_Shanghai + - modexp_d11g2v0_Shanghai + - modexp_d11g3v0_Shanghai + - modexp_d14g0v0_Shanghai + - modexp_d14g1v0_Shanghai + - modexp_d14g2v0_Shanghai + - modexp_d14g3v0_Shanghai + - modexp_d16g1v0_Shanghai + - modexp_d16g2v0_Shanghai + - modexp_d16g0v0_Shanghai + - modexp_d17g0v0_Shanghai + - modexp_d16g3v0_Shanghai + - modexp_d17g1v0_Shanghai + - modexp_d17g2v0_Shanghai + - modexp_d17g3v0_Shanghai + - modexp_d25g0v0_Shanghai + - modexp_d25g2v0_Shanghai + - modexp_d25g1v0_Shanghai + - modexp_d25g3v0_Shanghai + - modexp_d26g0v0_Shanghai + - modexp_d26g1v0_Shanghai + - modexp_d26g2v0_Shanghai + - modexp_d26g3v0_Shanghai + - modexp_d32g1v0_Shanghai + - modexp_d32g2v0_Shanghai + - modexp_d32g0v0_Shanghai + - modexp_d27g1v0_Shanghai + - modexp_d31g0v0_Shanghai + - modexp_d31g1v0_Shanghai + - modexp_d31g2v0_Shanghai + - modexp_d31g3v0_Shanghai + - modexp_d27g3v0_Shanghai + - modexp_d32g3v0_Shanghai + - modexp_d27g0v0_Shanghai + - modexp_d33g0v0_Shanghai + - modexp_d27g2v0_Shanghai + - modexp_d33g2v0_Shanghai + - modexp_d33g1v0_Shanghai + - modexp_d33g3v0_Shanghai + - modexp_d34g0v0_Shanghai + - modexp_d34g1v0_Shanghai + - modexp_d34g2v0_Shanghai + - modexp_d34g3v0_Shanghai + - modexp_d35g0v0_Shanghai + - modexp_d35g1v0_Shanghai + - modexp_d35g2v0_Shanghai + - modexp_d35g3v0_Shanghai + - modexp_d4g0v0_Shanghai + - modexp_d4g1v0_Shanghai + - modexp_d4g2v0_Shanghai + - modexp_d4g3v0_Shanghai + - modexp_d3g0v0_Shanghai + - modexp_d3g1v0_Shanghai + - modexp_d3g3v0_Shanghai + - modexp_d3g2v0_Shanghai + - modexp_d6g0v0_Shanghai + - modexp_d6g1v0_Shanghai + - modexp_d6g2v0_Shanghai + - modexp_d7g0v0_Shanghai + - modexp_d7g1v0_Shanghai + - modexp_d7g2v0_Shanghai + - modexp_d6g3v0_Shanghai + - modexp_d7g3v0_Shanghai + - precompsEIP2929_d10g0v0_Shanghai + - precompsEIP2929_d11g0v0_Shanghai + - precompsEIP2929_d106g0v0_Shanghai + - precompsEIP2929_d18g0v0_Shanghai + - precompsEIP2929_d19g0v0_Shanghai + - precompsEIP2929_d20g0v0_Shanghai + - precompsEIP2929_d21g0v0_Shanghai + - precompsEIP2929_d22g0v0_Shanghai + - precompsEIP2929_d23g0v0_Shanghai + - precompsEIP2929_d24g0v0_Shanghai + - precompsEIP2929_d25g0v0_Shanghai + - precompsEIP2929_d26g0v0_Shanghai + - precompsEIP2929_d270g0v0_Shanghai + - precompsEIP2929_d271g0v0_Shanghai + - precompsEIP2929_d272g0v0_Shanghai + - precompsEIP2929_d273g0v0_Shanghai + - precompsEIP2929_d274g0v0_Shanghai + - precompsEIP2929_d275g0v0_Shanghai + - precompsEIP2929_d276g0v0_Shanghai + - precompsEIP2929_d277g0v0_Shanghai + - precompsEIP2929_d278g0v0_Shanghai + - precompsEIP2929_d288g0v0_Shanghai + - precompsEIP2929_d289g0v0_Shanghai + - precompsEIP2929_d290g0v0_Shanghai + - precompsEIP2929_d291g0v0_Shanghai + - precompsEIP2929_d292g0v0_Shanghai + - precompsEIP2929_d293g0v0_Shanghai + - precompsEIP2929_d294g0v0_Shanghai + - precompsEIP2929_d295g0v0_Shanghai + - precompsEIP2929_d296g0v0_Shanghai + - precompsEIP2929_d306g0v0_Shanghai + - precompsEIP2929_d307g0v0_Shanghai + - precompsEIP2929_d308g0v0_Shanghai + - precompsEIP2929_d309g0v0_Shanghai + - precompsEIP2929_d310g0v0_Shanghai + - precompsEIP2929_d311g0v0_Shanghai + - precompsEIP2929_d312g0v0_Shanghai + - precompsEIP2929_d313g0v0_Shanghai + - precompsEIP2929_d314g0v0_Shanghai + - precompsEIP2929_d34g0v0_Shanghai + - precompsEIP2929_d36g0v0_Shanghai + - precompsEIP2929_d37g0v0_Shanghai + - precompsEIP2929_d38g0v0_Shanghai + - precompsEIP2929_d3g0v0_Shanghai + - precompsEIP2929_d39g0v0_Shanghai + - precompsEIP2929_d40g0v0_Shanghai + - precompsEIP2929_d41g0v0_Shanghai + - precompsEIP2929_d42g0v0_Shanghai + - precompsEIP2929_d43g0v0_Shanghai + - precompsEIP2929_d44g0v0_Shanghai + - precompsEIP2929_d4g0v0_Shanghai + - precompsEIP2929_d54g0v0_Shanghai + - precompsEIP2929_d55g0v0_Shanghai + - precompsEIP2929_d56g0v0_Shanghai + - precompsEIP2929_d5g0v0_Shanghai + - precompsEIP2929_d57g0v0_Shanghai + - precompsEIP2929_d58g0v0_Shanghai + - precompsEIP2929_d59g0v0_Shanghai + - precompsEIP2929_d60g0v0_Shanghai + - precompsEIP2929_d61g0v0_Shanghai + - precompsEIP2929_d62g0v0_Shanghai + - precompsEIP2929_d6g0v0_Shanghai + - precompsEIP2929_d7g0v0_Shanghai + - precompsEIP2929_d72g0v0_Shanghai + - precompsEIP2929_d73g0v0_Shanghai + - precompsEIP2929_d74g0v0_Shanghai + - precompsEIP2929_d75g0v0_Shanghai + - precompsEIP2929_d77g0v0_Shanghai + - precompsEIP2929_d76g0v0_Shanghai + - precompsEIP2929_d8g0v0_Shanghai + - precompsEIP2929_d78g0v0_Shanghai + - precompsEIP2929_d79g0v0_Shanghai + - precompsEIP2929_d80g0v0_Shanghai + - sec80_d0g0v0_Shanghai + - precompsEIP2929_d90g0v0_Shanghai + - precompsEIP2929_d91g0v0_Shanghai + - precompsEIP2929_d70g0v0_Shanghai + - precompsEIP2929_d92g0v0_Shanghai + - precompsEIP2929_d9g0v0_Shanghai + - precompsEIP2929_d93g0v0_Shanghai + - precompsEIP2929_d94g0v0_Shanghai + - precompsEIP2929_d95g0v0_Shanghai + - precompsEIP2929_d98g0v0_Shanghai + - precompsEIP2929_d96g0v0_Shanghai + - precompsEIP2929_d97g0v0_Shanghai + stRandom2: + - 201503110226PYTHON_DUP6_d0g0v0_Shanghai + - randomStatetest389_d0g0v0_Shanghai + - randomStatetest396_d0g0v0_Shanghai + - randomStatetest409_d0g0v0_Shanghai + - randomStatetest417_d0g0v0_Shanghai + - randomStatetest415_d0g0v0_Shanghai + - randomStatetest428_d0g0v0_Shanghai + - randomStatetest416_d0g0v0_Shanghai + - randomStatetest420_d0g0v0_Shanghai + - randomStatetest435_d0g0v0_Shanghai + - randomStatetest437_d0g0v0_Shanghai + - randomStatetest446_d0g0v0_Shanghai + - randomStatetest450_d0g0v0_Shanghai + - randomStatetest466_d0g0v0_Shanghai + - randomStatetest471_d0g0v0_Shanghai + - randomStatetest473_d0g0v0_Shanghai + - randomStatetest475_d0g0v0_Shanghai + - randomStatetest478_d0g0v0_Shanghai + - randomStatetest508_d0g0v0_Shanghai + - randomStatetest501_d0g0v0_Shanghai + - randomStatetest519_d0g0v0_Shanghai + - randomStatetest531_d0g0v0_Shanghai + - randomStatetest525_d0g0v0_Shanghai + - randomStatetest521_d0g0v0_Shanghai + - randomStatetest541_d0g0v0_Shanghai + - randomStatetest539_d0g0v0_Shanghai + - randomStatetest542_d0g0v0_Shanghai + - randomStatetest558_d0g0v0_Shanghai + - randomStatetest577_d0g0v0_Shanghai + - randomStatetest572_d0g0v0_Shanghai + - randomStatetest571_d0g0v0_Shanghai + - randomStatetest578_d0g0v0_Shanghai + - randomStatetest387_d0g0v0_Shanghai + - randomStatetest581_d0g0v0_Shanghai + - randomStatetest584_d0g0v0_Shanghai + - randomStatetest592_d0g0v0_Shanghai + - randomStatetest605_d0g0v0_Shanghai + - randomStatetest609_d0g0v0_Shanghai + - randomStatetest624_d0g0v0_Shanghai + - randomStatetest615_d0g0v0_Shanghai + - randomStatetest628_d0g0v0_Shanghai + - randomStatetest638_d0g0v0_Shanghai + - randomStatetest645_d0g0v0_Shanghai + - randomStatetest644_d0g0v0_Shanghai + - randomStatetest506_d0g0v0_Shanghai + - randomStatetest397_d0g0v0_Shanghai + - randomStatetest588_d0g0v0_Shanghai + - randomStatetest410_d0g0v0_Shanghai + - randomStatetest418_d0g0v0_Shanghai + - randomStatetest433_d0g0v0_Shanghai + - randomStatetest448_d0g0v0_Shanghai + - randomStatetest456_d0g0v0_Shanghai + - randomStatetest469_d0g0v0_Shanghai + - randomStatetest476_d0g0v0_Shanghai + - randomStatetest458_d0g0v0_Shanghai + - randomStatetest467_d0g0v0_Shanghai + - randomStatetest579_d0g0v0_Shanghai + - randomStatetest536_d0g0v0_Shanghai + - randomStatetest547_d0g0v0_Shanghai + - randomStatetest560_d0g0v0_Shanghai + - randomStatetest582_d0g0v0_Shanghai + - randomStatetest583_d0g0v0_Shanghai + - randomStatetest554_d0g0v0_Shanghai + - randomStatetest589_d0g0v0_Shanghai + - randomStatetest636_d0g0v0_Shanghai + - randomStatetest639_d0g0v0_Shanghai + - randomStatetest650_d0g0v0_Shanghai + stQuadraticComplexityTest: + - Call1MB1024Calldepth_d0g1v0_Shanghai + - Call20KbytesContract50_1_d0g1v0_Shanghai + - Call20KbytesContract50_2_d0g1v0_Shanghai + - Call20KbytesContract50_3_d0g1v0_Shanghai + - Return50000_d0g1v0_Shanghai + - Return50000_2_d0g1v0_Shanghai + stRandom: + - randomStatetest100_d0g0v0_Shanghai + - randomStatetest0_d0g0v0_Shanghai + - randomStatetest107_d0g0v0_Shanghai + - randomStatetest116_d0g0v0_Shanghai + - randomStatetest124_d0g0v0_Shanghai + - randomStatetest143_d0g0v0_Shanghai + - randomStatetest139_d0g0v0_Shanghai + - randomStatetest145_d0g0v0_Shanghai + - randomStatetest144_d0g0v0_Shanghai + - randomStatetest14_d0g0v0_Shanghai + - randomStatetest153_d0g0v0_Shanghai + - randomStatetest157_d0g0v0_Shanghai + - randomStatetest150_d0g0v0_Shanghai + - randomStatetest164_d0g0v0_Shanghai + - randomStatetest174_d0g0v0_Shanghai + - randomStatetest176_d0g0v0_Shanghai + - randomStatetest173_d0g0v0_Shanghai + - randomStatetest184_d0g0v0_Shanghai + - randomStatetest178_d0g0v0_Shanghai + - randomStatetest199_d0g0v0_Shanghai + - randomStatetest195_d0g0v0_Shanghai + - randomStatetest197_d0g0v0_Shanghai + - randomStatetest196_d0g0v0_Shanghai + - randomStatetest207_d0g0v0_Shanghai + - randomStatetest201_d0g0v0_Shanghai + - randomStatetest202_d0g0v0_Shanghai + - randomStatetest204_d0g0v0_Shanghai + - randomStatetest209_d0g0v0_Shanghai + - randomStatetest210_d0g0v0_Shanghai + - randomStatetest228_d0g0v0_Shanghai + - randomStatetest222_d0g0v0_Shanghai + - randomStatetest244_d0g0v0_Shanghai + - randomStatetest236_d0g0v0_Shanghai + - randomStatetest246_d0g0v0_Shanghai + - randomStatetest252_d0g0v0_Shanghai + - randomStatetest248_d0g0v0_Shanghai + - randomStatetest251_d0g0v0_Shanghai + - randomStatetest249_d0g0v0_Shanghai + - randomStatetest25_d0g0v0_Shanghai + - randomStatetest26_d0g0v0_Shanghai + - randomStatetest273_d0g0v0_Shanghai + - randomStatetest271_d0g0v0_Shanghai + - randomStatetest270_d0g0v0_Shanghai + - randomStatetest27_d0g0v0_Shanghai + - randomStatetest288_d0g0v0_Shanghai + - randomStatetest283_d0g0v0_Shanghai + - randomStatetest17_d0g0v0_Shanghai + - randomStatetest290_d0g0v0_Shanghai + - randomStatetest30_d0g0v0_Shanghai + - randomStatetest308_d0g0v0_Shanghai + - randomStatetest312_d0g0v0_Shanghai + - randomStatetest108_d0g0v0_Shanghai + - randomStatetest325_d0g0v0_Shanghai + - randomStatetest111_d0g0v0_Shanghai + - randomStatetest138_d0g0v0_Shanghai + - randomStatetest345_d0g0v0_Shanghai + - randomStatetest349_d0g0v0_Shanghai + - randomStatetest351_d0g0v0_Shanghai + - randomStatetest347_d0g0v0_Shanghai + - randomStatetest362_d0g0v0_Shanghai + - randomStatetest367_d0g0v0_Shanghai + - randomStatetest368_d0g0v0_Shanghai + - randomStatetest379_d0g0v0_Shanghai + - randomStatetest371_d0g0v0_Shanghai + - randomStatetest376_d0g0v0_Shanghai + - randomStatetest154_d0g0v0_Shanghai + - randomStatetest151_d0g0v0_Shanghai + - randomStatetest159_d0g0v0_Shanghai + - randomStatetest383_d0g0v0_Shanghai + - randomStatetest39_d0g0v0_Shanghai + - randomStatetest3_d0g0v0_Shanghai + - randomStatetest45_d0g0v0_Shanghai + - randomStatetest163_d0g0v0_Shanghai + - randomStatetest43_d0g0v0_Shanghai + - randomStatetest66_d0g0v0_Shanghai + - randomStatetest185_d0g0v0_Shanghai + - randomStatetest78_d0g0v0_Shanghai + - randomStatetest88_d0g0v0_Shanghai + - randomStatetest85_d0g0v0_Shanghai + - randomStatetest98_d0g0v0_Shanghai + - randomStatetest354_d0g0v0_Shanghai + - randomStatetest357_d0g0v0_Shanghai + - randomStatetest205_d0g0v0_Shanghai + - randomStatetest211_d0g0v0_Shanghai + - randomStatetest365_d0g0v0_Shanghai + - randomStatetest260_d0g0v0_Shanghai + - randomStatetest285_d0g0v0_Shanghai + - randomStatetest326_d0g0v0_Shanghai + - randomStatetest306_d0g0v0_Shanghai + - randomStatetest335_d0g0v0_Shanghai + - randomStatetest336_d0g0v0_Shanghai + - randomStatetest341_d0g0v0_Shanghai + - randomStatetest36_d0g0v0_Shanghai + - randomStatetest384_d0g0v0_Shanghai + - randomStatetest48_d0g0v0_Shanghai + - randomStatetest4_d0g0v0_Shanghai + - randomStatetest53_d0g0v0_Shanghai + stRefundTest: + - refundSuicide50procentCap_d1g0v0_Shanghai + - refund_CallToSuicideTwice_d1g0v0_Shanghai + - refund_multimpleSuicide_d0g0v0_Shanghai + stReturnDataTest: + - call_ecrec_success_empty_then_returndatasize_d0g0v0_Shanghai + - clearReturnBuffer_d100g0v0_Shanghai + - clearReturnBuffer_d101g0v0_Shanghai + - clearReturnBuffer_d106g0v0_Shanghai + - clearReturnBuffer_d102g0v0_Shanghai + - clearReturnBuffer_d103g0v0_Shanghai + - clearReturnBuffer_d107g0v0_Shanghai + - clearReturnBuffer_d108g0v0_Shanghai + - clearReturnBuffer_d109g0v0_Shanghai + - clearReturnBuffer_d112g0v0_Shanghai + - clearReturnBuffer_d104g0v0_Shanghai + - clearReturnBuffer_d105g0v0_Shanghai + - clearReturnBuffer_d113g0v0_Shanghai + - clearReturnBuffer_d110g0v0_Shanghai + - clearReturnBuffer_d111g0v0_Shanghai + - clearReturnBuffer_d114g0v0_Shanghai + - clearReturnBuffer_d115g0v0_Shanghai + - clearReturnBuffer_d116g0v0_Shanghai + - clearReturnBuffer_d10g0v0_Shanghai + - clearReturnBuffer_d117g0v0_Shanghai + - clearReturnBuffer_d120g0v0_Shanghai + - clearReturnBuffer_d121g0v0_Shanghai + - clearReturnBuffer_d123g0v0_Shanghai + - clearReturnBuffer_d122g0v0_Shanghai + - clearReturnBuffer_d0g0v0_Shanghai + - clearReturnBuffer_d118g0v0_Shanghai + - clearReturnBuffer_d119g0v0_Shanghai + - clearReturnBuffer_d124g0v0_Shanghai + - clearReturnBuffer_d127g0v0_Shanghai + - clearReturnBuffer_d126g0v0_Shanghai + - clearReturnBuffer_d128g0v0_Shanghai + - clearReturnBuffer_d129g0v0_Shanghai + - clearReturnBuffer_d125g0v0_Shanghai + - clearReturnBuffer_d130g0v0_Shanghai + - clearReturnBuffer_d131g0v0_Shanghai + - clearReturnBuffer_d134g0v0_Shanghai + - clearReturnBuffer_d11g0v0_Shanghai + - clearReturnBuffer_d135g0v0_Shanghai + - clearReturnBuffer_d136g0v0_Shanghai + - clearReturnBuffer_d137g0v0_Shanghai + - clearReturnBuffer_d132g0v0_Shanghai + - clearReturnBuffer_d133g0v0_Shanghai + - clearReturnBuffer_d138g0v0_Shanghai + - clearReturnBuffer_d139g0v0_Shanghai + - clearReturnBuffer_d12g0v0_Shanghai + - clearReturnBuffer_d140g0v0_Shanghai + - clearReturnBuffer_d141g0v0_Shanghai + - clearReturnBuffer_d142g0v0_Shanghai + - clearReturnBuffer_d143g0v0_Shanghai + - clearReturnBuffer_d13g0v0_Shanghai + - clearReturnBuffer_d144g0v0_Shanghai + - clearReturnBuffer_d145g0v0_Shanghai + - clearReturnBuffer_d148g0v0_Shanghai + - clearReturnBuffer_d149g0v0_Shanghai + - clearReturnBuffer_d14g0v0_Shanghai + - clearReturnBuffer_d150g0v0_Shanghai + - clearReturnBuffer_d151g0v0_Shanghai + - clearReturnBuffer_d146g0v0_Shanghai + - clearReturnBuffer_d147g0v0_Shanghai + - clearReturnBuffer_d152g0v0_Shanghai + - clearReturnBuffer_d154g0v0_Shanghai + - clearReturnBuffer_d153g0v0_Shanghai + - clearReturnBuffer_d15g0v0_Shanghai + - clearReturnBuffer_d155g0v0_Shanghai + - clearReturnBuffer_d156g0v0_Shanghai + - clearReturnBuffer_d157g0v0_Shanghai + - clearReturnBuffer_d158g0v0_Shanghai + - clearReturnBuffer_d159g0v0_Shanghai + - clearReturnBuffer_d162g0v0_Shanghai + - clearReturnBuffer_d163g0v0_Shanghai + - clearReturnBuffer_d164g0v0_Shanghai + - clearReturnBuffer_d160g0v0_Shanghai + - clearReturnBuffer_d28g0v0_Shanghai + - clearReturnBuffer_d165g0v0_Shanghai + - clearReturnBuffer_d161g0v0_Shanghai + - clearReturnBuffer_d29g0v0_Shanghai + - clearReturnBuffer_d30g0v0_Shanghai + - clearReturnBuffer_d31g0v0_Shanghai + - clearReturnBuffer_d166g0v0_Shanghai + - clearReturnBuffer_d32g0v0_Shanghai + - clearReturnBuffer_d1g0v0_Shanghai + - clearReturnBuffer_d16g0v0_Shanghai + - clearReturnBuffer_d17g0v0_Shanghai + - clearReturnBuffer_d33g0v0_Shanghai + - clearReturnBuffer_d37g0v0_Shanghai + - clearReturnBuffer_d167g0v0_Shanghai + - clearReturnBuffer_d18g0v0_Shanghai + - clearReturnBuffer_d19g0v0_Shanghai + - clearReturnBuffer_d38g0v0_Shanghai + - clearReturnBuffer_d39g0v0_Shanghai + - clearReturnBuffer_d23g0v0_Shanghai + - clearReturnBuffer_d24g0v0_Shanghai + - clearReturnBuffer_d25g0v0_Shanghai + - clearReturnBuffer_d34g0v0_Shanghai + - clearReturnBuffer_d35g0v0_Shanghai + - clearReturnBuffer_d20g0v0_Shanghai + - clearReturnBuffer_d2g0v0_Shanghai + - clearReturnBuffer_d42g0v0_Shanghai + - clearReturnBuffer_d21g0v0_Shanghai + - clearReturnBuffer_d43g0v0_Shanghai + - clearReturnBuffer_d44g0v0_Shanghai + - clearReturnBuffer_d45g0v0_Shanghai + - clearReturnBuffer_d40g0v0_Shanghai + - clearReturnBuffer_d46g0v0_Shanghai + - clearReturnBuffer_d41g0v0_Shanghai + - clearReturnBuffer_d26g0v0_Shanghai + - clearReturnBuffer_d27g0v0_Shanghai + - clearReturnBuffer_d47g0v0_Shanghai + - clearReturnBuffer_d51g0v0_Shanghai + - clearReturnBuffer_d52g0v0_Shanghai + - clearReturnBuffer_d3g0v0_Shanghai + - clearReturnBuffer_d53g0v0_Shanghai + - clearReturnBuffer_d56g0v0_Shanghai + - clearReturnBuffer_d57g0v0_Shanghai + - clearReturnBuffer_d48g0v0_Shanghai + - clearReturnBuffer_d49g0v0_Shanghai + - clearReturnBuffer_d58g0v0_Shanghai + - clearReturnBuffer_d59g0v0_Shanghai + - clearReturnBuffer_d54g0v0_Shanghai + - clearReturnBuffer_d61g0v0_Shanghai + - clearReturnBuffer_d60g0v0_Shanghai + - clearReturnBuffer_d55g0v0_Shanghai + - clearReturnBuffer_d65g0v0_Shanghai + - clearReturnBuffer_d66g0v0_Shanghai + - clearReturnBuffer_d67g0v0_Shanghai + - clearReturnBuffer_d4g0v0_Shanghai + - clearReturnBuffer_d62g0v0_Shanghai + - clearReturnBuffer_d63g0v0_Shanghai + - clearReturnBuffer_d70g0v0_Shanghai + - clearReturnBuffer_d71g0v0_Shanghai + - clearReturnBuffer_d72g0v0_Shanghai + - clearReturnBuffer_d73g0v0_Shanghai + - clearReturnBuffer_d74g0v0_Shanghai + - clearReturnBuffer_d5g0v0_Shanghai + - clearReturnBuffer_d75g0v0_Shanghai + - clearReturnBuffer_d68g0v0_Shanghai + - clearReturnBuffer_d69g0v0_Shanghai + - clearReturnBuffer_d85g0v0_Shanghai + - clearReturnBuffer_d84g0v0_Shanghai + - create_callprecompile_returndatasize_d0g0v0_Shanghai + - modexp_modsize0_returndatasize_d1g0v0_Shanghai + - clearReturnBuffer_d78g0v0_Shanghai + - clearReturnBuffer_d79g0v0_Shanghai + - clearReturnBuffer_d86g0v0_Shanghai + - modexp_modsize0_returndatasize_d2g0v0_Shanghai + - clearReturnBuffer_d87g0v0_Shanghai + - clearReturnBuffer_d88g0v0_Shanghai + - clearReturnBuffer_d89g0v0_Shanghai + - modexp_modsize0_returndatasize_d3g0v0_Shanghai + - clearReturnBuffer_d92g0v0_Shanghai + - clearReturnBuffer_d80g0v0_Shanghai + - clearReturnBuffer_d76g0v0_Shanghai + - clearReturnBuffer_d77g0v0_Shanghai + - clearReturnBuffer_d93g0v0_Shanghai + - clearReturnBuffer_d81g0v0_Shanghai + - returndatasize_after_failing_callcode_d0g0v0_Shanghai + - returndatasize_after_failing_staticcall_d0g0v0_Shanghai + - returndatasize_after_failing_delegatecall_d0g0v0_Shanghai + - clearReturnBuffer_d90g0v0_Shanghai + - returndatasize_bug_d0g0v0_Shanghai + - clearReturnBuffer_d91g0v0_Shanghai + - clearReturnBuffer_d82g0v0_Shanghai + - clearReturnBuffer_d83g0v0_Shanghai + - clearReturnBuffer_d95g0v0_Shanghai + - clearReturnBuffer_d94g0v0_Shanghai + - clearReturnBuffer_d6g0v0_Shanghai + - clearReturnBuffer_d99g0v0_Shanghai + - clearReturnBuffer_d98g0v0_Shanghai + - clearReturnBuffer_d96g0v0_Shanghai + - clearReturnBuffer_d97g0v0_Shanghai + - clearReturnBuffer_d7g0v0_Shanghai + - clearReturnBuffer_d9g0v0_Shanghai + - returndatasize_after_oog_after_deeper_d0g0v0_Shanghai + - revertRetDataSize_d10g0v0_Shanghai + - revertRetDataSize_d16g0v0_Shanghai + - revertRetDataSize_d0g0v0_Shanghai + - revertRetDataSize_d28g0v0_Shanghai + - revertRetDataSize_d1g0v0_Shanghai + - revertRetDataSize_d22g0v0_Shanghai + - revertRetDataSize_d25g0v0_Shanghai + - revertRetDataSize_d26g0v0_Shanghai + - revertRetDataSize_d24g0v0_Shanghai + - revertRetDataSize_d13g0v0_Shanghai + - revertRetDataSize_d14g0v0_Shanghai + - revertRetDataSize_d2g0v0_Shanghai + - revertRetDataSize_d15g0v0_Shanghai + - revertRetDataSize_d34g0v0_Shanghai + - revertRetDataSize_d12g0v0_Shanghai + - revertRetDataSize_d27g0v0_Shanghai + - tooLongReturnDataCopy_d0g0v0_Shanghai + - tooLongReturnDataCopy_d11g0v0_Shanghai + - revertRetDataSize_d20g0v0_Shanghai + - tooLongReturnDataCopy_d10g0v0_Shanghai + - revertRetDataSize_d19g0v0_Shanghai + - tooLongReturnDataCopy_d13g0v0_Shanghai + - revertRetDataSize_d21g0v0_Shanghai + - revertRetDataSize_d18g0v0_Shanghai + - tooLongReturnDataCopy_d12g0v0_Shanghai + - tooLongReturnDataCopy_d16g0v0_Shanghai + - tooLongReturnDataCopy_d18g0v0_Shanghai + - tooLongReturnDataCopy_d14g0v0_Shanghai + - tooLongReturnDataCopy_d15g0v0_Shanghai + - tooLongReturnDataCopy_d17g0v0_Shanghai + - tooLongReturnDataCopy_d1g0v0_Shanghai + - tooLongReturnDataCopy_d19g0v0_Shanghai + - tooLongReturnDataCopy_d20g0v0_Shanghai + - tooLongReturnDataCopy_d21g0v0_Shanghai + - tooLongReturnDataCopy_d22g0v0_Shanghai + - tooLongReturnDataCopy_d23g0v0_Shanghai + - tooLongReturnDataCopy_d4g0v0_Shanghai + - tooLongReturnDataCopy_d6g0v0_Shanghai + - tooLongReturnDataCopy_d2g0v0_Shanghai + - tooLongReturnDataCopy_d8g0v0_Shanghai + - tooLongReturnDataCopy_d9g0v0_Shanghai + - tooLongReturnDataCopy_d3g0v0_Shanghai + - tooLongReturnDataCopy_d5g0v0_Shanghai + - tooLongReturnDataCopy_d7g0v0_Shanghai + - revertRetDataSize_d3g0v0_Shanghai + - revertRetDataSize_d4g0v0_Shanghai + - revertRetDataSize_d6g0v0_Shanghai + - revertRetDataSize_d7g0v0_Shanghai + - revertRetDataSize_d8g0v0_Shanghai + - revertRetDataSize_d9g0v0_Shanghai + stRecursiveCreate: + - recursiveCreate_d0g0v0_Shanghai + stRevertTest: + - RevertDepthCreateOOG_d0g0v0_Shanghai + - RevertDepthCreateOOG_d0g0v1_Shanghai + - RevertDepthCreateOOG_d0g1v0_Shanghai + - RevertDepthCreateOOG_d0g1v1_Shanghai + - RevertDepthCreateOOG_d1g0v0_Shanghai + - RevertDepthCreateOOG_d1g0v1_Shanghai + - RevertInCreateInInit_d0g0v0_Shanghai + - RevertOpcodeCreate_d0g1v0_Shanghai + - RevertOpcodeMultipleSubCalls_d0g3v1_Shanghai + - RevertOpcodeMultipleSubCalls_d1g3v1_Shanghai + - RevertOpcodeMultipleSubCalls_d0g2v1_Shanghai + - RevertOpcodeMultipleSubCalls_d1g2v1_Shanghai + - RevertOpcodeMultipleSubCalls_d2g3v1_Shanghai + - RevertOpcodeMultipleSubCalls_d3g3v1_Shanghai + - RevertOpcodeMultipleSubCalls_d2g2v1_Shanghai + - RevertOpcodeMultipleSubCalls_d3g2v1_Shanghai + - RevertPrefoundEmpty_d0g0v0_Shanghai + - RevertPrefound_d0g0v0_Shanghai + - LoopCallsThenRevert_d0g0v0_Shanghai + - LoopDelegateCallsDepthThenRevert_d0g0v0_Shanghai + - LoopCallsDepthThenRevert_d0g0v0_Shanghai + - LoopCallsDepthThenRevert3_d0g0v0_Shanghai + - LoopCallsDepthThenRevert2_d0g0v0_Shanghai + - RevertRemoteSubCallStorageOOG_d0g0v0_Shanghai + stSLoadTest: + - sloadGasCost_d0g0v0_Shanghai + stSStoreTest: + - InitCollisionNonZeroNonce_d1g0v0_Shanghai + - InitCollision_d1g0v0_Shanghai + - sstore_0to0_d3g1v0_Shanghai + - InitCollisionNonZeroNonce_d3g0v0_Shanghai + - InitCollision_d3g0v0_Shanghai + - sstore_0to0_d0g1v0_Shanghai + - sstore_0to0_d1g1v0_Shanghai + - sstore_0to0_d2g1v0_Shanghai + - sstore_0to0to0_d3g1v0_Shanghai + - sstore_0to0_d4g0v0_Shanghai + - sstore_0to0to0_d0g1v0_Shanghai + - sstore_0to0_d4g1v0_Shanghai + - sstore_0to0to0_d1g1v0_Shanghai + - sstore_0to0to0_d2g1v0_Shanghai + - sstore_0to0toX_d3g1v0_Shanghai + - sstore_0to0to0_d4g1v0_Shanghai + - sstore_0to0to0_d4g0v0_Shanghai + - sstore_0to0toX_d0g1v0_Shanghai + - sstore_0to0toX_d1g1v0_Shanghai + - sstore_0to0toX_d2g1v0_Shanghai + - sstore_0toX_d3g1v0_Shanghai + - sstore_0to0toX_d4g0v0_Shanghai + - sstore_0toX_d0g1v0_Shanghai + - sstore_0to0toX_d4g1v0_Shanghai + - sstore_0toX_d1g1v0_Shanghai + - sstore_0toX_d2g1v0_Shanghai + - sstore_0toXto0_d3g1v0_Shanghai + - sstore_0toXto0_d0g1v0_Shanghai + - sstore_0toXto0_d1g1v0_Shanghai + - sstore_0toX_d4g0v0_Shanghai + - sstore_0toXto0_d2g1v0_Shanghai + - sstore_0toX_d4g1v0_Shanghai + - sstore_0toXto0toX_d3g1v0_Shanghai + - sstore_0toXto0toX_d0g1v0_Shanghai + - sstore_0toXto0toX_d1g1v0_Shanghai + - sstore_0toXto0_d4g0v0_Shanghai + - sstore_0toXto0_d4g1v0_Shanghai + - sstore_0toXto0toX_d2g1v0_Shanghai + - sstore_0toXtoX_d3g1v0_Shanghai + - sstore_0toXtoX_d0g1v0_Shanghai + - sstore_0toXtoX_d1g1v0_Shanghai + - sstore_0toXto0toX_d4g0v0_Shanghai + - sstore_0toXto0toX_d4g1v0_Shanghai + - sstore_0toXtoX_d2g1v0_Shanghai + - sstore_0toXtoY_d3g1v0_Shanghai + - sstore_0toXtoY_d0g1v0_Shanghai + - sstore_0toXtoY_d1g1v0_Shanghai + - sstore_0toXtoX_d4g0v0_Shanghai + - sstore_0toXtoY_d2g1v0_Shanghai + - sstore_0toXtoX_d4g1v0_Shanghai + - sstore_Xto0_d3g1v0_Shanghai + - sstore_Xto0_d0g1v0_Shanghai + - sstore_Xto0_d1g1v0_Shanghai + - sstore_0toXtoY_d4g0v0_Shanghai + - sstore_0toXtoY_d4g1v0_Shanghai + - sstore_Xto0_d2g1v0_Shanghai + - sstore_Xto0to0_d3g1v0_Shanghai + - sstore_Xto0to0_d0g1v0_Shanghai + - sstore_Xto0_d4g0v0_Shanghai + - sstore_Xto0to0_d1g1v0_Shanghai + - sstore_Xto0_d4g1v0_Shanghai + - sstore_Xto0to0_d2g1v0_Shanghai + - sstore_Xto0toX_d3g1v0_Shanghai + - sstore_Xto0toX_d0g1v0_Shanghai + - sstore_Xto0toX_d1g1v0_Shanghai + - sstore_Xto0toX_d2g1v0_Shanghai + - sstore_Xto0to0_d4g0v0_Shanghai + - sstore_Xto0to0_d4g1v0_Shanghai + - sstore_Xto0toXto0_d3g1v0_Shanghai + - sstore_Xto0toX_d4g0v0_Shanghai + - sstore_Xto0toXto0_d0g1v0_Shanghai + - sstore_Xto0toXto0_d1g1v0_Shanghai + - sstore_Xto0toXto0_d2g1v0_Shanghai + - sstore_Xto0toX_d4g1v0_Shanghai + - sstore_Xto0toY_d3g1v0_Shanghai + - sstore_Xto0toY_d0g1v0_Shanghai + - sstore_Xto0toY_d1g1v0_Shanghai + - sstore_Xto0toY_d2g1v0_Shanghai + - sstore_Xto0toXto0_d4g0v0_Shanghai + - sstore_Xto0toXto0_d4g1v0_Shanghai + - sstore_XtoX_d3g1v0_Shanghai + - sstore_Xto0toY_d4g0v0_Shanghai + - sstore_XtoX_d0g1v0_Shanghai + - sstore_Xto0toY_d4g1v0_Shanghai + - sstore_XtoX_d1g1v0_Shanghai + - sstore_XtoX_d2g1v0_Shanghai + - sstore_XtoXto0_d3g1v0_Shanghai + - sstore_XtoXto0_d0g1v0_Shanghai + - sstore_XtoX_d4g0v0_Shanghai + - sstore_XtoX_d4g1v0_Shanghai + - sstore_XtoXto0_d1g1v0_Shanghai + - sstore_XtoXto0_d2g1v0_Shanghai + - sstore_XtoXtoX_d3g1v0_Shanghai + - sstore_XtoXtoX_d0g1v0_Shanghai + - sstore_XtoXto0_d4g0v0_Shanghai + - sstore_XtoXto0_d4g1v0_Shanghai + - sstore_XtoXtoX_d2g1v0_Shanghai + - sstore_XtoXtoX_d1g1v0_Shanghai + - sstore_XtoXtoY_d3g1v0_Shanghai + - sstore_XtoXtoY_d0g1v0_Shanghai + - sstore_XtoXtoX_d4g0v0_Shanghai + - sstore_XtoXtoY_d1g1v0_Shanghai + - sstore_XtoXtoX_d4g1v0_Shanghai + - sstore_XtoXtoY_d2g1v0_Shanghai + - sstore_XtoY_d3g1v0_Shanghai + - sstore_XtoY_d0g1v0_Shanghai + - sstore_XtoXtoY_d4g0v0_Shanghai + - sstore_XtoY_d1g1v0_Shanghai + - sstore_XtoY_d2g1v0_Shanghai + - sstore_XtoXtoY_d4g1v0_Shanghai + - sstore_XtoYto0_d3g1v0_Shanghai + - sstore_XtoY_d4g0v0_Shanghai + - sstore_XtoYto0_d0g1v0_Shanghai + - sstore_XtoYto0_d1g1v0_Shanghai + - sstore_XtoYto0_d2g1v0_Shanghai + - sstore_XtoY_d4g1v0_Shanghai + - sstore_XtoYtoX_d3g1v0_Shanghai + - sstore_XtoYtoX_d0g1v0_Shanghai + - sstore_XtoYtoX_d1g1v0_Shanghai + - sstore_XtoYto0_d4g0v0_Shanghai + - sstore_XtoYto0_d4g1v0_Shanghai + - sstore_XtoYtoX_d2g1v0_Shanghai + - sstore_XtoYtoY_d3g1v0_Shanghai + - sstore_XtoYtoY_d0g1v0_Shanghai + - sstore_XtoYtoX_d4g0v0_Shanghai + - sstore_XtoYtoY_d1g1v0_Shanghai + - sstore_XtoYtoX_d4g1v0_Shanghai + - sstore_XtoYtoY_d2g1v0_Shanghai + - sstore_XtoYtoZ_d3g1v0_Shanghai + - sstore_XtoYtoZ_d0g1v0_Shanghai + - sstore_changeFromExternalCallInInitCode_d12g0v0_Shanghai + - sstore_XtoYtoY_d4g0v0_Shanghai + - sstore_XtoYtoZ_d1g1v0_Shanghai + - sstore_XtoYtoY_d4g1v0_Shanghai + - sstore_XtoYtoZ_d2g1v0_Shanghai + - sstore_gasLeft_d0g0v0_Shanghai + - sstore_gasLeft_d1g0v0_Shanghai + - sstore_changeFromExternalCallInInitCode_d13g0v0_Shanghai + - sstore_changeFromExternalCallInInitCode_d1g0v0_Shanghai + - sstore_gasLeft_d4g0v0_Shanghai + - sstore_gasLeft_d3g0v0_Shanghai + - sstore_gasLeft_d6g0v0_Shanghai + - sstore_gasLeft_d7g0v0_Shanghai + - sstore_changeFromExternalCallInInitCode_d5g0v0_Shanghai + - sstore_XtoYtoZ_d4g0v0_Shanghai + - sstore_changeFromExternalCallInInitCode_d15g0v0_Shanghai + - sstore_changeFromExternalCallInInitCode_d9g0v0_Shanghai + - sstore_XtoYtoZ_d4g1v0_Shanghai + - sstore_changeFromExternalCallInInitCode_d11g0v0_Shanghai + - sstore_changeFromExternalCallInInitCode_d3g0v0_Shanghai + - sstore_changeFromExternalCallInInitCode_d7g0v0_Shanghai + stSelfBalance: + - diffPlaces_d0g0v0_Shanghai + - diffPlaces_d1g0v0_Shanghai + - diffPlaces_d2g0v0_Shanghai + - diffPlaces_d3g0v0_Shanghai + - diffPlaces_d4g0v0_Shanghai + - diffPlaces_d5g0v0_Shanghai + - diffPlaces_d6g0v0_Shanghai + - diffPlaces_d10g0v0_Shanghai + - diffPlaces_d11g0v0_Shanghai + - diffPlaces_d12g0v0_Shanghai + - diffPlaces_d13g0v0_Shanghai + - diffPlaces_d14g0v0_Shanghai + - diffPlaces_d15g0v0_Shanghai + - diffPlaces_d16g0v0_Shanghai + - diffPlaces_d17g0v0_Shanghai + - diffPlaces_d7g0v0_Shanghai + - diffPlaces_d18g0v0_Shanghai + - diffPlaces_d19g0v0_Shanghai + - diffPlaces_d20g0v0_Shanghai + - diffPlaces_d8g0v0_Shanghai + - diffPlaces_d21g0v0_Shanghai + - diffPlaces_d9g0v0_Shanghai + - diffPlaces_d22g0v0_Shanghai + - diffPlaces_d24g0v0_Shanghai + - diffPlaces_d23g0v0_Shanghai + - diffPlaces_d25g0v0_Shanghai + - diffPlaces_d26g0v0_Shanghai + - diffPlaces_d28g0v0_Shanghai + - diffPlaces_d27g0v0_Shanghai + - diffPlaces_d31g0v0_Shanghai + - diffPlaces_d30g0v0_Shanghai + - diffPlaces_d29g0v0_Shanghai + - diffPlaces_d32g0v0_Shanghai + - diffPlaces_d33g0v0_Shanghai + - diffPlaces_d34g0v0_Shanghai + stShift: + - sar_2_xor_255_256_d0g0v0_Shanghai + - sar_2_xor_255_minus_1_256_d0g0v0_Shanghai + - sar_2_xor_256_minus_1_256_d0g0v0_Shanghai + - shiftSignedCombinations_d0g0v0_Shanghai + - shiftCombinations_d0g0v0_Shanghai + stSolidityTest: + - TestCryptographicFunctions_d0g0v0_Shanghai + - TestStructuresAndVariabless_d0g0v0_Shanghai + - SelfDestruct_d2g0v0_Shanghai + - SelfDestruct_d1g0v0_Shanghai + - SelfDestruct_d0g0v0_Shanghai + - RecursiveCreateContractsCreate4Contracts_d0g0v0_Shanghai + - RecursiveCreateContracts_d0g0v0_Shanghai + stSpecialTest: + - eoaEmpty_d0g0v1_Shanghai + - eoaEmpty_d1g0v1_Shanghai + - eoaEmpty_d0g0v0_Shanghai + - eoaEmpty_d0g1v0_Shanghai + - sha3_deja_d0g0v0_Shanghai + - makeMoney_d0g0v0_Shanghai + - eoaEmpty_d0g1v1_Shanghai + - eoaEmpty_d1g0v0_Shanghai + - eoaEmpty_d1g1v0_Shanghai + - eoaEmpty_d1g1v1_Shanghai + - selfdestructEIP2929_d0g0v0_Shanghai + - JUMPDEST_AttackwithJump_d0g0v0_Shanghai + - JUMPDEST_Attack_d0g0v0_Shanghai + - deploymentError_d0g0v0_Shanghai + - block504980_d0g0v0_Shanghai + - tx_e1c174e2_d0g0v0_Shanghai + stStackTests: + - stackOverflowM1DUP_d0g0v0_Shanghai + - stackOverflowM1DUP_d10g0v0_Shanghai + - stackOverflowM1DUP_d11g0v0_Shanghai + - stackOverflowM1DUP_d12g0v0_Shanghai + - stackOverflowM1DUP_d13g0v0_Shanghai + - stackOverflowM1DUP_d14g0v0_Shanghai + - stackOverflowM1DUP_d15g0v0_Shanghai + - stackOverflowM1DUP_d1g0v0_Shanghai + - stackOverflowM1DUP_d2g0v0_Shanghai + - stackOverflowM1DUP_d3g0v0_Shanghai + - stackOverflowM1DUP_d4g0v0_Shanghai + - stackOverflowM1DUP_d5g0v0_Shanghai + - stackOverflowM1DUP_d6g0v0_Shanghai + - stackOverflowM1DUP_d7g0v0_Shanghai + - stackOverflowM1DUP_d8g0v0_Shanghai + - stackOverflowM1DUP_d9g0v0_Shanghai + - stackOverflowM1PUSH_d0g0v0_Shanghai + - stackOverflowM1PUSH_d1g0v0_Shanghai + - stackOverflowM1PUSH_d11g0v0_Shanghai + - stackOverflowM1PUSH_d10g0v0_Shanghai + - stackOverflowM1PUSH_d12g0v0_Shanghai + - stackOverflowM1PUSH_d13g0v0_Shanghai + - stackOverflowM1PUSH_d14g0v0_Shanghai + - stackOverflowM1PUSH_d16g0v0_Shanghai + - stackOverflowM1PUSH_d17g0v0_Shanghai + - stackOverflowM1PUSH_d15g0v0_Shanghai + - stackOverflowM1PUSH_d18g0v0_Shanghai + - stackOverflowM1PUSH_d19g0v0_Shanghai + - stackOverflowM1PUSH_d20g0v0_Shanghai + - stackOverflowM1PUSH_d21g0v0_Shanghai + - stackOverflowM1PUSH_d22g0v0_Shanghai + - stackOverflowM1PUSH_d24g0v0_Shanghai + - stackOverflowM1PUSH_d23g0v0_Shanghai + - stackOverflowM1PUSH_d25g0v0_Shanghai + - stackOverflowM1PUSH_d26g0v0_Shanghai + - stackOverflowM1PUSH_d27g0v0_Shanghai + - stackOverflowM1PUSH_d28g0v0_Shanghai + - stackOverflowM1PUSH_d29g0v0_Shanghai + - stackOverflowM1PUSH_d2g0v0_Shanghai + - stackOverflowM1PUSH_d3g0v0_Shanghai + - stackOverflowM1PUSH_d4g0v0_Shanghai + - stackOverflowM1PUSH_d5g0v0_Shanghai + - stackOverflowM1PUSH_d30g0v0_Shanghai + - stackOverflowM1PUSH_d6g0v0_Shanghai + - stackOverflowM1PUSH_d7g0v0_Shanghai + - stackOverflowM1PUSH_d9g0v0_Shanghai + - stackOverflowM1PUSH_d8g0v0_Shanghai + - stackOverflowM1_d0g0v0_Shanghai + - stackOverflowM1_d10g0v0_Shanghai + - stackOverflowM1_d11g0v0_Shanghai + - stackOverflowM1_d12g0v0_Shanghai + - stackOverflowM1_d15g0v0_Shanghai + - stackOverflowM1_d13g0v0_Shanghai + - stackOverflowM1_d14g0v0_Shanghai + - stackOverflowM1_d1g0v0_Shanghai + - stackOverflowM1_d4g0v0_Shanghai + - stackOverflowM1_d2g0v0_Shanghai + - stackOverflowM1_d3g0v0_Shanghai + - stackOverflowM1_d5g0v0_Shanghai + - stackOverflowM1_d6g0v0_Shanghai + - stackOverflowM1_d7g0v0_Shanghai + - stackOverflowM1_d8g0v0_Shanghai + - stackOverflowM1_d9g0v0_Shanghai + - stackOverflowPUSH_d17g0v0_Shanghai + - stackOverflowPUSH_d18g0v0_Shanghai + - stackOverflowPUSH_d19g0v0_Shanghai + - stackOverflowPUSH_d20g0v0_Shanghai + - stackOverflowPUSH_d21g0v0_Shanghai + - stackOverflowPUSH_d23g0v0_Shanghai + - stackOverflowPUSH_d22g0v0_Shanghai + - stackOverflowPUSH_d24g0v0_Shanghai + - stackOverflowPUSH_d25g0v0_Shanghai + - stackOverflowSWAP_d0g0v0_Shanghai + - stackOverflowPUSH_d26g0v0_Shanghai + - stackOverflowPUSH_d27g0v0_Shanghai + - stackOverflowPUSH_d28g0v0_Shanghai + - stackOverflowPUSH_d29g0v0_Shanghai + - stackOverflowPUSH_d30g0v0_Shanghai + - stacksanitySWAP_d0g0v0_Shanghai + stStaticCall: + - StaticcallToPrecompileFromCalledContract_d0g0v0_Shanghai + - StaticcallToPrecompileFromTransaction_d0g0v0_Shanghai + - static_CREATE_EmptyContractAndCallIt_0wei_d0g0v0_Shanghai + - static_CREATE_EmptyContractWithStorageAndCallIt_0wei_d0g0v0_Shanghai + - StaticcallToPrecompileFromContractInitialization_d0g0v0_Shanghai + - static_ABAcalls2_d1g0v0_Shanghai + - static_ABAcalls1_d1g0v0_Shanghai + - static_ABAcalls1_d0g0v0_Shanghai + - static_Call1024BalanceTooLow2_d1g0v0_Shanghai + - static_Call1024BalanceTooLow_d1g0v0_Shanghai + - static_CallContractToCreateContractOOGBonusGas_d0g1v0_Shanghai + - static_CallEcrecover0_0input_d1g0v0_Shanghai + - static_CallEcrecover0_0input_d2g0v0_Shanghai + - static_CallEcrecover0_0input_d3g0v0_Shanghai + - static_CallEcrecover0_0input_d4g0v0_Shanghai + - static_Call1024OOG_d1g0v0_Shanghai + - static_CallEcrecover0_0input_d5g0v0_Shanghai + - static_CallEcrecover0_0input_d6g0v0_Shanghai + - static_CallEcrecover0_0input_d7g0v0_Shanghai + - static_CallEcrecover0_0input_d8g0v0_Shanghai + - static_CallEcrecover0_Gas2999_d0g0v0_Shanghai + - static_CallEcrecover0_NoGas_d0g0v0_Shanghai + - static_ABAcallsSuicide1_d1g0v0_Shanghai + - static_CallEcrecover0_completeReturnValue_d0g0v0_Shanghai + - static_CallEcrecover0_d0g0v0_Shanghai + - static_CallEcrecover0_gas3000_d0g0v0_Shanghai + - static_CallEcrecover0_overlappingInputOutput_d0g0v0_Shanghai + - static_CallEcrecover1_d0g0v0_Shanghai + - static_CallEcrecover2_d0g0v0_Shanghai + - static_CallEcrecover3_d0g0v0_Shanghai + - static_CallEcrecover80_d0g0v0_Shanghai + - static_CallEcrecoverCheckLengthWrongV_d0g0v0_Shanghai + - static_CallEcrecoverH_prefixed0_d0g0v0_Shanghai + - static_CallEcrecoverCheckLength_d0g0v0_Shanghai + - static_CallEcrecoverR_prefixed0_d0g0v0_Shanghai + - static_CallEcrecoverS_prefixed0_d0g0v0_Shanghai + - static_Call1024PreCalls2_d1g0v0_Shanghai + - static_CallEcrecoverV_prefixed0_d0g0v0_Shanghai + - static_CallIdentitiy_1_d0g0v0_Shanghai + - static_CallIdentity_2_d0g0v0_Shanghai + - static_CallIdentity_1_nonzeroValue_d0g0v0_Shanghai + - static_CallIdentity_3_d0g0v0_Shanghai + - static_CallIdentity_4_d0g0v0_Shanghai + - static_CallIdentity_4_gas17_d0g0v0_Shanghai + - static_CallIdentity_4_gas18_d0g0v0_Shanghai + - static_Call1024PreCalls2_d0g0v0_Shanghai + - static_CallRipemd160_1_d0g0v0_Shanghai + - static_Call1024PreCalls3_d1g0v0_Shanghai + - static_CallRipemd160_2_d0g0v0_Shanghai + - static_Call10_d0g0v0_Shanghai + - static_CallRipemd160_3_d0g0v0_Shanghai + - static_Call1024PreCalls_d1g0v0_Shanghai + - static_Call10_d1g0v0_Shanghai + - static_CallRipemd160_3_postfixed0_d0g0v0_Shanghai + - static_CallRipemd160_3_prefixed0_d0g0v0_Shanghai + - static_CallRipemd160_4_d0g0v0_Shanghai + - static_CallRipemd160_4_gas719_d0g0v0_Shanghai + - static_CallSha256_1_d0g0v0_Shanghai + - static_Call1MB1024Calldepth_d0g0v0_Shanghai + - static_CallSha256_1_nonzeroValue_d0g0v0_Shanghai + - static_CallSha256_2_d0g0v0_Shanghai + - static_CallSha256_3_d0g0v0_Shanghai + - static_CallSha256_3_postfix0_d0g0v0_Shanghai + - static_CallSha256_3_prefix0_d0g0v0_Shanghai + - static_CallSha256_4_d0g0v0_Shanghai + - static_CallSha256_4_gas99_d0g0v0_Shanghai + - static_Call1MB1024Calldepth_d1g0v0_Shanghai + - static_Call50000_ecrec_d0g0v0_Shanghai + - static_Call50000_ecrec_d1g0v0_Shanghai + - static_Call50000_identity2_d0g0v0_Shanghai + - static_Call50000_d0g0v0_Shanghai + - static_Call50000_identity2_d1g0v0_Shanghai + - static_Call50000_d1g0v0_Shanghai + - static_Call50000_identity_d0g0v0_Shanghai + - static_Call50000_rip160_d0g0v0_Shanghai + - static_Call50000_identity_d1g0v0_Shanghai + - static_Call50000_rip160_d1g0v0_Shanghai + - static_RETURN_BoundsOOG_d1g0v0_Shanghai + - static_RETURN_Bounds_d0g0v0_Shanghai + - static_CallRecursiveBomb0_d0g0v0_Shanghai + - static_callOutput3Fail_d0g0v0_Shanghai + - static_callOutput3_d0g0v0_Shanghai + - static_CallRecursiveBombPreCall2_d0g0v0_Shanghai + - static_CallRecursiveBomb1_d0g0v0_Shanghai + - static_callOutput3partialFail_d0g0v0_Shanghai + - static_CallRecursiveBomb2_d0g0v0_Shanghai + - static_callOutput3partial_d0g0v0_Shanghai + - static_Call50000bytesContract50_1_d0g0v0_Shanghai + - static_Call50000bytesContract50_1_d1g0v0_Shanghai + - static_CallRecursiveBombPreCall_d0g0v0_Shanghai + - static_Call50000bytesContract50_2_d0g0v0_Shanghai + - static_Call50000bytesContract50_2_d1g0v0_Shanghai + - static_CallRecursiveBomb0_OOG_atMaxCallDepth_d0g0v0_Shanghai + - static_Call50000bytesContract50_3_d0g0v0_Shanghai + - static_Call50000bytesContract50_3_d1g0v0_Shanghai + - static_CallIdentity_5_d0g0v0_Shanghai + - static_CallRipemd160_5_d0g0v0_Shanghai + - static_CallSha256_5_d0g0v0_Shanghai + - static_LoopCallsThenRevert_d0g0v0_Shanghai + - static_LoopCallsThenRevert_d0g1v0_Shanghai + - static_callcall_00_OOGE_1_d1g0v0_Shanghai + - static_callcallcallcode_001_OOGE_d0g0v0_Shanghai + - static_callcallcallcode_001_OOGE_2_d1g0v0_Shanghai + - static_callcallcall_000_OOGMBefore_d0g0v0_Shanghai + - static_Return50000_2_d0g0v0_Shanghai + - static_callCreate2_d2g0v0_Shanghai + - static_callcallcall_000_OOGMAfter2_d0g0v0_Shanghai + - static_callcallcallcode_001_OOGMAfter2_d1g0v0_Shanghai + - static_callcallcallcode_001_OOGMAfter_2_d1g0v0_Shanghai + - static_callcallcallcode_001_OOGMAfter_3_d1g0v0_Shanghai + - static_callcallcodecall_010_OOGE_2_d1g0v0_Shanghai + - static_callcode_checkPC_d0g0v0_Shanghai + - static_callcallcallcode_001_OOGMBefore2_d1g0v0_Shanghai + - static_callcallcallcode_001_OOGMAfter_d1g0v0_Shanghai + - static_callChangeRevert_d1g0v0_Shanghai + - static_callcallcallcode_001_OOGMBefore_d0g0v0_Shanghai + - static_callcallcodecall_010_OOGE_d0g0v0_Shanghai + - static_callcallcodecall_010_OOGMAfter2_d0g0v0_Shanghai + - static_callcallcodecall_010_OOGMAfter_2_d1g0v0_Shanghai + - static_callcallcodecall_010_OOGMAfter_3_d1g0v0_Shanghai + - static_callcallcodecall_010_OOGMAfter_d1g0v0_Shanghai + - static_callcallcodecall_010_OOGMBefore2_d0g0v0_Shanghai + - static_callcallcodecall_010_OOGMBefore_d1g0v0_Shanghai + - static_callcallcodecallcode_011_OOGMAfter2_d1g0v0_Shanghai + - static_callcallcodecallcode_011_OOGMAfter_1_d1g0v0_Shanghai + - static_callcallcodecallcode_011_OOGMAfter_2_d1g0v0_Shanghai + - static_callcallcodecallcode_011_OOGMAfter_d1g0v0_Shanghai + - static_callcallcodecallcode_011_OOGMBefore2_d1g0v0_Shanghai + - static_callcallcodecallcode_011_OOGMBefore_d1g0v0_Shanghai + - static_callcodecallcall_100_OOGMAfter2_d0g0v0_Shanghai + - static_callcodecallcall_100_OOGMAfter2_d0g0v1_Shanghai + - static_callcodecallcall_100_OOGMBefore2_d0g0v0_Shanghai + - static_callcodecallcall_100_OOGMAfter_3_d0g0v1_Shanghai + - static_callcodecallcall_100_OOGMAfter_2_d0g0v0_Shanghai + - static_callcodecallcall_100_OOGMAfter_3_d0g0v0_Shanghai + - static_callcodecallcall_100_OOGMAfter_d0g0v0_Shanghai + - static_callcodecallcall_100_OOGMBefore2_d0g0v1_Shanghai + - static_callcodecallcallcode_101_OOGE_d0g0v0_Shanghai + - static_callcodecallcall_100_OOGMBefore_d0g0v0_Shanghai + - static_contractCreationMakeCallThatAskMoreGasThenTransactionProvided_d0g0v0_Shanghai + - static_callcodecallcallcode_101_OOGMAfter2_d0g0v0_Shanghai + - static_callcodecallcallcode_101_OOGMAfter_1_d0g0v0_Shanghai + - static_callcodecallcallcode_101_OOGMAfter2_d0g0v1_Shanghai + - static_callcodecallcallcode_101_OOGMAfter_3_d0g0v0_Shanghai + - static_callcodecallcallcode_101_OOGMBefore2_d0g0v0_Shanghai + - static_callcodecallcallcode_101_OOGMBefore_d0g0v0_Shanghai + - static_callcodecallcallcode_101_OOGMBefore2_d0g0v1_Shanghai + - static_callcodecallcallcode_101_OOGMAfter_d0g0v0_Shanghai + - static_makeMoney_d0g0v0_Shanghai + - static_callcodecallcodecall_110_OOGMAfter_2_d0g0v0_Shanghai + - static_callcodecallcodecall_110_OOGMAfter2_d0g0v0_Shanghai + - static_callcodecallcodecall_110_OOGMAfter2_d0g0v1_Shanghai + - static_callcodecallcodecall_110_OOGMAfter2_d0g0v2_Shanghai + - static_callcodecallcodecall_110_OOGMAfter_d0g0v0_Shanghai + - static_callcodecallcodecall_110_OOGMBefore2_d0g0v1_Shanghai + - static_callcodecallcodecall_110_OOGMBefore2_d0g0v2_Shanghai + - static_callcodecallcodecall_110_OOGMBefore_d0g0v0_Shanghai + - static_callcodecallcodecall_110_OOGMAfter_3_d0g0v0_Shanghai + - static_contractCreationMakeCallThatAskMoreGasThenTransactionProvided_d2g0v0_Shanghai + - static_contractCreationOOGdontLeaveEmptyContractViaTransaction_d0g0v0_Shanghai + stStaticFlagEnabled: + - CallWithNOTZeroValueToPrecompileFromContractInitialization_d0g0v0_Shanghai + - CallWithNOTZeroValueToPrecompileFromContractInitialization_d1g0v0_Shanghai + - CallWithNOTZeroValueToPrecompileFromContractInitialization_d2g0v0_Shanghai + - CallWithNOTZeroValueToPrecompileFromContractInitialization_d3g0v0_Shanghai + - CallWithNOTZeroValueToPrecompileFromContractInitialization_d6g0v0_Shanghai + - CallWithNOTZeroValueToPrecompileFromContractInitialization_d4g0v0_Shanghai + - CallWithNOTZeroValueToPrecompileFromContractInitialization_d5g0v0_Shanghai + - CallWithNOTZeroValueToPrecompileFromContractInitialization_d7g0v0_Shanghai + - CallWithZeroValueToPrecompileFromTransaction_d0g0v0_Shanghai + - CallWithZeroValueToPrecompileFromCalledContract_d0g0v0_Shanghai + - DelegatecallToPrecompileFromTransaction_d0g0v0_Shanghai + - DelegatecallToPrecompileFromCalledContract_d0g0v0_Shanghai + - CallWithZeroValueToPrecompileFromContractInitialization_d0g0v0_Shanghai + - CallcodeToPrecompileFromTransaction_d0g0v0_Shanghai + - CallcodeToPrecompileFromCalledContract_d0g0v0_Shanghai + - DelegatecallToPrecompileFromContractInitialization_d0g0v0_Shanghai + - CallcodeToPrecompileFromContractInitialization_d0g0v0_Shanghai + stSystemOperationsTest: + - ABAcalls0_d0g0v0_Shanghai + - ABAcallsSuicide0_d0g0v0_Shanghai + - ABAcallsSuicide1_d0g0v0_Shanghai + - CallToNameRegistratorNotMuchMemory0_d0g0v0_Shanghai + - CallToNameRegistratorNotMuchMemory1_d0g0v0_Shanghai + - callerAccountBalance_d0g0v0_Shanghai + - createNameRegistratorZeroMem2_d0g0v0_Shanghai + - createWithInvalidOpcode_d0g0v0_Shanghai + - ABAcallsSuicide1_d1g0v0_Shanghai + - doubleSelfdestructTouch_d0g0v2_Shanghai + - extcodecopy_d0g0v0_Shanghai + - doubleSelfdestructTest_d0g0v0_Shanghai + - doubleSelfdestructTest_d5g0v0_Shanghai + - doubleSelfdestructTest_d2g0v0_Shanghai + - doubleSelfdestructTest_d1g0v0_Shanghai + - doubleSelfdestructTest_d4g0v0_Shanghai + - doubleSelfdestructTest_d6g0v0_Shanghai + - testRandomTest_d0g0v0_Shanghai + - multiSelfdestruct_d0g0v0_Shanghai + - multiSelfdestruct_d1g0v0_Shanghai + - multiSelfdestruct_d2g0v0_Shanghai + - ABAcalls3_d0g0v0_Shanghai + - multiSelfdestruct_d3g0v0_Shanghai + - multiSelfdestruct_d4g0v0_Shanghai + - suicideSendEtherPostDeath_d0g0v0_Shanghai + - ABAcalls2_d0g0v0_Shanghai + - CallRecursiveBomb0_d0g0v0_Shanghai + - CallRecursiveBomb1_d0g0v0_Shanghai + - ABAcalls1_d0g0v0_Shanghai + - CallRecursiveBomb2_d0g0v0_Shanghai + - CallRecursiveBomb3_d0g0v0_Shanghai + - CallRecursiveBomb0_OOG_atMaxCallDepth_d0g0v0_Shanghai + - Call10_d0g0v0_Shanghai + - CallRecursiveBombLog2_d0g0v0_Shanghai + - CallRecursiveBombLog_d0g0v0_Shanghai + stTimeConsuming: + - CALLBlake2f_MaxRounds_d0g0v0_Shanghai + - static_Call50000_sha256_d1g0v0_Shanghai + - static_Call50000_sha256_d0g0v0_Shanghai + stTransactionTest: + - HighGasPrice_d0g0v0_Shanghai + - InternalCallHittingGasLimit2_d0g0v0_Shanghai + - Opcodes_TransactionInit_d120g0v0_Shanghai + - Opcodes_TransactionInit_d23g0v0_Shanghai + - ValueOverflow_d0g0v0_Shanghai + - OverflowGasRequire2_d0g0v0_Shanghai + - SuicidesAndInternlCallSuicidesBonusGasAtCall_d0g0v0_Shanghai + - PointAtInfinityECRecover_d0g0v0_Shanghai + - SuicidesAndInternlCallSuicidesSuccess_d0g0v0_Shanghai + - SuicidesAndInternlCallSuicidesSuccess_d1g0v0_Shanghai + - StoreGasOnCreate_d0g0v0_Shanghai + stWalletTest: + - multiOwnedRemoveOwner_d0g0v0_Shanghai + - multiOwnedIsOwnerFalse_d0g0v0_Shanghai + - multiOwnedIsOwnerTrue_d0g0v0_Shanghai + - multiOwnedConstructionCorrect_d0g0v0_Shanghai + - multiOwnedConstructionNotEnoughGasPartial_d0g1v0_Shanghai + - dayLimitConstruction_d0g0v0_Shanghai + - dayLimitConstructionPartial_d0g0v0_Shanghai + - dayLimitConstruction_d0g1v0_Shanghai + - multiOwnedRemoveOwnerByNonOwner_d0g0v0_Shanghai + - multiOwnedRemoveOwner_mySelf_d0g0v0_Shanghai + - multiOwnedRemoveOwner_ownerIsNotOwner_d0g0v0_Shanghai + - multiOwnedRevokeNothing_d0g0v0_Shanghai + - multiOwnedAddOwner_d0g0v0_Shanghai + - multiOwnedAddOwnerAddMyself_d0g0v0_Shanghai + - dayLimitResetSpentToday_d0g0v0_Shanghai + - multiOwnedChangeRequirementTo0_d0g0v0_Shanghai + - multiOwnedChangeRequirementTo2_d0g0v0_Shanghai + - multiOwnedChangeRequirementTo1_d0g0v0_Shanghai + - dayLimitSetDailyLimitNoData_d0g0v0_Shanghai + - dayLimitSetDailyLimit_d0g0v0_Shanghai + - multiOwnedChangeOwner_fromNotOwner_d0g0v0_Shanghai + - multiOwnedChangeOwnerNoArgument_d0g0v0_Shanghai + - multiOwnedChangeOwner_d0g0v0_Shanghai + - multiOwnedChangeOwner_toIsOwner_d0g0v0_Shanghai + - walletChangeRequirementRemovePendingTransaction_d0g0v0_Shanghai + - walletAddOwnerRemovePendingTransaction_d0g0v0_Shanghai + - walletChangeOwnerRemovePendingTransaction_d0g0v0_Shanghai + - walletConfirm_d0g0v0_Shanghai + - walletConstructionOOG_d0g1v0_Shanghai + - walletConstructionPartial_d0g0v0_Shanghai + - walletConstruction_d0g1v0_Shanghai + - walletConstruction_d0g0v0_Shanghai + - walletRemoveOwnerRemovePendingTransaction_d0g0v0_Shanghai + - walletExecuteOverDailyLimitOnlyOneOwner_d0g0v0_Shanghai + - walletExecuteOverDailyLimitOnlyOneOwnerNew_d0g0v0_Shanghai + - walletExecuteOverDailyLimitMultiOwner_d0g0v0_Shanghai + - walletKillNotByOwner_d0g0v0_Shanghai + - walletExecuteUnderDailyLimit_d0g0v0_Shanghai + - walletKill_d0g0v0_Shanghai + - walletKillToWallet_d0g0v0_Shanghai + stZeroKnowledge2: + - ecadd_0_minus_0_0_minus_0_21000_0_d0g1v0_Shanghai + - ecadd_0_minus_0_0_minus_0_21000_0_d0g3v0_Shanghai + - ecadd_0_minus_0_0_minus_0_21000_0_d0g2v0_Shanghai + - ecadd_0_minus_0_0_minus_0_21000_128_d0g1v0_Shanghai + - ecadd_0_minus_0_0_minus_0_21000_128_d0g2v0_Shanghai + - ecadd_0_minus_0_0_minus_0_21000_128_d0g3v0_Shanghai + - ecadd_0_minus_0_0_minus_0_21000_192_d0g1v0_Shanghai + - ecadd_0_minus_0_0_minus_0_21000_64_d0g1v0_Shanghai + - ecadd_0_minus_0_0_minus_0_21000_192_d0g2v0_Shanghai + - ecadd_0_minus_0_0_minus_0_21000_192_d0g3v0_Shanghai + - ecadd_0_minus_0_0_minus_0_21000_64_d0g2v0_Shanghai + - ecadd_0_minus_0_0_minus_0_21000_64_d0g3v0_Shanghai + - ecadd_0_minus_0_0_minus_0_21000_80_d0g1v0_Shanghai + - ecadd_0_minus_0_0_minus_0_21000_80_d0g2v0_Shanghai + - ecadd_0_minus_0_0_minus_0_21000_80_d0g3v0_Shanghai + - ecadd_0_minus_0_0_minus_0_25000_128_d0g0v0_Shanghai + - ecadd_0_minus_0_0_minus_0_25000_128_d0g1v0_Shanghai + - ecadd_0_minus_0_0_minus_0_25000_128_d0g2v0_Shanghai + - ecadd_0_minus_0_0_minus_0_25000_128_d0g3v0_Shanghai + - ecadd_0_minus_0_1_minus_2_21000_128_d0g1v0_Shanghai + - ecadd_0_minus_0_1_minus_2_21000_128_d0g2v0_Shanghai + - ecadd_0_minus_0_1_minus_2_21000_128_d0g3v0_Shanghai + - ecadd_0_minus_0_1_minus_2_21000_192_d0g1v0_Shanghai + - ecadd_0_minus_0_1_minus_2_25000_128_d0g0v0_Shanghai + - ecadd_0_minus_0_1_minus_2_25000_128_d0g1v0_Shanghai + - ecadd_0_minus_0_1_minus_2_21000_192_d0g2v0_Shanghai + - ecadd_0_minus_0_1_minus_2_21000_192_d0g3v0_Shanghai + - ecadd_0_minus_0_1_minus_2_25000_128_d0g2v0_Shanghai + - ecadd_0_minus_0_1_minus_2_25000_128_d0g3v0_Shanghai + - ecadd_1145_minus_3932_1145_minus_4651_21000_192_d0g1v0_Shanghai + - ecadd_1145_minus_3932_1145_minus_4651_21000_192_d0g2v0_Shanghai + - ecadd_1145_minus_3932_1145_minus_4651_21000_192_d0g3v0_Shanghai + - ecadd_1145_minus_3932_1145_minus_4651_25000_192_d0g1v0_Shanghai + - ecadd_1145_minus_3932_1145_minus_4651_25000_192_d0g0v0_Shanghai + - ecadd_1145_minus_3932_1145_minus_4651_25000_192_d0g2v0_Shanghai + - ecadd_1145_minus_3932_1145_minus_4651_25000_192_d0g3v0_Shanghai + - ecadd_1145_minus_3932_2969_minus_1336_21000_128_d0g2v0_Shanghai + - ecadd_1145_minus_3932_2969_minus_1336_21000_128_d0g1v0_Shanghai + - ecadd_1145_minus_3932_2969_minus_1336_21000_128_d0g3v0_Shanghai + - ecadd_1145_minus_3932_2969_minus_1336_25000_128_d0g0v0_Shanghai + - ecadd_1145_minus_3932_2969_minus_1336_25000_128_d0g1v0_Shanghai + - ecadd_1145_minus_3932_2969_minus_1336_25000_128_d0g3v0_Shanghai + - ecadd_1145_minus_3932_2969_minus_1336_25000_128_d0g2v0_Shanghai + - ecadd_1_minus_2_0_minus_0_21000_128_d0g1v0_Shanghai + - ecadd_1_minus_2_0_minus_0_21000_128_d0g2v0_Shanghai + - ecadd_1_minus_2_0_minus_0_21000_128_d0g3v0_Shanghai + - ecadd_1_minus_2_0_minus_0_21000_192_d0g1v0_Shanghai + - ecadd_1_minus_2_0_minus_0_21000_192_d0g2v0_Shanghai + - ecadd_1_minus_2_0_minus_0_21000_64_d0g1v0_Shanghai + - ecadd_1_minus_2_0_minus_0_21000_192_d0g3v0_Shanghai + - ecadd_1_minus_2_0_minus_0_21000_64_d0g2v0_Shanghai + - ecadd_1_minus_2_0_minus_0_21000_64_d0g3v0_Shanghai + - ecadd_1_minus_2_1_minus_2_21000_128_d0g1v0_Shanghai + - ecadd_1_minus_2_1_minus_2_21000_128_d0g2v0_Shanghai + - ecadd_1_minus_2_1_minus_2_21000_128_d0g3v0_Shanghai + - ecadd_1_minus_2_1_minus_2_21000_192_d0g1v0_Shanghai + - ecadd_1_minus_2_1_minus_2_21000_192_d0g2v0_Shanghai + - ecadd_1_minus_2_1_minus_2_25000_128_d0g0v0_Shanghai + - ecadd_1_minus_2_1_minus_2_21000_192_d0g3v0_Shanghai + - ecadd_1_minus_2_1_minus_2_25000_128_d0g1v0_Shanghai + - ecadd_1_minus_2_1_minus_2_25000_128_d0g2v0_Shanghai + - ecadd_1_minus_2_1_minus_2_25000_128_d0g3v0_Shanghai + - ecmul_0_minus_0_0_21000_0_d0g1v0_Shanghai + - ecmul_0_minus_0_0_21000_0_d0g3v0_Shanghai + - ecmul_0_minus_0_0_21000_0_d0g2v0_Shanghai + - ecmul_0_minus_0_0_21000_128_d0g1v0_Shanghai + - ecmul_0_minus_0_0_21000_128_d0g2v0_Shanghai + - ecmul_0_minus_0_0_21000_40_d0g1v0_Shanghai + - ecmul_0_minus_0_0_21000_128_d0g3v0_Shanghai + - ecmul_0_minus_0_0_21000_40_d0g2v0_Shanghai + - ecmul_0_minus_0_0_21000_40_d0g3v0_Shanghai + - ecmul_0_minus_0_0_21000_64_d0g1v0_Shanghai + - ecmul_0_minus_0_0_21000_64_d0g2v0_Shanghai + - ecmul_0_minus_0_0_21000_64_d0g3v0_Shanghai + - ecmul_0_minus_0_0_21000_80_d0g1v0_Shanghai + - ecmul_0_minus_0_0_21000_80_d0g2v0_Shanghai + - ecmul_0_minus_0_0_21000_80_d0g3v0_Shanghai + - ecmul_0_minus_0_0_21000_96_d0g2v0_Shanghai + - ecmul_0_minus_0_0_21000_96_d0g1v0_Shanghai + - ecmul_0_minus_0_0_21000_96_d0g3v0_Shanghai + - ecmul_0_minus_0_0_28000_96_d0g1v0_Shanghai + - ecmul_0_minus_0_0_28000_96_d0g2v0_Shanghai + - ecmul_0_minus_0_0_28000_96_d0g3v0_Shanghai + - ecmul_0_minus_0_1_21000_96_d0g2v0_Shanghai + - ecmul_0_minus_0_1_21000_96_d0g1v0_Shanghai + - ecmul_0_minus_0_1_21000_128_d0g1v0_Shanghai + - ecmul_0_minus_0_1_21000_96_d0g3v0_Shanghai + - ecmul_0_minus_0_1_21000_128_d0g2v0_Shanghai + - ecmul_0_minus_0_1_21000_128_d0g3v0_Shanghai + - ecmul_0_minus_0_2_21000_128_d0g1v0_Shanghai + - ecmul_0_minus_0_2_21000_128_d0g2v0_Shanghai + - ecmul_0_minus_0_2_21000_128_d0g3v0_Shanghai + - ecmul_0_minus_0_2_21000_96_d0g1v0_Shanghai + - ecmul_0_minus_0_2_21000_96_d0g2v0_Shanghai + - ecmul_0_minus_0_2_21000_96_d0g3v0_Shanghai + - ecmul_0_minus_0_2_28000_96_d0g1v0_Shanghai + - ecmul_0_minus_0_2_28000_96_d0g2v0_Shanghai + - ecmul_0_minus_0_2_28000_96_d0g3v0_Shanghai + - ecmul_0_minus_0_340282366920938463463374607431768211456_21000_80_d0g1v0_Shanghai + - ecmul_0_minus_0_340282366920938463463374607431768211456_21000_80_d0g3v0_Shanghai + - ecmul_0_minus_0_340282366920938463463374607431768211456_21000_80_d0g2v0_Shanghai + - ecmul_0_minus_0_340282366920938463463374607431768211456_21000_128_d0g1v0_Shanghai + - ecmul_0_minus_0_340282366920938463463374607431768211456_21000_128_d0g2v0_Shanghai + - ecmul_0_minus_0_340282366920938463463374607431768211456_21000_128_d0g3v0_Shanghai + - ecmul_0_minus_0_340282366920938463463374607431768211456_21000_96_d0g1v0_Shanghai + - ecmul_0_minus_0_340282366920938463463374607431768211456_21000_96_d0g2v0_Shanghai + - ecmul_0_minus_0_340282366920938463463374607431768211456_21000_96_d0g3v0_Shanghai + - ecmul_0_minus_0_340282366920938463463374607431768211456_28000_96_d0g1v0_Shanghai + - ecmul_0_minus_0_340282366920938463463374607431768211456_28000_96_d0g2v0_Shanghai + - ecmul_0_minus_0_340282366920938463463374607431768211456_28000_96_d0g3v0_Shanghai + - ecmul_0_minus_0_5616_21000_128_d0g1v0_Shanghai + - ecmul_0_minus_0_5616_21000_128_d0g2v0_Shanghai + - ecmul_0_minus_0_5616_21000_128_d0g3v0_Shanghai + - ecmul_0_minus_0_5616_21000_96_d0g1v0_Shanghai + - ecmul_0_minus_0_5616_21000_96_d0g2v0_Shanghai + - ecmul_0_minus_0_5616_21000_96_d0g3v0_Shanghai + - ecmul_0_minus_0_5616_28000_96_d0g1v0_Shanghai + - ecmul_0_minus_0_5616_28000_96_d0g2v0_Shanghai + - ecmul_0_minus_0_5616_28000_96_d0g3v0_Shanghai + - ecmul_0_minus_0_5617_21000_128_d0g1v0_Shanghai + - ecmul_0_minus_0_5617_21000_128_d0g2v0_Shanghai + - ecmul_0_minus_0_5617_21000_128_d0g3v0_Shanghai + - ecmul_0_minus_0_5617_21000_96_d0g1v0_Shanghai + - ecmul_0_minus_0_5617_21000_96_d0g2v0_Shanghai + - ecmul_0_minus_0_5617_21000_96_d0g3v0_Shanghai + - ecmul_0_minus_0_5617_28000_96_d0g1v0_Shanghai + - ecmul_0_minus_0_5617_28000_96_d0g2v0_Shanghai + - ecmul_0_minus_0_5617_28000_96_d0g3v0_Shanghai + - ecmul_0_minus_0_9935_21000_128_d0g1v0_Shanghai + - ecmul_0_minus_0_9935_21000_128_d0g2v0_Shanghai + - ecmul_0_minus_0_9935_21000_128_d0g3v0_Shanghai + - ecmul_0_minus_0_9935_21000_96_d0g1v0_Shanghai + - ecmul_0_minus_0_9935_21000_96_d0g2v0_Shanghai + - ecmul_0_minus_0_9935_21000_96_d0g3v0_Shanghai + - ecmul_0_minus_0_9_21000_128_d0g1v0_Shanghai + - ecmul_0_minus_0_9_21000_128_d0g2v0_Shanghai + - ecmul_0_minus_0_9_21000_128_d0g3v0_Shanghai + - ecmul_0_minus_0_9_21000_96_d0g1v0_Shanghai + - ecmul_0_minus_0_9_21000_96_d0g2v0_Shanghai + - ecmul_0_minus_0_9_21000_96_d0g3v0_Shanghai + - ecmul_0_minus_0_9_28000_96_d0g1v0_Shanghai + - ecmul_0_minus_0_9_28000_96_d0g2v0_Shanghai + - ecmul_0_minus_0_9_28000_96_d0g3v0_Shanghai + - ecmul_1_minus_2_0_21000_64_d0g1v0_Shanghai + - ecmul_1_minus_2_0_21000_64_d0g2v0_Shanghai + - ecmul_1_minus_2_0_21000_64_d0g3v0_Shanghai + - ecmul_1_minus_2_0_21000_128_d0g1v0_Shanghai + - ecmul_1_minus_2_0_21000_128_d0g2v0_Shanghai + - ecmul_1_minus_2_0_21000_128_d0g3v0_Shanghai + - ecmul_1_minus_2_0_21000_80_d0g1v0_Shanghai + - ecmul_1_minus_2_0_21000_80_d0g2v0_Shanghai + - ecmul_1_minus_2_0_21000_80_d0g3v0_Shanghai + - ecmul_1_minus_2_0_21000_96_d0g1v0_Shanghai + - ecmul_1_minus_2_0_21000_96_d0g2v0_Shanghai + - ecmul_1_minus_2_0_21000_96_d0g3v0_Shanghai + - ecmul_1_minus_2_1_21000_128_d0g1v0_Shanghai + - ecmul_1_minus_2_1_21000_128_d0g2v0_Shanghai + - ecmul_1_minus_2_1_21000_96_d0g1v0_Shanghai + - ecmul_1_minus_2_1_21000_128_d0g3v0_Shanghai + - ecmul_1_minus_2_1_21000_96_d0g2v0_Shanghai + - ecmul_1_minus_2_1_21000_96_d0g3v0_Shanghai + - ecmul_1_minus_2_1_28000_96_d0g1v0_Shanghai + - ecmul_1_minus_2_1_28000_96_d0g3v0_Shanghai + - ecmul_1_minus_2_1_28000_96_d0g2v0_Shanghai + - ecmul_1_minus_2_2_21000_128_d0g1v0_Shanghai + - ecmul_1_minus_2_2_21000_128_d0g2v0_Shanghai + - ecmul_1_minus_2_2_21000_96_d0g1v0_Shanghai + - ecmul_1_minus_2_2_21000_128_d0g3v0_Shanghai + - ecmul_1_minus_2_2_21000_96_d0g2v0_Shanghai + - ecmul_1_minus_2_2_21000_96_d0g3v0_Shanghai + stZeroKnowledge: + - ecmul_1_minus_2_2_28000_96_d0g2v0_Shanghai + - ecmul_1_minus_2_2_28000_96_d0g1v0_Shanghai + - ecmul_1_minus_2_2_28000_96_d0g3v0_Shanghai + - ecmul_1_minus_2_2_28000_96_d0g4v0_Shanghai + - ecmul_1_minus_2_340282366920938463463374607431768211456_21000_80_d0g1v0_Shanghai + - ecmul_1_minus_2_340282366920938463463374607431768211456_21000_80_d0g2v0_Shanghai + - ecmul_1_minus_2_340282366920938463463374607431768211456_21000_128_d0g1v0_Shanghai + - ecmul_1_minus_2_340282366920938463463374607431768211456_21000_128_d0g2v0_Shanghai + - ecmul_1_minus_2_340282366920938463463374607431768211456_21000_128_d0g3v0_Shanghai + - ecmul_1_minus_2_340282366920938463463374607431768211456_21000_80_d0g3v0_Shanghai + - ecmul_1_minus_2_340282366920938463463374607431768211456_21000_96_d0g1v0_Shanghai + - ecmul_1_minus_2_340282366920938463463374607431768211456_21000_96_d0g2v0_Shanghai + - ecmul_1_minus_2_340282366920938463463374607431768211456_21000_96_d0g3v0_Shanghai + - ecmul_1_minus_2_340282366920938463463374607431768211456_28000_96_d0g1v0_Shanghai + - ecmul_1_minus_2_340282366920938463463374607431768211456_28000_96_d0g2v0_Shanghai + - ecmul_1_minus_2_340282366920938463463374607431768211456_28000_96_d0g3v0_Shanghai + - ecmul_1_minus_2_5616_21000_96_d0g1v0_Shanghai + - ecmul_1_minus_2_5616_21000_128_d0g1v0_Shanghai + - ecmul_1_minus_2_5616_21000_96_d0g2v0_Shanghai + - ecmul_1_minus_2_5616_21000_128_d0g2v0_Shanghai + - ecmul_1_minus_2_5616_21000_128_d0g3v0_Shanghai + - ecmul_1_minus_2_5616_21000_96_d0g3v0_Shanghai + - ecmul_1_minus_2_5617_21000_128_d0g1v0_Shanghai + - ecmul_1_minus_2_5617_21000_128_d0g2v0_Shanghai + - ecmul_1_minus_2_5617_21000_128_d0g3v0_Shanghai + - ecmul_1_minus_2_5617_21000_96_d0g1v0_Shanghai + - ecmul_1_minus_2_5617_21000_96_d0g2v0_Shanghai + - ecmul_1_minus_2_5617_21000_96_d0g3v0_Shanghai + - ecmul_1_minus_2_616_28000_96_d0g1v0_Shanghai + - ecmul_1_minus_2_616_28000_96_d0g2v0_Shanghai + - ecmul_1_minus_2_616_28000_96_d0g3v0_Shanghai + - ecmul_1_minus_2_616_28000_96_d0g4v0_Shanghai + - ecmul_1_minus_2_9935_21000_96_d0g1v0_Shanghai + - ecmul_1_minus_2_9935_21000_128_d0g1v0_Shanghai + - ecmul_1_minus_2_9935_21000_128_d0g2v0_Shanghai + - ecmul_1_minus_2_9935_21000_128_d0g3v0_Shanghai + - ecmul_1_minus_2_9935_21000_96_d0g2v0_Shanghai + - ecmul_1_minus_2_9935_21000_96_d0g3v0_Shanghai + - ecmul_1_minus_2_9935_28000_96_d0g1v0_Shanghai + - ecmul_1_minus_2_9935_28000_96_d0g2v0_Shanghai + - ecmul_1_minus_2_9935_28000_96_d0g3v0_Shanghai + - ecmul_1_minus_2_9_21000_128_d0g1v0_Shanghai + - ecmul_1_minus_2_9_21000_128_d0g2v0_Shanghai + - ecmul_1_minus_2_9_21000_96_d0g1v0_Shanghai + - ecmul_1_minus_2_9_21000_128_d0g3v0_Shanghai + - ecmul_1_minus_2_9_21000_96_d0g2v0_Shanghai + - ecmul_1_minus_2_9_21000_96_d0g3v0_Shanghai + - ecmul_1_minus_2_9_28000_96_d0g1v0_Shanghai + - ecmul_1_minus_2_9_28000_96_d0g2v0_Shanghai + - ecmul_1_minus_2_9_28000_96_d0g3v0_Shanghai + - ecmul_7827_minus_6598_0_21000_64_d0g1v0_Shanghai + - ecmul_7827_minus_6598_0_21000_64_d0g2v0_Shanghai + - ecmul_7827_minus_6598_0_21000_64_d0g3v0_Shanghai + - ecmul_7827_minus_6598_0_21000_128_d0g1v0_Shanghai + - ecmul_7827_minus_6598_0_21000_128_d0g2v0_Shanghai + - ecmul_7827_minus_6598_0_21000_128_d0g3v0_Shanghai + - ecmul_7827_minus_6598_0_21000_80_d0g1v0_Shanghai + - ecmul_7827_minus_6598_0_21000_80_d0g2v0_Shanghai + - ecmul_7827_minus_6598_0_21000_80_d0g3v0_Shanghai + - ecmul_7827_minus_6598_0_21000_96_d0g1v0_Shanghai + - ecmul_7827_minus_6598_0_21000_96_d0g2v0_Shanghai + - ecmul_7827_minus_6598_0_21000_96_d0g3v0_Shanghai + - ecmul_7827_minus_6598_1456_21000_128_d0g1v0_Shanghai + - ecmul_7827_minus_6598_1456_21000_80_d0g1v0_Shanghai + - ecmul_7827_minus_6598_1456_21000_128_d0g2v0_Shanghai + - ecmul_7827_minus_6598_1456_21000_80_d0g2v0_Shanghai + - ecmul_7827_minus_6598_1456_21000_128_d0g3v0_Shanghai + - ecmul_7827_minus_6598_1456_21000_80_d0g3v0_Shanghai + - ecmul_7827_minus_6598_1456_21000_96_d0g1v0_Shanghai + - ecmul_7827_minus_6598_1456_21000_96_d0g3v0_Shanghai + - ecmul_7827_minus_6598_1456_21000_96_d0g2v0_Shanghai + - ecmul_7827_minus_6598_1456_28000_96_d0g1v0_Shanghai + - ecmul_7827_minus_6598_1456_28000_96_d0g2v0_Shanghai + - ecmul_7827_minus_6598_1456_28000_96_d0g3v0_Shanghai + - ecmul_7827_minus_6598_1_21000_96_d0g1v0_Shanghai + - ecmul_7827_minus_6598_1_21000_128_d0g1v0_Shanghai + - ecmul_7827_minus_6598_1_21000_128_d0g2v0_Shanghai + - ecmul_7827_minus_6598_1_21000_128_d0g3v0_Shanghai + - ecmul_7827_minus_6598_1_21000_96_d0g2v0_Shanghai + - ecmul_7827_minus_6598_1_21000_96_d0g3v0_Shanghai + - ecmul_7827_minus_6598_1_28000_96_d0g1v0_Shanghai + - ecmul_7827_minus_6598_1_28000_96_d0g3v0_Shanghai + - ecmul_7827_minus_6598_1_28000_96_d0g2v0_Shanghai + - ecmul_7827_minus_6598_2_21000_128_d0g1v0_Shanghai + - ecmul_7827_minus_6598_2_21000_128_d0g2v0_Shanghai + - ecmul_7827_minus_6598_2_21000_96_d0g1v0_Shanghai + - ecmul_7827_minus_6598_2_21000_128_d0g3v0_Shanghai + - ecmul_7827_minus_6598_2_21000_96_d0g2v0_Shanghai + - ecmul_7827_minus_6598_2_21000_96_d0g3v0_Shanghai + - ecmul_7827_minus_6598_2_28000_96_d0g1v0_Shanghai + - ecmul_7827_minus_6598_2_28000_96_d0g2v0_Shanghai + - ecmul_7827_minus_6598_2_28000_96_d0g3v0_Shanghai + - ecmul_7827_minus_6598_5616_21000_96_d0g1v0_Shanghai + - ecmul_7827_minus_6598_5616_21000_128_d0g1v0_Shanghai + - ecmul_7827_minus_6598_5616_21000_128_d0g2v0_Shanghai + - ecmul_7827_minus_6598_5616_21000_128_d0g3v0_Shanghai + - ecmul_7827_minus_6598_5616_21000_96_d0g3v0_Shanghai + - ecmul_7827_minus_6598_5616_21000_96_d0g2v0_Shanghai + - ecmul_7827_minus_6598_5616_28000_96_d0g1v0_Shanghai + - ecmul_7827_minus_6598_5616_28000_96_d0g2v0_Shanghai + - ecmul_7827_minus_6598_5616_28000_96_d0g3v0_Shanghai + - ecmul_7827_minus_6598_5617_21000_96_d0g1v0_Shanghai + - ecmul_7827_minus_6598_5617_21000_96_d0g2v0_Shanghai + - ecmul_7827_minus_6598_5617_21000_96_d0g3v0_Shanghai + - ecmul_7827_minus_6598_5617_21000_128_d0g1v0_Shanghai + - ecmul_7827_minus_6598_5617_21000_128_d0g2v0_Shanghai + - ecmul_7827_minus_6598_9935_21000_128_d0g2v0_Shanghai + - ecmul_7827_minus_6598_9935_21000_128_d0g3v0_Shanghai + - ecmul_7827_minus_6598_9935_21000_96_d0g2v0_Shanghai + - ecmul_7827_minus_6598_9935_21000_96_d0g3v0_Shanghai + - ecmul_7827_minus_6598_9935_28000_96_d0g2v0_Shanghai + - ecmul_7827_minus_6598_9935_28000_96_d0g1v0_Shanghai + - ecmul_7827_minus_6598_9935_28000_96_d0g3v0_Shanghai + - ecmul_7827_minus_6598_9_21000_96_d0g1v0_Shanghai + - ecmul_7827_minus_6598_9_21000_96_d0g2v0_Shanghai + - ecmul_7827_minus_6598_9_21000_128_d0g1v0_Shanghai + - ecmul_7827_minus_6598_9_21000_128_d0g2v0_Shanghai + - ecmul_7827_minus_6598_9_21000_96_d0g3v0_Shanghai + - ecmul_7827_minus_6598_9_21000_128_d0g3v0_Shanghai + - ecmul_7827_minus_6598_9_28000_96_d0g1v0_Shanghai + - ecmul_7827_minus_6598_9_28000_96_d0g3v0_Shanghai + - ecmul_7827_minus_6598_9_28000_96_d0g2v0_Shanghai + - ecpairing_empty_data_d0g0v0_Shanghai + - ecpairing_empty_data_d0g3v0_Shanghai + - ecpairing_empty_data_insufficient_gas_d0g2v0_Shanghai + - ecpairing_one_point_fail_d0g0v0_Shanghai + - ecpairing_one_point_with_g1_zero_d0g0v0_Shanghai + - ecpairing_three_point_fail_1_d0g0v0_Shanghai + - ecpairing_two_point_fail_1_d0g0v0_Shanghai + - ecpairing_two_point_fail_2_d0g0v0_Shanghai + - ecpairing_two_point_match_1_d0g0v0_Shanghai + - ecpairing_two_point_match_5_d0g0v0_Shanghai + - pairingTest_d0g0v0_Shanghai + - pairingTest_d1g0v0_Shanghai + - pointAddTrunc_d0g1v0_Shanghai + - pointAddTrunc_d0g0v0_Shanghai + - pointAddTrunc_d0g2v0_Shanghai + - pairingTest_d2g0v0_Shanghai + - pairingTest_d3g0v0_Shanghai + - pointAddTrunc_d2g0v0_Shanghai + - pointAddTrunc_d2g1v0_Shanghai + - pointAddTrunc_d2g2v0_Shanghai + - pointAddTrunc_d3g0v0_Shanghai + - pointAddTrunc_d3g1v0_Shanghai + - pointAddTrunc_d3g2v0_Shanghai + - pairingTest_d4g0v0_Shanghai + - pointAddTrunc_d7g0v0_Shanghai + - pointAddTrunc_d7g1v0_Shanghai + - pointAddTrunc_d7g2v0_Shanghai + - pointAddTrunc_d8g0v0_Shanghai + - pointAddTrunc_d8g1v0_Shanghai + - pointAddTrunc_d8g2v0_Shanghai + - pointAddTrunc_d9g0v0_Shanghai + - pointAddTrunc_d9g1v0_Shanghai + - pointAddTrunc_d9g2v0_Shanghai + - pointAdd_d0g0v0_Shanghai + - pointAdd_d0g1v0_Shanghai + - pointAdd_d0g2v0_Shanghai + - pointAdd_d3g0v0_Shanghai + - pointAdd_d3g1v0_Shanghai + - pointAdd_d3g2v0_Shanghai + - pointAdd_d4g0v0_Shanghai + - pointAdd_d4g1v0_Shanghai + - pointAdd_d4g2v0_Shanghai + - pointAdd_d7g1v0_Shanghai + - pointAdd_d7g0v0_Shanghai + - pointAdd_d7g2v0_Shanghai + - pointAdd_d8g0v0_Shanghai + - pointAdd_d8g1v0_Shanghai + - pointAdd_d8g2v0_Shanghai + - pointAdd_d9g0v0_Shanghai + - pointAdd_d9g1v0_Shanghai + - pointAdd_d9g2v0_Shanghai + - pointMulAdd2_d10g0v0_Shanghai + - pointMulAdd2_d11g0v0_Shanghai + - pointMulAdd2_d13g0v0_Shanghai + - pointMulAdd2_d14g0v0_Shanghai + - pointMulAdd2_d15g0v0_Shanghai + - pointMulAdd2_d16g0v0_Shanghai + - pointMulAdd2_d17g0v0_Shanghai + - pointMulAdd2_d17g3v0_Shanghai + - pointMulAdd2_d18g0v0_Shanghai + - pointMulAdd2_d19g0v0_Shanghai + - pointMulAdd2_d20g0v0_Shanghai + - pointMulAdd2_d21g0v0_Shanghai + - pointMulAdd2_d21g3v0_Shanghai + - pointMulAdd2_d22g0v0_Shanghai + - pointMulAdd2_d23g0v0_Shanghai + - pointMulAdd2_d24g0v0_Shanghai + - pointMulAdd2_d25g0v0_Shanghai + - pointMulAdd2_d27g0v0_Shanghai + - pointMulAdd2_d28g0v0_Shanghai + - pointMulAdd2_d29g0v0_Shanghai + - pointMulAdd2_d30g0v0_Shanghai + - pointMulAdd2_d30g3v0_Shanghai + - pointMulAdd2_d31g0v0_Shanghai + - pointMulAdd2_d32g0v0_Shanghai + - pointMulAdd2_d33g0v0_Shanghai + - pointMulAdd2_d34g0v0_Shanghai + - pointMulAdd2_d35g0v0_Shanghai + - pointMulAdd2_d34g3v0_Shanghai + - pointMulAdd2_d36g0v0_Shanghai + - pointMulAdd2_d37g0v0_Shanghai + - pointMulAdd_d0g0v0_Shanghai + - pointMulAdd_d1g0v0_Shanghai + - pointMulAdd_d4g0v0_Shanghai + - pointMulAdd_d7g3v0_Shanghai + - pointMulAdd_d3g0v0_Shanghai + - pointMulAdd_d7g0v0_Shanghai + - pointMulAdd_d6g0v0_Shanghai + - pointMulAdd_d5g0v0_Shanghai diff --git a/kakarot-ssj/bun.lockb b/kakarot-ssj/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..3a0d4b4921e98b571370bcbc8b21c638de9aa551 GIT binary patch literal 48666 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::new(); +//! // Push some items to the vec. +//! vec.push(1); +//! vec.push(2); +//! ... +//! ``` + +pub trait VecTrait { + /// Creates a new V instance. + /// Returns + /// * V The new vec instance. + fn new() -> V; + + /// Returns the item at the given index, or None if the index is out of bounds. + /// Parameters + /// * self The vec instance. + /// * index The index of the item to get. + /// Returns + /// * Option The item at the given index, or None if the index is out of bounds. + fn get(ref self: V, index: usize) -> Option; + + /// Returns the item at the given index, or panics if the index is out of bounds. + /// Parameters + /// * self The vec instance. + /// * index The index of the item to get. + /// Returns + /// * T The item at the given index. + fn at(ref self: V, index: usize) -> T; + + /// Pushes a new item to the vec. + /// Parameters + /// * self The vec instance. + /// * value The value to push onto the vec. + fn push(ref self: V, value: T); + + /// Sets the item at the given index to the given value. + /// Panics if the index is out of bounds. + /// Parameters + /// * self The vec instance. + /// * index The index of the item to set. + /// * value The value to set the item to. + fn set(ref self: V, index: usize, value: T); + + /// Returns the length of the vec. + /// Parameters + /// * self The vec instance. + /// Returns + /// * usize The length of the vec. + fn len(self: @V) -> usize; +} + +impl VecIndex> of Index { + type Target = T; + + #[inline(always)] + fn index(ref self: V, index: usize) -> T { + self.at(index) + } +} + +pub struct Felt252Vec { + pub items: Felt252Dict, + pub len: usize, +} + +impl DefaultFeltVec, +Copy, +Felt252DictValue> of Default> { + fn default() -> Felt252Vec { + Felt252VecImpl::::new() + } +} + +impl DestructFeltVec, +Felt252DictValue> of Destruct> { + fn destruct(self: Felt252Vec) nopanic { + self.items.squash(); + } +} + + +impl Felt252VecImpl, +Copy, +Felt252DictValue> of VecTrait, T> { + fn new() -> Felt252Vec { + Felt252Vec { items: Default::default(), len: 0 } + } + + fn get(ref self: Felt252Vec, index: usize) -> Option { + if index < self.len() { + let item = self.items.get(index.into()); + Option::Some(item) + } else { + Option::None + } + } + + fn at(ref self: Felt252Vec, index: usize) -> T { + assert(index < self.len(), 'Index out of bounds'); + let item = self.items.get(index.into()); + item + } + + fn push(ref self: Felt252Vec, value: T) { + self.items.insert(self.len.into(), value); + self.len = self.len.wrapping_add(1); + } + + fn set(ref self: Felt252Vec, index: usize, value: T) { + assert(index < self.len(), 'Index out of bounds'); + self.items.insert(index.into(), value); + } + + fn len(self: @Felt252Vec) -> usize { + *self.len + } +} + +pub struct NullableVec { + items: Felt252Dict>, + len: usize, +} + +impl DestructNullableVec> of Destruct> { + fn destruct(self: NullableVec) nopanic { + self.items.squash(); + } +} + +impl NullableVecImpl, +Copy> of VecTrait, T> { + fn new() -> NullableVec { + NullableVec { items: Default::default(), len: 0 } + } + + fn get(ref self: NullableVec, index: usize) -> Option { + if index < self.len() { + Option::Some(self.items.get(index.into()).deref()) + } else { + Option::None + } + } + + fn at(ref self: NullableVec, index: usize) -> T { + assert(index < self.len(), 'Index out of bounds'); + self.items.get(index.into()).deref() + } + + fn push(ref self: NullableVec, value: T) { + self.items.insert(self.len.into(), NullableImpl::new(value)); + self.len = self.len.wrapping_add(1); + } + + fn set(ref self: NullableVec, index: usize, value: T) { + assert(index < self.len(), 'Index out of bounds'); + self.items.insert(index.into(), NullableImpl::new(value)); + } + + fn len(self: @NullableVec) -> usize { + *self.len + } +} diff --git a/kakarot-ssj/crates/contracts/Scarb.toml b/kakarot-ssj/crates/contracts/Scarb.toml new file mode 100644 index 000000000..1e689c03e --- /dev/null +++ b/kakarot-ssj/crates/contracts/Scarb.toml @@ -0,0 +1,32 @@ +[package] +name = "contracts" +version = "0.1.0" +edition = "2024_07" + +# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html + +[dependencies] +starknet.workspace = true +evm = { path = "../evm" } +openzeppelin = { path = "../openzeppelin" } +utils = { path = "../utils" } + +[tool] +fmt.workspace = true + +[[target.starknet-contract]] +casm = true +casm-add-pythonic-hints = true +build-external-contracts = ["openzeppelin::token::erc20::erc20::ERC20"] + +[lib] +name = "contracts" + +[dev-dependencies] +snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry.git", tag = "v0.31.0" } +assert_macros = "2.8.2" +snforge_utils = { path = "../snforge_utils" } + +[scripts] +test = "snforge test --max-n-steps 4294967295" +test-profiling = "snforge test --max-n-steps 4294967295 --build-profile" diff --git a/kakarot-ssj/crates/contracts/src/account_contract.cairo b/kakarot-ssj/crates/contracts/src/account_contract.cairo new file mode 100644 index 000000000..9391ac4db --- /dev/null +++ b/kakarot-ssj/crates/contracts/src/account_contract.cairo @@ -0,0 +1,283 @@ +//! The generic account that is deployed by Kakarot Core before being "specialized" into an +//! Externally Owned Account or a Contract Account This aims at having only one class hash for all +//! the contracts deployed by Kakarot, thus enforcing a unique and consistent address mapping Eth +//! Address <=> Starknet Address + +use core::starknet::account::{Call}; +use core::starknet::{EthAddress, ClassHash, ContractAddress}; + +#[derive(Copy, Drop, Serde, Debug)] +pub struct OutsideExecution { + pub caller: ContractAddress, + pub nonce: u64, + pub execute_after: u64, + pub execute_before: u64, + pub calls: Span +} + +#[starknet::interface] +pub trait IAccount { + fn initialize( + ref self: TContractState, evm_address: EthAddress, implementation_class: ClassHash + ); + fn get_implementation(self: @TContractState) -> ClassHash; + fn get_evm_address(self: @TContractState) -> EthAddress; + fn get_code_hash(self: @TContractState) -> u256; + fn set_code_hash(ref self: TContractState, code_hash: u256); + fn is_initialized(self: @TContractState) -> bool; + + // EOA functions + fn __validate__(ref self: TContractState, calls: Array) -> felt252; + fn __validate_declare__(self: @TContractState, class_hash: felt252) -> felt252; + fn __execute__(ref self: TContractState, calls: Array) -> Array>; + + // CA functions + fn write_bytecode(ref self: TContractState, bytecode: Span); + fn bytecode(self: @TContractState) -> Span; + fn write_storage(ref self: TContractState, key: u256, value: u256); + fn storage(self: @TContractState, key: u256) -> u256; + fn get_nonce(self: @TContractState) -> u64; + fn set_nonce(ref self: TContractState, nonce: u64); + fn execute_starknet_call(ref self: TContractState, call: Call) -> (bool, Span); + fn execute_from_outside( + ref self: TContractState, outside_execution: OutsideExecution, signature: Span, + ) -> Array>; +} + +#[starknet::contract(account)] +pub mod AccountContract { + use core::cmp::min; + use core::num::traits::Bounded; + use core::num::traits::zero::Zero; + use core::starknet::account::{Call}; + use core::starknet::eth_signature::verify_eth_signature; + use core::starknet::storage::{ + Map, StorageMapReadAccess, StorageMapWriteAccess, StoragePointerReadAccess, + StoragePointerWriteAccess + }; + use core::starknet::syscalls::call_contract_syscall; + use core::starknet::{ + EthAddress, ClassHash, get_caller_address, get_tx_info, get_block_timestamp + }; + use crate::components::ownable::IOwnable; + use crate::components::ownable::ownable_component::InternalTrait; + use crate::components::ownable::ownable_component; + use crate::errors::KAKAROT_REENTRANCY; + use crate::kakarot_core::eth_rpc::{IEthRPCDispatcher, IEthRPCDispatcherTrait}; + use crate::kakarot_core::interface::{IKakarotCoreDispatcher, IKakarotCoreDispatcherTrait}; + use crate::storage::StorageBytecode; + use openzeppelin::token::erc20::interface::{IERC20CamelDispatcher, IERC20CamelDispatcherTrait}; + use super::OutsideExecution; + use utils::eth_transaction::transaction::TransactionUnsignedTrait; + use utils::serialization::{deserialize_signature, deserialize_bytes, serialize_bytes}; + use utils::traits::DefaultSignature; + + // Add ownable component + component!(path: ownable_component, storage: ownable, event: OwnableEvent); + #[abi(embed_v0)] + impl OwnableImpl = ownable_component::Ownable; + impl OwnableInternal = ownable_component::InternalImpl; + + + const VERSION: u32 = 000_001_000; + + + #[storage] + pub(crate) struct Storage { + pub(crate) Account_bytecode: StorageBytecode, + pub(crate) Account_bytecode_len: u32, + pub(crate) Account_storage: Map, + pub(crate) Account_is_initialized: bool, + pub(crate) Account_nonce: u64, + pub(crate) Account_implementation: ClassHash, + pub(crate) Account_evm_address: EthAddress, + pub(crate) Account_code_hash: u256, + #[substorage(v0)] + ownable: ownable_component::Storage + } + + #[event] + #[derive(Drop, starknet::Event)] + pub enum Event { + transaction_executed: TransactionExecuted, + OwnableEvent: ownable_component::Event + } + + #[derive(Drop, starknet::Event, Debug)] + pub struct TransactionExecuted { + pub response: Span, + pub success: bool, + pub gas_used: u64 + } + + #[constructor] + fn constructor(ref self: ContractState) { + panic!("Accounts cannot be created directly"); + } + + #[abi(embed_v0)] + impl Account of super::IAccount { + fn initialize( + ref self: ContractState, evm_address: EthAddress, implementation_class: ClassHash + ) { + assert(!self.Account_is_initialized.read(), 'Account already initialized'); + self.Account_is_initialized.write(true); + + self.Account_evm_address.write(evm_address); + self.Account_implementation.write(implementation_class); + + let kakarot_address = self.ownable.owner(); + let kakarot = IKakarotCoreDispatcher { contract_address: kakarot_address }; + let native_token = kakarot.get_native_token(); + // To internally perform value transfer of the network's native + // token (which conforms to the ERC20 standard), we need to give the + // KakarotCore contract infinite allowance + IERC20CamelDispatcher { contract_address: native_token } + .approve(kakarot_address, Bounded::::MAX); + + kakarot.register_account(evm_address); + } + + fn get_implementation(self: @ContractState) -> ClassHash { + self.Account_implementation.read() + } + + fn get_evm_address(self: @ContractState) -> EthAddress { + self.Account_evm_address.read() + } + + fn get_code_hash(self: @ContractState) -> u256 { + self.Account_code_hash.read() + } + + fn set_code_hash(ref self: ContractState, code_hash: u256) { + self.ownable.assert_only_owner(); + self.Account_code_hash.write(code_hash); + } + + fn is_initialized(self: @ContractState) -> bool { + self.Account_is_initialized.read() + } + + // EOA functions + fn __validate__(ref self: ContractState, calls: Array) -> felt252 { + panic!("EOA: __validate__ not supported") + } + + /// Validate Declare is not used for Kakarot + fn __validate_declare__(self: @ContractState, class_hash: felt252) -> felt252 { + panic!("EOA: declare not supported") + } + + fn __execute__(ref self: ContractState, calls: Array) -> Array> { + panic!("EOA: __execute__ not supported") + } + + fn write_bytecode(ref self: ContractState, bytecode: Span) { + self.ownable.assert_only_owner(); + self.Account_bytecode.write(StorageBytecode { bytecode }); + } + + fn bytecode(self: @ContractState) -> Span { + self.Account_bytecode.read().bytecode + } + + fn write_storage(ref self: ContractState, key: u256, value: u256) { + self.ownable.assert_only_owner(); + self.Account_storage.write(key, value); + } + + fn storage(self: @ContractState, key: u256) -> u256 { + self.Account_storage.read(key) + } + + fn get_nonce(self: @ContractState) -> u64 { + self.Account_nonce.read() + } + + fn set_nonce(ref self: ContractState, nonce: u64) { + self.ownable.assert_only_owner(); + self.Account_nonce.write(nonce); + } + + /// Used to preserve caller in Cairo Precompiles + /// Reentrency check is done for Kakarot contract, only get_starknet_address is allowed + /// for Solidity contracts to be able to get the corresponding Starknet address in their + /// calldata. + fn execute_starknet_call(ref self: ContractState, call: Call) -> (bool, Span) { + self.ownable.assert_only_owner(); + let kakarot_address = self.ownable.owner(); + if call.to == kakarot_address && call.selector != selector!("get_starknet_address") { + return (false, KAKAROT_REENTRANCY.span()); + } + let response = call_contract_syscall(call.to, call.selector, call.calldata); + if response.is_ok() { + return (true, response.unwrap().into()); + } + return (false, response.unwrap_err().into()); + } + + fn execute_from_outside( + ref self: ContractState, outside_execution: OutsideExecution, signature: Span, + ) -> Array> { + let caller = get_caller_address(); + let tx_info = get_tx_info(); + + // SNIP-9 Validation + if (outside_execution.caller.into() != 'ANY_CALLER') { + assert(caller == outside_execution.caller, 'SNIP9: Invalid caller'); + } + + let block_timestamp = get_block_timestamp(); + assert(block_timestamp > outside_execution.execute_after, 'SNIP9: Too early call'); + assert(block_timestamp < outside_execution.execute_before, 'SNIP9: Too late call'); + + // Kakarot-Specific Validation + assert(outside_execution.calls.len() == 1, 'KKRT: Multicall not supported'); + assert(tx_info.version.into() >= 1_u256, 'KKRT: Deprecated tx version: 0'); + + // EOA Validation + assert(self.Account_bytecode_len.read().is_zero(), 'EOA: cannot have code'); + + let kakarot = IEthRPCDispatcher { contract_address: self.ownable.owner() }; + + let chain_id: u64 = kakarot.eth_chain_id(); + assert(signature.len() == 5, 'EOA: Invalid signature length'); + let signature = deserialize_signature(signature, chain_id) + .expect('EOA: invalid signature'); + + let mut encoded_tx_data = deserialize_bytes((*outside_execution.calls[0]).calldata) + .expect('conversion to Span failed') + .span(); + let unsigned_transaction = TransactionUnsignedTrait::decode_enveloped( + ref encoded_tx_data + ) + .expect('EOA: could not decode tx'); + + let address = self.Account_evm_address.read(); + verify_eth_signature(unsigned_transaction.hash, signature, address); + + //TODO: refactor this to call eth_send_raw_unsigned_tx. Only the transactions bytes are + //passed. + let (success, return_data, gas_used) = kakarot + .eth_send_transaction(unsigned_transaction.transaction); + let return_data = serialize_bytes(return_data).span(); + + // See Argent account + // https://github.com/argentlabs/argent-contracts-starknet/blob/1352198956f36fb35fa544c4e46a3507a3ec20e3/src/presets/user_account.cairo#L211-L213 + // See 300 max data_len for events + // https://github.com/starkware-libs/blockifier/blob/9bfb3d4c8bf1b68a0c744d1249b32747c75a4d87/crates/blockifier/resources/versioned_constants.json + // The whole data_len should be less than 300, so it's the return_data should be less + // than 297 (+3 for return_data_len, success, gas_used) + self + .emit( + TransactionExecuted { + response: return_data.slice(0, min(297, return_data.len())), + success: success, + gas_used + } + ); + array![return_data] + } + } +} diff --git a/kakarot-ssj/crates/contracts/src/cairo1_helpers.cairo b/kakarot-ssj/crates/contracts/src/cairo1_helpers.cairo new file mode 100644 index 000000000..4bd3b89d2 --- /dev/null +++ b/kakarot-ssj/crates/contracts/src/cairo1_helpers.cairo @@ -0,0 +1,233 @@ +use core::starknet::{EthAddress, secp256_trait::Signature}; + +#[starknet::interface] +pub trait IPrecompiles { + /// Executes a precompiled contract at a given address with provided data. + /// + /// # Arguments + /// + /// * `self` - The instance of the current class. + /// * `address` - The address of the precompiled contract to be executed. + /// * `data` - The data to be passed to the precompiled contract. + /// + /// # Returns + /// + /// * A tuple containing: + /// * True if the execution was successful, false otherwise. + /// * The gas cost of the execution if successful, otherwise 0. + /// * The output data from the execution. + fn exec_precompile(self: @T, address: felt252, data: Span) -> (bool, u64, Span); +} + +#[starknet::interface] +pub trait IHelpers { + /// Gets the hash of a specific StarkNet block within the range of + /// [first_v0_12_0_block, current_block - 10]. + /// + /// # Arguments + /// + /// * `block_number` - The block number for which to get the hash. + /// + /// # Returns + /// The hash of the specified block. + /// + /// # Errors + /// `Block number out of range` - If the block number is greater than `current_block - 10`. + /// `0`: The block number is inferior to `first_v0_12_0_block`. + fn get_block_hash(self: @T, block_number: u64) -> felt252; + + /// Computes the keccak hash of the provided data. + /// + /// The data is expected to be an array of full 64-bit words. + /// The last u64-word to hash may be incomplete and is provided separately. + /// # Arguments + /// + /// * `words` - The full 64-bit words to hash. + /// * `last_input_word` - The last word to hash. + /// * `last_input_num_bytes` - The number of bytes in the last word. + /// + /// # Returns + /// The EVM-compatible keccak hash of the provided data. + fn keccak( + self: @T, words: Array, last_input_word: u64, last_input_num_bytes: usize + ) -> u256; + + /// Computes the SHA-256 of the provided data. + /// + /// The data is expected to be an array of full 32-bit unsigned words. + /// The last u32-word to hash may be incomplete and is provided separately. + /// # Arguments + /// + /// * `input` - The full 32-bit unsigned words to hash. + /// * `last_input_word` - the last word to hash. + /// * `last_input_num_bytes` - the number of bytes in the last word. + /// + /// # Returns + /// The SHA-256 of the provided data. + fn compute_sha256_u32_array( + self: @T, input: Array, last_input_word: u32, last_input_num_bytes: u32 + ) -> [ + u32 + ; 8]; + + // DEPRECATED + fn verify_eth_signature( + self: @T, msg_hash: u256, signature: Signature, eth_address: EthAddress + ); + + /// Recovers the Ethereum address from a message hash and a signature. + /// + /// # Arguments + /// + /// * `msg_hash` - The hash of the message. + /// * `signature` - The signature to recover the address from. + /// + /// # Returns + /// A tuple containing: + /// * A boolean indicating whether the recovery was successful. + /// * The recovered Ethereum address. + fn recover_eth_address(self: @T, msg_hash: u256, signature: Signature) -> (bool, EthAddress); + + /// Performs signature verification in the secp256r1 ellipitic curve. + /// + /// # Arguments + /// + /// * `msg_hash` - The hash of the message. + /// * `r` - The r component of the signature. + /// * `s` - The s component of the signature. + /// * `x` - The x coordinate of the public key. + /// * `y` - The y coordinate of the public key. + /// + /// # Returns + /// A boolean indicating whether the signature is valid. + fn verify_signature_secp256r1( + self: @T, msg_hash: u256, r: u256, s: u256, x: u256, y: u256 + ) -> bool; +} + + +pub mod embeddable_impls { + use core::keccak::{cairo_keccak, keccak_u256s_be_inputs}; + use core::num::traits::Zero; + use core::starknet::EthAddress; + use core::starknet::eth_signature::{verify_eth_signature}; + use core::starknet::secp256_trait::{ + Signature, recover_public_key, Secp256PointTrait, is_valid_signature + }; + use core::starknet::secp256_trait::{Secp256Trait}; + use core::starknet::secp256k1::Secp256k1Point; + use core::starknet::secp256r1::{Secp256r1Point}; + use core::traits::Into; + use core::{starknet, starknet::SyscallResultTrait}; + use evm::errors::EVMError; + use evm::precompiles::EcAdd; + use evm::precompiles::EcMul; + use evm::precompiles::Sha256; + use utils::traits::integer::U256Trait; + + + #[starknet::embeddable] + pub impl Precompiles of super::IPrecompiles { + fn exec_precompile( + self: @TContractState, address: felt252, data: Span + ) -> (bool, u64, Span) { + let result = match address { + 0 => Result::Err(EVMError::NotImplemented), + 1 => Result::Err(EVMError::NotImplemented), + 2 => Sha256::exec(data), + 3 | 4 => Result::Err(EVMError::NotImplemented), + 5 => Result::Err(EVMError::NotImplemented), + 6 => EcAdd::exec(data), + 7 => EcMul::exec(data), + _ => Result::Err(EVMError::NotImplemented), + }; + match result { + Result::Ok((gas, output)) => (true, gas, output), + Result::Err(_) => (false, 0, [].span()) + } + } + } + + #[starknet::embeddable] + pub impl Helpers of super::IHelpers { + fn get_block_hash(self: @TContractState, block_number: u64) -> felt252 { + starknet::syscalls::get_block_hash_syscall(block_number).unwrap_syscall() + } + + fn keccak( + self: @TContractState, + mut words: Array, + last_input_word: u64, + last_input_num_bytes: usize + ) -> u256 { + cairo_keccak(ref words, last_input_word, last_input_num_bytes).reverse_endianness() + } + + fn compute_sha256_u32_array( + self: @TContractState, + input: Array, + last_input_word: u32, + last_input_num_bytes: u32 + ) -> [ + u32 + ; 8] { + core::sha256::compute_sha256_u32_array(input, last_input_word, last_input_num_bytes) + } + + // DEPRECATED + fn verify_eth_signature( + self: @TContractState, msg_hash: u256, signature: Signature, eth_address: EthAddress + ) { + verify_eth_signature(msg_hash, signature, eth_address); + } + + fn recover_eth_address( + self: @TContractState, msg_hash: u256, signature: Signature + ) -> (bool, EthAddress) { + match recover_public_key::(:msg_hash, :signature) { + Option::Some(public_key_point) => { + let (x, y) = public_key_point.get_coordinates().unwrap_syscall(); + if (x == 0 && y == 0) { + return (false, Zero::zero()); + } + // Keccak output is little endian. + let point_hash_le = keccak_u256s_be_inputs([x, y].span()); + let point_hash = u256 { + low: core::integer::u128_byte_reverse(point_hash_le.high), + high: core::integer::u128_byte_reverse(point_hash_le.low) + }; + + (true, point_hash.into()) + }, + Option::None => (false, Zero::zero()) + } + } + + fn verify_signature_secp256r1( + self: @TContractState, msg_hash: u256, r: u256, s: u256, x: u256, y: u256 + ) -> bool { + let maybe_public_key: Option = Secp256Trait::secp256_ec_new_syscall( + x, y + ) + .unwrap_syscall(); + let public_key = match maybe_public_key { + Option::Some(public_key) => public_key, + Option::None => { return false; } + }; + + return is_valid_signature(msg_hash, r, s, public_key); + } + } +} + +#[starknet::contract] +pub mod Cairo1Helpers { + #[storage] + struct Storage {} + + #[abi(embed_v0)] + pub impl Precompiles = super::embeddable_impls::Precompiles; + + #[abi(embed_v0)] + pub impl Helpers = super::embeddable_impls::Helpers; +} diff --git a/kakarot-ssj/crates/contracts/src/components.cairo b/kakarot-ssj/crates/contracts/src/components.cairo new file mode 100644 index 000000000..5ba62d80e --- /dev/null +++ b/kakarot-ssj/crates/contracts/src/components.cairo @@ -0,0 +1,2 @@ +pub mod ownable; +pub mod upgradeable; diff --git a/kakarot-ssj/crates/contracts/src/components/ownable.cairo b/kakarot-ssj/crates/contracts/src/components/ownable.cairo new file mode 100644 index 000000000..fc8f88db7 --- /dev/null +++ b/kakarot-ssj/crates/contracts/src/components/ownable.cairo @@ -0,0 +1,91 @@ +// This implementation of an Ownable is inspired by Openzeppelin's work on +// OpenZeppelin Contracts for Cairo available here: https://github.com/OpenZeppelin/cairo-contracts + +use core::starknet::ContractAddress; +pub mod Errors { + pub const NOT_OWNER: felt252 = 'Caller is not the owner'; + pub const ZERO_ADDRESS_CALLER: felt252 = 'Caller is the zero address'; + pub const ZERO_ADDRESS_OWNER: felt252 = 'New owner is the zero address'; +} + +#[starknet::interface] +pub trait IOwnable { + fn owner(self: @TContractState) -> ContractAddress; + fn transfer_ownership(ref self: TContractState, new_owner: ContractAddress); + fn renounce_ownership(ref self: TContractState); +} + +#[starknet::component] +pub mod ownable_component { + use core::num::traits::Zero; + use core::starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; + use core::starknet::{get_caller_address, ContractAddress}; + use super::Errors; + + #[storage] + pub struct Storage { + pub Ownable_owner: ContractAddress + } + + #[event] + #[derive(Drop, starknet::Event)] + pub enum Event { + OwnershipTransferred: OwnershipTransferred + } + + #[derive(Drop, starknet::Event)] + pub struct OwnershipTransferred { + pub previous_owner: ContractAddress, + pub new_owner: ContractAddress, + } + + + #[embeddable_as(Ownable)] + pub impl OwnableImpl< + TContractState, +HasComponent + > of super::IOwnable> { + fn owner(self: @ComponentState) -> ContractAddress { + self.Ownable_owner.read() + } + + fn transfer_ownership( + ref self: ComponentState, new_owner: ContractAddress + ) { + assert(!new_owner.is_zero(), Errors::ZERO_ADDRESS_OWNER); + self.assert_only_owner(); + self._transfer_ownership(new_owner); + } + + fn renounce_ownership(ref self: ComponentState) { + self.assert_only_owner(); + self._transfer_ownership(Zero::zero()); + } + } + + #[generate_trait] + pub impl InternalImpl< + TContractState, +HasComponent + > of InternalTrait { + fn initializer(ref self: ComponentState, owner: ContractAddress) { + self._transfer_ownership(owner); + } + + fn assert_only_owner(self: @ComponentState) { + let owner: ContractAddress = self.Ownable_owner.read(); + let caller: ContractAddress = get_caller_address(); + assert(!caller.is_zero(), Errors::ZERO_ADDRESS_CALLER); + assert(caller == owner, Errors::NOT_OWNER); + } + + fn _transfer_ownership( + ref self: ComponentState, new_owner: ContractAddress + ) { + let previous_owner: ContractAddress = self.Ownable_owner.read(); + self.Ownable_owner.write(new_owner); + self + .emit( + OwnershipTransferred { previous_owner: previous_owner, new_owner: new_owner } + ); + } + } +} diff --git a/kakarot-ssj/crates/contracts/src/components/upgradeable.cairo b/kakarot-ssj/crates/contracts/src/components/upgradeable.cairo new file mode 100644 index 000000000..67c441ef5 --- /dev/null +++ b/kakarot-ssj/crates/contracts/src/components/upgradeable.cairo @@ -0,0 +1,40 @@ +use core::starknet::ClassHash; + +#[starknet::interface] +pub trait IUpgradeable { + fn upgrade_contract(ref self: TContractState, new_class_hash: ClassHash); +} + + +#[starknet::component] +pub mod upgradeable_component { + use core::starknet::ClassHash; + use core::starknet::syscalls::{replace_class_syscall}; + + + #[storage] + pub struct Storage {} + + #[event] + #[derive(Drop, starknet::Event)] + pub enum Event { + ContractUpgraded: ContractUpgraded + } + + #[derive(Drop, starknet::Event)] + struct ContractUpgraded { + new_class_hash: ClassHash + } + + #[embeddable_as(Upgradeable)] + pub impl UpgradeableImpl< + TContractState, +HasComponent + > of super::IUpgradeable> { + fn upgrade_contract( + ref self: ComponentState, new_class_hash: starknet::ClassHash + ) { + replace_class_syscall(new_class_hash).expect('replace class failed'); + self.emit(ContractUpgraded { new_class_hash: new_class_hash }); + } + } +} diff --git a/kakarot-ssj/crates/contracts/src/errors.cairo b/kakarot-ssj/crates/contracts/src/errors.cairo new file mode 100644 index 000000000..22b37eeee --- /dev/null +++ b/kakarot-ssj/crates/contracts/src/errors.cairo @@ -0,0 +1,49 @@ +pub const BYTECODE_READ_ERROR: felt252 = 'CA: Bytecode Read Error'; +pub const BYTECODE_WRITE_ERROR: felt252 = 'CA: Bytecode Write Error'; + +pub const STORAGE_READ_ERROR: felt252 = 'CA: Storage Read Error'; +pub const STORAGE_WRITE_ERROR: felt252 = 'CA: Storage Write Error'; + +pub const NONCE_READ_ERROR: felt252 = 'CA: Nonce Read Error'; +pub const NONCE_WRITE_ERROR: felt252 = 'CA: Nonce Write Error'; + +pub const KAKAROT_VALIDATION_FAILED: [ + u8 + ; 30] = [ + 'K', + 'a', + 'k', + 'a', + 'r', + 'o', + 't', + ':', + ' ', + 'e', + 't', + 'h', + ' ', + 'v', + 'a', + 'l', + 'i', + 'd', + 'a', + 't', + 'i', + 'o', + 'n', + ' ', + 'f', + 'a', + 'i', + 'l', + 'e', + 'd' +]; + +pub const KAKAROT_REENTRANCY: [ + felt252 + ; 19] = [ + 'K', 'a', 'k', 'a', 'r', 'o', 't', ':', ' ', 'r', 'e', 'e', 'n', 't', 'r', 'a', 'n', 'c', 'y' +]; diff --git a/kakarot-ssj/crates/contracts/src/kakarot_core.cairo b/kakarot-ssj/crates/contracts/src/kakarot_core.cairo new file mode 100644 index 000000000..0989f1244 --- /dev/null +++ b/kakarot-ssj/crates/contracts/src/kakarot_core.cairo @@ -0,0 +1,8 @@ +pub mod eth_rpc; +pub mod interface; +mod kakarot; +pub use interface::{ + IKakarotCore, IKakarotCoreDispatcher, IKakarotCoreDispatcherTrait, + IExtendedKakarotCoreDispatcher, IExtendedKakarotCoreDispatcherTrait +}; +pub use kakarot::KakarotCore; diff --git a/kakarot-ssj/crates/contracts/src/kakarot_core/eth_rpc.cairo b/kakarot-ssj/crates/contracts/src/kakarot_core/eth_rpc.cairo new file mode 100644 index 000000000..c824fb4f6 --- /dev/null +++ b/kakarot-ssj/crates/contracts/src/kakarot_core/eth_rpc.cairo @@ -0,0 +1,305 @@ +use core::num::traits::Zero; +use core::starknet::get_tx_info; +use core::starknet::{EthAddress, get_caller_address}; +use crate::account_contract::{IAccountDispatcher, IAccountDispatcherTrait}; +use crate::kakarot_core::interface::IKakarotCore; +use crate::kakarot_core::kakarot::{KakarotCore, KakarotCore::{KakarotCoreState}}; +use evm::backend::starknet_backend; +use evm::backend::validation::validate_eth_tx; +use evm::model::{TransactionResult, Address}; +use evm::{EVMTrait}; +use openzeppelin::token::erc20::interface::{IERC20CamelDispatcher, IERC20CamelDispatcherTrait}; +use utils::constants::POW_2_53; +use utils::eth_transaction::transaction::Transaction; + +#[starknet::interface] +pub trait IEthRPC { + /// Returns the balance of the specified address. + /// + /// This is a view-only function that doesn't modify the state. + /// + /// # Arguments + /// + /// * `address` - The Ethereum address to get the balance from + /// + /// # Returns + /// + /// The balance of the address as a u256 + fn eth_get_balance(self: @T, address: EthAddress) -> u256; + + /// Returns the number of transactions sent from the specified address. + /// + /// This is a view-only function that doesn't modify the state. + /// + /// # Arguments + /// + /// * `address` - The Ethereum address to get the transaction count from + /// + /// # Returns + /// + /// The transaction count of the address as a u64 + fn eth_get_transaction_count(self: @T, address: EthAddress) -> u64; + + /// Returns the current chain ID. + /// + /// This is a view-only function that doesn't modify the state. + /// + /// # Returns + /// + /// The chain ID as a u64 + fn eth_chain_id(self: @T) -> u64; + + /// Executes a new message call immediately without creating a transaction on the block chain. + /// + /// This is a view-only function that doesn't modify the state. + /// + /// # Arguments + /// + /// * `origin` - The address the transaction is sent from + /// * `tx` - The transaction object + /// + /// # Returns + /// + /// A tuple containing: + /// * A boolean indicating success + /// * The return data as a Span + /// * The amount of gas used as a u64 + fn eth_call(self: @T, origin: EthAddress, tx: Transaction) -> (bool, Span, u64); + + /// Generates and returns an estimate of how much gas is necessary to allow the transaction to + /// complete. + /// + /// This is a view-only function that doesn't modify the state. + /// + /// # Arguments + /// + /// * `origin` - The address the transaction is sent from + /// * `tx` - The transaction object + /// + /// # Returns + /// + /// A tuple containing: + /// * A boolean indicating success + /// * The return data as a Span + /// * The estimated gas as a u64 + fn eth_estimate_gas(self: @T, origin: EthAddress, tx: Transaction) -> (bool, Span, u64); + + //TODO: make this an internal function. The account contract should call + //eth_send_raw_transaction. + /// Executes a transaction and possibly modifies the state. + /// + /// # Arguments + /// + /// * `tx` - The transaction object + /// + /// # Returns + /// + /// A tuple containing: + /// * A boolean indicating success + /// * The return data as a Span + /// * The amount of gas used as a u64 + fn eth_send_transaction(ref self: T, tx: Transaction) -> (bool, Span, u64); + + /// Executes an unsigned transaction. + /// + /// This is a modified version of the eth_sendRawTransaction function. + /// Signature validation should be done before calling this function. + /// + /// # Arguments + /// + /// * `tx_data` - The unsigned transaction data as a Span + /// + /// # Returns + /// + /// A tuple containing: + /// * A boolean indicating success + /// * The return data as a Span + /// * The amount of gas used as a u64 + fn eth_send_raw_unsigned_tx(ref self: T, tx_data: Span) -> (bool, Span, u64); +} + + +#[starknet::embeddable] +pub impl EthRPC< + TContractState, impl KakarotState: KakarotCoreState, +Drop +> of IEthRPC { + fn eth_get_balance(self: @TContractState, address: EthAddress) -> u256 { + let kakarot_state = KakarotState::get_state(); + let starknet_address = kakarot_state.get_starknet_address(address); + let native_token_address = kakarot_state.get_native_token(); + let native_token = IERC20CamelDispatcher { contract_address: native_token_address }; + native_token.balanceOf(starknet_address) + } + + fn eth_get_transaction_count(self: @TContractState, address: EthAddress) -> u64 { + let kakarot_state = KakarotState::get_state(); + let starknet_address = kakarot_state.get_starknet_address(address); + println!("starknet_address: {:?}", starknet_address); + let account = IAccountDispatcher { contract_address: starknet_address }; + let nonce = account.get_nonce(); + nonce + } + + fn eth_chain_id(self: @TContractState) -> u64 { + let tx_info = get_tx_info().unbox(); + let tx_chain_id: u64 = tx_info.chain_id.try_into().unwrap(); + tx_chain_id % POW_2_53.try_into().unwrap() + } + + fn eth_call( + self: @TContractState, origin: EthAddress, tx: Transaction + ) -> (bool, Span, u64) { + let mut kakarot_state = KakarotState::get_state(); + if !is_view(@kakarot_state) { + core::panic_with_felt252('fn must be called, not invoked'); + }; + + let origin = Address { + evm: origin, starknet: kakarot_state.compute_starknet_address(origin) + }; + + let TransactionResult { success, return_data, gas_used, state: _state } = + EVMTrait::process_transaction( + ref kakarot_state, origin, tx, 0 + ); + + (success, return_data, gas_used) + } + + fn eth_estimate_gas( + self: @TContractState, origin: EthAddress, tx: Transaction + ) -> (bool, Span, u64) { + panic!("unimplemented") + } + + //TODO: make this one internal, and the eth_send_raw_unsigned_tx one public + fn eth_send_transaction( + ref self: TContractState, mut tx: Transaction + ) -> (bool, Span, u64) { + let mut kakarot_state = KakarotState::get_state(); + let intrinsic_gas = validate_eth_tx(@kakarot_state, tx); + + let starknet_caller_address = get_caller_address(); + let account = IAccountDispatcher { contract_address: starknet_caller_address }; + let origin = Address { evm: account.get_evm_address(), starknet: starknet_caller_address }; + + let TransactionResult { success, return_data, gas_used, mut state } = + EVMTrait::process_transaction( + ref kakarot_state, origin, tx, intrinsic_gas + ); + starknet_backend::commit(ref state).expect('Committing state failed'); + (success, return_data, gas_used) + } + + fn eth_send_raw_unsigned_tx( + ref self: TContractState, tx_data: Span + ) -> (bool, Span, u64) { + panic!("unimplemented") + } +} + +trait IEthRPCInternal { + fn eth_send_transaction( + ref self: T, origin: EthAddress, tx: Transaction + ) -> (bool, Span, u64); +} + +impl EthRPCInternalImpl> of IEthRPCInternal { + fn eth_send_transaction( + ref self: TContractState, origin: EthAddress, tx: Transaction + ) -> (bool, Span, u64) { + panic!("unimplemented") + } +} + +fn is_view(self: @KakarotCore::ContractState) -> bool { + let tx_info = get_tx_info().unbox(); + + // If the account that originated the transaction is not zero, this means we + // are in an invoke transaction instead of a call; therefore, `eth_call` is being + // wrongly called For invoke transactions, `eth_send_transaction` must be used + if !tx_info.account_contract_address.is_zero() { + return false; + } + true +} + +#[cfg(test)] +mod tests { + use crate::kakarot_core::KakarotCore; + use crate::kakarot_core::eth_rpc::IEthRPC; + use crate::kakarot_core::interface::IExtendedKakarotCoreDispatcherTrait; + use crate::test_utils::{setup_contracts_for_testing, fund_account_with_native_token}; + use evm::test_utils::{sequencer_evm_address, evm_address, uninitialized_account}; + use snforge_std::{ + start_mock_call, start_cheat_chain_id_global, stop_cheat_chain_id_global, test_address + }; + use utils::constants::POW_2_53; + use utils::helpers::compute_starknet_address; + + fn set_up() -> KakarotCore::ContractState { + // Define the kakarot state to access contract functions + let kakarot_state = KakarotCore::unsafe_new_contract_state(); + + kakarot_state + } + + fn tear_down() { + stop_cheat_chain_id_global(); + } + + #[test] + fn test_eth_get_transaction_count() { + let kakarot_state = set_up(); + // Deployed eoa should return a zero nonce + let starknet_address = compute_starknet_address( + test_address(), + evm_address(), + 0.try_into().unwrap() // Using 0 as the kakarot storage is empty + ); + start_mock_call::(starknet_address, selector!("get_nonce"), 1); + assert_eq!(kakarot_state.eth_get_transaction_count(evm_address()), 1); + } + + #[test] + fn test_eth_get_balance() { + let (native_token, kakarot_core) = setup_contracts_for_testing(); + // Uninitialized accounts should return a zero balance + assert_eq!(kakarot_core.eth_get_balance(evm_address()), 0); + let sequencer_starknet_address = kakarot_core.get_starknet_address(sequencer_evm_address()); + // Fund an initialized account and make sure the balance is correct + fund_account_with_native_token(sequencer_starknet_address, native_token, 0x1); + assert_eq!(kakarot_core.eth_get_balance(sequencer_evm_address()), 0x1); + } + + #[test] + fn test_eth_chain_id_returns_input_when_less_than_pow_2_53() { + let kakarot_state = KakarotCore::unsafe_new_contract_state(); + // Convert POW_2_53 - 1 to u64 since POW_2_53 is defined as u128 + let chain_id: u64 = (POW_2_53 - 1).try_into().unwrap(); + start_cheat_chain_id_global(chain_id.into()); + assert_eq!( + kakarot_state.eth_chain_id(), + chain_id, + "Should return original chain ID when below 2^53" + ); + tear_down(); + } + + #[test] + fn test_eth_chain_id_returns_modulo_when_greater_than_or_equal_to_pow_2_53() { + // Test with a value equal to 2^53 + let kakarot_state = set_up(); + let chain_id: u64 = POW_2_53.try_into().unwrap(); + start_cheat_chain_id_global(chain_id.into()); + assert_eq!(kakarot_state.eth_chain_id(), 0, "Should return 0 when chain ID is 2^53"); + + // Test with a value greater than 2^53 + let chain_id: u64 = (POW_2_53 + 53).try_into().unwrap(); + start_cheat_chain_id_global(chain_id.into()); + assert_eq!( + kakarot_state.eth_chain_id(), 53, "Should return correct value after modulo operation" + ); + tear_down(); + } +} diff --git a/kakarot-ssj/crates/contracts/src/kakarot_core/interface.cairo b/kakarot-ssj/crates/contracts/src/kakarot_core/interface.cairo new file mode 100644 index 000000000..aa5e8e9fa --- /dev/null +++ b/kakarot-ssj/crates/contracts/src/kakarot_core/interface.cairo @@ -0,0 +1,122 @@ +use core::starknet::{ContractAddress, EthAddress, ClassHash}; +use utils::eth_transaction::transaction::Transaction; + +#[starknet::interface] +pub trait IKakarotCore { + /// Sets the native token, this token will be considered the native coin in the Ethereum sense + fn set_native_token(ref self: TContractState, native_token: ContractAddress); + + /// Gets the native token used by the Kakarot smart contract + fn get_native_token(self: @TContractState) -> ContractAddress; + + /// Deterministically computes a Starknet address for an given EVM address + /// The address is computed as the Starknet address corresponding to the deployment of an EOA, + /// Using its EVM address as salt, and KakarotCore as deployer. + fn compute_starknet_address(self: @TContractState, evm_address: EthAddress) -> ContractAddress; + + /// Checks into KakarotCore storage if an EOA or a CA has been deployed for + /// a particular EVM address and. If so returns its corresponding address, + /// otherwise returns 0 + fn address_registry(self: @TContractState, evm_address: EthAddress) -> ContractAddress; + + /// Deploys an EOA for a particular EVM address + fn deploy_externally_owned_account( + ref self: TContractState, evm_address: EthAddress + ) -> ContractAddress; + + /// Upgrade the KakarotCore smart contract + /// Using replace_class_syscall + fn upgrade(ref self: TContractState, new_class_hash: ClassHash); + + // Setter for the Account Class Hash + fn set_account_contract_class_hash(ref self: TContractState, new_class_hash: ClassHash); + fn get_account_contract_class_hash(self: @TContractState) -> ClassHash; + + // Getter for the Generic Account Class + fn uninitialized_account_class_hash(self: @TContractState) -> ClassHash; + // Setter for the Generic Account Class + fn set_account_class_hash(ref self: TContractState, new_class_hash: ClassHash); + + fn register_account(ref self: TContractState, evm_address: EthAddress); + + // Getter for the Block Gas Limit + fn get_block_gas_limit(self: @TContractState) -> u64; + + // Getter for the Base Fee + fn get_base_fee(self: @TContractState) -> u64; + /// Setter for the base fee + fn set_base_fee(ref self: TContractState, base_fee: u64); + + // Getter for the Starknet Address + fn get_starknet_address(self: @TContractState, evm_address: EthAddress) -> ContractAddress; +} + +#[starknet::interface] +pub trait IExtendedKakarotCore { + /// Sets the native token, this token will be considered the native coin in the Ethereum sense + fn set_native_token(ref self: TContractState, native_token: ContractAddress); + + /// Gets the native token used by the Kakarot smart contract + fn get_native_token(self: @TContractState) -> ContractAddress; + + /// Deterministically computes a Starknet address for an given EVM address + /// The address is computed as the Starknet address corresponding to the deployment of an EOA, + /// Using its EVM address as salt, and KakarotCore as deployer. + fn compute_starknet_address(self: @TContractState, evm_address: EthAddress) -> ContractAddress; + + /// Checks into KakarotCore storage if an EOA or a CA has been deployed for + /// a particular EVM address and. If so returns its corresponding address, + /// otherwise returns 0 + fn address_registry(self: @TContractState, evm_address: EthAddress) -> ContractAddress; + + /// Deploys an EOA for a particular EVM address + fn deploy_externally_owned_account( + ref self: TContractState, evm_address: EthAddress + ) -> ContractAddress; + + /// Returns the balance of the specified address. + fn eth_get_balance(self: @TContractState, address: EthAddress) -> u256; + + /// View entrypoint into the EVM + /// Performs view calls into the blockchain + /// It cannot modify the state of the chain + fn eth_call( + self: @TContractState, origin: EthAddress, tx: Transaction + ) -> (bool, Span, u64); + + /// Transaction entrypoint into the EVM + /// Executes an EVM transaction and possibly modifies the state + fn eth_send_transaction(ref self: TContractState, tx: Transaction) -> (bool, Span, u64); + + // Returns the transaction count (nonce) of the specified address + fn eth_get_transaction_count(self: @TContractState, address: EthAddress) -> u64; + + /// Upgrade the KakarotCore smart contract + /// Using replace_class_syscall + fn upgrade(ref self: TContractState, new_class_hash: ClassHash); + + // Setter for the Account Class Hash + fn set_account_contract_class_hash(ref self: TContractState, new_class_hash: ClassHash); + fn get_account_contract_class_hash(self: @TContractState) -> ClassHash; + + // Getter for the Generic Account Class + fn uninitialized_account_class_hash(self: @TContractState) -> ClassHash; + // Setter for the Generic Account Class + fn set_account_class_hash(ref self: TContractState, new_class_hash: ClassHash); + + fn register_account(ref self: TContractState, evm_address: EthAddress); + + // Getter for the Block Gas Limit + fn get_block_gas_limit(self: @TContractState) -> u64; + // Getter for the Base Fee + fn get_base_fee(self: @TContractState) -> u64; + /// Setter for the base fee + fn set_base_fee(ref self: TContractState, base_fee: u64); + + // Getter for the Starknet Address + fn get_starknet_address(self: @TContractState, evm_address: EthAddress) -> ContractAddress; + + fn owner(self: @TContractState) -> ContractAddress; + fn transfer_ownership(ref self: TContractState, new_owner: ContractAddress); + fn renounce_ownership(ref self: TContractState); +} diff --git a/kakarot-ssj/crates/contracts/src/kakarot_core/kakarot.cairo b/kakarot-ssj/crates/contracts/src/kakarot_core/kakarot.cairo new file mode 100644 index 000000000..fec55b8a0 --- /dev/null +++ b/kakarot-ssj/crates/contracts/src/kakarot_core/kakarot.cairo @@ -0,0 +1,230 @@ +const INVOKE_ETH_CALL_FORBIDDEN: felt252 = 'KKT: Cannot invoke eth_call'; + + +#[starknet::contract] +pub mod KakarotCore { + use core::num::traits::Zero; + use core::starknet::event::EventEmitter; + use core::starknet::storage::{ + Map, StorageMapReadAccess, StorageMapWriteAccess, StoragePointerReadAccess, + StoragePointerWriteAccess + }; + use core::starknet::{EthAddress, ContractAddress, ClassHash, get_contract_address}; + use crate::components::ownable::{ownable_component}; + use crate::components::upgradeable::{IUpgradeable, upgradeable_component}; + use crate::kakarot_core::eth_rpc; + use crate::kakarot_core::interface::IKakarotCore; + use evm::backend::starknet_backend; + use utils::helpers::compute_starknet_address; + + component!(path: ownable_component, storage: ownable, event: OwnableEvent); + component!(path: upgradeable_component, storage: upgradeable, event: UpgradeableEvent); + + /// STORAGE /// + + #[storage] + pub struct Storage { + pub Kakarot_evm_to_starknet_address: Map::, + pub Kakarot_uninitialized_account_class_hash: ClassHash, + pub Kakarot_account_contract_class_hash: ClassHash, + pub Kakarot_native_token_address: ContractAddress, + pub Kakarot_coinbase: EthAddress, + pub Kakarot_base_fee: u64, + pub Kakarot_prev_randao: u256, + pub Kakarot_block_gas_limit: u64, + // Components + #[substorage(v0)] + ownable: ownable_component::Storage, + #[substorage(v0)] + upgradeable: upgradeable_component::Storage, + } + + /// EVENTS /// + + #[event] + #[derive(Drop, starknet::Event)] + pub enum Event { + OwnableEvent: ownable_component::Event, + UpgradeableEvent: upgradeable_component::Event, + AccountDeployed: AccountDeployed, + AccountClassHashChange: AccountClassHashChange, + EOAClassHashChange: EOAClassHashChange, + } + + #[derive(Copy, Drop, starknet::Event)] + pub struct AccountDeployed { + #[key] + pub evm_address: EthAddress, + #[key] + pub starknet_address: ContractAddress, + } + + #[derive(Copy, Drop, starknet::Event)] + pub struct AccountClassHashChange { + pub old_class_hash: ClassHash, + pub new_class_hash: ClassHash, + } + + + #[derive(Copy, Drop, starknet::Event)] + pub struct EOAClassHashChange { + pub old_class_hash: ClassHash, + pub new_class_hash: ClassHash, + } + + + /// Trait bounds allowing embedded implementations to be specific to this contract + pub trait KakarotCoreState { + fn get_state() -> ContractState; + } + + impl _KakarotCoreState of KakarotCoreState { + fn get_state() -> ContractState { + unsafe_new_contract_state() + } + } + + /// CONSTRUCTOR /// + + #[constructor] + fn constructor( + ref self: ContractState, + owner: ContractAddress, + native_token: ContractAddress, + account_contract_class_hash: ClassHash, + uninitialized_account_class_hash: ClassHash, + coinbase: EthAddress, + block_gas_limit: u64, + mut eoas_to_deploy: Span, + ) { + self.ownable.initializer(owner); + self.Kakarot_native_token_address.write(native_token); + self.Kakarot_account_contract_class_hash.write(account_contract_class_hash); + self.Kakarot_uninitialized_account_class_hash.write(uninitialized_account_class_hash); + self.Kakarot_coinbase.write(coinbase); + self.Kakarot_block_gas_limit.write(block_gas_limit); + for eoa_address in eoas_to_deploy { + self.deploy_externally_owned_account(*eoa_address); + }; + } + + /// PUBLIC-FACING FUNCTIONS /// + + // Public-facing "ownable" functions + #[abi(embed_v0)] + impl OwnableImpl = ownable_component::Ownable; + + /// Public-facing "ethereum" functions + /// Used to make EVM-related actions through Kakarot. + #[abi(embed_v0)] + pub impl EthRPCImpl = eth_rpc::EthRPC; + + + /// Public-facing "kakarot" functions + /// Used to interact with the Kakarot contract outside of EVM-related actions. + #[abi(embed_v0)] + pub impl KakarotCoreImpl of IKakarotCore { + fn set_native_token(ref self: ContractState, native_token: ContractAddress) { + self.ownable.assert_only_owner(); + self.Kakarot_native_token_address.write(native_token); + } + + fn get_native_token(self: @ContractState) -> ContractAddress { + self.Kakarot_native_token_address.read() + } + + fn compute_starknet_address( + self: @ContractState, evm_address: EthAddress + ) -> ContractAddress { + let kakarot_address = get_contract_address(); + compute_starknet_address( + kakarot_address, evm_address, self.Kakarot_uninitialized_account_class_hash.read() + ) + } + + fn address_registry(self: @ContractState, evm_address: EthAddress) -> ContractAddress { + self.Kakarot_evm_to_starknet_address.read(evm_address) + } + + fn deploy_externally_owned_account( + ref self: ContractState, evm_address: EthAddress + ) -> ContractAddress { + starknet_backend::deploy(evm_address).expect('EOA Deployment failed').starknet + } + + fn upgrade(ref self: ContractState, new_class_hash: ClassHash) { + self.ownable.assert_only_owner(); + self.upgradeable.upgrade_contract(new_class_hash); + } + + fn get_account_contract_class_hash(self: @ContractState) -> ClassHash { + self.Kakarot_account_contract_class_hash.read() + } + + fn set_account_contract_class_hash(ref self: ContractState, new_class_hash: ClassHash) { + self.ownable.assert_only_owner(); + let old_class_hash = self.Kakarot_account_contract_class_hash.read(); + self.Kakarot_account_contract_class_hash.write(new_class_hash); + self.emit(EOAClassHashChange { old_class_hash, new_class_hash }); + } + + fn uninitialized_account_class_hash(self: @ContractState) -> ClassHash { + self.Kakarot_uninitialized_account_class_hash.read() + } + + fn set_account_class_hash(ref self: ContractState, new_class_hash: ClassHash) { + self.ownable.assert_only_owner(); + let old_class_hash = self.Kakarot_uninitialized_account_class_hash.read(); + self.Kakarot_uninitialized_account_class_hash.write(new_class_hash); + self.emit(AccountClassHashChange { old_class_hash, new_class_hash }); + } + + fn register_account(ref self: ContractState, evm_address: EthAddress) { + let existing_address = self.Kakarot_evm_to_starknet_address.read(evm_address); + assert(existing_address.is_zero(), 'Account already exists'); + + let starknet_address = self.compute_starknet_address(evm_address); + //TODO: enable this assertion. Will require changing test runner to snfoundry + // assert!(starknet_address == caller, "Account must be registered by the caller"); + + self.Kakarot_evm_to_starknet_address.write(evm_address, starknet_address); + self.emit(AccountDeployed { evm_address, starknet_address }); + } + + fn get_block_gas_limit(self: @ContractState) -> u64 { + self.Kakarot_block_gas_limit.read() + } + + fn set_base_fee(ref self: ContractState, base_fee: u64) { + self.ownable.assert_only_owner(); + self.Kakarot_base_fee.write(base_fee); + } + + fn get_base_fee(self: @ContractState) -> u64 { + self.Kakarot_base_fee.read() + } + + // @notice Returns the corresponding Starknet address for a given EVM address. + // @dev Returns the registered address if there is one, otherwise returns the deterministic + // address got when Kakarot deploys an account. + // @param evm_address The EVM address to transform to a starknet address + // @return starknet_address The Starknet Account Contract address + fn get_starknet_address(self: @ContractState, evm_address: EthAddress) -> ContractAddress { + let registered_starknet_address = self.address_registry(evm_address); + if (!registered_starknet_address.is_zero()) { + return registered_starknet_address; + } + + let computed_starknet_address = self.compute_starknet_address(evm_address); + return computed_starknet_address; + } + } + + /// INTERNAL-FACING FUNCTIONS /// + + // Internal-facing "ownable" functions + impl OwnableInternalImpl = ownable_component::InternalImpl; + + // Internal-facing "upgradeable" functions + impl UpgradeableImpl = upgradeable_component::Upgradeable; +} diff --git a/kakarot-ssj/crates/contracts/src/lib.cairo b/kakarot-ssj/crates/contracts/src/lib.cairo new file mode 100644 index 000000000..995015b10 --- /dev/null +++ b/kakarot-ssj/crates/contracts/src/lib.cairo @@ -0,0 +1,37 @@ +pub mod account_contract; +pub mod cairo1_helpers; +pub mod components; + +pub mod errors; + +// Kakarot smart contract +pub mod kakarot_core; +pub mod storage; + +#[cfg(target: 'test')] +pub mod test_data; + +#[cfg(target: 'test')] +pub mod test_utils; + +// Account transparent proxy +mod uninitialized_account; +pub use account_contract::{AccountContract, IAccount, IAccountDispatcher, IAccountDispatcherTrait}; +pub use cairo1_helpers::{ + Cairo1Helpers, IPrecompiles, IHelpers, IPrecompilesDispatcher, IHelpersDispatcher, + IPrecompilesDispatcherTrait, IHelpersDispatcherTrait +}; +pub use kakarot_core::{ + KakarotCore, IKakarotCore, IKakarotCoreDispatcher, IKakarotCoreDispatcherTrait, + IExtendedKakarotCoreDispatcher, IExtendedKakarotCoreDispatcherTrait +}; +pub use uninitialized_account::{UninitializedAccount}; + +//TODO: hide this behind a feature flag +pub mod test_contracts { + pub mod test_upgradeable; +} + +pub mod mocks { + pub mod cairo1_helpers_fixture; +} diff --git a/kakarot-ssj/crates/contracts/src/mocks/cairo1_helpers_fixture.cairo b/kakarot-ssj/crates/contracts/src/mocks/cairo1_helpers_fixture.cairo new file mode 100644 index 000000000..1a00d76b5 --- /dev/null +++ b/kakarot-ssj/crates/contracts/src/mocks/cairo1_helpers_fixture.cairo @@ -0,0 +1,15 @@ +#[starknet::contract] +pub mod Cairo1HelpersFixture { + use crate::cairo1_helpers::embeddable_impls; + + const VERSION: felt252 = 2; + + #[storage] + struct Storage {} + + #[abi(embed_v0)] + impl Precompiles = embeddable_impls::Precompiles; + + #[abi(embed_v0)] + impl Helpers = embeddable_impls::Helpers; +} diff --git a/kakarot-ssj/crates/contracts/src/storage.cairo b/kakarot-ssj/crates/contracts/src/storage.cairo new file mode 100644 index 000000000..3f047b1a8 --- /dev/null +++ b/kakarot-ssj/crates/contracts/src/storage.cairo @@ -0,0 +1,199 @@ +use core::ops::DerefMut; +use core::ops::SnapshotDeref; +use core::starknet::storage::{ + StoragePointerReadAccess, StoragePointerWriteAccess, StorageTrait, StorageTraitMut +}; +use core::starknet::storage_access::StorageBaseAddress; +use core::starknet::syscalls::{storage_read_syscall, storage_write_syscall}; +use core::starknet::{SyscallResult, Store, StorageAddress}; +use crate::account_contract::AccountContract::unsafe_new_contract_state as account_contract_state; +use utils::utils::{pack_bytes, load_packed_bytes}; + +/// A wrapper type for the bytecode storage. Packing / unpacking is done transparently inside the +/// `read` and `write` methods of `Store`. +#[derive(Copy, Drop)] +pub struct StorageBytecode { + pub bytecode: Span +} + +const BYTES_PER_FELT: NonZero = 31; + +/// An implementation of the `Store` trait for our specific `StorageBytecode` type. +/// The packing-unpacking is done inside the `read` and `write` methods, thus transparent to the +/// user. +/// The bytecode is stored sequentially, starting from storage address 0, for compatibility purposes +/// with KakarotZero. +/// The bytecode length is stored in the `Account_bytecode_len` storage variable, which is accessed +/// by the `read` and `write` methods. +impl StoreBytecode of Store { + /// Side effect: reads the bytecode len from the Account_bytecode_len storage variable + fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult { + // Read the bytecode len from the storage of the current contract + let state = account_contract_state(); + let bytecode_len: u32 = state.snapshot_deref().storage().Account_bytecode_len.read(); + let (chunks_count, _remainder) = DivRem::div_rem(bytecode_len, BYTES_PER_FELT); + + // Read the bytecode from the storage of the current contract, starting from address 0. + //TODO(opti): unpack chunks directly instead of reading them one by one and unpacking them + // afterwards. + let base: felt252 = 0; + let mut packed_bytecode = array![]; + for i in 0 + ..chunks_count + + 1 { + let storage_address: StorageAddress = (base + i.into()).try_into().unwrap(); + let chunk = storage_read_syscall(address_domain, storage_address).unwrap(); + packed_bytecode.append(chunk); + }; + let bytecode = load_packed_bytes(packed_bytecode.span(), bytecode_len); + SyscallResult::Ok(StorageBytecode { bytecode: bytecode.span() }) + } + + /// Side effect: Writes the bytecode len to the Account_bytecode_len storage variable + fn write( + address_domain: u32, base: StorageBaseAddress, value: StorageBytecode + ) -> SyscallResult<()> { + let base: felt252 = 0; + let mut state = account_contract_state(); + let bytecode_len: u32 = value.bytecode.len(); + state.deref_mut().storage_mut().Account_bytecode_len.write(bytecode_len); + + let mut packed_bytecode = pack_bytes(value.bytecode); + let mut i = 0; + for chunk in packed_bytecode { + let storage_address: StorageAddress = (base + i.into()).try_into().unwrap(); + storage_write_syscall(address_domain, storage_address, chunk).unwrap(); + i += 1; + }; + SyscallResult::Ok(()) + } + + fn read_at_offset( + address_domain: u32, base: StorageBaseAddress, offset: u8 + ) -> SyscallResult { + panic!("'read_at_offset' is not implemented for StoreBytecode") + } + + fn write_at_offset( + address_domain: u32, base: StorageBaseAddress, offset: u8, value: StorageBytecode + ) -> SyscallResult<()> { + panic!("'write_at_offset' is not implemented for StoreBytecode") + } + + fn size() -> u8 { + panic!("'size' is not implemented for StoreBytecode") + } +} + +#[cfg(test)] +mod tests { + use core::starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; + use crate::account_contract::AccountContract::unsafe_new_contract_state as account_contract_state; + use starknet::storage_access::Store; + use starknet::storage_access::{ + StorageBaseAddress, StorageAddress, storage_base_address_from_felt252 + }; + use starknet::syscalls::storage_read_syscall; + use super::DerefMut; + use super::SnapshotDeref; + use super::StorageBytecode; + use super::StorageTrait; + use super::StorageTraitMut; + use utils::utils::pack_bytes; + + #[test] + fn test_store_bytecode_empty() { + let mut state = account_contract_state(); + let bytecode = [].span(); + // Write the bytecode to the storage + state.deref_mut().storage_mut().Account_bytecode.write(StorageBytecode { bytecode }); + // Verify that the bytecode was written correctly and the len as well + let bytecode_len = state.snapshot_deref().storage().Account_bytecode_len.read(); + let stored_bytecode = state.snapshot_deref().storage().Account_bytecode.read(); + assert_eq!(bytecode_len, bytecode.len()); + assert_eq!(stored_bytecode.bytecode, bytecode); + } + + #[test] + fn test_store_bytecode_single_chunk() { + let mut state = account_contract_state(); + let bytecode = [0, 1, 2, 3, 4, 5].span(); + // Write the bytecode to the storage + state.deref_mut().storage_mut().Account_bytecode.write(StorageBytecode { bytecode }); + // Verify that the bytecode was written correctly and the len as well + let bytecode_len = state.snapshot_deref().storage().Account_bytecode_len.read(); + let stored_bytecode = state.snapshot_deref().storage().Account_bytecode.read(); + assert_eq!(bytecode_len, bytecode.len()); + assert_eq!(stored_bytecode.bytecode, bytecode); + } + + #[test] + fn test_store_bytecode_multiple_chunks() { + let mut state = account_contract_state(); + let mut bytecode_array = array![]; + for i in 0..100_u8 { + bytecode_array.append(i); + }; + let bytecode = bytecode_array.span(); + // Write the bytecode to the storage + state.deref_mut().storage_mut().Account_bytecode.write(StorageBytecode { bytecode }); + // Verify that the bytecode was written correctly and the len as well + let bytecode_len = state.snapshot_deref().storage().Account_bytecode_len.read(); + let stored_bytecode = state.snapshot_deref().storage().Account_bytecode.read(); + assert_eq!(bytecode_len, bytecode.len()); + assert_eq!(stored_bytecode.bytecode, bytecode); + } + + #[test] + fn test_store_bytecode_partial_chunk() { + let mut state = account_contract_state(); + let bytecode = [ + 1 + ; 33].span(); // 33 bytes will require 2 chunks, with the second chunk partially filled + // Write the bytecode to the storage + state.deref_mut().storage_mut().Account_bytecode.write(StorageBytecode { bytecode }); + // Verify that the bytecode was written correctly and the len as well + let bytecode_len = state.snapshot_deref().storage().Account_bytecode_len.read(); + let stored_bytecode = state.snapshot_deref().storage().Account_bytecode.read(); + assert_eq!(bytecode_len, bytecode.len()); + assert_eq!(stored_bytecode.bytecode, bytecode); + } + + #[test] + fn test_storage_layout_sequential_from_zero() { + let base_address: StorageAddress = 0.try_into().unwrap(); + let bytecode = [0x12; 33].span(); + let stored_bytecode = StorageBytecode { bytecode }; + let mut state = account_contract_state(); + state.deref_mut().storage_mut().Account_bytecode.write(stored_bytecode); + + // Verify that the bytecode was packed in chunks sequential from zero + let chunk0 = storage_read_syscall(0, base_address).unwrap(); + let chunk1 = storage_read_syscall(0, 1.try_into().unwrap()).unwrap(); + + assert_eq!(chunk0, (*pack_bytes([0x12; 31].span())[0])); + assert_eq!(chunk1, 0x1212); + } + + #[test] + #[should_panic(expected: "'read_at_offset' is not implemented for StoreBytecode")] + fn test_read_at_offset_panics() { + let base_address: StorageBaseAddress = storage_base_address_from_felt252(0); + let _ = Store::::read_at_offset(0, base_address, 0); + } + + #[test] + #[should_panic(expected: "'write_at_offset' is not implemented for StoreBytecode")] + fn test_write_at_offset_panics() { + let base_address: StorageBaseAddress = storage_base_address_from_felt252(0); + let bytecode = array![].span(); + let stored_bytecode = StorageBytecode { bytecode }; + let _ = Store::::write_at_offset(0, base_address, 0, stored_bytecode); + } + + #[test] + #[should_panic(expected: "'size' is not implemented for StoreBytecode")] + fn test_size_panics() { + let _ = Store::::size(); + } +} diff --git a/kakarot-ssj/crates/contracts/src/test_contracts/test_upgradeable.cairo b/kakarot-ssj/crates/contracts/src/test_contracts/test_upgradeable.cairo new file mode 100644 index 000000000..22cf19587 --- /dev/null +++ b/kakarot-ssj/crates/contracts/src/test_contracts/test_upgradeable.cairo @@ -0,0 +1,102 @@ +use crate::components::upgradeable::{upgradeable_component}; + +use upgradeable_component::{UpgradeableImpl}; + +#[starknet::interface] +pub trait IMockContractUpgradeable { + fn version(self: @TContractState) -> felt252; +} + +#[starknet::contract] +pub mod MockContractUpgradeableV0 { + use crate::components::upgradeable::{upgradeable_component}; + use super::IMockContractUpgradeable; + component!(path: upgradeable_component, storage: upgradeable, event: UpgradeableEvent); + + #[abi(embed_v0)] + impl UpgradeableImpl = upgradeable_component::Upgradeable; + + #[storage] + struct Storage { + #[substorage(v0)] + upgradeable: upgradeable_component::Storage + } + + #[event] + #[derive(Drop, starknet::Event)] + pub enum Event { + UpgradeableEvent: upgradeable_component::Event + } + + #[abi(embed_v0)] + impl MockContractUpgradeableImpl of IMockContractUpgradeable { + fn version(self: @ContractState) -> felt252 { + 0 + } + } +} + +#[starknet::contract] +pub mod MockContractUpgradeableV1 { + use crate::components::upgradeable::{upgradeable_component}; + use super::IMockContractUpgradeable; + component!(path: upgradeable_component, storage: upgradeable, event: upgradeableEvent); + + #[storage] + struct Storage { + #[substorage(v0)] + upgradeable: upgradeable_component::Storage + } + + #[event] + #[derive(Drop, starknet::Event)] + pub enum Event { + upgradeableEvent: upgradeable_component::Event + } + + #[abi(embed_v0)] + impl MockContractUpgradeableImpl of IMockContractUpgradeable { + fn version(self: @ContractState) -> felt252 { + 1 + } + } +} + +#[cfg(test)] +mod tests { + use core::starknet::syscalls::{deploy_syscall}; + use crate::components::upgradeable::{IUpgradeableDispatcher, IUpgradeableDispatcherTrait}; + use snforge_std::{declare, DeclareResultTrait}; + use starknet::{ClassHash}; + use super::{IMockContractUpgradeableDispatcher, IMockContractUpgradeableDispatcherTrait}; + + #[test] + fn test_upgradeable_update_contract() { + let mock_contract_upgradeable_v0_class_hash = (*declare("MockContractUpgradeableV0") + .unwrap() + .contract_class() + .class_hash); + let (contract_address, _) = deploy_syscall( + mock_contract_upgradeable_v0_class_hash, 0, [].span(), false + ) + .unwrap(); + + let version = IMockContractUpgradeableDispatcher { contract_address: contract_address } + .version(); + + assert(version == 0, 'version is not 0'); + + let mock_contract_upgradeable_v1_class_hash = (*declare("MockContractUpgradeableV1") + .unwrap() + .contract_class() + .class_hash); + let new_class_hash: ClassHash = mock_contract_upgradeable_v1_class_hash; + + IUpgradeableDispatcher { contract_address: contract_address } + .upgrade_contract(new_class_hash); + + let version = IMockContractUpgradeableDispatcher { contract_address: contract_address } + .version(); + assert(version == 1, 'version is not 1'); + } +} diff --git a/kakarot-ssj/crates/contracts/src/test_data.cairo b/kakarot-ssj/crates/contracts/src/test_data.cairo new file mode 100644 index 000000000..b56a08684 --- /dev/null +++ b/kakarot-ssj/crates/contracts/src/test_data.cairo @@ -0,0 +1,1781 @@ +// Counter Smart Contract Bytecode: +// 0.8.18+commit.87f61d96 +// with optimisation enabled (depth 200) (remix.ethereum.org) +// SPDX-License-Identifier: MIT +// pragma solidity >=0.7.0 <0.9.0; + +// contract Counter { +// uint public count; + +// // Function to get the current count +// function get() public view returns (uint) { +// return count; +// } + +// // Function to increment count by 1 +// function inc() public { +// count += 1; +// } + +// // Function to decrement count by 1 +// function dec() public { +// // This function will fail if count = 0 +// count -= 1; +// } +// } + +pub fn deploy_counter_calldata() -> Span { + [ + 0x60, + 0x80, + 0x60, + 0x40, + 0x52, + 0x34, + 0x80, + 0x15, + 0x61, + 0x00, + 0x0f, + 0x57, + 0x5f, + 0x80, + 0xfd, + 0x5b, + 0x50, + 0x61, + 0x01, + 0xd9, + 0x80, + 0x61, + 0x00, + 0x1d, + 0x5f, + 0x39, + 0x5f, + 0xf3, + 0xfe, + 0x60, + 0x80, + 0x60, + 0x40, + 0x52, + 0x34, + 0x80, + 0x15, + 0x61, + 0x00, + 0x0f, + 0x57, + 0x5f, + 0x80, + 0xfd, + 0x5b, + 0x50, + 0x60, + 0x04, + 0x36, + 0x10, + 0x61, + 0x00, + 0x4a, + 0x57, + 0x5f, + 0x35, + 0x60, + 0xe0, + 0x1c, + 0x80, + 0x63, + 0x06, + 0x66, + 0x1a, + 0xbd, + 0x14, + 0x61, + 0x00, + 0x4e, + 0x57, + 0x80, + 0x63, + 0x37, + 0x13, + 0x03, + 0xc0, + 0x14, + 0x61, + 0x00, + 0x6c, + 0x57, + 0x80, + 0x63, + 0x6d, + 0x4c, + 0xe6, + 0x3c, + 0x14, + 0x61, + 0x00, + 0x76, + 0x57, + 0x80, + 0x63, + 0xb3, + 0xbc, + 0xfa, + 0x82, + 0x14, + 0x61, + 0x00, + 0x94, + 0x57, + 0x5b, + 0x5f, + 0x80, + 0xfd, + 0x5b, + 0x61, + 0x00, + 0x56, + 0x61, + 0x00, + 0x9e, + 0x56, + 0x5b, + 0x60, + 0x40, + 0x51, + 0x61, + 0x00, + 0x63, + 0x91, + 0x90, + 0x61, + 0x00, + 0xf7, + 0x56, + 0x5b, + 0x60, + 0x40, + 0x51, + 0x80, + 0x91, + 0x03, + 0x90, + 0xf3, + 0x5b, + 0x61, + 0x00, + 0x74, + 0x61, + 0x00, + 0xa3, + 0x56, + 0x5b, + 0x00, + 0x5b, + 0x61, + 0x00, + 0x7e, + 0x61, + 0x00, + 0xbd, + 0x56, + 0x5b, + 0x60, + 0x40, + 0x51, + 0x61, + 0x00, + 0x8b, + 0x91, + 0x90, + 0x61, + 0x00, + 0xf7, + 0x56, + 0x5b, + 0x60, + 0x40, + 0x51, + 0x80, + 0x91, + 0x03, + 0x90, + 0xf3, + 0x5b, + 0x61, + 0x00, + 0x9c, + 0x61, + 0x00, + 0xc5, + 0x56, + 0x5b, + 0x00, + 0x5b, + 0x5f, + 0x54, + 0x81, + 0x56, + 0x5b, + 0x60, + 0x01, + 0x5f, + 0x80, + 0x82, + 0x82, + 0x54, + 0x61, + 0x00, + 0xb4, + 0x91, + 0x90, + 0x61, + 0x01, + 0x3d, + 0x56, + 0x5b, + 0x92, + 0x50, + 0x50, + 0x81, + 0x90, + 0x55, + 0x50, + 0x56, + 0x5b, + 0x5f, + 0x80, + 0x54, + 0x90, + 0x50, + 0x90, + 0x56, + 0x5b, + 0x60, + 0x01, + 0x5f, + 0x80, + 0x82, + 0x82, + 0x54, + 0x61, + 0x00, + 0xd6, + 0x91, + 0x90, + 0x61, + 0x01, + 0x70, + 0x56, + 0x5b, + 0x92, + 0x50, + 0x50, + 0x81, + 0x90, + 0x55, + 0x50, + 0x56, + 0x5b, + 0x5f, + 0x81, + 0x90, + 0x50, + 0x91, + 0x90, + 0x50, + 0x56, + 0x5b, + 0x61, + 0x00, + 0xf1, + 0x81, + 0x61, + 0x00, + 0xdf, + 0x56, + 0x5b, + 0x82, + 0x52, + 0x50, + 0x50, + 0x56, + 0x5b, + 0x5f, + 0x60, + 0x20, + 0x82, + 0x01, + 0x90, + 0x50, + 0x61, + 0x01, + 0x0a, + 0x5f, + 0x83, + 0x01, + 0x84, + 0x61, + 0x00, + 0xe8, + 0x56, + 0x5b, + 0x92, + 0x91, + 0x50, + 0x50, + 0x56, + 0x5b, + 0x7f, + 0x4e, + 0x48, + 0x7b, + 0x71, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x5f, + 0x52, + 0x60, + 0x11, + 0x60, + 0x04, + 0x52, + 0x60, + 0x24, + 0x5f, + 0xfd, + 0x5b, + 0x5f, + 0x61, + 0x01, + 0x47, + 0x82, + 0x61, + 0x00, + 0xdf, + 0x56, + 0x5b, + 0x91, + 0x50, + 0x61, + 0x01, + 0x52, + 0x83, + 0x61, + 0x00, + 0xdf, + 0x56, + 0x5b, + 0x92, + 0x50, + 0x82, + 0x82, + 0x01, + 0x90, + 0x50, + 0x80, + 0x82, + 0x11, + 0x15, + 0x61, + 0x01, + 0x6a, + 0x57, + 0x61, + 0x01, + 0x69, + 0x61, + 0x01, + 0x10, + 0x56, + 0x5b, + 0x5b, + 0x92, + 0x91, + 0x50, + 0x50, + 0x56, + 0x5b, + 0x5f, + 0x61, + 0x01, + 0x7a, + 0x82, + 0x61, + 0x00, + 0xdf, + 0x56, + 0x5b, + 0x91, + 0x50, + 0x61, + 0x01, + 0x85, + 0x83, + 0x61, + 0x00, + 0xdf, + 0x56, + 0x5b, + 0x92, + 0x50, + 0x82, + 0x82, + 0x03, + 0x90, + 0x50, + 0x81, + 0x81, + 0x11, + 0x15, + 0x61, + 0x01, + 0x9d, + 0x57, + 0x61, + 0x01, + 0x9c, + 0x61, + 0x01, + 0x10, + 0x56, + 0x5b, + 0x5b, + 0x92, + 0x91, + 0x50, + 0x50, + 0x56, + 0xfe, + 0xa2, + 0x64, + 0x69, + 0x70, + 0x66, + 0x73, + 0x58, + 0x22, + 0x12, + 0x20, + 0x7e, + 0x79, + 0x2f, + 0xcf, + 0xf2, + 0x8a, + 0x4b, + 0xf0, + 0xba, + 0xd8, + 0x67, + 0x5c, + 0x5b, + 0xc2, + 0x28, + 0x8b, + 0x07, + 0x83, + 0x5a, + 0xeb, + 0xaa, + 0x90, + 0xb8, + 0xdc, + 0x5e, + 0x0d, + 0xf1, + 0x91, + 0x83, + 0xfb, + 0x72, + 0xcf, + 0x64, + 0x73, + 0x6f, + 0x6c, + 0x63, + 0x43, + 0x00, + 0x08, + 0x16, + 0x00, + 0x33 + ].span() +} + +pub fn counter_evm_bytecode() -> Span { + [ + 0x60, + 0x80, + 0x60, + 0x40, + 0x52, + 0x34, + 0x80, + 0x15, + 0x61, + 0x00, + 0x0f, + 0x57, + 0x5f, + 0x80, + 0xfd, + 0x5b, + 0x50, + 0x60, + 0x04, + 0x36, + 0x10, + 0x61, + 0x00, + 0x4a, + 0x57, + 0x5f, + 0x35, + 0x60, + 0xe0, + 0x1c, + 0x80, + 0x63, + 0x06, + 0x66, + 0x1a, + 0xbd, + 0x14, + 0x61, + 0x00, + 0x4e, + 0x57, + 0x80, + 0x63, + 0x37, + 0x13, + 0x03, + 0xc0, + 0x14, + 0x61, + 0x00, + 0x6c, + 0x57, + 0x80, + 0x63, + 0x6d, + 0x4c, + 0xe6, + 0x3c, + 0x14, + 0x61, + 0x00, + 0x76, + 0x57, + 0x80, + 0x63, + 0xb3, + 0xbc, + 0xfa, + 0x82, + 0x14, + 0x61, + 0x00, + 0x94, + 0x57, + 0x5b, + 0x5f, + 0x80, + 0xfd, + 0x5b, + 0x61, + 0x00, + 0x56, + 0x61, + 0x00, + 0x9e, + 0x56, + 0x5b, + 0x60, + 0x40, + 0x51, + 0x61, + 0x00, + 0x63, + 0x91, + 0x90, + 0x61, + 0x00, + 0xf7, + 0x56, + 0x5b, + 0x60, + 0x40, + 0x51, + 0x80, + 0x91, + 0x03, + 0x90, + 0xf3, + 0x5b, + 0x61, + 0x00, + 0x74, + 0x61, + 0x00, + 0xa3, + 0x56, + 0x5b, + 0x00, + 0x5b, + 0x61, + 0x00, + 0x7e, + 0x61, + 0x00, + 0xbd, + 0x56, + 0x5b, + 0x60, + 0x40, + 0x51, + 0x61, + 0x00, + 0x8b, + 0x91, + 0x90, + 0x61, + 0x00, + 0xf7, + 0x56, + 0x5b, + 0x60, + 0x40, + 0x51, + 0x80, + 0x91, + 0x03, + 0x90, + 0xf3, + 0x5b, + 0x61, + 0x00, + 0x9c, + 0x61, + 0x00, + 0xc5, + 0x56, + 0x5b, + 0x00, + 0x5b, + 0x5f, + 0x54, + 0x81, + 0x56, + 0x5b, + 0x60, + 0x01, + 0x5f, + 0x80, + 0x82, + 0x82, + 0x54, + 0x61, + 0x00, + 0xb4, + 0x91, + 0x90, + 0x61, + 0x01, + 0x3d, + 0x56, + 0x5b, + 0x92, + 0x50, + 0x50, + 0x81, + 0x90, + 0x55, + 0x50, + 0x56, + 0x5b, + 0x5f, + 0x80, + 0x54, + 0x90, + 0x50, + 0x90, + 0x56, + 0x5b, + 0x60, + 0x01, + 0x5f, + 0x80, + 0x82, + 0x82, + 0x54, + 0x61, + 0x00, + 0xd6, + 0x91, + 0x90, + 0x61, + 0x01, + 0x70, + 0x56, + 0x5b, + 0x92, + 0x50, + 0x50, + 0x81, + 0x90, + 0x55, + 0x50, + 0x56, + 0x5b, + 0x5f, + 0x81, + 0x90, + 0x50, + 0x91, + 0x90, + 0x50, + 0x56, + 0x5b, + 0x61, + 0x00, + 0xf1, + 0x81, + 0x61, + 0x00, + 0xdf, + 0x56, + 0x5b, + 0x82, + 0x52, + 0x50, + 0x50, + 0x56, + 0x5b, + 0x5f, + 0x60, + 0x20, + 0x82, + 0x01, + 0x90, + 0x50, + 0x61, + 0x01, + 0x0a, + 0x5f, + 0x83, + 0x01, + 0x84, + 0x61, + 0x00, + 0xe8, + 0x56, + 0x5b, + 0x92, + 0x91, + 0x50, + 0x50, + 0x56, + 0x5b, + 0x7f, + 0x4e, + 0x48, + 0x7b, + 0x71, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x5f, + 0x52, + 0x60, + 0x11, + 0x60, + 0x04, + 0x52, + 0x60, + 0x24, + 0x5f, + 0xfd, + 0x5b, + 0x5f, + 0x61, + 0x01, + 0x47, + 0x82, + 0x61, + 0x00, + 0xdf, + 0x56, + 0x5b, + 0x91, + 0x50, + 0x61, + 0x01, + 0x52, + 0x83, + 0x61, + 0x00, + 0xdf, + 0x56, + 0x5b, + 0x92, + 0x50, + 0x82, + 0x82, + 0x01, + 0x90, + 0x50, + 0x80, + 0x82, + 0x11, + 0x15, + 0x61, + 0x01, + 0x6a, + 0x57, + 0x61, + 0x01, + 0x69, + 0x61, + 0x01, + 0x10, + 0x56, + 0x5b, + 0x5b, + 0x92, + 0x91, + 0x50, + 0x50, + 0x56, + 0x5b, + 0x5f, + 0x61, + 0x01, + 0x7a, + 0x82, + 0x61, + 0x00, + 0xdf, + 0x56, + 0x5b, + 0x91, + 0x50, + 0x61, + 0x01, + 0x85, + 0x83, + 0x61, + 0x00, + 0xdf, + 0x56, + 0x5b, + 0x92, + 0x50, + 0x82, + 0x82, + 0x03, + 0x90, + 0x50, + 0x81, + 0x81, + 0x11, + 0x15, + 0x61, + 0x01, + 0x9d, + 0x57, + 0x61, + 0x01, + 0x9c, + 0x61, + 0x01, + 0x10, + 0x56, + 0x5b, + 0x5b, + 0x92, + 0x91, + 0x50, + 0x50, + 0x56, + 0xfe, + 0xa2, + 0x64, + 0x69, + 0x70, + 0x66, + 0x73, + 0x58, + 0x22, + 0x12, + 0x20, + 0x7e, + 0x79, + 0x2f, + 0xcf, + 0xf2, + 0x8a, + 0x4b, + 0xf0, + 0xba, + 0xd8, + 0x67, + 0x5c, + 0x5b, + 0xc2, + 0x28, + 0x8b, + 0x07, + 0x83, + 0x5a, + 0xeb, + 0xaa, + 0x90, + 0xb8, + 0xdc, + 0x5e, + 0x0d, + 0xf1, + 0x91, + 0x83, + 0xfb, + 0x72, + 0xcf, + 0x64, + 0x73, + 0x6f, + 0x6c, + 0x63, + 0x43, + 0x00, + 0x08, + 0x16, + 0x00, + 0x33 + ].span() +} + + +// // SPDX-License-Identifier: GPL-3.0 + +// pragma solidity >=0.8.2 <0.9.0; + +// /** +// * @title Storage +// * @dev Store & retrieve value in a variable +// * @custom:dev-run-script ./scripts/deploy_with_ethers.ts +// */ +// contract Storage { + +// uint256 number; + +// /** +// * @dev Store value in variable +// * @param num value to store +// */ +// function store(uint256 num) public { +// number = num; +// } + +// /** +// * @dev Return value +// * @return value of 'number' +// */ +// function retrieve() public view returns (uint256){ +// return number; +// } +// } +// Remix compiler: 0.8.20+commit.a1b79de6 +pub fn storage_evm_initcode() -> Span { + [ + 0x60, + 0x80, + 0x60, + 0x40, + 0x52, + 0x34, + 0x80, + 0x15, + 0x61, + 0x00, + 0x0f, + 0x57, + 0x5f, + 0x80, + 0xfd, + 0x5b, + 0x50, + 0x61, + 0x01, + 0x43, + 0x80, + 0x61, + 0x00, + 0x1d, + 0x5f, + 0x39, + 0x5f, + 0xf3, + 0xfe, + 0x60, + 0x80, + 0x60, + 0x40, + 0x52, + 0x34, + 0x80, + 0x15, + 0x61, + 0x00, + 0x0f, + 0x57, + 0x5f, + 0x80, + 0xfd, + 0x5b, + 0x50, + 0x60, + 0x04, + 0x36, + 0x10, + 0x61, + 0x00, + 0x34, + 0x57, + 0x5f, + 0x35, + 0x60, + 0xe0, + 0x1c, + 0x80, + 0x63, + 0x2e, + 0x64, + 0xce, + 0xc1, + 0x14, + 0x61, + 0x00, + 0x38, + 0x57, + 0x80, + 0x63, + 0x60, + 0x57, + 0x36, + 0x1d, + 0x14, + 0x61, + 0x00, + 0x56, + 0x57, + 0x5b, + 0x5f, + 0x80, + 0xfd, + 0x5b, + 0x61, + 0x00, + 0x40, + 0x61, + 0x00, + 0x72, + 0x56, + 0x5b, + 0x60, + 0x40, + 0x51, + 0x61, + 0x00, + 0x4d, + 0x91, + 0x90, + 0x61, + 0x00, + 0x9b, + 0x56, + 0x5b, + 0x60, + 0x40, + 0x51, + 0x80, + 0x91, + 0x03, + 0x90, + 0xf3, + 0x5b, + 0x61, + 0x00, + 0x70, + 0x60, + 0x04, + 0x80, + 0x36, + 0x03, + 0x81, + 0x01, + 0x90, + 0x61, + 0x00, + 0x6b, + 0x91, + 0x90, + 0x61, + 0x00, + 0xe2, + 0x56, + 0x5b, + 0x61, + 0x00, + 0x7a, + 0x56, + 0x5b, + 0x00, + 0x5b, + 0x5f, + 0x80, + 0x54, + 0x90, + 0x50, + 0x90, + 0x56, + 0x5b, + 0x80, + 0x5f, + 0x81, + 0x90, + 0x55, + 0x50, + 0x50, + 0x56, + 0x5b, + 0x5f, + 0x81, + 0x90, + 0x50, + 0x91, + 0x90, + 0x50, + 0x56, + 0x5b, + 0x61, + 0x00, + 0x95, + 0x81, + 0x61, + 0x00, + 0x83, + 0x56, + 0x5b, + 0x82, + 0x52, + 0x50, + 0x50, + 0x56, + 0x5b, + 0x5f, + 0x60, + 0x20, + 0x82, + 0x01, + 0x90, + 0x50, + 0x61, + 0x00, + 0xae, + 0x5f, + 0x83, + 0x01, + 0x84, + 0x61, + 0x00, + 0x8c, + 0x56, + 0x5b, + 0x92, + 0x91, + 0x50, + 0x50, + 0x56, + 0x5b, + 0x5f, + 0x80, + 0xfd, + 0x5b, + 0x61, + 0x00, + 0xc1, + 0x81, + 0x61, + 0x00, + 0x83, + 0x56, + 0x5b, + 0x81, + 0x14, + 0x61, + 0x00, + 0xcb, + 0x57, + 0x5f, + 0x80, + 0xfd, + 0x5b, + 0x50, + 0x56, + 0x5b, + 0x5f, + 0x81, + 0x35, + 0x90, + 0x50, + 0x61, + 0x00, + 0xdc, + 0x81, + 0x61, + 0x00, + 0xb8, + 0x56, + 0x5b, + 0x92, + 0x91, + 0x50, + 0x50, + 0x56, + 0x5b, + 0x5f, + 0x60, + 0x20, + 0x82, + 0x84, + 0x03, + 0x12, + 0x15, + 0x61, + 0x00, + 0xf7, + 0x57, + 0x61, + 0x00, + 0xf6, + 0x61, + 0x00, + 0xb4, + 0x56, + 0x5b, + 0x5b, + 0x5f, + 0x61, + 0x01, + 0x04, + 0x84, + 0x82, + 0x85, + 0x01, + 0x61, + 0x00, + 0xce, + 0x56, + 0x5b, + 0x91, + 0x50, + 0x50, + 0x92, + 0x91, + 0x50, + 0x50, + 0x56, + 0xfe, + 0xa2, + 0x64, + 0x69, + 0x70, + 0x66, + 0x73, + 0x58, + 0x22, + 0x12, + 0x20, + 0xb5, + 0xc3, + 0x07, + 0x5f, + 0x2f, + 0x20, + 0x34, + 0xd0, + 0x39, + 0xa2, + 0x27, + 0xfa, + 0xc6, + 0xdd, + 0x31, + 0x4b, + 0x05, + 0x2f, + 0xfb, + 0x2b, + 0x3d, + 0xa5, + 0x2c, + 0x7b, + 0x6f, + 0x5b, + 0xc3, + 0x74, + 0xd5, + 0x28, + 0xed, + 0x36, + 0x64, + 0x73, + 0x6f, + 0x6c, + 0x63, + 0x43, + 0x00, + 0x08, + 0x14, + 0x00, + 0x33 + ].span() +} + +pub fn storage_evm_bytecode() -> Span { + [ + 0x60, + 0x80, + 0x60, + 0x40, + 0x52, + 0x34, + 0x80, + 0x15, + 0x61, + 0x00, + 0x0f, + 0x57, + 0x5f, + 0x80, + 0xfd, + 0x5b, + 0x50, + 0x60, + 0x04, + 0x36, + 0x10, + 0x61, + 0x00, + 0x34, + 0x57, + 0x5f, + 0x35, + 0x60, + 0xe0, + 0x1c, + 0x80, + 0x63, + 0x2e, + 0x64, + 0xce, + 0xc1, + 0x14, + 0x61, + 0x00, + 0x38, + 0x57, + 0x80, + 0x63, + 0x60, + 0x57, + 0x36, + 0x1d, + 0x14, + 0x61, + 0x00, + 0x56, + 0x57, + 0x5b, + 0x5f, + 0x80, + 0xfd, + 0x5b, + 0x61, + 0x00, + 0x40, + 0x61, + 0x00, + 0x72, + 0x56, + 0x5b, + 0x60, + 0x40, + 0x51, + 0x61, + 0x00, + 0x4d, + 0x91, + 0x90, + 0x61, + 0x00, + 0x9b, + 0x56, + 0x5b, + 0x60, + 0x40, + 0x51, + 0x80, + 0x91, + 0x03, + 0x90, + 0xf3, + 0x5b, + 0x61, + 0x00, + 0x70, + 0x60, + 0x04, + 0x80, + 0x36, + 0x03, + 0x81, + 0x01, + 0x90, + 0x61, + 0x00, + 0x6b, + 0x91, + 0x90, + 0x61, + 0x00, + 0xe2, + 0x56, + 0x5b, + 0x61, + 0x00, + 0x7a, + 0x56, + 0x5b, + 0x00, + 0x5b, + 0x5f, + 0x80, + 0x54, + 0x90, + 0x50, + 0x90, + 0x56, + 0x5b, + 0x80, + 0x5f, + 0x81, + 0x90, + 0x55, + 0x50, + 0x50, + 0x56, + 0x5b, + 0x5f, + 0x81, + 0x90, + 0x50, + 0x91, + 0x90, + 0x50, + 0x56, + 0x5b, + 0x61, + 0x00, + 0x95, + 0x81, + 0x61, + 0x00, + 0x83, + 0x56, + 0x5b, + 0x82, + 0x52, + 0x50, + 0x50, + 0x56, + 0x5b, + 0x5f, + 0x60, + 0x20, + 0x82, + 0x01, + 0x90, + 0x50, + 0x61, + 0x00, + 0xae, + 0x5f, + 0x83, + 0x01, + 0x84, + 0x61, + 0x00, + 0x8c, + 0x56, + 0x5b, + 0x92, + 0x91, + 0x50, + 0x50, + 0x56, + 0x5b, + 0x5f, + 0x80, + 0xfd, + 0x5b, + 0x61, + 0x00, + 0xc1, + 0x81, + 0x61, + 0x00, + 0x83, + 0x56, + 0x5b, + 0x81, + 0x14, + 0x61, + 0x00, + 0xcb, + 0x57, + 0x5f, + 0x80, + 0xfd, + 0x5b, + 0x50, + 0x56, + 0x5b, + 0x5f, + 0x81, + 0x35, + 0x90, + 0x50, + 0x61, + 0x00, + 0xdc, + 0x81, + 0x61, + 0x00, + 0xb8, + 0x56, + 0x5b, + 0x92, + 0x91, + 0x50, + 0x50, + 0x56, + 0x5b, + 0x5f, + 0x60, + 0x20, + 0x82, + 0x84, + 0x03, + 0x12, + 0x15, + 0x61, + 0x00, + 0xf7, + 0x57, + 0x61, + 0x00, + 0xf6, + 0x61, + 0x00, + 0xb4, + 0x56, + 0x5b, + 0x5b, + 0x5f, + 0x61, + 0x01, + 0x04, + 0x84, + 0x82, + 0x85, + 0x01, + 0x61, + 0x00, + 0xce, + 0x56, + 0x5b, + 0x91, + 0x50, + 0x50, + 0x92, + 0x91, + 0x50, + 0x50, + 0x56, + 0xfe, + 0xa2, + 0x64, + 0x69, + 0x70, + 0x66, + 0x73, + 0x58, + 0x22, + 0x12, + 0x20, + 0xb5, + 0xc3, + 0x07, + 0x5f, + 0x2f, + 0x20, + 0x34, + 0xd0, + 0x39, + 0xa2, + 0x27, + 0xfa, + 0xc6, + 0xdd, + 0x31, + 0x4b, + 0x05, + 0x2f, + 0xfb, + 0x2b, + 0x3d, + 0xa5, + 0x2c, + 0x7b, + 0x6f, + 0x5b, + 0xc3, + 0x74, + 0xd5, + 0x28, + 0xed, + 0x36, + 0x64, + 0x73, + 0x6f, + 0x6c, + 0x63, + 0x43, + 0x00, + 0x08, + 0x14, + 0x00, + 0x33 + ].span() +} + + +// eip-2930 RLP encoded tx { unsigned }, calls the `inc` function of counter bytecode +// format: 0x01 || rlp([chainId, nonce, gasPrice, gasLimit, to, value, data, accessList]) +// rlp decoding: [ '0x01', '0x', '0x3b9aca00', '0x1e8480', +// '0x0000006f746865725f65766d5f61646472657373', '0x', '0x371303c0', [] ] +pub fn eip_2930_rlp_encoded_counter_inc_tx() -> Span { + [ + 1, + 235, + 132, + 75, + 75, + 82, + 84, + 128, + 132, + 59, + 154, + 202, + 0, + 131, + 30, + 132, + 128, + 148, + 0, + 0, + 0, + 111, + 116, + 104, + 101, + 114, + 95, + 101, + 118, + 109, + 95, + 97, + 100, + 100, + 114, + 101, + 115, + 115, + 128, + 132, + 55, + 19, + 3, + 192, + 192, + ].span() +} diff --git a/kakarot-ssj/crates/contracts/src/test_utils.cairo b/kakarot-ssj/crates/contracts/src/test_utils.cairo new file mode 100644 index 000000000..d412068a2 --- /dev/null +++ b/kakarot-ssj/crates/contracts/src/test_utils.cairo @@ -0,0 +1,148 @@ +use core::result::ResultTrait; +use core::starknet::syscalls::deploy_syscall; +use core::starknet::{EthAddress, ContractAddress}; +use crate::account_contract::{IAccountDispatcher, IAccountDispatcherTrait}; +use crate::kakarot_core::{ + interface::IExtendedKakarotCoreDispatcher, interface::IExtendedKakarotCoreDispatcherTrait +}; +use evm::model::{Address}; + +use evm::test_utils::{other_starknet_address, sequencer_evm_address, chain_id}; +use openzeppelin::token::erc20::interface::{IERC20CamelDispatcher, IERC20CamelDispatcherTrait}; +use snforge_std::start_cheat_chain_id_global; +use snforge_std::{ + declare, DeclareResultTrait, start_cheat_caller_address, start_cheat_sequencer_address_global, + stop_cheat_caller_address, start_cheat_caller_address_global, cheat_caller_address, CheatSpan +}; +use utils::constants::BLOCK_GAS_LIMIT; +use utils::eth_transaction::legacy::TxLegacy; + + +pub mod constants { + use core::starknet::{EthAddress, contract_address_const, ContractAddress}; + pub fn ZERO() -> ContractAddress { + contract_address_const::<0>() + } + + pub fn OWNER() -> ContractAddress { + contract_address_const::<0xabde1>() + } + + pub fn OTHER() -> ContractAddress { + contract_address_const::<0xe1145>() + } + + pub fn EVM_ADDRESS() -> EthAddress { + 0xc0ffee.try_into().unwrap() + } + + pub fn ETH_BANK() -> ContractAddress { + contract_address_const::<0x777>() + } +} + +pub fn deploy_native_token() -> IERC20CamelDispatcher { + let calldata: Array = array![ + 'STARKNET_ETH', 'ETH', 0x00, 0xfffffffffffffffffffffffffff, constants::ETH_BANK().into() + ]; + let class = declare("ERC20").unwrap().contract_class().class_hash; + let maybe_address = deploy_syscall(*class, 0, calldata.span(), false); + match maybe_address { + Result::Ok((contract_address, _)) => { IERC20CamelDispatcher { contract_address } }, + Result::Err(err) => panic(err) + } +} + +pub fn deploy_kakarot_core( + native_token: ContractAddress, mut eoas: Span +) -> IExtendedKakarotCoreDispatcher { + let account_contract_class_hash = declare("AccountContract") + .unwrap() + .contract_class() + .class_hash; + let uninitialized_account_class_hash = declare("UninitializedAccount") + .unwrap() + .contract_class() + .class_hash; + let kakarot_core_class_hash = declare("KakarotCore").unwrap().contract_class().class_hash; + let mut calldata: Array = array![ + other_starknet_address().into(), + native_token.into(), + (*account_contract_class_hash).into(), + (*uninitialized_account_class_hash).into(), + 'coinbase', + BLOCK_GAS_LIMIT.into(), + ]; + + Serde::serialize(@eoas, ref calldata); + + let maybe_address = deploy_syscall( + (*kakarot_core_class_hash).into(), 0, calldata.span(), false + ); + + let kakarot_core = match maybe_address { + Result::Ok(( + contract_address, _ + )) => { IExtendedKakarotCoreDispatcher { contract_address } }, + Result::Err(err) => panic(err) + }; + cheat_caller_address( + kakarot_core.contract_address, other_starknet_address(), CheatSpan::TargetCalls(1) + ); + kakarot_core.set_base_fee(1000); + + kakarot_core +} + +pub fn deploy_contract_account( + kakarot_core: IExtendedKakarotCoreDispatcher, evm_address: EthAddress, bytecode: Span +) -> Address { + let eoa = deploy_eoa(kakarot_core, evm_address); + let starknet_address = eoa.contract_address; + start_cheat_caller_address(starknet_address, kakarot_core.contract_address); + IAccountDispatcher { contract_address: starknet_address }.set_nonce(1); + IAccountDispatcher { contract_address: starknet_address }.write_bytecode(bytecode); + stop_cheat_caller_address(starknet_address); + Address { evm: evm_address, starknet: starknet_address } +} + +pub fn deploy_eoa( + kakarot_core: IExtendedKakarotCoreDispatcher, evm_address: EthAddress +) -> IAccountDispatcher { + let starknet_address = kakarot_core.deploy_externally_owned_account(evm_address); + IAccountDispatcher { contract_address: starknet_address } +} + +pub fn call_transaction( + chain_id: u64, destination: Option, input: Span +) -> TxLegacy { + TxLegacy { + chain_id: Option::Some(chain_id), + nonce: 0, + gas_price: 0, + gas_limit: 500000000, + to: destination.into(), + value: 0, + input + } +} + +pub fn fund_account_with_native_token( + contract_address: ContractAddress, native_token: IERC20CamelDispatcher, amount: u256, +) { + start_cheat_caller_address(native_token.contract_address, constants::ETH_BANK()); + native_token.transfer(contract_address, amount); + stop_cheat_caller_address(native_token.contract_address); +} + +pub fn setup_contracts_for_testing() -> (IERC20CamelDispatcher, IExtendedKakarotCoreDispatcher) { + let sequencer: EthAddress = sequencer_evm_address(); + let native_token = deploy_native_token(); + let kakarot_core = deploy_kakarot_core(native_token.contract_address, [sequencer].span()); + + let sequencer_sn_address = kakarot_core.address_registry(sequencer); + start_cheat_sequencer_address_global(sequencer_sn_address); + start_cheat_caller_address_global(kakarot_core.contract_address); + start_cheat_chain_id_global(chain_id().into()); + return (native_token, kakarot_core); +} diff --git a/kakarot-ssj/crates/contracts/src/uninitialized_account.cairo b/kakarot-ssj/crates/contracts/src/uninitialized_account.cairo new file mode 100644 index 000000000..46c4ea9e0 --- /dev/null +++ b/kakarot-ssj/crates/contracts/src/uninitialized_account.cairo @@ -0,0 +1,66 @@ +//! The generic account that is deployed by Kakarot Core before being "specialized" into an +//! Externally Owned Account or a Contract Account This aims at having only one class hash for all +//! the contracts deployed by Kakarot, thus enforcing a unique and consistent address mapping Eth +//! Address <=> Starknet Address + +use core::starknet::ClassHash; +use core::starknet::{ContractAddress, EthAddress}; + +#[starknet::interface] +trait IAccount { + fn initialize( + ref self: TContractState, + kakarot_address: ContractAddress, + evm_address: EthAddress, + implementation_class: ClassHash + ); +} + + +#[starknet::contract] +pub mod UninitializedAccount { + use core::starknet::SyscallResultTrait; + use core::starknet::syscalls::{library_call_syscall, replace_class_syscall}; + use core::starknet::{ContractAddress, get_caller_address}; + use crate::components::ownable::ownable_component::InternalTrait; + use crate::components::ownable::ownable_component; + use crate::kakarot_core::interface::{IKakarotCoreDispatcher, IKakarotCoreDispatcherTrait}; + + // Add ownable component + component!(path: ownable_component, storage: ownable, event: OwnableEvent); + #[abi(embed_v0)] + impl OwnableImpl = ownable_component::Ownable; + impl OwnableInternal = ownable_component::InternalImpl; + + #[storage] + struct Storage { + #[substorage(v0)] + ownable: ownable_component::Storage, + } + + #[event] + #[derive(Drop, starknet::Event)] + enum Event { + OwnableEvent: ownable_component::Event + } + + #[constructor] + fn constructor(ref self: ContractState, mut calldata: Array) { + let owner_address: ContractAddress = get_caller_address(); + self.ownable.initializer(owner_address); + let implementation_class = IKakarotCoreDispatcher { contract_address: owner_address } + .get_account_contract_class_hash(); + //TODO: Difference from KakarotZero in that the account contract takes the class + //implementation to write it in storage, + // as it is not a transparent proxy in Cairo1 + calldata.append(implementation_class.into()); + library_call_syscall( + class_hash: implementation_class, + function_selector: selector!("initialize"), + calldata: calldata.span() + ) + .unwrap_syscall(); + + replace_class_syscall(implementation_class).unwrap_syscall(); + } +} diff --git a/kakarot-ssj/crates/contracts/tests/lib.cairo b/kakarot-ssj/crates/contracts/tests/lib.cairo new file mode 100644 index 000000000..df3d540ee --- /dev/null +++ b/kakarot-ssj/crates/contracts/tests/lib.cairo @@ -0,0 +1,8 @@ +mod test_account_contract; +mod test_cairo1_helpers; + +mod test_execution_from_outside; + +mod test_kakarot_core; + +mod test_ownable; diff --git a/kakarot-ssj/crates/contracts/tests/test_account_contract.cairo b/kakarot-ssj/crates/contracts/tests/test_account_contract.cairo new file mode 100644 index 000000000..430a5501c --- /dev/null +++ b/kakarot-ssj/crates/contracts/tests/test_account_contract.cairo @@ -0,0 +1,148 @@ +use contracts::errors::KAKAROT_REENTRANCY; +use contracts::test_data::counter_evm_bytecode; +use contracts::test_utils::{ + setup_contracts_for_testing, deploy_contract_account, fund_account_with_native_token, deploy_eoa +}; +use contracts::{IAccountDispatcher, IAccountDispatcherTrait}; +use core::starknet::EthAddress; +use core::starknet::account::{Call}; +use evm::test_utils::{ca_address, eoa_address}; +use openzeppelin::token::erc20::interface::IERC20CamelDispatcherTrait; +use snforge_std::{start_cheat_caller_address, stop_cheat_caller_address}; + +#[test] +fn test_ca_deploy() { + let (_, kakarot_core) = setup_contracts_for_testing(); + let ca_address = deploy_contract_account(kakarot_core, ca_address(), [].span()); + let contract_account = IAccountDispatcher { contract_address: ca_address.starknet }; + + let initial_bytecode = contract_account.bytecode(); + assert(initial_bytecode.is_empty(), 'bytecode should be empty'); + assert(contract_account.get_evm_address() == ca_address.evm, 'wrong ca evm address'); + assert(contract_account.get_nonce() == 1, 'wrong nonce'); +} + +#[test] +fn test_ca_bytecode() { + let (_, kakarot_core) = setup_contracts_for_testing(); + let bytecode = counter_evm_bytecode(); + let ca_address = deploy_contract_account(kakarot_core, ca_address(), bytecode); + let contract_account = IAccountDispatcher { contract_address: ca_address.starknet }; + + let contract_bytecode = contract_account.bytecode(); + assert(contract_bytecode == bytecode, 'wrong contract bytecode'); +} + + +#[test] +fn test_ca_get_nonce() { + let (_, kakarot_core) = setup_contracts_for_testing(); + let ca_address = deploy_contract_account(kakarot_core, ca_address(), [].span()); + let contract_account = IAccountDispatcher { contract_address: ca_address.starknet }; + + let initial_nonce = contract_account.get_nonce(); + assert(initial_nonce == 1, 'nonce should be 1'); + + let expected_nonce = 100; + start_cheat_caller_address(ca_address.starknet, kakarot_core.contract_address); + contract_account.set_nonce(expected_nonce); + stop_cheat_caller_address(ca_address.starknet); + + let nonce = contract_account.get_nonce(); + + assert(nonce == expected_nonce, 'wrong contract nonce'); +} + +#[test] +fn test_get_evm_address() { + let expected_address: EthAddress = eoa_address(); + let (_, kakarot_core) = setup_contracts_for_testing(); + + let eoa_contract = deploy_eoa(kakarot_core, eoa_address()); + + assert(eoa_contract.get_evm_address() == expected_address, 'wrong evm_address'); +} + + +#[test] +fn test_ca_storage() { + let (_, kakarot_core) = setup_contracts_for_testing(); + let ca_address = deploy_contract_account(kakarot_core, ca_address(), [].span()); + let contract_account = IAccountDispatcher { contract_address: ca_address.starknet }; + + let storage_slot = 0x555; + + let initial_storage = contract_account.storage(storage_slot); + assert(initial_storage == 0, 'value should be 0'); + + let expected_storage = 0x444; + start_cheat_caller_address(ca_address.starknet, kakarot_core.contract_address); + contract_account.write_storage(storage_slot, expected_storage); + stop_cheat_caller_address(ca_address.starknet); + + let storage = contract_account.storage(storage_slot); + + assert(storage == expected_storage, 'wrong contract storage'); +} + +#[test] +fn test_ca_external_starknet_call_native_token() { + let (native_token, kakarot_core) = setup_contracts_for_testing(); + let ca_address = deploy_contract_account(kakarot_core, ca_address(), [].span()); + let contract_account = IAccountDispatcher { contract_address: ca_address.starknet }; + fund_account_with_native_token(ca_address.starknet, native_token, 0x1); + + let call = Call { + to: native_token.contract_address, + selector: selector!("balanceOf"), + calldata: array![ca_address.starknet.into()].span(), + }; + start_cheat_caller_address(ca_address.starknet, kakarot_core.contract_address); + let (success, data) = contract_account.execute_starknet_call(call); + stop_cheat_caller_address(ca_address.starknet); + + assert(success, 'execute_starknet_call failed'); + assert(data.len() == 2, 'wrong return data length'); + let balance = native_token.balanceOf(ca_address.starknet); + assert((*data[0], *data[1]) == (balance.low.into(), balance.high.into()), 'wrong return data'); +} + +#[test] +fn test_ca_external_starknet_call_kakarot_get_starknet_address() { + let (_, kakarot_core) = setup_contracts_for_testing(); + let ca_address = deploy_contract_account(kakarot_core, ca_address(), [].span()); + let contract_account = IAccountDispatcher { contract_address: ca_address.starknet }; + + let call = Call { + to: kakarot_core.contract_address, selector: selector!("get_starknet_address"), calldata: [ + ca_address.evm.into() + ].span(), + }; + start_cheat_caller_address(ca_address.starknet, kakarot_core.contract_address); + let (success, data) = contract_account.execute_starknet_call(call); + stop_cheat_caller_address(ca_address.starknet); + + assert(success, 'execute_starknet_call failed'); + assert(data.len() == 1, 'wrong return data length'); + assert(*data[0] == ca_address.starknet.try_into().unwrap(), 'wrong return data'); +} + +#[test] +fn test_ca_external_starknet_call_cannot_call_kakarot_other_selector() { + let (_, kakarot_core) = setup_contracts_for_testing(); + let ca_address = deploy_contract_account(kakarot_core, ca_address(), [].span()); + let contract_account = IAccountDispatcher { contract_address: ca_address.starknet }; + + let call = Call { + to: kakarot_core.contract_address, + selector: selector!("get_native_token"), + calldata: [].span(), + }; + start_cheat_caller_address(ca_address.starknet, kakarot_core.contract_address); + let (success, data) = contract_account.execute_starknet_call(call); + stop_cheat_caller_address(ca_address.starknet); + + assert(!success, 'execute_starknet_call failed'); + assert(data.len() == 19, 'wrong return data length'); + assert(data == KAKAROT_REENTRANCY.span(), 'wrong return data'); +} diff --git a/kakarot-ssj/crates/contracts/tests/test_cairo1_helpers.cairo b/kakarot-ssj/crates/contracts/tests/test_cairo1_helpers.cairo new file mode 100644 index 000000000..ace7677d7 --- /dev/null +++ b/kakarot-ssj/crates/contracts/tests/test_cairo1_helpers.cairo @@ -0,0 +1,20 @@ +use contracts::cairo1_helpers::Cairo1Helpers; +use utils::traits::integer::BytesUsedTrait; + +#[test] +fn test_keccak() { + // "Hello world!" + // where: + // 8031924123371070792 == int.from_bytes(b'Hello wo', 'little') + // 560229490 == int.from_bytes(b'rld!', 'little') + let input = array![8031924123371070792]; + let last_input_word: u64 = 560229490; + let last_input_num_bytes = last_input_word.bytes_used(); + let state = Cairo1Helpers::contract_state_for_testing(); + + let res = Cairo1Helpers::Helpers::keccak( + @state, input, last_input_word, last_input_num_bytes.into() + ); + + assert_eq!(res, 0xecd0e108a98e192af1d2c25055f4e3bed784b5c877204e73219a5203251feaab); +} diff --git a/kakarot-ssj/crates/contracts/tests/test_execution_from_outside.cairo b/kakarot-ssj/crates/contracts/tests/test_execution_from_outside.cairo new file mode 100644 index 000000000..9daff0fe4 --- /dev/null +++ b/kakarot-ssj/crates/contracts/tests/test_execution_from_outside.cairo @@ -0,0 +1,545 @@ +use contracts::account_contract::{ + AccountContract, IAccountDispatcher, IAccountDispatcherTrait, OutsideExecution +}; +use contracts::kakarot_core::interface::{ + IExtendedKakarotCoreDispatcher, IExtendedKakarotCoreDispatcherTrait +}; +use contracts::test_data::{counter_evm_bytecode, eip_2930_rlp_encoded_counter_inc_tx,}; +use contracts::test_utils::{ + setup_contracts_for_testing, deploy_contract_account, fund_account_with_native_token, + call_transaction +}; +use core::num::traits::Bounded; +use core::starknet::account::Call; +use core::starknet::secp256_trait::Signature; +use core::starknet::{ContractAddress, contract_address_const, EthAddress, Event}; +use evm::test_utils::chain_id; +use evm::test_utils::other_evm_address; +use openzeppelin::token::erc20::interface::IERC20CamelDispatcher; +use snforge_std::{ + start_cheat_caller_address, stop_cheat_caller_address, start_cheat_transaction_hash, spy_events, + EventSpyTrait, CheatSpan, cheat_caller_address, stop_cheat_block_timestamp, + start_cheat_block_timestamp, start_cheat_chain_id_global, stop_cheat_chain_id_global, + start_cheat_caller_address_global, stop_cheat_caller_address_global +}; + +use snforge_utils::snforge_utils::EventsFilterBuilderTrait; +use utils::eth_transaction::transaction::Transaction; +use utils::eth_transaction::tx_type::TxType; +use utils::helpers::u256_to_bytes_array; +use utils::serialization::{serialize_bytes, serialize_transaction_signature}; +use utils::test_data::{legacy_rlp_encoded_tx, eip_2930_encoded_tx, eip_1559_encoded_tx}; + +fn transaction_signer() -> EthAddress { + 0x6Bd85F39321B00c6d603474C5B2fddEB9c92A466.try_into().unwrap() +} + +const PLACEHOLDER_SIGNATURE: [felt252; 5] = [1, 2, 3, 4, 0]; + +const SNIP9_CALLER: felt252 = 0xaA36F24f65b5F0f2c642323f3d089A3F0f2845Bf; + +#[derive(Drop)] +struct CallBuilder { + call: Call +} + +#[generate_trait] +impl CallBuilderImpl of CallBuilderTrait { + fn new(kakarot_core: ContractAddress) -> CallBuilder { + CallBuilder { + call: Call { + to: kakarot_core, + selector: selector!("eth_send_transaction"), + calldata: serialize_bytes(eip_2930_encoded_tx()).span() + } + } + } + + fn with_to(mut self: CallBuilder, to: ContractAddress) -> CallBuilder { + self.call.to = to; + self + } + + fn with_selector(mut self: CallBuilder, selector: felt252) -> CallBuilder { + self.call.selector = selector; + self + } + + fn with_calldata(mut self: CallBuilder, calldata: Span) -> CallBuilder { + self.call.calldata = serialize_bytes(calldata).span(); + self + } + + fn build(mut self: CallBuilder) -> Call { + return self.call; + } +} + +#[derive(Drop)] +struct OutsideExecutionBuilder { + outside_execution: OutsideExecution +} + +#[generate_trait] +impl OutsideExecutionBuilderImpl of OutsideExecutionBuilderTrait { + fn new(kakarot_core: ContractAddress) -> OutsideExecutionBuilder { + OutsideExecutionBuilder { + outside_execution: OutsideExecution { + caller: 'ANY_CALLER'.try_into().unwrap(), + nonce: 0, + execute_after: 998, + execute_before: 1000, + calls: [ + CallBuilderTrait::new(kakarot_core).build(), + ].span() + } + } + } + + fn with_caller( + mut self: OutsideExecutionBuilder, caller: ContractAddress + ) -> OutsideExecutionBuilder { + self.outside_execution.caller = caller; + self + } + + fn with_nonce(mut self: OutsideExecutionBuilder, nonce: u64) -> OutsideExecutionBuilder { + self.outside_execution.nonce = nonce; + self + } + + fn with_execute_after( + mut self: OutsideExecutionBuilder, execute_after: u64 + ) -> OutsideExecutionBuilder { + self.outside_execution.execute_after = execute_after; + self + } + + fn with_execute_before( + mut self: OutsideExecutionBuilder, execute_before: u64 + ) -> OutsideExecutionBuilder { + self.outside_execution.execute_before = execute_before; + self + } + + fn with_calls(mut self: OutsideExecutionBuilder, calls: Span) -> OutsideExecutionBuilder { + self.outside_execution.calls = calls; + self + } + + fn build(mut self: OutsideExecutionBuilder) -> OutsideExecution { + return self.outside_execution; + } +} + +fn set_up() -> (IExtendedKakarotCoreDispatcher, IAccountDispatcher, IERC20CamelDispatcher) { + let (native_token, kakarot_core) = setup_contracts_for_testing(); + // When we deploy the EOA, we use get_caller_address to get the address of the KakarotCore + // contract and set the caller address to that. + // Therefore, we need to stop the global caller address cheat so that the EOA is deployed + // by the real KakarotCore contract and not the one impersonated by the cheat + stop_cheat_caller_address_global(); + let eoa = IAccountDispatcher { + contract_address: kakarot_core.deploy_externally_owned_account(transaction_signer()) + }; + start_cheat_caller_address_global(kakarot_core.contract_address); + + start_cheat_block_timestamp(eoa.contract_address, 999); + start_cheat_chain_id_global(chain_id().into()); + + (kakarot_core, eoa, native_token) +} + +fn tear_down(contract_account: IAccountDispatcher) { + stop_cheat_chain_id_global(); + stop_cheat_block_timestamp(contract_account.contract_address); +} + +#[test] +#[should_panic(expected: 'SNIP9: Invalid caller')] +fn test_execute_from_outside_invalid_caller() { + let (kakarot_core, contract_account, _) = set_up(); + + let outside_execution = OutsideExecutionBuilderTrait::new(kakarot_core.contract_address) + .with_caller(contract_address_const::<0xb0b>()) + .build(); + let signature = PLACEHOLDER_SIGNATURE.span(); + + let _ = contract_account.execute_from_outside(outside_execution, signature); + + tear_down(contract_account); +} + +#[test] +#[should_panic(expected: 'SNIP9: Too early call')] +fn test_execute_from_outside_too_early_call() { + let (kakarot_core, contract_account, _) = set_up(); + + let outside_execution = OutsideExecutionBuilderTrait::new(kakarot_core.contract_address) + .with_execute_after(999) + .build(); + let signature = PLACEHOLDER_SIGNATURE.span(); + + let _ = contract_account.execute_from_outside(outside_execution, signature); + + tear_down(contract_account); +} + +#[test] +#[should_panic(expected: 'SNIP9: Too late call')] +fn test_execute_from_outside_too_late_call() { + let (kakarot_core, contract_account, _) = set_up(); + + let outside_execution = OutsideExecutionBuilderTrait::new(kakarot_core.contract_address) + .with_execute_before(999) + .build(); + let signature = PLACEHOLDER_SIGNATURE.span(); + + let _ = contract_account.execute_from_outside(outside_execution, signature); + + tear_down(contract_account); +} + +#[test] +#[should_panic(expected: 'EOA: Invalid signature length')] +fn test_execute_from_outside_inPLACEHOLDER_SIGNATURE_length() { + let (kakarot_core, contract_account, _) = set_up(); + + let outside_execution = OutsideExecutionBuilderTrait::new(kakarot_core.contract_address) + .build(); + + let _ = contract_account.execute_from_outside(outside_execution, [].span()); + + tear_down(contract_account); +} + +#[test] +#[should_panic(expected: 'KKRT: Multicall not supported')] +fn test_execute_from_outside_multicall_not_supported() { + let (kakarot_core, contract_account, _) = set_up(); + + let outside_execution = OutsideExecutionBuilderTrait::new(kakarot_core.contract_address) + .with_calls( + [ + CallBuilderTrait::new(kakarot_core.contract_address).build(), + CallBuilderTrait::new(kakarot_core.contract_address).build(), + ].span() + ) + .build(); + let signature = PLACEHOLDER_SIGNATURE.span(); + + let _ = contract_account.execute_from_outside(outside_execution, signature); + + tear_down(contract_account); +} + +#[test] +#[should_panic(expected: 'EOA: invalid signature')] +fn test_execute_from_outside_invalid_signature() { + let (kakarot_core, contract_account, _) = set_up(); + + let caller = contract_address_const::(); + + let outside_execution = OutsideExecutionBuilderTrait::new(kakarot_core.contract_address) + .with_caller(caller) + .build(); + let signature: Span = [1, 2, 3, 4, (chain_id() * 2 + 40).into()].span(); + + start_cheat_caller_address(contract_account.contract_address, caller); + let _ = contract_account.execute_from_outside(outside_execution, signature); + + tear_down(contract_account); +} + +#[test] +#[should_panic(expected: 'EOA: could not decode tx')] +fn test_execute_from_outside_invalid_tx() { + let (kakarot_core, contract_account, _) = set_up(); + + let mut faulty_eip_2930_tx = eip_2930_encoded_tx(); + let signature = Signature { + r: 0x5c4ae1ed01c8df4277f02aa3443f8183ed44627217fd7f27badaed8795906e78, + s: 0x4d2af576441428d47c174ffddc6e70b980527a57795b3c87a71878f97ecef274, + y_parity: true + }; + let _ = faulty_eip_2930_tx.pop_front(); + + let outside_execution = OutsideExecutionBuilderTrait::new(kakarot_core.contract_address) + .with_calls( + [ + CallBuilderTrait::new(kakarot_core.contract_address) + .with_calldata(faulty_eip_2930_tx) + .build() + ].span() + ) + .build(); + + let signature = serialize_transaction_signature(signature, TxType::Eip2930, chain_id()).span(); + + let _ = contract_account.execute_from_outside(outside_execution, signature); + + tear_down(contract_account); +} + +#[test] +#[should_panic(expected: 'KKRT: Multicall not supported')] +fn test_execute_from_outside_should_fail_with_zero_calls() { + let (kakarot_core, contract_account, _) = set_up(); + + let outside_execution = OutsideExecutionBuilderTrait::new(kakarot_core.contract_address) + .with_calls([].span()) + .build(); + let signature = PLACEHOLDER_SIGNATURE.span(); + + let _ = contract_account.execute_from_outside(outside_execution, signature); + + tear_down(contract_account); +} + +#[test] +#[should_panic(expected: 'EOA: cannot have code')] +fn test_execute_from_outside_should_fail_account_with_code() { + let (kakarot_core, _, _) = set_up(); + + let contract_address = deploy_contract_account( + kakarot_core, other_evm_address(), counter_evm_bytecode() + ) + .starknet; + let contract_account = IAccountDispatcher { contract_address }; + + let outside_execution = OutsideExecutionBuilderTrait::new(kakarot_core.contract_address) + .build(); + let signature = PLACEHOLDER_SIGNATURE.span(); + + start_cheat_block_timestamp(contract_account.contract_address, 999); + let _ = contract_account.execute_from_outside(outside_execution, signature); + + tear_down(contract_account); +} + + +#[test] +#[should_panic(expected: 'KKRT: Multicall not supported')] +fn test_execute_from_outside_should_fail_with_multi_calls() { + let (kakarot_core, eoa, _) = set_up(); + + let outside_execution = OutsideExecutionBuilderTrait::new(kakarot_core.contract_address) + .with_calls( + [ + CallBuilderTrait::new(kakarot_core.contract_address) + .with_calldata(legacy_rlp_encoded_tx()) + .build() + ; 2].span() + ) + .build(); + let signature = PLACEHOLDER_SIGNATURE.span(); + + let _ = eoa.execute_from_outside(outside_execution, signature); + + tear_down(eoa); +} + + +#[test] +fn test_execute_from_outside_legacy_tx() { + let (kakarot_core, eoa, native_token) = set_up(); + fund_account_with_native_token(eoa.contract_address, native_token, Bounded::::MAX.into()); + + let caller = contract_address_const::(); + + let outside_execution = OutsideExecutionBuilderTrait::new(kakarot_core.contract_address) + .with_caller(caller) + .with_calls( + [ + CallBuilderTrait::new(kakarot_core.contract_address) + .with_calldata(legacy_rlp_encoded_tx()) + .build() + ].span() + ) + .build(); + + // to reproduce locally: + // run: cp .env.example .env + // bun install & bun run scripts/compute_rlp_encoding.ts + + let signature = serialize_transaction_signature( + Signature { + r: 0xf2805d01dd4fa240c79039c85a77554fc186cc73c2025d7f8c02bc8fe1a982b5, + s: 0x27ff351275563c1a29ab9eaeec4a3b63fbc4035d6da6b8b6af52c7993b5869ec, + y_parity: true + }, + TxType::Legacy, + chain_id() + ) + .span(); + + cheat_caller_address(eoa.contract_address, caller, CheatSpan::TargetCalls(1)); + stop_cheat_caller_address(kakarot_core.contract_address); + let data = eoa.execute_from_outside(outside_execution, signature); + + assert_eq!(data.len(), 1); + assert_eq!(*data[0], [].span()); + + stop_cheat_caller_address(eoa.contract_address); + tear_down(eoa); +} + +#[test] +fn test_execute_from_outside_eip2930_tx() { + let (kakarot_core, eoa, native_token) = set_up(); + fund_account_with_native_token(eoa.contract_address, native_token, Bounded::::MAX.into()); + let caller = contract_address_const::(); + + // Signature for the default eip2930 tx + let signature = Signature { + r: 0x5c4ae1ed01c8df4277f02aa3443f8183ed44627217fd7f27badaed8795906e78, + s: 0x4d2af576441428d47c174ffddc6e70b980527a57795b3c87a71878f97ecef274, + y_parity: true + }; + + // Defaults with an eip2930 tx + let outside_execution = OutsideExecutionBuilderTrait::new(kakarot_core.contract_address) + .with_caller(caller) + .build(); + let signature = serialize_transaction_signature(signature, TxType::Eip2930, chain_id()).span(); + + cheat_caller_address(eoa.contract_address, caller, CheatSpan::TargetCalls(1)); + stop_cheat_caller_address(kakarot_core.contract_address); + let data = eoa.execute_from_outside(outside_execution, signature); + + assert_eq!(data.len(), 1); + assert_eq!(*data[0], [].span()); + + stop_cheat_caller_address(eoa.contract_address); + tear_down(eoa); +} + + +#[test] +fn test_execute_from_outside_eip1559_tx() { + let (kakarot_core, eoa, native_token) = set_up(); + fund_account_with_native_token(eoa.contract_address, native_token, Bounded::::MAX.into()); + + let caller = contract_address_const::(); + + let outside_execution = OutsideExecutionBuilderTrait::new(kakarot_core.contract_address) + .with_caller(caller) + .with_calls( + [ + CallBuilderTrait::new(kakarot_core.contract_address) + .with_calldata(eip_1559_encoded_tx()) + .build() + ].span() + ) + .build(); + + // to reproduce locally: + // run: cp .env.example .env + // bun install & bun run scripts/compute_rlp_encoding.ts + let signature = Signature { + r: 0xb2563dbafa29dd6f126f0e6581b772d3f07063e2f07fb7bdf73aad34a04c4283, + s: 0x73df539e40359b81b8f260ed04431de098fc149bc5e27120e6711acabaecd067, + y_parity: true + }; + let signature = serialize_transaction_signature(signature, TxType::Eip1559, chain_id()).span(); + + // Stop all cheats and only mock the EFO caller. + stop_cheat_caller_address_global(); + cheat_caller_address(eoa.contract_address, caller, CheatSpan::TargetCalls(1)); + let data = eoa.execute_from_outside(outside_execution, signature); + + assert_eq!(data.len(), 1); + assert_eq!(*data[0], [].span()); + + tear_down(eoa); +} + +#[test] +fn test_execute_from_outside_eip_2930_counter_inc_tx() { + let (kakarot_core, eoa, native_token) = set_up(); + fund_account_with_native_token(eoa.contract_address, native_token, Bounded::::MAX.into()); + + let kakarot_address = kakarot_core.contract_address; + + deploy_contract_account(kakarot_core, other_evm_address(), counter_evm_bytecode()); + + start_cheat_caller_address(kakarot_address, eoa.contract_address); + + // Then + // selector: function get() + let data_get_tx = [0x6d, 0x4c, 0xe6, 0x3c].span(); + + // check counter value is 0 before doing inc + let tx = call_transaction(chain_id(), Option::Some(other_evm_address()), data_get_tx); + + let (_, return_data, _) = kakarot_core + .eth_call(origin: transaction_signer(), tx: Transaction::Legacy(tx),); + + assert_eq!(return_data, u256_to_bytes_array(0).span()); + + // perform inc on the counter + let call = Call { + to: kakarot_address, + selector: selector!("eth_send_transaction"), + calldata: serialize_bytes(eip_2930_rlp_encoded_counter_inc_tx()).span() + }; + + start_cheat_transaction_hash(eoa.contract_address, selector!("transaction_hash")); + start_cheat_block_timestamp(eoa.contract_address, 100); + cheat_caller_address( + eoa.contract_address, contract_address_const::<0>(), CheatSpan::TargetCalls(1) + ); + let mut spy = spy_events(); + let outside_execution = OutsideExecution { + caller: contract_address_const::<'ANY_CALLER'>(), + nonce: 0, + execute_after: 0, + execute_before: 10000000, + calls: array![call].span() + }; + let signature = Signature { + r: 0x8cd55583b5da62b3fd23586bf4f1ffd496046b9d248a7983ec41bd6fb673f379, + s: 0x09432a74ec3720a226ac040ce828f92e22350c4d8f7b188693cad035e99372ed, + y_parity: true + }; + let signature = serialize_transaction_signature(signature, TxType::Eip2930, chain_id()).span(); + stop_cheat_caller_address(kakarot_core.contract_address); + let result = eoa.execute_from_outside(outside_execution, signature); + assert_eq!(result.len(), 1); + + let expected_event = AccountContract::Event::transaction_executed( + AccountContract::TransactionExecuted { + response: *result.span()[0], success: true, gas_used: 0 + } + ); + let mut keys = array![]; + let mut data = array![]; + expected_event.append_keys_and_data(ref keys, ref data); + let mut contract_events = EventsFilterBuilderTrait::from_events(@spy.get_events()) + .with_contract_address(eoa.contract_address) + .with_keys(keys.span()) + .build(); + + let mut received_keys = contract_events.events[0].keys.span(); + let mut received_data = contract_events.events[0].data.span(); + let deserialized_received: AccountContract::Event = Event::deserialize( + ref received_keys, ref received_data + ) + .unwrap(); + if let AccountContract::Event::transaction_executed(transaction_executed) = + deserialized_received { + let expected_response = *result.span()[0]; + let expected_success = true; + let not_expected_gas_used = 0; + assert_eq!(transaction_executed.response, expected_response); + assert_eq!(transaction_executed.success, expected_success); + assert_ne!(transaction_executed.gas_used, not_expected_gas_used); + } else { + panic!("Expected transaction_executed event"); + } + // check counter value has increased + let tx = call_transaction(chain_id(), Option::Some(other_evm_address()), data_get_tx); + let (_, return_data, _) = kakarot_core + .eth_call(origin: transaction_signer(), tx: Transaction::Legacy(tx),); + assert_eq!(return_data, u256_to_bytes_array(1).span()); +} diff --git a/kakarot-ssj/crates/contracts/tests/test_kakarot_core.cairo b/kakarot-ssj/crates/contracts/tests/test_kakarot_core.cairo new file mode 100644 index 000000000..89bcde981 --- /dev/null +++ b/kakarot-ssj/crates/contracts/tests/test_kakarot_core.cairo @@ -0,0 +1,383 @@ +use contracts::account_contract::{IAccountDispatcher, IAccountDispatcherTrait}; +use contracts::kakarot_core::interface::IExtendedKakarotCoreDispatcherTrait; +use contracts::kakarot_core::{KakarotCore}; +use contracts::test_contracts::test_upgradeable::{ + IMockContractUpgradeableDispatcher, IMockContractUpgradeableDispatcherTrait +}; +use contracts::test_data::{deploy_counter_calldata, counter_evm_bytecode}; +use contracts::{test_utils as contract_utils,}; +use core::num::traits::Zero; +use core::ops::SnapshotDeref; +use core::option::OptionTrait; +use core::starknet::storage::StoragePathEntry; +use core::starknet::{contract_address_const, ContractAddress, EthAddress, ClassHash}; + + +use core::traits::TryInto; +use evm::test_utils::chain_id; +use evm::test_utils; +use snforge_std::{ + declare, DeclareResultTrait, start_cheat_caller_address, spy_events, EventSpyTrait, + cheat_caller_address, CheatSpan, store +}; +use snforge_utils::snforge_utils::{EventsFilterBuilderTrait, ContractEventsTrait}; +use starknet::storage::StorageTrait; +use utils::eth_transaction::legacy::TxLegacy; +use utils::eth_transaction::transaction::Transaction; +use utils::helpers::{u256_to_bytes_array}; +use utils::traits::eth_address::EthAddressExTrait; + +#[test] +fn test_kakarot_core_owner() { + let (_, kakarot_core) = contract_utils::setup_contracts_for_testing(); + + assert(kakarot_core.owner() == test_utils::other_starknet_address(), 'wrong owner') +} + +#[test] +fn test_kakarot_core_transfer_ownership() { + let (_, kakarot_core) = contract_utils::setup_contracts_for_testing(); + + assert(kakarot_core.owner() == test_utils::other_starknet_address(), 'wrong owner'); + start_cheat_caller_address(kakarot_core.contract_address, test_utils::other_starknet_address()); + kakarot_core.transfer_ownership(test_utils::starknet_address()); + assert(kakarot_core.owner() == test_utils::starknet_address(), 'wrong owner') +} + +#[test] +fn test_kakarot_core_renounce_ownership() { + let (_, kakarot_core) = contract_utils::setup_contracts_for_testing(); + + assert(kakarot_core.owner() == test_utils::other_starknet_address(), 'wrong owner'); + start_cheat_caller_address(kakarot_core.contract_address, test_utils::other_starknet_address()); + kakarot_core.renounce_ownership(); + assert(kakarot_core.owner() == contract_address_const::<0x00>(), 'wrong owner') +} + +#[test] +fn test_kakarot_core_chain_id() { + contract_utils::setup_contracts_for_testing(); + + assert(chain_id() == test_utils::chain_id(), 'wrong chain id'); +} + +#[test] +fn test_kakarot_core_set_native_token() { + let (native_token, kakarot_core) = contract_utils::setup_contracts_for_testing(); + + assert(kakarot_core.get_native_token() == native_token.contract_address, 'wrong native_token'); + + start_cheat_caller_address(kakarot_core.contract_address, test_utils::other_starknet_address()); + kakarot_core.set_native_token(contract_address_const::<0xdead>()); + assert( + kakarot_core.get_native_token() == contract_address_const::<0xdead>(), + 'wrong new native_token' + ); +} + +#[test] +fn test_kakarot_core_deploy_eoa() { + let (_, kakarot_core) = contract_utils::setup_contracts_for_testing(); + let mut spy = spy_events(); + let eoa_starknet_address = kakarot_core + .deploy_externally_owned_account(test_utils::evm_address()); + + let expected = KakarotCore::Event::AccountDeployed( + KakarotCore::AccountDeployed { + evm_address: test_utils::evm_address(), starknet_address: eoa_starknet_address + } + ); + let contract_events = EventsFilterBuilderTrait::from_events(@spy.get_events()) + .with_contract_address(kakarot_core.contract_address) + .build(); + contract_events.assert_emitted(@expected); +} + +#[test] +fn test_kakarot_core_eoa_mapping() { + // Given + let (_, kakarot_core) = contract_utils::setup_contracts_for_testing(); + assert( + kakarot_core.address_registry(test_utils::evm_address()).is_zero(), + 'should be uninitialized' + ); + + let expected_eoa_starknet_address = kakarot_core + .deploy_externally_owned_account(test_utils::evm_address()); + + // When + let address = kakarot_core.address_registry(test_utils::evm_address()); + + // Then + assert_eq!(address, expected_eoa_starknet_address); + + let another_sn_address: ContractAddress = 0xbeef.try_into().unwrap(); + + // Set the address registry to the another_sn_address + let mut kakarot_state = KakarotCore::unsafe_new_contract_state(); + let map_entry_address = kakarot_state + .snapshot_deref() + .storage() + .Kakarot_evm_to_starknet_address + .entry(test_utils::evm_address()) + .deref() + .__storage_pointer_address__; + store( + kakarot_core.contract_address, map_entry_address.into(), [another_sn_address.into()].span() + ); + + let address = kakarot_core.address_registry(test_utils::evm_address()); + assert_eq!(address, another_sn_address) +} + +#[test] +fn test_kakarot_core_compute_starknet_address() { + let evm_address = test_utils::evm_address(); + let (_, kakarot_core) = contract_utils::setup_contracts_for_testing(); + let expected_starknet_address = kakarot_core.deploy_externally_owned_account(evm_address); + + let actual_starknet_address = kakarot_core.compute_starknet_address(evm_address); + assert_eq!(actual_starknet_address, expected_starknet_address); +} + +#[test] +fn test_kakarot_core_upgrade_contract() { + let (_, kakarot_core) = contract_utils::setup_contracts_for_testing(); + + let class_hash: ClassHash = (*declare("MockContractUpgradeableV1") + .unwrap() + .contract_class() + .class_hash); + + start_cheat_caller_address(kakarot_core.contract_address, test_utils::other_starknet_address()); + kakarot_core.upgrade(class_hash); + + let version = IMockContractUpgradeableDispatcher { + contract_address: kakarot_core.contract_address + } + .version(); + assert(version == 1, 'version is not 1'); +} + +#[test] +fn test_eth_send_transaction_non_deploy_tx() { + // Given + let (native_token, kakarot_core) = contract_utils::setup_contracts_for_testing(); + + let evm_address = test_utils::evm_address(); + let eoa = kakarot_core.deploy_externally_owned_account(evm_address); + contract_utils::fund_account_with_native_token( + eoa, native_token, 0xfffffffffffffffffffffffffff + ); + + let counter_address = 'counter_contract'.try_into().unwrap(); + contract_utils::deploy_contract_account(kakarot_core, counter_address, counter_evm_bytecode()); + + let gas_limit = test_utils::tx_gas_limit(); + let gas_price = test_utils::gas_price(); + let value = 0; + + // Then + // selector: function get() + let data_get_tx = [0x6d, 0x4c, 0xe6, 0x3c].span(); + + // check counter value is 0 before doing inc + let tx = contract_utils::call_transaction( + chain_id(), Option::Some(counter_address), data_get_tx + ); + let (_, return_data, _) = kakarot_core + .eth_call(origin: evm_address, tx: Transaction::Legacy(tx)); + + assert_eq!(return_data, u256_to_bytes_array(0).span()); + + // selector: function inc() + let data_increment_counter = [0x37, 0x13, 0x03, 0xc0].span(); + + // When + start_cheat_caller_address(kakarot_core.contract_address, eoa); + + let tx = TxLegacy { + chain_id: Option::Some(chain_id()), + nonce: 0, + to: counter_address.into(), + value, + gas_price, + gas_limit, + input: data_increment_counter + }; + + let (success, _, _) = kakarot_core.eth_send_transaction(Transaction::Legacy(tx)); + assert!(success); + + // Then + // selector: function get() + let data_get_tx = [0x6d, 0x4c, 0xe6, 0x3c].span(); + + // check counter value is 1 + let tx = contract_utils::call_transaction( + chain_id(), Option::Some(counter_address), data_get_tx + ); + let (_, return_data, _) = kakarot_core + .eth_call(origin: evm_address, tx: Transaction::Legacy(tx)); + + // Then + assert_eq!(return_data, u256_to_bytes_array(1).span()); +} + +#[test] +fn test_eth_call() { + // Given + let (_, kakarot_core) = contract_utils::setup_contracts_for_testing(); + + let evm_address = test_utils::evm_address(); + kakarot_core.deploy_externally_owned_account(evm_address); + + let account = contract_utils::deploy_contract_account( + kakarot_core, test_utils::other_evm_address(), counter_evm_bytecode() + ); + let counter = IAccountDispatcher { contract_address: account.starknet }; + cheat_caller_address( + counter.contract_address, kakarot_core.contract_address, CheatSpan::TargetCalls(1) + ); + counter.write_storage(0, 1); + + let to = Option::Some(test_utils::other_evm_address()); + // selector: function get() + let calldata = [0x6d, 0x4c, 0xe6, 0x3c].span(); + + // When + let tx = contract_utils::call_transaction(chain_id(), to, calldata); + let (success, return_data, _) = kakarot_core + .eth_call(origin: evm_address, tx: Transaction::Legacy(tx)); + + // Then + assert_eq!(success, true); + assert_eq!(return_data, u256_to_bytes_array(1).span()); +} + + +#[test] +fn test_eth_send_transaction_deploy_tx() { + // Given + let (native_token, kakarot_core) = contract_utils::setup_contracts_for_testing(); + + let evm_address = test_utils::evm_address(); + let eoa = kakarot_core.deploy_externally_owned_account(evm_address); + contract_utils::fund_account_with_native_token( + eoa, native_token, 0xfffffffffffffffffffffffffff + ); + + let gas_limit = test_utils::tx_gas_limit(); + let gas_price = test_utils::gas_price(); + let value = 0; + + // When + // Set the contract address to the EOA address, so that the caller of the `eth_send_transaction` + // is an eoa + let tx = TxLegacy { + chain_id: Option::Some(chain_id()), + nonce: 0, + to: Option::None.into(), + value, + gas_price, + gas_limit, + input: deploy_counter_calldata() + }; + start_cheat_caller_address(kakarot_core.contract_address, eoa); + let (_, deploy_result, _) = kakarot_core.eth_send_transaction(Transaction::Legacy(tx)); + + // Then + let expected_address: EthAddress = 0x19587b345dcadfe3120272bd0dbec24741891759 + .try_into() + .unwrap(); + assert_eq!(deploy_result, expected_address.to_bytes().span()); + + // Set back the contract address to Kakarot for the calculation of the deployed SN contract + // address, where we use a kakarot internal functions and thus must "mock" its address. + let computed_sn_addr = kakarot_core.compute_starknet_address(expected_address); + let CA = IAccountDispatcher { contract_address: computed_sn_addr }; + let bytecode = CA.bytecode(); + assert_eq!(bytecode, counter_evm_bytecode()); + + // Check that the account was created and `get` returns 0. + let input = [0x6d, 0x4c, 0xe6, 0x3c].span(); + + // No need to set address back to eoa, as eth_call doesn't use the caller address. + let tx = TxLegacy { + chain_id: Option::Some(chain_id()), + nonce: 0, + to: expected_address.into(), + value, + gas_price, + gas_limit, + input + }; + let (_, result, _) = kakarot_core.eth_call(origin: evm_address, tx: Transaction::Legacy(tx)); + // Then + assert(result == u256_to_bytes_array(0).span(), 'wrong result'); +} + + +#[test] +fn test_account_class_hash() { + let (_, kakarot_core) = contract_utils::setup_contracts_for_testing(); + let uninitialized_account_class_hash = declare("UninitializedAccount") + .unwrap() + .contract_class() + .class_hash; + + let class_hash = kakarot_core.uninitialized_account_class_hash(); + + assert(class_hash == *uninitialized_account_class_hash, 'wrong class hash'); + + let new_class_hash: ClassHash = (*declare("MockContractUpgradeableV1") + .unwrap() + .contract_class() + .class_hash); + start_cheat_caller_address(kakarot_core.contract_address, test_utils::other_starknet_address()); + let mut spy = spy_events(); + kakarot_core.set_account_class_hash(new_class_hash); + + assert(kakarot_core.uninitialized_account_class_hash() == new_class_hash, 'wrong class hash'); + let expected = KakarotCore::Event::AccountClassHashChange( + KakarotCore::AccountClassHashChange { + old_class_hash: class_hash, new_class_hash: new_class_hash + } + ); + let contract_events = EventsFilterBuilderTrait::from_events(@spy.get_events()) + .with_contract_address(kakarot_core.contract_address) + .build(); + contract_events.assert_emitted(@expected); +} + +#[test] +fn test_account_contract_class_hash() { + let (_, kakarot_core) = contract_utils::setup_contracts_for_testing(); + + let account_contract_class_hash = (*declare("AccountContract") + .unwrap() + .contract_class() + .class_hash); + let class_hash = kakarot_core.get_account_contract_class_hash(); + + assert(class_hash == account_contract_class_hash, 'wrong class hash'); + + let new_class_hash: ClassHash = (*declare("MockContractUpgradeableV1") + .unwrap() + .contract_class() + .class_hash); + start_cheat_caller_address(kakarot_core.contract_address, test_utils::other_starknet_address()); + let mut spy = spy_events(); + kakarot_core.set_account_contract_class_hash(new_class_hash); + assert(kakarot_core.get_account_contract_class_hash() == new_class_hash, 'wrong class hash'); + + let expected = KakarotCore::Event::EOAClassHashChange( + KakarotCore::EOAClassHashChange { + old_class_hash: class_hash, new_class_hash: new_class_hash + } + ); + let contract_events = EventsFilterBuilderTrait::from_events(@spy.get_events()) + .with_contract_address(kakarot_core.contract_address) + .build(); + contract_events.assert_emitted(@expected); +} diff --git a/kakarot-ssj/crates/contracts/tests/test_ownable.cairo b/kakarot-ssj/crates/contracts/tests/test_ownable.cairo new file mode 100644 index 000000000..d5ac7ca2a --- /dev/null +++ b/kakarot-ssj/crates/contracts/tests/test_ownable.cairo @@ -0,0 +1,210 @@ +use contracts::components::ownable::{ownable_component}; +use contracts::test_utils::constants::{ZERO, OWNER, OTHER}; +use core::num::traits::Zero; +use core::starknet::ContractAddress; + + +use ownable_component::{InternalImpl, OwnableImpl}; +use snforge_std::{start_cheat_caller_address, spy_events, test_address, EventSpyTrait}; +use snforge_utils::snforge_utils::{EventsFilterBuilderTrait, ContractEventsTrait}; + + +#[starknet::contract] +pub mod MockContract { + use contracts::components::ownable::{ownable_component}; + + component!(path: ownable_component, storage: ownable, event: OwnableEvent); + + #[abi(embed_v0)] + impl OwnableImpl = ownable_component::Ownable; + + impl OwnableInternalImpl = ownable_component::InternalImpl; + + #[storage] + struct Storage { + #[substorage(v0)] + ownable: ownable_component::Storage + } + + + #[event] + #[derive(Drop, starknet::Event)] + pub enum Event { + OwnableEvent: ownable_component::Event + } +} +type TestingState = ownable_component::ComponentState; + +impl TestingStateDefault of Default { + fn default() -> TestingState { + ownable_component::component_state_for_testing() + } +} + +#[generate_trait] +impl TestingStateImpl of TestingStateTrait { + fn new_with(owner: ContractAddress) -> TestingState { + let mut ownable: TestingState = Default::default(); + ownable.initializer(owner); + ownable + } +} + +#[test] +fn test_ownable_initializer() { + let mut ownable: TestingState = Default::default(); + let test_address: ContractAddress = test_address(); + assert(ownable.owner().is_zero(), 'owner should be zero'); + + let mut spy = spy_events(); + ownable.initializer(OWNER()); + let expected = MockContract::Event::OwnableEvent( + ownable_component::Event::OwnershipTransferred( + ownable_component::OwnershipTransferred { previous_owner: ZERO(), new_owner: OWNER() } + ) + ); + let contract_events = EventsFilterBuilderTrait::from_events(@spy.get_events()) + .with_contract_address(test_address) + .build(); + contract_events.assert_emitted(@expected); + assert(ownable.owner() == OWNER(), 'Owner should be set'); +} + +#[test] +fn test_assert_only_owner() { + let mut ownable: TestingState = TestingStateTrait::new_with(OWNER()); + let test_address: ContractAddress = test_address(); + start_cheat_caller_address(test_address, OWNER()); + + ownable.assert_only_owner(); +} + +#[test] +#[should_panic(expected: ('Caller is not the owner',))] +fn test_assert_only_owner_not_owner() { + let mut ownable: TestingState = TestingStateTrait::new_with(OWNER()); + let test_address: ContractAddress = test_address(); + start_cheat_caller_address(test_address, OTHER()); + + ownable.assert_only_owner(); +} + +#[test] +#[should_panic(expected: ('Caller is the zero address',))] +fn test_assert_only_owner_zero() { + let mut ownable: TestingState = TestingStateTrait::new_with(OWNER()); + let test_address: ContractAddress = test_address(); + start_cheat_caller_address(test_address, ZERO()); + ownable.assert_only_owner(); +} + +#[test] +fn test__transfer_ownership() { + let mut ownable: TestingState = TestingStateTrait::new_with(OWNER()); + let test_address: ContractAddress = test_address(); + + let mut spy = spy_events(); + let expected = MockContract::Event::OwnableEvent( + ownable_component::Event::OwnershipTransferred( + ownable_component::OwnershipTransferred { previous_owner: OWNER(), new_owner: OTHER() } + ) + ); + ownable._transfer_ownership(OTHER()); + + let contract_events = EventsFilterBuilderTrait::from_events(@spy.get_events()) + .with_contract_address(test_address) + .build(); + contract_events.assert_emitted(@expected); + assert(ownable.owner() == OTHER(), 'Owner should be OTHER'); +} + + +#[test] +fn test_transfer_ownership() { + let mut ownable: TestingState = TestingStateTrait::new_with(OWNER()); + let test_address: ContractAddress = test_address(); + start_cheat_caller_address(test_address, OWNER()); + + let mut spy = spy_events(); + ownable.transfer_ownership(OTHER()); + let expected = MockContract::Event::OwnableEvent( + ownable_component::Event::OwnershipTransferred( + ownable_component::OwnershipTransferred { previous_owner: OWNER(), new_owner: OTHER() } + ) + ); + let contract_events = EventsFilterBuilderTrait::from_events(@spy.get_events()) + .with_contract_address(test_address) + .build(); + contract_events.assert_emitted(@expected); + + assert(ownable.owner() == OTHER(), 'Should transfer ownership'); +} + +#[test] +#[should_panic(expected: ('New owner is the zero address',))] +fn test_transfer_ownership_to_zero() { + let mut ownable: TestingState = TestingStateTrait::new_with(OWNER()); + let test_address: ContractAddress = test_address(); + start_cheat_caller_address(test_address, OWNER()); + + ownable.transfer_ownership(ZERO()); +} + + +#[test] +#[should_panic(expected: ('Caller is the zero address',))] +fn test_transfer_ownership_from_zero() { + let mut ownable: TestingState = Default::default(); + + ownable.transfer_ownership(OTHER()); +} + + +#[test] +#[should_panic(expected: ('Caller is not the owner',))] +fn test_transfer_ownership_from_nonowner() { + let mut ownable: TestingState = TestingStateTrait::new_with(OWNER()); + let test_address: ContractAddress = test_address(); + start_cheat_caller_address(test_address, OTHER()); + + ownable.transfer_ownership(OTHER()); +} + + +#[test] +fn test_renounce_ownership() { + let mut ownable: TestingState = TestingStateTrait::new_with(OWNER()); + let test_address: ContractAddress = test_address(); + + start_cheat_caller_address(test_address, OWNER()); + let mut spy = spy_events(); + ownable.renounce_ownership(); + let expected = MockContract::Event::OwnableEvent( + ownable_component::Event::OwnershipTransferred( + ownable_component::OwnershipTransferred { previous_owner: OWNER(), new_owner: ZERO() } + ) + ); + let contract_events = EventsFilterBuilderTrait::from_events(@spy.get_events()) + .with_contract_address(test_address) + .build(); + contract_events.assert_emitted(@expected); + + assert(ownable.owner().is_zero(), 'ownership not renounced'); +} + +#[test] +#[should_panic(expected: ('Caller is the zero address',))] +fn test_renounce_ownership_from_zero_address() { + let mut ownable: TestingState = Default::default(); + ownable.renounce_ownership(); +} + +#[test] +#[should_panic(expected: ('Caller is not the owner',))] +fn test_renounce_ownership_from_nonowner() { + let mut ownable: TestingState = TestingStateTrait::new_with(OWNER()); + let test_address: ContractAddress = test_address(); + start_cheat_caller_address(test_address, OTHER()); + + ownable.renounce_ownership(); +} diff --git a/kakarot-ssj/crates/evm/.gitignore b/kakarot-ssj/crates/evm/.gitignore new file mode 100644 index 000000000..eb5a316cb --- /dev/null +++ b/kakarot-ssj/crates/evm/.gitignore @@ -0,0 +1 @@ +target diff --git a/kakarot-ssj/crates/evm/Scarb.toml b/kakarot-ssj/crates/evm/Scarb.toml new file mode 100644 index 000000000..1180c54a4 --- /dev/null +++ b/kakarot-ssj/crates/evm/Scarb.toml @@ -0,0 +1,25 @@ +[package] +name = "evm" +version = "0.1.0" +edition = "2024_07" + +# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html + +[dependencies] +starknet.workspace = true +utils = { path = "../utils" } +contracts = { path = "../contracts" } +openzeppelin = { path = "../openzeppelin" } +garaga = { git = "https://github.com/keep-starknet-strange/garaga.git" } + +[dev-dependencies] +snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry.git", tag = "v0.31.0" } +snforge_utils = { path = "../snforge_utils" } +assert_macros = "2.8.2" + +[tool] +fmt.workspace = true + +[scripts] +test = "snforge test --max-n-steps 4294967295" +test-profiling = "snforge test --max-n-steps 4294967295 --build-profile" diff --git a/kakarot-ssj/crates/evm/src/backend.cairo b/kakarot-ssj/crates/evm/src/backend.cairo new file mode 100644 index 000000000..49f713b44 --- /dev/null +++ b/kakarot-ssj/crates/evm/src/backend.cairo @@ -0,0 +1,2 @@ +pub mod starknet_backend; +pub mod validation; diff --git a/kakarot-ssj/crates/evm/src/backend/starknet_backend.cairo b/kakarot-ssj/crates/evm/src/backend/starknet_backend.cairo new file mode 100644 index 000000000..52a0de60c --- /dev/null +++ b/kakarot-ssj/crates/evm/src/backend/starknet_backend.cairo @@ -0,0 +1,517 @@ +use contracts::account_contract::{IAccountDispatcher, IAccountDispatcherTrait}; +use contracts::kakarot_core::eth_rpc::IEthRPC; +use contracts::kakarot_core::{KakarotCore, KakarotCore::KakarotCoreImpl}; +use core::num::traits::zero::Zero; +use core::ops::SnapshotDeref; +use core::starknet::storage::StoragePointerReadAccess; +use core::starknet::syscalls::{deploy_syscall}; +use core::starknet::syscalls::{emit_event_syscall}; +use core::starknet::{EthAddress, get_block_info, SyscallResultTrait}; +use crate::errors::{ensure, EVMError}; +use crate::model::{Address, AddressTrait, Environment, Account, AccountTrait}; +use crate::model::{Transfer}; +use crate::state::{State, StateTrait}; +use openzeppelin::token::erc20::interface::{IERC20CamelDispatcher, IERC20CamelDispatcherTrait}; +use utils::constants::BURN_ADDRESS; +use utils::constants; +use utils::set::SetTrait; + + +/// Commits the state changes to Starknet. +/// +/// # Arguments +/// +/// * `state` - The state to commit. +/// +/// # Returns +/// +/// `Ok(())` if the commit was successful, otherwise an `EVMError`. +pub fn commit(ref state: State) -> Result<(), EVMError> { + commit_accounts(ref state)?; + transfer_native_token(ref state)?; + emit_events(ref state)?; + commit_storage(ref state) +} + +/// Deploys a new EOA contract. +/// +/// # Arguments +/// +/// * `evm_address` - The EVM address of the EOA to deploy. +pub fn deploy(evm_address: EthAddress) -> Result { + // Unlike CAs, there is not check for the existence of an EOA prealably to calling + // `EOATrait::deploy` - therefore, we need to check that there is no collision. + let mut is_deployed = evm_address.is_deployed(); + ensure(!is_deployed, EVMError::Collision)?; + + let mut kakarot_state = KakarotCore::unsafe_new_contract_state(); + let uninitialized_account_class_hash = kakarot_state.uninitialized_account_class_hash(); + let calldata: Span = [1, evm_address.into()].span(); + + let (starknet_address, _) = deploy_syscall( + uninitialized_account_class_hash, + contract_address_salt: evm_address.into(), + calldata: calldata, + deploy_from_zero: false + ) + .unwrap_syscall(); + + Result::Ok(Address { evm: evm_address, starknet: starknet_address }) +} + +pub fn get_bytecode(evm_address: EthAddress) -> Span { + let kakarot_state = KakarotCore::unsafe_new_contract_state(); + let starknet_address = kakarot_state.address_registry(evm_address); + if starknet_address.is_non_zero() { + let account = IAccountDispatcher { contract_address: starknet_address }; + account.bytecode() + } else { + [].span() + } +} + +/// Populate an Environment with Starknet syscalls. +pub fn get_env(origin: Address, gas_price: u128) -> Environment { + let kakarot_state = KakarotCore::unsafe_new_contract_state(); + let kakarot_storage = kakarot_state.snapshot_deref(); + let block_info = get_block_info().unbox(); + + // tx.gas_price and env.gas_price have the same values here + // - this is not always true in EVM transactions + Environment { + origin: origin, + gas_price, + chain_id: kakarot_state.eth_chain_id(), + prevrandao: kakarot_storage.Kakarot_prev_randao.read(), + block_number: block_info.block_number, + block_gas_limit: constants::BLOCK_GAS_LIMIT, + block_timestamp: block_info.block_timestamp, + coinbase: kakarot_storage.Kakarot_coinbase.read(), + base_fee: kakarot_storage.Kakarot_base_fee.read(), + state: Default::default(), + } +} + +/// Fetches the value stored at the given key for the corresponding contract accounts. +/// If the account is not deployed (in case of a create/deploy transaction), returns 0. +/// # Arguments +/// +/// * `account` The account to read from. +/// * `key` The key to read. +/// +/// # Returns +/// +/// A `Result` containing the value stored at the given key or an `EVMError` if there was an error. +pub fn fetch_original_storage(account: @Account, key: u256) -> u256 { + let is_deployed = account.evm_address().is_deployed(); + if is_deployed { + return IAccountDispatcher { contract_address: account.starknet_address() }.storage(key); + } + 0 +} + +/// Fetches the balance of the given address. +/// +/// # Arguments +/// +/// * `self` - The address to fetch the balance of. +/// +/// # Returns +/// +/// The balance of the given address. +pub fn fetch_balance(self: @Address) -> u256 { + let kakarot_state = KakarotCore::unsafe_new_contract_state(); + kakarot_state.eth_get_balance(*self.evm) +} + + +/// Commits the account changes to Starknet. +/// +/// # Arguments +/// +/// * `state` - The state containing the accounts to commit. +/// +/// # Returns +/// +/// `Ok(())` if the commit was successful, otherwise an `EVMError`. +fn commit_accounts(ref state: State) -> Result<(), EVMError> { + let mut account_keys = state.accounts.keyset.to_span(); + for evm_address in account_keys { + let account = state.accounts.changes.get(*evm_address).deref(); + commit_account(@account, ref state); + }; + return Result::Ok(()); +} + +/// Commits the account to Starknet by updating the account state if it +/// exists, or deploying a new account if it doesn't. +/// +/// # Arguments +/// * `self` - The account to commit +/// * `state` - The state, modified in the case of selfdestruct transfers +/// +/// # Returns +/// +/// `Ok(())` if the commit was successful, otherwise an `EVMError`. +fn commit_account(self: @Account, ref state: State) { + if self.evm_address().is_precompile() { + return; + } + + // Case new account + if !self.evm_address().is_deployed() { + deploy(self.evm_address()).expect('account deployment failed'); + } + + // @dev: EIP-6780 - If selfdestruct on an account created, dont commit data + // and burn any leftover balance. + if (self.is_selfdestruct() && self.is_created()) { + let kakarot_state = KakarotCore::unsafe_new_contract_state(); + let burn_starknet_address = kakarot_state + .compute_starknet_address(BURN_ADDRESS.try_into().unwrap()); + let burn_address = Address { + starknet: burn_starknet_address, evm: BURN_ADDRESS.try_into().unwrap() + }; + state + .add_transfer( + Transfer { sender: self.address(), recipient: burn_address, amount: self.balance() } + ) + .expect('Failed to burn on selfdestruct'); + return; + } + + if !self.has_code_or_nonce() { + // Nothing to commit + return; + } + + // Write updated nonce and storage + //TODO: storage commits are done in the State commitment as they're not part of the account + //model in SSJ + let starknet_account = IAccountDispatcher { contract_address: self.starknet_address() }; + starknet_account.set_nonce(*self.nonce); + + //Storage is handled outside of the account and must be committed after all accounts are + //committed. + if self.is_created() { + starknet_account.write_bytecode(self.bytecode()); + starknet_account.set_code_hash(self.code_hash()); + //TODO: save valid jumpdests https://github.com/kkrt-labs/kakarot-ssj/issues/839 + } + return; +} + +/// Iterates through the list of pending transfer and triggers them +fn transfer_native_token(ref self: State) -> Result<(), EVMError> { + let kakarot_state = KakarotCore::unsafe_new_contract_state(); + let native_token = kakarot_state.get_native_token(); + while let Option::Some(transfer) = self.transfers.pop_front() { + IERC20CamelDispatcher { contract_address: native_token } + .transferFrom(transfer.sender.starknet, transfer.recipient.starknet, transfer.amount); + }; + Result::Ok(()) +} + +/// Iterates through the list of events and emits them. +fn emit_events(ref self: State) -> Result<(), EVMError> { + while let Option::Some(event) = self.events.pop_front() { + let mut keys = Default::default(); + let mut data = Default::default(); + Serde::>::serialize(@event.keys, ref keys); + Serde::>::serialize(@event.data, ref data); + emit_event_syscall(keys.span(), data.span()).unwrap_syscall(); + }; + return Result::Ok(()); +} + +/// Commits storage changes to the KakarotCore contract by writing pending +/// state changes to Starknet Storage. +/// commit_storage MUST be called after commit_accounts. +fn commit_storage(ref self: State) -> Result<(), EVMError> { + let mut storage_keys = self.accounts_storage.keyset.to_span(); + for state_key in storage_keys { + let (evm_address, key, value) = self.accounts_storage.changes.get(*state_key).deref(); + let mut account = self.get_account(evm_address); + // @dev: EIP-6780 - If selfdestruct on an account created, dont commit data + if account.is_selfdestruct() && account.is_created() { + continue; + } + IAccountDispatcher { contract_address: account.starknet_address() } + .write_storage(key, value); + }; + Result::Ok(()) +} + +#[cfg(test)] +mod tests { + use core::starknet::ClassHash; + use crate::backend::starknet_backend; + use crate::model::Address; + use crate::model::account::Account; + use crate::state::{State, StateTrait}; + use crate::test_utils::{ + setup_test_environment, uninitialized_account, account_contract, register_account + }; + use crate::test_utils::{evm_address}; + use snforge_std::{test_address, start_mock_call, get_class_hash}; + use snforge_utils::snforge_utils::{assert_not_called, assert_called}; + use super::commit_storage; + use utils::helpers::compute_starknet_address; + use utils::traits::bytes::U8SpanExTrait; + + // Helper function to create a test account + fn create_test_account(is_selfdestruct: bool, is_created: bool, id: felt252) -> Account { + let evm_address = (evm_address().into() + id).try_into().unwrap(); + let starknet_address = (0x5678 + id).try_into().unwrap(); + Account { + address: Address { evm: evm_address, starknet: starknet_address }, + nonce: 0, + code: [].span(), + code_hash: 0, + balance: 0, + selfdestruct: is_selfdestruct, + is_created: is_created, + } + } + + mod test_commit_storage { + use snforge_std::start_mock_call; + use snforge_utils::snforge_utils::{assert_called_with, assert_not_called}; + use super::{create_test_account, StateTrait, commit_storage}; + + #[test] + fn test_commit_storage_normal_case() { + let mut state = Default::default(); + let account = create_test_account(false, false, 0); + state.set_account(account); + + let key = 0x100; + let value = 0x200; + state.write_state(account.address.evm, key, value); + + // Mock the write_storage call + start_mock_call::<()>(account.address.starknet, selector!("write_storage"), ()); + + commit_storage(ref state).expect('commit storage failed'); + + //TODO(starknet-foundry): verify call args in assert_called + assert_called_with::< + (u256, u256) + >(account.address.starknet, selector!("write_storage"), (key, value)); + } + + #[test] + fn test_commit_storage_selfdestruct_and_created() { + let mut state = Default::default(); + let account = create_test_account(true, true, 0); + state.set_account(account); + + let key = 0x100; + let value = 0x200; + state.write_state(account.address.evm, key, value); + + // Mock the write_storage call + start_mock_call::<()>(account.address.starknet, selector!("write_storage"), ()); + + commit_storage(ref state).expect('commit storage failed'); + + // Assert that write_storage was not called + assert_not_called(account.address.starknet, selector!("write_storage")); + } + + #[test] + fn test_commit_storage_only_selfdestruct() { + let mut state = Default::default(); + let account = create_test_account(true, false, 0); + state.set_account(account); + + let key = 0x100; + let value = 0x200; + state.write_state(account.address.evm, key, value); + + // Mock the write_storage call + start_mock_call::<()>(account.address.starknet, selector!("write_storage"), ()); + + commit_storage(ref state).expect('commit storage failed'); + + // Assert that write_storage was called + assert_called_with::< + (u256, u256) + >(account.address.starknet, selector!("write_storage"), (key, value)); + } + + #[test] + fn test_commit_storage_multiple_accounts() { + let mut state = Default::default(); + + // Account 0: Normal + let account0 = create_test_account(false, false, 0); + state.set_account(account0); + + // Account 1: Selfdestruct and created + let account1 = create_test_account(true, true, 1); + state.set_account(account1); + + // Account 2: Only selfdestruct + let account2 = create_test_account(true, false, 2); + state.set_account(account2); + + // Set storage for all accounts + let key = 0x100; + let value = 0x200; + state.write_state(account0.address.evm, key, value); + state.write_state(account1.address.evm, key, value); + state.write_state(account2.address.evm, key, value); + + // Mock the write_storage calls + start_mock_call::<()>(account0.address.starknet, selector!("write_storage"), ()); + start_mock_call::<()>(account1.address.starknet, selector!("write_storage"), ()); + start_mock_call::<()>(account2.address.starknet, selector!("write_storage"), ()); + + commit_storage(ref state).expect('commit storage failed'); + + // Assert that write_storage was called for accounts 1 and 3, but not for account 2 + assert_called_with::< + (u256, u256) + >(account0.address.starknet, selector!("write_storage"), (key, value)); + assert_not_called(account1.address.starknet, selector!("write_storage")); + assert_called_with::< + (u256, u256) + >(account2.address.starknet, selector!("write_storage"), (key, value)); + } + } + + #[test] + #[ignore] + //TODO(starknet-fonudry): it's impossible to deploy an un-declared class, nor is it possible to + //mock_deploy. + fn test_deploy() { + // store the classes in the context of the local execution, to be used for deploying the + // account class + setup_test_environment(); + let test_address = test_address(); + + start_mock_call::< + ClassHash + >(test_address, selector!("get_account_contract_class_hash"), account_contract()); + start_mock_call::<()>(test_address, selector!("initialize"), ()); + let eoa_address = starknet_backend::deploy(evm_address()) + .expect('deployment of EOA failed'); + + let class_hash = get_class_hash(eoa_address.starknet); + assert_eq!(class_hash, account_contract()); + } + + #[test] + #[ignore] + //TODO(starknet-foundry): it's impossible to deploy an un-declared class, nor is it possible to + //mock_deploy. + fn test_account_commit_undeployed_create_should_change_set_all() { + setup_test_environment(); + let test_address = test_address(); + let evm_address = evm_address(); + let starknet_address = compute_starknet_address( + test_address, evm_address, uninitialized_account() + ); + + let mut state: State = Default::default(); + + // When + let bytecode = [0x1].span(); + let code_hash = bytecode.compute_keccak256_hash(); + let mut account = Account { + address: Address { evm: evm_address, starknet: starknet_address }, + nonce: 420, + code: bytecode, + code_hash: code_hash, + balance: 0, + selfdestruct: false, + is_created: true, + }; + state.set_account(account); + + start_mock_call::<()>(starknet_address, selector!("set_nonce"), ()); + start_mock_call::< + ClassHash + >(test_address, selector!("get_account_contract_class_hash"), account_contract()); + starknet_backend::commit(ref state).expect('commitment failed'); + + // Then + //TODO(starknet-foundry): we should be able to assert this has been called with specific + //data, to pass in mock_call + assert_called(starknet_address, selector!("set_nonce")); + assert_not_called(starknet_address, selector!("write_bytecode")); + } + + #[test] + fn test_account_commit_deployed_and_created_should_write_code() { + setup_test_environment(); + let test_address = test_address(); + let evm_address = evm_address(); + let starknet_address = compute_starknet_address( + test_address, evm_address, uninitialized_account() + ); + register_account(evm_address, starknet_address); + + let mut state: State = Default::default(); + let bytecode = [0x1].span(); + let code_hash = bytecode.compute_keccak256_hash(); + let mut account = Account { + address: Address { evm: evm_address, starknet: starknet_address }, + nonce: 420, + code: bytecode, + code_hash: code_hash, + balance: 0, + selfdestruct: false, + is_created: true, + }; + state.set_account(account); + + start_mock_call::<()>(starknet_address, selector!("write_bytecode"), ()); + start_mock_call::<()>(starknet_address, selector!("set_code_hash"), ()); + start_mock_call::<()>(starknet_address, selector!("set_nonce"), ()); + starknet_backend::commit(ref state).expect('commitment failed'); + + // Then the account should have a new code. + //TODO(starknet-foundry): we should be able to assert this has been called with specific + //data, to pass in mock_call + assert_called(starknet_address, selector!("write_bytecode")); + assert_called(starknet_address, selector!("set_code_hash")); + assert_called(starknet_address, selector!("set_nonce")); + } +} +// #[test] +// #[ignore] +//TODO(starknet-foundry): it's impossible to deploy an un-declared class, nor is it possible to +//mock_deploy. +// fn test_exec_sstore_finalized() { // // Given +// setup_test_environment(); +// let mut vm = VMBuilderTrait::new_with_presets().build(); +// let evm_address = vm.message().target.evm; +// let starknet_address = compute_starknet_address( +// test_address(), evm_address, uninitialized_account() +// ); +// let account = Account { +// address: Address { evm: evm_address, starknet: starknet_address }, +// code: [].span(), +// nonce: 1, +// balance: 0, +// selfdestruct: false, +// is_created: false, +// }; +// let key: u256 = 0x100000000000000000000000000000001; +// let value: u256 = 0xABDE1E11A5; +// vm.stack.push(value).expect('push failed'); +// vm.stack.push(key).expect('push failed'); + +// // When + +// vm.exec_sstore().expect('exec_sstore failed'); +// starknet_backend::commit(ref vm.env.state).expect('commit storage failed'); + +// // Then +// assert(fetch_original_storage(@account, key) == value, 'wrong committed value') +// } +// } + + diff --git a/kakarot-ssj/crates/evm/src/backend/validation.cairo b/kakarot-ssj/crates/evm/src/backend/validation.cairo new file mode 100644 index 000000000..30414f5ed --- /dev/null +++ b/kakarot-ssj/crates/evm/src/backend/validation.cairo @@ -0,0 +1,322 @@ +use contracts::account_contract::{IAccountDispatcher, IAccountDispatcherTrait}; +use contracts::kakarot_core::KakarotCore; +use contracts::kakarot_core::eth_rpc::IEthRPC; +use core::num::traits::Bounded; +use core::ops::SnapshotDeref; +use core::starknet::storage::{StoragePointerReadAccess}; +use core::starknet::{get_caller_address}; +use crate::gas; +use starknet::storage::StorageTrait; +use utils::eth_transaction::check_gas_fee; +use utils::eth_transaction::transaction::{Transaction, TransactionTrait}; + +/// Validates the ethereum transaction by checking adherence to Ethereum rules regarding +/// Gas logic, nonce, chainId and required balance. +/// +/// # Returns +/// +/// * The intrinsic gas cost of the transaction +pub fn validate_eth_tx(kakarot_state: @KakarotCore::ContractState, tx: Transaction) -> u64 { + let kakarot_storage = kakarot_state.snapshot_deref().storage(); + // Validate transaction + + // Validate chain_id for post eip155 + let tx_chain_id = tx.chain_id(); + let kakarot_chain_id: u64 = kakarot_state.eth_chain_id(); + if (tx_chain_id.is_some()) { + assert(tx_chain_id.unwrap() == kakarot_chain_id, 'Invalid chain id'); + } + + // Validate nonce + let starknet_caller_address = get_caller_address(); + let account = IAccountDispatcher { contract_address: starknet_caller_address }; + let account_nonce = account.get_nonce(); + assert(account_nonce == tx.nonce(), 'Invalid nonce'); + assert(account_nonce != Bounded::::MAX, 'Nonce overflow'); + + // Validate gas + let gas_limit = tx.gas_limit(); + assert(gas_limit <= kakarot_storage.Kakarot_block_gas_limit.read(), 'Tx gas > Block gas'); + let block_base_fee = kakarot_storage.Kakarot_base_fee.read(); + let gas_fee_check = check_gas_fee( + tx.max_fee_per_gas(), tx.max_priority_fee_per_gas(), block_base_fee.into() + ); + assert!(gas_fee_check.is_ok(), "{:?}", gas_fee_check.unwrap_err()); + + // Intrinsic Gas + let intrinsic_gas = gas::calculate_intrinsic_gas_cost(@tx); + assert(gas_limit >= intrinsic_gas, 'Intrinsic gas > gas limit'); + + // Validate balance + let balance = kakarot_state.eth_get_balance(account.get_evm_address()); + let max_gas_fee = tx.gas_limit().into() * tx.max_fee_per_gas(); + let tx_cost = tx.value() + max_gas_fee.into(); + assert(tx_cost <= balance, 'Not enough ETH'); + intrinsic_gas +} + +#[cfg(test)] +mod tests { + use contracts::kakarot_core::KakarotCore; + use core::num::traits::Bounded; + use core::ops::SnapshotDeref; + use core::starknet::storage::{StorageTrait, StoragePathEntry}; + use core::starknet::{EthAddress, ContractAddress}; + use evm::gas; + use snforge_std::cheatcodes::storage::{store_felt252}; + use snforge_std::{ + start_mock_call, test_address, start_cheat_chain_id_global, store, + start_cheat_caller_address, mock_call + }; + use super::validate_eth_tx; + use utils::constants::BLOCK_GAS_LIMIT; + use utils::eth_transaction::common::TxKind; + use utils::eth_transaction::eip1559::TxEip1559; + use utils::eth_transaction::legacy::TxLegacy; + use utils::eth_transaction::transaction::Transaction; + + fn set_up() -> (KakarotCore::ContractState, ContractAddress) { + // Define the addresses used in the tests, whose calls will be mocked + let kakarot_state = KakarotCore::unsafe_new_contract_state(); + let kakarot_storage = kakarot_state.snapshot_deref().storage(); + let kakarot_address = test_address(); + let account_evm_address: EthAddress = 'account_evm_address'.try_into().unwrap(); + let account_starknet_address = 'account_starknet_address'.try_into().unwrap(); + let native_token_address = 'native_token_address'.try_into().unwrap(); + + // Set up the environment + start_cheat_chain_id_global(1); + let base_fee_storage = kakarot_storage.Kakarot_base_fee.__base_address__; + let block_gas_limit_storage = kakarot_storage.Kakarot_block_gas_limit.__base_address__; + let native_token_storage_address = kakarot_storage + .Kakarot_native_token_address + .__base_address__; + store_felt252(kakarot_address, base_fee_storage, 1_000_000_000); // 1 Gwei + store_felt252(kakarot_address, block_gas_limit_storage, BLOCK_GAS_LIMIT.into()); + store_felt252(kakarot_address, native_token_storage_address, native_token_address.into()); + let map_entry_address = kakarot_storage + .Kakarot_evm_to_starknet_address + .entry(account_evm_address) + .deref() + .__storage_pointer_address__; + store( + kakarot_address, + map_entry_address.into(), + array![account_starknet_address.into()].span() + ); + + // Mock the calls to the account contract and the native token contract + start_cheat_caller_address(kakarot_address, account_starknet_address); + start_mock_call(account_starknet_address, selector!("get_nonce"), 0); + start_mock_call( + account_starknet_address, selector!("get_evm_address"), account_evm_address + ); + start_mock_call( + native_token_address, selector!("balanceOf"), Bounded::::MAX + ); // Min to pay for gas + value + + (kakarot_state, native_token_address) + } + + #[test] + fn test_validate_eth_tx_typical_case() { + // Setup the environment + let (kakarot_state, _) = set_up(); + + // Create a transaction object for the test + let tx = Transaction::Eip1559( + TxEip1559 { + chain_id: 1, // Should match the chain_id in the environment + nonce: 0, + max_priority_fee_per_gas: 1_000_000_000, // 1 Gwei + max_fee_per_gas: 2_000_000_000, // 2 Gwei + gas_limit: 21000, // Standard gas limit for a simple transfer + to: TxKind::Call(0x1234567890123456789012345678901234567890.try_into().unwrap()), + value: 1000000000000000000_u256, // 1 ETH + input: array![].span(), + access_list: array![].span(), + } + ); + + // Test that the function performs validation and assert expected results + let intrinsic_gas = validate_eth_tx(@kakarot_state, tx); + + assert_eq!(intrinsic_gas, 21000); // Standard intrinsic gas for a simple transfer + } + + #[test] + #[should_panic(expected: ('Invalid chain id',))] + fn test_validate_eth_tx_invalid_chain_id() { + // Setup the environment + let (kakarot_state, _) = set_up(); + + // Create a transaction object for the test + let tx = Transaction::Eip1559( + TxEip1559 { + chain_id: 600, // wrong chain_id + nonce: 0, + max_priority_fee_per_gas: 1_000_000_000, // 1 Gwei + max_fee_per_gas: 2_000_000_000, // 2 Gwei + gas_limit: 21000, // Standard gas limit for a simple transfer + to: TxKind::Call(0x1234567890123456789012345678901234567890.try_into().unwrap()), + value: 1000000000000000000_u256, // 1 ETH + input: array![].span(), + access_list: array![].span(), + } + ); + + // Test that the function performs validation and assert expected results + validate_eth_tx(@kakarot_state, tx); + } + + #[test] + #[should_panic(expected: ('Invalid nonce',))] + fn test_validate_eth_tx_invalid_nonce() { + // Setup the environment + let (kakarot_state, _) = set_up(); + + // Create a transaction object for the test + let tx = Transaction::Eip1559( + TxEip1559 { + chain_id: 1, // Should match the chain_id in the environment + nonce: 600, //Invalid nonce + max_priority_fee_per_gas: 1_000_000_000, // 1 Gwei + max_fee_per_gas: 2_000_000_000, // 2 Gwei + gas_limit: 21000, // Standard gas limit for a simple transfer + to: TxKind::Call(0x1234567890123456789012345678901234567890.try_into().unwrap()), + value: 1000000000000000000_u256, // 1 ETH + input: array![].span(), + access_list: array![].span(), + } + ); + + // Test that the function performs validation and assert expected results + validate_eth_tx(@kakarot_state, tx); + } + + #[test] + #[should_panic(expected: ('Tx gas > Block gas',))] + fn test_validate_eth_tx_gas_limit_exceeds_block_gas_limit() { + // Setup the environment + let (kakarot_state, _) = set_up(); + + // Create a transaction object for the test + let tx = Transaction::Eip1559( + TxEip1559 { + chain_id: 1, // Should match the chain_id in the environment + nonce: 0, + max_priority_fee_per_gas: 1_000_000_000, // 1 Gwei + max_fee_per_gas: 2_000_000_000, // 2 Gwei + gas_limit: BLOCK_GAS_LIMIT + 1, // Gas limit greater than block gas limit + to: TxKind::Call(0x1234567890123456789012345678901234567890.try_into().unwrap()), + value: 1000000000000000000_u256, // 1 ETH + input: array![].span(), + access_list: array![].span(), + } + ); + + // Test that the function performs validation and assert expected results + validate_eth_tx(@kakarot_state, tx); + } + + #[test] + #[should_panic(expected: ('Intrinsic gas > gas limit',))] + fn test_validate_eth_tx_intrinsic_gas_exceeds_gas_limit() { + // Setup the environment + let (kakarot_state, _) = set_up(); + + // Create a transaction object for the test + let mut tx = Transaction::Eip1559( + TxEip1559 { + chain_id: 1, // Should match the chain_id in the environment + nonce: 0, + max_priority_fee_per_gas: 1_000_000_000, // 1 Gwei + max_fee_per_gas: 2_000_000_000, // 2 Gwei + gas_limit: 0, + to: TxKind::Call(0x1234567890123456789012345678901234567890.try_into().unwrap()), + value: 1000000000000000000_u256, // 1 ETH + input: array![].span(), + access_list: array![].span(), + } + ); + + // Test that the function performs validation and assert expected results + validate_eth_tx(@kakarot_state, tx); + } + + #[test] + #[should_panic(expected: ('Not enough ETH',))] + fn test_validate_eth_tx_insufficient_balance() { + // Setup the environment + let (kakarot_state, native_token_address) = set_up(); + + // Create a transaction object for the test + let tx = Transaction::Eip1559( + TxEip1559 { + chain_id: 1, // Should match the chain_id in the environment + nonce: 0, + max_priority_fee_per_gas: 1_000_000_000, // 1 Gwei + max_fee_per_gas: 2_000_000_000, // 2 Gwei + gas_limit: 21000, // Standard gas limit for a simple transfer + to: TxKind::Call(0x1234567890123456789012345678901234567890.try_into().unwrap()), + value: 1000000000000000000_u256, // 1 ETH + input: array![].span(), + access_list: array![].span(), + } + ); + + start_mock_call(native_token_address, selector!("balanceOf"), Bounded::::MIN); + + // Test that the function performs validation and assert expected results + validate_eth_tx(@kakarot_state, tx); + } + + #[test] + fn test_validate_eth_tx_max_gas_limit() { + // Setup the environment + let (kakarot_state, _) = set_up(); + + // Create a transaction object for the test + let tx = Transaction::Eip1559( + TxEip1559 { + chain_id: 1, // Should match the chain_id in the environment + nonce: 0, + max_priority_fee_per_gas: 1_000_000_000, // 1 Gwei + max_fee_per_gas: 2_000_000_000, // 2 Gwei + gas_limit: BLOCK_GAS_LIMIT, // Gas limit = Max block gas limit + to: TxKind::Call(0x1234567890123456789012345678901234567890.try_into().unwrap()), + value: 1000000000000000000_u256, // 1 ETH + input: array![].span(), + access_list: array![].span(), + } + ); + + // Test that the function performs validation and assert expected results + let intrinsic_gas = validate_eth_tx(@kakarot_state, tx); + assert_eq!(intrinsic_gas, 21000); // Standard intrinsic gas for a simple transfer + } + + #[test] + fn test_validate_eth_tx_pre_eip155() { + // Setup the environment + let (kakarot_state, _) = set_up(); + + // Create a transaction object for the test + let tx = Transaction::Legacy( + TxLegacy { + chain_id: Option::None, + nonce: 0, + gas_price: 120000000000000000000000000, + gas_limit: 21000, + to: TxKind::Call(0x1234567890123456789012345678901234567890.try_into().unwrap()), + value: 1000000000000000000_u256, // Standard gas limit for a simple transfer + input: array![].span(), + } + ); + + // Test that the function performs validation and assert expected results + let intrinsic_gas = validate_eth_tx(@kakarot_state, tx); + + assert_eq!(intrinsic_gas, 21000); // Standard intrinsic gas for a simple transfer + } +} diff --git a/kakarot-ssj/crates/evm/src/call_helpers.cairo b/kakarot-ssj/crates/evm/src/call_helpers.cairo new file mode 100644 index 000000000..61e67031d --- /dev/null +++ b/kakarot-ssj/crates/evm/src/call_helpers.cairo @@ -0,0 +1,129 @@ +use contracts::kakarot_core::KakarotCore; +use contracts::kakarot_core::interface::IKakarotCore; +//! CALL, CALLCODE, DELEGATECALL, STATICCALL opcode helpers +use core::cmp::min; +use core::starknet::EthAddress; + +use crate::errors::EVMError; +use crate::interpreter::EVMTrait; +use crate::memory::MemoryTrait; +use crate::model::vm::{VM, VMTrait}; +use crate::model::{Address, Message, ExecutionResultStatus}; +use crate::stack::StackTrait; +use crate::state::StateTrait; +use utils::constants; +use utils::set::SetTrait; +use utils::traits::{BoolIntoNumeric, U256TryIntoResult}; + +/// CallArgs is a subset of CallContext +/// Created in order to simplify setting up the call opcodes +#[derive(Drop, PartialEq)] +pub struct CallArgs { + caller: Address, + code_address: Address, + to: Address, + gas: u128, + value: u256, + calldata: Span, + ret_offset: usize, + ret_size: usize, + read_only: bool, + should_transfer: bool, + max_memory_size: usize, +} + +#[derive(Drop)] +pub enum CallType { + Call, + DelegateCall, + CallCode, + StaticCall, +} + +#[generate_trait] +pub impl CallHelpersImpl of CallHelpers { + /// Initializes and enters into a new sub-context + /// The Machine will change its `current_ctx` to point to the + /// newly created sub-context. + /// Then, the EVM execution loop will start on this new execution context. + fn generic_call( + ref self: VM, + gas: u64, + value: u256, + caller: EthAddress, + to: EthAddress, + code_address: EthAddress, + should_transfer_value: bool, + is_staticcall: bool, + args_offset: usize, + args_size: usize, + ret_offset: usize, + ret_size: usize + ) -> Result<(), EVMError> { + self.return_data = [].span(); + if self.message().depth >= constants::STACK_MAX_DEPTH { + self.gas_left += gas; + return self.stack.push(0); + } + + let mut calldata = Default::default(); + self.memory.load_n(args_size, ref calldata, args_offset); + + // We enter the standard flow + let code_account = self.env.state.get_account(code_address); + let read_only = is_staticcall || self.message.read_only; + + let kakarot_core = KakarotCore::unsafe_new_contract_state(); + let to = Address { evm: to, starknet: kakarot_core.compute_starknet_address(to) }; + let caller = Address { + evm: caller, starknet: kakarot_core.compute_starknet_address(caller) + }; + + let message = Message { + caller, + target: to, + gas_limit: gas, + data: calldata.span(), + code: code_account.code, + code_address: code_account.address, + value: value, + should_transfer_value: should_transfer_value, + depth: self.message().depth + 1, + read_only: read_only, + accessed_addresses: self.accessed_addresses.clone().spanset(), + accessed_storage_keys: self.accessed_storage_keys.clone().spanset(), + }; + + let result = EVMTrait::process_message(message, ref self.env); + self.merge_child(@result); + + match result.status { + ExecutionResultStatus::Success => { + self.return_data = result.return_data; + self.stack.push(1)?; + }, + ExecutionResultStatus::Revert => { + self.return_data = result.return_data; + self.stack.push(0)?; + }, + ExecutionResultStatus::Exception => { + // If the call has halted exceptionnaly, + // the return_data is emptied, and nothing is stored in memory + self.return_data = [].span(); + self.stack.push(0)?; + return Result::Ok(()); + }, + } + + // Get the min between len(return_data) and call_ctx.ret_size. + let actual_returndata_len = min(result.return_data.len(), ret_size); + + let actual_return_data = result.return_data.slice(0, actual_returndata_len); + // TODO: Check if need to pad the memory with zeroes if result.return_data.len() < + // call_ctx.ret_size and memory is not empty at offset call_args.ret_offset + + // result.return_data.len() + self.memory.store_n(actual_return_data, ret_offset); + + Result::Ok(()) + } +} diff --git a/kakarot-ssj/crates/evm/src/create_helpers.cairo b/kakarot-ssj/crates/evm/src/create_helpers.cairo new file mode 100644 index 000000000..28e8dc40b --- /dev/null +++ b/kakarot-ssj/crates/evm/src/create_helpers.cairo @@ -0,0 +1,186 @@ +use core::num::traits::Bounded; +use core::num::traits::Zero; +use core::starknet::EthAddress; +use crate::errors::{ensure, EVMError}; +use crate::gas; +use crate::interpreter::EVMTrait; +use crate::memory::MemoryTrait; +use crate::model::Message; +use crate::model::account::{Account, AccountTrait}; +use crate::model::vm::{VM, VMTrait}; +use crate::model::{ExecutionResult, ExecutionResultTrait, ExecutionResultStatus}; +use crate::stack::StackTrait; +use crate::state::StateTrait; +use utils::address::{compute_contract_address, compute_create2_contract_address}; +use utils::constants; +use utils::helpers::bytes_32_words_size; +use utils::set::SetTrait; +use utils::traits::{ + BoolIntoNumeric, EthAddressIntoU256, U256TryIntoResult, SpanU8TryIntoResultEthAddress +}; + +/// Helper struct to prepare CREATE and CREATE2 opcodes +#[derive(Drop)] +pub struct CreateArgs { + to: EthAddress, + value: u256, + bytecode: Span, +} + +#[derive(Copy, Drop)] +pub enum CreateType { + Create, + Create2, +} + +#[generate_trait] +pub impl CreateHelpersImpl of CreateHelpers { + /// Prepare the initialization of a new child or so-called sub-context + /// As part of the CREATE family of opcodes. + fn prepare_create(ref self: VM, create_type: CreateType) -> Result { + let value = self.stack.pop()?; + let offset = self.stack.pop_saturating_usize()?; + let size = self.stack.pop_usize()?; + + let memory_expansion = gas::memory_expansion(self.memory.size(), [(offset, size)].span())?; + self.memory.ensure_length(memory_expansion.new_size); + let init_code_gas = gas::init_code_cost(size); + let charged_gas = match create_type { + CreateType::Create => gas::CREATE + memory_expansion.expansion_cost + init_code_gas, + CreateType::Create2 => { + let calldata_words = bytes_32_words_size(size); + gas::CREATE + + gas::KECCAK256WORD * calldata_words.into() + + memory_expansion.expansion_cost + + init_code_gas + }, + }; + self.charge_gas(charged_gas)?; + + let mut bytecode = Default::default(); + self.memory.load_n(size, ref bytecode, offset); + + let to = match create_type { + CreateType::Create => { + let nonce = self.env.state.get_account(self.message().target.evm).nonce(); + compute_contract_address(self.message().target.evm, sender_nonce: nonce) + }, + CreateType::Create2 => compute_create2_contract_address( + self.message().target.evm, salt: self.stack.pop()?, bytecode: bytecode.span() + )?, + }; + + Result::Ok(CreateArgs { to, value, bytecode: bytecode.span() }) + } + + + /// Initializes and enters into a new sub-context + /// The Machine will change its `current_ctx` to point to the + /// newly created sub-context. + /// Then, the EVM execution loop will start on this new execution context. + fn generic_create(ref self: VM, create_args: CreateArgs) -> Result<(), EVMError> { + self.accessed_addresses.add(create_args.to); + + let create_message_gas = gas::max_message_call_gas(self.gas_left); + self.gas_left -= create_message_gas; + + ensure(!self.message().read_only, EVMError::WriteInStaticContext)?; + self.return_data = [].span(); + + // The sender in the subcontext is the message's target + let sender_address = self.message().target; + let mut sender = self.env.state.get_account(sender_address.evm); + let sender_current_nonce = sender.nonce(); + if sender.balance() < create_args.value + || sender_current_nonce == Bounded::::MAX + || self.message.depth == constants::STACK_MAX_DEPTH { + self.gas_left += create_message_gas; + return self.stack.push(0); + } + + sender + .set_nonce( + sender_current_nonce + 1 + ); // Will not overflow because of the previous check. + self.env.state.set_account(sender); + + let mut target_account = self.env.state.get_account(create_args.to); + let target_address = target_account.address(); + // Collision happens if the target account loaded in state has code or nonce set, meaning + // - it's deployed on SN and is an active EVM contract + // - it's not deployed on SN and is an active EVM contract in the Kakarot cache + if target_account.has_code_or_nonce() { + return self.stack.push(0); + }; + + ensure(create_args.bytecode.len() <= constants::MAX_INITCODE_SIZE, EVMError::OutOfGas)?; + + let child_message = Message { + caller: sender_address, + target: target_address, + gas_limit: create_message_gas, + data: [].span(), + code: create_args.bytecode, + code_address: Zero::zero(), + value: create_args.value, + should_transfer_value: true, + depth: self.message().depth + 1, + read_only: false, + accessed_addresses: self.accessed_addresses.clone().spanset(), + accessed_storage_keys: self.accessed_storage_keys.clone().spanset(), + }; + + let result = EVMTrait::process_create_message(child_message, ref self.env); + self.merge_child(@result); + + match result.status { + ExecutionResultStatus::Success => { + self.return_data = [].span(); + self.stack.push(target_address.evm.into())?; + }, + ExecutionResultStatus::Revert => { + self.return_data = result.return_data; + self.stack.push(0)?; + }, + ExecutionResultStatus::Exception => { + // returndata is emptied in case of exception + self.return_data = [].span(); + self.stack.push(0)?; + }, + } + Result::Ok(()) + } + + /// Finalizes the creation of an account contract by + /// setting its code and charging the gas for the code deposit. + /// Since we don't have access to the child vm anymore, we charge the gas on + /// the returned ExecutionResult of the childVM. + /// + /// # Arguments + /// * `self` - The ExecutionResult to charge the gas on. + /// * `account` - The Account to finalize + #[inline(always)] + fn finalize_creation( + ref self: ExecutionResult, mut account: Account + ) -> Result { + let code = self.return_data; + let contract_code_gas = code.len().into() * gas::CODEDEPOSIT; + + if code.len() != 0 { + ensure(*code[0] != 0xEF, EVMError::InvalidCode)?; + } + self.charge_gas(contract_code_gas)?; + + ensure(code.len() <= constants::MAX_CODE_SIZE, EVMError::OutOfGas)?; + + account.set_code(code); + Result::Ok(account) + } +} + +#[cfg(test)] +mod tests { + //TODO: test create helpers + + +} diff --git a/kakarot-ssj/crates/evm/src/errors.cairo b/kakarot-ssj/crates/evm/src/errors.cairo new file mode 100644 index 000000000..b6d17eaa5 --- /dev/null +++ b/kakarot-ssj/crates/evm/src/errors.cairo @@ -0,0 +1,112 @@ +use core::fmt::{Debug, Formatter, Error, Display}; +use utils::traits::bytes::ToBytes; + +// STACK + +// INSTRUCTIONS +pub const PC_OUT_OF_BOUNDS: felt252 = 'KKT: pc >= bytecode length'; + +// TYPE CONVERSION +pub const TYPE_CONVERSION_ERROR: felt252 = 'KKT: type conversion error'; + +// NUMERIC OPERATIONS +pub const BALANCE_OVERFLOW: felt252 = 'KKT: balance overflow'; + +// JUMP +pub const INVALID_DESTINATION: felt252 = 'KKT: invalid JUMP destination'; + +// CALL +pub const VALUE_TRANSFER_IN_STATIC_CALL: felt252 = 'KKT: transfer value in static'; +pub const ACTIVE_MACHINE_STATE_IN_CALL_FINALIZATION: felt252 = 'KKT: active state in end call'; +pub const MISSING_PARENT_CONTEXT: felt252 = 'KKT: missing parent context'; +pub const CALL_GAS_GT_GAS_LIMIT: felt252 = 'KKT: call gas gt gas limit'; + +// EVM STATE + +// STARKNET_SYSCALLS +pub const READ_SYSCALL_FAILED: felt252 = 'KKT: read syscall failed'; +pub const BLOCK_HASH_SYSCALL_FAILED: felt252 = 'KKT: block_hash syscall failed'; +pub const WRITE_SYSCALL_FAILED: felt252 = 'KKT: write syscall failed'; +pub const CONTRACT_SYSCALL_FAILED: felt252 = 'KKT: contract syscall failed'; +pub const EXECUTION_INFO_SYSCALL_FAILED: felt252 = 'KKT: exec info syscall failed'; + +// CREATE +pub const CONTRACT_ACCOUNT_EXISTS: felt252 = 'KKT: Contract Account exists'; +pub const EOA_EXISTS: felt252 = 'KKT: EOA already exists'; +pub const ACCOUNT_EXISTS: felt252 = 'KKT: Account already exists'; +pub const DEPLOYMENT_FAILED: felt252 = 'KKT: deployment failed'; + +// TRANSACTION ORIGIN +pub const CALLING_FROM_UNDEPLOYED_ACCOUNT: felt252 = 'EOA: from is undeployed EOA'; +pub const CALLING_FROM_CA: felt252 = 'EOA: from is a contract account'; + +#[derive(Drop, Copy, PartialEq)] +pub enum EVMError { + StackOverflow, + StackUnderflow, + TypeConversionError: felt252, + NumericOperations: felt252, + InsufficientBalance, + ReturnDataOutOfBounds, + InvalidJump, + InvalidCode, + NotImplemented, + InvalidParameter: felt252, + InvalidOpcode: u8, + WriteInStaticContext, + Collision, + OutOfGas, + Assertion, + DepthLimit, + MemoryLimitOOG, + NonceOverflow +} + +#[generate_trait] +pub impl EVMErrorImpl of EVMErrorTrait { + fn to_string(self: EVMError) -> felt252 { + match self { + EVMError::StackOverflow => 'stack overflow', + EVMError::StackUnderflow => 'stack underflow', + EVMError::TypeConversionError(error_message) => error_message, + EVMError::NumericOperations(error_message) => error_message, + EVMError::InsufficientBalance => 'insufficient balance', + EVMError::ReturnDataOutOfBounds => 'return data out of bounds', + EVMError::InvalidJump => 'invalid jump destination', + EVMError::InvalidCode => 'invalid code', + EVMError::NotImplemented => 'not implemented', + EVMError::InvalidParameter(error_message) => error_message, + // TODO: refactor with dynamic strings once supported + EVMError::InvalidOpcode => 'invalid opcode'.into(), + EVMError::WriteInStaticContext => 'write protection', + EVMError::Collision => 'create collision'.into(), + EVMError::OutOfGas => 'out of gas'.into(), + EVMError::Assertion => 'assertion failed'.into(), + EVMError::DepthLimit => 'max call depth exceeded'.into(), + EVMError::MemoryLimitOOG => 'memory limit out of gas'.into(), + EVMError::NonceOverflow => 'nonce overflow'.into(), + } + } + + fn to_bytes(self: EVMError) -> Span { + let error_message: felt252 = self.to_string(); + let error_message: u256 = error_message.into(); + error_message.to_be_bytes() + } +} + +pub impl DebugEVMError of Debug { + fn fmt(self: @EVMError, ref f: Formatter) -> Result<(), Error> { + let error_message = (*self).to_string(); + Display::fmt(@error_message, ref f) + } +} + +#[inline(always)] +pub fn ensure(cond: bool, err: EVMError) -> Result<(), EVMError> { + if cond { + Result::Ok(()) + } else { + Result::Err(err) + } +} diff --git a/kakarot-ssj/crates/evm/src/gas.cairo b/kakarot-ssj/crates/evm/src/gas.cairo new file mode 100644 index 000000000..fa359bd2e --- /dev/null +++ b/kakarot-ssj/crates/evm/src/gas.cairo @@ -0,0 +1,402 @@ +use core::cmp::min; +use core::num::traits::CheckedAdd; +use crate::errors::EVMError; +use utils::eth_transaction::common::TxKindTrait; +use utils::eth_transaction::eip2930::{AccessListItem}; +use utils::eth_transaction::transaction::{Transaction, TransactionTrait}; +use utils::helpers; + +//! Gas costs for EVM operations +//! Code is based on alloy project +//! Source: + +pub const ZERO: u64 = 0; +pub const BASE: u64 = 2; +pub const VERYLOW: u64 = 3; +pub const LOW: u64 = 5; +pub const MID: u64 = 8; +pub const HIGH: u64 = 10; +pub const JUMPDEST: u64 = 1; +pub const SELFDESTRUCT: u64 = 5000; +pub const CREATE: u64 = 32000; +pub const CALLVALUE: u64 = 9000; +pub const NEWACCOUNT: u64 = 25000; +pub const EXP: u64 = 10; +pub const EXP_GAS_PER_BYTE: u64 = 50; +pub const MEMORY: u64 = 3; +pub const LOG: u64 = 375; +pub const LOGDATA: u64 = 8; +pub const LOGTOPIC: u64 = 375; +pub const KECCAK256: u64 = 30; +pub const KECCAK256WORD: u64 = 6; +pub const COPY: u64 = 3; +pub const BLOCKHASH: u64 = 20; +pub const CODEDEPOSIT: u64 = 200; + +pub const SSTORE_SET: u64 = 20000; +pub const SSTORE_RESET: u64 = 5000; +pub const REFUND_SSTORE_CLEARS: u64 = 4800; + +pub const TRANSACTION_ZERO_DATA: u64 = 4; +pub const TRANSACTION_NON_ZERO_DATA_INIT: u64 = 16; +pub const TRANSACTION_NON_ZERO_DATA_FRONTIER: u64 = 68; +pub const TRANSACTION_BASE_COST: u64 = 21000; +pub const TRANSACTION_CREATE_COST: u64 = 32000; + +// Berlin EIP-2929 constants +pub const ACCESS_LIST_ADDRESS: u64 = 2400; +pub const ACCESS_LIST_STORAGE_KEY: u64 = 1900; +pub const COLD_SLOAD_COST: u64 = 2100; +pub const COLD_ACCOUNT_ACCESS_COST: u64 = 2600; +pub const WARM_ACCESS_COST: u64 = 100; + +/// EIP-3860 : Limit and meter initcode +pub const INITCODE_WORD_COST: u64 = 2; + +pub const CALL_STIPEND: u64 = 2300; + +// EIP-4844 +pub const BLOB_HASH_COST: u64 = 3; + +/// Defines the gas cost and stipend for executing call opcodes. +/// +/// # Struct fields +/// +/// * `cost`: The non-refundable portion of gas reserved for executing the call opcode. +/// * `stipend`: The portion of gas available to sub-calls that is refundable if not consumed. +#[derive(Drop)] +pub struct MessageCallGas { + pub cost: u64, + pub stipend: u64, +} + +/// Defines the new size and the expansion cost after memory expansion. +/// +/// # Struct fields +/// +/// * `new_size`: The new size of the memory after extension. +/// * `expansion_cost`: The cost of the memory extension. +#[derive(Drop)] +pub struct MemoryExpansion { + pub new_size: u32, + pub expansion_cost: u64, +} + +/// Calculates the maximum gas that is allowed for making a message call. +/// +/// # Arguments +/// * `gas`: The gas available for the message call. +/// +/// # Returns +/// * The maximum gas allowed for the message call. +pub fn max_message_call_gas(gas: u64) -> u64 { + gas - (gas / 64) +} + +/// Calculates the MessageCallGas (cost and stipend) for executing call Opcodes. +/// +/// # Parameters +/// +/// * `value`: The amount of native token that needs to be transferred. +/// * `gas`: The amount of gas provided to the message-call. +/// * `gas_left`: The amount of gas left in the current frame. +/// * `memory_cost`: The amount needed to extend the memory in the current frame. +/// * `extra_gas`: The amount of gas needed for transferring value + creating a new account inside a +/// message call. +/// +/// # Returns +/// +/// * `Result`: The calculated MessageCallGas or an error if overflow +/// occurs. +pub fn calculate_message_call_gas( + value: u256, gas: u64, gas_left: u64, memory_cost: u64, extra_gas: u64 +) -> Result { + let call_stipend = if value == 0 { + 0 + } else { + CALL_STIPEND + }; + + // Check for overflow when adding extra_gas and memory_cost + let total_extra_cost = extra_gas.checked_add(memory_cost).ok_or(EVMError::OutOfGas)?; + let gas = if gas_left < total_extra_cost { + gas + } else { + let remaining_gas = gas_left - total_extra_cost; // Safe because of the check above + min(gas, max_message_call_gas(remaining_gas)) + }; + + let cost = gas.checked_add(extra_gas).ok_or(EVMError::OutOfGas)?; + let stipend = gas.checked_add(call_stipend).ok_or(EVMError::OutOfGas)?; + + Result::Ok(MessageCallGas { cost, stipend }) +} + + +/// Calculates the gas cost for allocating memory +/// to the smallest multiple of 32 bytes, +/// such that the allocated size is at least as big as the given size. +/// +/// To optimize computations on u128 and avoid overflows, we compute size_in_words / 512 +/// instead of size_in_words * size_in_words / 512. Then we recompute the +/// resulting quotient: x^2 = 512q + r becomes +/// x = 512 q0 + r0 => x^2 = 512(512 q0^2 + 2 q0 r0) + r0^2 +/// r0^2 = 512 q1 + r1 +/// x^2 = 512(512 q0^2 + 2 q0 r0 + q1) + r1 +/// q = 512 * q0 * q0 + 2 * q0 * r0 + q1 +/// # Parameters +/// +/// * `size_in_bytes` - The size of the data in bytes. +/// +/// # Returns +/// +/// * `total_gas_cost` - The gas cost for storing data in memory. +pub fn calculate_memory_gas_cost(size_in_bytes: usize) -> u64 { + let _512: NonZero = 512_u64.try_into().unwrap(); + let size_in_words = (size_in_bytes + 31) / 32; + let linear_cost = size_in_words.into() * MEMORY; + + let (q0, r0) = DivRem::div_rem(size_in_words.into(), _512); + let (q1, _) = DivRem::div_rem(r0 * r0, _512); + let quadratic_cost = 512 * q0 * q0 + 2 * q0 * r0 + q1; + + linear_cost + quadratic_cost +} + + +/// Calculates memory expansion based on multiple memory operations. +/// +/// # Arguments +/// +/// * `current_size`: Current size of the memory. +/// * `operations`: A span of tuples (offset, size) representing memory operations. +/// +/// # Returns +/// +/// * `MemoryExpansion`: New size and expansion cost. +pub fn memory_expansion( + current_size: usize, mut operations: Span<(usize, usize)> +) -> Result { + let mut current_max_size = current_size; + + // Using a high-level loop because Cairo doesn't support the `for` loop syntax with breaks + let max_size = loop { + match operations.pop_front() { + Option::Some(( + offset, size + )) => { + if *size != 0 { + match (*offset).checked_add(*size) { + Option::Some(end) => { + if end > current_max_size { + current_max_size = end; + } + }, + Option::None => { break Result::Err(EVMError::MemoryLimitOOG); }, + } + } + }, + Option::None => { break Result::Ok((current_max_size)); }, + } + }?; + + let new_size = helpers::bytes_32_words_size(max_size) * 32; + + if new_size <= current_size { + return Result::Ok(MemoryExpansion { new_size: current_size, expansion_cost: 0 }); + } + + let prev_cost = calculate_memory_gas_cost(current_size); + let new_cost = calculate_memory_gas_cost(new_size); + let expansion_cost = new_cost - prev_cost; + Result::Ok(MemoryExpansion { new_size, expansion_cost }) +} + +/// Calculates the gas to be charged for the init code in CREATE/CREATE2 +/// opcodes as well as create transactions. +/// +/// # Arguments +/// +/// * `code_size` - The size of the init code +/// +/// # Returns +/// +/// * `init_code_gas` - The gas to be charged for the init code. +#[inline(always)] +pub fn init_code_cost(code_size: usize) -> u64 { + let code_size_in_words = helpers::bytes_32_words_size(code_size); + code_size_in_words.into() * INITCODE_WORD_COST +} + +/// Calculates the gas that is charged before execution is started. +/// +/// The intrinsic cost of the transaction is charged before execution has +/// begun. Functions/operations in the EVM cost money to execute so this +/// intrinsic cost is for the operations that need to be paid for as part of +/// the transaction. Data transfer, for example, is part of this intrinsic +/// cost. It costs ether to send data over the wire and that ether is +/// accounted for in the intrinsic cost calculated in this function. This +/// intrinsic cost must be calculated and paid for before execution in order +/// for all operations to be implemented. +/// +/// Reference: +/// https://github.com/ethereum/execution-specs/blob/master/src/ethereum/shanghai/fork.py#L689 +pub fn calculate_intrinsic_gas_cost(tx: @Transaction) -> u64 { + let mut data_cost: u64 = 0; + + let mut calldata = tx.input(); + let calldata_len: usize = calldata.len(); + + for data in calldata { + data_cost += + if *data == 0 { + TRANSACTION_ZERO_DATA + } else { + TRANSACTION_NON_ZERO_DATA_INIT + }; + }; + + let create_cost: u64 = if tx.kind().is_create() { + TRANSACTION_CREATE_COST + init_code_cost(calldata_len) + } else { + 0 + }; + + let access_list_cost = if let Option::Some(mut access_list) = tx.access_list() { + let mut access_list_cost: u64 = 0; + for access_list_item in access_list { + let AccessListItem { ethereum_address: _, storage_keys } = *access_list_item; + access_list_cost += ACCESS_LIST_ADDRESS + + (ACCESS_LIST_STORAGE_KEY * storage_keys.len().into()); + }; + access_list_cost + } else { + 0 + }; + + TRANSACTION_BASE_COST + data_cost + create_cost + access_list_cost +} + +#[cfg(test)] +mod tests { + use core::starknet::EthAddress; + + use crate::gas::{ + calculate_intrinsic_gas_cost, calculate_memory_gas_cost, ACCESS_LIST_ADDRESS, + ACCESS_LIST_STORAGE_KEY + }; + use crate::test_utils::evm_address; + use utils::eth_transaction::eip2930::{AccessListItem, TxEip2930}; + use utils::eth_transaction::legacy::TxLegacy; + use utils::eth_transaction::transaction::Transaction; + use utils::traits::bytes::ToBytes; + + #[test] + fn test_calculate_intrinsic_gas_cost() { + // RLP decoded value: (https://toolkit.abdk.consulting/ethereum#rlp,transaction) + // ["0xc9", "0x81", "0xf7", "0x81", "0x80", "0x81", "0x84", "0x00", "0x00", "0x12"] + // 16 16 16 16 16 16 16 4 4 16 + // + 21000 + // + 0 + // --------------------------- + // = 21136 + let rlp_encoded: u256 = 0xc981f781808184000012; + + let input = rlp_encoded.to_be_bytes(); + let to: EthAddress = 'vitalik.eth'.try_into().unwrap(); + + let tx: Transaction = Transaction::Legacy( + TxLegacy { + to: to.into(), + nonce: 0, + gas_price: 50, + gas_limit: 433926, + value: 1, + input, + chain_id: Option::Some(0x1) + } + ); + + let expected_cost: u64 = 21136; + let out_cost: u64 = calculate_intrinsic_gas_cost(@tx); + + assert_eq!(out_cost, expected_cost, "wrong cost"); + } + + #[test] + fn test_calculate_intrinsic_gas_cost_with_access_list() { + // RLP decoded value: (https://toolkit.abdk.consulting/ethereum#rlp,transaction) + // ["0xc9", "0x81", "0xf7", "0x81", "0x80", "0x81", "0x84", "0x00", "0x00", "0x12"] + // 16 16 16 16 16 16 16 4 4 16 + // + 21000 + // + 0 + // --------------------------- + // = 21136 + let rlp_encoded: u256 = 0xc981f781808184000012; + + let input = rlp_encoded.to_be_bytes(); + let to: EthAddress = 'vitalik.eth'.try_into().unwrap(); + + let access_list = [ + AccessListItem { ethereum_address: evm_address(), storage_keys: [1, 2, 3, 4, 5].span() } + ].span(); + + let tx: Transaction = Transaction::Eip2930( + TxEip2930 { + to: to.into(), + nonce: 0, + gas_price: 50, + gas_limit: 433926, + value: 1, + input, + chain_id: 0x1, + access_list + } + ); + + let expected_cost: u64 = 21136 + ACCESS_LIST_ADDRESS + 5 * ACCESS_LIST_STORAGE_KEY; + let out_cost: u64 = calculate_intrinsic_gas_cost(@tx); + + assert_eq!(out_cost, expected_cost, "wrong cost"); + } + + + #[test] + fn test_calculate_intrinsic_gas_cost_without_destination() { + // RLP decoded value: (https://toolkit.abdk.consulting/ethereum#rlp,transaction) + // ["0xc9", "0x81", "0xf7", "0x81", "0x80", "0x81", "0x84", "0x00", "0x00", "0x12"] + // 16 16 16 16 16 16 16 4 4 16 + // + 21000 + // + (32000 + 2) + // --------------------------- + // = 53138 + let rlp_encoded: u256 = 0xc981f781808184000012; + + let input = rlp_encoded.to_be_bytes(); + + let tx: Transaction = Transaction::Legacy( + TxLegacy { + to: Option::None.into(), + nonce: 0, + gas_price: 50, + gas_limit: 433926, + value: 1, + input, + chain_id: Option::Some(0x1) + } + ); + + let expected_cost: u64 = 53138; + let out_cost: u64 = calculate_intrinsic_gas_cost(@tx); + + assert_eq!(out_cost, expected_cost, "wrong cost"); + } + + #[test] + fn test_calculate_memory_allocation_cost() { + let size_in_bytes: usize = 10018613; + let expected_cost: u64 = 192385220; + let out_cost: u64 = calculate_memory_gas_cost(size_in_bytes); + assert_eq!(out_cost, expected_cost, "wrong cost"); + } +} diff --git a/kakarot-ssj/crates/evm/src/instructions.cairo b/kakarot-ssj/crates/evm/src/instructions.cairo new file mode 100644 index 000000000..e632d1169 --- /dev/null +++ b/kakarot-ssj/crates/evm/src/instructions.cairo @@ -0,0 +1,34 @@ +/// Sub modules. +mod block_information; + +mod comparison_operations; + +mod duplication_operations; + +mod environmental_information; + +mod exchange_operations; + +mod logging_operations; + +mod memory_operations; + +mod push_operations; + +mod sha3; + +mod stop_and_arithmetic_operations; + +mod system_operations; + +pub use block_information::BlockInformationTrait; +pub use comparison_operations::ComparisonAndBitwiseOperationsTrait; +pub use duplication_operations::DuplicationOperationsTrait; +pub use environmental_information::EnvironmentInformationTrait; +pub use exchange_operations::ExchangeOperationsTrait; +pub use logging_operations::LoggingOperationsTrait; +pub use memory_operations::MemoryOperationTrait; +pub use push_operations::PushOperationsTrait; +pub use sha3::Sha3Trait; +pub use stop_and_arithmetic_operations::StopAndArithmeticOperationsTrait; +pub use system_operations::SystemOperationsTrait; diff --git a/kakarot-ssj/crates/evm/src/instructions/block_information.cairo b/kakarot-ssj/crates/evm/src/instructions/block_information.cairo new file mode 100644 index 000000000..f5e61db79 --- /dev/null +++ b/kakarot-ssj/crates/evm/src/instructions/block_information.cairo @@ -0,0 +1,368 @@ +//! Block Information. + +use core::starknet::SyscallResultTrait; +use core::starknet::syscalls::get_block_hash_syscall; + +use crate::errors::EVMError; + +use crate::gas; +use crate::model::vm::{VM, VMTrait}; +use crate::stack::StackTrait; +use crate::state::StateTrait; +use utils::constants::MIN_BASE_FEE_PER_BLOB_GAS; +use utils::traits::{EthAddressTryIntoResultContractAddress, EthAddressIntoU256}; + +#[generate_trait] +pub impl BlockInformation of BlockInformationTrait { + /// 0x40 - BLOCKHASH + /// Get the hash of one of the 256 most recent complete blocks. + /// # Specification: https://www.evm.codes/#40?fork=shanghai + fn exec_blockhash(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::BLOCKHASH)?; + + let block_number = self.stack.pop_u64()?; + let current_block = self.env.block_number; + + // If input block number is lower than current_block - 256, return 0 + // If input block number is higher than current_block - 10, return 0 + // Note: in the specs, input block number can be equal - at most - to the current block + // number minus one. + // In Starknet, the `get_block_hash_syscall` is capped at current block minus ten. + // TODO: monitor the changes in the `get_block_hash_syscall` syscall. + // source: + // https://docs.starknet.io/documentation/architecture_and_concepts/Smart_Contracts/system-calls-cairo1/#get_block_hash + if block_number + 10 > current_block || block_number + 256 < current_block { + return self.stack.push(0); + } + + self.stack.push(get_block_hash_syscall(block_number).unwrap_syscall().into()) + } + + /// 0x41 - COINBASE + /// Get the block's beneficiary address. + /// # Specification: https://www.evm.codes/#41?fork=shanghai + fn exec_coinbase(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::BASE)?; + + let coinbase = self.env.coinbase; + self.stack.push(coinbase.into()) + } + + /// 0x42 - TIMESTAMP + /// Get the block’s timestamp + /// # Specification: https://www.evm.codes/#42?fork=shanghai + fn exec_timestamp(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::BASE)?; + + self.stack.push(self.env.block_timestamp.into()) + } + + /// 0x43 - NUMBER + /// Get the block number. + /// # Specification: https://www.evm.codes/#43?fork=shanghai + fn exec_number(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::BASE)?; + + self.stack.push(self.env.block_number.into()) + } + + /// 0x44 - PREVRANDAO + /// # Specification: https://www.evm.codes/#44?fork=shanghai + fn exec_prevrandao(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::BASE)?; + + self.stack.push(self.env.prevrandao) + } + + /// 0x45 - GASLIMIT + /// Get the block’s gas limit + /// # Specification: https://www.evm.codes/#45?fork=shanghai + fn exec_gaslimit(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::BASE)?; + + self.stack.push(self.env.block_gas_limit.into()) + } + + /// 0x46 - CHAINID + /// Get the chain ID. + /// # Specification: https://www.evm.codes/#46?fork=shanghai + fn exec_chainid(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::BASE)?; + + let chain_id = self.env.chain_id; + self.stack.push(chain_id.into()) + } + + /// 0x47 - SELFBALANCE + /// Get balance of currently executing contract + /// # Specification: https://www.evm.codes/#47?fork=shanghai + fn exec_selfbalance(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::LOW)?; + + let evm_address = self.message().target.evm; + + let balance = self.env.state.get_account(evm_address).balance; + + self.stack.push(balance) + } + + /// 0x48 - BASEFEE + /// Get base fee. + /// # Specification: https://www.evm.codes/#48?fork=shanghai + fn exec_basefee(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::BASE)?; + + self.stack.push(self.env.base_fee.into()) + } + + /// 0x49 - BLOBHASH + /// Returns the value of the blob hash of the current block + /// Always returns Zero in the context of Kakarot + /// # Specification: https://www.evm.codes/#49?fork=cancun + fn exec_blobhash(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::BLOB_HASH_COST)?; + + self.stack.push(0) + } + + /// 0x4A - BLOBBASEFEE + /// Returns the value of the blob base-fee of the current block + /// Always returns Zero in the context of Kakarot + /// # Specification: https://www.evm.codes/#4a?fork=cancun + fn exec_blobbasefee(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::BASE)?; + + self.stack.push(MIN_BASE_FEE_PER_BLOB_GAS.into()) + } +} + + +#[cfg(test)] +mod tests { + use core::result::ResultTrait; + use crate::instructions::BlockInformationTrait; + use crate::model::account::Account; + use crate::model::vm::VMTrait; + use crate::stack::StackTrait; + use crate::state::StateTrait; + use crate::test_utils::{VMBuilderTrait, gas_price, setup_test_environment}; + use snforge_std::{start_cheat_block_number_global, start_cheat_block_timestamp_global}; + use utils::constants::EMPTY_KECCAK; + use utils::constants; + use utils::traits::{EthAddressIntoU256}; + + + /// 0x40 - BLOCKHASH + #[test] + fn test_exec_blockhash_below_bounds() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + start_cheat_block_number_global(500); + + // When + vm.stack.push(243).expect('push failed'); + vm.exec_blockhash().unwrap(); + + // Then + assert(vm.stack.peek().unwrap() == 0, 'stack top should be 0'); + } + + #[test] + fn test_exec_blockhash_above_bounds() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + start_cheat_block_number_global(500); + + // When + vm.stack.push(491).expect('push failed'); + vm.exec_blockhash().unwrap(); + + // Then + assert(vm.stack.peek().unwrap() == 0, 'stack top should be 0'); + } + + // TODO: implement exec_blockhash testing for block number within bounds + //TODO(sn-foundry): mock the block hash + // https://github.com/starkware-libs/cairo/blob/77a7e7bc36aa1c317bb8dd5f6f7a7e6eef0ab4f3/crates/cairo-lang-starknet/cairo_level_tests/interoperability.cairo#L173 + #[test] + #[ignore] + fn test_exec_blockhash_within_bounds() { + // If not set the default block number is 0. + let queried_block = 244; + start_cheat_block_number_global(500); + //TODO: restore start_cheat_block_hash_global(queried_block, 0xF); + + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + // When + vm.stack.push(queried_block.into()).expect('push failed'); + vm.exec_blockhash().expect('exec failed'); + //TODO the CASM runner used in tests doesn't implement + //`get_block_hash_syscall` yet. As such, this test should fail no if the + //queried block is within bounds + // Then + assert(vm.stack.peek().unwrap() == 0xF, 'stack top should be 0xF'); + } + + + #[test] + fn test_block_timestamp_set_to_1692873993() { + // 24/08/2023 12h46 33s + // If not set the default timestamp is 0. + start_cheat_block_timestamp_global(1692873993); + + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + // When + vm.exec_timestamp().unwrap(); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 1692873993, 'stack top should be 1692873993'); + } + + #[test] + fn test_block_number_set_to_32() { + // If not set the default block number is 0. + start_cheat_block_number_global(32); + + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + // When + vm.exec_number().unwrap(); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 32, 'stack top should be 32'); + } + + #[test] + fn test_gaslimit() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + // When + vm.exec_gaslimit().unwrap(); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + // This value is set in [new_with_presets]. + assert_eq!(vm.stack.peek().unwrap(), constants::BLOCK_GAS_LIMIT.into()) + } + + // ************************************************************************* + // 0x47: SELFBALANCE + // ************************************************************************* + #[test] + fn test_exec_selfbalance_should_push_balance() { + // Given + setup_test_environment(); + let mut vm = VMBuilderTrait::new_with_presets().build(); + let account = Account { + address: vm.message().target, + balance: 400, + nonce: 0, + code: [].span(), + code_hash: EMPTY_KECCAK, + selfdestruct: false, + is_created: true, + }; + vm.env.state.set_account(account); + + // When + vm.exec_selfbalance().unwrap(); + + // Then + assert_eq!(vm.stack.peek().unwrap(), 400); + } + + + #[test] + fn test_basefee_should_push_env_base_fee() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + // When + vm.exec_basefee().unwrap(); + + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.peek().unwrap(), vm.env.base_fee.into()); + } + + #[test] + fn test_chainid_should_push_chain_id_to_stack() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + // When + vm.exec_chainid().unwrap(); + + // Then + let chain_id = vm.stack.peek().unwrap(); + assert(vm.env.chain_id.into() == chain_id, 'stack should have chain id'); + } + + + #[test] + fn test_randao_should_push_zero_to_stack() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + // When + vm.exec_prevrandao().unwrap(); + + // Then + let result = vm.stack.peek().unwrap(); + assert(result == 0x00, 'stack top should be zero'); + } + + #[test] + fn test_blobhash_should_return_zero() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + // When + vm.exec_blobhash().unwrap(); + + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.peek().unwrap(), 0); + } + + + #[test] + fn test_blobbasefee_should_return_one() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + // When + vm.exec_blobbasefee().unwrap(); + + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.peek().unwrap(), 1); + } + + + // ************************************************************************* + // 0x41: COINBASE + // ************************************************************************* + #[test] + fn test_exec_coinbase() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + // When + vm.exec_coinbase().unwrap(); + + // Then + let coinbase_address = vm.stack.peek().unwrap(); + assert(vm.env.coinbase.into() == coinbase_address, 'wrong coinbase address'); + } +} diff --git a/kakarot-ssj/crates/evm/src/instructions/comparison_operations.cairo b/kakarot-ssj/crates/evm/src/instructions/comparison_operations.cairo new file mode 100644 index 000000000..e6f6e84b4 --- /dev/null +++ b/kakarot-ssj/crates/evm/src/instructions/comparison_operations.cairo @@ -0,0 +1,1980 @@ +use core::num::traits::Bounded; +use crate::errors::EVMError; +use crate::gas; +use crate::model::vm::{VM, VMTrait}; +// Internal imports +use crate::stack::StackTrait; +use utils::constants::{POW_2_127}; +use utils::i256::i256; +use utils::math::{Bitshift, WrappingBitshift}; +use utils::traits::BoolIntoNumeric; + +#[generate_trait] +pub impl ComparisonAndBitwiseOperations of ComparisonAndBitwiseOperationsTrait { + /// 0x10 - LT + /// # Specification: https://www.evm.codes/#10?fork=shanghai + fn exec_lt(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::VERYLOW)?; + let popped = self.stack.pop_n(2)?; + let a = *popped[0]; + let b = *popped[1]; + let result = (a < b).into(); + self.stack.push(result) + } + + /// 0x11 - GT + /// # Specification: https://www.evm.codes/#11?fork=shanghai + fn exec_gt(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::VERYLOW)?; + let popped = self.stack.pop_n(2)?; + let a = *popped[0]; + let b = *popped[1]; + let result = (a > b).into(); + self.stack.push(result) + } + + + /// 0x12 - SLT + /// # Specification: https://www.evm.codes/#12?fork=shanghai + fn exec_slt(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::VERYLOW)?; + let a: i256 = self.stack.pop_i256()?; + let b: i256 = self.stack.pop_i256()?; + let result: u256 = (a < b).into(); + self.stack.push(result) + } + + /// 0x13 - SGT + /// # Specification: https://www.evm.codes/#13?fork=shanghai + fn exec_sgt(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::VERYLOW)?; + let a: i256 = self.stack.pop_i256()?; + let b: i256 = self.stack.pop_i256()?; + let result: u256 = (a > b).into(); + self.stack.push(result) + } + + + /// 0x14 - EQ + /// # Specification: https://www.evm.codes/#14?fork=shanghai + fn exec_eq(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::VERYLOW)?; + let popped = self.stack.pop_n(2)?; + let a = *popped[0]; + let b = *popped[1]; + let result = (a == b).into(); + self.stack.push(result) + } + + /// 0x15 - ISZERO + /// # Specification: https://www.evm.codes/#15?fork=shanghai + fn exec_iszero(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::VERYLOW)?; + let popped = self.stack.pop()?; + let result: u256 = (popped == 0).into(); + self.stack.push(result) + } + + /// 0x16 - AND + /// # Specification: https://www.evm.codes/#16?fork=shanghai + fn exec_and(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::VERYLOW)?; + let popped = self.stack.pop_n(2)?; + let a = *popped[0]; + let b = *popped[1]; + let result = a & b; + self.stack.push(result) + } + + /// 0x17 - OR + /// # Specification: https://www.evm.codes/#17?fork=shanghai + fn exec_or(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::VERYLOW)?; + let popped = self.stack.pop_n(2)?; + let a = *popped[0]; + let b = *popped[1]; + let result = a | b; + self.stack.push(result) + } + + /// 0x18 - XOR operation + /// # Specification: https://www.evm.codes/#18?fork=shanghai + fn exec_xor(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::VERYLOW)?; + let popped = self.stack.pop_n(2)?; + let a = *popped[0]; + let b = *popped[1]; + let result = a ^ b; + self.stack.push(result) + } + + /// 0x19 - NOT + /// Bitwise NOT operation + /// # Specification: https://www.evm.codes/#19?fork=shanghai + fn exec_not(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::VERYLOW)?; + let a = self.stack.pop()?; + let result = ~a; + self.stack.push(result) + } + + /// 0x1A - BYTE + /// # Specification: https://www.evm.codes/#1a?fork=shanghai + /// Retrieve single byte located at the byte offset of value, starting from the most significant + /// byte. + fn exec_byte(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::VERYLOW)?; + let popped = self.stack.pop_n(2)?; + let i = *popped[0]; + let x = *popped[1]; + + /// If the byte offset is out of range, we early return with 0. + if i > 31 { + return self.stack.push(0); + } + + // Right shift value by offset bits and then take the least significant byte. + let result = x.shr((31 - i) * 8) & 0xFF; + self.stack.push(result) + } + + /// 0x1B - SHL + /// # Specification: https://www.evm.codes/#1b?fork=shanghai + fn exec_shl(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::VERYLOW)?; + let popped = self.stack.pop_n(2)?; + let shift = *popped[0]; + let val = *popped[1]; + + // if shift is bigger than 255 return 0 + if shift > 255 { + return self.stack.push(0); + } + + let result = val.wrapping_shl(shift); + self.stack.push(result) + } + + /// 0x1C - SHR + /// # Specification: https://www.evm.codes/#1c?fork=shanghai + fn exec_shr(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::VERYLOW)?; + let popped = self.stack.pop_n(2)?; + let shift = *popped[0]; + let value = *popped[1]; + + let result = value.wrapping_shr(shift); + self.stack.push(result) + } + + /// 0x1D - SAR + /// # Specification: https://www.evm.codes/#1d?fork=shanghai + fn exec_sar(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::VERYLOW)?; + let shift: u256 = self.stack.pop()?; + let value: i256 = self.stack.pop_i256()?; + + // Checks the MSB bit sign for a 256-bit integer + let positive = value.value.high < POW_2_127; + let sign = if positive { + // If sign is positive, set it to 0. + 0 + } else { + // If sign is negative, set the number to -1. + Bounded::::MAX + }; + + if (shift >= 256) { + self.stack.push(sign) + } else { + // XORing with sign before and after the shift propagates the sign bit of the operation + let result = (sign ^ value.value).shr(shift) ^ sign; + self.stack.push(result) + } + } +} + + +#[cfg(test)] +mod tests { + use core::num::traits::Bounded; + use crate::instructions::ComparisonAndBitwiseOperationsTrait; + use crate::stack::StackTrait; + use crate::test_utils::VMBuilderTrait; + + #[test] + fn test_eq_same_pair() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm + .stack + .push(0xFEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210) + .expect('push failed'); + vm + .stack + .push(0xFEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210) + .expect('push failed'); + + // When + vm.exec_eq().expect('exec_eq failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 0x01, 'stack top should be 0x01'); + } + + #[test] + fn test_eq_different_pair() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm + .stack + .push(0xAB8765432DCBA98765410F149E87610FDCBA98765432543217654DCBA93210F8) + .expect('push failed'); + vm + .stack + .push(0xFEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210) + .expect('push failed'); + + // When + vm.exec_eq().expect('exec_eq failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 0x00, 'stack top should be 0x00'); + } + + #[test] + fn test_and_zero_and_max() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(0x00).expect('push failed'); + vm.stack.push(Bounded::::MAX).unwrap(); + + // When + vm.exec_and().expect('exec_and failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 0x00, 'stack top should be 0x00'); + } + + #[test] + fn test_and_max_and_max() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(Bounded::::MAX).unwrap(); + vm.stack.push(Bounded::::MAX).unwrap(); + + // When + vm.exec_and().expect('exec_and failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == Bounded::::MAX, 'stack top should be 0xFF...FFF'); + } + + #[test] + fn test_and_two_random_uint() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm + .stack + .push(0xAB8765432DCBA98765410F149E87610FDCBA98765432543217654DCBA93210F8) + .expect('push failed'); + vm + .stack + .push(0xFEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210) + .expect('push failed'); + + // When + vm.exec_and().expect('exec_and failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert( + vm + .stack + .peek() + .unwrap() == 0xAA8420002440200064400A1016042000DC989810541010101644088820101010, + 'stack top is wrong' + ); + } + + + #[test] + fn test_xor_different_pair() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(0b010101).expect('push failed'); + vm.stack.push(0b101010).expect('push failed'); + + // When + vm.exec_xor().expect('exec_xor failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 0b111111, 'stack top should be 0xFF'); + } + + #[test] + fn test_xor_same_pair() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(0b000111).expect('push failed'); + vm.stack.push(0b000111).expect('push failed'); + + // When + vm.exec_xor().expect('exec_xor failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 0x00, 'stack top should be 0x00'); + } + + #[test] + fn test_xor_half_same_pair() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(0b111000).expect('push failed'); + vm.stack.push(0b000000).expect('push failed'); + + // When + vm.exec_xor().expect('exec_xor failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 0b111000, 'stack top should be 0xFF'); + } + + + #[test] + fn test_not_zero() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(0x00).expect('push failed'); + + // When + vm.exec_not().expect('exec_not failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == Bounded::::MAX, 'stack top should be 0xFFF..FFFF'); + } + + #[test] + fn test_not_max_uint() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(Bounded::::MAX).unwrap(); + + // When + vm.exec_not().expect('exec_not failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 0x00, 'stack top should be 0x00'); + } + + #[test] + fn test_not_random_uint() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm + .stack + .push(0x123456789ABCDEF123456789ABCDEF123456789ABCDEF123456789ABCDEF1234) + .expect('push failed'); + + // When + vm.exec_not().expect('exec_not failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert( + vm + .stack + .peek() + .unwrap() == 0xEDCBA9876543210EDCBA9876543210EDCBA9876543210EDCBA9876543210EDCB, + 'stack top should be 0x7553' + ); + } + + #[test] + fn test_is_zero_true() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(0x00).expect('push failed'); + + // When + vm.exec_iszero().expect('exec_iszero failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 0x01, 'stack top should be true'); + } + + #[test] + fn test_is_zero_false() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(0x01).expect('push failed'); + + // When + vm.exec_iszero().expect('exec_iszero failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 0x00, 'stack top should be false'); + } + + #[test] + fn test_byte_random_u256() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm + .stack + .push(0xf7ec8b2ea4a6b7fd5f4ed41b66197fcc14c4a37d68275ea151d899bb4d7c2ae7) + .expect('push failed'); + vm.stack.push(0x08).expect('push failed'); + + // When + vm.exec_byte().expect('exec_byte failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 0x5f, 'stack top should be 0x22'); + } + + #[test] + fn test_byte_offset_out_of_range() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm + .stack + .push(0x01be893aefcfa1592f60622b80d45c2db74281d2b9e10c14b0f6ce7c8f58e209) + .expect('push failed'); + vm.stack.push(32_u256).expect('push failed'); + + // When + vm.exec_byte().expect('exec_byte failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 0x00, 'stack top should be 0x00'); + } + + #[test] + fn test_exec_gt_true() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(9_u256).expect('push failed'); + vm.stack.push(10_u256).expect('push failed'); + + // When + vm.exec_gt().expect('exec_gt failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 1, 'stack top should be 1'); + } + + #[test] + fn test_exec_shl() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm + .stack + .push(0xff00000000000000000000000000000000000000000000000000000000000000) + .expect('push failed'); + vm.stack.push(4_u256).expect('push failed'); + + // When + vm.exec_shl().expect('exec_shl failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert( + vm + .stack + .peek() + .unwrap() == 0xf000000000000000000000000000000000000000000000000000000000000000, + 'stack top should be 0xf00000...' + ); + } + + #[test] + fn test_exec_shl_wrapping() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm + .stack + .push(0xff00000000000000000000000000000000000000000000000000000000000000) + .expect('push failed'); + vm.stack.push(256_u256).expect('push failed'); + + // When + vm.exec_shl().expect('exec_shl failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 0, 'if shift > 255 should return 0'); + } + + #[test] + fn test_exec_gt_false() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(10_u256).expect('push failed'); + vm.stack.push(9_u256).expect('push failed'); + + // When + vm.exec_gt().expect('exec_gt failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 0, 'stack top should be 0'); + } + + #[test] + fn test_exec_gt_false_equal() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(10_u256).expect('push failed'); + vm.stack.push(10_u256).expect('push failed'); + + // When + vm.exec_gt().expect('exec_gt failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 0, 'stack top should be 0'); + } + + #[test] + fn test_exec_slt() { + // https://github.com/ethereum/go-ethereum/blob/master/core/vm/testdata/testcases_slt.json + assert_slt(0x0, 0x0, 0); + assert_slt(0x0, 0x1, 0); + assert_slt(0x0, 0x5, 0); + assert_slt(0x0, 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0); + assert_slt(0x0, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0); + assert_slt(0x0, 0x8000000000000000000000000000000000000000000000000000000000000000, 1); + assert_slt(0x0, 0x8000000000000000000000000000000000000000000000000000000000000001, 1); + assert_slt(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, 1); + assert_slt(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 1); + assert_slt(0x1, 0x0, 1); + assert_slt(0x1, 0x1, 0); + assert_slt(0x1, 0x5, 0); + assert_slt(0x1, 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0); + assert_slt(0x1, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0); + assert_slt(0x0, 0x8000000000000000000000000000000000000000000000000000000000000000, 1); + assert_slt(0x1, 0x8000000000000000000000000000000000000000000000000000000000000001, 1); + assert_slt(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, 1); + assert_slt(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 1); + assert_slt(0x5, 0x0, 1); + assert_slt(0x5, 0x1, 1); + assert_slt(0x5, 0x5, 0); + assert_slt(0x5, 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0); + assert_slt(0x5, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0); + assert_slt(0x5, 0x8000000000000000000000000000000000000000000000000000000000000000, 1); + assert_slt(0x5, 0x8000000000000000000000000000000000000000000000000000000000000001, 1); + assert_slt(0x5, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, 1); + assert_slt(0x5, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 1); + assert_slt(0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0, 1); + assert_slt(0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1, 1); + assert_slt(0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x5, 1); + assert_slt( + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0 + ); + assert_slt( + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0 + ); + assert_slt( + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x8000000000000000000000000000000000000000000000000000000000000000, + 1 + ); + assert_slt( + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x8000000000000000000000000000000000000000000000000000000000000001, + 1 + ); + assert_slt( + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 1 + ); + assert_slt( + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 1 + ); + assert_slt(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0, 1); + assert_slt(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1, 1); + assert_slt(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x5, 1); + assert_slt( + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 1 + ); + assert_slt( + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0 + ); + assert_slt( + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x8000000000000000000000000000000000000000000000000000000000000000, + 1 + ); + assert_slt( + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x8000000000000000000000000000000000000000000000000000000000000001, + 1 + ); + assert_slt( + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 1 + ); + assert_slt( + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 1 + ); + assert_slt(0x8000000000000000000000000000000000000000000000000000000000000000, 0x0, 0); + assert_slt(0x8000000000000000000000000000000000000000000000000000000000000000, 0x1, 0); + assert_slt(0x8000000000000000000000000000000000000000000000000000000000000000, 0x5, 0); + assert_slt( + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0 + ); + assert_slt( + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0 + ); + assert_slt( + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0 + ); + assert_slt( + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0 + ); + assert_slt( + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0 + ); + assert_slt( + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0 + ); + assert_slt(0x8000000000000000000000000000000000000000000000000000000000000001, 0x0, 0); + assert_slt(0x8000000000000000000000000000000000000000000000000000000000000001, 0x1, 0); + assert_slt(0x8000000000000000000000000000000000000000000000000000000000000001, 0x5, 0); + assert_slt( + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0 + ); + assert_slt( + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0 + ); + assert_slt( + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x8000000000000000000000000000000000000000000000000000000000000000, + 1 + ); + assert_slt( + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0 + ); + assert_slt( + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0 + ); + assert_slt( + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0 + ); + assert_slt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, 0x0, 0); + assert_slt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, 0x1, 0); + assert_slt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, 0x5, 0); + assert_slt( + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0 + ); + assert_slt( + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0 + ); + assert_slt( + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x8000000000000000000000000000000000000000000000000000000000000000, + 1 + ); + assert_slt( + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x8000000000000000000000000000000000000000000000000000000000000001, + 1 + ); + assert_slt( + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0 + ); + assert_slt( + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0 + ); + assert_slt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0, 0); + assert_slt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1, 0); + assert_slt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x5, 0); + assert_slt( + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0 + ); + assert_slt( + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0 + ); + assert_slt( + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x8000000000000000000000000000000000000000000000000000000000000000, + 1 + ); + assert_slt( + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x8000000000000000000000000000000000000000000000000000000000000001, + 1 + ); + assert_slt( + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 1 + ); + assert_slt( + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0 + ); + } + + fn assert_slt(b: u256, a: u256, expected: u256) { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(b).expect('push failed'); + vm.stack.push(a).expect('push failed'); + + // When + vm.exec_slt().expect('exec_slt failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == expected, 'slt failed'); + } + + #[test] + fn test_exec_sgt() { + // https://github.com/ethereum/go-ethereum/blob/master/core/vm/testdata/testcases_sgt.json + assert_sgt(0x0, 0x0, 0); + assert_sgt(0x0, 0x1, 1); + assert_sgt(0x0, 0x5, 1); + assert_sgt(0x0, 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 1); + assert_sgt(0x0, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 1); + assert_sgt(0x0, 0x8000000000000000000000000000000000000000000000000000000000000000, 0); + assert_sgt(0x0, 0x8000000000000000000000000000000000000000000000000000000000000001, 0); + assert_sgt(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, 0); + assert_sgt(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0); + assert_sgt(0x1, 0x0, 0); + assert_sgt(0x1, 0x1, 0); + assert_sgt(0x1, 0x5, 1); + assert_sgt(0x1, 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 1); + assert_sgt(0x1, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 1); + assert_sgt(0x1, 0x8000000000000000000000000000000000000000000000000000000000000000, 0); + assert_sgt(0x1, 0x8000000000000000000000000000000000000000000000000000000000000001, 0); + assert_sgt(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, 0); + assert_sgt(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0); + assert_sgt(0x5, 0x0, 0); + assert_sgt(0x5, 0x1, 0); + assert_sgt(0x5, 0x5, 0); + assert_sgt(0x5, 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 1); + assert_sgt(0x5, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 1); + assert_sgt(0x5, 0x8000000000000000000000000000000000000000000000000000000000000000, 0); + assert_sgt(0x5, 0x8000000000000000000000000000000000000000000000000000000000000001, 0); + assert_sgt(0x5, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, 0); + assert_sgt(0x5, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0); + assert_sgt(0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0, 0); + assert_sgt(0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1, 0); + assert_sgt(0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x5, 0); + assert_sgt( + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0 + ); + assert_sgt( + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 1 + ); + assert_sgt( + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0 + ); + assert_sgt( + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0 + ); + assert_sgt( + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0 + ); + assert_sgt( + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0 + ); + assert_sgt(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0, 0); + assert_sgt(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1, 0); + assert_sgt(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x5, 0); + assert_sgt( + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0 + ); + assert_sgt( + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0 + ); + assert_sgt( + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0 + ); + assert_sgt( + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0 + ); + assert_sgt( + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0 + ); + assert_sgt( + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0 + ); + assert_sgt(0x8000000000000000000000000000000000000000000000000000000000000000, 0x0, 1); + assert_sgt(0x8000000000000000000000000000000000000000000000000000000000000000, 0x1, 1); + assert_sgt(0x8000000000000000000000000000000000000000000000000000000000000000, 0x5, 1); + assert_sgt( + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 1 + ); + assert_sgt( + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 1 + ); + assert_sgt( + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0 + ); + assert_sgt( + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x8000000000000000000000000000000000000000000000000000000000000001, + 1 + ); + assert_sgt( + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 1 + ); + assert_sgt( + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 1 + ); + assert_sgt(0x8000000000000000000000000000000000000000000000000000000000000001, 0x0, 1); + assert_sgt(0x8000000000000000000000000000000000000000000000000000000000000001, 0x1, 1); + assert_sgt(0x8000000000000000000000000000000000000000000000000000000000000001, 0x5, 1); + assert_sgt( + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 1 + ); + assert_sgt( + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 1 + ); + assert_sgt( + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0 + ); + assert_sgt( + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0 + ); + assert_sgt( + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 1 + ); + assert_sgt( + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 1 + ); + assert_sgt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, 0x0, 1); + assert_sgt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, 0x1, 1); + assert_sgt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, 0x5, 1); + assert_sgt( + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 1 + ); + assert_sgt( + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 1 + ); + assert_sgt( + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0 + ); + assert_sgt( + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0 + ); + assert_sgt( + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0 + ); + assert_sgt( + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 1 + ); + assert_sgt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0, 1); + assert_sgt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1, 1); + assert_sgt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x5, 1); + assert_sgt( + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 1 + ); + assert_sgt( + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 1 + ); + assert_sgt( + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0 + ); + assert_sgt( + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0 + ); + assert_sgt( + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0 + ); + assert_sgt( + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0 + ); + } + + fn assert_sgt(b: u256, a: u256, expected: u256) { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(b).expect('push failed'); + vm.stack.push(a).expect('push failed'); + + // When + vm.exec_sgt().expect('exec_sgt failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == expected, 'sgt failed'); + } + + #[test] + fn test_exec_shr() { + // https://github.com/ethereum/go-ethereum/blob/master/core/vm/testdata/testcases_shr.json + assert_shr( + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0x0000000000000000000000000000000000000000000000000000000000000001 + ); + assert_shr( + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0x0000000000000000000000000000000000000000000000000000000000000005 + ); + assert_shr( + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000002 + ); + assert_shr( + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe + ); + assert_shr( + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_shr( + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0x03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_shr( + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_shr( + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_shr( + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0x03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_shr( + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0x8000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0x4000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0x0400000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0x8000000000000000000000000000000000000000000000000000000000000001 + ); + assert_shr( + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0x4000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0x0400000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb + ); + assert_shr( + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd + ); + assert_shr( + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0x07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_shr( + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_shr( + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_shr( + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0x07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_shr( + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_shr( + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + } + + fn assert_shr(a: u256, b: u256, expected: u256) { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(a).expect('push failed'); + vm.stack.push(b).expect('push failed'); + + // When + vm.exec_shr().expect('exec_shr failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == expected, 'shr failed'); + } + + #[test] + fn test_exec_sar() { + // https://github.com/ethereum/go-ethereum/blob/master/core/vm/testdata/testcases_sar.json + assert_sar( + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0x0000000000000000000000000000000000000000000000000000000000000001 + ); + assert_sar( + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0x0000000000000000000000000000000000000000000000000000000000000005 + ); + assert_sar( + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000002 + ); + assert_sar( + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe + ); + assert_sar( + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_sar( + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0x03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_sar( + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_sar( + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_sar( + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0x03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_sar( + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0x8000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0xc000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0xfc00000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_sar( + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_sar( + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_sar( + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_sar( + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_sar( + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_sar( + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0x8000000000000000000000000000000000000000000000000000000000000001 + ); + assert_sar( + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0xc000000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0xfc00000000000000000000000000000000000000000000000000000000000000 + ); + assert_sar( + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_sar( + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_sar( + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_sar( + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_sar( + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_sar( + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_sar( + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb + ); + assert_sar( + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd + ); + assert_sar( + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_sar( + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_sar( + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_sar( + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_sar( + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_sar( + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_sar( + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_sar( + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000000, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_sar( + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000001, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_sar( + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x0000000000000000000000000000000000000000000000000000000000000005, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_sar( + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_sar( + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_sar( + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x8000000000000000000000000000000000000000000000000000000000000000, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_sar( + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0x8000000000000000000000000000000000000000000000000000000000000001, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_sar( + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + assert_sar( + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + } + + fn assert_sar(a: u256, b: u256, expected: u256) { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(a).expect('push failed'); + vm.stack.push(b).expect('push failed'); + + // When + + vm.exec_sar().expect('exec_sar failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == expected, 'sar failed'); + } + + #[test] + fn test_exec_or_should_pop_0_and_1_and_push_0xCD_when_0_is_0x89_and_1_is_0xC5() { + //Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(0x89).expect('push failed'); + vm.stack.push(0xC5).expect('push failed'); + + //When + vm.exec_or().expect('exec_or failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 0xCD, 'stack top should be 0xCD'); + } + + #[test] + fn test_or_true() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(0x01).expect('push failed'); + vm.stack.push(0x00).expect('push failed'); + + // When + vm.exec_or().expect('exec_or failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 0x01, 'stack top should be 0x01'); + } + + #[test] + fn test_or_false() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(0x00).expect('push failed'); + vm.stack.push(0x00).expect('push failed'); + + // When + vm.exec_or().expect('exec_or failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 0x00, 'stack top should be 0x00'); + } + + + #[test] + fn test_exec_lt_true() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(10_u256).expect('push failed'); + vm.stack.push(9_u256).expect('push failed'); + + // When + vm.exec_lt().expect('exec_lt failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 0x01, 'stack top should be true'); + } + + #[test] + fn test_exec_lt_false() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(10_u256).expect('push failed'); + vm.stack.push(20_u256).expect('push failed'); + + // When + vm.exec_lt().expect('exec_lt failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 0x00, 'stack top should be false'); + } + + #[test] + fn test_exec_lt_false_eq() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(10_u256).expect('push failed'); + vm.stack.push(10_u256).expect('push failed'); + + // When + vm.exec_lt().expect('exec_lt failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 0x00, 'stack top should be false'); + } +} diff --git a/kakarot-ssj/crates/evm/src/instructions/duplication_operations.cairo b/kakarot-ssj/crates/evm/src/instructions/duplication_operations.cairo new file mode 100644 index 000000000..5752279ba --- /dev/null +++ b/kakarot-ssj/crates/evm/src/instructions/duplication_operations.cairo @@ -0,0 +1,556 @@ +//! Duplication Operations. + +// Internal imports +use crate::errors::EVMError; +use crate::gas; +use crate::model::vm::{VM, VMTrait}; +use crate::stack::StackTrait; + +/// Generic DUP operation +#[inline(always)] +fn exec_dup_i(ref self: VM, i: u8) -> Result<(), EVMError> { + self.charge_gas(gas::VERYLOW)?; + let item = self.stack.peek_at((i - 1).into())?; + self.stack.push(item) +} + +#[generate_trait] +pub impl DuplicationOperations of DuplicationOperationsTrait { + /// 0x80 - DUP1 operation + #[inline(always)] + fn exec_dup1(ref self: VM) -> Result<(), EVMError> { + exec_dup_i(ref self, 1) + } + + /// 0x81 - DUP2 operation + #[inline(always)] + fn exec_dup2(ref self: VM) -> Result<(), EVMError> { + exec_dup_i(ref self, 2) + } + + /// 0x82 - DUP3 operation + #[inline(always)] + fn exec_dup3(ref self: VM) -> Result<(), EVMError> { + exec_dup_i(ref self, 3) + } + + /// 0x83 - DUP2 operation + #[inline(always)] + fn exec_dup4(ref self: VM) -> Result<(), EVMError> { + exec_dup_i(ref self, 4) + } + + /// 0x84 - DUP5 operation + #[inline(always)] + fn exec_dup5(ref self: VM) -> Result<(), EVMError> { + exec_dup_i(ref self, 5) + } + + /// 0x85 - DUP6 operation + #[inline(always)] + fn exec_dup6(ref self: VM) -> Result<(), EVMError> { + exec_dup_i(ref self, 6) + } + + /// 0x86 - DUP7 operation + #[inline(always)] + fn exec_dup7(ref self: VM) -> Result<(), EVMError> { + exec_dup_i(ref self, 7) + } + + /// 0x87 - DUP8 operation + #[inline(always)] + fn exec_dup8(ref self: VM) -> Result<(), EVMError> { + exec_dup_i(ref self, 8) + } + + /// 0x88 - DUP9 operation + #[inline(always)] + fn exec_dup9(ref self: VM) -> Result<(), EVMError> { + exec_dup_i(ref self, 9) + } + + /// 0x89 - DUP10 operation + #[inline(always)] + fn exec_dup10(ref self: VM) -> Result<(), EVMError> { + exec_dup_i(ref self, 10) + } + + /// 0x8A - DUP11 operation + #[inline(always)] + fn exec_dup11(ref self: VM) -> Result<(), EVMError> { + exec_dup_i(ref self, 11) + } + + /// 0x8B - DUP12 operation + #[inline(always)] + fn exec_dup12(ref self: VM) -> Result<(), EVMError> { + exec_dup_i(ref self, 12) + } + + /// 0x8C - DUP13 operation + #[inline(always)] + fn exec_dup13(ref self: VM) -> Result<(), EVMError> { + exec_dup_i(ref self, 13) + } + + /// 0x8D - DUP14 operation + #[inline(always)] + fn exec_dup14(ref self: VM) -> Result<(), EVMError> { + exec_dup_i(ref self, 14) + } + + /// 0x8E - DUP15 operation + #[inline(always)] + fn exec_dup15(ref self: VM) -> Result<(), EVMError> { + exec_dup_i(ref self, 15) + } + + /// 0x8F - DUP16 operation + #[inline(always)] + fn exec_dup16(ref self: VM) -> Result<(), EVMError> { + exec_dup_i(ref self, 16) + } +} + +#[cfg(test)] +mod tests { + use crate::instructions::DuplicationOperationsTrait; + use crate::stack::Stack; + use crate::stack::StackTrait; + use crate::test_utils::VMBuilderTrait; + + + // ensures all values start from index `from` upto index `to` of stack are `0x0` + fn ensures_zeros(ref stack: Stack, from: u32, to: u32) { + if to > from { + return; + } + + for idx in from..to { + assert(stack.peek_at(idx).unwrap() == 0x00, 'should be zero'); + }; + } + + // push `n` number of `0x0` to the stack + fn push_zeros(ref stack: Stack, n: u8) { + for _ in 0..n { + stack.push(0x0).unwrap(); + }; + } + + #[test] + fn test_dup1() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + let initial_len = vm.stack.len(); + + vm.stack.push(0x01).expect('push failed'); + + let old_stack_len = vm.stack.len(); + + // When + vm.exec_dup1().expect('exec_dup1 failed'); + + // Then + let new_stack_len = vm.stack.len(); + + assert(new_stack_len == old_stack_len + 1, 'len should increase by 1'); + + assert(vm.stack.peek_at(initial_len).unwrap() == 0x01, 'first inserted spot should be 1'); + assert(vm.stack.peek_at(new_stack_len - 1).unwrap() == 0x01, 'top of stack should be 1'); + + ensures_zeros(ref vm.stack, initial_len + 1, new_stack_len - 1); + } + + #[test] + fn test_dup2() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + let initial_len = vm.stack.len(); + + vm.stack.push(0x01).expect('push failed'); + push_zeros(ref vm.stack, 1); + + let old_stack_len = vm.stack.len(); + + // When + vm.exec_dup2().expect('exec_dup2 failed'); + + // Then + let new_stack_len = vm.stack.len(); + + assert(new_stack_len == old_stack_len + 1, 'len should increase by 1'); + + assert(vm.stack.peek_at(initial_len).unwrap() == 0x01, 'first inserted spot should be 1'); + assert(vm.stack.peek_at(new_stack_len - 1).unwrap() == 0x01, 'top of stack should be 1'); + + ensures_zeros(ref vm.stack, initial_len + 1, new_stack_len - 1); + } + + #[test] + fn test_dup3() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + let initial_len = vm.stack.len(); + + vm.stack.push(0x01).expect('push failed'); + push_zeros(ref vm.stack, 2); + + let old_stack_len = vm.stack.len(); + + // When + vm.exec_dup3().expect('exec_dup3 failed'); + + // Then + let new_stack_len = vm.stack.len(); + + assert(new_stack_len == old_stack_len + 1, 'len should increase by 1'); + + assert(vm.stack.peek_at(initial_len).unwrap() == 0x01, 'first inserted spot should be 1'); + assert(vm.stack.peek_at(new_stack_len - 1).unwrap() == 0x01, 'top of stack should be 1'); + + ensures_zeros(ref vm.stack, initial_len + 1, new_stack_len - 1); + } + + #[test] + fn test_dup4() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + let initial_len = vm.stack.len(); + + vm.stack.push(0x01).expect('push failed'); + push_zeros(ref vm.stack, 3); + + let old_stack_len = vm.stack.len(); + + // When + vm.exec_dup4().expect('exec_dup4 failed'); + + // Then + let new_stack_len = vm.stack.len(); + + assert(new_stack_len == old_stack_len + 1, 'len should increase by 1'); + + assert(vm.stack.peek_at(initial_len).unwrap() == 0x01, 'first inserted spot should be 1'); + assert(vm.stack.peek_at(new_stack_len - 1).unwrap() == 0x01, 'top of stack should be 1'); + + ensures_zeros(ref vm.stack, initial_len + 1, new_stack_len - 1); + } + + #[test] + fn test_dup5() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + let initial_len = vm.stack.len(); + + vm.stack.push(0x01).expect('push failed'); + push_zeros(ref vm.stack, 4); + + let old_stack_len = vm.stack.len(); + + // When + vm.exec_dup5().expect('exec_dup5 failed'); + + // Then + let new_stack_len = vm.stack.len(); + + assert(new_stack_len == old_stack_len + 1, 'len should increase by 1'); + + assert(vm.stack.peek_at(initial_len).unwrap() == 0x01, 'first inserted spot should be 1'); + assert(vm.stack.peek_at(new_stack_len - 1).unwrap() == 0x01, 'top of stack should be 1'); + + ensures_zeros(ref vm.stack, initial_len + 1, new_stack_len - 1); + } + + #[test] + fn test_dup6() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + let initial_len = vm.stack.len(); + + vm.stack.push(0x01).expect('push failed'); + push_zeros(ref vm.stack, 5); + + let old_stack_len = vm.stack.len(); + + // When + vm.exec_dup6().expect('exec_dup6 failed'); + + // Then + let new_stack_len = vm.stack.len(); + + assert(new_stack_len == old_stack_len + 1, 'len should increase by 1'); + + assert(vm.stack.peek_at(initial_len).unwrap() == 0x01, 'first inserted spot should be 1'); + assert(vm.stack.peek_at(new_stack_len - 1).unwrap() == 0x01, 'top of stack should be 1'); + + ensures_zeros(ref vm.stack, initial_len + 1, new_stack_len - 1); + } + + #[test] + fn test_dup7() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + let initial_len = vm.stack.len(); + + vm.stack.push(0x01).expect('push failed'); + push_zeros(ref vm.stack, 6); + + let old_stack_len = vm.stack.len(); + + // When + vm.exec_dup7().expect('exec_dup7 failed'); + + // Then + let new_stack_len = vm.stack.len(); + + assert(new_stack_len == old_stack_len + 1, 'len should increase by 1'); + + assert(vm.stack.peek_at(initial_len).unwrap() == 0x01, 'first inserted spot should be 1'); + assert(vm.stack.peek_at(new_stack_len - 1).unwrap() == 0x01, 'top of stack should be 1'); + + ensures_zeros(ref vm.stack, initial_len + 1, new_stack_len - 1); + } + + #[test] + fn test_dup8() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + let initial_len = vm.stack.len(); + + vm.stack.push(0x01).expect('push failed'); + push_zeros(ref vm.stack, 7); + + let old_stack_len = vm.stack.len(); + + // When + vm.exec_dup8().expect('exec_dup8 failed'); + + // Then + let new_stack_len = vm.stack.len(); + + assert(new_stack_len == old_stack_len + 1, 'len should increase by 1'); + + assert(vm.stack.peek_at(initial_len).unwrap() == 0x01, 'first inserted spot should be 1'); + assert(vm.stack.peek_at(new_stack_len - 1).unwrap() == 0x01, 'top of stack should be 1'); + + ensures_zeros(ref vm.stack, initial_len + 1, new_stack_len - 1); + } + + #[test] + fn test_dup9() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + let initial_len = vm.stack.len(); + + vm.stack.push(0x01).expect('push failed'); + push_zeros(ref vm.stack, 8); + + let old_stack_len = vm.stack.len(); + + // When + vm.exec_dup9().expect('exec_dup9 failed'); + + // Then + let new_stack_len = vm.stack.len(); + + assert(new_stack_len == old_stack_len + 1, 'len should increase by 1'); + + assert(vm.stack.peek_at(initial_len).unwrap() == 0x01, 'first inserted spot should be 1'); + assert(vm.stack.peek_at(new_stack_len - 1).unwrap() == 0x01, 'top of stack should be 1'); + + ensures_zeros(ref vm.stack, initial_len + 1, new_stack_len - 1); + } + + #[test] + fn test_dup10() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + let initial_len = vm.stack.len(); + + vm.stack.push(0x01).expect('push failed'); + push_zeros(ref vm.stack, 9); + + let old_stack_len = vm.stack.len(); + + // When + vm.exec_dup10().expect('exec_dup10 failed'); + + // Then + let new_stack_len = vm.stack.len(); + + assert(new_stack_len == old_stack_len + 1, 'len should increase by 1'); + + assert(vm.stack.peek_at(initial_len).unwrap() == 0x01, 'first inserted spot should be 1'); + assert(vm.stack.peek_at(new_stack_len - 1).unwrap() == 0x01, 'top of stack should be 1'); + + ensures_zeros(ref vm.stack, initial_len + 1, new_stack_len - 1); + } + + #[test] + fn test_dup11() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + let initial_len = vm.stack.len(); + + vm.stack.push(0x01).expect('push failed'); + push_zeros(ref vm.stack, 10); + + let old_stack_len = vm.stack.len(); + + // When + vm.exec_dup11().expect('exec_dup11 failed'); + + // Then + let new_stack_len = vm.stack.len(); + + assert(new_stack_len == old_stack_len + 1, 'len should increase by 1'); + + assert(vm.stack.peek_at(initial_len).unwrap() == 0x01, 'first inserted spot should be 1'); + assert(vm.stack.peek_at(new_stack_len - 1).unwrap() == 0x01, 'top of stack should be 1'); + + ensures_zeros(ref vm.stack, initial_len + 1, new_stack_len - 1); + } + + #[test] + fn test_dup12() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + let initial_len = vm.stack.len(); + + vm.stack.push(0x01).expect('push failed'); + push_zeros(ref vm.stack, 11); + + let old_stack_len = vm.stack.len(); + + // When + vm.exec_dup12().expect('exec_dup12 failed'); + + // Then + let new_stack_len = vm.stack.len(); + + assert(new_stack_len == old_stack_len + 1, 'len should increase by 1'); + + assert(vm.stack.peek_at(initial_len).unwrap() == 0x01, 'first inserted spot should be 1'); + assert(vm.stack.peek_at(new_stack_len - 1).unwrap() == 0x01, 'top of stack should be 1'); + + ensures_zeros(ref vm.stack, initial_len + 1, new_stack_len - 1); + } + + #[test] + fn test_dup13() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + let initial_len = vm.stack.len(); + + vm.stack.push(0x01).expect('push failed'); + push_zeros(ref vm.stack, 12); + + let old_stack_len = vm.stack.len(); + + // When + vm.exec_dup13().expect('exec_dup13 failed'); + + // Then + let new_stack_len = vm.stack.len(); + + assert(new_stack_len == old_stack_len + 1, 'len should increase by 1'); + + assert(vm.stack.peek_at(initial_len).unwrap() == 0x01, 'first inserted spot should be 1'); + assert(vm.stack.peek_at(new_stack_len - 1).unwrap() == 0x01, 'top of stack should be 1'); + + ensures_zeros(ref vm.stack, initial_len + 1, new_stack_len - 1); + } + + #[test] + fn test_dup14() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + let initial_len = vm.stack.len(); + + vm.stack.push(0x01).expect('push failed'); + push_zeros(ref vm.stack, 13); + + let old_stack_len = vm.stack.len(); + + // When + vm.exec_dup14().expect('exec_dup14 failed'); + + // Then + let new_stack_len = vm.stack.len(); + + assert(new_stack_len == old_stack_len + 1, 'len should increase by 1'); + + assert(vm.stack.peek_at(initial_len).unwrap() == 0x01, 'first inserted spot should be 1'); + assert(vm.stack.peek_at(new_stack_len - 1).unwrap() == 0x01, 'top of stack should be 1'); + + ensures_zeros(ref vm.stack, initial_len + 1, new_stack_len - 1); + } + + #[test] + fn test_dup15() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + let initial_len = vm.stack.len(); + + vm.stack.push(0x01).expect('push failed'); + push_zeros(ref vm.stack, 14); + + let old_stack_len = vm.stack.len(); + + // When + vm.exec_dup15().expect('exec_dup15 failed'); + + // Then + let new_stack_len = vm.stack.len(); + + assert(new_stack_len == old_stack_len + 1, 'len should increase by 1'); + + assert(vm.stack.peek_at(initial_len).unwrap() == 0x01, 'first inserted spot should be 1'); + assert(vm.stack.peek_at(new_stack_len - 1).unwrap() == 0x01, 'top of stack should be 1'); + + ensures_zeros(ref vm.stack, initial_len + 1, new_stack_len - 1); + } + + #[test] + fn test_dup16() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + let initial_len = vm.stack.len(); + + vm.stack.push(0x01).expect('push failed'); + push_zeros(ref vm.stack, 15); + + let old_stack_len = vm.stack.len(); + + // When + vm.exec_dup16().expect('exec_dup16 failed'); + + // Then + let new_stack_len = vm.stack.len(); + + assert(new_stack_len == old_stack_len + 1, 'len should increase by 1'); + + assert(vm.stack.peek_at(initial_len).unwrap() == 0x01, 'first inserted spot should be 1'); + assert(vm.stack.peek_at(new_stack_len - 1).unwrap() == 0x01, 'top of stack should be 1'); + + ensures_zeros(ref vm.stack, initial_len + 1, new_stack_len - 1); + } +} diff --git a/kakarot-ssj/crates/evm/src/instructions/environmental_information.cairo b/kakarot-ssj/crates/evm/src/instructions/environmental_information.cairo new file mode 100644 index 000000000..d675193ff --- /dev/null +++ b/kakarot-ssj/crates/evm/src/instructions/environmental_information.cairo @@ -0,0 +1,1153 @@ +use core::num::traits::OverflowingAdd; +use core::num::traits::Zero; +use crate::errors::{ensure, EVMError}; +use crate::gas; +use crate::memory::MemoryTrait; +use crate::model::account::{AccountTrait}; +use crate::model::vm::{VM, VMTrait}; +use crate::model::{AddressTrait}; +use crate::stack::StackTrait; +use crate::state::StateTrait; +use utils::helpers::bytes_32_words_size; +use utils::set::SetTrait; +use utils::traits::bytes::FromBytes; +use utils::traits::{EthAddressIntoU256}; + + +#[generate_trait] +pub impl EnvironmentInformationImpl of EnvironmentInformationTrait { + /// 0x30 - ADDRESS + /// Get address of currently executing account. + /// # Specification: https://www.evm.codes/#30?fork=shanghai + fn exec_address(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::BASE)?; + self.stack.push(self.message().target.evm.into()) + } + + /// 0x31 - BALANCE opcode. + /// Get ETH balance of the specified address. + /// # Specification: https://www.evm.codes/#31?fork=shanghai + fn exec_balance(ref self: VM) -> Result<(), EVMError> { + let evm_address = self.stack.pop_eth_address()?; + + // GAS + if self.accessed_addresses.contains(evm_address) { + self.charge_gas(gas::WARM_ACCESS_COST)?; + } else { + self.accessed_addresses.add(evm_address); + self.charge_gas(gas::COLD_ACCOUNT_ACCESS_COST)? + } + + let balance = self.env.state.get_account(evm_address).balance(); + self.stack.push(balance) + } + + /// 0x32 - ORIGIN + /// Get execution origination address. + /// # Specification: https://www.evm.codes/#32?fork=shanghai + fn exec_origin(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::BASE)?; + self.stack.push(self.env.origin.evm.into()) + } + + /// 0x33 - CALLER + /// Get caller address. + /// # Specification: https://www.evm.codes/#33?fork=shanghai + fn exec_caller(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::BASE)?; + self.stack.push(self.message().caller.evm.into()) + } + + /// 0x34 - CALLVALUE + /// Get deposited value by the instruction/transaction responsible for this execution. + /// # Specification: https://www.evm.codes/#34?fork=shanghai + fn exec_callvalue(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::BASE)?; + self.stack.push(self.message().value) + } + + /// 0x35 - CALLDATALOAD + /// Push a word from the calldata onto the stack. + /// # Specification: https://www.evm.codes/#35?fork=shanghai + fn exec_calldataload(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::VERYLOW)?; + + let offset: usize = self.stack.pop_usize()?; + + let calldata = self.message().data; + let calldata_len = calldata.len(); + + // All bytes after the end of the calldata are set to 0. + if offset >= calldata_len { + return self.stack.push(0); + } + + // Slice the calldata + let bytes_len = core::cmp::min(32, calldata_len - offset); + let sliced = calldata.slice(offset, bytes_len); + + let mut data_to_load: u256 = sliced + .from_be_bytes_partial() + .expect('Failed to parse calldata'); + + // Fill the rest of the data to load with zeros + // TODO: optimize once we have dw-based exponentiation + for _ in 0..32 - bytes_len { + data_to_load *= 256; + }; + self.stack.push(data_to_load) + } + + /// 0x36 - CALLDATASIZE + /// Get the size of return data. + /// # Specification: https://www.evm.codes/#36?fork=shanghai + fn exec_calldatasize(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::BASE)?; + let size: u256 = self.message().data.len().into(); + self.stack.push(size) + } + + /// 0x37 - CALLDATACOPY operation + /// Save word to memory. + /// # Specification: https://www.evm.codes/#37?fork=shanghai + fn exec_calldatacopy(ref self: VM) -> Result<(), EVMError> { + let dest_offset = self.stack.pop_saturating_usize()?; + let offset = self.stack.pop_saturating_usize()?; + let size = self.stack.pop_usize()?; + + let words_size = bytes_32_words_size(size).into(); + let copy_gas_cost = gas::COPY * words_size; + let memory_expansion = gas::memory_expansion( + self.memory.size(), [(dest_offset, size)].span() + )?; + self.memory.ensure_length(memory_expansion.new_size); + self.charge_gas(gas::VERYLOW + copy_gas_cost + memory_expansion.expansion_cost)?; + + let calldata: Span = self.message().data; + copy_bytes_to_memory(ref self, calldata, dest_offset, offset, size); + Result::Ok(()) + } + + /// 0x38 - CODESIZE + /// Get size of bytecode running in current environment. + /// # Specification: https://www.evm.codes/#38?fork=shanghai + fn exec_codesize(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::BASE)?; + let size: u256 = self.message().code.len().into(); + self.stack.push(size) + } + + /// 0x39 - CODECOPY + /// Copies slice of bytecode to memory. + /// # Specification: https://www.evm.codes/#39?fork=shanghai + fn exec_codecopy(ref self: VM) -> Result<(), EVMError> { + let dest_offset = self.stack.pop_saturating_usize()?; + let offset = self.stack.pop_saturating_usize()?; + let size = self.stack.pop_usize()?; + + let words_size = bytes_32_words_size(size).into(); + let copy_gas_cost = gas::COPY * words_size; + let memory_expansion = gas::memory_expansion( + self.memory.size(), [(dest_offset, size)].span() + )?; + self.memory.ensure_length(memory_expansion.new_size); + self.charge_gas(gas::VERYLOW + copy_gas_cost + memory_expansion.expansion_cost)?; + + let bytecode: Span = self.message().code; + + copy_bytes_to_memory(ref self, bytecode, dest_offset, offset, size); + Result::Ok(()) + } + + /// 0x3A - GASPRICE + /// Get price of gas in current environment. + /// # Specification: https://www.evm.codes/#3a?fork=shanghai + fn exec_gasprice(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::BASE)?; + self.stack.push(self.env.gas_price.into()) + } + + /// 0x3B - EXTCODESIZE + /// Get size of an account's code. + /// # Specification: https://www.evm.codes/#3b?fork=shanghai + fn exec_extcodesize(ref self: VM) -> Result<(), EVMError> { + let evm_address = self.stack.pop_eth_address()?; + + // GAS + if self.accessed_addresses.contains(evm_address) { + self.charge_gas(gas::WARM_ACCESS_COST)?; + } else { + self.accessed_addresses.add(evm_address); + self.charge_gas(gas::COLD_ACCOUNT_ACCESS_COST)? + } + + let account = self.env.state.get_account(evm_address); + self.stack.push(account.code.len().into()) + } + + /// 0x3C - EXTCODECOPY + /// Copy an account's code to memory + /// # Specification: https://www.evm.codes/#3c?fork=shanghai + fn exec_extcodecopy(ref self: VM) -> Result<(), EVMError> { + let evm_address = self.stack.pop_eth_address()?; + let dest_offset = self.stack.pop_saturating_usize()?; + let offset = self.stack.pop_saturating_usize()?; + let size = self.stack.pop_usize()?; + + // GAS + let words_size = bytes_32_words_size(size).into(); + let memory_expansion = gas::memory_expansion( + self.memory.size(), [(dest_offset, size)].span() + )?; + self.memory.ensure_length(memory_expansion.new_size); + let copy_gas_cost = gas::COPY * words_size; + let access_gas_cost = if self.accessed_addresses.contains(evm_address) { + gas::WARM_ACCESS_COST + } else { + self.accessed_addresses.add(evm_address); + gas::COLD_ACCOUNT_ACCESS_COST + }; + self.charge_gas(access_gas_cost + copy_gas_cost + memory_expansion.expansion_cost)?; + + let bytecode = self.env.state.get_account(evm_address).code; + copy_bytes_to_memory(ref self, bytecode, dest_offset, offset, size); + Result::Ok(()) + } + + /// 0x3D - RETURNDATASIZE + /// Get the size of return data. + /// # Specification: https://www.evm.codes/#3d?fork=shanghai + fn exec_returndatasize(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::BASE)?; + let size = self.return_data().len(); + self.stack.push(size.into()) + } + + /// 0x3E - RETURNDATACOPY + /// Save word to memory. + /// # Specification: https://www.evm.codes/#3e?fork=shanghai + fn exec_returndatacopy(ref self: VM) -> Result<(), EVMError> { + let dest_offset = self.stack.pop_saturating_usize()?; + let offset = self.stack.pop_saturating_usize()?; + let size = self.stack.pop_usize()?; + let return_data: Span = self.return_data(); + + let (last_returndata_index, overflow) = offset.overflowing_add(size); + if overflow { + return Result::Err(EVMError::ReturnDataOutOfBounds); + } + ensure(!(last_returndata_index > return_data.len()), EVMError::ReturnDataOutOfBounds)?; + + let words_size = bytes_32_words_size(size).into(); + let copy_gas_cost = gas::COPY * words_size; + + let memory_expansion = gas::memory_expansion( + self.memory.size(), [(dest_offset, size)].span() + )?; + self.memory.ensure_length(memory_expansion.new_size); + self.charge_gas(gas::VERYLOW + copy_gas_cost + memory_expansion.expansion_cost)?; + + let data_to_copy: Span = return_data.slice(offset, size); + self.memory.store_n(data_to_copy, dest_offset); + + Result::Ok(()) + } + + /// 0x3F - EXTCODEHASH + /// Get hash of a contract's code. + // If the account has no code, return the empty hash: + // `0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470` + // If the account does not exist, is a precompile or was destroyed (SELFDESTRUCT), return 0 + // Else return, the hash of the account's code + /// # Specification: https://www.evm.codes/#3f?fork=shanghai + fn exec_extcodehash(ref self: VM) -> Result<(), EVMError> { + let evm_address = self.stack.pop_eth_address()?; + + // GAS + if self.accessed_addresses.contains(evm_address) { + self.charge_gas(gas::WARM_ACCESS_COST)?; + } else { + self.accessed_addresses.add(evm_address); + self.charge_gas(gas::COLD_ACCOUNT_ACCESS_COST)? + } + + let account = self.env.state.get_account(evm_address); + // Relevant cases: + // https://github.com/ethereum/go-ethereum/blob/master/core/vm/instructions.go#L392 + if account.evm_address().is_precompile() + || (!account.has_code_or_nonce() && account.balance.is_zero()) { + return self.stack.push(0); + } + self.stack.push(account.code_hash) + } +} + +#[inline(always)] +fn copy_bytes_to_memory( + ref self: VM, bytes: Span, dest_offset: usize, offset: usize, size: usize +) { + let bytes_slice = if offset < bytes.len() { + bytes.slice(offset, core::cmp::min(size, bytes.len() - offset)) + } else { + [].span() + }; + + self.memory.store_padded_segment(dest_offset, size, bytes_slice); +} + + +#[cfg(test)] +mod tests { + use contracts::test_data::counter_evm_bytecode; + use core::starknet::EthAddress; + use crate::errors::{EVMError, TYPE_CONVERSION_ERROR}; + use crate::instructions::EnvironmentInformationTrait; + use crate::memory::{InternalMemoryTrait, MemoryTrait}; + + use crate::model::vm::VMTrait; + use crate::model::{Account, Address}; + use crate::stack::StackTrait; + use crate::state::StateTrait; + use crate::test_utils::{VMBuilderTrait, origin, callvalue, gas_price}; + use snforge_std::test_address; + use utils::constants::EMPTY_KECCAK; + use utils::helpers::{u256_to_bytes_array, compute_starknet_address}; + use utils::traits::array::ArrayExtTrait; + use utils::traits::bytes::{U8SpanExTrait}; + use utils::traits::{EthAddressIntoU256}; + + + mod test_internals { + use crate::memory::MemoryTrait; + use crate::test_utils::VMBuilderTrait; + use super::super::copy_bytes_to_memory; + + fn test_copy_bytes_to_memory_helper( + bytes: Span, dest_offset: usize, offset: usize, size: usize, expected: Span + ) { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + // When + copy_bytes_to_memory(ref vm, bytes, dest_offset, offset, size); + + // Then + let mut result = ArrayTrait::new(); + vm.memory.load_n(size, ref result, dest_offset); + assert_eq!(result.span(), expected); + } + + #[test] + fn test_copy_bytes_to_memory_normal_case() { + let bytes = [1, 2, 3, 4, 5].span(); + test_copy_bytes_to_memory_helper(bytes, 0, 0, 5, bytes); + } + + #[test] + fn test_copy_bytes_to_memory_with_offset() { + let bytes = [1, 2, 3, 4, 5].span(); + test_copy_bytes_to_memory_helper(bytes, 0, 2, 3, [3, 4, 5].span()); + } + + #[test] + fn test_copy_bytes_to_memory_size_larger_than_remaining_bytes() { + let bytes = [1, 2, 3, 4, 5].span(); + test_copy_bytes_to_memory_helper(bytes, 0, 3, 5, [4, 5, 0, 0, 0].span()); + } + + #[test] + fn test_copy_bytes_to_memory_offset_out_of_bounds() { + let bytes = [1, 2, 3, 4, 5].span(); + test_copy_bytes_to_memory_helper(bytes, 0, 10, 5, [0, 0, 0, 0, 0].span()); + } + + #[test] + fn test_copy_bytes_to_memory_zero_size() { + let bytes = [1, 2, 3, 4, 5].span(); + test_copy_bytes_to_memory_helper(bytes, 0, 0, 0, [].span()); + } + + #[test] + fn test_copy_bytes_to_memory_non_zero_dest_offset() { + let bytes = [1, 2, 3, 4, 5].span(); + test_copy_bytes_to_memory_helper(bytes, 10, 0, 5, bytes); + } + } + + // ************************************************************************* + // 0x30: ADDRESS + // ************************************************************************* + + #[test] + fn test_address_basic() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + // When + vm.exec_address().expect('exec_address failed'); + + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.pop_eth_address().unwrap(), vm.message().target.evm.into()); + } + + // ************************************************************************* + // 0x31: BALANCE + // ************************************************************************* + #[test] + fn test_exec_balance_eoa() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + let account = Account { + address: vm.message().target, + balance: 400, + nonce: 0, + code: [].span(), + code_hash: EMPTY_KECCAK, + selfdestruct: false, + is_created: true, + }; + vm.env.state.set_account(account); + vm.stack.push(vm.message.target.evm.into()).unwrap(); + + // When + vm.exec_balance().expect('exec_balance failed'); + + // Then + assert_eq!(vm.stack.peek().unwrap(), 400); + } + + // ************************************************************************* + // 0x33: CALLER + // ************************************************************************* + #[test] + fn test_caller() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + // When + vm.exec_caller().expect('exec_caller failed'); + + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.peek().unwrap(), origin().into()); + } + + + // ************************************************************************* + // 0x32: ORIGIN + // ************************************************************************* + #[test] + fn test_origin_nested_ctx() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + // When + vm.exec_origin().expect('exec_origin failed'); + + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.peek().unwrap(), vm.env.origin.evm.into()); + } + + + // ************************************************************************* + // 0x34: CALLVALUE + // ************************************************************************* + #[test] + fn test_exec_callvalue() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + // When + vm.exec_callvalue().expect('exec_callvalue failed'); + + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.pop().unwrap(), callvalue()); + } + + // ************************************************************************* + // 0x35: CALLDATALOAD + // ************************************************************************* + + #[test] + fn test_calldataload() { + // Given + let calldata = u256_to_bytes_array( + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + ); + let mut vm = VMBuilderTrait::new_with_presets().with_calldata(calldata.span()).build(); + + let offset: u32 = 0; + vm.stack.push(offset.into()).expect('push failed'); + + // When + vm.exec_calldataload().expect('exec_calldataload failed'); + + // Then + let result: u256 = vm.stack.pop().unwrap(); + assert_eq!(result, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + } + + #[test] + fn test_calldataload_with_offset() { + // Given + let calldata = u256_to_bytes_array( + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + ); + + let mut vm = VMBuilderTrait::new_with_presets().with_calldata(calldata.span()).build(); + + let offset: u32 = 31; + vm.stack.push(offset.into()).expect('push failed'); + + // When + vm.exec_calldataload().expect('exec_calldataload failed'); + + // Then + let result: u256 = vm.stack.pop().unwrap(); + + assert_eq!(result, 0xFF00000000000000000000000000000000000000000000000000000000000000); + } + + #[test] + fn test_calldataload_with_offset_beyond_calldata() { + // Given + let calldata = u256_to_bytes_array( + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + ); + let mut vm = VMBuilderTrait::new_with_presets().with_calldata(calldata.span()).build(); + + let offset: u32 = calldata.len() + 1; + vm.stack.push(offset.into()).expect('push failed'); + + // When + vm.exec_calldataload().expect('exec_calldataload failed'); + + // Then + let result: u256 = vm.stack.pop().unwrap(); + assert_eq!(result, 0); + } + + #[test] + fn test_calldataload_with_function_selector() { + // Given + let calldata = array![0x6d, 0x4c, 0xe6, 0x3c]; + let mut vm = VMBuilderTrait::new_with_presets().with_calldata(calldata.span()).build(); + + let offset: u32 = 0; + vm.stack.push(offset.into()).expect('push failed'); + + // When + vm.exec_calldataload().expect('exec_calldataload failed'); + + // Then + let result: u256 = vm.stack.pop().unwrap(); + assert_eq!(result, 0x6d4ce63c00000000000000000000000000000000000000000000000000000000); + } + + + #[test] + fn test_calldataload_with_offset_conversion_error() { + // Given + let calldata = u256_to_bytes_array( + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + ); + let mut vm = VMBuilderTrait::new_with_presets().with_calldata(calldata.span()).build(); + let offset: u256 = 5000000000; + vm.stack.push(offset).expect('push failed'); + + // When + let result = vm.exec_calldataload(); + + // Then + assert!(result.is_err()); + assert_eq!(result.unwrap_err(), EVMError::TypeConversionError(TYPE_CONVERSION_ERROR)); + } + + // ************************************************************************* + // 0x36: CALLDATASIZE + // ************************************************************************* + + #[test] + fn test_calldata_size() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + let calldata: Span = vm.message.data; + + // When + vm.exec_calldatasize().expect('exec_calldatasize failed'); + + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.peek().unwrap(), calldata.len().into()); + } + + // ************************************************************************* + // 0x37: CALLDATACOPY + // ************************************************************************* + + #[test] + fn test_calldatacopy_type_conversion_error() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm + .stack + .push(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) + .expect('push failed'); + vm + .stack + .push(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) + .expect('push failed'); + vm + .stack + .push(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) + .expect('push failed'); + + // When + let res = vm.exec_calldatacopy(); + + // Then + assert!(res.is_err()); + assert_eq!(res.unwrap_err(), EVMError::TypeConversionError(TYPE_CONVERSION_ERROR)); + } + + #[test] + fn test_calldatacopy_basic() { + test_calldatacopy(32, 0, 3, [4, 5, 6].span()); + } + + #[test] + fn test_calldatacopy_with_out_of_bound_bytes() { + // For out of bound bytes, 0s will be copied. + let mut expected = array![4, 5, 6]; + expected.append_n(0, 5); + + test_calldatacopy(32, 0, 8, expected.span()); + } + + #[test] + fn test_calldatacopy_with_out_of_bound_bytes_multiple_words() { + // For out of bound bytes, 0s will be copied. + let mut expected = array![4, 5, 6]; + expected.append_n(0, 31); + + test_calldatacopy(32, 0, 34, expected.span()); + } + + fn test_calldatacopy(dest_offset: u32, offset: u32, mut size: u32, expected: Span) { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + let _calldata: Span = vm.message.data; + + vm.stack.push(size.into()).expect('push failed'); + vm.stack.push(offset.into()).expect('push failed'); + vm.stack.push(dest_offset.into()).expect('push failed'); + + // Memory initialization with a value to verify that if the offset + size is out of the + // bound bytes, 0's have been copied. + // Otherwise, the memory value would be 0, and we wouldn't be able to check it. + for i in 0 + ..(size / 32) + + 1 { + vm + .memory + .store( + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, + dest_offset + (i * 32) + ); + + let initial: u256 = vm.memory.load_internal(dest_offset + (i * 32)).into(); + + assert_eq!( + initial, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + ); + }; + + // When + vm.exec_calldatacopy().expect('exec_calldatacopy failed'); + + // Then + assert!(vm.stack.is_empty()); + + let mut results: Array = ArrayTrait::new(); + vm.memory.load_n_internal(size, ref results, dest_offset); + + assert_eq!(results.span(), expected); + } + + // ************************************************************************* + // 0x38: CODESIZE + // ************************************************************************* + + #[test] + fn test_codesize() { + // Given + let bytecode: Span = [1, 2, 3, 4, 5].span(); + + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(bytecode).build(); + + // When + vm.exec_codesize().expect('exec_codesize failed'); + + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.pop().unwrap(), bytecode.len().into()); + } + + // ************************************************************************* + // 0x39: CODECOPY + // ************************************************************************* + + #[test] + fn test_codecopy_type_conversion_error() { + // Given + let bytecode: Span = [1, 2, 3, 4, 5].span(); + + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(bytecode).build(); + + vm + .stack + .push(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) + .expect('push failed'); + vm + .stack + .push(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) + .expect('push failed'); + vm + .stack + .push(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) + .expect('push failed'); + + // When + let res = vm.exec_codecopy(); + + // Then + assert!(res.is_err()); + assert_eq!(res.unwrap_err(), EVMError::TypeConversionError(TYPE_CONVERSION_ERROR)); + } + + #[test] + fn test_codecopy_basic() { + test_codecopy(32, 0, 0); + } + + #[test] + fn test_codecopy_with_out_of_bound_bytes() { + test_codecopy(32, 0, 8); + } + + #[test] + fn test_codecopy_with_out_of_bound_offset() { + test_codecopy(0, 0xFFFFFFFE, 2); + } + + fn test_codecopy(dest_offset: u32, offset: u32, mut size: u32) { + // Given + let bytecode: Span = [1, 2, 3, 4, 5].span(); + + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(bytecode).build(); + + if (size == 0) { + size = bytecode.len() - offset; + } + + vm.stack.push(size.into()).expect('push failed'); + vm.stack.push(offset.into()).expect('push failed'); + vm.stack.push(dest_offset.into()).expect('push failed'); + + vm + .memory + .store(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, dest_offset); + let initial: u256 = vm.memory.load_internal(dest_offset).into(); + assert_eq!(initial, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + + // When + vm.exec_codecopy().expect('exec_codecopy failed'); + + // Then + assert!(vm.stack.is_empty()); + + let result: u256 = vm.memory.load_internal(dest_offset).into(); + let mut results: Array = u256_to_bytes_array(result); + + for i in 0 + ..size { + // For out of bound bytes, 0s will be copied. + if (i + offset >= bytecode.len()) { + assert_eq!(*results[i], 0); + } else { + assert_eq!(*results[i], *bytecode[i + offset]); + } + }; + } + + // ************************************************************************* + // 0x3A: GASPRICE + // ************************************************************************* + + #[test] + fn test_gasprice() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + // When + vm.exec_gasprice().expect('exec_gasprice failed'); + + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.peek().unwrap(), gas_price().into()); + } + + // ************************************************************************* + // 0x3B - EXTCODESIZE + // ************************************************************************* + #[test] + fn test_exec_extcodesize_should_push_bytecode_len_0() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + let account = Account { + address: vm.message().target, + balance: 1, + nonce: 1, + code: [].span(), + code_hash: EMPTY_KECCAK, + selfdestruct: false, + is_created: true, + }; + vm.env.state.set_account(account); + vm.stack.push(account.address.evm.into()).expect('push failed'); + + // When + vm.exec_extcodesize().unwrap(); + + // Then + assert_eq!(vm.stack.peek().unwrap(), 0); + } + + #[test] + fn test_exec_extcodesize_should_push_bytecode_len() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + let bytecode = [0xff; 350].span(); + let code_hash = bytecode.compute_keccak256_hash(); + let account = Account { + address: vm.message().target, + balance: 1, + nonce: 1, + code: bytecode, + code_hash, + selfdestruct: false, + is_created: true, + }; + vm.env.state.set_account(account); + vm.stack.push(account.address.evm.into()).expect('push failed'); + + // When + vm.exec_extcodesize().unwrap(); + + // Then + assert_eq!(vm.stack.peek().unwrap(), 350); + } + + // ************************************************************************* + // 0x3C - EXTCODECOPY + // ************************************************************************* + + #[test] + fn test_exec_extcodecopy_should_copy_code_of_input_account() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + let bytecode = counter_evm_bytecode(); + let code_hash = bytecode.compute_keccak256_hash(); + let account = Account { + address: vm.message().target, + balance: 1, + nonce: 1, + code: bytecode, + code_hash, + selfdestruct: false, + is_created: true, + }; + vm.env.state.set_account(account); + + vm.stack.push(account.address.evm.into()).expect('push failed'); + // size + vm.stack.push(50).expect('push failed'); + // offset + vm.stack.push(200).expect('push failed'); + // destOffset (memory offset) + vm.stack.push(20).expect('push failed'); + vm.stack.push(account.address.evm.into()).unwrap(); + + // When + vm.exec_extcodecopy().unwrap(); + + // Then + let mut bytecode_slice = array![]; + vm.memory.load_n(50, ref bytecode_slice, 20); + assert_eq!(bytecode_slice.span(), account.code.slice(200, 50)); + } + + #[test] + fn test_exec_extcodecopy_ca_offset_out_of_bounds_should_return_zeroes() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + let bytecode = counter_evm_bytecode(); + let code_hash = bytecode.compute_keccak256_hash(); + let account = Account { + address: vm.message().target, + balance: 1, + nonce: 1, + code: bytecode, + code_hash, + selfdestruct: false, + is_created: true, + }; + vm.env.state.set_account(account); + vm.stack.push(account.address.evm.into()).expect('push failed'); + + // size + vm.stack.push(5).expect('push failed'); + // offset + vm.stack.push(5000).expect('push failed'); + // destOffset + vm.stack.push(20).expect('push failed'); + vm.stack.push(account.address.evm.into()).expect('push failed'); + + // When + vm.exec_extcodecopy().unwrap(); + + // Then + let mut bytecode_slice = array![]; + vm.memory.load_n(5, ref bytecode_slice, 20); + assert_eq!(bytecode_slice.span(), [0, 0, 0, 0, 0].span()); + } + + #[test] + fn test_exec_returndatasize() { + // Given + let return_data: Array = array![1, 2, 3, 4, 5]; + let size = return_data.len(); + + let mut vm = VMBuilderTrait::new_with_presets() + .with_return_data(return_data.span()) + .build(); + + vm.exec_returndatasize().expect('exec_returndatasize failed'); + + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.pop().unwrap(), size.into()); + } + + // ************************************************************************* + // 0x3E: RETURNDATACOPY + // ************************************************************************* + + #[test] + fn test_returndata_copy_type_conversion_error() { + // Given + let return_data: Array = array![1, 2, 3, 4, 5]; + let mut vm = VMBuilderTrait::new_with_presets() + .with_return_data(return_data.span()) + .build(); + + vm + .stack + .push(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) + .expect('push failed'); + vm + .stack + .push(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) + .expect('push failed'); + vm + .stack + .push(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) + .expect('push failed'); + + // When + let res = vm.exec_returndatacopy(); + + // Then + assert_eq!(res.unwrap_err(), EVMError::TypeConversionError(TYPE_CONVERSION_ERROR)); + } + + fn test_returndatacopy_helper( + return_data: Span, + dest_offset: u32, + offset: u32, + size: u32, + expected_result: Result, EVMError> + ) { + // Given + let mut vm = VMBuilderTrait::new_with_presets().with_return_data(return_data).build(); + + vm.stack.push(size.into()).expect('push failed'); + vm.stack.push(offset.into()).expect('push failed'); + vm.stack.push(dest_offset.into()).expect('push failed'); + + // When + let res = vm.exec_returndatacopy(); + + // Then + match expected_result { + Result::Ok(expected) => { + assert!(res.is_ok()); + let mut result = ArrayTrait::new(); + vm + .memory + .load_n(size.try_into().unwrap(), ref result, dest_offset.try_into().unwrap()); + assert_eq!(result.span(), expected); + }, + Result::Err(expected_error) => { + assert!(res.is_err()); + assert_eq!(res.unwrap_err(), expected_error); + } + } + } + + #[test] + fn test_returndatacopy_basic() { + let return_data = array![1, 2, 3, 4, 5].span(); + test_returndatacopy_helper(return_data, 0, 0, 5, Result::Ok(return_data)); + } + + #[test] + fn test_returndatacopy_with_offset() { + let return_data = array![1, 2, 3, 4, 5].span(); + test_returndatacopy_helper(return_data, 0, 2, 3, Result::Ok([3, 4, 5].span())); + } + + #[test] + fn test_returndatacopy_out_of_bounds() { + let return_data = array![1, 2, 3, 4, 5].span(); + test_returndatacopy_helper( + return_data, 0, 3, 3, Result::Err(EVMError::ReturnDataOutOfBounds) + ); + } + + #[test] + fn test_returndatacopy_overflowing_add() { + let return_data = array![1, 2, 3, 4, 5].span(); + test_returndatacopy_helper( + return_data, 0, 0xFFFFFFFF, 1, Result::Err(EVMError::ReturnDataOutOfBounds) + ); + } + + // ************************************************************************* + // 0x3F: EXTCODEHASH + // ************************************************************************* + #[test] + fn test_exec_extcodehash_precompile() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + let precompile_evm_address: EthAddress = evm::precompiles::LAST_ETHEREUM_PRECOMPILE_ADDRESS + .try_into() + .unwrap(); + let precompile_starknet_address = compute_starknet_address( + test_address(), precompile_evm_address, 0.try_into().unwrap() + ); + let account = Account { + address: Address { + evm: precompile_evm_address, starknet: precompile_starknet_address, + }, + balance: 1, + nonce: 0, + code: [].span(), + code_hash: EMPTY_KECCAK, + selfdestruct: false, + is_created: true, + }; + vm.env.state.set_account(account); + vm.stack.push(precompile_evm_address.into()).expect('push failed'); + + // When + vm.exec_extcodehash().unwrap(); + + // Then + assert_eq!(vm.stack.peek().unwrap(), 0); + } + + #[test] + fn test_exec_extcodehash_empty_account() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + let account = Account { + address: vm.message().target, + balance: 0, + nonce: 0, + code: [].span(), + code_hash: EMPTY_KECCAK, + selfdestruct: false, + is_created: true, + }; + vm.env.state.set_account(account); + vm.stack.push(account.address.evm.into()).expect('push failed'); + + // When + vm.exec_extcodehash().unwrap(); + + // Then + assert_eq!(vm.stack.peek().unwrap(), 0); + } + + #[test] + fn test_exec_extcodehash_no_bytecode() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + let account = Account { + address: vm.message().target, + balance: 1, + nonce: 1, + code: [].span(), + code_hash: EMPTY_KECCAK, + selfdestruct: false, + is_created: true, + }; + vm.env.state.set_account(account); + vm.stack.push(account.address.evm.into()).expect('push failed'); + + // When + vm.exec_extcodehash().unwrap(); + + // Then + assert_eq!(vm.stack.peek().unwrap(), EMPTY_KECCAK); + } + + #[test] + fn test_exec_extcodehash_with_bytecode() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + let bytecode = counter_evm_bytecode(); + let code_hash = bytecode.compute_keccak256_hash(); + let account = Account { + address: vm.message().target, + balance: 1, + nonce: 1, + code: bytecode, + code_hash, + selfdestruct: false, + is_created: true, + }; + vm.env.state.set_account(account); + vm.stack.push(account.address.evm.into()).expect('push failed'); + + // When + vm.exec_extcodehash().unwrap(); + + // Then + assert_eq!( + vm.stack.peek() // extcodehash(Counter.sol) := + // 0x82abf19c13d2262cc530f54956af7e4ec1f45f637238ed35ed7400a3409fd275 (source: + // remix) + // + .unwrap(), + 0xec976f44607e73ea88910411e3da156757b63bea5547b169e1e0d733443f73b0, + ); + } +} diff --git a/kakarot-ssj/crates/evm/src/instructions/exchange_operations.cairo b/kakarot-ssj/crates/evm/src/instructions/exchange_operations.cairo new file mode 100644 index 000000000..349e0f3c1 --- /dev/null +++ b/kakarot-ssj/crates/evm/src/instructions/exchange_operations.cairo @@ -0,0 +1,439 @@ +//! Exchange Operations. + +use crate::errors::EVMError; +use crate::gas; +use crate::model::vm::{VM, VMTrait}; +use crate::stack::StackTrait; + +/// Place i bytes items on stack. +#[inline(always)] +fn exec_swap_i(ref self: VM, i: u8) -> Result<(), EVMError> { + self.charge_gas(gas::VERYLOW)?; + self.stack.swap_i(i.into()) +} + +#[generate_trait] +pub impl ExchangeOperations of ExchangeOperationsTrait { + /// 0x90 - SWAP1 operation + /// Exchange 1st and 2nd stack items. + /// # Specification: https://www.evm.codes/#90?fork=shanghai + + fn exec_swap1(ref self: VM) -> Result<(), EVMError> { + exec_swap_i(ref self, 1) + } + + /// 0x91 - SWAP2 operation + /// Exchange 1st and 3rd stack items. + /// # Specification: https://www.evm.codes/#91?fork=shanghai + fn exec_swap2(ref self: VM) -> Result<(), EVMError> { + exec_swap_i(ref self, 2) + } + + /// 0x92 - SWAP3 operation + /// Exchange 1st and 4th stack items. + /// # Specification: https://www.evm.codes/#92?fork=shanghai + fn exec_swap3(ref self: VM) -> Result<(), EVMError> { + exec_swap_i(ref self, 3) + } + + /// 0x93 - SWAP4 operation + /// Exchange 1st and 5th stack items. + /// # Specification: https://www.evm.codes/#93?fork=shanghai + fn exec_swap4(ref self: VM) -> Result<(), EVMError> { + exec_swap_i(ref self, 4) + } + + /// 0x94 - SWAP5 operation + /// Exchange 1st and 6th stack items. + /// # Specification: https://www.evm.codes/#94?fork=shanghai + fn exec_swap5(ref self: VM) -> Result<(), EVMError> { + exec_swap_i(ref self, 5) + } + + /// 0x95 - SWAP6 operation + /// Exchange 1st and 7th stack items. + /// # Specification: https://www.evm.codes/#95?fork=shanghai + fn exec_swap6(ref self: VM) -> Result<(), EVMError> { + exec_swap_i(ref self, 6) + } + + /// 0x96 - SWAP7 operation + /// Exchange 1st and 8th stack items. + /// # Specification: https://www.evm.codes/#96?fork=shanghai + fn exec_swap7(ref self: VM) -> Result<(), EVMError> { + exec_swap_i(ref self, 7) + } + + /// 0x97 - SWAP8 operation + /// Exchange 1st and 9th stack items. + /// # Specification: https://www.evm.codes/#97?fork=shanghai + fn exec_swap8(ref self: VM) -> Result<(), EVMError> { + exec_swap_i(ref self, 8) + } + + /// 0x98 - SWAP9 operation + /// Exchange 1st and 10th stack items. + /// # Specification: https://www.evm.codes/#98?fork=shanghai + fn exec_swap9(ref self: VM) -> Result<(), EVMError> { + exec_swap_i(ref self, 9) + } + + /// 0x99 - SWAP10 operation + /// Exchange 1st and 11th stack items. + /// # Specification: https://www.evm.codes/#99?fork=shanghai + fn exec_swap10(ref self: VM) -> Result<(), EVMError> { + exec_swap_i(ref self, 10) + } + + /// 0x9A - SWAP11 operation + /// Exchange 1st and 12th stack items. + /// # Specification: https://www.evm.codes/#9a?fork=shanghai + fn exec_swap11(ref self: VM) -> Result<(), EVMError> { + exec_swap_i(ref self, 11) + } + + /// 0x9B - SWAP12 operation + /// Exchange 1st and 13th stack items. + /// # Specification: https://www.evm.codes/#9b?fork=shanghai + fn exec_swap12(ref self: VM) -> Result<(), EVMError> { + exec_swap_i(ref self, 12) + } + + /// 0x9C - SWAP13 operation + /// Exchange 1st and 14th stack items. + /// # Specification: https://www.evm.codes/#9c?fork=shanghai + fn exec_swap13(ref self: VM) -> Result<(), EVMError> { + exec_swap_i(ref self, 13) + } + + /// 0x9D - SWAP14 operation + /// Exchange 1st and 15th stack items. + /// # Specification: https://www.evm.codes/#9d?fork=shanghai + fn exec_swap14(ref self: VM) -> Result<(), EVMError> { + exec_swap_i(ref self, 14) + } + + /// 0x9E - SWAP15 operation + /// Exchange 1st and 16th stack items. + /// # Specification: https://www.evm.codes/#9e?fork=shanghai + fn exec_swap15(ref self: VM) -> Result<(), EVMError> { + exec_swap_i(ref self, 15) + } + + /// 0x9F - SWAP16 operation + /// Exchange 1st and 16th stack items. + /// # Specification: https://www.evm.codes/#9f?fork=shanghai + fn exec_swap16(ref self: VM) -> Result<(), EVMError> { + exec_swap_i(ref self, 16) + } +} + + +#[cfg(test)] +mod tests { + use crate::instructions::exchange_operations::ExchangeOperationsTrait; + use crate::stack::StackTrait; + use crate::test_utils::VMBuilderTrait; + + + #[test] + fn test_exec_swap1() { + let mut vm = VMBuilderTrait::new_with_presets().build(); + // given + vm.stack.push(0xf).expect('push failed'); + vm.stack.push(1).expect('push failed'); + vm.exec_swap1().expect('exec_swap1 failed'); + + assert(vm.stack.peek().unwrap() == 0xf, 'Top should be now 0xf'); + assert(vm.stack.peek_at(1).unwrap() == 1, 'val at index 1 should be now 1'); + } + + + #[test] + fn test_exec_swap2() { + let mut vm = VMBuilderTrait::new_with_presets().build(); + // given + vm.stack.push(0xf).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(1).expect('push failed'); + vm.exec_swap2().expect('exec_swap2 failed'); + assert(vm.stack.peek().unwrap() == 0xf, 'Top should be now 0xf'); + assert(vm.stack.peek_at(2).unwrap() == 1, 'val at index 2 should be now 1'); + } + + #[test] + fn test_exec_swap3() { + let mut vm = VMBuilderTrait::new_with_presets().build(); + // given + vm.stack.push(0xf).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(1).expect('push failed'); + vm.exec_swap3().expect('exec_swap3 failed'); + assert(vm.stack.peek().unwrap() == 0xf, 'Top should be now 0xf'); + assert(vm.stack.peek_at(3).unwrap() == 1, 'val at index 3 should be now 1'); + } + + #[test] + fn test_exec_swap4() { + let mut vm = VMBuilderTrait::new_with_presets().build(); + // given + vm.stack.push(0xf).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(1).expect('push failed'); + vm.exec_swap4().expect('exec_swap4 failed'); + assert(vm.stack.peek().unwrap() == 0xf, 'Top should be now 0xf'); + assert(vm.stack.peek_at(4).unwrap() == 1, 'val at index 4 should be now 1'); + } + + + #[test] + fn test_exec_swap5() { + let mut vm = VMBuilderTrait::new_with_presets().build(); + // given + vm.stack.push(0xf).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(1).expect('push failed'); + vm.exec_swap5().expect('exec_swap5 failed'); + assert(vm.stack.peek().unwrap() == 0xf, 'Top should be now 0xf'); + assert(vm.stack.peek_at(5).unwrap() == 1, 'val at index 5 should be now 1'); + } + + #[test] + fn test_exec_swap6() { + let mut vm = VMBuilderTrait::new_with_presets().build(); + // given + vm.stack.push(0xf).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(1).expect('push failed'); + vm.exec_swap6().expect('exec_swap6 failed'); + assert(vm.stack.peek().unwrap() == 0xf, 'Top should be now 0xf'); + assert(vm.stack.peek_at(6).unwrap() == 1, 'val at index 6 should be now 1'); + } + + + #[test] + fn test_exec_swap7() { + let mut vm = VMBuilderTrait::new_with_presets().build(); + // given + vm.stack.push(0xf).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(1).expect('push failed'); + vm.exec_swap7().expect('exec_swap7 failed'); + assert(vm.stack.peek().unwrap() == 0xf, 'Top should be now 0xf'); + assert(vm.stack.peek_at(7).unwrap() == 1, 'val at index 7 should be now 1'); + } + + #[test] + fn test_exec_swap8() { + let mut vm = VMBuilderTrait::new_with_presets().build(); + // given + vm.stack.push(0xf).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(1).expect('push failed'); + vm.exec_swap8().expect('exec_swap8 failed'); + assert(vm.stack.peek().unwrap() == 0xf, 'Top should be now 0xf'); + assert(vm.stack.peek_at(8).unwrap() == 1, 'val at index 8 should be now 1'); + } + + + #[test] + fn test_exec_swap9() { + let mut vm = VMBuilderTrait::new_with_presets().build(); + // given + vm.stack.push(0xf).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(1).expect('push failed'); + vm.exec_swap9().expect('exec_swap9 failed'); + assert(vm.stack.peek().unwrap() == 0xf, 'Top should be now 0xf'); + assert(vm.stack.peek_at(9).unwrap() == 1, 'val at index 9 should be now 1'); + } + + #[test] + fn test_exec_swap10() { + let mut vm = VMBuilderTrait::new_with_presets().build(); + // given + vm.stack.push(0xf).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(1).expect('push failed'); + vm.exec_swap10().expect('exec_swap10 failed'); + assert(vm.stack.peek().unwrap() == 0xf, 'Top should be now 0xf'); + assert(vm.stack.peek_at(10).unwrap() == 1, 'val at index 10 should be now 1'); + } + + #[test] + fn test_exec_swap11() { + let mut vm = VMBuilderTrait::new_with_presets().build(); + // given + vm.stack.push(0xf).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(1).expect('push failed'); + vm.exec_swap11().expect('exec_swap11 failed'); + assert(vm.stack.peek().unwrap() == 0xf, 'Top should be now 0xf'); + assert(vm.stack.peek_at(11).unwrap() == 1, 'val at index 11 should be now 1'); + } + + #[test] + fn test_exec_swap12() { + let mut vm = VMBuilderTrait::new_with_presets().build(); + // given + vm.stack.push(0xf).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(1).expect('push failed'); + vm.exec_swap12().expect('exec_swap12 failed'); + assert(vm.stack.peek().unwrap() == 0xf, 'Top should be now 0xf'); + assert(vm.stack.peek_at(12).unwrap() == 1, 'val at index 12 should be now 1'); + } + + #[test] + fn test_exec_swap13() { + let mut vm = VMBuilderTrait::new_with_presets().build(); + // given + vm.stack.push(0xf).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(1).expect('push failed'); + vm.exec_swap13().expect('exec_swap13 failed'); + assert(vm.stack.peek().unwrap() == 0xf, 'Top should be now 0xf'); + assert(vm.stack.peek_at(13).unwrap() == 1, 'val at index 13 should be now 1'); + } + + #[test] + fn test_exec_swap14() { + let mut vm = VMBuilderTrait::new_with_presets().build(); + // given + vm.stack.push(0xf).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(1).expect('push failed'); + vm.exec_swap14().expect('exec_swap14 failed'); + assert(vm.stack.peek().unwrap() == 0xf, 'Top should be now 0xf'); + assert(vm.stack.peek_at(14).unwrap() == 1, 'val at index 14 should be now 1'); + } + + #[test] + fn test_exec_swap15() { + let mut vm = VMBuilderTrait::new_with_presets().build(); + // given + vm.stack.push(0xf).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(1).expect('push failed'); + vm.exec_swap15().expect('exec_swap15 failed'); + assert(vm.stack.peek().unwrap() == 0xf, 'Top should be now 0xf'); + assert(vm.stack.peek_at(15).unwrap() == 1, 'val at index 15 should be now 1'); + } + + #[test] + fn test_exec_swap16() { + let mut vm = VMBuilderTrait::new_with_presets().build(); + // given + vm.stack.push(0xf).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.stack.push(1).expect('push failed'); + vm.exec_swap16().expect('exec_swap16 failed'); + assert(vm.stack.peek().unwrap() == 0xf, 'Top should be now 0xf'); + assert(vm.stack.peek_at(16).unwrap() == 1, 'val at index 16 should be now 1'); + } +} diff --git a/kakarot-ssj/crates/evm/src/instructions/logging_operations.cairo b/kakarot-ssj/crates/evm/src/instructions/logging_operations.cairo new file mode 100644 index 000000000..6e8b1cd4a --- /dev/null +++ b/kakarot-ssj/crates/evm/src/instructions/logging_operations.cairo @@ -0,0 +1,400 @@ +//! Logging Operations. + +use crate::errors::{EVMError, ensure}; +use crate::gas; +use crate::memory::MemoryTrait; +use crate::model::Event; +use crate::model::vm::{VM, VMTrait}; +use crate::stack::StackTrait; +use crate::state::StateTrait; + + +#[generate_trait] +pub impl LoggingOperations of LoggingOperationsTrait { + /// 0xA0 - LOG0 operation + /// Append log record with no topic. + /// # Specification: https://www.evm.codes/#a0?fork=shanghai + fn exec_log0(ref self: VM) -> Result<(), EVMError> { + exec_log_i(ref self, 0) + } + + /// 0xA1 - LOG1 + /// Append log record with one topic. + /// # Specification: https://www.evm.codes/#a1?fork=shanghai + fn exec_log1(ref self: VM) -> Result<(), EVMError> { + exec_log_i(ref self, 1) + } + + /// 0xA2 - LOG2 + /// Append log record with two topics. + /// # Specification: https://www.evm.codes/#a2?fork=shanghai + fn exec_log2(ref self: VM) -> Result<(), EVMError> { + exec_log_i(ref self, 2) + } + + /// 0xA3 - LOG3 + /// Append log record with three topics. + /// # Specification: https://www.evm.codes/#a3?fork=shanghai + fn exec_log3(ref self: VM) -> Result<(), EVMError> { + exec_log_i(ref self, 3) + } + + /// 0xA4 - LOG4 + /// Append log record with four topics. + /// # Specification: https://www.evm.codes/#a4?fork=shanghai + fn exec_log4(ref self: VM) -> Result<(), EVMError> { + exec_log_i(ref self, 4) + } +} + + +/// Store a new event in the dynamic context using topics +/// popped from the stack and data from the memory. +/// +/// # Arguments +/// +/// * `self` - The context to which the event will be added +/// * `topics_len` - The amount of topics to pop from the stack +fn exec_log_i(ref self: VM, topics_len: u8) -> Result<(), EVMError> { + // Revert if the transaction is in a read only context + ensure(!self.message().read_only, EVMError::WriteInStaticContext)?; + + // TODO(optimization): check benefits of n `pop` instead of `pop_n` + let offset = self.stack.pop_saturating_usize()?; + let size = self.stack.pop_usize()?; + let topics: Array = self.stack.pop_n(topics_len.into())?; + + let memory_expansion = gas::memory_expansion(self.memory.size(), [(offset, size)].span())?; + self.memory.ensure_length(memory_expansion.new_size); + self + .charge_gas( + gas::LOG + + topics_len.into() * gas::LOGTOPIC + + size.into() * gas::LOGDATA + + memory_expansion.expansion_cost + )?; + + let mut data: Array = Default::default(); + self.memory.load_n(size, ref data, offset); + + let event: Event = Event { keys: topics, data }; + self.env.state.add_event(event); + + Result::Ok(()) +} + +#[cfg(test)] +mod tests { + use core::num::traits::Bounded; + use core::result::ResultTrait; + use crate::errors::{EVMError, TYPE_CONVERSION_ERROR}; + use crate::instructions::LoggingOperationsTrait; + use crate::stack::StackTrait; + use crate::test_utils::{VMBuilderTrait, MemoryTestUtilsTrait}; + use utils::helpers::u256_to_bytes_array; + + #[test] + fn test_exec_log0() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm.memory.store_with_expansion(Bounded::::MAX, 0); + + vm.stack.push(0x1F).expect('push failed'); + vm.stack.push(0x00).expect('push failed'); + + // When + let result = vm.exec_log0(); + + // Then + assert!(result.is_ok()); + assert_eq!(vm.stack.len(), 0); + + let mut events = vm.env.state.events; + assert_eq!(events.len(), 1); + + let event = events.pop_front().unwrap(); + assert_eq!(event.keys.len(), 0); + + assert_eq!(event.data.len(), 31); + let data_expected = u256_to_bytes_array(Bounded::::MAX).span().slice(0, 31); + assert_eq!(event.data.span(), data_expected); + } + + #[test] + fn test_exec_log1() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm.memory.store_with_expansion(Bounded::::MAX, 0); + + vm.stack.push(0x0123456789ABCDEF).expect('push failed'); + vm.stack.push(0x20).expect('push failed'); + vm.stack.push(0x00).expect('push failed'); + + // When + let result = vm.exec_log1(); + + // Then + assert!(result.is_ok()); + assert_eq!(vm.stack.len(), 0); + + let mut events = vm.env.state.events; + assert_eq!(events.len(), 1); + + let event = events.pop_front().unwrap(); + assert_eq!(event.keys.len(), 1); + assert_eq!(event.keys.span(), [0x0123456789ABCDEF].span()); + + assert_eq!(event.data.len(), 32); + let data_expected = u256_to_bytes_array(Bounded::::MAX).span().slice(0, 32); + assert_eq!(event.data.span(), data_expected); + } + + #[test] + fn test_exec_log2() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm.memory.store_with_expansion(Bounded::::MAX, 0); + + vm.stack.push(Bounded::::MAX).expect('push failed'); + vm.stack.push(0x0123456789ABCDEF).expect('push failed'); + vm.stack.push(0x05).expect('push failed'); + vm.stack.push(0x05).expect('push failed'); + + // When + let result = vm.exec_log2(); + + // Then + assert!(result.is_ok()); + assert_eq!(vm.stack.len(), 0); + + let mut events = vm.env.state.events; + assert_eq!(events.len(), 1); + + let event = events.pop_front().unwrap(); + assert_eq!(event.keys.len(), 2); + assert_eq!(event.keys.span(), [0x0123456789ABCDEF, Bounded::::MAX].span()); + + assert_eq!(event.data.len(), 5); + let data_expected = u256_to_bytes_array(Bounded::::MAX).span().slice(0, 5); + assert_eq!(event.data.span(), data_expected); + } + + #[test] + fn test_exec_log3() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm.memory.store_with_expansion(Bounded::::MAX, 0); + vm + .memory + .store_with_expansion( + 0x0123456789ABCDEF000000000000000000000000000000000000000000000000, 0x20 + ); + + vm.stack.push(0x00).expect('push failed'); + vm.stack.push(Bounded::::MAX).expect('push failed'); + vm.stack.push(0x0123456789ABCDEF).expect('push failed'); + vm.stack.push(0x28).expect('push failed'); + vm.stack.push(0x00).expect('push failed'); + + // When + let result = vm.exec_log3(); + + // Then + assert!(result.is_ok()); + assert_eq!(vm.stack.len(), 0); + + let mut events = vm.env.state.events; + assert_eq!(events.len(), 1); + + let event = events.pop_front().unwrap(); + assert_eq!(event.keys.span(), [0x0123456789ABCDEF, Bounded::::MAX, 0x00].span()); + + assert_eq!(event.data.len(), 40); + let data_expected = u256_to_bytes_array(Bounded::::MAX).span(); + assert_eq!(event.data.span().slice(0, 32), data_expected); + let data_expected = [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF].span(); + assert_eq!(event.data.span().slice(32, 8), data_expected); + } + + #[test] + fn test_exec_log4() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm.memory.store_with_expansion(Bounded::::MAX, 0); + vm + .memory + .store_with_expansion( + 0x0123456789ABCDEF000000000000000000000000000000000000000000000000, 0x20 + ); + + vm.stack.push(Bounded::::MAX).expect('push failed'); + vm.stack.push(0x00).expect('push failed'); + vm.stack.push(Bounded::::MAX).expect('push failed'); + vm.stack.push(0x0123456789ABCDEF).expect('push failed'); + vm.stack.push(0x0A).expect('push failed'); + vm.stack.push(0x20).expect('push failed'); + + // When + let result = vm.exec_log4(); + + // Then + assert!(result.is_ok()); + assert_eq!(vm.stack.len(), 0); + + let mut events = vm.env.state.events; + assert_eq!(events.len(), 1); + + let event = events.pop_front().unwrap(); + assert_eq!( + event.keys.span(), + [0x0123456789ABCDEF, Bounded::::MAX, 0x00, Bounded::::MAX].span() + ); + + assert_eq!(event.data.len(), 10); + let data_expected = [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x00, 0x00].span(); + assert_eq!(event.data.span(), data_expected); + } + + #[test] + fn test_exec_log1_read_only_context() { + // Given + let mut vm = VMBuilderTrait::new().with_read_only().build(); + + vm.memory.store_with_expansion(Bounded::::MAX, 0); + + vm.stack.push(0x0123456789ABCDEF).expect('push failed'); + vm.stack.push(0x20).expect('push failed'); + vm.stack.push(0x00).expect('push failed'); + + // When + let result = vm.exec_log1(); + + // Then + assert!(result.is_err()); + assert_eq!(result.unwrap_err(), EVMError::WriteInStaticContext); + } + + #[test] + fn test_exec_log1_size_0_offset_0() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm.memory.store_with_expansion(Bounded::::MAX, 0); + + vm.stack.push(0x0123456789ABCDEF).expect('push failed'); + vm.stack.push(0x00).expect('push failed'); + vm.stack.push(0x00).expect('push failed'); + + // When + let result = vm.exec_log1(); + + // Then + assert!(result.is_ok()); + assert_eq!(vm.stack.len(), 0); + + let mut events = vm.env.state.events; + assert_eq!(events.len(), 1); + + let event = events.pop_front().unwrap(); + assert_eq!(event.keys.span(), [0x0123456789ABCDEF].span()); + + assert_eq!(event.data.len(), 0); + } + + #[test] + fn test_exec_log1_size_too_big() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm.memory.store_with_expansion(Bounded::::MAX, 0); + + vm.stack.push(0x0123456789ABCDEF).expect('push failed'); + vm.stack.push(Bounded::::MAX).expect('push failed'); + vm.stack.push(0x00).expect('push failed'); + + // When + let result = vm.exec_log1(); + + // Then + assert!(result.is_err()); + assert_eq!(result.unwrap_err(), EVMError::TypeConversionError(TYPE_CONVERSION_ERROR)); + } + + #[test] + fn test_exec_log1_offset_too_big() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm.memory.store_with_expansion(Bounded::::MAX, 0); + + vm.stack.push(0x0123456789ABCDEF).expect('push failed'); + vm.stack.push(0x20).expect('push failed'); + vm.stack.push(Bounded::::MAX).expect('push failed'); + + // When + let result = vm.exec_log1(); + + // Then + assert!(result.is_err()); + assert_eq!(result.unwrap_err(), EVMError::MemoryLimitOOG); + } + + #[test] + fn test_exec_log_multiple_events() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm.memory.store_with_expansion(Bounded::::MAX, 0); + vm + .memory + .store_with_expansion( + 0x0123456789ABCDEF000000000000000000000000000000000000000000000000, 0x20 + ); + + vm.stack.push(Bounded::::MAX).expect('push failed'); + vm.stack.push(0x00).expect('push failed'); + vm.stack.push(Bounded::::MAX).expect('push failed'); + vm.stack.push(0x0123456789ABCDEF).expect('push failed'); + vm.stack.push(0x0A).expect('push failed'); + vm.stack.push(0x20).expect('push failed'); + vm.stack.push(0x00).expect('push failed'); + vm.stack.push(Bounded::::MAX).expect('push failed'); + vm.stack.push(0x0123456789ABCDEF).expect('push failed'); + vm.stack.push(0x28).expect('push failed'); + vm.stack.push(0x00).expect('push failed'); + + // When + vm.exec_log3().expect('exec_log3 failed'); + vm.exec_log4().expect('exec_log4 failed'); + + // Then + assert!(vm.stack.is_empty()); + + let mut events = vm.env.state.events; + assert_eq!(events.len(), 2); + + let event1 = events.pop_front().unwrap(); + assert_eq!(event1.keys.span(), [0x0123456789ABCDEF, Bounded::::MAX, 0x00].span()); + + assert_eq!(event1.data.len(), 40); + let data_expected = u256_to_bytes_array(Bounded::::MAX).span(); + assert_eq!(event1.data.span().slice(0, 32), data_expected); + let data_expected = [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF].span(); + assert_eq!(event1.data.span().slice(32, 8), data_expected); + + let event2 = events.pop_front().unwrap(); + assert_eq!( + event2.keys.span(), + [0x0123456789ABCDEF, Bounded::::MAX, 0x00, Bounded::::MAX].span() + ); + + assert_eq!(event2.data.len(), 10); + let data_expected = [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x00, 0x00].span(); + assert_eq!(event2.data.span(), data_expected); + } +} diff --git a/kakarot-ssj/crates/evm/src/instructions/memory_operations.cairo b/kakarot-ssj/crates/evm/src/instructions/memory_operations.cairo new file mode 100644 index 000000000..0248a7b35 --- /dev/null +++ b/kakarot-ssj/crates/evm/src/instructions/memory_operations.cairo @@ -0,0 +1,1069 @@ +use core::cmp::max; +use crate::backend::starknet_backend::fetch_original_storage; +//! Stack Memory Storage and Flow Operations. +use crate::errors::{EVMError, ensure}; +use crate::gas; +use crate::memory::MemoryTrait; +use crate::model::vm::{VM, VMTrait}; +use crate::stack::StackTrait; +use crate::state::StateTrait; +use utils::helpers::bytes_32_words_size; +use utils::set::SetTrait; + +#[inline(always)] +fn jump(ref self: VM, index: usize) -> Result<(), EVMError> { + match self.message().code.get(index) { + Option::Some(_) => { ensure(self.is_valid_jump(index), EVMError::InvalidJump)?; }, + Option::None => { return Result::Err(EVMError::InvalidJump); } + } + self.set_pc(index); + Result::Ok(()) +} + +#[generate_trait] +pub impl MemoryOperation of MemoryOperationTrait { + /// 0x50 - POP operation. + /// Pops the first item on the stack (top of the stack). + /// # Specification: https://www.evm.codes/#50?fork=shanghai + fn exec_pop(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::BASE)?; + + // self.stack.pop() returns a Result so we cannot simply return its result + self.stack.pop()?; + Result::Ok(()) + } + + /// MLOAD operation. + /// Load word from memory and push to stack. + fn exec_mload(ref self: VM) -> Result<(), EVMError> { + let offset: usize = self.stack.pop_usize()?; + + let memory_expansion = gas::memory_expansion(self.memory.size(), [(offset, 32)].span())?; + self.memory.ensure_length(memory_expansion.new_size); + self.charge_gas(gas::VERYLOW + memory_expansion.expansion_cost)?; + + let result = self.memory.load(offset); + self.stack.push(result) + } + + /// 0x52 - MSTORE operation. + /// Save word to memory. + /// # Specification: https://www.evm.codes/#52?fork=shanghai + fn exec_mstore(ref self: VM) -> Result<(), EVMError> { + let offset: usize = self.stack.pop_usize()?; + let value: u256 = self.stack.pop()?; + let memory_expansion = gas::memory_expansion(self.memory.size(), [(offset, 32)].span())?; + self.memory.ensure_length(memory_expansion.new_size); + self.charge_gas(gas::VERYLOW + memory_expansion.expansion_cost)?; + + self.memory.store(value, offset); + Result::Ok(()) + } + + /// 0x53 - MSTORE8 operation. + /// Save single byte to memory + /// # Specification: https://www.evm.codes/#53?fork=shanghai + fn exec_mstore8(ref self: VM) -> Result<(), EVMError> { + let offset = self.stack.pop_saturating_usize()?; + let value = self.stack.pop()?; + let value: u8 = (value.low & 0xFF).try_into().unwrap(); + + let memory_expansion = gas::memory_expansion(self.memory.size(), [(offset, 1)].span())?; + self.memory.ensure_length(memory_expansion.new_size); + self.charge_gas(gas::VERYLOW + memory_expansion.expansion_cost)?; + + self.memory.store_byte(value, offset); + + Result::Ok(()) + } + + + /// 0x54 - SLOAD operation + /// Load from storage. + /// # Specification: https://www.evm.codes/#54?fork=shanghai + fn exec_sload(ref self: VM) -> Result<(), EVMError> { + let key = self.stack.pop()?; + let evm_address = self.message().target.evm; + + // GAS + if self.accessed_storage_keys.contains((evm_address, key)) { + self.charge_gas(gas::WARM_ACCESS_COST)?; + } else { + self.accessed_storage_keys.add((evm_address, key)); + self.charge_gas(gas::COLD_SLOAD_COST)?; + } + + let value = self.env.state.read_state(evm_address, key); + self.stack.push(value) + } + + + /// 0x55 - SSTORE operation + /// Save 32-byte word to storage. + /// # Specification: https://www.evm.codes/#55?fork=shanghai + fn exec_sstore(ref self: VM) -> Result<(), EVMError> { + let key = self.stack.pop()?; + let new_value = self.stack.pop()?; + ensure(self.gas_left() > gas::CALL_STIPEND, EVMError::OutOfGas)?; // EIP-1706 + + let evm_address = self.message().target.evm; + let account = self.env.state.get_account(evm_address); + let original_value = fetch_original_storage(@account, key); + let current_value = self.env.state.read_state(evm_address, key); + + // GAS + let mut gas_cost = 0; + if !self.accessed_storage_keys.contains((evm_address, key)) { + self.accessed_storage_keys.add((evm_address, key)); + gas_cost += gas::COLD_SLOAD_COST; + } + + if original_value == current_value && current_value != new_value { + if original_value == 0 { + gas_cost += gas::SSTORE_SET + } else { + gas_cost += gas::SSTORE_RESET - gas::COLD_SLOAD_COST; + } + } else { + gas_cost += gas::WARM_ACCESS_COST; + } + + // Gas refunds + if current_value != new_value { + if original_value != 0 && current_value != 0 && new_value == 0 { + // Storage is cleared for the first time in the transaction + self.gas_refund += gas::REFUND_SSTORE_CLEARS; + } + + if original_value != 0 && current_value == 0 { + // Earlier gas refund needs to be reversed + self.gas_refund -= gas::REFUND_SSTORE_CLEARS; + } + + if original_value == new_value { + // Restoring slot to original value (used as transient storage) + if original_value == 0 { + // The access cost is still charged but the SSTORE cost is refunded + self.gas_refund += (gas::SSTORE_SET - gas::WARM_ACCESS_COST); + } else { + // Slot was originally non-empty and was updated earlier + // cold sload cost and warm access cost are not refunded + self + .gas_refund += + (gas::SSTORE_RESET - gas::COLD_SLOAD_COST - gas::WARM_ACCESS_COST); + } + } + } + + self.charge_gas(gas_cost)?; + + ensure(!self.message().read_only, EVMError::WriteInStaticContext)?; + + self.env.state.write_state(:evm_address, :key, value: new_value); + Result::Ok(()) + } + + + /// 0x56 - JUMP operation + /// The JUMP instruction changes the pc counter. + /// The new pc target has to be a JUMPDEST opcode. + /// # Specification: https://www.evm.codes/#56?fork=shanghai + /// + /// Valid jump destinations are defined as follows: + /// * The jump destination is less than the length of the code. + /// * The jump destination should have the `JUMPDEST` opcode (0x5B). + /// * The jump destination shouldn't be part of the data corresponding to + /// `PUSH-N` opcodes. + /// + /// Note: Jump destinations are 0-indexed. + fn exec_jump(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::MID)?; + + let index = self.stack.pop_usize()?; + jump(ref self, index) + } + + /// 0x57 - JUMPI operation. + /// Change the pc counter under a provided certain condition. + /// The new pc target has to be a JUMPDEST opcode. + /// # Specification: https://www.evm.codes/#57?fork=shanghai + fn exec_jumpi(ref self: VM) -> Result<(), EVMError> { + let index = self.stack.pop_usize()?; + let b = self.stack.pop()?; + + self.charge_gas(gas::HIGH)?; + + if b != 0x0 { + jump(ref self, index)?; + } else { + // Return with a PC incremented by one - as JUMP and JUMPi increments + // are skipped in the main `execute_code` loop + self.set_pc(self.pc() + 1); + } + + Result::Ok(()) + } + + /// 0x58 - PC operation + /// Get the value of the program counter prior to the increment. + /// # Specification: https://www.evm.codes/#58?fork=shanghai + fn exec_pc(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::BASE)?; + + let pc = self.pc().into(); + self.stack.push(pc) + } + + /// 0x59 - MSIZE operation. + /// Get the value of memory size. + /// # Specification: https://www.evm.codes/#59?fork=shanghai + fn exec_msize(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::BASE)?; + + let msize: u256 = self.memory.size().into(); + self.stack.push(msize) + } + + + /// 0x5A - GAS operation + /// Get the amount of available gas, including the corresponding reduction for the cost of this + /// instruction. + /// # Specification: https://www.evm.codes/#5a?fork=shanghai + fn exec_gas(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::BASE)?; + self.stack.push(self.gas_left().into()) + } + + + /// 0x5b - JUMPDEST operation + /// Serves as a check that JUMP or JUMPI was executed correctly. + /// # Specification: https://www.evm.codes/#5b?fork=shanghai + /// + /// This doesn't have any affect on execution state, so we don't have + /// to do anything here. It's a NO-OP. + fn exec_jumpdest(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::JUMPDEST)?; + Result::Ok(()) + } + + /// 0x5c - TLOAD operation. + /// Load a word from the transient storage. + /// # Specification: https://www.evm.codes/#5c?fork=cancun + fn exec_tload(ref self: VM) -> Result<(), EVMError> { + let key = self.stack.pop()?; + let evm_address = self.message().target.evm; + + self.charge_gas(gas::WARM_ACCESS_COST)?; + + let value = self.env.state.read_transient_storage(evm_address, key); + self.stack.push(value) + } + + /// 0x5d - TSTORE operation. + /// Save a word to the transient storage. + /// # Specification: https://www.evm.codes/#5d?fork=cancun + fn exec_tstore(ref self: VM) -> Result<(), EVMError> { + let key = self.stack.pop()?; + let value = self.stack.pop()?; + + self.charge_gas(gas::WARM_ACCESS_COST)?; + + ensure(!self.message().read_only, EVMError::WriteInStaticContext)?; + self.env.state.write_transient_storage(self.message().target.evm, key, value); + + return Result::Ok(()); + } + + /// 0x5e - MCOPY operation. + /// Copy memory from one location to another. + /// # Specification: https://www.evm.codes/#5e?fork=cancun + fn exec_mcopy(ref self: VM) -> Result<(), EVMError> { + let dest_offset = self.stack.pop_saturating_usize()?; + let source_offset = self.stack.pop_saturating_usize()?; + let size = self.stack.pop_usize()?; + + let words_size = bytes_32_words_size(size).into(); + let copy_gas_cost = gas::COPY * words_size; + let memory_expansion = gas::memory_expansion( + self.memory.size(), [(max(dest_offset, source_offset), size)].span() + )?; + self.memory.ensure_length(memory_expansion.new_size); + self.charge_gas(gas::VERYLOW + copy_gas_cost + memory_expansion.expansion_cost)?; + + if size == 0 { + return Result::Ok(()); + } + + self.memory.copy(size, source_offset, dest_offset); + Result::Ok(()) + } +} + + +#[cfg(test)] +mod tests { + use core::cmp::max; + use core::num::traits::Bounded; + use core::result::ResultTrait; + use crate::errors::EVMError; + use crate::gas; + use crate::instructions::MemoryOperationTrait; + use crate::memory::MemoryTrait; + use crate::model::Address; + use crate::model::vm::VMTrait; + use crate::model::{Account, AccountTrait}; + use crate::stack::StackTrait; + use crate::state::StateTrait; + use crate::test_utils::{ + VMBuilderTrait, MemoryTestUtilsTrait, setup_test_environment, uninitialized_account, + native_token + }; + use snforge_std::{test_address, start_mock_call}; + use utils::helpers::compute_starknet_address; + use utils::traits::bytes::U8SpanExTrait; + + #[test] + fn test_pc_basic() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + // When + vm.exec_pc().expect('exec_pc failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.pop().unwrap() == 0, 'PC should be 0'); + } + + + #[test] + fn test_pc_gets_updated_properly_1() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + // When + vm.set_pc(9000); + vm.exec_pc().expect('exec_pc failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.pop().unwrap() == 9000, 'updating PC failed'); + } + + // 0x51 - MLOAD + + #[test] + fn test_exec_mload_should_load_a_value_from_memory() { + assert_mload(0x1, 0, 0x1, 32); + } + + #[test] + fn test_exec_mload_should_load_a_value_from_memory_with_memory_expansion() { + assert_mload(0x1, 16, 0x100000000000000000000000000000000, 64); + } + + #[test] + fn test_exec_mload_should_load_a_value_from_memory_with_offset_larger_than_msize() { + assert_mload(0x1, 684, 0x0, 736); + } + + fn assert_mload(value: u256, offset: u256, expected_value: u256, expected_memory_size: u32) { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.memory.store_with_expansion(value, 0); + + vm.stack.push(offset).expect('push failed'); + + // When + vm.exec_mload().expect('exec_mload failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.pop().unwrap() == expected_value, 'mload failed'); + assert(vm.memory.size() == expected_memory_size, 'memory size error'); + } + + #[test] + fn test_exec_pop_should_pop_an_item_from_stack() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm.stack.push(0x01).expect('push failed'); + vm.stack.push(0x02).expect('push failed'); + + // When + let result = vm.exec_pop(); + + // Then + assert(result.is_ok(), 'should have succeeded'); + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 0x01, 'stack peek should return 0x01'); + } + + #[test] + fn test_exec_pop_should_stack_underflow() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + // When + let result = vm.exec_pop(); + + // Then + assert(result.is_err(), 'should return Err '); + assert!(result.unwrap_err() == EVMError::StackUnderflow, "should return StackUnderflow"); + } + + #[test] + fn test_exec_mstore_should_store_max_uint256_offset_0() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm.stack.push(Bounded::::MAX).expect('push failed'); + vm.stack.push(0x00).expect('push failed'); + + // When + let result = vm.exec_mstore(); + + // Then + assert(result.is_ok(), 'should have succeeded'); + assert(vm.memory.size() == 32, 'memory should be 32 bytes long'); + let stored = vm.memory.load(0); + assert(stored == Bounded::::MAX, 'should have stored max_uint256'); + } + + #[test] + fn test_exec_mstore_should_store_max_uint256_offset_1() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm.stack.push(Bounded::::MAX).expect('push failed'); + vm.stack.push(0x01).expect('push failed'); + + // When + let result = vm.exec_mstore(); + + // Then + assert(result.is_ok(), 'should have succeeded'); + assert(vm.memory.size() == 64, 'memory should be 64 bytes long'); + let stored = vm.memory.load(1); + assert(stored == Bounded::::MAX, 'should have stored max_uint256'); + } + + #[test] + fn test_exec_mstore8_should_store_uint8_offset_31() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm.stack.push(0xAB).expect('push failed'); + vm.stack.push(31).expect('push failed'); + + // When + let result = vm.exec_mstore8(); + + // Then + assert(result.is_ok(), 'should have succeeded'); + assert(vm.memory.size() == 32, 'memory should be 32 bytes long'); + let stored = vm.memory.load(0); + assert(stored == 0xAB, 'mstore8 failed'); + } + + #[test] + fn test_exec_mstore8_should_store_uint8_offset_30() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm.stack.push(0xAB).expect('push failed'); + vm.stack.push(30).expect('push failed'); + + // When + let result = vm.exec_mstore8(); + + // Then + assert(result.is_ok(), 'should have succeeded'); + assert(vm.memory.size() == 32, 'memory should be 32 bytes long'); + let stored = vm.memory.load(0); + assert(stored == 0xAB00, 'mstore8 failed'); + } + + #[test] + fn test_exec_mstore8_should_store_uint8_offset_31_then_uint8_offset_30() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm.stack.push(0xAB).expect('push failed'); + vm.stack.push(30).expect('push failed'); + vm.stack.push(0xCD).expect('push failed'); + vm.stack.push(31).expect('push failed'); + + // When + let result1 = vm.exec_mstore8(); + let result2 = vm.exec_mstore8(); + + // Then + assert(result1.is_ok() && result2.is_ok(), 'should have succeeded'); + assert(vm.memory.size() == 32, 'memory should be 32 bytes long'); + let stored = vm.memory.load(0); + assert(stored == 0xABCD, 'mstore8 failed'); + } + + #[test] + fn test_exec_mstore8_should_store_last_uint8_offset_31() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm.stack.push(0x123456789ABCDEF).expect('push failed'); + vm.stack.push(31).expect('push failed'); + + // When + let result = vm.exec_mstore8(); + + // Then + assert(result.is_ok(), 'should have succeeded'); + assert(vm.memory.size() == 32, 'memory should be 32 bytes long'); + let stored = vm.memory.load(0); + assert(stored == 0xEF, 'mstore8 failed'); + } + + + #[test] + fn test_exec_mstore8_should_store_last_uint8_offset_63() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm.stack.push(0x123456789ABCDEF).expect('push failed'); + vm.stack.push(63).expect('push failed'); + + // When + let result = vm.exec_mstore8(); + + // Then + assert(result.is_ok(), 'should have succeeded'); + assert(vm.memory.size() == 64, 'memory should be 64 bytes long'); + let stored = vm.memory.load(32); + assert(stored == 0xEF, 'mstore8 failed'); + } + + #[test] + fn test_msize_initial() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + // When + let result = vm.exec_msize(); + + // Then + assert(result.is_ok(), 'should have succeeded'); + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.pop().unwrap() == 0, 'initial memory size should be 0'); + } + + #[test] + fn test_exec_msize_should_return_size_of_memory() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.memory.store_with_expansion(Bounded::::MAX, 0x00); + + // When + let result = vm.exec_msize(); + + // Then + assert(result.is_ok(), 'should have succeeded'); + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.pop().unwrap() == 32, 'should 32 bytes after MSIZE'); + } + + #[test] + fn test_exec_jump_valid() { + // Given + let bytecode: Span = [0x01, 0x02, 0x03, 0x5B, 0x04, 0x05].span(); + + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(bytecode).build(); + + let counter = 0x03; + vm.stack.push(counter).expect('push failed'); + + // When + vm.exec_jump().expect('exec_jump failed'); + + // Then + let pc = vm.pc(); + assert(pc == 0x03, 'PC should be JUMPDEST'); + } + + + #[test] + fn test_exec_jump_invalid() { + // Given + let bytecode: Span = [0x01, 0x02, 0x03, 0x5B, 0x04, 0x05].span(); + + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(bytecode).build(); + + let counter = 0x02; + vm.stack.push(counter).expect('push failed'); + + // When + let result = vm.exec_jump(); + + // Then + assert(result.is_err(), 'invalid jump dest'); + assert(result.unwrap_err() == EVMError::InvalidJump, 'invalid jump dest'); + } + + #[test] + fn test_exec_jump_out_of_bounds() { + // Given + let bytecode: Span = [0x01, 0x02, 0x03, 0x5B, 0x04, 0x05].span(); + + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(bytecode).build(); + + let counter = 0xFF; + vm.stack.push(counter).expect('push failed'); + + // When + let result = vm.exec_jump(); + + // Then + assert(result.is_err(), 'invalid jump dest'); + assert(result.unwrap_err() == EVMError::InvalidJump, 'invalid jump dest'); + } + + // TODO: This is third edge case in which `0x5B` is part of PUSHN instruction and hence + // not a valid opcode to jump to + #[test] + fn test_exec_jump_inside_pushn() { + // Given + let bytecode: Span = [0x60, 0x5B, 0x60, 0x00].span(); + + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(bytecode).build(); + + let counter = 0x01; + vm.stack.push(counter).expect('push failed'); + + // When + let result = vm.exec_jump(); + + // Then + assert(result.is_err(), 'exec_jump should throw error'); + assert(result.unwrap_err() == EVMError::InvalidJump, 'jump dest should be invalid'); + } + + #[test] + fn test_exec_jumpi_valid_non_zero_1() { + // Given + let bytecode: Span = [0x01, 0x02, 0x03, 0x5B, 0x04, 0x05].span(); + + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(bytecode).build(); + + let b = 0x1; + vm.stack.push(b).expect('push failed'); + let counter = 0x03; + vm.stack.push(counter).expect('push failed'); + + // When + vm.exec_jumpi().expect('exec_jumpi failed'); + + // Then + let pc = vm.pc(); + assert(pc == 0x03, 'PC should be JUMPDEST'); + } + + #[test] + fn test_exec_jumpi_valid_non_zero_2() { + // Given + let bytecode: Span = [0x01, 0x02, 0x03, 0x5B, 0x04, 0x05].span(); + + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(bytecode).build(); + + let b = 0x69; + vm.stack.push(b).expect('push failed'); + let counter = 0x03; + vm.stack.push(counter).expect('push failed'); + + // When + vm.exec_jumpi().expect('exec_jumpi failed'); + + // Then + let pc = vm.pc(); + assert(pc == 0x03, 'PC should be JUMPDEST'); + } + + #[test] + fn test_exec_jumpi_valid_zero() { + // Given + let bytecode: Span = [0x01, 0x02, 0x03, 0x5B, 0x04, 0x05].span(); + + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(bytecode).build(); + + let b = 0x0; + vm.stack.push(b).expect('push failed'); + let counter = 0x03; + vm.stack.push(counter).expect('push failed'); + let old_pc = vm.pc(); + + // When + vm.exec_jumpi().expect('exec_jumpi failed'); + + // Then + let pc = vm.pc(); + // If the jump is not taken, the PC should be incremented by 1 + assert_eq!(pc, old_pc + 1); + } + + #[test] + fn test_exec_jumpi_invalid_non_zero() { + // Given + let bytecode: Span = [0x60, 0x5B, 0x60, 0x00].span(); + + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(bytecode).build(); + + let b = 0x69; + vm.stack.push(b).expect('push failed'); + let counter = 0x69; + vm.stack.push(counter).expect('push failed'); + + // When + let result = vm.exec_jumpi(); + + // Then + assert(result.is_err(), 'invalid jump dest'); + assert(result.unwrap_err() == EVMError::InvalidJump, 'invalid jump dest'); + } + + + #[test] + fn test_exec_jumpi_invalid_zero() { + // Given + let bytecode: Span = [0x01, 0x02, 0x03, 0x5B, 0x04, 0x05].span(); + + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(bytecode).build(); + + let b = 0x0; + vm.stack.push(b).expect('push failed'); + let counter = 0x69; + vm.stack.push(counter).expect('push failed'); + let old_pc = vm.pc(); + + // When + vm.exec_jumpi().expect('exec_jumpi failed'); + + // Then + let pc = vm.pc(); + // If the jump is not taken, the PC should be incremented by 1 + assert_eq!(pc, old_pc + 1); + } + + #[test] + #[should_panic(expected: ('exec_jump should throw error',))] + fn test_exec_jumpi_inside_pushn() { + // Given + let bytecode: Span = [0x60, 0x5B, 0x60, 0x00].span(); + + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(bytecode).build(); + + let b = 0x00; + vm.stack.push(b).expect('push failed'); + let counter = 0x01; + vm.stack.push(counter).expect('push failed'); + + // When + let result = vm.exec_jumpi(); + + // Then + assert(result.is_err(), 'exec_jump should throw error'); + assert(result.unwrap_err() == EVMError::InvalidJump, 'jump dest should be invalid'); + } + + #[test] + fn test_exec_sload_should_push_value_on_stack() { + // Given + setup_test_environment(); + let mut vm = VMBuilderTrait::new_with_presets().build(); + let evm_address = vm.message().target.evm; + + let key: u256 = 0x100000000000000000000000000000001; + let value: u256 = 0x02; + vm.env.state.write_state(evm_address, key, value); + vm.stack.push(key.into()).expect('push failed'); + + // When + let result = vm.exec_sload(); + + // Then + assert(result.is_ok(), 'should have succeeded'); + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.pop().unwrap() == value, 'sload failed'); + } + + #[test] + fn test_exec_sstore_on_account_in_st() { + // Given + setup_test_environment(); + let mut vm = VMBuilderTrait::new_with_presets().build(); + let test_address = test_address(); + let evm_address = vm.message().target.evm; + let starknet_address = compute_starknet_address( + test_address, evm_address, uninitialized_account() + ); + let bytecode = [0xab, 0xcd, 0xef].span(); + let code_hash = bytecode.compute_keccak256_hash(); + let account = Account { + address: Address { evm: evm_address, starknet: starknet_address }, + code: bytecode, + code_hash: code_hash, + nonce: 1, + balance: 0, + selfdestruct: false, + is_created: false, + }; + vm.env.state.set_account(account); + + let key: u256 = 0x100000000000000000000000000000001; + let value: u256 = 0xABDE1E11A5; + + vm.stack.push(value).expect('push failed'); + vm.stack.push(key).expect('push failed'); + + // When + start_mock_call::(starknet_address, selector!("storage"), 0); + let result = vm.exec_sstore(); + + // Then + assert(result.is_ok(), 'exec sstore failed'); + assert(vm.env.state.read_state(evm_address, key) == value, 'wrong value in state'); + } + + #[test] + fn test_exec_sstore_on_account_undeployed() { + // Given + setup_test_environment(); + let mut vm = VMBuilderTrait::new_with_presets().build(); + let evm_address = vm.message().target.evm; + let key: u256 = 0x100000000000000000000000000000001; + let value: u256 = 0xABDE1E11A5; + + vm.stack.push(value).expect('push failed'); + vm.stack.push(key).expect('push failed'); + + // When + start_mock_call::(native_token(), selector!("balanceOf"), 0); + let result = vm.exec_sstore(); + + // Then + assert(result.is_ok(), 'exec sstore failed'); + assert(vm.env.state.read_state(evm_address, key) == value, 'wrong value in state'); + } + + #[test] + fn test_exec_sstore_on_contract_account_alive() { + // Given + setup_test_environment(); + let mut vm = VMBuilderTrait::new_with_presets().build(); + let test_address = test_address(); + let evm_address = vm.message().target.evm; + let starknet_address = compute_starknet_address( + test_address, evm_address, uninitialized_account() + ); + let bytecode = [0xab, 0xcd, 0xef].span(); + let code_hash = bytecode.compute_keccak256_hash(); + let account = Account { + address: Address { evm: evm_address, starknet: starknet_address }, + code: bytecode, + code_hash: code_hash, + nonce: 1, + balance: 0, + selfdestruct: false, + is_created: false, + }; + let key: u256 = 0x100000000000000000000000000000001; + let value: u256 = 0xABDE1E11A5; + + vm.stack.push(value).expect('push failed'); + vm.stack.push(key).expect('push failed'); + + vm.env.state.set_account(account); + assert!(vm.env.state.is_account_alive(account.address.evm)); + + // When + start_mock_call::(account.starknet_address(), selector!("storage"), 0); + let result = vm.exec_sstore(); + + // Then + assert(result.is_ok(), 'exec sstore failed'); + assert(vm.env.state.read_state(evm_address, key) == value, 'wrong value in state'); + } + + #[test] + fn test_exec_sstore_should_fail_static_call() { + // Given + setup_test_environment(); + let mut vm = VMBuilderTrait::new_with_presets().with_read_only().build(); + let key: u256 = 0x100000000000000000000000000000001; + let value: u256 = 0xABDE1E11A5; + vm.stack.push(value).expect('push failed'); + vm.stack.push(key).expect('push failed'); + + // When + start_mock_call::(vm.message().target.starknet, selector!("storage"), 0); + start_mock_call::(native_token(), selector!("balanceOf"), 0); + let result = vm.exec_sstore(); + + // Then + assert(result.is_err(), 'should have errored'); + assert(result.unwrap_err() == EVMError::WriteInStaticContext, 'wrong error returned'); + } + + #[test] + fn test_exec_sstore_should_fail_gas_left_inf_call_stipend_eip_1706() { + // Given + setup_test_environment(); + let mut vm = VMBuilderTrait::new_with_presets().with_gas_left(gas::CALL_STIPEND).build(); + let test_address = test_address(); + let evm_address = vm.message().target.evm; + let starknet_address = compute_starknet_address( + test_address, evm_address, uninitialized_account() + ); + let key: u256 = 0x100000000000000000000000000000001; + let value: u256 = 0xABDE1E11A5; + vm.stack.push(value).expect('push failed'); + vm.stack.push(key).expect('push failed'); + + // When + start_mock_call::(starknet_address, selector!("storage"), 0); + start_mock_call::(native_token(), selector!("balanceOf"), 0); + let result = vm.exec_sstore(); + + // Then + assert(result.is_err(), 'should have errored'); + assert(result.unwrap_err() == EVMError::OutOfGas, 'wrong error returned'); + } + + + #[test] + fn test_gas_should_push_gas_left_to_stack() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + // When + vm.exec_gas().unwrap(); + + // Then + let result = vm.stack.peek().unwrap(); + assert(result == vm.gas_left().into(), 'stack top should be gas_limit'); + } + + #[test] + fn test_tload_should_load_a_value_from_transient_storage() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + let key: u256 = 0x100000000000000000000000000000001; + let value: u256 = 0xABDE1E11A5; + vm.env.state.write_transient_storage(vm.message().target.evm, key, value); + vm.stack.push(key.into()).expect('push failed'); + + // When + let gas_before = vm.gas_left(); + vm.exec_tload().expect('exec_tload failed'); + let gas_after = vm.gas_left(); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.pop().unwrap() == value, 'tload failed'); + assert(gas_before - gas_after == gas::WARM_ACCESS_COST, 'gas charged error'); + } + + #[test] + fn test_tstore_should_fail_staticcall() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().with_read_only().build(); + let key: u256 = 0x100000000000000000000000000000001; + let value: u256 = 0xABDE1E11A5; + vm.stack.push(value).expect('push failed'); + vm.stack.push(key.into()).expect('push failed'); + + // When + let gas_before = vm.gas_left(); + let result = vm.exec_tstore(); + let gas_after = vm.gas_left(); + + // Then + assert(result.is_err(), 'should have errored'); + assert(result.unwrap_err() == EVMError::WriteInStaticContext, 'wrong error returned'); + assert(gas_before - gas_after == gas::WARM_ACCESS_COST, 'gas charged error'); + } + + #[test] + fn test_tstore_should_store_a_value_to_transient_storage() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + let key: u256 = 0x100000000000000000000000000000001; + let value: u256 = 0xABDE1E11A5; + vm.stack.push(value).expect('push failed'); + vm.stack.push(key.into()).expect('push failed'); + + // When + let gas_before = vm.gas_left(); + vm.exec_tstore().expect('exec_tstore failed'); + let gas_after = vm.gas_left(); + + // Then + assert( + vm.env.state.read_transient_storage(vm.message().target.evm, key) == value, + 'tstore failed' + ); + assert(gas_before - gas_after == gas::WARM_ACCESS_COST, 'gas charged error'); + } + + #[test] + fn test_exec_mcopy_should_copy_two_words_at_destination_offset() { + let values: Array = array![0xFF, 0xEE]; + assert_mcopy(0x00, 0x80, 0x40, values); + } + + #[test] + fn test_exec_mcopy_should_copy_two_words_at_destination_offset_with_overlap() { + let values: Array = array![0xFF, 0xEE]; + assert_mcopy(0x00, 0x20, 0x40, values); + } + + fn assert_mcopy(source_offset: u32, dest_offset: u32, size: u32, values: Array) { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + let mut i = 0; + for element in values + .span() { + vm.memory.store_with_expansion((*element).into(), source_offset + 0x20 * i); + i += 1; + }; + vm.stack.push(size.into()).expect('push failed'); + vm.stack.push(source_offset.into()).expect('push failed'); + vm.stack.push(dest_offset.into()).expect('push failed'); + + let words_size = ((size + 31) / 32).into(); + let copy_gas_cost = gas::COPY * words_size; + + // When + let expected_gas = gas::VERYLOW + + gas::memory_expansion( + vm.memory.size(), [(max(dest_offset, source_offset), size)].span() + ) + .unwrap() + .expansion_cost + + copy_gas_cost; + let gas_before = vm.gas_left(); + let result = vm.exec_mcopy(); + let gas_after = vm.gas_left(); + + // Then + assert(result.is_ok(), 'should have succeeded'); + assert(vm.stack.is_empty(), 'stack should be empty'); + assert(vm.memory.size() == dest_offset + size, 'memory size error'); + i = 0; + for element in values + .span() { + let stored_word = vm.memory.load(dest_offset + 0x20 * i); + assert(stored_word == (*element).into(), 'mcopy failed'); + i += 1; + }; + assert(gas_before - gas_after == expected_gas, 'gas error'); + } +} diff --git a/kakarot-ssj/crates/evm/src/instructions/push_operations.cairo b/kakarot-ssj/crates/evm/src/instructions/push_operations.cairo new file mode 100644 index 000000000..d6bd057cb --- /dev/null +++ b/kakarot-ssj/crates/evm/src/instructions/push_operations.cairo @@ -0,0 +1,751 @@ +//! Push Operations. + +use crate::errors::EVMError; +use crate::gas; +use crate::model::vm::{VM, VMTrait}; +use crate::stack::StackTrait; +use utils::traits::bytes::{FromBytes, U8SpanExTrait}; + +/// Place i bytes items on stack. +#[inline(always)] +fn exec_push_i(ref self: VM, i: u8) -> Result<(), EVMError> { + self.charge_gas(gas::VERYLOW)?; + let i = i.into(); + let args_pc = self.pc() + 1; // PUSH_N Arguments begin at pc + 1 + let data = self.read_code(args_pc, i); + + self.set_pc(self.pc() + i); + + if data.len() == 0 { + self.stack.push(0) + } else { + self.stack.push(data.pad_right_with_zeroes(i).from_be_bytes_partial().unwrap()) + } +} + +#[generate_trait] +pub impl PushOperations of PushOperationsTrait { + /// 5F - PUSH0 operation + /// # Specification: https://www.evm.codes/#5f?fork=shanghai + #[inline(always)] + fn exec_push0(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::BASE)?; + self.stack.push(0) + } + + + /// 0x60 - PUSH1 operation + /// # Specification: https://www.evm.codes/#60?fork=shanghai + #[inline(always)] + fn exec_push1(ref self: VM) -> Result<(), EVMError> { + exec_push_i(ref self, 1) + } + + + /// 0x61 - PUSH2 operation + /// # Specification: https://www.evm.codes/#61?fork=shanghai + #[inline(always)] + fn exec_push2(ref self: VM) -> Result<(), EVMError> { + exec_push_i(ref self, 2) + } + + + /// 0x62 - PUSH3 operation + /// # Specification: https://www.evm.codes/#62?fork=shanghai + #[inline(always)] + fn exec_push3(ref self: VM) -> Result<(), EVMError> { + exec_push_i(ref self, 3) + } + + /// 0x63 - PUSH4 operation + /// # Specification: https://www.evm.codes/#63?fork=shanghai + #[inline(always)] + fn exec_push4(ref self: VM) -> Result<(), EVMError> { + exec_push_i(ref self, 4) + } + + /// 0x64 - PUSH5 operation + /// # Specification: https://www.evm.codes/#64?fork=shanghai + #[inline(always)] + fn exec_push5(ref self: VM) -> Result<(), EVMError> { + exec_push_i(ref self, 5) + } + + /// 0x65 - PUSH6 operation + /// # Specification: https://www.evm.codes/#65?fork=shanghai + #[inline(always)] + fn exec_push6(ref self: VM) -> Result<(), EVMError> { + exec_push_i(ref self, 6) + } + + /// 0x66 - PUSH7 operation + /// # Specification: https://www.evm.codes/#66?fork=shanghai + #[inline(always)] + fn exec_push7(ref self: VM) -> Result<(), EVMError> { + exec_push_i(ref self, 7) + } + + /// 0x67 - PUSH8 operation + /// # Specification: https://www.evm.codes/#67?fork=shanghai + #[inline(always)] + fn exec_push8(ref self: VM) -> Result<(), EVMError> { + exec_push_i(ref self, 8) + } + + + /// 0x68 - PUSH9 operation + /// # Specification: https://www.evm.codes/#68?fork=shanghai + #[inline(always)] + fn exec_push9(ref self: VM) -> Result<(), EVMError> { + exec_push_i(ref self, 9) + } + + /// 0x69 - PUSH10 operation + /// # Specification: https://www.evm.codes/#69?fork=shanghai + #[inline(always)] + fn exec_push10(ref self: VM) -> Result<(), EVMError> { + exec_push_i(ref self, 10) + } + + /// 0x6A - PUSH11 operation + /// # Specification: https://www.evm.codes/#6a?fork=shanghai + #[inline(always)] + fn exec_push11(ref self: VM) -> Result<(), EVMError> { + exec_push_i(ref self, 11) + } + + /// 0x6B - PUSH12 operation + /// # Specification: https://www.evm.codes/#6b?fork=shanghai + #[inline(always)] + fn exec_push12(ref self: VM) -> Result<(), EVMError> { + exec_push_i(ref self, 12) + } + + + /// 0x6C - PUSH13 operation + /// # Specification: https://www.evm.codes/#6c?fork=shanghai + #[inline(always)] + fn exec_push13(ref self: VM) -> Result<(), EVMError> { + exec_push_i(ref self, 13) + } + + /// 0x6D - PUSH14 operation + /// # Specification: https://www.evm.codes/#6d?fork=shanghai + #[inline(always)] + fn exec_push14(ref self: VM) -> Result<(), EVMError> { + exec_push_i(ref self, 14) + } + + + /// 0x6E - PUSH15 operation + /// # Specification: https://www.evm.codes/#6e?fork=shanghai + #[inline(always)] + fn exec_push15(ref self: VM) -> Result<(), EVMError> { + exec_push_i(ref self, 15) + } + + /// 0x6F - PUSH16 operation + /// # Specification: https://www.evm.codes/#6f?fork=shanghai + #[inline(always)] + fn exec_push16(ref self: VM) -> Result<(), EVMError> { + exec_push_i(ref self, 16) + } + + /// 0x70 - PUSH17 operation + /// # Specification: https://www.evm.codes/#70?fork=shanghai + #[inline(always)] + fn exec_push17(ref self: VM) -> Result<(), EVMError> { + exec_push_i(ref self, 17) + } + + /// 0x71 - PUSH18 operation + /// # Specification: https://www.evm.codes/#71?fork=shanghai + #[inline(always)] + fn exec_push18(ref self: VM) -> Result<(), EVMError> { + exec_push_i(ref self, 18) + } + + + /// 0x72 - PUSH19 operation + /// # Specification: https://www.evm.codes/#72?fork=shanghai + #[inline(always)] + fn exec_push19(ref self: VM) -> Result<(), EVMError> { + exec_push_i(ref self, 19) + } + + /// 0x73 - PUSH20 operation + /// # Specification: https://www.evm.codes/#73?fork=shanghai + #[inline(always)] + fn exec_push20(ref self: VM) -> Result<(), EVMError> { + exec_push_i(ref self, 20) + } + + + /// 0x74 - PUSH21 operation + /// # Specification: https://www.evm.codes/#74?fork=shanghai + #[inline(always)] + fn exec_push21(ref self: VM) -> Result<(), EVMError> { + exec_push_i(ref self, 21) + } + + + /// 0x75 - PUSH22 operation + /// # Specification: https://www.evm.codes/#75?fork=shanghai + #[inline(always)] + fn exec_push22(ref self: VM) -> Result<(), EVMError> { + exec_push_i(ref self, 22) + } + + + /// 0x76 - PUSH23 operation + /// # Specification: https://www.evm.codes/#76?fork=shanghai + #[inline(always)] + fn exec_push23(ref self: VM) -> Result<(), EVMError> { + exec_push_i(ref self, 23) + } + + + /// 0x77 - PUSH24 operation + /// # Specification: https://www.evm.codes/#77?fork=shanghai + #[inline(always)] + fn exec_push24(ref self: VM) -> Result<(), EVMError> { + exec_push_i(ref self, 24) + } + + + /// 0x78 - PUSH21 operation + /// # Specification: https://www.evm.codes/#78?fork=shanghai + #[inline(always)] + fn exec_push25(ref self: VM) -> Result<(), EVMError> { + exec_push_i(ref self, 25) + } + + + /// 0x79 - PUSH26 operation + /// # Specification: https://www.evm.codes/#79?fork=shanghai + #[inline(always)] + fn exec_push26(ref self: VM) -> Result<(), EVMError> { + exec_push_i(ref self, 26) + } + + + /// 0x7A - PUSH27 operation + /// # Specification: https://www.evm.codes/#7a?fork=shanghai + #[inline(always)] + fn exec_push27(ref self: VM) -> Result<(), EVMError> { + exec_push_i(ref self, 27) + } + + /// 0x7B - PUSH28 operation + /// # Specification: https://www.evm.codes/#7b?fork=shanghai + #[inline(always)] + fn exec_push28(ref self: VM) -> Result<(), EVMError> { + exec_push_i(ref self, 28) + } + + + /// 0x7C - PUSH29 operation + /// # Specification: https://www.evm.codes/#7c?fork=shanghai + #[inline(always)] + fn exec_push29(ref self: VM) -> Result<(), EVMError> { + exec_push_i(ref self, 29) + } + + + /// 0x7D - PUSH30 operation + /// # Specification: https://www.evm.codes/#7d?fork=shanghai + #[inline(always)] + fn exec_push30(ref self: VM) -> Result<(), EVMError> { + exec_push_i(ref self, 30) + } + + + /// 0x7E - PUSH31 operation + /// # Specification: https://www.evm.codes/#7e?fork=shanghai + #[inline(always)] + fn exec_push31(ref self: VM) -> Result<(), EVMError> { + exec_push_i(ref self, 31) + } + + + /// 0x7F - PUSH32 operation + /// # Specification: https://www.evm.codes/#7f?fork=shanghai + #[inline(always)] + fn exec_push32(ref self: VM) -> Result<(), EVMError> { + exec_push_i(ref self, 32) + } +} + +#[cfg(test)] +mod tests { + use crate::gas; + use crate::instructions::PushOperationsTrait; + use crate::model::vm::VMTrait; + use crate::stack::StackTrait; + use crate::test_utils::{VMBuilderTrait}; + use super::exec_push_i; + + #[test] + fn test_exec_push_i() { + // Test cases: (bytes_to_push, bytecode_length, expected_value) + let test_cases: Span<(u8, u8, u256)> = [ + (1, 1, 0xFF), // Push 1 byte + (16, 16, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF), // Push 16 bytes + ( + 32, 32, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + ), // Push 32 bytes (max) + ( + 32, 16, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000 + ), // Push 32 bytes, but only 16 available + (1, 0, 0), // Push 1 byte, but no bytes available + ].span(); + + for elem in test_cases { + let (bytes_to_push, bytecode_length, expected_value) = *elem; + + let mut vm = VMBuilderTrait::new_with_presets() + .with_bytecode(get_n_0xFF(bytecode_length)) + .build(); + let initial_pc = vm.pc(); + let initial_gas = vm.gas_left(); + + // Execute exec_push_i + let result = exec_push_i(ref vm, bytes_to_push); + + assert!(result.is_ok()); + + // Check stack + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.peek().unwrap(), expected_value); + + // Check PC increment + let pc_increment = vm.pc() - initial_pc; + assert_eq!(pc_increment, bytes_to_push.into()); + + // Check gas consumption + let gas_consumed = initial_gas - vm.gas_left(); + assert_eq!(gas_consumed, gas::VERYLOW); + } + } + + /// Get a span of 0xFF bytes of length n preceded by a 0x00 byte + /// to account for the argument offset in push operations + fn get_n_0xFF(mut n: u8) -> Span { + let mut array: Array = ArrayTrait::new(); + array.append(0x00); + for _ in 0..n { + array.append(0xFF); + }; + array.span() + } + + #[test] + fn test_push0() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(get_n_0xFF(0)).build(); + + // When + vm.exec_push0().expect('exec_push0 failed'); + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.peek().unwrap(), 0); + } + + #[test] + fn test_push1() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(get_n_0xFF(1)).build(); + + // When + vm.exec_push1().expect('exec_push1 failed'); + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.peek().unwrap(), 0xFF); + } + + #[test] + fn test_push2() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(get_n_0xFF(2)).build(); + + // When + vm.exec_push2().expect('exec_push2 failed'); + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.peek().unwrap(), 0xFFFF); + } + + #[test] + fn test_push3() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(get_n_0xFF(3)).build(); + + // When + vm.exec_push3().expect('exec_push3 failed'); + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.peek().unwrap(), 0xFFFFFF); + } + + #[test] + fn test_push4() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(get_n_0xFF(4)).build(); + + // When + vm.exec_push4().expect('exec_push4 failed'); + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.peek().unwrap(), 0xFFFFFFFF); + } + + #[test] + fn test_push5() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(get_n_0xFF(5)).build(); + + // When + vm.exec_push5().expect('exec_push5 failed'); + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.peek().unwrap(), 0xFFFFFFFFFF); + } + + #[test] + fn test_push6() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(get_n_0xFF(6)).build(); + + // When + vm.exec_push6().expect('exec_push6 failed'); + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.peek().unwrap(), 0xFFFFFFFFFFFF); + } + + #[test] + fn test_push7() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(get_n_0xFF(7)).build(); + + // When + vm.exec_push7().expect('exec_push7 failed'); + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.peek().unwrap(), 0xFFFFFFFFFFFFFF); + } + + + #[test] + fn test_push8() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(get_n_0xFF(8)).build(); + + // When + vm.exec_push8().expect('exec_push8 failed'); + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.peek().unwrap(), 0xFFFFFFFFFFFFFFFF); + } + + #[test] + fn test_push9() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(get_n_0xFF(9)).build(); + + // When + vm.exec_push9().expect('exec_push9 failed'); + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.peek().unwrap(), 0xFFFFFFFFFFFFFFFFFF); + } + + #[test] + fn test_push10() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(get_n_0xFF(10)).build(); + + // When + vm.exec_push10().expect('exec_push10 failed'); + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.peek().unwrap(), 0xFFFFFFFFFFFFFFFFFFFF); + } + + #[test] + fn test_push11() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(get_n_0xFF(11)).build(); + + // When + vm.exec_push11().expect('exec_push11 failed'); + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.peek().unwrap(), 0xFFFFFFFFFFFFFFFFFFFFFF); + } + + #[test] + fn test_push12() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(get_n_0xFF(12)).build(); + + // When + vm.exec_push12().expect('exec_push12 failed'); + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.peek().unwrap(), 0xFFFFFFFFFFFFFFFFFFFFFFFF); + } + + #[test] + fn test_push13() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(get_n_0xFF(13)).build(); + + // When + vm.exec_push13().expect('exec_push13 failed'); + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.peek().unwrap(), 0xFFFFFFFFFFFFFFFFFFFFFFFFFF); + } + + #[test] + fn test_push14() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(get_n_0xFF(14)).build(); + + // When + vm.exec_push14().expect('exec_push14 failed'); + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.peek().unwrap(), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + } + + #[test] + fn test_push15() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(get_n_0xFF(15)).build(); + + // When + vm.exec_push15().expect('exec_push15 failed'); + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.peek().unwrap(), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + } + + #[test] + fn test_push16() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(get_n_0xFF(16)).build(); + + // When + vm.exec_push16().expect('exec_push16 failed'); + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.peek().unwrap(), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + } + + #[test] + fn test_push17() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(get_n_0xFF(17)).build(); + + // When + vm.exec_push17().expect('exec_push17 failed'); + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.peek().unwrap(), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + } + + #[test] + fn test_push18() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(get_n_0xFF(18)).build(); + + // When + vm.exec_push18().expect('exec_push18 failed'); + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.peek().unwrap(), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + } + #[test] + fn test_push19() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(get_n_0xFF(19)).build(); + + // When + vm.exec_push19().expect('exec_push19 failed'); + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.peek().unwrap(), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + } + + #[test] + fn test_push20() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(get_n_0xFF(20)).build(); + + // When + vm.exec_push20().expect('exec_push20 failed'); + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.peek().unwrap(), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + } + + #[test] + fn test_push21() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(get_n_0xFF(21)).build(); + + // When + vm.exec_push21().expect('exec_push21 failed'); + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.peek().unwrap(), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + } + + #[test] + fn test_push22() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(get_n_0xFF(22)).build(); + + // When + vm.exec_push22().expect('exec_push22 failed'); + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.peek().unwrap(), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + } + #[test] + fn test_push23() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(get_n_0xFF(23)).build(); + + // When + vm.exec_push23().expect('exec_push23 failed'); + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.peek().unwrap(), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + } + #[test] + fn test_push24() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(get_n_0xFF(24)).build(); + + // When + vm.exec_push24().expect('exec_push24 failed'); + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.peek().unwrap(), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + } + + #[test] + fn test_push25() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(get_n_0xFF(25)).build(); + + // When + vm.exec_push25().expect('exec_push25 failed'); + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!(vm.stack.peek().unwrap(), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + } + + #[test] + fn test_push26() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(get_n_0xFF(26)).build(); + + // When + vm.exec_push26().expect('exec_push26 failed'); + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!( + vm.stack.peek().unwrap(), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + ); + } + + #[test] + fn test_push27() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(get_n_0xFF(27)).build(); + + // When + vm.exec_push27().expect('exec_push27 failed'); + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!( + vm.stack.peek().unwrap(), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + ); + } + + #[test] + fn test_push28() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(get_n_0xFF(28)).build(); + + // When + vm.exec_push28().expect('exec_push28 failed'); + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!( + vm.stack.peek().unwrap(), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + ); + } + + #[test] + fn test_push29() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(get_n_0xFF(29)).build(); + + // When + vm.exec_push29().expect('exec_push29 failed'); + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!( + vm.stack.peek().unwrap(), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + ); + } + + #[test] + fn test_push30() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(get_n_0xFF(30)).build(); + + // When + vm.exec_push30().expect('exec_push30 failed'); + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!( + vm.stack.peek().unwrap(), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + ); + } + + #[test] + fn test_push31() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(get_n_0xFF(31)).build(); + + // When + vm.exec_push31().expect('exec_push31 failed'); + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!( + vm.stack.peek().unwrap(), + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + ); + } + + #[test] + fn test_push32() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(get_n_0xFF(32)).build(); + + // When + vm.exec_push32().expect('exec_push32 failed'); + // Then + assert_eq!(vm.stack.len(), 1); + assert_eq!( + vm.stack.peek().unwrap(), + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + ); + } +} diff --git a/kakarot-ssj/crates/evm/src/instructions/sha3.cairo b/kakarot-ssj/crates/evm/src/instructions/sha3.cairo new file mode 100644 index 000000000..28f740398 --- /dev/null +++ b/kakarot-ssj/crates/evm/src/instructions/sha3.cairo @@ -0,0 +1,600 @@ +use core::cmp::min; +//! SHA3. +use core::keccak::{cairo_keccak}; + +// Internal imports +use crate::errors::EVMError; +use crate::gas; +use crate::memory::MemoryTrait; +use crate::model::vm::{VM, VMTrait}; +use crate::stack::StackTrait; +use utils::helpers::bytes_32_words_size; +use utils::traits::array::ArrayExtTrait; +use utils::traits::integer::U256Trait; + +#[generate_trait] +pub impl Sha3Impl of Sha3Trait { + /// SHA3 operation : Hashes n bytes in memory at a given offset in memory + /// and push the hash result to the stack. + /// + /// # Inputs + /// * `offset` - The offset in memory where to read the data + /// * `size` - The amount of bytes to read + /// + /// # Specification: https://www.evm.codes/#20?fork=shanghai + fn exec_sha3(ref self: VM) -> Result<(), EVMError> { + let offset: usize = self.stack.pop_usize()?; + let mut size: usize = self.stack.pop_usize()?; + + let words_size = bytes_32_words_size(size).into(); + let word_gas_cost = gas::KECCAK256WORD * words_size; + let memory_expansion = gas::memory_expansion(self.memory.size(), [(offset, size)].span())?; + self.memory.ensure_length(memory_expansion.new_size); + self.charge_gas(gas::KECCAK256 + word_gas_cost + memory_expansion.expansion_cost)?; + + let mut to_hash: Array = Default::default(); + + let (nb_words, nb_zeroes) = compute_memory_words_amount(size, offset, self.memory.size()); + let mut last_input_offset = fill_array_with_memory_words( + ref self, ref to_hash, offset, nb_words + ); + // Fill array to hash with zeroes for bytes out of memory bound + // which is faster than reading them from memory + to_hash.append_n(0, 4 * nb_zeroes); + + // For cases where the size of bytes to hash isn't a multiple of 8, + // prepare the last bytes to hash into last_input instead of appending + // it to to_hash. + let last_input: u64 = if (size % 32 != 0) { + let loaded = self.memory.load(last_input_offset); + prepare_last_input(ref to_hash, loaded, size % 32) + } else { + 0 + }; + // Properly set the memory length in case we skipped reading zeroes + self.memory.ensure_length(size + offset); + let mut hash = cairo_keccak(ref to_hash, last_input, size % 8); + self.stack.push(hash.reverse_endianness()) + } +} + + +/// Computes how many words are read from the memory +/// and how many words must be filled with zeroes +/// given a target size, a memory offset and the length of the memory. +/// +/// # Arguments +/// +/// * `size` - The amount of bytes to hash +/// * `offset` - Offset in memory +/// * `mem_len` - Size of the memory +/// Returns : (nb_words, nb_zeroes) +fn compute_memory_words_amount(size: u32, offset: u32, mem_len: u32) -> (u32, u32) { + // Bytes to hash are less than a word size + if size < 32 { + return (0, 0); + } + // Bytes out of memory bound are zeroes + if offset > mem_len { + return (0, size / 32); + } + // The only word to read from memory is less than 32 bytes + if mem_len - offset < 32 { + return (1, (size / 32) - 1); + } + + let bytes_to_read = min(mem_len - offset, size); + let nb_words = bytes_to_read / 32; + (nb_words, (size / 32) - nb_words) +} + +/// Fills the `to_hash` array with little endian u64s +/// by splitting words read from the memory and +/// returns the next offset to read from. +/// +/// # Arguments +/// +/// * `self` - The context in which the memory is read +/// * `to_hash` - A reference to the array to fill +/// * `offset` - Offset in memory to start reading from +/// * `amount` - The amount of words to read from memory +/// Return the new offset +fn fill_array_with_memory_words( + ref self: VM, ref to_hash: Array, mut offset: u32, mut amount: u32 +) -> u32 { + for _ in 0 + ..amount { + let loaded = self.memory.load(offset); + let ((high_h, low_h), (high_l, low_l)) = loaded.split_into_u64_le(); + to_hash.append(low_h); + to_hash.append(high_h); + to_hash.append(low_l); + to_hash.append(high_l); + + offset += 32; + }; + offset +} + +/// Fills the `to_hash` array with the n-1 remaining little endian u64 +/// depending on size from a word and returns +/// the u64 containing the last 8 bytes word to hash. +/// +/// # Arguments +/// +/// * `to_hash` - A reference to the array to fill +/// * `value` - The word to split in u64 words +/// * `size` - The amount of bytes still required to hash +/// Returns the last u64 word that isn't 8 Bytes long. +fn prepare_last_input(ref to_hash: Array, value: u256, size: u32) -> u64 { + let ((high_h, low_h), (high_l, low_l)) = value.split_into_u64_le(); + if size < 8 { + return low_h; + } else if size < 16 { + to_hash.append(low_h); + return high_h; + } else if size < 24 { + to_hash.append(low_h); + to_hash.append(high_h); + return low_l; + } else { + to_hash.append(low_h); + to_hash.append(high_h); + to_hash.append(low_l); + return high_l; + } +} + +#[cfg(test)] +mod tests { + use crate::instructions::Sha3Trait; + use crate::instructions::sha3; + use crate::memory::MemoryTrait; + use crate::stack::StackTrait; + use crate::test_utils::{VMBuilderTrait, MemoryTestUtilsTrait}; + + #[test] + fn test_exec_sha3_size_0_offset_0() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm.stack.push(0x00).expect('push failed'); + vm.stack.push(0x00).expect('push failed'); + + vm + .memory + .store_with_expansion( + 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000, 0 + ); + + // When + vm.exec_sha3().expect('exec_sha3 failed'); + + // Then + let result = vm.stack.peek().unwrap(); + + assert( + result == 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470, + 'wrong result' + ); + assert(vm.memory.size() == 32, 'wrong memory size'); + } + + + #[test] + fn test_exec_sha3_should_not_expand_memory() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm.stack.push(0x05).expect('push failed'); + vm.stack.push(0x04).expect('push failed'); + + vm + .memory + .store_with_expansion( + 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000, 0 + ); + + // When + vm.exec_sha3().expect('exec_sha3 failed'); + + // Then + let result = vm.stack.peek().unwrap(); + assert_eq!(result, 0xc41589e7559804ea4a2080dad19d876a024ccb05117835447d72ce08c1d020ec); + assert_eq!(vm.memory.size(), 32); + } + + #[test] + fn test_exec_sha3_should_expand_memory() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm.stack.push(24).expect('push failed'); + vm.stack.push(10).expect('push failed'); + + vm + .memory + .store_with_expansion( + 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000, 0 + ); + + // When + vm.exec_sha3().expect('exec_sha3 failed'); + + // Then + let result = vm.stack.peek().unwrap(); + assert_eq!(result, 0x827b659bbda2a0bdecce2c91b8b68462545758f3eba2dbefef18e0daf84f5ccd); + assert_eq!(vm.memory.size(), 64); + } + + #[test] + fn test_exec_sha3_size_0xFFFFF_offset_1000() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm.stack.push(0xFFFFF).expect('push failed'); + vm.stack.push(1000).expect('push failed'); + + vm + .memory + .store_with_expansion( + 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000, 0 + ); + + // When + vm.exec_sha3().expect('exec_sha3 failed'); + + // Then + let result = vm.stack.peek().unwrap(); + assert( + result == 0xbe6f1b42b34644f918560a07f959d23e532dea5338e4b9f63db0caeb608018fa, + 'wrong result' + ); + assert(vm.memory.size() == (((0xFFFFF + 1000) + 31) / 32) * 32, 'wrong memory size'); + } + + #[test] + fn test_exec_sha3_size_1000000_offset_2() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm.stack.push(1000000).expect('push failed'); + vm.stack.push(2).expect('push failed'); + + vm + .memory + .store_with_expansion( + 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000, 0 + ); + + // When + vm.exec_sha3().expect('exec_sha3 failed'); + + // Then + let result = vm.stack.peek().unwrap(); + assert( + result == 0x4aa461ae9513f3b03ae397740ade979809dd02ae2c14e101b32842fbee21f0a, + 'wrong result' + ); + assert(vm.memory.size() == (((1000000 + 2) + 31) / 32) * 32, 'wrong memory size'); + } + + #[test] + fn test_exec_sha3_size_1000000_offset_23() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm.stack.push(1000000).expect('push failed'); + vm.stack.push(2).expect('push failed'); + + vm + .memory + .store_with_expansion( + 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000, 0 + ); + vm + .memory + .store_with_expansion( + 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000, 0 + ); + + // When + vm.exec_sha3().expect('exec_sha3 failed'); + + // Then + let result = vm.stack.peek().unwrap(); + assert( + result == 0x4aa461ae9513f3b03ae397740ade979809dd02ae2c14e101b32842fbee21f0a, + 'wrong result' + ); + assert(vm.memory.size() == (((1000000 + 23) + 31) / 32) * 32, 'wrong memory size'); + } + + #[test] + fn test_exec_sha3_size_1_offset_2048() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm.stack.push(1).expect('push failed'); + vm.stack.push(2048).expect('push failed'); + + vm + .memory + .store_with_expansion( + 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000, 0 + ); + + // When + vm.exec_sha3().expect('exec_sha3 failed'); + + // Then + let result = vm.stack.peek().unwrap(); + assert( + result == 0xbc36789e7a1e281436464229828f817d6612f7b477d66591ff96a9e064bcc98a, + 'wrong result' + ); + assert(vm.memory.size() == (((2048 + 1) + 31) / 32) * 32, 'wrong memory size'); + } + + #[test] + fn test_exec_sha3_size_0_offset_1024() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm.stack.push(0).expect('push failed'); + vm.stack.push(1024).expect('push failed'); + + vm + .memory + .store_with_expansion( + 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000, 0 + ); + + // When + vm.exec_sha3().expect('exec_sha3 failed'); + + // Then + let result = vm.stack.peek().unwrap(); + assert( + result == 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470, + 'wrong result' + ); + assert(vm.memory.size() == 1024, 'wrong memory size'); + } + + #[test] + fn test_exec_sha3_size_32_offset_2016() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm.stack.push(32).expect('push failed'); + vm.stack.push(2016).expect('push failed'); + + vm + .memory + .store_with_expansion( + 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000, 0 + ); + + // When + vm.exec_sha3().expect('exec_sha3 failed'); + + // Then + let result = vm.stack.peek().unwrap(); + assert( + result == 0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563, + 'wrong result' + ); + assert(vm.memory.size() == (((2016 + 32) + 31) / 32) * 32, 'wrong memory size'); + } + + #[test] + fn test_exec_sha3_size_32_offset_0() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm.stack.push(32).expect('push failed'); + vm.stack.push(0).expect('push failed'); + + vm + .memory + .store_with_expansion( + 0xFAFFFFFF000000E500000077000000DEAD0000000004200000FADE0000450000, 0 + ); + + // When + vm.exec_sha3().expect('exec_sha3 failed'); + + // Then + let result = vm.stack.peek().unwrap(); + assert( + result == 0x567d6b045256961aee949d6bb4d5f814c5b42e6b8bb49a833e8e89fbcddee86c, + 'wrong result' + ); + assert(vm.memory.size() == 32, 'wrong memory size'); + } + + #[test] + fn test_exec_sha3_size_31_offset_0() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm.stack.push(31).expect('push failed'); + vm.stack.push(0).expect('push failed'); + + vm + .memory + .store_with_expansion( + 0xFAFFFFFF000000E500000077000000DEAD0000000004200000FADE0000450000, 0 + ); + + // When + vm.exec_sha3().expect('exec_sha3 failed'); + + // Then + let result = vm.stack.peek().unwrap(); + assert( + result == 0x4b13f212816c02cc818ba4802e81a4ac1904d2c920fe8d8cf3e4f05233a57d2e, + 'wrong result' + ); + assert(vm.memory.size() == 32, 'wrong memory size'); + } + + #[test] + fn test_exec_sha3_size_33_offset_0() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm.stack.push(33).expect('push failed'); + vm.stack.push(0).expect('push failed'); + + vm + .memory + .store_with_expansion( + 0xFAFFFFFF000000E500000077000000DEAD0000000004200000FADE0000450000, 0 + ); + + // When + vm.exec_sha3().expect('exec_sha3 failed'); + + // Then + let result = vm.stack.peek().unwrap(); + assert( + result == 0xa6fa3edfabbe64b6ce26120b21ac9b8191005115d5e7e03fa58ec9cc74c0f2f4, + 'wrong result' + ); + assert(vm.memory.size() == 64, 'wrong memory size'); + } + + #[test] + fn test_exec_sha3_size_0x0C80_offset_0() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm.stack.push(0x0C80).expect('push failed'); + vm.stack.push(0x00).expect('push failed'); + + let mut mem_dst: u32 = 0; + while mem_dst <= 0x0C80 { + vm + .memory + .store_with_expansion( + 0xFAFAFAFA00000000000000000000000000000000000000000000000000000000, mem_dst + ); + mem_dst += 0x20; + }; + + // When + vm.exec_sha3().expect('exec_sha3 failed'); + + // Then + let result = vm.stack.peek().unwrap(); + assert( + result == 0x2022ae07f3a362b08ac0a4bcb785c830cb5c368dc0ce6972249c6abbc68a5291, + 'wrong result' + ); + assert(vm.memory.size() == 0x0C80 + 32, 'wrong memory size'); + } + + #[test] + fn test_internal_fill_array_with_memory_words() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + let mut to_hash: Array = Default::default(); + + vm + .memory + .store_with_expansion( + 0xFAFFFFFF000000E500000077000000DEAD0000000004200000FADE0000450000, 0 + ); + let mut size = 32; + let mut offset = 0; + + // When + let (words_from_mem, _) = sha3::compute_memory_words_amount(size, offset, vm.memory.size()); + sha3::fill_array_with_memory_words(ref vm, ref to_hash, offset, words_from_mem); + + // Then + assert(to_hash.len() == 4, 'wrong array length'); + assert((*to_hash[0]) == 0xE5000000FFFFFFFA, 'wrong array value'); + assert((*to_hash[1]) == 0xDE00000077000000, 'wrong array value'); + assert((*to_hash[2]) == 0x00200400000000AD, 'wrong array value'); + assert((*to_hash[3]) == 0x0000450000DEFA00, 'wrong array value'); + } + + #[test] + fn test_internal_fill_array_with_memory_words_size_33() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + let mut to_hash: Array = Default::default(); + + vm + .memory + .store_with_expansion( + 0xFAFFFFFF000000E500000077000000DEAD0000000004200000FADE0000450000, 0 + ); + let mut size = 33; + let mut offset = 0; + + // When + let (words_from_mem, _) = sha3::compute_memory_words_amount(size, offset, vm.memory.size()); + sha3::fill_array_with_memory_words(ref vm, ref to_hash, offset, words_from_mem); + + // Then + assert(to_hash.len() == 4, 'wrong array length'); + assert((*to_hash[0]) == 0xE5000000FFFFFFFA, 'wrong array value'); + assert((*to_hash[1]) == 0xDE00000077000000, 'wrong array value'); + assert((*to_hash[2]) == 0x00200400000000AD, 'wrong array value'); + assert((*to_hash[3]) == 0x0000450000DEFA00, 'wrong array value'); + } + + #[test] + fn test_internal_fill_array_with_last_inputs_size_5() { + // Given + let mut to_hash: Array = Default::default(); + let value: u256 = 0xFAFFFFFF000000E500000077000000DEAD0000000004200000FADE0000450000; + let size = 5; + + // When + let result = sha3::prepare_last_input(ref to_hash, value, size); + + // Then + assert(result == 0xE5000000FFFFFFFA, 'wrong result'); + assert(to_hash.len() == 0, 'wrong result'); + } + + #[test] + fn test_internal_fill_array_with_last_inputs_size_20() { + // Given + let mut to_hash: Array = Default::default(); + let value: u256 = 0xFAFFFFFF000000E500000077000000DEAD0000000004200000FADE0000450000; + let size = 20; + + // When + let result = sha3::prepare_last_input(ref to_hash, value, size); + + // Then + assert(result == 0x00200400000000AD, 'wrong result'); + assert(to_hash.len() == 2, 'wrong result'); + assert((*to_hash[0]) == 0xE5000000FFFFFFFA, 'wrong array value'); + assert((*to_hash[1]) == 0xDE00000077000000, 'wrong array value'); + } + + #[test] + fn test_internal_fill_array_with_last_inputs_size_50() { + // Given + let mut to_hash: Array = Default::default(); + let value: u256 = 0xFAFFFFFF000000E500000077000000DEAD0000000004200000FADE0000450000; + let size = 50; + + // When + let result = sha3::prepare_last_input(ref to_hash, value, size); + + // Then + assert(result == 0x0000450000DEFA00, 'wrong result'); + assert(to_hash.len() == 3, 'wrong result'); + assert((*to_hash[0]) == 0xE5000000FFFFFFFA, 'wrong array value'); + assert((*to_hash[1]) == 0xDE00000077000000, 'wrong array value'); + assert((*to_hash[2]) == 0x00200400000000AD, 'wrong array value'); + } +} diff --git a/kakarot-ssj/crates/evm/src/instructions/stop_and_arithmetic_operations.cairo b/kakarot-ssj/crates/evm/src/instructions/stop_and_arithmetic_operations.cairo new file mode 100644 index 000000000..9f302aee2 --- /dev/null +++ b/kakarot-ssj/crates/evm/src/instructions/stop_and_arithmetic_operations.cairo @@ -0,0 +1,740 @@ +//! Stop and Arithmetic Operations. +use core::integer::{u512_safe_div_rem_by_u256}; +use core::math::u256_mul_mod_n; +use core::num::traits::{OverflowingAdd, OverflowingMul, OverflowingSub}; +use crate::errors::EVMError; +use crate::gas; +use crate::model::vm::{VM, VMTrait}; +use crate::stack::StackTrait; +use utils::i256::i256; +use utils::math::{Exponentiation, WrappingExponentiation, u256_wide_add}; +use utils::traits::integer::BytesUsedTrait; + +#[generate_trait] +pub impl StopAndArithmeticOperations of StopAndArithmeticOperationsTrait { + /// 0x00 - STOP + /// Halts the execution of the current program. + /// # Specification: https://www.evm.codes/#00?fork=shanghai + fn exec_stop(ref self: VM) { + // return_data store the return_data for the last executed sub context + // see CALLs opcodes. When it runs the STOP opcode, it stops the current + // execution context with *no* return data (unlike RETURN and REVERT). + // hence it just clear the return_data and stop. + self.return_data = [].span(); + self.stop(); + } + + /// 0x01 - ADD + /// Addition operation + /// a + b: integer result of the addition modulo 2^256. + /// # Specification: https://www.evm.codes/#01?fork=shanghai + fn exec_add(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::VERYLOW)?; + let popped = self.stack.pop_n(2)?; + + // Compute the addition + let (result, _) = (*popped[0]).overflowing_add(*popped[1]); + + self.stack.push(result) + } + + /// 0x02 - MUL + /// Multiplication + /// a * b: integer result of the multiplication modulo 2^256. + /// # Specification: https://www.evm.codes/#02?fork=shanghai + fn exec_mul(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::LOW)?; + let popped = self.stack.pop_n(2)?; + + // Compute the multiplication + let (result, _) = (*popped[0]).overflowing_mul(*popped[1]); + + self.stack.push(result) + } + + /// 0x03 - SUB + /// Subtraction operation + /// a - b: integer result of the subtraction modulo 2^256. + /// # Specification: https://www.evm.codes/#03?fork=shanghai + fn exec_sub(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::VERYLOW)?; + let popped = self.stack.pop_n(2)?; + + // Compute the subtraction + let (result, _) = (*popped[0]).overflowing_sub(*popped[1]); + + self.stack.push(result) + } + + /// 0x04 - DIV + /// If the denominator is 0, the result will be 0. + /// a / b: integer result of the integer division. + /// # Specification: https://www.evm.codes/#04?fork=shanghai + fn exec_div(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::LOW)?; + let popped = self.stack.pop_n(2)?; + + let a: u256 = *popped[0]; + let b: u256 = *popped[1]; + + let result: u256 = match TryInto::>::try_into(b) { + Option::Some(_) => { + // Won't panic because b is not zero + a / b + }, + Option::None => 0, + }; + + self.stack.push(result) + } + + /// 0x05 - SDIV + /// Signed division operation + /// a / b: integer result of the signed integer division. + /// If the denominator is 0, the result will be 0. + /// # Specification: https://www.evm.codes/#05?fork=shanghai + fn exec_sdiv(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::LOW)?; + let a: i256 = self.stack.pop_i256()?; + let b: i256 = self.stack.pop_i256()?; + + let result: u256 = if b == 0_u256.into() { + 0 + } else { + (a / b).into() + }; + self.stack.push(result) + } + + /// 0x06 - MOD + /// Modulo operation + /// a % b: integer result of the integer modulo. If the denominator is 0, the result will be 0. + /// # Specification: https://www.evm.codes/#06?fork=shanghai + fn exec_mod(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::LOW)?; + let popped = self.stack.pop_n(2)?; + + let a: u256 = *popped[0]; + let b: u256 = *popped[1]; + + let result: u256 = match TryInto::>::try_into(b) { + Option::Some(_) => { + // Won't panic because b is not zero + a % b + }, + Option::None => 0, + }; + + self.stack.push(result) + } + + /// 0x07 - SMOD + /// Signed modulo operation + /// a % b: integer result of the signed integer modulo. If the denominator is 0, the result will + /// be 0. + /// All values are treated as two’s complement signed 256-bit integers. Note the overflow + /// semantic when −2^255 is negated. + /// # Specification: https://www.evm.codes/#07?fork=shanghai + fn exec_smod(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::LOW)?; + let a: i256 = self.stack.pop_i256()?; + let b: i256 = self.stack.pop_i256()?; + + let result: u256 = if b == 0_u256.into() { + 0 + } else { + (a % b).into() + }; + self.stack.push(result) + } + + /// 0x08 - ADDMOD + /// Addition and modulo operation + /// (a + b) % N: integer result of the addition followed by a modulo. If the denominator is 0, + /// the result will be 0. + /// All intermediate calculations of this operation are not subject to the 2256 modulo. + /// # Specification: https://www.evm.codes/#08?fork=shanghai + fn exec_addmod(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::MID)?; + let popped = self.stack.pop_n(3)?; + + let a: u256 = *popped[0]; + let b: u256 = *popped[1]; + let n = *popped[2]; + + let result: u256 = match TryInto::>::try_into(n) { + Option::Some(nonzero_n) => { + // This is more gas efficient than computing (a mod N) + (b mod N) mod N + let sum = u256_wide_add(a, b); + let (_, r) = u512_safe_div_rem_by_u256(sum, nonzero_n); + r + }, + Option::None => 0, + }; + + self.stack.push(result) + } + + /// 0x09 - MULMOD operation. + /// (a * b) % N: integer result of the multiplication followed by a modulo. + /// All intermediate calculations of this operation are not subject to the 2^256 modulo. + /// If the denominator is 0, the result will be 0. + /// # Specification: https://www.evm.codes/#09?fork=shanghai + fn exec_mulmod(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::MID)?; + let a: u256 = self.stack.pop()?; + let b: u256 = self.stack.pop()?; + let n = self.stack.pop()?; + + let result: u256 = match TryInto::>::try_into(n) { + Option::Some(n_nz) => { u256_mul_mod_n(a, b, n_nz) }, + Option::None => 0, + }; + + self.stack.push(result) + } + + /// 0x0A - EXP + /// Exponential operation + /// a ** b: integer result of raising a to the bth power modulo 2^256. + /// # Specification: https://www.evm.codes/#0a?fork=shanghai + fn exec_exp(ref self: VM) -> Result<(), EVMError> { + let base = self.stack.pop()?; + let exponent = self.stack.pop()?; + + // Gas + let bytes_used = exponent.bytes_used(); + self.charge_gas(gas::EXP + gas::EXP_GAS_PER_BYTE * bytes_used.into())?; + + let result = base.wrapping_pow(exponent); + + self.stack.push(result) + } + + /// 0x0B - SIGNEXTEND + /// SIGNEXTEND takes two inputs `b` and `x` where x: integer value to sign extend + /// and b: size in byte - 1 of the integer to sign extend and extends the length of + /// x as a two’s complement signed integer. + /// The first `i` bits of the output (numbered from the /!\LEFT/!\ counting from zero) + /// are equal to the `t`-th bit of `x`, where `t` is equal to + /// `256 - 8(b + 1)`. The remaining bits of the output are equal to the corresponding bits of + /// `x`. + /// If b >= 32, then the output is x because t<=0. + /// To efficiently implement this algorithm we can implement it using a mask, which is all + /// zeroes until the t-th bit included, and all ones afterwards. The index of `t` when numbered + /// from the RIGHT is s = `255 - t` = `8b + 7`; so the integer value of the mask used is 2^s - + /// 1. + /// Let v be the t-th bit of x. If v == 1, then the output should be all 1s until the t-th bit + /// included, followed by the remaining bits of x; which is corresponds to (x | !mask). + /// If v == 0, then the output should be all 0s until the t-th bit included, followed by the + /// remaining bits of x; + /// which corresponds to (x & mask). + /// # Specification: https://www.evm.codes/#0b?fork=shanghai + /// Complex opcode, check: https://ethereum.github.io/yellowpaper/paper.pdf + fn exec_signextend(ref self: VM) -> Result<(), EVMError> { + self.charge_gas(gas::LOW)?; + let b = self.stack.pop()?; + let x = self.stack.pop()?; + + let result = if b < 32 { + let s = 8 * b + 7; + let two_pow_s = 2.pow(s); + // Get v, the t-th bit of x. To do this we bitshift x by s bits to the right and apply a + // mask to get the last bit. + let v = (x / two_pow_s) & 1; + // Compute the mask with 8b+7 bits set to one + let mask = two_pow_s - 1; + if v == 0 { + x & mask + } else { + x | ~mask + } + } else { + x + }; + + self.stack.push(result) + } +} + +#[cfg(test)] +mod tests { + use core::num::traits::Bounded; + use core::result::ResultTrait; + use crate::instructions::StopAndArithmeticOperationsTrait; + use crate::model::vm::VMTrait; + use crate::stack::StackTrait; + use crate::test_utils::VMBuilderTrait; + + + #[test] + fn test_exec_stop_should_stop_and_empty_return_data() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.return_data = [1, 2, 3].span(); + // When + vm.exec_stop(); + + // Then + assert!(!vm.is_running()); + assert_eq!(vm.return_data, [].span()); + } + + #[test] + fn test_exec_add() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(1).expect('push failed'); + vm.stack.push(2).expect('push failed'); + vm.stack.push(3).expect('push failed'); + + // When + vm.exec_add().expect('exec_add failed'); + + // Then + assert(vm.stack.len() == 2, 'stack should have two elems'); + assert(vm.stack.peek().unwrap() == 5, 'stack top should be 3+2'); + assert(vm.stack.peek_at(1).unwrap() == 1, 'stack[1] should be 1'); + } + + #[test] + fn test_exec_add_overflow() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(Bounded::::MAX).unwrap(); + vm.stack.push(1).expect('push failed'); + + // When + vm.exec_add().expect('exec_add failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 0, 'stack top should be 0'); + } + + #[test] + fn test_exec_mul() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(4).expect('push failed'); + vm.stack.push(5).expect('push failed'); + + // When + vm.exec_mul().expect('exec_mul failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 20, 'stack top should be 4*5'); + } + + #[test] + fn test_exec_mul_overflow() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(Bounded::::MAX).unwrap(); + vm.stack.push(2).expect('push failed'); + + // When + vm.exec_mul().expect('exec_mul failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == Bounded::::MAX - 1, 'expected MAX_U256 -1'); + } + + #[test] + fn test_exec_sub() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(7).expect('push failed'); + vm.stack.push(10).expect('push failed'); + + // When + vm.exec_sub().expect('exec_sub failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 3, 'stack top should be 10-7'); + } + + #[test] + fn test_exec_sub_underflow() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(1).expect('push failed'); + vm.stack.push(0).expect('push failed'); + + // When + vm.exec_sub().expect('exec_sub failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == Bounded::::MAX, 'stack top should be MAX_U256'); + } + + + #[test] + fn test_exec_div() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(4).expect('push failed'); + vm.stack.push(100).expect('push failed'); + + // When + vm.exec_div().expect('exec_div failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 25, 'stack top should be 100/4'); + } + + #[test] + fn test_exec_div_by_zero() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(0).expect('push failed'); + vm.stack.push(100).expect('push failed'); + + // When + vm.exec_div().expect('exec_div failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 0, 'stack top should be 0'); + } + + #[test] + fn test_exec_sdiv_pos() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(5).expect('push failed'); + vm.stack.push(10).expect('push failed'); + + // When + vm.exec_sdiv().expect('exec_sdiv failed'); // 10 / 5 + + // Then + assert(vm.stack.len() == 1, 'stack len should be 1'); + assert(vm.stack.peek().unwrap() == 2, 'ctx not stopped'); + } + + #[test] + fn test_exec_sdiv_neg() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(Bounded::MAX).unwrap(); + vm.stack.push(2).expect('push failed'); + + // When + vm.exec_sdiv().expect('exec_sdiv failed'); // 2 / -1 + + // Then + assert(vm.stack.len() == 1, 'stack len should be 1'); + assert(vm.stack.peek().unwrap() == Bounded::MAX - 1, 'sdiv_neg failed'); + } + + #[test] + fn test_exec_sdiv_by_0() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(0).expect('push failed'); + vm.stack.push(10).expect('push failed'); + + // When + vm.exec_sdiv().expect('exec_sdiv failed'); + + // Then + assert(vm.stack.len() == 1, 'stack len should be 1'); + assert(vm.stack.peek().unwrap() == 0, 'stack top should be 0'); + } + + #[test] + fn test_exec_mod() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(6).expect('push failed'); + vm.stack.push(100).expect('push failed'); + + // When + vm.exec_mod().expect('exec_mod failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 4, 'stack top should be 100%6'); + } + + #[test] + fn test_exec_mod_by_zero() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(0).expect('push failed'); + vm.stack.push(100).expect('push failed'); + + // When + vm.exec_smod().expect('exec_smod failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 0, 'stack top should be 100%6'); + } + + #[test] + fn test_exec_smod() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(3).expect('push failed'); + vm.stack.push(10).expect('push failed'); + + // When + vm.exec_smod().expect('exec_smod failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 1, 'stack top should be 10%3 = 1'); + } + + #[test] + fn test_exec_smod_neg() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm + .stack + .push(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD) + .unwrap(); // -3 + vm + .stack + .push(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8) + .unwrap(); // -8 + + // When + vm.exec_smod().expect('exec_smod failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert( + vm + .stack + .peek() + .unwrap() == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE, + 'stack top should be -8%-3 = -2' + ); + } + + #[test] + fn test_exec_smod_zero() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(0).expect('push failed'); + vm.stack.push(10).expect('push failed'); + + // When + vm.exec_mod().expect('exec_mod failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 0, 'stack top should be 0'); + } + + + #[test] + fn test_exec_addmod() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(7).expect('push failed'); + vm.stack.push(10).expect('push failed'); + vm.stack.push(20).expect('push failed'); + + // When + vm.exec_addmod().expect('exec_addmod failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 2, 'stack top should be (10+20)%7'); + } + + #[test] + fn test_exec_addmod_by_zero() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(0).expect('push failed'); + vm.stack.push(10).expect('push failed'); + vm.stack.push(20).expect('push failed'); + + // When + vm.exec_addmod().expect('exec_addmod failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 0, 'stack top should be 0'); + } + + + #[test] + fn test_exec_addmod_overflow() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(3).expect('push failed'); + vm.stack.push(2).expect('push failed'); + vm.stack.push(Bounded::::MAX).unwrap(); + + // When + vm.exec_addmod().expect('exec_addmod failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert( + vm.stack.peek().unwrap() == 2, 'stack top should be 2' + ); // (MAX_U256 + 2) % 3 = (2^256 + 1) % 3 = 2 + } + + #[test] + fn test_mulmod_basic() { + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(10).expect('push failed'); + vm.stack.push(7).expect('push failed'); + vm.stack.push(5).expect('push failed'); + + // When + vm.exec_mulmod().expect('exec_mulmod failed'); + + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 5, 'stack top should be 5'); // (5 * 7) % 10 = 5 + } + + #[test] + fn test_mulmod_zero_modulus() { + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(0).expect('push failed'); + vm.stack.push(7).expect('push failed'); + vm.stack.push(5).expect('push failed'); + + vm.exec_mulmod().expect('exec_mulmod failed'); + + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 0, 'stack top should be 0'); // modulus is 0 + } + + #[test] + fn test_mulmod_overflow() { + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(12).expect('push failed'); + vm.stack.push(Bounded::::MAX).unwrap(); + vm.stack.push(Bounded::::MAX).unwrap(); + + vm.exec_mulmod().expect('exec_mulmod failed'); + + assert(vm.stack.len() == 1, 'stack should have one element'); + assert( + vm.stack.peek().unwrap() == 9, 'stack top should be 1' + ); // (MAX_U256 * MAX_U256) % 12 = 9 + } + + #[test] + fn test_mulmod_zero() { + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(10).expect('push failed'); + vm.stack.push(7).expect('push failed'); + vm.stack.push(0).expect('push failed'); + + vm.exec_mulmod().expect('exec_mulmod failed'); + + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 0, 'stack top should be 0'); // 0 * 7 % 10 = 0 + } + + #[test] + fn test_exec_exp() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + let initial_gas = vm.gas_left(); + vm.stack.push(2).expect('push failed'); + vm.stack.push(10).expect('push failed'); + + // When + vm.exec_exp().expect('exec exp failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert(vm.stack.peek().unwrap() == 100, 'stack top should be 100'); + let expected_gas_used = 10 + 50 * 1; + assert_eq!(initial_gas - vm.gas_left(), expected_gas_used); + } + + #[test] + fn test_exec_exp_overflow() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + let initial_gas = vm.gas_left(); + vm.stack.push(2).expect('push failed'); + vm.stack.push(Bounded::::MAX.into() + 1).unwrap(); + + // When + vm.exec_exp().expect('exec exp failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert( + vm.stack.peek().unwrap() == 0, 'stack top should be 0' + ); // (2^128)^2 = 2^256 = 0 % 2^256 + let expected_gas_used = 10 + 50 * 1; + assert_eq!(initial_gas - vm.gas_left(), expected_gas_used); + } + + #[test] + fn test_exec_signextend() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(0xFF).expect('push failed'); + vm.stack.push(0x00).expect('push failed'); + + // When + vm.exec_signextend().expect('exec_signextend failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert( + vm + .stack + .peek() + .unwrap() == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, + 'stack top should be MAX_u256 -1' + ); + } + + #[test] + fn test_exec_signextend_no_effect() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm.stack.push(0x7F).expect('push failed'); + vm.stack.push(0x00).expect('push failed'); + + // When + vm.exec_signextend().expect('exec_signextend failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert( + vm.stack.peek().unwrap() == 0x7F, 'stack top should be 0x7F' + ); // The 248-th bit of x is 0, so the output is not changed. + } + + #[test] + fn test_exec_signextend_on_negative() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + vm + .stack + .push(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0001) + .expect('push failed'); + vm.stack.push(0x01).expect('push failed'); // s = 15, v = 0 + + // When + vm.exec_signextend().expect('exec_signextend failed'); + + // Then + assert(vm.stack.len() == 1, 'stack should have one element'); + assert( + vm.stack.peek().unwrap() == 0x01, 'stack top should be 0' + ); // The 241-th bit of x is 0, so all bits before t are switched to 0 + } +} diff --git a/kakarot-ssj/crates/evm/src/instructions/system_operations.cairo b/kakarot-ssj/crates/evm/src/instructions/system_operations.cairo new file mode 100644 index 000000000..fcfb1a633 --- /dev/null +++ b/kakarot-ssj/crates/evm/src/instructions/system_operations.cairo @@ -0,0 +1,1180 @@ +use core::num::traits::CheckedAdd; +use crate::call_helpers::CallHelpers; +use crate::create_helpers::{CreateHelpers, CreateType}; +use crate::errors::{ensure, EVMError}; +use crate::gas; +use crate::memory::MemoryTrait; +use crate::model::Transfer; +use crate::model::account::{AccountTrait}; +use crate::model::vm::{VM, VMTrait}; +use crate::stack::StackTrait; +use crate::state::StateTrait; +use utils::set::SetTrait; + +#[generate_trait] +pub impl SystemOperations of SystemOperationsTrait { + /// CREATE + /// # Specification: https://www.evm.codes/#f0?fork=shanghai + fn exec_create(ref self: VM) -> Result<(), EVMError> { + ensure(!self.message().read_only, EVMError::WriteInStaticContext)?; + + let create_args = self.prepare_create(CreateType::Create)?; + self.generic_create(create_args) + } + + + /// CALL + /// # Specification: https://www.evm.codes/#f1?fork=shanghai + fn exec_call(ref self: VM) -> Result<(), EVMError> { + let gas = self.stack.pop_saturating_u64()?; + let to = self.stack.pop_eth_address()?; + let value = self.stack.pop()?; + let args_offset = self.stack.pop_saturating_usize()?; + let args_size = self.stack.pop_usize()?; + let ret_offset = self.stack.pop_saturating_usize()?; + let ret_size = self.stack.pop_usize()?; + + // GAS + let memory_expansion = gas::memory_expansion( + self.memory.size(), [(args_offset, args_size), (ret_offset, ret_size)].span() + )?; + self.memory.ensure_length(memory_expansion.new_size); + + let access_gas_cost = if self.accessed_addresses.contains(to) { + gas::WARM_ACCESS_COST + } else { + self.accessed_addresses.add(to); + gas::COLD_ACCOUNT_ACCESS_COST + }; + + let create_gas_cost = if self.env.state.is_account_alive(to) || value == 0 { + 0 + } else { + gas::NEWACCOUNT + }; + + let transfer_gas_cost = if value != 0 { + gas::CALLVALUE + } else { + 0 + }; + + let message_call_gas = gas::calculate_message_call_gas( + value, + gas, + self.gas_left(), + memory_expansion.expansion_cost, + access_gas_cost + transfer_gas_cost + create_gas_cost + )?; + self.charge_gas(message_call_gas.cost + memory_expansion.expansion_cost)?; + // Only the transfer gas is left to charge. + + let read_only = self.message().read_only; + + // Check if current context is read only that value == 0. + // De Morgan's law: !(read_only && value != 0) == !read_only || value == 0 + ensure(!read_only || value == 0, EVMError::WriteInStaticContext)?; + + // If sender_balance < value, return early, pushing + // 0 on the stack to indicate call failure. + // The gas cost relative to the transfer is refunded. + let sender_balance = self.env.state.get_account(self.message().target.evm).balance(); + if sender_balance < value { + self.return_data = [].span(); + self.gas_left += message_call_gas.stipend; + return self.stack.push(0); + } + + self + .generic_call( + gas: message_call_gas.stipend, + :value, + caller: self.message().target.evm, + :to, + code_address: to, + should_transfer_value: true, + is_staticcall: false, + :args_offset, + :args_size, + :ret_offset, + :ret_size, + ) + } + + + /// CALLCODE + /// # Specification: https://www.evm.codes/#f2?fork=shanghai + fn exec_callcode(ref self: VM) -> Result<(), EVMError> { + let gas = self.stack.pop_saturating_u64()?; + let code_address = self.stack.pop_eth_address()?; + let value = self.stack.pop()?; + let args_offset = self.stack.pop_saturating_usize()?; + let args_size = self.stack.pop_usize()?; + let ret_offset = self.stack.pop_saturating_usize()?; + let ret_size = self.stack.pop_usize()?; + + let to = self.message().target.evm; + + // GAS + let memory_expansion = gas::memory_expansion( + self.memory.size(), [(args_offset, args_size), (ret_offset, ret_size)].span() + )?; + self.memory.ensure_length(memory_expansion.new_size); + + let access_gas_cost = if self.accessed_addresses.contains(code_address) { + gas::WARM_ACCESS_COST + } else { + self.accessed_addresses.add(code_address); + gas::COLD_ACCOUNT_ACCESS_COST + }; + + let transfer_gas_cost = if value != 0 { + gas::CALLVALUE + } else { + 0 + }; + + let message_call_gas = gas::calculate_message_call_gas( + value, + gas, + self.gas_left(), + memory_expansion.expansion_cost, + access_gas_cost + transfer_gas_cost + )?; + self.charge_gas(message_call_gas.cost + memory_expansion.expansion_cost)?; + + // If sender_balance < value, return early, pushing + // 0 on the stack to indicate call failure. + // The gas cost relative to the transfer is refunded. + let sender_balance = self.env.state.get_account(self.message().target.evm).balance(); + if sender_balance < value { + self.return_data = [].span(); + self.gas_left += message_call_gas.stipend; + return self.stack.push(0); + } + + self + .generic_call( + message_call_gas.stipend, + value, + self.message().target.evm, + to, + code_address, + true, + false, + args_offset, + args_size, + ret_offset, + ret_size, + ) + } + /// RETURN + /// # Specification: https://www.evm.codes/#f3?fork=shanghai + fn exec_return(ref self: VM) -> Result<(), EVMError> { + let offset = self.stack.pop_saturating_usize()?; + let size = self.stack.pop_usize()?; + let memory_expansion = gas::memory_expansion(self.memory.size(), [(offset, size)].span())?; + self.memory.ensure_length(memory_expansion.new_size); + self.charge_gas(gas::ZERO + memory_expansion.expansion_cost)?; + + let mut return_data = Default::default(); + self.memory.load_n(size, ref return_data, offset); + + // Set the memory data to the parent context return data + // and halt the context. + self.set_return_data(return_data.span()); + self.stop(); + Result::Ok(()) + } + + /// DELEGATECALL + /// # Specification: https://www.evm.codes/#f4?fork=shanghai + fn exec_delegatecall(ref self: VM) -> Result<(), EVMError> { + let gas = self.stack.pop_saturating_u64()?; + let code_address = self.stack.pop_eth_address()?; + let args_offset = self.stack.pop_saturating_usize()?; + let args_size = self.stack.pop_usize()?; + let ret_offset = self.stack.pop_saturating_usize()?; + let ret_size = self.stack.pop_usize()?; + + // GAS + let memory_expansion = gas::memory_expansion( + self.memory.size(), [(args_offset, args_size), (ret_offset, ret_size)].span() + )?; + self.memory.ensure_length(memory_expansion.new_size); + + let access_gas_cost = if self.accessed_addresses.contains(code_address) { + gas::WARM_ACCESS_COST + } else { + self.accessed_addresses.add(code_address); + gas::COLD_ACCOUNT_ACCESS_COST + }; + + let message_call_gas = gas::calculate_message_call_gas( + 0, gas, self.gas_left(), memory_expansion.expansion_cost, access_gas_cost + )?; + self.charge_gas(message_call_gas.cost + memory_expansion.expansion_cost)?; + + self + .generic_call( + message_call_gas.stipend, + self.message().value, + self.message().caller.evm, + self.message().target.evm, + code_address, + false, + false, + args_offset, + args_size, + ret_offset, + ret_size, + ) + } + + /// CREATE2 + /// # Specification: https://www.evm.codes/#f5?fork=shanghai + fn exec_create2(ref self: VM) -> Result<(), EVMError> { + ensure(!self.message().read_only, EVMError::WriteInStaticContext)?; + + let create_args = self.prepare_create(CreateType::Create2)?; + self.generic_create(create_args) + } + + /// STATICCALL + /// # Specification: https://www.evm.codes/#fa?fork=shanghai + fn exec_staticcall(ref self: VM) -> Result<(), EVMError> { + let gas = self.stack.pop_saturating_u64()?; + let to = self.stack.pop_eth_address()?; + let args_offset = self.stack.pop_saturating_usize()?; + let args_size = self.stack.pop_usize()?; + let ret_offset = self.stack.pop_saturating_usize()?; + let ret_size = self.stack.pop_usize()?; + + // GAS + let memory_expansion = gas::memory_expansion( + self.memory.size(), [(args_offset, args_size), (ret_offset, ret_size)].span() + )?; + self.memory.ensure_length(memory_expansion.new_size); + + let access_gas_cost = if self.accessed_addresses.contains(to) { + gas::WARM_ACCESS_COST + } else { + self.accessed_addresses.add(to); + gas::COLD_ACCOUNT_ACCESS_COST + }; + + let message_call_gas = gas::calculate_message_call_gas( + 0, gas, self.gas_left(), memory_expansion.expansion_cost, access_gas_cost + )?; + let gas_to_charge = message_call_gas + .cost + .checked_add(memory_expansion.expansion_cost) + .ok_or(EVMError::OutOfGas)?; + self.charge_gas(gas_to_charge)?; + + self + .generic_call( + message_call_gas.stipend, + 0, + self.message().target.evm, + to, + to, + true, + true, + args_offset, + args_size, + ret_offset, + ret_size, + ) + } + + + /// REVERT + /// # Specification: https://www.evm.codes/#fd?fork=shanghai + fn exec_revert(ref self: VM) -> Result<(), EVMError> { + let offset = self.stack.pop_saturating_usize()?; + let size = self.stack.pop_usize()?; + + let memory_expansion = gas::memory_expansion(self.memory.size(), [(offset, size)].span())?; + self.memory.ensure_length(memory_expansion.new_size); + self.charge_gas(memory_expansion.expansion_cost)?; + + let mut return_data = Default::default(); + self.memory.load_n(size, ref return_data, offset); + + // Set the memory data to the parent context return data + // and halt the context. + self.set_return_data(return_data.span()); + self.stop(); + self.set_error(); + Result::Ok(()) + } + + /// INVALID + /// # Specification: https://www.evm.codes/#fe?fork=shanghai + fn exec_invalid(ref self: VM) -> Result<(), EVMError> { + Result::Err(EVMError::InvalidOpcode(0xfe)) + } + + + /// SELFDESTRUCT + /// # Specification: https://www.evm.codes/#ff?fork=shanghai + fn exec_selfdestruct(ref self: VM) -> Result<(), EVMError> { + let recipient = self.stack.pop_eth_address()?; + + // GAS + let mut gas_cost = gas::SELFDESTRUCT; + if !self.accessed_addresses.contains(recipient) { + self.accessed_addresses.add(recipient); + gas_cost += gas::COLD_ACCOUNT_ACCESS_COST; + }; + + let mut self_account = self.env.state.get_account(self.message().target.evm); + let self_balance = self_account.balance(); + if (!self.env.state.is_account_alive(recipient) && self_balance != 0) { + gas_cost += gas::NEWACCOUNT; + } + self.charge_gas(gas_cost)?; + + // Operation + ensure(!self.message().read_only, EVMError::WriteInStaticContext)?; + + // If the account was created in the same transaction and recipient is self, the native + // token is burnt + let recipient_evm_address = if (self_account.is_created + && recipient == self_account.evm_address()) { + 0.try_into().unwrap() + } else { + recipient + }; + let recipient_account = self.env.state.get_account(recipient_evm_address); + // Transfer balance + self + .env + .state + .add_transfer( + Transfer { + sender: self_account.address(), + recipient: recipient_account.address(), + amount: self_balance + } + )?; + + //@dev: get_account again because add_transfer modified its balance + self_account = self.env.state.get_account(self.message().target.evm); + // Register for selfdestruct + self_account.selfdestruct(); + self.env.state.set_account(self_account); + self.stop(); + Result::Ok(()) + } +} + +#[cfg(test)] +mod tests { + use contracts::test_data::{storage_evm_bytecode, storage_evm_initcode}; + use core::result::ResultTrait; + use core::starknet::EthAddress; + use core::traits::TryInto; + use crate::call_helpers::CallHelpersImpl; + use crate::instructions::MemoryOperationTrait; + use crate::instructions::SystemOperationsTrait; + use crate::interpreter::{EVMTrait}; + use crate::model::account::{Account}; + use crate::model::vm::VMTrait; + use crate::model::{AccountTrait, Address}; + use crate::stack::StackTrait; + use crate::state::{StateTrait}; + use crate::test_utils::{ + VMBuilderTrait, MemoryTestUtilsTrait, native_token, evm_address, setup_test_environment, + origin, uninitialized_account + }; + use snforge_std::{test_address, start_mock_call}; + use utils::constants::EMPTY_KECCAK; + use utils::helpers::compute_starknet_address; + use utils::traits::bytes::{U8SpanExTrait, FromBytes}; + + use utils::traits::{EthAddressIntoU256}; + + + #[test] + fn test_exec_return() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + // When + vm.stack.push(1000).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.exec_mstore().expect('exec_mstore failed'); + + vm.stack.push(32).expect('push failed'); + vm.stack.push(0).expect('push failed'); + assert(vm.exec_return().is_ok(), 'Exec return failed'); + + let return_data = vm.return_data(); + let parsed_return_data: u256 = return_data + .from_be_bytes() + .expect('Failed to parse return data'); + assert(1000 == parsed_return_data, 'Wrong return_data'); + assert(!vm.is_running(), 'vm should be stopped'); + assert_eq!(vm.error, false); + } + + #[test] + fn test_exec_revert() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + // When + vm.stack.push(1000).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.exec_mstore().expect('exec_mstore failed'); + + vm.stack.push(32).expect('push failed'); + vm.stack.push(0).expect('push failed'); + assert(vm.exec_revert().is_ok(), 'Exec revert failed'); + + let return_data = vm.return_data(); + let parsed_return_data: u256 = return_data + .from_be_bytes() + .expect('Failed to parse return data'); + assert(1000 == parsed_return_data, 'Wrong return_data'); + assert(!vm.is_running(), 'vm should be stopped'); + assert_eq!(vm.error, true); + } + + #[test] + fn test_exec_return_with_offset() { + // Given + let mut vm = VMBuilderTrait::new_with_presets().build(); + // When + vm.stack.push(1).expect('push failed'); + vm.stack.push(0).expect('push failed'); + vm.exec_mstore().expect('exec_mstore failed'); + + vm.stack.push(32).expect('push failed'); + vm.stack.push(1).expect('push failed'); + assert(vm.exec_return().is_ok(), 'Exec return failed'); + let return_data = vm.return_data(); + let parsed_return_data: u256 = return_data + .from_be_bytes_partial() + .expect('Failed to parse return data'); + assert(256 == parsed_return_data, 'Wrong return_data'); + assert(!vm.is_running(), 'vm should be stopped'); + assert_eq!(vm.error, false); + } + + #[test] + fn test_exec_call() { + // Given + + // Set vm bytecode + // (call 0xffffff 0xabfa740ccd 0 0 0 0 1) + let bytecode = [ + 0x60, + 0x01, + 0x60, + 0x00, + 0x60, + 0x00, + 0x60, + 0x00, + 0x60, + 0x00, + 0x64, + 0xab, + 0xfa, + 0x74, + 0x0c, + 0xcd, + 0x62, + 0xff, + 0xff, + 0xff, + // CALL + 0xf1, + 0x00 + ].span(); + let code_hash = bytecode.compute_keccak256_hash(); + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(bytecode).build(); + let caller_account = Account { + address: vm.message().target, + balance: 0, + code: bytecode, + code_hash: code_hash, + nonce: 0, + is_created: false, + selfdestruct: false, + }; + vm.env.state.set_account(caller_account); + + // Deploy bytecode at 0xabfa740ccd + // SSTORE 0x42 at 0x42 + let eth_address: EthAddress = 0xabfa740ccd_u256.into(); + let starknet_address = compute_starknet_address( + test_address(), eth_address, 0.try_into().unwrap() + ); + let deployed_bytecode = [ + 0x60, + 0x01, + 0x60, + 0x01, + 0x01, + 0x60, + 0x00, + 0x53, + 0x60, + 0x42, + 0x60, + 0x42, + 0x55, + 0x60, + 0x20, + 0x60, + 0x00, + 0xf3 + ].span(); + let code_hash = deployed_bytecode.compute_keccak256_hash(); + let contract_account = Account { + address: Address { evm: eth_address, starknet: starknet_address, }, + balance: 0, + code: deployed_bytecode, + code_hash: code_hash, + nonce: 1, + is_created: false, + selfdestruct: false, + }; + vm.env.state.set_account(contract_account); + + // When + EVMTrait::execute_code(ref vm); + + // Then + assert!(!vm.is_error()); + assert!(!vm.is_running()); + let storage_val = vm.env.state.read_state(contract_account.address.evm, 0x42); + assert_eq!(storage_val, 0x42); + } + + #[test] + fn test_should_fail_exec_staticcall() { + // Given + + // Set vm bytecode + // (staticcall 0xffffff 0xabfa740ccd 0 0 0 0 1) + let bytecode = [ + 0x60, + 0x01, + 0x60, + 0x00, + 0x60, + 0x00, + 0x60, + 0x00, + 0x60, + 0x00, + 0x64, + 0xab, + 0xfa, + 0x74, + 0x0c, + 0xcd, + 0x62, + 0xff, + 0xff, + 0xff, + // STATICCALL + 0xfa, + 0x00 + ].span(); + let code_hash = bytecode.compute_keccak256_hash(); + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(bytecode).build(); + let caller_account = Account { + address: vm.message().target, + balance: 0, + code: bytecode, + code_hash: code_hash, + nonce: 0, + is_created: false, + selfdestruct: false, + }; + vm.env.state.set_account(caller_account); + + // Deploy bytecode at 0xabfa740ccd + // SSTORE 0x42 at 0x42 + let eth_address: EthAddress = 0xabfa740ccd_u256.into(); + let starknet_address = compute_starknet_address( + test_address(), eth_address, 0.try_into().unwrap() + ); + let deployed_bytecode = [ + 0x60, + 0x01, + 0x60, + 0x01, + 0x01, + 0x60, + 0x00, + 0x53, + 0x60, + 0x42, + 0x60, + 0x42, + 0x55, + 0x60, + 0x20, + 0x60, + 0x00, + 0xf3 + ].span(); + let code_hash = deployed_bytecode.compute_keccak256_hash(); + let contract_account = Account { + address: Address { evm: eth_address, starknet: starknet_address, }, + balance: 0, + code: deployed_bytecode, + code_hash: code_hash, + nonce: 1, + is_created: false, + selfdestruct: false, + }; + vm.env.state.set_account(contract_account); + + // When + EVMTrait::execute_code(ref vm); + + // Then + assert!(!vm.is_error()); + assert!(!vm.is_running()); + assert_eq!(vm.stack.peek().unwrap(), 0); // STATICCALL should fail because of SSTORE + } + + + #[test] + fn test_exec_call_code() { + // Given + // Set vm bytecode + // (callcode 0xffffff 0x1234 0 0 0 0 1) + let bytecode = [ + 0x60, + 0x01, + 0x60, + 0x00, + 0x60, + 0x00, + 0x60, + 0x00, + 0x60, + 0x00, + 0x60, + 0x00, + 0x61, + 0x12, + 0x34, + 0x62, + 0xff, + 0xff, + 0xff, + // CALLCODE + 0xf2, + 0x00 + ].span(); + let _code_hash = bytecode.compute_keccak256_hash(); + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(bytecode).build(); + let eoa_account = Account { + address: vm.message().target, + balance: 0, + code: [].span(), + code_hash: EMPTY_KECCAK, + nonce: 0, + is_created: false, + selfdestruct: false, + }; + vm.env.state.set_account(eoa_account); + + // Deploy bytecode at 0x1234 + // SSTORE 0x42 at 0x42 + let deployed_bytecode = [ + 0x60, + 0x01, + 0x60, + 0x01, + 0x01, + 0x60, + 0x00, + 0x53, + 0x60, + 0x42, + 0x60, + 0x42, + 0x55, + 0x60, + 0x20, + 0x60, + 0x00, + 0xf3 + ].span(); + let code_hash = deployed_bytecode.compute_keccak256_hash(); + let eth_address: EthAddress = 0x1234.try_into().unwrap(); + let starknet_address = compute_starknet_address( + test_address(), eth_address, 0.try_into().unwrap() + ); + let contract_account = Account { + address: Address { evm: eth_address, starknet: starknet_address, }, + balance: 0, + code: deployed_bytecode, + code_hash: code_hash, + nonce: 1, + is_created: false, + selfdestruct: false, + }; + vm.env.state.set_account(contract_account); + + // When + EVMTrait::execute_code(ref vm); + + // Then + assert!(!vm.is_error()); + assert!(!vm.is_running()); + + let storage_val = vm.env.state.read_state(vm.message.target.evm, 0x42); + + assert_eq!(storage_val, 0x42); + } + + #[test] + fn test_exec_delegatecall() { + // Given + + // Set vm bytecode + // (delegatecall 0xffffff 0x1234 0 0 0 0 1) + let bytecode = [ + 0x60, + 0x01, + 0x60, + 0x00, + 0x60, + 0x00, + 0x60, + 0x00, + 0x60, + 0x00, + 0x61, + 0x12, + 0x34, + 0x62, + 0xff, + 0xff, + 0xff, + // DELEGATECALL + 0xf4, + 0x00 + ].span(); + let _code_hash = bytecode.compute_keccak256_hash(); + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(bytecode).build(); + let eoa_account = Account { + address: vm.message().target, + balance: 0, + code: [].span(), + code_hash: EMPTY_KECCAK, + nonce: 0, + is_created: false, + selfdestruct: false, + }; + vm.env.state.set_account(eoa_account); + + // SSTORE 0x42 at 0x42 + let deployed_bytecode = [ + 0x60, + 0x01, + 0x60, + 0x01, + 0x01, + 0x60, + 0x00, + 0x53, + 0x60, + 0x42, + 0x60, + 0x42, + 0x55, + 0x60, + 0x20, + 0x60, + 0x00, + 0xf3 + ].span(); + let code_hash = deployed_bytecode.compute_keccak256_hash(); + let eth_address: EthAddress = 0x1234.try_into().unwrap(); + let starknet_address = compute_starknet_address( + test_address(), eth_address, 0.try_into().unwrap() + ); + let contract_account = Account { + address: Address { evm: eth_address, starknet: starknet_address, }, + balance: 0, + code: deployed_bytecode, + code_hash: code_hash, + nonce: 1, + is_created: false, + selfdestruct: false, + }; + vm.env.state.set_account(contract_account); + + // When + EVMTrait::execute_code(ref vm); + + // Then + assert!(!vm.is_error()); + assert!(!vm.is_running()); + + let storage_val = vm.env.state.read_state(vm.message.target.evm, 0x42); + + assert_eq!(storage_val, 0x42); + } + + //! In the exec_create tests, we query the balance of the contract being created by doing a + //! starknet_call to the native token. + //! Thus, we must store the native token address in the Kakarot storage preemptively. + //! As such, the address computation uses the uninitialized account class. + #[test] + fn test_exec_create_no_value_transfer() { + // Given + setup_test_environment(); + + let deployed_bytecode = [0xff].span(); + let eth_address: EthAddress = evm_address(); + let starknet_address = compute_starknet_address( + test_address(), eth_address, uninitialized_account() + ); + let origin_account = Account { + address: Address { + evm: origin(), + starknet: compute_starknet_address( + test_address(), origin(), uninitialized_account() + ) + }, + balance: 2, + code: [].span(), + code_hash: EMPTY_KECCAK, + nonce: 0, + is_created: false, + selfdestruct: false, + }; + let code_hash = deployed_bytecode.compute_keccak256_hash(); + let contract_account = Account { + address: Address { evm: eth_address, starknet: starknet_address, }, + balance: 2, + code: deployed_bytecode, + code_hash: code_hash, + nonce: 1, + is_created: false, + selfdestruct: false, + }; + let mut vm = VMBuilderTrait::new_with_presets() + .with_target(contract_account.address) + .build(); + vm.env.state.set_account(contract_account); + vm.env.state.set_account(origin_account); + + // Load into memory the bytecode of Storage.sol + let storage_initcode = storage_evm_initcode(); + vm.memory.store_n_with_expansion(storage_initcode, 0); + + vm.stack.push(storage_initcode.len().into()).unwrap(); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + + // When + start_mock_call::(native_token(), selector!("balanceOf"), 0); + vm.exec_create().unwrap(); + EVMTrait::execute_code(ref vm); + + // computed using `compute_create_address` script + // run `bun run compute_create_address` -> CREATE -> EthAddress = evm_address() -> + //nonce = 1 + let account = vm + .env + .state + .get_account(0x930b3d8D35621F2e27Db700cA5D16Df771642fdD.try_into().unwrap()); + + assert_eq!(account.nonce(), 1); + assert_eq!(account.code, storage_evm_bytecode()); + assert_eq!(account.balance(), 0); + + let deployer = vm.env.state.get_account(eth_address); + assert_eq!(deployer.nonce(), 2); + assert_eq!(deployer.balance(), 2); + } + //TODO add test with value transfer + + #[test] + fn test_exec_create_failure() { + // Given + setup_test_environment(); + + let deployed_bytecode = [0xFF].span(); + let eth_address: EthAddress = evm_address(); + let starknet_address = compute_starknet_address( + test_address(), eth_address, 0.try_into().unwrap() + ); + let origin_account = Account { + address: Address { + evm: origin(), + starknet: compute_starknet_address( + test_address(), origin(), uninitialized_account() + ), + }, + balance: 2, + code: [].span(), + code_hash: EMPTY_KECCAK, + nonce: 0, + is_created: false, + selfdestruct: false, + }; + let code_hash = deployed_bytecode.compute_keccak256_hash(); + let deployer = Account { + address: Address { evm: eth_address, starknet: starknet_address, }, + balance: 2, + code: deployed_bytecode, + code_hash: code_hash, + nonce: 1, + is_created: false, + selfdestruct: false, + }; + let mut vm = VMBuilderTrait::new_with_presets().with_target(deployer.address).build(); + vm.env.state.set_account(deployer); + vm.env.state.set_account(origin_account); + + // Load into memory the bytecode to init, which is the revert opcode + let revert_initcode = [0xFD].span(); + vm.memory.store_n_with_expansion(revert_initcode, 0); + + vm.stack.push(revert_initcode.len().into()).unwrap(); + vm.stack.push(0).expect('push failed'); + vm.stack.push(1).expect('push failed'); + + // When + start_mock_call::(native_token(), selector!("balanceOf"), 0); + vm.exec_create().expect('exec_create failed'); + EVMTrait::execute_code(ref vm); + + let expected_address = 0x930b3d8D35621F2e27Db700cA5D16Df771642fdD.try_into().unwrap(); + + // computed using `compute_create_address` script + let account = vm.env.state.get_account(expected_address); + assert_eq!(account.nonce(), 0); + assert_eq!(account.code.len(), 0); + assert_eq!(account.balance(), 0); + + let deployer = vm.env.state.get_account(eth_address); + assert_eq!(deployer.nonce(), 2); + assert_eq!(deployer.balance(), 2); + } + + #[test] + fn test_exec_create2() { + // Given + setup_test_environment(); + + let deployed_bytecode = [0xff].span(); + let eth_address: EthAddress = evm_address(); + let starknet_address = compute_starknet_address( + test_address(), eth_address, 0.try_into().unwrap() + ); + let origin_account = Account { + address: Address { + evm: origin(), + starknet: compute_starknet_address( + test_address(), origin(), uninitialized_account() + ), + }, + balance: 2, + code: [].span(), + code_hash: EMPTY_KECCAK, + nonce: 0, + is_created: false, + selfdestruct: false, + }; + let code_hash = deployed_bytecode.compute_keccak256_hash(); + let contract_account = Account { + address: Address { evm: eth_address, starknet: starknet_address, }, + balance: 2, + code: deployed_bytecode, + code_hash: code_hash, + nonce: 1, + is_created: false, + selfdestruct: false, + }; + let mut vm = VMBuilderTrait::new_with_presets() + .with_caller(contract_account.address) + .build(); + + vm.env.state.set_account(origin_account); + vm.env.state.set_account(contract_account); + + // Load into memory the bytecode of Storage.sol + let storage_initcode = storage_evm_initcode(); + vm.memory.store_n_with_expansion(storage_initcode, 0); + + vm.stack.push(0).expect('push failed'); + vm.stack.push(storage_initcode.len().into()).unwrap(); + vm.stack.push(0).expect('push failed'); + vm.stack.push(0).expect('push failed'); + + // When + start_mock_call::(native_token(), selector!("balanceOf"), 0); + vm.exec_create2().unwrap(); + EVMTrait::execute_code(ref vm); + + assert!(!vm.is_running() && !vm.is_error()); + + // Add SNJS script to precompute the address of the Storage.sol contract + // import { getContractAddress } from 'viem' + + // const address = getContractAddress({ + // bytecode: + // + // '0x608060405234801561000f575f80fd5b506101438061001d5f395ff3fe608060405234801561000f575f80fd5b5060043610610034575f3560e01c80632e64cec1146100385780636057361d14610056575b5f80fd5b610040610072565b60405161004d919061009b565b60405180910390f35b610070600480360381019061006b91906100e2565b61007a565b005b5f8054905090565b805f8190555050565b5f819050919050565b61009581610083565b82525050565b5f6020820190506100ae5f83018461008c565b92915050565b5f80fd5b6100c181610083565b81146100cb575f80fd5b50565b5f813590506100dc816100b8565b92915050565b5f602082840312156100f7576100f66100b4565b5b5f610104848285016100ce565b9150509291505056fea2646970667358221220b5c3075f2f2034d039a227fac6dd314b052ffb2b3da52c7b6f5bc374d528ed3664736f6c63430008140033', + // from: '0x00000000000000000065766d5f61646472657373', opcode: 'CREATE2', + //salt: '0x00', + // }); + // console.log(address) + let account = vm + .env + .state + .get_account(0x0f48B8c382B5234b1a92368ee0f6864a429d0Cb8.try_into().unwrap()); + + assert(account.nonce() == 1, 'wrong nonce'); + assert(account.code == storage_evm_bytecode(), 'wrong bytecode'); + } + + #[test] + fn test_exec_selfdestruct_should_fail_if_readonly() { + // Given + let deployed_bytecode = [0xff].span(); + let eth_address: EthAddress = evm_address(); + let starknet_address = compute_starknet_address( + test_address(), eth_address, 0.try_into().unwrap() + ); + let code_hash = deployed_bytecode.compute_keccak256_hash(); + let contract_account = Account { + address: Address { evm: eth_address, starknet: starknet_address, }, + balance: 2, + code: deployed_bytecode, + code_hash: code_hash, + nonce: 1, + is_created: false, + selfdestruct: false, + }; + let mut vm = VMBuilderTrait::new_with_presets() + .with_target(contract_account.address) + .with_read_only() + .build(); + vm.env.state.set_account(contract_account); + + // When + vm.stack.push(contract_account.address.evm.into()).unwrap(); + let res = vm.exec_selfdestruct(); + // Then + assert!(res.is_err()) + } + + #[test] + fn test_exec_selfdestruct_should_burn_tokens_if_created_same_tx_and_recipient_self() { + // Given + let deployed_bytecode = [0xff].span(); + let eth_address: EthAddress = evm_address(); + let starknet_address = compute_starknet_address( + test_address(), eth_address, 0.try_into().unwrap() + ); + let code_hash = deployed_bytecode.compute_keccak256_hash(); + let contract_account = Account { + address: Address { evm: eth_address, starknet: starknet_address, }, + balance: 2, + code: deployed_bytecode, + code_hash: code_hash, + nonce: 1, + is_created: true, + selfdestruct: false, + }; + let burn_account = Account { + address: Address { + evm: 0.try_into().unwrap(), + starknet: compute_starknet_address( + test_address(), 0.try_into().unwrap(), 0.try_into().unwrap() + ), + }, + balance: 0, + code: [].span(), + code_hash: EMPTY_KECCAK, + nonce: 0, + is_created: false, + selfdestruct: false, + }; + let mut vm = VMBuilderTrait::new_with_presets() + .with_target(contract_account.address) + .build(); + vm.env.state.set_account(burn_account); + vm.env.state.set_account(contract_account); + + // When + vm.stack.push(contract_account.address.evm.into()).unwrap(); + vm.exec_selfdestruct().expect('selfdestruct failed'); + + // Then + let contract_account = vm.env.state.get_account(contract_account.address.evm); + assert!(contract_account.is_selfdestruct()); + assert_eq!(contract_account.balance(), 0); + + let burn_account = vm.env.state.get_account(burn_account.address.evm); + assert_eq!(burn_account.balance(), 2); + } + + #[test] + fn test_exec_selfdestruct_should_transfer_balance_to_recipient() { + // Given + let deployed_bytecode = [0xff].span(); + let eth_address: EthAddress = evm_address(); + let starknet_address = compute_starknet_address( + test_address(), eth_address, 0.try_into().unwrap() + ); + let code_hash = deployed_bytecode.compute_keccak256_hash(); + let contract_account = Account { + address: Address { evm: eth_address, starknet: starknet_address, }, + balance: 2, + code: deployed_bytecode, + code_hash: code_hash, + nonce: 1, + is_created: false, + selfdestruct: false, + }; + let recipient = Account { + address: Address { + evm: 'recipient'.try_into().unwrap(), + starknet: compute_starknet_address( + test_address(), 'recipient'.try_into().unwrap(), 0.try_into().unwrap() + ), + }, + balance: 0, + code: [].span(), + code_hash: EMPTY_KECCAK, + nonce: 0, + is_created: false, + selfdestruct: false, + }; + + let mut vm = VMBuilderTrait::new_with_presets() + .with_target(contract_account.address) + .build(); + vm.env.state.set_account(contract_account); + vm.env.state.set_account(recipient); + + // When + vm.stack.push(recipient.address.evm.into()).unwrap(); + vm.exec_selfdestruct().expect('selfdestruct failed'); + + // Then + let contract_account = vm.env.state.get_account(contract_account.address.evm); + assert!(contract_account.is_selfdestruct()); + assert_eq!(contract_account.balance(), 0); + + let recipient = vm.env.state.get_account(recipient.address.evm); + assert_eq!(recipient.balance(), 2); + } +} diff --git a/kakarot-ssj/crates/evm/src/interpreter.cairo b/kakarot-ssj/crates/evm/src/interpreter.cairo new file mode 100644 index 000000000..a17d06317 --- /dev/null +++ b/kakarot-ssj/crates/evm/src/interpreter.cairo @@ -0,0 +1,1115 @@ +use contracts::kakarot_core::KakarotCore; +use contracts::kakarot_core::interface::IKakarotCore; +use core::num::traits::{Bounded, Zero}; +use core::ops::SnapshotDeref; +use core::starknet::EthAddress; +use core::starknet::storage::{StoragePointerReadAccess}; +use crate::backend::starknet_backend; +use crate::create_helpers::CreateHelpers; +use crate::errors::{EVMError, EVMErrorTrait}; + +use crate::instructions::{ + ExchangeOperationsTrait, LoggingOperationsTrait, StopAndArithmeticOperationsTrait, + ComparisonAndBitwiseOperationsTrait, SystemOperationsTrait, BlockInformationTrait, + DuplicationOperationsTrait, EnvironmentInformationTrait, PushOperationsTrait, + MemoryOperationTrait, Sha3Trait +}; + +use crate::model::account::{Account, AccountTrait}; +use crate::model::vm::{VM, VMTrait}; +use crate::model::{ + Message, Environment, Transfer, ExecutionSummary, ExecutionResult, ExecutionResultTrait, + ExecutionResultStatus, AddressTrait, TransactionResult, TransactionResultTrait, Address +}; +use crate::precompiles::Precompiles; +use crate::precompiles::eth_precompile_addresses; +use crate::state::StateTrait; +use utils::address::compute_contract_address; +use utils::constants; +use utils::eth_transaction::common::TxKind; +use utils::eth_transaction::eip2930::{AccessListItem, AccessListItemTrait}; +use utils::eth_transaction::transaction::{Transaction, TransactionTrait}; +use utils::set::{Set, SetTrait}; +use utils::traits::eth_address::EthAddressExTrait; + +#[generate_trait] +pub impl EVMImpl of EVMTrait { + fn prepare_message( + self: @KakarotCore::ContractState, + tx: @Transaction, + sender_account: @Account, + ref env: Environment, + gas_left: u64 + ) -> (Message, bool) { + let (to, is_deploy_tx, code, code_address, calldata) = match tx.kind() { + TxKind::Create => { + let origin_nonce: u64 = sender_account.nonce(); + let to_evm_address = compute_contract_address( + sender_account.address().evm, origin_nonce + ); + let to_starknet_address = self.compute_starknet_address(to_evm_address); + let to = Address { evm: to_evm_address, starknet: to_starknet_address }; + (to, true, tx.input(), Zero::zero(), [].span()) + }, + TxKind::Call(to) => { + let target_starknet_address = self.compute_starknet_address(to); + let to = Address { evm: to, starknet: target_starknet_address }; + let code = env.state.get_account(to.evm).code; + (to, false, code, to, tx.input()) + } + }; + + let mut accessed_addresses: Set = Default::default(); + accessed_addresses.add(env.coinbase); + accessed_addresses.add(to.evm); + accessed_addresses.add(env.origin.evm); + accessed_addresses.extend(eth_precompile_addresses().spanset()); + + let mut accessed_storage_keys: Set<(EthAddress, u256)> = Default::default(); + + if let Option::Some(mut access_list) = tx.access_list() { + for access_list_item in access_list { + let AccessListItem { ethereum_address, storage_keys: _ } = *access_list_item; + let storage_keys = access_list_item.to_storage_keys(); + accessed_addresses.add(ethereum_address); + accessed_storage_keys.extend_from_span(storage_keys); + } + }; + + let message = Message { + caller: env.origin, + target: to, + gas_limit: gas_left, + data: calldata, + code, + code_address: code_address, + value: tx.value(), + should_transfer_value: true, + depth: 0, + read_only: false, + accessed_addresses: accessed_addresses.spanset(), + accessed_storage_keys: accessed_storage_keys.spanset(), + }; + + (message, is_deploy_tx) + } + + fn process_transaction( + ref self: KakarotCore::ContractState, origin: Address, tx: Transaction, intrinsic_gas: u64 + ) -> TransactionResult { + // Charge the cost of intrinsic gas - which has been verified to be <= gas_limit. + let block_base_fee = self.snapshot_deref().Kakarot_base_fee.read(); + let gas_price = tx.effective_gas_price(Option::Some(block_base_fee.into())); + let gas_left = tx.gas_limit() - intrinsic_gas; + let max_fee = tx.gas_limit().into() * gas_price; + let mut env = starknet_backend::get_env(origin, gas_price); + + let (message, is_deploy_tx) = { + let mut sender_account = env.state.get_account(origin.evm); + + // Charge the intrinsic gas to the sender so that it's not available for the execution + // of the transaction but don't trigger any actual transfer, as only the actual consumde + // gas is charged at the end of the transaction + sender_account.set_balance(sender_account.balance() - max_fee.into()); + + let (message, is_deploy_tx) = self + .prepare_message(@tx, @sender_account, ref env, gas_left); + + // Increment nonce of sender AFTER computing the created address + // to use the correct nonce when computing the address. + sender_account.set_nonce(sender_account.nonce() + 1); + + env.state.set_account(sender_account); + (message, is_deploy_tx) + }; + + let mut summary = Self::process_message_call(message, env, is_deploy_tx); + + // Cancel the max_fee that was taken from the sender to prevent double charging + let mut sender_account = summary.state.get_account(origin.evm); + sender_account.set_balance(sender_account.balance() + max_fee.into()); + summary.state.set_account(sender_account); + + // Gas refunds + let gas_used = tx.gas_limit() - summary.gas_left; + let gas_refund = core::cmp::min(gas_used / 5, summary.gas_refund); + + // Charging gas fees to the sender + // At the end of the tx, the sender must have paid + // (gas_used - gas_refund) * gas_price to the miner + // Because tx.gas_price == env.gas_price, and we checked the sender has enough balance + // to cover the gas fees + the value transfer, this transfer should never fail. + // We can thus directly charge the sender for the effective gas fees, + // without pre-emtively charging for the tx gas fee and then refund. + // This is not true for EIP-1559 transactions - not supported yet. + let total_gas_used = gas_used - gas_refund; + let _transaction_fee = total_gas_used.into() * gas_price; + + //TODO(gas): EF-tests doesn't yet support in-EVM gas charging, they assume that the gas + //charged is always correct for now. + // As correct gas accounting is not an immediate priority, we can just ignore the gas + // charging for now. + // match summary + // .state + // .add_transfer( + // Transfer { + // sender: origin, + // recipient: Address { + // evm: coinbase, starknet: block_info.sequencer_address, + // }, + // amount: transaction_fee.into() + // } + // ) { + // Result::Ok(_) => {}, + // Result::Err(err) => { + // + // return TransactionResultTrait::exceptional_failure( + // err.to_bytes(), tx.gas_limit() + // ); + // } + // }; + + TransactionResult { + success: summary.status == ExecutionResultStatus::Success, + return_data: summary.return_data, + gas_used: total_gas_used, + state: summary.state, + } + } + + + fn process_message_call( + message: Message, mut env: Environment, is_deploy_tx: bool, + ) -> ExecutionSummary { + let mut target_account = env.state.get_account(message.target.evm); + let result = if is_deploy_tx { + // Check collision + if target_account.has_code_or_nonce() { + return ExecutionSummary { + status: ExecutionResultStatus::Exception, + return_data: EVMError::Collision.to_bytes(), + gas_left: 0, + state: env.state, + gas_refund: 0 + }; + } + + let mut result = Self::process_create_message(message, ref env); + if result.is_success() { + result.return_data = message.target.evm.to_bytes().span(); + } + result + } else { + Self::process_message(message, ref env) + }; + + // No need to take snapshot of state, as the state is still empty at this point. + ExecutionSummary { + status: result.status, + state: env.state, + return_data: result.return_data, + gas_left: result.gas_left, + gas_refund: result.gas_refund + } + } + + fn process_create_message(message: Message, ref env: Environment) -> ExecutionResult { + //TODO(optimization) - Since the effects of executed code are + //reverted in the `process_message` function already, + // we only need to revert the changes made to the target account. Take a + // snapshot of the environment state so that we can revert if the + let state_snapshot = env.state.clone(); + let target_evm_address = message.target.evm; + + //@dev: Adding a scope block around `target_account` to ensure that the same instance is not + //being accessed after the state has been modified in `process_message`. + { + let mut target_account = env.state.get_account(target_evm_address); + // Increment nonce of target + target_account.set_nonce(1); + // Set the target as created + target_account.set_created(true); + target_account.address = message.target; + env.state.set_account(target_account); + } + + let mut result = Self::process_message(message, ref env); + if result.is_success() { + // Write the return_data of the initcode + // as the deployed contract's bytecode and charge gas + let target_account = env.state.get_account(target_evm_address); + match result.finalize_creation(target_account) { + Result::Ok(account_created) => { env.state.set_account(account_created) }, + Result::Err(err) => { + env.state = state_snapshot; + result.return_data = [].span(); + return ExecutionResultTrait::exceptional_failure( + err.to_bytes(), result.accessed_addresses, result.accessed_storage_keys + ); + } + }; + } else { + // Revert state to the snapshot taken before the create processing. + env.state = state_snapshot; + } + result + } + + fn process_message(message: Message, ref env: Environment) -> ExecutionResult { + if (message.depth > constants::STACK_MAX_DEPTH) { + // Because the failure happens before any modification to warm address/storage, + // we can pass an empty set + + return ExecutionResultTrait::exceptional_failure( + EVMError::DepthLimit.to_bytes(), Default::default(), Default::default() + ); + } + + let state_snapshot = env.state.clone(); + if message.should_transfer_value && message.value != 0 { + let transfer = Transfer { + sender: message.caller, recipient: message.target, amount: message.value + }; + match env.state.add_transfer(transfer) { + Result::Ok(_) => {}, + Result::Err(err) => { + return ExecutionResultTrait::exceptional_failure( + err.to_bytes(), Default::default(), Default::default() + ); + } + } + } + + // Instantiate a new VM using the message to process and the current environment. + let mut vm: VM = VMTrait::new(message, env); + + // Decode and execute the current opcode. + // until we have processed all opcodes or until we have stopped. + // Use a recursive function to allow passing VM by ref - which wouldn't work in a loop; + let result = Self::execute_code(ref vm); + + // Retrieve ownership of the `env` variable + // The state in the environment has been modified by the VM. + env = vm.env; + + if !result.is_success() { + // The `process_message` function has mutated the environment state. + // Revert state changes using the old snapshot as execution failed. + + env.state = state_snapshot; + } + + result + } + + fn execute_code(ref vm: VM) -> ExecutionResult { + // Handle precompile logic + if vm.message.code_address.evm.is_precompile() { + let result = Precompiles::exec_precompile(ref vm); + + match result { + Result::Ok(_) => { + let status = if vm.is_error() { + ExecutionResultStatus::Revert + } else { + ExecutionResultStatus::Success + }; + return ExecutionResult { + status, + return_data: vm.return_data(), + gas_left: vm.gas_left(), + accessed_addresses: vm.accessed_addresses(), + accessed_storage_keys: vm.accessed_storage_keys(), + gas_refund: vm.gas_refund() + }; + }, + Result::Err(error) => { + // If an error occurred, revert execution self. + // Currently, revert reason is a Span. + return ExecutionResultTrait::exceptional_failure( + error.to_bytes(), vm.accessed_addresses(), vm.accessed_storage_keys() + ); + } + } + } + + // Retrieve the current program counter. + let pc = vm.pc(); + let bytecode = vm.message().code; + + // If PC is out of bounds, stop the VM + // Also empties the returndata - akin to executing the STOP opcode. + if pc >= bytecode.len() { + vm.exec_stop(); + } + + if !vm.is_running() { + // REVERT opcode case + if vm.is_error() { + return ExecutionResult { + status: ExecutionResultStatus::Revert, + return_data: vm.return_data(), + gas_left: vm.gas_left(), + accessed_addresses: vm.accessed_addresses(), + accessed_storage_keys: vm.accessed_storage_keys(), + gas_refund: 0 + }; + }; + // Success case + return ExecutionResult { + status: ExecutionResultStatus::Success, + return_data: vm.return_data(), + gas_left: vm.gas_left(), + accessed_addresses: vm.accessed_addresses(), + accessed_storage_keys: vm.accessed_storage_keys(), + gas_refund: vm.gas_refund() + }; + } + + let opcode: u8 = *bytecode.at(pc); + + match Self::execute_opcode(ref vm, opcode) { + Result::Ok(_) => { + if opcode != 0x56 && opcode != 0x57 { + // Increment pc if not a JUMP family opcode + vm.set_pc(vm.pc() + 1); + } + + if vm.is_running() { + return Self::execute_code(ref vm); + } + // REVERT opcode case + if vm.is_error() { + return ExecutionResult { + status: ExecutionResultStatus::Revert, + return_data: vm.return_data(), + gas_left: vm.gas_left(), + accessed_addresses: vm.accessed_addresses(), + accessed_storage_keys: vm.accessed_storage_keys(), + gas_refund: 0 + }; + }; + // Success case + return ExecutionResult { + status: ExecutionResultStatus::Success, + return_data: vm.return_data(), + gas_left: vm.gas_left(), + accessed_addresses: vm.accessed_addresses(), + accessed_storage_keys: vm.accessed_storage_keys(), + gas_refund: vm.gas_refund() + }; + }, + Result::Err(error) => { + // If an error occurred, revert execution self. + // Currently, revert reason is a Span. + return ExecutionResultTrait::exceptional_failure( + error.to_bytes(), vm.accessed_addresses(), vm.accessed_storage_keys() + ); + } + } + } + + fn execute_opcode(ref self: VM, opcode: u8) -> Result<(), EVMError> { + // Call the appropriate function based on the opcode. + if opcode == 0x00 { + // STOP + return Result::Ok(self.exec_stop()); + } + if opcode == 0x01 { + // ADD + return self.exec_add(); + } + if opcode == 0x02 { + // MUL + return self.exec_mul(); + } + if opcode == 0x03 { + // SUB + return self.exec_sub(); + } + if opcode == 0x04 { + // DIV + return self.exec_div(); + } + if opcode == 0x05 { + // SDIV + return self.exec_sdiv(); + } + if opcode == 0x06 { + // MOD + return self.exec_mod(); + } + if opcode == 0x07 { + // SMOD + return self.exec_smod(); + } + if opcode == 0x08 { + // ADDMOD + return self.exec_addmod(); + } + if opcode == 0x09 { + // MULMOD + return self.exec_mulmod(); + } + if opcode == 0x0A { + // EXP + return self.exec_exp(); + } + if opcode == 0x0B { + // SIGNEXTEND + return self.exec_signextend(); + } + if opcode == 0x10 { + // LT + return self.exec_lt(); + } + if opcode == 0x11 { + // GT + return self.exec_gt(); + } + if opcode == 0x12 { + // SLT + return self.exec_slt(); + } + if opcode == 0x13 { + // SGT + return self.exec_sgt(); + } + if opcode == 0x14 { + // EQ + return self.exec_eq(); + } + if opcode == 0x15 { + // ISZERO + return self.exec_iszero(); + } + if opcode == 0x16 { + // AND + return self.exec_and(); + } + if opcode == 0x17 { + // OR + return self.exec_or(); + } + if opcode == 0x18 { + // XOR + return self.exec_xor(); + } + if opcode == 0x19 { + // NOT + return self.exec_not(); + } + if opcode == 0x1A { + // BYTE + return self.exec_byte(); + } + if opcode == 0x1B { + // SHL + return self.exec_shl(); + } + if opcode == 0x1C { + // SHR + return self.exec_shr(); + } + if opcode == 0x1D { + // SAR + return self.exec_sar(); + } + if opcode == 0x20 { + // KECCAK256 + return self.exec_sha3(); + } + if opcode == 0x30 { + // ADDRESS + return self.exec_address(); + } + if opcode == 0x31 { + // BALANCE + return self.exec_balance(); + } + if opcode == 0x32 { + // ORIGIN + return self.exec_origin(); + } + if opcode == 0x33 { + // CALLER + return self.exec_caller(); + } + if opcode == 0x34 { + // CALLVALUE + return self.exec_callvalue(); + } + if opcode == 0x35 { + // CALLDATALOAD + return self.exec_calldataload(); + } + if opcode == 0x36 { + // CALLDATASIZE + return self.exec_calldatasize(); + } + if opcode == 0x37 { + // CALLDATACOPY + return self.exec_calldatacopy(); + } + if opcode == 0x38 { + // CODESIZE + return self.exec_codesize(); + } + if opcode == 0x39 { + // CODECOPY + return self.exec_codecopy(); + } + if opcode == 0x3A { + // GASPRICE + return self.exec_gasprice(); + } + if opcode == 0x3B { + // EXTCODESIZE + return self.exec_extcodesize(); + } + if opcode == 0x3C { + // EXTCODECOPY + return self.exec_extcodecopy(); + } + if opcode == 0x3D { + // RETURNDATASIZE + return self.exec_returndatasize(); + } + if opcode == 0x3E { + // RETURNDATACOPY + return self.exec_returndatacopy(); + } + if opcode == 0x3F { + // EXTCODEHASH + return self.exec_extcodehash(); + } + if opcode == 0x40 { + // BLOCKHASH + return self.exec_blockhash(); + } + if opcode == 0x41 { + // COINBASE + return self.exec_coinbase(); + } + if opcode == 0x42 { + // TIMESTAMP + return self.exec_timestamp(); + } + if opcode == 0x43 { + // NUMBER + return self.exec_number(); + } + if opcode == 0x44 { + // PREVRANDAO + return self.exec_prevrandao(); + } + if opcode == 0x45 { + // GASLIMIT + return self.exec_gaslimit(); + } + if opcode == 0x46 { + // CHAINID + return self.exec_chainid(); + } + if opcode == 0x47 { + // SELFBALANCE + return self.exec_selfbalance(); + } + if opcode == 0x48 { + // BASEFEE + return self.exec_basefee(); + } + if opcode == 0x49 { + // BLOBHASH + return self.exec_blobhash(); + } + if opcode == 0x4A { + // BLOBBASEFEE + return self.exec_blobbasefee(); + } + if opcode == 0x50 { + // POP + return self.exec_pop(); + } + if opcode == 0x51 { + // MLOAD + return self.exec_mload(); + } + if opcode == 0x52 { + // MSTORE + return self.exec_mstore(); + } + if opcode == 0x53 { + // MSTORE8 + return self.exec_mstore8(); + } + if opcode == 0x54 { + // SLOAD + return self.exec_sload(); + } + if opcode == 0x55 { + // SSTORE + return self.exec_sstore(); + } + if opcode == 0x56 { + // JUMP + return self.exec_jump(); + } + if opcode == 0x57 { + // JUMPI + return self.exec_jumpi(); + } + if opcode == 0x58 { + // PC + return self.exec_pc(); + } + if opcode == 0x59 { + // MSIZE + return self.exec_msize(); + } + if opcode == 0x5A { + // GAS + return self.exec_gas(); + } + if opcode == 0x5B { + // JUMPDEST + return self.exec_jumpdest(); + } + if opcode == 0x5C { + // TLOAD + return self.exec_tload(); + } + if opcode == 0x5D { + // TSTORE + return self.exec_tstore(); + } + if opcode == 0x5E { + // MCOPY + return self.exec_mcopy(); + } + if opcode == 0x5F { + // PUSH0 + return self.exec_push0(); + } + if opcode == 0x60 { + // PUSH1 + return self.exec_push1(); + } + if opcode == 0x61 { + // PUSH2 + return self.exec_push2(); + } + if opcode == 0x62 { + // PUSH3 + return self.exec_push3(); + } + if opcode == 0x63 { + // PUSH4 + return self.exec_push4(); + } + if opcode == 0x64 { + // PUSH5 + return self.exec_push5(); + } + if opcode == 0x65 { + // PUSH6 + return self.exec_push6(); + } + if opcode == 0x66 { + // PUSH7 + return self.exec_push7(); + } + if opcode == 0x67 { + // PUSH8 + return self.exec_push8(); + } + if opcode == 0x68 { + // PUSH9 + return self.exec_push9(); + } + if opcode == 0x69 { + // PUSH10 + return self.exec_push10(); + } + if opcode == 0x6A { + // PUSH11 + return self.exec_push11(); + } + if opcode == 0x6B { + // PUSH12 + return self.exec_push12(); + } + if opcode == 0x6C { + // PUSH13 + return self.exec_push13(); + } + if opcode == 0x6D { + // PUSH14 + return self.exec_push14(); + } + if opcode == 0x6E { + // PUSH15 + return self.exec_push15(); + } + if opcode == 0x6F { + // PUSH16 + return self.exec_push16(); + } + if opcode == 0x70 { + // PUSH17 + return self.exec_push17(); + } + if opcode == 0x71 { + // PUSH18 + return self.exec_push18(); + } + if opcode == 0x72 { + // PUSH19 + return self.exec_push19(); + } + if opcode == 0x73 { + // PUSH20 + return self.exec_push20(); + } + if opcode == 0x74 { + // PUSH21 + return self.exec_push21(); + } + if opcode == 0x75 { + // PUSH22 + return self.exec_push22(); + } + if opcode == 0x76 { + // PUSH23 + return self.exec_push23(); + } + if opcode == 0x77 { + // PUSH24 + return self.exec_push24(); + } + if opcode == 0x78 { + // PUSH25 + return self.exec_push25(); + } + if opcode == 0x79 { + // PUSH26 + return self.exec_push26(); + } + if opcode == 0x7A { + // PUSH27 + return self.exec_push27(); + } + if opcode == 0x7B { + // PUSH28 + return self.exec_push28(); + } + if opcode == 0x7C { + // PUSH29 + return self.exec_push29(); + } + if opcode == 0x7D { + // PUSH30 + return self.exec_push30(); + } + if opcode == 0x7E { + // PUSH31 + return self.exec_push31(); + } + if opcode == 0x7F { + // PUSH32 + return self.exec_push32(); + } + if opcode == 0x80 { + // DUP1 + return self.exec_dup1(); + } + if opcode == 0x81 { + // DUP2 + return self.exec_dup2(); + } + if opcode == 0x82 { + // DUP3 + return self.exec_dup3(); + } + if opcode == 0x83 { + // DUP4 + return self.exec_dup4(); + } + if opcode == 0x84 { + // DUP5 + return self.exec_dup5(); + } + if opcode == 0x85 { + // DUP6 + return self.exec_dup6(); + } + if opcode == 0x86 { + // DUP7 + return self.exec_dup7(); + } + if opcode == 0x87 { + // DUP8 + return self.exec_dup8(); + } + if opcode == 0x88 { + // DUP9 + return self.exec_dup9(); + } + if opcode == 0x89 { + // DUP10 + return self.exec_dup10(); + } + if opcode == 0x8A { + // DUP11 + return self.exec_dup11(); + } + if opcode == 0x8B { + // DUP12 + return self.exec_dup12(); + } + if opcode == 0x8C { + // DUP13 + return self.exec_dup13(); + } + if opcode == 0x8D { + // DUP14 + return self.exec_dup14(); + } + if opcode == 0x8E { + // DUP15 + return self.exec_dup15(); + } + if opcode == 0x8F { + // DUP16 + return self.exec_dup16(); + } + if opcode == 0x90 { + // SWAP1 + return self.exec_swap1(); + } + if opcode == 0x91 { + // SWAP2 + return self.exec_swap2(); + } + if opcode == 0x92 { + // SWAP3 + return self.exec_swap3(); + } + if opcode == 0x93 { + // SWAP4 + return self.exec_swap4(); + } + if opcode == 0x94 { + // SWAP5 + return self.exec_swap5(); + } + if opcode == 0x95 { + // SWAP6 + return self.exec_swap6(); + } + if opcode == 0x96 { + // SWAP7 + return self.exec_swap7(); + } + if opcode == 0x97 { + // SWAP8 + return self.exec_swap8(); + } + if opcode == 0x98 { + // SWAP9 + return self.exec_swap9(); + } + if opcode == 0x99 { + // SWAP10 + return self.exec_swap10(); + } + if opcode == 0x9A { + // SWAP11 + return self.exec_swap11(); + } + if opcode == 0x9B { + // SWAP12 + return self.exec_swap12(); + } + if opcode == 0x9C { + // SWAP13 + return self.exec_swap13(); + } + if opcode == 0x9D { + // SWAP14 + return self.exec_swap14(); + } + if opcode == 0x9E { + // SWAP15 + return self.exec_swap15(); + } + if opcode == 0x9F { + // SWAP16 + return self.exec_swap16(); + } + if opcode == 0xA0 { + // LOG0 + return self.exec_log0(); + } + if opcode == 0xA1 { + // LOG1 + return self.exec_log1(); + } + if opcode == 0xA2 { + // LOG2 + return self.exec_log2(); + } + if opcode == 0xA3 { + // LOG3 + return self.exec_log3(); + } + if opcode == 0xA4 { + // LOG4 + return self.exec_log4(); + } + if opcode == 0xF0 { + // CREATE + return self.exec_create(); + } + if opcode == 0xF1 { + // CALL + return self.exec_call(); + } + if opcode == 0xF2 { + // CALLCODE + return self.exec_callcode(); + } + if opcode == 0xF3 { + // RETURN + return self.exec_return(); + } + if opcode == 0xF4 { + // DELEGATECALL + return self.exec_delegatecall(); + } + if opcode == 0xF5 { + // CREATE2 + return self.exec_create2(); + } + if opcode == 0xFA { + // STATICCALL + return self.exec_staticcall(); + } + if opcode == 0xFD { + // REVERT + return self.exec_revert(); + } + if opcode == 0xFE { + // INVALID + return self.exec_invalid(); + } + if opcode == 0xFF { + // SELFDESTRUCT + return self.exec_selfdestruct(); + } + // Unknown opcode + return Result::Err(EVMError::InvalidOpcode(opcode)); + } +} + +#[cfg(test)] +mod tests { + use contracts::kakarot_core::KakarotCore; + use core::num::traits::Zero; + use crate::model::{Account, Environment, Message}; + use crate::state::StateTrait; + use crate::test_utils::{dual_origin, test_dual_address}; + use super::EVMTrait; + use utils::constants::EMPTY_KECCAK; + use utils::eth_transaction::common::TxKind; + use utils::eth_transaction::legacy::TxLegacy; + use utils::eth_transaction::transaction::{Transaction, TransactionTrait}; + + fn setup() -> (KakarotCore::ContractState, Account, Environment) { + let state = KakarotCore::contract_state_for_testing(); + let sender_account = Account { + address: test_dual_address(), + nonce: 5, + balance: 1000000000000000000_u256, // 1 ETH + code: array![].span(), + code_hash: EMPTY_KECCAK, + selfdestruct: false, + is_created: true, + }; + let mut env = Environment { + origin: dual_origin(), + gas_price: 20000000000_u128, // 20 Gwei + chain_id: 1_u64, + prevrandao: 0_u256, + block_number: 12345_u64, + block_gas_limit: 30000000_u64, + block_timestamp: 1634567890_u64, + coinbase: 0x0000000000000000000000000000000000000000.try_into().unwrap(), + base_fee: 0_u64, + state: Default::default(), + }; + env.state.set_account(sender_account); + (state, sender_account, env) + } + + #[test] + fn test_prepare_message_create() { + let (mut state, sender_account, mut env) = setup(); + let tx = Transaction::Legacy( + TxLegacy { + chain_id: Option::Some(1), + nonce: 5, + gas_price: 20000000000_u128, // 20 Gwei + gas_limit: 1000000_u64, + to: TxKind::Create, + value: 0_u256, + input: array![0x60, 0x80, 0x60, 0x40, 0x52].span(), // Simple contract bytecode + } + ); + + let (message, is_deploy_tx) = state + .prepare_message(@tx, @sender_account, ref env, tx.gas_limit()); + + assert_eq!(is_deploy_tx, true); + assert_eq!(message.code, tx.input()); + assert_eq!( + message.target.evm, 0xf50541960eec6df5caa295adee1a1a95c3c3241c.try_into().unwrap() + ); // compute_contract_address('evm_address', 5); + assert_eq!(message.code_address, Zero::zero()); + assert_eq!(message.data, [].span()); + assert_eq!(message.gas_limit, tx.gas_limit()); + assert_eq!(message.depth, 0); + assert_eq!(message.should_transfer_value, true); + assert_eq!(message.value, 0_u256); + } + + #[test] + fn test_prepare_message_call() { + let (mut state, sender_account, mut env) = setup(); + let target_address = sender_account.address; + let tx = Transaction::Legacy( + TxLegacy { + chain_id: Option::Some(1), + nonce: 5, + gas_price: 20000000000_u128, // 20 Gwei + gas_limit: 1000000_u64, + to: TxKind::Call(target_address.evm), + value: 1000000000000000000_u256, // 1 ETH + input: array![0x12, 0x34, 0x56, 0x78].span(), // Some calldata + } + ); + + let (message, is_deploy_tx) = state + .prepare_message(@tx, @sender_account, ref env, tx.gas_limit()); + + assert_eq!(is_deploy_tx, false); + assert_eq!(message.target.evm, target_address.evm); + assert_eq!(message.code_address.evm, target_address.evm); + assert_eq!(message.code, sender_account.code); + assert_eq!(message.data, tx.input()); + assert_eq!(message.gas_limit, tx.gas_limit()); + assert_eq!(message.depth, 0); + assert_eq!(message.should_transfer_value, true); + assert_eq!(message.value, 1000000000000000000_u256); + } +} diff --git a/kakarot-ssj/crates/evm/src/lib.cairo b/kakarot-ssj/crates/evm/src/lib.cairo new file mode 100644 index 000000000..dc80be6c3 --- /dev/null +++ b/kakarot-ssj/crates/evm/src/lib.cairo @@ -0,0 +1,40 @@ +pub mod backend; +// Call opcodes helpers +mod call_helpers; + +// Create opcodes helpers +mod create_helpers; + +// Errors module +pub mod errors; + +// Gas module +pub mod gas; + +// instructions module +pub mod instructions; + +// interpreter module +mod interpreter; + +// Memory module +mod memory; + +// Data Models module +pub mod model; + +// instructions module +pub mod precompiles; + +// Stack module +mod stack; + +// Local state +pub mod state; + +#[cfg(target: 'test')] +pub mod test_data; + +#[cfg(target: 'test')] +pub mod test_utils; +pub use interpreter::EVMTrait; diff --git a/kakarot-ssj/crates/evm/src/memory.cairo b/kakarot-ssj/crates/evm/src/memory.cairo new file mode 100644 index 000000000..9659045c8 --- /dev/null +++ b/kakarot-ssj/crates/evm/src/memory.cairo @@ -0,0 +1,1199 @@ +use core::cmp::min; +use core::dict::{Felt252Dict, Felt252DictTrait}; +use core::integer::{u32_safe_divmod}; +use utils::constants::{ + POW_2_0, POW_2_8, POW_2_16, POW_2_24, POW_2_32, POW_2_40, POW_2_48, POW_2_56, POW_2_64, + POW_2_72, POW_2_80, POW_2_88, POW_2_96, POW_2_104, POW_2_112, POW_2_120, POW_256_16 +}; +use utils::traits::array::ArrayExtTrait; +use utils::traits::bytes::FromBytes; +use utils::{helpers, math::Bitshift}; + +#[derive(Destruct, Default)] +pub struct Memory { + items: Felt252Dict, + bytes_len: usize, +} + +pub trait MemoryTrait { + fn new() -> Memory; + fn size(self: @Memory) -> usize; + fn store(ref self: Memory, element: u256, offset: usize); + fn store_byte(ref self: Memory, value: u8, offset: usize); + fn store_n(ref self: Memory, elements: Span, offset: usize); + fn store_padded_segment(ref self: Memory, offset: usize, length: usize, source: Span); + fn ensure_length(ref self: Memory, length: usize); + fn load(ref self: Memory, offset: usize) -> u256; + fn load_n(ref self: Memory, elements_len: usize, ref elements: Array, offset: usize); + fn copy(ref self: Memory, size: usize, source_offset: usize, dest_offset: usize); +} + +impl MemoryImpl of MemoryTrait { + /// Initializes a new `Memory` instance. + #[inline(always)] + fn new() -> Memory { + Memory { items: Default::default(), bytes_len: Default::default() } + } + /// Returns the size of the memory. + #[inline(always)] + fn size(self: @Memory) -> usize { + *self.bytes_len + } + + /// Stores a 32-bytes element into the memory. + /// + /// If the offset is aligned with the 16-bytes words in memory, the element is stored directly. + /// Otherwise, the element is split and stored in multiple words. + #[inline(always)] + fn store(ref self: Memory, element: u256, offset: usize) { + let nonzero_16: NonZero = 16_u32.try_into().unwrap(); + + // Check alignment of offset to bytes16 chunks + let (chunk_index, offset_in_chunk) = u32_safe_divmod(offset, nonzero_16); + + if offset_in_chunk == 0 { + // Offset is aligned. This is the simplest and most efficient case, + // so we optimize for it. + self.items.store_u256(element, chunk_index); + return (); + } + + // Offset is misaligned. + // | W0 | W1 | w2 | + // | EL_H | EL_L | + // ^---^ + // |-- mask = 256 ** offset_in_chunk + + self.store_element(element, chunk_index, offset_in_chunk); + } + + + /// Stores a single byte into memory at a specified offset. + /// + /// # Arguments + /// + /// * `self` - A mutable reference to the `Memory` instance to store the byte in. + /// * `value` - The byte value to store in memory. + /// * `offset` - The offset within memory to store the byte at. + #[inline(always)] + fn store_byte(ref self: Memory, value: u8, offset: usize) { + let nonzero_16: NonZero = 16_u32.try_into().unwrap(); + + // Get offset's memory word index and left-based offset of byte in word. + let (chunk_index, left_offset) = u32_safe_divmod(offset, nonzero_16); + + // As the memory words are in big-endian order, we need to convert our left-based offset + // to a right-based one. + let right_offset = 15 - left_offset; + let mask: u128 = 0xFF * helpers::pow2(right_offset.into() * 8); + + // First erase byte value at offset, then set the new value using bitwise ops + let word: u128 = self.items.get(chunk_index.into()); + let new_word = (word & ~mask) | (value.into().shl(right_offset.into() * 8)); + self.items.insert(chunk_index.into(), new_word); + } + + + /// Stores a span of N bytes into memory at a specified offset. + /// + /// This function checks the alignment of the offset to 16-byte chunks, and handles the special + /// case where the bytes to be stored are within the same word in memory using the + /// `store_bytes_in_single_chunk` function. If the bytes span multiple words, the function + /// stores the first word using the `store_first_word` function, the aligned words using the + /// `store_aligned_words` function, and the last word using the `store_last_word` function. + /// + /// # Arguments + /// + /// * `self` - A mutable reference to the `Memory` instance to store the bytes in. + /// * `elements` - A span of bytes to store in memory. + /// * `offset` - The offset within memory to store the bytes at. + #[inline(always)] + fn store_n(ref self: Memory, elements: Span, offset: usize) { + if elements.len() == 0 { + return; + } + + let nonzero_16: NonZero = 16_u32.try_into().unwrap(); + + // Compute the offset inside the Memory, given its active segment, following the formula: + // index = offset + self.active_segment * 125000 + + // Check alignment of offset to bytes16 chunks. + let (initial_chunk, offset_in_chunk_i) = u32_safe_divmod(offset, nonzero_16); + let (final_chunk, mut offset_in_chunk_f) = u32_safe_divmod( + offset + elements.len() - 1, nonzero_16 + ); + offset_in_chunk_f += 1; + let mask_i: u256 = helpers::pow256_rev(offset_in_chunk_i); + let mask_f: u256 = helpers::pow256_rev(offset_in_chunk_f); + + // Special case: the bytes are stored within the same word. + if initial_chunk == final_chunk { + self.store_bytes_in_single_chunk(initial_chunk, mask_i, mask_f, elements); + return (); + } + + // Otherwise, fill first word. + self.store_first_word(initial_chunk, offset_in_chunk_i, mask_i, elements); + + // Store aligned bytes in [initial_chunk + 1, final_chunk - 1]. + // If initial_chunk + 1 == final_chunk, this will store nothing. + if initial_chunk + 1 != final_chunk { + let aligned_bytes = elements + .slice( + 16 - offset_in_chunk_i, + elements.len() - (16 - offset_in_chunk_i) - offset_in_chunk_f, + ); + self.store_aligned_words(initial_chunk + 1, aligned_bytes); + } + + let final_bytes = elements.slice(elements.len() - offset_in_chunk_f, offset_in_chunk_f); + self.store_last_word(final_chunk, offset_in_chunk_f, mask_f, final_bytes); + } + + /// Stores a span of N bytes into memory at a specified offset with padded with 0s to match the + /// size parameter. + /// + /// # Arguments + /// + /// * `self` - A mutable reference to the `Memory` instance to store the bytes in. + /// * `offset` - The offset within memory to store the bytes at. + /// * `length` - The length of bytes to store in memory. + /// * `source` - A span of bytes to store in memory. + #[inline(always)] + fn store_padded_segment(ref self: Memory, offset: usize, length: usize, source: Span) { + if length == 0 { + return; + } + + // For performance reasons, we don't add the zeros directly to the source, which would + // generate an implicit copy, which might be expensive if the source is big. + // Instead, we'll copy the source into memory, then create a new span containing the zeros. + // TODO: optimize this with a specific function + let mut slice_size = min(source.len(), length); + + let data_to_copy: Span = source.slice(0, slice_size); + self.store_n(data_to_copy, offset); + // For out of bound bytes, 0s will be copied. + if (length > source.len()) { + let mut out_of_bounds_bytes: Array = ArrayTrait::new(); + out_of_bounds_bytes.append_n(0, length - source.len()); + + self.store_n(out_of_bounds_bytes.span(), offset + slice_size); + } + } + + /// Ensures that the memory is at least `length` bytes long. Expands if necessary. + /// + /// # Arguments + /// + /// * `self` - A mutable reference to the `Memory` instance. + /// * `length` - The desired minimum length of the memory. + #[inline(always)] + fn ensure_length(ref self: Memory, length: usize) { + if self.size() < length { + self.expand(length - self.size()) + } else { + return; + } + } + + /// Expands memory if necessary, then load 32 bytes from it at the given offset. + /// + /// # Arguments + /// + /// * `self` - A mutable reference to the `Memory` instance. + /// * `offset` - The offset within memory to load from. + /// + /// # Returns + /// + /// * `u256` - The loaded value. + #[inline(always)] + fn load(ref self: Memory, offset: usize) -> u256 { + self.load_internal(offset) + } + + /// Expands memory if necessary, then load elements_len bytes from the memory at given offset + /// inside elements. + /// + /// # Arguments + /// + /// * `self` - A mutable reference to the `Memory` instance. + /// * `elements_len` - The number of bytes to load. + /// * `elements` - A mutable reference to the array to store the loaded bytes. + /// * `offset` - The offset within memory to load from. + #[inline(always)] + fn load_n(ref self: Memory, elements_len: usize, ref elements: Array, offset: usize) { + self.load_n_internal(elements_len, ref elements, offset); + } + + /// Copies a segment of memory from the source offset to the destination offset. + /// + /// # Arguments + /// + /// * `self` - A mutable reference to the `Memory` instance. + /// * `size` - The number of bytes to copy. + /// * `source_offset` - The offset to copy from. + /// * `dest_offset` - The offset to copy to. + #[inline(always)] + fn copy(ref self: Memory, size: usize, source_offset: usize, dest_offset: usize) { + let mut data: Array = Default::default(); + self.load_n(size, ref data, source_offset); + self.store_n(data.span(), dest_offset); + } +} + +#[generate_trait] +pub(crate) impl InternalMemoryMethods of InternalMemoryTrait { + /// Stores a `u256` element at a specified offset within a memory chunk. + /// + /// It first computes the + /// masks for the high and low parts of the element, then splits the `u256` element into high + /// and low parts, and computes the new words to write to memory using the masks and the high + /// and low parts of the element. Finally, it writes the new words to memory. + /// + /// # Arguments + /// + /// * `self` - A reference to the `Memory` instance to store the element in. + /// * `element` - The `u256` element to store in memory. + /// * `chunk_index` - The index of the memory chunk to start storing the element in. + /// * `offset_in_chunk` - The offset within the memory chunk to store the element at. + #[inline(always)] + fn store_element(ref self: Memory, element: u256, chunk_index: usize, offset_in_chunk: u32) { + let mask: u256 = helpers::pow256_rev(offset_in_chunk); + let mask_c: u256 = POW_256_16 / mask; + + // Split the 2 input bytes16 chunks at offset_in_chunk. + let nonzero_mask_c: NonZero = mask_c.try_into().unwrap(); + let (el_hh, el_hl) = DivRem::div_rem(element.high.into(), nonzero_mask_c); + let (el_lh, el_ll) = DivRem::div_rem(element.low.into(), nonzero_mask_c); + + // Read the words at chunk_index, chunk_index + 2. + let w0: u128 = self.items.get(chunk_index.into()); + let w2: u128 = self.items.get(chunk_index.into() + 2); + + // Compute the new words + let w0_h: u256 = (w0.into() / mask); + let w2_l: u256 = (w2.into() / mask); + + // We can convert them back to felt252 as we know they fit in one word. + let new_w0: u128 = (w0_h.into() * mask + el_hh).try_into().unwrap(); + let new_w1: u128 = (el_hl.into() * mask + el_lh).try_into().unwrap(); + let new_w2: u128 = (el_ll.into() * mask + w2_l).try_into().unwrap(); + + // Write the new words + self.items.insert(chunk_index.into(), new_w0); + self.items.insert(chunk_index.into() + 1, new_w1); + self.items.insert(chunk_index.into() + 2, new_w2); + } + + /// Stores a span of bytes into a single memory chunk. + /// + /// This function computes a new word to be stored by combining the existing word with the new + /// bytes. + /// + /// # Arguments + /// + /// * `self` - A reference to the `Memory` instance to store the bytes in. + /// * `initial_chunk` - The index of the initial memory chunk to store the bytes in. + /// * `mask_i` - The mask for the high part of the word. + /// * `mask_f` - The mask for the low part of the word. + /// * `elements` - A span of bytes to store in memory. + #[inline(always)] + fn store_bytes_in_single_chunk( + ref self: Memory, initial_chunk: usize, mask_i: u256, mask_f: u256, elements: Span + ) { + let word: u128 = self.items.get(initial_chunk.into()); + let nonzero_mask_i: NonZero = mask_i.try_into().unwrap(); + let nonzero_mask_f: NonZero = mask_f.try_into().unwrap(); + let (word_high, word_low) = DivRem::div_rem(word.into(), nonzero_mask_i); + let (_, word_low_l) = DivRem::div_rem(word_low, nonzero_mask_f); + let bytes_as_word: u128 = elements + .slice(0, elements.len()) + .from_be_bytes_partial() + .expect('Failed to parse word_low'); + let new_w: u128 = (word_high * mask_i + bytes_as_word.into() * mask_f + word_low_l) + .try_into() + .unwrap(); + self.items.insert(initial_chunk.into(), new_w); + } + + /// Stores a sequence of bytes into memory in chunks of 16 bytes each. + /// + /// It combines each byte in the span into a single 16-byte value in big-endian order, + /// and stores this value in memory. The function then updates + /// the chunk index and slices the byte span to the next 16 bytes until all chunks have been + /// stored. + /// + /// # Arguments + /// + /// * `self` - A mutable reference to the `Memory` instance to store the bytes in. + /// * `chunk_index` - The index of the chunk to start storing at. + /// * `elements` - A span of bytes to store in memory. + fn store_aligned_words(ref self: Memory, mut chunk_index: usize, mut elements: Span) { + while let Option::Some(words) = elements.multi_pop_front::<16>() { + let words = (*words).unbox().span(); + let current: u128 = ((*words[0]).into() * POW_2_120 + + (*words[1]).into() * POW_2_112 + + (*words[2]).into() * POW_2_104 + + (*words[3]).into() * POW_2_96 + + (*words[4]).into() * POW_2_88 + + (*words[5]).into() * POW_2_80 + + (*words[6]).into() * POW_2_72 + + (*words[7]).into() * POW_2_64 + + (*words[8]).into() * POW_2_56 + + (*words[9]).into() * POW_2_48 + + (*words[10]).into() * POW_2_40 + + (*words[11]).into() * POW_2_32 + + (*words[12]).into() * POW_2_24 + + (*words[13]).into() * POW_2_16 + + (*words[14]).into() * POW_2_8 + + (*words[15]).into() * POW_2_0); + + self.items.insert(chunk_index.into(), current); + chunk_index += 1; + } + } + + /// Retrieves aligned values from the memory structure, converts them back into a bytes array, + /// and appends them to the `elements` array. + /// + /// It iterates + /// over the chunks between the first and last chunk indices, retrieves the `u128` values from + /// the memory chunk, and splits them into big-endian byte arrays and concatenates using the + /// `split_word_128` function. + /// The results are concatenated to the `elements` array. + /// + /// # Arguments + /// + /// * `self` - A reference to the `Memory` instance to load the values from. + /// * `chunk_index` - The index of the first chunk to load from. + /// * `final_chunk` - The index of the last chunk to load from. + /// * `elements` - A reference to the byte array to append the loaded bytes to. + fn load_aligned_words( + ref self: Memory, mut chunk_index: usize, final_chunk: usize, ref elements: Array + ) { + for i in chunk_index + ..final_chunk { + let value = self.items.get(i.into()); + // Pushes 16 items to `elements` + helpers::split_word_128(value.into(), ref elements); + }; + } + + /// Loads a `u256` element from the memory chunk at a specified offset. + /// + /// If the offset is aligned with the memory words, the function returns the `u256` element at + /// the specified offset directly from the memory chunk. If the offset is misaligned, the + /// function computes the masks for the high and low parts of the first and last words of the + /// `u256` element, reads the words at the specified offset and the next two offsets, and + /// computes the high and low parts of the `u256` element using the masks and the read words. + /// The resulting `u256` element is then returned. + /// + /// # Arguments + /// + /// * `self` - A reference to the `Memory` instance to load the element from. + /// * `offset` - The offset within the memory chunk to load the element from. + /// + /// # Returns + /// + /// The `u256` element at the specified offset in the memory chunk. + #[inline(always)] + fn load_internal(ref self: Memory, offset: usize) -> u256 { + // Compute the offset inside the dict, given its active segment, following the formula: + // index = offset + self.active_segment * 125000 + let nonzero_16: NonZero = 16_u32.try_into().unwrap(); + let (chunk_index, offset_in_chunk) = u32_safe_divmod(offset, nonzero_16); + + if offset_in_chunk == 0 { + // Offset is aligned. This is the simplest and most efficient case, + // so we optimize for it. Note that no locals were allocated at all. + return self.items.read_u256(chunk_index); + } + + // Offset is misaligned. + // | W0 | W1 | w2 | + // | EL_H | EL_L | + // ^---^ + // |-- mask = 256 ** offset_in_chunk + + // Compute mask. + + let mask: u256 = helpers::pow256_rev(offset_in_chunk); + let mask_c: u256 = POW_256_16 / mask; + + // Read the words at chunk_index, +1, +2. + let w0: u128 = self.items.get(chunk_index.into()); + let w1: u128 = self.items.get(chunk_index.into() + 1); + let w2: u128 = self.items.get(chunk_index.into() + 2); + + // Compute element words + let w0_l: u256 = w0.into() % mask; + let nonzero_mask: NonZero = mask.try_into().unwrap(); + let (w1_h, w1_l): (u256, u256) = DivRem::div_rem(w1.into(), nonzero_mask); + let w2_h: u256 = w2.into() / mask; + let el_h: u128 = (w0_l * mask_c + w1_h).try_into().unwrap(); + let el_l: u128 = (w1_l * mask_c + w2_h).try_into().unwrap(); + + u256 { low: el_l, high: el_h } + } + + /// Loads a span of bytes from the memory chunk at a specified offset. + /// + /// This function loads the n bytes from the memory chunks, and splits the first word, + /// the aligned words, and the last word into bytes using the masks, and stored in + /// the parameter `elements` array. + /// + /// # Arguments + /// + /// * `self` - A reference to the `Memory` instance to load the bytes from. + /// * `elements_len` - The length of the array of bytes to load. + /// * `elements` - A reference to the array of bytes to load. + /// * `offset` - The chunk memory offset to load the bytes from. + #[inline(always)] + fn load_n_internal( + ref self: Memory, elements_len: usize, ref elements: Array, offset: usize + ) { + if elements_len == 0 { + return; + } + + let nonzero_16: NonZero = 16_u32.try_into().unwrap(); + + // Compute the offset inside the Memory, given its active segment, following the formula: + // index = offset + self.active_segment * 125000 + + // Check alignment of offset to bytes16 chunks. + let (initial_chunk, offset_in_chunk_i) = u32_safe_divmod(offset, nonzero_16); + let (final_chunk, mut offset_in_chunk_f) = u32_safe_divmod( + offset + elements_len - 1, nonzero_16 + ); + offset_in_chunk_f += 1; + let mask_i: u256 = helpers::pow256_rev(offset_in_chunk_i); + let mask_f: u256 = helpers::pow256_rev(offset_in_chunk_f); + + // Special case: within the same word. + if initial_chunk == final_chunk { + let w: u128 = self.items.get(initial_chunk.into()); + let w_l = w.into() % mask_i; + let w_lh = w_l / mask_f; + helpers::split_word(w_lh, elements_len, ref elements); + return; + } + + // Otherwise. + // Get first word. + let w_i = self.items.get(initial_chunk.into()); + let w_i_l = (w_i.into() % mask_i); + let _elements_first_word = helpers::split_word(w_i_l, 16 - offset_in_chunk_i, ref elements); + + // Get blocks. + self.load_aligned_words(initial_chunk + 1, final_chunk, ref elements); + + // Get last word. + let w_f = self.items.get(final_chunk.into()); + let w_f_h = w_f.into() / mask_f; + //TODO investigate why these two variables are not used + let _elements_last_word = helpers::split_word(w_f_h, offset_in_chunk_f, ref elements); + } + + + /// Expands the memory by a specified length + /// + /// The function updates the `bytes_len` field of the `Memory` instance to reflect the new size + /// of the memory chunk, + /// + /// # Arguments + /// + /// * `self` - A reference to the `Memory` instance to expand. + /// * `length` - The length to expand the memory chunk by. + #[inline(always)] + fn expand(ref self: Memory, length: usize) { + if (length == 0) { + return; + } + + let adjusted_length = (((length + 31) / 32) * 32); + let new_bytes_len = self.size() + adjusted_length; + + // Update memory size. + self.bytes_len = new_bytes_len; + } + + + /// Stores the first word of a span of bytes in the memory chunk at a specified offset. + /// The function computes the high part of the word by dividing the current word at the + /// specified offset by the mask, and computes the low part of the word by loading the remaining + /// bytes from the span of bytes. It then combines the high and low parts of the word using the + /// mask and stores the resulting word in the memory chunk at the specified offset. + /// + /// # Arguments + /// + /// * `self` - A reference to the `Memory` instance to store the word in. + /// * `chunk_index` - The index of the memory chunk to store the word in. + /// * `start_offset_in_chunk` - The offset within the chunk to store the word at. + /// * `start_mask` - The mask for the high part of the word. + /// * `elements` - A span of bytes to store. + /// + /// # Panics + /// + /// This function panics if the resulting word cannot be converted to a `u128` - which should + /// never happen. + #[inline(always)] + fn store_first_word( + ref self: Memory, + chunk_index: usize, + start_offset_in_chunk: usize, + start_mask: u256, + elements: Span + ) { + let word = self.items.get(chunk_index.into()); + let word_high = (word.into() / start_mask); + + let bytes_to_read = 16 - start_offset_in_chunk; + + let word_low: u128 = elements + .slice(0, bytes_to_read) + .from_be_bytes_partial() + .expect('Failed to parse word_low'); + + let new_word: u128 = (word_high * start_mask + word_low.into()).try_into().unwrap(); + self.items.insert(chunk_index.into(), new_word); + } + + /// Stores the last word of a span of bytes in the memory chunk at a specified offset. + /// The function computes the low part of the word by taking the current word at the specified + /// offset modulo the mask, and computes the high part of the word by loading the remaining + /// bytes from the span of bytes. It then combines the high and low parts of the word using the + /// mask and stores the resulting word in the memory chunk at the specified offset. + /// + /// # Arguments + /// + /// * `self` - A reference to the `Memory` instance to store the word in. + /// * `chunk_index` - The index of the memory chunk to store the word in. + /// * `end_offset_in_chunk` - The offset within the chunk to store the word at. + /// * `end_mask` - The mask for the low part of the word. + /// * `elements` - A span of bytes to store. + /// + /// # Panics + /// + /// This function panics if the resulting word cannot be converted to a `u128` - which should + /// never happen. + #[inline(always)] + fn store_last_word( + ref self: Memory, + chunk_index: usize, + end_offset_in_chunk: usize, + end_mask: u256, + elements: Span + ) { + let word = self.items.get(chunk_index.into()); + let word_low = (word.into() % end_mask); + + let low_bytes: u128 = elements + .slice(0, end_offset_in_chunk) + .from_be_bytes_partial() + .expect('Failed to parse low_bytes'); + let new_word: u128 = (low_bytes.into() * end_mask + word_low).try_into().unwrap(); + self.items.insert(chunk_index.into(), new_word); + } +} + +#[generate_trait] +impl Felt252DictExtensionImpl of Felt252DictExtension { + /// Stores a u256 element into the dictionary. + /// The element will be stored as two distinct u128 elements, + /// thus taking two indexes. + /// + /// # Arguments + /// * `self` - A mutable reference to the `Felt252Dict` instance. + /// * `element` - The element to store, of type `u256`. + /// * `index` - The `usize` index at which to store the element. + #[inline(always)] + fn store_u256(ref self: Felt252Dict, element: u256, index: usize) { + let index: felt252 = index.into(); + self.insert(index, element.high.into()); + self.insert(index + 1, element.low.into()); + } + + /// Reads a u256 element from the dictionary. + /// The element is stored as two distinct u128 elements, + /// thus we have to read the low and high parts and combine them. + /// The memory is big-endian organized, so the high part is stored first. + /// + /// # Arguments + /// * `self` - A mutable reference to the `Felt252Dict` instance. + /// * `index` - The `usize` index at which the element is stored. + /// + /// # Returns + /// * The element read, of type `u256`. + #[inline(always)] + fn read_u256(ref self: Felt252Dict, index: usize) -> u256 { + let index: felt252 = index.into(); + let high: u128 = self.get(index); + let low: u128 = self.get(index + 1); + u256 { low: low, high: high } + } +} + + +#[cfg(test)] +mod tests { + use core::num::traits::Bounded; + use crate::memory::{MemoryTrait, InternalMemoryTrait}; + use utils::constants::{POW_2_8, POW_2_56, POW_2_64, POW_2_120}; + use utils::{ + math::Exponentiation, math::WrappingExponentiation, helpers, traits::array::SpanExtTrait + }; + + + fn load_should_load_an_element_from_the_memory_with_offset_stored_with_store_n( + offset: usize, low: u128, high: u128 + ) { + // Given + let mut memory = MemoryTrait::new(); + + let value: u256 = u256 { low: low, high: high }; + + let bytes_array = helpers::u256_to_bytes_array(value); + + memory.store_n(bytes_array.span(), offset); + + // When + let mut elements: Array = Default::default(); + memory.load_n_internal(32, ref elements, offset); + + // Then + assert(elements == bytes_array, 'result not matching expected'); + } + + fn load_should_load_an_element_from_the_memory_with_offset_stored_with_store( + offset: usize, low: u128, high: u128, active_segment: usize, + ) { + // Given + let mut memory = MemoryTrait::new(); + + let value: u256 = u256 { low: low, high: high }; + + memory.store(value, offset); + + // When + let result: u256 = memory.load_internal(offset); + + // Then + assert(result == value, 'result not matching expected'); + } + + + #[test] + fn test_init_should_return_an_empty_memory() { + // When + let mut result = MemoryTrait::new(); + + // Then + assert(result.size() == 0, 'memory not empty'); + } + + #[test] + fn test_len_should_return_the_length_of_the_memory() { + // Given + let mut memory = MemoryTrait::new(); + + // When + let result = memory.size(); + + // Then + assert(result == 0, 'memory not empty'); + } + + #[test] + fn test_store_should_add_an_element_to_the_memory() { + // Given + let mut memory = MemoryTrait::new(); + + // When + let value: u256 = 1; + memory.store(value, 0); + + // Then + assert_eq!(memory.items.get(0), 0); + assert_eq!(memory.items.get(1), 1); + } + + #[test] + fn test_store_should_add_an_element_with_offset_to_the_memory() { + // Given + let mut memory = MemoryTrait::new(); + + // When + let value: u256 = 1; + let offset = 1; + memory.store(value, offset); + + // Then + let internal_index = offset / 2; + assert_eq!(memory.items.get(internal_index.into()), 0); + assert_eq!(memory.items.get(internal_index.into() + 1), 0); + assert_eq!(memory.items.get(internal_index.into() + 2), 0x01000000000000000000000000000000); + } + + #[test] + fn test_store_should_add_n_elements_to_the_memory() { + // Given + let mut memory = MemoryTrait::new(); + + // When + let value: u256 = 1; + let offset = 0; + let bytes_array = helpers::u256_to_bytes_array(value); + memory.store_n(bytes_array.span(), offset); + + // Then + let internal_index = offset / 2; + assert_eq!(memory.items.get(internal_index.into()), 0); + assert_eq!(memory.items.get(internal_index.into() + 1), 1); + } + + + #[test] + fn test_store_n_no_aligned_words() { + let mut memory = MemoryTrait::new(); + let byte_offset = 15; + memory.store_n([1, 2].span(), byte_offset); + + let internal_index = byte_offset / 16; + assert_eq!(memory.items.get(internal_index.into()), 0x01); + assert_eq!(memory.items.get(internal_index.into() + 1), 0x02000000000000000000000000000000); + } + + #[test] + fn test_store_n_2_aligned_words() { + let mut memory = MemoryTrait::new(); + let bytes_arr = [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35 + ].span(); + memory.store_n(bytes_arr, 15); + // value [1], will be stored in first word, values [2:34] will be stored in aligned words, + // value [35] will be stored in final word + + let mut stored_bytes = Default::default(); + memory.load_n_internal(35, ref stored_bytes, 15); + assert(stored_bytes.span() == bytes_arr, 'stored bytes not == expected'); + } + + #[test] + fn test_load_n_internal_same_word() { + let mut memory = MemoryTrait::new(); + memory.store(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0); + + let mut results: Array = ArrayTrait::new(); + memory.load_n_internal(16, ref results, 0); + + assert(results.len() == 16, 'error'); + for result in results { + assert(result == 0xFF, 'byte value loaded not correct'); + } + } + + + #[test] + fn test_load_should_load_an_element_from_the_memory() { + // Given + let mut memory = MemoryTrait::new(); + // In the memory, the following values are stored in the order 1, 2, 3, 4 (Big Endian) + let first_value: u256 = u256 { low: 2, high: 1 }; + let second_value = u256 { low: 4, high: 3 }; + let first_bytes_array = helpers::u256_to_bytes_array(first_value); + let second_bytes_array = helpers::u256_to_bytes_array(second_value); + memory.store_n(first_bytes_array.span(), 0); + + memory.store_n(second_bytes_array.span(), 32); + + // When + let result: u256 = memory.load_internal(0); + + // Then + assert(result == first_value, 'res not u256{2,1}'); + + // When + let result: u256 = memory.load_internal(32); + + // Then + assert(result == second_value, 'res not u256{4,3}'); + + // When + let result: u256 = memory.load_internal(16); + + // Then + assert(result == u256 { low: 3, high: 2 }, 'res not u256{3,2}'); + } + + #[test] + fn test_load_should_load_an_element_from_the_memory_with_offset_8() { + load_should_load_an_element_from_the_memory_with_offset_stored_with_store_n( + 8, 2 * POW_2_64, POW_2_64 + ); + } + #[test] + fn test_load_should_load_an_element_from_the_memory_with_offset_7() { + load_should_load_an_element_from_the_memory_with_offset_stored_with_store_n( + 7, 2 * POW_2_56, POW_2_56 + ); + } + #[test] + fn test_load_should_load_an_element_from_the_memory_with_offset_23() { + load_should_load_an_element_from_the_memory_with_offset_stored_with_store_n( + 23, 3 * POW_2_56, 2 * POW_2_56 + ); + } + + #[test] + fn test_load_should_load_an_element_from_the_memory_with_offset_33() { + load_should_load_an_element_from_the_memory_with_offset_stored_with_store_n( + 33, 4 * POW_2_8, 3 * POW_2_8 + ); + } + #[test] + fn test_load_should_load_an_element_from_the_memory_with_offset_63() { + load_should_load_an_element_from_the_memory_with_offset_stored_with_store_n( + 63, 0, 4 * POW_2_120 + ); + } + + #[test] + fn test_load_should_load_an_element_from_the_memory_with_offset_500() { + load_should_load_an_element_from_the_memory_with_offset_stored_with_store_n(500, 0, 0); + } + + + #[test] + fn test_expand__should_return_the_same_memory_and_no_cost() { + // Given + let mut memory = MemoryTrait::new(); + let value: u256 = 1; + let bytes_array = helpers::u256_to_bytes_array(value); + memory.bytes_len = 32; + memory.store_n(bytes_array.span(), 0); + + // When + memory.expand(0); + + // Then + assert(memory.size() == 32, 'memory should be 32bytes'); + let value = memory.load_internal(0); + assert(value == 1, 'value should be 1'); + } + + #[test] + fn test_expand__should_return_expanded_memory_by_one_word() { + // Given + let mut memory = MemoryTrait::new(); + + // When + memory.expand(1); + + // Then + assert_eq!(memory.size(), 32); + } + + #[test] + fn test_expand__should_return_expanded_memory_by_exactly_one_word_and_cost() { + // Given + let mut memory = MemoryTrait::new(); + + // When + memory.expand(32); + + // Then + assert_eq!(memory.size(), 32); + } + + #[test] + fn test_expand__should_return_expanded_memory_by_two_words_and_cost() { + // Given + let mut memory = MemoryTrait::new(); + + // When + memory.expand(33); + + // Then + assert_eq!(memory.size(), 64); + } + + #[test] + fn test_ensure_length__should_return_the_same_memory_and_no_cost() { + // Given + let mut memory = MemoryTrait::new(); + let value: u256 = 1; + let bytes_array = helpers::u256_to_bytes_array(value); + + memory.bytes_len = 32; + memory.store_n(bytes_array.span(), 0); + + // When + memory.ensure_length(1); + + // Then + assert_eq!(memory.size(), 32); + let value = memory.load_internal(0); + assert_eq!(value, 1); + } + + #[test] + fn test_ensure_length__should_return_expanded_memory_and_cost() { + // Given + let mut memory = MemoryTrait::new(); + let value: u256 = 1; + let bytes_array = helpers::u256_to_bytes_array(value); + + memory.bytes_len = 32; + memory.store_n(bytes_array.span(), 0); + + // When + memory.ensure_length(33); + + // Then + assert_eq!(memory.size(), 64); + let value = memory.load_internal(0); + assert_eq!(value, 1); + } + + #[test] + fn test_load_should_return_element() { + // Given + let mut memory = MemoryTrait::new(); + let value: u256 = 1; + let bytes_array = helpers::u256_to_bytes_array(value); + memory.bytes_len = 32; + memory.store_n(bytes_array.span(), 0); + + // When + let value = memory.load(32); + + // Then + assert_eq!(value, 0); + } + + #[test] + fn test_store_padded_segment_should_not_change_the_memory() { + // Given + let mut memory = MemoryTrait::new(); + + // When + let bytes = [1, 2, 3, 4, 5].span(); + memory.store_padded_segment(0, 0, bytes); + + // Then + let item_0 = memory.items.get(0); + let item_1 = memory.items.get(1); + assert_eq!(item_0, 0); + assert_eq!(item_1, 0); + } + + #[test] + fn test_store_padded_segment_should_write_to_memory() { + // Given + let mut memory = MemoryTrait::new(); + + // When + let bytes = [].span(); + memory.store_padded_segment(10, 10, bytes); + + // Then + let word = memory.load(10); + assert_eq!(word, 0); + } + + #[test] + fn test_store_padded_segment_should_add_n_elements_to_the_memory() { + // Given + let mut memory = MemoryTrait::new(); + + // When + let bytes = [1, 2, 3, 4, 5].span(); + memory.store_padded_segment(0, 5, bytes); + + // Then + let first_word = memory.load_internal(0); + assert( + first_word == 0x0102030405000000000000000000000000000000000000000000000000000000, + 'Wrong memory value' + ); + } + + #[test] + fn test_store_padded_segment_should_add_n_elements_padded_to_the_memory() { + // Given + let mut memory = MemoryTrait::new(); + + // Memory initialization with a value to verify that if the size is out of the bound bytes, + // 0's have been copied. + // Otherwise, the memory value would be 0, and we wouldn't be able to check it. + memory.store(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0); + + // When + let bytes = [1, 2, 3, 4, 5].span(); + memory.store_padded_segment(0, 10, bytes); + + // Then + let first_word = memory.load_internal(0); + assert( + first_word == 0x01020304050000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, + 'Wrong memory value' + ); + } + + #[test] + fn test_store_padded_segment_should_add_n_elements_padded_with_offset_to_the_memory() { + // Given + let mut memory = MemoryTrait::new(); + + // Memory initialization with a value to verify that if the size is out of the bound bytes, + // 0's have been copied. + // Otherwise, the memory value would be 0, and we wouldn't be able to check it. + memory.store(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0); + + // When + let bytes = [1, 2, 3, 4, 5].span(); + memory.store_padded_segment(5, 10, bytes); + + let first_word = memory.load_internal(0); + assert( + first_word == 0xFFFFFFFFFF01020304050000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, + 'Wrong memory value' + ); + } + + #[test] + fn test_store_padded_segment_should_add_n_elements_padded_with_offset_between_two_words_to_the_memory() { + // Given + let mut memory = MemoryTrait::new(); + + // Memory initialization with a value to verify that if the size is out of the bound bytes, + // 0's have been copied. + // Otherwise, the memory value would be 0, and we wouldn't be able to check it. + memory.store(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0); + memory.store(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 32); + + // When + let bytes = [1, 2, 3, 4, 5].span(); + memory.store_padded_segment(30, 10, bytes); + + // Then + let first_word = memory.load_internal(0); + assert( + first_word == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0102, + 'Wrong memory value' + ); + + let second_word = memory.load_internal(32); + assert( + second_word == 0x0304050000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, + 'Wrong memory value' + ); + } + + + #[test] + fn test_store_byte_should_store_byte_at_offset() { + // Given + let mut memory = MemoryTrait::new(); + + // When + memory.store_byte(0x01, 15); + + // Then + assert(memory.items[0] == 0x01, 'Wrong value for word 0'); + assert(memory.items[1] == 0x00, 'Wrong value for word 1'); + } + #[test] + fn test_store_byte_should_store_byte_at_offset_2() { + // Given + let mut memory = MemoryTrait::new(); + + // When + memory.store_byte(0xff, 14); + + // Then + assert(memory.items[0] == 0xff00, 'Wrong value for word 0'); + assert(memory.items[1] == 0x00, 'Wrong value for word 1'); + } + + #[test] + fn test_store_byte_should_store_byte_at_offset_in_existing_word() { + // Given + let mut memory = MemoryTrait::new(); + memory.items.insert(0, 0xFFFF); // Set the first word in memory to 0xFFFF; + memory.items.insert(1, 0xFFFF); + + // When + memory.store_byte(0x01, 30); + + // Then + assert(memory.items[0] == 0xFFFF, 'Wrong value for word 0'); + assert(memory.items[1] == 0x01FF, 'Wrong value for word 1'); + } + + #[test] + fn test_store_byte_should_store_byte_at_offset_in_new_word() { + // Given + let mut memory = MemoryTrait::new(); + + // When + memory.store_byte(0x01, 32); + + // Then + assert(memory.items[0] == 0x0, 'Wrong value for word 0'); + assert(memory.items[1] == 0x0, 'Wrong value for word 1'); + assert(memory.items[2] == 0x01000000000000000000000000000000, 'Wrong value for word 2'); + } + + #[test] + fn test_store_byte_should_store_byte_at_offset_in_new_word_with_existing_value_in_previous_word() { + // Given + let mut memory = MemoryTrait::new(); + memory.items.insert(0, 0x0100); + memory.items.insert(1, 0xffffffffffffffffffffffffffffffff); + + // When + memory.store_byte(0xAB, 17); + + // Then + assert(memory.items[0] == 0x0100, 'Wrong value in word 0'); + assert(memory.items[1] == 0xffABffffffffffffffffffffffffffff, 'Wrong value in word 1'); + } +} diff --git a/kakarot-ssj/crates/evm/src/model.cairo b/kakarot-ssj/crates/evm/src/model.cairo new file mode 100644 index 000000000..fb217dfae --- /dev/null +++ b/kakarot-ssj/crates/evm/src/model.cairo @@ -0,0 +1,365 @@ +pub mod account; +pub mod vm; +pub use account::{Account, AccountTrait}; +pub use vm::{VM, VMTrait}; +use contracts::kakarot_core::{KakarotCore, IKakarotCore}; +use core::num::traits::{CheckedSub, Zero}; +use core::starknet::{EthAddress, ContractAddress}; +use crate::errors::EVMError; +use crate::precompiles::{ + FIRST_ROLLUP_PRECOMPILE_ADDRESS, FIRST_ETHEREUM_PRECOMPILE_ADDRESS, + LAST_ETHEREUM_PRECOMPILE_ADDRESS +}; +use crate::state::State; +use utils::fmt::{TSpanSetDebug}; +use utils::set::SpanSet; +use utils::traits::{EthAddressDefault, ContractAddressDefault, SpanDefault}; + +/// Represents the execution environment for EVM transactions. +#[derive(Destruct, Default)] +pub struct Environment { + /// The origin address of the transaction. + pub origin: Address, + /// The gas price for the transaction. + pub gas_price: u128, + /// The chain ID of the network. + pub chain_id: u64, + /// The previous RANDAO value. + pub prevrandao: u256, + /// The current block number. + pub block_number: u64, + /// The gas limit for the current block. + pub block_gas_limit: u64, + /// The timestamp of the current block. + pub block_timestamp: u64, + /// The address of the coinbase. + pub coinbase: EthAddress, + /// The base fee for the current block. + pub base_fee: u64, + /// The state of the EVM. + pub state: State +} + +/// Represents a message call in the EVM. +#[derive(Copy, Drop, Default, PartialEq, Debug)] +pub struct Message { + /// The address of the caller. + pub caller: Address, + /// The target address of the call. + pub target: Address, + /// The gas limit for the call. + pub gas_limit: u64, + /// The data passed to the call. + pub data: Span, + /// The code of the contract being called. + pub code: Span, + /// The address of the code being executed. + pub code_address: Address, + /// The value sent with the call. + pub value: u256, + /// Whether the value should be transferred. + pub should_transfer_value: bool, + /// The depth of the call stack. + pub depth: usize, + /// Whether the call is read-only. + pub read_only: bool, + /// Set of accessed addresses during execution. + pub accessed_addresses: SpanSet, + /// Set of accessed storage keys during execution. + pub accessed_storage_keys: SpanSet<(EthAddress, u256)>, +} + +/// Represents the result of an EVM execution. +#[derive(Drop, Debug)] +pub struct ExecutionResult { + /// The status of the execution result. + pub status: ExecutionResultStatus, + /// The return data of the execution. + pub return_data: Span, + /// The remaining gas after execution. + pub gas_left: u64, + /// Set of accessed addresses during execution. + pub accessed_addresses: SpanSet, + /// Set of accessed storage keys during execution. + pub accessed_storage_keys: SpanSet<(EthAddress, u256)>, + /// The amount of gas refunded during execution. + pub gas_refund: u64, +} + +/// Represents the status of an EVM execution result. +#[derive(Copy, Drop, PartialEq, Debug)] +pub enum ExecutionResultStatus { + /// The execution was successful. + Success, + /// The execution was reverted. + Revert, + /// An exception occurred during execution. + Exception, +} + +#[generate_trait] +pub impl ExecutionResultImpl of ExecutionResultTrait { + /// Creates an `ExecutionResult` for an exceptional failure. + /// + /// # Arguments + /// + /// * `error` - The error message as a span of bytes. + /// * `accessed_addresses` - Set of accessed addresses during execution. + /// * `accessed_storage_keys` - Set of accessed storage keys during execution. + /// + /// # Returns + /// + /// An `ExecutionResult` with the Exception status and provided data. + fn exceptional_failure( + error: Span, + accessed_addresses: SpanSet, + accessed_storage_keys: SpanSet<(EthAddress, u256)> + ) -> ExecutionResult { + ExecutionResult { + status: ExecutionResultStatus::Exception, + return_data: error, + gas_left: 0, + accessed_addresses, + accessed_storage_keys, + gas_refund: 0, + } + } + + /// Decrements the gas_left field of the current execution context by the value amount. + /// + /// # Arguments + /// + /// * `value` - The amount of gas to charge. + /// + /// # Returns + /// + /// `Ok(())` if successful, or `Err(EVMError::OutOfGas)` if there's not enough gas. + #[inline(always)] + fn charge_gas(ref self: ExecutionResult, value: u64) -> Result<(), EVMError> { + self.gas_left = self.gas_left.checked_sub(value).ok_or(EVMError::OutOfGas)?; + Result::Ok(()) + } + + /// Checks if the execution result status is Success. + /// + /// # Returns + /// + /// `true` if the status is Success, `false` otherwise. + fn is_success(self: @ExecutionResult) -> bool { + *self.status == ExecutionResultStatus::Success + } + + /// Checks if the execution result status is Exception. + /// + /// # Returns + /// + /// `true` if the status is Exception, `false` otherwise. + fn is_exception(self: @ExecutionResult) -> bool { + *self.status == ExecutionResultStatus::Exception + } + + /// Checks if the execution result status is Revert. + /// + /// # Returns + /// + /// `true` if the status is Revert, `false` otherwise. + fn is_revert(self: @ExecutionResult) -> bool { + *self.status == ExecutionResultStatus::Revert + } +} + +/// Represents a summary of an EVM execution. +#[derive(Destruct)] +pub struct ExecutionSummary { + /// The status of the execution result. + pub status: ExecutionResultStatus, + /// The return data of the execution. + pub return_data: Span, + /// The remaining gas after execution. + pub gas_left: u64, + /// The state of the EVM after execution. + pub state: State, + /// The amount of gas refunded during execution. + pub gas_refund: u64 +} + +/// Represents the result of an EVM transaction. +pub struct TransactionResult { + /// Whether the transaction was successful. + pub success: bool, + /// The return data of the transaction. + pub return_data: Span, + /// The amount of gas used by the transaction. + pub gas_used: u64, + /// The state of the EVM after the transaction. + pub state: State +} + +#[generate_trait] +pub impl TransactionResultImpl of TransactionResultTrait { + /// Creates a `TransactionResult` for an exceptional failure. + /// + /// # Arguments + /// + /// * `error` - The error message as a span of bytes. + /// * `gas_used` - The amount of gas used during the transaction. + /// + /// # Returns + /// + /// A `TransactionResult` with failure status and provided data. + fn exceptional_failure(error: Span, gas_used: u64) -> TransactionResult { + TransactionResult { + success: false, return_data: error, gas_used, state: Default::default() + } + } +} + +/// Represents an EVM event. +#[derive(Drop, Clone, Default, PartialEq)] +pub struct Event { + /// The keys of the event. + pub keys: Array, + /// The data of the event. + pub data: Array, +} + +/// Represents an address in both EVM and Starknet formats. +#[derive(Copy, Drop, PartialEq, Default, Debug)] +pub struct Address { + /// The EVM address. + pub evm: EthAddress, + /// The Starknet address. + pub starknet: ContractAddress, +} + +impl ZeroAddress of core::num::traits::Zero
{ + fn zero() -> Address { + Address { evm: Zero::zero(), starknet: Zero::zero(), } + } + fn is_zero(self: @Address) -> bool { + self.evm.is_zero() && self.starknet.is_zero() + } + fn is_non_zero(self: @Address) -> bool { + !self.is_zero() + } +} + +#[generate_trait] +pub impl AddressImpl of AddressTrait { + /// Checks if the EVM address is deployed. + /// + /// # Returns + /// + /// `true` if the address is deployed, `false` otherwise. + fn is_deployed(self: @EthAddress) -> bool { + let mut kakarot_state = KakarotCore::unsafe_new_contract_state(); + let address = kakarot_state.address_registry(*self); + return address.is_non_zero(); + } + + /// Checks if the address is a precompile for a call-family opcode. + /// + /// # Returns + /// + /// `true` if the address is a precompile, `false` otherwise. + fn is_precompile(self: EthAddress) -> bool { + let self: felt252 = self.into(); + return self != 0x00 + && (FIRST_ETHEREUM_PRECOMPILE_ADDRESS <= self.into() + && self.into() <= LAST_ETHEREUM_PRECOMPILE_ADDRESS) + || self.into() == FIRST_ROLLUP_PRECOMPILE_ADDRESS; + } +} + +/// Represents a native token transfer to be made when finalizing a transaction. +#[derive(Copy, Drop, PartialEq, Debug)] +pub struct Transfer { + /// The sender of the transfer. + pub sender: Address, + /// The recipient of the transfer. + pub recipient: Address, + /// The amount of tokens to transfer. + pub amount: u256 +} + +#[cfg(test)] +mod tests { + mod test_is_deployed { + use crate::model::AddressTrait; + use crate::test_utils; + use snforge_std::test_address; + use utils::helpers::compute_starknet_address; + + + #[test] + fn test_is_deployed_returns_true_if_in_registry() { + // Given + test_utils::setup_test_environment(); + let starknet_address = compute_starknet_address( + test_address(), test_utils::evm_address(), test_utils::uninitialized_account() + ); + test_utils::register_account(test_utils::evm_address(), starknet_address); + + // When + let is_deployed = test_utils::evm_address().is_deployed(); + + // Then + assert!(is_deployed); + } + + #[test] + fn test_is_deployed_undeployed() { + // Given + test_utils::setup_test_environment(); + + // When + let is_deployed = test_utils::evm_address().is_deployed(); + + // Then + assert!(!is_deployed); + } + } + mod test_is_precompile { + use core::starknet::EthAddress; + use crate::model::{AddressTrait}; + #[test] + fn test_is_precompile() { + // Given + let valid_precompiles = array![ + 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x0a, 0x100 + ]; + + //When + for el in valid_precompiles { + let evm_address: EthAddress = (el).try_into().unwrap(); + //Then + assert_eq!(true, evm_address.is_precompile()); + }; + } + + #[test] + fn test_is_precompile_zero() { + // Given + let evm_address: EthAddress = 0x0.try_into().unwrap(); + + // When + let is_precompile = evm_address.is_precompile(); + + // Then + assert_eq!(false, is_precompile); + } + + #[test] + fn test_is_not_precompile() { + // Given + let not_valid_precompiles = array![0xb, 0xc, 0xd, 0xe, 0xf, 0x99]; + + //When + for el in not_valid_precompiles { + let evm_address: EthAddress = (el).try_into().unwrap(); + //Then + assert_eq!(false, evm_address.is_precompile()); + }; + } + } +} diff --git a/kakarot-ssj/crates/evm/src/model/account.cairo b/kakarot-ssj/crates/evm/src/model/account.cairo new file mode 100644 index 000000000..f61590923 --- /dev/null +++ b/kakarot-ssj/crates/evm/src/model/account.cairo @@ -0,0 +1,467 @@ +use contracts::account_contract::{IAccountDispatcher, IAccountDispatcherTrait}; +use contracts::kakarot_core::{KakarotCore, IKakarotCore}; +use core::dict::{Felt252Dict, Felt252DictTrait}; +use core::num::traits::Zero; +use core::starknet::{ContractAddress, EthAddress}; +use crate::backend::starknet_backend::fetch_balance; +use crate::model::Address; +use utils::constants::EMPTY_KECCAK; +use utils::traits::bytes::U8SpanExTrait; + +#[derive(Drop)] +struct AccountBuilder { + account: Account +} + +#[generate_trait] +impl AccountBuilderImpl of AccountBuilderTrait { + fn new(address: Address) -> AccountBuilder { + AccountBuilder { + account: Account { + address: address, + code: [].span(), + code_hash: EMPTY_KECCAK, + nonce: 0, + balance: 0, + selfdestruct: false, + is_created: false + } + } + } + + #[inline(always)] + fn fetch_balance(mut self: AccountBuilder) -> AccountBuilder { + self.account.balance = fetch_balance(@self.account.address); + self + } + + #[inline(always)] + fn fetch_nonce(mut self: AccountBuilder) -> AccountBuilder { + let account = IAccountDispatcher { contract_address: self.account.address.starknet }; + self.account.nonce = account.get_nonce(); + self + } + + /// Loads the bytecode of a ContractAccount from Kakarot Core's contract storage into a + /// Span. + /// # Arguments + /// * `self` - The address of the Contract Account to load the bytecode from + /// # Returns + /// * The bytecode of the Contract Account as a ByteArray + #[inline(always)] + fn fetch_bytecode(mut self: AccountBuilder) -> AccountBuilder { + let account = IAccountDispatcher { contract_address: self.account.address.starknet }; + let bytecode = account.bytecode(); + self.account.code = bytecode; + self + } + + #[inline(always)] + fn fetch_code_hash(mut self: AccountBuilder) -> AccountBuilder { + let account = IAccountDispatcher { contract_address: self.account.address.starknet }; + self.account.code_hash = account.get_code_hash(); + self + } + + #[inline(always)] + fn build(self: AccountBuilder) -> Account { + self.account + } +} + +#[derive(Copy, Drop, PartialEq, Debug)] +pub struct Account { + pub address: Address, + pub code: Span, + pub code_hash: u256, + pub nonce: u64, + pub balance: u256, + pub selfdestruct: bool, + pub is_created: bool, +} + +#[generate_trait] +pub impl AccountImpl of AccountTrait { + /// Fetches an account from Starknet + /// An non-deployed account is just an empty account. + /// # Arguments + /// * `address` - The address of the account to fetch` + /// + /// # Returns + /// The fetched account if it existed, otherwise a new empty account. + fn fetch_or_create(evm_address: EthAddress) -> Account { + let maybe_acc = Self::fetch(evm_address); + + match maybe_acc { + Option::Some(account) => account, + Option::None => { + let kakarot_state = KakarotCore::unsafe_new_contract_state(); + let starknet_address = kakarot_state.compute_starknet_address(evm_address); + // If no account exists at `address`, then we are trying to + // access an undeployed account. We create an + // empty account with the correct address, fetch the balance, and return it. + AccountBuilderTrait::new(Address { starknet: starknet_address, evm: evm_address }) + .fetch_balance() + .build() + } + } + } + + /// Fetches an account from Starknet + /// + /// # Arguments + /// * `address` - The address of the account to fetch` + /// + /// # Returns + /// The fetched account if it existed, otherwise `None`. + fn fetch(evm_address: EthAddress) -> Option { + let mut kakarot_state = KakarotCore::unsafe_new_contract_state(); + let starknet_address = kakarot_state.address_registry(evm_address); + if starknet_address.is_zero() { + return Option::None; + } + let address = Address { starknet: starknet_address, evm: evm_address }; + Option::Some( + AccountBuilderTrait::new(address) + .fetch_nonce() + .fetch_bytecode() + .fetch_balance() + .fetch_code_hash() + .build() + ) + } + + + /// Returns whether an account exists at the given address by checking + /// whether it has code or a nonce. + /// + /// # Arguments + /// + /// * `account` - The instance of the account to check. + /// + /// # Returns + /// + /// `true` if an account exists at this address (has code or nonce), `false` otherwise. + #[inline(always)] + fn has_code_or_nonce(self: @Account) -> bool { + return !(*self.code).is_empty() || *self.nonce != 0; + } + + #[inline(always)] + fn is_created(self: @Account) -> bool { + *self.is_created + } + + #[inline(always)] + fn set_created(ref self: Account, is_created: bool) { + self.is_created = is_created; + } + + #[inline(always)] + fn balance(self: @Account) -> u256 { + *self.balance + } + + #[inline(always)] + fn set_balance(ref self: Account, value: u256) { + self.balance = value; + } + + #[inline(always)] + fn address(self: @Account) -> Address { + *self.address + } + + #[inline(always)] + fn evm_address(self: @Account) -> EthAddress { + *self.address.evm + } + + #[inline(always)] + fn starknet_address(self: @Account) -> ContractAddress { + *self.address.starknet + } + + /// Returns the bytecode of the EVM account (EOA or CA) + #[inline(always)] + fn bytecode(self: @Account) -> Span { + *self.code + } + + #[inline(always)] + fn code_hash(self: @Account) -> u256 { + *self.code_hash + } + + + /// Sets the nonce of the Account + /// # Arguments + /// * `self` The Account to set the nonce on + /// * `nonce` The new nonce + #[inline(always)] + fn set_nonce(ref self: Account, nonce: u64) { + self.nonce = nonce; + } + + #[inline(always)] + fn nonce(self: @Account) -> u64 { + *self.nonce + } + + /// Sets the code of the Account + /// Also sets the code hash to be synced with the code + /// # Arguments + /// * `self` The Account to set the code on + /// * `code` The new code + #[inline(always)] + fn set_code(ref self: Account, code: Span) { + self.code = code; + if code.is_empty() { + self.code_hash = EMPTY_KECCAK; + return; + } + let hash = code.compute_keccak256_hash(); + self.code_hash = hash; + } + + /// Registers an account for SELFDESTRUCT + /// This will cause the account to be erased at the end of the transaction + #[inline(always)] + fn selfdestruct(ref self: Account) { + self.selfdestruct = true; + } + + /// Returns whether the account is registered for SELFDESTRUCT + /// `true` means that the account will be erased at the end of the transaction + #[inline(always)] + fn is_selfdestruct(self: @Account) -> bool { + *self.selfdestruct + } + + /// Initializes a dictionary of valid jump destinations in EVM bytecode. + /// + /// This function iterates over the bytecode from the current index 'i'. + /// If the opcode at the current index is between 0x5f and 0x7f (PUSHN opcodes) (inclusive), + /// it skips the next 'n_args' opcodes, where 'n_args' is the opcode minus 0x5f. + /// If the opcode is 0x5b (JUMPDEST), it marks the current index as a valid jump destination. + /// It continues by jumping back to the body flag until it has processed the entire bytecode. + /// + /// # Arguments + /// * `bytecode` The bytecode to analyze + /// + /// # Returns + /// A dictionary of valid jump destinations in the bytecode + fn get_jumpdests(mut bytecode: Span) -> Felt252Dict { + let mut jumpdests: Felt252Dict = Default::default(); + let mut i: usize = 0; + while i < bytecode.len() { + let opcode = *bytecode[i]; + // checking for PUSH opcode family + if opcode >= 0x5f && opcode <= 0x7f { + let n_args = opcode.into() - 0x5f; + i += n_args + 1; + continue; + } + + if opcode == 0x5b { + jumpdests.insert(i.into(), true); + } + + i += 1; + }; + jumpdests + } +} + +#[cfg(test)] +mod tests { + mod test_has_code_or_nonce { + use crate::model::account::{Account, AccountTrait, Address}; + use utils::constants::EMPTY_KECCAK; + use utils::traits::bytes::U8SpanExTrait; + + #[test] + fn test_should_return_false_when_empty() { + let account = Account { + address: Address { evm: 1.try_into().unwrap(), starknet: 1.try_into().unwrap() }, + nonce: 0, + code: [].span(), + code_hash: EMPTY_KECCAK, + balance: 0, + selfdestruct: false, + is_created: false, + }; + + assert!(!account.has_code_or_nonce()); + } + + #[test] + fn test_should_return_true_when_code() { + let bytecode = [0x5b].span(); + let code_hash = bytecode.compute_keccak256_hash(); + let account = Account { + address: Address { evm: 1.try_into().unwrap(), starknet: 1.try_into().unwrap() }, + nonce: 1, + code: bytecode, + code_hash: code_hash, + balance: 0, + selfdestruct: false, + is_created: false, + }; + + assert!(account.has_code_or_nonce()); + } + + #[test] + fn test_should_return_true_when_nonce() { + let account = Account { + address: Address { evm: 1.try_into().unwrap(), starknet: 1.try_into().unwrap() }, + nonce: 1, + code: [].span(), + code_hash: EMPTY_KECCAK, + balance: 0, + selfdestruct: false, + is_created: false, + }; + + assert!(account.has_code_or_nonce()); + } + } + + mod test_fetch { + use crate::model::account::{Account, AccountTrait, Address}; + use crate::test_utils::{ + register_account, setup_test_environment, uninitialized_account, evm_address, + native_token, + }; + use snforge_std::{test_address, start_mock_call}; + use snforge_utils::snforge_utils::assert_called; + use utils::constants::EMPTY_KECCAK; + use utils::helpers::compute_starknet_address; + + #[test] + fn test_should_fetch_data_from_storage_if_registered() { + // Given + setup_test_environment(); + let starknet_address = compute_starknet_address( + test_address(), evm_address(), uninitialized_account() + ); + register_account(evm_address(), starknet_address); + + let expected = Account { + address: Address { evm: evm_address(), starknet: starknet_address }, + nonce: 1, + code: [].span(), + code_hash: EMPTY_KECCAK, + balance: 100, + selfdestruct: false, + is_created: false, + }; + + // When + start_mock_call::(native_token(), selector!("balanceOf"), 100); + start_mock_call::(starknet_address, selector!("get_nonce"), 1); + start_mock_call::>(starknet_address, selector!("bytecode"), [].span()); + start_mock_call::(starknet_address, selector!("get_code_hash"), EMPTY_KECCAK); + let account = AccountTrait::fetch(evm_address()).expect('Account should exist'); + + // Then + assert_eq!(account, expected); + assert_called(starknet_address, selector!("get_nonce")); + assert_called(starknet_address, selector!("bytecode")); + assert_called(starknet_address, selector!("get_code_hash")); + //TODO(starknet-foundry): we mocked the balanceOf call, but we should also check if it + //was called with the right data + assert_called(native_token(), selector!("balanceOf")); + } + + #[test] + fn test_should_return_none_if_not_registered() { + // Given + setup_test_environment(); + let _starknet_address = compute_starknet_address( + test_address(), evm_address(), uninitialized_account() + ); + + assert!(AccountTrait::fetch(evm_address()).is_none()); + } + } + + mod test_fetch_or_create { + use crate::model::account::{Account, AccountTrait, Address}; + use crate::test_utils::{ + register_account, setup_test_environment, uninitialized_account, evm_address, + native_token, + }; + use snforge_std::{test_address, start_mock_call}; + use snforge_utils::snforge_utils::assert_called; + use utils::constants::EMPTY_KECCAK; + use utils::helpers::compute_starknet_address; + + #[test] + fn test_should_fetch_data_from_storage_if_registered() { + // Given + setup_test_environment(); + let starknet_address = compute_starknet_address( + test_address(), evm_address(), uninitialized_account() + ); + register_account(evm_address(), starknet_address); + + let expected = Account { + address: Address { evm: evm_address(), starknet: starknet_address }, + nonce: 1, + code: [].span(), + code_hash: EMPTY_KECCAK, + balance: 100, + selfdestruct: false, + is_created: false, + }; + + // When + start_mock_call::(native_token(), selector!("balanceOf"), 100); + start_mock_call::(starknet_address, selector!("get_nonce"), 1); + start_mock_call::>(starknet_address, selector!("bytecode"), [].span()); + start_mock_call::(starknet_address, selector!("get_code_hash"), EMPTY_KECCAK); + let account = AccountTrait::fetch_or_create(evm_address()); + + // Then + assert_eq!(account, expected); + assert_called(starknet_address, selector!("get_nonce")); + assert_called(starknet_address, selector!("bytecode")); + assert_called(starknet_address, selector!("get_code_hash")); + //TODO(starknet-foundry): we mocked the balanceOf call, but we should also check if it + //was called with the right data + assert_called(native_token(), selector!("balanceOf")); + } + + #[test] + fn test_should_create_new_account_with_starknet_balance_if_not_registered() { + // Given + setup_test_environment(); + let starknet_address = compute_starknet_address( + test_address(), evm_address(), uninitialized_account() + ); + + let expected = Account { + address: Address { evm: evm_address(), starknet: starknet_address }, + nonce: 0, + code: [].span(), + code_hash: EMPTY_KECCAK, + balance: 50, + selfdestruct: false, + is_created: false, + }; + + // When + start_mock_call::(native_token(), selector!("balanceOf"), 50); + let account = AccountTrait::fetch_or_create(evm_address()); + + // Then + assert_eq!(account, expected); + //TODO(starknet-foundry): we mocked the balanceOf call, but we should also check if it + //was called with the right data + assert_called(native_token(), selector!("balanceOf")); + } + } + //TODO(starknet-foundry): add a test for get_jumpdests +} diff --git a/kakarot-ssj/crates/evm/src/model/vm.cairo b/kakarot-ssj/crates/evm/src/model/vm.cairo new file mode 100644 index 000000000..d7704918b --- /dev/null +++ b/kakarot-ssj/crates/evm/src/model/vm.cairo @@ -0,0 +1,311 @@ +use core::cmp::min; +use core::dict::{Felt252Dict, Felt252DictTrait}; +use core::num::traits::{SaturatingSub, CheckedSub}; +use core::starknet::EthAddress; +use crate::errors::EVMError; +use crate::memory::Memory; +use crate::model::{Message, Environment, ExecutionResultStatus, ExecutionResult, AccountTrait}; +use crate::stack::Stack; +use utils::set::{Set, SetTrait, SpanSet, SpanSetTrait}; +use utils::traits::{SpanDefault}; + +#[derive(Default, Destruct)] +pub struct VM { + pub stack: Stack, + pub memory: Memory, + pub pc: usize, + pub valid_jumpdests: Felt252Dict, + pub return_data: Span, + pub env: Environment, + pub message: Message, + pub gas_left: u64, + pub running: bool, + pub error: bool, + pub accessed_addresses: Set, + pub accessed_storage_keys: Set<(EthAddress, u256)>, + pub gas_refund: u64 +} + + +#[generate_trait] +pub impl VMImpl of VMTrait { + #[inline(always)] + fn new(message: Message, env: Environment) -> VM { + VM { + stack: Default::default(), + memory: Default::default(), + pc: 0, + valid_jumpdests: AccountTrait::get_jumpdests(message.code), + return_data: [].span(), + env, + message, + gas_left: message.gas_limit, + running: true, + error: false, + accessed_addresses: message.accessed_addresses.clone_set(), + accessed_storage_keys: message.accessed_storage_keys.clone_set(), + gas_refund: 0 + } + } + + /// Decrements the gas_left field of the current vm by the value amount. + /// # Error : returns `EVMError::OutOfGas` if gas_left - value < 0 + #[inline(always)] + fn charge_gas(ref self: VM, value: u64) -> Result<(), EVMError> { + self.gas_left = match self.gas_left.checked_sub(value) { + Option::Some(gas_left) => gas_left, + Option::None => { return Result::Err(EVMError::OutOfGas); }, + }; + Result::Ok(()) + } + + + #[inline(always)] + fn pc(self: @VM) -> usize { + *self.pc + } + + #[inline(always)] + fn set_pc(ref self: VM, pc: usize) { + self.pc = pc; + } + + #[inline(always)] + fn is_valid_jump(ref self: VM, dest: u32) -> bool { + self.valid_jumpdests.get(dest.into()) + } + + #[inline(always)] + fn return_data(self: @VM) -> Span { + *self.return_data + } + + #[inline(always)] + fn set_return_data(ref self: VM, return_data: Span) { + self.return_data = return_data; + } + + #[inline(always)] + fn is_running(self: @VM) -> bool { + *self.running + } + + #[inline(always)] + fn stop(ref self: VM) { + self.running = false; + } + + #[inline(always)] + fn set_error(ref self: VM) { + self.error = true; + } + + #[inline(always)] + fn is_error(self: @VM) -> bool { + *self.error + } + + #[inline(always)] + fn message(self: @VM) -> Message { + *self.message + } + + #[inline(always)] + fn gas_left(self: @VM) -> u64 { + *self.gas_left + } + + #[inline(always)] + fn gas_refund(self: @VM) -> u64 { + *self.gas_refund + } + + #[inline(always)] + fn accessed_addresses(self: @VM) -> SpanSet { + self.accessed_addresses.spanset() + } + + #[inline(always)] + fn accessed_storage_keys(self: @VM) -> SpanSet<(EthAddress, u256)> { + self.accessed_storage_keys.spanset() + } + + /// Reads and returns data from bytecode starting at the provided pc. + /// + /// # Arguments + /// + /// * `self` - The `VM` instance to read the data from. + /// * `pc` - The starting position in the bytecode to read from. + /// * `len` - The length of the data to read from the bytecode. + /// + /// # Returns + /// + /// * A `Span` containing the requested bytecode slice. + /// * If the requested slice extends beyond the code length, returns remaining bytes. + #[inline(always)] + fn read_code(self: @VM, pc: usize, len: usize) -> Span { + let code_len = self.message().code.len(); + + // If pc is out of bounds, return an empty span + if pc >= code_len { + return [].span(); + } + + // Calculate the actual length to read + let remaining = code_len.saturating_sub(pc); + let actual_len = min(len, remaining); + + // Return the slice with the actual length + self.message().code.slice(pc, actual_len) + } + + #[inline(always)] + fn merge_child(ref self: VM, child: @ExecutionResult) { + match child.status { + ExecutionResultStatus::Success => { + self.accessed_addresses.extend(*child.accessed_addresses); + self.accessed_storage_keys.extend(*child.accessed_storage_keys); + self.gas_refund += *child.gas_refund; + self.gas_left += *child.gas_left; + self.return_data = *child.return_data; + }, + ExecutionResultStatus::Revert => { self.gas_left += *child.gas_left; }, + // If the call has halted exceptionnaly, the gas is not returned. + ExecutionResultStatus::Exception => {} + }; + } +} + +#[cfg(test)] +mod tests { + use crate::errors::EVMError; + use crate::model::Message; + use crate::model::vm::VMTrait; + use crate::test_utils::{tx_gas_limit, VMBuilderTrait}; + + #[test] + fn test_vm_default() { + let mut vm = VMTrait::new(Default::default(), Default::default()); + + assert!(vm.pc() == 0); + assert!(vm.is_running()); + assert!(!vm.error); + assert_eq!(vm.gas_left(), vm.message().gas_limit); + } + + + #[test] + fn test_set_pc() { + let mut vm = VMTrait::new(Default::default(), Default::default()); + + let new_pc = 42; + vm.set_pc(new_pc); + + assert(vm.pc() == new_pc, 'wrong pc'); + } + + #[test] + fn test_error() { + let mut vm = VMTrait::new(Default::default(), Default::default()); + + vm.set_error(); + + assert!(vm.error); + } + + #[test] + fn test_increment_gas_checked() { + let mut vm = VMTrait::new(Default::default(), Default::default()); + + assert_eq!(vm.gas_left(), vm.message().gas_limit); + + let result = vm.charge_gas(tx_gas_limit()); + + assert_eq!(result.unwrap_err(), EVMError::OutOfGas); + } + + #[test] + fn test_set_stopped() { + let mut vm = VMTrait::new(Default::default(), Default::default()); + + vm.stop(); + + assert!(!vm.is_running()) + } + + #[test] + fn test_read_code_within_bounds() { + let bytecode = [0x01, 0x02, 0x03, 0x04, 0x05].span(); + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(bytecode).build(); + vm.set_pc(1); + + let read_code = vm.read_code(vm.pc(), 3); + + assert_eq!(read_code, [0x02, 0x03, 0x04].span()); + assert_eq!(vm.pc(), 1); + } + + #[test] + fn test_read_code_out_of_bounds() { + let bytecode = [0x01, 0x02, 0x03].span(); + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(bytecode).build(); + vm.set_pc(2); + + let read_code = vm.read_code(vm.pc(), 3); + + assert_eq!(read_code, [0x03].span()); + assert_eq!(vm.pc(), 2); + } + + #[test] + fn test_read_code_at_boundary() { + let bytecode = [0x01, 0x02, 0x03, 0x04, 0x05].span(); + let mut vm = VMBuilderTrait::new_with_presets().with_bytecode(bytecode).build(); + vm.set_pc(3); + + let read_code = vm.read_code(vm.pc(), 3); + + assert_eq!(read_code, [0x04, 0x05].span()); + assert_eq!(vm.pc(), 3); + } + + #[test] + fn test_set_return() { + let mut vm = VMTrait::new(Default::default(), Default::default()); + vm.set_return_data([0x01, 0x02, 0x03].span()); + let return_data = vm.return_data(); + assert(return_data == [0x01, 0x02, 0x03].span(), 'wrong return data'); + } + + #[test] + fn test_return_data() { + let mut vm = VMTrait::new(Default::default(), Default::default()); + + let return_data = vm.return_data(); + assert(return_data.len() == 0, 'wrong length'); + } + + #[test] + fn test_is_valid_jump_destinations() { + // PUSH1, 0x03, JUMP, JUMPDEST, PUSH1, 0x09, JUMP, PUSH1 0x2, JUMPDDEST, PUSH1 0x2 + let mut message: Message = Default::default(); + message.code = [0x60, 0x3, 0x56, 0x5b, 0x60, 0x9, 0x56, 0x60, 0x2, 0x5b, 0x60, 0x2].span(); + + let mut vm = VMTrait::new(message, Default::default()); + + assert!(vm.is_valid_jump(0x3), "expected jump to be valid"); + assert!(vm.is_valid_jump(0x9), "expected jump to be valid"); + + assert!(!vm.is_valid_jump(0x4), "expected jump to be invalid"); + assert!(!vm.is_valid_jump(0x5), "expected jump to be invalid"); + } + + #[test] + fn test_valid_jump_destination_inside_jumpn() { + let mut message: Message = Default::default(); + message.code = [0x60, 0x5B, 0x60, 0x00].span(); + + let mut vm = VMTrait::new(message, Default::default()); + assert!(!vm.is_valid_jump(0x1), "expected false"); + } +} diff --git a/kakarot-ssj/crates/evm/src/precompiles.cairo b/kakarot-ssj/crates/evm/src/precompiles.cairo new file mode 100644 index 000000000..ff8dd9386 --- /dev/null +++ b/kakarot-ssj/crates/evm/src/precompiles.cairo @@ -0,0 +1,155 @@ +mod blake2f; +mod ec_operations; +mod ec_recover; +mod identity; +mod modexp; +mod p256verify; +mod sha256; + +pub use blake2f::Blake2f; +pub use ec_operations::ec_add::EcAdd; +pub use ec_operations::ec_mul::EcMul; +pub use ec_recover::EcRecover; +pub use identity::Identity; +pub use modexp::ModExp; +pub use p256verify::P256Verify; +pub use sha256::Sha256; + +use core::starknet::EthAddress; +use core::traits::Into; +use crate::errors::EVMError; +use crate::model::vm::VM; +use crate::model::vm::VMTrait; +use utils::set::{Set, SetTrait}; + + +/// The starting address for Ethereum precompiles. +pub const FIRST_ETHEREUM_PRECOMPILE_ADDRESS: u256 = 0x01; + +/// The ending address for Ethereum precompiles (inclusive). +pub const LAST_ETHEREUM_PRECOMPILE_ADDRESS: u256 = 0x0a; + +/// The starting address for Rollup precompiles. +pub const FIRST_ROLLUP_PRECOMPILE_ADDRESS: u256 = 0x100; + +/// Returns a set of Ethereum precompile addresses. +/// +/// # Returns +/// +/// * `Set` - A set containing all Ethereum precompile addresses. +pub fn eth_precompile_addresses() -> Set { + let mut precompile_addresses: Array = array![]; + for i in FIRST_ETHEREUM_PRECOMPILE_ADDRESS + ..LAST_ETHEREUM_PRECOMPILE_ADDRESS + + 0x01 { + precompile_addresses.append(i.try_into().unwrap()); + }; + SetTrait::from_array(precompile_addresses) +} + + +/// Trait for implementing precompiles. +pub trait Precompile { + /// Returns the address of the precompile. + /// + /// # Returns + /// + /// * `EthAddress` - The address of the precompile. + fn address() -> EthAddress; + + /// Executes the precompile with the given input. + /// + /// # Arguments + /// + /// * `input` - A span of bytes representing the input data. + /// + /// # Returns + /// + /// * `Result<(u64, Span), EVMError>` - A tuple containing the gas used and the output data, + /// or an error if the execution failed. + fn exec(input: Span) -> Result<(u64, Span), EVMError>; +} + +#[generate_trait] +pub impl PrecompilesImpl of Precompiles { + /// Executes a precompile contract based on the current VM state. + /// + /// # Arguments + /// + /// * `ref vm` - A mutable reference to the VM instance. + /// + /// # Returns + /// + /// * `Result<(), EVMError>` - Ok if the precompile execution was successful, or an error if it + /// failed. + fn exec_precompile(ref vm: VM) -> Result<(), EVMError> { + let precompile_address = vm.message.code_address.evm; + let input = vm.message().data; + + let (gas, result) = if precompile_address.into() == 0x100 { + P256Verify::exec(input)? + } else { + match precompile_address.into() { + 0x00 => { + // we should never reach this branch! + panic!("pre-compile address can't be 0") + }, + 0x01 => { EcRecover::exec(input)? }, + 0x02 => { Sha256::exec(input)? }, + 0x03 => { + // we should never reach this branch! + panic!("pre-compile at address {:?} isn't implemented yet", precompile_address) + }, + 0x04 => { Identity::exec(input)? }, + 0x05 => { ModExp::exec(input)? }, + 0x06 => { EcAdd::exec(input)? }, + 0x07 => { EcMul::exec(input)? }, + 0x08 => { + // we should never reach this branch! + panic!("pre-compile at address {:?} isn't implemented yet", precompile_address) + }, + 0x09 => { Blake2f::exec(input)? }, + 0x0a => { + // Point Evaluation + panic!("pre-compile at address {:?} isn't implemented yet", precompile_address) + }, + _ => { + // we should never reach this branch! + panic!("address {:?} isn't a pre-compile", precompile_address) + } + } + }; + + vm.charge_gas(gas)?; + vm.return_data = result; + vm.stop(); + return Result::Ok(()); + } +} + + +#[cfg(test)] +mod tests { + use super::eth_precompile_addresses; + use utils::set::SetTrait; + + #[test] + fn test_eth_precompile_addresses() { + let addresses = eth_precompile_addresses(); + assert_eq!( + addresses.to_span(), + [ + 0x01.try_into().unwrap(), + 0x02.try_into().unwrap(), + 0x03.try_into().unwrap(), + 0x04.try_into().unwrap(), + 0x05.try_into().unwrap(), + 0x06.try_into().unwrap(), + 0x07.try_into().unwrap(), + 0x08.try_into().unwrap(), + 0x09.try_into().unwrap(), + 0x0a.try_into().unwrap() + ].span() + ); + } +} diff --git a/kakarot-ssj/crates/evm/src/precompiles/blake2f.cairo b/kakarot-ssj/crates/evm/src/precompiles/blake2f.cairo new file mode 100644 index 000000000..ac16b81d2 --- /dev/null +++ b/kakarot-ssj/crates/evm/src/precompiles/blake2f.cairo @@ -0,0 +1,212 @@ +use core::array::ArrayTrait; +use core::option::OptionTrait; +use core::starknet::EthAddress; + +use crate::errors::{EVMError, ensure}; +use crate::precompiles::Precompile; +use utils::crypto::blake2_compress::compress; +use utils::traits::bytes::{FromBytes, ToBytes}; + +const GF_ROUND: u64 = 1; +const INPUT_LENGTH: usize = 213; + +pub impl Blake2f of Precompile { + #[inline(always)] + fn address() -> EthAddress { + 0x9.try_into().unwrap() + } + + fn exec(input: Span) -> Result<(u64, Span), EVMError> { + ensure( + input.len() == INPUT_LENGTH, EVMError::InvalidParameter('Blake2: wrong input length') + )?; + + let f = match (*input[212]).into() { + 0 => false, + 1 => true, + _ => { + return Result::Err(EVMError::InvalidParameter('Blake2: wrong final indicator')); + } + }; + + let rounds: u32 = input + .slice(0, 4) + .from_be_bytes() + .ok_or(EVMError::TypeConversionError('extraction of u32 failed'))?; + + let gas = (GF_ROUND * rounds.into()).into(); + + let mut h: Array = Default::default(); + let mut m: Array = Default::default(); + + let mut pos = 4; + for _ in 0..8_u8 { + // safe unwrap, because we have made sure of the input length to be 213 + h.append(input.slice(pos, 8).from_le_bytes().unwrap()); + pos += 8; + }; + + let mut pos = 68; + for _ in 0..16_u8 { + // safe unwrap, because we have made sure of the input length to be 213 + m.append(input.slice(pos, 8).from_le_bytes().unwrap()); + pos += 8 + }; + + let mut t: Array = Default::default(); + + // safe unwrap, because we have made sure of the input length to be 213 + t.append(input.slice(196, 8).from_le_bytes().unwrap()); + // safe unwrap, because we have made sure of the input length to be 213 + t.append(input.slice(204, 8).from_le_bytes().unwrap()); + + let res = compress(rounds, h.span(), m.span(), t.span(), f); + + let mut return_data: Array = Default::default(); + + for result in res { + let bytes = (*result).to_le_bytes_padded(); + return_data.append_span(bytes); + }; + + Result::Ok((gas, return_data.span())) + } +} + +#[cfg(test)] +mod tests { + use core::array::SpanTrait; + use crate::errors::EVMError; + use crate::instructions::MemoryOperationTrait; + use crate::instructions::SystemOperationsTrait; + use crate::memory::MemoryTrait; + use crate::precompiles::blake2f::Blake2f; + use crate::stack::StackTrait; + use crate::test_data::test_data_blake2f::{ + blake2_precompile_fail_wrong_length_input_1_test_case, + blake2_precompile_fail_wrong_length_input_2_test_case, + blake2_precompile_fail_wrong_length_input_3_test_case, blake2_precompile_pass_1_test_case, + blake2_precompile_pass_0_test_case, blake2_precompile_pass_2_test_case + }; + use crate::test_utils::{VMBuilderTrait, native_token, setup_test_environment}; + use snforge_std::start_mock_call; + use utils::traits::bytes::FromBytes; + + #[test] + fn test_blake2_precompile_fail_empty_input() { + let calldata = array![]; + + let res = Blake2f::exec(calldata.span()); + assert_eq!(res, Result::Err(EVMError::InvalidParameter('Blake2: wrong input length'))); + } + + #[test] + fn test_blake2_precompile_fail_wrong_length_input_1() { + let (calldata, _) = blake2_precompile_fail_wrong_length_input_1_test_case(); + + let res = Blake2f::exec(calldata); + assert_eq!(res, Result::Err(EVMError::InvalidParameter('Blake2: wrong input length'))); + } + #[test] + fn test_blake2_precompile_fail_wrong_length_input_2() { + let (calldata, _) = blake2_precompile_fail_wrong_length_input_2_test_case(); + + let res = Blake2f::exec(calldata); + assert_eq!(res, Result::Err(EVMError::InvalidParameter('Blake2: wrong input length'))); + } + + #[test] + fn test_blake2_precompile_fail_wrong_final_block_indicator_flag() { + let (calldata, _) = blake2_precompile_fail_wrong_length_input_3_test_case(); + + let res = Blake2f::exec(calldata); + assert_eq!(res, Result::Err(EVMError::InvalidParameter('Blake2: wrong final indicator'))); + } + + #[test] + fn test_blake2_precompile_pass_1() { + let (calldata, expected_result) = blake2_precompile_pass_1_test_case(); + let rounds: u32 = calldata.slice(0, 4).from_be_bytes().unwrap(); + + let (gas, result) = Blake2f::exec(calldata).unwrap(); + + assert_eq!(result, expected_result); + assert_eq!(gas, rounds.into()); + } + + #[test] + fn test_blake2_precompile_pass_0() { + let (calldata, expected_result) = blake2_precompile_pass_0_test_case(); + let rounds: u32 = calldata.slice(0, 4).from_be_bytes().unwrap(); + + let (gas, result) = Blake2f::exec(calldata).unwrap(); + + assert_eq!(result, expected_result); + assert_eq!(gas, rounds.into()); + } + + #[test] + fn test_blake2_precompile_pass_2() { + let (calldata, expected_result) = blake2_precompile_pass_2_test_case(); + let rounds: u32 = calldata.slice(0, 4).from_be_bytes().unwrap(); + + let (gas, result) = Blake2f::exec(calldata).unwrap(); + + assert_eq!(result, expected_result); + assert_eq!(gas, rounds.into()); + } + + // source: + // + #[test] + fn test_blake2_precompile_static_call() { + setup_test_environment(); + + let mut vm = VMBuilderTrait::new_with_presets().build(); + + // rounds + vm.stack.push(12).unwrap(); + vm.stack.push(3).unwrap(); + vm.exec_mstore8().unwrap(); + + // h + vm.stack.push(0x48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5).unwrap(); + vm.stack.push(4).unwrap(); + vm.exec_mstore().unwrap(); + vm.stack.push(0xd182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b).unwrap(); + vm.stack.push(36).unwrap(); + vm.exec_mstore().unwrap(); + + // m + vm.stack.push(0x6162630000000000000000000000000000000000000000000000000000000000).unwrap(); + vm.stack.push(68).unwrap(); + vm.exec_mstore().unwrap(); + + // t + vm.stack.push(3).unwrap(); + vm.stack.push(196).unwrap(); + vm.exec_mstore8().unwrap(); + + // f + vm.stack.push(1).unwrap(); + vm.stack.push(212).unwrap(); + vm.exec_mstore8().unwrap(); + + vm.stack.push(64).unwrap(); // retSize + vm.stack.push(213).unwrap(); // retOffset + vm.stack.push(213).unwrap(); // argsSize + vm.stack.push(0).unwrap(); // argsOffset + vm.stack.push(9).unwrap(); // address + vm.stack.push(0xFFFFFFFF).unwrap(); // gas + + start_mock_call::(native_token(), selector!("balanceOf"), 0); + vm.exec_staticcall().unwrap(); + + let mut result: Array = Default::default(); + vm.memory.load_n(64, ref result, 213); + + let (_, expected_result) = blake2_precompile_pass_1_test_case(); + + assert_eq!(result.span(), expected_result); + } +} diff --git a/kakarot-ssj/crates/evm/src/precompiles/ec_operations.cairo b/kakarot-ssj/crates/evm/src/precompiles/ec_operations.cairo new file mode 100644 index 000000000..d696d0fee --- /dev/null +++ b/kakarot-ssj/crates/evm/src/precompiles/ec_operations.cairo @@ -0,0 +1,107 @@ +pub(crate) mod ec_add; +pub(crate) mod ec_mul; +use core::circuit::CircuitElement as CE; +use core::circuit::CircuitInput as CI; +use core::circuit::{ + u96, u384, CircuitElement, CircuitInput, circuit_add, circuit_sub, circuit_mul, circuit_inverse, + EvalCircuitTrait, CircuitOutputsTrait, CircuitModulus, CircuitInputs +}; +use core::num::traits::Zero; +use garaga::core::circuit::AddInputResultTrait2; + +const BN254_ORDER: u256 = 0x30644E72E131A029B85045B68181585D2833E84879B9709143E1F593F0000001; +const BN254_PRIME: u256 = 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47; +const BN254_PRIME_LIMBS: [ + u96 + ; 4] = [ + 0x6871ca8d3c208c16d87cfd47, 0xb85045b68181585d97816a91, 0x30644e72e131a029, 0x0 +]; + +// Check if a point is on the curve. +// Point at infinity (0,0) will return false. +pub fn is_on_curve(x: u384, y: u384) -> bool { + let (b, _x, _y) = (CE::> {}, CE::> {}, CE::> {}); + + // Compute (y^2 - (x^3 + b)) % p_bn254 + let x2 = circuit_mul(_x, _x); + let x3 = circuit_mul(x2, _x); + let y2 = circuit_mul(_y, _y); + let rhs = circuit_add(x3, b); + let check = circuit_sub(y2, rhs); + + let modulus = TryInto::<_, CircuitModulus>::try_into(BN254_PRIME_LIMBS) + .unwrap(); // BN254 prime field modulus + + let mut circuit_inputs = (check,).new_inputs(); + // Prefill constants: + circuit_inputs = circuit_inputs.next_2([3, 0, 0, 0]); + // Fill inputs: + circuit_inputs = circuit_inputs.next_2(x); + circuit_inputs = circuit_inputs.next_2(y); + + let outputs = circuit_inputs.done_2().eval(modulus).unwrap(); + let zero_check: u384 = outputs.get_output(check); + return zero_check.is_zero(); +} + + +// Double BN254 EC point without checking if the point is on the curve +pub fn double_ec_point_unchecked(x: u384, y: u384) -> (u384, u384) { + // CONSTANT stack + let in0 = CE::> {}; // 0x3 + // INPUT stack + let (_x, _y) = (CE::> {}, CE::> {}); + + let x2 = circuit_mul(_x, _x); + let num = circuit_mul(in0, x2); + let den = circuit_add(_y, _y); + let inv_den = circuit_inverse(den); + let slope = circuit_mul(num, inv_den); + let slope_sqr = circuit_mul(slope, slope); + + let nx = circuit_sub(circuit_sub(slope_sqr, _x), _x); + let ny = circuit_sub(circuit_mul(slope, circuit_sub(_x, nx)), _y); + + let modulus = TryInto::<_, CircuitModulus>::try_into(BN254_PRIME_LIMBS) + .unwrap(); // BN254 prime field modulus + + let mut circuit_inputs = (nx, ny,).new_inputs(); + // Prefill constants: + circuit_inputs = circuit_inputs.next_2([0x3, 0x0, 0x0, 0x0]); // in0 + // Fill inputs: + circuit_inputs = circuit_inputs.next_2(x); // in1 + circuit_inputs = circuit_inputs.next_2(y); // in2 + + let outputs = circuit_inputs.done_2().eval(modulus).unwrap(); + + (outputs.get_output(nx), outputs.get_output(ny)) +} + + +// returns true if a == b mod p_bn254 +pub fn eq_mod_p(a: u384, b: u384) -> bool { + let in1 = CircuitElement::> {}; + let in2 = CircuitElement::> {}; + let sub = circuit_sub(in1, in2); + + let modulus = TryInto::<_, CircuitModulus>::try_into(BN254_PRIME_LIMBS) + .unwrap(); // BN254 prime field modulus + + let outputs = (sub,).new_inputs().next_2(a).next_2(b).done_2().eval(modulus).unwrap(); + + return outputs.get_output(sub).is_zero(); +} + +// returns true if a == -b mod p_bn254 +pub fn eq_neg_mod_p(a: u384, b: u384) -> bool { + let _a = CE::> {}; + let _b = CE::> {}; + let check = circuit_add(_a, _b); + + let modulus = TryInto::<_, CircuitModulus>::try_into(BN254_PRIME_LIMBS) + .unwrap(); // BN254 prime field modulus + + let outputs = (check,).new_inputs().next_2(a).next_2(b).done_2().eval(modulus).unwrap(); + + return outputs.get_output(check).is_zero(); +} diff --git a/kakarot-ssj/crates/evm/src/precompiles/ec_operations/ec_add.cairo b/kakarot-ssj/crates/evm/src/precompiles/ec_operations/ec_add.cairo new file mode 100644 index 000000000..1d8b9422e --- /dev/null +++ b/kakarot-ssj/crates/evm/src/precompiles/ec_operations/ec_add.cairo @@ -0,0 +1,185 @@ +use core::circuit::CircuitElement as CE; +use core::circuit::CircuitInput as CI; + +use core::circuit::{ + u384, circuit_sub, circuit_mul, circuit_inverse, EvalCircuitTrait, CircuitOutputsTrait, + CircuitModulus, CircuitInputs +}; +use core::option::Option; +use core::starknet::{EthAddress}; +use crate::errors::EVMError; +use crate::precompiles::Precompile; +use crate::precompiles::ec_operations::{ + eq_mod_p, eq_neg_mod_p, is_on_curve, double_ec_point_unchecked, BN254_PRIME_LIMBS, BN254_PRIME +}; +use garaga::core::circuit::AddInputResultTrait2; +use utils::traits::bytes::{ToBytes, U8SpanExTrait, FromBytes}; + + +const BASE_COST: u64 = 150; +const U256_BYTES_LEN: usize = 32; +pub impl EcAdd of Precompile { + #[inline(always)] + fn address() -> EthAddress { + 0x6.try_into().unwrap() + } + + fn exec(input: Span) -> Result<(u64, Span), EVMError> { + let gas = BASE_COST; + + // Pad the input to 128 bytes to avoid out-of-bounds accesses + let mut input = input.pad_right_with_zeroes(128); + + let x1: u256 = input.slice(0, 32).from_be_bytes().unwrap(); + + let y1: u256 = input.slice(32, 32).from_be_bytes().unwrap(); + + let x2: u256 = input.slice(64, 32).from_be_bytes().unwrap(); + + let y2: u256 = input.slice(96, 32).from_be_bytes().unwrap(); + + let (x, y) = match ec_add(x1, y1, x2, y2) { + Option::Some((x, y)) => { (x, y) }, + Option::None => { + return Result::Err(EVMError::InvalidParameter('invalid ec_add parameters')); + }, + }; + + let mut result_bytes = array![]; + // Append x to the result bytes. + let x_bytes = x.to_be_bytes_padded(); + result_bytes.append_span(x_bytes); + // Append y to the result bytes. + let y_bytes = y.to_be_bytes_padded(); + result_bytes.append_span(y_bytes); + + return Result::Ok((gas, result_bytes.span())); + } +} + + +fn ec_add(x1: u256, y1: u256, x2: u256, y2: u256) -> Option<(u256, u256)> { + if x1 >= BN254_PRIME || y1 >= BN254_PRIME || x2 >= BN254_PRIME || y2 >= BN254_PRIME { + return Option::None; + } + if x1 == 0 && y1 == 0 { + if x2 == 0 && y2 == 0 { + // Both are points at infinity, return either of them. + return Option::Some((x2, y2)); + } else { + // Only first point is at infinity. + let x2_u384: u384 = x2.into(); + let y2_u384: u384 = y2.into(); + if is_on_curve(x2_u384, y2_u384) { + // Second point is on the curve, return it. + return Option::Some((x2, y2)); + } else { + // Second point is not on the curve, return None (error). + return Option::None; + } + } + } else if x2 == 0 && y2 == 0 { + // Only second point is at infinity. + let x1_u384: u384 = x1.into(); + let y1_u384: u384 = y1.into(); + if is_on_curve(x1_u384, y1_u384) { + // First point is on the curve, return it. + return Option::Some((x1, y1)); + } else { + // First point is not on the curve, return None (error). + return Option::None; + } + } else { + // None of the points are at infinity. + let x1_u384: u384 = x1.into(); + let x2_u384: u384 = x2.into(); + let y1_u384: u384 = y1.into(); + let y2_u384: u384 = y2.into(); + + if is_on_curve(x1_u384, y1_u384) && is_on_curve(x2_u384, y2_u384) { + match ec_safe_add(x1_u384, y1_u384, x2_u384, y2_u384) { + Option::Some(( + x, y + )) => Option::Some( + ( + TryInto::::try_into(x).unwrap(), + TryInto::::try_into(y).unwrap() + ) + ), + Option::None => Option::Some((0, 0)), + } + } else { + // None of the points are infinity and at least one of them is not on the curve. + return Option::None; + } + } +} + + +// assumes that the points are on the curve and not the point at infinity. +// Returns None if the points are the same and opposite y coordinates (Point at infinity) +pub fn ec_safe_add(x1: u384, y1: u384, x2: u384, y2: u384) -> Option<(u384, u384)> { + let same_x = eq_mod_p(x1, x2); + + if same_x { + let opposite_y = eq_neg_mod_p(y1, y2); + + if opposite_y { + return Option::None; + } else { + let (x, y) = double_ec_point_unchecked(x1, y1); + return Option::Some((x, y)); + } + } else { + let (x, y) = add_ec_point_unchecked(x1, y1, x2, y2); + return Option::Some((x, y)); + } +} + +// Add two BN254 EC points without checking if: +// - the points are on the curve +// - the points are not the same +// - none of the points are the point at infinity +fn add_ec_point_unchecked(xP: u384, yP: u384, xQ: u384, yQ: u384) -> (u384, u384) { + // INPUT stack + let (_xP, _yP, _xQ, _yQ) = (CE::> {}, CE::> {}, CE::> {}, CE::> {}); + + let num = circuit_sub(_yP, _yQ); + let den = circuit_sub(_xP, _xQ); + let inv_den = circuit_inverse(den); + let slope = circuit_mul(num, inv_den); + let slope_sqr = circuit_mul(slope, slope); + + let nx = circuit_sub(circuit_sub(slope_sqr, _xP), _xQ); + let ny = circuit_sub(circuit_mul(slope, circuit_sub(_xP, nx)), _yP); + + let modulus = TryInto::<_, CircuitModulus>::try_into(BN254_PRIME_LIMBS) + .unwrap(); // BN254 prime field modulus + + let mut circuit_inputs = (nx, ny,).new_inputs(); + // Fill inputs: + circuit_inputs = circuit_inputs.next_2(xP); // in1 + circuit_inputs = circuit_inputs.next_2(yP); // in2 + circuit_inputs = circuit_inputs.next_2(xQ); // in3 + circuit_inputs = circuit_inputs.next_2(yQ); // in4 + + let outputs = circuit_inputs.done_2().eval(modulus).unwrap(); + + (outputs.get_output(nx), outputs.get_output(ny)) +} + + +#[cfg(test)] +mod tests { + use super::ec_add; + #[test] + fn test_ec_add() { + let x1 = 1; + let y1 = 2; + let x2 = 1; + let y2 = 2; + let (x, y) = ec_add(x1, y1, x2, y2).expect('ec_add failed'); + assert_eq!(x, 0x030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd3); + assert_eq!(y, 0x15ed738c0e0a7c92e7845f96b2ae9c0a68a6a449e3538fc7ff3ebf7a5a18a2c4); + } +} diff --git a/kakarot-ssj/crates/evm/src/precompiles/ec_operations/ec_mul.cairo b/kakarot-ssj/crates/evm/src/precompiles/ec_operations/ec_mul.cairo new file mode 100644 index 000000000..bfb60a7e5 --- /dev/null +++ b/kakarot-ssj/crates/evm/src/precompiles/ec_operations/ec_mul.cairo @@ -0,0 +1,142 @@ +use core::circuit::u384; +use core::option::Option; +use core::starknet::{EthAddress}; + +use crate::errors::EVMError; +use crate::precompiles::Precompile; +use crate::precompiles::ec_operations::ec_add::ec_safe_add; +use crate::precompiles::ec_operations::{is_on_curve, double_ec_point_unchecked, BN254_PRIME}; +use utils::traits::bytes::{ToBytes, U8SpanExTrait, FromBytes}; + +const BASE_COST: u64 = 6000; +const U256_BYTES_LEN: usize = 32; + +pub impl EcMul of Precompile { + fn address() -> EthAddress { + 0x7.try_into().unwrap() + } + + fn exec(mut input: Span) -> Result<(u64, Span), EVMError> { + let gas = BASE_COST; + + // Pad the input to 128 bytes to avoid out-of-bounds accesses + let mut input = input.pad_right_with_zeroes(96); + + let x1: u256 = input.slice(0, 32).from_be_bytes().unwrap(); + + let y1: u256 = input.slice(32, 32).from_be_bytes().unwrap(); + + let s: u256 = input.slice(64, 32).from_be_bytes().unwrap(); + + let (x, y) = match ec_mul(x1, y1, s) { + Option::Some((x, y)) => { (x, y) }, + Option::None => { + return Result::Err(EVMError::InvalidParameter('invalid ec_mul parameters')); + }, + }; + + // Append x and y to the result bytes. + let mut result_bytes = array![]; + let x_bytes = x.to_be_bytes_padded(); + result_bytes.append_span(x_bytes); + let y_bytes = y.to_be_bytes_padded(); + result_bytes.append_span(y_bytes); + + return Result::Ok((gas, result_bytes.span())); + } +} + +// Returns Option::None in case of error. +fn ec_mul(x1: u256, y1: u256, s: u256) -> Option<(u256, u256)> { + if x1 >= BN254_PRIME || y1 >= BN254_PRIME { + return Option::None; + } + if x1 == 0 && y1 == 0 { + // Input point is at infinity, return it + return Option::Some((x1, y1)); + } else { + // Point is not at infinity + let x1_u384: u384 = x1.into(); + let y1_u384: u384 = y1.into(); + + if is_on_curve(x1_u384, y1_u384) { + if s == 0 { + return Option::Some((0, 0)); + } else if s == 1 { + return Option::Some((x1, y1)); + } else { + // Point is on the curve. + // s is >= 2. + let bits = get_bits_little(s); + let pt = ec_mul_inner((x1_u384, y1_u384), bits); + match pt { + Option::Some(( + x, y + )) => Option::Some((x.try_into().unwrap(), y.try_into().unwrap())), + Option::None => Option::Some((0, 0)), + } + } + } else { + // Point is not on the curve + return Option::None; + } + } +} + +// Returns the bits of the 256 bit number in little endian format. +fn get_bits_little(s: u256) -> Array { + let mut bits = ArrayTrait::new(); + let mut s_low = s.low; + while s_low != 0 { + let (q, r) = core::traits::DivRem::div_rem(s_low, 2); + bits.append(r.into()); + s_low = q; + }; + let mut s_high = s.high; + if s_high != 0 { + while bits.len() != 128 { + bits.append(0); + } + } + while s_high != 0 { + let (q, r) = core::traits::DivRem::div_rem(s_high, 2); + bits.append(r.into()); + s_high = q; + }; + bits +} + + +// Should not be called outside of ec_mul. +// Returns Option::None in case of point at infinity. +// The size of bits array must be at minimum 2 and the point must be on the curve. +fn ec_mul_inner(pt: (u384, u384), mut bits: Array) -> Option<(u384, u384)> { + let (mut temp_x, mut temp_y) = pt; + let mut result: Option<(u384, u384)> = Option::None; + for bit in bits { + if bit != 0 { + match result { + Option::Some((xr, yr)) => result = ec_safe_add(temp_x, temp_y, xr, yr), + Option::None => result = Option::Some((temp_x, temp_y)), + }; + }; + let (_temp_x, _temp_y) = double_ec_point_unchecked(temp_x, temp_y); + temp_x = _temp_x; + temp_y = _temp_y; + }; + + return result; +} + +#[cfg(test)] +mod tests { + use super::ec_mul; + + #[test] + fn test_ec_mul() { + let (x1, y1, s) = (1, 2, 2); + let (x, y) = ec_mul(x1, y1, s).expect('ec_mul failed'); + assert_eq!(x, 0x030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd3); + assert_eq!(y, 0x15ed738c0e0a7c92e7845f96b2ae9c0a68a6a449e3538fc7ff3ebf7a5a18a2c4); + } +} diff --git a/kakarot-ssj/crates/evm/src/precompiles/ec_recover.cairo b/kakarot-ssj/crates/evm/src/precompiles/ec_recover.cairo new file mode 100644 index 000000000..cfa2f68f9 --- /dev/null +++ b/kakarot-ssj/crates/evm/src/precompiles/ec_recover.cairo @@ -0,0 +1,150 @@ +use core::starknet::secp256_trait::{Signature, recover_public_key, Secp256PointTrait}; +use core::starknet::{ + EthAddress, eth_signature::{public_key_point_to_eth_address}, secp256k1::{Secp256k1Point}, + SyscallResultTrait +}; +use core::traits::Into; +use crate::errors::EVMError; +use crate::precompiles::Precompile; +use utils::traits::EthAddressIntoU256; +use utils::traits::bytes::{U8SpanExTrait, FromBytes, ToBytes}; +use utils::traits::{NumericIntoBool, BoolIntoNumeric}; + +const EC_RECOVER_PRECOMPILE_GAS_COST: u64 = 3000; + +pub impl EcRecover of Precompile { + #[inline(always)] + fn address() -> EthAddress { + 0x1.try_into().unwrap() + } + + fn exec(input: Span) -> Result<(u64, Span), EVMError> { + let gas = EC_RECOVER_PRECOMPILE_GAS_COST; + + // Pad the input to 128 bytes to avoid out-of-bounds accesses + let input = input.pad_right_with_zeroes(128); + let message_hash = input.slice(0, 32); + let message_hash = match message_hash.from_be_bytes() { + Option::Some(message_hash) => message_hash, + Option::None => { return Result::Ok((gas, [].span())); } + }; + + let v: Option = input.slice(32, 32).from_be_bytes(); + let y_parity = match v { + Option::Some(v) => { + if !(v == 27 || v == 28) { + return Result::Ok((gas, [].span())); + } + let y_parity = v - 27; //won't overflow because v is 27 or 28 + y_parity.into() + }, + Option::None => { return Result::Ok((gas, [].span())); } + }; + + let r: Option = input.slice(64, 32).from_be_bytes(); + let r = match r { + Option::Some(r) => r, + Option::None => { return Result::Ok((gas, [].span())); } + }; + + let s: Option = input.slice(96, 32).from_be_bytes(); + let s = match s { + Option::Some(s) => s, + Option::None => { return Result::Ok((gas, [].span())); } + }; + + let signature = Signature { r, s, y_parity }; + + let recovered_public_key = + match recover_public_key::(message_hash, signature) { + Option::Some(public_key_point) => { + // EVM spec requires that the public key is not the point at infinity + let (x, y) = public_key_point.get_coordinates().unwrap_syscall(); + if (x == 0 && y == 0) { + return Result::Ok((gas, [].span())); + } + public_key_point + }, + Option::None => { return Result::Ok((gas, [].span())); } + }; + + let eth_address: u256 = public_key_point_to_eth_address(recovered_public_key).into(); + let eth_address = eth_address.to_be_bytes_padded(); + + return Result::Ok((gas, eth_address)); + } +} + +#[cfg(test)] +mod tests { + use core::array::ArrayTrait; + use crate::instructions::SystemOperationsTrait; + use crate::memory::MemoryTrait; + + use crate::precompiles::ec_recover::EcRecover; + use crate::stack::StackTrait; + use crate::test_utils::setup_test_environment; + use crate::test_utils::{VMBuilderTrait, MemoryTestUtilsTrait, native_token}; + use snforge_std::start_mock_call; + use utils::traits::bytes::{ToBytes, FromBytes}; + + + // source: + // + #[test] + fn test_ec_recover_precompile() { + let msg_hash = 0x456e9aea5e197a1f1af7a3e85a3212fa4049a3ba34c2289b4c860fc0b0c64ef3_u256 + .to_be_bytes_padded(); + let v = 28_u256.to_be_bytes_padded(); + let r = 0x9242685bf161793cc25603c231bc2f568eb630ea16aa137d2664ac8038825608_u256 + .to_be_bytes_padded(); + let s = 0x4f8ae3bd7535248d0bd448298cc2e2071e56992d0774dc340c368ae950852ada_u256 + .to_be_bytes_padded(); + + let mut calldata = array![]; + calldata.append_span(msg_hash); + calldata.append_span(v); + calldata.append_span(r); + calldata.append_span(s); + + let (gas, result) = EcRecover::exec(calldata.span()).unwrap(); + + let result: u256 = result.from_be_bytes().unwrap(); + assert_eq!(result, 0x7156526fbd7a3c72969b54f64e42c10fbb768c8a); + assert_eq!(gas, 3000); + } + + // source: + // + #[test] + fn test_ec_precompile_static_call() { + setup_test_environment(); + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm + .memory + .store( + 0x456e9aea5e197a1f1af7a3e85a3212fa4049a3ba34c2289b4c860fc0b0c64ef3, 0x0 + ); // msg_hash + vm.memory.store_with_expansion(0x1C, 0x20); // v + vm + .memory + .store(0x9242685bf161793cc25603c231bc2f568eb630ea16aa137d2664ac8038825608, 0x40); // r + vm + .memory + .store(0x4f8ae3bd7535248d0bd448298cc2e2071e56992d0774dc340c368ae950852ada, 0x60); // s + + vm.stack.push(0x20).unwrap(); // retSize + vm.stack.push(0x80).unwrap(); // retOffset + vm.stack.push(0x80).unwrap(); // argsSize + vm.stack.push(0x0).unwrap(); // argsOffset + vm.stack.push(0x1).unwrap(); // address + vm.stack.push(0xFFFFFFFF).unwrap(); // gas + + start_mock_call::(native_token(), selector!("balanceOf"), 0); + vm.exec_staticcall().unwrap(); + + let result = vm.memory.load(0x80); + assert_eq!(result, 0x7156526fbd7a3c72969b54f64e42c10fbb768c8a); + } +} diff --git a/kakarot-ssj/crates/evm/src/precompiles/identity.cairo b/kakarot-ssj/crates/evm/src/precompiles/identity.cairo new file mode 100644 index 000000000..7bd38806e --- /dev/null +++ b/kakarot-ssj/crates/evm/src/precompiles/identity.cairo @@ -0,0 +1,71 @@ +use core::starknet::EthAddress; +use crate::errors::EVMError; +use crate::precompiles::Precompile; + +const BASE_COST: u64 = 15; +const COST_PER_WORD: u64 = 3; + +pub impl Identity of Precompile { + #[inline(always)] + fn address() -> EthAddress { + 0x4.try_into().unwrap() + } + + fn exec(input: Span) -> Result<(u64, Span), EVMError> { + let data_word_size = ((input.len() + 31) / 32).into(); + let gas = BASE_COST + data_word_size * COST_PER_WORD; + + return Result::Ok((gas, input)); + } +} + +#[cfg(test)] +mod tests { + use core::result::ResultTrait; + use crate::instructions::SystemOperationsTrait; + + use crate::memory::MemoryTrait; + use crate::precompiles::identity::Identity; + use crate::stack::StackTrait; + use crate::test_utils::{ + VMBuilderTrait, MemoryTestUtilsTrait, native_token, setup_test_environment + }; + use snforge_std::start_mock_call; + + // source: + // + #[test] + fn test_identity_precompile() { + let calldata = [0x2A].span(); + + let (gas, result) = Identity::exec(calldata).unwrap(); + + assert_eq!(calldata, result); + assert_eq!(gas, 18); + } + + + // source: + // + //TODO(sn-foundry): fix or delete + #[test] + fn test_identity_precompile_static_call() { + setup_test_environment(); + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm.stack.push(0x20).unwrap(); // retSize + vm.stack.push(0x3F).unwrap(); // retOffset + vm.stack.push(0x20).unwrap(); // argsSize + vm.stack.push(0x1F).unwrap(); // argsOffset + vm.stack.push(0x4).unwrap(); // address + vm.stack.push(0xFFFFFFFF).unwrap(); // gas + + vm.memory.store_with_expansion(0x2A, 0x1F); + + start_mock_call::(native_token(), selector!("balanceOf"), 0); + vm.exec_staticcall().unwrap(); + + let result = vm.memory.load(0x3F); + assert_eq!(result, 0x2A); + } +} diff --git a/kakarot-ssj/crates/evm/src/precompiles/modexp.cairo b/kakarot-ssj/crates/evm/src/precompiles/modexp.cairo new file mode 100644 index 000000000..d2b35b73e --- /dev/null +++ b/kakarot-ssj/crates/evm/src/precompiles/modexp.cairo @@ -0,0 +1,302 @@ +use core::cmp::{min, max}; + +use core::num::traits::Bounded; +use core::num::traits::OverflowingAdd; +// CREDITS: The implementation has take reference from +// [revm](https://github.com/bluealloy/revm/blob/main/crates/precompile/src/modexp.rs) + +use core::option::OptionTrait; +use core::starknet::EthAddress; +use core::traits::TryInto; + +use crate::errors::EVMError; + +use crate::precompiles::Precompile; +use utils::crypto::modexp::lib::modexp; +use utils::traits::bytes::{U8SpanExTrait, FromBytes}; +use utils::traits::integer::BitsUsed; + +const HEADER_LENGTH: usize = 96; +const MIN_GAS: u64 = 200; + +pub impl ModExp of Precompile { + #[inline(always)] + fn address() -> EthAddress { + 0x5.try_into().unwrap() + } + + fn exec(input: Span) -> Result<(u64, Span), EVMError> { + // The format of input is: + // + // Where every length is a 32-byte left-padded integer representing the number of bytes + // to be taken up by the next value + + // safe unwraps, since we will always get a 32 byte span + let base_len: u256 = input.slice_right_padded(0, 32).from_be_bytes().unwrap(); + let exp_len: u256 = input.slice_right_padded(32, 32).from_be_bytes().unwrap(); + let mod_len: u256 = input.slice_right_padded(64, 32).from_be_bytes().unwrap(); + + // cast base_len, exp_len , modulus_len to usize, it does not make sense to handle larger + // values + let base_len: usize = match base_len.try_into() { + Option::Some(base_len) => { base_len }, + Option::None => { + return Result::Err(EVMError::InvalidParameter('base_len casting to u32 failed')); + } + }; + let exp_len: usize = match exp_len.try_into() { + Option::Some(exp_len) => { exp_len }, + Option::None => { + return Result::Err(EVMError::InvalidParameter('exp_len casting to u32 failed')); + } + }; + let mod_len: usize = match mod_len.try_into() { + Option::Some(mod_len) => { mod_len }, + Option::None => { + return Result::Err(EVMError::InvalidParameter('mod_len casting to u32 failed')); + } + }; + + // Handle a special case when both the base and mod length is zero + if base_len == 0 && mod_len == 0 { + return Result::Ok((MIN_GAS, [].span())); + } + + // Used to extract ADJUSTED_EXPONENT_LENGTH. + let exp_highp_len = min(exp_len, 32); + + let input = if input.len() >= HEADER_LENGTH { + input.slice(HEADER_LENGTH, input.len() - HEADER_LENGTH) + } else { + [].span() + }; + + let exp_highp = { + // get right padded bytes so if data.len is less then exp_len we will get right padded + // zeroes. + let right_padded_highp = input.slice_right_padded(base_len, 32); + // If exp_len is less then 32 bytes get only exp_len bytes and do left padding. + let out = right_padded_highp.slice(0, exp_highp_len).pad_left_with_zeroes(32); + match out.from_be_bytes() { + Option::Some(result) => result, + Option::None => { + return Result::Err(EVMError::InvalidParameter('failed to extract exp_highp')); + } + } + }; + + let gas = calc_gas(base_len.into(), exp_len.into(), mod_len.into(), exp_highp); + + // Padding is needed if the input does not contain all 3 values. + let base = input.slice_right_padded(0, base_len); + let exponent = input.slice_right_padded(base_len, exp_len); + + let (mod_start_idx, _) = base_len.overflowing_add(exp_len); + + let modulus = input.slice_right_padded(mod_start_idx, mod_len); + + let output = modexp(base, exponent, modulus); + + let return_data = output.pad_left_with_zeroes(mod_len); + Result::Ok((gas.into(), return_data)) + } +} + +// Calculate gas cost according to EIP 2565: +// https://eips.ethereum.org/EIPS/eip-2565 +fn calc_gas(base_length: u64, exp_length: u64, mod_length: u64, exp_highp: u256) -> u64 { + let multiplication_complexity = calculate_multiplication_complexity(base_length, mod_length); + + let iteration_count = calculate_iteration_count(exp_length, exp_highp); + + let gas = (multiplication_complexity * iteration_count.into()) / 3; + let gas: u64 = gas.try_into().unwrap_or(Bounded::::MAX); + + max(gas, 200) +} + +fn calculate_multiplication_complexity(base_length: u64, mod_length: u64) -> u256 { + let max_length = max(base_length, mod_length); + + let _8: NonZero = 8_u64.try_into().unwrap(); + let (words, rem) = DivRem::div_rem(max_length, _8); + + let words: u256 = if rem != 0 { + (words + 1).into() + } else { + words.into() + }; + + words * words +} + +fn calculate_iteration_count(exp_length: u64, exp_highp: u256) -> u64 { + let mut iteration_count: u64 = if exp_length < 33 { + if exp_highp == 0 { + 0 + } else { + (exp_highp.bits_used() - 1).into() + } + } else { + let length_part = 8 * (exp_length - 32); + let bits_part = if exp_highp != 0 { + exp_highp.bits_used() - 1 + } else { + 0 + }; + + length_part + bits_part.into() + }; + + max(iteration_count, 1) +} + +#[cfg(tests)] +mod tests { + use core::result::ResultTrait; + use core::starknet::EthAddress; + use core::starknet::testing::set_contract_address; + + use crate::instructions::SystemOperationsTrait; + + use crate::memory::MemoryTrait; + use crate::precompiles::Precompiles; + use crate::stack::StackTrait; + use crate::test_utils::{VMBuilderTrait, native_token, other_starknet_address}; + use evm_tests::test_precompiles::test_data::test_data_modexp::{ + test_modexp_modsize0_returndatasizeFiller_data, + test_modexp_create2callPrecompiles_test0_berlin_data, test_modexp_eip198_example_1_data, + test_modexp_eip198_example_2_data, test_modexp_nagydani_1_square_data, + test_modexp_nagydani_1_qube_data + }; + use snforge_std::{start_mock_call, test_address}; + use utils::helpers::U256Trait; + + // the tests are taken from + // [revm](https://github.com/bluealloy/revm/blob/0629883f5a40e913a5d9498fa37886348c858c70/crates/precompile/src/modexp.rs#L175) + + #[test] + fn test_modexp_modsize0_returndatasizeFiller_filler() { + let mut vm = VMBuilderTrait::new_with_presets().build(); + + let (calldata, expected) = test_modexp_modsize0_returndatasizeFiller_data(); + + vm.message.target.evm = EthAddress { address: 5 }; + vm.message.data = calldata; + + let expected_gas = 44_954; + + let gas_before = vm.gas_left; + Precompiles::exec_precompile(ref vm).unwrap(); + let gas_after = vm.gas_left; + + assert_eq!(gas_before - gas_after, expected_gas); + assert_eq!(vm.return_data, expected); + } + + #[test] + fn test_modexp_create2callPrecompiles_test0_berlin() { + let mut vm = VMBuilderTrait::new_with_presets().build(); + + let (calldata, expected) = test_modexp_create2callPrecompiles_test0_berlin_data(); + + vm.message.data = calldata; + vm.message.target.evm = EthAddress { address: 5 }; + let expected_gas = 1_360; + + let gas_before = vm.gas_left; + Precompiles::exec_precompile(ref vm).unwrap(); + let gas_after = vm.gas_left; + + assert_eq!(gas_before - gas_after, expected_gas); + assert_eq!(vm.return_data, expected); + } + + #[test] + fn test_modexp_eip198_example_1() { + let mut vm = VMBuilderTrait::new_with_presets().build(); + + let (calldata, expected) = test_modexp_eip198_example_1_data(); + + vm.message.target.evm = EthAddress { address: 5 }; + vm.message.data = calldata; + let expected_gas = 1_360; + + let gas_before = vm.gas_left; + Precompiles::exec_precompile(ref vm).unwrap(); + let gas_after = vm.gas_left; + + assert_eq!(gas_before - gas_after, expected_gas); + assert_eq!(vm.return_data, expected); + } + + #[test] + fn test_modexp_eip198_example_2() { + let mut vm = VMBuilderTrait::new_with_presets().build(); + + let (calldata, expected) = test_modexp_eip198_example_2_data(); + + vm.message.target.evm = EthAddress { address: 5 }; + vm.message.data = calldata; + let expected_gas = 1_360; + + let gas_before = vm.gas_left; + Precompiles::exec_precompile(ref vm).unwrap(); + let gas_after = vm.gas_left; + + assert_eq!(gas_before - gas_after, expected_gas); + assert_eq!(vm.return_data, expected); + } + + + #[test] + fn test_modexp_nagydani_1_square() { + let mut vm = VMBuilderTrait::new_with_presets().build(); + + let (calldata, expected) = test_modexp_nagydani_1_square_data(); + + vm.message.target.evm = EthAddress { address: 5 }; + vm.message.data = calldata; + let expected_gas = 200; + + let gas_before = vm.gas_left; + Precompiles::exec_precompile(ref vm).unwrap(); + let gas_after = vm.gas_left; + + assert_eq!(gas_before - gas_after, expected_gas); + assert_eq!(vm.return_data, expected); + } + + #[test] + fn test_modexp_nagydani_1_qube() { + let mut vm = VMBuilderTrait::new_with_presets().build(); + + let (calldata, expected) = test_modexp_nagydani_1_qube_data(); + + vm.message.target.evm = EthAddress { address: 5 }; + vm.message.data = calldata; + let expected_gas = 200; + + let gas_before = vm.gas_left; + Precompiles::exec_precompile(ref vm).unwrap(); + let gas_after = vm.gas_left; + + assert_eq!(gas_before - gas_after, expected_gas); + assert_eq!(vm.return_data, expected); + } + + #[test] + fn test_modexp_berlin_empty_input() { + let mut vm = VMBuilderTrait::new_with_presets().build(); + + let calldata = [].span(); + let expected = [].span(); + + vm.message.target.evm = EthAddress { address: 5 }; + vm.message.data = calldata; + + Precompiles::exec_precompile(ref vm).unwrap(); + + assert_eq!(vm.return_data, expected); + } +} diff --git a/kakarot-ssj/crates/evm/src/precompiles/p256verify.cairo b/kakarot-ssj/crates/evm/src/precompiles/p256verify.cairo new file mode 100644 index 000000000..fd5efe49f --- /dev/null +++ b/kakarot-ssj/crates/evm/src/precompiles/p256verify.cairo @@ -0,0 +1,251 @@ +use core::starknet::SyscallResultTrait; +use core::starknet::secp256_trait::{Secp256Trait}; +use core::starknet::{EthAddress, secp256r1::{Secp256r1Point}, secp256_trait::is_valid_signature}; +use crate::errors::{EVMError}; +use crate::precompiles::Precompile; +use utils::traits::bytes::FromBytes; + +const P256VERIFY_PRECOMPILE_GAS_COST: u64 = 3450; + +const ONE_32_BYTES: [ + u8 + ; 32] = [ + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01 +]; + +pub impl P256Verify of Precompile { + #[inline(always)] + fn address() -> EthAddress { + 0x100.try_into().unwrap() + } + + fn exec(input: Span) -> Result<(u64, Span), EVMError> { + let gas = P256VERIFY_PRECOMPILE_GAS_COST; + + if input.len() != 160 { + return Result::Ok((gas, [].span())); + } + + let message_hash = input.slice(0, 32); + let message_hash = match message_hash.from_be_bytes() { + Option::Some(message_hash) => message_hash, + Option::None => { return Result::Ok((gas, [].span())); } + }; + + let r: Option = input.slice(32, 32).from_be_bytes(); + let r = match r { + Option::Some(r) => r, + Option::None => { return Result::Ok((gas, [].span())); } + }; + + let s: Option = input.slice(64, 32).from_be_bytes(); + let s = match s { + Option::Some(s) => s, + Option::None => { return Result::Ok((gas, [].span())); } + }; + + let x: Option = input.slice(96, 32).from_be_bytes(); + let x = match x { + Option::Some(x) => x, + Option::None => { return Result::Ok((gas, [].span())); } + }; + + let y: Option = input.slice(128, 32).from_be_bytes(); + let y = match y { + Option::Some(y) => y, + Option::None => { return Result::Ok((gas, [].span())); } + }; + + let public_key: Option = Secp256Trait::secp256_ec_new_syscall(x, y) + .unwrap_syscall(); + let public_key = match public_key { + Option::Some(public_key) => public_key, + Option::None => { return Result::Ok((gas, [].span())); } + }; + + if !is_valid_signature(message_hash, r, s, public_key) { + return Result::Ok((gas, [].span())); + } + + return Result::Ok((gas, ONE_32_BYTES.span())); + } +} + +#[cfg(test)] +mod tests { + use core::array::ArrayTrait; + use crate::instructions::SystemOperationsTrait; + use crate::memory::MemoryTrait; + + use crate::precompiles::p256verify::P256Verify; + use crate::stack::StackTrait; + use crate::test_utils::{VMBuilderTrait}; + use crate::test_utils::{setup_test_environment, native_token}; + use snforge_std::start_mock_call; + use utils::traits::bytes::{ToBytes, FromBytes}; + + + // source: + // + #[test] + fn test_p256verify_precompile() { + let msg_hash = 0x4cee90eb86eaa050036147a12d49004b6b9c72bd725d39d4785011fe190f0b4d_u256 + .to_be_bytes_padded(); + let r = 0xa73bd4903f0ce3b639bbbf6e8e80d16931ff4bcf5993d58468e8fb19086e8cac_u256 + .to_be_bytes_padded(); + let s = 0x36dbcd03009df8c59286b162af3bd7fcc0450c9aa81be5d10d312af6c66b1d60_u256 + .to_be_bytes_padded(); + let x = 0x4aebd3099c618202fcfe16ae7770b0c49ab5eadf74b754204a3bb6060e44eff3_u256 + .to_be_bytes_padded(); + let y = 0x7618b065f9832de4ca6ca971a7a1adc826d0f7c00181a5fb2ddf79ae00b4e10e_u256 + .to_be_bytes_padded(); + + let mut calldata = array![]; + calldata.append_span(msg_hash); + calldata.append_span(r); + calldata.append_span(s); + calldata.append_span(x); + calldata.append_span(y); + + let (gas, result) = P256Verify::exec(calldata.span()).unwrap(); + + let result: u256 = result.from_be_bytes().expect('p256verify_precompile_test'); + assert_eq!(result, 0x01); + assert_eq!(gas, 3450); + } + + // source: + // + #[test] + //TODO(sn-foundry): fix or delete + fn test_p256verify_precompile_static_call() { + setup_test_environment(); + + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm + .memory + .store( + 0x4cee90eb86eaa050036147a12d49004b6b9c72bd725d39d4785011fe190f0b4d, 0x0 + ); // msg_hash + vm + .memory + .store(0xa73bd4903f0ce3b639bbbf6e8e80d16931ff4bcf5993d58468e8fb19086e8cac, 0x20); // r + vm + .memory + .store(0x36dbcd03009df8c59286b162af3bd7fcc0450c9aa81be5d10d312af6c66b1d60, 0x40); // s + vm + .memory + .store(0x4aebd3099c618202fcfe16ae7770b0c49ab5eadf74b754204a3bb6060e44eff3, 0x60); // x + vm + .memory + .store(0x7618b065f9832de4ca6ca971a7a1adc826d0f7c00181a5fb2ddf79ae00b4e10e, 0x80); // y + + vm.stack.push(0x20).unwrap(); // retSize + vm.stack.push(0xa0).unwrap(); // retOffset + vm.stack.push(0xa0).unwrap(); // argsSize + vm.stack.push(0x0).unwrap(); // argsOffset + vm.stack.push(0x100).unwrap(); // address + vm.stack.push(0xFFFFFFFF).unwrap(); // gas + + start_mock_call::(native_token(), selector!("balanceOf"), 0); + vm.exec_staticcall().unwrap(); + + let mut result = Default::default(); + vm.memory.load_n(0x20, ref result, 0xa0); + + assert_eq!(result.span(), super::ONE_32_BYTES.span()); + } + + #[test] + fn test_p256verify_precompile_input_too_short() { + let msg_hash = 0x4cee90eb86eaa050036147a12d49004b6b9c72bd725d39d4785011fe190f0b4d_u256 + .to_be_bytes_padded(); + let r = 0xa73bd4903f0ce3b639bbbf6e8e80d16931ff4bcf5993d58468e8fb19086e8cac_u256 + .to_be_bytes_padded(); + let s = 0x36dbcd03009df8c59286b162af3bd7fcc0450c9aa81be5d10d312af6c66b1d60_u256 + .to_be_bytes_padded(); + let x = 0x4aebd3099c618202fcfe16ae7770b0c49ab5eadf74b754204a3bb6060e44eff3_u256 + .to_be_bytes_padded(); + + let mut calldata = array![]; + calldata.append_span(msg_hash); + calldata.append_span(r); + calldata.append_span(s); + calldata.append_span(x); + + let (gas, result) = P256Verify::exec(calldata.span()).unwrap(); + + assert_eq!(result, [].span()); + assert_eq!(gas, 3450); + } + + //TODO(sn-foundry): fix or delete + #[test] + fn test_p256verify_precompile_input_too_short_static_call() { + setup_test_environment(); + + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm + .memory + .store( + 0x4cee90eb86eaa050036147a12d49004b6b9c72bd725d39d4785011fe190f0b4d, 0x0 + ); // msg_hash + vm + .memory + .store(0xa73bd4903f0ce3b639bbbf6e8e80d16931ff4bcf5993d58468e8fb19086e8cac, 0x20); // r + vm + .memory + .store(0x36dbcd03009df8c59286b162af3bd7fcc0450c9aa81be5d10d312af6c66b1d60, 0x40); // s + vm + .memory + .store(0x4aebd3099c618202fcfe16ae7770b0c49ab5eadf74b754204a3bb6060e44eff3, 0x60); // x + + vm.stack.push(0x01).unwrap(); // retSize + vm.stack.push(0x80).unwrap(); // retOffset + vm.stack.push(0x80).unwrap(); // argsSize + vm.stack.push(0x0).unwrap(); // argsOffset + vm.stack.push(0x100).unwrap(); // address + vm.stack.push(0xFFFFFFFF).unwrap(); // gas + + start_mock_call::(native_token(), selector!("balanceOf"), 0); + vm.exec_staticcall().unwrap(); + + let mut result = Default::default(); + vm.memory.load_n(0x1, ref result, 0x80); + + assert_eq!(result, array![0]); + } +} diff --git a/kakarot-ssj/crates/evm/src/precompiles/sha256.cairo b/kakarot-ssj/crates/evm/src/precompiles/sha256.cairo new file mode 100644 index 000000000..af9174531 --- /dev/null +++ b/kakarot-ssj/crates/evm/src/precompiles/sha256.cairo @@ -0,0 +1,171 @@ +use core::sha256::compute_sha256_u32_array; +use core::starknet::EthAddress; +use crate::errors::EVMError; +use crate::precompiles::Precompile; +use utils::math::Bitshift; +use utils::traits::bytes::{FromBytes, ToBytes}; + +const BASE_COST: u64 = 60; +const COST_PER_WORD: u64 = 12; + +pub impl Sha256 of Precompile { + #[inline(always)] + fn address() -> EthAddress { + 0x2.try_into().unwrap() + } + + fn exec(mut input: Span) -> Result<(u64, Span), EVMError> { + let data_word_size = ((input.len() + 31) / 32).into(); + let gas = BASE_COST + data_word_size * COST_PER_WORD; + + let mut sha256_input: Array = array![]; + while let Option::Some(bytes4) = input.multi_pop_front::<4>() { + let bytes4 = (*bytes4).unbox(); + sha256_input.append(FromBytes::from_be_bytes(bytes4.span()).unwrap()); + }; + let (last_input_word, last_input_num_bytes) = if input.len() == 0 { + (0, 0) + } else { + let mut last_input_word: u32 = 0; + let mut last_input_num_bytes: u32 = 0; + for remaining_byte in input { + last_input_word = last_input_word.shl(8) + (*remaining_byte).into(); + last_input_num_bytes += 1; + }; + (last_input_word, last_input_num_bytes) + }; + let result_words_32: [u32; 8] = compute_sha256_u32_array( + sha256_input, last_input_word, last_input_num_bytes + ); + let mut result_bytes = array![]; + for word in result_words_32 + .span() { + let word_bytes = (*word).to_be_bytes_padded(); + result_bytes.append_span(word_bytes); + }; + + return Result::Ok((gas, result_bytes.span())); + } +} + +#[cfg(test)] +mod tests { + use core::result::ResultTrait; + use crate::instructions::SystemOperationsTrait; + + use crate::memory::MemoryTrait; + use crate::precompiles::sha256::Sha256; + use crate::stack::StackTrait; + use crate::test_utils::{ + VMBuilderTrait, MemoryTestUtilsTrait, native_token, setup_test_environment + }; + use snforge_std::{start_mock_call}; + use utils::traits::bytes::{ToBytes, FromBytes}; + + //source: + // + #[test] + fn test_sha_256_precompile() { + let calldata = array![0xFF,]; + + let (gas, result) = Sha256::exec(calldata.span()).unwrap(); + + let result: u256 = result.from_be_bytes().unwrap(); + let expected_result = 0xa8100ae6aa1940d0b663bb31cd466142ebbdbd5187131b92d93818987832eb89; + + assert_eq!(result, expected_result); + assert_eq!(gas, 72); + } + + #[test] + fn test_sha_256_precompile_full_word() { + let calldata = ToBytes::to_be_bytes( + 0xa8100ae6aa1940d0b663bb31cd466142ebbdbd5187131b92d93818987832eb89_u256 + ); + + let (gas, result) = Sha256::exec(calldata).unwrap(); + + let result: u256 = result.from_be_bytes().unwrap(); + let expected_result = 0xc0b057f584795eff8b06d5e420e71d747587d20de836f501921fd1b5741f1283; + + assert_eq!(result, expected_result); + assert_eq!(gas, 72); + } + + #[test] + fn test_sha256_more_than_32_bytes() { + let calldata = [ + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xf3, + 0x45, + 0x78, + 0x90, + 0x7f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00 + ]; + + let (gas, result) = Sha256::exec(calldata.span()).unwrap(); + + let result: u256 = result.from_be_bytes().unwrap(); + let expected_result = 0x3b745a1c00d035c334f358d007a430e4cf0ae63aa0556fb05529706de546464d; + + assert_eq!(result, expected_result); + assert_eq!(gas, 84); // BASE + 2 WORDS + } + + + // source: + // + #[test] + fn test_sha_256_precompile_static_call() { + setup_test_environment(); + + let mut vm = VMBuilderTrait::new_with_presets().build(); + + vm.stack.push(0x20).unwrap(); // retSize + vm.stack.push(0x20).unwrap(); // retOffset + vm.stack.push(0x1).unwrap(); // argsSize + vm.stack.push(0x1F).unwrap(); // argsOffset + vm.stack.push(0x2).unwrap(); // address + vm.stack.push(0xFFFFFFFF).unwrap(); // gas + + vm.memory.store_with_expansion(0xFF, 0x0); + + start_mock_call::(native_token(), selector!("balanceOf"), 0); + vm.exec_staticcall().unwrap(); + + let result = vm.memory.load(0x20); + let expected_result = 0xa8100ae6aa1940d0b663bb31cd466142ebbdbd5187131b92d93818987832eb89; + assert_eq!(result, expected_result); + } +} diff --git a/kakarot-ssj/crates/evm/src/stack.cairo b/kakarot-ssj/crates/evm/src/stack.cairo new file mode 100644 index 000000000..506e87d9f --- /dev/null +++ b/kakarot-ssj/crates/evm/src/stack.cairo @@ -0,0 +1,635 @@ +use core::dict::{Felt252Dict, Felt252DictTrait}; +//! Stack implementation. +//! # Example +//! ``` +//! use crate::stack::StackTrait; +//! +//! // Create a new stack instance. +//! let mut stack = StackTrait::new(); +//! let val_1: u256 = 1.into(); +//! let val_2: u256 = 1.into(); + +//! stack.push(val_1)?; +//! stack.push(val_2)?; + +//! let value = stack.pop()?; +//! ``` +use core::nullable::{NullableTrait}; +use core::num::traits::Bounded; +use core::starknet::EthAddress; +use crate::errors::{ensure, EVMError}; + +use utils::constants; +use utils::i256::i256; +use utils::traits::{TryIntoResult}; + + +//TODO(optimization): make len `felt252` based to avoid un-necessary checks +#[derive(Destruct, Default)] +pub struct Stack { + pub items: Felt252Dict>, + pub len: usize, +} + +pub trait StackTrait { + fn new() -> Stack; + fn push(ref self: Stack, item: u256) -> Result<(), EVMError>; + fn pop(ref self: Stack) -> Result; + fn pop_usize(ref self: Stack) -> Result; + fn pop_saturating_usize(ref self: Stack) -> Result; + fn pop_u64(ref self: Stack) -> Result; + fn pop_saturating_u64(ref self: Stack) -> Result; + fn pop_u128(ref self: Stack) -> Result; + fn pop_saturating_u128(ref self: Stack) -> Result; + fn pop_i256(ref self: Stack) -> Result; + fn pop_eth_address(ref self: Stack) -> Result; + fn pop_n(ref self: Stack, n: usize) -> Result, EVMError>; + fn peek(ref self: Stack) -> Option; + fn peek_at(ref self: Stack, index: usize) -> Result; + fn swap_i(ref self: Stack, index: usize) -> Result<(), EVMError>; + fn len(self: @Stack) -> usize; + fn is_empty(self: @Stack) -> bool; +} + +impl StackImpl of StackTrait { + #[inline(always)] + fn new() -> Stack { + Default::default() + } + + /// Pushes a new bytes32 word onto the stack. + /// + /// The item is stored at the current length of the stack. + /// + /// # Errors + /// + /// If the stack is full, returns with a StackOverflow error. + #[inline(always)] + fn push(ref self: Stack, item: u256) -> Result<(), EVMError> { + let length = self.len(); + // we can store at most 1024 256-bits words + ensure(length != constants::STACK_MAX_DEPTH, EVMError::StackOverflow)?; + + self.items.insert(length.into(), NullableTrait::new(item)); + self.len += 1; + Result::Ok(()) + } + + /// Pops the top item off the stack. + /// + /// # Errors + /// + /// If the stack is empty, returns with a StackUnderflow error. + #[inline(always)] + fn pop(ref self: Stack) -> Result { + ensure(self.len() != 0, EVMError::StackUnderflow)?; + + self.len -= 1; + let item = self.items.get(self.len().into()); + Result::Ok(item.deref()) + } + + /// Calls `Stack::pop` and tries to convert it to usize + /// + /// # Errors + /// + /// Returns `EVMError::StackError` with appropriate message + /// In case: + /// - Stack is empty + /// - Type conversion failed + #[inline(always)] + fn pop_usize(ref self: Stack) -> Result { + let item: u256 = self.pop()?; + let item: usize = item.try_into_result()?; + Result::Ok(item) + } + + /// Calls `Stack::pop` and saturates the result to usize + #[inline(always)] + fn pop_saturating_usize(ref self: Stack) -> Result { + let item: u256 = self.pop()?; + if item.high != 0 { + return Result::Ok(Bounded::::MAX); + }; + match item.low.try_into() { + Option::Some(value) => Result::Ok(value), + Option::None => Result::Ok(Bounded::::MAX), + } + } + + /// Calls `Stack::pop` and tries to convert it to u64 + /// + /// # Errors + /// + /// Returns `EVMError::StackError` with appropriate message + /// In case: + /// - Stack is empty + /// - Type conversion failed + #[inline(always)] + fn pop_u64(ref self: Stack) -> Result { + let item: u256 = self.pop()?; + let item: u64 = item.try_into_result()?; + Result::Ok(item) + } + + /// Calls `Stack::pop` and saturates the result to u64 + #[inline(always)] + fn pop_saturating_u64(ref self: Stack) -> Result { + let item: u256 = self.pop()?; + if item.high != 0 { + return Result::Ok(Bounded::::MAX); + }; + match item.low.try_into() { + Option::None => Result::Ok(Bounded::::MAX), + Option::Some(value) => Result::Ok(value), + } + } + + /// Calls `Stack::pop` and convert it to i256 + /// + /// # Errors + /// + /// Returns `EVMError::StackError` with appropriate message + /// In case: + /// - Stack is empty + #[inline(always)] + fn pop_i256(ref self: Stack) -> Result { + let item: u256 = self.pop()?; + let item: i256 = item.into(); + Result::Ok(item) + } + + + /// Calls `Stack::pop` and tries to convert it to u128 + /// + /// # Errors + /// + /// Returns `EVMError::StackError` with appropriate message + /// In case: + /// - Stack is empty + /// - Type conversion failed + #[inline(always)] + fn pop_u128(ref self: Stack) -> Result { + let item: u256 = self.pop()?; + let item: u128 = item.try_into_result()?; + Result::Ok(item) + } + + /// Calls `Stack::pop` and saturates the result to u128 + /// + #[inline(always)] + fn pop_saturating_u128(ref self: Stack) -> Result { + let item: u256 = self.pop()?; + if item.high != 0 { + return Result::Ok(Bounded::::MAX); + }; + Result::Ok(item.low) + } + + /// Calls `Stack::pop` and converts it to usize + /// + /// # Errors + /// + /// Returns `EVMError::StackError` with appropriate message + /// In case: + /// - Stack is empty + #[inline(always)] + fn pop_eth_address(ref self: Stack) -> Result { + let item: u256 = self.pop()?; + let item: EthAddress = item.into(); + Result::Ok(item) + } + + /// Pops N elements from the stack. + /// + /// # Errors + /// + /// If the stack length is less than than N, returns with a StackUnderflow error. + fn pop_n(ref self: Stack, mut n: usize) -> Result, EVMError> { + ensure(!(n > self.len()), EVMError::StackUnderflow)?; + let mut popped_items = ArrayTrait::::new(); + for _ in 0..n { + popped_items.append(self.pop().unwrap()); + }; + Result::Ok(popped_items) + } + + /// Peeks at the top item on the stack. + /// + /// # Errors + /// + /// If the stack is empty, returns None. + #[inline(always)] + fn peek(ref self: Stack) -> Option { + if self.len() == 0 { + Option::None(()) + } else { + let last_index = self.len() - 1; + let item = self.items.get(last_index.into()); + Option::Some(item.deref()) + } + } + + /// Peeks at the item at the given index on the stack. + /// index is 0-based, where 0 is the top of the stack (most recently pushed item). + /// + /// # Errors + /// + /// If the index is greater than the stack length, returns with a StackUnderflow error. + #[inline(always)] + fn peek_at(ref self: Stack, index: usize) -> Result { + ensure(index < self.len(), EVMError::StackUnderflow)?; + + let position = self.len() - 1 - index; + let item = self.items.get(position.into()); + + Result::Ok(item.deref()) + } + + /// Swaps the item at the given index with the item on top of the stack. + /// index is 0-based, where 0 would mean no swap (top item swapped with itself). + #[inline(always)] + fn swap_i(ref self: Stack, index: usize) -> Result<(), EVMError> { + ensure(index < self.len(), EVMError::StackUnderflow)?; + + let position_0: felt252 = self.len().into() - 1; + let position_item: felt252 = position_0 - index.into(); + let top_item = self.items.get(position_0); + let swapped_item = self.items.get(position_item); + self.items.insert(position_0, swapped_item.into()); + self.items.insert(position_item, top_item.into()); + Result::Ok(()) + } + + /// Returns the length of the stack. + #[inline(always)] + fn len(self: @Stack) -> usize { + *self.len + } + + /// Returns true if the stack is empty. + #[inline(always)] + fn is_empty(self: @Stack) -> bool { + self.len() == 0 + } +} + +#[cfg(test)] +mod tests { + // Core lib imports + + // Internal imports + use crate::stack::StackTrait; + use utils::constants; + + #[test] + fn test_stack_new_should_return_empty_stack() { + // When + let mut stack = StackTrait::new(); + + // Then + assert_eq!(stack.len(), 0); + } + + #[test] + fn test_empty_should_return_if_stack_is_empty() { + // Given + let mut stack = StackTrait::new(); + + // Then + assert!(stack.is_empty()); + + // When + stack.push(1).unwrap(); + // Then + assert!(!stack.is_empty()); + } + + #[test] + fn test_len_should_return_the_length_of_the_stack() { + // Given + let mut stack = StackTrait::new(); + + // Then + assert_eq!(stack.len(), 0); + + // When + stack.push(1).unwrap(); + // Then + assert_eq!(stack.len(), 1); + } + + mod push { + use crate::errors::{EVMError}; + use super::StackTrait; + + use super::constants; + + #[test] + fn test_should_add_an_element_to_the_stack() { + // Given + let mut stack = StackTrait::new(); + + // When + stack.push(1).unwrap(); + + // Then + let res = stack.peek().unwrap(); + + assert_eq!(stack.is_empty(), false); + assert_eq!(stack.len(), 1); + assert_eq!(res, 1); + } + + #[test] + fn test_should_fail_when_overflow() { + // Given + let mut stack = StackTrait::new(); + + // When + for _ in 0..constants::STACK_MAX_DEPTH { + stack.push(1).unwrap(); + }; + + // Then + let res = stack.push(1); + assert_eq!(stack.len(), constants::STACK_MAX_DEPTH); + assert!(res.is_err()); + assert_eq!(res.unwrap_err(), EVMError::StackOverflow); + } + } + + mod pop { + use core::num::traits::Bounded; + use crate::errors::EVMError; + use super::StackTrait; + use utils::traits::StorageBaseAddressPartialEq; + + #[test] + fn test_should_pop_an_element_from_the_stack() { + // Given + let mut stack = StackTrait::new(); + stack.push(1).unwrap(); + stack.push(2).unwrap(); + stack.push(3).unwrap(); + + // When + let last_item = stack.pop().unwrap(); + + // Then + assert_eq!(last_item, 3); + assert_eq!(stack.len(), 2); + } + + + #[test] + fn test_should_pop_N_elements_from_the_stack() { + // Given + let mut stack = StackTrait::new(); + stack.push(1).unwrap(); + stack.push(2).unwrap(); + stack.push(3).unwrap(); + + // When + let elements = stack.pop_n(3).unwrap(); + + // Then + assert_eq!(stack.len(), 0); + assert_eq!(elements.len(), 3); + assert_eq!(elements.span(), [3, 2, 1].span()) + } + + + #[test] + fn test_pop_return_err_when_stack_underflow() { + // Given + let mut stack = StackTrait::new(); + + // When & Then + let result = stack.pop(); + assert(result.is_err(), 'should return Err '); + assert!( + result.unwrap_err() == EVMError::StackUnderflow, "should return StackUnderflow" + ); + } + + #[test] + fn test_pop_n_should_return_err_when_stack_underflow() { + // Given + let mut stack = StackTrait::new(); + stack.push(1).unwrap(); + + // When & Then + let result = stack.pop_n(2); + assert(result.is_err(), 'should return Error'); + assert!( + result.unwrap_err() == EVMError::StackUnderflow, "should return StackUnderflow" + ); + } + + #[test] + fn test_pop_saturating_usize_should_return_max_when_overflow() { + // Given + let mut stack = StackTrait::new(); + stack.push(Bounded::::MAX.into()).unwrap(); + + // When + let result = stack.pop_saturating_usize(); + assert!(result.is_ok()); + assert_eq!(result.unwrap(), Bounded::::MAX); + } + + #[test] + fn test_pop_saturating_usize_should_return_value_when_no_overflow() { + // Given + let mut stack = StackTrait::new(); + stack.push(1234567890).unwrap(); + + // When + let result = stack.pop_saturating_usize(); + assert!(result.is_ok()); + assert_eq!(result.unwrap(), 1234567890); + } + + + #[test] + fn test_pop_saturating_u64_should_return_max_when_overflow() { + // Given + let mut stack = StackTrait::new(); + stack.push(Bounded::::MAX).unwrap(); + + // When + let result = stack.pop_saturating_u64(); + assert!(result.is_ok()); + assert_eq!(result.unwrap(), Bounded::::MAX); + } + + #[test] + fn test_pop_saturating_u64_should_return_value_when_no_overflow() { + // Given + let mut stack = StackTrait::new(); + stack.push(1234567890).unwrap(); + + // When + let result = stack.pop_saturating_u64(); + + // Then + assert!(result.is_ok()); + assert_eq!(result.unwrap(), 1234567890); + } + + + #[test] + fn test_pop_saturating_u128_should_return_max_when_overflow() { + // Given + let mut stack = StackTrait::new(); + stack.push(Bounded::::MAX).unwrap(); + + // When + let result = stack.pop_saturating_u128(); + + // Then + assert!(result.is_ok()); + assert_eq!(result.unwrap(), Bounded::::MAX); + } + + #[test] + fn test_pop_saturating_u128_should_return_value_when_no_overflow() { + // Given + let mut stack = StackTrait::new(); + stack.push(1234567890).unwrap(); + + // When + let result = stack.pop_saturating_u128(); + + // Then + assert!(result.is_ok()); + assert_eq!(result.unwrap(), 1234567890); + } + } + + mod peek { + use crate::errors::{EVMError}; + use super::StackTrait; + + #[test] + fn test_should_return_last_item() { + // Given + let mut stack = StackTrait::new(); + + // When + stack.push(1).unwrap(); + stack.push(2).unwrap(); + + // Then + let last_item = stack.peek().unwrap(); + assert_eq!(last_item, 2); + } + + + #[test] + fn test_should_return_stack_at_given_index_when_value_is_0() { + // Given + let mut stack = StackTrait::new(); + stack.push(1).unwrap(); + stack.push(2).unwrap(); + stack.push(3).unwrap(); + + // When + let result = stack.peek_at(0).unwrap(); + + // Then + assert_eq!(result, 3); + } + + #[test] + fn test_should_return_stack_at_given_index_when_value_is_1() { + // Given + let mut stack = StackTrait::new(); + stack.push(1).unwrap(); + stack.push(2).unwrap(); + stack.push(3).unwrap(); + + // When + let result = stack.peek_at(1).unwrap(); + + // Then + assert_eq!(result, 2); + } + + #[test] + fn test_should_return_err_when_underflow() { + // Given + let mut stack = StackTrait::new(); + + // When & Then + let result = stack.peek_at(1); + + assert(result.is_err(), 'should return an EVMError'); + assert!( + result.unwrap_err() == EVMError::StackUnderflow, "should return StackUnderflow" + ); + } + } + + mod swap { + use crate::errors::{EVMError}; + use super::StackTrait; + + #[test] + fn test_should_swap_2_stack_items() { + // Given + let mut stack = StackTrait::new(); + stack.push(1).unwrap(); + stack.push(2).unwrap(); + stack.push(3).unwrap(); + stack.push(4).unwrap(); + let index3 = stack.peek_at(3).unwrap(); + assert_eq!(index3, 1); + let index2 = stack.peek_at(2).unwrap(); + assert_eq!(index2, 2); + let index1 = stack.peek_at(1).unwrap(); + assert_eq!(index1, 3); + let index0 = stack.peek_at(0).unwrap(); + assert_eq!(index0, 4); + + // When + stack.swap_i(2).expect('swap failed'); + + // Then + let index3 = stack.peek_at(3).unwrap(); + assert_eq!(index3, 1); + let index2 = stack.peek_at(2).unwrap(); + assert_eq!(index2, 4); + let index1 = stack.peek_at(1).unwrap(); + assert_eq!(index1, 3); + let index0 = stack.peek_at(0).unwrap(); + assert_eq!(index0, 2); + } + + #[test] + fn test_should_return_err_when_index_1_is_underflow() { + // Given + let mut stack = StackTrait::new(); + + // When & Then + let result = stack.swap_i(1); + + assert!(result.is_err()); + assert_eq!(result.unwrap_err(), EVMError::StackUnderflow); + } + + #[test] + fn test_should_return_err_when_index_2_is_underflow() { + // Given + let mut stack = StackTrait::new(); + stack.push(1).unwrap(); + + // When & Then + let result = stack.swap_i(2); + + assert!(result.is_err()); + assert_eq!(result.unwrap_err(), EVMError::StackUnderflow); + } + } +} diff --git a/kakarot-ssj/crates/evm/src/state.cairo b/kakarot-ssj/crates/evm/src/state.cairo new file mode 100644 index 000000000..0ea8ce3ca --- /dev/null +++ b/kakarot-ssj/crates/evm/src/state.cairo @@ -0,0 +1,784 @@ +use core::dict::{Felt252Dict, Felt252DictTrait}; +use core::hash::{HashStateTrait, HashStateExTrait}; +use core::nullable::{match_nullable, FromNullableResult}; +use core::num::traits::{OverflowingAdd, OverflowingSub}; +use core::poseidon::PoseidonTrait; +use core::starknet::storage_access::{StorageBaseAddress, storage_base_address_from_felt252}; +use core::starknet::{EthAddress}; +use crate::backend::starknet_backend::fetch_original_storage; + +use crate::errors::{ensure, EVMError, BALANCE_OVERFLOW}; +use crate::model::account::{AccountTrait}; +use crate::model::{Event, Transfer, Account}; +use utils::set::{Set, SetTrait}; + +/// The `StateChangeLog` tracks the changes applied to storage during the execution of a +/// transaction. +/// Upon exiting an execution context, contextual changes must be finalized into transactional +/// changes. +/// Upon exiting the transaction, transactional changes must be finalized into storage updates. +/// +/// # Type Parameters +/// +/// * `T` - The type of values stored in the log. +/// +/// # Fields +/// +/// * `changes` - A `Felt252Dict` of contextual changes. Tracks the changes applied inside a single +/// execution context. +/// * `keyset` - An `Array` of contextual keys. +pub struct StateChangeLog { + pub changes: Felt252Dict>, + pub keyset: Set, +} + +impl StateChangeLogDestruct> of Destruct> { + fn destruct(self: StateChangeLog) nopanic { + self.changes.squash(); + } +} + +impl StateChangeLogDefault> of Default> { + fn default() -> StateChangeLog { + StateChangeLog { changes: Default::default(), keyset: Default::default(), } + } +} + +#[generate_trait] +impl StateChangeLogImpl, +Copy> of StateChangeLogTrait { + /// Reads a value from the StateChangeLog. Starts by looking for the value in the + /// contextual changes. If the value is not found, looks for it in the + /// transactional changes. + /// + /// # Arguments + /// + /// * `self` - A reference to a `StateChangeLog` instance. + /// * `key` - The key of the value to read. + /// + /// # Returns + /// + /// An `Option` containing the value if it exists, or `None` if it does not. + #[inline(always)] + fn read(ref self: StateChangeLog, key: felt252) -> Option { + match match_nullable(self.changes.get(key)) { + FromNullableResult::Null => { Option::None }, + FromNullableResult::NotNull(value) => Option::Some(value.unbox()), + } + } + + /// Writes a value to the StateChangeLog. + /// Values written to the StateChangeLog are not written to storage until the StateChangeLog is + /// totally finalized at the end of the transaction. + /// + /// # Arguments + /// + /// * `self` - A mutable reference to a `StateChangeLog` instance. + /// * `key` - The key of the value to write. + /// * `value` - The value to write. + #[inline(always)] + fn write(ref self: StateChangeLog, key: felt252, value: T) { + self.changes.insert(key, NullableTrait::new(value)); + self.keyset.add(key); + } + + /// Creates a clone of the current StateChangeLog. + /// + /// # Arguments + /// + /// * `self` - A reference to the `StateChangeLog` instance to clone. + /// + /// # Returns + /// + /// A new `StateChangeLog` instance with the same contents as the original. + fn clone(ref self: StateChangeLog) -> StateChangeLog { + let mut cloned_changes = Default::default(); + let mut keyset_span = self.keyset.to_span(); + for key in keyset_span { + let value = self.changes.get(*key).deref(); + cloned_changes.insert(*key, NullableTrait::new(value)); + }; + + StateChangeLog { changes: cloned_changes, keyset: self.keyset.clone(), } + } +} + +#[derive(Default, Destruct)] +pub struct State { + /// Accounts states - without storage and balances, which are handled separately. + pub accounts: StateChangeLog, + /// Account storage states. `EthAddress` indicates the target contract, + /// `u256` indicates the storage key. + /// `u256` indicates the value stored. + /// We have to store the target contract, as we can't derive it from the + /// hashed address only when finalizing. + pub accounts_storage: StateChangeLog<(EthAddress, u256, u256)>, + /// Account states + /// Pending emitted events + pub events: Array, + /// Pending transfers + pub transfers: Array, + /// Account transient storage states. `EthAddress` indicates the target contract, + /// `u256` indicates the storage key. + /// `u256` indicates the value stored. + pub transient_account_storage: StateChangeLog<(EthAddress, u256, u256)>, +} + +#[generate_trait] +pub impl StateImpl of StateTrait { + /// Retrieves an account from the state, creating it if it doesn't exist. + /// + /// # Arguments + /// + /// * `self` - A mutable reference to the `State` instance. + /// * `evm_address` - The EVM address of the account to retrieve. + /// + /// # Returns + /// + /// The `Account` associated with the given EVM address. + fn get_account(ref self: State, evm_address: EthAddress) -> Account { + let maybe_account = self.accounts.read(evm_address.into()); + match maybe_account { + Option::Some(acc) => { return acc; }, + Option::None => { + let account = AccountTrait::fetch_or_create(evm_address); + self.accounts.write(evm_address.into(), account); + return account; + } + } + } + + /// Sets an account in the state. + /// + /// # Arguments + /// + /// * `self` - A mutable reference to the `State` instance. + /// * `account` - The `Account` to set. + #[inline(always)] + fn set_account(ref self: State, account: Account) { + let evm_address = account.evm_address(); + + self.accounts.write(evm_address.into(), account) + } + + /// Reads a value from the state for a given EVM address and key. + /// + /// # Arguments + /// + /// * `self` - A mutable reference to the `State` instance. + /// * `evm_address` - The EVM address of the account. + /// * `key` - The storage key. + /// + /// # Returns + /// + /// The value stored at the given address and key. + #[inline(always)] + fn read_state(ref self: State, evm_address: EthAddress, key: u256) -> u256 { + let internal_key = compute_storage_key(evm_address, key); + let maybe_entry = self.accounts_storage.read(internal_key); + match maybe_entry { + Option::Some((_, _, value)) => { return value; }, + Option::None => { + let account = self.get_account(evm_address); + return fetch_original_storage(@account, key); + } + } + } + + /// Writes a value to the state for a given EVM address and key. + /// + /// # Arguments + /// + /// * `self` - A mutable reference to the `State` instance. + /// * `evm_address` - The EVM address of the account. + /// * `key` - The storage key. + /// * `value` - The value to write. + #[inline(always)] + fn write_state(ref self: State, evm_address: EthAddress, key: u256, value: u256) { + let internal_key = compute_storage_key(evm_address, key); + self.accounts_storage.write(internal_key.into(), (evm_address, key, value)); + } + + /// Adds an event to the state. + /// + /// # Arguments + /// + /// * `self` - A mutable reference to the `State` instance. + /// * `event` - The `Event` to add. + #[inline(always)] + fn add_event(ref self: State, event: Event) { + self.events.append(event) + } + + /// Adds a transfer to the state and updates account balances. + /// + /// # Arguments + /// + /// * `self` - A mutable reference to the `State` instance. + /// * `transfer` - The `Transfer` to add. + /// + /// # Returns + /// + /// A `Result` indicating success or an `EVMError` if the transfer fails. + #[inline(always)] + fn add_transfer(ref self: State, transfer: Transfer) -> Result<(), EVMError> { + if (transfer.amount == 0 || transfer.sender.evm == transfer.recipient.evm) { + return Result::Ok(()); + } + let mut sender = self.get_account(transfer.sender.evm); + let mut recipient = self.get_account(transfer.recipient.evm); + + let (new_sender_balance, underflow) = sender.balance().overflowing_sub(transfer.amount); + ensure(!underflow, EVMError::InsufficientBalance)?; + + let (new_recipient_balance, overflow) = recipient.balance.overflowing_add(transfer.amount); + ensure(!overflow, EVMError::NumericOperations(BALANCE_OVERFLOW))?; + + sender.set_balance(new_sender_balance); + recipient.set_balance(new_recipient_balance); + + self.set_account(sender); + self.set_account(recipient); + + self.transfers.append(transfer); + Result::Ok(()) + } + + /// Reads a value from transient storage for a given EVM address and key. + /// + /// # Arguments + /// + /// * `self` - A mutable reference to the `State` instance. + /// * `evm_address` - The EVM address of the account. + /// * `key` - The storage key. + /// + /// # Returns + /// + /// The value stored in transient storage at the given address and key. + #[inline(always)] + fn read_transient_storage(ref self: State, evm_address: EthAddress, key: u256) -> u256 { + let internal_key = compute_storage_key(evm_address, key); + let maybe_entry = self.transient_account_storage.read(internal_key); + match maybe_entry { + Option::Some((_, _, value)) => { return value; }, + Option::None => { return 0; } + } + } + + /// Writes a value to transient storage for a given EVM address and key. + /// + /// # Arguments + /// + /// * `self` - A mutable reference to the `State` instance. + /// * `evm_address` - The EVM address of the account. + /// * `key` - The storage key. + /// * `value` - The value to write. + #[inline(always)] + fn write_transient_storage(ref self: State, evm_address: EthAddress, key: u256, value: u256) { + let internal_key = compute_storage_key(evm_address, key); + self.transient_account_storage.write(internal_key.into(), (evm_address, key, value)); + } + + /// Creates a clone of the current State. + /// + /// # Arguments + /// + /// * `self` - A reference to the `State` instance to clone. + /// + /// # Returns + /// + /// A new `State` instance with the same contents as the original. + #[inline(always)] + fn clone(ref self: State) -> State { + State { + accounts: self.accounts.clone(), + accounts_storage: self.accounts_storage.clone(), + events: self.events.clone(), + transfers: self.transfers.clone(), + transient_account_storage: self.transient_account_storage.clone(), + } + } + + /// Checks if an account is both in the global state and non-empty. + /// + /// # Arguments + /// + /// * `self` - A mutable reference to the `State` instance. + /// * `evm_address` - The EVM address of the account to check. + /// + /// # Returns + /// + /// `true` if the account exists and is non-empty, `false` otherwise. + #[inline(always)] + fn is_account_alive(ref self: State, evm_address: EthAddress) -> bool { + let account = self.get_account(evm_address); + return !(account.nonce == 0 && account.code.len() == 0 && account.balance == 0); + } +} + +/// Computes the key for the internal state for a given EVM storage key. +/// The key is computed as follows: +/// 1. Compute the hash of the EVM address and the key(low, high) using Poseidon. +/// 2. Return the hash +#[inline(always)] +pub fn compute_storage_key(evm_address: EthAddress, key: u256) -> felt252 { + let hash = PoseidonTrait::new().update_with(evm_address).update_with(key).finalize(); + hash +} + +/// Computes the storage address for a given EVM storage key. +/// The storage address is computed as follows: +/// 1. Compute the hash of the key (low, high) using Poseidon. +/// 2. Use `storage_base_address_from_felt252` to obtain the starknet storage base address. +/// Note: the storage_base_address_from_felt252 function always works for any felt - and returns the +/// number normalized into the range [0, 2^251 - 256). (x % (2^251 - 256)) +/// https://github.com/starkware-libs/cairo/issues/4187 +#[inline(always)] +pub fn compute_storage_address(key: u256) -> StorageBaseAddress { + let hash = PoseidonTrait::new().update_with(key).finalize(); + storage_base_address_from_felt252(hash) +} + +#[cfg(test)] +mod tests { + use crate::state::compute_storage_key; + use crate::test_utils; + + #[test] + fn test_compute_storage_key() { + let key = 100; + let evm_address = test_utils::evm_address(); + + // The values can be computed externally by running a Rust program using the + // `starknet_crypto` crate and `poseidon_hash_many`. + // ```rust + // use starknet_crypto::{FieldElement,poseidon_hash_many}; + // use crypto_bigint::{U256}; + + // fn main() { + // let keys: Vec = vec![ + // FieldElement::from_hex_be("0x65766d5f61646472657373").unwrap(), + // FieldElement::from_hex_be("0x64").unwrap(), + // FieldElement::from_hex_be("0x00").unwrap(), + // ]; + // let values_to_hash = [keys[0],keys[1],keys[2]]; + // let hash = poseidon_hash_many(&values_to_hash); + // + // } + // + let address = compute_storage_key(evm_address, key); + assert( + address == 0x1b0f25b79b18f8734761533714f234825f965d6215cebdc391ceb3b964dd36, + 'hash not expected value' + ) + } + + mod test_state_changelog { + use crate::state::{StateChangeLog, StateChangeLogTrait}; + use crate::test_utils; + use utils::set::SetTrait; + + #[test] + fn test_read_empty_log() { + let mut changelog: StateChangeLog = Default::default(); + let key = test_utils::storage_base_address().into(); + assert!(changelog.read(key).is_none()) + } + + #[test] + fn test_write_read() { + let mut changelog: StateChangeLog = Default::default(); + let key = test_utils::storage_base_address().into(); + + changelog.write(key, 42); + assert_eq!(changelog.read(key).unwrap(), 42); + assert_eq!(changelog.keyset.len(), 1); + + changelog.write(key, 43); + assert_eq!(changelog.read(key).unwrap(), 43); + assert_eq!(changelog.keyset.len(), 1); + + // Write multiple keys + let second_key = 'second_location'; + changelog.write(second_key, 1337.into()); + + assert_eq!(changelog.read(second_key).unwrap(), 1337); + assert_eq!(changelog.keyset.len(), 2); + } + } + + mod test_state { + use core::starknet::EthAddress; + use crate::model::account::{Account, AccountTrait}; + use crate::model::{Event, Transfer, Address}; + use crate::state::{State, StateTrait}; + use crate::test_utils; + use snforge_std::{test_address, start_mock_call}; + use utils::constants::EMPTY_KECCAK; + use utils::helpers::compute_starknet_address; + use utils::set::SetTrait; + use utils::traits::bytes::U8SpanExTrait; + + #[test] + fn test_get_account_when_inexistant() { + test_utils::setup_test_environment(); + let deployer = test_address(); + let mut state: State = Default::default(); + + // Transfer native tokens to sender + let evm_address: EthAddress = test_utils::evm_address(); + let starknet_address = compute_starknet_address( + deployer, evm_address, test_utils::uninitialized_account() + ); + let expected_account = Account { + address: Address { evm: evm_address, starknet: starknet_address }, + code: [].span(), + code_hash: EMPTY_KECCAK, + nonce: 0, + balance: 0, + selfdestruct: false, + is_created: false, + }; + + start_mock_call::(test_utils::native_token(), selector!("balanceOf"), 0); + let account = state.get_account(evm_address); + + assert_eq!(account, expected_account); + assert_eq!(state.accounts.keyset.len(), 1); + } + + #[test] + fn test_get_account_when_cached() { + test_utils::setup_test_environment(); + let deployer = test_address(); + let mut state: State = Default::default(); + + let evm_address: EthAddress = test_utils::evm_address(); + let starknet_address = compute_starknet_address( + deployer.into(), evm_address, test_utils::uninitialized_account() + ); + + let bytecode = [0xab, 0xcd, 0xef].span(); + let code_hash = bytecode.compute_keccak256_hash(); + let expected_account = Account { + address: Address { evm: evm_address, starknet: starknet_address }, + code: bytecode, + code_hash: code_hash, + nonce: 1, + balance: 420, + selfdestruct: false, + is_created: false, + }; + + state.set_account(expected_account); + let account = state.get_account(evm_address); + + assert_eq!(account, expected_account); + assert_eq!(state.accounts.keyset.len(), 1); + } + + #[test] + fn test_get_account_when_deployed() { + test_utils::setup_test_environment(); + let deployer = test_address(); + let mut state: State = Default::default(); + + let evm_address: EthAddress = test_utils::evm_address(); + let starknet_address = compute_starknet_address( + deployer, evm_address, test_utils::uninitialized_account() + ); + test_utils::register_account(evm_address, starknet_address); + let bytecode = [0xab, 0xcd, 0xef].span(); + let code_hash = bytecode.compute_keccak256_hash(); + let expected_account = Account { + address: Address { evm: evm_address, starknet: starknet_address }, + code: bytecode, + code_hash: code_hash, + nonce: 1, + balance: 420, + selfdestruct: false, + is_created: false, + }; + + start_mock_call::(test_utils::native_token(), selector!("balanceOf"), 420); + start_mock_call::< + Span + >(starknet_address, selector!("bytecode"), [0xab, 0xcd, 0xef].span()); + start_mock_call::(starknet_address, selector!("get_code_hash"), code_hash); + start_mock_call::(starknet_address, selector!("get_nonce"), 1); + let account = state.get_account(evm_address); + + assert_eq!(account, expected_account); + assert_eq!(state.accounts.keyset.len(), 1); + } + + #[test] + fn test_write_read_cached_storage() { + let mut state: State = Default::default(); + let evm_address: EthAddress = test_utils::evm_address(); + let key = 10; + let value = 100; + + state.write_state(evm_address, key, value); + let read_value = state.read_state(evm_address, key); + + assert(value == read_value, 'Storage mismatch'); + } + + #[test] + fn test_read_state_from_sn_storage() { + test_utils::setup_test_environment(); + let starknet_address = compute_starknet_address( + test_address(), test_utils::evm_address(), test_utils::uninitialized_account() + ); + test_utils::register_account(test_utils::evm_address(), starknet_address); + + let mut state: State = Default::default(); + let key = 10; + let value = 100; + + let bytecode = [0xab, 0xcd, 0xef].span(); + let code_hash = bytecode.compute_keccak256_hash(); + + start_mock_call::(starknet_address, selector!("storage"), value); + start_mock_call::(test_utils::native_token(), selector!("balanceOf"), 10000); + start_mock_call::>(starknet_address, selector!("bytecode"), bytecode); + start_mock_call::(starknet_address, selector!("get_code_hash"), code_hash); + start_mock_call::(starknet_address, selector!("get_nonce"), 1); + let read_value = state.read_state(test_utils::evm_address(), key); + + assert_eq!(value, read_value) + } + + #[test] + fn test_add_event() { + let mut state: State = Default::default(); + let event = Event { keys: array![100, 200], data: array![0xab, 0xde] }; + + state.add_event(event.clone()); + + assert(state.events.len() == 1, 'Event not added'); + assert(state.events[0].clone() == event, 'Event mismatch'); + } + + #[test] + fn test_add_transfer() { + //Given + let mut state: State = Default::default(); + test_utils::setup_test_environment(); + let deployer = test_address(); + + let sender_evm_address = test_utils::evm_address(); + let sender_starknet_address = compute_starknet_address( + deployer, sender_evm_address, test_utils::uninitialized_account() + ); + let sender_address = Address { + evm: sender_evm_address, starknet: sender_starknet_address + }; + + let recipient_evm_address = test_utils::other_evm_address(); + let recipient_starknet_address = compute_starknet_address( + deployer, recipient_evm_address, test_utils::uninitialized_account() + ); + let recipient_address = Address { + evm: recipient_evm_address, starknet: recipient_starknet_address + }; + let transfer = Transfer { + sender: sender_address, recipient: recipient_address, amount: 100 + }; + + // Write user balances in cache to avoid fetching from SN storage + let mut sender = Account { + address: sender_address, + balance: 300, + code: [].span(), + code_hash: EMPTY_KECCAK, + nonce: 0, + selfdestruct: false, + is_created: false, + }; + state.set_account(sender); + let mut recipient = Account { + address: recipient_address, + balance: 0, + code: [].span(), + code_hash: EMPTY_KECCAK, + nonce: 0, + selfdestruct: false, + is_created: false, + }; + state.set_account(recipient); + + // When + state.add_transfer(transfer).unwrap(); + + // Then, transfer appended to log and cached balances updated + assert_eq!(state.transfers.len(), 1); + assert_eq!(*(state.transfers[0]), transfer); + + assert_eq!(state.get_account(sender_address.evm).balance(), 200); + assert_eq!(state.get_account(recipient_address.evm).balance(), 100); + } + + #[test] + fn test_add_transfer_with_same_sender_and_recipient() { + //Given + let mut state: State = Default::default(); + test_utils::setup_test_environment(); + let deployer = test_address(); + + let sender_evm_address = test_utils::evm_address(); + let sender_starknet_address = compute_starknet_address( + deployer, sender_evm_address, test_utils::uninitialized_account() + ); + let sender_address = Address { + evm: sender_evm_address, starknet: sender_starknet_address + }; + + // since sender and recipient is same + let transfer = Transfer { + sender: sender_address, recipient: sender_address, amount: 100 + }; + + // Write user balances in cache to avoid fetching from SN storage + let mut sender = Account { + address: sender_address, + balance: 300, + code: [].span(), + code_hash: EMPTY_KECCAK, + nonce: 0, + selfdestruct: false, + is_created: false, + }; + state.set_account(sender); + + // When + state.add_transfer(transfer).unwrap(); + + // Then, no transfer appended to log and cached balances updated + assert_eq!(state.transfers.len(), 0); + + assert_eq!(state.get_account(sender_address.evm).balance(), 300); + } + + #[test] + fn test_add_transfer_when_amount_is_zero() { + //Given + let mut state: State = Default::default(); + test_utils::setup_test_environment(); + let deployer = test_address(); + + let sender_evm_address = test_utils::evm_address(); + let sender_starknet_address = compute_starknet_address( + deployer, sender_evm_address, test_utils::uninitialized_account() + ); + let sender_address = Address { + evm: sender_evm_address, starknet: sender_starknet_address + }; + + let recipient_evm_address = test_utils::other_evm_address(); + let recipient_starknet_address = compute_starknet_address( + deployer, recipient_evm_address, test_utils::uninitialized_account() + ); + let recipient_address = Address { + evm: recipient_evm_address, starknet: recipient_starknet_address + }; + let transfer = Transfer { + sender: sender_address, recipient: recipient_address, amount: 0 + }; + // Write user balances in cache to avoid fetching from SN storage + let mut sender = Account { + address: sender_address, + balance: 300, + code: [].span(), + code_hash: EMPTY_KECCAK, + nonce: 0, + selfdestruct: false, + is_created: false, + }; + state.set_account(sender); + let mut recipient = Account { + address: recipient_address, + balance: 0, + code: [].span(), + code_hash: EMPTY_KECCAK, + nonce: 0, + selfdestruct: false, + is_created: false, + }; + state.set_account(recipient); + + // When + state.add_transfer(transfer).unwrap(); + + // Then, no transfer appended to log and cached balances updated + assert_eq!(state.transfers.len(), 0); + assert_eq!(state.get_account(sender_address.evm).balance(), 300); + assert_eq!(state.get_account(recipient_address.evm).balance(), 0); + } + + #[test] + fn test_read_balance_cached() { + let mut state: State = Default::default(); + test_utils::setup_test_environment(); + let deployer = test_address(); + + let evm_address = test_utils::evm_address(); + let starknet_address = compute_starknet_address( + deployer, evm_address, test_utils::uninitialized_account() + ); + let address = Address { evm: evm_address, starknet: starknet_address }; + + let balance = 100; + + let mut account = Account { + address, + balance, + code: [].span(), + code_hash: EMPTY_KECCAK, + nonce: 0, + selfdestruct: false, + is_created: false, + }; + state.set_account(account); + let read_balance = state.get_account(address.evm).balance(); + + assert_eq!(balance, read_balance,); + } + + #[test] + fn test_read_balance_from_storage() { + test_utils::setup_test_environment(); + let deployer = test_address(); + let evm_address = test_utils::evm_address(); + let starknet_address = compute_starknet_address( + deployer, evm_address, test_utils::uninitialized_account() + ); + test_utils::register_account(evm_address, starknet_address); + + // Transfer native tokens to sender + let mut state: State = Default::default(); + let bytecode = [0xab, 0xcd, 0xef].span(); + let code_hash = bytecode.compute_keccak256_hash(); + start_mock_call::(test_utils::native_token(), selector!("balanceOf"), 10000); + start_mock_call::>(starknet_address, selector!("bytecode"), bytecode); + start_mock_call::(starknet_address, selector!("get_code_hash"), code_hash); + start_mock_call::(starknet_address, selector!("get_nonce"), 1); + let read_balance = state.get_account(evm_address).balance(); + + assert_eq!(read_balance, 10000); + } + + #[test] + fn test_write_read_transient_storage() { + let mut state: State = Default::default(); + let evm_address: EthAddress = test_utils::evm_address(); + let key = 10; + let value = 100; + + state.write_transient_storage(evm_address, key, value); + let read_value = state.read_transient_storage(evm_address, key); + + assert(value == read_value, 'Transient storage mismatch'); + } + } +} diff --git a/kakarot-ssj/crates/evm/src/test_data.cairo b/kakarot-ssj/crates/evm/src/test_data.cairo new file mode 100644 index 000000000..dff05e57a --- /dev/null +++ b/kakarot-ssj/crates/evm/src/test_data.cairo @@ -0,0 +1,2 @@ +pub mod test_data_blake2f; +pub mod test_data_modexp; diff --git a/kakarot-ssj/crates/evm/src/test_data/test_data_blake2f.cairo b/kakarot-ssj/crates/evm/src/test_data/test_data_blake2f.cairo new file mode 100644 index 000000000..2edd31c01 --- /dev/null +++ b/kakarot-ssj/crates/evm/src/test_data/test_data_blake2f.cairo @@ -0,0 +1,1533 @@ +// source: [EIP-152](https://eips.ethereum.org/EIPS/eip-152), Test Vector 1 +pub fn blake2_precompile_fail_wrong_length_input_1_test_case() -> (Span, Span) { + let input = [ + 0, + 0, + 12, + 72, + 201, + 189, + 242, + 103, + 230, + 9, + 106, + 59, + 167, + 202, + 132, + 133, + 174, + 103, + 187, + 43, + 248, + 148, + 254, + 114, + 243, + 110, + 60, + 241, + 54, + 29, + 95, + 58, + 245, + 79, + 165, + 209, + 130, + 230, + 173, + 127, + 82, + 14, + 81, + 31, + 108, + 62, + 43, + 140, + 104, + 5, + 155, + 107, + 189, + 65, + 251, + 171, + 217, + 131, + 31, + 121, + 33, + 126, + 19, + 25, + 205, + 224, + 91, + 97, + 98, + 99, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1 + ].span(); + + let output = [].span(); + + (input, output) +} + +// source: [EIP-152](https://eips.ethereum.org/EIPS/eip-152), Test Vector 2 +pub fn blake2_precompile_fail_wrong_length_input_2_test_case() -> (Span, Span) { + let input = [ + 0, + 0, + 0, + 0, + 12, + 72, + 201, + 189, + 242, + 103, + 230, + 9, + 106, + 59, + 167, + 202, + 132, + 133, + 174, + 103, + 187, + 43, + 248, + 148, + 254, + 114, + 243, + 110, + 60, + 241, + 54, + 29, + 95, + 58, + 245, + 79, + 165, + 209, + 130, + 230, + 173, + 127, + 82, + 14, + 81, + 31, + 108, + 62, + 43, + 140, + 104, + 5, + 155, + 107, + 189, + 65, + 251, + 171, + 217, + 131, + 31, + 121, + 33, + 126, + 19, + 25, + 205, + 224, + 91, + 97, + 98, + 99, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1 + ].span(); + + let output = [].span(); + + (input, output) +} + +// source: [EIP-152](https://eips.ethereum.org/EIPS/eip-152), Test Vector 3 +pub fn blake2_precompile_fail_wrong_length_input_3_test_case() -> (Span, Span) { + let input = [ + 0, + 0, + 0, + 12, + 72, + 201, + 189, + 242, + 103, + 230, + 9, + 106, + 59, + 167, + 202, + 132, + 133, + 174, + 103, + 187, + 43, + 248, + 148, + 254, + 114, + 243, + 110, + 60, + 241, + 54, + 29, + 95, + 58, + 245, + 79, + 165, + 209, + 130, + 230, + 173, + 127, + 82, + 14, + 81, + 31, + 108, + 62, + 43, + 140, + 104, + 5, + 155, + 107, + 189, + 65, + 251, + 171, + 217, + 131, + 31, + 121, + 33, + 126, + 19, + 25, + 205, + 224, + 91, + 97, + 98, + 99, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2 + ].span(); + + let output = [].span(); + + (input, output) +} + +// source: [EIP-152](https://eips.ethereum.org/EIPS/eip-152), Test Vector 4 +pub fn blake2_precompile_pass_0_test_case() -> (Span, Span) { + let input = [ + 0, + 0, + 0, + 0, + 72, + 201, + 189, + 242, + 103, + 230, + 9, + 106, + 59, + 167, + 202, + 132, + 133, + 174, + 103, + 187, + 43, + 248, + 148, + 254, + 114, + 243, + 110, + 60, + 241, + 54, + 29, + 95, + 58, + 245, + 79, + 165, + 209, + 130, + 230, + 173, + 127, + 82, + 14, + 81, + 31, + 108, + 62, + 43, + 140, + 104, + 5, + 155, + 107, + 189, + 65, + 251, + 171, + 217, + 131, + 31, + 121, + 33, + 126, + 19, + 25, + 205, + 224, + 91, + 97, + 98, + 99, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1 + ].span(); + + let output = [ + 8, + 201, + 188, + 243, + 103, + 230, + 9, + 106, + 59, + 167, + 202, + 132, + 133, + 174, + 103, + 187, + 43, + 248, + 148, + 254, + 114, + 243, + 110, + 60, + 241, + 54, + 29, + 95, + 58, + 245, + 79, + 165, + 210, + 130, + 230, + 173, + 127, + 82, + 14, + 81, + 31, + 108, + 62, + 43, + 140, + 104, + 5, + 155, + 148, + 66, + 190, + 4, + 84, + 38, + 124, + 224, + 121, + 33, + 126, + 19, + 25, + 205, + 224, + 91 + ].span(); + + (input, output) +} + + +// source: [EIP-152](https://eips.ethereum.org/EIPS/eip-152), Test Vector 5 +pub fn blake2_precompile_pass_1_test_case() -> (Span, Span) { + let input = [ + 0, + 0, + 0, + 12, + 72, + 201, + 189, + 242, + 103, + 230, + 9, + 106, + 59, + 167, + 202, + 132, + 133, + 174, + 103, + 187, + 43, + 248, + 148, + 254, + 114, + 243, + 110, + 60, + 241, + 54, + 29, + 95, + 58, + 245, + 79, + 165, + 209, + 130, + 230, + 173, + 127, + 82, + 14, + 81, + 31, + 108, + 62, + 43, + 140, + 104, + 5, + 155, + 107, + 189, + 65, + 251, + 171, + 217, + 131, + 31, + 121, + 33, + 126, + 19, + 25, + 205, + 224, + 91, + 97, + 98, + 99, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1 + ].span(); + + let output = [ + 186, + 128, + 165, + 63, + 152, + 28, + 77, + 13, + 106, + 39, + 151, + 182, + 159, + 18, + 246, + 233, + 76, + 33, + 47, + 20, + 104, + 90, + 196, + 183, + 75, + 18, + 187, + 111, + 219, + 255, + 162, + 209, + 125, + 135, + 197, + 57, + 42, + 171, + 121, + 45, + 194, + 82, + 213, + 222, + 69, + 51, + 204, + 149, + 24, + 211, + 138, + 168, + 219, + 241, + 146, + 90, + 185, + 35, + 134, + 237, + 212, + 0, + 153, + 35 + ].span(); + + (input, output) +} + +// source: [EIP-152](https://eips.ethereum.org/EIPS/eip-152), Test Vector 6 +pub fn blake2_precompile_pass_2_test_case() -> (Span, Span) { + let input = [ + 0, + 0, + 0, + 12, + 72, + 201, + 189, + 242, + 103, + 230, + 9, + 106, + 59, + 167, + 202, + 132, + 133, + 174, + 103, + 187, + 43, + 248, + 148, + 254, + 114, + 243, + 110, + 60, + 241, + 54, + 29, + 95, + 58, + 245, + 79, + 165, + 209, + 130, + 230, + 173, + 127, + 82, + 14, + 81, + 31, + 108, + 62, + 43, + 140, + 104, + 5, + 155, + 107, + 189, + 65, + 251, + 171, + 217, + 131, + 31, + 121, + 33, + 126, + 19, + 25, + 205, + 224, + 91, + 97, + 98, + 99, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ].span(); + + let output = [ + 117, + 171, + 105, + 211, + 25, + 10, + 86, + 44, + 81, + 174, + 248, + 216, + 143, + 28, + 39, + 117, + 135, + 105, + 68, + 64, + 114, + 112, + 196, + 44, + 152, + 68, + 37, + 44, + 38, + 210, + 135, + 82, + 152, + 116, + 62, + 127, + 109, + 94, + 162, + 242, + 211, + 232, + 210, + 38, + 3, + 156, + 211, + 27, + 78, + 66, + 106, + 196, + 242, + 211, + 214, + 102, + 166, + 16, + 194, + 17, + 111, + 222, + 71, + 53 + ].span(); + + (input, output) +} diff --git a/kakarot-ssj/crates/evm/src/test_data/test_data_modexp.cairo b/kakarot-ssj/crates/evm/src/test_data/test_data_modexp.cairo new file mode 100644 index 000000000..c11e97103 --- /dev/null +++ b/kakarot-ssj/crates/evm/src/test_data/test_data_modexp.cairo @@ -0,0 +1,1553 @@ +fn test_modexp_modsize0_returndatasizeFiller_data() -> (Span, Span) { + let calldata = [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 100, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 100, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 100, + 84, + 66, + 221, + 194, + 183, + 15, + 102, + 193, + 246, + 210, + 178, + 150, + 192, + 168, + 117, + 190, + 126, + 221, + 208, + 168, + 9, + 88, + 203, + 199, + 66, + 95, + 24, + 153, + 204, + 249, + 5, + 17, + 165, + 195, + 24, + 34, + 110, + 72, + 238, + 35, + 241, + 48, + 180, + 77, + 193, + 122, + 105, + 28, + 230, + 107, + 229, + 218, + 24, + 184, + 94, + 215, + 148, + 53, + 53, + 178, + 5, + 170, + 18, + 94, + 159, + 89, + 41, + 74, + 0, + 240, + 81, + 85, + 194, + 62, + 151, + 218, + 198, + 179, + 160, + 11, + 12, + 99, + 200, + 65, + 27, + 248, + 21, + 252, + 24, + 59, + 66, + 11, + 77, + 157, + 197, + 247, + 21, + 4, + 13, + 92, + 96, + 149, + 127, + 82, + 211, + 52, + 184, + 67, + 25, + 122, + 222, + 197, + 140, + 19, + 28, + 144, + 124, + 217, + 96, + 89, + 252, + 90, + 220, + 233, + 221, + 163, + 81, + 181, + 223, + 61, + 102, + 111, + 207, + 62, + 182, + 60, + 70, + 133, + 28, + 24, + 22, + 227, + 35, + 242, + 17, + 158, + 189, + 245, + 239, + 53 + ].span(); + + let expected = [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ].span(); + + (calldata, expected) +} + +fn test_modexp_create2callPrecompiles_test0_berlin_data() -> (Span, Span) { + let calldata = [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 32, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 32, + 3, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 254, + 255, + 255, + 252, + 46, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 47 + ].span(); + + let expected = [ + 22, + 46, + 173, + 130, + 202, + 222, + 250, + 234, + 246, + 233, + 40, + 50, + 72, + 253, + 242, + 242, + 132, + 95, + 99, + 150, + 246, + 241, + 124, + 77, + 90, + 57, + 248, + 32, + 182, + 246, + 181, + 249 + ].span(); + + (calldata, expected) +} + +fn test_modexp_eip198_example_1_data() -> (Span, Span) { + let calldata = [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 32, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 32, + 3, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 254, + 255, + 255, + 252, + 46, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 254, + 255, + 255, + 252, + 47 + ].span(); + + let expected = [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1 + ].span(); + + (calldata, expected) +} + + +fn test_modexp_eip198_example_2_data() -> (Span, Span) { + let calldata = [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 32, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 32, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 254, + 255, + 255, + 252, + 46, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 254, + 255, + 255, + 252, + 47 + ].span(); + + let expected = [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ].span(); + + (calldata, expected) +} + + +fn test_modexp_nagydani_1_square_data() -> (Span, Span) { + let calldata = [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 64, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 64, + 224, + 154, + 217, + 103, + 84, + 101, + 197, + 58, + 16, + 159, + 172, + 102, + 164, + 69, + 201, + 27, + 41, + 45, + 43, + 178, + 197, + 38, + 138, + 221, + 179, + 12, + 216, + 47, + 128, + 252, + 176, + 3, + 63, + 249, + 124, + 128, + 165, + 252, + 111, + 57, + 25, + 58, + 233, + 105, + 198, + 237, + 230, + 113, + 10, + 107, + 122, + 194, + 112, + 120, + 160, + 109, + 144, + 239, + 28, + 114, + 229, + 200, + 95, + 181, + 2, + 252, + 158, + 31, + 107, + 235, + 129, + 81, + 101, + 69, + 151, + 82, + 24, + 7, + 94, + 194, + 175, + 17, + 140, + 216, + 121, + 141, + 246, + 224, + 138, + 20, + 124, + 96, + 253, + 96, + 149, + 172, + 43, + 176, + 44, + 41, + 8, + 207, + 77, + 215, + 200, + 31, + 17, + 194, + 137, + 228, + 188, + 233, + 143, + 53, + 83, + 118, + 143, + 57, + 42, + 128, + 206, + 34, + 191, + 92, + 79, + 74, + 36, + 140, + 107 + ].span(); + + let expected = [ + 96, + 0, + 143, + 22, + 20, + 204, + 1, + 220, + 251, + 107, + 251, + 9, + 198, + 37, + 207, + 144, + 180, + 125, + 68, + 104, + 219, + 129, + 181, + 248, + 183, + 163, + 157, + 66, + 243, + 50, + 234, + 185, + 178, + 218, + 143, + 45, + 149, + 49, + 22, + 72, + 168, + 242, + 67, + 244, + 187, + 19, + 207, + 179, + 216, + 247, + 242, + 163, + 192, + 20, + 18, + 46, + 187, + 62, + 212, + 27, + 2, + 120, + 58, + 220 + ].span(); + + (calldata, expected) +} + +fn test_modexp_nagydani_1_qube_data() -> (Span, Span) { + let calldata = [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 64, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 64, + 224, + 154, + 217, + 103, + 84, + 101, + 197, + 58, + 16, + 159, + 172, + 102, + 164, + 69, + 201, + 27, + 41, + 45, + 43, + 178, + 197, + 38, + 138, + 221, + 179, + 12, + 216, + 47, + 128, + 252, + 176, + 3, + 63, + 249, + 124, + 128, + 165, + 252, + 111, + 57, + 25, + 58, + 233, + 105, + 198, + 237, + 230, + 113, + 10, + 107, + 122, + 194, + 112, + 120, + 160, + 109, + 144, + 239, + 28, + 114, + 229, + 200, + 95, + 181, + 3, + 252, + 158, + 31, + 107, + 235, + 129, + 81, + 101, + 69, + 151, + 82, + 24, + 7, + 94, + 194, + 175, + 17, + 140, + 216, + 121, + 141, + 246, + 224, + 138, + 20, + 124, + 96, + 253, + 96, + 149, + 172, + 43, + 176, + 44, + 41, + 8, + 207, + 77, + 215, + 200, + 31, + 17, + 194, + 137, + 228, + 188, + 233, + 143, + 53, + 83, + 118, + 143, + 57, + 42, + 128, + 206, + 34, + 191, + 92, + 79, + 74, + 36, + 140, + 107 + ].span(); + + let expected = [ + 72, + 52, + 164, + 107, + 165, + 101, + 219, + 39, + 144, + 59, + 28, + 114, + 12, + 157, + 89, + 62, + 132, + 228, + 203, + 214, + 173, + 46, + 100, + 179, + 24, + 133, + 217, + 68, + 246, + 140, + 216, + 1, + 249, + 34, + 37, + 168, + 150, + 28, + 149, + 45, + 223, + 39, + 151, + 250, + 71, + 1, + 179, + 48, + 200, + 92, + 75, + 54, + 55, + 152, + 16, + 11, + 146, + 26, + 26, + 34, + 164, + 106, + 127, + 236 + ].span(); + + (calldata, expected) +} diff --git a/kakarot-ssj/crates/evm/src/test_utils.cairo b/kakarot-ssj/crates/evm/src/test_utils.cairo new file mode 100644 index 000000000..4726c297d --- /dev/null +++ b/kakarot-ssj/crates/evm/src/test_utils.cairo @@ -0,0 +1,298 @@ +use contracts::kakarot_core::KakarotCore; +use core::ops::DerefMut; +use core::starknet::storage::{StoragePointerWriteAccess, StoragePathEntry}; +use core::starknet::storage_access::{StorageBaseAddress, storage_base_address_from_felt252}; +use core::starknet::{ContractAddress, EthAddress, contract_address_const, ClassHash}; +use core::traits::TryInto; +use crate::memory::{Memory, MemoryTrait}; + +use crate::model::vm::{VM, VMTrait}; +use crate::model::{Message, Environment, Address, AccountTrait}; +use snforge_std::start_cheat_chain_id_global; +use snforge_std::test_address; +use starknet::storage::StorageTraitMut; +use utils::constants; + +pub fn uninitialized_account() -> ClassHash { + 'uninitialized_account'.try_into().unwrap() +} + +pub fn account_contract() -> ClassHash { + 'account_contract'.try_into().unwrap() +} + + +pub fn setup_test_environment() { + let mut kakarot_core = KakarotCore::contract_state_for_testing(); + let mut kakarot_storage = kakarot_core.deref_mut().storage_mut(); + kakarot_storage.Kakarot_account_contract_class_hash.write(account_contract()); + kakarot_storage.Kakarot_uninitialized_account_class_hash.write(uninitialized_account()); + kakarot_storage.Kakarot_native_token_address.write(native_token()); + start_cheat_chain_id_global(chain_id().into()); +} + +pub fn register_account(evm_address: EthAddress, starknet_address: ContractAddress) { + let mut kakarot_core = KakarotCore::contract_state_for_testing(); + let mut kakarot_storage = kakarot_core.deref_mut().storage_mut(); + kakarot_storage.Kakarot_evm_to_starknet_address.entry(evm_address).write(starknet_address); +} + + +#[generate_trait] +pub impl MemoryUtilsImpl of MemoryTestUtilsTrait { + fn store_with_expansion(ref self: Memory, element: u256, offset: usize) { + self.ensure_length(offset + 32); + self.store(element, offset); + } + + fn store_n_with_expansion(ref self: Memory, elements: Span, offset: usize) { + self.ensure_length(offset + elements.len()); + self.store_n(elements, offset); + } +} + +#[derive(Destruct)] +struct VMBuilder { + vm: VM +} + +#[generate_trait] +pub impl VMBuilderImpl of VMBuilderTrait { + fn new() -> VMBuilder { + VMBuilder { vm: Default::default() }.with_gas_limit(0x1000000000000000) + } + + fn new_with_presets() -> VMBuilder { + VMBuilder { vm: preset_vm() } + } + + fn with_return_data(mut self: VMBuilder, return_data: Span) -> VMBuilder { + self.vm.set_return_data(return_data); + self + } + + fn with_caller(mut self: VMBuilder, address: Address) -> VMBuilder { + self.vm.message.caller = address; + self + } + + fn with_calldata(mut self: VMBuilder, calldata: Span) -> VMBuilder { + self.vm.message.data = calldata; + self + } + + fn with_read_only(mut self: VMBuilder) -> VMBuilder { + self.vm.message.read_only = true; + self + } + + fn with_bytecode(mut self: VMBuilder, bytecode: Span) -> VMBuilder { + self.vm.message.code = bytecode; + self + } + + fn with_gas_limit(mut self: VMBuilder, gas_limit: u64) -> VMBuilder { + self.vm.message.gas_limit = gas_limit; + self + } + + // pub fn with_nested_vm(mut self: VMBuilder) -> VMBuilder { + // let current_ctx = self.machine.current_ctx.unbox(); + + // // Second Execution Context + // let context_id = ExecutionContextType::Call(1); + // let mut child_context = preset_message(); + // child_context.ctx_type = context_id; + // child_context.parent_ctx = NullableTrait::new(current_ctx); + // let mut call_ctx = child_context.call_ctx(); + // call_ctx.caller = other_address(); + // child_context.call_ctx = BoxTrait::new(call_ctx); + // self.machine.current_ctx = BoxTrait::new(child_context); + // self + // } + + fn with_target(mut self: VMBuilder, target: Address) -> VMBuilder { + self.vm.message.target = target; + self + } + + fn build(mut self: VMBuilder) -> VM { + self.vm.valid_jumpdests = AccountTrait::get_jumpdests(self.vm.message.code); + return self.vm; + } + + fn with_gas_left(mut self: VMBuilder, gas_left: u64) -> VMBuilder { + self.vm.gas_left = gas_left; + self + } +} + +pub fn origin() -> EthAddress { + 'origin'.try_into().unwrap() +} + +pub fn dual_origin() -> Address { + let origin_evm = origin(); + let origin_starknet = utils::helpers::compute_starknet_address( + test_address(), origin_evm, uninitialized_account() + ); + Address { evm: origin_evm, starknet: origin_starknet } +} + +pub fn caller() -> EthAddress { + 'caller'.try_into().unwrap() +} + +pub fn coinbase() -> EthAddress { + 'coinbase'.try_into().unwrap() +} + +pub fn starknet_address() -> ContractAddress { + contract_address_const::<'starknet_address'>() +} + +pub fn evm_address() -> EthAddress { + 'evm_address'.try_into().unwrap() +} + +pub fn test_dual_address() -> Address { + Address { evm: evm_address(), starknet: starknet_address() } +} + +pub fn other_evm_address() -> EthAddress { + 'other_evm_address'.try_into().unwrap() +} + +pub fn other_starknet_address() -> ContractAddress { + contract_address_const::<'other_starknet_address'>() +} + +pub fn other_address() -> Address { + Address { evm: other_evm_address(), starknet: other_starknet_address() } +} + +pub fn storage_base_address() -> StorageBaseAddress { + storage_base_address_from_felt252('storage_base_address') +} + +pub fn zero_address() -> ContractAddress { + contract_address_const::<0x00>() +} + +pub fn callvalue() -> u256 { + 123456789 +} + +pub fn native_token() -> ContractAddress { + contract_address_const::<'native_token'>() +} + +pub fn chain_id() -> u64 { + 'KKRT'.try_into().unwrap() +} + +pub fn kakarot_address() -> ContractAddress { + contract_address_const::<'kakarot'>() +} + +pub fn sequencer_evm_address() -> EthAddress { + 'sequencer'.try_into().unwrap() +} + +pub fn eoa_address() -> EthAddress { + let evm_address: EthAddress = 0xe0a.try_into().unwrap(); + evm_address +} + +pub fn tx_gas_limit() -> u64 { + constants::BLOCK_GAS_LIMIT +} + +pub const BASE_FEE: u64 = 1000; + +pub fn gas_price() -> u128 { + BASE_FEE.into() + 1 +} + +pub fn value() -> u256 { + 0xffffffffffffffffffffffffffffffff +} + +pub fn ca_address() -> EthAddress { + let evm_address: EthAddress = 0xca.try_into().unwrap(); + evm_address +} + +pub fn preset_message() -> Message { + let code: Span = [0x00].span(); + let data: Span = [4, 5, 6].span(); + let value: u256 = callvalue(); + let caller = Address { + evm: origin(), + starknet: utils::helpers::compute_starknet_address( + test_address(), origin(), uninitialized_account() + ) + }; + let target = Address { + evm: evm_address(), + starknet: utils::helpers::compute_starknet_address( + test_address(), evm_address(), uninitialized_account() + ) + }; + let code_address = target; + let read_only = false; + let tx_gas_limit = tx_gas_limit(); + + Message { + target, + caller, + data, + value, + gas_limit: tx_gas_limit, + read_only, + code, + code_address, + should_transfer_value: true, + depth: 0, + accessed_addresses: Default::default(), + accessed_storage_keys: Default::default(), + } +} + +pub fn preset_environment() -> Environment { + let block_info = starknet::get_block_info().unbox(); + + Environment { + origin: dual_origin(), + gas_price: gas_price(), + chain_id: chain_id(), + prevrandao: 0, + block_number: block_info.block_number, + block_timestamp: block_info.block_timestamp, + block_gas_limit: constants::BLOCK_GAS_LIMIT, + coinbase: coinbase(), + base_fee: BASE_FEE, + state: Default::default(), + } +} + +pub fn preset_vm() -> VM { + let message = preset_message(); + let environment = preset_environment(); + let return_data = [1, 2, 3].span(); + VM { + stack: Default::default(), + memory: Default::default(), + pc: 0, + valid_jumpdests: AccountTrait::get_jumpdests(message.code), + return_data, + env: environment, + message, + gas_left: message.gas_limit, + running: true, + error: false, + accessed_addresses: Default::default(), + accessed_storage_keys: Default::default(), + gas_refund: 0, + } +} diff --git a/kakarot-ssj/crates/openzeppelin/Scarb.toml b/kakarot-ssj/crates/openzeppelin/Scarb.toml new file mode 100644 index 000000000..5b90de13d --- /dev/null +++ b/kakarot-ssj/crates/openzeppelin/Scarb.toml @@ -0,0 +1,32 @@ +# Due to the following error, we have to manually copy paste contracts from Open Zeppelin +# error: Version solving failed: +# - openzeppelin v0.7.0 (git+https:#github.com/OpenZeppelin/cairo-contracts.git?tag=v0.7.0#61a2505fe0c0f19b5de2b3f8dedf421ba2cff657) cannot use starknet v2.3.0-rc0 (std), because openzeppelin requires starknet >=2.2.0 + +# Scarb does not have real version solving algorithm yet. +# Perhaps in the future this conflict could be resolved, but currently, +# please upgrade your dependencies to use latest versions of their dependencies. +# +# +# Credits: "https://github.com/OpenZeppelin/cairo-contracts.git", tag = "v0.7.0" + + +[package] +name = "openzeppelin" +version = "0.1.0" +edition = "2024_07" + +# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html + +[dependencies] +starknet.workspace = true + +[tool] +fmt.workspace = true + +[dev-dependencies] +snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry.git", tag = "v0.31.0" } +assert_macros = "2.8.2" + +[scripts] +test = "snforge test --max-n-steps 4294967295" +test-profiling = "snforge test --max-n-steps 4294967295 --build-profile" diff --git a/kakarot-ssj/crates/openzeppelin/src/lib.cairo b/kakarot-ssj/crates/openzeppelin/src/lib.cairo new file mode 100644 index 000000000..79c66ba63 --- /dev/null +++ b/kakarot-ssj/crates/openzeppelin/src/lib.cairo @@ -0,0 +1 @@ +pub mod token; diff --git a/kakarot-ssj/crates/openzeppelin/src/token.cairo b/kakarot-ssj/crates/openzeppelin/src/token.cairo new file mode 100644 index 000000000..8f3777f6b --- /dev/null +++ b/kakarot-ssj/crates/openzeppelin/src/token.cairo @@ -0,0 +1 @@ +pub mod erc20; diff --git a/kakarot-ssj/crates/openzeppelin/src/token/erc20.cairo b/kakarot-ssj/crates/openzeppelin/src/token/erc20.cairo new file mode 100644 index 000000000..6779800b1 --- /dev/null +++ b/kakarot-ssj/crates/openzeppelin/src/token/erc20.cairo @@ -0,0 +1,6 @@ +pub mod erc20; +pub mod interface; + +pub use erc20::ERC20; +pub use interface::ERC20ABIDispatcher; +pub use interface::ERC20ABIDispatcherTrait; diff --git a/kakarot-ssj/crates/openzeppelin/src/token/erc20/erc20.cairo b/kakarot-ssj/crates/openzeppelin/src/token/erc20/erc20.cairo new file mode 100644 index 000000000..e5604d4ed --- /dev/null +++ b/kakarot-ssj/crates/openzeppelin/src/token/erc20/erc20.cairo @@ -0,0 +1,259 @@ +// We manually copy pasted contracts from Open Zeppelin +// We adapted it to 2.7.1 version of Cairo +// Credits: "https://github.com/OpenZeppelin/cairo-contracts.git", tag = "v0.7.0" + +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts for Cairo v0.7.0 (token/erc20/erc20.cairo) + +#[starknet::contract] +pub mod ERC20 { + use core::num::traits::Bounded; + use core::num::traits::Zero; + use core::starknet::ContractAddress; + use core::starknet::get_caller_address; + use core::starknet::storage::{ + Map, StorageMapWriteAccess, StorageMapReadAccess, StoragePointerReadAccess, + StoragePointerWriteAccess, + }; + use openzeppelin::token::erc20::interface::{IERC20, IERC20CamelOnly}; + + #[storage] + struct Storage { + _name: felt252, + _symbol: felt252, + _total_supply: u256, + _balances: Map, + _allowances: Map<(ContractAddress, ContractAddress), u256>, + } + + #[event] + #[derive(Drop, starknet::Event)] + enum Event { + Transfer: Transfer, + Approval: Approval, + } + + #[derive(Drop, starknet::Event)] + struct Transfer { + #[key] + from: ContractAddress, + #[key] + to: ContractAddress, + value: u256 + } + + #[derive(Drop, starknet::Event)] + struct Approval { + #[key] + owner: ContractAddress, + #[key] + spender: ContractAddress, + value: u256 + } + + mod Errors { + pub const APPROVE_FROM_ZERO: felt252 = 'ERC20: approve from 0'; + pub const APPROVE_TO_ZERO: felt252 = 'ERC20: approve to 0'; + pub const TRANSFER_FROM_ZERO: felt252 = 'ERC20: transfer from 0'; + pub const TRANSFER_TO_ZERO: felt252 = 'ERC20: transfer to 0'; + pub const BURN_FROM_ZERO: felt252 = 'ERC20: burn from 0'; + pub const MINT_TO_ZERO: felt252 = 'ERC20: mint to 0'; + } + + #[constructor] + fn constructor( + ref self: ContractState, + name: felt252, + symbol: felt252, + initial_supply: u256, + recipient: ContractAddress + ) { + self.initializer(name, symbol); + self._mint(recipient, initial_supply); + } + + // + // External + // + + #[abi(embed_v0)] + impl ERC20Impl of IERC20 { + fn name(self: @ContractState) -> felt252 { + self._name.read() + } + + fn symbol(self: @ContractState) -> felt252 { + self._symbol.read() + } + + fn decimals(self: @ContractState) -> u8 { + 18 + } + + fn total_supply(self: @ContractState) -> u256 { + self._total_supply.read() + } + + fn balance_of(self: @ContractState, account: ContractAddress) -> u256 { + self._balances.read(account) + } + + fn allowance( + self: @ContractState, owner: ContractAddress, spender: ContractAddress + ) -> u256 { + self._allowances.read((owner, spender)) + } + + fn transfer(ref self: ContractState, recipient: ContractAddress, amount: u256) -> bool { + let sender = get_caller_address(); + self._transfer(sender, recipient, amount); + true + } + + fn transfer_from( + ref self: ContractState, + sender: ContractAddress, + recipient: ContractAddress, + amount: u256 + ) -> bool { + let caller = get_caller_address(); + self._spend_allowance(sender, caller, amount); + self._transfer(sender, recipient, amount); + true + } + + fn approve(ref self: ContractState, spender: ContractAddress, amount: u256) -> bool { + let caller = get_caller_address(); + self._approve(caller, spender, amount); + true + } + } + + #[abi(embed_v0)] + impl ERC20CamelOnlyImpl of IERC20CamelOnly { + fn totalSupply(self: @ContractState) -> u256 { + ERC20Impl::total_supply(self) + } + + fn balanceOf(self: @ContractState, account: ContractAddress) -> u256 { + ERC20Impl::balance_of(self, account) + } + + fn transferFrom( + ref self: ContractState, + sender: ContractAddress, + recipient: ContractAddress, + amount: u256 + ) -> bool { + ERC20Impl::transfer_from(ref self, sender, recipient, amount) + } + } + + + #[abi(embed_v0)] + fn increase_allowance( + ref self: ContractState, spender: ContractAddress, added_value: u256 + ) -> bool { + self._increase_allowance(spender, added_value) + } + + + #[abi(embed_v0)] + fn increaseAllowance( + ref self: ContractState, spender: ContractAddress, addedValue: u256 + ) -> bool { + increase_allowance(ref self, spender, addedValue) + } + + + #[abi(embed_v0)] + fn decrease_allowance( + ref self: ContractState, spender: ContractAddress, subtracted_value: u256 + ) -> bool { + self._decrease_allowance(spender, subtracted_value) + } + + + #[abi(embed_v0)] + fn decreaseAllowance( + ref self: ContractState, spender: ContractAddress, subtractedValue: u256 + ) -> bool { + decrease_allowance(ref self, spender, subtractedValue) + } + + // + // Internal + // + + #[generate_trait] + impl InternalImpl of InternalTrait { + fn initializer(ref self: ContractState, name: felt252, symbol: felt252) { + self._name.write(name); + self._symbol.write(symbol); + } + + fn _increase_allowance( + ref self: ContractState, spender: ContractAddress, added_value: u256 + ) -> bool { + let caller = get_caller_address(); + self._approve(caller, spender, self._allowances.read((caller, spender)) + added_value); + true + } + + fn _decrease_allowance( + ref self: ContractState, spender: ContractAddress, subtracted_value: u256 + ) -> bool { + let caller = get_caller_address(); + self + ._approve( + caller, spender, self._allowances.read((caller, spender)) - subtracted_value + ); + true + } + + fn _mint(ref self: ContractState, recipient: ContractAddress, amount: u256) { + assert(!recipient.is_zero(), Errors::MINT_TO_ZERO); + self._total_supply.write(self._total_supply.read() + amount); + self._balances.write(recipient, self._balances.read(recipient) + amount); + self.emit(Transfer { from: Zero::zero(), to: recipient, value: amount }); + } + + fn _burn(ref self: ContractState, account: ContractAddress, amount: u256) { + assert(!account.is_zero(), Errors::BURN_FROM_ZERO); + self._total_supply.write(self._total_supply.read() - amount); + self._balances.write(account, self._balances.read(account) - amount); + self.emit(Transfer { from: account, to: Zero::zero(), value: amount }); + } + + fn _approve( + ref self: ContractState, owner: ContractAddress, spender: ContractAddress, amount: u256 + ) { + assert(!owner.is_zero(), Errors::APPROVE_FROM_ZERO); + assert(!spender.is_zero(), Errors::APPROVE_TO_ZERO); + self._allowances.write((owner, spender), amount); + self.emit(Approval { owner, spender, value: amount }); + } + + fn _transfer( + ref self: ContractState, + sender: ContractAddress, + recipient: ContractAddress, + amount: u256 + ) { + assert(!sender.is_zero(), Errors::TRANSFER_FROM_ZERO); + assert(!recipient.is_zero(), Errors::TRANSFER_TO_ZERO); + self._balances.write(sender, self._balances.read(sender) - amount); + self._balances.write(recipient, self._balances.read(recipient) + amount); + self.emit(Transfer { from: sender, to: recipient, value: amount }); + } + + fn _spend_allowance( + ref self: ContractState, owner: ContractAddress, spender: ContractAddress, amount: u256 + ) { + let current_allowance = self._allowances.read((owner, spender)); + if current_allowance != Bounded::MAX { + self._approve(owner, spender, current_allowance - amount); + } + } + } +} diff --git a/kakarot-ssj/crates/openzeppelin/src/token/erc20/interface.cairo b/kakarot-ssj/crates/openzeppelin/src/token/erc20/interface.cairo new file mode 100644 index 000000000..02c8c4f95 --- /dev/null +++ b/kakarot-ssj/crates/openzeppelin/src/token/erc20/interface.cairo @@ -0,0 +1,90 @@ +// Due to the following error, we have to manually copy paste contracts from Open Zeppelin +// error: Version solving failed: +// - openzeppelin v0.7.0 +// (git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.7.0#61a2505fe0c0f19b5de2b3f8dedf421ba2cff657) +// cannot use starknet v2.3.0-rc0 (std), because openzeppelin requires starknet >=2.2.0 + +// Scarb does not have real version solving algorithm yet. +// Perhaps in the future this conflict could be resolved, but currently, +// please upgrade your dependencies to use latest versions of their dependencies. +// Credits: "https://github.com/OpenZeppelin/cairo-contracts.git", tag = "v0.7.0" + +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts for Cairo v0.7.0 (token/erc20/interface.cairo) + +use core::starknet::ContractAddress; + +#[starknet::interface] +pub trait IERC20 { + fn name(self: @TState) -> felt252; + fn symbol(self: @TState) -> felt252; + fn decimals(self: @TState) -> u8; + fn total_supply(self: @TState) -> u256; + fn balance_of(self: @TState, account: ContractAddress) -> u256; + fn allowance(self: @TState, owner: ContractAddress, spender: ContractAddress) -> u256; + fn transfer(ref self: TState, recipient: ContractAddress, amount: u256) -> bool; + fn transfer_from( + ref self: TState, sender: ContractAddress, recipient: ContractAddress, amount: u256 + ) -> bool; + fn approve(ref self: TState, spender: ContractAddress, amount: u256) -> bool; +} + +#[starknet::interface] +pub trait IERC20Camel { + fn name(self: @TState) -> felt252; + fn symbol(self: @TState) -> felt252; + fn decimals(self: @TState) -> u8; + fn totalSupply(self: @TState) -> u256; + fn balanceOf(self: @TState, account: ContractAddress) -> u256; + fn allowance(self: @TState, owner: ContractAddress, spender: ContractAddress) -> u256; + fn transfer(ref self: TState, recipient: ContractAddress, amount: u256) -> bool; + fn transferFrom( + ref self: TState, sender: ContractAddress, recipient: ContractAddress, amount: u256 + ) -> bool; + fn approve(ref self: TState, spender: ContractAddress, amount: u256) -> bool; +} + +#[starknet::interface] +pub trait IERC20CamelOnly { + fn totalSupply(self: @TState) -> u256; + fn balanceOf(self: @TState, account: ContractAddress) -> u256; + fn transferFrom( + ref self: TState, sender: ContractAddress, recipient: ContractAddress, amount: u256 + ) -> bool; +} + +#[starknet::interface] +pub trait ERC20ABI { + fn name(self: @TState) -> felt252; + fn symbol(self: @TState) -> felt252; + fn decimals(self: @TState) -> u8; + fn total_supply(self: @TState) -> u256; + fn balance_of(self: @TState, account: ContractAddress) -> u256; + fn allowance(self: @TState, owner: ContractAddress, spender: ContractAddress) -> u256; + fn transfer(ref self: TState, recipient: ContractAddress, amount: u256) -> bool; + fn transfer_from( + ref self: TState, sender: ContractAddress, recipient: ContractAddress, amount: u256 + ) -> bool; + fn approve(ref self: TState, spender: ContractAddress, amount: u256) -> bool; + fn increase_allowance(ref self: TState, spender: ContractAddress, added_value: u256) -> bool; + fn decrease_allowance( + ref self: TState, spender: ContractAddress, subtracted_value: u256 + ) -> bool; +} + +#[starknet::interface] +pub trait ERC20CamelABI { + fn name(self: @TState) -> felt252; + fn symbol(self: @TState) -> felt252; + fn decimals(self: @TState) -> u8; + fn totalSupply(self: @TState) -> u256; + fn balanceOf(self: @TState, account: ContractAddress) -> u256; + fn allowance(self: @TState, owner: ContractAddress, spender: ContractAddress) -> u256; + fn transfer(ref self: TState, recipient: ContractAddress, amount: u256) -> bool; + fn transferFrom( + ref self: TState, sender: ContractAddress, recipient: ContractAddress, amount: u256 + ) -> bool; + fn approve(ref self: TState, spender: ContractAddress, amount: u256) -> bool; + fn increaseAllowance(ref self: TState, spender: ContractAddress, addedValue: u256) -> bool; + fn decreaseAllowance(ref self: TState, spender: ContractAddress, subtractedValue: u256) -> bool; +} diff --git a/kakarot-ssj/crates/snforge_utils/.gitignore b/kakarot-ssj/crates/snforge_utils/.gitignore new file mode 100644 index 000000000..73aa31e60 --- /dev/null +++ b/kakarot-ssj/crates/snforge_utils/.gitignore @@ -0,0 +1,2 @@ +target +.snfoundry_cache/ diff --git a/kakarot-ssj/crates/snforge_utils/Scarb.toml b/kakarot-ssj/crates/snforge_utils/Scarb.toml new file mode 100644 index 000000000..baa7e7add --- /dev/null +++ b/kakarot-ssj/crates/snforge_utils/Scarb.toml @@ -0,0 +1,26 @@ +[package] +name = "snforge_utils" +version = "0.1.0" +edition = "2024_07" + +# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html + +[dependencies] +starknet = "2.8.2" +evm = { path = "../evm" } + +[dev-dependencies] +snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry.git", tag = "v0.31.0" } +assert_macros = "2.8.2" + +[[target.starknet-contract]] +sierra = true +casm = true +casm-add-pythonic-hints = true + + +[lib] +name = "snforge_utils" + +[scripts] +test = "snforge test" diff --git a/kakarot-ssj/crates/snforge_utils/src/contracts.cairo b/kakarot-ssj/crates/snforge_utils/src/contracts.cairo new file mode 100644 index 000000000..bcc872368 --- /dev/null +++ b/kakarot-ssj/crates/snforge_utils/src/contracts.cairo @@ -0,0 +1,51 @@ +#[starknet::interface] +trait IHello { + fn hello(self: @T); + fn bar(self: @T); +} + +#[starknet::contract] +mod HelloContract { + use super::{IHelloDispatcher, IHelloDispatcherTrait}; + use core::starknet::get_contract_address; + + #[storage] + struct Storage {} + + #[external(v0)] + fn hello(self: @ContractState) {} + + #[external(v0)] + fn bar(self: @ContractState) { + IHelloDispatcher { contract_address: get_contract_address() }.hello(); + } +} + +#[cfg(test)] +mod tests { + use snforge_std::{declare, DeclareResultTrait, ContractClassTrait}; + use snforge_utils::snforge_utils::{assert_called, assert_called_with}; + use super::{IHelloDispatcher, IHelloDispatcherTrait}; + + #[test] + fn test_calltrace_entrypoint() { + let helloclass = declare("HelloContract").unwrap().contract_class(); + let (hellocontract, _) = helloclass.deploy(@array![]).unwrap(); + + IHelloDispatcher { contract_address: hellocontract }.hello(); + + assert_called(hellocontract, selector!("hello")); + assert_called_with::<()>(hellocontract, selector!("hello"), ()); + } + + #[test] + fn test_calltrace_rec() { + let helloclass = declare("HelloContract").unwrap().contract_class(); + let (hellocontract, _) = helloclass.deploy(@array![]).unwrap(); + + IHelloDispatcher { contract_address: hellocontract }.bar(); + + assert_called(hellocontract, selector!("hello")); + assert_called_with::<()>(hellocontract, selector!("hello"), ()); + } +} diff --git a/kakarot-ssj/crates/snforge_utils/src/lib.cairo b/kakarot-ssj/crates/snforge_utils/src/lib.cairo new file mode 100644 index 000000000..0588fe66c --- /dev/null +++ b/kakarot-ssj/crates/snforge_utils/src/lib.cairo @@ -0,0 +1,319 @@ +mod contracts; + +#[cfg(target: 'test')] +pub mod snforge_utils { + use core::array::ArrayTrait; + use core::option::OptionTrait; + use evm::state::compute_storage_key; + use starknet::ContractAddress; + use evm::model::Address; + use snforge_std::cheatcodes::storage::store_felt252; + use snforge_std::Event; + use snforge_std::cheatcodes::events::{Events}; + use array_utils::ArrayExtTrait; + + use snforge_std::trace::{get_call_trace, CallTrace, CallEntryPoint}; + + pub fn is_called(contract_address: ContractAddress, selector: felt252) -> bool { + let call_trace = get_call_trace(); + + // Check if the top-level call matches + if check_call_match(call_trace.entry_point, contract_address, selector) { + return true; + } + + // Check nested calls recursively + if check_nested_calls(call_trace.nested_calls, contract_address, selector) { + return true; + } + + false + } + + pub fn assert_called(contract_address: ContractAddress, selector: felt252) { + assert!(is_called(contract_address, selector), "Expected call not found in trace"); + } + + pub fn assert_not_called(contract_address: ContractAddress, selector: felt252) { + assert!(!is_called(contract_address, selector), "Unexpected call found in trace"); + } + + fn check_call_match( + entry_point: CallEntryPoint, contract_address: ContractAddress, selector: felt252 + ) -> bool { + entry_point.contract_address == contract_address + && entry_point.entry_point_selector == selector + } + + fn check_nested_calls( + calls: Array, contract_address: ContractAddress, selector: felt252 + ) -> bool { + let mut i = 0; + loop { + if i == calls.len() { + break false; + } + let call = calls.at(i).clone(); + if check_call_match(call.entry_point, contract_address, selector) { + break true; + } + if check_nested_calls(call.nested_calls, contract_address, selector) { + break true; + } + i += 1; + } + } + + pub fn assert_called_with, +Drop, +Copy>( + contract_address: ContractAddress, selector: felt252, calldata: C + ) { + let mut serialized_calldata = array![]; + Serde::serialize(@calldata, ref serialized_calldata); + assert!( + is_called_with(contract_address, selector, serialized_calldata.span()), + "Expected call with specific data not found in trace" + ); + } + + + pub fn is_called_with( + contract_address: ContractAddress, selector: felt252, calldata: Span + ) -> bool { + let call_trace = get_call_trace(); + + if check_call_match_with_data( + call_trace.entry_point, contract_address, selector, calldata + ) { + return true; + } + + check_nested_calls_with_data(call_trace.nested_calls, contract_address, selector, calldata) + } + + + fn check_call_match_with_data( + call: CallEntryPoint, + contract_address: ContractAddress, + selector: felt252, + calldata: Span + ) -> bool { + call.contract_address == contract_address + && call.entry_point_selector == selector + && call.calldata.span() == calldata + } + + fn check_nested_calls_with_data( + calls: Array, + contract_address: ContractAddress, + selector: felt252, + calldata: Span + ) -> bool { + let mut i = 0; + loop { + if i == calls.len() { + break false; + } + let call = calls.at(i).clone(); + if check_call_match_with_data(call.entry_point, contract_address, selector, calldata) { + break true; + } + if check_nested_calls_with_data( + call.nested_calls, contract_address, selector, calldata + ) { + break true; + } + i += 1; + } + } + + mod array_utils { + #[generate_trait] + pub impl ArrayExtImpl, +Drop> of ArrayExtTrait { + fn includes<+PartialEq>(self: @Array, item: T) -> bool { + let mut i = 0; + let mut found = false; + found = + loop { + if i == self.len() { + break false; + }; + if (*self.at(i)) == item { + break true; + } + i += 1; + }; + return found; + } + } + } + + /// A wrapper structure on an array of events emitted by a given contract. + #[derive(Drop, Clone)] + pub struct ContractEvents { + pub events: Array + } + + pub trait EventsFilterTrait { + fn emitted_by(self: @Events, contract_address: ContractAddress) -> EventsFilter; + } + + impl EventsFilterTraitImpl of EventsFilterTrait { + fn emitted_by(self: @Events, contract_address: ContractAddress) -> EventsFilter { + EventsFilter { + events: self, + contract_address: Option::Some(contract_address), + key_filter: Option::None, + data_filter: Option::None, + } + } + } + + #[derive(Copy, Drop)] + pub struct EventsFilter { + events: @Events, + contract_address: Option, + key_filter: Option>, + data_filter: Option, + } + + pub trait EventsFilterBuilderTrait { + fn from_events(events: @Events) -> EventsFilter; + fn with_contract_address( + self: EventsFilter, contract_address: ContractAddress + ) -> EventsFilter; + fn with_keys(self: EventsFilter, keys: Span) -> EventsFilter; + fn with_data(self: EventsFilter, data: felt252) -> EventsFilter; + fn build(self: @EventsFilter) -> ContractEvents; + } + + impl EventsFilterBuilderTraitImpl of EventsFilterBuilderTrait { + fn from_events(events: @Events) -> EventsFilter { + EventsFilter { + events: events, + contract_address: Option::None, + key_filter: Option::None, + data_filter: Option::None, + } + } + + fn with_contract_address( + mut self: EventsFilter, contract_address: ContractAddress + ) -> EventsFilter { + self.contract_address = Option::Some(contract_address); + self + } + + fn with_keys(mut self: EventsFilter, keys: Span) -> EventsFilter { + self.key_filter = Option::Some(keys); + self + } + + fn with_data(mut self: EventsFilter, data: felt252) -> EventsFilter { + self.data_filter = Option::Some(data); + self + } + + fn build(self: @EventsFilter) -> ContractEvents { + let events = (*self.events.events).span(); + let mut filtered_events = array![]; + + for i in 0 + ..events + .len() { + let (from, event) = events.at(i).clone(); + let mut include = true; + + if let Option::Some(addr) = self.contract_address { + if from != *addr { + include = false; + } + } + + if include && self.key_filter.is_some() { + if !(event.keys.span() == (*self.key_filter).unwrap()) { + include = false; + } + } + + if include && self.data_filter.is_some() { + if !event.data.includes((*self.data_filter).unwrap()) { + include = false; + } + } + + if include { + filtered_events.append(event.clone()); + } + }; + + ContractEvents { events: filtered_events } + } + } + + pub trait ContractEventsTrait { + fn assert_emitted, impl TDrop: Drop>( + self: ContractEvents, event: @T + ); + fn assert_not_emitted, impl TDrop: Drop>( + self: ContractEvents, event: @T + ); + } + + impl ContractEventsTraitImpl of ContractEventsTrait { + fn assert_emitted, impl TDrop: Drop>( + self: ContractEvents, event: @T + ) { + let mut expected_keys = array![]; + let mut expected_data = array![]; + event.append_keys_and_data(ref expected_keys, ref expected_data); + + let mut found = false; + for i in 0 + ..self + .events + .len() { + let event = self.events.at(i); + if event.keys == @expected_keys && event.data == @expected_data { + found = true; + break; + } + }; + + assert(found, 'Expected event was not emitted'); + } + + fn assert_not_emitted, impl TDrop: Drop>( + self: ContractEvents, event: @T + ) { + let mut expected_keys = array![]; + let mut expected_data = array![]; + event.append_keys_and_data(ref expected_keys, ref expected_data); + + for i in 0 + ..self + .events + .len() { + let event = self.events.at(i); + assert( + event.keys != @expected_keys || event.data != @expected_data, + 'Unexpected event was emitted' + ); + } + } + } + + /// Stores a value in the EVM storage of a given Starknet contract. + pub fn store_evm(target: Address, evm_key: u256, evm_value: u256) { + let storage_address = compute_storage_key(target.evm, evm_key); + let serialized_value = [evm_value.low.into(), evm_value.high.into()].span(); + for offset in 0 + ..serialized_value + .len() { + store_felt252( + target.starknet, + storage_address + offset.into(), + *serialized_value.at(offset) + ); + }; + } +} diff --git a/kakarot-ssj/crates/utils/.gitignore b/kakarot-ssj/crates/utils/.gitignore new file mode 100644 index 000000000..eb5a316cb --- /dev/null +++ b/kakarot-ssj/crates/utils/.gitignore @@ -0,0 +1 @@ +target diff --git a/kakarot-ssj/crates/utils/Scarb.toml b/kakarot-ssj/crates/utils/Scarb.toml new file mode 100644 index 000000000..83548065f --- /dev/null +++ b/kakarot-ssj/crates/utils/Scarb.toml @@ -0,0 +1,25 @@ +[package] +name = "utils" +version = "0.1.0" +edition = "2024_07" + +# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html + +[dependencies] +evm = { path = "../evm" } +alexandria_data_structures = { path = "../alexandria_data_structures" } + +# For profiling +[cairo] +unstable-add-statements-functions-debug-info = true + +[tool] +fmt.workspace = true + +[dev-dependencies] +snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry.git", tag = "v0.31.0" } +assert_macros = "2.8.2" + +[scripts] +test = "snforge test --max-n-steps 4294967295" +test-profiling = "snforge test --max-n-steps 4294967295 --build-profile" diff --git a/kakarot-ssj/crates/utils/src/address.cairo b/kakarot-ssj/crates/utils/src/address.cairo new file mode 100644 index 000000000..97a782c26 --- /dev/null +++ b/kakarot-ssj/crates/utils/src/address.cairo @@ -0,0 +1,100 @@ +use core::array::ArrayTrait; +use core::starknet::EthAddress; +use core::traits::TryInto; +use crate::rlp::{RLPTrait, RLPItem}; +use crate::traits::bytes::{ToBytes, U8SpanExTrait}; +use crate::traits::eth_address::EthAddressExTrait; +use crate::traits::{TryIntoResult}; + +use evm::errors::EVMError; + +/// Computes the address of the new account that needs to be created. +/// +/// # Arguments +/// +/// * `sender_address` - The address of the account that wants to create the new account. +/// * `sender_nonce` - The transaction count of the account that wants to create the new account. +/// +/// # Returns +/// +/// The computed address of the new account as an `EthAddress`. +pub fn compute_contract_address(sender_address: EthAddress, sender_nonce: u64) -> EthAddress { + let mut sender_address: RLPItem = RLPItem::String(sender_address.to_bytes().span()); + let sender_nonce: RLPItem = RLPItem::String(sender_nonce.to_be_bytes()); + let computed_address = U8SpanExTrait::compute_keccak256_hash( + RLPTrait::encode_sequence([sender_address, sender_nonce].span()) + ); + let canonical_address = computed_address & 0xffffffffffffffffffffffffffffffffffffffff; + canonical_address.try_into().unwrap() +} + + +/// Computes the address of the new account that needs to be created, which is +/// based on the sender address, salt, and the bytecode. +/// +/// # Arguments +/// +/// * `sender_address` - The address of the account that wants to create the new account. +/// * `salt` - Address generation salt. +/// * `bytecode` - The bytecode of the new account to be created. +/// +/// # Returns +/// +/// A `Result` containing the computed address of the new account as an `EthAddress`, +/// or an `EVMError` if the conversion fails. +pub fn compute_create2_contract_address( + sender_address: EthAddress, salt: u256, bytecode: Span +) -> Result { + let hash = bytecode.compute_keccak256_hash().to_be_bytes_padded(); + + let sender_address = sender_address.to_bytes().span(); + + let salt = salt.to_be_bytes_padded(); + + let mut preimage: Array = array![]; + + preimage.append_span([0xff].span()); + preimage.append_span(sender_address); + preimage.append_span(salt); + preimage.append_span(hash); + + let address_hash = preimage.span().compute_keccak256_hash().to_be_bytes_padded(); + + let address: EthAddress = address_hash.slice(12, 20).try_into_result()?; + + Result::Ok(address) +} + +#[cfg(test)] +mod tests { + use contracts::test_data::counter_evm_bytecode; + use core::starknet::EthAddress; + use crate::address::{compute_contract_address, compute_create2_contract_address}; + + #[test] + fn test_compute_create2_contract_address() { + let bytecode = counter_evm_bytecode(); + let salt = 0xbeef; + let from: EthAddress = 0xF39FD6E51AAD88F6F4CE6AB8827279CFFFB92266 + .try_into() + .expect('Wrong Eth address'); + + let address = compute_create2_contract_address(from, salt, bytecode) + .expect('create2_contract_address fail'); + + assert_eq!(address.into(), 0x088a44D7CdD8DEA4d1Db6E3F4059c70c405a0C97); + } + + #[test] + fn test_compute_contract_address() { + let nonce = 420; + let from: EthAddress = 0xF39FD6E51AAD88F6F4CE6AB8827279CFFFB92266 + .try_into() + .expect('Wrong Eth address'); + + let address = compute_contract_address(from, nonce); + assert( + address.into() == 0x40A633EeF249F21D95C8803b7144f19AAfeEF7ae, 'wrong create address' + ); + } +} diff --git a/kakarot-ssj/crates/utils/src/constants.cairo b/kakarot-ssj/crates/utils/src/constants.cairo new file mode 100644 index 000000000..78ce66bb3 --- /dev/null +++ b/kakarot-ssj/crates/utils/src/constants.cairo @@ -0,0 +1,232 @@ +use crate::traits::{U8IntoEthAddress}; + +// FELT PRIME +// 2^251 + 17 * 2^192 + 1 +pub const FELT252_PRIME: u256 = 0x800000000000011000000000000000000000000000000000000000000000001; + +// Prefix used to compute the address of a Starknet contract being deployed. +// +pub const CONTRACT_ADDRESS_PREFIX: felt252 = 'STARKNET_CONTRACT_ADDRESS'; + + +// BLOCK +pub const BLOCK_GAS_LIMIT: u64 = 7_000_000; +pub const MIN_BASE_FEE_PER_BLOB_GAS: u64 = 1; +// CHAIN_ID = KKRT (0x4b4b5254) in ASCII +pub const CHAIN_ID: u64 = 1263227476; + +// STACK +pub const STACK_MAX_DEPTH: usize = 1024; + +// CODE +pub const MAX_CODE_SIZE: usize = 0x6000; +pub const MAX_INITCODE_SIZE: usize = 0x6000 * 2; + +// KECCAK +// The empty keccak256 hash, Solidity equivalent: +// contract EmptyHash { +// function emptyHash() public pure returns(bytes32) { +// return keccak256(""); +// } +// } +// Reproducing link: +// +pub const EMPTY_KECCAK: u256 = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; + +pub const BURN_ADDRESS: felt252 = 0xdead; + + +// Numeric constants +pub const POW_256_0: u128 = 0x1; +pub const POW_256_1: u128 = 0x100; +pub const POW_256_2: u128 = 0x10000; +pub const POW_256_3: u128 = 0x1000000; +pub const POW_256_4: u128 = 0x100000000; +pub const POW_256_5: u128 = 0x10000000000; +pub const POW_256_6: u128 = 0x1000000000000; +pub const POW_256_7: u128 = 0x100000000000000; +pub const POW_256_8: u128 = 0x10000000000000000; +pub const POW_256_9: u128 = 0x1000000000000000000; +pub const POW_256_10: u128 = 0x100000000000000000000; +pub const POW_256_11: u128 = 0x10000000000000000000000; +pub const POW_256_12: u128 = 0x1000000000000000000000000; +pub const POW_256_13: u128 = 0x100000000000000000000000000; +pub const POW_256_14: u128 = 0x10000000000000000000000000000; +pub const POW_256_15: u128 = 0x1000000000000000000000000000000; +pub const POW_256_16: u256 = 0x100000000000000000000000000000000; + +pub const POW_256_REV: [ + u256 + ; 17] = [ + 0x100000000000000000000000000000000, + 0x1000000000000000000000000000000, + 0x10000000000000000000000000000, + 0x100000000000000000000000000, + 0x1000000000000000000000000, + 0x10000000000000000000000, + 0x100000000000000000000, + 0x1000000000000000000, + 0x10000000000000000, + 0x100000000000000, + 0x1000000000000, + 0x10000000000, + 0x100000000, + 0x1000000, + 0x10000, + 0x100, + 0x1 +]; + +pub const POW_2: [ + u128 + ; 128] = [ + 0x1, + 0x2, + 0x4, + 0x8, + 0x10, + 0x20, + 0x40, + 0x80, + 0x100, + 0x200, + 0x400, + 0x800, + 0x1000, + 0x2000, + 0x4000, + 0x8000, + 0x10000, + 0x20000, + 0x40000, + 0x80000, + 0x100000, + 0x200000, + 0x400000, + 0x800000, + 0x1000000, + 0x2000000, + 0x4000000, + 0x8000000, + 0x10000000, + 0x20000000, + 0x40000000, + 0x80000000, + 0x100000000, + 0x200000000, + 0x400000000, + 0x800000000, + 0x1000000000, + 0x2000000000, + 0x4000000000, + 0x8000000000, + 0x10000000000, + 0x20000000000, + 0x40000000000, + 0x80000000000, + 0x100000000000, + 0x200000000000, + 0x400000000000, + 0x800000000000, + 0x1000000000000, + 0x2000000000000, + 0x4000000000000, + 0x8000000000000, + 0x10000000000000, + 0x20000000000000, + 0x40000000000000, + 0x80000000000000, + 0x100000000000000, + 0x200000000000000, + 0x400000000000000, + 0x800000000000000, + 0x1000000000000000, + 0x2000000000000000, + 0x4000000000000000, + 0x8000000000000000, + 0x10000000000000000, + 0x20000000000000000, + 0x40000000000000000, + 0x80000000000000000, + 0x100000000000000000, + 0x200000000000000000, + 0x400000000000000000, + 0x800000000000000000, + 0x1000000000000000000, + 0x2000000000000000000, + 0x4000000000000000000, + 0x8000000000000000000, + 0x10000000000000000000, + 0x20000000000000000000, + 0x40000000000000000000, + 0x80000000000000000000, + 0x100000000000000000000, + 0x200000000000000000000, + 0x400000000000000000000, + 0x800000000000000000000, + 0x1000000000000000000000, + 0x2000000000000000000000, + 0x4000000000000000000000, + 0x8000000000000000000000, + 0x10000000000000000000000, + 0x20000000000000000000000, + 0x40000000000000000000000, + 0x80000000000000000000000, + 0x100000000000000000000000, + 0x200000000000000000000000, + 0x400000000000000000000000, + 0x800000000000000000000000, + 0x1000000000000000000000000, + 0x2000000000000000000000000, + 0x4000000000000000000000000, + 0x8000000000000000000000000, + 0x10000000000000000000000000, + 0x20000000000000000000000000, + 0x40000000000000000000000000, + 0x80000000000000000000000000, + 0x100000000000000000000000000, + 0x200000000000000000000000000, + 0x400000000000000000000000000, + 0x800000000000000000000000000, + 0x1000000000000000000000000000, + 0x2000000000000000000000000000, + 0x4000000000000000000000000000, + 0x8000000000000000000000000000, + 0x10000000000000000000000000000, + 0x20000000000000000000000000000, + 0x40000000000000000000000000000, + 0x80000000000000000000000000000, + 0x100000000000000000000000000000, + 0x200000000000000000000000000000, + 0x400000000000000000000000000000, + 0x800000000000000000000000000000, + 0x1000000000000000000000000000000, + 0x2000000000000000000000000000000, + 0x4000000000000000000000000000000, + 0x8000000000000000000000000000000, + 0x10000000000000000000000000000000, + 0x20000000000000000000000000000000, + 0x40000000000000000000000000000000, + 0x80000000000000000000000000000000 +]; + +pub const POW_2_0: u128 = 0x1; +pub const POW_2_8: u128 = 0x100; +pub const POW_2_16: u128 = 0x10000; +pub const POW_2_24: u128 = 0x1000000; +pub const POW_2_32: u128 = 0x100000000; +pub const POW_2_40: u128 = 0x10000000000; +pub const POW_2_48: u128 = 0x1000000000000; +pub const POW_2_53: u128 = 0x20000000000000; +pub const POW_2_56: u128 = 0x100000000000000; +pub const POW_2_64: u128 = 0x10000000000000000; +pub const POW_2_72: u128 = 0x1000000000000000000; +pub const POW_2_80: u128 = 0x100000000000000000000; +pub const POW_2_88: u128 = 0x10000000000000000000000; +pub const POW_2_96: u128 = 0x1000000000000000000000000; +pub const POW_2_104: u128 = 0x100000000000000000000000000; +pub const POW_2_112: u128 = 0x10000000000000000000000000000; +pub const POW_2_120: u128 = 0x1000000000000000000000000000000; +pub const POW_2_127: u128 = 0x80000000000000000000000000000000; + +pub const MAX_ADDRESS: u256 = 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; diff --git a/kakarot-ssj/crates/utils/src/crypto.cairo b/kakarot-ssj/crates/utils/src/crypto.cairo new file mode 100644 index 000000000..261fd6b16 --- /dev/null +++ b/kakarot-ssj/crates/utils/src/crypto.cairo @@ -0,0 +1,2 @@ +pub mod blake2_compress; +pub mod modexp; diff --git a/kakarot-ssj/crates/utils/src/crypto/blake2_compress.cairo b/kakarot-ssj/crates/utils/src/crypto/blake2_compress.cairo new file mode 100644 index 000000000..e008e7271 --- /dev/null +++ b/kakarot-ssj/crates/utils/src/crypto/blake2_compress.cairo @@ -0,0 +1,170 @@ +use alexandria_data_structures::vec::{Felt252Vec, VecTrait}; +use core::num::traits::{BitSize, WrappingAdd}; +use crate::math::WrappingBitshift; + +const SIGMA_LINE_1: [usize; 16] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; +const SIGMA_LINE_2: [usize; 16] = [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3]; +const SIGMA_LINE_3: [usize; 16] = [11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4]; +const SIGMA_LINE_4: [usize; 16] = [7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8]; +const SIGMA_LINE_5: [usize; 16] = [9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13]; +const SIGMA_LINE_6: [usize; 16] = [2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9]; +const SIGMA_LINE_7: [usize; 16] = [12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11]; +const SIGMA_LINE_8: [usize; 16] = [13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10]; +const SIGMA_LINE_9: [usize; 16] = [6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5]; +const SIGMA_LINE_10: [usize; 16] = [10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0]; + +const IV_DATA: [ + u64 + ; 8] = [ + 0x6a09e667f3bcc908, + 0xbb67ae8584caa73b, + 0x3c6ef372fe94f82b, + 0xa54ff53a5f1d36f1, + 0x510e527fade682d1, + 0x9b05688c2b3e6c1f, + 0x1f83d9abfb41bd6b, + 0x5be0cd19137e2179, +]; + +/// SIGMA from [spec](https://datatracker.ietf.org/doc/html/rfc7693#section-2.7) +fn SIGMA() -> Span> { + [ + SIGMA_LINE_1.span(), + SIGMA_LINE_2.span(), + SIGMA_LINE_3.span(), + SIGMA_LINE_4.span(), + SIGMA_LINE_5.span(), + SIGMA_LINE_6.span(), + SIGMA_LINE_7.span(), + SIGMA_LINE_8.span(), + SIGMA_LINE_9.span(), + SIGMA_LINE_10.span(), + ].span() +} + +/// got IV from [here](https://en.wikipedia.org/wiki/BLAKE_(hash_function)) +fn IV() -> Span { + IV_DATA.span() +} + +fn rotate_right(value: u64, n: u32) -> u64 { + if n == 0 { + value // No rotation needed + } else { + let bits = BitSize::::bits(); // The number of bits in a u64 + let n = n % bits; // Ensure n is less than 64 + + let res = value.wrapping_shr(n.into()) | value.wrapping_shl((bits - n).into()); + res + } +} + +/// compression function: [see](https://datatracker.ietf.org/doc/html/rfc7693#section-3.2) +/// # Parameters +/// * `rounds` - number of rounds for mixing +/// * `h` - state vector +/// * `m` - message block, padded with 0s to full block size +/// * `t` - 2w-bit counter +/// * `f` - final block indicator flag +/// # Returns +/// updated state vector +pub fn compress(rounds: usize, h: Span, m: Span, t: Span, f: bool) -> Span { + let mut v = VecTrait::::new(); + for _ in 0..16_u8 { + v.push(0); + }; + + let IV = IV(); + + let mut i = 0; + loop { + if (i == h.len()) { + break; + } + + v.set(i, *h[i]); + v.set(i + h.len(), *IV[i]); + + i += 1; + }; + + v.set(12, v[12] ^ *t[0]); + v.set(13, v[13] ^ *t[1]); + + if f { + v.set(14, ~v[14]); + } + + let mut i = 0; + loop { + if i == rounds { + break; + } + + let s = *(SIGMA()[i % 10]); + + g(ref v, 0, 4, 8, 12, *m[*s[0]], *m[*s[1]]); + g(ref v, 1, 5, 9, 13, *m[*s[2]], *m[*s[3]]); + g(ref v, 2, 6, 10, 14, *m[*s[4]], *m[*s[5]]); + g(ref v, 3, 7, 11, 15, *m[*s[6]], *m[*s[7]]); + + g(ref v, 0, 5, 10, 15, *m[*s[8]], *m[*s[9]]); + g(ref v, 1, 6, 11, 12, *m[*s[10]], *m[*s[11]]); + g(ref v, 2, 7, 8, 13, *m[*s[12]], *m[*s[13]]); + g(ref v, 3, 4, 9, 14, *m[*s[14]], *m[*s[15]]); + + i += 1; + }; + + let mut result: Array = Default::default(); + + let mut i = 0; + loop { + if (i == 8) { + break; + } + + result.append(*h[i] ^ (v[i] ^ v[i + 8])); + + i += 1; + }; + + result.span() +} + + +/// Mixing Function G +/// It mixes input words into four words indexed by "a", "b", "c", and "d" in the working vector, +/// see [spec](https://datatracker.ietf.org/doc/html/rfc7693#section-3.1) +/// +/// # Parameters +/// * `v` - working vector +/// * `a`- index of word v[a] +/// * `b`- index of word v[b] +/// * `c`- index of word v[c] +/// * `d`- index of word v[d] +/// * `x` - input word x to be used for mixing +/// * `y` - input word y to be used for mixing +fn g(ref v: Felt252Vec, a: usize, b: usize, c: usize, d: usize, x: u64, y: u64) { + let mut v_a = v[a]; + let mut v_b = v[b]; + let mut v_c = v[c]; + let mut v_d = v[d]; + + let tmp = v_a.wrapping_add(v_b); + v_a = tmp.wrapping_add(x); + v_d = rotate_right(v_d ^ v_a, 32); + v_c = v_c.wrapping_add(v_d); + v_b = rotate_right(v_b ^ v_c, 24); + + let tmp = v_a.wrapping_add(v_b); + v_a = tmp.wrapping_add(y); + v_d = rotate_right(v_d ^ v_a, 16); + v_c = v_c.wrapping_add(v_d); + v_b = rotate_right(v_b ^ v_c, 63); + + v.set(a, v_a); + v.set(b, v_b); + v.set(c, v_c); + v.set(d, v_d); +} diff --git a/kakarot-ssj/crates/utils/src/crypto/modexp.cairo b/kakarot-ssj/crates/utils/src/crypto/modexp.cairo new file mode 100644 index 000000000..0fde2f4c2 --- /dev/null +++ b/kakarot-ssj/crates/utils/src/crypto/modexp.cairo @@ -0,0 +1,3 @@ +pub mod arith; +pub mod lib; +pub mod mpnat; diff --git a/kakarot-ssj/crates/utils/src/crypto/modexp/arith.cairo b/kakarot-ssj/crates/utils/src/crypto/modexp/arith.cairo new file mode 100644 index 000000000..d82bf2f61 --- /dev/null +++ b/kakarot-ssj/crates/utils/src/crypto/modexp/arith.cairo @@ -0,0 +1,2524 @@ +// CREDITS: The implementation has been take from +// [aurora-engine](https://github.com/aurora-is-near/aurora-engine/tree/develop/engine-modexp) +use alexandria_data_structures::vec::{Felt252Vec, Felt252VecImpl}; + +use core::num::traits::{WideMul, OverflowingAdd, OverflowingSub, WrappingMul}; +use core::option::OptionTrait; +use crate::felt_vec::{Felt252VecTrait}; +use crate::helpers::{u128_split}; +use crate::math::WrappingBitshift; +use crate::math::{Bitshift}; +use crate::traits::BoolIntoNumeric; +use crate::traits::integer::U128Trait; +use super::mpnat::{MPNat, Word, DoubleWord, WORD_BITS, BASE, DOUBLE_WORD_MAX, WORD_MAX}; + +// Computes the "Montgomery Product" of two numbers. +// See Coarsely Integrated Operand Scanning (CIOS) Method in +// https://www.microsoft.com/en-us/research/wp-content/uploads/1996/01/j37acmon.pdf +// In short, computes `xy (r^-1) mod n`, where `r = 2^(8*4*s)` and `s` is the number of +// digits needs to represent `n`. `n_prime` has the property that `r(r^(-1)) - nn' = 1`. +// Note: This algorithm only works if `xy < rn` (generally we will either have both `x < n`, `y < n` +// or we will have `x < r`, `y < n`). +pub fn monpro(ref x: MPNat, ref y: MPNat, ref n: MPNat, n_prime: Word, ref out: Felt252Vec) { + let s = out.len() - 2; + + let mut i = 0; + loop { + if i == s { + break; + } + + let mut c = 0; + let mut j = 0; + + loop { + if j == s { + break; + } + + let (prod, carry) = shifted_carrying_mul( + out[j], x.digits.get(j).unwrap_or(0), y.digits.get(i).unwrap_or(0), c, + ); + out.set(j, prod); + c = carry; + + j += 1; + }; + + let (sum, carry) = carrying_add(out[s], c, false); + out.set(s, sum); + out.set(s + 1, carry.into()); + + let m = out[0].wrapping_mul(n_prime); + let (_, carry) = shifted_carrying_mul(out[0], m, n.digits.get(0).unwrap_or(0), 0); + c = carry; + + let mut j = 1; + loop { + if j == s { + break; + } + + let (prod, carry) = shifted_carrying_mul(out[j], m, n.digits.get(j).unwrap_or(0), c); + out.set(j - 1, prod); + c = carry; + + j += 1; + }; + + let (sum, carry) = carrying_add(out[s], c, false); + out.set(s - 1, sum); + out.set(s, out[s + 1] + (carry.into())); // overflow impossible at this stage + + i += 1; + }; + + // Result is only in the first s + 1 words of the output. + out.set(s + 1, 0); + + let mut j = s + 1; + let should_return = loop { + if j == 0 { + break false; + } + + let i = j - 1; + + if out[i] > n.digits.get(i).unwrap_or(0) { + break false; + } else if out[i] < n.digits.get(i).unwrap_or(0) { + break true; + } + + j -= 1; + }; + + if should_return { + return; + } + + let mut b = false; + let mut i: u32 = 0; + loop { + if i == s || i == out.len { + break; + } + + let out_digit = out[i]; + + let (diff, borrow) = borrowing_sub(out_digit, n.digits.get(i).unwrap_or(0), b); + out.set(i, diff); + b = borrow; + + i += 1; + }; + + let (diff, _) = borrowing_sub(out[s], 0, b); + out.set(s, diff); +} + +// Equivalent to `monpro(x, x, n, n_prime, out)`, but more efficient. +pub fn monsq(ref x: MPNat, ref n: MPNat, n_prime: Word, ref out: Felt252Vec) { + let s = n.digits.len(); + + big_sq(ref x, ref out); + let mut i = 0; + + loop { + if i == s { + break false; + } + + let mut c: Word = 0; + let m = out[i].wrapping_mul(n_prime); + + let mut j = 0; + loop { + if j == s { + break; + } + + let (prod, carry) = shifted_carrying_mul( + out[i + j], m, n.digits.get(j).unwrap_or(0), c + ); + out.set(i + j, prod); + c = carry; + + j += 1; + }; + + let mut j = i + s; + loop { + if c == 0 { + break; + } + let (sum, carry) = carrying_add(out[j], c, false); + out.set(j, sum); + c = carry.into(); + + j += 1; + }; + + i += 1; + }; + + // Only keep the last `s + 1` digits in `out`. + let mut new_vec: Felt252Vec = out.clone_slice(s, s + 1); + + // safe unwrap, since new_vec.len <= out.len + new_vec.expand(out.len).unwrap(); + out = new_vec; + + let mut k = s + 1; + let should_return = loop { + if k == 0 { + break false; + } + + let i = k - 1; + + if out[i] < n.digits.get(i).unwrap_or(0) { + break true; + } + if out[i] > n.digits.get(i).unwrap_or(0) { + break false; + } + + k -= 1; + }; + + if should_return { + return; + } + + let mut b = false; + let mut i = 0; + loop { + if i == s || i == out.len { + break; + } + + let out_digit = out[i]; + let (diff, borrow) = borrowing_sub(out_digit, n.digits.get(i).unwrap_or(0), b); + out.set(i, diff); + b = borrow; + + i += 1; + }; + + let (diff, _) = borrowing_sub(out[s], 0, b); + out.set(s, diff); +} + + +/// Computes `base ^ exp`, ignoring overflow. +pub fn big_wrapping_pow( + ref base: MPNat, exp: Span, ref scratch_space: Felt252Vec +) -> MPNat { + let mut digits = Felt252VecImpl::new(); + digits.expand(scratch_space.len()).unwrap(); + let mut result = MPNat { digits }; + result.digits.set(0, 1); + + let mut i = 0; + loop { + if i == exp.len() { + break; + } + + let b = *exp[i]; + let mut mask: u8 = 128; + + loop { + if mask == 0 { + break; + } + + // TODO: investigae if deep clone can be avoided + let digits = result.digits.duplicate(); + let mut tmp = MPNat { digits }; + + big_wrapping_mul(ref result, ref tmp, ref scratch_space); + result.digits.copy_from_vec_le(ref scratch_space).unwrap(); + scratch_space.reset(); // zero-out the scatch space + + if (b & mask) != 0 { + big_wrapping_mul(ref result, ref base, ref scratch_space); + result.digits.copy_from_vec_le(ref scratch_space).unwrap(); + scratch_space.reset(); // zero-out the scatch space + } + + mask = mask.shr(1); + }; + + i += 1; + }; + + result +} + +/// Computes `(x * y) mod 2^(WORD_BITS*out.len())`. +pub fn big_wrapping_mul(ref x: MPNat, ref y: MPNat, ref out: Felt252Vec) { + let s = out.len(); + let mut i = 0; + + loop { + if i == s { + break; + } + + let mut c: Word = 0; + + let mut j = 0; + let stop_condition = s - i; + loop { + if j == stop_condition { + break; + } + + let (prod, carry) = shifted_carrying_mul( + out[i + j], x.digits.get(j).unwrap_or(0), y.digits.get(i).unwrap_or(0), c + ); + c = carry; + out.set(i + j, prod); + + j += 1; + }; + + i += 1; + } +} + +// Given x odd, computes `x^(-1) mod 2^32`. +// See `MODULAR-INVERSE` in https://link.springer.com/content/pdf/10.1007/3-540-46877-3_21.pdf +pub fn mod_inv(x: Word) -> Word { + let mut y = 1; + let mut i = 2; + + loop { + if i == WORD_BITS { + break; + } + + let mask: u64 = 1_u64.shl(i.into()) - 1; + let xy = x.wrapping_mul(y) & mask; + let q = (mask + 1) / 2; + if xy >= q { + y += q; + } + i += 1; + }; + + let xy = x.wrapping_mul(y); + let q = 1_u64.wrapping_shl((WORD_BITS - 1).into()); + if xy >= q { + y += q; + } + y +} + +/// Computes R mod n, where R = 2^(WORD_BITS*k) and k = n.digits.len() +/// Note that if R = qn + r, q must be smaller than 2^WORD_BITS since `2^(WORD_BITS) * n > R` +/// (adding a whole additional word to n is too much). +/// Uses the two most significant digits of n to approximate the quotient, +/// then computes the difference to get the remainder. It is possible that this +/// quotient is too big by 1; we can catch that case by looking for overflow +/// in the subtraction. +pub fn compute_r_mod_n(ref n: MPNat, ref out: Felt252Vec) { + let k = n.digits.len(); + + if k == 1 { + let r = BASE; + let result = r % (n.digits[0].into()); + out.set(0, result.as_u64()); + return; + } + + let approx_n = join_as_double(n.digits[k - 1], n.digits[k - 2]); + let approx_q = DOUBLE_WORD_MAX / approx_n; + let mut approx_q: Word = approx_q.as_u64(); + + loop { + let mut c = 0; + let mut b = false; + + let mut i: usize = 0; + loop { + if i == n.digits.len || i == out.len { + break; + } + + let n_digit = n.digits[i]; + + let (prod, carry) = carrying_mul(approx_q, n_digit, c); + c = carry; + + let (diff, borrow) = borrowing_sub(0, prod, b); + b = borrow; + out.set(i, diff); + + i += 1; + }; + + let (_, borrow) = borrowing_sub(1, c, b); + if borrow { + // approx_q was too large so `R - approx_q*n` overflowed. + // try again with approx_q -= 1 + approx_q -= 1; + } else { + break; + } + } +} + +/// Computes `a + xy + c` where any overflow is captured as the "carry", +/// the second part of the output. The arithmetic in this function is +/// guaranteed to never overflow because even when all 4 variables are +/// equal to `WORD_MAX` the output is smaller than `DOUBLEWORD_MAX`. +pub fn shifted_carrying_mul(a: Word, x: Word, y: Word, c: Word) -> (Word, Word) { + let res: DoubleWord = a.into() + x.wide_mul(y) + c.into(); + let (top_word, bottom_word) = u128_split(res); + (bottom_word, top_word) +} + +/// Computes `xy + c` where any overflow is captured as the "carry", +/// the second part of the output. The arithmetic in this function is +/// guaranteed to never overflow because even when all 3 variables are +/// equal to `Word::MAX` the output is smaller than `DoubleWord::MAX`. +pub fn carrying_mul(x: Word, y: Word, c: Word) -> (Word, Word) { + let wide = x.wide_mul(y) + c.into(); + let (top_word, bottom_word) = u128_split(wide); + (bottom_word, top_word) +} + +/// computes x + y accounting for any carry from a previous addition +pub fn carrying_add(x: Word, y: Word, carry: bool) -> (Word, bool) { + let (a, b) = x.overflowing_add(y); + let (c, d) = a.overflowing_add(carry.into()); + (c, b | d) +} + +// Computes `x - y` accounting for any borrow from a previous subtraction +pub fn borrowing_sub(x: Word, y: Word, borrow: bool) -> (Word, bool) { + let (a, b) = x.overflowing_sub(y); + let (c, d) = a.overflowing_sub(borrow.into()); + (c, b | d) +} + +/// Takes 2 words and joins them into a double word +/// +/// # Arguments +/// `hi` is the most significant word +/// `lo` is the least significant word +/// +/// # Returns +/// The double word obtained by joining `hi` and `lo` +pub fn join_as_double(hi: Word, lo: Word) -> DoubleWord { + let hi: DoubleWord = hi.into(); + (hi.shl(WORD_BITS.into())).into() + lo.into() +} + +/// Computes `x^2`, storing the result in `out`. +fn big_sq(ref x: MPNat, ref out: Felt252Vec) { + let s = x.digits.len(); + let mut i = 0; + + loop { + if i == s { + break; + } + + let (product, carry) = shifted_carrying_mul(out[i + i], x.digits[i], x.digits[i], 0); + out.set(i + i, product); + let mut c: DoubleWord = carry.into(); + + let mut j = i + 1; + + loop { + if j == s { + break; + } + + let mut new_c: DoubleWord = 0; + let res: DoubleWord = (x.digits[i].into()) * (x.digits[j].into()); + let (res, overflow) = res.overflowing_add(res); + if overflow { + new_c += BASE; + } + + let (res, overflow) = out[i + j].into().overflowing_add(res); + if overflow { + new_c += BASE; + } + + let (res, overflow) = res.overflowing_add(c); + if overflow { + new_c += BASE; + } + + out.set(i + j, res.as_u64()); + c = new_c + res.shr(WORD_BITS.into()); + + j += 1; + }; + + let (sum, carry) = carrying_add(out[i + s], c.as_u64(), false); + out.set(i + s, sum); + out.set(i + s + 1, (c.shr(WORD_BITS.into()) + (carry.into())).as_u64()); + + i += 1; + } +} + +// Performs `a <<= shift`, returning the overflow +pub fn in_place_shl(ref a: Felt252Vec, shift: u32) -> Word { + let mut c: Word = 0; + let carry_shift = WORD_BITS - shift; + + let mut i = 0; + loop { + if i == a.len { + break; + } + + let mut a_digit = a[i]; + let carry = a_digit.wrapping_shr(carry_shift.into()); + a_digit = a_digit.wrapping_shl(shift.into()) | c; + a.set(i, a_digit); + + c = carry; + + i += 1; + }; + + c +} + +// Performs `a >>= shift`, returning the overflow +pub fn in_place_shr(ref a: Felt252Vec, shift: u32) -> Word { + let mut b: Word = 0; + let borrow_shift = WORD_BITS - shift; + + let mut i = a.len; + loop { + if i == 0 { + break; + } + + let j = i - 1; + + let mut a_digit = a[j]; + let borrow = a_digit.wrapping_shl(borrow_shift.into()); + a_digit = a_digit.wrapping_shr(shift.into()) | b; + a.set(j, a_digit); + + b = borrow; + + i -= 1; + }; + + b +} + +// Performs a += b, returning if there was overflow +pub fn in_place_add(ref a: Felt252Vec, ref b: Felt252Vec) -> bool { + let mut c = false; + + let mut i = 0; + + loop { + if i == a.len() || i == b.len() { + break; + } + + let a_digit = a[i]; + let b_digit = b[i]; + + let (sum, carry) = carrying_add(a_digit, b_digit, c); + a.set(i, sum); + c = carry; + + i += 1; + }; + + c +} + +// Performs `a -= xy`, returning the "borrow". +pub fn in_place_mul_sub(ref a: Felt252Vec, ref x: Felt252Vec, y: Word) -> Word { + // a -= x*0 leaves a unchanged, so return early + if y == 0 { + return 0; + } + + // carry is between -big_digit::MAX and 0, so to avoid overflow we store + // offset_carry = carry + big_digit::MAX + let mut offset_carry = WORD_MAX; + + let mut i = 0; + + loop { + if i == a.len() || i == x.len() { + break; + } + + let a_digit = a[i]; + let x_digit = x[i]; + + // We want to calculate sum = x - y * c + carry. + // sum >= -(big_digit::MAX * big_digit::MAX) - big_digit::MAX + // sum <= big_digit::MAX + // Offsetting sum by (big_digit::MAX << big_digit::BITS) puts it in DoubleBigDigit range. + let offset_sum = join_as_double(WORD_MAX, a_digit) + - WORD_MAX.into() + + offset_carry.into() + - ((x_digit.into()) * (y.into())); + + let new_offset_carry = (offset_sum.shr(WORD_BITS.into())).as_u64(); + let new_x = offset_sum.as_u64(); + offset_carry = new_offset_carry; + a.set(i, new_x); + + i += 1; + }; + + // Return the borrow. + WORD_MAX - offset_carry +} + + +#[cfg(test)] +mod tests { + use alexandria_data_structures::vec::VecTrait; + use alexandria_data_structures::vec::{Felt252Vec, Felt252VecImpl}; + use core::num::traits::{WrappingSub, WrappingMul}; + use core::result::ResultTrait; + use core::traits::Into; + + use crate::crypto::modexp::arith::{ + mod_inv, monsq, monpro, compute_r_mod_n, in_place_shl, in_place_shr, big_wrapping_pow, + big_wrapping_mul, big_sq, borrowing_sub, shifted_carrying_mul + }; + use crate::crypto::modexp::mpnat::{ + MPNat, MPNatTrait, WORD_MAX, DOUBLE_WORD_MAX, BASE, Word, WORD_BYTES + }; + use crate::crypto::modexp::mpnat::{mp_nat_to_u128}; + use crate::felt_vec::{Felt252VecTrait}; + use crate::math::{WrappingBitshift, WrappingExponentiation}; + use crate::traits::bytes::ToBytes; + + // the tests are taken from + // [aurora-engine](https://github.com/aurora-is-near/aurora-engine/blob/1213f2c7c035aa523601fced8f75bef61b4728ab/engine-modexp/src/arith.rs#L401) + + fn check_monsq(x: u128, n: u128) { + let mut a = MPNatTrait::from_big_endian(x.to_be_bytes_padded()); + let mut m = MPNatTrait::from_big_endian(n.to_be_bytes_padded()); + let n_prime = WORD_MAX - mod_inv(m.digits[0]) + 1; + + let mut output = Felt252VecImpl::new(); + output.expand(2 * m.digits.len() + 1).unwrap(); + + monsq(ref a, ref m, n_prime, ref output); + let mut result = MPNat { digits: output }; + + let mut output = Felt252VecImpl::new(); + output.expand(m.digits.len() + 2).unwrap(); + let mut tmp = MPNat { digits: a.digits.duplicate() }; + monpro(ref a, ref tmp, ref m, n_prime, ref output); + + let mut expected = MPNat { digits: output }; + + assert!(result.digits.equal_remove_trailing_zeroes(ref expected.digits)); + } + + fn check_monpro(x: u128, y: u128, n: u128, ref expected: MPNat) { + let mut a = MPNatTrait::from_big_endian(x.to_be_bytes_padded()); + let mut b = MPNatTrait::from_big_endian(y.to_be_bytes_padded()); + let mut m = MPNatTrait::from_big_endian(n.to_be_bytes()); + let n_prime = WORD_MAX - mod_inv(m.digits[0]) + 1; + + let mut output = Felt252VecImpl::new(); + output.expand(m.digits.len() + 2).unwrap(); + monpro(ref a, ref b, ref m, n_prime, ref output); + let mut result = MPNat { digits: output }; + + assert!(result.digits.equal_remove_trailing_zeroes(ref expected.digits)); + } + + + fn check_r_mod_n(n: u128, ref expected: MPNat) { + let mut x = MPNatTrait::from_big_endian(n.to_be_bytes_padded()); + let mut out: Felt252Vec = Felt252VecImpl::new(); + out.expand(x.digits.len()).unwrap(); + compute_r_mod_n(ref x, ref out); + let mut result = MPNat { digits: out }; + assert!(result.digits.equal_remove_trailing_zeroes(ref expected.digits)); + } + + fn check_in_place_shl(n: u128, shift: u32) { + let mut x = MPNatTrait::from_big_endian(n.to_be_bytes_padded()); + in_place_shl(ref x.digits, shift); + let mut result = mp_nat_to_u128(ref x); + + let mask = BASE.wrapping_pow(x.digits.len().into()).wrapping_sub(1); + assert_eq!(result, n.wrapping_shl(shift.into()) & mask); + } + + fn check_in_place_shr(n: u128, shift: u32) { + let mut x = MPNatTrait::from_big_endian(n.to_be_bytes_padded()); + in_place_shr(ref x.digits, shift); + let mut result = mp_nat_to_u128(ref x); + + assert_eq!(result, n.wrapping_shr(shift.into())); + } + + fn check_mod_inv(n: Word) { + let n_inv = mod_inv(n); + assert_eq!(n.wrapping_mul(n_inv), 1); + } + + fn check_big_wrapping_pow(a: u128, b: u32, expected_bytes: Span) { + let mut x = MPNatTrait::from_big_endian(a.to_be_bytes_padded()); + let mut y = b.to_be_bytes_padded(); + + let mut scratch = Felt252VecImpl::new(); + scratch.expand(1 + (expected_bytes.len() / WORD_BYTES)).unwrap(); + + let mut result = big_wrapping_pow(ref x, y, ref scratch); + + let mut expected = MPNatTrait::from_big_endian(expected_bytes); + assert!(result.digits.equal_remove_trailing_zeroes(ref expected.digits)); + } + + fn check_big_wrapping_mul(a: u128, b: u128, output_digits: usize, ref expected: MPNat) { + let mut x = MPNatTrait::from_big_endian(a.to_be_bytes_padded()); + let mut y = MPNatTrait::from_big_endian(b.to_be_bytes_padded()); + + let mut out = Felt252VecImpl::new(); + out.expand(output_digits).unwrap(); + + big_wrapping_mul(ref x, ref y, ref out); + let mut result = MPNat { digits: out }; + + assert!(result.digits.equal_remove_trailing_zeroes(ref expected.digits)); + } + + fn check_big_sq(a: u128, ref expected: MPNat) { + let mut x = MPNatTrait::from_big_endian(a.to_be_bytes_padded()); + let mut out = Felt252VecImpl::new(); + out.expand(2 * x.digits.len() + 1).unwrap(); + + big_sq(ref x, ref out); + + let mut result = MPNat { digits: out }; + assert!(result.digits.equal_remove_trailing_zeroes(ref expected.digits)); + } + + #[test] + fn test_monsq_alpha() { + let mut x = Felt252VecImpl::new(); + x.push(0xf72fc634c83435bc); + x.push(0xa6b0ce70ac511873); + let mut x = MPNat { digits: x }; + + let mut y = Felt252VecImpl::new(); + y.push(0xf3e77eceb2ecfce5); + y.push(0xc4550871a1cfc67a); + let mut y = MPNat { digits: y }; + + let n_prime = 0xa51080a4eb8b9f13; + let mut scratch = Felt252VecImpl::new(); + scratch.expand(5).unwrap(); + + monsq(ref x, ref y, n_prime, ref scratch); + } + + + #[test] + fn test_monsq_0() { + check_monsq(1, 31); + } + + #[test] + fn test_monsq_1() { + check_monsq(6, 31); + } + + #[test] + fn test_monsq_2() { + // This example is intentionally chosen because 5 * 5 = 25 = 0 mod 25, + // therefore it requires the final subtraction step in the algorithm. + check_monsq(5, 25); + } + + #[test] + fn test_monsq_3() { + check_monsq(0x1FFF_FFFF_FFFF_FFF0, 0x1FFF_FFFF_FFFF_FFF1); + } + + #[test] + fn test_monsq_4() { + check_monsq(0x16FF_221F_CB7D, 0x011E_842B_6BAA_5017_EBF2_8293); + } + + #[test] + fn test_monsq_5() { + check_monsq(0x0A2D_63F5_CFF9, 0x1F3B_3BD9_43EF); + } + + #[test] + fn test_monsq_6() { + check_monsq(0xa6b0ce71a380dea7c83435bc, 0xc4550871a1cfc67af3e77eceb2ecfce5,); + } + + #[test] + fn test_monpro_0() { + let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); + expected_digits.push(2); + let mut expected = MPNat { digits: expected_digits }; + + check_monpro(1, 1, 31, ref expected); + } + + #[test] + fn test_monpro_1() { + let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); + expected_digits.push(22); + let mut expected = MPNat { digits: expected_digits }; + + check_monpro(6, 7, 31, ref expected); + } + + #[test] + fn test_monpro_2() { + let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); + expected_digits.push(0); + let mut expected = MPNat { digits: expected_digits }; + + // This example is intentionally chosen because 5 * 7 = 35 = 0 mod 35, + // therefore it requires the final subtraction step in the algorithm. + check_monpro(5, 7, 35, ref expected); + } + + #[test] + fn test_monpro_3() { + let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); + expected_digits.push(384307168202282284); + + let mut expected = MPNat { digits: expected_digits }; + + // This example is intentionally chosen because 5 * 7 = 35 = 0 mod 35, + // therefore it requires the final subtraction step in the algorithm. + check_monpro(0x1FFF_FFFF_FFFF_FFF0, 0x1234, 0x1FFF_FFFF_FFFF_FFF1, ref expected); + } + + #[test] + fn test_monpro_4() { + let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); + expected_digits.push(0); + let mut expected = MPNat { digits: expected_digits }; + + // This example is intentionally chosen because 5 * 7 = 35 = 0 mod 35, + // therefore it requires the final subtraction step in the algorithm. + check_monpro( + 0x16FF_221F_CB7D, 0x0C75_8535_434F, 0x011E_842B_6BAA_5017_EBF2_8293, ref expected + ); + } + + #[test] + fn test_monpro_5() { + let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); + expected_digits.push(4425093052866); + let mut expected = MPNat { digits: expected_digits }; + + // This example is intentionally chosen because 5 * 7 = 35 = 0 mod 35, + // therefore it requires the final subtraction step in the algorithm. + check_monpro(0x0A2D_63F5_CFF9, 0x1B21_FF3C_FA8E, 0x1F3B_3BD9_43EF, ref expected); + } + + #[test] + fn test_r_mod_n_0() { + let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); + expected_digits.push(1); + let mut expected = MPNat { digits: expected_digits }; + + check_r_mod_n(0x01_00_00_00_01, ref expected); + } + + #[test] + fn test_r_mod_n_1() { + let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); + expected_digits.push(549722259457); + let mut expected = MPNat { digits: expected_digits }; + + check_r_mod_n(0x80_00_00_00_01, ref expected); + } + + #[test] + fn test_r_mod_n_2() { + let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); + expected_digits.push(1); + let mut expected = MPNat { digits: expected_digits }; + + check_r_mod_n(0xFFFF_FFFF_FFFF_FFFF, ref expected); + } + + #[test] + fn test_r_mod_n_3() { + let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); + expected_digits.push(1); + let mut expected = MPNat { digits: expected_digits }; + + check_r_mod_n(0x0001_0000_0000_0000_0001, ref expected); + } + + #[test] + fn test_r_mod_n_4() { + let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); + expected_digits.push(18446181123756130305); + expected_digits.push(32767); + + let mut expected = MPNat { digits: expected_digits }; + + check_r_mod_n(0x8000_0000_0000_0000_0001, ref expected); + } + + #[test] + fn test_r_mod_n_5() { + let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); + expected_digits.push(3491005389787767287); + expected_digits.push(2668502225); + + let mut expected = MPNat { digits: expected_digits }; + + check_r_mod_n(0xbf2d_c9a3_82c5_6e85_b033_7651, ref expected); + } + + #[test] + fn test_r_mod_n_6() { + let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); + expected_digits.push(4294967296); + + let mut expected = MPNat { digits: expected_digits }; + + check_r_mod_n(0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF, ref expected); + } + + #[test] + fn test_in_place_shl() { + check_in_place_shl(0, 0); + check_in_place_shl(1, 10); + check_in_place_shl(WORD_MAX.into(), 5); + check_in_place_shl(DOUBLE_WORD_MAX.into(), 16); + } + + #[test] + fn test_in_place_shr() { + check_in_place_shr(0, 0); + check_in_place_shr(1, 10); + check_in_place_shr(0x1234_5678, 10); + check_in_place_shr(WORD_MAX.into(), 5); + check_in_place_shr(DOUBLE_WORD_MAX, 16); + } + + #[test] + #[available_gas(10000000000000)] + fn test_mod_inv_0() { + let mut i = 1; + loop { + if i == 1025 { + break; + }; + + check_mod_inv(2 * i - 1); + i += 1; + } + } + + #[test] + #[available_gas(10000000000000)] + fn test_mod_inv_1() { + let mut i = 0; + loop { + if i == 1025 { + break; + }; + + check_mod_inv(0xFF_FF_FF_FF - 2 * i); + i += 1; + } + } + + #[test] + fn test_big_wrapping_pow_0() { + let expected_bytes: Span = [1].span(); + check_big_wrapping_pow(1, 1, expected_bytes); + } + + #[test] + fn test_big_wrapping_pow_1() { + let expected_bytes: Span = [100].span(); + + check_big_wrapping_pow(10, 2, expected_bytes); + } + + #[test] + fn test_big_wrapping_pow_2() { + let expected_bytes: Span = [1, 0, 0, 0, 0].span(); + + check_big_wrapping_pow(2, 32, expected_bytes); + } + + #[test] + fn test_big_wrapping_pow_3() { + let expected_bytes: Span = [1, 0, 0, 0, 0, 0, 0, 0, 0].span(); + check_big_wrapping_pow(2, 64, expected_bytes); + } + + #[test] + #[available_gas(10000000000000)] + fn test_big_wrapping_pow_4() { + let expected_bytes: Span = [ + 3, + 218, + 116, + 252, + 230, + 21, + 167, + 46, + 59, + 185, + 199, + 194, + 149, + 140, + 133, + 157, + 60, + 102, + 160, + 27, + 104, + 79, + 16, + 104, + 20, + 104, + 116, + 207, + 214, + 100, + 237, + 159, + 0, + 245, + 249, + 156, + 52, + 33, + 217, + 113, + 130, + 6, + 65, + 78, + 49, + 141, + 141, + 160, + 29, + 125, + 168, + 236, + 88, + 174, + 146, + 81, + 137, + 165, + 242, + 90, + 251, + 115, + 144, + 169, + 141, + 66, + 207, + 230, + 56, + 199, + 140, + 109, + 7, + 99, + 35, + 155, + 88, + 29, + 90, + 192, + 55, + 127, + 112, + 26, + 176, + 181, + 13, + 72, + 107, + 209, + 1, + 210, + 88, + 233, + 185, + 87, + 108, + 122, + 168, + 137, + 255, + 36, + 201, + 185, + 31, + 36, + 51, + 208, + 64, + 154, + 113, + 233, + 71, + 95, + 35, + 253, + 0, + 3, + 159, + 183, + 10, + 83, + 233, + 88, + 96, + 19, + 104, + 229, + 132, + 73, + 219, + 152, + 126, + 215, + 249, + 46, + 110, + 157, + 234, + 2, + 100, + 178, + 150, + 110, + 217, + 246, + 128, + 219, + 121, + 21, + 234, + 55, + 101, + 81, + 207, + 191, + 200, + 201, + 2, + 40, + 13, + 80, + 107, + 226, + 143, + 164, + 254, + 91, + 54, + 46, + 254, + 7, + 14, + 136, + 149, + 194, + 6, + 191, + 14, + 49, + 140, + 193, + 40, + 1, + 138, + 165, + 82, + 34, + 33, + 169, + 41, + 136, + 130, + 47, + 84, + 173, + 58, + 121, + 192, + 247, + 98, + 237, + 165, + 215, + 161, + 198, + 87, + 228, + 76, + 160, + 66, + 78, + 169, + 139, + 234, + 169, + 83, + 15, + 16, + 192, + 170, + 71, + 227, + 232, + 116, + 189, + 81, + 64, + 104, + 182, + 129, + 203, + 191, + 210, + 151, + 132, + 254, + 239, + 19, + 138, + 49, + 113, + 140, + 77, + 38, + 49, + 117, + 127, + 203, + 123, + 127, + 49, + 32, + 61, + 108, + 120, + 133, + 119, + 8, + 232, + 84, + 57, + 103, + 197, + 160, + 65, + 191, + 82, + 253, + 60, + 191, + 209, + 63, + 176, + 43, + 33, + 54, + 75, + 17, + 73, + 222, + 198, + 80, + 5, + 14, + 50, + 117, + 156, + 77, + 147, + 190, + 230, + 143, + 47, + 149, + 180, + 203, + 144, + 202, + 102, + 231, + 2, + 91, + 22, + 101, + 178, + 211, + 233, + 109, + 156, + 72, + 151, + 199, + 189, + 90, + 76, + 21, + 112, + 21, + 2, + 44, + 96, + 42, + 141, + 217, + 142, + 23, + 75, + 248, + 209, + 26, + 3, + 198, + 103, + 227, + 103, + 140, + 99, + 75, + 211, + 152, + 109, + 19, + 72, + 6, + 116, + 67, + 70, + 32, + 45, + 5, + 113, + 179, + 252, + 2, + 202, + 115, + 244, + 68, + 128, + 156, + 233, + 227, + 211, + 5, + 146, + 147, + 186, + 34, + 3, + 105, + 147, + 64, + 79, + 172, + 141, + 14, + 60, + 69, + 249, + 169, + 76, + 252, + 84, + 151, + 49, + 81, + 246, + 185, + 181, + 181, + 226, + 28, + 152, + 30, + 47, + 248, + 103, + 21, + 184, + 140, + 193, + 112, + 139, + 250, + 206, + 35, + 180, + 122, + 32, + 151, + 105, + 30, + 193, + 68, + 232, + 170, + 174, + 254, + 143, + 29, + 165, + 194, + 14, + 164, + 35, + 25, + 250, + 86, + 76, + 213, + 159, + 21, + 0, + 212, + 146, + 21, + 8, + 180, + 73, + 250, + 116, + 137, + 221, + 20, + 22, + 146, + 169, + 120, + 166, + 229, + 226, + 136, + 201, + 177, + 49, + 21, + 228, + 191, + 246, + 26, + 36, + 183, + 175, + 137, + 71, + 4, + 46, + 235, + 197, + 99, + 0, + 142, + 97, + 184, + 34, + 84, + 254, + 41, + 95, + 198, + 178, + 48, + 105, + 215, + 72, + 155, + 238, + 51, + 164, + 52, + 179, + 126, + 254, + 100, + 35, + 236, + 63, + 215, + 238, + 217, + 239, + 229, + 160, + 192, + 33, + 82, + 165, + 81, + 149, + 186, + 53, + 109, + 184, + 187, + 186, + 8, + 43, + 249, + 20, + 37, + 255, + 241, + 18, + 61, + 97, + 229, + 29, + 201, + 144, + 92, + 202, + 215, + 161, + 165, + 133, + 89, + 180, + 246, + 37, + 16, + 133, + 226, + 209, + 23, + 61, + 241, + 25, + 9, + 150, + 154, + 150, + 133, + 210, + 62, + 115, + 34, + 201, + 187, + 217, + 3, + 82, + 102, + 174, + 233, + 33, + 31, + 7, + 4, + 88, + 70, + 173, + 157, + 111, + 96, + 102, + 223, + 157, + 224, + 158, + 235, + 191, + 55, + 219, + 218, + 146, + 233, + 242, + 250, + 170, + 100, + 68, + 37, + 56, + 251, + 109, + 112, + 217, + 209, + 46, + 229, + 198, + 198, + 156, + 198, + 70, + 76, + 131, + 79, + 40, + 25, + 176, + 21, + 43, + 31, + 121, + 204, + 225, + 128, + 182, + 191, + 148, + 72, + 22, + 112, + 63, + 223, + 182, + 155, + 177, + 183, + 72, + 111, + 6, + 196, + 250, + 189, + 45, + 97, + 182, + 14, + 219, + 189, + 50, + 226, + 91, + 1, + 86, + 95, + 131, + 120, + 224, + 0, + 71, + 28, + 151, + 69, + 24, + 93, + 82, + 237, + 136, + 103, + 90, + 247, + 173, + 204, + 121, + 199, + 17, + 164, + 80, + 49, + 183, + 10, + 200, + 235, + 56, + 72, + 72, + 147, + 150, + 223, + 110, + 165, + 60, + 13, + 251, + 42, + 193, + 78, + 212, + 166, + 178, + 103, + 19, + 35, + 69, + 10, + 137, + 62, + 13, + 90, + 203, + 126, + 203, + 207, + 190, + 184, + 89, + 118, + 186, + 203, + 6, + 115, + 158, + 168, + 35, + 206, + 227, + 48, + 221, + 252, + 190, + 166, + 249, + 96, + 92, + 244, + 77, + 213, + 119, + 44, + 207, + 17, + 16, + 118, + 104, + 106, + 188, + 205, + 5, + 240, + 14, + 181, + 227, + 4, + 11, + 32, + 91, + 224, + 78, + 175, + 49, + 19, + 12, + 233, + 131, + 141, + 47, + 32, + 14, + 195, + 214, + 77, + 158, + 39, + 114, + 167, + 37, + 16, + 249, + 73, + 167, + 230, + 165, + 19, + 4, + 199, + 227, + 251, + 184, + 131, + 137, + 74, + 176, + 116, + 35, + 182, + 121, + 62, + 114, + 64, + 163, + 84, + 208, + 111, + 56, + 191, + 88, + 130, + 64, + 64, + 181, + 162, + 53, + 34, + 16, + 179, + 155, + 137, + 138, + 101, + 121, + 73, + 234, + 189, + 100, + 141, + 122, + 123, + 79, + 200, + 90, + 208, + 83, + 253, + 124, + 125, + 116, + 72, + 138, + 63, + 42, + 144, + 200, + 73, + 233, + 113, + 143, + 85, + 140, + 16, + 240, + 230, + 42, + 114, + 137, + 193, + 10, + 129, + 124, + 193, + 104, + 177, + 55, + 156, + 173, + 135, + 168, + 217, + 1, + 46, + 41, + 132, + 17, + 222, + 178, + 226, + 24, + 108, + 117, + 199, + 171, + 232, + 129, + 82, + 225, + 214, + 105, + 94, + 188, + 72, + 62, + 91, + 193, + 188, + 18, + 33, + 131, + 18, + 194, + 70, + 151, + 187, + 42, + 5, + 62, + 85, + 38, + 134, + 252, + 183, + 227, + 120, + 19, + 152, + 243, + 235, + 114, + 208, + 78, + 57, + 113, + 217, + 182, + 125, + 195, + 64, + 229, + 232, + 54, + 118, + 11, + 119, + 163, + 235, + 12, + 67, + 90, + 246, + 76, + 219, + 200, + 124, + 234, + 41, + 172, + 31, + 167, + 213, + 127, + 100, + 163, + 72, + 44, + 107, + 171, + 229, + 189, + 68, + 201, + 244, + 154, + 27, + 172, + 228, + 234, + 192, + 156, + 127, + 170, + 9, + 78, + 166, + 249, + 154, + 178, + 179, + 172, + 220, + 205, + 220, + 60, + 86, + 98, + 134, + 60, + 134, + 89, + 244, + 187, + 231, + 128, + 6, + 109, + 152, + 251, + 44, + 208, + 238, + 169, + 71, + 51, + 192, + 242, + 57, + 8, + 62, + 206, + 94, + 94, + 25, + 220, + 160, + 175, + 35, + 113, + 66, + 42, + 134, + 241, + 57, + 253, + 44, + 244, + 163, + 158, + 152, + 147, + 79, + 142, + 190, + 139, + 222, + 202, + 216, + 220, + 47, + 179, + 207, + 199, + 104, + 1, + 21, + 106, + 142, + 188, + 105, + 247, + 111, + 202, + 78, + 145, + 66, + 216, + 222, + 96, + 138, + 133, + 28, + 235, + 204, + 100, + 183, + 232, + 65, + 138, + 196, + 133, + 23, + 154, + 0, + 187, + 252, + 32, + 106, + 76, + 94, + 129, + 173, + 13, + 79, + 167, + 103, + 54, + 51, + 102, + 224, + 231, + 159, + 127, + 54, + 131, + 122, + 65, + 83, + 195, + 9, + 175, + 45, + 179, + 32, + 118, + 230, + 101, + 85, + 13, + 85, + 234, + 26, + 16, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ].span(); + check_big_wrapping_pow(2766, 844, expected_bytes); + } + + #[test] + fn test_big_wrapping_mul_0() { + let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); + expected_digits.push(0); + + let mut expected = MPNat { digits: expected_digits }; + + check_big_wrapping_mul(0, 0, 1, ref expected); + } + + + #[test] + fn test_big_wrapping_mul_1() { + let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); + expected_digits.push(1); + + let mut expected = MPNat { digits: expected_digits }; + + check_big_wrapping_mul(1, 1, 1, ref expected); + } + + #[test] + fn test_big_wrapping_mul_2() { + let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); + expected_digits.push(42); + + let mut expected = MPNat { digits: expected_digits }; + + check_big_wrapping_mul(7, 6, 1, ref expected); + } + + #[test] + fn test_big_wrapping_mul_3() { + let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); + expected_digits.push(1); + expected_digits.push(18446744073709551614); + + let mut expected = MPNat { digits: expected_digits }; + + check_big_wrapping_mul(WORD_MAX.into(), WORD_MAX.into(), 2, ref expected); + } + + #[test] + fn test_big_wrapping_mul_4() { + let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); + expected_digits.push(1); + + let mut expected = MPNat { digits: expected_digits }; + + check_big_wrapping_mul(WORD_MAX.into(), WORD_MAX.into(), 1, ref expected); + } + + #[test] + fn test_big_wrapping_mul_5() { + let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); + expected_digits.push(42); + + let mut expected = MPNat { digits: expected_digits }; + + check_big_wrapping_mul(DOUBLE_WORD_MAX - 5, DOUBLE_WORD_MAX - 6, 2, ref expected); + } + + #[test] + fn test_big_wrapping_mul_6() { + let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); + expected_digits.push(6727192404480162174); + expected_digits.push(3070707315540124665); + + let mut expected = MPNat { digits: expected_digits }; + + check_big_wrapping_mul(0xa945_aa5e_429a_6d1a, 0x4072_d45d_3355_237b, 3, ref expected); + } + + #[test] + fn test_big_wrapping_mul_7() { + let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); + expected_digits.push(2063196614268007784); + expected_digits.push(7048986299143829482); + expected_digits.push(14065833420641261004); + + let mut expected = MPNat { digits: expected_digits }; + + check_big_wrapping_mul( + 0x8ae1_5515_fc92_b1c0_b473_8ce8_6bbf_7218, + 0x43e9_8b77_1f7c_aa93_6c4c_85e9_7fd0_504f, + 3, + ref expected + ); + } + + #[test] + fn test_big_sq_0() { + let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); + expected_digits.push(0); + + let mut expected = MPNat { digits: expected_digits }; + + check_big_sq(0, ref expected); + } + + #[test] + fn test_big_sq_1() { + let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); + expected_digits.push(1); + + let mut expected = MPNat { digits: expected_digits }; + + check_big_sq(1, ref expected); + } + + #[test] + fn test_big_sq_2() { + let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); + expected_digits.push(1); + expected_digits.push(18446744073709551614); + + let mut expected = MPNat { digits: expected_digits }; + + check_big_sq(WORD_MAX.into(), ref expected); + } + + #[test] + fn test_big_sq_3() { + let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); + expected_digits.push(4); + expected_digits.push(18446744073709551608); + expected_digits.push(3); + + let mut expected = MPNat { digits: expected_digits }; + + check_big_sq(2 * WORD_MAX.into(), ref expected); + } + + #[test] + fn test_big_sq_4() { + let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); + expected_digits.push(0); + + let mut expected = MPNat { digits: expected_digits }; + + check_big_sq(0, ref expected); + } + + #[test] + fn test_big_sq_5() { + let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); + expected_digits.push(2532367871917050473); + expected_digits.push(16327525306720758713); + expected_digits.push(15087745550001425684); + expected_digits.push(5708046406239628566); + + let mut expected = MPNat { digits: expected_digits }; + + check_big_sq(0x8e67904953db9a2bf6da64bf8bda866d, ref expected); + } + + + #[test] + fn test_big_sq_6() { + let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); + expected_digits.push(15092604974397072849); + expected_digits.push(3791921091882282235); + expected_digits.push(12594445234582458012); + expected_digits.push(7165619740963215273); + + let mut expected = MPNat { digits: expected_digits }; + + check_big_sq(0x9f8dc1c3fc0bf50fe75ac3bbc03124c9, ref expected); + } + + #[test] + fn test_big_sq_7() { + let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); + expected_digits.push(5163998055150312593); + expected_digits.push(8460506958278925118); + expected_digits.push(17089393176389340230); + expected_digits.push(6902937458884066534); + + let mut expected = MPNat { digits: expected_digits }; + + check_big_sq(0x9c9a17378f3d064e5eaa80eeb3850cd7, ref expected); + } + + + #[test] + fn test_big_sq_8() { + let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); + expected_digits.push(2009857620356723108); + expected_digits.push(5657228334642978155); + expected_digits.push(88889113116670247); + expected_digits.push(12075559273075793199); + + let mut expected = MPNat { digits: expected_digits }; + + check_big_sq(0xcf2025cee03025d247ad190e9366d926, ref expected); + } + + #[test] + fn test_big_sq_9() { + let mut expected_digits: Felt252Vec = Felt252VecImpl::new(); + expected_digits.push(1); + expected_digits.push(0); + expected_digits.push(18446744073709551614); + expected_digits.push(18446744073709551615); + + let mut expected = MPNat { digits: expected_digits }; + + check_big_sq(DOUBLE_WORD_MAX, ref expected); + } + + // Test for addition overflows in the big_sq inner loop */ + #[test] + fn test_big_sq_10() { + let mut x = MPNatTrait::from_big_endian( + [ + 0xff, + 0xff, + 0xff, + 0xff, + 0x80, + 0x00, + 0x00, + 0x00, + 0x80, + 0x00, + 0x00, + 0x00, + 0x40, + 0x00, + 0x00, + 0x00, + 0xff, + 0xff, + 0xff, + 0xff, + 0x80, + 0x00, + 0x00, + 0x00, + ].span() + ); + + let mut out = Felt252VecImpl::new(); + out.expand(2 * x.digits.len() + 1).unwrap(); + + big_sq(ref x, ref out); + let mut result = MPNat { digits: out }; + + let mut expected = MPNatTrait::from_big_endian( + [ + 0xff, + 0xff, + 0xff, + 0xff, + 0x00, + 0x00, + 0x00, + 0x01, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0xff, + 0xff, + 0xff, + 0xfe, + 0x40, + 0x00, + 0x00, + 0x01, + 0x90, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xbf, + 0xff, + 0xff, + 0xff, + 0x00, + 0x00, + 0x00, + 0x00, + 0x40, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + ].span() + ); + + assert!(result.digits.equal_remove_trailing_zeroes(ref expected.digits)); + } + + #[test] + fn test_borrowing_sub() { + assert_eq!(borrowing_sub(0, 0, false), (0, false)); + assert_eq!(borrowing_sub(1, 0, false), (1, false)); + assert_eq!(borrowing_sub(47, 5, false), (42, false)); + assert_eq!(borrowing_sub(101, 7, true), (93, false)); + assert_eq!(borrowing_sub(0x00_00_01_00, 0x00_00_02_00, false), (WORD_MAX - 0xFF, true)); + assert_eq!(borrowing_sub(0x00_00_01_00, 0x00_00_10_00, true), (WORD_MAX - 0x0F_00, true)); + } + + + #[test] + fn test_shifted_carrying_mul() { + assert_eq!(shifted_carrying_mul(0, 0, 0, 0), (0, 0)); + assert_eq!(shifted_carrying_mul(0, 6, 7, 0), (42, 0)); + assert_eq!(shifted_carrying_mul(0, 6, 7, 8), (50, 0)); + assert_eq!(shifted_carrying_mul(5, 6, 7, 8), (55, 0)); + assert_eq!( + shifted_carrying_mul( + WORD_MAX - 0x11, WORD_MAX - 0x1234, WORD_MAX - 0xABCD, WORD_MAX - 0xFF + ), + (0x0C_38_0C_94, WORD_MAX - 0xBE00) + ); + assert_eq!( + shifted_carrying_mul(WORD_MAX, WORD_MAX, WORD_MAX, WORD_MAX), (WORD_MAX, WORD_MAX) + ); + } +} diff --git a/kakarot-ssj/crates/utils/src/crypto/modexp/lib.cairo b/kakarot-ssj/crates/utils/src/crypto/modexp/lib.cairo new file mode 100644 index 000000000..a904bf8af --- /dev/null +++ b/kakarot-ssj/crates/utils/src/crypto/modexp/lib.cairo @@ -0,0 +1,19 @@ +// CREDITS: The implementation has been take from +// [aurora-engine](https://github.com/aurora-is-near/aurora-engine/tree/develop/engine-modexp) + +use crate::crypto::modexp::mpnat::MPNatTrait; +use crate::felt_vec::{Felt252VecTrait}; + +/// Computes `(base ^ exp) % modulus`, where all values are given as big-endian +/// encoded bytes. +pub fn modexp(base: Span, exp: Span, modulus: Span) -> Span { + let mut x = MPNatTrait::from_big_endian(base); + let mut m = MPNatTrait::from_big_endian(modulus); + + if m.digits.len == 1 && m.digits[0] == 0 { + return [].span(); + } + + let mut result = x.modpow(exp, ref m); + result.digits.to_be_bytes() +} diff --git a/kakarot-ssj/crates/utils/src/crypto/modexp/mpnat.cairo b/kakarot-ssj/crates/utils/src/crypto/modexp/mpnat.cairo new file mode 100644 index 000000000..5f461837f --- /dev/null +++ b/kakarot-ssj/crates/utils/src/crypto/modexp/mpnat.cairo @@ -0,0 +1,1034 @@ +// CREDITS: The implementation has been take from +// [aurora-engine](https://github.com/aurora-is-near/aurora-engine/tree/develop/engine-modexp) +use alexandria_data_structures::vec::VecTrait; +use alexandria_data_structures::vec::{Felt252Vec, Felt252VecImpl}; +use core::array::SpanTrait; +use core::num::traits::CheckedMul; +use core::option::OptionTrait; +use core::result::ResultTrait; +use crate::felt_vec::{Felt252VecTrait}; +use crate::math::Bitshift; +use crate::traits::bytes::FromBytes; +use crate::traits::integer::{U64Trait, U128Trait, BitsUsed, ByteSize}; + +use super::arith::{ + big_wrapping_pow, mod_inv, compute_r_mod_n, join_as_double, in_place_shl, in_place_shr, + in_place_add, in_place_mul_sub, big_wrapping_mul, monsq, monpro, borrowing_sub, carrying_add +}; + +pub type Word = u64; +pub type DoubleWord = u128; +pub const WORD_BYTES: usize = 8; +pub const WORD_BITS: usize = 64; +pub const WORD_MAX: Word = 18446744073709551615; +// 2**64 +pub const BASE: DoubleWord = 18446744073709551616; +pub const DOUBLE_WORD_MAX: DoubleWord = 340282366920938463463374607431768211455; +/// Multi-precision natural number, represented in base `Word::MAX + 1 = 2^WORD_BITS`. +/// The digits are stored in little-endian order, i.e. digits[0] is the least +/// significant digit. +#[derive(Destruct)] +pub struct MPNat { + pub digits: Felt252Vec +} + + +#[generate_trait] +pub impl MPNatTraitImpl of MPNatTrait { + fn from_big_endian(bytes: Span) -> MPNat { + if bytes.is_empty() { + let mut digits = Default::default(); + digits.expand(1).unwrap(); + return MPNat { digits }; + } + + // Remainder on division by WORD_BYTES + let r = bytes.len() & (WORD_BYTES - 1); + let n_digits: usize = if r == 0 { + bytes.len() / WORD_BYTES + } else { + // Need an extra digit for the remainder + (bytes.len() / WORD_BYTES) + 1 + }; + + let mut digits: Felt252Vec = Felt252VecImpl::new(); + // safe unwrap, since n_digits >= 0; + digits.expand(n_digits).unwrap(); + + // buffer to hold Word-sized slices of the input bytes + // TODO: optimize, see if we can avoid using this Felt252Vec + let mut buf: Felt252Vec = Felt252VecImpl::new(); + // safe unwrap, since WORD_BYTES > 0 + buf.expand(WORD_BYTES).unwrap(); + + let mut i = n_digits - 1; + if r != 0 { + // safe unwrap, since we know index is in bound + no overflow + buf.copy_from_bytes_le((WORD_BYTES - r), bytes.slice(0, r)).unwrap(); + + // safe unwrap, since we know that bytes won't overflow + let word = buf.to_le_bytes().from_be_bytes().expect('mpnat_from_big_endian_word'); + digits.set(i, word); + + if i == 0 { + // Special case where there is just one digit + return MPNat { digits }; + } + + i -= 1; + }; + + let mut j = r; + loop { + let next_j = j + WORD_BYTES; + // safe unwrap, since we know index is in bound + no overflow + buf.copy_from_bytes_le(0, bytes.slice(j, next_j - j)).unwrap(); + + // safe unwrap, since we know that bytes won't overflow + let word: u64 = buf.to_le_bytes().from_be_bytes().expect('mpnat_from_big_endian_word'); + digits.set(i, word); + + if i == 0 { + break; + } + + i -= 1; + j = next_j; + }; + + digits.remove_trailing_zeroes(); + + if digits.len() == 0 { + digits.expand(1).unwrap(); + } + + MPNat { digits } + } + + /// Makes `self` have the same number of digits as `other` by + /// pushing 0s or dropping higher order digits as needed. + /// This is equivalent to reducing `self` modulo `2^(WORD_BITS*k)` where + /// `k` is the number of digits in `other`. + fn sub_to_same_size(ref self: MPNat, ref other: MPNat) { + self.digits.remove_trailing_zeroes(); + if (self.digits.len() == 0) { + self.digits.expand(1).unwrap(); + } + + let n = other.digits.len(); + let s = self.digits.len(); + let m = if n >= s { + return; + } else { + s - n + }; + + let other_most_sig: DoubleWord = other.digits[other.digits.len() - 1].into(); + + if self.digits.len() == 2 { // This is the smallest case since `n >= 1` and `m > 0` + // implies that `self.digits.len() >= 2`. + // In this case we can use DoubleWord-sized arithmetic + // to get the answer directly. + let self_most_sig = self.digits.pop().unwrap(); + let a = join_as_double(self_most_sig, self.digits[0]); + let b = other_most_sig; + self.digits.set(0, (a % b).as_u64()); + return; + }; + + if n == 1 { + // The divisor is only 1 digit, so the long-division + // algorithm is easy. + let k = self.digits.len() - 1; + let mut i = k; + loop { + if i == 0 { + break; + }; + + i -= 1; + + let self_most_sig = self.digits.pop().unwrap(); + let self_second_sig = self.digits[i]; + let r = join_as_double(self_most_sig, self_second_sig) % other_most_sig; + self.digits.set(i, r.as_u64()); + }; + + return; + } + + // At this stage we know that `n >= 2` and `self.digits.len() >= 3`. + // The smaller cases are covered in the if-statements above. + + // The algorithm below only works well when the divisor's + // most significant digit is at least `BASE / 2`. + // If it is too small then we "normalize" by multiplying + // both numerator and denominator by a common factor + // and run the algorithm on those numbers. + // See Knuth The Art of Computer Programming vol. 2 section 4.3 for details. + let shift: u32 = other_most_sig.as_u64().count_leading_zeroes().into(); + if shift > 0 { + // Normalize self + let overflow = in_place_shl(ref self.digits, shift); + self.digits.push(overflow); + + // Normalize other + let mut normalized = other.digits.duplicate(); + in_place_shl(ref normalized, shift); + + let mut v = MPNat { digits: normalized }; + // Run algorithm on normalized values + self.sub_to_same_size(ref v); + + // need to de-normalize to get the correct result + in_place_shr(ref self.digits, shift); + + return; + }; + + let other_second_sig: DoubleWord = other.digits[n - 2].into(); + let mut self_most_sig: Word = 0; + + let mut j = m + 1; + + loop { + if j == 0 { + break; + } + + j -= 1; + + let self_second_sig = self.digits[self.digits.len() - 1]; + let self_third_sig = self.digits[self.digits.len() - 2]; + + let a = join_as_double(self_most_sig, self_second_sig); + let mut q_hat = a / other_most_sig; + let mut r_hat = a % other_most_sig; + + loop { + let a = q_hat * other_second_sig; + let b = join_as_double(r_hat.as_u64(), self_third_sig); + if q_hat >= BASE || a > b { + q_hat -= 1; + r_hat += other_most_sig; + if BASE <= r_hat { + break; + } + } else { + break; + } + }; + + //TODO: optimize with [#720](https://github.com/kkrt-labs/kakarot-ssj/issues/720) + let mut a = self.digits.clone_slice(j, self.digits.len() - j); + + let mut borrow = in_place_mul_sub(ref a, ref other.digits, q_hat.as_u64()); + self.digits.insert_vec(j, ref a).unwrap(); + if borrow > self_most_sig { + // q_hat was too large, add back one multiple of the modulus + //TODO: optimize with [#720](https://github.com/kkrt-labs/kakarot-ssj/issues/720) + let mut a = self.digits.clone_slice(j, self.digits.len() - j); + in_place_add(ref a, ref other.digits); + self.digits.insert_vec(j, ref a).unwrap(); + borrow -= 1; + } + + self_most_sig = self.digits.pop().unwrap(); + }; + + self.digits.push(self_most_sig); + } + + fn is_power_of_two(ref self: MPNat) -> bool { + // A multi-precision number is a power of 2 iff exactly one digit + // is a power of 2 and all others are zero. + + let mut found_power_of_two = false; + + let mut i = 0; + loop { + if i == self.digits.len() { + break found_power_of_two; + } + + let d = self.digits[i]; + let is_p2 = if d != 0 { + (d & (d - 1)) == 0 + } else { + false + }; + + if ((!is_p2 && d != 0) || (is_p2 && found_power_of_two)) { + break false; + } else if is_p2 { + found_power_of_two = true; + } + + i += 1; + } + } + + fn is_odd(ref self: MPNat) -> bool { + // when the value is 0 + if self.digits.len() == 0 { + return false; + }; + + // A binary number is odd iff its lowest order bit is set. + self.digits[0] & 1 == 1 + } + + // Koç's algorithm for inversion mod 2^k + // https://eprint.iacr.org/2017/411.pdf + fn koc_2017_inverse(ref aa: MPNat, k: usize) -> MPNat { + let length = k / WORD_BITS; + let mut digits = Felt252VecImpl::new(); + digits.expand(length + 1).unwrap(); + let mut b = MPNat { digits }; + + b.digits.set(0, 1); + + let mut a = MPNat { digits: aa.digits.duplicate(), }; + a.digits.resize(length + 1); + + let mut neg: bool = false; + + let mut digits = Felt252VecImpl::new(); + digits.expand(length + 1).unwrap(); + let mut res = MPNat { digits }; + + let (mut wordpos, mut bitpos) = (0, 0); + + let mut i = 0; + loop { + if i == k { + break; + } + + let x = b.digits[0] & 1; + if x != 0 { + if !neg { + // b = a - b + //TODO: optimize with + //[#720](https://github.com/kkrt-labs/kakarot-ssj/issues/720) + let mut tmp = MPNat { digits: a.digits.duplicate(), }; + in_place_mul_sub(ref tmp.digits, ref b.digits, 1); + b = tmp; + neg = true; + } else { + // b = b - a + in_place_add(ref b.digits, ref a.digits); + } + } + + in_place_shr(ref b.digits, 1); + + res.digits.set(wordpos, res.digits[wordpos] | (x.shl(bitpos.into()))); + + bitpos += 1; + if bitpos == WORD_BITS { + bitpos = 0; + wordpos += 1; + } + + i += 1; + }; + + res + } + + + /// Computes `self ^ exp mod modulus`. `exp` must be given as big-endian bytes. + fn modpow(ref self: MPNat, exp: Span, ref modulus: MPNat) -> MPNat { + // exp must be stripped because it is iterated over in + // big_wrapping_pow and modpow_montgomery, and a large + // zero-padded exp leads to performance issues. + let (exp, exp_is_zero) = Self::strip_leading_zeroes(exp); + + // base^0 is always 1, regardless of base. + // Hence the result is 0 for (base^0) % 1, and 1 + // for every modulus larger than 1. + // + // The case of modulus being 0 should have already been + // handled in modexp(). + if exp_is_zero { + if modulus.digits.len() == 1 && modulus.digits[0] == 1 { + let mut digits = Felt252VecImpl::new(); + digits.expand(1).unwrap(); + + return MPNat { digits }; + } else { + let mut digits = Felt252VecImpl::new(); + digits.push(1); + + return MPNat { digits }; + } + } + + if exp.len() <= (ByteSize::::byte_size()) { + let exp_as_number: usize = exp.from_le_bytes_partial().expect('modpow_exp_as_number'); + + match self.digits.len().checked_mul(exp_as_number) { + Option::Some(max_output_digits) => { + if (modulus.digits.len() > max_output_digits) { + // Special case: modulus is larger than `base ^ exp`, so division is not + // relevant + let mut scratch_space: Felt252Vec = Felt252VecImpl::new(); + scratch_space.expand(max_output_digits).unwrap(); + + return big_wrapping_pow(ref self, exp, ref scratch_space); + } + }, + Option::None => {} + }; + } + + if modulus.is_power_of_two() { // return + return self.modpow_with_power_of_two(exp, ref modulus); + } else if modulus.is_odd() { + return self.modpow_montgomery(exp, ref modulus); + } + + // If the modulus is not a power of two and not an odd number then + // it is a product of some power of two with an odd number. In this + // case we will use the Chinese remainder theorem to get the result. + // See http://www.people.vcu.edu/~jwang3/CMSC691/j34monex.pdf + + let trailing_zeros = modulus.digits.count_leading_zeroes(); + let additional_zero_bits: usize = modulus + .digits[trailing_zeros] + .count_trailing_zeroes() + .into(); + + let mut power_of_two = { + let mut digits = Felt252VecImpl::new(); + digits.expand(trailing_zeros + 1).unwrap(); + let mut tmp = MPNat { digits }; + tmp.digits.set(trailing_zeros, 1_u64.shl(additional_zero_bits.into())); + tmp + }; + + let power_of_two_mask = power_of_two.digits[power_of_two.digits.len() - 1] - 1; + let mut odd = { + let num_digits = modulus.digits.len() - trailing_zeros; + let mut digits = Felt252VecImpl::new(); + digits.expand(num_digits).unwrap(); + let mut tmp = MPNat { digits }; + if additional_zero_bits > 0 { + tmp.digits.set(0, modulus.digits[trailing_zeros].shr(additional_zero_bits.into())); + let mut i = 1; + loop { + if i == num_digits { + break; + } + + let d = modulus.digits[trailing_zeros + i]; + tmp + .digits + .set( + i - 1, + tmp.digits[i + - 1] + + (d & power_of_two_mask) + .shl((WORD_BITS - additional_zero_bits).into()) + ); + tmp.digits.set(i, d.shr(additional_zero_bits.into())); + + i += 1; + }; + } else { + // TODO: explore if we can avoid this clone and just use a copy to avoid deep + // cloning + let mut slice = modulus + .digits + .clone_slice(trailing_zeros, modulus.digits.len() - trailing_zeros); + tmp.digits.insert_vec(0, ref slice).unwrap(); + } + if tmp.digits.len() > 0 { + loop { + if tmp.digits[tmp.digits.len() - 1] != 0 { + break; + }; + + tmp.digits.pop().unwrap(); + }; + }; + tmp + }; + + let mut base_copy = MPNat { digits: self.digits.duplicate(), }; + let mut x1 = base_copy.modpow_montgomery(exp, ref odd); + let mut x2 = self.modpow_with_power_of_two(exp, ref power_of_two); + + let mut odd_inv = Self::koc_2017_inverse( + ref odd, trailing_zeros * WORD_BITS + additional_zero_bits + ); + + let s = power_of_two.digits.len(); + let mut scratch: Felt252Vec = Felt252VecImpl::new(); + scratch.expand(s).unwrap(); + + let mut diff = { + let mut b = false; + let mut i = 0; + loop { + if i == scratch.len() || i == s { + break; + } + + let (diff, borrow) = borrowing_sub( + x2.digits.get(i).unwrap_or(0), x1.digits.get(i).unwrap_or(0), b, + ); + + scratch.set(i, diff); + b = borrow; + + i += 1; + }; + + MPNat { digits: scratch } + }; + + let mut y = { + let mut out: Felt252Vec = Felt252VecImpl::new(); + out.expand(s).unwrap(); + big_wrapping_mul(ref diff, ref odd_inv, ref out); + + out.set(out.len() - 1, out[out.len() - 1] & power_of_two_mask); + MPNat { digits: out } + }; + + // Re-use allocation for efficiency + let mut digits = diff.digits; + let s = modulus.digits.len(); + digits.reset(); + digits.resize(s); + big_wrapping_mul(ref odd, ref y, ref digits); + let mut c = false; + + let mut i = 0; + loop { + if i == digits.len() { + break; + }; + + let out_digit = digits[i]; + + let (sum, carry) = carrying_add(x1.digits.get(i).unwrap_or(0), out_digit, c); + c = carry; + digits.set(i, sum); + + i += 1; + }; + + MPNat { digits } + } + + // Computes `self ^ exp mod modulus` using Montgomery multiplication. + // See https://www.microsoft.com/en-us/research/wp-content/uploads/1996/01/j37acmon.pdf + fn modpow_montgomery(ref self: MPNat, exp: Span, ref modulus: MPNat) -> MPNat { + // n_prime satisfies `r * (r^(-1)) - modulus * n' = 1`, where + // `r = 2^(WORD_BITS*modulus.digits.len())`. + let n_prime = WORD_MAX - mod_inv(modulus.digits[0]) + 1; + let s = modulus.digits.len; + + let mut digits = Felt252VecImpl::new(); + // safe unwrap, since intiail length is 0; + digits.expand(s).unwrap(); + let mut x_bar = MPNat { digits }; + // Initialize result as `r mod modulus` (Montgomery form of 1) + compute_r_mod_n(ref modulus, ref x_bar.digits); + + // Reduce base mod modulus + self.sub_to_same_size(ref modulus); + + // Need to compute a_bar = base * r mod modulus; + // First directly multiply base * r to get a 2s-digit number, + // then reduce mod modulus. + let mut a_bar = { + let mut digits = Felt252VecImpl::new(); + digits.expand(2 * s).unwrap(); + let mut tmp = MPNat { digits }; + big_wrapping_mul(ref self, ref x_bar, ref tmp.digits); + + tmp.sub_to_same_size(ref modulus); + tmp + }; + + // scratch space for monpro algorithm + let mut scratch: Felt252Vec = Felt252VecImpl::new(); + scratch.expand(2 * s + 1).unwrap(); + let monpro_len = s + 2; + + let mut i = 0; + loop { + if i == exp.len() { + break; + } + + let b = *exp[i]; + + let mut mask: u8 = 128; + + loop { + if mask == 0 { + break; + }; + + monsq(ref x_bar, ref modulus, n_prime, ref scratch); + //TODO: optimize + let mut slice = scratch.clone_slice(0, s); + x_bar.digits.copy_from_vec_le(ref slice).unwrap(); + scratch.reset(); + + if b & mask != 0 { + let mut slice = scratch.clone_slice(0, monpro_len); + monpro(ref x_bar, ref a_bar, ref modulus, n_prime, ref slice); + scratch.insert_vec(0, ref slice).unwrap(); + + //TODO: optimize + let mut slice = scratch.clone_slice(0, s); + x_bar.digits.copy_from_vec_le(ref slice).unwrap(); + scratch.reset(); + } + mask = mask.shr(1); + }; + + i += 1; + }; + + // Convert out of Montgomery form by computing monpro with 1 + let mut one = { + // We'll reuse the memory space from a_bar for efficiency. + let mut digits = a_bar.digits; + digits.reset(); + digits.set(0, 1); + MPNat { digits } + }; + + let mut slice = scratch.clone_slice(0, monpro_len); + monpro(ref x_bar, ref one, ref modulus, n_prime, ref slice); + scratch.insert_vec(0, ref slice).unwrap(); + + scratch.resize(s); + MPNat { digits: scratch } + } + + fn modpow_with_power_of_two(ref self: MPNat, exp: Span, ref modulus: MPNat) -> MPNat { + // We know `modulus` is a power of 2. So reducing is as easy as bit shifting. + // We also know the modulus is non-zero because 0 is not a power of 2. + + // First reduce self to be the same size as the modulus + self.force_same_size(ref modulus); + + // The modulus is a power of 2 but that power may not be a multiple of a whole word. + // We can clear out any higher order bits to fix this. + let modulus_mask = modulus.digits[modulus.digits.len() - 1] - 1; + self.digits.set(self.digits.len() - 1, self.digits[self.digits.len() - 1] & modulus_mask); + + // We know that `totient(2^k) = 2^(k-1)`, therefore by Euler's theorem + // we can also reduce the exponent mod `2^(k-1)`. Effectively this means + // throwing away bytes to make `exp` shorter. Note: Euler's theorem only applies + // if the base and modulus are coprime (which in this case means the base is odd). + let exp = if self.is_odd() && (exp.len() > WORD_BYTES * modulus.digits.len()) { + let i = exp.len() - WORD_BYTES * modulus.digits.len(); + exp.slice(i, exp.len() - i) + } else { + exp + }; + + let mut scratch_space = Felt252VecImpl::new(); + // safe unwrap, since the initial length is 0 + scratch_space.expand(modulus.digits.len()).unwrap(); + + let mut result = big_wrapping_pow(ref self, exp, ref scratch_space); + + // The modulus is a power of 2 but that power may not be a multiple of a whole word. + // We can clear out any higher order bits to fix this. + + result + .digits + .set(result.digits.len() - 1, result.digits[result.digits.len() - 1] & modulus_mask); + + result + } + + + /// Makes `self` have the same number of digits as `other` by + /// pushing 0s or dropping higher order digits as needed. + /// This is equivalent to reducing `self` modulo `2^(WORD_BITS*k)` where + /// `k` is the number of digits in `other`. + fn force_same_size(ref self: MPNat, ref other: MPNat) { + self.digits.resize(other.digits.len); + } + + /// stips leading zeroes from little endian bytes + /// # Arguments + /// * `input` a Span in little endian + /// # Returns + /// * (Span<8>, bool), where span is the resulting Span after removing leading zeroes, and the + /// boolean indicates if all bytes were zero + fn strip_leading_zeroes(mut v: Span) -> (Span, bool) { + loop { + let stripped_span = v; + match v.pop_front() { + Option::Some(v) => { if (*v != 0) { + break (stripped_span, false); + } }, + Option::None => { break (v, true); } + } + } + } +} + +pub fn mp_nat_to_u128(ref x: MPNat) -> u128 { + let result = x.digits.to_le_bytes(); + let mut i: usize = 0; + loop { + if i == result.len() { + break; + }; + + i += 1; + }; + result.from_le_bytes_partial().expect('mpnat_to_u128') +} + +#[cfg(test)] +mod tests { + use alexandria_data_structures::vec::Felt252VecImpl; + use alexandria_data_structures::vec::VecTrait; + use crate::crypto::modexp::mpnat::MPNatTrait; + use crate::math::{Bitshift, WrappingBitshift}; + use crate::traits::bytes::ToBytes; + use super::mp_nat_to_u128; + + // the tests are taken from + // [aurora-engine](https://github.com/aurora-is-near/aurora-engine/blob/1213f2c7c035aa523601fced8f75bef61b4728ab/engine-modexp/src/mpnat.rs#L825) + + fn check_modpow_even(base: u128, exp: u128, modulus: u128, expected: u128) { + let mut x = MPNatTrait::from_big_endian(base.to_be_bytes()); + let mut m = MPNatTrait::from_big_endian(modulus.to_be_bytes()); + let mut result = x.modpow(exp.to_be_bytes_padded(), ref m); + let result = mp_nat_to_u128(ref result); + assert_eq!(result, expected); + } + + fn check_modpow_with_power_of_two(base: u128, exp: u128, modulus: u128, expected: u128) { + let mut x = MPNatTrait::from_big_endian(base.to_be_bytes()); + let mut m = MPNatTrait::from_big_endian(modulus.to_be_bytes()); + let mut result = x.modpow_with_power_of_two(exp.to_be_bytes(), ref m); + let result = mp_nat_to_u128(ref result); + assert_eq!(result, expected); + } + + fn check_modpow_montgomery(base: u128, exp: u128, modulus: u128, expected: u128) { + let mut x = MPNatTrait::from_big_endian(base.to_be_bytes()); + let mut m = MPNatTrait::from_big_endian(modulus.to_be_bytes()); + let mut result = x.modpow_montgomery(exp.to_be_bytes(), ref m); + let result = mp_nat_to_u128(ref result); + assert_eq!(result, expected, "({base} ^ {exp}) % {modulus} failed check_modpow_montgomery"); + } + + fn check_sub_to_same_size(a: u128, n: u128) { + let mut x = MPNatTrait::from_big_endian(a.to_be_bytes()); + let mut y = MPNatTrait::from_big_endian(n.to_be_bytes()); + x.sub_to_same_size(ref y); + + assert!(x.digits.len() <= y.digits.len()); + let result = mp_nat_to_u128(ref x); + assert_eq!(result % n, a % n, "{a} % {n} failed sub_to_same_size check"); + } + + + fn check_is_odd(n: u128) { + let mut mp = MPNatTrait::from_big_endian(n.to_be_bytes()); + assert_eq!(mp.is_odd(), n % 2 == 1, "{n} failed is_odd test"); + } + + fn check_is_p2(n: u128, expected_result: bool) { + let mut mp = MPNatTrait::from_big_endian(n.to_be_bytes()); + assert_eq!(mp.is_power_of_two(), expected_result, "{n} failed is_power_of_two test"); + } + + #[test] + #[available_gas(100000000000000)] + fn test_modpow_even() { + check_modpow_even(3, 5, 500, 243); + check_modpow_even(3, 5, 20, 3); + check_modpow_even( + 0x2ff4f4df4c518867207c84b57a77aa50, + 0xca83c2925d17c577c9a03598b6f360, + 0xf863d4f17a5405d84814f54c92f803c8, + 0x8d216c9a1fb275ed18eb340ed43cacc0, + ); + check_modpow_even( + 0x13881e1614244c56d15ac01096b070e7, + 0x336df5b4567cbe4c093271dc151e6c72, + 0x7540f399a0b6c220f1fc60d2451a1ff0, + 0x1251d64c552e8f831f5b841d2811f9c1, + ); + check_modpow_even( + 0x774d5b2494a449d8f22b22ea542d4ddf, + 0xd2f602e1688f271853e7794503c2837e, + 0xa80d20ebf75f92192159197b60f36e8e, + 0x3fbbba42489b27fc271fb39f54aae2e1, + ); + check_modpow_even( + 0x756e409cc3583a6b68ae27ccd9eb3d50, + 0x16dafb38a334288954d038bedbddc970, + 0x1f9b2237f09413d1fc44edf9bd02b8bc, + 0x9347445ac61536a402723cd07a3f5a4, + ); + check_modpow_even( + 0x6dcb8405e2cc4dcebee3e2b14861b47d, + 0xe6c1e5251d6d5deb8dddd0198481d671, + 0xe34a31d814536e8b9ff6cc5300000000, + 0xaa86af638386880334694967564d0c3d, + ); + check_modpow_even( + 0x9c12fe4a1a97d17c1e4573247a43b0e5, + 0x466f3e0a2e8846b8c48ecbf612b96412, + 0x710d7b9d5718acff0000000000000000, + 0x569bf65929e71cd10a553a8623bdfc99, + ); + check_modpow_even( + 0x6d018fdeaa408222cb10ff2c36124dcf, + 0x8e35fc05d490bb138f73c2bc284a67a7, + 0x6c237160750d78400000000000000000, + 0x3fe14e11392c6c6be8efe956c965d5af, + ); + } + + #[test] + fn test_modpow_with_power_of_two() { + check_modpow_with_power_of_two(3, 2, 1.wrapping_shl(30), 9); + check_modpow_with_power_of_two(3, 5, 1.wrapping_shl(30), 243); + check_modpow_with_power_of_two(3, 1_000_000, 1.wrapping_shl(30), 641836289); + check_modpow_with_power_of_two(3, 1_000_000, 1.wrapping_shl(31), 1715578113); + check_modpow_with_power_of_two(3, 1_000_000, 1.wrapping_shl(32), 3863061761); + check_modpow_with_power_of_two( + 0xabcd_ef01_2345_6789_1111, 0x1234_5678_90ab_cdef, 1.wrapping_shl(5), 17, + ); + check_modpow_with_power_of_two( + 0x3f47_9dc0_d5b9_6003, + 0xa180_e045_e314_8581, + 1.wrapping_shl(118), + 0x0028_3d19_e6cc_b8a0_e050_6abb_b9b1_1a03, + ); + } + + #[test] + #[available_gas(100000000000000)] + fn test_modpow_montgomery() { + check_modpow_montgomery(3, 5, 0x9346_9d50_1f74_d1c1, 243); + check_modpow_montgomery(3, 5, 19, 15); + check_modpow_montgomery( + 0x5c4b74ec760dfb021499f5c5e3c69222, + 0x62b2a34b21cf4cc036e880b3fb59fe09, + 0x7b799c4502cd69bde8bb12601ce3ff15, + 0x10c9d9071d0b86d6a59264d2f461200, + ); + check_modpow_montgomery( + 0xadb5ce8589030e3a9112123f4558f69c, + 0xb002827068f05b84a87431a70fb763ab, + 0xc4550871a1cfc67af3e77eceb2ecfce5, + 0x7cb78c0e1c1b43f6412e9d1155ea96d2, + ); + check_modpow_montgomery( + 0x26eb51a5d9bf15a536b6e3c67867b492, + 0xddf007944a79bf55806003220a58cc6, + 0xc96275a80c694a62330872b2690f8773, + 0x23b75090ead913def3a1e0bde863eda7, + ); + check_modpow_montgomery( + 0xb93fa81979e597f548c78f2ecb6800f3, + 0x5fad650044963a271898d644984cb9f0, + 0xbeb60d6bd0439ea39d447214a4f8d3ab, + 0x354e63e6a5e007014acd3e5ea88dc3ad, + ); + check_modpow_montgomery( + 0x1993163e4f578869d04949bc005c878f, + 0x8cb960f846475690259514af46868cf5, + 0x52e104dc72423b534d8e49d878f29e3b, + 0x2aa756846258d5cfa6a3f8b9b181a11c, + ); + } + + #[test] + fn test_sub_to_same_size() { + check_sub_to_same_size(0x10_00_00_00_00, 0xFF_00_00_00); + check_sub_to_same_size(0x10_00_00_00_00, 0x01_00_00_00); + check_sub_to_same_size(0x35_00_00_00_00, 0x01_00_00_00); + check_sub_to_same_size(0xEF_00_00_00_00_00_00, 0x02_FF_FF_FF); + + let n = 10; + let a = 57 + 2 * n + 0x1234_0000_0000 * n + 0x000b_0000_0000_0000_0000 * n; + check_sub_to_same_size(a, n); + + // Test that borrow equals self_most_sig at end of sub_to_same_size */ + { + let mut x = MPNatTrait::from_big_endian( + [ + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xae, + 0x5f, + 0xf0, + 0x8b, + 0xfc, + 0x02, + 0x71, + 0xa4, + 0xfe, + 0xe0, + 0x49, + 0x02, + 0xc9, + 0xd9, + 0x12, + 0x61, + 0x8e, + 0xf5, + 0x02, + 0x2c, + 0xa0, + 0x00, + 0x00, + 0x00, + ].span() + ); + let mut y = MPNatTrait::from_big_endian( + [ + 0xae, + 0x5f, + 0xf0, + 0x8b, + 0xfc, + 0x02, + 0x71, + 0xa4, + 0xfe, + 0xe0, + 0x49, + 0x0f, + 0x70, + 0x00, + 0x00, + 0x00, + ].span() + ); + x.sub_to_same_size(ref y); + } + + // Additional test for sub_to_same_size q_hat/r_hat adjustment logic */ + { + let mut x = MPNatTrait::from_big_endian( + [ + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xff, + 0xff, + 0xff, + 0xff, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + ].span() + ); + let mut y = MPNatTrait::from_big_endian( + [ + 0xff, + 0xff, + 0xff, + 0xff, + 0x00, + 0x00, + 0x00, + 0x00, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x00, + 0x00, + 0x00, + ].span() + ); + x.sub_to_same_size(ref y); + } + } + + #[test] + #[available_gas(100000000000000)] + fn test_mp_nat_is_odd() { + let mut n = 0; + loop { + if n == 1025 { + break; + }; + check_is_odd(n); + + n += 1; + }; + + let mut n = 0xFF_FF_FF_FF_00_00_00_00; + + loop { + if n == 0xFF_FF_FF_FF_00_00_04_01 { + break; + } + + check_is_odd(n); + n += 1; + }; + } + + #[test] + fn test_mp_nat_is_power_of_two() { + check_is_p2(0, false); + check_is_p2(1, true); + check_is_p2(1327, false); + check_is_p2((1.shl(1)) + (1.shl(35)), false); + check_is_p2(1.shl(1), true); + check_is_p2(1.shl(2), true); + check_is_p2(1.shl(3), true); + check_is_p2(1.shl(4), true); + check_is_p2(1.shl(5), true); + check_is_p2(1.shl(31), true); + check_is_p2(1.shl(32), true); + check_is_p2(1.shl(64), true); + check_is_p2(1.shl(65), true); + check_is_p2(1.shl(127), true); + } +} diff --git a/kakarot-ssj/crates/utils/src/errors.cairo b/kakarot-ssj/crates/utils/src/errors.cairo new file mode 100644 index 000000000..24aa9d7ba --- /dev/null +++ b/kakarot-ssj/crates/utils/src/errors.cairo @@ -0,0 +1,69 @@ +// LENGTH +pub const RLP_EMPTY_INPUT: felt252 = 'KKT: EmptyInput'; +pub const RLP_INPUT_TOO_SHORT: felt252 = 'KKT: InputTooShort'; + +#[derive(Drop, Copy, PartialEq, Debug)] +pub enum RLPError { + EmptyInput, + InputTooShort, + InvalidInput, + Custom: felt252, + NotAString, + FailedParsingU128, + FailedParsingU256, + FailedParsingAddress, + FailedParsingAccessList, + NotAList +} + + +pub impl RLPErrorIntoU256 of Into { + fn into(self: RLPError) -> u256 { + match self { + RLPError::EmptyInput => 'input is null'.into(), + RLPError::InputTooShort => 'input too short'.into(), + RLPError::InvalidInput => 'rlp input not conform'.into(), + RLPError::Custom(msg) => msg.into(), + RLPError::NotAString => 'rlp input is not a string'.into(), + RLPError::FailedParsingU128 => 'rlp failed parsing u128'.into(), + RLPError::FailedParsingU256 => 'rlp failed parsing u256'.into(), + RLPError::FailedParsingAddress => 'rlp failed parsing address'.into(), + RLPError::FailedParsingAccessList => 'rlp failed parsing access_list'.into(), + RLPError::NotAList => 'rlp input is not a list'.into() + } + } +} + +#[generate_trait] +pub impl RLPErrorImpl of RLPErrorTrait { + fn map_err(self: Result) -> Result { + match self { + Result::Ok(val) => Result::Ok(val), + Result::Err(error) => { Result::Err(EthTransactionError::RLPError(error)) } + } + } +} + +#[derive(Drop, Copy, PartialEq, Debug)] +pub enum EthTransactionError { + RLPError: RLPError, + ExpectedRLPItemToBeList, + ExpectedRLPItemToBeString, + TransactionTypeError, + // the usize represents the encountered length of payload + TopLevelRlpListWrongLength: usize, + // the usize represents the encountered length of payload + LegacyTxWrongPayloadLength: usize, + // the usize represents the encountered length of payload + TypedTxWrongPayloadLength: usize, + IncorrectChainId, + IncorrectAccountNonce, + /// If the transaction's fee is less than the base fee of the block + FeeCapTooLow, + /// Thrown to ensure no one is able to specify a transaction with a tip higher than the total + /// fee cap. + TipAboveFeeCap, + /// Thrown to ensure no one is able to specify a transaction with a tip that is too high. + TipVeryHigh, + Other: felt252 +} diff --git a/kakarot-ssj/crates/utils/src/eth_transaction.cairo b/kakarot-ssj/crates/utils/src/eth_transaction.cairo new file mode 100644 index 000000000..f10c40ba3 --- /dev/null +++ b/kakarot-ssj/crates/utils/src/eth_transaction.cairo @@ -0,0 +1,68 @@ +pub mod common; +pub mod eip1559; +pub mod eip2930; +pub mod legacy; +pub mod transaction; +pub mod tx_type; +use crate::errors::{EthTransactionError, RLPErrorImpl}; +use crate::traits::bytes::ByteArrayExt; + + +/// Checks the effective gas price of a transaction as specified in EIP-1559 with relevant checks. +/// +/// # Arguments +/// +/// * `max_fee_per_gas` - The maximum fee per gas the user is willing to pay. +/// * `max_priority_fee_per_gas` - The maximum priority fee per gas the user is willing to pay +/// (optional). +/// * `block_base_fee` - The base fee per gas for the current block. +/// +/// # Returns +/// +/// * `Result<(), EthTransactionError>` - Ok if the gas fee is valid, or an error if not. +pub fn check_gas_fee( + max_fee_per_gas: u128, max_priority_fee_per_gas: Option, block_base_fee: u128, +) -> Result<(), EthTransactionError> { + let max_priority_fee_per_gas = max_priority_fee_per_gas.unwrap_or(0); + + if max_fee_per_gas < block_base_fee { + // `base_fee_per_gas` is greater than the `max_fee_per_gas` + return Result::Err(EthTransactionError::FeeCapTooLow); + } + if max_fee_per_gas < max_priority_fee_per_gas { + // `max_priority_fee_per_gas` is greater than the `max_fee_per_gas` + return Result::Err(EthTransactionError::TipAboveFeeCap); + } + + Result::Ok(()) +} + +#[cfg(test)] +mod tests { + use crate::errors::EthTransactionError; + use super::check_gas_fee; + + #[test] + fn test_happy_path() { + let result = check_gas_fee(100, Option::Some(10), 50); + assert!(result.is_ok()); + } + + #[test] + fn test_fee_cap_too_low() { + let result = check_gas_fee(40, Option::Some(10), 50); + assert_eq!(result, Result::Err(EthTransactionError::FeeCapTooLow)); + } + + #[test] + fn test_tip_above_fee_cap() { + let result = check_gas_fee(100, Option::Some(110), 50); + assert_eq!(result, Result::Err(EthTransactionError::TipAboveFeeCap)); + } + + #[test] + fn test_priority_fee_none() { + let result = check_gas_fee(100, Option::None, 50); + assert!(result.is_ok()); + } +} diff --git a/kakarot-ssj/crates/utils/src/eth_transaction/common.cairo b/kakarot-ssj/crates/utils/src/eth_transaction/common.cairo new file mode 100644 index 000000000..92b012a3b --- /dev/null +++ b/kakarot-ssj/crates/utils/src/eth_transaction/common.cairo @@ -0,0 +1,51 @@ +use core::starknet::EthAddress; + +/// The `to` field of a transaction. Either a target address, or empty for a +/// contract creation. +#[derive(Copy, Drop, Debug, Default, PartialEq, Serde)] +pub enum TxKind { + /// A transaction that creates a contract. + #[default] + Create, + /// A transaction that calls a contract or transfer. + Call: EthAddress, +} + +impl OptionAddressIntoTxKind of Into, TxKind> { + fn into(self: Option) -> TxKind { + match self { + Option::None => TxKind::Create, + Option::Some(address) => TxKind::Call(address), + } + } +} + +impl AddressIntoTxKind of Into { + fn into(self: EthAddress) -> TxKind { + TxKind::Call(self) + } +} + +#[generate_trait] +pub impl TxKindImpl of TxKindTrait { + fn is_create(self: @TxKind) -> bool { + match self { + TxKind::Create => true, + TxKind::Call(_) => false, + } + } + + fn is_call(self: @TxKind) -> bool { + match self { + TxKind::Create => false, + TxKind::Call(_) => true, + } + } + + fn to(self: @TxKind) -> Option { + match self { + TxKind::Create => Option::None, + TxKind::Call(address) => Option::Some(*address), + } + } +} diff --git a/kakarot-ssj/crates/utils/src/eth_transaction/eip1559.cairo b/kakarot-ssj/crates/utils/src/eth_transaction/eip1559.cairo new file mode 100644 index 000000000..eda69f7e8 --- /dev/null +++ b/kakarot-ssj/crates/utils/src/eth_transaction/eip1559.cairo @@ -0,0 +1,144 @@ +use core::num::traits::SaturatingSub; +use crate::errors::{EthTransactionError, RLPError, RLPErrorTrait}; +use crate::eth_transaction::common::TxKind; +use crate::eth_transaction::eip2930::AccessListItem; +use crate::rlp::{RLPItem, RLPHelpersTrait}; +use crate::traits::SpanDefault; + +/// A transaction with a priority fee ([EIP-1559](https://eips.ethereum.org/EIPS/eip-1559)). +#[derive(Copy, Drop, Debug, Default, PartialEq, Serde)] +pub struct TxEip1559 { + /// EIP-155: Simple replay attack protection + pub chain_id: u64, + /// A scalar value equal to the number of transactions sent by the sender + pub nonce: u64, + /// A scalar value equal to the maximum + /// amount of gas that should be used in executing + /// this transaction. This is paid up-front, before any + /// computation is done and may not be increased + /// later; + pub gas_limit: u64, + /// A scalar value equal to the maximum + /// amount of gas that should be used in executing + /// this transaction. This is paid up-front, before any + /// computation is done and may not be increased + /// later; + /// + /// As ethereum circulation is around 120mil eth as of 2022 that is around + /// 120000000000000000000000000 wei we are safe to use u128 as its max number is: + /// 340282366920938463463374607431768211455 + /// + pub max_fee_per_gas: u128, + /// Max Priority fee that transaction is paying + /// + /// As ethereum circulation is around 120mil eth as of 2022 that is around + /// 120000000000000000000000000 wei we are safe to use u128 as its max number is: + /// 340282366920938463463374607431768211455 + /// + pub max_priority_fee_per_gas: u128, + /// The 160-bit address of the message call’s recipient or, for a contract creation + /// transaction, ∅ + pub to: TxKind, + /// A scalar value equal to the number of Wei to + /// be transferred to the message call’s recipient or, + /// in the case of contract creation, as an endowment + /// to the newly created account; + pub value: u256, + /// The accessList specifies a list of addresses and storage keys; + /// these addresses and storage keys are added into the `accessed_addresses` + /// and `accessed_storage_keys` global sets (introduced in EIP-2929). + /// A gas cost is charged, though at a discount relative to the cost of + /// accessing outside the list. + pub access_list: Span, + /// Input has two uses depending if transaction is Create or Call (if `to` field is None or + /// Some). pub init: An unlimited size byte array specifying the + /// EVM-code for the account initialisation procedure CREATE, + /// data: An unlimited size byte array specifying the + /// input data of the message call, formally Td. + pub input: Span, +} + +#[generate_trait] +pub impl _impl of TxEip1559Trait { + /// Returns the effective gas price for the given `base_fee`. + /// + /// # Arguments + /// + /// * `base_fee` - The current network base fee, if available + /// + /// # Returns + /// + /// The effective gas price as a u128 + fn effective_gas_price(self: @TxEip1559, base_fee: Option) -> u128 { + match base_fee { + Option::Some(base_fee) => { + let tip = (*self.max_fee_per_gas).saturating_sub(base_fee); + if tip > (*self.max_priority_fee_per_gas) { + (*self.max_priority_fee_per_gas) + base_fee + } else { + *self.max_fee_per_gas + } + }, + Option::None => { *self.max_fee_per_gas } + } + } + + /// Decodes the RLP-encoded fields into a TxEip1559 struct. + /// + /// # Arguments + /// + /// * `data` - A span of RLPItems containing the encoded transaction fields + /// + /// # Returns + /// + /// A Result containing either the decoded TxEip1559 struct or an EthTransactionError + fn decode_fields(ref data: Span) -> Result { + let boxed_fields = data + .multi_pop_front::<9>() + .ok_or(EthTransactionError::RLPError(RLPError::InputTooShort))?; + let [ + chain_id_encoded, + nonce_encoded, + max_priority_fee_per_gas_encoded, + max_fee_per_gas_encoded, + gas_limit_encoded, + to_encoded, + value_encoded, + input_encoded, + access_list_encoded + ] = + (*boxed_fields) + .unbox(); + + let chain_id = chain_id_encoded.parse_u64_from_string().map_err()?; + let nonce = nonce_encoded.parse_u64_from_string().map_err()?; + let max_priority_fee_per_gas = max_priority_fee_per_gas_encoded + .parse_u128_from_string() + .map_err()?; + let max_fee_per_gas = max_fee_per_gas_encoded.parse_u128_from_string().map_err()?; + let gas_limit = gas_limit_encoded.parse_u64_from_string().map_err()?; + let to = to_encoded.try_parse_address_from_string().map_err()?; + let value = value_encoded.parse_u256_from_string().map_err()?; + let input = input_encoded.parse_bytes_from_string().map_err()?; + let access_list = access_list_encoded.parse_access_list().map_err()?; + + let txkind_to = match to { + Option::Some(to) => { TxKind::Call(to) }, + Option::None => { TxKind::Create } + }; + + Result::Ok( + TxEip1559 { + chain_id, + nonce, + max_priority_fee_per_gas, + max_fee_per_gas, + gas_limit, + to: txkind_to, + value, + access_list, + input, + } + ) + } +} diff --git a/kakarot-ssj/crates/utils/src/eth_transaction/eip2930.cairo b/kakarot-ssj/crates/utils/src/eth_transaction/eip2930.cairo new file mode 100644 index 000000000..d59ed6be3 --- /dev/null +++ b/kakarot-ssj/crates/utils/src/eth_transaction/eip2930.cairo @@ -0,0 +1,128 @@ +use core::starknet::EthAddress; +use crate::errors::{EthTransactionError, RLPError, RLPErrorTrait}; +use crate::eth_transaction::common::TxKind; +use crate::rlp::{RLPItem, RLPHelpersTrait}; +use crate::traits::SpanDefault; + + +#[derive(Copy, Drop, Serde, PartialEq, Debug)] +pub struct AccessListItem { + pub ethereum_address: EthAddress, + pub storage_keys: Span +} + +#[generate_trait] +pub impl AccessListItemImpl of AccessListItemTrait { + fn to_storage_keys(self: @AccessListItem) -> Span<(EthAddress, u256)> { + let AccessListItem { ethereum_address, mut storage_keys } = *self; + + let mut storage_keys_arr = array![]; + for storage_key in storage_keys { + storage_keys_arr.append((ethereum_address, *storage_key)); + }; + + storage_keys_arr.span() + } +} + + +/// Transaction with an [`AccessList`] ([EIP-2930](https://eips.ethereum.org/EIPS/eip-2930)). +#[derive(Copy, Drop, Debug, Default, PartialEq, Serde)] +pub struct TxEip2930 { + /// Added as EIP-pub 155: Simple replay attack protection + pub chain_id: u64, + /// A scalar value equal to the number of transactions sent by the sender; formally Tn. + pub nonce: u64, + /// A scalar value equal to the number of + /// Wei to be paid per unit of gas for all computation + /// costs incurred as a result of the execution of this transaction; formally Tp. + /// + /// As ethereum circulation is around 120mil eth as of 2022 that is around + /// 120000000000000000000000000 wei we are safe to use u128 as its max number is: + /// 340282366920938463463374607431768211455 + pub gas_price: u128, + /// A scalar value equal to the maximum + /// amount of gas that should be used in executing + /// this transaction. This is paid up-front, before any + /// computation is done and may not be increased + /// later; formally Tg. + pub gas_limit: u64, + /// The 160-bit address of the message call’s recipient or, for a contract creation + /// transaction, ∅, used here to denote the only member of B0 ; formally Tt. + pub to: TxKind, + /// A scalar value equal to the number of Wei to + /// be transferred to the message call’s recipient or, + /// in the case of contract creation, as an endowment + /// to the newly created account; + pub value: u256, + /// The accessList specifies a list of addresses and storage keys; + /// these addresses and storage keys are added into the `accessed_addresses` + /// and `accessed_storage_keys` global sets (introduced in EIP-2929). + /// A gas cost is charged, though at a discount relative to the cost of + /// accessing outside the list. + pub access_list: Span, + /// Input has two uses depending if transaction is Create or Call (if `to` field is None or + /// Some). pub init: An unlimited size byte array specifying the + /// EVM-code for the account initialisation procedure CREATE, + /// data: An unlimited size byte array specifying the + /// input data of the message call; + pub input: Span, +} + + +#[generate_trait] +pub impl _impl of TxEip2930Trait { + /// Decodes the RLP-encoded fields into a TxEip2930 struct. + /// + /// # Arguments + /// + /// * `data` - A span of RLPItems containing the encoded transaction fields + /// + /// # Returns + /// + /// A Result containing either the decoded TxEip2930 struct or an EthTransactionError + fn decode_fields(ref data: Span) -> Result { + let boxed_fields = data + .multi_pop_front::<8>() + .ok_or(EthTransactionError::RLPError(RLPError::InputTooShort))?; + let [ + chain_id_encoded, + nonce_encoded, + gas_price_encoded, + gas_limit_encoded, + to_encoded, + value_encoded, + input_encoded, + access_list_encoded + ] = + (*boxed_fields) + .unbox(); + + let chain_id = chain_id_encoded.parse_u64_from_string().map_err()?; + let nonce = nonce_encoded.parse_u64_from_string().map_err()?; + let gas_price = gas_price_encoded.parse_u128_from_string().map_err()?; + let gas_limit = gas_limit_encoded.parse_u64_from_string().map_err()?; + let to = to_encoded.try_parse_address_from_string().map_err()?; + let value = value_encoded.parse_u256_from_string().map_err()?; + let input = input_encoded.parse_bytes_from_string().map_err()?; + let access_list = access_list_encoded.parse_access_list().map_err()?; + + let txkind_to = match to { + Option::Some(to) => { TxKind::Call(to) }, + Option::None => { TxKind::Create } + }; + + Result::Ok( + TxEip2930 { + chain_id: chain_id, + nonce, + gas_price, + gas_limit, + input, + access_list, + to: txkind_to, + value, + } + ) + } +} diff --git a/kakarot-ssj/crates/utils/src/eth_transaction/legacy.cairo b/kakarot-ssj/crates/utils/src/eth_transaction/legacy.cairo new file mode 100644 index 000000000..3119ef4bc --- /dev/null +++ b/kakarot-ssj/crates/utils/src/eth_transaction/legacy.cairo @@ -0,0 +1,39 @@ +use crate::eth_transaction::common::TxKind; +use crate::traits::SpanDefault; + + +#[derive(Copy, Drop, Debug, Default, PartialEq, Serde)] +pub struct TxLegacy { + /// Added as EIP-155: Simple replay attack protection + pub chain_id: Option, + /// A scalar value equal to the number of transactions sent by the sender; formally Tn. + pub nonce: u64, + /// A scalar value equal to the number of + /// Wei to be paid per unit of gas for all computation + /// costs incurred as a result of the execution of this transaction; formally Tp. + /// + /// As ethereum circulation is around 120mil eth as of 2022 that is around + /// 120000000000000000000000000 wei we are safe to use u128 as its max number is: + /// 340282366920938463463374607431768211455 + pub gas_price: u128, + /// A scalar value equal to the maximum + /// amount of gas that should be used in executing + /// this transaction. This is paid up-front, before any + /// computation is done and may not be increased + /// later; + pub gas_limit: u64, + /// The 160-bit address of the message call’s recipient or, for a contract creation + /// transaction, ∅. + pub to: TxKind, + /// A scalar value equal to the number of Wei to + /// be transferred to the message call’s recipient or, + /// in the case of contract creation, as an endowment + /// to the newly created account; + pub value: u256, + /// Input has two uses depending if transaction is Create or Call (if `to` field is None or + /// Some). pub init: An unlimited size byte array specifying the + /// EVM-code for the account initialisation procedure CREATE, + /// data: An unlimited size byte array specifying the + /// input data of the message call. + pub input: Span, +} diff --git a/kakarot-ssj/crates/utils/src/eth_transaction/transaction.cairo b/kakarot-ssj/crates/utils/src/eth_transaction/transaction.cairo new file mode 100644 index 000000000..f301c8b4e --- /dev/null +++ b/kakarot-ssj/crates/utils/src/eth_transaction/transaction.cairo @@ -0,0 +1,532 @@ +use core::starknet::EthAddress; +use crate::errors::{RLPError, EthTransactionError, RLPErrorTrait}; +use crate::eth_transaction::common::{TxKind, TxKindTrait}; +use crate::eth_transaction::eip1559::{TxEip1559, TxEip1559Trait}; +use crate::eth_transaction::eip2930::{AccessListItem, TxEip2930, TxEip2930Trait}; +use crate::eth_transaction::legacy::TxLegacy; +use crate::eth_transaction::tx_type::{TxType}; +use crate::rlp::{RLPItem, RLPTrait, RLPHelpersTrait}; +use crate::traits::bytes::U8SpanExTrait; +use crate::traits::{DefaultSignature}; + + +#[derive(Copy, Debug, Drop, PartialEq, Serde)] +pub enum Transaction { + /// Legacy transaction (type `0x0`). + /// + /// Traditional Ethereum transactions, containing parameters `nonce`, `gasPrice`, `gasLimit`, + /// `to`, `value`, `data`, `v`, `r`, and `s`. + /// + /// These transactions do not utilize access lists nor do they incorporate EIP-1559 fee market + /// changes. + #[default] + Legacy: TxLegacy, + /// Transaction with an [`AccessList`] ([EIP-2930](https://eips.ethereum.org/EIPS/eip-2930)), + /// type `0x1`. + /// + /// The `accessList` specifies an array of addresses and storage keys that the transaction + /// plans to access, enabling gas savings on cross-contract calls by pre-declaring the accessed + /// contract and storage slots. + Eip2930: TxEip2930, + /// A transaction with a priority fee ([EIP-1559](https://eips.ethereum.org/EIPS/eip-1559)), + /// type `0x2`. + /// + /// Unlike traditional transactions, EIP-1559 transactions use an in-protocol, dynamically + /// changing base fee per gas, adjusted at each block to manage network congestion. + /// + /// - `maxPriorityFeePerGas`, specifying the maximum fee above the base fee the sender is + /// willing to pay + /// - `maxFeePerGas`, setting the maximum total fee the sender is willing to pay. + /// + /// The base fee is burned, while the priority fee is paid to the miner who includes the + /// transaction, incentivizing miners to include transactions with higher priority fees per + /// gas. + Eip1559: TxEip1559, +} + +#[generate_trait] +pub impl _Transasction of TransactionTrait { + /// Get `chain_id`. + fn chain_id(self: @Transaction) -> Option { + match (*self) { + Transaction::Legacy(tx) => tx.chain_id, + Transaction::Eip2930(TxEip2930 { chain_id, .. }) | + Transaction::Eip1559(TxEip1559 { chain_id, .. }) => Option::Some(chain_id), + } + } + + /// Gets the transaction's [`TxKind`], which is the address of the recipient or + /// [`TxKind::Create`] if the transaction is a contract creation. + fn kind(self: @Transaction) -> TxKind { + match (*self) { + Transaction::Legacy(TxLegacy { to, .. }) | Transaction::Eip2930(TxEip2930 { to, .. }) | + Transaction::Eip1559(TxEip1559 { to, .. }) => to, + } + } + + /// Get the transaction's address of the contract that will be called, or the address that will + /// receive the transfer. + /// + /// Returns `None` if this is a `CREATE` transaction. + fn to(self: @Transaction) -> Option { + self.kind().to() + } + + /// Get the transaction's type + fn transaction_type(self: @Transaction) -> TxType { + match (*self) { + Transaction::Legacy(_) => TxType::Legacy, + Transaction::Eip2930(_) => TxType::Eip2930, + Transaction::Eip1559(_) => TxType::Eip1559, + } + } + + /// Gets the transaction's value field. + fn value(self: @Transaction) -> u256 { + match (*self) { + Transaction::Legacy(TxLegacy { value, .. }) | + Transaction::Eip2930(TxEip2930 { value, .. }) | + Transaction::Eip1559(TxEip1559 { value, .. }) => value, + } + } + + /// Get the transaction's nonce. + fn nonce(self: @Transaction) -> u64 { + match (*self) { + Transaction::Legacy(TxLegacy { nonce, .. }) | + Transaction::Eip2930(TxEip2930 { nonce, .. }) | + Transaction::Eip1559(TxEip1559 { nonce, .. }) => nonce, + } + } + + /// Returns the [`AccessList`] of the transaction. + /// + /// Returns `None` for legacy transactions. + fn access_list(self: @Transaction) -> Option> { + match (*self) { + Transaction::Eip2930(TxEip2930 { access_list, .. }) | + Transaction::Eip1559(TxEip1559 { access_list, .. }) => Option::Some(access_list), + _ => Option::None, + } + } + + /// Get the gas limit of the transaction. + fn gas_limit(self: @Transaction) -> u64 { + match (*self) { + Transaction::Legacy(TxLegacy { gas_limit, .. }) | + Transaction::Eip2930(TxEip2930 { gas_limit, .. }) | + Transaction::Eip1559(TxEip1559 { gas_limit, .. }) => gas_limit.try_into().unwrap(), + } + } + + /// Max fee per gas for eip1559 transaction, for legacy transactions this is `gas_price`. + fn max_fee_per_gas(self: @Transaction) -> u128 { + match (*self) { + Transaction::Eip1559(TxEip1559 { max_fee_per_gas, .. }) => max_fee_per_gas, + Transaction::Legacy(TxLegacy { gas_price, .. }) | + Transaction::Eip2930(TxEip2930 { gas_price, .. }) => gas_price, + } + } + + /// Max priority fee per gas for eip1559 transaction, for legacy and eip2930 transactions this + /// is `None` + fn max_priority_fee_per_gas(self: @Transaction) -> Option { + match (*self) { + Transaction::Eip1559(TxEip1559 { max_priority_fee_per_gas, + .. }) => Option::Some(max_priority_fee_per_gas), + _ => Option::None, + } + } + + /// Return the max priority fee per gas if the transaction is an EIP-1559 transaction, and + /// otherwise return the gas price. + /// + /// # Warning + /// + /// This is different than the `max_priority_fee_per_gas` method, which returns `None` for + /// non-EIP-1559 transactions. + fn priority_fee_or_price(self: @Transaction) -> u128 { + match (*self) { + Transaction::Eip1559(TxEip1559 { max_priority_fee_per_gas, + .. }) => max_priority_fee_per_gas, + Transaction::Legacy(TxLegacy { gas_price, .. }) | + Transaction::Eip2930(TxEip2930 { gas_price, .. }) => gas_price, + } + } + + /// Returns the effective gas price for the given base fee. + /// + /// If the transaction is a legacy or EIP2930 transaction, the gas price is returned. + fn effective_gas_price(self: @Transaction, base_fee: Option) -> u128 { + match (*self) { + Transaction::Legacy(tx) => tx.gas_price, + Transaction::Eip2930(tx) => tx.gas_price, + Transaction::Eip1559(tx) => tx.effective_gas_price(base_fee) + } + } + + /// Get the transaction's input field. + fn input(self: @Transaction) -> Span { + match (*self) { + Transaction::Legacy(tx) => tx.input, + Transaction::Eip2930(tx) => tx.input, + Transaction::Eip1559(tx) => tx.input, + } + } +} + + +#[derive(Copy, Drop, Debug, PartialEq)] +pub struct TransactionUnsigned { + /// Transaction hash + pub hash: u256, + /// Raw transaction info + pub transaction: Transaction, +} + +#[generate_trait] +pub impl _TransactionUnsigned of TransactionUnsignedTrait { + /// Decodes the "raw" format of transaction (similar to `eth_sendRawTransaction`). + /// + /// This should be used for any method that accepts a raw transaction. + /// * `eth_send_raw_transaction`. + /// + /// A raw transaction is either a legacy transaction or EIP-2718 typed transaction. + /// + /// For legacy transactions, the format is encoded as: `rlp(tx-data)`. This format will start + /// with a RLP list header. + /// + /// For EIP-2718 typed transactions, the format is encoded as the type of the transaction + /// followed by the rlp of the transaction: `type || rlp(tx-data)`. + /// + /// Both for legacy and EIP-2718 transactions, an error will be returned if there is an excess + /// of bytes in input data. + fn decode_enveloped( + ref tx_data: Span, + ) -> Result { + if tx_data.is_empty() { + return Result::Err(EthTransactionError::RLPError(RLPError::InputTooShort)); + } + + // Check if it's a list + let transaction_signed = if Self::is_legacy_tx(tx_data) { + // Decode as a legacy transaction + Self::decode_legacy_tx(ref tx_data)? + } else { + Self::decode_enveloped_typed_transaction(ref tx_data)? + }; + + //TODO: check that the entire input was consumed and that there are no extra bytes at the + //end. + + Result::Ok(transaction_signed) + } + + /// Decode a legacy Ethereum transaction + /// This function decodes a legacy Ethereum transaction in accordance with EIP-155. + /// It returns transaction details including nonce, gas price, gas limit, destination address, + /// amount, payload, message hash, chain id. The transaction hash is computed by keccak hashing + /// the signed transaction data, which includes the chain ID in accordance with EIP-155. + /// # Arguments + /// * encoded_tx_data - The raw rlp encoded transaction data + /// * encoded_tx_data - is of the format: rlp![nonce, gasPrice, gasLimit, to , value, data, + /// chainId, 0, 0] + /// Note: this function assumes that tx_type has been checked to make sure it is a legacy + /// transaction + fn decode_legacy_tx( + ref encoded_tx_data: Span + ) -> Result { + let rlp_decoded_data = RLPTrait::decode(encoded_tx_data); + let rlp_decoded_data = rlp_decoded_data.map_err()?; + + if (rlp_decoded_data.len() != 1) { + return Result::Err( + EthTransactionError::TopLevelRlpListWrongLength(rlp_decoded_data.len()) + ); + } + + let rlp_decoded_data = *rlp_decoded_data.at(0); + let legacy_tx: TxLegacy = match rlp_decoded_data { + RLPItem::String => { Result::Err(EthTransactionError::ExpectedRLPItemToBeList)? }, + RLPItem::List(mut val) => { + if (val.len() != 9) { + return Result::Err(EthTransactionError::LegacyTxWrongPayloadLength(val.len())); + } + + let boxed_fields = val + .multi_pop_front::<7>() + .ok_or(EthTransactionError::RLPError(RLPError::InputTooShort))?; + let [ + nonce_encoded, + gas_price_encoded, + gas_limit_encoded, + to_encoded, + value_encoded, + input_encoded, + chain_id_encoded + ] = + (*boxed_fields) + .unbox(); + + let nonce = nonce_encoded.parse_u64_from_string().map_err()?; + let gas_price = gas_price_encoded.parse_u128_from_string().map_err()?; + let gas_limit = gas_limit_encoded.parse_u64_from_string().map_err()?; + let to = to_encoded.try_parse_address_from_string().map_err()?; + let value = value_encoded.parse_u256_from_string().map_err()?; + let input = input_encoded.parse_bytes_from_string().map_err()?; + let chain_id = chain_id_encoded.parse_u64_from_string().map_err()?; + + let transact_to = match to { + Option::Some(to) => { TxKind::Call(to) }, + Option::None => { TxKind::Create } + }; + + TxLegacy { + nonce, + gas_price, + gas_limit, + to: transact_to, + value, + input, + chain_id: Option::Some(chain_id), + } + } + }; + + let tx_hash = Self::compute_hash(encoded_tx_data); + + Result::Ok( + TransactionUnsigned { transaction: Transaction::Legacy(legacy_tx), hash: tx_hash, } + ) + } + + /// Decodes an enveloped EIP-2718 typed transaction. + /// + /// This should _only_ be used internally in general transaction decoding methods, + /// which have already ensured that the input is a typed transaction with the following format: + /// `tx-type || rlp(tx-data)` + /// + /// Note that this format does not start with any RLP header, and instead starts with a single + /// byte indicating the transaction type. + /// + /// CAUTION: this expects that `data` is `tx-type || rlp(tx-data)` + fn decode_enveloped_typed_transaction( + ref encoded_tx_data: Span + ) -> Result { + // keep this around so we can use it to calculate the hash + let original_data = encoded_tx_data; + + let tx_type = encoded_tx_data + .pop_front() + .ok_or(EthTransactionError::RLPError(RLPError::InputTooShort))?; + let tx_type: TxType = (*tx_type) + .try_into() + .ok_or(EthTransactionError::RLPError(RLPError::Custom('unsupported tx type')))?; + + let rlp_decoded_data = RLPTrait::decode(encoded_tx_data).map_err()?; + if (rlp_decoded_data.len() != 1) { + return Result::Err( + EthTransactionError::RLPError(RLPError::Custom('not encoded as list')) + ); + } + + let mut rlp_decoded_data = match *rlp_decoded_data.at(0) { + RLPItem::String => { + return Result::Err( + EthTransactionError::RLPError(RLPError::Custom('not encoded as list')) + ); + }, + RLPItem::List(v) => { v } + }; + + let transaction = match tx_type { + TxType::Eip2930 => Transaction::Eip2930( + TxEip2930Trait::decode_fields(ref rlp_decoded_data)? + ), + TxType::Eip1559 => Transaction::Eip1559( + TxEip1559Trait::decode_fields(ref rlp_decoded_data)? + ), + TxType::Legacy => { + return Result::Err( + EthTransactionError::RLPError(RLPError::Custom('unexpected legacy tx type')) + ); + } + }; + + let tx_hash = Self::compute_hash(original_data); + Result::Ok(TransactionUnsigned { transaction, hash: tx_hash }) + } + + /// Returns the hash of the unsigned transaction + /// + /// The hash is used to recover the sender address when verifying the signature + /// attached to the transaction + #[inline(always)] + fn compute_hash(encoded_tx_data: Span) -> u256 { + encoded_tx_data.compute_keccak256_hash() + } + + /// Check if a raw transaction is a legacy Ethereum transaction + /// This function checks if a raw transaction is a legacy Ethereum transaction by checking the + /// transaction type according to EIP-2718. + /// # Arguments + /// * `encoded_tx_data` - The raw rlp encoded transaction data + #[inline(always)] + fn is_legacy_tx(encoded_tx_data: Span) -> bool { + // From EIP2718: if it starts with a value in the range [0xc0, 0xfe] then it is a legacy + // transaction type + if (*encoded_tx_data[0] > 0xbf && *encoded_tx_data[0] < 0xff) { + return true; + } + + return false; + } +} + +#[cfg(test)] +mod tests { + use crate::eth_transaction::common::TxKind; + use crate::eth_transaction::eip2930::AccessListItem; + use crate::eth_transaction::tx_type::TxType; + use crate::test_data::{ + legacy_rlp_encoded_tx, legacy_rlp_encoded_deploy_tx, eip_2930_encoded_tx, + eip_1559_encoded_tx + }; + use super::{TransactionTrait, TransactionUnsignedTrait}; + + + #[test] + fn test_decode_legacy_tx() { + // tx_format (EIP-155, unsigned): [nonce, gasPrice, gasLimit, to, value, data, chainId, 0, + // 0] + // expected rlp decoding: [ "0x", "0x3b9aca00", "0x1e8480", + // "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984", "0x016345785d8a0000", "0xabcdef", + // "0x4b4b5254", "0x", "0x" ] + // message_hash: 0xcf71743e6e25fef715398915997f782b95554c8bbfb7b3f7701e007332ed31b4 + // chain id used: 'KKRT' + let mut encoded_tx_data = legacy_rlp_encoded_tx(); + let decoded = TransactionUnsignedTrait::decode_enveloped(ref encoded_tx_data).unwrap(); + assert_eq!(decoded.transaction.nonce(), 0); + assert_eq!(decoded.transaction.max_fee_per_gas(), 0x3b9aca00); + assert_eq!(decoded.transaction.gas_limit(), 0x1e8480); + assert_eq!( + decoded.transaction.kind(), + TxKind::Call(0x1f9840a85d5af5bf1d1762f925bdaddc4201f984.try_into().unwrap()) + ); + assert_eq!(decoded.transaction.value(), 0x016345785d8a0000); + assert_eq!(decoded.transaction.input(), [0xab, 0xcd, 0xef].span()); + assert_eq!(decoded.transaction.chain_id(), Option::Some(0x4b4b5254)); + assert_eq!(decoded.transaction.transaction_type(), TxType::Legacy); + } + + #[test] + fn test_decode_deploy_tx() { + // tx_format (EIP-155, unsigned): [nonce, gasPrice, gasLimit, to, value, data, chainId, 0, + // 0] + // expected rlp decoding: + // ["0x","0x0a","0x061a80","0x","0x0186a0","0x600160010a5060006000f3","0x4b4b5254","0x","0x"] + let mut encoded_tx_data = legacy_rlp_encoded_deploy_tx(); + let decoded = TransactionUnsignedTrait::decode_enveloped(ref encoded_tx_data).unwrap(); + assert_eq!(decoded.transaction.nonce(), 0); + assert_eq!(decoded.transaction.max_fee_per_gas(), 0x0a); + assert_eq!(decoded.transaction.gas_limit(), 0x061a80); + assert_eq!(decoded.transaction.kind(), TxKind::Create); + assert_eq!(decoded.transaction.value(), 0x0186a0); + assert_eq!( + decoded.transaction.input(), + [0x60, 0x01, 0x60, 0x01, 0x0a, 0x50, 0x60, 0x00, 0x60, 0x00, 0xf3].span() + ); + assert_eq!(decoded.transaction.chain_id(), Option::Some(0x4b4b5254)); + assert_eq!(decoded.transaction.transaction_type(), TxType::Legacy); + } + + #[test] + fn test_decode_eip2930_tx() { + // tx_format (EIP-2930, unsigned): 0x01 || rlp([chainId, nonce, gasPrice, gasLimit, to, + // value, data, accessList]) + // expected rlp decoding: [ "0x4b4b5254", "0x", "0x3b9aca00", "0x1e8480", + // "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984", "0x016345785d8a0000", "0xabcdef", + // [["0x1f9840a85d5af5bf1d1762f925bdaddc4201f984", + // ["0xde9fbe35790b85c23f42b7430c78f122636750cc217a534c80a9a0520969fa65", + // "0xd5362e94136f76bfc8dad0b510b94561af7a387f1a9d0d45e777c11962e5bd94"]]] ] + // message_hash: 0xc00f61dcc99a78934275c404267b9d035cad7f71cf3ae2ed2c5a55b601a5c107 + // chain id used: 'KKRT' + + let mut encoded_tx_data = eip_2930_encoded_tx(); + let decoded = TransactionUnsignedTrait::decode_enveloped(ref encoded_tx_data).unwrap(); + assert_eq!(decoded.transaction.chain_id(), Option::Some(0x4b4b5254)); + assert_eq!(decoded.transaction.nonce(), 0); + assert_eq!(decoded.transaction.max_fee_per_gas(), 0x3b9aca00); + assert_eq!(decoded.transaction.gas_limit(), 0x1e8480); + assert_eq!( + decoded.transaction.kind(), + TxKind::Call(0x1f9840a85d5af5bf1d1762f925bdaddc4201f984.try_into().unwrap()) + ); + assert_eq!(decoded.transaction.value(), 0x016345785d8a0000); + assert_eq!(decoded.transaction.input(), [0xab, 0xcd, 0xef].span()); + assert_eq!(decoded.transaction.transaction_type(), TxType::Eip2930); + } + + #[test] + fn test_decode_eip1559_tx() { + // tx_format (EIP-1559, unsigned): 0x02 || rlp([chain_id, nonce, max_priority_fee_per_gas, + // max_fee_per_gas, gas_limit, destination, amount, data, access_list]) + // expected rlp decoding: [ "0x4b4b5254", "0x", "0x", "0x3b9aca00", "0x1e8480", + // "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984", "0x016345785d8a0000", "0xabcdef", + // [[["0x1f9840a85d5af5bf1d1762f925bdaddc4201f984", + // ["0xde9fbe35790b85c23f42b7430c78f122636750cc217a534c80a9a0520969fa65", + // "0xd5362e94136f76bfc8dad0b510b94561af7a387f1a9d0d45e777c11962e5bd94"]]] ] ] + // message_hash: 0xa2de478d0c94b4be637523b818d03b6a1841fca63fd044976fcdbef3c57a87b0 + // chain id used: 'KKRT' + + let mut encoded_tx_data = eip_1559_encoded_tx(); + let decoded = TransactionUnsignedTrait::decode_enveloped(ref encoded_tx_data).unwrap(); + assert_eq!(decoded.transaction.chain_id(), Option::Some(0x4b4b5254)); + assert_eq!(decoded.transaction.nonce(), 0); + assert_eq!(decoded.transaction.max_fee_per_gas(), 0x3b9aca00); + assert_eq!(decoded.transaction.gas_limit(), 0x1e8480); + assert_eq!( + decoded.transaction.kind(), + TxKind::Call(0x1f9840a85d5af5bf1d1762f925bdaddc4201f984.try_into().unwrap()) + ); + assert_eq!(decoded.transaction.value(), 0x016345785d8a0000); + assert_eq!(decoded.transaction.input(), [0xab, 0xcd, 0xef].span()); + let expected_access_list = [ + AccessListItem { + ethereum_address: 0x1f9840a85d5af5bf1d1762f925bdaddc4201f984.try_into().unwrap(), + storage_keys: [ + 0xde9fbe35790b85c23f42b7430c78f122636750cc217a534c80a9a0520969fa65, + 0xd5362e94136f76bfc8dad0b510b94561af7a387f1a9d0d45e777c11962e5bd94 + ].span() + } + ].span(); + assert_eq!( + decoded.transaction.access_list().expect('access_list is none'), expected_access_list + ); + assert_eq!(decoded.transaction.transaction_type(), TxType::Eip1559); + } + + #[test] + fn test_is_legacy_tx_eip_155_tx() { + let encoded_tx_data = legacy_rlp_encoded_tx(); + let result = TransactionUnsignedTrait::is_legacy_tx(encoded_tx_data); + + assert(result, 'is_legacy_tx expected true'); + } + + #[test] + fn test_is_legacy_tx_eip_1559_tx() { + let encoded_tx_data = eip_1559_encoded_tx(); + let result = TransactionUnsignedTrait::is_legacy_tx(encoded_tx_data); + + assert(!result, 'is_legacy_tx expected false'); + } + + #[test] + fn test_is_legacy_tx_eip_2930_tx() { + let encoded_tx_data = eip_2930_encoded_tx(); + let result = TransactionUnsignedTrait::is_legacy_tx(encoded_tx_data); + + assert(!result, 'is_legacy_tx expected false'); + } +} diff --git a/kakarot-ssj/crates/utils/src/eth_transaction/tx_type.cairo b/kakarot-ssj/crates/utils/src/eth_transaction/tx_type.cairo new file mode 100644 index 000000000..3acaf3b72 --- /dev/null +++ b/kakarot-ssj/crates/utils/src/eth_transaction/tx_type.cairo @@ -0,0 +1,23 @@ +/// Transaction Type +#[derive(Copy, Drop, Debug, PartialEq)] +pub enum TxType { + /// Legacy transaction pre EIP-2929 + #[default] + Legacy, + /// AccessList transaction + Eip2930, + /// Transaction with Priority fee + Eip1559, +} + + +impl _TryInto of TryInto { + fn try_into(self: u8) -> Option { + match self { + 0 => Option::Some(TxType::Legacy), + 1 => Option::Some(TxType::Eip2930), + 2 => Option::Some(TxType::Eip1559), + _ => Option::None, + } + } +} diff --git a/kakarot-ssj/crates/utils/src/felt_vec.cairo b/kakarot-ssj/crates/utils/src/felt_vec.cairo new file mode 100644 index 000000000..cff02ceb0 --- /dev/null +++ b/kakarot-ssj/crates/utils/src/felt_vec.cairo @@ -0,0 +1,785 @@ +use alexandria_data_structures::vec::VecTrait; +use alexandria_data_structures::vec::{Felt252Vec, Felt252VecImpl}; +use core::num::traits::Zero; +use crate::math::Exponentiation; +use crate::traits::bytes::{ToBytes}; + + +#[derive(Drop, Debug, PartialEq)] +pub enum Felt252VecTraitErrors { + IndexOutOfBound, + Overflow, + LengthIsNotSame, + SizeLessThanCurrentLength +} + +#[generate_trait] +pub impl Felt252VecTraitImpl< + T, + +Drop, + +Copy, + +Felt252DictValue, + +Zero, + +Add, + +Sub, + +Div, + +Mul, + +Exponentiation, + +ToBytes, + +PartialOrd, + +Into, + +PartialEq, +> of Felt252VecTrait { + /// Returns Felt252Vec as a Span<8>, the returned Span is in big endian format + /// # Arguments + /// * `self` a ref Felt252Vec + /// # Returns + /// * A Span representing bytes conversion of `self` in big endian format + fn to_be_bytes(ref self: Felt252Vec) -> Span { + let mut res: Array = array![]; + self.remove_trailing_zeroes(); + + let mut i = self.len(); + + while i != 0 { + i -= 1; + res.append_span(self[i].to_be_bytes_padded()); + }; + + res.span() + } + + /// Returns Felt252Vec as a Span<8>, the returned Span is in little endian format + /// # Arguments + /// * `self` a ref Felt252Vec + /// # Returns + /// * A Span representing bytes conversion of `self` in little endian format + fn to_le_bytes(ref self: Felt252Vec) -> Span { + let mut res: Array = array![]; + + for i in 0 + ..self + .len() { + if self[i] == Zero::zero() { + res.append(Zero::zero()); + } else { + res.append_span(self[i].to_le_bytes()); + } + }; + + res.span() + } + + /// Expands a Felt252Vec to a new length by appending zeroes + /// + /// This function will mutate the Felt252Vec in-place and will expand its length, + /// since the default value for Felt252Dict item is 0, all new elements will be set to 0. + /// If the new length is less than the current length, it will return an error. + /// + /// # Arguments + /// * `self` a ref Felt252Vec + /// * `new_length` the new length of the Felt252Vec + /// + /// # Returns + /// * Result::<(), Felt252VecTraitErrors> + /// + /// # Errors + /// * Felt252VecTraitErrors::SizeLessThanCurrentLength if the new length is less than the + /// current length + fn expand(ref self: Felt252Vec, new_length: usize) -> Result<(), Felt252VecTraitErrors> { + if (new_length < self.len) { + return Result::Err(Felt252VecTraitErrors::SizeLessThanCurrentLength); + }; + + self.len = new_length; + + Result::Ok(()) + } + + /// Sets all elements of the Felt252Vec to zero, mutates the Felt252Vec in-place + /// + /// # Arguments + /// self a ref Felt252Vec + fn reset(ref self: Felt252Vec) { + let mut new_vec: Felt252Vec = Default::default(); + new_vec.len = self.len; + self = new_vec; + } + + /// Returns the leading zeroes of a Felt252Vec + /// + /// # Arguments + /// * `self` a ref Felt252Vec + /// + /// # Returns + /// * The number of leading zeroes in `self`. + fn count_leading_zeroes(ref self: Felt252Vec) -> usize { + let mut i = 0; + while i != self.len() && self[i] == Zero::zero() { + i += 1; + }; + + i + } + + /// Resizes the Felt252Vec in-place so that len is equal to new_len. + /// + /// This function will mutate the Felt252Vec in-place and will resize its length to the new + /// length. + /// If new_len is greater than len, the Vec is extended by the difference, with each additional + /// slot filled with 0. If new_len is less than len, the Vec is simply truncated from the right. + /// + /// # Arguments + /// * `self` a ref Felt252Vec + /// * `new_len` the new length of the Felt252Vec + fn resize(ref self: Felt252Vec, new_len: usize) { + self.len = new_len; + } + + + /// Copies the elements from a Span into the Felt252Vec in little endian format, in case + /// of overflow or index being out of bounds, an error is returned + /// + /// # Arguments + /// * `self` a ref Felt252Vec + /// * `index` the index at `self` to start copying from + /// * `slice` a Span + /// + /// # Errors + /// * Felt252VecTraitErrors::IndexOutOfBound if the index is out of bounds + /// * Felt252VecTraitErrors::Overflow if the Span is too big to fit in the Felt252Vec + fn copy_from_bytes_le( + ref self: Felt252Vec, index: usize, mut slice: Span + ) -> Result<(), Felt252VecTraitErrors> { + if (index >= self.len) { + return Result::Err(Felt252VecTraitErrors::IndexOutOfBound); + } + + if ((slice.len() + index) > self.len()) { + return Result::Err(Felt252VecTraitErrors::Overflow); + } + + let mut i = index; + for val in slice { + // safe unwrap, as in case of none, we will never reach this branch + self.set(i, (*val).into()); + i += 1; + }; + + Result::Ok(()) + } + + /// Copies the elements from a Felt252Vec into the Felt252Vec in little endian format, If + /// length of both Felt252Vecs are not same, it will return an error + /// + /// # Arguments + /// * `self` a ref Felt252Vec + /// * `vec` a ref Felt252Vec + /// + /// # Errors + /// * Felt252VecTraitErrors::LengthIsNotSame if the length of both Felt252Vecs are not same + fn copy_from_vec_le( + ref self: Felt252Vec, ref vec: Felt252Vec + ) -> Result<(), Felt252VecTraitErrors> { + if (vec.len() != self.len) { + return Result::Err(Felt252VecTraitErrors::LengthIsNotSame); + } + + self = vec.duplicate(); + + Result::Ok(()) + } + + /// Insert elements of Felt252Vec into another Felt252Vec at a given index, in case of overflow + /// or index being out of bounds, an error is returned + /// + /// # Arguments + /// * `self` a ref Felt252Vec + /// * `idx` the index at `self` to start inserting from + /// * `vec` a ref Felt252Vec + /// + /// # Errors + /// * Felt252VecTraitErrors::IndexOutOfBound if the index is out of bounds + /// * Felt252VecTraitErrors::Overflow if the Felt252Vec is too big to fit in the Felt252Vec + fn insert_vec( + ref self: Felt252Vec, idx: usize, ref vec: Felt252Vec + ) -> Result<(), Felt252VecTraitErrors> { + if idx >= self.len() { + return Result::Err(Felt252VecTraitErrors::IndexOutOfBound); + } + + if (idx + vec.len > self.len) { + return Result::Err(Felt252VecTraitErrors::Overflow); + } + + let stop = idx + vec.len(); + for i in idx..stop { + self.set(i, vec[i - idx]); + }; + + Result::Ok(()) + } + + + /// Removes trailing zeroes from a Felt252Vec + /// + /// # Arguments + /// * `input` a ref Felt252Vec + fn remove_trailing_zeroes(ref self: Felt252Vec) { + let mut new_len = self.len; + while (new_len != 0) && (self[new_len - 1] == Zero::zero()) { + new_len -= 1; + }; + + self.len = new_len; + } + + /// Pops an element out of the vector, returns Option::None if the vector is empty + /// + /// # Arguments + /// * `self` a ref Felt252Vec + /// # Returns + /// + /// * Option::Some(T), returns the last element or Option::None if the vector is empty + fn pop(ref self: Felt252Vec) -> Option { + if (self.len) == 0 { + return Option::None; + } + + let popped_ele = self[self.len() - 1]; + self.len = self.len - 1; + Option::Some(popped_ele) + } + + /// takes a Felt252Vec and returns a new Felt252Vec with the same elements + /// + /// Note: this is an expensive operation, as it will create a new Felt252Vec + /// + /// # Arguments + /// * `self` a ref Felt252Vec + /// + /// # Returns + /// * A new Felt252Vec with the same elements + fn duplicate(ref self: Felt252Vec) -> Felt252Vec { + let mut new_vec = Default::default(); + + for i in 0..self.len { + new_vec.push(self[i]); + }; + + new_vec + } + + /// Returns a new Felt252Vec with elements starting from `idx` to `idx + len` + /// + /// This function will start cloning from `idx` and will clone `len` elements, it will firstly + /// clone the elements and then return a new Felt252Vec + /// In case of overflow return Option::None + /// + /// # Arguments + /// * `self` a ref Felt252Vec + /// * `idx` the index to start cloning from + /// * `len` the length of the clone + /// + /// # Returns + /// * Felt252Vec + /// + /// # Panics + /// * If the index is out of bounds + /// + /// Note: this is an expensive operation, as it will create a new Felt252Vec + fn clone_slice(ref self: Felt252Vec, idx: usize, len: usize) -> Felt252Vec { + let mut new_vec = Default::default(); + + for i in 0..len { + new_vec.push(self[idx + i]); + }; + + new_vec + } + + /// Returns whether two Felt252Vec are equal after removing trailing_zeroes + /// + /// # Arguments + /// * `self` a ref Felt252Vec + /// * `rhs` a ref Felt252Vec + /// + /// # Returns + /// * bool, returns true if both Felt252Vecs are equal, false otherwise + /// TODO: if this utils is only used for testing, then refactor as a test util + fn equal_remove_trailing_zeroes(ref self: Felt252Vec, ref rhs: Felt252Vec) -> bool { + let mut lhs = self.duplicate(); + lhs.remove_trailing_zeroes(); + + let mut rhs = rhs.duplicate(); + rhs.remove_trailing_zeroes(); + + if lhs.len() != rhs.len() { + return false; + }; + + let mut result = true; + for i in 0..lhs.len() { + if lhs[i] != rhs[i] { + result = false; + break; + } + }; + result + } + + /// Fills a Felt252Vec with a given `value` starting from `start_idx` to `start_idx + len` + /// In case of index out of bounds or overflow, error is returned + /// + /// # Arguments + /// * `self` a ref Felt252Vec + /// * `start_idx` the index to start filling from + /// * `len` the length of the fill + /// * `value` the value to fill the Felt252Vec with + /// + /// # Returns + /// * Result::<(), Felt252VecTraitErrors> + /// + /// # Errors + /// * Felt252VecTraitErrors::IndexOutOfBound if the index is out of bounds + /// * Felt252VecTraitErrors::Overflow if the Felt252Vec is too big to fit in the Felt252Vec + fn fill( + ref self: Felt252Vec, start_idx: usize, len: usize, value: T + ) -> Result<(), Felt252VecTraitErrors> { + // Index out of bounds + if (start_idx >= self.len()) { + return Result::Err(Felt252VecTraitErrors::IndexOutOfBound); + } + + // Overflow + if (start_idx + len > self.len()) { + return Result::Err(Felt252VecTraitErrors::Overflow); + } + + for i in start_idx..start_idx + len { + self.set(i, value); + }; + + Result::Ok(()) + } +} + +#[cfg(test)] +mod tests { + mod felt252_vec_u8_test { + use alexandria_data_structures::vec::{VecTrait, Felt252Vec}; + use crate::felt_vec::{Felt252VecTrait}; + + #[test] + fn test_felt252_vec_u8_to_bytes() { + let mut vec: Felt252Vec = Default::default(); + vec.push(0); + vec.push(1); + vec.push(2); + vec.push(3); + + let result = vec.to_le_bytes(); + let expected = [0, 1, 2, 3].span(); + + assert_eq!(result, expected); + } + } + + mod felt252_vec_u64_test { + use alexandria_data_structures::vec::{VecTrait, Felt252Vec}; + use crate::felt_vec::{Felt252VecTrait}; + + #[test] + fn test_felt252_vec_u64_words64_to_le_bytes() { + let mut vec: Felt252Vec = Default::default(); + vec.push(0); + vec.push(1); + vec.push(2); + vec.push(3); + + let result = vec.to_le_bytes(); + let expected = [0, 1, 2, 3].span(); + + assert_eq!(result, expected); + } + + #[test] + fn test_felt252_vec_u64_words64_to_be_bytes() { + let mut vec: Felt252Vec = Default::default(); + vec.push(0); + vec.push(1); + vec.push(2); + vec.push(3); + + let result = vec.to_be_bytes(); + let expected = [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ].span(); + + assert_eq!(result, expected); + } + } + + mod felt252_vec_test { + use alexandria_data_structures::vec::{VecTrait, Felt252Vec}; + use crate::felt_vec::{Felt252VecTrait, Felt252VecTraitErrors}; + + #[test] + fn test_felt252_vec_expand() { + let mut vec: Felt252Vec = Default::default(); + vec.push(0); + vec.push(1); + + vec.expand(4).unwrap(); + + assert_eq!(vec.len(), 4); + assert_eq!(vec.pop().unwrap(), 0); + assert_eq!(vec.pop().unwrap(), 0); + assert_eq!(vec.pop().unwrap(), 1); + assert_eq!(vec.pop().unwrap(), 0); + } + + #[test] + fn test_felt252_vec_expand_fail() { + let mut vec: Felt252Vec = Default::default(); + vec.push(0); + vec.push(1); + + let result = vec.expand(1); + assert_eq!(result, Result::Err(Felt252VecTraitErrors::SizeLessThanCurrentLength)); + } + + #[test] + fn test_felt252_vec_reset() { + let mut vec: Felt252Vec = Default::default(); + vec.push(0); + vec.push(1); + + vec.reset(); + + assert_eq!(vec.len(), 2); + assert_eq!(vec.pop().unwrap(), 0); + assert_eq!(vec.pop().unwrap(), 0); + } + + #[test] + fn test_felt252_vec_count_leading_zeroes() { + let mut vec: Felt252Vec = Default::default(); + vec.push(0); + vec.push(0); + vec.push(0); + vec.push(1); + + let result = vec.count_leading_zeroes(); + + assert_eq!(result, 3); + } + + + #[test] + fn test_felt252_vec_resize_len_greater_than_current_len() { + let mut vec: Felt252Vec = Default::default(); + vec.push(0); + vec.push(1); + + vec.expand(4).unwrap(); + + assert_eq!(vec.len(), 4); + assert_eq!(vec.pop().unwrap(), 0); + assert_eq!(vec.pop().unwrap(), 0); + assert_eq!(vec.pop().unwrap(), 1); + assert_eq!(vec.pop().unwrap(), 0); + } + + #[test] + fn test_felt252_vec_resize_len_less_than_current_len() { + let mut vec: Felt252Vec = Default::default(); + vec.push(0); + vec.push(1); + vec.push(0); + vec.push(0); + + vec.resize(2); + + assert_eq!(vec.len(), 2); + assert_eq!(vec.pop().unwrap(), 1); + assert_eq!(vec.pop().unwrap(), 0); + } + + #[test] + fn test_felt252_vec_len_0() { + let mut vec: Felt252Vec = Default::default(); + vec.push(0); + vec.push(1); + + vec.resize(0); + + assert_eq!(vec.len(), 0); + } + + #[test] + fn test_copy_from_bytes_le_size_equal_to_vec_size() { + let mut vec: Felt252Vec = Default::default(); + vec.expand(4).unwrap(); + + let bytes = [1, 2, 3, 4].span(); + vec.copy_from_bytes_le(0, bytes).unwrap(); + + assert_eq!(vec.len(), 4); + assert_eq!(vec.pop().unwrap(), 4); + assert_eq!(vec.pop().unwrap(), 3); + assert_eq!(vec.pop().unwrap(), 2); + assert_eq!(vec.pop().unwrap(), 1); + } + + #[test] + fn test_copy_from_bytes_le_size_less_than_vec_size() { + let mut vec: Felt252Vec = Default::default(); + vec.expand(4).unwrap(); + + let bytes = [1, 2].span(); + vec.copy_from_bytes_le(2, bytes).unwrap(); + + assert_eq!(vec.len(), 4); + assert_eq!(vec.pop().unwrap(), 2); + assert_eq!(vec.pop().unwrap(), 1); + assert_eq!(vec.pop().unwrap(), 0); + assert_eq!(vec.pop().unwrap(), 0); + } + + #[test] + fn test_copy_from_bytes_le_size_greater_than_vec_size() { + let mut vec: Felt252Vec = Default::default(); + vec.expand(4).unwrap(); + + let bytes = [1, 2, 3, 4].span(); + let result = vec.copy_from_bytes_le(2, bytes); + + assert_eq!(result, Result::Err(Felt252VecTraitErrors::Overflow)); + } + + #[test] + fn test_copy_from_bytes_index_out_of_bound() { + let mut vec: Felt252Vec = Default::default(); + vec.expand(4).unwrap(); + + let bytes = [1, 2].span(); + let result = vec.copy_from_bytes_le(4, bytes); + + assert_eq!(result, Result::Err(Felt252VecTraitErrors::IndexOutOfBound)); + } + + #[test] + fn test_copy_from_vec_le() { + let mut vec: Felt252Vec = Default::default(); + vec.expand(2).unwrap(); + + let mut vec2: Felt252Vec = Default::default(); + vec2.push(1); + vec2.push(2); + + vec.copy_from_vec_le(ref vec2).unwrap(); + + assert_eq!(vec.len, 2); + assert_eq!(vec.pop().unwrap(), 2); + assert_eq!(vec.pop().unwrap(), 1); + } + + #[test] + fn test_copy_from_vec_le_not_equal_lengths() { + let mut vec: Felt252Vec = Default::default(); + vec.expand(2).unwrap(); + + let mut vec2: Felt252Vec = Default::default(); + vec2.push(1); + + let result = vec.copy_from_vec_le(ref vec2); + + assert_eq!(result, Result::Err(Felt252VecTraitErrors::LengthIsNotSame)); + } + + + #[test] + fn test_insert_vec_size_equal_to_vec_size() { + let mut vec: Felt252Vec = Default::default(); + vec.expand(2).unwrap(); + + let mut vec2: Felt252Vec = Default::default(); + vec2.push(1); + vec2.push(2); + + vec.insert_vec(0, ref vec2).unwrap(); + + assert_eq!(vec.len(), 2); + assert_eq!(vec.pop().unwrap(), 2); + assert_eq!(vec.pop().unwrap(), 1); + } + + #[test] + fn test_insert_vec_size_less_than_vec_size() { + let mut vec: Felt252Vec = Default::default(); + vec.expand(4).unwrap(); + + let mut vec2: Felt252Vec = Default::default(); + vec2.push(1); + vec2.push(2); + + vec.insert_vec(2, ref vec2).unwrap(); + + assert_eq!(vec.len(), 4); + assert_eq!(vec.pop().unwrap(), 2); + assert_eq!(vec.pop().unwrap(), 1); + assert_eq!(vec.pop().unwrap(), 0); + assert_eq!(vec.pop().unwrap(), 0); + } + + #[test] + fn test_insert_vec_size_greater_than_vec_size() { + let mut vec: Felt252Vec = Default::default(); + vec.expand(2).unwrap(); + + let mut vec2: Felt252Vec = Default::default(); + vec2.push(1); + vec2.push(2); + vec2.push(3); + vec2.push(4); + + let result = vec.insert_vec(1, ref vec2); + assert_eq!(result, Result::Err(Felt252VecTraitErrors::Overflow)); + } + + #[test] + fn test_insert_vec_index_out_of_bound() { + let mut vec: Felt252Vec = Default::default(); + vec.expand(4).unwrap(); + + let mut vec2: Felt252Vec = Default::default(); + vec2.push(1); + vec2.push(2); + + let result = vec.insert_vec(4, ref vec2); + assert_eq!(result, Result::Err(Felt252VecTraitErrors::IndexOutOfBound)); + } + + #[test] + fn test_remove_trailing_zeroes_le() { + let mut vec: Felt252Vec = Default::default(); + vec.push(1); + vec.push(2); + vec.push(0); + vec.push(0); + + vec.remove_trailing_zeroes(); + + assert_eq!(vec.len(), 2); + assert_eq!(vec.pop().unwrap(), 2); + assert_eq!(vec.pop().unwrap(), 1); + } + + #[test] + fn test_pop() { + let mut vec: Felt252Vec = Default::default(); + vec.push(1); + vec.push(2); + + assert_eq!(vec.pop().unwrap(), 2); + assert_eq!(vec.pop().unwrap(), 1); + assert_eq!(vec.pop(), Option::::None); + } + + #[test] + fn test_duplicate() { + let mut vec: Felt252Vec = Default::default(); + vec.push(1); + vec.push(2); + + let mut vec2 = vec.duplicate(); + + assert_eq!(vec.len(), vec2.len()); + assert_eq!(vec.pop(), vec2.pop()); + assert_eq!(vec.pop(), vec2.pop()); + assert_eq!(vec.pop().is_none(), true); + assert_eq!(vec2.pop().is_none(), true); + } + + #[test] + fn test_clone_slice() { + let mut vec: Felt252Vec = Default::default(); + vec.push(1); + vec.push(2); + + let mut vec2 = vec.clone_slice(1, 1); + + assert_eq!(vec2.len(), 1); + assert_eq!(vec2.pop().unwrap(), 2); + } + + #[test] + fn test_equal() { + let mut vec: Felt252Vec = Default::default(); + vec.push(1); + vec.push(2); + + let mut vec2: Felt252Vec = Default::default(); + vec2.push(1); + vec2.push(2); + + assert!(vec.equal_remove_trailing_zeroes(ref vec2)); + vec2.pop().unwrap(); + assert!(!vec.equal_remove_trailing_zeroes(ref vec2)); + } + + #[test] + fn test_fill() { + let mut vec: Felt252Vec = Default::default(); + vec.expand(4).unwrap(); + + vec.fill(1, 3, 1).unwrap(); + + assert_eq!(vec.pop().unwrap(), 1); + assert_eq!(vec.pop().unwrap(), 1); + assert_eq!(vec.pop().unwrap(), 1); + assert_eq!(vec.pop().unwrap(), 0); + } + + #[test] + fn test_fill_overflow() { + let mut vec: Felt252Vec = Default::default(); + vec.expand(4).unwrap(); + + assert_eq!(vec.fill(4, 0, 1), Result::Err(Felt252VecTraitErrors::IndexOutOfBound)); + assert_eq!(vec.fill(2, 4, 1), Result::Err(Felt252VecTraitErrors::Overflow)); + } + } +} diff --git a/kakarot-ssj/crates/utils/src/fmt.cairo b/kakarot-ssj/crates/utils/src/fmt.cairo new file mode 100644 index 000000000..d343b31cb --- /dev/null +++ b/kakarot-ssj/crates/utils/src/fmt.cairo @@ -0,0 +1,50 @@ +use core::fmt::{Debug, Formatter, Error}; +use crate::set::{SpanSet, SpanSetTrait}; + +mod display_felt252_based { + use core::fmt::{Display, Formatter, Error}; + use core::to_byte_array::AppendFormattedToByteArray; + pub impl TDisplay, +Copy> of Display { + fn fmt(self: @T, ref f: Formatter) -> Result<(), Error> { + let value: felt252 = (*self).into(); + let base: felt252 = 10_u8.into(); + value.append_formatted_to_byte_array(ref f.buffer, base.try_into().unwrap()); + Result::Ok(()) + } + } +} + +mod debug_display_based { + use core::fmt::{Display, Debug, Formatter, Error}; + pub impl TDisplay> of Debug { + fn fmt(self: @T, ref f: Formatter) -> Result<(), Error> { + Display::fmt(self, ref f) + } + } +} + +pub impl TSpanSetDebug, +Copy, +Drop> of Debug> { + fn fmt(self: @SpanSet, ref f: Formatter) -> Result<(), Error> { + // For a reason I don't understand, the following code doesn't compile: + // Debug::fmt(@(*self.to_span())sc, ref f) + let mut self = (*self).to_span(); + write!(f, "[")?; + loop { + match self.pop_front() { + Option::Some(value) => { + if Debug::fmt(value, ref f).is_err() { + break Result::Err(Error {}); + }; + if self.is_empty() { + break Result::Ok(()); + } + if write!(f, ", ").is_err() { + break Result::Err(Error {}); + }; + }, + Option::None => { break Result::Ok(()); } + }; + }?; + write!(f, "]") + } +} diff --git a/kakarot-ssj/crates/utils/src/helpers.cairo b/kakarot-ssj/crates/utils/src/helpers.cairo new file mode 100644 index 000000000..94e99eafd --- /dev/null +++ b/kakarot-ssj/crates/utils/src/helpers.cairo @@ -0,0 +1,282 @@ +use core::array::ArrayTrait; +use core::array::SpanTrait; +use core::cmp::min; +use core::hash::{HashStateExTrait, HashStateTrait}; +use core::num::traits::SaturatingAdd; + +use core::panic_with_felt252; +use core::pedersen::PedersenTrait; +use core::starknet::{EthAddress, ContractAddress, ClassHash}; +use core::traits::TryInto; +use core::traits::{DivRem}; +use crate::constants::{CONTRACT_ADDRESS_PREFIX, MAX_ADDRESS}; +use crate::constants::{POW_2, POW_256_1, POW_256_REV}; +use crate::math::{Bitshift, WrappingBitshift}; + +use crate::traits::array::{ArrayExtTrait}; +use crate::traits::{U256TryIntoContractAddress, EthAddressIntoU256, BoolIntoNumeric}; + +/// Splits a u128 into two u64 parts, representing the high and low parts of the input. +/// +/// # Arguments +/// * `input` - The u128 value to be split. +/// +/// # Returns +/// A tuple containing two u64 values, where the first element is the high part of the input +/// and the second element is the low part of the input. +pub fn u128_split(input: u128) -> (u64, u64) { + let (high, low) = core::integer::u128_safe_divmod( + input, 0x10000000000000000_u128.try_into().unwrap() + ); + + (high.try_into().unwrap(), low.try_into().unwrap()) +} + +/// Computes the number of 32-byte words required to represent `size` bytes +/// +/// # Arguments +/// * `size` - The size in bytes +/// +/// # Returns +/// The number of 32-byte words required to represent `size` bytes +/// +/// # Examples +/// bytes_32_words_size(2) = 1 +/// bytes_32_words_size(34) = 2 +#[inline(always)] +pub fn bytes_32_words_size(size: usize) -> usize { + size.saturating_add(31) / 32 +} + +/// Computes 256 ** (16 - i) for 0 <= i <= 16. +pub fn pow256_rev(i: usize) -> u256 { + if (i > 16) { + panic_with_felt252('pow256_rev: i > 16'); + } + let v = POW_256_REV.span().at(i); + *v +} + +/// Computes 2**pow for 0 <= pow < 128. +pub fn pow2(pow: usize) -> u128 { + if (pow > 127) { + return panic_with_felt252('pow2: pow >= 128'); + } + let v = POW_2.span().at(pow); + *v +} + +/// Splits a u256 into `len` bytes, big-endian, and appends the result to `dst`. +pub fn split_word(mut value: u256, mut len: usize, ref dst: Array) { + let word_le = split_word_le(value, len); + let word_be = ArrayExtTrait::reverse(word_le.span()); + ArrayExtTrait::concat(ref dst, word_be.span()); +} + +/// Splits a u128 into `len` bytes in little-endian order and appends them to the destination array. +/// +/// # Arguments +/// * `dest` - The destination array to append the bytes to +/// * `value` - The u128 value to split into bytes +/// * `len` - The number of bytes to split the value into +pub fn split_u128_le(ref dest: Array, mut value: u128, mut len: usize) { + for _ in 0..len { + dest.append((value % 256).try_into().unwrap()); + value /= 256; + }; +} + +/// Splits a u256 into `len` bytes, little-endian, and returns the bytes array. +/// +/// # Arguments +/// * `value` - The u256 value to be split. +/// * `len` - The number of bytes to split the value into. +/// +/// # Returns +/// An `Array` containing the little-endian byte representation of the input value. +pub fn split_word_le(mut value: u256, mut len: usize) -> Array { + let mut dst: Array = ArrayTrait::new(); + let low_len = min(len, 16); + split_u128_le(ref dst, value.low, low_len); + let high_len = min(len - low_len, 16); + split_u128_le(ref dst, value.high, high_len); + dst +} + +/// Splits a u256 into 16 bytes, big-endian, and appends the result to `dst`. +/// +/// # Arguments +/// * `value` - The u256 value to be split. +/// * `dst` - The destination array to append the bytes to. +pub fn split_word_128(value: u256, ref dst: Array) { + split_word(value, 16, ref dst) +} + +/// Converts a u256 to a bytes array represented by an array of u8 values in big-endian order. +/// +/// # Arguments +/// * `value` - The u256 value to convert. +/// +/// # Returns +/// An `Array` representing the big-endian byte representation of the input value. +pub fn u256_to_bytes_array(mut value: u256) -> Array { + let mut bytes_arr: Array = ArrayTrait::new(); + // low part + for _ in 0 + ..16_u8 { + bytes_arr.append((value.low & 0xFF).try_into().unwrap()); + value.low /= 256; + }; + + // high part + for _ in 0 + ..16_u8 { + bytes_arr.append((value.high & 0xFF).try_into().unwrap()); + value.high /= 256; + }; + + // Reverse the array as memory is arranged in big endian order. + let mut counter = bytes_arr.len(); + let mut bytes_arr_reversed: Array = ArrayTrait::new(); + while counter != 0 { + bytes_arr_reversed.append(*bytes_arr[counter - 1]); + counter -= 1; + }; + bytes_arr_reversed +} + + +/// Computes the Starknet address for a given Kakarot address, EVM address, and class hash. +/// +/// # Arguments +/// * `kakarot_address` - The Kakarot contract address. +/// * `evm_address` - The Ethereum address. +/// * `class_hash` - The class hash. +/// +/// # Returns +/// A `ContractAddress` representing the computed Starknet address. +pub fn compute_starknet_address( + kakarot_address: ContractAddress, evm_address: EthAddress, class_hash: ClassHash +) -> ContractAddress { + // Deployer is always Kakarot (current contract) + // pedersen(a1, a2, a3) is defined as: + // pedersen(pedersen(pedersen(a1, a2), a3), len([a1, a2, a3])) + // https://github.com/starkware-libs/cairo-lang/blob/master/src/starkware/cairo/common/hash_state.py#L6 + // https://github.com/xJonathanLEI/starknet-rs/blob/master/starknet-core/src/crypto.rs#L49 + // Constructor Calldata For an Account, the constructor calldata is: + // [1, evm_address] + let constructor_calldata_hash = PedersenTrait::new(0) + .update_with(1) + .update_with(evm_address) + .update(2) + .finalize(); + + let hash = PedersenTrait::new(0) + .update_with(CONTRACT_ADDRESS_PREFIX) + .update_with(kakarot_address) + .update_with(evm_address) + .update_with(class_hash) + .update_with(constructor_calldata_hash) + .update(5) + .finalize(); + + let normalized_address: ContractAddress = (hash.into() & MAX_ADDRESS).try_into().unwrap(); + // We know this unwrap is safe, because of the above bitwise AND on 2 ** 251 + normalized_address +} + + +#[cfg(test)] +mod tests { + use crate::helpers; + + #[test] + fn test_u256_to_bytes_array() { + let value: u256 = 256; + + let bytes_array = helpers::u256_to_bytes_array(value); + assert(1 == *bytes_array[30], 'wrong conversion'); + } + + #[test] + fn test_split_word_le() { + // Test with 0 value and 0 len + let res0 = helpers::split_word_le(0, 0); + assert(res0.len() == 0, 'res0: wrong length'); + + // Test with single byte value + let res1 = helpers::split_word_le(1, 1); + assert(res1.len() == 1, 'res1: wrong length'); + assert(*res1[0] == 1, 'res1: wrong value'); + + // Test with two byte value + let res2 = helpers::split_word_le(257, 2); // 257 = 0x0101 + assert(res2.len() == 2, 'res2: wrong length'); + assert(*res2[0] == 1, 'res2: wrong value at index 0'); + assert(*res2[1] == 1, 'res2: wrong value at index 1'); + + // Test with four byte value + let res3 = helpers::split_word_le(67305985, 4); // 67305985 = 0x04030201 + assert(res3.len() == 4, 'res3: wrong length'); + assert(*res3[0] == 1, 'res3: wrong value at index 0'); + assert(*res3[1] == 2, 'res3: wrong value at index 1'); + assert(*res3[2] == 3, 'res3: wrong value at index 2'); + assert(*res3[3] == 4, 'res3: wrong value at index 3'); + + // Test with 16 byte value (u128 max value) + let max_u128: u256 = 340282366920938463463374607431768211454; // u128 max value - 1 + let res4 = helpers::split_word_le(max_u128, 16); + assert(res4.len() == 16, 'res4: wrong length'); + assert(*res4[0] == 0xfe, 'res4: wrong MSB value'); + + for counter in 1..16_u32 { + assert(*res4[counter] == 0xff, 'res4: wrong value at index'); + }; + } + + #[test] + fn test_split_word() { + // Test with 0 value and 0 len + let mut dst0: Array = ArrayTrait::new(); + helpers::split_word(0, 0, ref dst0); + assert(dst0.len() == 0, 'dst0: wrong length'); + + // Test with single byte value + let mut dst1: Array = ArrayTrait::new(); + helpers::split_word(1, 1, ref dst1); + assert(dst1.len() == 1, 'dst1: wrong length'); + assert(*dst1[0] == 1, 'dst1: wrong value'); + + // Test with two byte value + let mut dst2: Array = ArrayTrait::new(); + helpers::split_word(257, 2, ref dst2); // 257 = 0x0101 + assert(dst2.len() == 2, 'dst2: wrong length'); + assert(*dst2[0] == 1, 'dst2: wrong value at index 0'); + assert(*dst2[1] == 1, 'dst2: wrong value at index 1'); + + // Test with four byte value + let mut dst3: Array = ArrayTrait::new(); + helpers::split_word(16909060, 4, ref dst3); // 16909060 = 0x01020304 + assert(dst3.len() == 4, 'dst3: wrong length'); + assert(*dst3[0] == 1, 'dst3: wrong value at index 0'); + assert(*dst3[1] == 2, 'dst3: wrong value at index 1'); + assert(*dst3[2] == 3, 'dst3: wrong value at index 2'); + assert(*dst3[3] == 4, 'dst3: wrong value at index 3'); + + // Test with 16 byte value (u128 max value) + let max_u128: u256 = 340282366920938463463374607431768211454; // u128 max value -1 + let mut dst4: Array = ArrayTrait::new(); + helpers::split_word(max_u128, 16, ref dst4); + assert(dst4.len() == 16, 'dst4: wrong length'); + assert(*dst4[15] == 0xfe, 'dst4: wrong LSB value'); + for counter in 0..dst4.len() - 1 { + assert_eq!(*dst4[counter], 0xff); + }; + } + + #[test] + fn test_bytes_32_words_size_edge_case() { + let max_usize = core::num::traits::Bounded::::MAX; + assert_eq!(helpers::bytes_32_words_size(max_usize), (max_usize / 32)); + } +} diff --git a/kakarot-ssj/crates/utils/src/i256.cairo b/kakarot-ssj/crates/utils/src/i256.cairo new file mode 100644 index 000000000..9e8bf5dda --- /dev/null +++ b/kakarot-ssj/crates/utils/src/i256.cairo @@ -0,0 +1,535 @@ +use core::num::traits::Bounded; +use crate::constants::POW_2_127; + +/// Represents a signed 256-bit integer. +#[derive(Copy, Drop, PartialEq)] +pub struct i256 { + /// The underlying unsigned 256-bit value. + pub value: u256, +} + + +pub impl U256IntoI256 of Into { + #[inline(always)] + fn into(self: u256) -> i256 { + i256 { value: self } + } +} + +pub impl I256IntoU256 of Into { + #[inline(always)] + fn into(self: i256) -> u256 { + self.value + } +} + +pub impl I256PartialOrd of PartialOrd { + #[inline(always)] + fn le(lhs: i256, rhs: i256) -> bool { + !(rhs < lhs) + } + + #[inline(always)] + fn ge(lhs: i256, rhs: i256) -> bool { + !(lhs < rhs) + } + + #[inline(always)] + fn lt(lhs: i256, rhs: i256) -> bool { + let lhs_positive = lhs.value.high < POW_2_127; + let rhs_positive = rhs.value.high < POW_2_127; + + if (lhs_positive != rhs_positive) { + !lhs_positive + } else { + lhs.value < rhs.value + } + } + + #[inline(always)] + fn gt(lhs: i256, rhs: i256) -> bool { + let lhs_positive = lhs.value.high < POW_2_127; + let rhs_positive = rhs.value.high < POW_2_127; + + if (lhs_positive != rhs_positive) { + lhs_positive + } else { + lhs.value > rhs.value + } + } +} + +pub impl I256Div of Div { + fn div(lhs: i256, rhs: i256) -> i256 { + let (q, _) = i256_signed_div_rem(lhs, rhs.value.try_into().expect('Division by 0')); + return q.into(); + } +} + +pub impl I256Rem of Rem { + fn rem(lhs: i256, rhs: i256) -> i256 { + let (_, r) = i256_signed_div_rem(lhs, rhs.value.try_into().expect('Division by 0')); + return r.into(); + } +} + +/// Performs signed integer division between two integers. +/// +/// This function conforms to EVM specifications, except that the type system enforces div != zero. +/// See ethereum yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf, page 29). +/// +/// Note: +/// - The remainder may be negative if one of the inputs is negative. +/// - (-2**255) / (-1) = -2**255 because 2**255 is out of range. +/// +/// # Arguments +/// +/// * `a` - The dividend. +/// * `div` - The divisor, passed as a signed NonZero. +/// +/// # Returns +/// +/// A tuple containing (quotient, remainder) of the signed division of `a` by `div`. +fn i256_signed_div_rem(a: i256, div: NonZero) -> (i256, i256) { + let mut div = i256 { value: div.into() }; + + // When div=-1, simply return -a. + if div.value == Bounded::::MAX { + return (i256_neg(a).into(), 0_u256.into()); + } + + // Take the absolute value of a and div. + // Checks the MSB bit sign for a 256-bit integer + let a_positive = a.value.high < POW_2_127; + let a = if a_positive { + a + } else { + i256_neg(a).into() + }; + + let div_positive = div.value.high < POW_2_127; + div = if div_positive { + div + } else { + i256_neg(div).into() + }; + + // Compute the quotient and remainder. + // Can't panic as zero case is handled in the first instruction + let (quot, rem) = DivRem::div_rem(a.value, div.value.try_into().unwrap()); + + // Restore remainder sign. + let rem = if a_positive { + rem.into() + } else { + i256_neg(rem.into()) + }; + + // If the signs of a and div are the same, return the quotient and remainder. + if a_positive == div_positive { + return (quot.into(), rem.into()); + } + + // Otherwise, return the negation of the quotient and the remainder. + (i256_neg(quot.into()), rem.into()) +} + +/// Computes the negation of an i256 integer. +/// +/// Note that the negation of -2**255 is -2**255. +/// +/// # Arguments +/// +/// * `a` - The i256 value to negate. +/// +/// # Returns +/// +/// The negation of the input value. +fn i256_neg(a: i256) -> i256 { + // If a is 0, adding one to its bitwise NOT will overflow and return 0. + if a.value == 0 { + return 0_u256.into(); + } + (~a.value + 1).into() +} + +#[cfg(test)] +mod tests { + use core::num::traits::Bounded; + use crate::i256::{i256, i256_neg, i256_signed_div_rem}; + + const MAX_SIGNED_VALUE: u256 = + 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; + const MIN_SIGNED_VALUE: u256 = + 0x8000000000000000000000000000000000000000000000000000000000000000; + + #[test] + fn test_i256_eq() { + let val: i256 = 1_u256.into(); + + assert(val == 1_u256.into(), 'i256 should be eq'); + } + + #[test] + fn test_i256_ne() { + let val: i256 = 1_u256.into(); + + assert(val != 2_u256.into(), 'i256 should be ne'); + } + + #[test] + fn test_i256_positive() { + let val: i256 = MAX_SIGNED_VALUE.into(); + + assert(val > 0_u256.into(), 'i256 should be positive'); + } + + #[test] + fn test_i256_negative() { + let val: i256 = Bounded::::MAX.into(); // -1 + + assert(val < 0_u256.into(), 'i256 should be negative'); + } + + #[test] + fn test_lt_positive_positive() { + let lhs: i256 = 1_u256.into(); + let rhs: i256 = 2_u256.into(); + + assert(lhs < rhs, 'lhs should be lt rhs'); + } + + #[test] + fn test_lt_negative_negative() { + let lhs: i256 = (Bounded::::MAX - 1).into(); // -2 + let rhs: i256 = Bounded::::MAX.into(); // -1 + + assert(lhs < rhs, 'lhs should be lt rhs'); + } + + #[test] + fn test_lt_negative_positive() { + let lhs: i256 = Bounded::::MAX.into(); // -1 + let rhs: i256 = 1_u256.into(); + + assert(lhs < rhs, 'lhs should be lt rhs'); + } + + #[test] + fn test_lt_positive_negative() { + let lhs: i256 = 1_u256.into(); + let rhs: i256 = Bounded::::MAX.into(); // -1 + + assert(!(lhs < rhs), 'lhs should not be lt rhs'); + } + + #[test] + fn test_lt_equals() { + let lhs: i256 = 1_u256.into(); + let rhs: i256 = 1_u256.into(); + + assert(!(lhs < rhs), 'lhs should not be lt rhs'); + } + + #[test] + fn test_le_positive_positive() { + let lhs: i256 = 1_u256.into(); + let rhs: i256 = 2_u256.into(); + + assert(lhs <= rhs, 'lhs should be le rhs'); + } + + #[test] + fn test_le_negative_negative() { + let lhs: i256 = (Bounded::::MAX - 1).into(); // -2 + let rhs: i256 = Bounded::::MAX.into(); // -1 + + assert(lhs <= rhs, 'lhs should be le rhs'); + } + + #[test] + fn test_le_negative_positive() { + let lhs: i256 = Bounded::::MAX.into(); // -1 + let rhs: i256 = 1_u256.into(); + + assert(lhs <= rhs, 'lhs should be le rhs'); + } + + #[test] + fn test_le_positive_negative() { + let lhs: i256 = 1_u256.into(); + let rhs: i256 = Bounded::::MAX.into(); // -1 + + assert(!(lhs <= rhs), 'lhs should not be le rhs'); + } + + #[test] + fn test_le_equals() { + let lhs: i256 = 1_u256.into(); + let rhs: i256 = 1_u256.into(); + + assert(lhs <= rhs, 'lhs should be le rhs'); + } + + #[test] + fn test_gt_positive_positive() { + let lhs: i256 = 2_u256.into(); + let rhs: i256 = 1_u256.into(); + + assert(lhs > rhs, 'lhs should be gt rhs'); + } + + #[test] + fn test_gt_negative_negative() { + let lhs: i256 = Bounded::::MAX.into(); // -1 + let rhs: i256 = (Bounded::::MAX - 1).into(); // -2 + + assert(lhs > rhs, 'lhs should be gt rhs'); + } + + #[test] + fn test_gt_negative_positive() { + let lhs: i256 = Bounded::::MAX.into(); // -1 + let rhs: i256 = 1_u256.into(); + + assert(!(lhs > rhs), 'lhs should not be gt rhs'); + } + + #[test] + fn test_gt_positive_negative() { + let lhs: i256 = 1_u256.into(); + let rhs: i256 = Bounded::::MAX.into(); // -1 + + assert(lhs > rhs, 'lhs should be gt rhs'); + } + + #[test] + fn test_gt_equals() { + let lhs: i256 = 1_u256.into(); + let rhs: i256 = 1_u256.into(); + + assert(!(lhs > rhs), 'lhs should not be gt rhs'); + } + + #[test] + fn test_ge_positive_positive() { + let lhs: i256 = 2_u256.into(); + let rhs: i256 = 1_u256.into(); + + assert(lhs >= rhs, 'lhs should be ge rhs'); + } + + #[test] + fn test_ge_negative_negative() { + let lhs: i256 = Bounded::::MAX.into(); // -1 + let rhs: i256 = (Bounded::::MAX - 1).into(); // -2 + + assert(lhs >= rhs, 'lhs should be ge rhs'); + } + + #[test] + fn test_ge_negative_positive() { + let lhs: i256 = Bounded::::MAX.into(); // -1 + let rhs: i256 = 1_u256.into(); + + assert(!(lhs >= rhs), 'lhs should not be ge rhs'); + } + + #[test] + fn test_ge_positive_negative() { + let lhs: i256 = 1_u256.into(); + let rhs: i256 = Bounded::::MAX.into(); // -1 + + assert(lhs >= rhs, 'lhs should be ge rhs'); + } + + #[test] + fn test_ge_equals() { + let lhs: i256 = 1_u256.into(); + let rhs: i256 = 1_u256.into(); + + assert(lhs >= rhs, 'lhs should be ge rhs'); + } + + #[test] + fn test_i256_neg() { + let max_u256 = Bounded::::MAX; + let x = i256_neg(1_u256.into()); + // 0000_0001 turns into 1111_1110 + 1 = 1111_1111 + assert(x.value.low == max_u256.low && x.value.high == max_u256.high, 'i256_neg failed.'); + + let x = i256_neg(0_u256.into()); + // 0000_0000 turns into 1111_1111 + 1 = 0000_0000 + assert(x == 0_u256.into(), 'i256_neg with zero failed.'); + + let x = max_u256; + // 1111_1111 turns into 0000_0000 + 1 = 0000_0001 + assert(i256_neg(x.into()) == 1_u256.into(), 'i256_neg with max_u256 failed.'); + } + + #[test] + fn test_signed_div_rem() { + let max_u256 = Bounded::::MAX; + let max_i256 = i256 { value: max_u256 }; + // Division by -1 + assert( + i256_signed_div_rem( + i256 { value: 1 }, max_u256.try_into().unwrap() + ) == (max_i256, 0_u256.into()), + 'Division by -1 failed - 1.' + ); // 1 / -1 == -1 + assert( + i256_signed_div_rem( + max_i256, max_u256.try_into().unwrap() + ) == (i256 { value: 1 }, 0_u256.into()), + 'Division by -1 failed - 2.' + ); // -1 / -1 == 1 + assert( + i256_signed_div_rem( + i256 { value: 0 }, max_u256.try_into().unwrap() + ) == (i256 { value: 0 }, 0_u256.into()), + 'Division by -1 failed - 3.' + ); // 0 / -1 == 0 + + // Simple Division + assert( + i256_signed_div_rem( + i256 { value: 10 }, 2_u256.try_into().unwrap() + ) == (i256 { value: 5 }, 0_u256.into()), + 'Simple Division failed - 1.' + ); // 10 / 2 == 5 + assert( + i256_signed_div_rem( + i256 { value: 10 }, 3_u256.try_into().unwrap() + ) == (i256 { value: 3 }, 1_u256.into()), + 'Simple Division failed - 2.' + ); // 10 / 3 == 3 remainder 1 + + // Dividing a Negative Number + assert( + i256_signed_div_rem(max_i256, 1_u256.try_into().unwrap()) == (max_i256, 0_u256.into()), + 'Dividing a neg num failed - 1.' + ); // -1 / 1 == -1 + assert( + i256_signed_div_rem( + i256 { value: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE }, + 0x2_u256.try_into().unwrap() + ) == (max_i256, 0_u256.into()), + 'Dividing a neg num failed - 2.' + ); // -2 / 2 == -1 + // - 2**255 / 2 == - 2**254 + assert( + i256_signed_div_rem( + i256 { value: 0x8000000000000000000000000000000000000000000000000000000000000000 }, + 0x2_u256.try_into().unwrap() + ) == ( + i256 { value: 0xc000000000000000000000000000000000000000000000000000000000000000 }, + 0_u256.into() + ), + 'Dividing a neg num failed - 3.' + ); + + // Dividing by a Negative Number + assert( + i256_signed_div_rem( + i256 { value: 0x4 }, + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE_u256 + .try_into() + .unwrap() + ) == ( + i256 { value: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE }, + 0_u256.into() + ), + 'Div by a neg num failed - 1.' + ); // 4 / -2 == -2 + assert( + i256_signed_div_rem( + i256 { value: MAX_SIGNED_VALUE }, + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_u256 + .try_into() + .unwrap() + ) == (i256 { value: (MIN_SIGNED_VALUE + 1) }, 0_u256.into()), + 'Div by a neg num failed - 2.' + ); // MAX_VALUE (2**255 -1) / -1 == MIN_VALUE + 1 + assert( + i256_signed_div_rem( + i256 { value: 0x1 }, + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_u256 + .try_into() + .unwrap() + ) == ( + i256 { value: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF }, + 0_u256.into() + ), + 'Div by a neg num failed - 3.' + ); // 1 / -1 == -1 + + // Both Dividend and Divisor Negative + assert( + i256_signed_div_rem( + i256 { value: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 }, + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB_u256 + .try_into() + .unwrap() + ) == (i256 { value: 2 }, 0_u256.into()), + 'Div w/ both neg num failed - 1.' + ); // -10 / -5 == 2 + assert( + i256_signed_div_rem( + i256 { value: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 }, + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5_u256 + .try_into() + .unwrap() + ) == ( + i256 { value: 0 }, + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6_u256.into() + ), + 'Div w/ both neg num failed - 2.' + ); // -10 / -11 == 0 remainder -10 + + // Division with Remainder + assert( + i256_signed_div_rem( + i256 { value: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 }, + 0x3_u256.try_into().unwrap() + ) == ( + i256 { value: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE }, + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_u256.into() + ), + 'Div with rem failed - 1.' + ); // -7 / 3 == -2 remainder -1 + assert( + i256_signed_div_rem( + i256 { value: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF }, + 0x2_u256.try_into().unwrap() + ) == ( + i256 { value: 0 }, + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_u256.into() + ), + 'Div with rem failed - 2.' + ); // -1 / 2 == 0 remainder -1 + + // Edge Case: Dividing Minimum Value by -1 + assert( + i256_signed_div_rem( + i256 { value: MIN_SIGNED_VALUE }, + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_u256 + .try_into() + .unwrap() + ) == (i256 { value: MIN_SIGNED_VALUE }, 0_u256.into()), + 'Div w/ both neg num failed - 3.' + ); // MIN / -1 == MIN because 2**255 is out of range + } + + #[test] + #[should_panic(expected: ('Option::unwrap failed.',))] + fn test_signed_div_rem_by_zero() { + // Zero Division + assert( + i256_signed_div_rem( + i256 { value: 0 }, 0_u256.try_into().unwrap() + ) == (i256 { value: 0 }, i256 { value: 0 }), + 'Zero Division failed - 1.' + ); + } +} diff --git a/kakarot-ssj/crates/utils/src/lib.cairo b/kakarot-ssj/crates/utils/src/lib.cairo new file mode 100644 index 000000000..05a2f2975 --- /dev/null +++ b/kakarot-ssj/crates/utils/src/lib.cairo @@ -0,0 +1,16 @@ +pub mod address; +pub mod constants; +pub mod crypto; +pub mod errors; +pub mod eth_transaction; +pub mod felt_vec; +pub mod fmt; +pub mod helpers; +pub mod i256; +pub mod math; +pub mod rlp; +pub mod serialization; +pub mod set; +pub mod test_data; +pub mod traits; +pub mod utils; diff --git a/kakarot-ssj/crates/utils/src/math.cairo b/kakarot-ssj/crates/utils/src/math.cairo new file mode 100644 index 000000000..6e77fdbc9 --- /dev/null +++ b/kakarot-ssj/crates/utils/src/math.cairo @@ -0,0 +1,724 @@ +use core::integer::{u512}; +use core::num::traits::{Zero, One, BitSize, OverflowingAdd, OverflowingMul}; +use core::panic_with_felt252; +use core::traits::{BitAnd}; + +// === Exponentiation === + +pub trait Exponentiation { + /// Raise a number to a power. + /// + /// # Arguments + /// + /// * `self` - The base number + /// * `exponent` - The exponent to raise the base to + /// + /// # Returns + /// + /// The result of raising `self` to the power of `exponent` + /// + /// # Panics + /// + /// Panics if the result overflows the type T. + fn pow(self: T, exponent: T) -> T; +} + +impl ExponentiationImpl< + T, + +Zero, + +One, + +Add, + +Sub, + +Mul, + +Div, + +BitAnd, + +PartialEq, + +Copy, + +Drop +> of Exponentiation { + fn pow(self: T, mut exponent: T) -> T { + let zero = Zero::zero(); + if self.is_zero() { + return zero; + } + let one = One::one(); + let mut result = one; + let mut base = self; + let two = one + one; + + loop { + if exponent & one == one { + result = result * base; + } + + exponent = exponent / two; + if exponent == zero { + break result; + } + + base = base * base; + } + } +} + +pub trait WrappingExponentiation { + /// Raise a number to a power modulo MAX (max value of type T). + /// Instead of explicitly providing a modulo, we use overflowing functions + /// from the core library, which wrap around when overflowing. + /// + /// # Arguments + /// + /// * `self` - The base number + /// * `exponent` - The exponent to raise the base to + /// + /// # Returns + /// + /// The result of base raised to the power of exp modulo MAX. + fn wrapping_pow(self: T, exponent: T) -> T; + + /// Performs exponentiation by repeatedly multiplying the base number with itself. + /// + /// This function uses a simple loop to perform exponentiation. It continues to multiply + /// the base number (`self`) with itself, for the number of times specified by `exponent`. + /// The method uses a wrapping strategy to handle overflow, which means if the result + /// overflows the type `T`, then higher bits are discarded and the result is wrapped. + /// + /// # Arguments + /// + /// * `self` - The base number of type `T`. + /// * `exponent` - The exponent to which the base number is raised, also of type `T`. + /// + /// # Returns + /// + /// The result of raising `self` to the power of `exponent`, of type `T`. + /// The result is wrapped in case of overflow. + fn wrapping_spow(self: T, exponent: T) -> T; + + /// Performs exponentiation using the binary exponentiation method. + /// + /// This function calculates the power of a number using binary exponentiation, which is + /// an optimized method for exponentiation that reduces the number of multiplications. + /// It works by repeatedly squaring the base and reducing the exponent by half, using + /// a wrapping strategy to handle overflow. This means if intermediate or final results + /// overflow the type `T`, then the higher bits are discarded and the result is wrapped. + /// + /// # Arguments + /// + /// * `self` - The base number of type `T`. + /// * `exponent` - The exponent to which the base number is raised, also of type `T`. + /// + /// # Returns + /// + /// The result of raising `self` to the power of `exponent`, of type `T`. + /// The result is wrapped in case of overflow. + fn wrapping_fpow(self: T, exponent: T) -> T; +} + + +pub impl WrappingExponentiationImpl< + T, + +OverflowingMul, + +Zero, + +One, + +Add, + +Mul, + +Div, + +Rem, + +Copy, + +Drop, + +PartialEq, + +PartialOrd, + +core::ops::SubAssign +> of WrappingExponentiation { + fn wrapping_pow(self: T, exponent: T) -> T { + if exponent == Zero::zero() { + return One::one(); + } + + if self == Zero::zero() { + return Zero::zero(); + } + + let one = One::::one(); + let ten = one + one + one + one + one + one + one + one + one + one; + + if exponent > ten { + self.wrapping_fpow(exponent) + } else { + self.wrapping_spow(exponent) + } + } + + fn wrapping_spow(self: T, exponent: T) -> T { + let mut exponent = exponent; + let mut base = self; + let mut result = One::one(); + + while exponent != Zero::zero() { + let (new_result, _) = result.overflowing_mul(base); + result = new_result; + exponent -= One::one(); + }; + result + } + + fn wrapping_fpow(self: T, exponent: T) -> T { + let mut result = One::one(); + let mut base = self; + let mut exponent = exponent; + let two = One::::one() + One::::one(); + + loop { + if exponent % two != Zero::zero() { + let (new_result, _) = result.overflowing_mul(base); + result = new_result; + } + + exponent = exponent / two; + if exponent == Zero::zero() { + break result; + } + + let (new_base, _) = base.overflowing_mul(base); + base = new_base; + } + } +} + +// === BitShift === + +pub trait Bitshift { + /// Shift a number left by a given number of bits. + /// + /// # Arguments + /// + /// * `self` - The number to shift + /// * `shift` - The number of bits to shift by + /// + /// # Returns + /// + /// The result of shifting `self` left by `shift` bits + /// + /// # Panics + /// + /// Panics if the shift is greater than 255. + /// Panics if the result overflows the type T. + fn shl(self: T, shift: T) -> T; + + /// Shift a number right by a given number of bits. + /// + /// # Arguments + /// + /// * `self` - The number to shift + /// * `shift` - The number of bits to shift by + /// + /// # Returns + /// + /// The result of shifting `self` right by `shift` bits + /// + /// # Panics + /// + /// Panics if the shift is greater than 255. + fn shr(self: T, shift: T) -> T; +} + +impl BitshiftImpl< + T, + +Zero, + +One, + +Add, + +Sub, + +Div, + +Mul, + +Exponentiation, + +Copy, + +Drop, + +PartialOrd, + +BitSize, + +TryInto, +> of Bitshift { + fn shl(self: T, shift: T) -> T { + // if we shift by more than nb_bits of T, the result is 0 + // we early return to save gas and prevent unexpected behavior + if shift > BitSize::::bits().try_into().unwrap() - One::one() { + panic_with_felt252('mul Overflow'); + } + let two = One::one() + One::one(); + self * two.pow(shift) + } + + fn shr(self: T, shift: T) -> T { + // early return to save gas if shift > nb_bits of T + if shift > BitSize::::bits().try_into().unwrap() - One::one() { + panic_with_felt252('mul Overflow'); + } + let two = One::one() + One::one(); + self / two.pow(shift) + } +} + +pub trait WrappingBitshift { + /// Shift a number left by a given number of bits. + /// If the shift is greater than 255, the result is 0. + /// The bits moved after the 256th one are discarded, the new bits are set to 0. + /// + /// # Arguments + /// + /// * `self` - The number to shift + /// * `shift` - The number of bits to shift by + /// + /// # Returns + /// + /// The result of shifting `self` left by `shift` bits, wrapped if necessary + fn wrapping_shl(self: T, shift: T) -> T; + + /// Shift a number right by a given number of bits. + /// If the shift is greater than 255, the result is 0. + /// + /// # Arguments + /// + /// * `self` - The number to shift + /// * `shift` - The number of bits to shift by + /// + /// # Returns + /// + /// The result of shifting `self` right by `shift` bits, or 0 if shift > 255 + fn wrapping_shr(self: T, shift: T) -> T; +} + +pub impl WrappingBitshiftImpl< + T, + +Zero, + +One, + +Add, + +Sub, + +Div, + +Exponentiation, + +PartialOrd, + +Drop, + +Copy, + +OverflowingMul, + +WrappingExponentiation, + +BitSize, + +TryInto, +> of WrappingBitshift { + fn wrapping_shl(self: T, shift: T) -> T { + let two = One::::one() + One::::one(); + let (result, _) = self.overflowing_mul(two.wrapping_pow(shift)); + result + } + + fn wrapping_shr(self: T, shift: T) -> T { + let two = One::::one() + One::::one(); + + if shift > BitSize::::bits().try_into().unwrap() - One::one() { + return Zero::zero(); + } + self / two.pow(shift) + } +} + +// === Standalone functions === + +/// Adds two 256-bit unsigned integers, returning a 512-bit unsigned integer result. +/// +/// limb3 will always be 0, because the maximum sum of two 256-bit numbers is at most +/// 2**257 - 2 which fits in 257 bits. +/// +/// # Arguments +/// +/// * `a` - First 256-bit unsigned integer +/// * `b` - Second 256-bit unsigned integer +/// +/// # Returns +/// +/// A 512-bit unsigned integer representing the sum of `a` and `b` +pub fn u256_wide_add(a: u256, b: u256) -> u512 { + let (sum, overflow) = a.overflowing_add(b); + + let limb0 = sum.low; + let limb1 = sum.high; + + let limb2 = if overflow { + 1 + } else { + 0 + }; + + let limb3 = 0; + + u512 { limb0, limb1, limb2, limb3 } +} + +#[cfg(test)] +mod tests { + use core::integer::{u512}; + use core::num::traits::{OverflowingMul, WrappingMul, SaturatingAdd, Bounded}; + use crate::math::{ + Exponentiation, WrappingExponentiation, u256_wide_add, Bitshift, WrappingBitshift, + }; + use super::OverflowingAdd; + + #[test] + fn test_wrapping_pow() { + assert(5_u256.wrapping_pow(10) == 9765625, '5^10 should be 9765625'); + assert( + 5_u256 + .wrapping_pow( + 90 + ) == 807793566946316088741610050849573099185363389551639556884765625, + '5^90 failed' + ); + assert(2_u256.wrapping_pow(256) == 0, 'should wrap to 0'); + assert(123456_u256.wrapping_pow(0) == 1, 'n^0 should be 1'); + assert(0_u256.wrapping_pow(123456) == 0, '0^n should be 0'); + } + + #[test] + fn test_pow() { + assert(5_u256.pow(10) == 9765625, '5^10 should be 9765625'); + assert(5_u256.pow(45) == 28421709430404007434844970703125, '5^45 failed'); + assert(123456_u256.pow(0) == 1, 'n^0 should be 1'); + assert(0_u256.pow(123456) == 0, '0^n should be 0'); + } + + #[test] + fn test_wrapping_fast_pow() { + let exp = 3_u256.wrapping_fpow(10); + assert( + 3_u256 + .wrapping_fpow( + exp + ) == 6701808933569337837891967767170127839253608180143676463326689955522159283811, + '3^(3^10) failed' + ); + } + + #[test] + fn test_wrapping_fast_pow_0() { + assert(3_u256.wrapping_fpow(0) == 1, '3^(0) should be 1'); + } + + #[test] + fn test_wrapping_fast_base_0() { + assert(0_u256.wrapping_fpow(42) == 0, '0^(42) should be 0'); + } + + #[test] + fn test_wrapping_fast_base_0_pow_0() { + assert(0_u256.wrapping_fpow(0) == 1, '0^(0) should be 1'); + } + + #[test] + #[should_panic(expected: ('u256_mul Overflow',))] + fn test_pow_should_overflow() { + 2_u256.pow(256); + } + + + #[test] + fn test_wide_add_basic() { + let a = 1000; + let b = 500; + + let (_, overflow) = a.overflowing_add(b); + + let expected = u512 { limb0: 1500, limb1: 0, limb2: 0, limb3: 0, }; + + let result = u256_wide_add(a, b); + + assert(!overflow, 'shouldnt overflow'); + assert(result == expected, 'wrong result'); + } + + #[test] + fn test_wide_add_overflow() { + let a = Bounded::::MAX; + let b = 1; + + let (_, overflow) = a.overflowing_add(b); + + let expected = u512 { limb0: 0, limb1: 0, limb2: 1, limb3: 0, }; + + let result = u256_wide_add(a, b); + + assert(overflow, 'should overflow'); + assert(result == expected, 'wrong result'); + } + + #[test] + fn test_wide_add_max_values() { + let a = Bounded::::MAX; + let b = Bounded::::MAX; + + let expected = u512 { + limb0: 0xfffffffffffffffffffffffffffffffe, + limb1: 0xffffffffffffffffffffffffffffffff, + limb2: 1, + limb3: 0, + }; + + let result = u256_wide_add(a, b); + + assert(result == expected, 'wrong result'); + } + + #[test] + fn test_shl() { + // Given + let a = 0x00000091b2efa2bfd58aee61f24201bac4e64f70ca2b9d9491e82a498f2aab3f_u256; + // 1-byte shift is an 8-bit shift + let shift = 3 * 8; + + // When + let result = a.shl(shift); + + // Then + let expected = 0x91b2efa2bfd58aee61f24201bac4e64f70ca2b9d9491e82a498f2aab3f000000_u256; + assert(result == expected, 'wrong result'); + } + + + #[test] + #[should_panic(expected: ('mul Overflow',))] + fn test_shl_256_bits_overflow() { + // Given + let a = 0x00000091b2efa2bfd58aee61f24201bac4e64f70ca2b9d9491e82a498faab3fe_u256; + // 1-byte shift is an 8-bit shift + let shift = 32 * 8; + + // When & Then 2.pow(256) overflows u256 + a.shl(shift); + } + + #[test] + #[should_panic(expected: ('u256_mul Overflow',))] + fn test_shl_overflow() { + // Given + let a = 0x00000091b2efa2bfd58aee61f24201bac4e64f70ca2b9d9491e82a498faab3fe_u256; + // 1-byte shift is an 8-bit shift + let shift = 4 * 8; + + // When & Then a << 32 overflows u256 + a.shl(shift); + } + + #[test] + fn test_wrapping_shl_overflow() { + // Given + let a = 0x00000091b2efa2bfd58aee61f24201bac4e64f70ca2b9d9491e82a498faab3fe_u256; + // 1-byte shift is an 8-bit shift + let shift = 12 * 8; + + // When + let result = a.wrapping_shl(shift); + + // Then + // The bits moved after the 256th one are discarded, the new bits are set to 0. + let expected = 0xf24201bac4e64f70ca2b9d9491e82a498faab3fe000000000000000000000000_u256; + assert(result == expected, 'wrong result'); + } + + + #[test] + fn test_wrapping_shl() { + // Given + let a = 0x00000091b2efa2bfd58aee61f24201bac4e64f70ca2b9d9491e82a498f2aab3f_u256; + // 1-byte shift is an 8-bit shift + let shift = 3 * 8; + + // When + let result = a.wrapping_shl(shift); + + // Then + let expected = 0x91b2efa2bfd58aee61f24201bac4e64f70ca2b9d9491e82a498f2aab3f000000_u256; + assert(result == expected, 'wrong result'); + } + + #[test] + fn test_shr() { + // Given + let a = 0x0091b2efa2bfd58aee61f24201bac4e64f70ca2b9d9491e82a498f2aade6263a_u256; + // 1-byte shift is an 8-bit shift + let shift = 1 * 8; + + // When + let result = a.shr(shift); + + // Then + let expected = 0x000091b2efa2bfd58aee61f24201bac4e64f70ca2b9d9491e82a498f2aade626_u256; + assert(result == expected, 'wrong result'); + } + + #[test] + #[should_panic(expected: ('mul Overflow',))] + fn test_shr_256_bits_overflow() { + let a = 0xab91b2efa2bfd58aee61f24201bac4e64f70ca2b9d9491e82a498f2aade6263a_u256; + let shift = 32 * 8; + + // When & Then 2.pow(256) overflows u256 + a.shr(shift); + } + + + #[test] + fn test_wrapping_shr() { + // Given + let a = 0x0091b2efa2bfd58aee61f24201bac4e64f70ca2b9d9491e82a498f2aade6263a_u256; + // 1-byte shift is an 8-bit shift + let shift = 2 * 8; + + // When + let result = a.wrapping_shr(shift); + + // Then + let expected = 0x00000091b2efa2bfd58aee61f24201bac4e64f70ca2b9d9491e82a498f2aade6_u256; + assert(result == expected, 'wrong result'); + } + + + #[test] + fn test_wrapping_shr_to_zero() { + // Given + let a = 0xab91b2efa2bfd58aee61f24201bac4e64f70ca2b9d9491e82a498f2aade6263a_u256; + // 1-byte shift is an 8-bit shift + let shift = 32 * 8; + + // When + let result = a.wrapping_shr(shift); + + // Then + let expected = 0_u256; + assert(result == expected, 'wrong result'); + } + + #[test] + fn test_u8_overflowing_mul_not_overflow_case() { + let result = 5_u8.overflowing_mul(10); + assert_eq!(result, (50, false)); + } + + #[test] + fn test_u8_overflowing_mul_overflow_case() { + let result = Bounded::::MAX.overflowing_mul(Bounded::MAX); + assert_eq!(result, (1, true)); + } + + #[test] + fn test_u8_wrapping_mul_not_overflow_case() { + let result = 5_u8.wrapping_mul(10); + assert_eq!(result, 50); + } + + #[test] + fn test_u8_wrapping_mul_overflow_case() { + let result = Bounded::::MAX.wrapping_mul(Bounded::MAX); + assert_eq!(result, 1); + } + + #[test] + fn test_u32_overflowing_mul_not_overflow_case() { + let result = 5_u32.overflowing_mul(10); + assert_eq!(result, (50, false)); + } + + #[test] + fn test_u32_overflowing_mul_overflow_case() { + let result = Bounded::::MAX.overflowing_mul(Bounded::MAX); + assert_eq!(result, (1, true)); + } + + #[test] + fn test_u32_wrapping_mul_not_overflow_case() { + let result = 5_u32.wrapping_mul(10); + assert_eq!(result, 50); + } + + #[test] + fn test_u32_wrapping_mul_overflow_case() { + let result = Bounded::::MAX.wrapping_mul(Bounded::MAX); + assert_eq!(result, 1); + } + + + #[test] + fn test_u64_overflowing_mul_not_overflow_case() { + let result = 5_u64.overflowing_mul(10); + assert_eq!(result, (50, false)); + } + + #[test] + fn test_u64_overflowing_mul_overflow_case() { + let result = Bounded::::MAX.overflowing_mul(Bounded::MAX); + assert_eq!(result, (1, true)); + } + + #[test] + fn test_u64_wrapping_mul_not_overflow_case() { + let result = 5_u64.wrapping_mul(10); + assert_eq!(result, 50); + } + + #[test] + fn test_u64_wrapping_mul_overflow_case() { + let result = Bounded::::MAX.wrapping_mul(Bounded::MAX); + assert_eq!(result, 1); + } + + + #[test] + fn test_u128_overflowing_mul_not_overflow_case() { + let result = 5_u128.overflowing_mul(10); + assert_eq!(result, (50, false)); + } + + #[test] + fn test_u128_overflowing_mul_overflow_case() { + let result = Bounded::::MAX.overflowing_mul(Bounded::MAX); + assert_eq!(result, (1, true)); + } + + #[test] + fn test_u128_wrapping_mul_not_overflow_case() { + let result = 5_u128.wrapping_mul(10); + assert_eq!(result, 50); + } + + #[test] + fn test_u128_wrapping_mul_overflow_case() { + let result = Bounded::::MAX.wrapping_mul(Bounded::MAX); + assert_eq!(result, 1); + } + + #[test] + fn test_u256_overflowing_mul_not_overflow_case() { + let result = 5_u256.overflowing_mul(10); + assert_eq!(result, (50, false)); + } + + #[test] + fn test_u256_overflowing_mul_overflow_case() { + let result = Bounded::::MAX.overflowing_mul(Bounded::MAX); + assert_eq!(result, (1, true)); + } + + #[test] + fn test_u256_wrapping_mul_not_overflow_case() { + let result = 5_u256.wrapping_mul(10); + assert_eq!(result, 50); + } + + #[test] + fn test_u256_wrapping_mul_overflow_case() { + let result = Bounded::::MAX.wrapping_mul(Bounded::MAX); + assert_eq!(result, 1); + } + + #[test] + fn test_saturating_add() { + let max = Bounded::::MAX; + + assert_eq!(max.saturating_add(1), Bounded::::MAX); + assert_eq!((max - 2).saturating_add(1), max - 1); + } +} diff --git a/kakarot-ssj/crates/utils/src/rlp.cairo b/kakarot-ssj/crates/utils/src/rlp.cairo new file mode 100644 index 000000000..9c991671e --- /dev/null +++ b/kakarot-ssj/crates/utils/src/rlp.cairo @@ -0,0 +1,2766 @@ +use core::array::ArrayTrait; +use core::array::SpanTrait; +use core::option::OptionTrait; +use core::panic_with_felt252; +use core::starknet::EthAddress; +use crate::errors::{RLPError}; +use crate::eth_transaction::eip2930::AccessListItem; +use crate::traits::array::ArrayExtension; +use crate::traits::bytes::{ToBytes, FromBytes}; +use crate::traits::eth_address::EthAddressExTrait; + +// Possible RLP types +#[derive(Drop, PartialEq, Debug)] +pub enum RLPType { + String, + List +} + +#[derive(Drop, Copy, PartialEq, Debug)] +pub enum RLPItem { + String: Span, + List: Span +} + +#[generate_trait] +pub impl RLPImpl of RLPTrait { + /// Returns RLPType from the leading byte with + /// its offset in the array as well as its size. + /// + /// # Arguments + /// * `input` - Span of bytes to decode + /// + /// # Returns + /// * `Result<(RLPType, u32, u32), RLPError>` - A tuple containing the RLPType, + /// the offset, and the size of the RLPItem to decode + /// + /// # Errors + /// * `RLPError::EmptyInput` - if the input is empty + /// * `RLPError::InputTooShort` - if the input is too short for a given type + /// * `RLPError::InvalidInput` - if the input is invalid + fn decode_type(input: Span) -> Result<(RLPType, u32, u32), RLPError> { + let input_len = input.len(); + if input_len == 0 { + return Result::Err(RLPError::EmptyInput); + } + + let prefix = *input[0]; + + if prefix < 0x80 { // Char + Result::Ok((RLPType::String, 0, 1)) + } else if prefix < 0xb8 { // Short String + Result::Ok((RLPType::String, 1, prefix.into() - 0x80)) + } else if prefix < 0xc0 { // Long String + let len_bytes_count: u32 = (prefix - 0xb7).into(); + if input_len <= len_bytes_count { + return Result::Err(RLPError::InputTooShort); + } + let string_len_bytes = input.slice(1, len_bytes_count); + let string_len: u32 = string_len_bytes + .from_be_bytes_partial() + .expect('rlp_decode_type_string_len'); + if input_len <= len_bytes_count + string_len { + return Result::Err(RLPError::InputTooShort); + } + + Result::Ok((RLPType::String, 1 + len_bytes_count, string_len)) + } else if prefix < 0xf8 { // Short List + let list_len: u32 = prefix.into() - 0xc0; + if input_len <= list_len { + return Result::Err(RLPError::InputTooShort); + } + Result::Ok((RLPType::List, 1, list_len)) + } else if prefix <= 0xff { // Long List + let len_bytes_count = prefix.into() - 0xf7; + if input.len() <= len_bytes_count { + return Result::Err(RLPError::InputTooShort); + } + let list_len_bytes = input.slice(1, len_bytes_count); + let list_len: u32 = list_len_bytes + .from_be_bytes_partial() + .expect('rlp_decode_type_list_len'); + if input_len <= len_bytes_count + list_len { + return Result::Err(RLPError::InputTooShort); + } + Result::Ok((RLPType::List, 1 + len_bytes_count, list_len)) + } else { + Result::Err(RLPError::InvalidInput) + } + } + + /// RLP encodes a sequence of RLPItems + /// + /// # Arguments + /// * `input` - Span of RLPItems to encode + /// + /// # Returns + /// * `Span` - RLP encoded byte array + /// + /// # Panics + /// * If encoding a long sequence (should not happen in current implementation) + fn encode_sequence(mut input: Span) -> Span { + let mut joined_encodings: Array = Default::default(); + for item in input { + match item { + RLPItem::String(string) => { + joined_encodings.append_span(Self::encode_string(*string)); + }, + RLPItem::List(_) => { panic_with_felt252('List encoding unimplemented') } + } + }; + let len_joined_encodings = joined_encodings.len(); + if len_joined_encodings < 0x38 { + let mut result: Array = array![0xC0 + len_joined_encodings.try_into().unwrap()]; + result.append_span(joined_encodings.span()); + return result.span(); + } else { + // Actual implementation of long list encoding is commented out + // as we should never reach this point in the current implementation + // let bytes_count_len_joined_encodings = len_joined_encodings.bytes_used(); + // let len_joined_encodings: Span = len_joined_encodings.to_bytes(); + // let mut result = array![0xF7 + bytes_count_len_joined_encodings]; + // result.append_span(len_joined_encodings); + // result.append_span(joined_encodings.span()); + // return result.span(); + return panic_with_felt252('Shouldnt encode long sequence'); + } + } + + /// RLP encodes a Span, which is the underlying type used to represent + /// string data in Cairo. + /// + /// # Arguments + /// * `input` - Span to encode + /// + /// # Returns + /// * `Span` - RLP encoded byte array + fn encode_string(input: Span) -> Span { + let len = input.len(); + if len == 0 { + return [0x80].span(); + } else if len == 1 && *input[0] < 0x80 { + return input; + } else if len < 56 { + let mut encoding: Array = Default::default(); + encoding.append(0x80 + len.try_into().unwrap()); + encoding.append_span(input); + return encoding.span(); + } else { + let mut encoding: Array = Default::default(); + let len_as_bytes = len.to_be_bytes(); + let len_bytes_count = len_as_bytes.len(); + let prefix = 0xb7 + len_bytes_count.try_into().unwrap(); + encoding.append(prefix); + encoding.append_span(len_as_bytes); + encoding.append_span(input); + return encoding.span(); + } + } + + /// RLP decodes a rlp encoded byte array + /// as described in https://ethereum.org/en/developers/docs/data-structures-and-encoding/rlp/ + /// + /// # Arguments + /// * `input` - Span of bytes to decode + /// + /// # Returns + /// * `Result, RLPError>` - Span of RLPItems + /// + /// # Errors + /// * `RLPError::InputTooShort` - if the input is too short for a given type + fn decode(input: Span) -> Result, RLPError> { + let mut output: Array = Default::default(); + let input_len = input.len(); + + let (rlp_type, offset, len) = Self::decode_type(input)?; + + if input_len < offset + len { + return Result::Err(RLPError::InputTooShort); + } + + match rlp_type { + RLPType::String => { + if (len == 0) { + output.append(RLPItem::String([].span())); + } else { + output.append(RLPItem::String(input.slice(offset, len))); + } + }, + RLPType::List => { + if len == 0 { + output.append(RLPItem::List([].span())); + } else { + let res = Self::decode(input.slice(offset, len))?; + output.append(RLPItem::List(res)); + } + } + }; + + let total_item_len = len + offset; + if total_item_len < input_len { + output + .append_span( + Self::decode(input.slice(total_item_len, input_len - total_item_len))? + ); + } + + Result::Ok(output.span()) + } +} + +#[generate_trait] +pub impl RLPHelpersImpl of RLPHelpersTrait { + /// Parses a u64 from an RLPItem::String + /// + /// # Returns + /// * `Result` - The parsed u64 value + /// + /// # Errors + /// * `RLPError::NotAString` - if the RLPItem is not a String + fn parse_u64_from_string(self: RLPItem) -> Result { + match self { + RLPItem::String(bytes) => { + // Empty strings means 0 + if bytes.len() == 0 { + return Result::Ok(0); + } + let value = bytes.from_be_bytes_partial().expect('parse_u64_from_string'); + Result::Ok(value) + }, + RLPItem::List(_) => { Result::Err(RLPError::NotAString) } + } + } + + /// Parses a u128 from an RLPItem::String + /// + /// # Returns + /// * `Result` - The parsed u128 value + /// + /// # Errors + /// * `RLPError::NotAString` - if the RLPItem is not a String + fn parse_u128_from_string(self: RLPItem) -> Result { + match self { + RLPItem::String(bytes) => { + // Empty strings means 0 + if bytes.len() == 0 { + return Result::Ok(0); + } + let value = bytes.from_be_bytes_partial().expect('parse_u128_from_string'); + Result::Ok(value) + }, + RLPItem::List(_) => { Result::Err(RLPError::NotAString) } + } + } + + /// Tries to parse an EthAddress from an RLPItem::String + /// + /// # Returns + /// * `Result, RLPError>` - The parsed EthAddress, if present + /// + /// # Errors + /// * `RLPError::NotAString` - if the RLPItem is not a String + /// * `RLPError::FailedParsingAddress` - if the address parsing fails + fn try_parse_address_from_string(self: RLPItem) -> Result, RLPError> { + match self { + RLPItem::String(bytes) => { + if bytes.len() == 0 { + return Result::Ok(Option::None); + } + if bytes.len() == 20 { + let maybe_value = EthAddressExTrait::from_bytes(bytes); + return Result::Ok(maybe_value); + } + return Result::Err(RLPError::FailedParsingAddress); + }, + RLPItem::List(_) => { Result::Err(RLPError::NotAString) } + } + } + + /// Parses a u256 from an RLPItem::String + /// + /// # Returns + /// * `Result` - The parsed u256 value + /// + /// # Errors + /// * `RLPError::NotAString` - if the RLPItem is not a String + fn parse_u256_from_string(self: RLPItem) -> Result { + match self { + RLPItem::String(bytes) => { + // Empty strings means 0 + if bytes.len() == 0 { + return Result::Ok(0); + } + let value = bytes.from_be_bytes_partial().expect('parse_u256_from_string'); + Result::Ok(value) + }, + RLPItem::List(_) => { Result::Err(RLPError::NotAString) } + } + } + + /// Parses bytes from an RLPItem::String + /// + /// # Returns + /// * `Result, RLPError>` - The parsed bytes + /// + /// # Errors + /// * `RLPError::NotAString` - if the RLPItem is not a String + fn parse_bytes_from_string(self: RLPItem) -> Result, RLPError> { + match self { + RLPItem::String(bytes) => { Result::Ok(bytes) }, + RLPItem::List(_) => { Result::Err(RLPError::NotAString) } + } + } + + /// Parses storage keys from an RLPItem + /// + /// # Returns + /// * `Result, RLPError>` - The parsed storage keys + /// + /// # Errors + /// * `RLPError::NotAList` - if the RLPItem is not a List + /// * `RLPError::FailedParsingAddress` - if parsing a storage key fails + fn parse_storage_keys_from_rlp_item(self: RLPItem) -> Result, RLPError> { + match self { + RLPItem::String(_) => { return Result::Err(RLPError::NotAList); }, + RLPItem::List(mut keys) => { + let mut storage_keys: Array = array![]; + let storage_keys: Result, RLPError> = loop { + match keys.pop_front() { + Option::Some(rlp_item) => { + let storage_key = match ((*rlp_item).parse_u256_from_string()) { + Result::Ok(storage_key) => { storage_key }, + Result::Err(err) => { break Result::Err(err); } + }; + + storage_keys.append(storage_key); + }, + Option::None => { break Result::Ok(storage_keys.span()); } + } + }; + + storage_keys + } + } + } + + /// Parses an access list from an RLPItem + /// + /// # Returns + /// * `Result, RLPError>` - The parsed access list + /// + /// # Errors + /// * `RLPError::NotAList` - if the RLPItem is not a List + /// * `RLPError::InputTooShort` - if the input is too short + /// * `RLPError::FailedParsingAccessList` - if parsing the access list fails + fn parse_access_list(self: RLPItem) -> Result, RLPError> { + let mut list_of_accessed_tuples: Span = match self { + RLPItem::String(_) => { return Result::Err(RLPError::NotAList); }, + RLPItem::List(list) => list + }; + + let mut parsed_access_list = array![]; + + // Iterate over the List of [Tuples (RLPString, RLPList)] representing all access list + // entries + let result = loop { + // Get the front Tuple (RLPString, RLPList) + let mut inner_tuple = match list_of_accessed_tuples.pop_front() { + Option::None => { break Result::Ok(parsed_access_list.span()); }, + Option::Some(inner_tuple) => match inner_tuple { + RLPItem::String(_) => { break Result::Err(RLPError::NotAList); }, + RLPItem::List(accessed_tuples) => *accessed_tuples + } + }; + + match inner_tuple.multi_pop_front::<2>() { + Option::None => { break Result::Err(RLPError::InputTooShort); }, + Option::Some(inner_tuple) => { + let [rlp_address, rlp_keys] = (*inner_tuple).unbox(); + let ethereum_address = match rlp_address.try_parse_address_from_string() { + Result::Ok(maybe_eth_address) => { + match (maybe_eth_address) { + Option::Some(eth_address) => { eth_address }, + Option::None => { + break Result::Err(RLPError::FailedParsingAccessList); + } + } + }, + Result::Err(err) => { break Result::Err(err); } + }; + + let storage_keys: Span = + match rlp_keys.parse_storage_keys_from_rlp_item() { + Result::Ok(storage_keys) => storage_keys, + Result::Err(err) => { break Result::Err(err); } + }; + parsed_access_list.append(AccessListItem { ethereum_address, storage_keys }); + } + } + }; + result + } +} +#[cfg(test)] +mod tests { + use core::array::SpanTrait; + use core::option::OptionTrait; + + use core::result::ResultTrait; + use crate::errors::RLPError; + use crate::eth_transaction::eip2930::AccessListItem; + use crate::rlp::{RLPType, RLPTrait, RLPItem, RLPHelpersTrait}; + + // Tests source : + // https://github.com/HerodotusDev/cairo-lib/blob/main/src/encoding/tests/test_rlp.cairo + // https://github.com/ethereum/tests/blob/develop/RLPTests/rlptest.json + + #[test] + fn test_rlp_decode_type_byte() { + let mut arr = array![0x78]; + + let (rlp_type, offset, size) = RLPTrait::decode_type(arr.span()).unwrap(); + + assert(rlp_type == RLPType::String, 'Wrong type'); + assert_eq!(offset, 0); + assert_eq!(size, 1); + } + + #[test] + fn test_rlp_decode_type_short_string() { + let mut arr = array![0x82]; + + let (rlp_type, offset, size) = RLPTrait::decode_type(arr.span()).unwrap(); + + assert(rlp_type == RLPType::String, 'Wrong type'); + assert_eq!(offset, 1); + assert_eq!(size, 2); + } + + #[test] + fn test_rlp_decode_type_long_string() { + let mut arr = array![0xb8, 0x01, 0x02]; + + let (rlp_type, offset, size) = RLPTrait::decode_type(arr.span()).unwrap(); + + assert(rlp_type == RLPType::String, 'Wrong type'); + assert_eq!(offset, 2); + assert_eq!(size, 1); + } + + #[test] + fn test_rlp_decode_type_short_list() { + let mut arr = array![0xc3, 0x01, 0x02, 0x03]; + + let (rlp_type, offset, size) = RLPTrait::decode_type(arr.span()).unwrap(); + + assert(rlp_type == RLPType::List, 'Wrong type'); + assert_eq!(offset, 1); + assert_eq!(size, 3); + } + + #[test] + fn test_rlp_decode_type_long_list() { + let mut arr = array![0xf8, 0x01, 0x00]; + + let (rlp_type, offset, size) = RLPTrait::decode_type(arr.span()).unwrap(); + + assert(rlp_type == RLPType::List, 'Wrong type'); + assert_eq!(offset, 2); + assert_eq!(size, 1); + } + + #[test] + fn test_rlp_decode_type_long_list_len_too_short() { + let mut arr = array![0xf9, 0x01]; + + let res = RLPTrait::decode_type(arr.span()); + + assert(res.is_err(), 'Wrong type'); + assert!(res.unwrap_err() == RLPError::InputTooShort); + } + + #[test] + fn test_rlp_empty() { + let res = RLPTrait::decode(ArrayTrait::new().span()); + + assert(res.is_err(), 'should return an error'); + assert(res.unwrap_err() == RLPError::EmptyInput, 'err != EmptyInput'); + } + + + #[test] + fn test_rlp_encode_string_single_byte_lt_0x80() { + let mut input: Array = Default::default(); + input.append(0x40); + + let res = RLPTrait::encode_string(input.span()); + + assert(res.len() == 1, 'wrong len'); + assert(*res[0] == 0x40, 'wrong encoded value'); + } + + #[test] + fn test_rlp_encode_string_single_byte_ge_0x80() { + let mut input: Array = Default::default(); + input.append(0x80); + + let res = RLPTrait::encode_string(input.span()); + + assert(res.len() == 2, 'wrong len'); + assert(*res[0] == 0x81, 'wrong prefix'); + assert(*res[1] == 0x80, 'wrong encoded value'); + } + + #[test] + fn test_rlp_encode_string_length_between_2_and_55() { + let mut input: Array = Default::default(); + input.append(0x40); + input.append(0x50); + + let res = RLPTrait::encode_string(input.span()); + + assert(res.len() == 3, 'wrong len'); + assert(*res[0] == 0x82, 'wrong prefix'); + assert(*res[1] == 0x40, 'wrong first value'); + assert(*res[2] == 0x50, 'wrong second value'); + } + + #[test] + fn test_rlp_encode_string_length_exactly_56() { + let mut input: Array = Default::default(); + let mut i = 0; + loop { + if i == 56 { + break; + } + input.append(0x60); + i += 1; + }; + + let res = RLPTrait::encode_string(input.span()); + + assert(res.len() == 58, 'wrong len'); + assert(*res[0] == 0xb8, 'wrong prefix'); + assert(*res[1] == 56, 'wrong string length'); + let mut i = 2; + loop { + if i == 58 { + break; + } + assert(*res[i] == 0x60, 'wrong value in sequence'); + i += 1; + }; + } + + #[test] + fn test_rlp_encode_string_length_greater_than_56() { + let mut input: Array = Default::default(); + let mut i = 0; + loop { + if i == 60 { + break; + } + input.append(0x70); + i += 1; + }; + + let res = RLPTrait::encode_string(input.span()); + + assert(res.len() == 62, 'wrong len'); + assert(*res[0] == 0xb8, 'wrong prefix'); + assert(*res[1] == 60, 'wrong length byte'); + let mut i = 2; + loop { + if i == 62 { + break; + } + assert(*res[i] == 0x70, 'wrong value in sequence'); + i += 1; + } + } + + #[test] + fn test_rlp_encode_string_large_bytearray_inputs() { + let mut input: Array = Default::default(); + let mut i = 0; + loop { + if i == 500 { + break; + } + input.append(0x70); + i += 1; + }; + + let res = RLPTrait::encode_string(input.span()); + + assert(res.len() == 503, 'wrong len'); + assert(*res[0] == 0xb9, 'wrong prefix'); + assert(*res[1] == 0x01, 'wrong first length byte'); + assert(*res[2] == 0xF4, 'wrong second length byte'); + let mut i = 3; + loop { + if i == 503 { + break; + } + assert(*res[i] == 0x70, 'wrong value in sequence'); + i += 1; + } + } + + #[test] + fn test_rlp_encode_sequence_empty() { + let res = RLPTrait::encode_sequence([].span()); + + assert(res.len() == 1, 'wrong len'); + assert(*res[0] == 0xC0, 'wrong encoded value'); + } + + #[test] + fn test_rlp_encode_sequence() { + let cat = RLPItem::String([0x63, 0x61, 0x74].span()); + let dog = RLPItem::String([0x64, 0x6f, 0x67].span()); + let input = array![cat, dog]; + + let encoding = RLPTrait::encode_sequence(input.span()); + + let expected = [0xc8, 0x83, 0x63, 0x61, 0x74, 0x83, 0x64, 0x6f, 0x67].span(); + assert(expected == encoding, 'wrong rlp encoding') + } + + #[test] + #[should_panic(expected: ('Shouldnt encode long sequence',))] + fn test_rlp_encode_sequence_long_sequence() { + // encoding of a sequence with more than 55 bytes + let mut lorem_ipsum = RLPItem::String( + [ + 0x4c, + 0x6f, + 0x72, + 0x65, + 0x6d, + 0x20, + 0x69, + 0x70, + 0x73, + 0x75, + 0x6d, + 0x20, + 0x64, + 0x6f, + 0x6c, + 0x6f, + 0x72, + 0x20, + 0x73, + 0x69, + 0x74, + 0x20, + 0x61, + 0x6d, + 0x65, + 0x74, + 0x2c, + 0x20, + 0x63, + 0x6f, + 0x6e, + 0x73, + 0x65, + 0x63, + 0x74, + 0x65, + 0x74, + 0x75, + 0x72, + 0x20, + 0x61, + 0x64, + 0x69, + 0x70, + 0x69, + 0x73, + 0x69, + 0x63, + 0x69, + 0x6e, + 0x67, + 0x20, + 0x65, + 0x6c, + 0x69, + 0x74 + ].span() + ); + let input = [lorem_ipsum].span(); + let encoding = RLPTrait::encode_sequence(input); + + let expected = [ + 0xf8, + 0x3a, + 0xb8, + 0x38, + 0x4c, + 0x6f, + 0x72, + 0x65, + 0x6d, + 0x20, + 0x69, + 0x70, + 0x73, + 0x75, + 0x6d, + 0x20, + 0x64, + 0x6f, + 0x6c, + 0x6f, + 0x72, + 0x20, + 0x73, + 0x69, + 0x74, + 0x20, + 0x61, + 0x6d, + 0x65, + 0x74, + 0x2c, + 0x20, + 0x63, + 0x6f, + 0x6e, + 0x73, + 0x65, + 0x63, + 0x74, + 0x65, + 0x74, + 0x75, + 0x72, + 0x20, + 0x61, + 0x64, + 0x69, + 0x70, + 0x69, + 0x73, + 0x69, + 0x63, + 0x69, + 0x6e, + 0x67, + 0x20, + 0x65, + 0x6c, + 0x69, + 0x74 + ].span(); + assert(expected == encoding, 'wrong rlp encoding') + } + + #[test] + fn test_rlp_decode_string_default_value() { + let mut arr = array![0x80]; + + let rlp_item = RLPTrait::decode(arr.span()).unwrap(); + let expected = RLPItem::String([].span()); + + assert(rlp_item.len() == 1, 'item length not 1'); + assert(*rlp_item[0] == expected, 'default value not 0'); + } + + #[test] + fn test_rlp_decode_string() { + let mut i = 0; + loop { + if i == 0x80 { + break; + } + let mut arr = ArrayTrait::new(); + arr.append(i); + + let res = RLPTrait::decode(arr.span()).unwrap(); + + assert(res == [RLPItem::String(arr.span())].span(), 'Wrong value'); + + i += 1; + }; + } + + #[test] + fn test_rlp_decode_short_string() { + let mut arr = array![ + 0x9b, + 0x5a, + 0x80, + 0x6c, + 0xf6, + 0x34, + 0xc0, + 0x39, + 0x8d, + 0x8f, + 0x2d, + 0x89, + 0xfd, + 0x49, + 0xa9, + 0x1e, + 0xf3, + 0x3d, + 0xa4, + 0x74, + 0xcd, + 0x84, + 0x94, + 0xbb, + 0xa8, + 0xda, + 0x3b, + 0xf7 + ]; + + let res = RLPTrait::decode(arr.span()).unwrap(); + + // Remove the byte representing the data type + arr.pop_front().expect('pop_front failed'); + let expected_item = [RLPItem::String(arr.span())].span(); + + assert(res == expected_item, 'Wrong value'); + } + + #[test] + fn test_rlp_decode_short_string_input_too_short() { + let mut arr = array![ + 0x9b, + 0x5a, + 0x80, + 0x6c, + 0xf6, + 0x34, + 0xc0, + 0x39, + 0x8d, + 0x8f, + 0x2d, + 0x89, + 0xfd, + 0x49, + 0xa9, + 0x1e, + 0xf3, + 0x3d, + 0xa4, + 0x74, + 0xcd, + 0x84, + 0x94, + 0xbb, + 0xa8, + 0xda, + 0x3b + ]; + + let res = RLPTrait::decode(arr.span()); + assert(res.is_err(), 'should return an RLPError'); + assert!(res.unwrap_err() == RLPError::InputTooShort); + } + + #[test] + fn test_rlp_decode_long_string_with_payload_len_on_1_byte() { + let mut arr = array![ + 0xb8, + 0x3c, + 0xf7, + 0xa1, + 0x7e, + 0xf9, + 0x59, + 0xd4, + 0x88, + 0x38, + 0x8d, + 0xdc, + 0x34, + 0x7b, + 0x3a, + 0x10, + 0xdd, + 0x85, + 0x43, + 0x1d, + 0x0c, + 0x37, + 0x98, + 0x6a, + 0x63, + 0xbd, + 0x18, + 0xba, + 0xa3, + 0x8d, + 0xb1, + 0xa4, + 0x81, + 0x6f, + 0x24, + 0xde, + 0xc3, + 0xec, + 0x16, + 0x6e, + 0xb3, + 0xb2, + 0xac, + 0xc4, + 0xc4, + 0xf7, + 0x79, + 0x04, + 0xba, + 0x76, + 0x3c, + 0x67, + 0xc6, + 0xd0, + 0x53, + 0xda, + 0xea, + 0x10, + 0x86, + 0x19, + 0x7d, + 0xd9 + ]; + + let res = RLPTrait::decode(arr.span()).unwrap(); + + // Remove the bytes representing the data type and their length + arr.pop_front().expect('pop_front failed'); + arr.pop_front().expect('pop_front failed'); + let expected_item = [RLPItem::String(arr.span())].span(); + + assert(res == expected_item, 'Wrong value'); + } + + #[test] + fn test_rlp_decode_long_string_with_input_too_short() { + let mut arr = array![ + 0xb8, + 0x3c, + 0xf7, + 0xa1, + 0x7e, + 0xf9, + 0x59, + 0xd4, + 0x88, + 0x38, + 0x8d, + 0xdc, + 0x34, + 0x7b, + 0x3a, + 0x10, + 0xdd, + 0x85, + 0x43, + 0x1d, + 0x0c, + 0x37, + 0x98, + 0x6a, + 0x63, + 0xbd, + 0x18, + 0xba, + 0xa3, + 0x8d, + 0xb1, + 0xa4, + 0x81, + 0x6f, + 0x24, + 0xde, + 0xc3, + 0xec, + 0x16, + 0x6e, + 0xb3, + 0xb2, + 0xac, + 0xc4, + 0xc4, + 0xf7, + 0x79, + 0x04, + 0xba, + 0x76, + 0x3c, + 0x67, + 0xc6, + 0xd0, + 0x53, + 0xda, + 0xea, + 0x10, + 0x86, + 0x19, + ]; + + let res = RLPTrait::decode(arr.span()); + assert(res.is_err(), 'should return an RLPError'); + assert!(res.unwrap_err() == RLPError::InputTooShort); + } + + #[test] + fn test_rlp_decode_long_string_with_payload_len_on_2_bytes() { + let mut arr = array![ + 0xb9, + 0x01, + 0x02, + 0xf7, + 0xa1, + 0x7e, + 0xf9, + 0x59, + 0xd4, + 0x88, + 0x38, + 0x8d, + 0xdc, + 0x34, + 0x7b, + 0x3a, + 0x10, + 0xdd, + 0x85, + 0x43, + 0x1d, + 0x0c, + 0x37, + 0x98, + 0x6a, + 0x63, + 0xbd, + 0x18, + 0xba, + 0xa3, + 0x8d, + 0xb1, + 0xa4, + 0x81, + 0x6f, + 0x24, + 0xde, + 0xc3, + 0xec, + 0x16, + 0x6e, + 0xb3, + 0xb2, + 0xac, + 0xc4, + 0xc4, + 0xf7, + 0x79, + 0x04, + 0xba, + 0x76, + 0x3c, + 0x67, + 0xc6, + 0xd0, + 0x53, + 0xda, + 0xea, + 0x10, + 0x86, + 0x19, + 0x7d, + 0xd9, + 0x33, + 0x58, + 0x47, + 0x69, + 0x34, + 0x76, + 0x89, + 0x43, + 0x67, + 0x93, + 0x45, + 0x76, + 0x87, + 0x34, + 0x95, + 0x67, + 0x89, + 0x34, + 0x36, + 0x43, + 0x86, + 0x79, + 0x43, + 0x63, + 0x34, + 0x78, + 0x63, + 0x49, + 0x58, + 0x67, + 0x83, + 0x59, + 0x64, + 0x56, + 0x37, + 0x93, + 0x74, + 0x58, + 0x69, + 0x69, + 0x43, + 0x67, + 0x39, + 0x48, + 0x67, + 0x98, + 0x45, + 0x63, + 0x89, + 0x45, + 0x67, + 0x94, + 0x37, + 0x63, + 0x04, + 0x56, + 0x40, + 0x39, + 0x68, + 0x43, + 0x08, + 0x68, + 0x40, + 0x65, + 0x03, + 0x46, + 0x80, + 0x93, + 0x48, + 0x64, + 0x95, + 0x36, + 0x87, + 0x39, + 0x84, + 0x56, + 0x73, + 0x76, + 0x89, + 0x34, + 0x95, + 0x86, + 0x73, + 0x65, + 0x40, + 0x93, + 0x60, + 0x98, + 0x34, + 0x56, + 0x83, + 0x04, + 0x56, + 0x80, + 0x36, + 0x08, + 0x59, + 0x68, + 0x45, + 0x06, + 0x83, + 0x06, + 0x68, + 0x40, + 0x59, + 0x68, + 0x40, + 0x65, + 0x84, + 0x03, + 0x68, + 0x30, + 0x48, + 0x65, + 0x03, + 0x46, + 0x83, + 0x49, + 0x57, + 0x68, + 0x95, + 0x79, + 0x68, + 0x34, + 0x76, + 0x83, + 0x74, + 0x69, + 0x87, + 0x43, + 0x59, + 0x63, + 0x84, + 0x75, + 0x63, + 0x98, + 0x47, + 0x56, + 0x34, + 0x86, + 0x73, + 0x94, + 0x87, + 0x65, + 0x43, + 0x98, + 0x67, + 0x34, + 0x96, + 0x79, + 0x34, + 0x86, + 0x57, + 0x93, + 0x48, + 0x57, + 0x69, + 0x34, + 0x87, + 0x56, + 0x89, + 0x34, + 0x57, + 0x68, + 0x73, + 0x49, + 0x56, + 0x53, + 0x79, + 0x43, + 0x95, + 0x67, + 0x34, + 0x96, + 0x79, + 0x38, + 0x47, + 0x63, + 0x94, + 0x65, + 0x37, + 0x89, + 0x63, + 0x53, + 0x45, + 0x68, + 0x79, + 0x88, + 0x97, + 0x68, + 0x87, + 0x68, + 0x68, + 0x68, + 0x76, + 0x99, + 0x87, + 0x60 + ]; + + let res = RLPTrait::decode(arr.span()).unwrap(); + + // Remove the bytes representing the data type and their length + arr.pop_front().expect('pop_front failed'); + arr.pop_front().expect('pop_front failed'); + arr.pop_front().expect('pop_front failed'); + let expected_item = [RLPItem::String(arr.span())].span(); + + assert(res == expected_item, 'Wrong value'); + } + + + #[test] + fn test_rlp_decode_long_string_with_payload_len_too_short() { + let mut arr = array![0xb9, 0x01,]; + + let res = RLPTrait::decode(arr.span()); + assert(res.is_err(), 'should return an RLPError'); + assert!(res.unwrap_err() == RLPError::InputTooShort); + } + + #[test] + fn test_rlp_decode_short_list() { + let mut arr = array![0xc9, 0x83, 0x35, 0x35, 0x35, 0x42, 0x83, 0x45, 0x38, 0x92]; + let res = RLPTrait::decode(arr.span()).unwrap(); + + let mut expected_0 = RLPItem::String([0x35, 0x35, 0x35].span()); + let mut expected_1 = RLPItem::String([0x42].span()); + let mut expected_2 = RLPItem::String([0x45, 0x38, 0x92].span()); + + let expected_list = RLPItem::List([expected_0, expected_1, expected_2].span()); + + assert(res == [expected_list].span(), 'Wrong value'); + } + + #[test] + fn test_rlp_decode_short_nested_list() { + let mut arr = array![0xc7, 0xc0, 0xc1, 0xc0, 0xc3, 0xc0, 0xc1, 0xc0]; + let res = RLPTrait::decode(arr.span()).unwrap(); + + let mut expected_0 = RLPItem::List([].span()); + let mut expected_1 = RLPItem::List([expected_0].span()); + let mut expected_2 = RLPItem::List([expected_0, expected_1].span()); + + let expected = RLPItem::List([expected_0, expected_1, expected_2].span()); + + assert(res == [expected].span(), 'Wrong value'); + } + + #[test] + fn test_rlp_decode_multi_list() { + let mut arr = array![0xc6, 0x82, 0x7a, 0x77, 0xc1, 0x04, 0x01,]; + + let res = RLPTrait::decode(arr.span()).unwrap(); + + let mut expected_0 = RLPItem::String([0x7a, 0x77].span()); + let mut expected_1 = RLPItem::String([0x04].span()); + let mut expected_1 = RLPItem::List([expected_1].span()); + let mut expected_2 = RLPItem::String([0x01].span()); + let mut expected = RLPItem::List([expected_0, expected_1, expected_2].span()); + + assert(res == [expected].span(), 'Wrong value'); + } + + #[test] + fn test_rlp_decode_short_list_with_input_too_short() { + let mut arr = array![0xc9, 0x83, 0x35, 0x35, 0x89, 0x42, 0x83, 0x45, 0x38]; + + let res = RLPTrait::decode(arr.span()); + assert(res.is_err(), 'should return an RLPError'); + assert!(res.unwrap_err() == RLPError::InputTooShort); + } + + #[test] + fn test_rlp_decode_long_list() { + let mut arr = array![ + 0xf9, + 0x02, + 0x11, + 0xa0, + 0x77, + 0x70, + 0xcf, + 0x09, + 0xb5, + 0x06, + 0x7a, + 0x1b, + 0x35, + 0xdf, + 0x62, + 0xa9, + 0x24, + 0x89, + 0x81, + 0x75, + 0xce, + 0xae, + 0xec, + 0xad, + 0x1f, + 0x68, + 0xcd, + 0xb4, + 0xa8, + 0x44, + 0x40, + 0x0c, + 0x73, + 0xc1, + 0x4a, + 0xf4, + 0xa0, + 0x1e, + 0xa3, + 0x85, + 0xd0, + 0x5a, + 0xb2, + 0x61, + 0x46, + 0x6d, + 0x5c, + 0x04, + 0x87, + 0xfe, + 0x68, + 0x45, + 0x34, + 0xc1, + 0x9f, + 0x1a, + 0x4b, + 0x5c, + 0x4b, + 0x18, + 0xdc, + 0x1a, + 0x36, + 0x35, + 0x60, + 0x02, + 0x50, + 0x71, + 0xb4, + 0xa0, + 0x2c, + 0x4c, + 0x04, + 0xce, + 0x35, + 0x40, + 0xd3, + 0xd1, + 0x46, + 0x18, + 0x72, + 0x30, + 0x3c, + 0x53, + 0xa5, + 0xe5, + 0x66, + 0x83, + 0xc1, + 0x30, + 0x4f, + 0x8d, + 0x36, + 0xa8, + 0x80, + 0x0c, + 0x6a, + 0xf5, + 0xfa, + 0x3f, + 0xcd, + 0xee, + 0xa0, + 0xa9, + 0xdc, + 0x77, + 0x8d, + 0xc5, + 0x4b, + 0x7d, + 0xd3, + 0xc4, + 0x82, + 0x22, + 0xe7, + 0x39, + 0xd1, + 0x61, + 0xfe, + 0xb0, + 0xc0, + 0xee, + 0xce, + 0xb2, + 0xdc, + 0xd5, + 0x17, + 0x37, + 0xf0, + 0x5b, + 0x8e, + 0x37, + 0xa6, + 0x38, + 0x51, + 0xa0, + 0xa9, + 0x5f, + 0x4d, + 0x55, + 0x56, + 0xdf, + 0x62, + 0xdd, + 0xc2, + 0x62, + 0x99, + 0x04, + 0x97, + 0xae, + 0x56, + 0x9b, + 0xcd, + 0x8e, + 0xfd, + 0xda, + 0x7b, + 0x20, + 0x07, + 0x93, + 0xf8, + 0xd3, + 0xde, + 0x4c, + 0xdb, + 0x97, + 0x18, + 0xd7, + 0xa0, + 0x39, + 0xd4, + 0x06, + 0x6d, + 0x14, + 0x38, + 0x22, + 0x6e, + 0xaf, + 0x4a, + 0xc9, + 0xe9, + 0x43, + 0xa8, + 0x74, + 0xa9, + 0xa9, + 0xc2, + 0x5f, + 0xb0, + 0xd8, + 0x1d, + 0xb9, + 0x86, + 0x1d, + 0x8c, + 0x13, + 0x36, + 0xb3, + 0xe2, + 0x03, + 0x4c, + 0xa0, + 0x7a, + 0xcc, + 0x7c, + 0x63, + 0xb4, + 0x6a, + 0xa4, + 0x18, + 0xb3, + 0xc9, + 0xa0, + 0x41, + 0xa1, + 0x25, + 0x6b, + 0xcb, + 0x73, + 0x61, + 0x31, + 0x6b, + 0x39, + 0x7a, + 0xda, + 0x5a, + 0x88, + 0x67, + 0x49, + 0x1b, + 0xbb, + 0x13, + 0x01, + 0x30, + 0xa0, + 0x15, + 0x35, + 0x8a, + 0x81, + 0x25, + 0x2e, + 0xc4, + 0x93, + 0x71, + 0x13, + 0xfe, + 0x36, + 0xc7, + 0x80, + 0x46, + 0xb7, + 0x11, + 0xfb, + 0xa1, + 0x97, + 0x34, + 0x91, + 0xbb, + 0x29, + 0x18, + 0x7a, + 0x00, + 0x78, + 0x5f, + 0xf8, + 0x52, + 0xae, + 0xa0, + 0x68, + 0x91, + 0x42, + 0xd3, + 0x16, + 0xab, + 0xfa, + 0xa7, + 0x1c, + 0x8b, + 0xce, + 0xdf, + 0x49, + 0x20, + 0x1d, + 0xdb, + 0xb2, + 0x10, + 0x4e, + 0x25, + 0x0a, + 0xdc, + 0x90, + 0xc4, + 0xe8, + 0x56, + 0x22, + 0x1f, + 0x53, + 0x4a, + 0x96, + 0x58, + 0xa0, + 0xdc, + 0x36, + 0x50, + 0x99, + 0x25, + 0x34, + 0xfd, + 0xa8, + 0xa3, + 0x14, + 0xa7, + 0xdb, + 0xb0, + 0xae, + 0x3b, + 0xa8, + 0xc7, + 0x9d, + 0xb5, + 0x55, + 0x0c, + 0x69, + 0xce, + 0x2a, + 0x24, + 0x60, + 0xc0, + 0x07, + 0xad, + 0xc4, + 0xc1, + 0xa3, + 0xa0, + 0x20, + 0xb0, + 0x68, + 0x3b, + 0x66, + 0x55, + 0xb0, + 0x05, + 0x9e, + 0xe1, + 0x03, + 0xd0, + 0x4e, + 0x4b, + 0x50, + 0x6b, + 0xcb, + 0xc1, + 0x39, + 0x00, + 0x63, + 0x92, + 0xb7, + 0xda, + 0xb1, + 0x11, + 0x78, + 0xc2, + 0x66, + 0x03, + 0x42, + 0xe7, + 0xa0, + 0x8e, + 0xed, + 0xeb, + 0x45, + 0xfb, + 0x63, + 0x0f, + 0x1c, + 0xd9, + 0x97, + 0x36, + 0xeb, + 0x18, + 0x57, + 0x22, + 0x17, + 0xcb, + 0xc6, + 0xd5, + 0xf3, + 0x15, + 0xb7, + 0x1b, + 0xe2, + 0x03, + 0xb0, + 0x3c, + 0xe8, + 0xd9, + 0x9b, + 0x26, + 0x14, + 0xa0, + 0x79, + 0x23, + 0xa3, + 0x3d, + 0xf6, + 0x5a, + 0x98, + 0x6f, + 0xd5, + 0xe7, + 0xf9, + 0xe6, + 0xe4, + 0xc2, + 0xb9, + 0x69, + 0x73, + 0x6b, + 0x08, + 0x94, + 0x4e, + 0xbe, + 0x99, + 0x39, + 0x4a, + 0x86, + 0x14, + 0x61, + 0x2f, + 0xe6, + 0x09, + 0xf3, + 0xa0, + 0x65, + 0x34, + 0xd7, + 0xd0, + 0x1a, + 0x20, + 0x71, + 0x4a, + 0xa4, + 0xfb, + 0x2a, + 0x55, + 0xb9, + 0x46, + 0xce, + 0x64, + 0xc3, + 0x22, + 0x2d, + 0xff, + 0xad, + 0x2a, + 0xa2, + 0xd1, + 0x8a, + 0x92, + 0x34, + 0x73, + 0xc9, + 0x2a, + 0xb1, + 0xfd, + 0xa0, + 0xbf, + 0xf9, + 0xc2, + 0x8b, + 0xfe, + 0xb8, + 0xbf, + 0x2d, + 0xa9, + 0xb6, + 0x18, + 0xc8, + 0xc3, + 0xb0, + 0x6f, + 0xe8, + 0x0c, + 0xb1, + 0xc0, + 0xbd, + 0x14, + 0x47, + 0x38, + 0xf7, + 0xc4, + 0x21, + 0x61, + 0xff, + 0x29, + 0xe2, + 0x50, + 0x2f, + 0xa0, + 0x7f, + 0x14, + 0x61, + 0x69, + 0x3c, + 0x70, + 0x4e, + 0xa5, + 0x02, + 0x1b, + 0xbb, + 0xa3, + 0x5e, + 0x72, + 0xc5, + 0x02, + 0xf6, + 0x43, + 0x9e, + 0x45, + 0x8f, + 0x98, + 0x24, + 0x2e, + 0xd0, + 0x37, + 0x48, + 0xea, + 0x8f, + 0xe2, + 0xb3, + 0x5f, + 0x80 + ]; + let res = RLPTrait::decode(arr.span()).unwrap(); + + let mut expected_0 = RLPItem::String( + [ + 0x77, + 0x70, + 0xcf, + 0x09, + 0xb5, + 0x06, + 0x7a, + 0x1b, + 0x35, + 0xdf, + 0x62, + 0xa9, + 0x24, + 0x89, + 0x81, + 0x75, + 0xce, + 0xae, + 0xec, + 0xad, + 0x1f, + 0x68, + 0xcd, + 0xb4, + 0xa8, + 0x44, + 0x40, + 0x0c, + 0x73, + 0xc1, + 0x4a, + 0xf4 + ].span() + ); + let mut expected_1 = RLPItem::String( + [ + 0x1e, + 0xa3, + 0x85, + 0xd0, + 0x5a, + 0xb2, + 0x61, + 0x46, + 0x6d, + 0x5c, + 0x04, + 0x87, + 0xfe, + 0x68, + 0x45, + 0x34, + 0xc1, + 0x9f, + 0x1a, + 0x4b, + 0x5c, + 0x4b, + 0x18, + 0xdc, + 0x1a, + 0x36, + 0x35, + 0x60, + 0x02, + 0x50, + 0x71, + 0xb4 + ].span() + ); + let mut expected_2 = RLPItem::String( + [ + 0x2c, + 0x4c, + 0x04, + 0xce, + 0x35, + 0x40, + 0xd3, + 0xd1, + 0x46, + 0x18, + 0x72, + 0x30, + 0x3c, + 0x53, + 0xa5, + 0xe5, + 0x66, + 0x83, + 0xc1, + 0x30, + 0x4f, + 0x8d, + 0x36, + 0xa8, + 0x80, + 0x0c, + 0x6a, + 0xf5, + 0xfa, + 0x3f, + 0xcd, + 0xee + ].span() + ); + let mut expected_3 = RLPItem::String( + [ + 0xa9, + 0xdc, + 0x77, + 0x8d, + 0xc5, + 0x4b, + 0x7d, + 0xd3, + 0xc4, + 0x82, + 0x22, + 0xe7, + 0x39, + 0xd1, + 0x61, + 0xfe, + 0xb0, + 0xc0, + 0xee, + 0xce, + 0xb2, + 0xdc, + 0xd5, + 0x17, + 0x37, + 0xf0, + 0x5b, + 0x8e, + 0x37, + 0xa6, + 0x38, + 0x51 + ].span() + ); + let mut expected_4 = RLPItem::String( + [ + 0xa9, + 0x5f, + 0x4d, + 0x55, + 0x56, + 0xdf, + 0x62, + 0xdd, + 0xc2, + 0x62, + 0x99, + 0x04, + 0x97, + 0xae, + 0x56, + 0x9b, + 0xcd, + 0x8e, + 0xfd, + 0xda, + 0x7b, + 0x20, + 0x07, + 0x93, + 0xf8, + 0xd3, + 0xde, + 0x4c, + 0xdb, + 0x97, + 0x18, + 0xd7 + ].span() + ); + let mut expected_5 = RLPItem::String( + [ + 0x39, + 0xd4, + 0x06, + 0x6d, + 0x14, + 0x38, + 0x22, + 0x6e, + 0xaf, + 0x4a, + 0xc9, + 0xe9, + 0x43, + 0xa8, + 0x74, + 0xa9, + 0xa9, + 0xc2, + 0x5f, + 0xb0, + 0xd8, + 0x1d, + 0xb9, + 0x86, + 0x1d, + 0x8c, + 0x13, + 0x36, + 0xb3, + 0xe2, + 0x03, + 0x4c + ].span() + ); + let mut expected_6 = RLPItem::String( + [ + 0x7a, + 0xcc, + 0x7c, + 0x63, + 0xb4, + 0x6a, + 0xa4, + 0x18, + 0xb3, + 0xc9, + 0xa0, + 0x41, + 0xa1, + 0x25, + 0x6b, + 0xcb, + 0x73, + 0x61, + 0x31, + 0x6b, + 0x39, + 0x7a, + 0xda, + 0x5a, + 0x88, + 0x67, + 0x49, + 0x1b, + 0xbb, + 0x13, + 0x01, + 0x30 + ].span() + ); + let mut expected_7 = RLPItem::String( + [ + 0x15, + 0x35, + 0x8a, + 0x81, + 0x25, + 0x2e, + 0xc4, + 0x93, + 0x71, + 0x13, + 0xfe, + 0x36, + 0xc7, + 0x80, + 0x46, + 0xb7, + 0x11, + 0xfb, + 0xa1, + 0x97, + 0x34, + 0x91, + 0xbb, + 0x29, + 0x18, + 0x7a, + 0x00, + 0x78, + 0x5f, + 0xf8, + 0x52, + 0xae + ].span() + ); + let mut expected_8 = RLPItem::String( + [ + 0x68, + 0x91, + 0x42, + 0xd3, + 0x16, + 0xab, + 0xfa, + 0xa7, + 0x1c, + 0x8b, + 0xce, + 0xdf, + 0x49, + 0x20, + 0x1d, + 0xdb, + 0xb2, + 0x10, + 0x4e, + 0x25, + 0x0a, + 0xdc, + 0x90, + 0xc4, + 0xe8, + 0x56, + 0x22, + 0x1f, + 0x53, + 0x4a, + 0x96, + 0x58 + ].span() + ); + let mut expected_9 = RLPItem::String( + [ + 0xdc, + 0x36, + 0x50, + 0x99, + 0x25, + 0x34, + 0xfd, + 0xa8, + 0xa3, + 0x14, + 0xa7, + 0xdb, + 0xb0, + 0xae, + 0x3b, + 0xa8, + 0xc7, + 0x9d, + 0xb5, + 0x55, + 0x0c, + 0x69, + 0xce, + 0x2a, + 0x24, + 0x60, + 0xc0, + 0x07, + 0xad, + 0xc4, + 0xc1, + 0xa3 + ].span() + ); + let mut expected_10 = RLPItem::String( + [ + 0x20, + 0xb0, + 0x68, + 0x3b, + 0x66, + 0x55, + 0xb0, + 0x05, + 0x9e, + 0xe1, + 0x03, + 0xd0, + 0x4e, + 0x4b, + 0x50, + 0x6b, + 0xcb, + 0xc1, + 0x39, + 0x00, + 0x63, + 0x92, + 0xb7, + 0xda, + 0xb1, + 0x11, + 0x78, + 0xc2, + 0x66, + 0x03, + 0x42, + 0xe7 + ].span() + ); + let mut expected_11 = RLPItem::String( + [ + 0x8e, + 0xed, + 0xeb, + 0x45, + 0xfb, + 0x63, + 0x0f, + 0x1c, + 0xd9, + 0x97, + 0x36, + 0xeb, + 0x18, + 0x57, + 0x22, + 0x17, + 0xcb, + 0xc6, + 0xd5, + 0xf3, + 0x15, + 0xb7, + 0x1b, + 0xe2, + 0x03, + 0xb0, + 0x3c, + 0xe8, + 0xd9, + 0x9b, + 0x26, + 0x14 + ].span() + ); + let mut expected_12 = RLPItem::String( + [ + 0x79, + 0x23, + 0xa3, + 0x3d, + 0xf6, + 0x5a, + 0x98, + 0x6f, + 0xd5, + 0xe7, + 0xf9, + 0xe6, + 0xe4, + 0xc2, + 0xb9, + 0x69, + 0x73, + 0x6b, + 0x08, + 0x94, + 0x4e, + 0xbe, + 0x99, + 0x39, + 0x4a, + 0x86, + 0x14, + 0x61, + 0x2f, + 0xe6, + 0x09, + 0xf3 + ].span() + ); + let mut expected_13 = RLPItem::String( + [ + 0x65, + 0x34, + 0xd7, + 0xd0, + 0x1a, + 0x20, + 0x71, + 0x4a, + 0xa4, + 0xfb, + 0x2a, + 0x55, + 0xb9, + 0x46, + 0xce, + 0x64, + 0xc3, + 0x22, + 0x2d, + 0xff, + 0xad, + 0x2a, + 0xa2, + 0xd1, + 0x8a, + 0x92, + 0x34, + 0x73, + 0xc9, + 0x2a, + 0xb1, + 0xfd + ].span() + ); + let mut expected_14 = RLPItem::String( + [ + 0xbf, + 0xf9, + 0xc2, + 0x8b, + 0xfe, + 0xb8, + 0xbf, + 0x2d, + 0xa9, + 0xb6, + 0x18, + 0xc8, + 0xc3, + 0xb0, + 0x6f, + 0xe8, + 0x0c, + 0xb1, + 0xc0, + 0xbd, + 0x14, + 0x47, + 0x38, + 0xf7, + 0xc4, + 0x21, + 0x61, + 0xff, + 0x29, + 0xe2, + 0x50, + 0x2f + ].span() + ); + let mut expected_15 = RLPItem::String( + [ + 0x7f, + 0x14, + 0x61, + 0x69, + 0x3c, + 0x70, + 0x4e, + 0xa5, + 0x02, + 0x1b, + 0xbb, + 0xa3, + 0x5e, + 0x72, + 0xc5, + 0x02, + 0xf6, + 0x43, + 0x9e, + 0x45, + 0x8f, + 0x98, + 0x24, + 0x2e, + 0xd0, + 0x37, + 0x48, + 0xea, + 0x8f, + 0xe2, + 0xb3, + 0x5f + ].span() + ); + + let mut expected_16 = RLPItem::String([].span()); + + let mut expected = array![ + expected_0, + expected_1, + expected_2, + expected_3, + expected_4, + expected_5, + expected_6, + expected_7, + expected_8, + expected_9, + expected_10, + expected_11, + expected_12, + expected_13, + expected_14, + expected_15, + expected_16 + ]; + + let expected_item = RLPItem::List(expected.span()); + + assert(res == [expected_item].span(), 'Wrong value'); + } + + #[test] + fn test_rlp_decode_long_list_with_input_too_short() { + let mut arr = array![ + 0xf9, + 0x02, + 0x11, + 0xa0, + 0x77, + 0x70, + 0xcf, + 0x09, + 0xb5, + 0x06, + 0x7a, + 0x1b, + 0x35, + 0xdf, + 0x62, + 0xa9, + 0x24, + 0x89, + 0x81, + 0x75, + 0xce, + 0xae, + 0xec, + 0xad, + 0x1f, + 0x68, + 0xcd, + 0xb4 + ]; + + let res = RLPTrait::decode(arr.span()); + assert(res.is_err(), 'should return an RLPError'); + assert!(res.unwrap_err() == RLPError::InputTooShort); + } + + #[test] + fn test_rlp_decode_long_list_with_len_too_short() { + let mut arr = array![0xf9, 0x02,]; + + let res = RLPTrait::decode(arr.span()); + assert(res.is_err(), 'should return an RLPError'); + assert!(res.unwrap_err() == RLPError::InputTooShort); + } + + #[test] + fn test_rlp_item_parse_access_list_empty() { + let rlp_encoded_access_list: Span = [0xc0].span(); + let decoded_data = RLPTrait::decode(rlp_encoded_access_list).unwrap(); + assert_eq!(decoded_data.len(), 1); + + let rlp_item = *decoded_data[0]; + let res = rlp_item.parse_access_list().unwrap(); + assert_eq!(res.len(), 0); + } + + #[test] + fn test_rlp_item_parse_access_list() { + // (('0x0000000000000000000000000000000000000001', + // ('0x0100000000000000000000000000000000000000000000000000000000000000',)), + // ('0x0000000000000000000000000000000000000002', + // ('0x0100000000000000000000000000000000000000000000000000000000000000', + // '0x0200000000000000000000000000000000000000000000000000000000000000')), + // ('0x0000000000000000000000000000000000000003', ())) + let rlp_encoded_access_list: Span = [ + 248, + 170, + 247, + 148, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 225, + 160, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 248, + 89, + 148, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2, + 248, + 66, + 160, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 160, + 2, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 214, + 148, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3, + 192 + ].span(); + let decoded_data = RLPTrait::decode(rlp_encoded_access_list).unwrap(); + assert_eq!(decoded_data.len(), 1); + + let rlp_item = *decoded_data[0]; + + let expected_access_list = [ + AccessListItem { + ethereum_address: 0x0000000000000000000000000000000000000001.try_into().unwrap(), + storage_keys: [ + 0x0100000000000000000000000000000000000000000000000000000000000000 + ].span() + }, + AccessListItem { + ethereum_address: 0x0000000000000000000000000000000000000002.try_into().unwrap(), + storage_keys: [ + 0x0100000000000000000000000000000000000000000000000000000000000000, + 0x0200000000000000000000000000000000000000000000000000000000000000 + ].span() + }, + AccessListItem { + ethereum_address: 0x0000000000000000000000000000000000000003.try_into().unwrap(), + storage_keys: [].span() + } + ].span(); + + let res = rlp_item.parse_access_list().unwrap(); + assert!(res == expected_access_list); + } +} diff --git a/kakarot-ssj/crates/utils/src/serialization.cairo b/kakarot-ssj/crates/utils/src/serialization.cairo new file mode 100644 index 000000000..371f9dd1c --- /dev/null +++ b/kakarot-ssj/crates/utils/src/serialization.cairo @@ -0,0 +1,301 @@ +use core::starknet::secp256_trait::{Signature}; +use crate::eth_transaction::tx_type::TxType; +use crate::traits::BoolIntoNumeric; + +/// Deserializes a signature from a span of felt252 values. +/// +/// # Arguments +/// +/// * `signature` - A span of felt252 values representing the signature components. +/// * `chain_id` - The chain ID used for EIP-155 signature recovery. +/// +/// # Returns +/// +/// * `Option` - The deserialized signature if successful, or None if deserialization +/// fails. +pub fn deserialize_signature(signature: Span, chain_id: u64) -> Option { + let r_low: u128 = (*signature.at(0)).try_into()?; + let r_high: u128 = (*signature.at(1)).try_into()?; + + let s_low: u128 = (*signature.at(2)).try_into()?; + let s_high: u128 = (*signature.at(3)).try_into()?; + + let v: u128 = (*signature.at(4)).try_into()?; + + let odd_y_parity = if v == 0 { + false + } else if v == 1 { + true + } else { + compute_y_parity(v, chain_id)? + }; + + Option::Some( + Signature { + r: u256 { low: r_low, high: r_high }, + s: u256 { low: s_low, high: s_high }, + y_parity: odd_y_parity, + } + ) +} + +/// Computes the y-parity value for EIP-155 signature recovery. +/// +/// # Arguments +/// +/// * `v` - The v value from the signature. +/// * `chain_id` - The chain ID used for EIP-155 signature recovery. +/// +/// # Returns +/// +/// * `Option` - The computed y-parity value if valid, or None if invalid. +fn compute_y_parity(v: u128, chain_id: u64) -> Option { + let y_parity = v - (chain_id.into() * 2 + 35); + if (y_parity == 0 || y_parity == 1) { + return Option::Some(y_parity == 1); + } + + return Option::None; +} + +/// Serializes a transaction signature into an array of felt252 values. +/// +/// # Arguments +/// +/// * `sig` - The signature to serialize. +/// * `tx_type` - The transaction type (Legacy, EIP-2930, or EIP-1559). +/// * `chain_id` - The chain ID used for EIP-155 signature recovery. +/// +/// # Returns +/// +/// * `Array` - The serialized signature as an array of felt252 values. +pub fn serialize_transaction_signature( + sig: Signature, tx_type: TxType, chain_id: u64 +) -> Array { + let mut res: Array = array![ + sig.r.low.into(), sig.r.high.into(), sig.s.low.into(), sig.s.high.into() + ]; + + let value = match tx_type { + TxType::Legacy(_) => { sig.y_parity.into() + 2 * chain_id + 35 }, + TxType::Eip2930(_) | TxType::Eip1559(_) => { sig.y_parity.into() } + }; + + res.append(value.into()); + res +} + +/// Deserializes a span of felt252 values into an array of bytes. +/// +/// # Arguments +/// +/// * `self` - A span of felt252 values to deserialize. +/// +/// # Returns +/// +/// * `Option>` - The deserialized bytes if successful, or None if deserialization fails. +pub fn deserialize_bytes(self: Span) -> Option> { + let mut bytes: Array = Default::default(); + + for item in self { + let v: Option = (*item).try_into(); + + match v { + Option::Some(v) => { bytes.append(v); }, + Option::None => { break; } + } + }; + + // it means there was an error in the above loop + if (bytes.len() != self.len()) { + Option::None + } else { + Option::Some(bytes) + } +} + +/// Serializes a span of bytes into an array of felt252 values. +/// +/// # Arguments +/// +/// * `self` - A span of bytes to serialize. +/// +/// # Returns +/// +/// * `Array` - The serialized bytes as an array of felt252 values. +pub fn serialize_bytes(self: Span) -> Array { + let mut array: Array = Default::default(); + + for item in self { + let value: felt252 = (*item).into(); + array.append(value); + }; + + array +} + +#[cfg(test)] +mod tests { + use core::starknet::secp256_trait::Signature; + use crate::constants::CHAIN_ID; + use crate::eth_transaction::tx_type::TxType; + use crate::serialization::{deserialize_signature, serialize_transaction_signature}; + + #[test] + fn test_serialize_transaction_signature() { + // generated via ./scripts/compute_rlp_encoding.ts + // inputs: + // to: 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984 + // value: 1 + // gasLimit: 1 + // gasPrice: 1 + // nonce: 1 + // chainId: 1263227476 + // data: 0xabcdef + // tx_type: 0 for signature_0, 1 for signature_1, 2 for signature_2 + + // tx_type = 0, v: 0x9696a4cb + let signature_0 = Signature { + r: 0x306c3f638450a95f1f669481bf8ede9b056ef8d94259a3104f3a28673e02823d, + s: 0x41ea07e6d3d02773e380e752e5b3f9d28aca3882ee165e56b402cca0189967c9, + y_parity: false + }; + + // tx_type = 1 + let signature_1 = Signature { + r: 0x615c33039b7b09e3d5aa3cf1851c35abe7032f92111cc95ef45f83d032ccff5d, + s: 0x30b5f1a58abce1c7d45309b7a3b0befeddd1aee203021172779dd693a1e59505, + y_parity: false + }; + + // tx_type = 2 + let signature_2 = Signature { + r: 0xbc485ed0b43483ebe5fbff90962791c015755cc03060a33360b1b3e823bb71a4, + s: 0x4c47017509e1609db6c2e8e2b02327caeb709c986d8b63099695105432afa533, + y_parity: false + }; + + let expected_signature_0: Span = [ + signature_0.r.low.into(), + signature_0.r.high.into(), + signature_0.s.low.into(), + signature_0.s.high.into(), + 0x9696a4cb + ].span(); + + let expected_signature_1: Span = [ + signature_1.r.low.into(), + signature_1.r.high.into(), + signature_1.s.low.into(), + signature_1.s.high.into(), + 0x0_felt252, + ].span(); + + let expected_signature_2: Span = [ + signature_2.r.low.into(), + signature_2.r.high.into(), + signature_2.s.low.into(), + signature_2.s.high.into(), + 0x0_felt252, + ].span(); + + let result = serialize_transaction_signature(signature_0, TxType::Legacy, CHAIN_ID).span(); + assert_eq!(result, expected_signature_0); + + let result = serialize_transaction_signature(signature_1, TxType::Eip2930, CHAIN_ID).span(); + assert_eq!(result, expected_signature_1); + + let result = serialize_transaction_signature(signature_2, TxType::Eip1559, CHAIN_ID).span(); + assert_eq!(result, expected_signature_2); + } + + #[test] + fn test_deserialize_transaction_signature() { + // generated via ./scripts/compute_rlp_encoding.ts + // using json inputs + // to: 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984 + // value: 1 + // gasLimit: 1 + // gasPrice: 1 + // nonce: 1 + // chainId: 1263227476 + // data: 0xabcdef + // tx_type: 0 for signature_0, 1 for signature_1, 2 for signature_2 + + // tx_type = 0, v: 0x9696a4cb + let signature_0 = Signature { + r: 0x5e5202c7e9d6d0964a1f48eaecf12eef1c3cafb2379dfeca7cbd413cedd4f2c7, + s: 0x66da52d0b666fc2a35895e0c91bc47385fe3aa347c7c2a129ae2b7b06cb5498b, + y_parity: false + }; + + // tx_type = 1 + let signature_1 = Signature { + r: 0xbced8d81c36fe13c95b883b67898b47b4b70cae79e89fa27856ddf8c533886d1, + s: 0x3de0109f00bc3ed95ffec98edd55b6f750cb77be8e755935dbd6cfec59da7ad0, + y_parity: true + }; + + // tx_type = 2 + let signature_2 = Signature { + r: 0x0f9a716653c19fefc240d1da2c5759c50f844fc8835c82834ea3ab7755f789a0, + s: 0x71506d904c05c6e5ce729b5dd88bcf29db9461c8d72413b864923e8d8f6650c0, + y_parity: true + }; + + // tx_type = 2 with false y parity - cf input_eip1559_y_parity_false.json + let signature_3 = Signature { + r: 0x782ce82b688abbf13a5e7536b27be67d2795a28b9d4bf819120c17630d88e609, + s: 0x43b90a3315977fe71c9b3687a89857544158e23c5045e7a5852bae03323c9898, + y_parity: false + }; + + let signature_0_felt252_arr: Array = array![ + signature_0.r.low.into(), + signature_0.r.high.into(), + signature_0.s.low.into(), + signature_0.s.high.into(), + 0x9696a4cb + ]; + + let signature_1_felt252_arr: Array = array![ + signature_1.r.low.into(), + signature_1.r.high.into(), + signature_1.s.low.into(), + signature_1.s.high.into(), + 0x1 + ]; + + let signature_2_felt252_arr: Array = array![ + signature_2.r.low.into(), + signature_2.r.high.into(), + signature_2.s.low.into(), + signature_2.s.high.into(), + 0x1 + ]; + + let signature_3_felt252_arr: Array = array![ + signature_3.r.low.into(), + signature_3.r.high.into(), + signature_3.s.low.into(), + signature_3.s.high.into(), + 0x0 + ]; + + let result: Signature = deserialize_signature(signature_0_felt252_arr.span(), CHAIN_ID) + .unwrap(); + assert_eq!(result, signature_0); + + let result: Signature = deserialize_signature(signature_1_felt252_arr.span(), CHAIN_ID) + .unwrap(); + assert_eq!(result, signature_1); + + let result: Signature = deserialize_signature(signature_2_felt252_arr.span(), CHAIN_ID) + .unwrap(); + assert_eq!(result, signature_2); + + let result: Signature = deserialize_signature(signature_3_felt252_arr.span(), CHAIN_ID) + .unwrap(); + assert_eq!(result, signature_3); + } +} diff --git a/kakarot-ssj/crates/utils/src/set.cairo b/kakarot-ssj/crates/utils/src/set.cairo new file mode 100644 index 000000000..1b654bd53 --- /dev/null +++ b/kakarot-ssj/crates/utils/src/set.cairo @@ -0,0 +1,281 @@ +use crate::traits::array::{SpanExtTrait, ArrayExtTrait}; + +/// A set implementation using an array as the underlying storage. +/// We are not using dicts because of the Destruct requirements. +#[derive(Drop, PartialEq)] +pub struct Set { + inner: Array +} + +pub impl SetDefault> of Default> { + #[inline] + fn default() -> Set { + let arr: Array = Default::default(); + Set { inner: arr } + } +} + +#[generate_trait] +pub impl SetImpl, +Copy> of SetTrait { + /// Creates a new, empty Set. + /// + /// # Returns + /// + /// A new, empty Set. + #[inline] + fn new() -> Set { + Set { inner: Default::default() } + } + + /// Creates a Set from an existing Array. + /// + /// # Arguments + /// + /// * `arr` - The Array to create the Set from. + /// + /// # Returns + /// + /// A new Set containing the elements from the input Array. + fn from_array(arr: Array) -> Set { + Set { inner: arr } + } + + /// Adds an item to the Set if it's not already present. + /// + /// # Arguments + /// + /// * `item` - The item to add to the Set. + #[inline] + fn add<+PartialEq>(ref self: Set, item: T) { + self.inner.append_unique(item); + } + + /// Extends the Set with elements from another SpanSet. + /// + /// # Arguments + /// + /// * `other` - The SpanSet to extend from. + #[inline] + fn extend<+PartialEq>(ref self: Set, other: SpanSet) { + self.extend_from_span(other.to_span()); + } + + /// Extends the Set with elements from a Span. + /// + /// # Arguments + /// + /// * `other` - The Span to extend from. + #[inline] + fn extend_from_span<+PartialEq>(ref self: Set, mut other: Span) { + for v in other { + self.add(*v); + }; + } + + /// Checks if the Set contains a specific item. + /// + /// # Arguments + /// + /// * `item` - The item to check for. + /// + /// # Returns + /// + /// `true` if the item is in the Set, `false` otherwise. + #[inline] + fn contains<+PartialEq>(self: @Set, item: T) -> bool { + self.inner.span().contains(item) + } + + /// Converts the Set to an Array. + /// + /// # Returns + /// + /// An Array containing all elements of the Set. + #[inline] + fn to_array(self: Set) -> Array { + self.inner + } + + /// Converts the Set to a Span. + /// + /// # Returns + /// + /// A Span view of the Set's elements. + #[inline] + fn to_span(self: @Set) -> Span { + self.inner.span() + } + + /// Creates a SpanSet from this Set. + /// + /// # Returns + /// + /// A SpanSet view of this Set. + #[inline] + fn spanset(self: @Set) -> SpanSet { + SpanSet { inner: self } + } + + /// Returns the number of elements in the Set. + /// + /// # Returns + /// + /// The number of elements in the Set. + #[inline] + fn len(self: @Set) -> usize { + self.inner.span().len() + } +} + +pub impl SetTCloneImpl, +Drop, +PartialEq, +Copy> of Clone> { + fn clone(self: @Set) -> Set { + let mut response: Array = Default::default(); + let mut span = self.to_span(); + for v in span { + response.append(*v); + }; + Set { inner: response } + } +} + +/// A read-only view of a Set. +#[derive(Copy, Drop, PartialEq)] +pub struct SpanSet { + inner: @Set +} + +/// Default implementation for SpanSet. +pub impl SpanSetDefault> of Default> { + /// Creates a new, empty SpanSet. + /// + /// # Returns + /// + /// A new, empty SpanSet. + #[inline] + fn default() -> SpanSet { + let set: Set = Default::default(); + SpanSet { inner: @set } + } +} + +#[generate_trait] +pub impl SpanSetImpl, +Drop> of SpanSetTrait { + /// Checks if the SpanSet contains a specific item. + /// + /// # Arguments + /// + /// * `item` - The item to check for. + /// + /// # Returns + /// + /// `true` if the item is in the SpanSet, `false` otherwise. + #[inline] + fn contains<+PartialEq>(self: SpanSet, item: T) -> bool { + self.inner.contains(item) + } + + /// Converts the SpanSet to a Span. + /// + /// # Returns + /// + /// A Span view of the SpanSet's elements. + #[inline] + fn to_span(self: SpanSet) -> Span { + self.inner.to_span() + } + + /// Creates a new Set from this SpanSet. + /// + /// # Returns + /// + /// A new Set with the same elements as this SpanSet. + fn clone_set(self: SpanSet) -> Set { + let mut response: Array = Default::default(); + let mut span = self.to_span(); + for v in span { + response.append(*v); + }; + Set { inner: response } + } + + /// Returns the number of elements in the SpanSet. + /// + /// # Returns + /// + /// The number of elements in the SpanSet. + #[inline] + fn len(self: SpanSet) -> usize { + self.inner.len() + } +} + +#[cfg(test)] +mod tests { + use crate::set::{Set, SetTrait, SpanSet, SpanSetTrait}; + + #[test] + fn test_add() { + let mut set: Set = Default::default(); + set.add(1); + set.add(2); + set.add(3); + set.add(3); + assert_eq!(set.len(), 3); + assert_eq!(set.contains(1), true); + assert_eq!(set.contains(2), true); + assert_eq!(set.contains(3), true); + assert_eq!(set.contains(4), false); + } + + #[test] + fn test_clone() { + let mut set: Set = Default::default(); + set.add(1); + set.add(2); + set.add(3); + set.add(3); + let mut set2 = set.clone(); + assert!(set == set2); + set2.add(4); + assert_eq!(set.len(), 3); + assert_eq!(set2.len(), 4); + assert_eq!(set.contains(1), true); + assert_eq!(set.contains(2), true); + assert_eq!(set.contains(3), true); + assert_eq!(set.contains(4), false); + assert_eq!(set2.contains(1), true); + assert_eq!(set2.contains(2), true); + assert_eq!(set2.contains(3), true); + assert_eq!(set2.contains(4), true); + } + + #[test] + fn test_spanset_clone_set() { + let mut set: Set = Default::default(); + set.add(1); + set.add(2); + let span_set = SpanSet { inner: @set }; + let set2 = span_set.clone_set(); + assert!(set == set2); + } + + #[test] + fn test_set_extend() { + let mut other: Set = Default::default(); + other.add(2); + other.add(1); + let other = other.spanset(); + + let mut set: Set = Default::default(); + set.add(3); + set.add(4); + set.extend(other); + + assert_eq!(set.len(), 4); + assert_eq!(set.contains(1), true); + assert_eq!(set.contains(2), true); + assert_eq!(set.contains(3), true); + assert_eq!(set.contains(4), true); + assert_eq!(set.contains(5), false); + } +} diff --git a/kakarot-ssj/crates/utils/src/test_data.cairo b/kakarot-ssj/crates/utils/src/test_data.cairo new file mode 100644 index 000000000..b9084552b --- /dev/null +++ b/kakarot-ssj/crates/utils/src/test_data.cairo @@ -0,0 +1,421 @@ +pub fn legacy_rlp_encoded_tx() -> Span { + // tx_format (EIP-155, unsigned): [nonce, gasPrice, gasLimit, to, value, data, chainId, 0, 0] + // expected rlp decoding: [ "0x", "0x3b9aca00", "0x1e8480", + // "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984", "0x016345785d8a0000", "0xabcdef", "0x4b4b5254", + // "0x", "0x" ] + // message_hash: 0xcf71743e6e25fef715398915997f782b95554c8bbfb7b3f7701e007332ed31b4 + // chain id used: 'KKRT' + [ + 243, + 128, + 132, + 59, + 154, + 202, + 0, + 131, + 30, + 132, + 128, + 148, + 31, + 152, + 64, + 168, + 93, + 90, + 245, + 191, + 29, + 23, + 98, + 249, + 37, + 189, + 173, + 220, + 66, + 1, + 249, + 132, + 136, + 1, + 99, + 69, + 120, + 93, + 138, + 0, + 0, + 131, + 171, + 205, + 239, + 132, + 75, + 75, + 82, + 84, + 128, + 128, + ].span() +} + +pub fn legacy_rlp_encoded_deploy_tx() -> Span { + // tx_format (EIP-155, unsigned): [nonce, gasPrice, gasLimit, to, value, data, chainId, 0, 0] + // expected rlp decoding: + // ["0x","0x0a","0x061a80","0x","0x0186a0","0x600160010a5060006000f3","0x4b4b5254","0x","0x"] + [ + 222, + 128, + 10, + 131, + 6, + 26, + 128, + 128, + 131, + 1, + 134, + 160, + 139, + 96, + 1, + 96, + 1, + 10, + 80, + 96, + 0, + 96, + 0, + 243, + 132, + 75, + 75, + 82, + 84, + 128, + 128, + ].span() +} + + +pub fn eip_2930_encoded_tx() -> Span { + // tx_format (EIP-2930, unsigned): 0x01 || rlp([chainId, nonce, gasPrice, gasLimit, to, value, + // data, accessList]) + // expected rlp decoding: [ "0x4b4b5254", "0x", "0x3b9aca00", "0x1e8480", + // "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984", "0x016345785d8a0000", "0xabcdef", + // [["0x1f9840a85d5af5bf1d1762f925bdaddc4201f984", + // ["0xde9fbe35790b85c23f42b7430c78f122636750cc217a534c80a9a0520969fa65", + // "0xd5362e94136f76bfc8dad0b510b94561af7a387f1a9d0d45e777c11962e5bd94"]]] ] + // message_hash: 0xc00f61dcc99a78934275c404267b9d035cad7f71cf3ae2ed2c5a55b601a5c107 + // chain id used: 'KKRT' + [ + 1, + 248, + 142, + 132, + 75, + 75, + 82, + 84, + 128, + 132, + 59, + 154, + 202, + 0, + 131, + 30, + 132, + 128, + 148, + 31, + 152, + 64, + 168, + 93, + 90, + 245, + 191, + 29, + 23, + 98, + 249, + 37, + 189, + 173, + 220, + 66, + 1, + 249, + 132, + 136, + 1, + 99, + 69, + 120, + 93, + 138, + 0, + 0, + 131, + 171, + 205, + 239, + 248, + 91, + 248, + 89, + 148, + 31, + 152, + 64, + 168, + 93, + 90, + 245, + 191, + 29, + 23, + 98, + 249, + 37, + 189, + 173, + 220, + 66, + 1, + 249, + 132, + 248, + 66, + 160, + 222, + 159, + 190, + 53, + 121, + 11, + 133, + 194, + 63, + 66, + 183, + 67, + 12, + 120, + 241, + 34, + 99, + 103, + 80, + 204, + 33, + 122, + 83, + 76, + 128, + 169, + 160, + 82, + 9, + 105, + 250, + 101, + 160, + 213, + 54, + 46, + 148, + 19, + 111, + 118, + 191, + 200, + 218, + 208, + 181, + 16, + 185, + 69, + 97, + 175, + 122, + 56, + 127, + 26, + 157, + 13, + 69, + 231, + 119, + 193, + 25, + 98, + 229, + 189, + 148, + ].span() +} + +pub fn eip_1559_encoded_tx() -> Span { + // tx_format (EIP-1559, unsigned): 0x02 || rlp([chain_id, nonce, max_priority_fee_per_gas, + // max_fee_per_gas, gas_limit, destination, amount, data, access_list]) + // expected rlp decoding: [ "0x4b4b5254", "0x", "0x", "0x3b9aca00", "0x1e8480", + // "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984", "0x016345785d8a0000", "0xabcdef", + // [[["0x1f9840a85d5af5bf1d1762f925bdaddc4201f984", + // ["0xde9fbe35790b85c23f42b7430c78f122636750cc217a534c80a9a0520969fa65", + // "0xd5362e94136f76bfc8dad0b510b94561af7a387f1a9d0d45e777c11962e5bd94"]]] ] ] + // message_hash: 0xa2de478d0c94b4be637523b818d03b6a1841fca63fd044976fcdbef3c57a87b0 + // chain id used: 'KKRT' + [ + 2, + 248, + 143, + 132, + 75, + 75, + 82, + 84, + 128, + 128, + 132, + 59, + 154, + 202, + 0, + 131, + 30, + 132, + 128, + 148, + 31, + 152, + 64, + 168, + 93, + 90, + 245, + 191, + 29, + 23, + 98, + 249, + 37, + 189, + 173, + 220, + 66, + 1, + 249, + 132, + 136, + 1, + 99, + 69, + 120, + 93, + 138, + 0, + 0, + 131, + 171, + 205, + 239, + 248, + 91, + 248, + 89, + 148, + 31, + 152, + 64, + 168, + 93, + 90, + 245, + 191, + 29, + 23, + 98, + 249, + 37, + 189, + 173, + 220, + 66, + 1, + 249, + 132, + 248, + 66, + 160, + 222, + 159, + 190, + 53, + 121, + 11, + 133, + 194, + 63, + 66, + 183, + 67, + 12, + 120, + 241, + 34, + 99, + 103, + 80, + 204, + 33, + 122, + 83, + 76, + 128, + 169, + 160, + 82, + 9, + 105, + 250, + 101, + 160, + 213, + 54, + 46, + 148, + 19, + 111, + 118, + 191, + 200, + 218, + 208, + 181, + 16, + 185, + 69, + 97, + 175, + 122, + 56, + 127, + 26, + 157, + 13, + 69, + 231, + 119, + 193, + 25, + 98, + 229, + 189, + 148, + ].span() +} diff --git a/kakarot-ssj/crates/utils/src/traits.cairo b/kakarot-ssj/crates/utils/src/traits.cairo new file mode 100644 index 000000000..e5bfc3eb8 --- /dev/null +++ b/kakarot-ssj/crates/utils/src/traits.cairo @@ -0,0 +1,162 @@ +pub mod array; +pub mod bytes; +pub mod eth_address; +pub mod integer; + +use core::array::SpanTrait; +use core::num::traits::{Zero, One}; +use core::starknet::secp256_trait::{Signature}; +use core::starknet::storage_access::{StorageBaseAddress, storage_address_from_base}; +use core::starknet::{EthAddress, ContractAddress}; +use crate::math::{Bitshift}; +use evm::errors::{EVMError, ensure, TYPE_CONVERSION_ERROR}; + +pub impl DefaultSignature of Default { + #[inline(always)] + fn default() -> Signature { + Signature { r: 0, s: 0, y_parity: false, } + } +} + +pub impl SpanDefault> of Default> { + #[inline(always)] + fn default() -> Span { + array![].span() + } +} + +pub impl EthAddressDefault of Default { + #[inline(always)] + fn default() -> EthAddress { + 0.try_into().unwrap() + } +} + +pub impl ContractAddressDefault of Default { + #[inline(always)] + fn default() -> ContractAddress { + 0.try_into().unwrap() + } +} + +pub impl BoolIntoNumeric, +One> of Into { + #[inline(always)] + fn into(self: bool) -> T { + if self { + One::::one() + } else { + Zero::::zero() + } + } +} + +pub impl NumericIntoBool, +Zero, +One, +PartialEq> of Into { + #[inline(always)] + fn into(self: T) -> bool { + self != Zero::::zero() + } +} + +pub impl EthAddressIntoU256 of Into { + fn into(self: EthAddress) -> u256 { + let intermediate: felt252 = self.into(); + intermediate.into() + } +} + +pub impl U256TryIntoContractAddress of TryInto { + fn try_into(self: u256) -> Option { + let maybe_value: Option = self.try_into(); + match maybe_value { + Option::Some(value) => value.try_into(), + Option::None => Option::None, + } + } +} + +pub impl StorageBaseAddressIntoU256 of Into { + fn into(self: StorageBaseAddress) -> u256 { + let self: felt252 = storage_address_from_base(self).into(); + self.into() + } +} + +//TODO remove once merged in corelib +pub impl StorageBaseAddressPartialEq of PartialEq { + fn eq(lhs: @StorageBaseAddress, rhs: @StorageBaseAddress) -> bool { + let lhs: felt252 = (*lhs).into(); + let rhs: felt252 = (*rhs).into(); + lhs == rhs + } + fn ne(lhs: @StorageBaseAddress, rhs: @StorageBaseAddress) -> bool { + !(*lhs == *rhs) + } +} + +pub trait TryIntoResult { + fn try_into_result(self: T) -> Result; +} + +pub impl SpanU8TryIntoResultEthAddress of TryIntoResult, EthAddress> { + fn try_into_result(mut self: Span) -> Result { + let len = self.len(); + if len == 0 { + return Result::Ok(0.try_into().unwrap()); + } + ensure(!(len > 20), EVMError::TypeConversionError(TYPE_CONVERSION_ERROR))?; + let offset: u32 = len.into() - 1; + let mut result: u256 = 0; + for i in 0 + ..len { + let byte: u256 = (*self.at(i)).into(); + result += byte.shl(8 * (offset - i).into()); + }; + let address: felt252 = result.try_into_result()?; + + Result::Ok(address.try_into().unwrap()) + } +} + +pub impl EthAddressTryIntoResultContractAddress of TryIntoResult { + fn try_into_result(self: ContractAddress) -> Result { + let tmp: felt252 = self.into(); + tmp.try_into().ok_or(EVMError::TypeConversionError(TYPE_CONVERSION_ERROR)) + } +} + +pub impl U256TryIntoResult> of TryIntoResult { + fn try_into_result(self: u256) -> Result { + match self.try_into() { + Option::Some(value) => Result::Ok(value), + Option::None => Result::Err(EVMError::TypeConversionError(TYPE_CONVERSION_ERROR)) + } + } +} + +pub impl U8IntoEthAddress of Into { + fn into(self: u8) -> EthAddress { + let value: felt252 = self.into(); + value.try_into().unwrap() + } +} + +#[cfg(test)] +mod tests { + use core::starknet::storage_access::storage_base_address_from_felt252; + use crate::traits::{StorageBaseAddressPartialEq}; + + #[test] + fn test_eq_storage_base_address() { + let val_1 = storage_base_address_from_felt252(0x01); + + assert_eq!(@val_1, @val_1) + } + + #[test] + fn test_ne_storage_base_address() { + let val_1 = storage_base_address_from_felt252(0x01); + let val_2 = storage_base_address_from_felt252(0x02); + + assert_ne!(@val_1, @val_2) + } +} diff --git a/kakarot-ssj/crates/utils/src/traits/array.cairo b/kakarot-ssj/crates/utils/src/traits/array.cairo new file mode 100644 index 000000000..35b3669f7 --- /dev/null +++ b/kakarot-ssj/crates/utils/src/traits/array.cairo @@ -0,0 +1,143 @@ +#[generate_trait] +pub impl ArrayExtension> of ArrayExtTrait { + /// Concatenates two arrays by adding the elements of `arr2` to `self`. + /// + /// # Arguments + /// + /// * `self` - The array to append to. + /// * `arr2` - The array to append from. + fn concat<+Copy>(ref self: Array, mut arr2: Span) { + for elem in arr2 { + self.append(*elem); + }; + } + + /// Reverses an array. + /// + /// # Arguments + /// + /// * `self` - The array to reverse. + /// + /// # Returns + /// + /// A new `Array` with the elements in reverse order. + fn reverse<+Copy>(self: Span) -> Array { + let mut counter = self.len(); + let mut dst: Array = ArrayTrait::new(); + while counter != 0 { + dst.append(*self[counter - 1]); + counter -= 1; + }; + dst + } + + /// Appends a value to the array `n` times. + /// + /// # Arguments + /// + /// * `self` - The array to append to. + /// * `value` - The value to append. + /// * `n` - The number of times to append the value. + fn append_n<+Copy>(ref self: Array, value: T, mut n: usize) { + for _ in 0..n { + self.append(value); + }; + } + + /// Appends an item only if it is not already in the array. + /// + /// # Arguments + /// + /// * `self` - The array to append to. + /// * `value` - The value to append if not present. + fn append_unique<+Copy, +PartialEq>(ref self: Array, value: T) { + if self.span().contains(value) { + return (); + } + self.append(value); + } + + /// Concatenates two arrays by adding the unique elements of `arr2` to `self`. + /// + /// # Arguments + /// + /// * `self` - The array to append to. + /// * `arr2` - The array to append from. + fn concat_unique<+Copy, +PartialEq>(ref self: Array, mut arr2: Span) { + for elem in arr2 { + self.append_unique(*elem) + }; + } +} + +#[generate_trait] +pub impl SpanExtension, +Drop> of SpanExtTrait { + /// Returns true if the array contains an item. + /// + /// # Arguments + /// + /// * `self` - The array to search. + /// * `value` - The value to search for. + /// + /// # Returns + /// + /// `true` if the value is found, `false` otherwise. + fn contains<+PartialEq>(mut self: Span, value: T) -> bool { + let mut result = false; + for elem in self { + if *elem == value { + result = true; + } + }; + result + } + + /// Returns the index of an item in the array. + /// + /// # Arguments + /// + /// * `self` - The array to search. + /// * `value` - The value to search for. + /// + /// # Returns + /// + /// `Option::Some(index)` if the value is found, `Option::None` otherwise. + fn index_of<+PartialEq>(mut self: Span, value: T) -> Option { + let mut i = 0; + let mut result = Option::None; + for elem in self { + if *elem == value { + result = Option::Some(i); + } + i += 1; + }; + return result; + } +} + +#[cfg(test)] +mod tests { + mod test_array_ext { + use super::super::{ArrayExtTrait}; + #[test] + fn test_append_n() { + // Given + let mut original: Array = array![1, 2, 3, 4]; + + // When + original.append_n(9, 3); + + // Then + assert(original == array![1, 2, 3, 4, 9, 9, 9], 'append_n failed'); + } + + #[test] + fn test_append_unique() { + let mut arr = array![1, 2, 3]; + arr.append_unique(4); + assert(arr == array![1, 2, 3, 4], 'should have appended'); + arr.append_unique(2); + assert(arr == array![1, 2, 3, 4], 'shouldnt have appended'); + } + } +} diff --git a/kakarot-ssj/crates/utils/src/traits/bytes.cairo b/kakarot-ssj/crates/utils/src/traits/bytes.cairo new file mode 100644 index 000000000..6cec31aee --- /dev/null +++ b/kakarot-ssj/crates/utils/src/traits/bytes.cairo @@ -0,0 +1,820 @@ +use core::cmp::min; +use core::keccak::{cairo_keccak}; +use core::num::traits::{Zero, One, Bounded, BitSize, SaturatingAdd}; +use core::traits::{BitAnd}; +use crate::constants::{POW_2, POW_256_1, POW_256_REV}; +use crate::math::{Bitshift}; +use crate::traits::integer::{BytesUsedTrait, ByteSize, U256Trait}; + +#[generate_trait] +pub impl U8SpanExImpl of U8SpanExTrait { + /// Computes the keccak256 hash of a bytes message + /// # Arguments + /// * `self` - The input bytes as a Span + /// # Returns + /// * The keccak256 hash as a u256 + fn compute_keccak256_hash(self: Span) -> u256 { + let (mut keccak_input, last_input_word, last_input_num_bytes) = self.to_u64_words(); + let hash = cairo_keccak(ref keccak_input, :last_input_word, :last_input_num_bytes) + .reverse_endianness(); + + hash + } + + /// Transforms a Span into an Array of u64 full words, a pending u64 word and its length in + /// bytes + /// # Arguments + /// * `self` - The input bytes as a Span + /// # Returns + /// * A tuple containing: + /// - An Array of full words + /// - A u64 representing the last (potentially partial) word + /// - A usize representing the number of bytes in the last word + fn to_u64_words(self: Span) -> (Array, u64, usize) { + let nonzero_8: NonZero = 8_u32.try_into().unwrap(); + let (full_u64_word_count, last_input_num_bytes) = DivRem::div_rem(self.len(), nonzero_8); + + let mut u64_words: Array = Default::default(); + let mut byte_counter: u8 = 0; + let mut pending_word: u64 = 0; + let mut u64_word_counter: usize = 0; + + while u64_word_counter != full_u64_word_count { + if byte_counter == 8 { + u64_words.append(pending_word); + byte_counter = 0; + pending_word = 0; + u64_word_counter += 1; + } + pending_word += match self.get(u64_word_counter * 8 + byte_counter.into()) { + Option::Some(byte) => { + let byte: u64 = (*byte.unbox()).into(); + // Accumulate pending_word in a little endian manner + byte.shl(8_u64 * byte_counter.into()) + }, + Option::None => { break; }, + }; + byte_counter += 1; + }; + + // Fill the last input word + let mut last_input_word: u64 = 0; + + // We enter a second loop for clarity. + // O(2n) should be okay + // We might want to regroup every computation into a single loop with appropriate `if` + // branching For optimisation + for byte_counter in 0 + ..last_input_num_bytes { + last_input_word += match self.get(full_u64_word_count * 8 + byte_counter.into()) { + Option::Some(byte) => { + let byte: u64 = (*byte.unbox()).into(); + byte.shl(8_u64 * byte_counter.into()) + }, + Option::None => { break; }, + }; + }; + + (u64_words, last_input_word, last_input_num_bytes) + } + + /// Returns right padded slice of the span, starting from index offset + /// If offset is greater than the span length, returns an empty span + /// # Examples + /// + /// ``` + /// let span = [0x0, 0x01, 0x02, 0x03, 0x04, 0x05].span(); + /// let expected = [0x04, 0x05, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0].span(); + /// let result = span.slice_right_padded(4, 10); + /// assert_eq!(result, expected); + /// ``` + /// # Arguments + /// * `offset` - The offset to start the slice from + /// * `len` - The length of the slice + /// + /// # Returns + /// * A span of length `len` starting from `offset` right padded with 0s if `offset` is greater + /// than the span length, returns an empty span of length `len` if offset is grearter than the + /// span length + fn slice_right_padded(self: Span, offset: usize, len: usize) -> Span { + let start = if offset <= self.len() { + offset + } else { + self.len() + }; + + let end = min(start.saturating_add(len), self.len()); + + let slice = self.slice(start, end - start); + // Save appending to span for this case as it is more efficient to just return the slice + if slice.len() == len { + return slice; + } + + // Copy the span + let mut arr = array![]; + arr.append_span(slice); + + while arr.len() != len { + arr.append(0); + }; + + arr.span() + } + + /// Clones and pads the given span with 0s to the right to the given length + /// If data is more than the given length, it is truncated from the right side + /// # Arguments + /// * `self` - The input bytes as a Span + /// * `len` - The desired length of the padded span + /// # Returns + /// * A Span of length `len` right padded with 0s if the span length is less than `len`, + /// or truncated from the right if the span length is greater than `len` + /// # Examples + /// ``` + /// let span = array![1, 2, 3].span(); + /// let padded = span.pad_right_with_zeroes(5); + /// assert_eq!(padded, array![1, 2, 3, 0, 0].span()); + /// ``` + fn pad_right_with_zeroes(self: Span, len: usize) -> Span { + if self.len() >= len { + return self.slice(0, len); + } + + // Create a new array with the original data + let mut arr = array![]; + for i in self { + arr.append(*i); + }; + + // Pad with zeroes + while arr.len() != len { + arr.append(0); + }; + + arr.span() + } + + + /// Clones and pads the given span with 0s to the left to the given length + /// If data is more than the given length, it is truncated from the right side + /// # Arguments + /// * `self` - The input bytes as a Span + /// * `len` - The desired length of the padded span + /// # Returns + /// * A Span of length `len` left padded with 0s if the span length is less than `len`, + /// or truncated from the right if the span length is greater than `len` + /// # Examples + /// ``` + /// let span = array![1, 2, 3].span(); + /// let padded = span.pad_left_with_zeroes(5); + /// assert_eq!(padded, array![0, 0, 1, 2, 3].span()); + /// ``` + fn pad_left_with_zeroes(self: Span, len: usize) -> Span { + if self.len() >= len { + return self.slice(0, len); + } + + // left pad with 0 + let mut arr = array![]; + while arr.len() != (len - self.len()) { + arr.append(0); + }; + + // append the data + for item in self { + arr.append(*item); + }; + + arr.span() + } +} + +pub trait ToBytes { + /// Unpacks a type T into a span of big endian bytes + /// + /// # Arguments + /// * `self` a value of type T. + /// + /// # Returns + /// * The bytes representation of the value in big endian. + fn to_be_bytes(self: T) -> Span; + /// Unpacks a type T into a span of big endian bytes, padded to the byte size of T + /// + /// # Arguments + /// * `self` a value of type T. + /// + /// # Returns + /// * The bytesrepresentation of the value in big endian padded to the byte size of T. + fn to_be_bytes_padded(self: T) -> Span; + /// Unpacks a type T into a span of little endian bytes + /// + /// # Arguments + /// * `self` a value of type T. + /// + /// # Returns + /// * The bytes representation of the value in little endian. + fn to_le_bytes(self: T) -> Span; + /// Unpacks a type T into a span of little endian bytes, padded to the byte size of T + /// + /// # Arguments + /// * `self` a value of type T. + /// + /// # Returns + /// * The bytesrepresentation of the value in little endian padded to the byte size of T. + fn to_le_bytes_padded(self: T) -> Span; +} + +pub impl ToBytesImpl< + T, + +Zero, + +One, + +Add, + +Sub, + +Mul, + +BitAnd, + +Bitshift, + +BitSize, + +BytesUsedTrait, + +Into, + +TryInto, + +Copy, + +Drop, + +core::ops::AddAssign, + +PartialEq +> of ToBytes { + fn to_be_bytes(self: T) -> Span { + let bytes_used = self.bytes_used(); + + let one = One::::one(); + let two = one + one; + let eight = two * two * two; + + // 0xFF + let mask = Bounded::::MAX.into(); + + let mut bytes: Array = Default::default(); + for i in 0 + ..bytes_used { + let val = Bitshift::::shr(self, eight * (bytes_used - i - 1).into()); + bytes.append((val & mask).try_into().unwrap()); + }; + + bytes.span() + } + + fn to_be_bytes_padded(mut self: T) -> Span { + let padding = (BitSize::::bits() / 8); + self.to_be_bytes().pad_left_with_zeroes(padding) + } + + fn to_le_bytes(mut self: T) -> Span { + let bytes_used = self.bytes_used(); + let one = One::::one(); + let two = one + one; + let eight = two * two * two; + + // 0xFF + let mask = Bounded::::MAX.into(); + + let mut bytes: Array = Default::default(); + + for i in 0 + ..bytes_used { + let val = self.shr(eight * i.into()); + bytes.append((val & mask).try_into().unwrap()); + }; + + bytes.span() + } + + fn to_le_bytes_padded(mut self: T) -> Span { + let padding = (BitSize::::bits() / 8); + self.to_le_bytes().slice_right_padded(0, padding) + } +} + +pub trait FromBytes { + /// Parses a span of big endian bytes into a type T + /// + /// # Arguments + /// * `self` a span of big endian bytes. + /// + /// # Returns + /// * The Option::(value) represented by the bytes in big endian, Option::None if the span is + /// not the byte size of T. + fn from_be_bytes(self: Span) -> Option; + + /// Parses a span of big endian bytes into a type T, allowing for partial input + /// + /// # Arguments + /// * `self` a span of big endian bytes. + /// + /// # Returns + /// * The Option::(value) represented by the bytes in big endian, Option::None if the span is + /// longer than the byte size of T. + fn from_be_bytes_partial(self: Span) -> Option; + + + /// Parses a span of little endian bytes into a type T + /// + /// # Arguments + /// * `self` a span of little endian bytes. + /// + /// # Returns + /// * The Option::(value) represented by the bytes in little endian, Option::None if the span is + /// not the byte size of T. + fn from_le_bytes(self: Span) -> Option; + + /// Parses a span of little endian bytes into a type T, allowing for partial input + /// + /// # Arguments + /// * `self` a span of little endian bytes. + /// + /// # Returns + /// * The Option::(value) represented by the bytes in little endian, Option::None if the span is + /// longer than the byte size of T. + fn from_le_bytes_partial(self: Span) -> Option; +} + +pub impl FromBytesImpl< + T, + +Zero, + +One, + +Add, + +Sub, + +Mul, + +BitAnd, + +Bitshift, + +ByteSize, + +BytesUsedTrait, + +Into, + +Into, + +TryInto, + +Copy, + +Drop, + +core::ops::AddAssign, + +PartialEq +> of FromBytes { + fn from_be_bytes(self: Span) -> Option { + let byte_size = ByteSize::::byte_size(); + + if self.len() != byte_size { + return Option::None; + } + + let mut result: T = Zero::zero(); + for byte in self { + let tmp = result * 256_u16.into(); + result = tmp + (*byte).into(); + }; + Option::Some(result) + } + + fn from_be_bytes_partial(self: Span) -> Option { + let byte_size = ByteSize::::byte_size(); + + if self.len() > byte_size { + return Option::None; + } + + let mut result: T = Zero::zero(); + for byte in self { + let tmp = result * 256_u16.into(); + result = tmp + (*byte).into(); + }; + + Option::Some(result) + } + + fn from_le_bytes(self: Span) -> Option { + let byte_size = ByteSize::::byte_size(); + + if self.len() != byte_size { + return Option::None; + } + + let mut result: T = Zero::zero(); + let mut i = self.len(); + while i != 0 { + i -= 1; + let tmp = result * 256_u16.into(); + result = tmp + (*self[i]).into(); + }; + Option::Some(result) + } + + fn from_le_bytes_partial(self: Span) -> Option { + let byte_size = ByteSize::::byte_size(); + + if self.len() > byte_size { + return Option::None; + } + + let mut result: T = Zero::zero(); + let mut i = self.len(); + while i != 0 { + i -= 1; + let tmp = result * 256_u16.into(); + result = tmp + (*self[i]).into(); + }; + Option::Some(result) + } +} + + +#[generate_trait] +pub impl ByteArrayExt of ByteArrayExTrait { + /// Appends a span of bytes to the ByteArray + /// # Arguments + /// * `self` - The ByteArray to append to + /// * `bytes` - The span of bytes to append + fn append_span_bytes(ref self: ByteArray, mut bytes: Span) { + for val in bytes { + self.append_byte(*val); + }; + } + + /// Creates a ByteArray from a span of bytes + /// # Arguments + /// * `bytes` - The span of bytes to convert + /// # Returns + /// * A new ByteArray containing the input bytes + fn from_bytes(mut bytes: Span) -> ByteArray { + let mut arr: ByteArray = Default::default(); + let (nb_full_words, pending_word_len) = DivRem::div_rem( + bytes.len(), 31_u32.try_into().unwrap() + ); + for _ in 0 + ..nb_full_words { + let mut word: felt252 = 0; + for _ in 0 + ..31_u8 { + word = word * POW_256_1.into() + (*bytes.pop_front().unwrap()).into(); + }; + arr.append_word(word.try_into().unwrap(), 31); + }; + + if pending_word_len == 0 { + return arr; + }; + + let mut pending_word: felt252 = 0; + + for _ in 0 + ..pending_word_len { + pending_word = pending_word * POW_256_1.into() + + (*bytes.pop_front().unwrap()).into(); + }; + arr.append_word(pending_word.try_into().unwrap(), pending_word_len); + arr + } + + /// Checks if the ByteArray is empty + /// # Arguments + /// * `self` - The ByteArray to check + /// # Returns + /// * true if the ByteArray is empty, false otherwise + fn is_empty(self: @ByteArray) -> bool { + self.len() == 0 + } + + /// Converts the ByteArray into a span of bytes + /// # Arguments + /// * `self` - The ByteArray to convert + /// # Returns + /// * A Span containing the bytes from the ByteArray + fn into_bytes(self: ByteArray) -> Span { + let mut output: Array = Default::default(); + for i in 0..self.len() { + output.append(self[i]); + }; + output.span() + } + + + /// Transforms a ByteArray into an Array of u64 full words, a pending u64 word and its length in + /// bytes + /// # Arguments + /// * `self` - The ByteArray to transform + /// # Returns + /// * A tuple containing: + /// - An Array of full words + /// - A u64 representing the last (potentially partial) word + /// - A usize representing the number of bytes in the last word + fn to_u64_words(self: ByteArray) -> (Array, u64, usize) { + // We pass it by value because we want to take ownership, but we snap it + // because `at` takes a snap and if this snap is automatically done by + // the compiler in the loop, it won't compile + let self = @self; + let nonzero_8: NonZero = 8_u32.try_into().unwrap(); + let (full_u64_word_count, last_input_num_bytes) = DivRem::div_rem(self.len(), nonzero_8); + + let mut u64_words: Array = Default::default(); + let mut byte_counter: u8 = 0; + let mut pending_word: u64 = 0; + let mut u64_word_counter: usize = 0; + + while u64_word_counter != full_u64_word_count { + if byte_counter == 8 { + u64_words.append(pending_word); + byte_counter = 0; + pending_word = 0; + u64_word_counter += 1; + } + pending_word += match self.at(u64_word_counter * 8 + byte_counter.into()) { + Option::Some(byte) => { + let byte: u64 = byte.into(); + // Accumulate pending_word in a little endian manner + byte.shl(8_u64 * byte_counter.into()) + }, + Option::None => { break; }, + }; + byte_counter += 1; + }; + + // Fill the last input word + let mut last_input_word: u64 = 0; + + // We enter a second loop for clarity. + // O(2n) should be okay + // We might want to regroup every computation into a single loop with appropriate `if` + // branching For optimisation + + for byte_counter in 0 + ..last_input_num_bytes { + last_input_word += match self.at(full_u64_word_count * 8 + byte_counter.into()) { + Option::Some(byte) => { + let byte: u64 = byte.into(); + byte.shl(8_u64 * byte_counter.into()) + }, + Option::None => { break; }, + }; + }; + + (u64_words, last_input_word, last_input_num_bytes) + } +} + + +#[cfg(test)] +mod tests { + mod bytearray_test { + use super::super::{ByteArrayExTrait}; + #[test] + fn test_pack_bytes_ge_bytes31() { + let mut arr = array![ + 0x01, + 0x02, + 0x03, + 0x04, + 0x05, + 0x06, + 0x07, + 0x08, + 0x09, + 0x0A, + 0x0B, + 0x0C, + 0x0D, + 0x0E, + 0x0F, + 0x10, + 0x11, + 0x12, + 0x13, + 0x14, + 0x15, + 0x16, + 0x17, + 0x18, + 0x19, + 0x1A, + 0x1B, + 0x1C, + 0x1D, + 0x1E, + 0x1F, + 0x20, + 0x21 // 33 elements + ]; + + let res = ByteArrayExTrait::from_bytes(arr.span()); + + // Ensure that the result is complete and keeps the same order + for i in 0..arr.len() { + assert(*arr[i] == res[i], 'byte mismatch'); + }; + } + + #[test] + fn test_bytearray_append_span_bytes() { + let bytes = array![0x01, 0x02, 0x03, 0x04]; + let mut byte_arr: ByteArray = Default::default(); + byte_arr.append_byte(0xFF); + byte_arr.append_byte(0xAA); + byte_arr.append_span_bytes(bytes.span()); + assert_eq!(byte_arr.len(), 6); + assert_eq!(byte_arr[0], 0xFF); + assert_eq!(byte_arr[1], 0xAA); + assert_eq!(byte_arr[2], 0x01); + assert_eq!(byte_arr[3], 0x02); + assert_eq!(byte_arr[4], 0x03); + assert_eq!(byte_arr[5], 0x04); + } + + #[test] + fn test_byte_array_into_bytes() { + let input = array![ + 0x01, + 0x02, + 0x03, + 0x04, + 0x05, + 0x06, + 0x07, + 0x08, + 0x09, + 0x0A, + 0x0B, + 0x0C, + 0x0D, + 0x0E, + 0x0F, + 0x10, + 0x11, + 0x12, + 0x13, + 0x14, + 0x15, + 0x16, + 0x17, + 0x18, + 0x19, + 0x1A, + 0x1B, + 0x1C, + 0x1D, + 0x1E, + 0x1F, + 0x20, + 0x21 // 33 elements + ]; + let byte_array = ByteArrayExTrait::from_bytes(input.span()); + let res = byte_array.into_bytes(); + + // Ensure that the elements are correct + assert(res == input.span(), 'bytes mismatch'); + } + + #[test] + fn test_pack_bytes_le_bytes31() { + let mut arr = array![0x11, 0x22, 0x33, 0x44]; + let res = ByteArrayExTrait::from_bytes(arr.span()); + + // Ensure that the result is complete and keeps the same order + for i in 0..arr.len() { + assert(*arr[i] == res[i], 'byte mismatch'); + }; + } + + + #[test] + fn test_bytearray_to_64_words_partial() { + let input = ByteArrayExTrait::from_bytes([0x01, 0x02, 0x03, 0x04, 0x05, 0x06].span()); + let (u64_words, pending_word, pending_word_len) = input.to_u64_words(); + assert(pending_word == 6618611909121, 'wrong pending word'); + assert(pending_word_len == 6, 'wrong pending word length'); + assert(u64_words.len() == 0, 'wrong u64 words length'); + } + + #[test] + fn test_bytearray_to_64_words_full() { + let input = ByteArrayExTrait::from_bytes( + [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08].span() + ); + let (u64_words, pending_word, pending_word_len) = input.to_u64_words(); + + assert(pending_word == 0, 'wrong pending word'); + assert(pending_word_len == 0, 'wrong pending word length'); + assert(u64_words.len() == 1, 'wrong u64 words length'); + assert(*u64_words[0] == 578437695752307201, 'wrong u64 words length'); + } + } + + + mod span_u8_test { + use super::super::{U8SpanExTrait, ToBytes}; + + #[test] + fn test_span_u8_to_64_words_partial() { + let mut input: Span = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06].span(); + let (u64_words, pending_word, pending_word_len) = input.to_u64_words(); + assert(pending_word == 6618611909121, 'wrong pending word'); + assert(pending_word_len == 6, 'wrong pending word length'); + assert(u64_words.len() == 0, 'wrong u64 words length'); + } + + #[test] + fn test_span_u8_to_64_words_full() { + let mut input: Span = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08].span(); + let (u64_words, pending_word, pending_word_len) = input.to_u64_words(); + + assert(pending_word == 0, 'wrong pending word'); + assert(pending_word_len == 0, 'wrong pending word length'); + assert(u64_words.len() == 1, 'wrong u64 words length'); + assert(*u64_words[0] == 578437695752307201, 'wrong u64 words length'); + } + + + #[test] + fn test_compute_msg_hash() { + let msg = 0xabcdef_u32.to_be_bytes(); + let expected_hash = 0x800d501693feda2226878e1ec7869eef8919dbc5bd10c2bcd031b94d73492860; + let hash = msg.compute_keccak256_hash(); + + assert_eq!(hash, expected_hash); + } + + #[test] + fn test_right_padded_span_offset_0() { + let span = [0x0, 0x01, 0x02, 0x03, 0x04, 0x05].span(); + let expected = [0x0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x0, 0x0, 0x0, 0x0].span(); + let result = span.slice_right_padded(0, 10); + + assert_eq!(result, expected); + } + + #[test] + fn test_right_padded_span_offset_4() { + let span = [0x0, 0x01, 0x02, 0x03, 0x04, 0x05].span(); + let expected = [0x04, 0x05, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0].span(); + let result = span.slice_right_padded(4, 10); + + assert_eq!(result, expected); + } + + #[test] + fn test_right_padded_span_offset_greater_than_span_len() { + let span = [0x0, 0x01, 0x02, 0x03, 0x04, 0x05].span(); + let expected = [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0].span(); + let result = span.slice_right_padded(6, 10); + + assert_eq!(result, expected); + } + + #[test] + fn test_pad_left_with_zeroes_len_10() { + let span = [0x0, 0x01, 0x02, 0x03, 0x04, 0x05].span(); + let expected = [0x0, 0x0, 0x0, 0x0, 0x0, 0x01, 0x02, 0x03, 0x04, 0x05].span(); + let result = span.pad_left_with_zeroes(10); + + assert_eq!(result, expected); + } + + #[test] + fn test_pad_left_with_zeroes_len_equal_than_data_len() { + let span = [0x0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x6, 0x7, 0x8, 0x9].span(); + let expected = [0x0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x6, 0x7, 0x8, 0x9].span(); + let result = span.pad_left_with_zeroes(10); + + assert_eq!(result, expected); + } + + #[test] + fn test_pad_left_with_zeroes_len_equal_than_smaller_len() { + let span = [0x0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x6, 0x7, 0x8, 0x9].span(); + let expected = [0x0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x6, 0x7, 0x8].span(); + let result = span.pad_left_with_zeroes(9); + + assert_eq!(result, expected); + } + + #[test] + fn test_pad_right_with_zeroes_len_10() { + let span = [0x01, 0x02, 0x03, 0x04, 0x05].span(); + let expected = [0x01, 0x02, 0x03, 0x04, 0x05, 0x0, 0x0, 0x0, 0x0, 0x0].span(); + let result = span.pad_right_with_zeroes(10); + + assert_eq!(result, expected); + } + + #[test] + fn test_pad_right_with_zeroes_truncate() { + let span = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a].span(); + let expected = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09].span(); + let result = span.pad_right_with_zeroes(9); + + assert_eq!(result, expected); + } + + #[test] + fn test_pad_right_with_zeroes_same_length() { + let span = [0x01, 0x02, 0x03, 0x04, 0x05].span(); + let expected = [0x01, 0x02, 0x03, 0x04, 0x05].span(); + let result = span.pad_right_with_zeroes(5); + + assert_eq!(result, expected); + } + } +} diff --git a/kakarot-ssj/crates/utils/src/traits/eth_address.cairo b/kakarot-ssj/crates/utils/src/traits/eth_address.cairo new file mode 100644 index 000000000..9f0122b29 --- /dev/null +++ b/kakarot-ssj/crates/utils/src/traits/eth_address.cairo @@ -0,0 +1,147 @@ +use core::starknet::EthAddress; +use crate::math::Bitshift; +use crate::traits::EthAddressIntoU256; + +#[generate_trait] +pub impl EthAddressExImpl of EthAddressExTrait { + /// Converts an EthAddress to an array of bytes. + /// + /// # Returns + /// + /// * `Array` - A 20-byte array representation of the EthAddress. + fn to_bytes(self: EthAddress) -> Array { + let bytes_used: u256 = 20; + let value: u256 = self.into(); + let mut bytes: Array = Default::default(); + for i in 0 + ..bytes_used { + let val = value.shr(8 * (bytes_used - i - 1)); + bytes.append((val & 0xFF).try_into().unwrap()); + }; + + bytes + } + + /// Converts a 20-byte array into an EthAddress. + /// + /// # Arguments + /// + /// * `input` - A `Span` of length 20 representing the bytes of an Ethereum address. + /// + /// # Returns + /// + /// * `Option` - `Some(EthAddress)` if the conversion succeeds, `None` if the input + /// length is not 20. + fn from_bytes(input: Span) -> Option { + let len = input.len(); + if len != 20 { + return Option::None; + } + let offset: u32 = len - 1; + let mut result: u256 = 0; + for i in 0 + ..len { + let byte: u256 = (*input.at(i)).into(); + result += byte.shl((8 * (offset - i)).into()); + }; + result.try_into() + } +} + +#[cfg(test)] +mod tests { + use core::starknet::EthAddress; + use super::EthAddressExTrait; + #[test] + fn test_eth_address_to_bytes() { + let eth_address: EthAddress = 0x1234567890123456789012345678901234567890 + .try_into() + .unwrap(); + let bytes = eth_address.to_bytes(); + assert_eq!( + bytes.span(), + [ + 0x12, + 0x34, + 0x56, + 0x78, + 0x90, + 0x12, + 0x34, + 0x56, + 0x78, + 0x90, + 0x12, + 0x34, + 0x56, + 0x78, + 0x90, + 0x12, + 0x34, + 0x56, + 0x78, + 0x90 + ].span() + ); + } + + #[test] + fn test_eth_address_from_bytes() { + let bytes = [ + 0x12, + 0x34, + 0x56, + 0x78, + 0x90, + 0x12, + 0x34, + 0x56, + 0x78, + 0x90, + 0x12, + 0x34, + 0x56, + 0x78, + 0x90, + 0x12, + 0x34, + 0x56, + 0x78, + 0x90 + ].span(); + let eth_address = EthAddressExTrait::from_bytes(bytes); + assert_eq!( + eth_address, + Option::Some(0x1234567890123456789012345678901234567890.try_into().unwrap()) + ); + } + + #[test] + fn test_eth_address_from_bytes_invalid_length() { + let bytes = [ + 0x12, + 0x34, + 0x56, + 0x78, + 0x90, + 0x12, + 0x34, + 0x56, + 0x78, + 0x90, + 0x12, + 0x34, + 0x56, + 0x78, + 0x90, + 0x12, + 0x34, + 0x56, + 0x78, + 0x90, + 0x12 + ]; + let eth_address = EthAddressExTrait::from_bytes(bytes.span()); + assert_eq!(eth_address, Option::None); + } +} diff --git a/kakarot-ssj/crates/utils/src/traits/integer.cairo b/kakarot-ssj/crates/utils/src/traits/integer.cairo new file mode 100644 index 000000000..ebd00f99e --- /dev/null +++ b/kakarot-ssj/crates/utils/src/traits/integer.cairo @@ -0,0 +1,671 @@ +use core::integer::{u128_byte_reverse}; +use core::num::traits::{Zero, One, Bounded, BitSize}; +use crate::helpers::{u128_split}; +use crate::math::{Bitshift}; + +#[generate_trait] +pub impl U64Impl of U64Trait { + /// Returns the number of trailing zeroes in the bit representation of `self`. + /// # Arguments + /// * `self` a `u64` value. + /// # Returns + /// * The number of trailing zeroes in the bit representation of `self`. + fn count_trailing_zeroes(self: u64) -> u8 { + let mut count = 0; + + if self == 0 { + return 64; // If n is 0, all 64 bits are zeros + }; + + let mut mask = 1; + + while (self & mask) == 0 { + count += 1; + mask *= 2; + }; + + count + } +} + + +#[generate_trait] +pub impl U128Impl of U128Trait { + /// Returns the Least significant 64 bits of a u128 + fn as_u64(self: u128) -> u64 { + let (_, bottom_word) = u128_split(self); + bottom_word + } +} + +#[generate_trait] +pub impl U256Impl of U256Trait { + /// Splits an u256 into 4 little endian u64. + /// Returns ((high_high, high_low),(low_high, low_low)) + fn split_into_u64_le(self: u256) -> ((u64, u64), (u64, u64)) { + let low_le = u128_byte_reverse(self.low); + let high_le = u128_byte_reverse(self.high); + (u128_split(high_le), u128_split(low_le)) + } + + /// Reverse the endianness of an u256 + fn reverse_endianness(self: u256) -> u256 { + let new_low = u128_byte_reverse(self.high); + let new_high = u128_byte_reverse(self.low); + u256 { low: new_low, high: new_high } + } +} + +pub trait BytesUsedTrait { + /// Returns the number of bytes used to represent a `T` value. + /// # Arguments + /// * `self` - The value to check. + /// # Returns + /// The number of bytes used to represent the value. + fn bytes_used(self: T) -> u8; +} + +pub impl U8BytesUsedTraitImpl of BytesUsedTrait { + fn bytes_used(self: u8) -> u8 { + if self == 0 { + return 0; + } + + return 1; + } +} + +pub impl USizeBytesUsedTraitImpl of BytesUsedTrait { + fn bytes_used(self: usize) -> u8 { + if self < 0x10000 { // 256^2 + if self < 0x100 { // 256^1 + if self == 0 { + return 0; + } else { + return 1; + }; + } + return 2; + } else { + if self < 0x1000000 { // 256^3 + return 3; + } + return 4; + } + } +} + +pub impl U64BytesUsedTraitImpl of BytesUsedTrait { + fn bytes_used(self: u64) -> u8 { + if self <= Bounded::::MAX.into() { // 256^4 + return BytesUsedTrait::::bytes_used(self.try_into().unwrap()); + } else { + if self < 0x1000000000000 { // 256^6 + if self < 0x10000000000 { + if self < 0x100000000 { + return 4; + } + return 5; + } + return 6; + } else { + if self < 0x100000000000000 { // 256^7 + return 7; + } else { + return 8; + } + } + } + } +} + +pub impl U128BytesTraitUsedImpl of BytesUsedTrait { + fn bytes_used(self: u128) -> u8 { + let (u64high, u64low) = u128_split(self); + if u64high == 0 { + return BytesUsedTrait::::bytes_used(u64low.try_into().unwrap()); + } else { + return BytesUsedTrait::::bytes_used(u64high.try_into().unwrap()) + 8; + } + } +} + +pub impl U256BytesUsedTraitImpl of BytesUsedTrait { + fn bytes_used(self: u256) -> u8 { + if self.high == 0 { + return BytesUsedTrait::::bytes_used(self.low.try_into().unwrap()); + } else { + return BytesUsedTrait::::bytes_used(self.high.try_into().unwrap()) + 16; + } + } +} + +pub trait ByteSize { + fn byte_size() -> usize; +} + +pub impl ByteSizeImpl> of ByteSize { + fn byte_size() -> usize { + BitSize::::bits() / 8 + } +} + +pub trait BitsUsed { + /// Returns the number of bits required to represent `self`, ignoring leading zeros. + /// # Arguments + /// `self` - The value to check. + /// # Returns + /// The number of bits used to represent the value, ignoring leading zeros. + fn bits_used(self: T) -> u32; + + /// Returns the number of leading zeroes in the bit representation of `self`. + /// # Arguments + /// `self` - The value to check. + /// # Returns + /// The number of leading zeroes in the bit representation of `self`. + fn count_leading_zeroes(self: T) -> u32; +} + +pub impl BitsUsedImpl< + T, + +Zero, + +One, + +Add, + +Sub, + +Mul, + +Bitshift, + +BitSize, + +BytesUsedTrait, + +Into, + +TryInto, + +Copy, + +Drop, + +PartialEq +> of BitsUsed { + fn bits_used(self: T) -> u32 { + if self == Zero::zero() { + return 0; + } + let two: T = One::one() + One::one(); + let eight: T = two * two * two; + + let bytes_used = self.bytes_used(); + let last_byte = self.shr(eight * (bytes_used.into() - One::one())); + + // safe unwrap since we know at most 8 bits are used + let bits_used: u8 = bits_used_internal::bits_used_in_byte(last_byte.try_into().unwrap()); + + bits_used.into() + 8 * (bytes_used - 1).into() + } + + fn count_leading_zeroes(self: T) -> u32 { + BitSize::::bits() - self.bits_used() + } +} + +pub(crate) mod bits_used_internal { + /// Returns the number of bits used to represent the value in binary representation + /// # Arguments + /// * `self` - The value to compute the number of bits used + /// # Returns + /// * The number of bits used to represent the value in binary representation + pub(crate) fn bits_used_in_byte(self: u8) -> u8 { + if self < 0b100000 { + if self < 0b1000 { + if self < 0b100 { + if self < 0b10 { + if self == 0 { + return 0; + } else { + return 1; + }; + } + return 2; + } + + return 3; + } + + if self < 0b10000 { + return 4; + } + + return 5; + } else { + if self < 0b10000000 { + if self < 0b1000000 { + return 6; + } + return 7; + } + return 8; + } + } +} + +#[cfg(test)] +mod tests { + mod u8_test { + use crate::math::Bitshift; + use super::super::BitsUsed; + + #[test] + fn test_bits_used() { + assert_eq!(0x00_u8.bits_used(), 0); + let mut value: u8 = 0xff; + let mut i = 8; + loop { + assert_eq!(value.bits_used(), i); + if i == 0 { + break; + }; + value = value.shr(1); + + i -= 1; + }; + } + } + + mod u32_test { + use crate::math::Bitshift; + use crate::traits::bytes::{ToBytes, FromBytes}; + use super::super::{BytesUsedTrait}; + + #[test] + fn test_u32_from_be_bytes() { + let input: Array = array![0xf4, 0x32, 0x15, 0x62]; + let res: Option = input.span().from_be_bytes(); + + assert!(res.is_some()); + assert_eq!(res.unwrap(), 0xf4321562); + } + + #[test] + fn test_u32_from_be_bytes_too_big_should_return_none() { + let input: Array = array![0xf4, 0x32, 0x15, 0x62, 0x01]; + let res: Option = input.span().from_be_bytes(); + + assert!(res.is_none()); + } + + #[test] + fn test_u32_from_be_bytes_too_small_should_return_none() { + let input: Array = array![0xf4, 0x32, 0x15]; + let res: Option = input.span().from_be_bytes(); + + assert!(res.is_none()); + } + + #[test] + fn test_u32_from_be_bytes_partial_full() { + let input: Array = array![0xf4, 0x32, 0x15, 0x62]; + let res: Option = input.span().from_be_bytes_partial(); + + assert!(res.is_some()); + assert_eq!(res.unwrap(), 0xf4321562); + } + + #[test] + fn test_u32_from_be_bytes_partial_smaller_input() { + let input: Array = array![0xf4, 0x32, 0x15]; + let res: Option = input.span().from_be_bytes_partial(); + + assert!(res.is_some()); + assert_eq!(res.unwrap(), 0xf43215); + } + + #[test] + fn test_u32_from_be_bytes_partial_single_byte() { + let input: Array = array![0xf4]; + let res: Option = input.span().from_be_bytes_partial(); + + assert!(res.is_some()); + assert_eq!(res.unwrap(), 0xf4); + } + + #[test] + fn test_u32_from_be_bytes_partial_empty_input() { + let input: Array = array![]; + let res: Option = input.span().from_be_bytes_partial(); + + assert!(res.is_some()); + assert_eq!(res.unwrap(), 0); + } + + #[test] + fn test_u32_from_be_bytes_partial_too_big_input() { + let input: Array = array![0xf4, 0x32, 0x15, 0x62, 0x01]; + let res: Option = input.span().from_be_bytes_partial(); + + assert!(res.is_none()); + } + + #[test] + fn test_u32_from_le_bytes() { + let input: Array = array![0x62, 0x15, 0x32, 0xf4]; + let res: Option = input.span().from_le_bytes(); + + assert!(res.is_some()); + assert_eq!(res.unwrap(), 0xf4321562); + } + + #[test] + fn test_u32_from_le_bytes_too_big() { + let input: Array = array![0x62, 0x15, 0x32, 0xf4, 0x01]; + let res: Option = input.span().from_le_bytes(); + + assert!(res.is_none()); + } + + #[test] + fn test_u32_from_le_bytes_too_small() { + let input: Array = array![0x62, 0x15, 0x32]; + let res: Option = input.span().from_le_bytes(); + + assert!(res.is_none()); + } + + #[test] + fn test_u32_from_le_bytes_zero() { + let input: Array = array![0x00, 0x00, 0x00, 0x00]; + let res: Option = input.span().from_le_bytes(); + + assert!(res.is_some()); + assert_eq!(res.unwrap(), 0); + } + + #[test] + fn test_u32_from_le_bytes_max() { + let input: Array = array![0xff, 0xff, 0xff, 0xff]; + let res: Option = input.span().from_le_bytes(); + + assert!(res.is_some()); + assert_eq!(res.unwrap(), 0xffffffff); + } + + #[test] + fn test_u32_from_le_bytes_partial() { + let input: Array = array![0x62, 0x15, 0x32]; + let res: Option = input.span().from_le_bytes_partial(); + + assert!(res.is_some()); + assert_eq!(res.unwrap(), 0x321562); + } + + #[test] + fn test_u32_from_le_bytes_partial_full() { + let input: Array = array![0x62, 0x15, 0x32, 0xf4]; + let res: Option = input.span().from_le_bytes_partial(); + + assert!(res.is_some()); + assert_eq!(res.unwrap(), 0xf4321562); + } + + #[test] + fn test_u32_from_le_bytes_partial_too_big() { + let input: Array = array![0x62, 0x15, 0x32, 0xf4, 0x01]; + let res: Option = input.span().from_le_bytes_partial(); + + assert!(res.is_none()); + } + + #[test] + fn test_u32_from_le_bytes_partial_empty() { + let input: Array = array![]; + let res: Option = input.span().from_le_bytes_partial(); + + assert!(res.is_some()); + assert_eq!(res.unwrap(), 0); + } + + #[test] + fn test_u32_from_le_bytes_partial_single_byte() { + let input: Array = array![0xff]; + let res: Option = input.span().from_le_bytes_partial(); + + assert!(res.is_some()); + assert_eq!(res.unwrap(), 0xff); + } + + #[test] + fn test_u32_to_bytes_full() { + let input: u32 = 0xf4321562; + let res: Span = input.to_be_bytes(); + + assert_eq!(res.len(), 4); + assert_eq!(*res[0], 0xf4); + assert_eq!(*res[1], 0x32); + assert_eq!(*res[2], 0x15); + assert_eq!(*res[3], 0x62); + } + + #[test] + fn test_u32_to_bytes_partial() { + let input: u32 = 0xf43215; + let res: Span = input.to_be_bytes(); + + assert_eq!(res.len(), 3); + assert_eq!(*res[0], 0xf4); + assert_eq!(*res[1], 0x32); + assert_eq!(*res[2], 0x15); + } + + + #[test] + fn test_u32_to_bytes_leading_zeros() { + let input: u32 = 0x00f432; + let res: Span = input.to_be_bytes(); + + assert_eq!(res.len(), 2); + assert_eq!(*res[0], 0xf4); + assert_eq!(*res[1], 0x32); + } + + #[test] + fn test_u32_to_be_bytes_padded() { + let input: u32 = 7; + let result = input.to_be_bytes_padded(); + let expected = [0x0, 0x0, 0x0, 7].span(); + + assert_eq!(result, expected); + } + + + #[test] + fn test_u32_bytes_used() { + assert_eq!(0x00_u32.bytes_used(), 0); + let mut value: u32 = 0xff; + let mut i = 1; + loop { + assert_eq!(value.bytes_used(), i); + if i == 4 { + break; + }; + i += 1; + value = value.shl(8); + }; + } + + #[test] + fn test_u32_bytes_used_leading_zeroes() { + let len: u32 = 0x001234; + let bytes_count = len.bytes_used(); + + assert_eq!(bytes_count, 2); + } + } + + mod u64_test { + use crate::math::Bitshift; + use crate::traits::bytes::{ToBytes}; + use super::super::{BitsUsed, BytesUsedTrait, U64Trait}; + + + #[test] + fn test_u64_bytes_used() { + assert_eq!(0x00_u64.bytes_used(), 0); + let mut value: u64 = 0xff; + let mut i = 1; + loop { + assert_eq!(value.bytes_used(), i); + if i == 8 { + break; + }; + i += 1; + value = value.shl(8); + }; + } + + #[test] + fn test_u64_to_be_bytes_padded() { + let input: u64 = 7; + let result = input.to_be_bytes_padded(); + let expected = [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 7].span(); + + assert_eq!(result, expected); + } + + #[test] + fn test_u64_trailing_zeroes() { + /// bit len is 3, and trailing zeroes are 2 + let input: u64 = 4; + let result = input.count_trailing_zeroes(); + let expected = 2; + + assert_eq!(result, expected); + } + + + #[test] + fn test_u64_leading_zeroes() { + /// bit len is 3, and leading zeroes are 64 - 3 = 61 + let input: u64 = 7; + let result = input.count_leading_zeroes(); + let expected = 61; + + assert_eq!(result, expected); + } + + #[test] + fn test_u64_bits_used() { + let input: u64 = 7; + let result = input.bits_used(); + let expected = 3; + + assert_eq!(result, expected); + } + } + + mod u128_test { + use core::num::traits::Bounded; + use crate::math::Bitshift; + use crate::traits::bytes::{ToBytes}; + use super::super::{BitsUsed, BytesUsedTrait}; + + #[test] + fn test_u128_bytes_used() { + assert_eq!(0x00_u128.bytes_used(), 0); + let mut value: u128 = 0xff; + let mut i = 1; + loop { + assert_eq!(value.bytes_used(), i); + if i == 16 { + break; + }; + i += 1; + value = value.shl(8); + }; + } + + #[test] + fn test_u128_to_bytes_full() { + let input: u128 = Bounded::MAX; + let result: Span = input.to_be_bytes(); + let expected = [ + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 + ].span(); + + assert_eq!(result, expected); + } + + #[test] + fn test_u128_to_bytes_partial() { + let input: u128 = 0xf43215; + let result: Span = input.to_be_bytes(); + let expected = [0xf4, 0x32, 0x15].span(); + + assert_eq!(result, expected); + } + + #[test] + fn test_u128_to_bytes_padded() { + let input: u128 = 0xf43215; + let result: Span = input.to_be_bytes_padded(); + let expected = [ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf4, 0x32, 0x15 + ].span(); + + assert_eq!(result, expected); + } + } + + mod u256_test { + use crate::math::Bitshift; + use crate::traits::integer::{U256Trait}; + use super::super::{BitsUsed, BytesUsedTrait}; + + #[test] + fn test_reverse_bytes_u256() { + let value: u256 = 0xFAFFFFFF000000E500000077000000DEAD0000000004200000FADE0000450000; + let res = value.reverse_endianness(); + assert( + res == 0x0000450000DEFA0000200400000000ADDE00000077000000E5000000FFFFFFFA, + 'reverse mismatch' + ); + } + + #[test] + fn test_split_u256_into_u64_little() { + let value: u256 = 0xFAFFFFFF000000E500000077000000DEAD0000000004200000FADE0000450000; + let ((high_h, low_h), (high_l, low_l)) = value.split_into_u64_le(); + assert_eq!(high_h, 0xDE00000077000000); + assert_eq!(low_h, 0xE5000000FFFFFFFA); + assert_eq!(high_l, 0x0000450000DEFA00); + assert_eq!(low_l, 0x00200400000000AD); + } + + #[test] + fn test_u256_bytes_used() { + assert_eq!(0x00_u256.bytes_used(), 0); + let mut value: u256 = 0xff; + let mut i = 1; + loop { + assert_eq!(value.bytes_used(), i); + if i == 32 { + break; + }; + i += 1; + value = value.shl(8); + }; + } + + #[test] + fn test_u256_leading_zeroes() { + /// bit len is 3, and leading zeroes are 256 - 3 = 253 + let input: u256 = 7; + let result = input.count_leading_zeroes(); + let expected = 253; + + assert_eq!(result, expected); + } + + #[test] + fn test_u64_bits_used() { + let input: u256 = 7; + let result = input.bits_used(); + let expected = 3; + + assert_eq!(result, expected); + } + } +} diff --git a/kakarot-ssj/crates/utils/src/utils.cairo b/kakarot-ssj/crates/utils/src/utils.cairo new file mode 100644 index 000000000..242b45b83 --- /dev/null +++ b/kakarot-ssj/crates/utils/src/utils.cairo @@ -0,0 +1,309 @@ +use core::num::traits::Zero; + +/// Pack an array of bytes into 31-byte words and a final word. +/// The bytes are packed in big-endian order. +/// +/// # Arguments +/// * `input` - An array of bytes to pack. +/// +/// # Returns +/// An array of felt252 values containing the packed bytes. The last word might not be full. +pub fn pack_bytes(input: Span) -> Array { + let mut result: Array = Default::default(); + let mut current_word: u256 = 0; + let mut byte_count: usize = 0; + + for byte in input { + current_word = (current_word * 256) + (*byte).into(); + byte_count += 1; + + if byte_count == 31 { + result.append(current_word.try_into().unwrap()); + current_word = 0; + byte_count = 0; + } + }; + + // Append the last word if there are any remaining bytes + if byte_count != 0 { + result.append(current_word.try_into().unwrap()); + } + + result +} + +/// Load packed bytes from an array of bytes packed in 31-byte words and a final word. +/// +/// # Arguments +/// +/// * `input` - An array of 31-bytes words and a final word. +/// * `bytes_len` - The total number of bytes to unpack. +/// +/// # Returns +/// +/// An `Array` containing the unpacked bytes in big-endian order. +/// +/// # Performance considerations +/// +/// This function uses head-recursive helper functions (`unpack_chunk`) for unpacking individual +/// felt252 values. Head recursion is used here instead of loops because the Array type in Cairo is +/// append-only. This approach allows us to append the bytes in the correct order (big-endian) +/// without needing to reverse the array afterwards. This leads to more efficient memory usage and +/// performance. +pub fn load_packed_bytes(input: Span, bytes_len: u32) -> Array { + if input.is_empty() { + return Default::default(); + } + let (chunk_counts, remainder) = DivRem::div_rem(bytes_len, 31); + let mut res: Array = Default::default(); + + for i in 0 + ..chunk_counts { + let mut value: u256 = (*input[i]).into(); + unpack_chunk(value, 31, ref res); + }; + + if remainder.is_zero() { + return res; + } + unpack_chunk((*input[input.len() - 1]).into(), remainder, ref res); + res +} + + +/// Unpacks only a specified number of bytes from the value. Uses head recursion to append bytes in +/// big-endian order. +/// +/// # Arguments +/// +/// * `value` - The u256 value to unpack. +/// * `remaining_bytes` - The number of bytes to unpack from the value. +/// * `output` - The array to append the unpacked bytes to. +fn unpack_chunk(value: u256, remaining_bytes: u32, ref output: Array) { + if remaining_bytes == 0 { + return; + } + let (q, r) = DivRem::div_rem(value, 256); + unpack_chunk(q, remaining_bytes - 1, ref output); + output.append(r.try_into().unwrap()); +} + +#[cfg(test)] +mod tests { + use super::{load_packed_bytes, pack_bytes}; + + #[test] + fn test_should_load_empty_array() { + let res = load_packed_bytes([].span(), 0); + + assert_eq!(res.span(), [].span()); + } + + #[test] + fn test_should_load_zeroes() { + let input = [0x00, 0x00]; + let res = load_packed_bytes(input.span(), 35); + + assert_eq!(res.span(), [0x00; 35].span()); + } + + #[test] + fn test_should_load_single_31bytes_felt() { + let input = [0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff]; + let res = load_packed_bytes(input.span(), 31); + + assert_eq!(res.span(), [0xff; 31].span()); + } + + #[test] + fn test_should_load_with_non_full_last_felt() { + let input = [0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffff]; + let res = load_packed_bytes(input.span(), 33); + + assert_eq!(res.span(), [0xff; 33].span()); + } + + #[test] + fn test_should_load_multiple_words() { + let input = [ + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0xffff + ]; + let res = load_packed_bytes(input.span(), 64); + + assert_eq!(res.span(), [0xff; 64].span()); + } + + #[test] + fn test_should_load_mixed_byte_values_big_endian() { + let input = [0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e, 0x1f2021]; + let res = load_packed_bytes(input.span(), 34); + assert_eq!( + res.span(), + [ + 0x00, + 0x01, + 0x02, + 0x03, + 0x04, + 0x05, + 0x06, + 0x07, + 0x08, + 0x09, + 0x0a, + 0x0b, + 0x0c, + 0x0d, + 0x0e, + 0x0f, + 0x10, + 0x11, + 0x12, + 0x13, + 0x14, + 0x15, + 0x16, + 0x17, + 0x18, + 0x19, + 0x1a, + 0x1b, + 0x1c, + 0x1d, + 0x1e, + 0x1f, + 0x20, + 0x21 + ].span() + ); + } + + #[test] + fn test_should_pack_empty_array() { + let res = pack_bytes([].span()); + + assert_eq!(res, array![]); + } + + #[test] + fn test_should_pack_single_31bytes_felt() { + let input = [0xff; 31]; + let res = pack_bytes(input.span()); + + assert_eq!(res, array![0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff]); + } + + #[test] + fn test_should_pack_with_non_full_last_felt() { + let mut input = [0xff; 33]; + let res = pack_bytes(input.span()); + + assert_eq!( + res, array![0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffff] + ); + } + + #[test] + fn test_should_pack_multiple_words() { + let input = [0xff; 64]; + let res = pack_bytes(input.span()); + + assert_eq!( + res, + array![ + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0xffff + ] + ); + } + + #[test] + fn test_should_pack_mixed_byte_values_big_endian() { + let input = [ + 0x00, + 0x01, + 0x02, + 0x03, + 0x04, + 0x05, + 0x06, + 0x07, + 0x08, + 0x09, + 0x0a, + 0x0b, + 0x0c, + 0x0d, + 0x0e, + 0x0f, + 0x10, + 0x11, + 0x12, + 0x13, + 0x14, + 0x15, + 0x16, + 0x17, + 0x18, + 0x19, + 0x1a, + 0x1b, + 0x1c, + 0x1d, + 0x1e, + 0x1f, + 0x20, + 0x21 + ]; + let res = pack_bytes(input.span()); + assert_eq!( + res, array![0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e, 0x1f2021] + ); + } + + #[test] + fn test_pack_and_unpack_roundtrip() { + let original = [ + 0x00, + 0x01, + 0x02, + 0x03, + 0x04, + 0x05, + 0x06, + 0x07, + 0x08, + 0x09, + 0x0a, + 0x0b, + 0x0c, + 0x0d, + 0x0e, + 0x0f, + 0x10, + 0x11, + 0x12, + 0x13, + 0x14, + 0x15, + 0x16, + 0x17, + 0x18, + 0x19, + 0x1a, + 0x1b, + 0x1c, + 0x1d, + 0x1e, + 0x1f, + 0x20, + 0x21 + ].span(); + let packed = pack_bytes(original); + let unpacked = load_packed_bytes(packed.span(), original.len().try_into().unwrap()); + assert_eq!(original, unpacked.span()); + } +} diff --git a/kakarot-ssj/docs/CODE_OF_CONDUCT.md b/kakarot-ssj/docs/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..87324b14f --- /dev/null +++ b/kakarot-ssj/docs/CODE_OF_CONDUCT.md @@ -0,0 +1,78 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to make participation in our project and our +community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and +expression, level of experience, education, socio-economic status, nationality, +personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +- The use of sexualized language or imagery and unwelcome sexual attention or + advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or electronic + address, without explicit permission +- Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, or to ban temporarily or permanently any +contributor for other behaviors that they deem inappropriate, threatening, +offensive, or harmful. + +## Scope + +This Code of Conduct applies within all project spaces, and it also applies when +an individual is representing the project or its community in public spaces. +Examples of representing a project or community include using an official +project email address, posting via an official social media account, or acting +as an appointed representative at an online or offline event. Representation of +a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project maintainer using any of the +[private contact addresses](https://github.com/sayajin-labs/kakarot-ssj#support). +All complaints will be reviewed and investigated and will result in a response +that is deemed necessary and appropriate to the circumstances. The project team +is obligated to maintain confidentiality with regard to the reporter of an +incident. Further details of specific enforcement policies may be posted +separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the +[Contributor Covenant](https://www.contributor-covenant.org), version 1.4, +available at + + +For answers to common questions about this code of conduct, see + diff --git a/kakarot-ssj/docs/CONTRIBUTING.md b/kakarot-ssj/docs/CONTRIBUTING.md new file mode 100644 index 000000000..526923a4b --- /dev/null +++ b/kakarot-ssj/docs/CONTRIBUTING.md @@ -0,0 +1,128 @@ +# Contributing + +When contributing to this repository, please first discuss the change you wish +to make via issue, email, or any other method with the owners of this repository +before making a change. Please note we have a +[code of conduct](CODE_OF_CONDUCT.md), please follow it in all your interactions +with the project. + +## Contributing guidelines + +Kakarot is an open-source project and we welcome contributions of all kinds. +However, we ask that you follow these guidelines when contributing: + +- If you have an idea for a new feature or a bug fix, please create an issue + first. This will allow us to discuss the idea and provide feedback before you + start working on it. +- If you are working on an issue, please ask to be assigned. This will help us + keep track of who is working on what and avoid duplicated work. +- Do not ask to be assigned to an issue if you are not planning to work on it + immediately. We want to keep the project backlog clean and organized. If you + are interested in working on an issue, please comment on the issue and we will + assign it to you. We will remove the assignment if you do not start working on + the issue within 2 days. You can, of course, submit a draft PR if you need + more time or have questions regarding the issue. +- Prefer rebasing over merging when updating your PR. This will keep the commit + history clean and make it easier to review your changes. +- Adopt + [conventional commit messages](https://www.conventionalcommits.org/en/v1.0.0/). + This will help us when reviewing your PR. + +## Prerequisites + +To set up a development environment, please follow the steps from +[the README.md](../README.md#installation). Make sure that your Scarb version +matches the one expected, specified in the [.tool-versions](../.tool-versions) +file. + +## Issues and feature requests + +You've found a bug in the source code, a mistake in the documentation or maybe +you'd like a new feature?Take a look at +[GitHub Discussions](https://github.com/sayajin-labs/kakarot-ssj/discussions) to +see if it's already being discussed. You can help us by +[submitting an issue on GitHub](https://github.com/sayajin-labs/kakarot-ssj/issues). +Before you create an issue, make sure to search the issue archive -- your issue +may have already been addressed! + +Please try to create bug reports that are: + +- _Reproducible._ Include steps to reproduce the problem. +- _Specific._ Include as much detail as possible: which version, what + environment, etc. +- _Unique._ Do not duplicate existing opened issues. +- _Scoped to a Single Bug._ One bug per report. + +**Even better: Submit a pull request with a fix or new feature!** + +### How to submit a Pull Request + +1. Search our repository for open or closed + [Pull Requests](https://github.com/sayajin-labs/kakarot-ssj/pulls) that + relate to your submission. You don't want to duplicate effort. +2. Fork the project +3. Create your feature branch (`git checkout -b feat/amazing_feature`) +4. Commit your changes (`git commit -m 'feat: add amazing_feature'`) +5. Push to the branch (`git push origin feat/amazing_feature`) +6. [Open a Pull Request](https://github.com/sayajin-labs/kakarot-ssj/compare?expand=1) + +### Migrating from Cairo Zero to Cairo + +Kakarot SSJ is a rewrite of +[Kakarot Zero](https://github.com/kkrt-labs/kakarot), an implementation of the +Ethereum Virtual Machine in Cairo Zero. As such, most logic has already been +written. As part of the migration path, this business logic will be either +ported and translated as is or improved. + +Here is a quick checklist when building on Kakarot SSJ and taking on issues. + +#### Working on Opcodes + +When working on opcodes, make sure to check several things: + +- The issue's specs, always start with the issue. +- The + [Ethereum yellow paper's](https://ethereum.github.io/yellowpaper/paper.pdf) + paragraph for the issue, there is a non-zero probability that the early + implementation missed a specific edge case. +- The [EVM playground](https://www.evm.codes/) to be able to read the specs and + play around directly on the [playground](https://www.evm.codes/playground). +- The [Cairo Zero implementation](https://github.com/kkrt-labs/kakarot) that + already exists in the above mentioned repo. + +Now, here are things to pay attention to: + +- The types: we **should avoid using felt252 type as much as possible**. In some + cases, enums, structs and trait might be a good idea to write more idiomatic + Cairo. +- The tests: we need extensive testing. Unit tests and integration tests. +- The gas: we need our code to be lean. When possible, test different ways to + implement the same feature and argue which one is least gas expensive. But be + careful, _first make it work, then make it fast_. No need to over-engineer and + prematurely optimise. + +#### Working on utils + +When working on test utils, script & practical helpers, remember to: + +- Check if the util is still relevant, a lot of new features make Cairo very + powerful and make old utils obsolete. +- Check if the utility function can be refactored into a trait for a specific + type, e.g. as + [per this PR](https://github.com/kkrt-labs/kakarot-ssj/pull/74/files#diff-888cfc6a9147d3727c6f8c083b5d0890ed686240e5dc4da1a741e025bdbd81f7R282) +- Check if the type is still relevant, don't forget: we **should avoid using + felt252 type as much as possible** and **use unsigned integers as much as + possible**. + +#### Working on data structures + +Kakarot has many data structures, e.g. an Ethereum Transaction (struct), a Stack +(Cairo dict), a Memory (Cairo dict), etc. When porting over the data structures, +pay attention: + +- Should it be a struct? +- Should it be an enum: this is a new type made available in Cairo. +- Which types to use? Remember! **use unsigned integers as much as possible**. +- Remember to add traits for specific types instead of utils to write Cairo (& + Rust) idiomatic code. +- Test everything! Even small traits for specific types. diff --git a/kakarot-ssj/docs/SECURITY.md b/kakarot-ssj/docs/SECURITY.md new file mode 100644 index 000000000..1882c7e51 --- /dev/null +++ b/kakarot-ssj/docs/SECURITY.md @@ -0,0 +1,23 @@ +# Security Policy + +## Reporting a Vulnerability + +If there are any vulnerabilities in **Kakarot**, don't hesitate to _report +them_. + +1. Use any of the + [private contact addresses](https://github.com/sayajin-labs/kakarot-ssj#support). +2. Describe the vulnerability. + + If you have a fix, that is most welcome -- please attach or summarize it in + your message! + +3. We will evaluate the vulnerability and, if necessary, release a fix or + mitigating steps to address it. We will contact you to let you know the + outcome, and will credit you in the report. + + Please **do not disclose the vulnerability publicly** until a fix is + released! + +4. Once we have either a) published a fix, or b) declined to address the + vulnerability for whatever reason, you are free to publicly disclose it. diff --git a/kakarot-ssj/docs/general/account_state.png b/kakarot-ssj/docs/general/account_state.png new file mode 100644 index 0000000000000000000000000000000000000000..4386b900a41a4e3db705041d68ab14e5130ad653 GIT binary patch literal 132360 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∨p{dGWX;mf&C7K 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%0A9y#gqZfcw@Z7MS}^SlG^kHS)!Vx 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 B["eth_sendTransaction"] + B --> |Check transaction type| C{Is deploy transaction?} + C -- Yes --> D1[Execute initialization code] + D1 -->|Set account code to return data| E1[Commit code to Starknet storage] + E1 --> F1[Return deployed contract address] + + C -- No --> D2[Load account code from KakarotCore storage] + D2 --> E2[Execute bytecode] + E2 --> F2[Return execution result] +``` + + Transaction flow for deploy and execute transactions in +Kakarot + +There are several different ways to store the bytecode of a contract, and this +document will provide a quick overview of the different options, to choose the +most optimized one for this use case. The three main ways of handling contract +bytecode that were considered are: + +- Storing the bytecode inside a contract's storage, using Ethereum as an L1 data + availability layer. +- Storing the bytecode inside a contract's storage, using another data + availability layer. +- Storing the bytecode directly in the contract code, not as a part of the + contract's storage. + +These three solutions all have their respective pros and cons, which will be +discussed in the following sections. + +## Foreword: Data availability + +In Validity Rollups, verifying the validity proof on L1 is sufficient to +guarantee the validity of a transaction execution on L2, without needing the +detailed transaction information to be sent to Ethereum. + +However, to allow independent verification of the L2 chain's state and prevent +malicious operators from censoring or freezing the chain, some amount of data is +still required to be posted on a Data Availability (DA) layer. This makes the +Starknet state available even if the operator suddenly ceases operations. Data +availability ensures that users can always reconstruct the state of the rollup +by deriving its current state from the data posted by the rollup operator. + +Without this, users would not be able to query an L2 contract's state if the +operator becomes unavailable. It provides users the security of knowing that if +the Starknet sequencer ever stops functioning, they can prove custody of their +funds using the data posted on the DA Layer. If that DA Layer is Ethereum +itself, then Ethereum's security guarantees are inherited. + +## Different approaches to storing contract bytecode + +### Using Ethereum as a DA Layer + +Starknet currently uses Ethereum as its DA Layer. Each state update verified +on-chain is accompanied by the state diff between the previous and new state, +sent as calldata to Ethereum. This allows anyone observing Ethereum to +reconstruct the current state of Starknet. This security comes with a +significant price, as the publication of state diffs on Ethereum accounted for +[over 93% of the transaction fees paid on Starknet](https://community.starknet.io/t/volition-hybrid-data-availability-solution/97387). + +The first choice when storing contract bytecode is to store it as a regular +variable in the contract account's storage, with its state diff posted on +Ethereum acting as the DA Layer. + +In this case, the following data would reach L1: + +- The Starknet address of the contract account +- The number of updated keys in that contract +- The keys to update +- The new values for these keys + +On Starknet, the associated storage update fee for a transaction updating $n$ +unique contracts and $m$ unique keys is: + +$$ gas\ price \cdot c_w \cdot (2n + 2m) $$ + +where $c_w$ is the calldata cost (in gas) per 32-byte word. + +When storing the EVM bytecode during deployment, one single contract (the +Starknet contract corresponding to the ContractAccount) would be updated, with +$m$ keys, where $m = (B / 31) + 2$ and $B$ is the size of the bytecode to store +(see [implementation details](./contract_bytecode.md#implementation-details)). + +Considering a gas price of 34 gwei (average gas price in 2023, according to +[Etherscan](https://etherscan.io/chart/gasprice)), a calldata cost of 16 per +non-zero byte of calldata and the size of a typical ERC20 contract size of 2174 +bytes, we would have $m = 72$. The associated storage update fee would be: + +$$ fee = 34 \cdot (16 \cdot 32) \cdot (2 + 144) = 2,541,468 \text{ gwei}$$ + +This is the solution that was chosen for Kakarot; but there are other options +that could be considered presented thereafter. + +### Using Starknet's volition mechanism + +Volition is a hybrid data availability solution, providing the ability to choose +the data availability layer used for contract data. It allows users to choose +between using Ethereum as a DA Layer, or using Starknet itself as a DA Layer. +The security of state transitions, verified by STARK proofs on L1, is the same +for both L2 and L1 data availability modes. The difference is in the data +availability guarantees. When a state transition is verified on L1, its +correctness is ensured - however, the actual state of the L2 is not known on L1. +By posting state diffs on L1, the current state of Starknet can be reconstructed +from the beginning, but this has a significant cost as mentioned previously. + +![Volition](volition.png) + +Volition will allow developers to choose whether data will be stored in L1DA or +L2DA mode. This makes it possible to store data on L2, which is much less +expensive than storing it on L1. Depending on the data stored, it can be +advantageous if the cost of storing it on L1 is higher than its intrinsic value. +For example, a Volition-ERC20 token standard could have two balances - one on +L1DA for maximal security (major assets), and one on L2DA for lower +security/fees (small transactions). + +In this case, the contract bytecode could be stored in a storage variable +settled on L2DA instead of L1DA. This would make Kakarot contract deployment +extremely cheap, by avoiding the cost of posting bytecode state diffs to +Ethereum. + +#### Associated Risks + +Some risks must be considered when using Volition. If a majority of malicious +sequencers collude and decide to not share an L2DA change with other +sequencers/full nodes, once the attack ends, the honest sequencers won't have +the data to reconstruct and compute the new L2DA root. In this case, not only is +the L2DA inaccessible, but any execution relying on L2DA will become unprovable, +since sequencers lack the correct L2DA state. + +While unlikely, this remains a possibility to consider since L2DA is less secure +than L1DA. If it happened, the stored bytecode would be lost and the deployed +contract unexecutable. + +> Note: While Volition could potentially store bytecode on L2DA in the future, +> this is not currently possible as Volition is not yet implemented on Starknet. + +### Storing the EVM bytecode in the Cairo contract code + +The last option is to store the EVM bytecode directly in the Cairo contract +code. This has the advantage of also being cheap, as this data is not stored on +L1. + +On Starknet, there is a distinction between classes which is the definition of a +contract containing the Cairo bytecode, and contracts which are instances of +classes. When you declare a contract on Starknet, its information is added to +the +[Classes Tree](https://docs.starknet.io/documentation/architecture_and_concepts/Network_Architecture/starknet-state/#classes_tree), +which encodes information about the existing classes in the state of Starknet by +mapping class hashes to their compiled class hash. This class tree is itself a +part of the Starknet State Commitment, which is verified on Ethereum during +state updates. The class itself is stored in the nodes (both sequencers and full +nodes) of Starknet. + +To implement this, a new class would need to be declared each time a +ContractAccount is deployed. This class would contain the contract's EVM +bytecode, exposed via a view function returning the bytecode. To do this, the +RPC would need to craft a custom Starknet contract containing the EVM bytecode +in its source code, and declare it on Starknet - not ideal for security and +practicality. + +## Implementation details + +Kakarot uses the first solution, storing bytecode in a storage variable +committed to Ethereum. This solution is the most secure one, as it relies on +Ethereum as a DA Layer, and thus inherits from Ethereum's security guarantees, +ensuring that the bytecode of the deployed contract is always available. + +In Ethereum, a `deploy` transaction is identified by a null `to` address +(`Option::None`). The calldata sent to the KakarotCore contract when deploying a +new contract will be passed as an `Array` to the `eth_send_transaction` +entrypoint of the KakarotCore contract. This bytecode will then be packed 31 +bytes at a time, reducing by 31 the size of the bytecode stored in storage, +which is the most expensive part of the transaction. + +The contract storage related to a deployed contract is organized as: + +```rust +struct Storage { + bytecode: List, + pending_word: felt252, + pending_word_len: usize, +} +``` + +We use the `List` type from the +[Alexandria](https://github.com/keep-starknet-strange/alexandria/blob/main/src/storage/src/list.cairo) +library to store the bytecode, allowing us to store up to 255 31-bytes values +per `StorageBaseAddress`. Indeed, the current limitation on the maximal size of +a complex storage value is 256 field elements, where a field element is the +native data type of the Cairo VM. If we want to store more than 256 field +elements, which is the case for bytecode larger than 255 31-bytes values, which +represents 7.9kB, we need to split the data between multiple storage addresses. +The `List` type abstracts this process by automatically calculating the next +storage address to use, by applying poseidon hashes on the base storage address +of the list with the index of the segment to store the element in. + +The logic behind this storage design is to make it very easy to load the +bytecode in the EVM when we want to execute a program. We will rely on the +ByteArray type, which is a type from the core library that we can use to access +individual byte indexes in an array of packed bytes31 values. + +The rationale behind this structure is thoroughly documented in the core library +code. The variable stored in our contract's storage reflect the fields of the +ByteArray type. Once our bytecode is written in storage, we can simply load it +with + +```rust + let bytecode = ByteArray { + data: self.bytecode.read().array(), + pending_word: self.pending_word.read(), + pending_word_len: self.pending_word_len.read() +}; +``` + +After which the value of the bytecode at offset `i` can be accessed by simply +doing `bytecode[i]` when executing the bytecode instructions in the EVM - making +it convenient to iterate over. diff --git a/kakarot-ssj/docs/general/contract_storage.md b/kakarot-ssj/docs/general/contract_storage.md new file mode 100644 index 000000000..042907767 --- /dev/null +++ b/kakarot-ssj/docs/general/contract_storage.md @@ -0,0 +1,274 @@ +# Kakarot Storage + +## Storage in Ethereum + +The top-level data structure that holds information about the state of the +Ethereum blockchain is called the _world state_, and is a mapping of Ethereum +addresses (160-bit values) to accounts. Each Ethereum address represents an +account composed by a _nonce_, an _ether balance_, a _storage_, and a _code_. We +make the distinction between EOA (Externally Owned Accounts) that have no code +and an empty storage, and contracts that can have code and storage. + +![Account state](account_state.png) + +_Account state associated to an Ethereum address. Source: +[EVM Illustrated](https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf)_ + +In traditional EVM clients, like Geth, the _world state_ is stored as a _trie_, +and information about account are stored in the world state trie and can be +retrieved through queries. Each account in the world state trie is associated +with an account storage trie, which stores all of the information related to the +account. When Geth updates the storage of a contract by executing the SSTORE +opcodes, it does the following: + +- It updates the `value` associated to a `key` of the storage of a contract + deployed at a specific `address`. However, it updates a `dirtyStorage`, which + refers to storage entries that have been modified in the current transaction + execution. +- It tracks the storage modifications in a `journal` so that it can be reverted + in case of a revert opcode or an exception in the transaction execution. +- At the end of the execution of a transaction, all dirty storage slots are + copied across to `pendingStorage`, which in turn is copied across to + `originStorage` when the trie is finally updated. This effectively updates the + storage root of the account state. + +The behavior for the SLOAD opcode is very complementary to the SSTORE opcode. +When Geth executes the SLOAD opcode, it does the following: + +- It starts by doing a check on `dirtyStorage` to see if it contains a value for + the queried key, and returns it if so. +- Otherwise, it retrieves the value from the committed account storage trie. + +Since one transaction can access a storage slot multiple times, we must ensure +that the result returned is the most recent value. This is why Geth first checks +`dirtyStorage`, which is the most up-to-date state of the storage. + +```mermaid +flowchart TD; + A[Start: Run Bytecode] -->|SSTORE| B[Update value in dirtyStorage] + B --> C[Track modifications in journal] + C --> D[End of current execution] + D -->|Execution reverted| M[Clear dirtyStorage from entries in journal] + D -->|Execution successful| E[ ] + A -->|SLOAD| H[Check dirtyStorage for queried key] + H -->|Key found| I[Return value from dirtyStorage] + H -->|Key not found| J[Retrieve value from committed account storage trie] + J --> K[Return retrieved value] + style A fill:#DB5729,stroke:#333,stroke-width:2px; + style B fill:#296FDB,stroke:#333,stroke-width:2px; + style C fill:#296FDB,stroke:#333,stroke-width:2px; + style D fill:#296FDB,stroke:#333,stroke-width:2px; + style E fill:#296FDB,stroke:#333,stroke-width:2px; + style H fill:#136727,stroke:#333,stroke-width:2px; + style I fill:#136727,stroke:#333,stroke-width:2px; + style J fill:#136727,stroke:#333,stroke-width:2px; + style K fill:#136727,stroke:#333,stroke-width:2px; + style M fill:#DB2929,stroke:#333,stroke-width:2px; +``` + +_Simplified representation of SSTORE and SLOAD Opcodes +behavior in the Geth EVM Client_ + +## Storage in Kakarot + +As Kakarot is a contract that is deployed on Starknet and is not a client that +can directly manipulate a storage database, our approach differs from one of a +traditional client. We do not directly manipulate tries. Instead, we have access +to contracts storage on the Starknet blockchain, that we can query using +syscalls to read and update the value of a of a storage slot. + +There are two different ways of handling Storage in Kakarot. + +### One storage space per Kakarot Contract + +The first approach is to have one storage space per Kakarot contract. This means +that for every contract that is deployed on Kakarot, we will deploy an +underlying Starknet contract, which has its own state which can only be queried +by itself. + +This design closely resembles the design of the EVM. It has the following +properties: + +- The two different kinds of EVM accounts - Externally Owned Accounts (EOA) and + Contract Accounts (CA) - are both represented by Starknet smart contracts. + Each EVM account is mapped to a unique Starknet contract. Each contract + account has its own storage, and has external functions that can be called by + Kakarot to read and write to its storage. +- Each contract is deployed by Kakarot, and contains its own bytecode in storage + in the case of a smart contract (as EOAs don't have code) +- Each contract account has external functions that can be called by Kakarot to + read the bytecode it stores and to read / write to its storage. This makes + Kakarot an effective "admin" to all contracts with rights to modify their + storage. + +This design has some limitations: + +- We perform a `call_contract_syscall` for each SLOAD/SSTORE operation that is + committed to Starknet, which has an extra overhead compared to directly + modifying the current contract's storage . Given that only KakarotCore can + modify the storage of a Kakarot contract, we could directly store the whole + world state in the main Kakarot contract storage. +- It adds external entrypoints with admin rights to read and write from storage + in each Kakarot contract, which adds security risks. +- It moves away from the traditional EVM design, in which execution clients + store account states in a common database backend. + +However, it has some interesting properties. It allows us to have a one-to-one +mapping between Kakarot contracts and Starknet contracts, which makes it easier +to perform value transfers with the chain's native token. Moreover, it allows +one to send funds from a Starknet account to a Kakarot account, which can be +useful to implement a bridging mechanism to Kakarot with low overhead, or any +other mechanism that requires interacting with funds of a Kakarot account. + +Considering the compatibility properties, we will use this design in Kakarot. +The second design, presented after, still has some interesting properties that +we will discuss. But the benefits it brings do not outweigh the loss of +compatibility. + +### A shared storage space for all Kakarot Contracts + +The second approach is to have a unified storage space for all contract accounts +in the main Kakarot smart contract. While Kakarot is not a traditional Ethereum +Client, we can still use a design that is similar. Traditional clients hold a +state database in which the account states are stored. We can do the same, but +instead of storing the account states in a database, we store them in the +KakarotCore contract storage. Therefore, we do not need to deploy a Starknet +contract for each Kakarot account contract, which saves users costs related to +deploying contracts. + +A contract’s storage on Starknet is a persistent storage space where you can +read, write, modify, and persist data. The storage is a map with $2^{251}$ +slots, where each slot is a `felt252` which is initialized to 0. + +This new model doesn't expose read and write methods on Kakarot contracts. +Instead of having $n$ contracts with `write_storage` and `read_storage` +entrypoints, the only way to update the storage of a Kakarot contract is now +through executing SLOAD / SSTORE internally to KakarotCore. + +Regarding the security of such a design, we can reason about the probability of +a collision occurring when interacting with this shared storage. +[65M contracts](https://dune.com/queries/2284893/3744521) have been deployed on +Ethereum so far. If we assume that Kakarot could reach the same number of +contracts, that would leave us with a total of +$2^{251} / 65\cdot10^6 \approx 2^{225}$ slots per contract. Even with a +hypothetical number of 100 billion contracts, we would still have around +$2^{214}$ storage slots available per contract. + +Considering the birthday paradox, the probability of a collision occurring, +given $2^{214}$ randomly chosen slots, is roughly $1/2^{107}$. This is a very +low probability, which is considered secure by today's standards. We can +therefore consider that the collision risk is negligible and that this storage +layout doesn't introduce any security risk to Kakarot. For reference, Ethereum +has 80 bits of security on its account addresses, which are 160 bits long. + +But, as we're looking for maximum compatibility between "pure" Starknet +contracts and "Kakarot" Starknet contracts, this design is not ideal from a +compatibility perspective. It requires us to keep an internal accounting of the +balances of each account, and to expose external entrypoints in order to query +the balances of each account. This is not ideal, as it completely breaks the +compatibility with Starknet. + +### Tracking and reverting storage changes + +The storage mechanism presented in the [Local State](./local_state.md) section +enable us to revert storage changes by using a concept similar to Geth's +journal. Each storage change will be stored in a `StateChangeLog` implemented +using a `Felt252Dict` data structure, that will associate each modified storage +address to its new value. This allows us to perform three things: + +- When executing a transaction, instead of using one `storage_write_syscall` per + SSTORE opcode, we can simply store the storage changes in this cache state. At + the end of the transaction, we can finalize all the storage writes together + and perform only one `storage_write_syscall` per modified storage address. +- When reading from storage, we can first read from the state to see if the + storage slot has been modified. If it's the case, we can read the new value + from the state instead of performing a `storage_read_syscall`. +- If the transaction reverts, we won't need to revert the storage changes + manually. Instead, we can simply not finalize the storage changes present in + the state, which can save a lot of gas. + +```mermaid +sequenceDiagram + participant C as Caller + participant K as KakarotCore + participant M as Machine + participant J as State + participant S as ContractState + + C->>K: Executes Kakarot contract + K->>M: Executes Opcode (Either SSTORE or SLOAD) + + Note over K,M: If it's an SSTORE operation, it writes to Storage. + Note over K,M: If it's an SLOAD operation, it reads from Storage. + + alt SSTORE + M-->>M: hash = hash(evm_address, storage_key) + M->>J: state.accounts_storage.insert(hash, (key, value)) + else SLOAD + M-->>M: hash = hash(evm_address, storage_key) + M->>J: state.accounts_storage.get(hash) + J -->> M: Nullable~value~ + alt State returns value + + else State returns nothing + M->>S: storage_read(evm_address, key) + S-->>M: value + end + end + Note over K,M: Committing State entries to storage + K->>M: Commit + M->>J: Get all state storage entries + J -->>M: entries + loop for each storage entry + M->>S: storage_write(evm_address, key, value) + end + + Note over S: Storage is now updated with the final state of all changes made during the transaction. +``` + +Sequence of interactions between Kakarot, the local State +and Starknet for the SSTORE and SLOAD Opcodes + +### Implementation + +The SSTORE and SLOAD opcodes are implemented to first read and write to the +`State` instead of directly writing to the KakarotCore contract's storage. The +internal location of the storage slot is computed by applying the poseidon hash +on the EVM address of the contract and the storage key. We store the key +nonetheless, as it will be needed to finalize the storage updates at the end of +the transaction when retrieving the address of the contract to apply storage +changes to. + +Using the `storage_at` and `set_storage_at` entrypoints in the contract +accounts, we can arbitrarily read and write to another contract's storage. +Therefore, we will be able to simply implement the SSTORE and SLOAD opcodes in +two steps, as follows: + +```rust + // SSTORE + let hash = poseidon_hash(evm_address, key); + self.state.accounts_storage.write(hash, (evm_address, key, value)); +``` + +```rust + // SLOAD + let storage_address = poseidon_hash(evm_address, storage_slot); + let maybe_entry = self.accounts_storage.read(internal_key); + match maybe_entry { + Option::Some((_, key, value)) => { return Result::Ok(value); }, + Option::None => { + let account = self.get_account(evm_address); + return account.read_storage(key); + } +} +``` + +```rust + // Finalizing storage updates + for storage_hash in accounts_storage{ + let (contract_address, key, value) = account_state_keys[storage_hash] + ContractAccountDispatcher{contract_address}.set_storage_at(key, value); + } +``` + +> Note: these code snippets are in pseudocode, not valid Cairo code. diff --git a/kakarot-ssj/docs/general/local_state.md b/kakarot-ssj/docs/general/local_state.md new file mode 100644 index 000000000..038ca8cfb --- /dev/null +++ b/kakarot-ssj/docs/general/local_state.md @@ -0,0 +1,177 @@ +# Local State + +A challenge with the implementation of Kakarot is that since it lives as a +contract deployed on chain, it cannot always manipulate the underlying state of +the blockchain once it has performed modifications on it to revert the changes +made. For example, a deployed contract cannot delete itself from the blockchain, +and emitted events cannot be deleted. + +This means that before committing any changes to the blockchain, Kakarot must +ensure that the changes are valid. This is done by maintaining a local state +that is updated as the code is executed. + +The machine is created along with a default empty state. The state is a struct +that wraps dictionaries holding the values stored in the blockchain storage +modified locally. + +Because of technical limitations around the usage of dictionaries preventing us +from using dicts in self-referring data structures, instead of having one state +per execution context that we could merge into the parent state if the context +exits successfully or discard if the context reverts, we have one global `State` +structs that achieves the same behavior by tracking transactional changes, which +refers to the changes made inside the current transaction as a whole, and a +contextual changes, which refers to changes made inside the current execution +context. + +The local state is updated as the code is executed, and when an execution +context is finalized, we merge the contextual state updates into the +transactional state. When a transaction finishes, we apply the transactional +state diffs by writing them inside the blockchain storage. + +This design allows us to simulate reverting the changes made to the blockchain +storage by simply discarding the contextual state updates, and to commit the +changes by applying the transactional state updates. + +The sequence diagram below illustrates how Kakarot interacts with both Starknet +storage and its local cached state. + +```mermaid +sequenceDiagram + participant User + participant KakarotCore + participant LocalState + participant Machine + participant Starknet + + User->>+KakarotCore:Sends transaction + KakarotCore->>+Machine: Instantiates machine with bytecode to run + Machine->>LocalState: Initialize local state + Machine->>+LocalState: Start execution + + loop Executes EVM bytecode + Machine->>LocalState: Record contextual changes + end + + alt Execution Context Stops Successfully + + Machine->>LocalState: Merge contextual changes into transactional state + else Execution Context Reverts + Machine->>LocalState: Discard contextual changes + end + + Machine-->>-Machine: Execution ended + + alt Execution terminated successfully + KakarotCore->>Starknet: Apply transactional state diffs to Starknet + + else Execution failed + KakarotCore->>LocalState: Discard transactional changes + end + + KakarotCore-->>-User: Transaction result + +``` + +Interactions between Kakarot, its local state and Starknet +storage + +## Implementation + +We need to be able to store in the local state the current information: + +- The existing modified accounts content, including balance, nonce, code and + storage updates, +- The emitted events, +- The newly created accounts, +- The deleted accounts through `selfdestruct` +- The pending transfers of native tokens. + +At the end of an execution context, we can merge the contextual state into the +transactional state, and at the end of a transaction, we can apply the +transactional state updates to the blockchain storage, emit pending events, and +perform actual token transfers. + +## Implementation design + +The state is implemented as a struct composed by `StateChangeLog` - for objects +that need to be overridden in the State - and `SimpleLog` data structures, for +objects that only need to be appended to a list. They are implemented as +follows: + +```rust +struct State { + /// Accounts states - without storage and balances, which are handled separately. + accounts: StateChangeLog, + /// Account storage states. `EthAddress` indicates the target contract, + /// `u256` indicates the storage key. + /// `u256` indicates the value stored. + /// We have to store the target contract, as we can't derive it from the + /// hashed address only when finalizing. + accounts_storage: StateChangeLog<(EthAddress, u256, u256)>, + /// Account states + /// Pending emitted events + events: SimpleLog, + /// Account balances updates. This is only internal accounting and stored + /// balances are updated when committing transfers. + balances: StateChangeLog, + /// Pending transfers + transfers: SimpleLog, +} +``` + +The State struct + +A `StateChangeLog` is a data structure that tracks the changes made to a +specific object both at the context-level and at the transaction-level using the +mechanism specified above. The `SimpleLog` is a simplified version of this +concept as an append-only data structure. + +```rust +/// The `StateChangeLog` tracks the changes applied to storage during the execution of a transaction. +/// Upon exiting an execution context, contextual changes must be finalized into transactional changes. +/// Upon exiting the transaction, transactional changes must be finalized into storage updates. +/// +/// # Type Parameters +/// +/// * `T` - The type of values stored in the log. +/// +/// # Fields +/// +/// * `contextual_changes` - A `Felt252Dict` of contextual changes. Tracks the changes applied inside a single execution context. +/// * `contextual_keyset` - An `Array` of contextual keys. +/// * `transactional_changes` - A `Felt252Dict` of transactional changes. Tracks +/// the changes applied in the entire transaction. +/// * `transactional_keyset` - An `Array` of transactional keys. +struct StateChangeLog { + contextual_changes: Felt252Dict>, + contextual_keyset: Array, + transactional_changes: Felt252Dict>, + transactional_keyset: Array +} +``` + +The StateChangeLog generic struct + +```rust + +/// `SimpleLog` is a straightforward logging mechanism. +/// +/// This structure is designed to manage both contextual and transactional logs of a generic type `T`. +/// +/// # Fields +/// +/// - `contextual_logs`: Contains logs that are context-specific. +/// - `transactional_logs`: Contains logs that are transaction-wide. +#[derive(Drop)] +struct SimpleLog { + contextual_logs: Array, + transactional_logs: Array, +} +``` + +The SimpleLog generic struct + +Storage changes are modeled using a dictionary where the key is the storage +address to update, and the value is the updated value. However, we can't create +nested dictionaries in Cairo - so we have to separate the accounts storage +updates from the account updates themselves. diff --git a/kakarot-ssj/docs/general/machine.md b/kakarot-ssj/docs/general/machine.md new file mode 100644 index 000000000..efc8f6d07 --- /dev/null +++ b/kakarot-ssj/docs/general/machine.md @@ -0,0 +1,242 @@ +# Kakarot's EVM - Internal Design + +The EVM is a stack-based computer responsible for the execution of EVM bytecode. +It has two context-bound data structures: the stack and the memory. The stack is +a 256bit-words based data structure used to store and retrieve intermediate +values during the execution of opcodes. The memory is a byte-addressable data +structure organized into 32-byte words used a volatile space to store data +during execution. Both the stack and the memory are initialized empty at the +start of a call context, and destroyed when a call context ends. + +The initial design of Kakarot's EVM had a single struct to model the execution +context, which contained the stack, the memory, and the execution state. Each +local execution context optionally contained parent and child execution +contexts, which were used to model the execution of sub-calls. However, this +design was not possible to implement in Cairo, as Cairo does not support the use +of `Nullable` types containing dictionaries. Since the `ExecutionContext` struct +contains such `Nullable` types, we had to change the design of the EVM to use a +machine with a single stack and memory, which are our dict-based data +structures. + +## The Kakarot Machine design + +To overcome the problem stated above, we have come up with the following design: + +- There is only one instance of the Memory and the Stack, which is shared + between the different execution contexts. +- Each execution context has its own identifier `id`, which uniquely identifies + it. +- Each execution context has a `parent_ctx` field, which value is either a + pointer to its parent execution context or `null`. +- Each execution context has a `return_data` field, whose value is either + nothing or the return data from the child context. This is meant to enable + opcodes `RETURNDATASIZE` and `RETURNDATACOPY`. These two opcodes are the only + ones enabling a current context to access its child context's return data. +- The execution context tree is a directed acyclic graph, where each execution + context has at most one parent. +- A specific execution context is accessible by traversing the execution context + tree, starting from the root execution context, and following the execution + context tree until the desired execution context is reached. The machine also + stores a pointer to the current execution context. +- The execution context tree is initialized with a single root execution + context, which has no parent and no child. It has an `id` field equal to 0. + +The following diagram describes the model of the Kakarot machine. + +```mermaid +classDiagram + class Machine{ + current_ctx: Box~ExecutionContext~, + ctx_count: usize, + stack: Stack, + memory: Memory, + state: State, + } + + class Memory{ + active_segment: usize, + items: Felt252Dict~u128~, + bytes_len: Felt252Dict~usize~, + } + + class Stack{ + +active_segment: usize, + +items: Felt252Dict~Nullable~u256~~, + +len: Felt252Dict~usize~ + } + + class ExecutionContext{ + ctx_type: ExecutionContextType, + address: Address, + program_counter: u32, + status: Status, + call_ctx: Box~CallContext~, + return_data: Span~u8~, + parent_ctx: Nullable~ExecutionContext~, + gas_used: u128, + } + + class ExecutionContextType { + <> + Root: IsCreate, + Call: usize, + Create: usize + } + + class CallContext{ + caller: EthAddress, + value: u256, + bytecode: Span~u8~, + calldata: Span~u8~, + gas_price: u128, + gas_limit: u128, + read_only: bool, + ret_offset: usize, + ret_size: usize, + } + + class State{ + accounts: StateChangeLog~Account~, + accounts_storage: StateChangeLog~EthAddress_u256_u256~, + events: SimpleLog~Event~, + transfers: SimpleLog~Transfer~, + } + + class StateChangeLog~T~ { + contextual_changes: Felt252Dict~Nullable~T~~, + contextual_keyset: Array~felt252~, + transactional_changes: Felt252Dict~Nullable~T~~, + transactional_keyset: Array~felt252~ + } + + class SimpleLog~T~ { + contextual_logs: Array~T~, + transactional_logs: Array~T~, + } + + class Status{ + <> + Active, + Stopped, + Reverted + } + + + Machine *-- Memory + Machine *-- Stack + Machine *-- ExecutionContext + Machine *-- State + ExecutionContext *-- ExecutionContext + ExecutionContext *-- ExecutionContextType + ExecutionContext *-- CallContext + ExecutionContext *-- Status + State *-- StateChangeLog + State *-- SimpleLog +``` + +Kakarot internal architecture model + +### The Stack + +Instead of having one Stack per execution context, we have a single Stack shared +between all execution contexts. Because our Stack is a dict-based data +structure, we can actually simulate multiple stacks by using different keys for +each execution context. The `active_segment` field of the Stack is used to keep +track of the current active execution context. The `len` field is a dictionary +field is a dictionary mapping execution context identifiers to the length of +their corresponding stacks. The `items` field is a dictionary mapping indexes to +values. + +The EVM imposes a limit of a maximum of 1024 items on the stack. At any given +time, the stack relative to an execution context contains at most 1024 items. +This means that if we consider items to be stored at sequential indexes, the +stack relative to an execution context is a contiguous segment of the global +stack of maximum size `1024`. When pushing an item to the stack, we will compute +an index which corresponds to the index in the dict the item will be stored at. +The internal index is computed as follows: + +$$index = len(Stack_i) + i \cdot 1024$$ + +where $i$ is the id of the active execution context. + +If we want to push an item to the stack of the root context, the internal index +will be $index = len(Stack_0) + 0 \cdot 1024 = len(Stack_0)$. + +The process is analogous for popping an item from the stack. + +### The Memory + +The Memory is modeled in a similar way to the Stack. The difference is that the +memory doesn't have a limit on the number of items it can store. Instead, the +cost of expanding the size of the memory grows quadratically relative to its +size. Given that an Ethereum block has a gas limit, we can assume that the +maximum size of the memory is bounded by the gas limit of a block, which is 30M +gas. + +The expansion cost of the memory is defined as follows in the Ethereum Yellow +Paper: + +$$C_{mem}(a) \equiv G_{memory} · a + [\frac{a^2}{512}]$$ + +where $G_{memory} = 3$ and $a$ is the number of 32-byte words allocated. + +Following this formula, the gas costs required to have a memory containing +125000 words is above the 30M gas limit. We will use this heuristic to bound the +maximum size of the memory to the closest power of two to 125000: $2^17$. +Therefore, we will bound the maximum size of the memory to 131072 256-bits +words. + +The internal index at which an item will be inserted in the memory, given a +specific offset, is computed as: + +$$index = offset + i \cdot 131072$$ + +where $i$ is the id of the active execution context. + +If we want to store an item at offset 10 of the memory relative to the execution +context of id 1, the internal index will be +$index = 10 + 1 \cdot 131072 = 131082$. + +## Execution flow + +The following diagram describe the flow of the execution context when executing +the `run` function given an instance of the `Machine` struct instantiated with +the bytecode to execute and the appropriate execution context. + +The run function is responsible for executing EVM bytecode. The flow of +execution involves decoding and executing the current opcode, handling the +execution, and continue executing the next opcode if the execution of the +previous one succeeded. If the execution of an opcode fails, the execution +context reverts, the changes made in this context are dropped, and the state of +the blockchain is not updated. + +```mermaid +flowchart TD +AA["START"] --> A +A["run()"] --> B[Decode and Execute Opcode] +B --> |pc+=1| C{Result OK?} +C -->|Yes| D{Execution stopped?} +D -->|No| A +D -->|Yes| F{Reverted?} +C -->|No| RA +F --> |No| FA +F -->|Yes| RA[Discard account updates] + +subgraph Discard context changes +RA --> RB["Discard storage updates"] +RB --> RC["Discard event log"] +RC --> RD["Discard transfers log"] +end + +RD --> FA[finalize context] +``` + +Execution flow of EVM bytecode + +## Conclusion + +With its shared stack and memory accessed via calculated internal indexes +relative to the current execution context, this EVM design remains compatible +with the original EVM design, easily refactorable if we implement all +interactions with the machine through type methods, and compatible with Cairo's +limitations. diff --git a/kakarot-ssj/docs/general/volition.png b/kakarot-ssj/docs/general/volition.png new file mode 100644 index 0000000000000000000000000000000000000000..d254f23146763edfb12c1f5a6e7c10246dee16e8 GIT binary patch literal 192376 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 F{||r!7tR0x literal 0 HcmV?d00001 diff --git a/kakarot-ssj/package-lock.json b/kakarot-ssj/package-lock.json new file mode 100644 index 000000000..d17076994 --- /dev/null +++ b/kakarot-ssj/package-lock.json @@ -0,0 +1,434 @@ +{ + "name": "kakarot-ssj", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "kakarot-ssj", + "dependencies": { + "@ethereumjs/tx": "^5.0.0", + "dotenv": "^16.3.1", + "ethers": "^6.8.1", + "rlp": "^3.0.0", + "starknet": "^5.19.5" + }, + "devDependencies": { + "bun-types": "latest" + }, + "peerDependencies": { + "typescript": "^5.0.0" + } + }, + "node_modules/@adraffy/ens-normalize": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz", + "integrity": "sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==" + }, + "node_modules/@ethereumjs/common": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-4.1.0.tgz", + "integrity": "sha512-XWdQvUjlQHVwh4uGEPFKHpsic69GOsMXEhlHrggS5ju/+2zAmmlz6B25TkCCymeElC9DUp13tH5Tc25Iuvtlcg==", + "dependencies": { + "@ethereumjs/util": "^9.0.1", + "crc": "^4.3.2" + } + }, + "node_modules/@ethereumjs/rlp": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-5.0.1.tgz", + "integrity": "sha512-Ab/Hfzz+T9Zl+65Nkg+9xAmwKPLicsnQ4NW49pgvJp9ovefuic95cgOS9CbPc9izIEgsqm1UitV0uNveCvud9w==", + "bin": { + "rlp": "bin/rlp.cjs" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@ethereumjs/tx": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-5.1.0.tgz", + "integrity": "sha512-VUhw2+4yXArJZRWhPjmZFrN4WUjUo0qUZUszVpW2KzsGlqCFf67kwJcH9Rca5eS0CRHjr2qHJLpvYOjNuaXVdA==", + "dependencies": { + "@ethereumjs/common": "^4.1.0", + "@ethereumjs/rlp": "^5.0.1", + "@ethereumjs/util": "^9.0.1", + "ethereum-cryptography": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "c-kzg": "^2.1.2" + }, + "peerDependenciesMeta": { + "c-kzg": { + "optional": true + } + } + }, + "node_modules/@ethereumjs/util": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@ethereumjs/util/-/util-9.0.1.tgz", + "integrity": "sha512-NdFFEzCc3H1sYkNnnySwLg6owdQMhjUc2jfuDyx8Xv162WSluCnnSKouKOSG3njGNEyy2I9NmF8zTRDwuqpZWA==", + "dependencies": { + "@ethereumjs/rlp": "^5.0.1", + "ethereum-cryptography": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "c-kzg": "^2.1.2" + }, + "peerDependenciesMeta": { + "c-kzg": { + "optional": true + } + } + }, + "node_modules/@noble/curves": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz", + "integrity": "sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==", + "dependencies": { + "@noble/hashes": "1.3.1" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", + "integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/base": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.3.tgz", + "integrity": "sha512-/+SgoRjLq7Xlf0CWuLHq2LUZeL/w65kfzAPG5NH9pcmBhs+nunQTn4gvdwgMTIXnt9b2C/1SeL2XiysZEyIC9Q==", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.3.1.tgz", + "integrity": "sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A==", + "dependencies": { + "@noble/curves": "~1.1.0", + "@noble/hashes": "~1.3.1", + "@scure/base": "~1.1.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip39": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.1.tgz", + "integrity": "sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==", + "dependencies": { + "@noble/hashes": "~1.3.0", + "@scure/base": "~1.1.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/starknet": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@scure/starknet/-/starknet-0.3.0.tgz", + "integrity": "sha512-Ma66yZlwa5z00qI5alSxdWtIpky5LBhy22acVFdoC5kwwbd9uDyMWEYzWHdNyKmQg9t5Y2UOXzINMeb3yez+Gw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/curves": "~1.2.0", + "@noble/hashes": "~1.3.2" + } + }, + "node_modules/@scure/starknet/node_modules/@noble/curves": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", + "dependencies": { + "@noble/hashes": "1.3.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/starknet/node_modules/@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@types/node": { + "version": "18.15.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.13.tgz", + "integrity": "sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==" + }, + "node_modules/aes-js": { + "version": "4.0.0-beta.5", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz", + "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==" + }, + "node_modules/bun-types": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/bun-types/-/bun-types-1.0.14.tgz", + "integrity": "sha512-hLVfM2fk8xSJeobfuPGilfvxM5gLtEy1bn7RJhrtw3u4OaC0kieXKYFFTVHU8jZ3hj8YyPLIFClIUodkFSrMBQ==", + "dev": true + }, + "node_modules/crc": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/crc/-/crc-4.3.2.tgz", + "integrity": "sha512-uGDHf4KLLh2zsHa8D8hIQ1H/HtFQhyHrc0uhHBcoKGol/Xnb+MPYfUMw7cvON6ze/GUESTudKayDcJC5HnJv1A==", + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "buffer": ">=6.0.3" + }, + "peerDependenciesMeta": { + "buffer": { + "optional": true + } + } + }, + "node_modules/dotenv": { + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", + "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/motdotla/dotenv?sponsor=1" + } + }, + "node_modules/ethereum-cryptography": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.1.2.tgz", + "integrity": "sha512-Z5Ba0T0ImZ8fqXrJbpHcbpAvIswRte2wGNR/KePnu8GbbvgJ47lMxT/ZZPG6i9Jaht4azPDop4HaM00J0J59ug==", + "dependencies": { + "@noble/curves": "1.1.0", + "@noble/hashes": "1.3.1", + "@scure/bip32": "1.3.1", + "@scure/bip39": "1.2.1" + } + }, + "node_modules/ethers": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.8.1.tgz", + "integrity": "sha512-iEKm6zox5h1lDn6scuRWdIdFJUCGg3+/aQWu0F4K0GVyEZiktFkqrJbRjTn1FlYEPz7RKA707D6g5Kdk6j7Ljg==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/ethers-io/" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@adraffy/ens-normalize": "1.10.0", + "@noble/curves": "1.2.0", + "@noble/hashes": "1.3.2", + "@types/node": "18.15.13", + "aes-js": "4.0.0-beta.5", + "tslib": "2.4.0", + "ws": "8.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/ethers/node_modules/@noble/curves": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", + "dependencies": { + "@noble/hashes": "1.3.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ethers/node_modules/@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/isomorphic-fetch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", + "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", + "dependencies": { + "node-fetch": "^2.6.1", + "whatwg-fetch": "^3.4.1" + } + }, + "node_modules/lossless-json": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/lossless-json/-/lossless-json-2.0.11.tgz", + "integrity": "sha512-BP0vn+NGYvzDielvBZaFain/wgeJ1hTvURCqtKvhr1SCPePdaaTanmmcplrHfEJSJOUql7hk4FHwToNJjWRY3g==" + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/pako": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", + "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==" + }, + "node_modules/rlp": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/rlp/-/rlp-3.0.0.tgz", + "integrity": "sha512-PD6U2PGk6Vq2spfgiWZdomLvRGDreBLxi5jv5M8EpRo3pU6VEm31KO+HFxE18Q3vgqfDrQ9pZA3FP95rkijNKw==", + "bin": { + "rlp": "bin/rlp" + } + }, + "node_modules/starknet": { + "version": "5.24.3", + "resolved": "https://registry.npmjs.org/starknet/-/starknet-5.24.3.tgz", + "integrity": "sha512-v0TuaNc9iNtHdbIRzX372jfQH1vgx2rwBHQDMqK4DqjJbwFEE5dog8Go6rGiZVW750NqRSWrZ7ahqyRNc3bscg==", + "dependencies": { + "@noble/curves": "~1.2.0", + "@scure/base": "^1.1.3", + "@scure/starknet": "~0.3.0", + "isomorphic-fetch": "^3.0.0", + "lossless-json": "^2.0.8", + "pako": "^2.0.4", + "url-join": "^4.0.1" + } + }, + "node_modules/starknet/node_modules/@noble/curves": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", + "dependencies": { + "@noble/hashes": "1.3.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/starknet/node_modules/@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, + "node_modules/typescript": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.2.tgz", + "integrity": "sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-fetch": { + "version": "3.6.19", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.19.tgz", + "integrity": "sha512-d67JP4dHSbm2TrpFj8AbO8DnL1JXL5J9u0Kq2xW6d0TFDbCA3Muhdt8orXC22utleTVj7Prqt82baN6RBvnEgw==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/ws": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", + "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + } + } +} diff --git a/kakarot-ssj/package.json b/kakarot-ssj/package.json new file mode 100644 index 000000000..6b1f6bed4 --- /dev/null +++ b/kakarot-ssj/package.json @@ -0,0 +1,24 @@ +{ + "name": "kakarot-ssj", + "type": "module", + "devDependencies": { + "bun-types": "latest" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "dependencies": { + "@ethereumjs/tx": "^5.0.0", + "dotenv": "^16.3.1", + "ethers": "^6.8.1", + "rlp": "^3.0.0", + "@types/inquirer": "^9.0.7", + "inquirer": "^9.2.12", + "starknet": "^5.19.5", + "viem": "^1.19.8" + }, + "scripts": { + "compute_starknet_address": "bun run scripts/compute_starknet_address.ts", + "compute_create_address": "bun run scripts/compute_create_address.ts" + } +} diff --git a/kakarot-ssj/rust-toolchain b/kakarot-ssj/rust-toolchain new file mode 100644 index 000000000..dbd41264a --- /dev/null +++ b/kakarot-ssj/rust-toolchain @@ -0,0 +1 @@ +1.81.0 diff --git a/kakarot-ssj/scripts/compare_snapshot.py b/kakarot-ssj/scripts/compare_snapshot.py new file mode 100644 index 000000000..e8c4c83eb --- /dev/null +++ b/kakarot-ssj/scripts/compare_snapshot.py @@ -0,0 +1,166 @@ +import json +import logging +import os +import re + +# trunk-ignore(bandit/B404) +import subprocess +import tempfile +import zipfile +from pathlib import Path + +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + + +def get_github_token_from_env(file_path=".env"): + """Read the .env file and extract the GITHUB_TOKEN value.""" + try: + with open(file_path, "r") as file: + for line in file: + if line.startswith("#"): + continue + key, value = line.strip().split("=", 1) + if key == "GITHUB_TOKEN": + return value if value != "" else None + except FileNotFoundError: + return None + except ValueError: + logger.error( + f"Error: Invalid format in {file_path}. Expected 'KEY=VALUE' format." + ) + return None + + +def get_previous_snapshot(): + REPO = "kkrt-labs/kakarot-ssj" # Replace with your GitHub username and repo name + GITHUB_TOKEN = os.environ.get("GITHUB_TOKEN", get_github_token_from_env()) + if GITHUB_TOKEN is None: + raise ValueError( + "GITHUB_TOKEN doesn't exist in current shell nor is defined .env" + ) + + # Fetch the list of workflow runs + cmd = f"curl -s -H 'Authorization: token {GITHUB_TOKEN}' -H 'Accept: application/vnd.github.v3+json' 'https://api.github.com/repos/{REPO}/actions/runs?branch=main&per_page=100'" + # trunk-ignore(bandit/B602) + result = subprocess.check_output(cmd, shell=True) + runs = json.loads(result) + + # Find the latest successful run + latest_successful_run = next( + ( + run + for run in runs["workflow_runs"] + if run["conclusion"] == "success" + and run["name"] == "Generate and Upload Gas Snapshot" + ), + None, + ) + + if latest_successful_run is None: + return + + # Fetch the artifacts for that run + run_id = latest_successful_run["id"] + cmd = f"curl -s -H 'Authorization: token {GITHUB_TOKEN}' -H 'Accept: application/vnd.github.v3+json' 'https://api.github.com/repos/{REPO}/actions/runs/{run_id}/artifacts'" + # trunk-ignore(bandit/B602) + result = subprocess.check_output(cmd, shell=True) + artifacts = json.loads(result) + + # Find the gas_snapshot.json artifact + snapshot_artifact = next( + ( + artifact + for artifact in artifacts["artifacts"] + if artifact["name"] == "gas-snapshot" + ), + None, + ) + + if snapshot_artifact is None: + return + + # Download the gas_snapshots.json archive + temp_dir = Path(tempfile.mkdtemp()) + + archive_name = temp_dir / "gas_snapshot.zip" + cmd = f"curl -s -L -o {archive_name} -H 'Authorization: token {GITHUB_TOKEN}' -H 'Accept: application/vnd.github.v3+json' '{snapshot_artifact['archive_download_url']}'" + # trunk-ignore(bandit/B602) + subprocess.check_call(cmd, shell=True) + with zipfile.ZipFile(archive_name, "r") as archive: + archive.extractall(temp_dir) + + return json.loads(archive_name.with_suffix(".json").read_text()) + + +def get_current_gas_snapshot(): + """Execute command and return current gas snapshots.""" + # trunk-ignore(bandit/B602) + # trunk-ignore(bandit/B607) + output = subprocess.check_output("scarb test", shell=True).decode("utf-8") + pattern = r"test ([\w\:]+).*gas usage est\.\: (\d+)" + matches = re.findall(pattern, output) + matches.sort() + return {match[0]: int(match[1]) for match in matches} + + +def compare_snapshots(current, previous): + """Compare current and previous snapshots and return differences.""" + worsened = [] + improvements = [] + common_keys = list(set(current.keys()) & set(previous.keys())) + common_keys.sort() + max_key_len = max(len(key) for key in common_keys) + for key in common_keys: + prev = previous[key] + cur = current[key] + log = ( + f"|{key:<{max_key_len + 5}} | {prev:>10} | {cur:>10} | {cur / prev:>6.2%}|" + ) + if prev < cur: + worsened.append(log) + elif prev > cur: + improvements.append(log) + + return improvements, worsened + + +def total_gas_used(current, previous): + """Return the total gas used in the current and previous snapshot, not taking into account added tests.""" + common_keys = set(current.keys()) & set(previous.keys()) + + cur_gas = sum(current[key] for key in common_keys) + prev_gas = sum(previous[key] for key in common_keys) + + return cur_gas, prev_gas + + +def main(): + previous_snapshot = get_previous_snapshot() + if previous_snapshot is None: + logger.error("Error: Failed to load previous snapshot.") + return + + current_snapshots = get_current_gas_snapshot() + improvements, worsened = compare_snapshots(current_snapshots, previous_snapshot) + cur_gas, prev_gas = total_gas_used(current_snapshots, previous_snapshot) + header = [ + "| Test | Prev | Cur | Ratio |", + "| ---- | ---- | --- | ----- |", + ] + if improvements: + logger.info("\n".join(["****BETTER****"] + header + improvements)) + if worsened: + logger.info("\n".join(["****WORST****"] + header + worsened)) + + logger.info( + f"\nTotal gas change: {prev_gas} -> {cur_gas} ({cur_gas / prev_gas:.2%})" + ) + if worsened: + logger.error("Gas usage increased") + else: + logger.info("Gas change ✅") + + +if __name__ == "__main__": + main() diff --git a/kakarot-ssj/scripts/compute_create_address.ts b/kakarot-ssj/scripts/compute_create_address.ts new file mode 100644 index 000000000..e912c34fd --- /dev/null +++ b/kakarot-ssj/scripts/compute_create_address.ts @@ -0,0 +1,60 @@ +import { Address, Hex, getContractAddress } from "viem"; +import { createPromptModule } from "inquirer"; + +const prompt = createPromptModule(); + +prompt([ + { + type: "list", + name: "opcode", + message: "Choose an opcode:", + choices: ["CREATE", "CREATE2"], + }, + { + type: "input", + name: "from", + message: "Enter from address:", + default: "0xF39FD6E51AAD88F6F4CE6AB8827279CFFFB92266", + }, + { + type: "input", + name: "nonce", + message: "Enter nonce:", + default: "420", + when: (answers) => answers.opcode === "CREATE", + filter: (value) => BigInt(value), + }, + { + type: "input", + name: "bytecode", + message: "Enter bytecode", + default: + "0x608060405234801561000f575f80fd5b506004361061004a575f3560e01c806306661abd1461004e578063371303c01461006c5780636d4ce63c14610076578063b3bcfa8214610094575b5f80fd5b61005661009e565b60405161006391906100f7565b60405180910390f35b6100746100a3565b005b61007e6100bd565b60405161008b91906100f7565b60405180910390f35b61009c6100c5565b005b5f5481565b60015f808282546100b4919061013d565b92505081905550565b5f8054905090565b60015f808282546100d69190610170565b92505081905550565b5f819050919050565b6100f1816100df565b82525050565b5f60208201905061010a5f8301846100e8565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f610147826100df565b9150610152836100df565b925082820190508082111561016a57610169610110565b5b92915050565b5f61017a826100df565b9150610185836100df565b925082820390508181111561019d5761019c610110565b5b9291505056fea26469706673582212207e792fcff28a4bf0bad8675c5bc2288b07835aebaa90b8dc5e0df19183fb72cf64736f6c63430008160033", + when: (answers) => answers.opcode === "CREATE2", + }, + { + type: "input", + name: "salt", + message: "Enter salt or press Enter for default [0xbeef]:", + default: "0xbeef", + when: (answers) => answers.opcode === "CREATE2", + }, +]).then((answers) => { + let address: Address; + if (answers.opcode === "CREATE") { + address = getContractAddress({ + opcode: "CREATE", + from: answers.from as Address, + nonce: answers.nonce, + }); + } else if (answers.opcode === "CREATE2") { + address = getContractAddress({ + opcode: "CREATE2", + from: answers.from as Address, + bytecode: answers.bytecode as Hex, + salt: answers.salt as Hex, + }); + } + + console.log(`Generated Address: ${address!}`); +}); diff --git a/kakarot-ssj/scripts/compute_rlp_encoding.ts b/kakarot-ssj/scripts/compute_rlp_encoding.ts new file mode 100644 index 000000000..692922397 --- /dev/null +++ b/kakarot-ssj/scripts/compute_rlp_encoding.ts @@ -0,0 +1,160 @@ +// This js script helps in creating unsigned and signed RLP data for tests + +import { ethers, toBeArray } from "ethers"; +import dotevn from "dotenv"; +import readline from "readline"; +import { readFileSync } from "fs"; + +dotevn.config(); + +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, +}); + +const question = (query: string): Promise => { + return new Promise((resolve, reject) => { + rl.question(query, (answer) => { + resolve(answer); + }); + }); +}; + +const main = async () => { + const { Transaction, Wallet } = ethers; + const { decodeRlp, getBytes } = ethers; + + if (!process.env.PRIVATE_KEY) { + console.log( + "missing private key in environment, please provide PRIVATE_KEY environment variable", + ); + process.exit(1); + } + + const wallet = new Wallet(process.env.PRIVATE_KEY); + console.log("address of the wallet is", wallet.address); + + let tx_type = parseInt( + await question( + "enter transaction, 0: legacy, 1: 2930, 2:1559, 3: inc_counter, 4: y_parity_false eip1559: ", + ), + ); + + // for type 0 and type 1 + let tx; + + switch (tx_type) { + case 0: + tx = JSON.parse( + readFileSync("./scripts/data/input_legacy_tx.json", "utf-8"), + ); + break; + case 1: + tx = JSON.parse( + readFileSync("./scripts/data/input_access_list_tx.json", "utf-8"), + ); + break; + case 2: + tx = JSON.parse( + readFileSync("./scripts/data/input_fee_tx.json", "utf-8"), + ); + break; + case 3: + tx_type = 1; + tx = JSON.parse( + readFileSync( + "./scripts/data/input_eip_2930_counter_inc_tx.json", + "utf-8", + ), + ); + break; + case 4: + tx_type = 2; + tx = JSON.parse( + readFileSync( + "./scripts/data/input_eip1559_y_parity_false.json", + "utf-8", + ), + ); + break; + default: + throw new Error( + `transaction type ${tx_type} isn't a valid transaction type`, + ); + } + + const transaction = Transaction.from(tx); + transaction.type = tx_type; + + let signed_tx = await wallet.signTransaction(transaction); + + console.log("unsigned serialized tx ----->", transaction.unsignedSerialized); + console.log("unsigned transaction hash", transaction.hash); + + // const bytes = getBytes(signedTX); + const bytes = getBytes(transaction.unsignedSerialized); + + console.log("unsigned RLP encoded bytes for the transaction: "); + + // this prints unsigned RLP encoded bytes of the transaction + bytes.forEach((v) => { + console.log(v, ","); + }); + console.log("\n"); + + let bytes2 = Uint8Array.from(transaction.type == 0 ? bytes : bytes.slice(1)); + + let decodedRlp = decodeRlp(bytes2); + console.log("decoded RLP is for unsigned transaction ....\n", decodedRlp); + + let bytes3 = getBytes(signed_tx); + + console.log("signed RLP encoded bytes for the transaction: "); + + // this prints unsigned RLP encoded bytes of the transaction + bytes3.forEach((v) => { + console.log(v, ","); + }); + console.log("\n"); + + bytes3 = Uint8Array.from(transaction.type == 0 ? bytes3 : bytes3.slice(1)); + decodedRlp = decodeRlp(bytes3); + console.log("signed decoded RLP for signed transaction ....\n", decodedRlp); + + const hash = ethers.keccak256(bytes); + console.log("the hash over which the signature was made:", hash); + + console.log("signature details: "); + const v = decodedRlp[decodedRlp.length - 3]; + const r = decodedRlp[decodedRlp.length - 2]; + const s = decodedRlp[decodedRlp.length - 1]; + + const y_parity = + tx_type == 0 + ? get_y_parity(BigInt(v), BigInt(tx.chainId)) + : parseInt(v, 16) == 1; + console.log("r: ", r); + console.log("s: ", s); + if (tx_type == 0) { + console.log("v: ", v); + } + console.log("y parity: ", y_parity); + + process.exit(0); +}; + +const get_y_parity = (v: bigint, chain_id: bigint): boolean => { + let y_parity = v - (chain_id * BigInt(2) + BigInt(35)); + if (y_parity == BigInt(0) || y_parity == BigInt(1)) { + return y_parity == BigInt(1); + } + + y_parity = v - (chain_id * BigInt(2) + BigInt(36)); + if (y_parity == BigInt(0) || y_parity == BigInt(1)) { + return y_parity == BigInt(1); + } + + throw new Error("invalid v value"); +}; + +main(); diff --git a/kakarot-ssj/scripts/compute_starknet_address.ts b/kakarot-ssj/scripts/compute_starknet_address.ts new file mode 100644 index 000000000..5e3cafd52 --- /dev/null +++ b/kakarot-ssj/scripts/compute_starknet_address.ts @@ -0,0 +1,48 @@ +import { hash } from "starknet"; +import inquirer from "inquirer"; + +inquirer + .prompt([ + { + type: "input", + name: "classHashInput", + message: "Enter the class hash:", + validate: (input) => { + if (input.trim() === "") { + return "Class hash is required."; + } + return true; + }, + }, + { + type: "input", + name: "saltInput", + message: "Enter the salt", + default: "0x65766d5f61646472657373", + }, + { + type: "input", + name: "deployerInput", + message: "Enter the deployer address", + default: + "0x7753aaa1814b9f978fd93b66453ae87419b66d764fbf9313847edeb0283ef63", + }, + ]) + .then((answers) => { + const classHash = BigInt(answers.classHashInput); + const salt = BigInt(answers.saltInput); + const deployerAddress = BigInt(answers.deployerInput); + + const CONSTRUCTOR_CALLDATA = [deployerAddress, salt]; + + function compute_starknet_address() { + return hash.calculateContractAddressFromHash( + salt, + classHash, + CONSTRUCTOR_CALLDATA, + deployerAddress, + ); + } + + console.log("Pre-computed Starknet Address: " + compute_starknet_address()); + }); diff --git a/kakarot-ssj/scripts/data/input_access_list_tx.json b/kakarot-ssj/scripts/data/input_access_list_tx.json new file mode 100644 index 000000000..3c5b2a88e --- /dev/null +++ b/kakarot-ssj/scripts/data/input_access_list_tx.json @@ -0,0 +1,18 @@ +{ + "nonce": "0x0", + "gasPrice": "0x3b9aca00", + "gasLimit": "0x1e8480", + "to": "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984", + "value": "0x016345785d8a0000", + "data": "0xabcdef", + "accessList": [ + [ + "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984", + [ + "0xde9fbe35790b85c23f42b7430c78f122636750cc217a534c80a9a0520969fa65", + "0xd5362e94136f76bfc8dad0b510b94561af7a387f1a9d0d45e777c11962e5bd94" + ] + ] + ], + "chainId": "0x4b4b5254" +} diff --git a/kakarot-ssj/scripts/data/input_eip1559_y_parity_false.json b/kakarot-ssj/scripts/data/input_eip1559_y_parity_false.json new file mode 100644 index 000000000..16ac42ade --- /dev/null +++ b/kakarot-ssj/scripts/data/input_eip1559_y_parity_false.json @@ -0,0 +1,11 @@ +{ + "nonce": "0x1", + "maxPriorityFeePerGas": "0x64", + "maxFeePerGas": "0x3e8", + "gasLimit": "0x64c9", + "to": "0xcccccccccccccccccccccccccccccccccccccccc", + "value": "0x0", + "data": "0x00", + "accessList": [], + "chainId": "0x4b4b5254" +} diff --git a/kakarot-ssj/scripts/data/input_eip_2930_counter_inc_tx.json b/kakarot-ssj/scripts/data/input_eip_2930_counter_inc_tx.json new file mode 100644 index 000000000..9792f0baa --- /dev/null +++ b/kakarot-ssj/scripts/data/input_eip_2930_counter_inc_tx.json @@ -0,0 +1,10 @@ +{ + "chainId": "0x4b4b5254", + "nonce": "0x0", + "gasPrice": "0x3b9aca00", + "gasLimit": "0x1e8480", + "to": "0x0000006f746865725f65766d5f61646472657373", + "value": "0x0", + "data": "0x371303c0", + "accessList": [] +} diff --git a/kakarot-ssj/scripts/data/input_fee_tx.json b/kakarot-ssj/scripts/data/input_fee_tx.json new file mode 100644 index 000000000..3ad77596e --- /dev/null +++ b/kakarot-ssj/scripts/data/input_fee_tx.json @@ -0,0 +1,19 @@ +{ + "nonce": "0x0", + "maxPriorityFeePerGas": "0x0", + "maxFeePerGas": "0x3b9aca00", + "gasLimit": "0x1e8480", + "to": "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984", + "value": "0x016345785d8a0000", + "data": "0xabcdef", + "accessList": [ + [ + "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984", + [ + "0xde9fbe35790b85c23f42b7430c78f122636750cc217a534c80a9a0520969fa65", + "0xd5362e94136f76bfc8dad0b510b94561af7a387f1a9d0d45e777c11962e5bd94" + ] + ] + ], + "chainId": "0x4b4b5254" +} diff --git a/kakarot-ssj/scripts/data/input_legacy_deploy_tx.json b/kakarot-ssj/scripts/data/input_legacy_deploy_tx.json new file mode 100644 index 000000000..48dc3c338 --- /dev/null +++ b/kakarot-ssj/scripts/data/input_legacy_deploy_tx.json @@ -0,0 +1,9 @@ +{ + "nonce": "0x0", + "gasPrice": "0x0a", + "gasLimit": "0x061a80", + "to": null, + "value": "0x0186a0", + "data": "0x600160010a5060006000f3", + "chainId": "0x4b4b5254" +} diff --git a/kakarot-ssj/scripts/data/input_legacy_tx.json b/kakarot-ssj/scripts/data/input_legacy_tx.json new file mode 100644 index 000000000..65349db27 --- /dev/null +++ b/kakarot-ssj/scripts/data/input_legacy_tx.json @@ -0,0 +1,9 @@ +{ + "nonce": "0x0", + "gasPrice": "0x3b9aca00", + "gasLimit": "0x1e8480", + "to": "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984", + "value": "0x016345785d8a0000", + "data": "0xabcdef", + "chainId": "0x4b4b5254" +} diff --git a/kakarot-ssj/scripts/filter_tests.py b/kakarot-ssj/scripts/filter_tests.py new file mode 100644 index 000000000..7d514b79a --- /dev/null +++ b/kakarot-ssj/scripts/filter_tests.py @@ -0,0 +1,50 @@ +import os +import re +import sys + + +def filter_tests(directory, filter_string): + for root, _, files in os.walk(directory): + for file in files: + if file.endswith(".cairo"): + file_path = os.path.join(root, file) + filter_file(file_path, filter_string) + + print(f"Filtered tests for {filter_string}") + + +def filter_file(file_path, filter_string): + with open(file_path, "r") as f: + content = f.read() + + # Regular expression to match test functions, including nested braces + test_pattern = re.compile( + r"#\[test\]\s*(?:#\[available_gas\([^\)]+\)\]\s*)?fn\s+(\w+)\s*\([^)]*\)\s*(\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})", + re.DOTALL, + ) + + def replace_func(match): + full_match = match.group(0) + func_name = match.group(1) + if filter_string.lower() in func_name.lower(): + return full_match + else: + return "" + + new_content = test_pattern.sub(replace_func, content) + + if new_content != content: + with open(file_path, "w") as f: + f.write(new_content) + + +if __name__ == "__main__": + if len(sys.argv) != 2: + print("Usage: python filter_tests.py ") + sys.exit(1) + + filter_string = sys.argv[1] + crates_dir = os.path.join( + os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "crates" + ) + filter_tests(crates_dir, filter_string) diff --git a/kakarot-ssj/scripts/find_selectory.py b/kakarot-ssj/scripts/find_selectory.py new file mode 100644 index 000000000..e126ad432 --- /dev/null +++ b/kakarot-ssj/scripts/find_selectory.py @@ -0,0 +1,30 @@ +import os +import re + +from starkware.starknet.public.abi import get_selector_from_name + + +def find_cairo_functions(directory): + return [ + match + for root, _, files in os.walk(directory) + for file in files + if file.endswith(".cairo") + for match in re.findall(r"fn\s+(\w+)\(", open(os.path.join(root, file)).read()) + ] + + +def map_selectors(functions): + return {get_selector_from_name(function): function for function in functions} + + +def get_function_from_selector(selectors): + selector = int(input("Enter the hexadecimal selector: "), 16) + print(f"Corresponding function: {selectors.get(selector, 'Not found')}") + + +if __name__ == "__main__": + directory = "." + functions = find_cairo_functions(directory) + selectors = map_selectors(functions) + get_function_from_selector(selectors) diff --git a/kakarot-ssj/scripts/gas_debug_call.py b/kakarot-ssj/scripts/gas_debug_call.py new file mode 100644 index 000000000..f9a5a49a7 --- /dev/null +++ b/kakarot-ssj/scripts/gas_debug_call.py @@ -0,0 +1,38 @@ +import re + + +def process_logs(logs): + gas_consumption = {} + previous_gas = {} + + pattern = re.compile( + r"Address (\d+), opcode (\w+), pc (\d+), gas left in call (\d+)" + ) + + for line in logs.split("\n"): + match = pattern.search(line) + if match: + address, opcode, pc, gas_left = match.groups() + address = int(address) + pc = int(pc) + gas_left = int(gas_left) + + if address not in gas_consumption: + gas_consumption[address] = 0 + previous_gas[address] = gas_left + else: + gas_used = previous_gas[address] - gas_left + gas_consumption[address] += gas_used + previous_gas[address] = gas_left + + print( + f"{hex(address)} - {pc} - {opcode} --> total gas used: {gas_consumption[address]}" + ) + + +# Example usage +logs = """ +Address 1169201309864722334562947866173026415724746034380, opcode 96, pc 1, gas left in call 79978644 +""" + +process_logs(logs) diff --git a/kakarot-ssj/scripts/gen_snapshot.py b/kakarot-ssj/scripts/gen_snapshot.py new file mode 100644 index 000000000..1e36f133c --- /dev/null +++ b/kakarot-ssj/scripts/gen_snapshot.py @@ -0,0 +1,22 @@ +import json +import re + +# trunk-ignore(bandit/B404) +import subprocess + +# Execute the command and capture the output +# trunk-ignore(bandit/B602) +# trunk-ignore(bandit/B607) +output = subprocess.check_output("scarb cairo-test", shell=True).decode("utf-8") + +# Use regex to capture test names and their associated gas usage +pattern = r"test (.+?) \.\.\. ok \(gas usage est.: (\d+)\)" +matches = re.findall(pattern, output) + +# Convert matches to a dictionary +results = {match[0]: int(match[1]) for match in matches} +sorted_results = {k: results[k] for k in sorted(results.keys())} + +# Dump the results to a JSON file +with open("gas_snapshot.json", "w") as outfile: + json.dump(sorted_results, outfile, indent=4) diff --git a/kakarot-ssj/scripts/install_hook.sh b/kakarot-ssj/scripts/install_hook.sh new file mode 100644 index 000000000..f5ab3d834 --- /dev/null +++ b/kakarot-ssj/scripts/install_hook.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +cat <>.git/hooks/pre-commit +#!/bin/sh + +# Run scarb fmt to format the project. +scarb fmt + +# Check if any files were modified after running scarb fmt. +changed_files=$(git diff --name-only || true) + +if [ -n "${changed_files}" ]; then + echo "The following files were reformatted and staged:" + echo "${changed_files}" + # Stage the changes. + git add ${changed_files} +else + echo "No files were reformatted." +fi + +# Continue with the commit +exit 0 +EOT + +# Check if the current directory is a git repository +if [[ ! -d .git ]]; then + echo "Error: This is not a git repository." + exit 1 +fi + +# Make the hook executable +chmod +x .git/hooks/pre-commit + +echo "pre-commit hook has been installed successfully!" +echo "pre-push hook has been installed successfully!" diff --git a/kakarot-ssj/scripts/run_filtered_tests.py b/kakarot-ssj/scripts/run_filtered_tests.py new file mode 100644 index 000000000..9c755c572 --- /dev/null +++ b/kakarot-ssj/scripts/run_filtered_tests.py @@ -0,0 +1,73 @@ +import os +import pty +import select +import shutil +import subprocess +import sys +import tempfile +from contextlib import contextmanager +from pathlib import Path + +from filter_tests import filter_tests + +PROJECT_FILES = ["Scarb.toml", "Scarb.lock", ".tool-versions"] + + +@contextmanager +def temporary_project_copy(src_dir): + with tempfile.TemporaryDirectory() as temp_dir: + temp_path = Path(temp_dir) + src_path = Path(src_dir) + + for file in PROJECT_FILES: + if (src_file := src_path / file).exists(): + shutil.copy2(src_file, temp_path / file) + + if (src_crates := src_path / "crates").exists(): + shutil.copytree(src_crates, temp_path / "crates", symlinks=True) + + yield temp_path + + +def stream_output(fd): + while True: + try: + r, _, _ = select.select([fd], [], [], 0.1) + if r: + data = os.read(fd, 1024) + if not data: + break + sys.stdout.buffer.write(data) + sys.stdout.buffer.flush() + except OSError: + break + + +def run_scarb_command(command, cwd): + master, slave = pty.openpty() + with subprocess.Popen( + command, shell=True, stdout=slave, stderr=slave, close_fds=True, cwd=cwd + ) as process: + os.close(slave) + stream_output(master) + return_code = process.wait() + + if return_code != 0: + print(f"Error: Scarb command failed with return code {return_code}") + sys.exit(return_code) + + +def run_filtered_tests(package, filter_name): + project_root = Path(__file__).parent.parent + + with temporary_project_copy(project_root) as temp_project_dir: + filter_tests(temp_project_dir / "crates", filter_name) + run_scarb_command(f"scarb test -p {package} {filter_name}", temp_project_dir) + + +if __name__ == "__main__": + if len(sys.argv) != 3: + print("Usage: python run_filtered_tests.py ") + sys.exit(1) + + run_filtered_tests(sys.argv[1], sys.argv[2]) diff --git a/kakarot-ssj/scripts/setup_cairo_native.sh b/kakarot-ssj/scripts/setup_cairo_native.sh new file mode 100755 index 000000000..8b74c612c --- /dev/null +++ b/kakarot-ssj/scripts/setup_cairo_native.sh @@ -0,0 +1,185 @@ +#!/bin/bash + +install_essential_deps_linux() { + apt-get update -y + apt-get install -y \ + curl \ + jq \ + ripgrep \ + wget \ + ca-certificates \ + gnupg \ + git +} + +setup_llvm_deps() { + case "$(uname)" in + Darwin) + brew update + brew install llvm@19 + + LIBRARY_PATH=/opt/homebrew/lib + MLIR_SYS_190_PREFIX="$(brew --prefix llvm@19)" + LLVM_SYS_191_PREFIX="${MLIR_SYS_190_PREFIX}" + TABLEGEN_190_PREFIX="${MLIR_SYS_190_PREFIX}" + + export LIBRARY_PATH + export MLIR_SYS_190_PREFIX + export LLVM_SYS_191_PREFIX + export TABLEGEN_190_PREFIX + ;; + Linux) + export DEBIAN_FRONTEND=noninteractive + export TZ=America/New_York + + # shellcheck disable=SC2312 + CODENAME=$(grep VERSION_CODENAME /etc/os-release | cut -d= -f2) + if [[ -z ${CODENAME} ]]; then + echo "Error: Unable to determine OS codename" + exit 1 + fi + + # shellcheck disable=SC2312 + echo "deb http://apt.llvm.org/${CODENAME}/ llvm-toolchain-${CODENAME}-19 main" >/etc/apt/sources.list.d/llvm-19.list + echo "deb-src http://apt.llvm.org/${CODENAME}/ llvm-toolchain-${CODENAME}-19 main" >>/etc/apt/sources.list.d/llvm-19.list + # shellcheck disable=SC2312 + if ! wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -; then + echo "Error: Failed to add LLVM GPG key" + exit 1 + fi + + if ! apt-get update && apt-get upgrade -y; then + echo "Error: Failed to update and upgrade packages" + exit 1 + fi + if ! apt-get install -y llvm-19 llvm-19-dev llvm-19-runtime clang-19 clang-tools-19 lld-19 libpolly-19-dev libmlir-19-dev mlir-19-tools; then + echo "Error: Failed to install LLVM packages" + exit 1 + fi + + MLIR_SYS_190_PREFIX=/usr/lib/llvm-19/ + LLVM_SYS_191_PREFIX=/usr/lib/llvm-19/ + TABLEGEN_190_PREFIX=/usr/lib/llvm-19/ + + export MLIR_SYS_190_PREFIX + export LLVM_SYS_191_PREFIX + export TABLEGEN_190_PREFIX + + { + echo "MLIR_SYS_190_PREFIX=${MLIR_SYS_190_PREFIX}" + echo "LLVM_SYS_191_PREFIX=${LLVM_SYS_191_PREFIX}" + echo "TABLEGEN_190_PREFIX=${TABLEGEN_190_PREFIX}" + } >>"${GITHUB_ENV}" + ;; + *) + echo "Error: Unsupported operating system" + exit 1 + ;; + esac + + # GitHub Actions specific + [[ -n ${GITHUB_ACTIONS} ]] && { + { + echo "MLIR_SYS_190_PREFIX=${MLIR_SYS_190_PREFIX}" + echo "LLVM_SYS_191_PREFIX=${LLVM_SYS_191_PREFIX}" + echo "TABLEGEN_190_PREFIX=${TABLEGEN_190_PREFIX}" + } >>"${GITHUB_ENV}" + } +} + +install_rust() { + if command -v cargo >/dev/null 2>&1; then + echo "Rust is already installed with cargo available in PATH." + return 0 + fi + + echo "cargo not found. Installing Rust..." + # shellcheck disable=SC2312 + if ! curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain 1.81.0 --no-modify-path; then + echo >&2 "Failed to install Rust. Aborting." + return 1 + fi + + # shellcheck disable=SC1091 + if [[ -f "${HOME}/.cargo/env" ]]; then + . "${HOME}/.cargo/env" + else + echo >&2 "Failed to find Rust environment file. Aborting." + return 1 + fi + + echo "Rust installed successfully." +} + +install_cairo_native_runtime() { + install_rust || { + echo "Error: Failed to install Rust" + exit 1 + } + + git clone https://github.com/lambdaclass/cairo_native.git + pushd ./cairo_native || exit 1 + make deps + make runtime + cp libcairo_native_runtime.a ../libcairo_native_runtime.a + popd || exit 1 + + rm -rf ./cairo_native + + CAIRO_NATIVE_RUNTIME_LIBRARY=$(pwd)/libcairo_native_runtime.a + if [[ -z ${CAIRO_NATIVE_RUNTIME_LIBRARY} ]]; then + echo "Error: Failed to set CAIRO_NATIVE_RUNTIME_LIBRARY" + exit 1 + fi + export CAIRO_NATIVE_RUNTIME_LIBRARY + + echo "CAIRO_NATIVE_RUNTIME_LIBRARY=${CAIRO_NATIVE_RUNTIME_LIBRARY}" + + [[ -n ${GITHUB_ACTIONS} ]] && echo "CAIRO_NATIVE_RUNTIME_LIBRARY=${CAIRO_NATIVE_RUNTIME_LIBRARY}" >>"${GITHUB_ENV}" +} + +main() { + # New argument parsing + SKIP_RUNTIME=false + while getopts ":s" opt; do + case ${opt} in + s) + SKIP_RUNTIME=true + ;; + \?) + echo "Invalid option: ${OPTARG}" 1>&2 + exit 1 + ;; + *) + echo "Error: Unhandled option" 1>&2 + exit 1 + ;; + esac + done + shift $((OPTIND - 1)) + + # shellcheck disable=SC2312 + [[ "$(uname)" == "Linux" ]] && install_essential_deps_linux + + setup_llvm_deps + + if [[ ${SKIP_RUNTIME} == false ]]; then + install_cairo_native_runtime + else + echo "Skipping Cairo native runtime installation" + # Set the environment variable if the library file exists + # shellcheck disable=SC2312 + if [[ -f "$(pwd)/libcairo_native_runtime.a" ]]; then + CAIRO_NATIVE_RUNTIME_LIBRARY=$(pwd)/libcairo_native_runtime.a + export CAIRO_NATIVE_RUNTIME_LIBRARY + echo "CAIRO_NATIVE_RUNTIME_LIBRARY=${CAIRO_NATIVE_RUNTIME_LIBRARY}" + [[ -n ${GITHUB_ACTIONS} ]] && echo "CAIRO_NATIVE_RUNTIME_LIBRARY=${CAIRO_NATIVE_RUNTIME_LIBRARY}" >>"${GITHUB_ENV}" + else + echo "Warning: libcairo_native_runtime.a not found. CAIRO_NATIVE_RUNTIME_LIBRARY not set." + fi + fi + + echo "LLVM and Cairo native runtime dependencies setup completed." +} + +main "$@" diff --git a/kakarot-ssj/tsconfig.json b/kakarot-ssj/tsconfig.json new file mode 100644 index 000000000..e9aac3373 --- /dev/null +++ b/kakarot-ssj/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "lib": ["ESNext"], + "module": "esnext", + "target": "esnext", + "moduleResolution": "bundler", + "moduleDetection": "force", + "allowImportingTsExtensions": true, + "noEmit": true, + "composite": true, + "strict": true, + "downlevelIteration": true, + "skipLibCheck": true, + "jsx": "react-jsx", + "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": true, + "allowJs": true, + "types": [ + "bun-types", // add Bun global + ], + }, +} From 99672e971ab91c08b188a6230cfd8c7ad4f0a53f Mon Sep 17 00:00:00 2001 From: Oba Date: Tue, 1 Oct 2024 10:56:00 +0200 Subject: [PATCH 02/56] chore: move sources to kakarot0/src --- experimental_contracts/foundry.toml | 9 -- kakarot-ssj/.github/CODEOWNERS | 3 - .../.github/ISSUE_TEMPLATE/01_BUG_REPORT.md | 40 ------ .../ISSUE_TEMPLATE/02_FEATURE_REQUEST.md | 23 ---- .../ISSUE_TEMPLATE/03_CODEBASE_IMPROVEMENT.md | 9 -- kakarot-ssj/.github/ISSUE_TEMPLATE/config.yml | 6 - kakarot-ssj/.github/PULL_REQUEST_TEMPLATE.md | 39 ------ kakarot-ssj/.github/workflows/build.yml | 32 ----- kakarot-ssj/.github/workflows/ci.yml | 82 ----------- kakarot-ssj/.github/workflows/ef-tests.yml | 129 ------------------ kakarot-ssj/.github/workflows/release.yml | 28 ---- kakarot-ssj/.github/workflows/test.yml | 26 ---- kakarot-ssj/.github/workflows/tests-unit.yml | 26 ---- .../.github/workflows/trunk-check.yaml | 24 ---- .../cairo1_contracts}/mock_pragma/.gitignore | 0 .../mock_pragma/.tool-versions | 0 .../cairo1_contracts}/mock_pragma/Scarb.lock | 0 .../cairo1_contracts}/mock_pragma/Scarb.toml | 0 .../mock_pragma/src/lib.cairo | 0 .../mock_pragma/src/mock_pragma_oracle.cairo | 0 .../cairo1_contracts}/token/.gitignore | 0 .../cairo1_contracts}/token/.tool-versions | 0 .../cairo1_contracts}/token/Scarb.lock | 0 .../cairo1_contracts}/token/Scarb.toml | 0 .../cairo1_contracts}/token/src/lib.cairo | 0 .../token/src/starknet_token.cairo | 0 .../cairo1_contracts}/utils/.gitignore | 0 .../cairo1_contracts}/utils/.tool-versions | 0 .../cairo1_contracts}/utils/Scarb.lock | 0 .../cairo1_contracts}/utils/Scarb.toml | 0 .../utils/src/benchmark_cairo_calls.cairo | 0 .../cairo1_contracts}/utils/src/lib.cairo | 0 .../utils/src/universal_library_caller.cairo | 0 {docs => kakarot0/docs}/CODE_OF_CONDUCT.md | 0 {docs => kakarot0/docs}/CONTRIBUTING.md | 0 {docs => kakarot0/docs}/SECURITY.md | 0 {docs => kakarot0/docs}/general/accounts.md | 0 .../docs}/general/cairo_precompiles.md | 0 .../docs}/general/decode_a_cairo_trace.md | 0 .../docs}/general/kakarot_components.md | 0 {docs => kakarot0/docs}/img/architecture.png | Bin {docs => kakarot0/docs}/img/codespaces.png | Bin .../docs}/img/core_evm_diagram.png | Bin .../docs}/img/kakarot_github_banner.png | Bin {src => kakarot0/src}/backend/starknet.cairo | 0 {src => kakarot0/src}/kakarot/account.cairo | 0 .../kakarot/accounts/account_contract.cairo | 0 .../src}/kakarot/accounts/library.cairo | 0 .../src}/kakarot/accounts/model.cairo | 0 .../accounts/uninitialized_account.cairo | 0 {src => kakarot0/src}/kakarot/constants.cairo | 0 {src => kakarot0/src}/kakarot/errors.cairo | 0 {src => kakarot0/src}/kakarot/eth_rpc.cairo | 0 {src => kakarot0/src}/kakarot/events.cairo | 0 {src => kakarot0/src}/kakarot/evm.cairo | 0 {src => kakarot0/src}/kakarot/gas.cairo | 0 .../instructions/block_information.cairo | 0 .../instructions/duplication_operations.cairo | 0 .../environmental_information.cairo | 0 .../instructions/exchange_operations.cairo | 0 .../instructions/logging_operations.cairo | 0 .../instructions/memory_operations.cairo | 0 .../instructions/push_operations.cairo | 0 .../src}/kakarot/instructions/sha3.cairo | 0 .../stop_and_math_operations.cairo | 0 .../instructions/system_operations.cairo | 0 .../src}/kakarot/interfaces/interfaces.cairo | 0 .../src}/kakarot/interpreter.cairo | 0 {src => kakarot0/src}/kakarot/kakarot.cairo | 0 {src => kakarot0/src}/kakarot/library.cairo | 0 {src => kakarot0/src}/kakarot/memory.cairo | 0 {src => kakarot0/src}/kakarot/model.cairo | 0 .../src}/kakarot/precompiles/blake2f.cairo | 0 .../src}/kakarot/precompiles/ec_recover.cairo | 0 .../src}/kakarot/precompiles/identity.cairo | 0 .../precompiles/kakarot_precompiles.cairo | 0 .../src}/kakarot/precompiles/p256verify.cairo | 0 .../kakarot/precompiles/precompiles.cairo | 0 .../precompiles/precompiles_helpers.cairo | 0 .../src}/kakarot/precompiles/ripemd160.cairo | 0 .../src}/kakarot/precompiles/sha256.cairo | 0 {src => kakarot0/src}/kakarot/stack.cairo | 0 {src => kakarot0/src}/kakarot/state.cairo | 0 {src => kakarot0/src}/kakarot/storages.cairo | 0 .../src}/openzeppelin/ERC20.cairo | 0 .../src}/utils/OpenzeppelinAccount.cairo | 0 {src => kakarot0/src}/utils/array.cairo | 0 {src => kakarot0/src}/utils/bytes.cairo | 0 {src => kakarot0/src}/utils/dict.cairo | 0 .../src}/utils/eth_transaction.cairo | 0 {src => kakarot0/src}/utils/maths.cairo | 0 {src => kakarot0/src}/utils/rlp.cairo | 0 {src => kakarot0/src}/utils/signature.cairo | 0 {src => kakarot0/src}/utils/uint256.cairo | 0 {src => kakarot0/src}/utils/utils.cairo | 0 kakarot_scripts/constants.py | 4 +- pyproject.toml | 2 +- tests/fixtures/starknet.py | 2 +- 98 files changed, 4 insertions(+), 480 deletions(-) delete mode 100644 experimental_contracts/foundry.toml delete mode 100644 kakarot-ssj/.github/CODEOWNERS delete mode 100644 kakarot-ssj/.github/ISSUE_TEMPLATE/01_BUG_REPORT.md delete mode 100644 kakarot-ssj/.github/ISSUE_TEMPLATE/02_FEATURE_REQUEST.md delete mode 100644 kakarot-ssj/.github/ISSUE_TEMPLATE/03_CODEBASE_IMPROVEMENT.md delete mode 100644 kakarot-ssj/.github/ISSUE_TEMPLATE/config.yml delete mode 100644 kakarot-ssj/.github/PULL_REQUEST_TEMPLATE.md delete mode 100644 kakarot-ssj/.github/workflows/build.yml delete mode 100644 kakarot-ssj/.github/workflows/ci.yml delete mode 100644 kakarot-ssj/.github/workflows/ef-tests.yml delete mode 100644 kakarot-ssj/.github/workflows/release.yml delete mode 100644 kakarot-ssj/.github/workflows/test.yml delete mode 100644 kakarot-ssj/.github/workflows/tests-unit.yml delete mode 100644 kakarot-ssj/.github/workflows/trunk-check.yaml rename {cairo1_contracts => kakarot0/cairo1_contracts}/mock_pragma/.gitignore (100%) rename {cairo1_contracts => kakarot0/cairo1_contracts}/mock_pragma/.tool-versions (100%) rename {cairo1_contracts => kakarot0/cairo1_contracts}/mock_pragma/Scarb.lock (100%) rename {cairo1_contracts => kakarot0/cairo1_contracts}/mock_pragma/Scarb.toml (100%) rename {cairo1_contracts => kakarot0/cairo1_contracts}/mock_pragma/src/lib.cairo (100%) rename {cairo1_contracts => kakarot0/cairo1_contracts}/mock_pragma/src/mock_pragma_oracle.cairo (100%) rename {cairo1_contracts => kakarot0/cairo1_contracts}/token/.gitignore (100%) rename {cairo1_contracts => kakarot0/cairo1_contracts}/token/.tool-versions (100%) rename {cairo1_contracts => kakarot0/cairo1_contracts}/token/Scarb.lock (100%) rename {cairo1_contracts => kakarot0/cairo1_contracts}/token/Scarb.toml (100%) rename {cairo1_contracts => kakarot0/cairo1_contracts}/token/src/lib.cairo (100%) rename {cairo1_contracts => kakarot0/cairo1_contracts}/token/src/starknet_token.cairo (100%) rename {cairo1_contracts => kakarot0/cairo1_contracts}/utils/.gitignore (100%) rename {cairo1_contracts => kakarot0/cairo1_contracts}/utils/.tool-versions (100%) rename {cairo1_contracts => kakarot0/cairo1_contracts}/utils/Scarb.lock (100%) rename {cairo1_contracts => kakarot0/cairo1_contracts}/utils/Scarb.toml (100%) rename {cairo1_contracts => kakarot0/cairo1_contracts}/utils/src/benchmark_cairo_calls.cairo (100%) rename {cairo1_contracts => kakarot0/cairo1_contracts}/utils/src/lib.cairo (100%) rename {cairo1_contracts => kakarot0/cairo1_contracts}/utils/src/universal_library_caller.cairo (100%) rename {docs => kakarot0/docs}/CODE_OF_CONDUCT.md (100%) rename {docs => kakarot0/docs}/CONTRIBUTING.md (100%) rename {docs => kakarot0/docs}/SECURITY.md (100%) rename {docs => kakarot0/docs}/general/accounts.md (100%) rename {docs => kakarot0/docs}/general/cairo_precompiles.md (100%) rename {docs => kakarot0/docs}/general/decode_a_cairo_trace.md (100%) rename {docs => kakarot0/docs}/general/kakarot_components.md (100%) rename {docs => kakarot0/docs}/img/architecture.png (100%) rename {docs => kakarot0/docs}/img/codespaces.png (100%) rename {docs => kakarot0/docs}/img/core_evm_diagram.png (100%) rename {docs => kakarot0/docs}/img/kakarot_github_banner.png (100%) rename {src => kakarot0/src}/backend/starknet.cairo (100%) rename {src => kakarot0/src}/kakarot/account.cairo (100%) rename {src => kakarot0/src}/kakarot/accounts/account_contract.cairo (100%) rename {src => kakarot0/src}/kakarot/accounts/library.cairo (100%) rename {src => kakarot0/src}/kakarot/accounts/model.cairo (100%) rename {src => kakarot0/src}/kakarot/accounts/uninitialized_account.cairo (100%) rename {src => kakarot0/src}/kakarot/constants.cairo (100%) rename {src => kakarot0/src}/kakarot/errors.cairo (100%) rename {src => kakarot0/src}/kakarot/eth_rpc.cairo (100%) rename {src => kakarot0/src}/kakarot/events.cairo (100%) rename {src => kakarot0/src}/kakarot/evm.cairo (100%) rename {src => kakarot0/src}/kakarot/gas.cairo (100%) rename {src => kakarot0/src}/kakarot/instructions/block_information.cairo (100%) rename {src => kakarot0/src}/kakarot/instructions/duplication_operations.cairo (100%) rename {src => kakarot0/src}/kakarot/instructions/environmental_information.cairo (100%) rename {src => kakarot0/src}/kakarot/instructions/exchange_operations.cairo (100%) rename {src => kakarot0/src}/kakarot/instructions/logging_operations.cairo (100%) rename {src => kakarot0/src}/kakarot/instructions/memory_operations.cairo (100%) rename {src => kakarot0/src}/kakarot/instructions/push_operations.cairo (100%) rename {src => kakarot0/src}/kakarot/instructions/sha3.cairo (100%) rename {src => kakarot0/src}/kakarot/instructions/stop_and_math_operations.cairo (100%) rename {src => kakarot0/src}/kakarot/instructions/system_operations.cairo (100%) rename {src => kakarot0/src}/kakarot/interfaces/interfaces.cairo (100%) rename {src => kakarot0/src}/kakarot/interpreter.cairo (100%) rename {src => kakarot0/src}/kakarot/kakarot.cairo (100%) rename {src => kakarot0/src}/kakarot/library.cairo (100%) rename {src => kakarot0/src}/kakarot/memory.cairo (100%) rename {src => kakarot0/src}/kakarot/model.cairo (100%) rename {src => kakarot0/src}/kakarot/precompiles/blake2f.cairo (100%) rename {src => kakarot0/src}/kakarot/precompiles/ec_recover.cairo (100%) rename {src => kakarot0/src}/kakarot/precompiles/identity.cairo (100%) rename {src => kakarot0/src}/kakarot/precompiles/kakarot_precompiles.cairo (100%) rename {src => kakarot0/src}/kakarot/precompiles/p256verify.cairo (100%) rename {src => kakarot0/src}/kakarot/precompiles/precompiles.cairo (100%) rename {src => kakarot0/src}/kakarot/precompiles/precompiles_helpers.cairo (100%) rename {src => kakarot0/src}/kakarot/precompiles/ripemd160.cairo (100%) rename {src => kakarot0/src}/kakarot/precompiles/sha256.cairo (100%) rename {src => kakarot0/src}/kakarot/stack.cairo (100%) rename {src => kakarot0/src}/kakarot/state.cairo (100%) rename {src => kakarot0/src}/kakarot/storages.cairo (100%) rename {src => kakarot0/src}/openzeppelin/ERC20.cairo (100%) rename {src => kakarot0/src}/utils/OpenzeppelinAccount.cairo (100%) rename {src => kakarot0/src}/utils/array.cairo (100%) rename {src => kakarot0/src}/utils/bytes.cairo (100%) rename {src => kakarot0/src}/utils/dict.cairo (100%) rename {src => kakarot0/src}/utils/eth_transaction.cairo (100%) rename {src => kakarot0/src}/utils/maths.cairo (100%) rename {src => kakarot0/src}/utils/rlp.cairo (100%) rename {src => kakarot0/src}/utils/signature.cairo (100%) rename {src => kakarot0/src}/utils/uint256.cairo (100%) rename {src => kakarot0/src}/utils/utils.cairo (100%) diff --git a/experimental_contracts/foundry.toml b/experimental_contracts/foundry.toml deleted file mode 100644 index d2f13274a..000000000 --- a/experimental_contracts/foundry.toml +++ /dev/null @@ -1,9 +0,0 @@ -[profile.default] -src = 'src' -test = 'tests' -out = '../solidity_contracts/build' -libs = ['../lib'] - -[rpc_endpoints] -anvil = "http://127.0.0.1:8545" -kakarot = "http://127.0.0.1:3030" diff --git a/kakarot-ssj/.github/CODEOWNERS b/kakarot-ssj/.github/CODEOWNERS deleted file mode 100644 index f5bcd1a3b..000000000 --- a/kakarot-ssj/.github/CODEOWNERS +++ /dev/null @@ -1,3 +0,0 @@ -* @abdelhamidbakhta -* @Eikix -* @ClementWalter diff --git a/kakarot-ssj/.github/ISSUE_TEMPLATE/01_BUG_REPORT.md b/kakarot-ssj/.github/ISSUE_TEMPLATE/01_BUG_REPORT.md deleted file mode 100644 index 350367dfd..000000000 --- a/kakarot-ssj/.github/ISSUE_TEMPLATE/01_BUG_REPORT.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -name: Bug Report -about: Create a report to help Kakarot to improve -title: "bug: " -labels: "bug" -assignees: "" ---- - -## Bug Report - -**Kakarot version:** - - - -**Current behavior:** - - - -**Expected behavior:** - - - -**Steps to reproduce:** - - - -**Related code:** - - - -```bash -insert short code snippets here -``` - -**Other information:** - - diff --git a/kakarot-ssj/.github/ISSUE_TEMPLATE/02_FEATURE_REQUEST.md b/kakarot-ssj/.github/ISSUE_TEMPLATE/02_FEATURE_REQUEST.md deleted file mode 100644 index 44ad3de06..000000000 --- a/kakarot-ssj/.github/ISSUE_TEMPLATE/02_FEATURE_REQUEST.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -name: Feature Request -about: Suggest an idea for this project -title: "feat: " -labels: "enhancement" -assignees: "" ---- - -## Feature Request - -### Describe the Feature Request - -### Describe Preferred Solution - -### Related Code - -### Additional Context - -**If the feature request is approved, would you be willing to submit a PR?** -_(Help can be provided if you need assistance submitting a PR)_ - -- [ ] Yes -- [ ] No diff --git a/kakarot-ssj/.github/ISSUE_TEMPLATE/03_CODEBASE_IMPROVEMENT.md b/kakarot-ssj/.github/ISSUE_TEMPLATE/03_CODEBASE_IMPROVEMENT.md deleted file mode 100644 index 5f0050e39..000000000 --- a/kakarot-ssj/.github/ISSUE_TEMPLATE/03_CODEBASE_IMPROVEMENT.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -name: Codebase improvement -about: - Provide your feedback for the existing codebase. Suggest a better solution for - algorithms, development tools, etc. -title: "dev: " -labels: "enhancement" -assignees: "" ---- diff --git a/kakarot-ssj/.github/ISSUE_TEMPLATE/config.yml b/kakarot-ssj/.github/ISSUE_TEMPLATE/config.yml deleted file mode 100644 index 6a42160f5..000000000 --- a/kakarot-ssj/.github/ISSUE_TEMPLATE/config.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -blank_issues_enabled: false -contact_links: - - name: Kakarot Community Support - url: https://github.com/sayajin-labs/kakarot-ssj/discussions - about: Please ask and answer questions here. diff --git a/kakarot-ssj/.github/PULL_REQUEST_TEMPLATE.md b/kakarot-ssj/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 77cf20ce2..000000000 --- a/kakarot-ssj/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,39 +0,0 @@ - - -## Pull Request type - - - -Please check the type of change your PR introduces: - -- [ ] Bugfix -- [ ] Feature -- [ ] Code style update (formatting, renaming) -- [ ] Refactoring (no functional changes, no API changes) -- [ ] Build-related changes -- [ ] Documentation content changes -- [ ] Other (please describe): - -## What is the current behavior? - - - -Resolves: # - -## What is the new behavior? - - - -- -- -- - -## Does this introduce a breaking change? - -- [ ] Yes -- [ ] No - - diff --git a/kakarot-ssj/.github/workflows/build.yml b/kakarot-ssj/.github/workflows/build.yml deleted file mode 100644 index 7cca4d20d..000000000 --- a/kakarot-ssj/.github/workflows/build.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Reusable Build Workflow - -on: - workflow_call: - inputs: - artifact-name: - required: true - type: string - -permissions: read-all - -jobs: - build: - runs-on: ubuntu-latest - env: - CI_COMMIT_MESSAGE: CI Formatting Auto Commit - CI_COMMIT_AUTHOR: ${{ github.event.repository.name }} CI - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Scarb - uses: software-mansion/setup-scarb@v1 - - - name: Build contracts - run: scarb build -p contracts - - - name: Upload artifacts - uses: actions/upload-artifact@v3 - with: - name: ${{ inputs.artifact-name }} - path: target/dev diff --git a/kakarot-ssj/.github/workflows/ci.yml b/kakarot-ssj/.github/workflows/ci.yml deleted file mode 100644 index b99ecd358..000000000 --- a/kakarot-ssj/.github/workflows/ci.yml +++ /dev/null @@ -1,82 +0,0 @@ -name: CI - -on: - push: - branches: - - main - -env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -permissions: read-all - -jobs: - build: - uses: ./.github/workflows/build.yml - with: - artifact-name: kakarot-ssj-build - - tests-unit: - uses: ./.github/workflows/tests-unit.yml - with: - run-fmt-check: false - - ef-tests: - uses: ./.github/workflows/ef-tests.yml - needs: [build] - with: - artifact-name: kakarot-ssj-build - - resources: - runs-on: ubuntu-latest - needs: [ef-tests] - steps: - - uses: actions/checkout@v4 - - - name: Set up Python 3.10.14 - uses: actions/setup-python@v4 - with: - python-version: 3.10.14 - - - name: Load cached Poetry installation - id: cached-poetry - uses: actions/cache@v4 - with: - path: ~/.local - key: poetry-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }} - - - name: Install Poetry - if: steps.cached-poetry.outputs.cache-hit != 'true' - uses: snok/install-poetry@v1 - with: - virtualenvs-create: true - virtualenvs-in-project: true - installer-parallel: true - - - run: poetry config installer.modern-installation false - - - name: Load cached venv - id: cached-poetry-dependencies - uses: actions/cache@v4 - with: - path: .venv - key: venv-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }} - - - name: Install dependencies - if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true' - run: make setup - - - name: Load performance artifacts - uses: actions/download-artifact@v3 - with: - path: resources - name: resources - - - name: Check resources evolution - run: | - result=$(GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }} make check-resources 2>&1) - echo "$result" >> "$GITHUB_STEP_SUMMARY" diff --git a/kakarot-ssj/.github/workflows/ef-tests.yml b/kakarot-ssj/.github/workflows/ef-tests.yml deleted file mode 100644 index 5957d20fc..000000000 --- a/kakarot-ssj/.github/workflows/ef-tests.yml +++ /dev/null @@ -1,129 +0,0 @@ -name: EF-Tests - -on: - workflow_call: - inputs: - artifact-name: - required: true - type: string - -permissions: read-all - -jobs: - ef-tests: - # trunk-ignore(actionlint/runner-label) - runs-on: ubuntu-latest-16-cores - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Cache cairo-native setup - id: cache-cairo-native - uses: actions/cache@v3 - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - target/ - ./libcairo_native_runtime.a - key: - ${{ runner.os }}-cairo-native-${{ hashFiles('**/Cargo.lock', - 'scripts/setup_cairo_native.sh') }} - - - name: Make setup script executable - run: chmod +x ./scripts/setup_cairo_native.sh - - - name: Setup Cairo Native - run: | - if [[ "${{ steps.cache-cairo-native.outputs.cache-hit }}" == 'true' ]]; then - sudo ./scripts/setup_cairo_native.sh -s - else - sudo ./scripts/setup_cairo_native.sh - fi - - - name: Set Environment Variables - run: | - echo "MLIR_SYS_190_PREFIX=/usr/lib/llvm-19/" >> $GITHUB_ENV - echo "LLVM_SYS_191_PREFIX=/usr/lib/llvm-19/" >> $GITHUB_ENV - echo "TABLEGEN_190_PREFIX=/usr/lib/llvm-19/" >> $GITHUB_ENV - echo "CAIRO_NATIVE_RUNTIME_LIBRARY=$(pwd)/libcairo_native_runtime.a" >> $GITHUB_ENV - - - name: Checkout ef-tests - uses: actions/checkout@v4 - with: - repository: kkrt-labs/ef-tests - ref: feat/cairo-native - path: ef-tests # Check out to a subdirectory to avoid cleaning the kakarot-ssj directory - - - name: Checkout local skip file - uses: actions/checkout@v4 - with: - sparse-checkout: | - blockchain-tests-skip.yml - sparse-checkout-cone-mode: false - path: skip-file - - - name: Setup ef-tests - run: | - mv skip-file/blockchain-tests-skip.yml ef-tests/blockchain-tests-skip.yml - cd ef-tests - mkdir -p build/common - make setup setup-kakarot-v0 - - - name: Install nextest - uses: taiki-e/install-action@nextest - - - name: Download Kakarot-SSJ build artifacts in v1 - uses: actions/download-artifact@v3 - with: - name: ${{ inputs.artifact-name }} - path: ef-tests/build/v1 - - - name: Move Cairo1Helpers - run: | - mv ef-tests/build/v1/contracts_Cairo1Helpers.compiled_contract_class.json \ - ef-tests/build/common/cairo1_helpers.json - - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: 3.10.14 - - # Add this step to verify the file exists - - name: Verify libcairo_native_runtime.a - run: | - echo $CAIRO_NATIVE_RUNTIME_LIBRARY - ls -l $CAIRO_NATIVE_RUNTIME_LIBRARY - - - name: Run tests - working-directory: ef-tests - run: | - set -o pipefail - RUST_MIN_STACK=1342177280 make ef-test-v1-native | tee data.txt - set +o pipefail - - - name: Retrieve ef-tests execution resources - working-directory: ef-tests - run: python scripts/compute_resources.py - env: - KAKAROT_VERSION: v1 - - - name: Upload resources - uses: actions/upload-artifact@v3 - with: - path: ef-tests/resources - name: resources - - - name: Generate blockchain-tests-skip.yml file - if: github.event_name == 'workflow_dispatch' - working-directory: ef-tests - run: make generate-skip-file - - - name: Upload skip file - if: github.event_name == 'workflow_dispatch' - uses: actions/upload-artifact@v3 - with: - path: ef-tests/blockchain-tests-skip.yml - name: blockchain-tests-skip diff --git a/kakarot-ssj/.github/workflows/release.yml b/kakarot-ssj/.github/workflows/release.yml deleted file mode 100644 index 122c07080..000000000 --- a/kakarot-ssj/.github/workflows/release.yml +++ /dev/null @@ -1,28 +0,0 @@ -# trunk-ignore-all(checkov/CKV2_GHA_1) -name: Release - -on: - release: - types: [published] - -jobs: - build-and-upload: - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v4 - - name: Set up Scarb - uses: software-mansion/setup-scarb@v1 - - name: Build contracts - run: | - scarb build -p contracts - - name: Zip dev artifacts - run: zip -rj kakarot-ssj-build.zip target/dev - - name: Upload artifacts to release - uses: svenstaro/upload-release-action@v2 - with: - repo_token: ${{ secrets.GITHUB_TOKEN }} - file: kakarot-ssj-build.zip - asset_name: kakarot-ssj-build.zip - tag: ${{ github.ref_name }} - overwrite: true diff --git a/kakarot-ssj/.github/workflows/test.yml b/kakarot-ssj/.github/workflows/test.yml deleted file mode 100644 index cc095668a..000000000 --- a/kakarot-ssj/.github/workflows/test.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: CI - -permissions: read-all - -on: [pull_request] - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - build: - uses: ./.github/workflows/build.yml - with: - artifact-name: kakarot-ssj-build - - tests-unit: - uses: ./.github/workflows/tests-unit.yml - with: - run-fmt-check: true - - ef-tests: - uses: ./.github/workflows/ef-tests.yml - needs: [build] - with: - artifact-name: kakarot-ssj-build diff --git a/kakarot-ssj/.github/workflows/tests-unit.yml b/kakarot-ssj/.github/workflows/tests-unit.yml deleted file mode 100644 index 2ff0ef28d..000000000 --- a/kakarot-ssj/.github/workflows/tests-unit.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: Reusable Unit Tests Workflow - -on: - workflow_call: - inputs: - run-fmt-check: - type: boolean - default: false - required: false - -permissions: read-all - -jobs: - unit-tests: - runs-on: ubuntu-latest-16-cores # trunk-ignore(actionlint/runner-label) - steps: - - uses: actions/checkout@v4 - - uses: foundry-rs/setup-snfoundry@v3 - - uses: software-mansion/setup-scarb@v1 - - - name: Run format check - if: inputs.run-fmt-check - run: scarb fmt --check - - - name: Run tests - run: scarb test diff --git a/kakarot-ssj/.github/workflows/trunk-check.yaml b/kakarot-ssj/.github/workflows/trunk-check.yaml deleted file mode 100644 index 2e0216311..000000000 --- a/kakarot-ssj/.github/workflows/trunk-check.yaml +++ /dev/null @@ -1,24 +0,0 @@ -name: Trunk - -on: [pull_request] - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -permissions: read-all - -jobs: - trunk_check: - name: Trunk Check Runner - runs-on: ubuntu-latest - permissions: - checks: write # For trunk to post annotations - contents: read # For repo checkout - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Trunk Check - uses: trunk-io/trunk-action@v1 diff --git a/cairo1_contracts/mock_pragma/.gitignore b/kakarot0/cairo1_contracts/mock_pragma/.gitignore similarity index 100% rename from cairo1_contracts/mock_pragma/.gitignore rename to kakarot0/cairo1_contracts/mock_pragma/.gitignore diff --git a/cairo1_contracts/mock_pragma/.tool-versions b/kakarot0/cairo1_contracts/mock_pragma/.tool-versions similarity index 100% rename from cairo1_contracts/mock_pragma/.tool-versions rename to kakarot0/cairo1_contracts/mock_pragma/.tool-versions diff --git a/cairo1_contracts/mock_pragma/Scarb.lock b/kakarot0/cairo1_contracts/mock_pragma/Scarb.lock similarity index 100% rename from cairo1_contracts/mock_pragma/Scarb.lock rename to kakarot0/cairo1_contracts/mock_pragma/Scarb.lock diff --git a/cairo1_contracts/mock_pragma/Scarb.toml b/kakarot0/cairo1_contracts/mock_pragma/Scarb.toml similarity index 100% rename from cairo1_contracts/mock_pragma/Scarb.toml rename to kakarot0/cairo1_contracts/mock_pragma/Scarb.toml diff --git a/cairo1_contracts/mock_pragma/src/lib.cairo b/kakarot0/cairo1_contracts/mock_pragma/src/lib.cairo similarity index 100% rename from cairo1_contracts/mock_pragma/src/lib.cairo rename to kakarot0/cairo1_contracts/mock_pragma/src/lib.cairo diff --git a/cairo1_contracts/mock_pragma/src/mock_pragma_oracle.cairo b/kakarot0/cairo1_contracts/mock_pragma/src/mock_pragma_oracle.cairo similarity index 100% rename from cairo1_contracts/mock_pragma/src/mock_pragma_oracle.cairo rename to kakarot0/cairo1_contracts/mock_pragma/src/mock_pragma_oracle.cairo diff --git a/cairo1_contracts/token/.gitignore b/kakarot0/cairo1_contracts/token/.gitignore similarity index 100% rename from cairo1_contracts/token/.gitignore rename to kakarot0/cairo1_contracts/token/.gitignore diff --git a/cairo1_contracts/token/.tool-versions b/kakarot0/cairo1_contracts/token/.tool-versions similarity index 100% rename from cairo1_contracts/token/.tool-versions rename to kakarot0/cairo1_contracts/token/.tool-versions diff --git a/cairo1_contracts/token/Scarb.lock b/kakarot0/cairo1_contracts/token/Scarb.lock similarity index 100% rename from cairo1_contracts/token/Scarb.lock rename to kakarot0/cairo1_contracts/token/Scarb.lock diff --git a/cairo1_contracts/token/Scarb.toml b/kakarot0/cairo1_contracts/token/Scarb.toml similarity index 100% rename from cairo1_contracts/token/Scarb.toml rename to kakarot0/cairo1_contracts/token/Scarb.toml diff --git a/cairo1_contracts/token/src/lib.cairo b/kakarot0/cairo1_contracts/token/src/lib.cairo similarity index 100% rename from cairo1_contracts/token/src/lib.cairo rename to kakarot0/cairo1_contracts/token/src/lib.cairo diff --git a/cairo1_contracts/token/src/starknet_token.cairo b/kakarot0/cairo1_contracts/token/src/starknet_token.cairo similarity index 100% rename from cairo1_contracts/token/src/starknet_token.cairo rename to kakarot0/cairo1_contracts/token/src/starknet_token.cairo diff --git a/cairo1_contracts/utils/.gitignore b/kakarot0/cairo1_contracts/utils/.gitignore similarity index 100% rename from cairo1_contracts/utils/.gitignore rename to kakarot0/cairo1_contracts/utils/.gitignore diff --git a/cairo1_contracts/utils/.tool-versions b/kakarot0/cairo1_contracts/utils/.tool-versions similarity index 100% rename from cairo1_contracts/utils/.tool-versions rename to kakarot0/cairo1_contracts/utils/.tool-versions diff --git a/cairo1_contracts/utils/Scarb.lock b/kakarot0/cairo1_contracts/utils/Scarb.lock similarity index 100% rename from cairo1_contracts/utils/Scarb.lock rename to kakarot0/cairo1_contracts/utils/Scarb.lock diff --git a/cairo1_contracts/utils/Scarb.toml b/kakarot0/cairo1_contracts/utils/Scarb.toml similarity index 100% rename from cairo1_contracts/utils/Scarb.toml rename to kakarot0/cairo1_contracts/utils/Scarb.toml diff --git a/cairo1_contracts/utils/src/benchmark_cairo_calls.cairo b/kakarot0/cairo1_contracts/utils/src/benchmark_cairo_calls.cairo similarity index 100% rename from cairo1_contracts/utils/src/benchmark_cairo_calls.cairo rename to kakarot0/cairo1_contracts/utils/src/benchmark_cairo_calls.cairo diff --git a/cairo1_contracts/utils/src/lib.cairo b/kakarot0/cairo1_contracts/utils/src/lib.cairo similarity index 100% rename from cairo1_contracts/utils/src/lib.cairo rename to kakarot0/cairo1_contracts/utils/src/lib.cairo diff --git a/cairo1_contracts/utils/src/universal_library_caller.cairo b/kakarot0/cairo1_contracts/utils/src/universal_library_caller.cairo similarity index 100% rename from cairo1_contracts/utils/src/universal_library_caller.cairo rename to kakarot0/cairo1_contracts/utils/src/universal_library_caller.cairo diff --git a/docs/CODE_OF_CONDUCT.md b/kakarot0/docs/CODE_OF_CONDUCT.md similarity index 100% rename from docs/CODE_OF_CONDUCT.md rename to kakarot0/docs/CODE_OF_CONDUCT.md diff --git a/docs/CONTRIBUTING.md b/kakarot0/docs/CONTRIBUTING.md similarity index 100% rename from docs/CONTRIBUTING.md rename to kakarot0/docs/CONTRIBUTING.md diff --git a/docs/SECURITY.md b/kakarot0/docs/SECURITY.md similarity index 100% rename from docs/SECURITY.md rename to kakarot0/docs/SECURITY.md diff --git a/docs/general/accounts.md b/kakarot0/docs/general/accounts.md similarity index 100% rename from docs/general/accounts.md rename to kakarot0/docs/general/accounts.md diff --git a/docs/general/cairo_precompiles.md b/kakarot0/docs/general/cairo_precompiles.md similarity index 100% rename from docs/general/cairo_precompiles.md rename to kakarot0/docs/general/cairo_precompiles.md diff --git a/docs/general/decode_a_cairo_trace.md b/kakarot0/docs/general/decode_a_cairo_trace.md similarity index 100% rename from docs/general/decode_a_cairo_trace.md rename to kakarot0/docs/general/decode_a_cairo_trace.md diff --git a/docs/general/kakarot_components.md b/kakarot0/docs/general/kakarot_components.md similarity index 100% rename from docs/general/kakarot_components.md rename to kakarot0/docs/general/kakarot_components.md diff --git a/docs/img/architecture.png b/kakarot0/docs/img/architecture.png similarity index 100% rename from docs/img/architecture.png rename to kakarot0/docs/img/architecture.png diff --git a/docs/img/codespaces.png b/kakarot0/docs/img/codespaces.png similarity index 100% rename from docs/img/codespaces.png rename to kakarot0/docs/img/codespaces.png diff --git a/docs/img/core_evm_diagram.png b/kakarot0/docs/img/core_evm_diagram.png similarity index 100% rename from docs/img/core_evm_diagram.png rename to kakarot0/docs/img/core_evm_diagram.png diff --git a/docs/img/kakarot_github_banner.png b/kakarot0/docs/img/kakarot_github_banner.png similarity index 100% rename from docs/img/kakarot_github_banner.png rename to kakarot0/docs/img/kakarot_github_banner.png diff --git a/src/backend/starknet.cairo b/kakarot0/src/backend/starknet.cairo similarity index 100% rename from src/backend/starknet.cairo rename to kakarot0/src/backend/starknet.cairo diff --git a/src/kakarot/account.cairo b/kakarot0/src/kakarot/account.cairo similarity index 100% rename from src/kakarot/account.cairo rename to kakarot0/src/kakarot/account.cairo diff --git a/src/kakarot/accounts/account_contract.cairo b/kakarot0/src/kakarot/accounts/account_contract.cairo similarity index 100% rename from src/kakarot/accounts/account_contract.cairo rename to kakarot0/src/kakarot/accounts/account_contract.cairo diff --git a/src/kakarot/accounts/library.cairo b/kakarot0/src/kakarot/accounts/library.cairo similarity index 100% rename from src/kakarot/accounts/library.cairo rename to kakarot0/src/kakarot/accounts/library.cairo diff --git a/src/kakarot/accounts/model.cairo b/kakarot0/src/kakarot/accounts/model.cairo similarity index 100% rename from src/kakarot/accounts/model.cairo rename to kakarot0/src/kakarot/accounts/model.cairo diff --git a/src/kakarot/accounts/uninitialized_account.cairo b/kakarot0/src/kakarot/accounts/uninitialized_account.cairo similarity index 100% rename from src/kakarot/accounts/uninitialized_account.cairo rename to kakarot0/src/kakarot/accounts/uninitialized_account.cairo diff --git a/src/kakarot/constants.cairo b/kakarot0/src/kakarot/constants.cairo similarity index 100% rename from src/kakarot/constants.cairo rename to kakarot0/src/kakarot/constants.cairo diff --git a/src/kakarot/errors.cairo b/kakarot0/src/kakarot/errors.cairo similarity index 100% rename from src/kakarot/errors.cairo rename to kakarot0/src/kakarot/errors.cairo diff --git a/src/kakarot/eth_rpc.cairo b/kakarot0/src/kakarot/eth_rpc.cairo similarity index 100% rename from src/kakarot/eth_rpc.cairo rename to kakarot0/src/kakarot/eth_rpc.cairo diff --git a/src/kakarot/events.cairo b/kakarot0/src/kakarot/events.cairo similarity index 100% rename from src/kakarot/events.cairo rename to kakarot0/src/kakarot/events.cairo diff --git a/src/kakarot/evm.cairo b/kakarot0/src/kakarot/evm.cairo similarity index 100% rename from src/kakarot/evm.cairo rename to kakarot0/src/kakarot/evm.cairo diff --git a/src/kakarot/gas.cairo b/kakarot0/src/kakarot/gas.cairo similarity index 100% rename from src/kakarot/gas.cairo rename to kakarot0/src/kakarot/gas.cairo diff --git a/src/kakarot/instructions/block_information.cairo b/kakarot0/src/kakarot/instructions/block_information.cairo similarity index 100% rename from src/kakarot/instructions/block_information.cairo rename to kakarot0/src/kakarot/instructions/block_information.cairo diff --git a/src/kakarot/instructions/duplication_operations.cairo b/kakarot0/src/kakarot/instructions/duplication_operations.cairo similarity index 100% rename from src/kakarot/instructions/duplication_operations.cairo rename to kakarot0/src/kakarot/instructions/duplication_operations.cairo diff --git a/src/kakarot/instructions/environmental_information.cairo b/kakarot0/src/kakarot/instructions/environmental_information.cairo similarity index 100% rename from src/kakarot/instructions/environmental_information.cairo rename to kakarot0/src/kakarot/instructions/environmental_information.cairo diff --git a/src/kakarot/instructions/exchange_operations.cairo b/kakarot0/src/kakarot/instructions/exchange_operations.cairo similarity index 100% rename from src/kakarot/instructions/exchange_operations.cairo rename to kakarot0/src/kakarot/instructions/exchange_operations.cairo diff --git a/src/kakarot/instructions/logging_operations.cairo b/kakarot0/src/kakarot/instructions/logging_operations.cairo similarity index 100% rename from src/kakarot/instructions/logging_operations.cairo rename to kakarot0/src/kakarot/instructions/logging_operations.cairo diff --git a/src/kakarot/instructions/memory_operations.cairo b/kakarot0/src/kakarot/instructions/memory_operations.cairo similarity index 100% rename from src/kakarot/instructions/memory_operations.cairo rename to kakarot0/src/kakarot/instructions/memory_operations.cairo diff --git a/src/kakarot/instructions/push_operations.cairo b/kakarot0/src/kakarot/instructions/push_operations.cairo similarity index 100% rename from src/kakarot/instructions/push_operations.cairo rename to kakarot0/src/kakarot/instructions/push_operations.cairo diff --git a/src/kakarot/instructions/sha3.cairo b/kakarot0/src/kakarot/instructions/sha3.cairo similarity index 100% rename from src/kakarot/instructions/sha3.cairo rename to kakarot0/src/kakarot/instructions/sha3.cairo diff --git a/src/kakarot/instructions/stop_and_math_operations.cairo b/kakarot0/src/kakarot/instructions/stop_and_math_operations.cairo similarity index 100% rename from src/kakarot/instructions/stop_and_math_operations.cairo rename to kakarot0/src/kakarot/instructions/stop_and_math_operations.cairo diff --git a/src/kakarot/instructions/system_operations.cairo b/kakarot0/src/kakarot/instructions/system_operations.cairo similarity index 100% rename from src/kakarot/instructions/system_operations.cairo rename to kakarot0/src/kakarot/instructions/system_operations.cairo diff --git a/src/kakarot/interfaces/interfaces.cairo b/kakarot0/src/kakarot/interfaces/interfaces.cairo similarity index 100% rename from src/kakarot/interfaces/interfaces.cairo rename to kakarot0/src/kakarot/interfaces/interfaces.cairo diff --git a/src/kakarot/interpreter.cairo b/kakarot0/src/kakarot/interpreter.cairo similarity index 100% rename from src/kakarot/interpreter.cairo rename to kakarot0/src/kakarot/interpreter.cairo diff --git a/src/kakarot/kakarot.cairo b/kakarot0/src/kakarot/kakarot.cairo similarity index 100% rename from src/kakarot/kakarot.cairo rename to kakarot0/src/kakarot/kakarot.cairo diff --git a/src/kakarot/library.cairo b/kakarot0/src/kakarot/library.cairo similarity index 100% rename from src/kakarot/library.cairo rename to kakarot0/src/kakarot/library.cairo diff --git a/src/kakarot/memory.cairo b/kakarot0/src/kakarot/memory.cairo similarity index 100% rename from src/kakarot/memory.cairo rename to kakarot0/src/kakarot/memory.cairo diff --git a/src/kakarot/model.cairo b/kakarot0/src/kakarot/model.cairo similarity index 100% rename from src/kakarot/model.cairo rename to kakarot0/src/kakarot/model.cairo diff --git a/src/kakarot/precompiles/blake2f.cairo b/kakarot0/src/kakarot/precompiles/blake2f.cairo similarity index 100% rename from src/kakarot/precompiles/blake2f.cairo rename to kakarot0/src/kakarot/precompiles/blake2f.cairo diff --git a/src/kakarot/precompiles/ec_recover.cairo b/kakarot0/src/kakarot/precompiles/ec_recover.cairo similarity index 100% rename from src/kakarot/precompiles/ec_recover.cairo rename to kakarot0/src/kakarot/precompiles/ec_recover.cairo diff --git a/src/kakarot/precompiles/identity.cairo b/kakarot0/src/kakarot/precompiles/identity.cairo similarity index 100% rename from src/kakarot/precompiles/identity.cairo rename to kakarot0/src/kakarot/precompiles/identity.cairo diff --git a/src/kakarot/precompiles/kakarot_precompiles.cairo b/kakarot0/src/kakarot/precompiles/kakarot_precompiles.cairo similarity index 100% rename from src/kakarot/precompiles/kakarot_precompiles.cairo rename to kakarot0/src/kakarot/precompiles/kakarot_precompiles.cairo diff --git a/src/kakarot/precompiles/p256verify.cairo b/kakarot0/src/kakarot/precompiles/p256verify.cairo similarity index 100% rename from src/kakarot/precompiles/p256verify.cairo rename to kakarot0/src/kakarot/precompiles/p256verify.cairo diff --git a/src/kakarot/precompiles/precompiles.cairo b/kakarot0/src/kakarot/precompiles/precompiles.cairo similarity index 100% rename from src/kakarot/precompiles/precompiles.cairo rename to kakarot0/src/kakarot/precompiles/precompiles.cairo diff --git a/src/kakarot/precompiles/precompiles_helpers.cairo b/kakarot0/src/kakarot/precompiles/precompiles_helpers.cairo similarity index 100% rename from src/kakarot/precompiles/precompiles_helpers.cairo rename to kakarot0/src/kakarot/precompiles/precompiles_helpers.cairo diff --git a/src/kakarot/precompiles/ripemd160.cairo b/kakarot0/src/kakarot/precompiles/ripemd160.cairo similarity index 100% rename from src/kakarot/precompiles/ripemd160.cairo rename to kakarot0/src/kakarot/precompiles/ripemd160.cairo diff --git a/src/kakarot/precompiles/sha256.cairo b/kakarot0/src/kakarot/precompiles/sha256.cairo similarity index 100% rename from src/kakarot/precompiles/sha256.cairo rename to kakarot0/src/kakarot/precompiles/sha256.cairo diff --git a/src/kakarot/stack.cairo b/kakarot0/src/kakarot/stack.cairo similarity index 100% rename from src/kakarot/stack.cairo rename to kakarot0/src/kakarot/stack.cairo diff --git a/src/kakarot/state.cairo b/kakarot0/src/kakarot/state.cairo similarity index 100% rename from src/kakarot/state.cairo rename to kakarot0/src/kakarot/state.cairo diff --git a/src/kakarot/storages.cairo b/kakarot0/src/kakarot/storages.cairo similarity index 100% rename from src/kakarot/storages.cairo rename to kakarot0/src/kakarot/storages.cairo diff --git a/src/openzeppelin/ERC20.cairo b/kakarot0/src/openzeppelin/ERC20.cairo similarity index 100% rename from src/openzeppelin/ERC20.cairo rename to kakarot0/src/openzeppelin/ERC20.cairo diff --git a/src/utils/OpenzeppelinAccount.cairo b/kakarot0/src/utils/OpenzeppelinAccount.cairo similarity index 100% rename from src/utils/OpenzeppelinAccount.cairo rename to kakarot0/src/utils/OpenzeppelinAccount.cairo diff --git a/src/utils/array.cairo b/kakarot0/src/utils/array.cairo similarity index 100% rename from src/utils/array.cairo rename to kakarot0/src/utils/array.cairo diff --git a/src/utils/bytes.cairo b/kakarot0/src/utils/bytes.cairo similarity index 100% rename from src/utils/bytes.cairo rename to kakarot0/src/utils/bytes.cairo diff --git a/src/utils/dict.cairo b/kakarot0/src/utils/dict.cairo similarity index 100% rename from src/utils/dict.cairo rename to kakarot0/src/utils/dict.cairo diff --git a/src/utils/eth_transaction.cairo b/kakarot0/src/utils/eth_transaction.cairo similarity index 100% rename from src/utils/eth_transaction.cairo rename to kakarot0/src/utils/eth_transaction.cairo diff --git a/src/utils/maths.cairo b/kakarot0/src/utils/maths.cairo similarity index 100% rename from src/utils/maths.cairo rename to kakarot0/src/utils/maths.cairo diff --git a/src/utils/rlp.cairo b/kakarot0/src/utils/rlp.cairo similarity index 100% rename from src/utils/rlp.cairo rename to kakarot0/src/utils/rlp.cairo diff --git a/src/utils/signature.cairo b/kakarot0/src/utils/signature.cairo similarity index 100% rename from src/utils/signature.cairo rename to kakarot0/src/utils/signature.cairo diff --git a/src/utils/uint256.cairo b/kakarot0/src/utils/uint256.cairo similarity index 100% rename from src/utils/uint256.cairo rename to kakarot0/src/utils/uint256.cairo diff --git a/src/utils/utils.cairo b/kakarot0/src/utils/utils.cairo similarity index 100% rename from src/utils/utils.cairo rename to kakarot0/src/utils/utils.cairo diff --git a/kakarot_scripts/constants.py b/kakarot_scripts/constants.py index 61dfa7029..a92df0a55 100644 --- a/kakarot_scripts/constants.py +++ b/kakarot_scripts/constants.py @@ -218,8 +218,8 @@ class ChainId(IntEnum): or "0x20eB005C0b9c906691F885eca5895338E15c36De", # Defaults to faucet on appchain sepolia 16, ) -CAIRO_ZERO_DIR = Path("src") -CAIRO_DIR = Path("cairo1_contracts") +CAIRO_ZERO_DIR = Path("kakarot0/src") +CAIRO_DIR = Path("kakarot0/cairo1_contracts") TESTS_DIR = Path("tests") CONTRACTS = { diff --git a/pyproject.toml b/pyproject.toml index f5adb40b8..5030e833e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -191,7 +191,7 @@ check-filenames = '' check-hidden = '' [tool.bandit] -exclude_dirs = ["tests"] +exclude_dirs = ["tests", "kakarot0/tests"] [build-system] requires = ["hatchling"] diff --git a/tests/fixtures/starknet.py b/tests/fixtures/starknet.py index a899fb347..13ec06542 100644 --- a/tests/fixtures/starknet.py +++ b/tests/fixtures/starknet.py @@ -38,7 +38,7 @@ def cairo_compile(path): - module_reader = get_module_reader(cairo_path=["src"]) + module_reader = get_module_reader(cairo_path=["kakarot0/src"]) pass_manager = starknet_pass_manager( prime=DEFAULT_PRIME, From f6d8bfa8f5f4d0af71563030017b348c7d6f21ed Mon Sep 17 00:00:00 2001 From: Oba Date: Tue, 1 Oct 2024 11:16:00 +0200 Subject: [PATCH 03/56] chore: add scarb and snforge tool-versions root --- .tool-versions | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.tool-versions b/.tool-versions index 250522192..70e7b8d55 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,4 @@ scarb 0.7.0 scarb 2.6.5 +scarb 2.8.3 +starknet-foundry 0.31.0 From 99901f5bd67dd96d572d828ad57b2bec255bd305 Mon Sep 17 00:00:00 2001 From: Oba Date: Tue, 1 Oct 2024 11:17:17 +0200 Subject: [PATCH 04/56] chore: ssj compiled contracts --- Makefile | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/Makefile b/Makefile index 5e21574ab..9f91533b6 100644 --- a/Makefile +++ b/Makefile @@ -6,34 +6,25 @@ endif .PHONY: build test coverage clean -# 176384150 corresponds to release v0.1.13 of Kakarot SSJ. -KKRT_SSJ_RELEASE_ID = 176384150 -# Kakarot SSJ artifacts for precompiles. -KKRT_SSJ_BUILD_ARTIFACT_URL = $(shell curl -L https://api.github.com/repos/kkrt-labs/kakarot-ssj/releases/${KKRT_SSJ_RELEASE_ID} | jq -r '.assets[0].browser_download_url') KATANA_VERSION = v1.0.0-alpha.14 -ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) BUILD_DIR = build SSJ_DIR = $(BUILD_DIR)/ssj -SSJ_ZIP = dev-artifacts.zip -build: $(SSJ_DIR) + +build-ssj: + @echo "Building Kakarot SSJ" + @mkdir -p $(SSJ_DIR) + @cd kakarot-ssj && scarb build && cp -r target/dev/contracts* ../$(SSJ_DIR) + +build: build-ssj uv run compile deploy: build build-sol uv run deploy -$(SSJ_DIR): $(SSJ_ZIP) - rm -rf $(SSJ_DIR) - mkdir -p $(SSJ_DIR) - unzip -o $(SSJ_ZIP) -d $(SSJ_DIR) - rm -f $(SSJ_ZIP) - -$(SSJ_ZIP): - curl -sL -o $(SSJ_ZIP) "$(KKRT_SSJ_BUILD_ARTIFACT_URL)" - fetch-ef-tests: - poetry run python ./kakarot_scripts/ef_tests/fetch.py + uv run python ./kakarot_scripts/ef_tests/fetch.py setup: uv sync --all-extras --dev From 0968c3fc813260e0185ad23307add838817edd40 Mon Sep 17 00:00:00 2001 From: Oba Date: Tue, 1 Oct 2024 11:54:49 +0200 Subject: [PATCH 05/56] fix trunk issues --- .../{workflows/kakarot0 => }/actionlint.yaml | 0 .github/workflows/kakarot-ssj/ci.yml | 6 +++--- .github/workflows/kakarot-ssj/test.yml | 6 +++--- .trunk/trunk.yaml | 3 ++- kakarot-ssj/README.md | 4 ++-- kakarot-ssj/docs/general/account_state.png | Bin 132360 -> 131560 bytes kakarot-ssj/docs/general/volition.png | Bin 192376 -> 192120 bytes kakarot-ssj/tsconfig.json | 6 +++--- kakarot0/docs/CODE_OF_CONDUCT.md | 2 +- kakarot0/docs/img/codespaces.png | Bin 21914 -> 21887 bytes 10 files changed, 14 insertions(+), 13 deletions(-) rename .github/{workflows/kakarot0 => }/actionlint.yaml (100%) diff --git a/.github/workflows/kakarot0/actionlint.yaml b/.github/actionlint.yaml similarity index 100% rename from .github/workflows/kakarot0/actionlint.yaml rename to .github/actionlint.yaml diff --git a/.github/workflows/kakarot-ssj/ci.yml b/.github/workflows/kakarot-ssj/ci.yml index b99ecd358..9dc03d85a 100644 --- a/.github/workflows/kakarot-ssj/ci.yml +++ b/.github/workflows/kakarot-ssj/ci.yml @@ -16,17 +16,17 @@ permissions: read-all jobs: build: - uses: ./.github/workflows/build.yml + uses: ./.github/workflows/kakarot-ssj/build.yml with: artifact-name: kakarot-ssj-build tests-unit: - uses: ./.github/workflows/tests-unit.yml + uses: ./.github/workflows/kakarot-ssj/tests-unit.yml with: run-fmt-check: false ef-tests: - uses: ./.github/workflows/ef-tests.yml + uses: ./.github/workflows/kakarot-ssj/ef-tests.yml needs: [build] with: artifact-name: kakarot-ssj-build diff --git a/.github/workflows/kakarot-ssj/test.yml b/.github/workflows/kakarot-ssj/test.yml index cc095668a..4fc91e845 100644 --- a/.github/workflows/kakarot-ssj/test.yml +++ b/.github/workflows/kakarot-ssj/test.yml @@ -10,17 +10,17 @@ concurrency: jobs: build: - uses: ./.github/workflows/build.yml + uses: ./.github/workflows/kakarot-ssj/build.yml with: artifact-name: kakarot-ssj-build tests-unit: - uses: ./.github/workflows/tests-unit.yml + uses: ./.github/workflows/kakarot-ssj/tests-unit.yml with: run-fmt-check: true ef-tests: - uses: ./.github/workflows/ef-tests.yml + uses: ./.github/workflows/kakarot-ssj/ef-tests.yml needs: [build] with: artifact-name: kakarot-ssj-build diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index 14f8bc7c8..dc05dbbd1 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -69,13 +69,14 @@ lint: paths: [uv.lock] - linters: [ALL] paths: - - cairo1_contracts - logs* - lib* - resources* + - kakarot0/cairo1_contracts - tests/ef_tests/test_data - .katana/messaging_config.json - deployments + - kakarot-ssj - linters: [solidity] paths: - solidity_contracts/src/UniswapV2/**/*.sol diff --git a/kakarot-ssj/README.md b/kakarot-ssj/README.md index 28016b6ce..196587351 100644 --- a/kakarot-ssj/README.md +++ b/kakarot-ssj/README.md @@ -100,8 +100,8 @@ scarb test ### Format -The project uses [trunk](https://trunk.io/) for everything except cairo files. If you -don't have it installed already, you can do: +The project uses [trunk](https://trunk.io/) for everything except cairo files. +If you don't have it installed already, you can do: ```bash curl https://get.trunk.io -fsSL | bash diff --git a/kakarot-ssj/docs/general/account_state.png b/kakarot-ssj/docs/general/account_state.png index 4386b900a41a4e3db705041d68ab14e5130ad653..0df32c4762faaed95ebb6839ade3c836f8924928 100644 GIT binary patch literal 131560 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 VbiXW zmUz8uQ+WFDBMwvpJELX7{Zy>`4gpUWVsi03=HQWQ%If9C{ywmcs2*b=x5p`breqNu zGdfyZle}cHG%9X3P7(|PdwXNx9r*bn6cyJS{kEbd=56uB^wbo#4j*w?+a)0h$vwTr zQBC&={A6+9)>(t3Ydd+Piy);V!r8}z3PiixDUFSdK{l#3b}}v^oSfe1vlK8a@Ricu zaB7!WY}wVzefwE5WPtOM9xpOZ?1K+HSEpr0v^`{beVh7&Vj-{W;EuqB#ZA`n`BHVN zs+Omma2_e_HlwG+KcPS8>pQHM*$S4m>LM)huUdb~X(u(IBLG(MsPzlHQC|`Ixsth2 z&ooa3--Za%?V$%zVF#dsWCgXC@!h&@+&&`0*L1H(V5@P150Yh8^L=8zzWcsyx5`_& zdvejJX^y=2jv2pVdVA74@TY|&><;8IyWk0wxas_I@o=+Z^DJ?tF*dbG(7}0oygTpB zU6SUTuk*K)rE7QJ<`dxsb?agWPHYl27J^VXEl%zTZLT~t+C?CB(q!((4=j-{#l<9q zgj|H74tzz1Qy6w#zpOqAwHQ_IY;OZF!Vl?aZ53^vPnD$HII3$<=SaLy+pVjhS)|VB z7iGW>WrE@bk!24V1UpGVqst~uczJn|z24i}+Pb^XZ`*Zhm#P*%W9nHw$TSBx0w3+t zHzLhf+PgbmHeV*VJhXB-%CL!ywV&!)j!G`m(BiPD>Qqw}tG$oY+)4|ME$Qy%8cWb* zCNuV)B%}?EH4M~Cj(Q&dUSuv5znJWOp}6KE&pgXPVo_)LiPMg2%Iu`AyP&%*;o$Ds z?1}Y_eDkiW#zYB=PDf4R!XOBY?Cm`u;u$Se<78xfFm3QXO&G*>;QseUTpXM>T>|jW z{+^zfva+2zURs6P?SbT;n~lIb5E&UsEt6DZzpLqkuVH0o#<=4SZt<3ady~MO-%0F@ z(R_5cJ`zUAogpSBCSJ3y4_i*I_a~NPkSO}9ARD4lf3fzK3KvAPM%?P z_r-=bJ#bkSOG!&VLh+k2z|4O5qruTS^4aS)g3xs~Ha2N9AK;7uA*+CD5a1YyXM4dP z{Pg)tLT~hq`$0c;-aOp^_f>3^byP<57srbTFV5obWguVY;;e(X3`|gN#6w6VFe*IU zqxH(5>LY7JaBwhGDPJ-ID|}&H1Rw7gRVu$T-bZf-(H@`Gw*mhC=+=tJxR6enn~xjl zU&dLln)|?Vne*PsJygel`h!Lig+b|`_C%Tv*62l>hSQKa50wTP z7m!-)7t#ZZ?I$3d(Oe_}oObQPibNO$a^|P@4(xBS@65UpJ1ig^F0YRl5(qFNU#~2- z2kF#*o2oS4mb7S@7dFl;(x|U89C>#6{05If^<9cE8Zs`i(L~W~jinCGXGxmF+@8U~ z3F91@Wl5xCQGEx9n>J53zVdg@EBOB})wbTZOg;V=+W+cJn#H+-|#!=f00f zxl0u5_j267D1&&4_iNTP5Ph^GM7n-<{xrS&6TShNl94cyUFaDJ&63>Xhhzq|2LrtA zE$>~WFh*ovy~07cw*vx&Aq@?D(?V$HN1Lnm1P&Z+EwZ(4S5EhR1ixlsu^``n3Tt>j z)g{>0B8MJ4Ut>0odM*%9YBtM5MNZCYcAkb9x_q_w!=I48{>q{W+Y24e@SeWHNDm)A zly`iO87g0oC4f6QPV1Kkni7Gc4~GNnI8YF4C?PDb{Q(;zeMpxYk+f2zhQa zTEd3mc5`(yj0Rm9NG^D<{N>GiX}aImZG3rL4!_g5)`Eb;hW5T!5B6ov;yc9Jc~d}w z`)we6lIg<@O!oeS=k11oYAl}UmuuR<8{2w4UbTVf7;wett@Kh%>@YS_Fwdi#?&RI% z&zrfNwlq&+B(K1<_j1DEIADw*a3dOgGUqJY3Zin|<98j1gsP3kda9Vqa&Pb+M9Cw+ zpPvcqMn4sG5d*gA#=HD-Cm{_Vd=MF>^+`kY+l}Z${hHm*m-nX0rS?7)9UZ-bxi^O4 zQ3N_J^xc41XDE?;GxiyWMYZXjQqFl7#m4(YJg_7HHO2VCNUD4RiUrCH1dSfi$;k{I zz}Xt@@4v?M5fv(fqkg&?t`vr$;rbK%j`Lqg!T1X)??E6IWU%~f^?Tl@qUA~jkEuP! z5J7TLPl}*;kzZXs=XB2&gNCRDfq&p!rwnm}GO$RaL@rOh+0E4wD?Ca>ZVyBPKl=gc z3-pqaW5I-ew~z`3zS+!)NZ(qQGgcnG_=Gzo(=8u{&ey##1wg16BJyCur<;wYjKyny zm&fh027e^y^$0ot`C4YxfCNC5B#*ne-(As_2j(i6WCH++0b6|hmgWiYByX$LkzfCT zbERz=Q!nruY9x7k-@Pc}ZvoE!_8+y@x#thB&`I1cOS$mxyS6?Mka(4BJG8ODKYW+V0Ey-FV6hV?|M>&Z)p#l53bx)%*=}L&33AD zfyE=5l$AvZ_*H?LS-9Pss=j1@s}d#ZFV4~Y#W{h*`z@YG_eNV=KHh2X>ggGlOLaT{ zj2}Vh-f4%#OZpS!0vtPUQ_H5%52a-&WWU@nJ=z$ndafu%d6&ipt96AOxI9~wBQU`6 z3&kTn^>GD}A;p|m0O*b9oA~ur{1vy-5Pz|1XXWHH!Lm9+2!a%gHTnOpN?dt|?8{}b z-i@NR+*iPq;%Urzq(EapFBB9MC`ae{B=e|K97IH4$1#76QO}bdD*oL?5#~QqYyF`y z0{D^rKdwkpJ%zp7@Nxn^$k$RRxOpicN)zT_nfMAQHpm8z7y1{EQj$1z(;lwiJg-0y z*_XC_&&p@!gZ=O!Hv$?I&x|WLy7T5k>|Ys1^!X#hPv9}Dni?)zM#95_kK;Fs@4lCw z<6NPGNpVn^h6+%4VWPq9L62h%X0kFRW@l`^ZjrJhAYl}y@uI5W?poN{s`{oQv z&p={+CrKQjk#m8xp<{hX)1J}(!_5HP@&ACkp1OpDuNXq1cY~%?v08Nze6B*ZYP?+g z-8m4zw+C`5g7)lFk9X&b!2%}0q|g2e6Y3vfVtwH1*7g}3ZV>7M#;jXb zTAEPupuokeBp|>wY-S`G>gm7-zqk;mW=_e=s}`KWDiy@wtN;ylTp41wJtdXb)+W~1-;s0x+{RZxb8Ym+v9#tqcJo4?rurh2%mbha z=F5`zJM53F09*p1LW4hEs7BpU^1hWFk*VRgCq9>%^6JHI^W!^y3meDi+IlUM8ooTwwqTVQ`4yk1|J4|S;}BpA^&4pq$XDg3rVUJ zzxz4o{fDxo9`WvxZ|S+n-h0egu~aXc!uR9~9iNqK07NA`2V_(!gB7r-1q6uY{dlTa zy_)4AXl0p2P0dnj62qW2#VF;6Npd_U)-_H}$_%$L zG`+5+9W-W}>WJqeSHGu=VhWt5UD?s+VFlrWbctLw^G4ttrq`&0iGt81|HW20qJCO? zt@Y~Yk9vEiq9K{%Igsr1G?q!L1BUrg0S#Jbv#t&N`GW46SE#8sA5lmJ1+`lHlDHLv z?dKe+hfROfF3v@hm*I*n}~k4WlP6~U%7z4-G9m+{tcMOY51|hx*{U!S;*PAwY9Zz z#i3d~F?x_RRJei_0oXXl>`Wq551Do_$&-kj;L6>ySsP1 zWJc-Io@L5sN?_<0?Xu z0>mjWB01SqYi_WsONfq`Rsm$4fsCUf2C5f1P#pC7CtIEE7DuP=C?UTi?%t&(9sR+P5ygGY;)x)lj0bbVp%HhEocPa{od>_0RqIfsdHHqj z$N~>BsGl(3+3E}xEk#pUX-rH^jGHg1-ye-Z8nC)$utEYIT0n=Z)-+kW<-c38L&T1{h;2N z73sh-sJU;!6@0okc0hh|a8QeW49{9(B zmX#!D2?g#dEa;!MCqj8Oe;jJJXY>F01vpjo z3*Lblf1PP?A0;F`qv!T5su=KCfg)V4^bDH+vGzRH+qZ~+>cCKC@@QUyoq41G@rYtU z^IyT=1`7Ro|NlCD%+QwKV@O`$B$FnBccA1y^Lk`66JSUjoiAJqXx;4WSWj+mSM$%$ z#Kp%mObE!7`uV*tXL%AveQ$(m<-TYUpf}gQLlqKbMn)oa-E)=HUK`N?v+Lpbl)7wa z*sx;-{(~2pLk>d>`^rCUkw{^8;Vw=Qak$qrO8I7=d@?`!0KL1fZ>yLy?6AMpt73Mb z%;Yy?7@lM4cPOCC{=bu0^$ZMt3aPZ3BLv~RtLdlCytDe{6PwwF33_i+=vE59amsnf z$vfV1$z9+S6+$~IE{36l#66d=`f1rh<=l~VyZT1X#2>+8H?Yd^oD z_H-Ibq~=E@zKiLJa)bC)PzcLLW3tZn(^bhA0tNzOw&}{v;hYjG>4Xa7PmHF+9ERHa zZSUUou7z(Yd^>2+bh-9JY1&=AI8!cYR39?oa869)fryAp-uh!7l7Y=)B$LuK9Vp)* zyk2jtF36-P+#ivtHw|X#@OJRjKX}J2fBo}fk)Zg<9i6TDvZ1t8{**}t28{-eYcH=m zylIeh@|jyo_`^BKw|}lp>*@uYnwIONVI>a)i|WY7xm~AN@Z#x8Xmd0uRG2j3REc_- zy}iAySzy4Cs0t|W9ewNZeF!MiQbOyxw|*dJxfu5nL5O|(ntM)b=aKtmQ(awxOzy#% zOS;@zWuQ}IkrLR%oB!HGEGf+)Lw(-mu`voHgBCTgbKd3nwfgnSW_x?PE^GYDY^z%J z(l;}clk2kuzpFUFq@VtsRPO9U{mjjYfwgJj9f zqop-JH3iCTDpd=I3>@ANU_rmVxaDkA!1?d;*vAj9(leAM*C9f%X!r9y$Gp?!!_m=E zkd0KWL>bxr>RCCc>0yjb)yM}@pH8m(Uo?Axbru+QDW%EScJq=D$t959i9&un&EwpQKD*tkHo5dD8GRFoXm z)2?1)un>ebEVy8Ot`_?LPu;rcKAv(2sJQ8rw^Hm4pq81^DLtbq z1{Vrhu*f^T7!3gCs%DMF&yBHySucNZ83Pprg5dstl44h=e2@a?iQs>E;vFE9LqH}b zE^r0bIv(WQemV7jeYq#8L8a=&WH6v4(|uf!-lC(U15Cpv%OwduVp&S;b(?dL+zu)P z!3l`Kx%_{Bd4wE-x4+!pAAA+cgLwP~oV0Kw+76F>rwY#B!v(d4n8bXN*$T6A@{F;d zsf;(eP#)@&Tfij;fb8)VZ1XpHIwI=B^u_3ZLM%Vwgd$BRzdf9RzCL;e27af*HLc^V zIMjEfz`$_NXdmLX7o;p;82WzVnt_Og8zJVChlMLHh6LFH?bqVOkg&vHNdf5cWKhs{ zEgW<$^T>nDiHTEzKZuDx1WnC&L07hC@(6by;(o{wf%&6@k;|Z&87b6*Q(j&Q{6St` z46Gs)EK&*v5f*EY2j8E82u3=BNBz+kUc+G6xL_y_7*#?6LL%~(39iTRB4)CMZjM;WHW-?C zf~u<~oU1z3MwSXWob&sLuT+{x%{RghJ$l1TD$Wm;ou)Z1EUI-zH_#uPecKVD#0r(j z*t-kR1VU;p1j_=m%YV#+0N{WK9fN<=FfNtWd|)5meNcsoAx(f&#f$kIWBYT3Io;01 zTHM>t(_iydjU@$VOpdSJXU2aY#yH_VAfA>x_yX*aLsm-dFy<^!YmsfpP<|=%Ln$a7i%~#7?ilA}vFOJKz-j18O z$%d^>>w**82Ky{$YvJ7@tLdhxuaSk1d+KKtNEK+Upr7c_Ab^w*4?0q4FzW3Fn6Utf zAs&>%Fi0OxYr16++Z*$}&xALom9EmlyLDd4bj`-G=HVs|+KSuebH#NZOwYE9aSOf| zCn_;&l+h0}G&>c%LR{Gkc|K@T=_=l#}c$s#i|V_N4a2G@%YZA6H~O+`%b1#;RFk^7fo_5^^?QyLN)2GGh;+*1J#X8|M`)2nca?Jd|J8sw`7~Zy1MF@ufPz(ud z@;&J-zes_NW07;=DH4mucQ;n+FGNQ2CwPCy_tqz6heV_(U33>a_R7p3zx-+1dvA49 zRlee#_|Ug#@%;Up%dwz|?c#N4t=^?o*+ebLl2*G*{3fE_SMQyuPxt2wY2M(gpw#|DOFSPfbXhh%y zblmxw$BSio+IqE^E;RWt>3>G2-zu?|nTJzE zFeKkAr_Sk~wDb1gUJS zNoIx0V-V!-zN@L^K1kShAs^^!}ytqb5&A6q53CMCQ<-T`t zPQScGcmfVeS}-a>eRZqVtI2}WNN$h$-by!-zYRCyn0}Z(={}uF!t{v~=6+stNP?XJMlEMOkTv@CAv1@#L}Yk;hDW z%a-4SZYTeAR~}*g6)9n1xx<*iO~(mQf{t8FYcPgH-V05?? z94=qo&-mv52eR(~*#OPGvBi+GFqcXlI$QiJz5)T7TF7ENO-d{vVp4y52>M3^zIMCm zG^3JF-QJsOB;%R?sXFtqi~FJ^=A{(dm(!~4?!gVWqj8MOQ^Pn>x^H$V>%|<-m+1hj zfr2PPkbf_9OJ1LkLNJfGkYP0!@~4UZVoP;6zE1+%JatNkq+_pNGy^G#y@6qlcyVh$ zJP?FoEtD939lfv23a?|O<$fIX)33_U?Jp4+j}A8dtZ{VTekYnb$o5nUGIO`Cev=SA z$)vHQutv6^C1p;bIPNep;Hc@Ke^|WsC=gxnjbPRtX+#XTzAEzkZ;HRe&cZ@=eLu3$ z&McA4ccfk0SfNGr2{SByUSKpE7t1J9?bCdn!;A7`MZv~wnL-Pr4%pFhlkG1aO{4WT zfKs`x5@Q6=b@^Q}Y3d52g|A1^H`nhg1=@BwCqCQS?1es4dK2S5orCn4rwy8+I9*!l ztM)pLT6I9h&Up&OcY6-&VJIYAm=wA|&GxAO>RRJhm7Z3r;_}fU&-mjnG)^u{ZyWty z=Q4KOStEKdQt&{#%FWlAF&M9cJ36!IqC>p)enMj$sLVK9s`3q??rSGv)WRy(rw0gU zfh6YhP#9=zEL>y&z(V9hr@yw^boxUt(Gxq4=lN%{-#Sy#Kn)cIF-{5#z8n6wD$vJM z$0jZ#QXu+7Q${-s-KWE5U}e;bp2i_{tm-tjMQV+Bg9v%2fQ4&OF!c4!)sp!(C#{Ra z)AtakZMU_?{Kw5kXInPApRHvQ{l;#>?Ifeu$E8o+6bjb4v?Sv) zSfU`TCh7|cTuBJS@Ui|;5^tp}==Cj;3;KzVWQ@9m9{Niks6F>8ev1;lHKItJ)mr&Z zFG5wh(&%kKM8fb7+TV1O$1$=^{fYvHj6&aK)!TJ(%dEb{b_UV*Ci}t(+># zOz$`ewUIWDL%y@b0<8*n#5nsVzFh)!*OHG)c}hCMw4FZu#&<`&LP#_b<#_DD z_}hkoh*HpdAp=o?3@1QJ#-K_z(~Xuv5{94>iKm)=V4K}Ix2V%drb|_N>g^=Pevq$` zIp{WY8pNsa$YF|+>St-S{=4swWrURB7*PPsu76C0z+hlntyv=}jed`7;JHejpUbji ztGpT9-=Gv1Gq4>_Z8m`g=LQ~4;bqU_Y+~AfHY&c7cg!9K$F3=d$;pFbAa7))l*qqN zLv)8iRo283`G{(5wSNU|z06sZhyQ^_-J#%}x$nQ`C+-|F^S?3Ieu}~V_UbvmrkOP>3~@$jT$NhAgenIrV%pxfP6aD>M&mwfJW|~+2+QW%Fl~38SHdJT=hhn9HY~^NB@Fh?jCaly18c%q3jF9!dGQjY$CK&@iZZ;bF@KZV0KaGCz~amTAY zhK&;W-FummPk`<5zi?>&Be6C*2 zHzwNKiR+ObO~j)yaqM))2sn(KuGCrdX^Hc3uS6pj^&}6eWz){PT&Iq0&BbB_1)=fu zhTg{7G?mE8W_67O^_5FQJyiqd>YPr3FvWoZ$p4L!EWK-7que;*%-`1~uRbLh)^r;N zIQF8mk1@8U-tE?iA#(KFn`hTpX!g(y)0h#_Pu03=&Ta*h|ied&QD)%=S_$V z&S_pc!ftO!7Fb?h+v?dY_loM%twLXG|){UojNuEJYo6=nno@*VjI z%eJLQz-9=I*x-|Vb|AGr+4G%o$HHfg8dB3Pn``B#74_z(qL3_}Dz#2rt08mUuTJ>5 zF#7@g-h(10zVQbhz+HqhQ>RqQ_j{yC#VGkK90?C?cEesjIGVCH>LC@0h%;nPg9Q%; zokw}(mqm>`y)ssU?U4wW%ekA$*Z1#)h^c=&TQ8ZMU*b0E`1(tYw7M=wIT{Cv_{C2 zkNuAnj^mWeSLl;7G9}sY_Cse%=i!!(F6MtxA&!?3Bh1jXu!>)jBMXPAl%`tq&LbpK z8G8>R0Sh9DZ$oU!X4_QZA0-WSelX3^48<_F$Nb>4xkS+A@DH?UCGt1uZ0uNg=1#0^ zd<^sn53&T<_eTc_iXMWI`#+Y0((#I*ZdVtfF>Wc5?udU_qTL35OUArNT@9eukDGo+VGPtqZN(o?RGs1#+VR@ zE~$SYI~iW8oX$sOR++LK+1KN;ZpyJLMtTewLgQG0ZK2P3V^*s3I}KPl&)k$WKSy7d zfa@fL)L97j>ds%AI&d;=o@hpS=44uS;8{GkCAi&EofU#>9YLXhe(QUEY5naxty65z z(DpWuqPyt>hINR~erx*`8-~xyL7v>n&>kq|@&fu}_Dp}B(oI|5%qyXof0PEHEY`pz zqoKF(EI=yQM{H%0s9$`WQMr)}OmF;Ock*_I?0$hSM6Y8{_+B|0iVx1)RlBJ03yD(o zJxz%D-shd=vqJsp)z5KV3De?OHUgmpue>Adpt9fDUkp z=P$1m_^_@k```?hqb>@7RyeTK6_CO0A6z9ev^xSisq_0&o(sn9oL$6!whmUo6^xz8 z>JDH;Y20A${J}?-tw@t8B8A(X_4dnUkw&3=QZ~ZyBeC`*x#6D*2|FPv+?C~;&hMc0 z{85dN;64w|EMcW1|5w9}hmP`E7W6T^s5RoBiBx^QMu=X`BB9(EHKW_mDZ3@3-2X%p?y+lSztgw0Jy5X z5X^5HQv3xh+NPokly5_KAuZ9XAwa=&d^X3aFI18z2u*YqR&IsUmO}Vne@A=&2sh66 z$ZMkF*jKfahGTQbpC0ghCyVrNr#5nGFvhfzsUJSO_B>-VC`yCY`34gJEo^d3|vg&_yG~d0MN+upW8C0ecty8 z-Z7b*z-mm}v9~|gF`vj@w3P5%xE);M#M1%aNxYhY{JA(H#0(>Yd?X^{hmu*n@#{(3 zRJ2{-ny@wuPCyXahuJs-!`wZy!nD#0%LESY7~o3&&m?R-Ij%=e%dH!-GRJYqh8f=U zS#bU}aRpuvO2hDj7+eEukiK|t2tSwCW78wA%fQIF5wp?W)!6xF8aJU7Ka7PR4KkA6 zy`kc%F>pVJE=uETGH@+JSP}mVrz!i>m>TxH9Y6V-B-6m^`spgC8q@E3AbkJPmh$o< zW5zcrJF?x(SnuQ6CAb@2KNJ(!Uwi_RNpl%ik@?YIJSEDKMQG_C`Grc~ZJu1c#UuN? zEbD`F1DX)*lEm5mWE%Da#o|&HTbw1&zwLzPvA>E$ro$4Fgl3dD7QSU!Wc`!EzL=GixQIj?=D)i%fO9jW2!Wtc7wX)L~w~T%;Q84^^ur9|j2SoBpo{6+mklvOqkixPw z=OfCG^u(XfY8Ui9ilInZA>YzLRPgV>emtemsxE9!WUFCy!KM3z6!u2T#8OIgyHDDi zAdoOODRK)22`2%+{9E|Tbmc?7Y3CG*IU6o$GD@oEjZXBZ)*^%tghZ5OehFN!$WJI5 zO8g+I8J*|v7QrlmW?pyMyJMKn%!luLPN{E2EpU>^(m=e?rT2aCuARHtFYQuxV)zHp zA^Va&d57|!vsO5xriyss(d$W4n1TOo>4ZVsPP#~nFq5-OA||h5QJ&e%{2R+Lg1~(= zr10lb5BD{%URu@#75rT7Kx--jKYpUTbd0RU_1&OGubVk#<*Nsx2V%raXyGVdWk!RY zH4 zF-W88A@?5lgKAF7WVyD-cDdGgYRyWB;2Q;qoPolt?8K)jIRb?n7)*R}q%epBjfhXo zZ3TyqgvnE=uHx`cIsfJ`M#kyY%J$t(**nJhMV&X-XtF)(rJ4EGeI!a?;XV|81zj_$ zt+VS#!!Z%f6zC9o(Yp1fgT|F)l1K#NY!GcC4wOr$03|D)a_JAJeb60i1m6lC&j|QA zR>H0+H!d#Gg$5iXyvlY5XHfO-SxX&ZT_7Nchzm<*pI&k<#Y0nJb~CFvcUwNWT^Vnz z&(aCpIGvSPYsV-9CJcX=E+Tzf4u`RRED*3Ck%&*|f9U%VitO^9yLPMuzs^i$R%O-sgJTp5`ilW4 zXd&?@>(stfjvft#kdz6DP@bT_D zwseEb+33Q>gGW<(jAz7Y3`KvptelGZtP-FmGdXPSKQd94o?(AJ zXH3;mJGr0w)t|ei4Dsjb3qf0aMzwgIA-*mtdQjgK5)H$AlJlX!eX{=GG+}`K!NM+0 zMwD^^!*e3j$`L#Lym8eEqbD|{blFjFR12pbsf}uu;#Mj@KOSO0^-?BB4WJVH)I%=r zO?m&JXSn3zaq?q?^X}?pde3G}>LCBz!S&pUBLrd-H0OFsX4S)B zwvrCP0WE<_ywkpgW5G!Cgyi0nQnBT6S?nwDGi_SQMsjpyzM~UDdr|BY!AQ{AA~uF~_n`l~ zngXa&&~!Wdwg0Pk1QnC-cMIr9cd_e!;|yAS@SRy$s6YL7{OZW;QLJs;1KLR&e0g3NX;%n*-Za81_Ur3Vu7!8&_;@cfKLF z|H}joQYSJN!yijh-UF>l_v8buyczQQ|L%kPoDk+y?L;Yl|C!@>?1pS$psHpn`^z-Y7fL!DO9EU zy4{wmzo+xrjqC#zDe!87-(v9nhvM?W;%)JL$T76-)Nb-LCwJ4d*elEWpq_340!#=H z;dcI0{gWq6OQ%pf!p%p6$ZJt8pe%p}ofY(;G3?x$ET!X^BEfL{xMg)yF~vNftKs&1xqucD=&I}+jdf|ftA#N%x(Ug z%L9-?`TO^8teCYAjG7Gw}ZpWeMQh)Egdxr@WQv@gy+VTqML=v?s!VY`6|W4SI3}gNC5Ou`lbN-d{EWIx>B>A zwyiIpZ4Up2vn-;p&qFdGA0N}c3B8n*6TZQaqd*s+-M!gnNy;t}afXn*Z@Spw{agvM zOW<`9>|BPUc@g?c9;IiOI3J>w2w(R_K|IpF*|Kvk*rtjsvQe%*(z~+(TL6j5Ib-hD z_cpcM&U|tndF~w@MaO_-;R2-seOrCc7L*iAI5GySA;3h z`|$qkab&>p3qJ{PCXy`3xGp?%+nW|mq3gATv_6$_aro~)gRFH0W7zH+n(MtVcLRGDY+|!az#3W0+r56i&an@01Mcw|vR?Ff$8~%7N1dGU0!je*E~+bA9Ol z;_WTNs!Z4SVMLISh9w{(-4X&ygLK29r9+UG4(UchKpLqLyleSQ)BmZ}! z-LB@YK#gnR?(b`f8VNGLE4{>&NX8u2GaxBr_)&)9A>{LCAPK1pn-Jf_e14sL8z`jL zbPu%IYHUQPKk`$&%9-pibCDGcT%;e30D?AX;^3A%jp)N;Y=Pq_DAa^nD=XHySg%=& z&Cx()I+?-|L4_SWUc=98OU$|3t#7Xi`zE}p;_KlBRb41*>+l86j0(QN{yS&^vxu&amGU-!x-Yioo#3`^05ce!M#l}Xe}}`q9+U7V zS_!_NAK-tIj`#|y)C0@h^0P&2Fp0y=&dHJHgOd)3dZ9&V8TqOOcucXz)0yI7=OHN8 zHnimAuh_nP`7#PIG&J-JiHL~D`bf;ty@ZNd_v!9Q9f_)AS};5@{INhO|GhvD9zcYj zZ>(x^r*&X80Xmh)bD++px8hSs0j8Mr;33a{Om>DmNj zxH_7FS)58|auU#3gYtvuF)F_NEs`*>%>mbzF#UYiI#*!P^!OMqcm~4fUxBXPbPydLH3S&-Ju5Z!$XyJK@QVjqw!oSh}+1Vjk51 z9ihXKJSt--s%K3Z7WU=ceWa3i$Ke(C=2$XqClPG)W-Cnt<9%N3 z>6=IaS_0h$$4?4b#Mgj~3%|4vn5utd;k(n?)|0*Y^rttQJ{k1g8C>XP(@o9IL+L`S zIWs`J6tMBWC$K8YGi(q>J{9;p$7#ia35W+VddncvuC(5slpSx8ytF#+rAr5VhS(c7 z$$Tx&n|i=S^4hImTMybu>6^d1b-Bzk$EIrD2hyYFY<_|!#LdOthzP3T`=I?9ITN2(Rswb>}4}^(0?7Su86nfRf^;K$^P96*tv;pwpD#(E_ zpWh@X_}6PT#~5ro_-?$a7d!hY8T7~JOSV- z^bx+Yqo2bG{aK_DNy?|5uUh(-$U+I`7wt=Sa(23&eMKV>d+asGF*^mG=uHm&uEXV-ariLlW#Ug~gRrZOZmY z!#5RqbEIDau~~!+*Z_V7IRyoUU&fgprcIC{aQSBFyiHI6(S(*jQRt=$DeG~~Dc2EI z>B%u08a$}8AVDPl15!$1luL57`h6MGQ3kT}EuMi(K%NoM96r?o72elufO+=`YsAA7 z$oXZGJ3{?YFdj#A`lHX$EB_K{eomuwo4YL+LUpVOxYh&ejBhjV1v&uT)a-WDOW}`( zQx<!s@tq=@iwX55rC*cGx3ZFV@NMUfsDuGg{_86D%F6%%n{RX5gsKgdJ(vuV)zF z8Ze+l!$dzD-v<(4c<8*=3=b=uceL7v?>#JeCoyX}ePB1lq){rD!fglSkpM+5n~R~4 z?gC_YbT~m7FP!fAO}8c0u6nKZBM%8g0J;r83d8v~9IEpReUY)&ud@G=qg(qUH%3j?r&>QMFSBUKY*01 zK&|Kz#K#Rt$fbE4O1J+iQWOB13xF93 zoZ!4@&2fR_3)+rr+pMpYR7@K1;b0Sm8cMiFZyB^!z;6jm+`3pXjNT)oepGfQFks!kup$7=krM+C?I zAg|8MWH&gh4f>8GHu34L!}dOf!d8uO5s zyCdUX8D?X-AFHx}%7I_T<38oUmlQx-R2RZ#CKSP&5Bn<4PE1UEShKKT(C)Z5H@iy0 zm)Zb}829k>Eqk28=Mq5}o=ZrST&=!7hL669&eAIo0YgDE*E~l48u(B{y6&?)I`N%~ zj;)p3=>R_xWDv%yb$wrlz){Pu)GQ8j-)pLBSP?>%L#p1Kn~xE@%EbYMNZOGeJdn{g zGBP^%RhlZw5Zo7j^z1eH&g%-}5Ce&DA`0O(g|ybWHojlia+bV?drq7S!XUFTf{gGV z00O$Z_C9z3|KRS4R6GoikdTf@UthoA5QtSCg58iM3;A4pbmK|jCB>JIR>Np8?E1tB z3a2W%&(aorje)8bsehzF8aJbO#ddt!f&G3zkpc(|PKlfl2jG}|kI%UYv1z?|`O|OM zAOLv9hJ;7g8-+bg_*CYm*T_#8#9Vx)pp!}nQg_sQs@j8dfos>kIoBV@6Zj<+zU%8| zEjIp}&o8g8ibzCWpL})$?7{rD+*K}72gqD*k^M^FCb|NUzXmtPSC6=k%$2mvOJ0AW zOm_m*Cs6_UOd73ArlZd>d5To|W3|O8*W+W%Zb8-}S0MZ$z=HmE67PbjI;Oby@Z;Xy z8iXQ2SXo(b(Phf2l>=AT{SHn~S!{8=0r_hbOG`WN%=sysnIIN6;}eZypmafqvGXJr z>t~t1K79}dF(m{A>j{n=kgv{Hj#15^jR#@WgBi9@wT{BP8P^}ErBjFDRh{~1=|mzO zHdRKRZyWyk`Unwv((E5etrri&*D|?pyuZ-CnWhF#+Q(XrfO7ZQmH%wUL47uR{l{C} z*?th>kPUf|AOSkH?{rmF37R=a7SW!Hzp6S#@@hU@8nZR|Vx2T38 zn~E~Sl_Xp?PR-3fOj?4<_*m`%-1iHVB3%E2mcamAUG6&0u>LMal2tWJTHSk3;EdBvrKS{PSXVv>_~IcQzRkj=ij6P zRU&BL$_(Gfth}d{`rDM?N!D*4HzRW|4v%FK!21sr_3)FVdOd)kU2Q>=G7bQbb}f`# z>KlEI>pXi7?ADO$=(y@Y91qOv0t=2R0SI$&MEmMYxGU<#$m+&9NEYjjjpoc^`FFo<+?)nGltEb z3M^O%j(jzZoCr$P_il_zb$>We^>D3HO-Ws|D~W5Yf@X@f$Rl_k9g9-itstm+|(=X+;TI-9;t_P*$MZi!ZpV{kE>Ma>E$EJ32Y` z%SXLLOYMUd3}g|kak9?N&Vt&S0h(Kov!IhXKz(4oHaVkf49-GtBHrxivQV6qu%-hH z+#&2idyr}8K2aqKZB5&(m2xH%8O13NTO=TXSvMd91+M>`95kQ@vd8b|xH;(vgU9zW z-#dd+lDMIghIB8d)vu_%Ca{cq5x_R)1997Is;ZzW3n*tVJq4QI5?Y`6-`o3=Fq3)g z3(tLM1UvUzb;@-v{wZ%|>0_LO;2)}C3|9mG-j#gPi0fp?kccq8lM7lS`Sp4sb_Z&I zm`F@<=KSFsb+Yp{%gpDEY_yk8M+#Q}63fSbK^g}m8!nQud+{k#=nQBu1MG4Qi1eU> zBeN$D7`aiUQnIpHH)O|zpfqs{lacjVQ-JXR{^ZL$*&7TB`Y95Vr(iV)}6#@@#@{opw zl7*2yTbl;DQVCEQITMm?mR`VOE9_BJpx`sO3|`E}P(iZdYk^{r%!FkCibg>HN0`Ma zJU32D^2*@<*3jLS@&6Oj*)ds4M*_j}@iU>1pm&RL-zI`&`A6lT2hu#H9 z?o=$D^)eFm90Bgi6GV?qcfi4)i>1P z`=KlUXs#~UjS>GII?{fO!;w^OgpAM?d8=e5vN1+t|?--HDKlJC- z(1HCZ-H?6)xrv!sz5!rlX5;5SiZKAEK3WKsWCTGdVB^XJ!%IsZ$~OVOh_QjUdYs>JZ^Y)4$QoC3SK;}Y;h^S z*b;K$$kkt<%^!~%SW-Y`+|66~6^1E^qFr)-w9mj8Pf!AZ{-s9cQTGjzX1@&c!0N_VcJ_XwJY*nZ%spW6JVYN3M_Ax1cv0ssy z`;;8YE`9X?`)M&cQ5Dg*6PRBbqhCfV%+U!r)R{hy5wE4ET{49uBygX1|L z)ryUb;HP+@TGbZPYr~FBZYP_5JV1T9=_4=8;rNVdd#`Y<#3phH77^zky%0oi2kKM_ zwe6~RCzj*Iy(C(R`U>kD1ff9v`}LIMod&%br}VBJQhDH@f|9J^5uta_XES*HvnoC= zM#$*qfVVFzsJ7^4!?q9!p^g=Aw4%Y2w3MY}@~y_d0lScYXF2bm>_T!3@Frz)-CvxGjRHlpHC_6>IE$N>L zu}#+xy~2K8Q_$sX4u=Y}SUQH5A5BVH8l3vkc-4&Y(6O;b|@ zaO6Lpz2tK`)X2-euP&CWGZ+uAX3H=lK?315AyDVHO@{f=eiC>@y2x=}@@+JmqU+nY zhxXXohvu{TY!0japU^=7N}|G zWWmc~z@lOvNQMDu7nlPug-nniX2U(<*M{^B!3zruKn+EJo!uU&DOpcd;bQzO0dQ}^ z0IA%O`rt5CVb-N|e5~``Y7#Xt1EzN?Na6t*a5P5J(@EczntE}qgqq;fVj?LPOf#*(x z87Ox7y$1qe0}hU#>r|3a7CD{T7JhS2J%9jFU@QroPGv;DBciI}2_qu-g*#0aYlt&IHsP_{KOoIvN>K-Vyhjy#Qz)$T}`~phSQ#8JeV)3(LbO^rU_L{osu0 z0c0iun1KRGZlSvAP})z>=;P^nCh!Gqb$-|Dd!!*L4uY`w^S;66lby6|c=4a3)YVeC z$1gSSwx|CS0)q4J)nr7<+x7Z$dT+OVLgF&a=OG(he?&iBVW<-7zmOUi2BX}HB7z7?TYA+*Op^SSb!Hc*%n5%GJwOz_+dE#nO(z)9&m4z$%HSlHODjvLXA zpL>lnxri+ag=blF<&xN4c6AC9szE)LcOUB0+8F@Jl8tb*PPqm+4WaWzDicVzV9*U3UtRdsOT)Sy19G&)8_|9x?J z){=pov^GD@~a0wv4b(1pHmch)Jf=YR0xiL)-VVfk%*Y`_)#{K~W{)BG95RD;L_&T$PPWBz~#|=^0^xZm1 z&&Tk}+ztgB*{4YbKxcxWx77k!5dls=7LXq~=6QIjVby+OPIY$sw1h;H(Mw~xe)`gR z6?TC%Az(wMRi0OzyW$~5L8K}bO7;Nqi6fs4JkTZ-2m(s1gkt@r)N(fF#oFvaY$o>E zX{Af7PIZCHbhalG9+PM^2BVRR)6vC6V_(NR%|nsevoGSroMmNB6Uw3TPx5}HPPFMt z%v+VP9sK^jbx72{LVFHGW~jSx{X-4mZvpQi_d{3ZbY`zCy`#w8v)>er&Xlk)Kk~du zD|8u>>*Jk#9BmB6T|RH2hNNdK<9nvN+C6j-U}N3M5?B$hCZ&*8inPxkkhDnGPLfB& zy)C#IzOEXIDVio#;sD}Qe;+$^Iq1EH7KN*d{5#Cf^{tcmjp#9fmH%FOk>7N`TE6CRXz zXN?SdUMfb%u9y!X(MunM#eZWk!XJWc7~-!_y53i@H#d^Mn!n`q%ngq+3**{gLkbJ)u{GqiMyQ>*8Qpu8^_Umdte<7&1%Z5B;mW{Xy+7X9990_M6@<&njgbuJLR$Y{!*!&ef01EpYyAW{_@gmr*Nr2Qddn|@rD;*AZR8EqqNLE%|+ zn9|0oVL-nw#{;t|g|eC%MlLlPpxkG$eR}pyp|#PFQ!&t|lRwfQHQ zN2T6aVWg(seqq_;vLXGA<~kr}cOBgiHibg9b07gOd|bc6jJW^R)ixNS0dLpr{ei0M zPL$wD23u)H!|ZQL{2hM9^A1r|p<612to0|f#HvVmWnShc101!49MWM4UoG`&6=(1I zL$@Izae>u4rFz*UIR#nCl>{m;A=js=zccvpB^4E5{YKLxyjN-x9N@JGK%uDTkG@jA zGGfU`$RiZGZSiO;a5-y9@9Qmi*j%F?_3rw1W49?NnD7blI?mD@@pNc&X95NzQj|bB z^u6PvlGY-oNl~l?hR8#$fhW)2*=v;%db6CysQIk< z$G!A-iYx@9625D@JF1Eqet6;KlH&i zvZ+w`;@OFi*pekHS`R|O=PC+sS+~@IRHF#tKx%{skbA~ZL-62|e<4vt*jQo49+X{9 zXIt1tr@eW}XQBPLbZ~cW1%(l1Yn%U_I{VGI2-u*UNTj-i?*}|AwVw|#2D`2&ZzYuN zy1NSVs#)rrq!|r7ibf2Pq1ybI&zpI=K4C+B_=9Mv%U@qBS=O>IM$pqJ2?W&dK(6RN z<1PTc|7L86e@C5ff1sf-ul2jRnc&md&a8t=eDo>ic~$1#(OU0M0YZT_CSp}H?!lCu zRsQoItmx7nSFPPaHh3q;d73GmV0Y+i&2Nak>niGwcvtv|n^_nW>4n5iW%K@hgEZYw z&Fo()>IOrHxDBBcXg~rC;m<&eB=rOUms7%*BiL@`66n{sWhZOy+bA@FTZdIlwYO#8 zD~b4?FQ{zX)|*?E*1rI&Ze60ldSl`%ZM54%z4*KO+h3yr_{Dx!W?4ky$fm0y;~xuN zjMY98s-gFP#ga+ak)Lj=FwABxKdOj1rjzrP46M2Yuyj8O2ZBf3=c@|zo^h&`r5B}P|ElXQe5W4X*8O!-O* z^6>6_rxfh{bofZpfeHPrh!*)D*)-0H^zvAI)Jmuy2-hjrGPK3LIjqDv{hhbMqyjvPi^!7s0k_ZUdCLlSjLNPC+fDwlTs%M?JDcP4e%B~u zVN~ay0U~J)X-TED-_mOh#l7982cNmm5*_KvQnV-4)qD{m%WUQbI$ks<5oq3*hVjyXj&7POM*74?8wF!b=ML40*(<%x zbDE?wtNuJEY?84n^v4e^r?q+AMM5oANz%>u6O^Z#PRwRAn;|w<44LQ`?eERQD>q3P z>{2IwB}u1HW}X_kOXw$jpr6M|4+}6BI=w3)7`0y#gk+he{4Qh!_~B2oEe)&}8sg38|wEVKk~ z_YR*amy%p%9e&q1d;TP%e$uKg%ISGUW~UJ;v8vSLM}ONI1`i-@^}BkzeNS7*U$RWx z^(*AiaPrl^>{NnC=$vMh#Y+nv!HwVZLl?{tW%YSq+)Nz%$KuZK+X!I7&VREO_ZhA2`|CY1< z{=POGtWpMbkhuH*OxzD3T#rbqsUO{$hvVOF^Vo<#JdGt~u(8|D&P0mCsaLaBy&JCH z{w&nFEi>HiUmtt&k}HPN6q->d_7(~qyVX??AZ4esVKh+29YE;Jp5-d1T?QLGTxazL zo}ikmOA?o`55qyE+b+R3FQ3UAAV@|YNENuJ?{c802tk}}&X4Zpos_{uy8r8Si~WL6 z239uW4|JhQ%Bw}>4LO-TlGp5`6FVwrV`!T>)%C|8f7^6$Z8^HTNU`Tf5rE`C`Sy>z zMByKbE7Jb8bjFRB$QEONN;jE~j=%burDjLSo1fM!flfzX)Y|V!)4o1j=8eUVU@g5h z*YQYRUdo|=3(Z&;4teT?y)CHX)ou|?;CqHEbKup-MjNqk>T-TW`6idNZY|Z=4PW4} zcO*|}!07ZaRvvlJ!zso79v;@*Bc86IW&xgWU_W=8LlxVEd>>;)Cyrh!oRaoz45jQC zDsbPm;qEkc6-E;)ZO_VTE`nxM)Rgl5Yo7n4q&G_l&q6fGXN^?mINbZ5%v zOFA{deW=t2&3AV-^Lnht5Gz=|y8Zp*yW6hE{^)4xO&+N{1)cLRzvPFI61#Jufi&?4 zg2w$5K}QL9NiCm7^J%01t|uYu(|wZaQSZJc$kCcR+tUBIo>Z$i0Fx<77B;@XwRIur_$eNo=k6F0)+G%=}A#u7{T(Vs|K{Lz89No`~JR* zO}dBOeT9)>l#yRJqIc7h9EYZZQN_Kk6b|b&br_5vT>IVq=DMJI+SZyNd3fG}ZQRG1 zgAp4N{+TG}ZcexbwfGTUfn^5yG5|V1Ov`yX*z2wx^OzN1Q2z_fe*F{e7(?yG%DYzx zo_;%aMOjjJ{@{sGr?HlsI_8m*@lblgHzpB8eY3(gx$WuT@m}8>Ty>34D1^YH~rt@y9z& zAjZE3k#;6ErwB{kEAD;hs?w7(o}W`c9Y(S+LY+b55P)Q5)W1?P*hW8yLX|xm5XPch z)=gLHgnkD+reeZ=#8o}*Bq^GBFvz)`gGToYx)8NG%tiGpD6ysbgKFohg7P+dKJ?Z8 z+i!+g-EMoVR#VY>wb!p!wn=F?35|XnseEVW*%xl4*o5T2{#b(dF50$T90vN zTlQ`ErL8yfiUEy^jJrcb6RkO$+wfHg+Hx6#i$Myv14E)hdpNoUWyq7n+ICvxBKZck z=K{%;kU}z|lEu>^fVD+NO~5U&f5XlPkcr5GaP7$P=V(6KOHz`g_LY6|C&wjSDL&u1 zN9@OY0}e`y@)GW6CrADmyu9QNmbeOni830 ziT^rYvyPqh4zj|(Kb#-R?-O>Z5hSi6EL$KcVz@kaEn$xiW8eogzP;X>tU zr~d`c6#c=Mf}DZ=ot`3#H}6hEx*e*S*GTvp7#x0=%qxWdQ3C*4{Qs%}5UYwYF*4Vg z?)LT>^?*lyi~*3pC7Ud1x#jujG9b0oD4jrob>dx>monhU%P=NV zm{Icmwny}CoUJM*_vdliEoDi(&2X}IXivcHvC<_dFJuDYlUDg~jz#>zd9_n(X93KL zn{jyBfCFS@ZlG`e*V-EKkA66}XtvAgV!CluWZyj?gT^sr;Ci(T$}X;VGn|00E)|-D z0>If$e@Py*>Uh;8Njwm3DBx6i%qVf@9uv^wX{oUFt=R=?@x$m$`8-IOwwS zYqB!GRMxCqCshih&Ng$^)B4=Xt~IzPf&aBSEKLKWc(A~VPkGKBmLJml^SDE+u6AkG zMkd#a5tJfKucO0J)^eUd_j@4kIXQ%?OZ~)SBkgrc``sQuaC{X&`)BHWDF8lv(bOQy zj10giff_jcVb4cpKV7%f8dSk7XDC_qw~;j`>8iEquR?uG9j?=JP}GYSaF2i{JUQ0>IF;}(K_5H33gkRCFX}!PRcO}AJ6-|`9 z>7kR3kWJzf0IiSk(OdB%Jeiyi0ZfRd-Ln+5Ya?F`|`RF2|YshW-3tH_;Y9z zL5<`2pS3t}8f=S@sN$H?81B(Q&sAw^so$@UoAkck@A*Y6?I}*A_bFa7sxGQJ>hmyB z=zBaQynccVsmz>8x<7UuH9WskJ%IctzXnpyUS!JR-F)IcA0m0G8n#!Y z9LAjZIi@{7-lc8j_WnBvLfwL8g0IC*y8Cy!;3%7W8PxRlk{w*P`>9XQu1@qr<4aYl zf-@Bfz9U~s%1=ezjn^1GFe#HO{%xIRgqmx~rj=D%{kTO;$1kS+lIS7ElkTg!Xj3AY)j#9=vj zt>m~HSDsJXI$hbwMA}}}=74(Gg{nu#*Ua2blL1XSZDKaB_Yp2Fm0Y`O`e?xWX($Pzi|Fh*3(xb!hAN%h?jG|_^{r~Ybx9QD% zcAy!6r$L5I($6fNpGXp7BL#cT4eebaXCStX;WEnoNt{bW zg)7#+0lX;${s=(G`hdfDEdh*CW6c+9n^$<#XmRL(mwu9QB=}ft*EiMenM|PPGv`i$wu*+d8794 zCY4`qjj)y6S-Z~Ny0pEzw+=ehJf*Mqw(NNJZqMFdo{pTI_+K&z2rG`o*g&e*OO9&} zx(3O1t4-CNUt98pku)+rd8fNtH_tOX$M=hmjgy;m`#xwh&M#Dm*S~3>zz5g^71D

P&D5+qkVT{(p~Yv{K{HU=#rC`(0(*)MeZ&D9a5%hsVP1nwKcef^EiN)Fp5j z`~T#E{W%lU6mvdqyFt&6x_(#ror8>~wxOto z!y3XjZk#9ok5^Z2^tomgwZdAM3aaGu?iodIIdZ?67{2r1yi4`u;e7?`L>d!832eNcu9M+J@z|L zTlod^=Et24xBT2^xBZ!&=r$5sb5ltf!MPmFH+!P<7YCBZDsCN1q>ltth9IqXs3TfJf#J=%To6{vxzF?ey?haaPldJuUF^-L zC;PhvYMH9hMcm09KkA7F>#1u%RiR2yYFBrg(@@dKRnigxl_z#ztj-4dMA2S6rpU3) zY?st>C>i+m*xR^Zy{Bm72eQkJxJ8PmeCch?(?~2F3=FpyUVU^i-YsH#63k=Hj+pDw z!Q+;ey)`AJ97TOO{aGv1T3<`zNE(Q6EzN)Y$SvDdwQlrKTwJrEdnowfi}_ZN`n!CX z*<{d5>!w(j#$21`niukfM#qv>R-ye`YAXM4&7M!k8Bv|Vbr4=vuSdYtrD zJ?MHcJ5tsU!&OGdxLn387oJ)pITYO9cCXTCsw$AY(+i=o*09FHv&ng;{TGaf6s z(K0L%#VbVQ{RAU9H7!$2377qK)TzSBWd2^Yv`_L^;3&{oRwXZ;eA0()GSF;+tuvBl z#mkpz596TW)j!mIJJufXm~;a5BeSyB`9OlEmWCkl-SL>{vJ;Znnl6EYqXcznPXUAB z_A$H-s>1)(2Bc92BzMn*TncleNN3G0iL0b7T6>SEK~Xc)&OWmuXA{e}pS-euR5;6X zZ4wh58itA=LhHFFAlwp8h9T(4?Aho899t4BFk%Z04J zIrB6e&7Q=p-8<_+;VC&7z96x*Uc+o$Hj_zJc(ZQX&v#{C#o-~cDl;$}TYNGLf=5d= z=cdcX5!>uTK+AqZshWuU$GEfM0`+Qy2e^zl+>W@K+V`r&v^qV!>iJY;Bfr&iyg$JD zUPzRzhnFs8IZSKOEM{tieLH`r`gkrULm6EI{Y`obO1q)M(IuMX}+c7 zuPKf$Uiar)_0BnFra{iFmK33a(N1$li6+}`LD*sog&G3QXTaI+5Q8U6A~CR1%UZ`% zmxJ*w@7!iuY-Kkcbox^X;}7TB`AhJJx2F9rSzbz$BWwuq>LMryOuN*|xUI^43IK9!vADhhrshW+XtvG+Q|B*M#}kB0iv$%$(F^o--jPRza731p#vL3|0@bo zL7Hzyip501anQ##nJT8avLG%8>yE?xnX=`=lIm1FS}|leH(Kexr?|{^=!oMsz_V;<`UzQy!%m%P98pqPJLPf zJTC!o@{g3bFY9u5A33P}p$Uln;WilKH_HuS*E;Gd^;rp))@>@4^Rtv|rCShh?)7hJ z7a%QakX3HQN>q>SbjJSg$@BT-{k7@yU{4XC`A|A&eHigoXi(H~3EN7uo8{TPzc6H~ zV-j}d;d}%(oR{ZlVD}^4FLN&L=i$kS|2uWMcE4Qs8vSyoI*stH+0Iv{^{fTcEIPAJVpM$*lhWVqlK)Cut9Wdirs1RDQKY*7U+@lgc zvizkk22xxm-X0x-({0zp0;X!=J5u(#<|^2PBR;+3b6X>Md54Rc)^AvYMwG&9&)$;B zfLvbKe`Zk|ixL({hJ zBfmE%<`SaD0*^Ys2_98Zk7i;)RdRoc8f2P(zpsi(~t+gGUqbqCP zIJCQcd!t`CD_P4C`_9y~C4HH8)|z&M_Qu=PtM#cb5|}590B8pBf6@!WGKK283KT89 z`QVj;waoXYhK_RMr&GFd*5MKNl>Mg5QmS}_E?2rgWKHW$yJ_B@Xwvkm@G(?GO}_NwH;LCl>G8TP_GR)cTW`a) zk^c1?f8pvjSD+~{viI<5!_1eubqhbL@5d)`hZ5T=FY~6$P!WP~u!6Uy+-lOAZYX>2JiYHWFWo@1sV(gcSL%*U;zU^@sD5^4E-e6;&bS5(wxvz$2K!QbLQQk zH$L1ou7e;tNmf^zQg`E__tSRzWP;S(%HchHYL#&^L^%GC(6|RrVBMnmQW1js`&Sj? z;qnJV#4BTvM&_Nn<11jzK$Rabbo29KPH#Hpg=>7&Tj#?~NCBotw|!a@7pg5vjx1SUZi?JwV)$3~dIaU+Tn z74rFS!}wIBE0Nd4q2>I&(~KC!-B1;0JrV+cd~0KKvX`~n<=COC!|%SAWH!5J$Z%6w z$4KY_(cj*WnPC)ORnPz3MK3Iwer{IxOma)~9zxdm&$Wccv$e9YqyG5fY&vTNc%ME0 zYZ4T7$cY$vEfZ>az9~fA*?N1vL7~z_;5TfZ^Cex=PWxW{broGxZn9E79|2|>fWGs$ z7h`2C^%lN!X6|Vv*efnC%^71xFz9!^-*@W3{3TAc<#1=uc@he5aTP!gcz;6yJ69a@*c6+djv*$_{0BAp!s6?QfLEbSNgYy zM%#kZ*Q46+S}768>y63c;y6!b&F2H%;cKH1m$CovCsij@2*ZM0vxA<3_zzzLuzP7G z(-C~^D47bZa?B@3BGropW_pO|!SGb0LUR8eP-Ozp1!6SH_QO3DepA3^Ox=HME__Az zdD^qqY|Qo10umNxLB{{b>I@Hu8cO^v*Mp`GGvB>3ThY_rKF~KU(?{@m7tpzAV-&sl zFkOwy@fhw?91dh<{`p6FaB5NHL?)y7Ant=gYDIJNjaXrDMVVlE2UvEgJYd$W5JTX_ z=gZ!m{P;)e?M`(q7ez4>tTBI;()=^e8)gcApDdebit#sY9K3Y||F-}E!^;p68YgS!IfmLOsx`LlgXRrZH}Y?g+(woW zCl_9N2!mhoLH$RcfZmK=k2ry7u%Ku8Uc)QOkMxKfke9#J6r30cN%38JqL z5$XF`35Q>d-tm=FKkQpFEX}-UJ(@HDY&QUK^Y4`q7*>V|tNQkr8<%)4*1V339y+#C zBT;d1o7c|npu*()+rbnD{S@HQ2MntKgT&;^>i}Mbyh`9k3CLPZOqRg6^pNy7@E7E^ zo2oJg6hmZWqIc)II|t2Ve-e!g}-r_;-6+shyC1J0SDJMor{>QSiVYT^T=z91~g2pBa*^ z8He=Ee?quQEC~`Y{^g|t3THpNYF~`nD;zqKb##qKz7gn5vGK5{$6w_S zqrxM)4+kowbl-FA{RMZ|W;8yMk_i?B+ye zlcS@~3stctJa9u-B?wra78MqThWS;rp&2iB1R944bpo%txEH%*fZ0IvkUxEeJfqm| zf}W9)(zbSQFip0HrTqpIRJBAz^M~=^F6<(Kpg056o>PSLZ3F$5Y!FqNzRvF~(o`Xh z(2635g@h>8;Njz2T3FB%+@1h?%#~kYic23eQre*rGlFTK%u^(DdhxQv2>2ad?+4iX zwEi@b*qII{bKFACr=e?_5`PvQRL{myIM7hAmo z8-iOG0N^FC(=!Fv`+<^;YB_LpuBobuLTgRj1Zo<1=fCoSXhNi-?UD^?`a(9+Z46*f z(D>fH3W+ua!1L{V`sFTte!cNTh8FpT>TFxcYNJ|s1A3xx(p z6393>I9OQ~vr|)3{|XM3(&>1@`10M16fLkwIvhdYB|A+IPOu5q2|3s-Dq}PR&XSJA zcVcKjTVll>HOcm3;R$8y69rPFcPGi1YQ7}1dqTW2Q=)L~RvgBv0H`l`GC;))G|Lo+ zF|%yF^0Mvv-HcHa(+s3P!{~f}(b)G)fyofuueWcno;hX%7uPFJM`c-i7Z!m#jyu{_ z8yg@zSF|a{_XJbWzgAX`<|irq^5v7rBHw-QVs>L=<6#qzuQBX1UROK(`7{rKgO565 zq#N3dg<5Y&+sDDmhUou2N`vI8V)N~)`+$S^S{`hUvk&)kg(qv1w_e5wn;fB=0eT1$RewIIu~=J)`xIVI76D}C1PLJ5(~zAJxg4TOxW4C6iu z7PW1WNn;Dz%z7^2(mEYj8*Kkv!SK1!chZ$L@cJh7dB_Pz>=Op$kdsau5JXf&R8&-Y zR)($@zzvgCNt{^e^9;&s*&Zk^A)(~>>F%s0gz@n35IED;C+K@=-sk{F*6sB+A+m(N z*H9ukR)91_@|^65ZP6m_B$RL7iDIOpn+ITw+QkT zkYQMS-hkJE4LMCfQ#DQQk6Zw>Je&X{t4<@xL-+pBO+T9%;1&rMN zW2Z9*1a}S0Giz zWdL?0;GnD|7{~yBZ@S4P7IyF3Yrsvh-{kfn`j%Tif{&akIsNf`C$D79^Z%I$!(u+} zbXM|`6)tFmBwQy-i^pIfPfw_25WV%1EOw%Ahk(gB zogDrR3=E3w{~44A86Dz>cem9k>&#O@g!Us8qJcA)Pz?=2d-b%$MEW5W3kwTM|8L8m z4BOtW4l>aY;E#F#IV|+5aCHi_>tF@~FN7ta(53NU?!@{w^cPV2=|xN@&Itg~5RvQR zP&H<|tl+%~p{E!841@|~BB}ln?iMN6SoCD{$`xzSZC1{Zl*mN_aR><~OqLOcaKO$h zLlX4=5CGSKK$DGsMuGoS7??IP#(=X2H!5UNj}n~VK&}ra`R$Ljil1U(X}Q;W=Vem2 z`q|R;nQX$rsSOK@Jrx%hhJ(+d^`mR0zTqMb*4q@M(ve?ohW{UVZ~Yc!+qDgo3PU49 zN+U6}NcWI}#3%yNAgO>NNVkBbboT%ZKm zu(8dY=Mn2z$6EV}y^r4C-a1oT7&MMVlhFY{#=opKa70TVJ|5+&eYT$(edU0a)5IQ? z4X5Tak#TlDdPghnDu|&mc$0v7EYJMJQ;M{wrzdU*P|B@lc$5NmLePY zx(TX0;ROW+6}Z>?R|odbBqwQ7dUvC0aF0D96Zw7ONu!MZdz>#Va15UpkNKqFq4Xu} zyu7RFGe%`DZ2`Ej$uQn#e+sJEj?Nt3N9iYV23j4i>V54?C-Q+`?dsh_WuV-`~8x=u8L7-uZ1*N!iu^Q+;c?T#`(nQQly1h?o zJ>#HYFeNorZcYri7I%(b>8A+UQAax9&MufgJv)(3*pE;xeSeZoaODRq*;dH^qTOhA zh3zhlTVi6RE-Osd`5W&{!9QPHKbNQbt5ubieUAHplW=uuY3CN2d4x}5B>acuOb-hy zYf$eeU_$oIWV;Plr?vEIE&$fUYr7Xz4=atI1jeYLq6!NOV`5|Fj)FjiBGAk++!89ppC#X0{fzm} zkoi@^nRox?$|(Lv@wwH07wJOF7%}q`_7)gmsCMS-LWX5$Gd>o+@R29gBsS*J|aLT9k)8&J5~i>#@8`*q*#PzyNRXxunZ z^1rYGu0M#ec0lM7>kLPR=OA5eB~xu5bF3^BO*^%JQ{!w&#URhMVN9@H05n~d!Gj0h z`3thbyN=~&5oEWa>D^?_I7Pwi3E5+1lZgt^%2k$HKc{wZJ4C*ZbJEXl(f|YX)eeAg z{uRvmYoIjnK>m~bwp2*z7Xqy17!F2W9rT?f1!NDp$9#(2vV%tM>*RNPgcvaJTd4pD z-amiK3=c$fne%P?E6tse2~)*A$$o&ptn?U7*Ns5Z&v>gqe^Sku+sXZ66b5c4Cq^yZ zzd)yQVlZ^0zMvP<77YWlC#o7fY-+7JxhayD2fO z_^)V!?w?c#I~-`xf!aQIGCt33isri71$a@UDY>sw?;_rPq;h{b@2qmg{`x?7axhq9 zUvmZ2P~@Ku!`CjV?;0^oJNUs33n}(TZGrVarZm>o1>f~4QQ4rMR7~GsyF9R1M@CX7 zdww9;<6{HpBEUGm{SC4u5oMd@Sp{ER?bPo~M?E%tC`tLQyaA)N9kq?y=w0qM+!@Bz ze_3d$j7UlaoTQX!0OI%?;e0QL(zUtE8Ml9n#$|#>Ov9ihr*ddcSWvtS!&gYC*5}cu zuL|@Wl}*y?wi7?Kbg%bImKb*McPfO5SU_l}+^ddL@_D>WK`t?UgVeQ??^;UhXvWTH zs?>NvM2`=8EiXGX5VmEL9u;iFDUW~^V8R{%x%kH%08q&9=oEgr(x8zPW;D1wPG5T4 zWDMtfGwRiL<;>Mv=8_7-solilEot2?f>(TD0BKGF_|88dQd)RNq4fss)i;WXgdV6y zHlF1CaCaA6u*}1S*o1p1(EfdGUa+GVb}}mY$oNSJg334u5N~{kL@P z0=ikxR;pSi@h!cUoV~KE=7rrrt#iN{>;e=lUWhC>)^u&h??>|4UUml(8uH0Wxtw^X(i)V*qzhH6Ix z%l5wq2FXc^oNIXX)OKQRfPh|yE#r01;ePS2lFpeyu@`g6=CioP{`GDO_LH-BBR3M1 z`*l}>;`{HtAgfJ#b{jWfMa%kHE&<5-Z@Fv>21js@$JP5ozWtOL<3yF{Yw?z?#-DrN z(k*X5ifz@L+&h>1)yv4mGCc>IH<~y)bML;ZzZ!M+u;eL(QveYIsZBrs5u^dBLqRKt z8a{}vZ(1(}?|7Y>F-os?G!axL>5%I^cuN(I5xGJ#EhXWGLS7xeEiLhy&(5Q@?<$;o z{juo12Uj8Agt`$h-}wJSYl1LuHDx*^)0*;fU#B$RMf(|5{CmsEJ9?fcW$JD-;hhv_ z%{Q!t$MH=QgRlmrsULU}?6(nVbGz;Fm?IcK=Mk9mqgn;57sWuzSC^@7a$H-rTy`+qCC3|GXx? zb0t5;NNr!cpr~tjeo|bjcV^#Ia?j-81paDHS)I0fidobzcX#f-Tj!Cdk=OVXPwEVP zTDp#@?*G0bbRo)G(Z9;KTO{{RwddeDl6tw8lSW-d^Ulbox>qvI{GME0Zg@$WB1i-J zlqjkQE{7@4tS1AMHZ4j^({&BbX9Xa})m*{AxvqAt^#Q#z_CK#UXf{S<%I%maYsQ@NHorb)`DVvq6WMp~EXyw~vZzFJ=)A1$~WDB*$7f4+kx8-uf78k+Extlom|$)gIP(d=6Nu7G2T zDZxt8#i|#QtEJz59bxA{M#WeX#bXx=ONZs47vREbxzuk@DX9?7UX##^bE}m5Z7|WF z)h7L_3giU@gPZTKM2)|0zG-6EPL{cs;1vmoHxW>M;nyITwF0X3 z7p@XnzRS7tS6_Tj6M2eQ?OCjNeh? zM7%LhHJiMti0acw|XrcZ) za|3;c;_r)UYs};<_-U;H$6JFrv1W>W8YkcL@f?qq?ZqB>!tzs=P%F+a3=_qRzN

VBj9y9W>4sAl1Rk+HtMpwS+nr;kRUU=)+ZXs5q@V#>u!N1$_z$^L zTa&b|(jJcI#V_jTxDk+vk*~iJ0(w6fs27<*thNTSPXeSu*eo-s`I=pL3K6}e9LbZE zI(<3?&yVy-6#|0;-XNKR|26SjVB);gdg7#bzclgWB}fkBXCG1ef$jy$(Sri+kM~aO zDArmhZyUo^G{6jsOXIT&?bq6eDviEP4%jaDohKNaVqyLlhKzHMN3+g9Ad4a3oq!b-~zsU78Ov z-A6@XgN_~^x^k;sf;X_cW`m?H?S4_r@a**pMf8Z1s)Q6ViJ-ohSvudn%{oWar3Sx| zOYzpMstDIw&!sZ>*u7`)iLHVrt)D(q0Y`X8a4?bAcKd4j@@B>dwzqfVlZs(;%kOAl zoM01_TfkUE|7-%B49djBgm{aD(~%3RZQgsmt;oRYn%I;V>B)&DDrj0{YXMp|SBNhvy>iBqcgTo?T3_bkt2_D{#d`JX>B()XkjIG9|@$V)!+y5Z&ac?lp`V9K?oF^^@+6_5T?nn~Edwh^LJ}fI1|7-ILS@yx4?GOJ;DA0?H%R`#mUzzY z?U#RCC%oMm*?4faOO>CIN~57ng6V%ek>_10nqGs6f71g~m2kDH)^F9secrFU`Im{1reVjR15{{`U(Q0?NAs23ta&oXyr^NbYr^>=d0#jsBRMLY^0*~-v05&!u zzxD?4?7297$AiBga1qmhZyJ{l4w34e+Ooz zS{A4XGFH-L-QFw*zn9rl9*%6AU1p+h>KKm%ewI=SiQ9Ko$6~S_AgFeHDWoQUF%X3c z*}{61%2Zg{LKF7NoL7gmDvmxw(}*v=o-lsl+>%qi2bS)Cf1d;w$|vj0@5fC&dX#6@ zwqNDV6gurrvXR}^k7$w*ClzKzCF28WPx})m$_Ad-vqAU9X<2Ot)0#OwF8vyz zoe-fk9!1gfXrudBx5gREDhnE$ODamLdN*(4!miaY(18D?jg*~QuRa{T<9UDenLZo6 zRJ(Sl$CuP(T;_?B`V;0Nx+i%A$$116s&G{F!4FM6#9-!mEYTjvpUnT&5$TOteickj zVuj%g-r+VC&1y{+YJA18~(%wc=W!v*U#x1q$oAZxx10dfQ zaG+1&ftrk3z>;mf&fdX+$^hJi1z^~41z;wlxdQ_PK=7?hAX5W;?HbxcD+g3KXmD)J zTQDYEDEKvrJP63pfiJ7WvCD%s`B|@j4Z>S!8{kR?p5RzOsPdneU;!gOO9^~ARui3z zNh|!%ul>No&cIW_2n4g4V*b1Y+_h*w!I!_YXrYDu|80m{8&ls@A30FA?n)Q%`12rj zJl?Pure@)^g#}~@LpXXKs}hv3!0)s(9zCm`ljpEoSQ$uJvB^jgTJ3$cZy{3h0hK&e z&V~%@;2Ge-5^dRjySkFLpXT%Z)Dmn5u!|Jt{&rAxiNLmjz4V>MfvWrkI6$sZ4iiG~ ze_va$4FJ37`a2~W4L~mda{-w=G}&;FtqRO(_#b1s@B05y5y0I829n!9+-OPg3?Nl# zub8#i|4L0^|AW7X20%=3?+;$2s9aFq_Y^=HH!dU}nIJoYrN`M)KYn>(Q{nDXJr1oO z7c!U<)B1hS)-gz3@G!G(#-(o8FuI++7;mHO>#@Q1l;PK=rjeEpv$X|UGp-2E^5--> zt`og!+XgNJRoY)xo;=+z=5e^9b&E^fyH9SemVmbb(DZKxD>K>)^KN;n1LPh>hnT{1 zbfB}*n91!1TCV1KpCi+*OY`p!_f5X;FZ@bmeodQ0FgGcAm9*b4@5pfZ<04M{UWro7 zs}0JlH1#|m%e!e$uG1&3h+$fPK}=+SQukTFaiCmT5s2-cYOWYt&(^T}^f@OZM3Gy2 zF;uG>KS4yUa~mt{cGKCj14EsL+PE_onqn^R59iirmCWRsP&UJ&0VidQDTgUuwY(im z8CdVyP5PdUz&ouX5{UbEOB5R&O<4I-&P6UR);G>EOccOM|8GOsNo{g;3uO1r*_oHe zd7?iV6Brke9;npwyt7RaCvb{AS64Z-gHJ9c`jc{Ukpxpva`>({&F+1Hkcg?5s{^MW z@gj>Rb<}=(`bHAUt-@dbL!Se@-;zcd=t|w*mg63bYy*{Zw;4p_kKyu>b=3$ z5A|X0+BlB)B5ANhZcq^6+SS#x8$5(hM3Ptt$|D&Oi~+$+i0E)-t?Lg92`Lng!}ysu z8b$nrW-xl9edl6t>-6(4+{dc-xE$zLRR&7Z!bDvh9qA5YPZ`5wo@_IqqUS3N?Dg{# z3cW1flEU&yevG}!(G3cw2!SvL1V*8PX+j{^pX*lTG@$@$$Zq~Q zwLs5}#sd<>1M?ur`|9bb4MjFb5_(P&yRAtTtn3KL%tSoSqT?O^22U5KJ7%A~?rn)? z9Nc&>?2oUo6LoH~Wj5|2wu&bjPQ2V9%<=CJ9OK<9{$k5 z+t=0^wGNKKj)X(cGa z{st~Y=HxzvFLDD5(;5APuZ|4Nge(dxqiMfnktXJL+JG@rf|$~t#`hzB(mKyc+__4L zPnTFX0-s}tkr{4pd>d4ab+`?1;%>s%A?(4y$Wjt{S~2;2{20Q#`;4s4!8od1V#-9P*>%ymU0hXP-rz33?CW< zp#mkcJ<>stO-lQdwaieyW2^K2uzk-_%Q?fShQx!g6vFtLz2&Rfb~?*h;q{hR@BP+; zM8bvy>FA7g!{iq^EEvc&yor=r9w>_JfBHo6k^4nP6bQ`3EjDH2h_h@p(=L*-l+ye_ z<`%o)C@vJg|9&h$Uv^4trakaEjlAt3jmll60quFUPx0rZd}7i%ROp=<3DVo?3$Vgl z@#zv!>?tX4hYjbOc>x0aAM75b5hfEV(bD&V`aEF)t=xX_Qa-INP)_;ql3$D6ah)cl zxf{o2Z)Z6{lHjb&s^tDg!|zLLH}PI*sRT{kzGYlk(&Tt6^g%COP!|Okv+2E2(T}?G zlKNlo85szFjv;DhwauvE=$nRP&ox(O0cKX zFuB0X52wqNIxv2Ym6*KP`1J4)0UJ`=QmIE@`hto%Cr9fT^%!NkvzayLK?F3Rxf!vy%Ya)CfhNEm`37pB{D zsYtPHw0Em_4y5OAu)Y}5_*T{f>uNTc~O z!LdI>W>;9k=$EL|46o`q8iI4o688!NX3;+|=WU(DkK4Z8S8qwR8ZpJL>}ja8(0rJD zK0oK&XlBD})YXRnWat7hKzo{B7yaNCxIL;sDEluXfcpA6&jLV}#SbSn6+~33<5IUn z@*Iz;6Q_9Ta=6aD$+y$8F6SWLcYu6J=`#5<+VKW^4$iq~4CQt5wtB zgP3-#vWjD{()r&X&!%kTB%(9RUHc=cX=rWA@Kjp8FwSCvL&5MB;BudNj#l&i5S!XV zY0!8(*7`V1rahTPC_fWLR#UWI%W2dzY|l%Xg>5O9 z^QLMmOPoL)fbs5t9B-w+OfnGvMnfY5RZ7#66S>9dQBC8agYLb~kop_2CZx{MV@fo- z?HE+!mrEDk8e284$k4~3dPnc#l;~%s%`%ldiSXCUAyY2I@ zwr$0YviJ5rfAqo@fA}lcs`?w7I$Cd=Aph(7OCwLq(S&0aXzape`1|LzH@v*x&#Zts zPlD8ldw)j~j^t3mT$Q;xbe-DC0be$Hd=9nx3;f^FNalnO`o=r?jO~{dHm4iU&7KT= z*qPxvB5O<@k6M1I?s{sL{jU1|6D$_@gu0bklxSBDW{owN>d!OHHN{`tt zXSBac^*x>Tg?4>k>#d}lLNKPn;66T?Q_06g8qb&YY8Zv_p0)uYDhGwRZhscB2ew7bHSnSdQX=NQf%Kk z_R#YYgK8?@2x8cSe;B~hAe2X)o)qInTA87<{O$~Cxm9gWrJm0YLsh2=@QB^d||k+aT_5*CP{PPytOLgK*1JXKj<3VE(h_bUodOx z$qWNpXv5Fgu}YaU-Y2zI-VGQ-tpO9fImpcOL-%0)Y$1BsB}+?tzdAKIlllx=N&kpO zIfG~vT{N15IzBx*j*p30S;f_1)oW7THyM<# z9*<@F%zu>r#ebcHoeWal|1lwYct_~&Z;VU|7oY7x1=;+F!OemB%weth4mKi&;7|P9 z`GM)Yw>bH8N=lz01cX zvD{>6eKFJ|spG`76iX)2K_tf=5uf;Z-T<=OVEq4DjMLelRNtH%nXHknr}7rwi@xY+ zk+NIv)2VYOo6;*c>ecKuWS`v^&T#}=vd;XUTheQ4JCgXaSrjIujC5UI{IxgEh>4a# zJeA9RR&7yq)P|{~S3vgYdg$beD87Hhc{hn+8Fi{31`c<1DAe(d#UFK++M@NEo6mY| zyecYQ&UD#R=8w0B9gczURx2q;-1^H&y7wo1Pm;~#?}Q)zLZg)MBM-QthR}R1#;;oU z6`x(SJ^I<;^ASey^*StO^EdVGwH#^!6+*cNZNhsI>SJj&_tv=9%?lk9O*=FWv6h49 z*zu06v##?6kY5?v|5CS1zJt=VnNy7~Sxgq zfer#|B#$b8uTntvLi*Kd!vp+vvD4YOI)l=!Eqlx&HcrlUeIn5Dx;yx#(3xYKJKtLD zhsmn9gS~7p0_;V)t97gOl@FnBC@7VI#ti^<3V&r3{J*;pukcys6;B{O{?o(6iRTqL5?N23mwGYq7C{slN#{{bAR;ej8Nqb5^M zq>r|i^FtWkVV<;@hY!ogx(|Q;*_KZtMaG z&M^5WBn`DnQ64!S2i(CW-7CDs6*UtWkR6sQes*C_B;jmjl`3S@GVkO(Nwq_}ebV)y znhXxlCSLAhhXpW95$!A&tDM z6Y8f06lgAFT1M#CjH@v>6~#vxofv4<-wbKGj(4LgD9~zZWr3lfvjagwGk=4G&$cc# z3f!6Xa41Jo-3B9x`ZJQnJ=f}=A2|kUM!m?`90qwLQ=ABA#^QhYA~71DXidq3)TI;K z&UFLTT6mb;!{Wx4!*5#&!s2aZ21TWA^VTxd2{-Z|4Tby+I*q$KT43z`TXr<7`{fQM z8T9aa9WWHIv#xV1qwqr^vOzZ64H8-rH`s+AP$Y_Gp?281W4yX~I_t-0Pj7~DCeAvV zYI10uD3)`b4Mluz`Mht=mE3`$$qthlJH{?ydmMUTm6~Jx?i+PpnWP<&j(CUSl(ov3 z>Ciz+4n$2b0S5JXc6l;IU>>@X+8TDzGuTeZ<8 zGi!~eR%wT99Uf!#_e>#=&;G0wKuzS*5_wRjM-yH>MqaNgB#J~Mi-zdMy&*<;Gh4#U7v zzzz+S-bj~4ks`=~ykHO{4pSWo1rOHir<{&=NKjFJ3<2U4+*piVl>Pbaq}0s|G9nmsfpF=2|#7 zcVRgG3^-;wT__O@J{4hlFWsy5mWw6Nda_c6uba+PK@Rl>ia7{ayb23xY&R&UAPvE) zZtOO%gw8+vKuO+Y#QQsJbj@7%VZoTKkiNsPtq^l`@XV$VB|aM)n@Zlu!pi`7wpoR% zTelUN?0s`x&2f;G)uH&yL0EaYxPQA)!%jt z?J!GMUp;iMnzC(~H@=7*wvOvvHtEjNT?&68pSSDUIBZ?4J4DouQ50l6zTqTx>M2Ex zlhki{5LCM1EZ)N#ucCbUT@gE`U}9YvANMJ0xOCVWj8QCog~KxveRgqVx+N`VRqc4< z(ADFSZlm+nMn?mE>ID9~&e4v+qICH$9=t6kxYPp^<69I&MqXad<5%1#uQ$6;46U9O zpUpkbf74`0zDlbhYB0aGauU&ZrhgjglHm=%;*&1lh0=M|ot+D4zigZRj6R1Xp=U%h z#reW<^menIhjCfNE9?@%8k){)y~@qgg(9Xi*NQ^ODhB#8y#RXA?679s^Whh%QRr$MOE!YmO z{8iS&g7IBqD!f1pJ^4l%VWPL~61Au8NE1N^d;d@0J*D2RRoYWU*0WJNX;6~-Oo|`> zL={#=Y-`)7au`1Q@U_&)3D<5Dj*i}e0rSUUdKl$zLLx7Pt;N&B?Q4L2O1$Jvp`a<> zbBBRp>4qN*@hdjm=l~g>sHgyzpa7Pn&li$#tLF4%Q8qTwTLQ`Z=i}$-EDr{z94%S* zFOSZo;51{iE?cu}iU>b5P6Pj;EI?TiM#1aM)0UzuQ~^2xA9jMmxHhKip&;St5(?O-ZU*#JBG{`{uo8_HqQO z)z3#f|CAyD=|5KJh|&F(53B1nEUZH5*4R?1bhn|gD?X)YX+}}< znfSiM9#EKLkd(YA^SLPE>+9uh*?8r!@l5unQ$SXpoUvBG+qbp0Qx7RkKvfIi-Vo%4 z4K=)+_c{(qXsJ6*VzayT>=(FVBXT;zT{cBWMoe(!61ggCJxfrlMnj~&plCk zHT62qHT3U%FZmd|Peu4{&z+R)ii{~ek45?!yUy)PhV@g$M{J(X{LDh3ZjnK+KLJR8 zVmQt&4?8S;X!%>t(cmUcP-FaCFQ#zN?$f*9q%Rb5-*dPn8VXsgZCZz+dNvnHGpr zFVZggeY`CV3g$qP?T^6$JM`7T%*3y|ySpS`ZN`hKf(Wx!Tj$`WN=jPaGkkW#jB&E! zzFjjv;rsf>f5N|mNC&(TNo3FgtK%U#qHnhi@5mf7f3jvRFtJ2eGt#pcr`5pt+BzWc zZrt?dy=T$(6i`8JJx03eu@%CZrp?U9lSxdT9I)c{i4H9(jzJ> zZ3D8XtAxcoF6XM`v=ye6`qt*lMZySkm&gR0%QL@#8=v-CXtGcYe@RWPEW(t0tyTspRu%xZ#U); ziimlipIpPJBy3T#i=Cc~O zU0~vj-fyh8qS5(O#tlX2s8=pZy(`*1b*GY*FnwT(K6P{N=<$Q2(qL6e&lfHFwhak_ zey-tqw6MEE;kG?ObFQ)o*}hw^vtRbHRn&>R=KV&WL1L69Zl{5xbV|ckR7FOlvE#Ep zTKBUWexDu2g{FWFK7oN?slf3Hha-lEu+qD$d{nmiIEGU4*vUMl+h@J-KbO zVzX+HW`JXlaM{)%Z6u_tOF8L=U^yc%uZFP}mtJ+(r(lsVzZv@mf_SAh2xVZycC-GZ z^+aj9)=L~6nXGCjjO01M05?tn1svLN)1fTcUu#8%6g%j@KDEv#QC!!BM5}}971Yx@ zF_$f_%_L)){Xc4oa_EyU!L)F%hF<;i&>oL7~B-}Zr~_4c7@NpqTZbr3mbiL|0JWUI8?=GhYUK0|KF?S>F@)2 z(SEv5uX|9N2r4}azApXvVYU_uDyx3b3>o4N zh#(*NCL{XONsIF40=ZRHSaivSo9@clSVc)o@OmBjlV5u5HO>*y_8wbQiT``_FzJ+^c5QIe*+-cQY}H2Z+<9;!?k|>w zkwJ~{{#K$yPUN@XBQyshr@H7T*<-xeXpbj!U3g+i0Ya`n&`kr-a2a8pn`^Nw;2Nk-8OTQ;x7w2o9q3*&67bti&$f(G_2Aj3XD%{ z;LAKhysA-9690vHC}QEk^lC4Cf*>rU+U@{;AC6df4Z3oHk1kFqMfj zj=dT!Y-!5M-6Gx#zc2N)^PME19<{M482eI((*5XEQ0{lWMBPcXKo>ypz<-1Uii?Xo zf+a$#9H(RC*0CJ`#m5YbIz``Q7HpN{ zBHMYj@IMkjbR(OPGAyz{Wg1gg-ON8izc3(^U6K4T-xP6c{}}8TdG&Sy%#Oi|$Ed^U z?rIUv8rQl%kM6VPN8i{RoxRjr-4c(gJ3X?k-^K(W+Zz5-rT=pS%d*3$Z?~MxUPYFs zld_aRocr-~vU+B7l!&xKV`F0af+2#NS%4*~lGW48D-iDO-K>h(jmDvW`tMTP){xYE`5<5k$ z^W8|FxM^@(<6(=S9dl=$s`j3*-Fx?oCDb>zF?&^7v&R&PSQ9DleCoQ1x^}Nn0l!Wkcd0C3j%g4AZ}QxNB$qmGTFW z7z6F{7W1DmQtGM?G&;}Z1HF_4YP?<29cSy!Ur5QW2IegsHRw5?q#fY*lH!Yv@M`icOfy9%IQ}j z6YiDM4IhtO)D9gx?E1rnrGO2>xn>}rNaH*G=(|bj&=&;#apabuD*$^Ko*^(DLXk#x z3fN3#fdo$YT`66?y|*9@&YKSv0JCTy;ndVrm%@-J$A#D#C_rSh1q{k6ph6UIeQB^3J*}#yV<`C?A4mN9Iub9kK%p;lrNF zQiVAF1M$RmE{L$NGEtn<*oTgnB_r!}k{W|gvr#C?e;H6>z<~0VWfztX*r%ZMeXtma zM#hg^gQvK=D-N5jRf&!qG42Za{MID!a^{P@62Or;w19nYRU7&_QkbHT7Yq!<7 zua57c2bit_*_grj6evSxx5cNIY8;@2%Dp9oLR`jTs;jGS5JOqXhtBgXo*=TdaS?&F zFQ7`?%>$;;RR7Vhxmz!qtc`rij@xfL4Lp^SWfuNoD-uJV`2=fS4zcjfL@Md`&q!VR z{w1s9l~^KuioDXDS;=CDM_R79e@%$o|Bp$?kE0OC_B}JI$eS=yb@jJ$RBY^;T165n-Vu%!)WPC+bgb0d8D4qm)!LArcAd>yctVqhvM&Vwx^4E_e+;ve*?H zHfVDpa+bt)?}@>X>!HKP7P&B zRw6G&wB7M26TT`6zoV(gZl6#vJsd(I5T}v~fr);@rb$ZXK6U)_#mJb*=v1I|Ar(iz z97AEj$Tso+(k~L|0d{7!l^2dDt;_i=1>Vq(FJFG2oSd%+w~#=tOW}E7KP12#D5O--i>A9N%$18i+LDVvkQ)_;iz=OvuP%Q?P)b8D=}{b9M1>A%rc1 zSZGL^vFJ@(rlu<>t;-W)?=RxNarJwmg$0#|q69rN%7+1AV8gGME1=f2_M3BR`EHT% zh03%H+s%6+<-iCgO0U-tvE)V|3=Fu)0N<|8k?ki%=2Xi#V=GC!-D;0N3834TyHg;X;m!NG zd92LdJntQ{jppC-cI{CH$>lqa#gI!q*0UnsPkqr`Ft91>rv7ZG$-~7I(d`?n zYK=^u^q;f!Rpovu-sa}H;|enkE-$hHJLo&H;85V~pz<7P`F)45vxfk~cLAS84_S8k z>violdBB#Kubz(ek{C+eiFsWmDF{5(WX&Y8*UvDWw376JkxQ-+=oZzV)%-r&nYRQh zS79X23@fCid97sx10zQfQSo)cXJGt$d-gCHG-EIen!l0ga^`|jSa^c=6%Qv*=VozJ zbxJ=cFj4<)&;uK60g;uFH-0$x``!RkJO@5CDFjtd0fpXY8!t2FCA)470|kB_uWhyc zw~y7;TH0)^tSbrn_9Q~(H|HlNChC7&0lsIvEG#{P2Imq&B*r3OvbEnsLrK4*5>OOD z7#Z={Ev>FzZ!Sb@!MJwqusvAtAI#>L*kerHu2>lmL zf&v0n=<4CwQVrC1F>OiM^F6`uK1bNB6}OrE~~bXe$OXQcQnGzjkwD=Ts(`1k8)&whcH zGvF+@;OOM$=c@*S8df~bCL6THR65u1=z>pVjX@9`7eVWkob`d}-o1NLQglydk4niN zhu%|8syY3?3$oCaEb;p0y>RSH1yape)KAIna>qJ_?LbqVNpXW`nQ&1wlxt zq(_Upt3MMg&0cpB-1-yPd3h@d$|G4QB>XkhgQ<$e;g-0D;WP0$dOTHxEMmdyzYMSp z|I5oyBs9ojTgImJtSkl(mP$gLL?a-VP8d}gbUx<}3s_>@w}Y@xPfjMSWNaKJ3|+E2 z;TX4&7>t8Qd{(sA&$4s+NRD$&wyIgu3Y)xrcEE^{?^_ zZGQSTIuyra5ir8~c(am$UPTVr;uJx$qp(g@WmqLIg*-2X~bM0A`&G2|?fP#UCv z?8aE-e8&QsaNmr29|>=YIAu9f*?oQgfv>2|ktu*efZE0VPZwz+`J`i2jO@(4k4Q4p zL(N@0I5($w2Ewj*+)Ynd`&qN376GUInQ`@8COw5(kGbBO^lz7$;lP&`g zs(^2ubc_Y|`)HH%wQPZVM<_Jdfm}Vy>D{#Z%a`Sj0f&P=myU@s49v`!2m+Bk>GK65 z5!uzunh0tHgDoDfQ;n$ zwMXDt{~o#PBSua=wr^+wwd@p+BkOz-Vb%7sL{S-kyuF49rta{6U1njfxy0eb1LJvnF#RGmXk`EaF$ zs*P`PF&A*9)5OnjnpJD0iv_Ofj@+Yb@SRRfICkOs%Bd6D`(nIiY-W->--hECE9~Wm zMR><(RaO?7>9hyaU2u|i#%31@IcHzsO794<6rz6e&j&t){~UY&{owg>d<aiwv|1ylqT+b{$pu1_0j;61~tO9}vo02wj98AIpy?&*%9TlM z;_%3+>a-J8yFPdS;rIXujZWQC)@J)ka$%>wY1MxSpqwlfXvEO#{#NCFLL>#~g~>_A zEVg|qf~uqs2Z6V(1&Dj*`7S?QVN@HJ618Q-}I>BG#j&CItJ&S}5ue9pU{e8Npuh#9Lw z@ew}rcQq*2@%m8{P#))5Q$Lo2DtF-9+N;8AuVx~jes@e?cRu#Zcb^?gRW-(`z%||n zR=6ORy*r6?`04bn5d;+#0(Id3xrz5kcM9g*dKrPQ9cX#CbhLp=t==hG8k;4(|4UX2 z6~MZBHTZ?H#0dSYePMr@>MCHi$inC{G~(7l*kJlc$=#4ApTzL|m)*S{;jb9=&|K?F zSN{JrNEMzkv2M;tg{h19lq+@c?K0K!d2l;8H~=&G7DO%Oo(-Uc2c|J_=%$ehc<6;b zf-o3ZJ87F*6#oa>Z8L~8{7t?7{HQ!O?7JRx0lin6@Yrm(ZC`Ray zM}H0J{sYvNMGOba0varMB6CJXCO=Pl*hU~0Hg*J!aOsQrW`M^wgWhG{#|`rz>}G0Q zw&w(_1|9%f^ME=J*WMp*I0izd>av%bfO}B=MES=q65fw{^5b(y>SN`^TGMqA!GU6M zq#&O(eR0OUUHuIizAlfOK4j2K2f(10sm)36^PKWXblL>eO4)&i0>#)?7uSLLcZ#5> zCC}V~x0#&5BF4n8vx$Yz(S16kf2f|^pd|AYxa@_rXq~&v;x3VI5xboA`D>ozoHGb? zhENcEo-8J4^qs>ikU=os`LFoUH994TB1LMW1XX?jWHVZs1D7%P$WEWV%{l4k?++F~ zQ@ViSW3jPC!f9~>CD2x*HE%BRsP5$iL*ln#MLz_>_%3nM$uAPp8c#E}u!YlZ5B{X_aPoeMAoI_> zuhH4vW0?^~T9fOGe7AlgW$5YXW;?BJ=xFVww}JK306{p)vVfSa@GF)D+S^jy0+Io} z3tBifN?bkfc2q^M(}If$6#~Jj(FReV|F|vbAS$K2Vo`fP;}{Z`F~i%9_Fk)4qL0?# zGV-+Mo*0rO8W~Uxe*u2NrNh#fq@;VzP9E{7a>s&l{1?QTLFURMFOhKRDW>ID_lJ@j zxf!YOjxsu4=3mkWF$=v{lbgh`<_`Dsm;Geg*uqQo)@kVh9pRwGG?qdjm^BxOpZ`PD zuH6j_vc$*5gd+1cze!4dw?#dUZbm#wsvjlRt?3_KF(HdB0Id zi!#6Pm&eg+GBI?E{wkQ!Ryoxd)+&BBKJ*~KNQTa2nlz)PtTL7oSf)pM5&hzn8vzTcW$@14C5ASkp_y9 ziwyeO@6X!#|7BxuMtA?ss zp+~dSV40h;BB5pjHyku6Eo9OXf&ahu*{y~+&?|&cV&Zmy;6#w!*2}2*8aHXShg6s{ z*h7b&S7SZ9HNH+bsZku_<#*4&pk@CUr1)L7ss7~EX=FgDmY9_mA3QKbGg|~62(pqv zqUWEKOoJfJZ2yq1!n90wp=Njj{y=;YT?Qeq_5D!n@9-GzCfSmO)9MZ083Re5gDu?& z*KnT%VbG8a+egG`vfAGHEvL}yTd)TKkPZ@9+BIVf4isb*qJ6&`0C{a*`MbBG>~0S7 zSNON6zV=#0y_+k{^OOw)aZM2qwjMJ${~ErTs?PD;I98)3H3#>dCg{;YzI8bGq*n@uvnZBUTTl+==HEzC640eILK5#;1+UK{7`9LV#G*U%3(c5% z&CR7bwllMemTtCr*u_F!X;msNN>wP@!q)e8D9rg;kHP<;?k&8k{JOnwQc}9RQ9w#c zx;7xaVFS`3-5t^mn=VP|*t8(s-GYLYbV?)L@Lc+Po^zjbpZom--r*QHU~E{|HP>8o ztu@#BerB!J#W!N@g*hIh7*%6g1@o#-tYNNC=o5q?&=nk(WEq%a(7*1Sj^eQVV9rd* z{tm;Ot*qMrva-0SFXp%|v3g=;YR_l}r`mNzJ%1Eg6vYvQk{N!Gvr;xC60URK=xret zwf{_>29n&6J-+16@9^eA`qra>8OEre%?jW&B}3Oy36=kt{hy1Zj--+x(qYq!?BT5z zX6h>*%(-LFk)I1Ym4|5u6p`#z&ebBnRf_oC98_B;dFj{kHrFC4Exh9vNo}q`Cc@1AUR z%rBV$kL)sx|GFh>zQKK}WAFY`dqMZKG#OFNS#jj`ZBqMdr>ZjHjo+Pxc21;~Gexf5 zg8hQ^Kf&e7hh@Qp1n4HX5WOzslzu{RVJ=Y(G>n0P2`G0T!ob8}${a6FgqH}HSAzYs zS(<%PDkC}bSaiZ?gJuz9emt~o!ppxC>+F+Sl94n>Qmca1vh~B7l|Gk^z6OCH6w392 zMU4#9@2UDP0W=yWs2@^N{D7MB^K~{$^n13Z(2ug*t-}>ZdoIE(r(&a#BOg0bw3R$6 z*fRN;S;u*Y1PK(t6*61`u?(STiVz0Z{-5_V*PQS@Ncx3N?0wtYUG%c3G{^p{#1XB@IiT)>^J}*!<}dl(GR9CNKiB*Aaw023SPg~BvK3nfW?sE8mrIk26E1!=uoS>!O8)Cv`igMr_{NjDg+6L z=U`l_zc!?c`O6UKlLpf!xlVX$=!#XAVYjLGQ$S6ouamULJ*egeK5blew%=`y`D#xu zQMUIc3=stChfn&p@1y@DvMrPNsV~a$lIoQVEgzR^h(sPgTM>2&4>6&SvEl9ST?NFG zfM2oeT>kHs)+42JK)+Turwu2!9=uN+Mues{o z4obZ(0l1j*Em{0_e$YPSjpQmvgus{Y-iGCJ!duKLM*_3Yvh(Q({y-~!|I^J@A^DQh z(hN*c^qZ%tnb+rFFJ^kGMJYN4YYLA~uNN2G3bTv>6L*7klS!@`=xKCxDQ zy?}RKt9SKox&KR|bCwB;;K{UtI3m;dMI7%96{`D?z@G z1EQhR?K>2JmR%eW=%Zo-^a@FEg3Moj#d+^TsJr zWbDyF`l$PIW5emZ%2kKqB6#M9O+{yP@Ox%u?gCoD922x#T6^!(WR1u^RW}NYpIH^@ zqfn|3)wdUmAA@dt<$2$_fZ@CN@Vw=QXE8+BEA%iib0RuI#i}bQ?rQyGLwGeqw(9^jb=cRyB- zz5L2@XR^N)>sq<|h&g%slcr4az$Y`Q0*^J5t?m{ddGrh$KAB@Kq2mKNzk z=ehY4;qjrpcTia%Oqtd*fp#^Di}A|LzqZ^(Ut$4> zDF-r(kMgAS;|kQVHuUSM1&&wz>aQP@u@$aT`L8AksUu&oFs;`=EK%BNu@Ai+IbZN| zHRaJ3HxOZBiQnwnu?3#*e|wk-;9;CbJ<~sYd0LAzu>xe5tJ{GPb`f=k-%5<{$DW?# z_BFpPN31pJZl_e*T<^kpyWi}3q*NdMGqPq~iH<4a^UJanR^3}m`5jSiZXa77bOJ@S<@;^j?B*|mZr)Z`SI6!EW-1xnlYo#oZM?(Sfb%4@E#!3X#O|ppckqQ1Z4yOFR!cDq6%iQ9bi%;P0HKZS zFAXO$CSP(AYrp^q1B`bc(o(8N?6A#$ja@)W+(Mhtel#Qa8e;9?{yTD2qXXIs5H;Qt$|b{Rb5 zx)-lnS6+lo-=hPEfo}Tl`-^dbZ0g^g_Y9qVh%6a*o}05OYt5nF*y@Mk4+3Ajd#Xve za4P!7M@A}`K4NCym~tS}TiZUh)R(%F$|kViSS(GcU1zdyQ?%U?JzKBA{cz~q=j}+8q~9sxuhqdkoY2kKs5h5 zpeO>67z;LIiXC$EcN3OW@Ld$pg?k6DnvjNI)@_F;`S+e`Cwk}8CP;@nsLZBlN1Of8 z13)aixd@-vBzG{DLtd$zSNsN+l@sUL#r=;fO>f@G=!$-F@{4&4hF0WAPZcM zpZz!cV6XMk<$=M5&i+(W-QvOzku3rL#|adm4{?8YeDae$=Jb+>h&#MI)-&`hi!{EO zc~-0w$@J_Q{OgZLP3~YSw{I&CqYXcJkdmBUpsrO}s5SVVYcvpcYZmHoZO~8bmHN*l znbz}lrYzf94@Xv+kmmdEcrxHoK%r=x(OM+VhjeiN@wI_yP4^Ox@^d(fiks4F6ISaT zU^!=^57&EQZorxtd}=2=n54Ux9t9qZIZUgs+Ea1RQ2VB|+hfO(qGl#xb`@QMp8lwg z;WXW&mqEMJB95lV&1^$v;l6z(fNf3(vb@>W6OKyi_P^m08|HBG#Ki6hIa4K?X!kMT zTiQ6+nNm~eMto{1_FA7IWUPq8sqS+|>@9e+fAx92YjG_yZqKqZx79?$9bbf~PCLG> zZy9Y(VRPt9SWnCZA0!H}FcG@j_~*O|gNI-5i(sfg7U$o`6M#9Amfi%`n#HI-ijH-| znYuZeR1xA}Tp&^U@9PO*W{rp#B7MQa&Iyda3cCcX@bJ~UTk@QjZEL%d>!&+qYo7)A zeBX9oJeeOagUQhI;V>QEE~Yg-OQkvL(zmo?gkFo|@^fBD8}~& z0H{eAKqBd*{|iC^5F~Kl;sH*Hn`FPR60^SEavB#z5&O)wyhar__}@Mk{mBO+ur)k)7kpS6eO%V4_t&Rfgvd4? z4|-5DUj^?TYkPP;@*D{J8?^f@x5e0d7ql+#cEW&5u{@chOTFZC995jDy!|?ytCQe4PAKG{* z2c0OMQV($SgV-qrk@e~F)xRBcV@u+0f$-$>3!{hXK7Qk1i`Lm8D_$dO*u8Wc-7;UW zbtymQD;a<28TcUU^GoAdQgx09wGWByogasg4@x!j9|;o-sQ(2A;79@V31VK)0V<)} zzc%iyGA?O!4EP#FwVAlNz{MX*w`p<6z`)?^2Cs6G$Ruzo$FO_TAA1RqQOcgt? zM;yi}BnhJYmk{#5HQ3t_24x3+OA?^_0RQFxEnznYG-{+4dYa=}l{G|EQ0l|kd=yuy zEL%ISx_x$aF578;!4zJC&rz}-9Q*F6Z#}q1F78mak(U7@RuN9i;A_3uS>y9tot$xl z&z8TkEiI_Mx3WloXH)&o-b>whb2H?Uf4oxOmV&)i{xmz(|Lax8BIDJ_x%*9jqm5MH z_}UHmaj=IB@rT2;juV*K=`RvL`|ha`c##ixJdhdh6!$+`f4h^(v){Pvf8 z0%Vz3_W^HY&gYigLo)2~?((zZ6QvYpIxKlOn3qCr^;6)TB?>qcrtdcWJ*jf+1R6rP0HNKmVpRwYUc^`bmMlhdTnN zlxDxU4IpW>?B_G+>4d#0{Fw4Qzo$iRM}drxgfVg9$8MN9GdF*~5)MfESLn6KCn|rf zTJp736bg@Q>R%?*7R0~WJtyYxymMspf%C@@&M4_n9B;bT<`jc>^y1=axo-p?UJ8I$ z63b4RP#HhhH}p{oJ~TbNoApS#d0IUKw zre|OQu41Dm$w5$Sbn${@<+*W?XkKXMt3`4b=~CxcWa48PJzp}OX7tmg96WCPRC?3| zA?|prip!O`m@rl&Gn7i|@FWZ8>8!O!tsw^f*vt5-=GS;;A9Q5I=E%7kmlko&6Zu1= zK?XGct3jbJiNnR_A74naCqU2Jf#)N!BcGo8qA zBQeN7JKBx0d`fHRgpjhIHGFfA&cAUhqP9ip_l;c{q4O&6m=xPt7h^F5LS5VRQWNzbK^cdpi#{%uUy~71Ml@24(+`myfW!9KU!|)*1_7CF_3> z3;qO~3(my823fR0PI_Rl0x9G+a30aZB;DN0y5x@v3ZYOd%RB_`w?7#+C69>ZYD4rg zyd{s&0Fr-`DD2QxEir2;gu#3K43i_k)I)`@^%q0uud4?i1Yqm&tv4z@jm8$~VWMK_ zOKhjT|4pwDMrqKy5keP5#Ed}3S4fDg+A!oc1e9Q~I3C4yZs;4h+Zs~j7xokt`y_Vc zB-A9Cg_X2hm%kE!1j3WGIF+DfjiU*6d7WB4nTH0+pdX+<+roZ=y@w0xK-Xd2sp?|< z_P*wW!i<`q?9oc{%~r{2JbQBZ6p`PHl9U~nZBBdTqB(r_(ujOIo@8F^HA@S{4+-iX z3nVbpwNme`2W$)Bay=Rr-TPhO<|EZVOZ$+&*%BlmTVfo<=n(}UXvOYD>qi`6eav=|mR8Gwq~SgT zt1}~Dtw;L@@dvQ}{@JQ?0$cSmMWq#{`be|f;5V-dLtZmTyy)|d<2b$LZU0nAE^?_x z+AX^<`Cbu`;;Vy@`m~Y<$oI+(GsN3G6$4M}or|#^{f6^#WPa>}_E(jhvK7~gXF~l@ z%rnv`D#?o*=31*4w35(N_%9q9mA&-tMgWWNakQwxn5jC#)a;mBoqKN)kcfYOV(PMNaU)7 z3sL{_#W@fk@18>L-Bi_==T`lnDqPPEJ4uPr;B-Ao2L-g2q&^bh^R3Kl-L57zW00<_ zHB{)>3+TN~5Hbj9?;Qw@%%@xAL>Mw%rk^m(+87fTrkoX0=1m}5qDP3DTHW5@^|^5o zeq*@cmOyw|YW1o*pKk1*yd3I3L|4F8ACY?=TugiqiVML3J5PmLfntrkcl-XYman%N zZ$GZQ+%K~v<@T06>aV2-8$sIClE$U65b;C4Gk>D4|KLK@S~eWGMrcEzXbN->ynI7K zvPobV@$@n2r9 zN>YMjdymb=>J8dhiMqn@6ETp*!N*SQ<~!x5#g3IjzNw@iqdU%8qs^ zG9pT7D1$c?p~C*#EEWv`Ni) zKH+M#U^?7c$Lp)gGWQKb-3yldXAZv>-#uNPlaz_(l}c>CipVRNUpKX~cspe@`>hY% zi!t70u$vPu!C-QD?P0qzW6*$QtB3Nwe52I!)byYy#c#q53PsKT?|wxB_|>M!Hi6`4 zqi#|8%Sh&o@LrC|%-HGps$Og5V@p(gP6q35p5SRgMIDiS?iJr=+mG)qo4JiW)mQh% zHQh3;h`0#|!C}U1g6RUxV-b?*e&#g3u?&n=X{Iui9Jc<|`I-AnYvD1o1Gh2`>?18= z9zCIHLYwxH)|<4RGS%2chBi}bRevlAiUuNQmP<^xxYG-1B2%AwRde zTa1Murn%1+S)VozfHm9=Y-yIxMN{ubUEF z+slQ;ds&f_h^bGvb9~wLV78t;D~4Fz(nJy zfEyMdOn*13CeQ;4{4u<_tzIeQ33?j}%qzN6dw!m|K8M+K5O_j?E4lZMjf-!vyAdCD zrlHJ}d!Cl;CloSIZVQEKK>i3gjQKO?0+?3-aSWWoKqa#k2ey`9IZVfEP@2*PL-tp4 zU}jq;Mq?v}2_SRpTfUBXGToqqVAH{~H|OUa*|Reu!nmoXst`GO$znP!{s@p0~{MPXM!#mR$zsTPt9SC~=!uDUwxo4(c$G_$gP0w_cvLDY!_b`)t51a-u z!~&-He?Z+GAn8j)zoE{oAjD5mgpdxuQYJfB=a}00r3?$d+_;_Lu=5VidMQ{WNde-_U1M^ zIiuHb*lzrOLrR=r78+4e*fq(u2<&;m3DZcRre$_s3bcoc5x&pWaN(QGKV*Ly*JC zqZ0-4B!B9A!O=K{Kq&}BlQ{!F{QUWTo`a_slFo_aui><`WiC`h>)`5I;$Lc=)p2xv zeRXBZL1fH(bcIq?x6rnfstV5#p^BUH|I!Wd0+Jx*Qit7ZpSv5hGlkkk{jd*QW*Q(* zo&_D-Asb_iqsOV)U-ngg&dVJKPp6>$SZaXwfkqCj#g`fj(2GBw zsxg%Kffk3k;kUaz+}khow~o}6JSMBUXl}-zoLtsaEP67aY_C@g?uvyEcHCdFL*Ryi z{KtP`ZW-cKojODMXVqsRW?rG|H!4_R5BS?c67cd@i%VYlyI-eM-dh~(9Y>&68{Ru^ zTDJ^tHL1dH^5@a<{g-{cLZAs+?loH%gtB+7K0dDQ*5k!{WeTDQG%d@^^(HF%9}`qn zCOEWpKfH;Ki^5?ExMzU$G5^0*4MVIdS0c2$y1n*XZrh1{%0t;ev!SRhZ@&RUHn$Pl zGIPb3O~x;jasr1|kpHp7+QCiR2*~c-$igC2{$#;`(tvPs6nQ45k3+hwVa31|b-Pygc)7B8pu{4Y1g-s@65 z<$CUpWAFtDjx^wqB`OG`@M&wVIM`m)%w&yg~cgNn&?7!v@&%$DjTCFJtXyx0XZq z2fmJQDm|vh$@4#I`U@QzTNqhFX6oB(TAUS&^|;)WG~Vl405q6Q&VRE#tw&wMMZe1H ziUL%z`{w+bl0hXR&hv4e2I5K~QFob~x2j*%SflnQl>yB0kcK44=fBcwz^w);*oEfR z!Sj+^(b@aCERlU|eW!3_%*MT2at?nd0jU@IuAlEsY=C9~mm#40+vVsHK#B;F0kRpz zi6zQ5c;xnmB)@;`f?3zzT^7i%ecB_(nhqEJc_on1xmBmd3V1D5UOvrVUNTr5=qwVN zJUR|GmFd`*dk?5*7*SXs^=%{JWb}3lzRctt+y%{Unwd?O0xi-&2pIlni%nGvB2zO| zuL-DzB=SyeC`Ld5uY$*AK~MNQRFVHco#F9VoV9%w1`GS!ugq1nHNJoQ zNeaIipsFav@4Exk+on>-o>*+JujP`2ksR=c_g-0AogC4i62AQ>ZwmZ1I3uGF=%R*8 zefz8$l=ES?{1Y)<0EIeu_O>tF+q)9b{FeaGvj_mpA>tSZ$QB~jYW$xb0Z}ICN&Yv- zE60B`b+AiIo<|W0zfk?Ysk$^?sBR`8#)-RKxIWn^xHAO`I2JsfFnfC(XULFrIo*>6 zN8ON9d=lLGRs^pQu8g&-hD4ki6pX5rr>eGtv80$sQyjcLiKYK@>>?&iTn87~=7)|o zGC6+r3u}&FqZhluTRSg*WM%AlUEL`Pdd5w(cX=5e=@~Z8+q(8!*$VD?{KVt)z#2S) z!;l^&z+oxgbQFld6bkXmE^*AWuFsg-WeD+XH@MX74Mva*75tNirGf1HQ?3`FB(p#S zsHzG0vky|01qpaq2+(mO=WUA>*3WJt`mF0G2}^2r*`BRXQuy55T+~TfOddvE8TeD# z5VmsFp@%?U@{q;U*Yk3-kYK7c3E0kZlf{IP@*zIQMhC8Ah5l0+^`C;R^0W}(F3*v@ zE%RpT%^b(TjCM|tJ1xXW(E4|Qll$3x_e#mwVNvXE1;Y2!cja>mYfnJLPd>eSkPec% zP9%r|^~ik{|N9Eo|Kk;agzz3Wj{l0^$y>j`&GhB$$8Ifj)Y~j z;#~^&_w2L6S{{<)O} z_X4=c!xXndw5fFkSXc-~AQ+$;xXY$>>wUKOkTCdF#8)f#3{ARonAr2-yXX<76ih&i zDTx-Zae)#mJhE@g8T@X`JV2ETO)~WHkJbOn?rMN_5?J`FhN|}U7nB|C0)wz<08=QO z=XGf}(w)LqKcwS*p!>8iQ(oaygS|`v7Kfz`0VRCVbjd3|X%T zl^B`%k%Ox{jBA<&wRu}Uq9~1WjTTIb!J6;$v*zBT2pNGdpegc<338vO``v$(O7@#o zD`x-NIPqjp-M{#dq@q5$#l0|NOSJ2n@mxLy7l}4!LY5Bq@+5sCUI9R`9Fx4P5{eZQ zjG&V~2AwP8+_3&E?hiN2kWdGxOzzc7BhQ;ZkiWE|zs1 zE|xwRP61skPJtv2k_3)0oeYRQFmzpoSogcl#eTAX@hD3_h6!ZI)sIbCf7G;*>o6q! zPV{j*MJ!05y&i>R;pc>TRuY1$2}GKx7^o{cTnR*j3br(b*(!ZNo88ml1gIx1DgMAteue^KE#3wJ z-`hGqlGo;n8*sL+KHfK{X4$2NogKBgc5Z+MRyj)`FIcUUTeocf@?Xi~XQ$kZpzk zROD53k(gnd!iufSFKwp-e19>>)A()eMTN(~Nw~v5BS0Mp)Hxmb1nAns!^Ze+X2xck+CAs6rdxqxzAS&}EaO>k z@YhBFp{kXA=4SMB`26lYw-AndfJj{v0SN$PX8SnT)Aq}4&CVz&Q6W@->%sq< z>$L%{ca%H32hknfZ|1((DtD+~#fSOfGbvh5ml4ut$-nGj&g8M0?DT&EriwM)9ZR5; zuzF$sA1;pd51OD_=}0_4ieG#}ZWW0b|lHnF0IXH9m#phey+CzTdMICT^U)oA@F=bOeTL8+_16rNs7B>ZN zxJv8e<@P9|S7gGToTJ&4ewkwak5EEZI_X*_@Zehog$;xcmj{vA{VjR?xV+KHUmVvY z>-2+6eKVDXyVdSRw}@I}Zssn{@4v4wuJBAai%4DibFuVH0V+*1r|aLwx@1*qMbO&Z zv^aMQ06M`E0xY1ZmSBe+6isHMM98$YP3U2{eo*>$w1OZPU?PzNnf8V~7bPQH#F4VF zU`CmXr(QiN;=6jf#f41nZ>1X>wTwrn)|pI(We2Z90+4UnoMzzG=Fzb~JZXpfibo~*mEVf;$Q zC|g*Jq7f@U*j4?05{ygII^xm3m33b;)=!)sw$R{ssL!B^zg3r!dBgT{0yq|Y36@Aj(5G=99JTsPZ7Q5bNwn61< zwEbdJAiP7^?=wu#6Pvf(;!%w;6i}!67^xkGZk>6tEe!U7(YNn)6g>)pOys3Wert1U z#c?DfZ}$O$$|Jt648|12w|_&zOiN}0j>}%oTIM5cdL4z5gfT#K2Ix+KIadb zGGkT&!kGmyHn$HGCpAnUn_honyks;~Kr$K~=v9f|P!huCfO(nG`J>L}Tx7A_AiiPz z5yYKcV|o|d>J*gt&S7%La#tRwb!o!q=gC7d{lFjq9->5;)BWJx&xrwh2n|}EU8$w2 zrEYkzr7BA_>qIn_h+thygvKX&pia)KGdn>q%3GDOxjT*qvM==GyZhL#<2R#QPmZ3- z)OOo#ck4DIL-WNY5qp)r#)1i(?IIt} z9_6|T%T2dolioC|}Pc{F! ziS#1sv#3b3{q{J;#h-D}3YOqTdT+iG+8p>Z^l?Wlk1dv3jH+P?^*EyTvu^NeF%U`g zwG}h@ViG8cu-+!&Mx%GQdHxb4x%Epj%xAMadL;u|mibR3WT)-m{%TsQP$-o8_n`1v zR_rb2b8@~yOS~fT7eMu_X~)eWT)O~qan#BU-k}##VVHR$R+b;(exgvj@edD#{6O#F zyt~+!y9;g?mztdbr;TmitjF9Tfbv)9@NU_k_8B2#ib*Y4pCbH;hJKTpW@V?0Ta+j%mLc*+W*`i;Z( zBNbjwZ5QMlJKMX@;@SuEUu01PJdUzzVcK7cy{uh=7NvX02zdrRpMje4lB!F4oh}cw z%_Q_?xmZs5{>-#M1f!sp3H<}k^OTN;Qh%zjFwAUOC`nhT$8j07ea(j-e6wJM+Q z@x5?NhZHYzRX{MMJfDae13lD1}_08*LzNtY~i$1-(-NF@=BYJiRUv9$?Zx{CM3l|IYgdbv`-VEO&>e zNCDlh!|u<}Bx z10;$-BGf0 z<%*sqWh5lPZ-@N_=GhNEf_KO~nU_IX%=3)FADPC6@+Xi>c>)?=sN z+|uKJ#iS9|ON#)VDGD2h61B&c#}yEM>ytmvsK15?wdYRDToK*I*+`xB*jrG|&prA- zj_=Puhx5S@i^>#2)t>o+6PUJ_x{x?8kKL?@_VykpuZ z3Fb3{x3c?k$AtC}OE}Q(#Rqmo=3JbDpqZc+V}uiAdmKcXs)zWwHkkCXo`lM3WMlLx2u|au)P(V)k;H z_eMjL!buy#f6j-tjxG;9*ZI<*(<3JLJf2353!FF+C3xKeVJU)21?q+3L%h~rh+yx+ z=L8u4bSjYSuTY$T%3m74M;E^mHab=eD17ln_|c1;45vHaa>pbhKaVzW@N-KRBC0$F z9V%W6Rv1)}byPe~&zTni1B!^SN7mCdQbbqF9*$ba3y}eS7&4yZHX4_wg(RD)ZyT^rAVL}oeNEN( z`kh#h!;2)$os(J|qfk+o@)3Oqr`_;sgeen02=D0nxgVV@Qyg;{O`9b&(e+5UB$$zi0_hMK^Ui$n zWH{aSAmr3!yn8d1`|JZA^?|LATH|?%9e`OzRGw`LM1{mpyd;;9j6ly}P#O3vM@Yb% z5&T`HV%hg*D>VTnlAfAVM6GwITUF*;kpi)HOX8i087psrvuIWsat(eA$}8+0X1~mo z*^BmisV9fK=pcvD#^HcKg@krjiq;WLns%|ppm0=ntJ-Z_3s%60!S`^_!lQhC2s8my z2NG<4xGu)~Fg;cT1D@a1lM$)a06nqWqBBoA)c>>@LnTsX;7?Kr5DYM@L(!=dXzVMr zwY7O|W_bMMz_@5RP1_kZcph1O_qX3+VEQCsPXaBh6TpV5TFo4cjYxuES zvu_PTsCjsM^62*_a{u(4|C`L`HEP+kW{5@%+Y)UndR)?vhnal+C8kP;k146EA#97D zT|rPNx_EM0QYfytrg(rfWUd}Nk6)Tox+f=ic4n9pm7RqIw8hE-8`Ua=#n;e9(?z2` zBPLsFdb&N}IUjai0gaK@VL4YBF$9l<3W1W;^uSKj8d{OM8u>+dTp$ntpHMvg#tkIp z&3jgU3Lc((w>E|4``jT@ACp7ee(J){y-4HVYEFxpN+~Dl@5ed71Z8leDk@wY6 zrA~eRM^hyGi|{Z^d<>*#?*%=}MA2C`0rRApNVg#7VMXeLqKsL?o}Tz^t|&SjN#D3y zNxNT7Za#0QeJSW}J>MX;Y5m(&t}WgoSgh6$r!6m^j^PMKK~(uZ*O27&xpqV}k(N^9vHaHM$!WiETVplFL~mrC@G2B{Z(t)q zmg>Zijs;NMJb%TSs^^TR(Pjz?O=ewVy_5D)kD&`DXf>k1i$bSTAB&A^HA$5u^hR?Q z*nP=j`kNQzHKKBLE^o?~fi+BdzspBgG4Zjn#%MO7JzBSIw3wuSQ014s*m+5)&}$3Z z2Kd~&$_xMMO+Dj`xRfj~7;N4oeT_7X3Xm#%zk`TLHz*khAT}3JJMNBz080x0 zv7`;c=Bq?+>9O($0G=3wLaWx0to%t3nG{#1!$T4Ly+nn2gA3SxlLJHZe+^H-f@(ow zh<@obDh&-9lHz>9ty!-H0HHV^)%gpg$UaU4C_zIq3YBMlAdsT~ zyXf^maQ)3p9MLNs5^U(jOt2-zhJfp_p;e? zYfSI^I1wUsh++oMOQRrySM;V1nB;uXjf((NO#=ckhCpC2RY17}duxWKQ+_8Pzf5805t1ZIur(6PNZ zMS9zriu45Roi6f#PX9n@WNdrk59d3$!nzSdjOys=&rg_WVn|;Pc>cEezqaiE8a{H^FHL8;&wVri}5woQ;d#zxn)Q0h$Pr}9Fq1!tddjNnC{yidJ`idf*ajx zzWafw{8X-5pY0&sEdX@u8GAHrwUSV;NTE>FA`7gTPU`@lCD{2VFjm2SI}E0a`nI^` zKIdYw&b&-W`$SY>mFvW5jaBF~TnKY~zun;)jrby}b7D!~{P=*#e&^0ek{HTY471166F`6-(4r%%Bqg zlIcTyX(o<#j6xIar0MZ?-%gTAC7VJW!Wp=P>e*1r!SZg^7D>y{mp7`|jzT7e%uLuC z;6dM))jDm+ggJbU#C1Jd)CQz<^2#|6CR5#FiVLp(ofO(G$6_`%*CUY4a3{6P*@+W% zi!c07oYzx_l`<8IwrnJLypETAgoNyc#6#Wog*dumi-o>D@hVvYxM=;&>rmEclr86$ z5xQv?^Xs9MQ&(4Q)J9`_`zrXghTWPkMOklL!pKBoOllEnPD{G7SP@MoX~4_2pf^-Y z?1@zD5wKh{iDF((l*lV8+KCzL#|&IxHGxq=r{6QBBKGQT)6>nzgY4Aw88P8v>K0`< zI|}Q&W@kqIv}Z^UcUP%jiG=OEEGz_Q!@HOp0YpaK28p9|Xx546yjdz~8~`*+(aOSh zE38pdz72{Ky_Exjre%P+9att>g#fY)FaZcH8VXGg$kNqb$mo0w&=^4~67fiBj}o#E zD#hyW@8?E4TaV%(DvF$*aivB2Kf@J7(5?WojyU=*N z;LsW4VeDp66afXmj1#DMS{d=dy>%;;1ZgQMO$KL1Xta4Lu6}rUCuYZL7*jj3$tO5bN+9G)P1Vr#k z>&KLokL*ZbV^XvD}Zje?7m>f1b~l7!C=O9(8(WGv?fh3d!f_XW#95mhcVKe!1Jl9 z(?9VSSc}8}U;j8eJQ$on_xa;ZqtqE)Xr&Bds=t3zAB$O##{EF>-rFt-6(DQ0=>fwg za|}~x8p@kKV#9d$PTil2N-?OG%KoTMFY+aZdvq8lLYcWUQ=|}YP;Dw^-RhJUKs_06 zGl_2$>X53cD#~Zr=be!nhx6JkO11U5R&N&90D;O*4AuEH+TEc@Qgxy$o-{54=J`Wg z;A0kHAm~2WcV$snbSbM^3d9r3u;#)`D&Ke*mx{g-)Wk8DG9VW0{fx{cs<*Q}{>g^Y zGY^=l?AFD<4E2O!jOs(0-r|j)OHx}V#z)TJmEJ@KH{jU*W3ja|S7Hcy43@{DlWboB zg`n$;J&l6Y9@NdN7;Mq&F1wC|)#<{A#33KHqYD<6GU0!V4B|j!z=AZH+Ldq2X;j!W z$e+efS|I_+#i$a}cVxRW1Tfwqb5zaaflqBK4VAcK*&;#)5JU}fmN-75=y6UOP-sAZ zHgFu&di+y>vulJ>5PXs!#LTuN6=aQ3N(dfx-eP@$;;LFz?*tq$q@1kI0?P|%Iepm142OPSEVPq>3-?kgR>e53#$+X#tA3$#V+!s{q| zVuUQ+Y>4wg%Agvck+qWJwfCy#BFV~nBUBH+Sb@+!Aj5fiAhyhnJir~N`EIJlc zq*^Qh?;b&xE2~rg9FBPSYQ;ZiH)0?#8ikAi)}<48tSptS_>#pFp`$YVIT?@RS9H7Q zz%FNdgUHRW_-xW{QQF1{qqp?Tq=q)BRiHPEh}43PT%LhKG8~H%2Rsm1{hU>^;&Tyz zBl}ODsHQrUb%lh#2_*g?1wknlK5je1 zdMZL6#vpd=1=dW`rYUk(RS{pLH?g-k#zd}oGZ_~1KC)>`W+IeC8OCejnwNB|m|s^H zd(w#7Brz$OC~su&+VmX?5eVm=tajMq_t<5?@C;nnUjQ^r!Z+T)UK;7&c8V_mUqO@C z!NxLtsSoOmYqWMM!;GIYLK+GnHuOp0#xcX~_=TVQs{E2sM8zThF%!)5{IfFtp+xGlGiqu60D2arG&GM6B*MC&AOt4!&qVb=cJ~<)0Qan@ z;Iz{Wmia_l{Mv4*C4~&%-|p&Y2{<4%OKy(rUvBrNXJi=I0R^Wg<(dC5qMtL zz(vo1twx9!Fp5yU7NW?`4OkG1(Aq!CQ-HaOmi(p1HO{){eM>gkwVMrqEnXqkq6Yv| z9%+(0@GcA<+zKT&;G`mv&13-H{%=0vzwML%ynXcHUEG6iPSK>sc}`IkomE=ecL30Z z9}R%IoWcq|a05F%i=aT{JSO}15(x=6y8|fHV2LF?#e~yv7$*8d3LT3nO_}${t^gYA z$t&RKwqkJnlTZRa6DN@WHv{(nrQ(nL*+swomUZezSx!KpS!UTL+(lCQvqzreeTPdb z2oO?Juto`@WuG1&eDO=t4jAY%e1HHO`yYaCkg3DtT8Eh5OIA%_H_co;&GJ^c&S=?n z{hhLr=rsUlGl^v;1L|?4!4qcMRJVVm!q}%ltT7u5#&|Q6X_Z!y;!R_JpB1Wn}CMHd$-eQ94Mu-n9Iw-G+x_Tnux5h^w9SIWf z_ZGMPfRqR8>9VzuMRuHGhv7a*`b}UKz}0qn-Q~ph?jwvX9sm_;RvRq!q)r~e#*2<^1u)@f2h9Y&0E=2qgy5oOrE7IK_e3<|qkJo-tz^}V$kGsO2i6-?I zXG?PWYl}nz>rten{V!j>crjs)7R&ccDw}J}{|IJ;QEbndySnPt1Sdm*7%bPP&bXI&54@&bE%2S#zwOStfS>83KWZ*Ib~$V3(4D$=M(FvDul!SjM z2_wV_eQ~_LVqsxC>l3(MB*@8#S1M9!g|$o_g{PMsUa zgMnbP*%?(9Idt``UGb1*X3x{%IoaJT%h|0##;X?~=LlhTXNiX22v5>BiD-~BwWJX( z*4X1lp7r-elfAaGSf^4U9|e^2kA&QnD0stWm}A4YirjD#`H(xVf)yjoRGabfK`~N( z*3ryM&s`!2FL@%+il@1mG=3+S^aX%iWCd8i#>?YwitYMWx?yiJSuT9Ez7P{^L24!z zKN}~fPQTW#_K39;E&8f?z+|ctm#N5!zU1vr5rp;azk1BfW5pXW!erz%PA_uz3w?CD z<*YLXQrX=6nJ=a@U;nAR@%_W?WSlz4vzgp$un8m94B7_@4GJYg{X!gRkN{~P6vICl zO)TW1wX!oeRx$)M?^O(7w?MO7;u4<;pYt@KxiT0#lwJOH(qYD^wXv((>oUo{*?lBM zizW7<^d%-WS`XF7R#ZsHH!@K;@jr>GWO!)3se0j{uo9e_2~^&!)vX650|%hOd++QI zOESBd2j4@dx?IGj&>M-m$C&ePd{N&m3(|(%t<7#T`Z|vhjFhQ6kF@bK+%_bH#R>m| zIA)9mWq%}(J(-4($E}HxD0BEqo0Knk4iaYGiUxe7+cQ@WHMCs5sr0$~7F6$>&<7Li zgLUy;+j+L?BSP)H+snod_pcVbR09dNe_U({Ze;w%DC^aKcjU$JN9Y#E903)n=KX^8 zNp(o@yLRF1m(G@YJDnCq=>Xyw`FR(yI?;%_z?H5W9$3GAFtw0sSaQDd2M9R(=eAK6 zN>TWah2~)GC<^yM|0tydt&D686IugOy@z+YrRZO#nN3o_xM?1_bf_K^}!@Ej#N1RTz1eo>7%} zk)DXsR580U-TgZno@54&&J*}Q*WP0b-KEtuuRsoLR>oHfqiG814##6}l9q)>tM;Tq zSa|J5U3TJQ2_$A8twCvotM3s&6oC1RQ` zQNgBeEX)ml#qx<6-xVl?ciL{hmDKTI^Zxn)UPNf=y!NoB6K!gOQDy2cR?%8!uJxk> z^;ZXyFIyx$-HBjbe_Z>^?Sq47gX>gLZ>|;bgu9_Cfxqc7Kr}{Y^v+RC&Ubre)ORx! z-QMi43Ta54sD7g!*{a_7gpz?Q2(j8*8`4^t3SXLth8a)i<9(L=Z=v-45XQ+D+N#3b z`|+W3*1Pq4yGfihiM@^^q2?GW`Uf(_xg^x60C&naV2|*YR`VV0$%ENFVRnth#I<@X!(h}hrL5McA`OOQ7H(YY8Q3vB0BUlz7YrBeo^@a@s|i9 zfNBBOAvo>{umIr=(Mxgdi)$LN+4og!O%4+hWDoS!-ZXbAaBJQ(d$5#O%-we0EBpgf zxP3!aOX?NbmvWF`{;MHuBm7DZw5jmw%ifL~Qb}kUrylxEn?s;iV_fALsW^G041_tb zpsWF>AO~lwXfTL9CU+mPPyDg9)UZZcaJl^1&31Mxx9@X@waeNmhohFNG6d{mgklp8 z!Go+JkrFl|3@a@gSX4Y%?uUrvgX$2v>3~>nv{f-a^jynZ|5bk(@60wgAubpsP6QJG z?r8@@^w;7_h(6zm$+ul`k{dA`aod1{FHbV%f#BdQfAuv z#iITdhfnHE)D4R?%F@dUv7aV-8nbbJ>fL;GPSp3E$Ctpn(Se~k;Yq|Rdlxyt{pkN` zZG21n@scwoW~4Os&ebQ5S{W5Ob7|R|`x4yey#?#%0inVBb58;j_KYjx1Zd z`|N;ev;7@MACKbj_jepMY!Vo(8QXovTZcH1bQ&ZWBN4E|d7hY0?H~(BgUB`Iv)fR_ zFO-gb+u%1l^|8b4%qF2S-7>BA2c2;T@#F$IVzRThHlW~iZz@b~ni0%963b?#&1(FN z=u^JuS!IXC1-9cMc_W=hxU0^Cpx%IkK(Ws!KM zVhq3!#VQWW(#vYc)T*Uk&eKx)W=WBkufl}6l&okv<*MG*)n)N1Q}(f0aePN5CE*uL zC4OMK`v}3bO6JCMZta-qr14ryH*F7@Ai37-OXLLg<@Z9F*<S2M@aZX2?f}PPE!DXabEZWT2$n8kVUCMDg@+{IHvNG z47AZud&|#6}G-mNDNsj6IX!EO+ z5(}&A-+yKCv6t*=S($Rp9;r8S((`;0HKhCUoZlwtd;<*}562HD(bsc?28r=M9SsJM z#sLuy#e%9?=_fsA(0s8Vw=IO-R5Zxfsy?3@XQ#ckYGI_cR58cv?C79lx)gJV`l^H1 ztX^`ql6UnNl5aMjY?-V!zF2;`Gj#psoq|$6m&G@Clk05cWREidkZXSF%UOt zn|b!5X@Yz5?bMhA@E*^4YTy1(62Lv^YRkEEjj|g#7yXuARaTiXsn0Mgyhycacy->! z&`(w;_f7L7Qr6yaI_>YVYA{AsvmNGoemU9_bAm}qS^6unZH{kugNC=3ie`HIcgLn7 zi7r8*uA|sBE;q)4FVo$OGX=n`b@bTh@3IhpOQ|2!jO}6Sc=-X0BfB z%MQRoF_;7^_PQw|$$eEMd;>qzJYaSfyLAU@)WvZNYJ~f}RQF*BoK-+4l2MONqKl`k zM%{@ghue0FVyd+5*v*5Q_h$Bfa;5YFH&tBwbaSZV_R}%(bcD^JZbk_M?5JUAYRAfN z$LW@;*&}gxfc8fN{NVu9Ncc2OuR~msn&-j=hvM;^u8M%!L@_UVix6NnX#2I68kQA( zekDFB0KetmNMq-skxm&$AI}zb+lGfXCQ9C2v&^?Pta9+cF^bSIfRi-k=EnUfH_qo9 zy398gF!wk*{0{aK_$uaux`RJvS8%*ee9^^8f|92N3Z6iuaTt-f<8%gM;8Q#wjVW9Tw=-3GtH5;k$Fbg-f|Am(I6<@1IixYQsS=4Gq#iG)wH9^sy+kPKe}<3!J6w_oDVDu5@gUgR?MZxAqyAy8Q3 z&}9@SWn9kRdj6m)hYTObd7v$?qu}NAZGxyJJdLaQ-jw)1@34w z`L3oeQ+lxJ@^;=?HI61qxT7@Sb;aw~s`eh3r3hhE*OvT`_)4e;yU#ds-6}>Ot z2=v9Ou0Bypyy3L@**-1zo`hIU-Y4Dc=d&!I8-;r>j7~Jy@;;|;ep;|?NT27P*tU-6 zI_>-8XZ42%Ns$dN)vyw^w%#bRf6-rG(tX9GD#1g8Pi5^TBK_*%5*)szE7hOw*KRLq zN;))OSeCXWc3pjx0mdfzM+)gQ0$HEp-FxA~aZXwcn?Sd-A#c`jY^BBJa~8aPgnN{A;Bu*UV$G1?%2Djv-dm;S_Ft@Pc4=E5 ztjl#~53DR$S{n|lu$W!)X>2G+xKreNL1E2>YN(t2(8ZB8bag@Xc;1e*zM$BIPU_<= zT>}z!D%@}H#C}}Ti_Tk$*73$c$W`I3?~yb7+(@9kf%K{RTn&C`ZeNCm&>GZz7A;QB zdL8Zk_`}sVjEgy1uSRiy;<3h7&C!;}<#4>xCd^@ar76w$sPSHa;9=kP&i;kiZk?r< zP+8f8Qbuyu$7}~^^8?#W;ugY%p}n5qfDOi;??0bPaH$JDeAgS8c^9Myn5hyd*Na@L z)C_LiyPr(!jkqU$8G4QdbMk`~AmU3atuey0Q==fWsm2JgSGk zxQ``Q@p=M-Uf6}hjtsc`Rx)}jK&ZmxZO&0 z#lmbSNo;Dh4qi<@hlm=9JgNbIJKd6F@AC4Rj{`{ z!n(Gjm53|iH8*?aKoL&EXPS$bp(j7*STXNt@5!9ZeIk8oH#_uFxgj!Q{#iFE!)UWuR4i(a|Jd0je) z$3F-~o~4TZu<^wer7e^YM|>e7(+W_Mp4^)k6y$BN{WcnKdzycGb8Mf~HIcdWT)+u- znG~k*`G^YVvE@RSCqnV^S?=NqW*P-Z6BQM`^n*sUHsUl9@&t-(@f4%%T$DV9A>=G= z5u_a6ehc0JNH=35^jP!XnZ8@#jWCA0;!tt+swbkI{4|4;_$14b8~Ap7d{7(6?yB_g zSV}n$DrNXGfJEavMLbgkHY5aOc|r)U!8+D=T7u*Y9PPNY8O_a?dpr@r?Eg(6TrY9Y z8+_wB9%|c^T0>3<%f5S(rwa!*3*@gZN;Ow!Zrg5!TUGS_t3LHEHj1f7lz`n=DH z!Y}`;u85ri=lbEpG8Of@a{!4g@m|P#LXjVGI$k2Gqi|8gV|Lp6()V#2n{lq&epDo; zJ3@WSFKTI~isYF_L{0_qL^f$h@@|@2*42$$3og|AtVd-zZ@FnP3v#uMMnx`nkFE>) zTa7eB-_$&y#@xY z{ZrgX*S&!TEH64F?cZ6}7s1ScpySdGN{=hJk)?&M+80Hx!$PkA&ZG7^l?O$YjEya2 zB)%`o>E+WWD^8n{6-F7{I*%d;NivD*H< zErz1K@o?MNhw-suMlLiysP{xC)zg5D6@=kLw0wO~gb!opEP01+31wsmTxV|7-ksBV zKPdTB;r;ZmM|DfMM-)gVR+2cK(8PefpHJ9Dd=2ImI#4YC6uI5y^(i`?G`_Sm-12+i z8me(_De_QJv?)I~?6mwe-_e`@S-#o^P0#+UVX091Aa~jI{dRSo%edxlrd)J9Hn=-T zd3q_8r8Wq`8ifcJJ(ZI$CleQb4G{1SLG*rk+m3(j`cbBt{B-Mjs0IC)>XgbYN;!<$ z%6NMK?UYI$NaglHA+PslNOt6-d@Fjy#r;`zUa z?+j#7VesvpV}%%P_EKf!(T}~268qKhjA!A#D1RT+XDsO5zti4DPlt=u@@RHpsJGX7 z<6!e;m863CazpClk-p8s`_ZI_HnNxiY$!Dm?AqUhTzytbF#n;W+$XM$0uTvcW|V2# zs41S6vpJS<(@jy!tS)aha9$D@+EzO9u4NbsTl?QF3r?k3xDQg%#q6)Nas4cC?fFrj zoXp-sE8(hO>jID;>5&)V7%BOafy6nH|C8Ytt=&1&xxG) zfGt|4|R$PFSd&CM3UgC*gf=mQ} z2A~3QqR2EtC;|8@00;cG>;L}t|NngOe70=)v2rY;6q7soa-G z3Dyk^Jv|7ZMH(3zOkCu6qP2b}&SP+WkS^pO4`AvU=;v2T;L)mP#DZS_=WOQdCn0p) z`er7Ab%q%N`I>svM7k%(s8KQIPy$zcElvXt#0a26mX0iBuO;q?)*90MkJ{D!P@z>i z0!Z0%S1kxcM^!RtX_jksJpHB*4*UQ5KB8^6>S5+i8%uAJh8?ZBSg z!OE|Uy7ATh!**kiut$^YyN?n&%sE}kDA9VMCkG6MA{Z9We;iufGiXuwE&WZU+P+1T z_$&yd(%oIqBZcZ)Oy{V3&h)C&`IiuMwZ@6BA?G%d?2n@!(+_Ap&d6I-l#k@=Qj|6L zZP#XXfQQVYSvjwwBT%Bpl&NCFc&XGPJ7bd{&+A84g(MxXOjrlzEr zkOMC@5sdQ&TF)1uD|6~gs+Kr$XqaOGZqS7;9r9({npwQ1DzL&IS-Mq0O7`qE>s1A! z;X`?1Qu)jgk%n19?TY@9k?mbqG=hOL$cQaMFH0@8yMHmCu?ZDN2;(FHqo_*)5MWQ; zB>>A50#W<1=F#6di`+d*cUcTs7}R^s`rTZxp$O`6fFQgW-gFnG$4wzmd#%qr9|`N8 z-;__X-3Tlzd8$bBcAUjsAUe-NJniX4`$BqqY!T8QB3JCsJq^!-mE(?czum!kd*#y$ z8c|NQqVeJYt6x{gOPqA@_-=Rf;nZT<{Fjvvs0`f?kDU0m7)cBl=#hg|=<1(X(3?J} zaq-hrw6|EmK!NP{`k-d*`YX~4w0IVF4ZneI9~L|!^4Q**n`>Nju%f~+5aUeRsP}BD zq&_6Wr3-DaDWXO8UI%^6Vg|sc|KQv{_e?`%JxMpriO?lmjEo#0SRPQI>|I|CVEss>h=o74M$@PE)D zo2S=Tod)MOKeZStcjhvOcXN^UFt=?0ION!9l{TtFo2Uaj{=wlO_U~lR%$HTIqg-89 zH|FQBj;<#Fq=oCgb>mquI0G@NRxc%GYTbFhLg9_XvwdM8TrpsnP;Mfa-gAFTpJz>O zQIbHkynl^u!9aS?eAuG|By7@#M_CyFIB-+oU-ph;!14OEz3(O%+cUojfjnm@b#xVs zy^RGzSwp@spw#avB_lZ_ACLroO6)exb0|6N@rZRFAI5^_OJI6$BPr-l&l0S~PbNpN zKNOb64qe}Mp-$cgb=5|~~2O4-#=+5@vw}@?v+@W;kj^TbArW7+R zo%&IhF1{TzvMiG^v-x7kvY>Oe^rqE!pp5z#TAaA_$Mt9RmuVH%K0KtrpA77_DYB!W z$2y;G|G@ynpBwBt@jFSBWSww5|2DGgANl_E@Q_G>S(z9foS6KR7gx*#n%Zs38QI{h zX;Z7i@|96WUN82$|LRSMC+9wkAYLE0I&UAJG;zL#LegWCt&I6c2?234HboQ8TAE4k zDw*e{F~)R&&2bN~pb!7io=yhJsqdJX4b-QcnbODXco(<#hb*UyGbX^)puX~T)yaHd zt6+6g{~|<~&+W#DpLrBx^umy4upMYRmFfUvM&C>6x?vz*bnN!rMXZBos;Qo3t6hsp&=5n~>p3&d7PTPGy;bhv- zHnAn|DBVjbAwJkh9{nHe*%S~;dyqcnUSXvEf%etUJtuxx0?5Sks^oI`P6C)RaHE|1 zCcRA3dtM6s5QZ^s`OXbMuZL^Ol2ScF=^pu8po5LCio)^!k*uSu9(@JRhVoOuMn34< zMJcI(bHktSUni*Sx~xod;j6uo?gd&LDdMRBVp=w2mu{R{gz+=Jrtz&n^w!PPl*vNhM^5#7@OLS?dXp%5q7a#Ti3NwBo?nRH8uYCcXH%4c>~pFjl^;?D zHDxoR^oaQ(o^q@>Ad+?n2M0tnD5=L0i-LqZs9k8>7066?o9B=FOfupiEck^-ajp3r~fs#}JHWYET zoBaKiM%rlM?nI=AR<=Z`oAY!>o=}E+$@XyfNNftR<-PN0n#ZSeK_9rKz~h4o%mZ{a zeS5XIyzM?*WM9%#vgx?okrxT8UB`kt|99Qn1;?)PQH4c^L&FNx@(V&}rBdKUqCef8 zvH|Z5ctmS274v^t&(irHoGj7;Ea{o9XY9?H9krti2Z}#>HJE5c%->!Iy96us5Tdb(z}y zI>s3WZQG`6)cNtZHHNMB%lYvkz-KZ&lT)M}n7q6p$0UGOdLMxxlKU;`5Xk3)HC(9G z8@H#jhjVog!)UO<#RR`M*I?v3n%I%K<$Rj5hr{0L|KlwS@?c{>e(GSwz(OQJ%Im+X zX2XTXwq}st5$X|2Rss?n@Hc`V1cGqC;fLaq3=a&}F5x<~OK{rN4vSMr;Ewng|KJ)3 z>+PzvNB=E+vy&t+_d$Mlk=hNf)0dzAkj!21QqZLM^Vsf@bQle_D4gSuUad7fKyqj! zR`<$GPT&1!j~^gQSLD+_ZXdQyBT+u!28Z7sO)#2|m{Sp}H8syjk**KRKA&j5|Ll{x zFDh#<>niLhnV1Sg+yG*x{!lCLwN=n@`$smc3-_tIk*M7NQT2`&N-vq%gy=ui(R(dH z^w_>X9}M2%gEIa@cTI*XV93%lQ;DUo|5rnxz?=Q1(*l1gy97|6aDA)i-!D{sP-6xA zkC=`VFc37&e{fO&A6oPvj0XN+JiM8n8J=@jV@Bzo5-n2vZ(j+3601m;^eEdH<(h29 zCe6|+YAE(VPA`i)N$>1cmU<^|DfFSMVb3-T5(B<7}gt! zaS%3MJ5^aJ9Kg!YuMt&dKd-{g#=&7XTbPlN@!Yg0Q`<^#puL?4rmLqHM`r5k%KzWB zJxSk^MUP2oYinmY1H2)^@vX&y+P>i6;OF|!pRaUSKX~w9e}8|Jn1qA`Kb91r-gTUL z>d)BlOGC7_zyApc@j7tjj_&U69_yNH3NI)qh{cEcHZ(Lm$0;i-1CVt<3{KEQ{~B8k ze-ucad#V8c zTHSjJBiy~Sp^VkDpY+}N*n#a!0?hkx#2Q9;8 z{wnInz^x-CS64Ip9I3ZHS9R|tNn#SsMnzv;Z z{Y*$P^m;!B+txc7hZK_X@>-grEawc1e+pI*1i4biEH3cGEXrWFrB_~x}7 zxjYRPSkqIpaZLLp4C3VBg(17TyEkV$>ms^SRhzP0_ZJIVL4dTZY#^e&%*D}Y<8DZZ zd^`;ZV+me7-3r%MoNhHiS$#^_`5eO*8^gJ-WE;l4hphnX`8P(+E>q9B)k;8 z%V`sQYW8L;*Y@^ z7GV0ZqN`_kEsa0}7hdH%t?C(B7EO{Ug2S%79<5HDU$1{+y<)MQlASKu84L6PxgWBk zzU9sp@#4h`*-fTqW})mg^O+Uy{U%98#vr`C4*>J!CZf^0dmFP%UQ6pv8|{*heQ<8M z+EiU4Ei~TSeyXTQ4d8BLR214428;M&{3m=+tsc30&JyzffJ}viMgK%+g z$+gVhsTD&yxla?a&wIWdA+8g_J}_&$S7Xx`8doWxYd&A}K{?%LWZY=Z&{SUK2S*}y zNAb`mb~qgFwQy!GK_ItCVCHkdG3k8T1(rh~`{ZtVU%o{oyZ04>d=sf)w5WJ1-*RbJ zXKXp(j1KQ(6BCmXF*vwk-pR5<-6(o! zm5!wBlQFX_S>!az<&rXsab1%(igBL0!Fo@$79e{?@9xcK-fg($I5_HhlGYfI%ZHrd zDQ5=>L7OsS>{g|#e(bz+u#f#5b~8U#EUw|uf?Tgcl0NEGw`3p4GUFh5cuFGi{(zS!EzU=ck7Fy6i$ za_v=dz9gNof_pRZE2YT}{wM;WgC7w9I#S99B&#Zn?A8znl^VCx9F9Lp%X3=DsuPF1 za)T_r=Y{~-am)pf6YV_eOWL8fpo^|Hlt@?)HRZw~f1OVV1~`Lb$T_jNnC>r%wwBUY zUt1m#=>wn7sp7=)M}c%+H@*I~_4T{ej}-(aU&}j(Oo2@I+2*8J_fPH^r@h&v_(UPO z82-N9jEbWdii>#A(HoBdjN^ygA-hhwR-nXQZGp@dy1L751FbWrIIlia!Pm@UJ&v4> zhF{F5SH!n`dYIY=Cj{HcN5_XR5)%zQ_z4=Yq0z?_{A$a-9COUnSAWZ|BvU76LP7#> zXTz?Yt+x+Q>d~%i4Xs={l@I{|h5N|fPi96-<@=Vbd3kwNF>`liKImVA88&|$eck#s zBo~i@`$t5X%Qi|{;P77WI#IcyqO$T`BD-|Qb%gG6(W2n)#C5G!g~A-7jL|#ct_&qT{Q&ty;-MgMt0{4cWi8JqZPRHrEg6-%EjOe&jF-!QhJeZbDsLEQ%F%v&5TO!=EU`3TnC*3lH3QrJ|%1LIGnco}uaC ztYI*%lD&J`4u`GKt?Zb4!}z0kQ5SFtG^>+ z9zb?Te1pdefp(_j&zK9^==%8+$VOJ~vpW1XV(1}#Ox?H-s*wNqaQQ{s%<;2-I?gMI z{OC{lqW)wB50ui7z`|VzfK=+=g(Z&U7t;8~b7|<0AFo+wjR)WH-W}l20l+IFB)<)V@oTW= z$#Cr@SCCjwpkUE)!BKG$2MVO5b6No0mK*I zlm*w{U7M8eQx3w+DgcAUCQ&kovY127)z{azb*4V;!WH~nUIIz&5MtOuUVfkpK>1WG z5Z>sJ&Z$xXi|w0-@@?iLN0R(Ob=XjA=f=iHffLZfKS(2oc@@c;f~BX`y!R_w09_40 z7yBbV<8g3s=o7=5(+h^@ngOsyUvDo%%j`8PqszEtD{Vr@0RirP^}%;)_Sp~eC|ZoS z$OK&r*+c0SNIJW^z#4%tTBh!gv3-O5sLEIZs98^oue}e9@vvuNX*G zW$uYuiY5sY!Kf8JN1H7TyDUS)bTMCV-W(0Q+5<3HmMe~#1m9fQ-Q7)!vO%#IKaZPC zG-G#I=p7r=TQ$kuS!-f$;~vK~0_duJV{_gatIw&g)5~|=Cmy@c%v^x2Dvhp|n4FlH z;AYpae+NWGe#By>WYl-Sv?1i~3C-#1Ip5D#v9k$SQt*>~Ph0nIzCx}-7m-LL?Y)+d ztThj}0XT;t8O+Y(1YuaC9;9TCD59%LFDaBr7k{K9ij6! zbhsF+QBs&xM(SFb|ETOcipvC)3$jQI0)Xn;w`?vAJq`DY@;KTBE2BN^z{C?lq$(#T zw-?mIo|kuJ%$Xl3rl!ZLj`deh3_i}^LQyIPf8KVRTcF2`8tjO9h2>g&gNN za-~{_f!J;r>@t*==f|rvabt~dNR`ePJ0#p@^69WIVHhI*LOhsUnjb2ymn5&(-@zFh zx^X|0fY%|Ufp)xkzOU2?m5WqdqikKS6LYvAMv~)n6t%8V6cV%LlsZ-{v3mE8C_KZj zMwj6R?%Q>ZpsUcL=7t9D_Y{wDs$AmX|Qr~xuFGczkZ=aGc)doL0QwSK~ zwV-+5=+z1B-t8hK6))Zh)BO+=0b+=H}+&DPn(g0ag4iEj@j@2$vML79Gx9LJfEsJa>|n2`=#j)Lsc~xJiGx zcxdRXlFnrUQR#}2Amq2Hm^1#TyREfoWYG-tQ(-}qFg^3WAyvP)+YA6ro6RjPJdYLO z17-1J)63(T{8ui3N`>XzHVksqg6%!1a6kdq&tt$IaL%amMGYpoCdPG}!eM&+F|Ip( zK~%EG&)4d>PuwrUEfhiDYi-Qu)?>eqzd~4}rlzOGvWw@0eG#jfh91Yt3_QHNDCD=K zkt3yp^GtRxh)(D?O&oGoW~@UU5I!S@$v0J1i7?D=YE2hiCWYC=wi~mtvtJKMQizp+ zjm4eN#40!}j6ci{GrxfIgyC4%d@AL@B-`4Xmb zZZ73EZT@oZTLD(L7p7ZZJFlN~4TLJ_QRJ4j$+gUlt0lJ^V#wkX67E9l4c84RD{sK6 z74x2`o@>h1=z;ot3u4NglUy-6enR@Y-|~-g3d8jZ zHlFVKYCqW<5&!+5rDF3pUN+skwQ*2BSclLJ7#h-i_@#U9lk)~ArynZbeXnzEEgK*` zIu7imAN2cvIU6j<^;hVz$99K%_JZ5sUpXmC$;s5fQRpRw8J=f3Jw^eOAq3A4r4fPF zL%xv^!%OboYUX#0q!6p6pL9MHr%68lb{vZa-M%nauol?X^4Bb232xPJRgJAjxybpU zh!Q$YplWJrE2ZTT)0UxtK~lceA8>l}7mG7)Uz1m8p%mg9TH3mJM$<=@@)4oUjpkRj zSsByp$k%b5vuYm_&ex9RNBCRToD@!1*^U=7f{W0)PAAOo6={^(OP&?=#10)2_)(X| zPD&~c<_xi~sK_OAzTsIXL&{>jAoSR%0oy$6oh;q{VfpO?_wCk1cP5Y3W&1P#9)zyh zmuqd0du#sK@CHm`bl;sO7;&zyA;Ni#Q^*hH-(x)Z7|2iY?Sn?Z#Q0cw0rrxSzlkQh z)pLB%)}2+C#Fgrg3ysGhVW#zEF8+owg)N|EDd2!j7KVjg6R%b{3h7{;>Jnl*bvQ#H zvahGL+U9b4x3$zsi2P8BjLgibm5q%l5p|1*ZwTuzj}o%UZJeAKuquWm_BXoH+&M>D7f1ti~gyPApX4qUCsQK{xp85JCnu0r(23MVZ$RrtD(s_ zE4luyNR3hRFXeK(Bjo0Ctm_L2s&5(J0#Ae$r_S21VxV_@&ycb}j7Y3jabS=UBg{|f zsHsYbo!LyhQQ~}HzQEPPSxPzb9vpIk#}jMqu)N$`U`t;%wpz=Hof*hk{ES0MzC~)~ z;=ohGn7o>6pdvF)zDMdX;0?bQfNFAB{Z>RUGLspla3E0h&(H_>WK37&tL^OtE)O4D z49yCCw|s>qRvWOkTZ*Ihq1)22h2PBot{+O0A-WagX)&$iY5J$_z=DTlFO%Hge@ozRS{F>YBUVnvL%{bACm_G9-U~at)eYpPl zRva0O67B8%Q_|yzLd0id->oUxhfV*EWTzu?zn{W>I;+>0k=%lF1 z!*gGmamhbQ{ZMG_Dy_j~ag9Fz85QFXqNEyHiKwRa8LpMf2YAC3;7(!(2a;gE^?8F- zm%W<9;WDM|$Ps+Y{{7hQBlm#qp4hw6A+*vVUyc(tP3HF{tfqf$nrFQ}GQbq3a#;=g z_yDsoY5je4IxduJe$7UODO@ZKtiCH51m%NTLf-~F%HN)h;%BEd0VGFc3t=iUMO8J> zE+#uC3_bR}%*mSY8eORLMZXiX5mLX8V5JNa6D@H0*m}odiVZnf*tbxulIq)A<4*vB zaejZcd=e3rpPw(9re)PU-DF3Z#U73xW?1b}^Yb zAHfF?NK*H=JqWTS;P$jN&Ljhi0g;u(#FPOGdlUeoy>?wG75RUYH!oJ(-OU$1Y?{X#-P+;&z7^r^4=HXSi0prvtIpn5&EfF8!wL3E( zy(w0@>3Z$-7;)8ARY+r`PH=xVh{5}^w}@2l(BhYM!sr}8t|f1@GOU~Met6UL^fVEC zZMC3e-hXF0TI6&=sa@Y?Zu_~N#q91zWY7Z8ykruT0+dtpnwp$>3EFv@5LvsIy%nX5 zImnOF;t)$=#h`4bIn(!(>Hb`j$~~{FJSZ&ob-XMH^4WYLKubXt)amTis_ln5{vvNA zLmFAW-Q5UQ-%z7>64LBsWZ z@Ch|Q)#|;a>+CG(c_#BJ>qcVdz}xZnkM53k8qZWw2uiY%Ky4ecqx7<9UG1XRH&dQ# zZXbBJ@jw1+b-Pq1PbGw~ewM%}mY|h+HP)s`Z$O^Kzb*JRyq1D0RVs5k^-z zw`^oJkM!oXvo;ZaJP|P^v1@eC8q#0l2FWL_j~E>B%T>kE@ZO?0Sl@WW7D4fbTQBpX zEt`PL@=nkJtot{$#UO}e}ld=&V;L5U{gSwzh*ZGE08X8rKbdz}2<6Rb%V#=%*~4U6A?z2>{B9ktda$$)vvPtM4?KKx7#(!vrHE zH+AGcDhI%8X+Fs&`d0g`fIZYT(;wtD?2bat9;TW1+pad5Jy@1;d0u$D4sHfLdl+6X zZV+70JIdJ}Af+@k^v;w~$bPzCVc;}V%;buyjWgh>qF_!X3`AWrAoBpB^h2~`5D=U; zalNqEjz!QbG}7wVl+N{=q@-8IpBZzka{I*N2ZZ{liGHOfWk7#}I_w=Hpw!1}Ub}2t_TOfZ} z(t~{18j25QA@O>S4@jCM;zv_4=}oCZu^v$rrN_HFEd~C}1lwDDF3i_XtDsHRUv#9r zMIq?Cf4G@6+7l1g;_T5valchiXseETKOY*emn27LLJTiIT{1l5G|P$MCcJpIvKh*6 zQJRjf{Hw~Rqf9*5BEuT-MYpxyzDaR3_4IcbZf1Br56ty!AEG>!fWnkfH}eN9 z&fZvtbYN$Tzm$HBGWMwVmEY1%WsX=&)e@>^9xpJwSg< z(zyY{8R~qTT`_|76X={avy&Y)#QcS`GYF8aDwc@9QP)<>f4&K^ivOrnxnN*mCxcu% zWa5;>1M0Wq;Iv+6s9jM=PPLZ*xDl}$Lyj+b(*xGMw7h)Q&9#H2B_>pyj+_a{o=S6Q zCN6Y2dwyO$K}p?XKf%@7I`}Uht|%I)17}--QZn&@KMQVBXQUpbivh-|u4Ov#MHyw9 zS>6+Cis{pKsoFX_ALsPp{sfnot*@-8HM5`8TFxyW+2XCEnV@tdsP2@9mHxp7eYLgl zA`SeXc~AVMvl*ves`{ZGm=tN;qKdtE6Q6*f>?__$m97`9DGHvX>(n$f%-Tdi*K_ZS z)#g8p9{y>Xr=v;c7urC3<>a$ot?|`DrR0nAbDMiDEkSxQwg#Bq{t*4X`Au)UMTh;} zU7oY=n5091Tki7By~FY8>2N(t8}QvxMy8P>@um5c?z!%6<Nbyl`7Kv;qkR+e6*mK=>}tH%_k2&YFBm zJnOGZXyR-`gLE z^c6j@cvt#K^BrKf?Ky@vD3hsp+RFwzn&SIi+>oue*Kb>8A{ovql(N)Wb+RBqk=tSNEZl zSWaJQF&NapSgoD&B%O(w`Q{sm6+hFw7Y+_Fv`u=HNCV6dp&iHC?d4D)M8EJ9iSaIb z(@LK;Bg8BnvcA5~fb!y6SmydZF5{tCk63LlDJz?|D^5_l=Oh;2PWDD3C@AP`G&31V z0!N=00{3Gn8VR#6DWejas^yOWj2ZzR-SypF9gBg%uQ@rk4i22Lz`fCQ%GslL27Mrq z2t)z{r*V585%u%lx z$y7(tSl`r zdsj`j#l|!2S!MXv)oB~%3`|z^mK4xFL^HguUZ;YhlCK%R{OPF|pDcJgy!3e~HKi^;=Ytp;7fMq=GHNW%e1Zg5Gp-N=sKOkV321KkDzdB zpA~+qA`R1^EXH}K1A9U3I_HTm!F33cAcvCf<>g=tzJ7Mu&Oyrp(E$Foz&K0_YV)sc zHra&)r22=G!~!~>6}J%<+{GJj$8m_l4Fp;N80uX=oEOFWhi$X(GkR`n_T(wF+Yhne z)>*rb5Y(`s;`rMV-k(NL=cg;B%omq0`|IwUFdaNAA9cz0%9o4f?{()}baE&wOW#}P z4~k>J6&u;URmX}uPW9F$uw}|9M1R|buk`|*924lM>m$7Xr@Oa~sLGCX{19Mq+3AgMoLNniH*RfyQNb=5Kua$8|mKPLV4cbbKdj)d(QaAcMo;TVDEdc zd&OLH&UMY}8n;QzJ@=uQsu9i@;`w_kxcUA!CDS#BCxp4yJ^*=te@RGd#MKmR>wpQ5W`hJZ+=CLK2z@G&6s!rYT{ZU&+0()y+t8RF|2M zHa_>~6NY^G0^gak%BqOt;RPQ6r<+*H#lw`;MTh{@mhZZ(t` ze`qMN`SZ~$^C2uJY-AvZvFodsS9||o=(%(Koc(FDFJ^}enNhzQH(C(-naY--LevEHSlTlMjv>#KBx{A+o44}y3#}zk zui=)<*yjAuJ%tG&ivNk502J?!`v8||dp#~NC?frH-QDOrP&WSa^WXG0oZrdaCvW+OZm+7_(qp)}?Me7schD~rR!aJQ z0R#LFlrY|2`!s)IEI2sTzwf^SWsSF&*xmPtLhkPWw?VBjcMbXf{^MfX1}J3&(qrUf z%#5gvs8CAiGMNG1hh91W$gA3^`RK#_C@4_z~Oa! zaHQNj5+1q~gU6gGJ<-=)(K%gyouq|YrSUFHpXJq=N%b3CgKZs8w(Ez#{I;St*DbRd zCqMrHlmqcTi4${};5Xo-GinyOe)%RD8ja8394GWMPgyioDVmheux1P*UD%nw`b}?L zINzW#IwwTIb!$vG1!0>a&2j_*hr-f__g1y>BO)#Vc=;_3cwU?Ep8fvy7_j8SAd`C3 zc2lY5Te}m5_T+3ien?oA+@~(mJP?EM4KwMRU*S)(J(nJeuv{ID4yDuA z&Uxv%b}#1VrJqPJ66vc@4l_d$JU81hFaU4?hTwsVA7)z&+8VCTH?Ke5Utl{^C(s%U z#20e-+~(gFXESu%w0Y98V6Ql>S|S4N!8lb)Rq%p?2SgpVKF2GaRB?LjURk++2;-}< zog6DO&R&u@YsY|@^iT^@K19GJ_?Z9pp`6C^G=3ccL5I13m%{p$7EL2R3SQV$K4x?@ zf-iCV`dC_C!!do4|FF^@3`wtJEEK$ip@m>ROkyvm-b$w8yax^#1$U}OseI571v>-@ zC*i-6#X@_Z@AQj7e)Y!9A1;4o8mf8aW>iM*zH<>~o2QUi!2f|oRkis|aGIgj`GNAj zBrZXkCI8@+?d_;@lF>4P7n6W~wwCt(f~zHpCwBAAG%0WCenkK%ktcn7>)?L0w7VE5 z3N0h2`sGL%lwJeMt`BSbUS-WS$%(-IHEBrXGOZ)j7XzD+;wsb@<(v^yDwvs+*S2rC z`l;LIb4b7;X3xir`(PyRiT{~lSlSh4^-mNgD^`{>0FQ5sMQwN;bpwj~C!9Gm8u#*FvgwQ=VNEFZDMW4?XA>_8^=>7uVKb4r(srfB2Bm(hAxc8 zOFg?*6-=kN%iS5niAS)~mpGKq7zbSt>Tp^OlE0mhfBI^K9LQ<`IloHW?&ljL=8k1v z$0X_W4o%1Q+=9ygePgBY2o6)j*r<#*2MmBW{1A57j&&&%i)b- zp<-$cEhGPsW14_5?rlGXqXXVD{sjQvIF{NND;C58FhpJQF92MWJ?TlE6jtP~2%$C= z2Y;*CDjXFwwx>N*EPhEp6m(C6Wh`yHh9oe)AVK*i1(b=3motDE@sUf`yf2K)sQD_~ z=qFS)UJ7aLVKmp1=eG+U+~@XX$7v-Ib|eK@Y2mSUr>fV$oF)u)u>V;e=jPXgh2M|$BqZC7hb?M91y5$Jt= z%$Le*2bkWEug-@gZBQ*Ro*n{ynShtH6&tiq-|Z|VP2ng?#(<&D{%h%*{MXSH8u|ed z|07YPMu~ZA<8F`n>xJ-&*S|Smdy>B?`;`2p)hb9jl#JN;u}ClnT4i5<$;)E;Gz|8L zf%^gJ^~Yn=w3gXK6QVCY)JCxa9IEW54ZU2B-t+C%18q=2=jGF~u@E->I_)vv?ee+k zbno^aGkT9%HxKqnu_u5EIa`Wo7-PV6akysv!zZz+2fZgdf(xJf6SpWr=G$Azg}rQ} ztJq9egk+1`=HYuHl0O4UZnJMG#|@@T7E2kwtlNgS769BZiHGA0)tp6VIJ)p@M-t2Q z)zyAsDX$l#RS?bByhf_)U?t<_o`q7js4+!ITGOJXMp(qzH(RCEk3U*?wvT@_(M`p; zklglgp1pdJZZ#pPV1+H-k2nmD*!#cQ7B^^ZP&Q{O*G%h(RARydGcC8P19h%}(UjA; zwFzxN8JbNw0c>WpN{XMJ8l*oxoq5yXWWtNT$XWL*;(dBdKvAmi)o-JIZ=KrRXRpz} zq$MaMGExYg*;F8xmtkP!4zS2I{%{jSCBb4EwiJ9(pwSf};f+$VTM~dc-sa-*OrupX zeS~vQ+zjDQ$9(2^8Aw2{@*U6o<|+o)vb6e+uPAlQ@6+!*?y~{mcS0xQ?QIBz{uEmZP zD(8UY%J&$CT#?Z_XrEX7D4_w(xTE^mg9tddR}ZX_`|7iJHYV(5&Is95{BLK-o|&#= z>09_P^wjBhoT~7cWcpR{$VyRgZ!N~9+OrHd}vUp+r@_Ex|^d17FnHA`sGx$5#>CMBkcMC zy$lZ)dFaB(8}Zud^5zFr@5|)~%RiJeVm~|2RrG%5abMrVz%DX+65VWJ%YM4X!01$~ z!i?b^OqPPB-EH2}5_wFJ=6R*s+N5R1&@j{@CGFDs{_JSrGs+WGvgGxvDr*Oijgk8{ z4)FptCcHN#xk#r|mUN8mP2a-s2*TVU%wad%l`mE^#5By_Vsc)Eh=ik)6={_=3x(0E zh1eLgyn)a`x|igVq@)M9nL0h`jvel!c#)*gH4v|@`<7^WeCx0g;p%gb z-aa7)N?jlPro~ywP+d4*EpHZn?ls~pcLqL&)IF(ijc(=MoNX+1HXu&3KtWd+FNs+v#NoV0 z-CbTZmL=KqeY$Oo@bj+5yApt$+h{{yARDGZZvD8D1a;h>!TF)B>1SZau;#qJyp*&) zeTtT2+B->HWO{<|@U>X1g}ReVYfuR4hR)N{hRs(xc;$*^LckiCZgmyY__{&W3wPbsF`=da*t(!Z|m^K0hQBgg+a_h zIuFE}bb-TT_Na)ipF!2XOGQU>?u%z(MJ^gfUBGOAnQ@1?;EO^{uI>5|v>?nNWWB9X zWi7^9I6NjD8vxRL!MQ<|sady!NiL*ey|z;e`&9JkUiS-$>(wD&ay5mgj~TZ!8U-N; zF{CBv_50sd@EUK9QOQ@M1#o*`jt6(BdZPDwf81_ZAGuu>Orra(fdVAc@7^EU>Upnz zv`l>QQ~Q3z(o^jD)r0=h-jQ;Gyx$%?EOp}|7?5^w3K@ppZ!#AF&k>ur*c6O6N=fWE z`7Dq8#B4bX>X)G^qXV2>+lmZRpQLlQ2W0#S|8!!$uMPi*dR~f^=%DrQdfX((lyLN* zB!!Q}ep3kqWjbd4Np=+hW+Jgo^UpOVY-G9bivh>&b)XcIIJQ&+!m9s!l|kj|nfjrC z;$Im65yY+|UQ2%@9R}~XQ$7CG9VqXZl|1kWESfLY^YGNvsR~|k-sdOQEmQ$4S)xE? z({WnC1M4gyXm^yfD}?DEwbMh9*P^~Lk9>}t__*Ij7Fz?<@Va` z_DQz!pBaWG%?}(-5UQy&AQRv3@YbKFLx9%|i}+qmlfp|0`s3YSKhwY;yD*);%=3-? z7hIQ!FpIuqK;IeGq3m?f>xAd&huRq|2 z-b-MID|a=Hp{%BK59=7~LNCIe_P4wj0-Z@N4c%b(c2ofpIJ^J!5@sfKtFX67lI>UW zXxP=Ep(pKK7qQi4`W4k!4XcrHXWLDmc=&o7zeBZ< z)M83W+j94}3B^a$hR_JRWrb5kyBvvXwc{#rsrpM{G2jIj>$N0Xf_N>G-ADlaMW{$n z$)n*acr*}#55oktpA)=k@*pTWhWjRvwvQg zD_4D_|E!|g8N?UydDvYN4_vZHy+a?s=%Tf&O~XW}B;h~!(*~u}JAUH-v&Kfr2!Qs9 z_8_WNh%FR|omH0-zI)_C8w+0&`Q5Gp>&t5|V)I9GY#ZU6R^PE*uHPlPxY+a#<(EF= zLHx*D>1x|$aYZA-LR`fLr)unyI{bt&c33x@KgOw_Gc6jE&nQz&990hvA|Ws0zcKa2 z4e{Dvjx;P{!b+3=@cHIEN%YZ=V7d_g!C{y_+A}a?kOEqAo?~{$_y#Nxg?Q#?Zh`Q1QsYiHDBmZ7SqUubjW z;vzFKdV9jmJqVLpB>j(k4Q7Hz2AN8~B(adct;#c*P#;9ZCfHA3SN@JE6{1R}$B}9Y z5nwqR{%co?!_n*1*M?y9a7PmgPqE2H@Q@fD9z6w7trlV6(n~l9Lfuj{-RinBr^IPyz_T(&;B=XF&CVS!=Ydjt(xVg=D#AF;gPC*IObfq?5>(ZhHMmr_^j21J9vE zvp@XDWzrjdcc&t_Qg*uQRyPdA_6)&&#y*ld2Nggiz%H)srbETp;iU*q-XX~w-R@7F zyAw5bjl!zNY`2r*3@zQQjZ)>dAKqSy829d5?*}RLXb!ACytJl5pUT4{81~!}A2^D_ ziH1W-6F9#&69?i>ycf>K!p<)t2&@u;?ya?94+Wjv$BG2N_M+sluky$D2F8O%5z{6u z8&?0z1bBwV6aG88n6Y1U)1`N@MTwA7sl)$RkEDNDk88i5^63Tw$3I4oCh8g%L#5;L zX&JF!!}kj@y(rjz7%}`~INQ|pTGuZ)qCOE0vd~t56-&Y)$P1ExBp;l^EQ)yXXUwVo50B{FqCuX z^G)%hobn@U6YV9k>!C!)V0Byq=XO^X6^=;7WG?btQdT z5h#W#)@@1$LNdIQ?>pO`@i~7+kxF^$6*fKisS$boow?u%MyFq2V&Q8DWpAAgL_(xz z9h<sug@kra!aUpizW+D4Lj~PuWn#9LXL`Xq3?arX3p9MHD8@ zH=E&V*)oa@1I{hdb6?h|1EL4f%oa z4|#cp#Wi;^AFz;Jfmg*L2fQlNzg`s=WlPR`2kgj#D>#mnCcOSMfkWzF75;%T8>9&8 zl#_HdZ!_aXulD2BU`>F<>)aWWFsQm50&Qdobf=kdQ(QG?)wDWsuLX;||qcAKmNvdl&yJrxj z`#LApaul{6`u&CvWSDxc(P?dgVV*93eH$=69qBCV7P!b@!peOMdeRURh+FO)GW7bt zcyCQwMU!Ij=s$VDsNX#lur4|$P)5!--VzyH=WPQQ+kYJKcN#j>ZC5GcLXVSo422 zHYfHS(s1-slYOufmR%L}>z$({G>E~&C;jW;IY0_ifw~#E0jDq*V&`;vcJ?xyY5y#% zL{hRrq#UiMFP9!3m>GImJ58p52k2SLC`|(DJYHctZ_XAaJh69iCB@QaP@i_QDJN0XsqYGa@nHA|cyYoV%r{iC90(c+7dXDNcKx|G*OMD`V+dQG=Ghq`oB>3D}GE^iU7z*B{ zy;rv}H7(u`vL}p3R<=M$`$z4(&yyH2rfY11^5LTYSb7Xa zOs7AV{^b-OF2Qcs%fr=Tg$d~Or7s6x*oRnjRh$NQsZnxTknraCn?S$=g~RUGku##8 zR$Owgb0kl>rDfI}F_Kl5FL?I%1kGMJ0!mJik>vh(ycEORFEya@$vPUy!^WNg`|A zW8n3;wU(sVk5B1-@vL!++aGW8T*cVQe69Zog^R7}@rB_COWNDVM;A}LYbmsDYdVR8 zvcnbj3#%?9dhb;8E#rL7!it3YP2+E{;t~J`1h&~WXaCBNcR|^|;)&Z`|8Ac687zSv z^AJYa8u>D>ZY1>9Wj^`Wre{~?vS!chjT!q?nFLMS`LUi~m-F_7k#A`~DEn`&z=`Gf z`l=6gyrOj?o&dX6JYD#3U`AUerKma(#rMTF1Y}XsYd?7%Z}u-Cq2o(U$*in}IG)q9 zKQa#n*=Tw}Q&7d2Uc^(>F8N6Vm%xkUCn(b9Et{ah$(aNsi0IhZlQSH$2oG(=uuXL} zB>_?6!Oz04E1@6oFw?QPI28uL`9*`rURF>U`!Zg)^D`Zt3w0B&zc~O|NITrU=u;_i zb|^?$D*O(7r-Ms?`=Q+Y)8U|?=x<*kn+z%GH12+%f2_yP+iX+hP@+oE=yQ$F+L-ur zM?jM8C0l~Pc$0+2t&hx&_Aeh9aRm=nHL6794Y`IGwcN~wn_nDx+!!X`cW-2h#th_x z&!SB@R;On_NqCW_rLU^?wflEJTj=$KK(c|mXWdTk&UwWrvmvb1Z;8EK+Q9`{lG?^y z6Y(3^D>*oNl*dv?gt)r=sm~ce1hwhMMdC%p)UnNdH$#|XHENK6-XkHJL%g(;{~Jap z-0uNH{@=I-hLWIuMrt~rriye9ncwO;_OA9Pi+=p~>bcqzZjUg%7pO)a@mSS(u7^Qg z^Ng19*JquRe|+Tp+oYuKo01^vG+<=9O#BoHuvN{)fBx#~Pk4obMTV<4Kmcj4cYmIG zauS3VkK5`JlRF7^m$=-&-UBbaLBqQz3cv$Gwz}s;F2t5>o2T??3uc)7tvf39w_eV( z2@!~fr0pcgvW5?)o}_|8U9Eh?L&T86qDqh*d5ntOSLd{3P~|e~R-K5BnsGg8S!njC zQ)PFoxKZtX(n*CmY#60jtF*^SlcT*H!|&DHp5Zc|PtcWW8S`UedEBT>pajGWsjxqXgdb`8T@FF%~; z^NlRe=(3O=1OZSwq$|*Xv}kZu|I<42#fcY>^qfe1wQh5p&(t9ZgHBS9(B1**%gZnJ z^Ucby<guD2$q9#T_$by zaUUy~Ih@-& zK)`ambUsrpr*Fh9)eC}vF=~d?@7DrqGRGYV2iayAsIfY(WKi~{go<0!AABz_yT`fj z_oKu>wiLPJEQHivYEG``>Strbe`ch(*?nTtJ|fdZ}`Fn`NiHsR^2T9$1H9y^FZUo1W2TgUwnO$u3B*y1&ew5uuEVVP6=S*^WxBL(16ki7tT)0%J{Cf!|$`>DEn52NC z2wc?9Ad0vBJJ>N&!4E-Uw7O69i=nXZzXG6sqWA(ni8+1z;GipPYrsNusLt1>4rc38 z8h&ycz<^A66(!?LnEyKxzSsLIIfdmySe&8N;|G5{0d24vP_wBoU5 zEHmC3)-3GSgDU0CKY@{)F$Ua+U+k&(jqjloFurpO7#TGi=Fs!6qQE9A)vG1n9bZTZ zg3ZFszT*GN3Qoi8V&68KdQzQ&t(Poa>% z{@!JWjQDHGdoeMIW$)Xt7gBkU{!ASr1fjL#Jx}@a%oA0AZbXjsN#?bWs9$)B?#`Kj zN!LcrLsDJbHkIf61_F`}4Rvrtipm(Qhq#57i-(USqrJ!8*OtJ5>NHj+`!$pwQgx6v=Hsm+o6?` zP&QNw(8V=W!29+t=m)L@zU029zgieo6b;KC0lb$kE?d35g)1w{ zzbo{NU}LkhdPcr25C~w8XwJ)XFkf+zAaQj$^nM*KBWt9rq*Pqu6W$afaU{~XFVxXN zv)KLK_(6V2bNpBC<6~hxZS82+_xwi8GND3&7!|d(q8z_VvX@jpI7~DfGd;k<`ZmNC zWUzijQIOGtm+ot|Ec^>z#-;4`UZ6@DM@mY==9j)~A)C!PGNSsx$P=llYgE5N5s;s045Ty}? zy|UYB%E^hDo^C`z2_+>>U0QPJ?{`3H%b~=rulKaEF^d0)4+oUc!1Y_4_3_czo1|T|Aq8g{x2+9?|(tXV*en)zzzSeZoooE`lHy}ZbQ9* zHBg~7W8eP&|2S;hZKM8$tSk3`aj1?vk@biw%K1Fa$`Tt1@tvTRzZkWMx3KU~Vzps zkJH4g0qPI(pRQ5}9LPWG&sorCg3dM^H}-38 z?A}P9Lu+e|>VM^&oKWnXc*Z9|C!xPqMPsLX>8MR1M;G+?14$9Q`rwyKiLAw4WL@_C%48-&Bz? zj4~(3(9zKa=SGvW{5}r9xIkW>i;Oa$BiFRHW=j*)Vp~Gzo0XOAL9AWiWYBNqRkWtv zqviKN`lpBd;O-HmOqDO$t+*A#Ha7>+0s7$u4*1d-Kq6YTF&q#vHpa`>go&Je5G~>; zF70+aj)N1|u5LGb5%Lod<6QRkYA+Ce$;?!#p#-SLKSKd1UZb8uCn{Es4H}&dY^ReF z<9@4YXjG}Zu(qBw-Dq}NV(JTWzL}X3J}`HZ?$SDVo&`Ewh#M*=?^*KY>RIs5S6V0p z!^0d~W?eZ z(9~pbicA?$)ht#}MRALKs6mX`-PuV?bx-_1{fiw?B_2$Ac}j#P%fsul=X;vSgqJv( zlH!9pc--bopfS@dOg*H7tANA|B_?fL!;~;FO|C!3Ti+sejD9YsZCpM<$O7#h9K?~p z{+|cQ`kI#sX@T)ALgSzG6OmX{Pn8<&#mR?|In)k$<7re?ZzMALC_ybabyy8;6CdQf z>8KoAUw;iIc64;V%uNpnwge@C>0)L;2me)fb^DDY~bDE9peh1w}>9c;M+} z>Z_OMQd2MchulgE3N-1I6%9TmBs^CUzXR~X1(9R~MELuQFG4FShN=(;GaQ~P`*JWd z>+>^ma=seP9Y{}4WnDX$lI@WjG(AmbjZ!J;wSJqT0@&_i66I4;-MYF^R?-05K{N$y zMqvBqIv>m;G&H6g^Sv1zlJH;jK6_^08ltA_gCoBN=nR<7_6gOv2zE`#m%X>brafcq zWTWJzdi6NzS0Q#+EpEArhKdU61S<6z3pH8<3L97F^N9~t*(Rf1 z)e9k`vWkij3OYl16ITAbXQC}oZcEFx51G`7Pp?qLySln^z6Wp6z^(7aw8*LqPpoTR z*C{^cqM|kA;hEps^f3w0(`%FtjQIFbC+{#>HNT(&B`~Y2Yo%{&adq`%#ew?skLVcX zxG{FQj(@!!g1$Yj7^XPEGYQ%4^6Fc zCPT5V<>jg}P4!VDp5*to_PeMC-ro5!ctB#_ccIs^G6woZR>l8Jb{z<9OXkp?E3bVB zj7Um?Y1Voh8|TkRzkc0&ehtrq5WuHFticYY{HMjJRLgh=Cz%L@yh;nIpLnN}1D4JN z1!*LbI~K{vfD*;~VJio_od?+>e0-%TG0{pd`2sgL9X8c$Y*GsV-%7GzrT~;3qnnRp zWWz?Wa)T#48`jhFWSp zUQl!`LSPv)HmYep4iYc5J2xsi7O`36*PGv|Y0Jr} z9O!=1Xylogth(S5OzqYNm+Bm%RNu>d(pjs(NqB*QMIq8oa=ftdk~Kg)i9*X-mfM`k(b^WqJ!&ql59|l zDgJEwJ76n}w_@#j|M*$4Oc(=oCc2{g4xG*u*wZi-7UurE@zx8r&TBd9 zd4;D+HE+=(?w)lFF=_SFyL##V^TkBC8N=F-nBfjW#bQ|v%K!0ArdSxHg9)guvcF7T zUIGq)N_f56vBECd)Qyu1-}g||3>8Q_r2efi;7?_ahaV%Bc6*RyQjCk@OWIIT!MOS+ z9Re{v6;83nX^(vhCm)$d`q!A z<}1lbgh(WEb0~*Ju&52@7m#2yeLvUwBYJeVXN!4vhoeWzsO$!)tolQ6X6zfy*#WQH z*LG3}{bYNHHQ){Oe(TEoo-{Ufnn_+GNZAS^@vKZ{>E<$2PdY5M^U0GZ<59!%DmT1G zHFknm)<$0W?Z=D>?bU#>bz0XKCjqwT}UDd!~$?NdYL78ju;+V8}A-B9-9)N)E>NP;a#k}e0 zo?o8*#v2Z@oQ%xPeQ@Cdh^jawxwCYTcKiTV;pt)`f~Nqx z03hOfqmk%|OWJ1FHl@WcFdztbzBp*e_rY)+0*RhMdYNhD87EnP9r)0kr+F>-<79tZ zk)>$oOT~&Qw34%V&zJP#NB$@W#AN;ZUVTzTgt?}2tShWz+~$~!wYj~;zHV{r__z_9 zfMfk;Vn^+fUBg+%4OcCF>Vj|31_^jT~flF3rwY@&w}U}6NDGoK6{@! z)ENeoJ{hbx?a2s~4t8cxdqNRZI{y8mG$5mW18}bsTPMSajeyTK5Xyd~f%~GV?stqZ zuR2ROJ?E@WkoPWw8mnBlbk`>jEX9q&ZU6eGFjMh=9B(j87E-~%qD%;FA&JQ?>r*Vu zZ8cqN1`Uv;sxzQ**lwnpWraRoh`+^Mi4+;p5lXsEL*e^Il|`fvqFrm>ktOLnZdl(k z_j1k`mT-`kojMyM@)QhF2N?I6*N^I!Z?rk+ojQMw$wrYB6aL!(!f`S);v)JO97!A< zWyL>%nHvBmX06B=p&;JUwE@qHii$q9NMThR5n~cnRW;7pV?umPCl;TbFvG%e+9Bc7 zRKSr4S_E)g)3Uq{b0;6!4vf6*Wce~n?4PxIxxpo4y-nd*T2nwBAD?75A~@O@B~rx+ zM2cAV`V~HM*4D7d`+79@TSh1})-pvDmY?+9$B!`J?r-AGa15|_stcOclEr_s{|s$vrk*!zU>4r| z7$Zk#%fgI}xUEMX1danlIsLfvQq=sLy(XDz;)G+jNUzoT&dSi!r-pyHYZL}21`ksiLZg^DvYD#HCd$MLk zgvXpfF6k~m_=bNk&i%)ao1oY~fAa8ZH||&tzA-cCBdjTzYjR*@`2^^&3)Vm+Q4epx zi19sN77aq}2qq-e5z8a$al{AD^&6_*bVY2+lAnM46~_{wJ4MN#-ClP(XL7j^OErJH zuf2_PpLSc1pA|z3SvaC(p@v+dbj+2+zqgO( z&$MCaY+YGUs}E5bLY@jo#fLaFGVWIABZ4fEVrXvN`EGBfK5}|cM&q;bQn#qv<`01zS@)fkoxza*$9GYh(h~}T zo&%+0qpuKLHzv|79C8auTHPjp7VDjMMJ9vtv964r)znL{j9<1NK_s|&c{jvpS0uSp zHPc&T=*Hrtyv9YMpeks=dv1OGM%%;Ld2fSvwwc5PZJTaRE;7YEABmW++3RLSBEUua zQVh+-m#?_=D!CspEDNHJdlR$epe;Q%5id$p%WLZ<9$2|jYWd0iEzL#n zly$dda0^FieRFd&IuDHppOKfhCiMaEa+{(;A|$d71G6BdrLcZUX(3J0v5HZBUY0*vlbT5@qJw-T1Oo7EQTAC5 zdY7!rG{?d!(BVCoc^2){(Bk_>G+tqaJ!Aa-U9IJr;D4p!M*ch1_TRa@qkre>hIam6 z#h7O}f6FWV?rfXS-FAKF1Nl+h?V5LP+=A@gK5=J&{(t`X6LQob0YO*%&D$QAmsXN0 Jk$4&KzW}>@_qPB5 literal 132360 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∨p{dGWX;mf&C7K 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%0A9y#gqZfcw@Z7MS}^SlG^kHS)!Vx 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
RxD-L)=UV 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 Dsp$ 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

;i%L-Y z8)NAI@^*QBeI%Krl50?XVU9o|a0rXVR~l0RG3ax%>#^`mqiciqrHXy8N{)vH=gEz+ zLeTiqOtMf&XDG@B+}I;3mTdC#05wf*e8}-F1*||dIu9*lh5|6~xR+iOKXgvpk#19) zCgNd3Hk$N{$SD!Aw1%^&IPUxVNp`SIch<}MK*XbZj?k9D2*0)qcZ6^6!;|DY|V9zeeClF+j0u~F*fW?>pz`ko>@U*!? zXlkHE7Es4>1{=;fq}_Y<7&ZqihpUX`;=@-7-GRfJ) +-q(Lx3-R6>*UsE2M8-1ve0tQy7Gk29l?gykesZ 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 Idbn2fr~tJNDn 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 literal 192376 zcmc$_V{oQT)G&C*wrwX9PHfvwCU!D$Cbn(cwry)-dtw`Rurts5ZPo79{@C3=+tt_(2#%s$ds0Z0s!y=mLejGQX(S6 zijH<>mNupUfMj^G29&1CIA)GcLY$yQz6?w^4C!~jBxG&CsTgu{95^(^kf36HVI*wL z4|)R;4KZ{cVoY=;din?ipplT678cyELpj)!j#{s4uboZcj_=I-@l?ChBp~ls0vYOI z!5QEW4BT)%3CM%PIF0kXiXRB?Bw?wbiCEct|G2l4tN1HN+)^|-sg@`f!CxA^muh84d>JrFsw ze3hj0SB>wPAR52wnv|eZQzIWbmVD$MzU-u=(&0oHLS#y(aI&d$n`^daa=q>;SAja@ zGV!s%8p(wTK)bQ{hABy>kh2M0#o{``Y1WwuLK#sJQZeBhiG&3Px5uNv^7DxxPlaID zAUjv&#StLY6Ar<>LI^p)=1%XwYl_h~@rz6u(Y`q0*VEUqEqhDJgR10zaYxRopBPsR zYu!pAs}Q$PqmqjYSHadB3(4!Y4VcS1VA45`NzjKUAK8I8(CcHP60eL#unhIr!+te% z1?0aPWj2CeNJ8){reP4#)*>xW9FE1mq$4ir+ar`^|1|0;s{)A&ZCxR##EpWf>W-EH4lR=JUDdUA70CzM7awF1;NTjDz!`&G|H(6{}~j91RF96 zG3N1_2Ysg>s`WYtVlw6tX+q}MhZc4($T=3gg1Sb%XWt}xgUu4)D|*~F68w5JKzaG~ z{EiIFHWa25?w1T9onH#!4Hp^`G@@osvxvmo?P=p61d08u<2r!fbh04a`G8S?&JGF< zIuEiPsFn&qy;abPf!I4Ehtr?qo)qPHR{7 zeDVB2Y+GY2m)2VXOufe2O!Qz|4(f#2Xn(UWWmB` zcIGn_fPXqLFi@h`$#5EQ@$47-6@Q(D0OrG;1j6YWM2CVk&ZX-?+}9d}>ox!2&&&kH zZqGl{N8kqLiwr&>h#m$tZa_N44_D*FoCa#<*Pe%-6liMjT@#7jzuJIm6%5f2(jGnw z)VyEJ9!D3-b@%KPgi%ny4T_%(T3EOY8evXC7FlM9&_NtKj1e_Rl(=4!B_YIwR9G}% zO7Mu}a17RjuK}W5=!r}sPG!u!2(3MsSI{GVWsC}4L`{)l5xQAeA|E~}Jf!gU1e^^m zI|{S#evaZqy9swIdbzOlcjSpn6P~v}q5(i<#Fw z(K_Jym3BG$(U8c2RDSTZ4NSK`-wkwTnChVMX86U!i%KuHbzkEa%1z)iT95)8^#Vo@ zoZS$gB#|jtQM!!Sh6OxO?HY>p6VN=E%6ma4*4%sA`~b| z@&x|zoIfHFqz;n7MauKs^R~*Yr?BOr4?>62A4!Y5FZ323R*Y|FdymCMyteXU@d<2r)0Mfl{p z6+ZH$Ra{g}EALdzE7dEOEA^DT%f;0jRgEj;RO!?!6?w{jNmVOkSJ@WNC?A*2D%YwC z6l@ps=Ls!fSECfim)2_ z`i8KdK#6_7FKi>EEI-?@YR`GFI^;40OngL~M4YtHMZ7fnEy^Y8Bf2qK11Fd1>U)0r zO9r&8dOBMsZ>jY{`h)J9wg+AJ&f;&jMOCAY;ikcd#`I>b0Il#fy++R?bf*yakXPD! z%zGa=w8(l)R(dN2Tb%?3oD{7TYx)iP9UUzl3N3~@t2z&}YV+xqZ!I;=J=P-4w~gsG zDnFg3Q!FOyrt7y1Jl7DLof;<_Dw{e@V%Ix2;4U~;U1P|j9`I@KwfGt)g@*l475^xn z-}EVsG7r=b)%V{XQb#J$6sE*l;XO`|Pt&YeW-esUWfTsIr$*W0eyp#}q@U}adQAtP zpigpQ8v0_0r}KjH9)+F* zrvq36tpkA~o5CfbS@0A=A)()pE{*W&+b?i``KC#%PSq{jC*QQ)JnkWpU62l;$QjSo z8yaiGbmLj#&_vmUfht{;B`ZA_R2Nc75Ji)Wh>og`@P-o*@Q}4I#9(sJ*lKKczWBWq z-@2mOppwHdgj_;wj1hR_H(@_FBqC zhC!~Ix!+@85$2c*S9U7f%`0J@e5NSSGN`Gj>4&90r&5;Hj375pH*I(Bo#q`}|#n>5I9r!s!ZG%W7hiUI@_{3T~Yg%SfCx-$J zBg1u=qDmT>%{0eMZpIEx16FcG2bHIs9$&jY{8-1LC*OpWOV}Jl&=tr%~;!gi|Inn=EkY$^4b3Ew2}^ zf4MbiYK<$Eg~R;nnnIp}PI`MrCS!$d$Ko^VHP#2_wYWvKSygwvxzDq|B=|+Re;`Ke zTjVmsoB9Y{r{a~Wp3y8!is-L>%^|osrjOUHZ`nB+7n>wbN&1GjF zklP`2cpn_gKUvmQdrlY3`j0Yogj*IhbksC#C~O(l-%ND&TUvIodzWlDR`q&5&Jp)w zuCnWSbgX%;tbXBKX=_I=OIvxmmR|LAQQ0dPXNzp5baQ)7KKpwoc+WnUUiLZ=zY9(Z zjr4bjq=Z%=E+D2Zkv%S)0r47eJMa?mcw&PHEG_SBxxE%|PhyNqMrmWMiS#`J9F0E1 z`;YdI{1Xcjy-QgX_^i?w9giQ{7FM*4wRvWOa=BdDUoKAB&2;X$a-BwJJhKHH{T=f6 z3V_3JzgnLLdpkdT+6KD|KNCiaM<#PpGr32dbK3S@4;PpED$Q%_YkzbRx_94;4@77F zDF3m=;m(n}HPQWe_G|8P*7azUVw0h>)Teg8XYb=oz~*ap<8s^kU1&G(DbxY!ns=Yy z(r?yRyH6j=^}cpEM6+qc1=7PXWc8q(3w&mftBJtfD*fxgCfe8))c zUtW;PY8p59uliTgURoYWB=P{z{Rb&gAyv2ai+=yV+Y5kS-bXoBIp{z1|Hovu;-j7k zy$^^{xZM?FED%$a9GJ=d;c6CHLKv)v9;_!i0l5IKWHB$-u$8nwTuDWgr?ATk%^y^| zTh6#E7JFc(1A!%D3BzF7OZ380YWh;|g!^yv^naT;rM%29#S1uc->aJ~!T+n$<}r2I z%JCzv^=Dn8ww6t5_3-n~7Ajm{#*9?~OYT@#)s4J7e`KY3`P{07Sao*k*|zh`s*kK1 zS!59M%KtQxx^;m%STRn8CF{%Ger~L0=lr{61C3-Tp)CGx*rl@bGvDU530AI4!D#Sy<88J z*lMD^sEKSZ%Z-=kwx&2MGJNTx`LFY7rNk!;Jjq0yYA;&#pT5ho-8S&OY?*dfpTLjF zLrny)f`&ooWh|_|42{ZgLXXlrE5uGgMov_&b%n)MqQ{TL#>(5!Re0~@8Sf(3$)^}v zFO!kaxxq~yp4WWSIkfK%P0hJ!@wM}X>z_{C#*Vva-G>^o?c$dD?`ET)TA2|8oH1WH ziJL8Ras5J21n+20SMA4UXb!SJg1*6$eh0VGZk}uEc!l%=u|*8nCGDS{lS0SOBH(U= ziAm0gFv#2n@*c&8G&$2WCH+1I({Hm+J+?17rY=rWKI_Bz2P7oFIb9%xDX>x)EPz-b zXU0;(kkK6xJjBw~@8e}B72yb>;phr_6(PHwz8Ea|y zSU)FlZc$8wFER6%#^hnT?X@RfWeV~DIdEc?rYT-@TYy6RM<}HCH$7^A1mX*FsVmjV3Q_tpGD z4$?Ul9*;7xpDeV?oSYS=Hpk?>XKGawb*xqQ8!;muHQz9C+`G zE^J#T44ZYTF>)(&?%KX9ecRHxcpAVu20E?XN6U1xK12*sg#WyM)PI^uYqcbX?ISc0 zBB+q2rwIGKdcEE0B#L5MyP7YehT9yTsE9@ta}bvzD=P`j?0TXNgMma3PYl^XOs-lk zf~koeFFovstq6rYxYxMB29vx_WS{#m9>}n><*9eI=D`k`mQxc2cl9&iP`urSd0*25 zq>jyWsElmRkuA?|$o^=`L33@Y@of9M(t7a4{=vg}Xrf^%T;e7@ABFukDd*0ZBR^VF z4q6#-i_E~CoGcDh<~o`cRI`S8IU(vhxrhSlGSXvW4$?vw z9cy}U_@}1xEXwL99vwtWQCu2SaApLBBwZ7UsqUr0BtC)D2+9vDS)h|n`IQOCdPfDWuHHOk|4 zNZBFfs0=4w@f?7+ozBGLd@5$Xpe$uknBWnCV1B~^Bd)xpx;2)A!IsVwBwbR)Pt01~ zt;x-RO4~WumHMt>`-?o|QR^UznEffyrSiSe)=1mWVj`2Z64l+(y9|XPi0AZG-G(gL z1$7+WBxfL}?IiZ`Iv38`5}w=pr>0EJwEz^D@9DT1-2wPz>bRE?4dz35k(U zoRJ8q#<7jnjA#uKsKHgJ1Z<ktIro4=_%R=2NbU*(*xRdiowXStqtb%=a^H=XwLU0R?YF+mj7xTr${w(qz?Svp z@xqfV?F^8zWiPq4UynYkZh;J(DKr|wD|xUd^)a!S5J#NKXtd}8Vvg7 z5Yhq#k;TQs>p((q#EElf2T`XNI+tfXqal8bfHMt1!%(6ZZrj=fVBI8ykGzXe$B$|7 zj*1DZU+Bw_@?Tq0cGPROgyAImg}sGI4oQJ;G+uS+qzMQd$VVUDskH)GE}k)r-7hn~bt+rk=D9!kk_9K~iKK8Z0iKLT5kV%entkmt z;{y@|)6<2<(A~ZU$Gt4KXnvw;`qH$Uf1uE$!s{^%Ug`241_@PXH{Hl8kO9mD1JXfh z;W%EfBcg;TNTyR!x+GA;EuJ2z;T>0fjDVZ|8z0W5XF-k%O{Fa{RHiOdKJ`{$3z)fY)I^OjMlbgm^dOZ5;C)#|wn(j;E08 z_VVc7P@FKT4ss|01H=dyaKHf>O<+vc*GA0v=IG&5@iDO5A3lazhK8o~dt6~E(D9wr z{)WS^Z%7m|xGOe9^xg^piGHvcOWuXZq(`r(k1^~iJMR`+RF8;H<0C$Qx?LG|!X1;Kv5E>kaS&iwS2>45w5Ctip4fVrVT2Cm;rhxN{Q&DL~HW6qZI?0s3BgGTRq z%GF^+IpUWo6)+Wqsbcn^#3DnAt7ZYH%hEnG!|jcB=;Sp2!;WWWos}stano7Kooh+< z=-01Cf@=VA5h$I)s1&DVsA$ArV%1GWt-H9oy|GT7=$-uWeT z(^r8mjOEsfF_~9i2WPWVUn(_?O3AS$#LXK&d}05azXt;Re+;h9&emkyT9k;z+O>rb z3Qo%!eB#A2mAaJ@%}_?F#L#zovGF|iG-!9t>kljBms<#m#*lV?uJ!i$V=$D^$9N_L zJp`rEh=-yLkpvNf-VPhr;|~33fE2zL%13tCqZiEJ=OqYq zI2ZPDwkz;aZhD%|v3)!xZTJ|Jw12*+%m)Wd@c^oY4FppOPZWF*ItDa1Dl7#oEI-H~ zPRIzt@7f3xi8yIiDOgDeA;RQBhr*%IKnf7=PxH!V3`*TCx;vdBl-UnD1s_M>@{L~h z2sUi=e1C6HL%{XVSWU$}GCcr8@*Oe2dvJpY{6>)-I6WNfbv5BuH3!)bGI!`_15l|) z;yM{ONfBUTy19c&BdvrKmZwU;=p{BQ$duBP7S54CzVD}G_Iy+~X|XZ*<-gha?B5Df zCTin3>?OSLgIhh6FR!QZ?nt_7GR}s60&O zH+qMAbudT(NC+ns#?*cVSy&wa50&-%5H1lBV-&;qG0cF4B2tl8dA`3M1Vk_7A1~5( zKX5<-0F4%>1R?J%m{>qpU+RY zc|*|!4TYFN7G?+pGH_SO(DI!C$_*S^5r7;C5)6vWu`j47i0p>VtI8P#I|N9D;#}>! z?vteC!9yZgcW`{#;$rmLw5ok?#s2ORV64cDEMUI88}TrKgp)n&(1C@f#nZUxmbzrR{B5I&Ij_p*-Bn}noeb3WZ?W$1SG0xW`U48kO_nKE4&b4 zpqGDElNLhO-B{HO4G96Kq#TLC=i{z-bbHA!4Gn3zLO?g#yML?m{$ds;lL3|H4N>fCWni^tR)&D`L0Z-`Rta%u>j)>Vx zc>8BJe>7Ch??{Nj z>7tf;R&>L4+uga>_iQNWY{MVvmlyQ^k#%TVJ|0a)mwOX$GJ@lGPPk=u#>|#CQ(e^c zSFUQ>Te^Q!cj+`ur3n#76G0HdmAA8y^d0axzzZCnbFsEO?`RR^JDkV>F#Zd7XOV|eAvAu}Uw6Cym!2^M8{Z+>ub|+PU>5l{=N(-@ zRVWKsheoxOu4=W^#cy=G_`k$5lPSQ)17xTm=3L2v$yR7O~anE>^qRG z45N@8i8BDAh`9l6ZQg?mfLicy%!M+bWo7qKxrv9GMrGrBglVeFFGjtFrzNi(EIECV zy@QwARwc0*KZposCbYyIP)wDTuvKWq`FTf~fblOfRk`mKnOgmlkN142X*8ITUn;zY zeN2FHc%j8y>1r!sDfW%~HP!PsjjEw^0U7V7<;MTC?|-Vs()8Ck0b^>ad2~vMi>gP& zq&@e?aGN*nob^xnS*4AuEdB0>^E0|7;NeH(69J3$Gn7n2=95C}g6ou&ox$kop-DyP z2IKn(-QJFCo9zzb%IVi?JqOX)YG!*@%VIW&eWCyFdAQz3D^04_jh(23pO;ekkW}rT z2{vcnVp5WtR~#~(CY`9q_eV5G+8^y7JUSS)9hc=EH&wLMo8y}~FlQIKPr0W4Is@S8 zs#p^B8dnk!qgw5>RvgVzOZliRjfT4eQ%5VT)!wD5y`qoneEykdS>1~@-M6DElMmd( zAL|Q0ggP6Iz8}?bI!&6M{<%Dmx8|r^t?pJ*KD|<2zJJBq#Q&jBwWY>e^C!j5IOL|y zw<<>AhbP98Pv#az6W4j+6YCQ}ce(}5PUk8@Ys`W#+rh*3aYwd}uKCuiZmG2*0dVoQ z6lhZ7a^J1;xY4R#ewKTc>4Wp6@H<7TvDcCK2Mq>2W+9V6 zqL~xdUv6(T9ur%c>f?Py1r6&7PDX3qM+_$X;trjp8PEztB52ar1P+_?yd>Q3yUG;p z67~Me@J}ZWp(LbIADi0pEHEq`65J$dp}qE}HylpF9)o2N1xhMAzWverV%_KIr}-8D zk>pnOS)?)6{d<-A%gA7N?u!`r6*IGU3&{ywsSXb1+*mVQsSlfm(gD6XoBq;?G-}-! zKY4o#IMo<6*KO`IBD|0eY7#?P^)eosuSuoWej4U5MM^nP=AlN(4A#rhbk9C=dzkmm z6xv6rng(X}2Z<%xj)(p2GogEsXGgI3%k=n4s{($I(@%faSR`KZK^h_5gBOREL29jx zq-k+?5qS<-oJ2_T0VF^>ASAE3pqf8OL?loIIwc?uT4}d)4dpTGcsvFdrSs5Nu-cW*NC(-(U^Exg|5|p z*Jwu;+blgap_q^~gM_ei9UW#P^Eq_T@5sM^ak_6%6nXv{S??ZNn5#E+v99H6sK2!r zzt!Aa-_(WfuEw54u~Q=}%L`0UHv^JpduFdpRoPtFe`D7PACGkB{-U-z8o47_!dqiG zMnY5AIhxGfxNCY~nbg2)>_WwBpf{t%j zpxS`_;JXa&nK8PZ|6Kis=Z)Z*k!hD>OTT><7MAg%&`j8-w4o>P+kJm^i&fzB_L*D) z>5+YzsNJKbIKQ{F_*T1K8^6Yvor=M?O^-cCi$MH{G_RksuWp}MMc1n3h-hy#$OTwlCsFn$N(CnIbT^! zcw0IMS=eY|<>U&+bl1t*sqjM463v>u7)AeViwW@^@vr$B;L?=Ktl#0+i=RT5&2%I+7 z^jqwz@V<{L(A@Ym=L{}UgY8&-cHYX3eys{PSwp3@d^t{5ZfQRso_nU!nltRO;6LTo zj?B8`_+wFPW=8w?W`G|N(AzH2vWH+(E!Cn<1?P(OmTF1pTs%i?*(8|(#oCS2z|C~S zfb-@l{62@L?X$v!IL^dPKE2M&^tba^lAwP_Q14Vy)KL7H>U`7eOQV=@-cPxyFqkDv z*-R+>?S(M8#>(EzFw2xo`T{@!poS4WyFAJ3QRI+zL*-PXok~(2gM>W<_0#o=Wz_`& z_SUK9@4Q9W1aMcZR}5gtRp(Pq9tu|5e8GJMm3o1SFpd7GHBiV$pxB3jOxfPBbb@&o zaiB~v(^Jl(6Kr%sRrJ9 zPW`GcCCop-g(rl%IBAJpP75#eI#SbJ#f~9ni2qgVEuZO3T*g*trdY=ptwba!Y9)?1 z1g9ED8i0)3tVHk~G|I_11Ym%_o;4Cj61}Etw(5?lm zYPvNv(+tPLaSWOg5rqevyG3?A48R!{?V}WZ&cBcWE%uw@CB-pl(LaogDyC2@uO!W{ z0+|_{dhAX}-$nsEg`On&Uj$w-XnzbpjT3TUbI0w?%>BT{*eO!ErIWR# z;npms27V9XuFRfX0g{@_Jdai-XDlXI@YOG! z9~MnLtfdYPi#;+R8gg9u7pG zOPM}#cpjtSO5lXt9s}8b$Tp3TD#PX%Urs&SC7w8p_xs7HU=AI{RmuJRUZTw0N^3}s zXc8WlN!J?+P_AqVOLc?y2%~#6>UtzDs~%1ycDodlGt=u$hgmbhtAk)1c;5{U_TDk? zd3HDdHaNwR!&K`bjDBCI869o01G+?d$VOSD8>c<1Hv^w)XZ_<%a$=tDL?~@sw}`BQ zopxGM0;^Gb<=gt0IM-;3t75j z(PP1% z#&-kuA4B$Su0d_06YVd-n3uK9nla`zl}?=>Rf`AiNqj5W{QiVCcJ750de{?uK*yEA zbfxOaN%3TX$+A0FvW5m0dTG0B7cj9jqZuWHS>|6Q>8zb*wAqIUr}Sb@iV}Eebr*M{ zDX{AvMp@btolD;@Rja9z`S|8aI#3=hMYyVA+?~~>wK}U*4_l&U#ut!s6ZduH!`&HU zRx-Oi=9&wRq%Kz%2H%oZX7Jd154A2YaZRl>nl-zO&GDC3-H=Z!v=q+gNeUwvj3eq( ztvvAgOcu)%3yntbFvRSJWRK$G{-v9p#IAyb|FADVG(mI#e4m}02{rY!lmjZD zXITEdpM&d?C=>}i^92?KpBVE?dXH;ll|k{1m_4x0Ad7WM%Jnq6v$x9?Mu(|aVDcpW zN&T|p7p8Yhxb=`q6zCgR-!uJiW0VpeG|=E2usw=7zz3u$q^czLL!mEEozJ_2oC|fE zDkanWgJ#Hh_2JP-7Td}Xd3?OD%Z;%6Lvx_k?BTgoLrc&&>J1^IZ$;W1grCK<$k@;_Ds3H zV37_P6yh)7{MQ>ZB15V~ztv~<$8)dsb*??4>CG+B0B7kmVPN#?C#XQ)Iy?L1*Yf(m zz8Q!xIEc&TRQ0>_mpBO0Et2Om5xIuiA;`PujQ3WpCkv|-8>DL(jbw+XhtH6H)zvrD zsQUMMgK}u*Z`l2LFqD#@Fz7Z-6BW&U)u671C>*;ru(Ta$DMri#gYwa!o zY(7m0qc7vG=Dt{ zHUdc>cwPFk+3%g+y+F}&84!??Z}c}ZfJc^d1h?cc76SmFZLvx@vBUCV=$biqbkWgtH`?Iz>A0I!X`=L3)3Md{UO$ zMq@aqBb$A;)gobvFR6o9H5QOC>-@?$PyS{|s!?#Y_Pmzr-(@L*g-B|DR^{UW6U5V9 z0#@zmq1=dp1b|Vl$2gzs1d7U|7CjTd)S5a>en_F$&Ffc~m9b&DZZ|{S2pSXp%QNOf zlpl&_FttmX>JcFzNMk(rpwMt{poU@M=t4Tr!ulE>jLspaP!Ru5E$xuIt&!N>w`4 zwc$ax~e*U?s;pv#` zZ9e~IKisn36**kl)Z6x&I_<9eVb{zaqK%%S$EvE?aGLe!dL;{|d6XAurK4KFWo@^2 z{}yAK>4Kte$}IAXqv2h}{8Nbla?p|fSDwJ5a zf?b~3Qq{XVuBTXQ*E47B_6su{99vU40pN@pwxpJiH>&gwB=KV^K} zyD*b=ZM7p|#RPWnoAu--rTBYKPfwh_6Mc9uDzh+9dGn=0I>dC={@&gJn>Yn|-@}1SNNr3-X%xBJp z)eHs0;suvRn1S;(QR+o(#1&<+Ev0-m>#8E+l7)AkiK-bI8$AKT7y^qCPz}^q*AzBN?APY%%J%N4+{Gl%v zx0_{s;s)1izF7d8E0Z55I#u+TpqRgy8y9LekL$OFpE$B95(cuCAgCS&U#%@yYfc-Z zPuE|e%%X^dT~0}>{CW5Vn8NI#>LpP$Uhs{-seFM;)t*mVEI(!Ycmd;im__OM@}N#< z1@mq=IK5~U+X{-M(gNz3ivfLD1rX`s1W`=oM7CelXUa5RWO=lGrhRx@{vD;cpPfHu zd7X4-d%S&n(Oim^Pk|G(S)@U@c}}03#TNY$X-ZSXfM5f%8{R<74&N^Vo#*Rb7j5~Z z04Twwq8=fxCS@>-4#K-fsvJox$DMxP_4IK!0kC9{iU9Nvx9WI+>WFO7wx1O)DZl21 z!1h#t9Rk+aiY;%8%1 z6qdu@l&IqHpg}60{}XyHrG$3}6;4lDJTXM%8-eNVy^^a2Ln$yrZm0AcuOCy0Qz%`Q z61Ol&nrYt<7VM^Eo!yKKQ}Pw3N&EN5Tul4jQDk!6)Oy~e@lL2>4L`D^`J|LGl<*$3 zHgc&CV*N3RaGY3L2#U(^xD?1u!T~qhh8Y2>F{R7_806YdVx*qyTqLhyo^$%5$)$NH zNsMIU0}%zj$LY|$|EwUjtN-9%h3Y=71%PxZ;ACfZ?1y87mz~iS8$NKKt%LIF7)y<`KNSt8H{Vbx@f4T4n-@&HW; zE>rNB5P|>&?J04VM*^7mJ3jJdceKP}Haai^rtmz7Oh6of+|mz*YCj*eOb}ctO^awu znuZ>;yg(OHxjbet5O_r>wNAdAQ#jw#*j-)d)SwL#4{-Rq-+=ZDV9o|fLO~mmjqGI4 zK5!Y6kFQH4A*L*&4Z|ovk5zznAf0ryP6=!%h4E8e4>Sc@)&Y<$&{eva7Thzqd@Y~_ zgiU7qJE4Gg8ef!gcRC*}i|=LA`ExaFhdv6^du~E_Xs9cWnxl5dFqZBT5wr`T7KOXKIyhpj&p!;Uy;EeTbeS!gjO3y zN3c=_OI6!44Wr^%8D=^Iy;hF}bTUl{Ig=}g+%=pj)Xykn1OgGsW+Bbe-X54Zyl)y< zK@dz_H8XoSag9qezKKp^J%~!qncy}1&+HweA8M=qCrnxO0Ghya2QSdLp;}gyHIO0j zoa5TG=a6+%|vts`ma?-`JGw(7w%-YSk@fWP(1wsH%6(-i8y61qPqaS3LBHyT-788mj4rI_8 z6UxLP%UK%(&zDcY3JjC#DPg^4O$C=)4+M%bKsxQ4WwA7N)5MJBHE7qLmpJ?ZHu%0w zQ(ht2#OF-6v**!Khbi%L7D3zq5`z>B_(s%;vA3UNMQhEa|M5NB|KfWB>@sZRVvxgw zDl{G#dyG5}H`6BADjbWfv~mP>@cutQFM(ib3jB3Gx935NV&2CtFtd9SHl;(&Uuvca z3D5q=<^mwie_t$tmBA}=eiS7H9)~l8fz{0^6sWDf_PY^IaB}?(e-ny=8ld31?G5zm zt}k?d>Lgn|>S9DVRT%ZAG@07am~Bi2STTVlqJ|NyIokg9RTK+TlZx46&h8*NZXmB3b-t$5q8*`N{&UQ^>&ohvLCHCLkmdTLHjckur63?dLZGYbNV=UI3!-dV zyi+!ga1dy>N4DQFcFq~~Tn2Ny4<EN*F*N|9J@z~3h zUf+Zuc3dW{)|tWpX^itgTsaC)#o38|AH>>nqiqF|7=1jx7chzAc4g1XPUmZgfcL2WHEByJ zhoe-pwpB4N5KJ+cP=uhqw}q$Gfx!q~Tr)RUh|b6z(M38e<}rD$e%pEB;d(7L2YgLP z&>%@e@K&CB#qoSy<)4mH$?5F-XJxt&=>^rOX%(9Rn1;Wmc^J(^&JYCom`vwstPYye z!D72WrUYS;6TZe0??j4@P@DUsi*F10mL{mJK&r1cx`As13%DYx`@}(M$xL}Tf(435 z2nUDrzm)kVCJZwD=N>w7PJ1cbumroI^rpeY5$N+Un1rE0nRIdizD83XLg^$RBxNZe z)!U`TWVu3H{ei9oH)9vKQF+Glcm@ltb#4;lcZGisrY9?)v_J|^jEW!2D#v~w`0>Sc zQ4xe(JT^;?ypQ--U0+L;E`%}L-qLt4%6P_B>}oeVDxv_OJHzS-M-7$QB@LC}0$yvu zpgwOYrs`a;k&tk1YVojKqh>5r;ujHHelnezB5+Q^#zFG@4p;&@D8lqJ8Q9M$yaxKv ze&AcWK>S%1AH=|JxPkXoUV1WwEev7G20=nb!3M_*s@!4n-9E$8?>ZNpIN-B^9x+C~ zWmuz+!A+1*8|0iF*DZsyIO3|&IrK;iWgDWv4dIZNk9r7Nf@x}fEt6M&x+L^+YNQ+% z$wD%WL)MNjfh-vb)Vd_;_OMcr+{Z^PsT{kHP5kZehIh*?sj`A*&u6AM1~5u6Lp7@~ z+J0~PUy|znza({?mCWECH7pcxed3^_nkGXW5g-E?VOBw2R_K!4N2Wpgc)qITk4m4S z-X)0Hr-*Yk=`3*WBt?%CG{jJKcUDGZgd&8QGoUQM2D`;JkWN#p0KWn6YhFQNd%toO zz;5w+m`#rPfJ}lfkBd;Qi+)*E;3RZ{pE}?qvE!UUDUKO>CAGtsKJde-MU57Kzy*R> zJS2KP`Q8`wi#!vGC-SkshAvg?eG_F#XD^yJqfdsh+i|^Vv4bPfLSlX3oLX(75PrV) zEi<~jaUU8)5_iBh19u>&Cuv*{`TSNN6%&Kl)anwYrPKX!>OGgXZO?WTKe~nwk*S0a zWqOpvsLBsotmG$7IOKplLR9tl@)!8gyu@1_Z8Z1(9Kj>+$UPZtvY0f_oY8F0hHoBp zFQgut zBHFtBj+C@T_jT~him4sWg`GNBF1iW|Ng!uYpOs1$%|PB!#>|U@xZS(L*n4lK3f|jg7205g266*Mf#ZpdIOl#zF-l}!?%sDbVj1> zZr^G?2ml~Y&h+!WY~p#o&Lf@>;TdT_zoOx>GtkDBV)E&DfGfh`ahW(qy~1xuHf zf?{&{cz}YHnmyJ>6&HP@oPHVc-@}ftTHpKA=Fg9D;a(oCZ=RhCw7Eqr?3U%)p7?$# zPV9Q$-VRR3p(K`kNzMP({)s)5TF9MS#JwZ$Vt1{f=J3uAs4m~1DLb<($yGbjDZjWZ zVv+v???*QXj|iyoJ3yA_5OEfkKD{}=J+1~coxIpgDxC$fvGTpM1EpsEwz!^fET?o_ zSaKE3ab}|op6BASjIPFSJF&ei{_P*d|5vHc_1DFAm>+cn=#6)0m4*2qSmN(wNnxsa zV8N2j4G?8QFh*o?li1g<^0f`F_t>`b0-Bsrw-Ptu*rizRz zH5+4rSUj$E>!Rr54)0SO8b)g9w;-E~$%>27-<&Z}w%W=Rhf?hi#5L~W`6HRFH1>rd zL>PonF3{Q>c@diMmO@n=XY+k@z6EXMBJOiKKz7s&PAs>j(7 zQY&j$*)fu?uzr^+qc6E{%ys`i&B&4tbLsPe@z%@dI3YVQBiWFqjxbt#!Z>vG$= zg&m7cL>A+r?D16ED)bs(fZ0_!;(y*BQP|MWGdI?~7*%`z&{7|7^q(NI=l!}lFk6XP z=D7-Y6#8#*@?_r=Nmv&~R@^MzZ$B?>AQ8D}U7$wqHW*VGs(&PBZh9yQOf>40l(8I5 zw7=F|?bZ#ry==uAdow;vK0n5K%dO_Fn&)~yt^FU0FTho1tPeCxyR2g(g--1`Tz)xh zx zZ@>Na+i$=9_S6{Rvoo&}QgBj3ESK zNQAyCM*V{TjM+{F0TkbSyZ-tG88Z6;4y~5A=uUDB zt1oIuOYFDbe*5jW-+ue;x8HvI?YI9J{^oBqu>3w33b)9R*$;4F#TyI(ed`rtj4{TT z{5peXD7?)WW72u9GIL(-u~eCX|w(r+<9dkjU8eVxLUw z?_Zyc%1_h&L!w>j>pQvqzb*FLZ~xT(dReL*AneOYEk93S{l^@QnXdm7y|MxXN)nU zkn>jx%ruDAq&|{SBnM!qfENNHqPA(qJ$qx!xMX*4TMDhZIZ~wXYDXbCGT|%mSJQTyL>4;j_M~EnW;t`=ry*POPOZ&@LpSU}XKT&R@SVB0m-yuH@jV>d$4tNq3N z_WxbjZ~qzz5ydNK0x0qvPRwqA!yFfaoldrFeL5o|lt<`?hlsG=!5tkQ{0iUf$QWbB zfGR&1F(~X>Mns7d`2r%r$(DzWPVSkfnC%4)z)t-;QJ`=zOw6Ht*<#GtP}q>~r?NAx zwmBwL*p44ByYSkb~vIYeEl026RI224i~ z5x{^gBW8$ETO!N8$ccKo95Yx5+7_??WPrG5n-u7@jr|?!M1W_Hd>x-50J5cuK#Ty2 z$}E(@_Sk9=+4Xdc0Yt4LVq02u3u8cFU%3P1D|;Qts@OjJNtxIR#9#myE`Zio){@!! z&8yFUdloZXzwZ9{cyw`LFfAP_i5s0auI(=j$C@Z%$Y(WBGp zKm{Q9{y8G2?3}yj45$<{Kp_Artj|!9%ucDj2#)r_p=%2&KA-h?#SEwss49%<06iZ8 z>DF=IYt^dCzgHnf!CaHk$cssEF-j=@<}fY3m@G#lV^TSSqad1_Eyt=ixJcpbu3A5o3Dh)|J_r z*|b)xrJJqR2gD2_Dhvz;gVarIumVfBH$GgNZ>Cd|we-`Ezf8aWYC7HA+I}AZ4i4It zGw-wY#+A7n)9HMDCY`I-)A^gX(y6KIX|r+nqi4T9f9Jh-BXBRkVLs(RRRuA33osGl zm@#bPD8j$&U0ZC^Rv7-{IF4fibep=dm6sx_4c1hew7qnQm+qmO)CVlBn^@qj5|o!A zU@)e^N;hDlbfAr~NgZ1+v`yOFlcr6R7J30R+Jd@C9T$~#T#5#R(x!=Xa&o-bj(S-e zK@mJ`_=`TBBzAtsKDNH!|Noz3oWPXB=`dNW7E`mW$>eMCna1wkOD^K-S?)#Ng_ zdIN>BtAzm~;V5(D@X^xt)=<&0Z;zLBgihsP>3hjJ=a|&FO(i*_|A`u{P@zJFiun)< zb*{8ptR|=3X6o(jTL%9EO-~0op3h*XblmUvuWYQhyj^+d=)09)A6wJj-u-GkiYZB7 zB%&|@j+v|5iWUR7?5!(3PLIjsbemlEX$D$?*|%=oT|`Ukrh*|XYlO#zAOIMRG!TO2 z;5y3!a2%B+4dDoS;x4eH@dzQgjZB28W{bl#lXq|a&Ekl%RhF7Lz&%A-Hy^jSnx03W zF<=Z(^JC3gNuN7fL+cLgJFr0xw9pLr9ll(5gTw4-Xg0fT?m_^1#(!D(v9Ve0>#M7( z&5nA9xv#tL73v|AfD02brsAuL((cagqPi2+C7pq;93xACFplBO>9e`klg(yJt<`L4 zuoe=W+C!0IDh^ea23i6|$GiA zPk2TG9OOUn9P+0R0%R&%5ejt_ggQHTyUot`bamw-K~RDL6js)qA(>2)LKxs&&*1VC zRka)44jZXXK{S5_66&mhV!%PFI27<>LL$B<*g#-QUJ1 zgByI!PqiC&@BDOo>E@l=to7bJnvya%v%85};L|;%w+>r#-WTQN#Rm=^EN*KHW3AKc!00b#(7l&9Z24fQsHfhqC#n{m$UvuWy|{KTyzcvf+bIKHj~l|6Jd4 zT9$h}?<933W%G3CR6$3_DcDO88`r@ScIosmr77YR6px%-I6Vg> zCdx?;BmngP(w`Zgm}E2}1qqaZ%fDaF!bnPh0B}YCyTg^YeaD{S^0NKKy}iBJ1OpI) zB%A7El2xd9hM->K&lrgG!UQ5?QHb6XAan6cAjUPa5Yp7#F|(K`?Va2Axh9M4y#yu{ zi4$P84Cpm_Flaf5PR0NsEZc@Op(6q*;Y?5 z_Ef&F6+wd$PABrShn&n7dF3;q;rj5+7q1WBST#B_y6Vp8{S0buNoQKpGwf22IBkuQ zGeZBli>q~_PCh<3ngD~=09S^FS0RDG9Lzf*Tk1QBGSW}9I(I@YP?&Ng^YY#p)QA+8 zoP^h3%N^7kD0ztOb4y>4oe`tK2pNl)DwP<7%r40#4@dJ4TL$vq%)dp6+S|0KgC&LxVNHJi5FyfUK!zrv0UgD_`1s^M>|Nb&99I?p z?VY=KXJ=>aO+u1~^utY3YLk-I#E?>nLM4iLi9`hw6si0HJVDaX&_+&3=?7XAgBz3@ zN)bYkQs_exglLgk5!45GvD5}q<0fwEe5~C#b#`aRcki4z!)ETt+u&H`p)X1IXaBUL z@%7$wKUTl9_ug{`V8AdiG&Fc_^~cuM(w#U})PsXtPE=O9psc;K=Ps_9JaKa1{PgTV zSPv@9)M*dNl#(q))~E6^33imbPjcy^i!MGgkl>KolB;^iROHWyl~r8 zkdA~S9OT^s%H=ZZ7aRVuSO0$h@UD@s=VIi7y6NOl03azNmSaZ)l>}za%&a+ma(ZC; zt?7Ze+Iy8Supt@%qw}us*HHyQYEkF@4~ID|Yls&^e*gCBu}`R+gzONL6O#iky5um8XY zB>i5Bga9QA$Z-yh`G%ckEIZ8JkF)u(5|^6YjqI)8{JXN-fe63d+@YZTaj8Apj|DyPKCTt*M=@4ZMA7YT%uz>5Avs(;UWJ z=`W$P5NGEUTMCw4{qLfS>j2l>0tbu#Au?Y1cZ+UzKkFf#Jf`{(E8dU|_%ar3$xj<578HAxQgv4=dDvb+xhMlh&N7If7KrW_xx zS_#hiD6LpEyMEJ#@r}2yAHT8hrim4m-ewdVXwBVaq_X6*gl@fq^dp6Hr=*3Hgc; zT^7qcg&t=`$`X{@Q47dDXY5^k86y9*4i#KN!w;J z3?`%`LuuLczNW?eCw4aos7OErfJ*>{W^w23YhT^=#(}3ttJ}Z3WB>5porhTgApwzT zfi)wl6BZg8uJVwD(7;vF_Dg8{LsCk6oe?3d4N|3bMOZ+S8;A=Au{4nB7zrofq1DcJ287XtnxOb?es6Gs*+B0a~pHCNiKFrOpy;$TX4ylBa(3gR$Ma zhev<1zgoTL^LNbH&%3odY>?+Wy;yipTZd9Ah|~rFna&g2Kfc73jXB{Zk^$XLxx z>ak}oL@2S3VqCC!8axjWNU2<9FIYlCrvKZa)nZp7!*a<}VQqv&vH&sl@3;FC0*VC{ z#Zk;Mm&fT-r~BTmUGk*0Ed^-<#a4q9I*S}iw#innSTjJ#PDa{3)!M*l0viBiY5juC zUWF{g2l(=~FTOGQ^Czl%e)#bI?GJzZu-0rfRXT_qAc_br-C9iMoxU1QZF7aSOHi9^ zU$Ll{fVo`81B?Mm`2rjUIEf(h0v$3WXy6 z@!D%&s5hFfrvRg^;5Wli{_({lo2u23`*uIF=UY3sKl$K~pLlNDu~+`NF$}a7dlvZX z%df0|^0ASxoSiy*yMjWF1Wvs^(9`d{P6*B*NA_jmo5y=x6> z>dNE)dvkMN{m*&6o|F4pUt9lc(n0!CkqL_e z_#OPW0ffD4>JP@4e(&}$6=3VGhTJ-bpqmx@npy7tf8^xU0v z_$kweOj;l;`R=<&YW{kCM}XZ<(h(dO8v~q$d!9ILKtX5nq%cp*%FY+wy;~NUotwA5 zQRR7O44}NSB6$D)jLp{0u9Yq)0Eg`hO^r=q3VE*RYSHBgty&lG&B=2jX=c9Y)QL+U zKOG<$!w}UR0In%OK!f}d zrKJmJV>k|P`uq3$a9*=>UiXE>q{NHAi;Y!(^2u*I_9gGR&h_O!p&~ok7!JKQ+ad?y z1SjcymM~)|^al$#$;rw8IP`UjEIj<3R?5phHarUVe)v9S z^y&CKN}u64Q{!WF$cdHSxDzHmCKK-1z9(VF_T;S@>C%m*cgmKN1Y=xxOps7nc0V{X zEo*a^wR`&kF*FPOhJh)pN zSD?7Ew!e3hg8>Q-=QE_4;Z<{y4l|AzlHmbBf-m9*2=JfZv0%Y`D|o=hFr>V!Is}_> z()9J(coMN#Bo$|gPUf6k&vF5R&z#mNKI3)+nk_yl%#un(vg{nu)1e6#jxqYZv$b>K z)k{~RGLEKg*}F42F*W5#T)~MmYoGKEaWIl{bkL3w`k-G?T^1yh%VREHDHNRlw(xxn zL+K*(Q!WywU2adK3{cE1Dm=fL^E;q0IXsD7E4m$~$SM&2JtZUIz|O;4b0qSOb(Iav z2`9B4jI0TQd5?6vX-5e`OoQ({UubUW4LE(OXx-kwWqh8NBH2_^RvQ8YUF3d_Z)AwG zg%#D6k-0L(dY!&4fR4z-m~>whWdX)w&DGYzxfo5i6pAy#yZrazc;rm##8&$@c8IHJ|u98h?nP?VdMD>{{*|1sle!sxnb z{yYp^lYmIl<6}sHsd)T~q#ex2EjTZ+O`07j8M?td~*EY3{u5R+JgULS3>J_xe(Sb~-HwQJ6u zFO1JPmKis@ge`66B^rY!Vt8nfO({vzMM8I%by;1lQqW>HhmZt8M`jckm8{B1mnYTU zQ*N-dSi>iWr}!Pl&QMi#V@&FS)NPG*IzEqwz3|qksH_Ne5iVe{FbG+(qW$gA6>TVs z1uQ_Is<>Bg9qgkM?SAC#SY59bM1e_{{iqC`lx676`n@rJKtwvz8 z^#o#U+(i+RqRZD;rDsTzD#|N2w6}GJkB`{-&CSiBwYAEal*5O&sp>SI@#1q!(bH|? z>-1VdOG}HuU^Ik3vj_eMj)@6c&Y8!>3D=8@V~qwwwB2qG8W|Z0HW&y_h4Gs(h>h${6o?^D2W@i_yV;moh4755! zl*w!s=#6^8h~4goVoWLuB|n$TML(V7H1*xNrf$+i)z{Stnp;c)OSjdJ!v$z-YhPmN zd=NoQO|w}T3mlUU=Li| z8Q9VOAlhIu3I?7G@Y&QBB?$UPA1}P{!i$$3sQWqftZ)F7gTojx0ZD)Psw^!lE$hoa ze|7rp)vNk|(q(jn0Ik=@=o(%Kc$ynwLjHd;=Z`+TB7o4hs*FuAz5)*KHD|(SpWUSX z%h_x;jE_4w^-5(BPS@okV8mnW$P|kcii=BPwK{$D;NW1;;NU>8PODpU?(Et4BS((L zIUGz%i^bZt#Aq-@APCC#@$rFaVj3Rx_bt;K3<6a{V+aly-~_;(lG0VjQ>97OrPUjH zEsw%S2JHOK=FZT&-VD7|qv)~Gf|_jL9K zJ+kx%t7|lCiq03sXQpOSJb;dxrQ~h5Q>iWlP|*_zfg#P~iWo@nPf)=AGouAWwOZ|>*?y>bR8=Vh^&VcS)9D0V9(l14Z=#A9UU=|}JsZCw298&Bx<7*i=D)RI zYWKcfr?`IHzKvTp{hPfjkB_3t)~9YQUA-iojSxTx1PGzo(dZBm5pZK<6&?<6d^76! z9*pA?9UVtOK_ZGGDsiHY&cL{^jDRzW%ZOtTSp`Ivq=6(PtXW7xl3uH;Yk76U+QU57;N3uAkLab?>bTIbWUgopV0)49scpDF8||46Ok_HI5w5;g;(6iOcE4m;ZP^ ztxDM+=X;m;>Dw(Jh=Ly}lS(iG^|f{BSlmq206zHOg96LQcSriFqC||$%*=X0;&r>r z4j4T;bE?Mk-n$zF1M>il0`6y2}&d={dMh{X-WVKSZO%di`F$k;W*&xYHIq6q5y>BV9dDdDh3W3 zTrS2s)SRuW&uMH3%D8k>2O}$^%TYvx(TEP)w(RJ~qD~qGNL7_px#$+b?*|ST-~~Y7 z;dB1;v(IjkB!MVl71Gnv0x78}El#HcYhNIElUDt8^|U|$AP`{H(*<6zl(+sr2;2{O zJ{Bl@XZ5Or+Sq3eJtOk1{W zzLDcNrznacHFnbwTz<2E|LD@P>I|TQa}1#4iJt58`RIKl6w43wRPzFazh68ktm_x6=>NH_A0&1(m zK@eN~{;WVKNLifSx?NExAp?#G9j-@cstU6gpmPxPg}^4;;urwCVYwUv^vg>LxZNp! zffwnqC#p}RgC&9_z`Aws7ARq*JGHsM8M5rCw`_ur_CgXxICiYk^T{U`4j=^7NYnt1 zGc-*HNtEb|JR!V^-hH$YK3@Q;t4}#MefG~=L`fuQ_hq|1V3!>&L?pBxNF<_2tKNBM zS}a}mI|bLT>%di6^&iltq2yZ*j{GaHDhErNn$E$w=H{H%=AcaNq6kLkPMJrM4U5PB z^Yef9V+0Pgk0IEzdv`8km{2eTeJtA)2q;i*;g-!MCAS0uexhnRaOhm(`4-JE!R~S* z<3?J$Zv8Y#5|Dk0is>h~7HU&9U60kr0uVS3cp98wDhX}rDH^O=v$~+6sj+)hk3vuh z8Sd1idV?6cD2otQ!*JqcmFIn{pr=afZL#N#K?%fXXzzD_z30Yrz9wgss3BhB@f_-4 z+P!=C=pzS@WGDdz?Kj$4#DjEhqKM2%h6@E63^TzrnNpjr;&+IB(g6h>U`jXy2E|{* z;04j(d7e64kUb-dvf0||Gl1}>?3C54tS*&^Q^Mh}71-FGCkTYHL{au1*q=uT0h1Uo zaPS~+NC`ng5|WTh_ucu@ob~@{nWSS;#vcU(tz&^K+!~x==?^=-XP@krrOTK8Y0{*h z9@J>QDuB%?f$WewumDK>M`$-7VcS?Pt`3IIqV$FV9n>b-f=F@X1py+8k|xQ_7|;H% zyGsUp2Jg(t&M7Z`x%jzfpMCbVqF0KRcJ11&kw?Q6!3x{^axk^_o_p@t`qn#d6uR8W z&AP79ac{l#){U#*T2Z*@sfFt>+LYBTEBLE>?_A;R>}Z;L$JEs;*T1;z`Bw^;Uo-BS zji#)DCTdXMRG)h4%$XDf3l2woEpdkqvMNZd=10kLE|9FmISpYYx4};kDyQks6JAaE0_|XjJs~ES0Dgs zX=%aV%(-txMrx;~SujhDAYhstBqyh|KEB|IWiP$7eCf~cxMMZp1q726NLk%w@&VXsE|&|w zM;NfVfHuu?YZW?PM2&(0_^j{T`j?f<3k5-J221dHUw_@0jqj~nTlm?O|M}_V*WWZ|W5iTIV=wKgCr+GBf$tG?&TQYdyJs*Ea_E`{NiJ7y z_Z}I6-2T1J*<{-}d}$AdLZqZ*bFL(@7x{t_Kk=e%vdgk%o6h999BhAbvIA;s>vPe` z!&^FXYjDn-dslSI>e6)kFMhuInW7h#6|a10`M8M_HnyrN__ZiBhr_8y zPn=8vhEu5Bizrd*Kp-4pSPP#aWo~eB^#wFQ!Ex@pe@;p6puRh^`gAUTuK1bf7A{-x z+DmV|u(VUJj7CF_f&yVUbm(9XbBf?OcsUZUCXHIiE#NZ@du_+k&AH;I0H=Xd+K)(JjO6I!H8GCHi=HZ zGvWVNaITyQajC7Tbw~oEej=0O{<(8E&3o*zwVg6kBQ6&@5`;*PUOkRTf{hlI_GIq&Pm(`_fGwU#d^X=cT^qD2a(P;?T>&ORoHhL9z*YOylu|?_uai|-n>WGcFK?=IEK^Z zjP&i>`v}CvOrsGXh~-qX2nxO4$ZM|IncbyJ08?$Q8#$^XyGQq9xF5l4C=|+!7cs+7 z7h%AP5KH6UBizTdqjQe!=Yhk+zV|N~bLL2J{qS3nF4M}}O~q68?LCxr zuKAoB9WdRyUva8y*Dihp?*altA@R2(Aqh#yNpqONI!h|6s0GWmsh7XH8!QA&9d04b^ZJIYnEi7Y}Nq- zavNTJ@!8@VZyrr?Mo0meHr1N1jPn&~k?w}ZhSWITF}Vw#H+Rw0dP!i#=2@G51@3>~ zzD6TtJ`GOd%Z+Y7f zV`(zy#t*FH!7gtwpkZFPpZ``PYnnjLr?j|QRE53VC%Yu@wfd#??`|0W?BZn;o_Ku8 z%qJH;HS55^1O2s#3Y=y@RM9w10ZeOOTcdde2@tM=`Pz4n$z@S6}y)2*B67zV2fh90fvy1`hPP zToSElPGX&54(vbJ<%MN`9J}!GrBmn6dvey(g@rThc00$I5jb{he7-ueWl(XhCJnt& z)lHM_*9}@I7BsdNR2;`jrJ?tE@uKAu7A-8C`NX`(XVsiO(;vYE)Asoz=tSZSgLc5- z2vHCmw6$*Qens{PffHyy`(SG@8Di@|K-b2qVAL2AbCdwvPdMPMtpMz6-130?2=L6+ z@h=o;12~f@6IN*+BZ(>LlA6&etuiUeMSm~8EGfyuTd`}`&OC?12Ei~=fcuoGnnoQP zBvBzfAqh#yk67BZ(biap2^j>?LJAnc5dXr{&rT~naG*ffHR{~>Nx_KE?)c@5y^02` zqnf6|#l+x#SjG&pAq7j_sc9{sp$#_%p8*EPq3uFeh%XQ% z7di%r@h|LHgQn|nwI^%(hk`-ifrpkBU&?E5tQr0K8>>e9T6{^k509%nQrWxitY0EP z+sEp8o&iT~yhKxNckJBJ7uULb=k7jsn**@>N^WkhH$G0Rfarm}hr7J6iywMpDLPA z_}KF^pPs*XR_Wfu{ml>n7bT!7I@cB)L7b-P8fE<`Y6LQ~G8Ko*0UBsD5YxY3zY_*x z1P!dYg_4pIX6Q>R#q?PuS`S-@;P9w5Ul!OwQxgEBfh z)s(dKO2#m8!LB`D<>3Xl@7R$S)mRM?Pyf6!LRf3rgd`*(m#$pq9P30E6%>P6<+veW zmcXPA3Iix2_%4vcgtWhvCaTG#)(IV5`7FFtO z(Jk5#Kz&$5b&*)X4!2s~{m%9|p+hAi1Y;suZiK6#1F#pLimU_-~3L67G- z;1(=;cKYd)r#xts1&#m$Dw9zR*!m2En#d4#_(&!lew#1?gCOOr9lLr&qYHY;CLPZ1Z7W1>9Ls4JpJK-#JN~F zZxe8M)7lEe#N*j@=mAjxPNNgy!KCv`NnvelLq34~tMkh~`tXxHbR1PxRQCoAc3N%w z`tX#_N?_!*qr6DRCPafoBm9IUBq5ih5aU8@5Cv0Y9W;Q`zvURx?s#-~1e$&JCC@x_ zdqaIw51Zr!o#V9W(`WpB!cWJQsT$C5h)c#azgQ{+`Id+pXN}9@m_~bNiXku?O;vYG zvJF{(&?PggNuz}+36zxV>hbQ|@6OV7!xl9Z2uGNG3Wb8msAQuUsO=ai@j4IWf+#-* z8vIQv_xzF zXgZ+O)Yc3>e&RTorcUvRD4{*laVuB_&-;$KaeSG>LEy?E!@Ont$_Al5JW_VF7XjE+ ze)w3gXv6@ND~Dg{#c@$Y9=N9#KR>4Lpc;JB0OcoGBxKL~DB};fRU$9CQNowXbX{RV!T)(dmJnDJ#cWLJueGB&@&cJB@ut_|E zg3JwCFe<75&@>R0-W1JX)>^|KmA$}YO#-BD5{&_osDgR3mU2-Dn?a!Yq?*bojtFrC z{8Rxy37mI!1jBv+UIW6JphgsM2rL?*T8c*SvrRjD`CD3TfJG#2G7Qce(4eV+#+rNU zFK^9Mm8i`w*`Z74t_Sb@#a$~Od|+;oXJFn=1TV;(;7w-aWQkof98y6C6JiFM0j`*l zT)XDO{FBuuJ<+I+Mpl_Nf=!|+KuO6?3apT2g2#OG_1B&h7hCUj*Nv>yL5uqReyFZGp6zP^ z-s%9-lZYI++|GuT3}gTW079w)b&U!TnjfeEA!@wsD60v<9R8-DfnXzGAZ`GL16&f@?)Y+V zuW&eM!5@*qxFn$GU;& zfWyXyZ2z9G_IUg)Ent^yXbyDN4em}3slk3@uY)oC%Arew)dJKt;6DLpd zjC~;~02%nDiUn5dlXw9!6+p5x$xna@#|eNtamyPFqY1#~htCqb(MTLmuaPDL$SSS} zZ~X;>F=4e_L=n%X_#qsMAO@irAoeQ{BSwuX4+eu8XeOMhsO=G`3)+=nv@7DL$^eLs*nrarrB5ci+@Sa{H&+I1bt<4k#1{Z6q`l+F?hrxKRS-lT z95y>OWLUSXxvp9I;Qi0@KHRu*3NML3L;*T=N;^Gj^swV-puXOFI0FlKs;Ww(HM8f; z`SgbILr)GE(65ntJw-5xk_D4P=`3U~$# z7{FHzuO`(WdT!zI}!D|!TS z2lVq|WKD^+Vmnq@nJo$;btd%a*6q-=$rDNk49sinoZcxI3i~+(Qz$k`0*7=y3TMWj zIR&ioB5|RJ0ywUzvjY*_9xbcNP(rE$3xA=(pZ)7OpWZlb)X5%KbZOT0sEM6V;;apF zfm_gI`=Y7}-qORp0T5KMPA=6ast2%s_5wH^&Q>D^E~8omD8k|iZdpo;WT|Xp4md3S z6-6f-1E{hL@%kJ1iSy7{Pkp*=X>Bn97>mS)&J@CW^vf~>KCUD|&FtE_G9@VmG}RQ> zu39s~VRvw%$Rm@cOp+4bjf5m5AwM2LM?6Nf((lC9WD9^+oyzsV3%YFv}n}H z(Nd>MpKSa*Z~fX0Q;>~-fA2eGWSt&AcGz(o&HZZP zlt~*VPPR0*9W-pnZe}|PoT)k8Hxyvp2X~5~S;f*T(B>MZZhQZO4~Ey*HOQi1gRVWg zc|-UtG{(lLsw&SmO@lH*`uFR9XySyMN(XuRG}_a7)>+LF;>o0L6RNRi`olI0qi@cBjCc|C;^jc#5~WG>f8OB5p){ zL{m>Cc0W{0O+sk56v-~a?tOcEJ7ji`(X>_`s~TXMI-P?}5?gUz5KE)gF%1Q`rU7^k ziX;la3k3Xr9}6@I0KP^VP-4tZzT=yWAh2hRYz$3j^;>YQvWqc`S^_?BBstZd+1Ztb zW`YDZ@x6EdHo}OS9RBVUj2vA?=)5kwm!pIv(*AVfr{*niCP{8KMXU$*F_=_~&5=P`mRfJ<0T}H>}?Ln?tP-6->DKwu%41(~&r#nbs#Uf#b2lx*tCN zx~!f2x=FXieIwnse?IZ>|`xgU&gVlK|z5&0h@L^5r*KjGl_x zzN&U<>7njEzuyIxq^75vQ*WERb>gInrIV+QFTHir^`$re^rq5@lP7L-r=~)Z+YMn= z6}N8R)+eMG6ch{`I>3wTawa=r`>w6mTWh5Zn4c6}<88ZrxJ3r3RTzshRgRWd_NuO~ zNjr18-u>DiUmed&BF71YIx)W3y2YCBzAT)b8Ds0jGmQi`?S7uz(>myYUr}YpSEVzJEQKO`|!ODO$|x@kdH=Ct{!o$Yt< zp%DHqXq07i)zD$ypmiZmk3z-K!y|%$0G<1oF<7A2;>IF6~VH zId}0N-xzOjI+jR1*bY$dA3I?PCdrLqj$wr%Ndg6YD}WU_2GZ~xiM zt&^u%7+~7?Qru3ow$rCg-Db0iAUka!Nuv1aryuue14l!K4faNL70@n!Uh?_%E|(p2 zU4?>zYrP;a7NXIv3@3q#imF~!$LrD>8zSyE-(EA`Fa=J-MR6i*{$l&E>SI+|24Sqy zsG+k0-j+g)!O=Ij&uL`w(l)MI#J#-u^>O9Zr`)nE8Q94VnWW)p7&et`8giySB7eEP zEZck3I}Dkr?$l(6M5FHF;=dHcy5OK=gLWe`coS-BPhY)o(aY0TzP)zTf8Y1;y^0b{ z;siWKf?@x|-j&Bjd0g??du?NzV6IXQ@2+>f_pT4j>5xF=sw5#Hh$Dm~1|PdVV~l~2 zq;!oUR4HvPsYs~^{R3506xSR!&f=H_46(7h9B~XvN>dRko7kAs>)mg!*Y{=}6H9IX zXjLgKJFA~({msmq_ukI;y`R3BZ@#%XS7-!MJMwQBLWnTG5i`0V6Lr)6EfDlGYIAe& zX6n1|?OE18FqlfZlaFKyY0Mtc*mFpHf+TI~#Cu|ii0?0UrS}WthwtxOcH%_4IuHoZ zYw-Exj@_PpMJAT<8%>>^oeRQ|*ygWGmoDY}BpjbBji-2ur~h{PwCC=Q<{rWI9a?%r zli_6n}Hi{P@%-_oC9E(4vZ0@N8!n3GWoS$R7+EZKFC zVXlC(Er*Y^o(Gr53oh%zZGMfZ9Q3BmU^Q(AgQgbDx~*Wh>;RLg4rZs9!fYMNShW3m z8`eK|PH?qe2J91f-iGjCzl#cX_Nz@LV6s+0rm+GtGMyY+qZ2fiGMHm4gV|Z-zRI0V z2T9MC4se~u{6uG{-j=_4Fx^@VGmRTTljY>l&Z~yvxQV9#6+&Od_ z`)fQMausbpbX0AtfSHC8NVi}cdnK&i`0**St9(aOgK0q>%rQG4BfE;{RM)n6`@nj~ z{$^cP73su}JGM18v~)*YEvQTLvExQN);Wj$Q{LKv zws*&nnN!uL$tp*AB~Y;XSD(AFjP&?}`~GfSPIU;u^_!7d2%4O-TkdY)@;$wnccU#^ z4mN1*<&bHq0Ij|ZvU0b8DzgOg7Vj8vZa&mJ$AEq@7lYR7fSR|CG_;}Yb&ikQGO{aR zmZb!8mcD+&?8i30cIdTXVQVrAAYWkyJo;Y!VmWRk0Xva z;`mpfxcqp*u70}4nr*dUG}nO6Q29MztWp<2?bhQ*Jni7hf1>`cdUF-%t<`|n`Y~kS zF@j2u^)t)BV6TNezrFrmJH>yxmiGD)LhQR&;PEGGL2ZAg1!IG$3bY#J0IE{R&E5{# zwmQ)2$~h;nW^MMp={j|=!wW8o8K*Hna{=lNd9{N-)|X;DFUMF}3@U_uRX`j~unrO| z!&CUnS`Q-w$)9SrG>qlb%IP3=Kc>lm&$w5#y@1c$x%YEDWb85|XV()-0*@5t-F_PWQOvz`1QjfL0)Z)EecbF*XZRK=%V^J>G! zE5UF9QoAvNAk3CA!;nhZn6y<*2%m6)+{@t=R3#@;+(!JS^2Qjs%y%c!^*CRdA4PteE(I1`Gqibz~DPe-H5-=Dvk6 z9jm})h}ah6{MxoLWkKG7w8%u3)eYluY^|qo8PDBA=Ccl0KJa{Y;BbWazPUAm^0*#D z5d*>;^wVY8dlnVIoe4sTCDE(})!oBQsz;Cn(ww+GfwoLt)}cT9g}9z8LmTbXeJe4O z{bVCP#(mfB1!Ok##6=8o_i%UC-tXdf`yn>r_d?$?SV-v$tH<|3+qXYK!aHE>5T0V!RL>c%ayZ zk#HbJPM03|9p%lf&9-7maHHT)an6u-`VZ1$)A=uS61=rm7vsbI`AD1hQOF)N{Kcb%HwgvZuWJ&?irhL*0Ub`yn_k|W0qr+LQ9?!m4%Nck}iXe_1|4$`>cc*lxg!D{l;g5 zyng;|Yz(k4a4&Y4lB?)!yL0TS7Y_!o58ImJjavl7<%DCINWM!x?~z39|A9u??l>X9 zAdx#yp%o{4hK64-hy0ai(r`ChSe5|umD+^tO&Z-Su+QpT2YA~q_h|wl{cmy616_O) zBRSL;bmZZ43ABW~+^+g6v21^IAaHt|Vn?!h`8R#_y>ptWXJhC6~azT?Mc;;W> zYEi8)0mAPR+Fy&MllyOv{8nkdCEgco=D`NWvZbZIs#GS{|JtXdR+dF&-{ejppKT^T z3PE_5OKGK%S0IX~rpq^0{xx=R&**6MGihXSWWTR)zR+48^S~?q>0PLp``8OFCm^C` zGwk1LEJgF+^UBl(5q#BwWsJJ!uEQvL?UV6T*^c^|wJrYUN+m7Tge`W%WD;#za0B4cAhOX6FWk*IzsaJ-_W zqhF0Du}Gayr|rW>ivnj{7I-)9Hb*@};WwP^_r#XSLg0uESo_tj74I-pTW$&nj&W?3_MxDGrw2wYxMqgXa~_~I_i z2H?h(i|Nz60||Kt;D$Y5D!40c<{_rHz*G6pPTKqw*bp&yz=mU7%m!q7#fE64eIWfBx9~;e8+}Ff>=- zma)AhEBp(KaPMYxvNz_r61a03y*NSE$wAb&V%xXifT!n7)7ixzvgovZ8#T?E*%3BU z+d1`$njM+yX1W=002d2;));j5=J9h*VFZn`#=^Ndz~or|{EuFAfQp%k!CT&G3Hq8I=cFbx#Mu zMWL?@ia5g9Ws$(3!}-;@zM>t01SW~bq7?ySBoq$iAQ~B&gTG?$(e^lmg0x;+>Na|ch|-*meY(jEgw%YVz@N-sAH(d4?YGaqWS1_vJy}0;D|z+W7c&f*K^g{Y z=gjd}%^9<3U;yRD1eeyNk>tl<$d3PVVKN36TY{*FZ{De2sv3vA7^k44JqmwFn zD2FNqb+<3B@@D$7-j3gq(onzu-OBY%>h!X(^7DD9DN>Z>KVp7;|MU_PxqX$84S$q1 zj9T_&O~KP#L6jJ-=_O7$1oS6ix4Xu9e-Me~5UeIVWw0bUTf4=;w-Cv5eUCRru+V$Q&0o@yLoL7;$ONm^I1=nhSLM=#vFP%0Qv zY%~$-?bCm?<0-Y>bRQw-p(uxVLFu3E*K5lZ$8*s#6e9IwTvjTDx0cAG$Koy~*@)o! zky7JgJrld9{7t!j=Cb~@-3JB z%b$yBmK>Dvq}3gA2m4cacj@t)uRV9xVaf}rH`aD$HFN6`JfAQ*>Yt;RR~MTrXzoZ3 zKY0xxdQLk{vRQR~^mfO*RxigdOWY)y^+P|RFY}9bihWL-*tGY}BTUrfzGCA07=&5w zA=p&fWpjWFt{HhBK+SrU76W`iy)w@6nWP)9WzwrTM~*b~#z{`@hS#WG$HgXaBdvHp z3l_9Ln;Na~;H%R%SyxNWDi$G2Da~6x3XkMz6px18wDYO# z+)Bx}*tWl+p-po&oA6nE9+CBGie>RgmGY|NK$KS=F3K9WB88Qs`UWl$b~O?*I{*#8 zTI9=DLWY6D&SgyI#F@HE6OWK}j?oacLROQnC&n!$2EH;Mnkv6-UVi&xccaF4_VG9C z9%jnI{-&SQE{sGYp!>^q^-J*h;U2Bjc{~K(-w8T)M}BcA zcv4bs^n~6GbW$NoRGNZdM^VIc50Pc`9?1bAU*ZMPG%F7y{~#PjDu-4%NIJ2kC>~C&YY4r&&2p~pwnU((S?Os&VQUsw380mZ^u)Gk(ic6o^k!6(r%_(- z&`QzHQM!5sWVGF%K{%U-(Av})`?xY;Y`;+9pzm(j;Qlm5=GWfKP9Eh{aTDL?9uvE` zsk;g>N!!XaK}59iFXL;(7ataVA@@?hkl1i!?wx)}!y zN6nb8sTGj+TP9$CTC-rBmsOcS_Cf5vbCp)5g}_795nc^T78jSbb(g~N;@FOjwifN5 zKt8%vM0dH1;_(Ao)5VRB65r)rJTA05PfZ=*rn0QDp?dwaSkY!h({}Slo^)SXRPIj# zk+25h{mVss7YRD7?-gf{S@Vz_7VGvFgt5ImG3&ag`Etx}=gF&LZZ?0Q;JBo*E(bCS z#zm?q`9Uf0KQ5QAfp>n?O|Z9jiap+sZ$O+_Vq}yXnFYTbq1Vfi;a&f*sn!65)VYkX zy&)LbYV5i*qaEI*NRaRQ$Jt1%;SNQAQW=n8Z8}s$`b%r5hKNRnm*Lc-t9izLiTCP# zTh@-fNPsy4q5?Y`z~&6f@*LKaM|+-Jrbf5JPv6EJ}3d=f8<4Od2QO9)>~(MpbsQ=K%2{PMoV4)*ltm+2N=LU zz7cl&a4te=$0qBr8{c~1#)HlGG1rc`rz;DhZKeisTnEwgpz}s8Pd%-n{!5mxoN}XW z$JX%T`eQqw?2cW7yWp?t_h?Oo;cot|JeS4v{*|5A?l$UAafeXn0zab@d?hS@spY&^6#)Gdjr?UH)^-S!im+1F@T|O=@JQ`)Z6;(`C z8P_d=!70iKB~U+}evEuiW$c4RquS-5#K*kBioy>hoKh7>?TZYu+s1G|x)DN&W9XB+ z>NnO7aZpe_qF6aKe>tB%Uzw5^-BO#o{|QplR0mFK&fl{$=>P>6XC|=Pf0Uk{^Y;n_ z96U4gQ1c&hPaOEK^xc#JiEXw#EZOgUoZqZ$HNqTie-w~Pa88VSxC+i{UulKM4GZc& zX#0tEA;P&x_jDk;=npW8V%G@?!wIH%q z{7zZO+uluN5V8Jd1pn0l9zQhKDA|Bb&5;JZu}}@D8gEi;*+}2Q8n6%qIpd+ z5%wHqi~`>I*9V6H4kXXRI&tN=IqErx*8T40oqhRYrTg`k{>&fz&f78}dtnJQrHF?% z^VBK45>!Nm`W-VmpEVNSy4jx61fOlZ3rl#$%oY(K$~tTWb3V*HbPQv z&o@=E#2|M^$K+5m-()E(AiZ83-CR2xYFP@A1tzdu&tmC>|CsTd=GNb$cz0lBdRN)< z0@7XGaOq?}G>6#W&Cg-)9Y}wVb90-Znm6uX?3O+bkBo7B<>xm; z!(;C0BNJo4TE-DJ;`KE@`W6>jb~XF2(x~I&N3A@mG$AE2X(Xh1y*0$~(>6>*RAy<3 z!7358Wqgj-IZgK}e_F4C5fl~b9i*o+BOW3DvRIZQvy=T`CETJ*SBg66rMK&A4S&wo z$6ZBD&(mJZoT1;x<3|^V*YGA$VKb6AIL)6sB3a}%M-x0#W6=~>`$>7paXqHzuk758 zN9;B^IO8YUQR;fG2q{MsZc~uo?#^Ix5_fzWo`D%%A)%fgCg98Pp@LfeRSEZqGY(OG zQ zsq=SLkEvdbZhuW9i-g!D$*>1#a=C8)!MD>yGND-1@!jb%P37;wLWOXOW{qDD=xJvu zHfO8H=lSKiW_mtL8EV^|5M(3%xx{rU2G_F1h4woHnKgl3A;E(DfHJ1Tqmx;c@+Cvo zcLU$^tOr7d*D1DUE9Om{%}wMP+n&f05++giQ{~bctZE{VL)}Yx6jPTE@K7>&xfQ00`|dkD;Cx&$U3hs-Dkdy^FX;8b!U1vfDEek>{QJkl#R9Ku_WKIG_;--n z{M}uns%!xd#}C_%uDYCy3k##=zYis61QTG?1*(m$qf1Zb$RSY;Y=5eW2&D!P#7_=u z0F*W;r^8)_nR!|RhoFfWJM!{%?&f+muo?~EkAX_Ygncv-Iagem7*FYj(=?T~3u7-o zw<9?>?EPm*2{Ad{{gSGYm}@3$YkEy_qG;61rsLgIfLJl5Bek?1RH1xqct^^K4eREW z(NSBO*+6(oo<+5yT{JJTA_%iVK;eXHMK9j?K`gbb;Fe~uiwWpD8qBS1C zfCwt(yx-Jd=+$fhWDV;846}hhAdcq0S8_CPlsspX|5sN06?ke3etNr{!=fWCx8q;6 zt-JCs{1V&X5@3_`zq>sCW5WMF{{NgjtIg{DOE&8r2j4ycZkRuVtN9lLxZS&dWnEX- za_E25k&^KK&rxw3d)~@&$*8cfyX!OdcZ%JPZ$5=%FjC_G^ONrx`;8P6MlyM8EK+?O78b@s zcE;l<0si|754kxx?jRdO2`3sFngwOfWh@doxxqM$)S#J}B*8PC03@n^FyohcVm@-a z1-MJ3*SikLn8gbTaq+>UF)sor{0nRQ=zGklSwTsuvlv6acn=aZf8$*im4-gF8z{?; z769=V&ifr0ssP?YFM;e+d7d#Y^g{M_hf2w>dyt>~tibKSTs_`&=q#Q$Z ze+yf&aGD0&!z60`BIJHYFgI^gPFtPRl4TxE1nrEXLDFC~ieB6Wkic@U+gx289JHCb zx28S{T5fsOcf%?<=g!;}3*Nr=kU-RzP3J-&$#xJ`UPbfv?+d3s)bpn62gurHXeN5C zAGhATj+8O4vL3qF4wV|fBz&MLqe}0op+TaezK|7}VcIL;(ql@-yIS1OKWSNeT3NmJ z@9&Rv%@|I1`n5RO+&v#g!J%T76r!1JcfG#~@^0PpU3`i&NVirzv|7+Pd01R)C?#z+ z` zwcZx=z$qm=|Hr#kNRx$Iwx)SgYm2}XnM=1TiWiVRoClCq{PHO;mrVla8ogjg7oYR1 znEd()>3z7!y3A~DR95D4hsWNct;fmbgxnE}FD)`rLGCA(-kW?8|HYCTn#-DMgBo?; zdN)6oZ<5A@y*=5;HFp;qVG)#t9>#&`YUdbJkl9n+KVlI>U%H4DDIIN={TQ4JXb5JGo4XYMbal9`pZ#gN%#v^Z{?gaz z<$V8g5W>!7L_#s2-QHV68<9_FAN3Jc%g9QOsy*8Zt>ll|rW5u#?r$LNn+Orq+L@O! zD((B_s~lU;45)t3`G}vudXUTnzt?#A)F+#bBc?864+jR;TTBzydncD=w&Tg_kL8|! zF@z_To;2g6fE@~~*t<_xwlpj1b?h&4LCd>}YBqmLRu`}FccI5TU9;~K11GPS_B?u5 zUJ}ZQpg4Sc+Hv7tI4-?C0Ge}kUsQ=6!^Fg95w{%0!k`JmrWyT-BM%|~G82swLhV~! zSbQ9-^T@|yFpW^r>Nr*IL!uK#DGC!h$=>5wUHDgyw9~&211B8%7F(CTYc@VF#|~TP z3Bj($GHPIOjm(^!oSxLF14UO?*Gg{b@uTkZOac<3j`*p4g0KD?wKzYcJy(jk@}AxA z6br^~hz1ulq?9owls{Bn@TG$N^Vm|uTdhr97CNw_W7HbZ^zUq`zNHuwmZ6B_1|>dp zvtYwhePwlqG6JC8%pbWIUBORdA5l~EqKlX~O$hPwvbEaSx@GaWa&A0EcD;I8(j)Ex zJ|-7el&3QbVaT31hC1n>Bj+=5Vl72}S4>E(8^nytK=M^F zXQ$-gKt$x1>PLL2(Vq77kxr1K){m`RIl-QVh%H* z^>R0BBsN7`U0s#e)6kIb$HiC3%xrV%a7#rc}F$a^mkYh05PBOgdT2upr9I1RnfjjE#kr6>u_ud4Tptv@PHp zIy4IA%e&bd9|IUPmtpqUyMEJqi+iFRajE{(%#}x-=l$q!DvAORez>)kEkDRyy#1Sw4)dv-RU_KVHQ$*on(@Tr%S(e=FJRv3j;T~~6!rsgvt7>>w0WZJ^6deG zLUT(CPK|PzKVI;kKgyC_QoAKVv=Qm8Wx2dtE|^@=z0M^HS<4>BvjHw!&yRC@=Ohx0 z#@>yC?go;>sMSP?Nxa{dKnpm3ADz98jEqk9 zw!9s);Pj?vXN}5wYFa1=#bzR*wl3-?J9q zJA?yA4{v*S_mjO?KkKYxv#uGrHXzZSd8KYccSS?_yj88sSu=B7KCHBxo1z8q86k^Y zR4%dsmU-coQkk)LR|26!GQqVL}k{ndKxFOf* zG+DXZ+oLii?H9d=RscL~?;q~n5Rs7noUUIR*~D25DNk5MdCXj2vrf~I0Z?Zy#sBfJ za{m@SIBQ0@1D41w(Hr65=3XUU&f&OK#j--Ldad)R-{9r7-7O>zV-l_pmxMvNO3muZ z`zVNp*!QSlCdLd8bp22RQu6~TMFM9Rljj*0JksQJcwHXvy|40g0!&9@-5Q&l9iMM1 zG^z*<8h_l_E4rZ=d&?se^66z|syY8Ks-++(-_cpOw_z<%K?`X>yA{YO2ZjvkkVrVi zZNMC{X1rZU{aO2FVIHB6B@)F*qT_7|sWg6|F}{lmSu|0GK&5(W`hC3d_BNb(`1ZvF z6(3PnvP(!IzIVj;L9@rJ%S*_yN_W{v@w85D<^w~gw9wB8TGHP?W*c7WBz?LbtySpD*8n5u`j{Sq#d7IiMTaPnkioUQO1u$$ysCde{L_Ts-#I zy|)ghDFh0VDJ;6HJ&r@;moYJ5gr_VpG?1}+Hh1=#Q@59goLrimm}*CPQX*=uP8Ifp z@A2*sy+3K{e@s;8Fr;F;Y|cM+Q8mcIL<0mhCu8fNjz$-%73;yKC98C?!8A({Ey#Wn zMTQ8BW;N$^frQZNbo@9zBwFhclS|uU$#LIb+xqzUto(F>0(x_+)UyC5n#};6&j^98 z4M9VO0xwfEA2;t5WJlSdmtOVjfi7wlD~BE2g1RhtTW^PcK3f=IA#wvfuj;SOE5(fMoh#Rt($b0IwF zpyy-mwfp&k<_pNK2k7^{KB3Q2Ly{8jb6mo*^qOf@Yq_QmYk$2D?9rTm&Cb4rX8htP z{)cd}GMdmK1xtc^uGLsIZ8(nH$Y9JGLS7kas>ti%t!Umlh?QNms7bVf+Gy`r9pVzC zsL{!8(T}c8edPgdq!O3$YIzwllsG!?a}E-}Y9HmMmMas#6T6SgD_`@@7=i1}R|U|z zl<=+QgeD7t=k3Xr&-I$3&rwd38u+{a`=p}KM+N9*DSHup0LJ{__(XOm3g49M8k^z1(=;}<>}AG#><#qX?;P=At9jjdx85K0y!@R(jD~Il?Q|%D z`a}J8YOtAfdG2FlL3^+{o`+?Ai+@*DJg*cxfj6;l6Na8TMAExYgC#=GgT=4Sf<-#n zKnue+knn8*PEL;||Jw0)Z1pdK{V! ziJCgzGfuGX$)?|NC}K)DiHGa1@4do&ywloL$)lnbTmKCyDm|h5wD%bT&i`8_7M9dC zDY(5Q!22<&Y(LK#*zRYPtpYVgygIhwGpfm41EA6^W!X($ju#5>eEFqG0zs2_b`dQ4 zDxjfa;|e2CNFfiu`ujtW!pT7P4V0;t{Hz2DKjgYFm+ij)FQ@`h6i-jzLJA znQV{!HVfaUfEv(y%d8_T#R?CVgKF$jvWD#G^B9WIqz};ML&v4>4a#QhtumdtpFkr1 z^AjO7DumhY2PRA;LkX?ew&T(g!pUK%;Ua>gDDkWX+x=#|zN_^s*)^ZeM$#<4ABVEAXC~niv`Ahd z;uRR+ALfO&+{U=s33u;x6B({|T^#`17GvtT2rj*?erC4wNF{s4528V8!G(R+0zfNe z7Q}t$g`t#z^q&!gD-0ii6_XgPM^qo;mAZtQrt<&`N7L;fSkf8x@~kX1hS|BJo4gy` za4DXDs~(~K1`INW2n4D?AG@B4onWWmmDh$lT+>Hn#p4BUo9&VlEG|B~NSnY+a3WI0 z(K=}Mi>pxW%~QwL-7JpZ)7#zEoa5T^i_2OLehrNa(`nrZ?+7IcB%g8#lJp!j+BNU5 zS@+5`E_@yF2tJ}tsRjM+nq`=XqY8TM?BA5gh~l40qQ{2jD5+$Atp{m~pdt=1ez6z- zb1~!ZABGyp`5j7XT@b9^#H9&xM~v?C0U#QB8-$-WX(Se^^cp_OY=B#!95x4$#>dmmo0HCwF*bph!X59vsXCKml%Bpn z{(Dv`UXzZ4;m`H3e}dr)Mzwk0(+*u5pqcyF)D*!d@?3}Jrt z4G$V?$6;dx=_F~*#no`_8MhHGM=CU!ANj|wG{c;qAU=8RJ1bm)( zXORf{6p?0>Yy?Mb1TgVO^PZOTa`QX<+ljwr(C)k}iG-^I%6=#A;&Mq!|001^4`nm;{e_GonsR_mz z9{fFWcBb3?V78xfm4;iDuHTU@V;|#?J+$g1w6fIUS2g8e2fdA^NeZAOF)1cmzgm_i zDqVbWj5>p+cTvaHTkHeSSs3s|&N?z+u$=_VB(VGoTghMwr8PfdCH?NE;&maZWxePTed9SE2=+RzQN(D-k(VV!WTX+ZycNrE;bho%kIkbOWNq*eYL+r38w)_=-3 zJZy1e=pe(;0|WeN-BEOGzdNtXZj$ODgE!t7Ir4(BR{;|#TMmbPuOx5ltqZXJ)<-Y> zCS9@Mx{(N#o!@OssKIe@k`Ze{GpL9q5twVlf%(+iP6|YV_t%$4-5`Er=R(Xt zEBk~fA$`Le70stxx9ix2gSZzA1@`+^yiT$YvT}$gGERsfwh@Z7ChHNU{k9I9Oy&`w zipba1U6+vfg9w4a+6&h@Z``-nfQS$<2(N`~f_M+KBO)g5cG@5!=#HbdfucwL%1Ss) zSwtoe&1xKvn|PW)V5G_x2k`Gxw@!-)6I-bJxe_lp5<~R7;B;iL$xMzryOL(##1rrh z?9t&&Nz<$Oj4u;!M7Dj0h>*>R291J?1N+i)_g`1&w;?@lffG zmYB>4H=XCNoD5|gQnmrJ$^fe@GjEg2+Ph!3`$;)MAE8V6gk`SYo~csjnM91?ItAhX&k=%v%>>4Jo)erq?PBBMkp^?& z-)#920g#_A3&>m4BFI(1B|NwEGTw?6@_sx1ZK#0;888%?g7Qh#iVFo!=vUd2(%Zas z_=Y&Qj)8XacW|yh={b*;_@N13BV1BKLDwgr(I5QrbJBpir=x#!aZ39OUY_x)h)Rj* z7uMNkJ8(jp93IcN6f`MTtZY5^ zB{QdKT*daF{D@8A3C}-9`aadhVma+bBw>g9J>GRr0^mBw^)$> z%ImrzVP;GW`E<5X6flX%YUUY5K%Ni@7e+eyUDYQd2!A8Wt@O~2*?%s%EPNDrBj3)TEsC?#Iz(w;` zAXg$GNXovm__70~KvZ$51$@eKvwgPPYmCA}mO$;T9(P$KjpMG{aXwVU7I!uw`1`mY z3cP3qB5Z7IxRrhG6a5pdo)ve%D}#Tu^Pm1e+{c>pyOd2Rc_P@UggY2j>09ew3=&v& z9m+jyVm%Op^>Dp#thOD99GBs`m!j00al~s8BkDBlp`Z1eE$`ReUM+rkul+@y!VV9~ zeF0z9h_sUvsOiAUos-1R?J!#e6A9Z?{ReUdquLgW_ip_eUvo|Zy@Nrx&C--|4`Osk zWF=M!d4GQyKqXoNxg#$eVE9}<*8tMYv19b?Wey9I1MmqlsWCzJbr%7+c{j@aw-5vE z;67~+s8pUbCrkPZUz+sa3X&d;<>50J^-H7*IQfDDHW7dCsM80c1hh9Edc-lLL}3a4 ziR`Dol#B51j46m#c^{UHTUJ9f7l*DL)+kcRQ@Lohzlyool4gJ>??2(Nxctp`!1?XE z4?{xPIce?D1RC52R#uwKcg5V^+Y~U<0#?Lq47)zt_icAqI^eAD+#1Y=chGQJ1#+cw zgwzpzj2y)X)PJ=KaQmZcGuDfi2XW9cR;TYou0`RD%zwqr`0W&R<(yvh)XFbxw{x_} zaR6l_!L2xqBh_3|WOC#pBYh&5?hVc4u$bwxK8Z-$(rPn#zzDJDW&S3OK5~ww17LC- zSSp}VidPc-wWLT58D=E;TVMuGNWKDCa0l#aJW}=X>6%b;esS8{@xzp8aiIuBm-r@w z1_i+?(yK%|nJF;YT1*n0W`vE(QEsAlepdE~Y@p{bvWf(&hH<(1c#VS;P_~3NNo_bG zVx~h8N;W*1L#k)&*u~H^xr)otmb}zjfQI&&I>8Q=!)Vu6JuUqgCdL=Lc3_7T3WEaLi7?| zFcRZi?(}se3?c;GK03^iNi3?uQ{dOw`Z}J{Z|(U_yd$i?oos;FzDAprtXwyxI`p1Ki4}iVh>q#998Ba*q`z3 z(mdg#U^0kzhQqpaVlmVgY?&vFN#N}$cIzXtr*42%pt9EgD* zm7m0JhI9aI{!07zX{rRUFrFHKLQB5J?`K_xHdlID6W*kDn>~9=>nN1aV2B!jN*Q?b zpUd_~Eqr{3Sv=n7*HU!2fw0~J1K{b1xe;HCzh^u=xJiyDI~?3F!fkMVrA>w_la9FI z1MD)qIB!+EavFGTu_li2e6PYIt4<9-@&6i6xi4ff@>sPMXus>Od=-7h#^GQ5VUHn! z#u`fSd6$q-IRPE9W11DwzTEvvW-c+H8xfQCx%oZx@r}KY-gd@Q;>vKA} zf1c(8`p!4a@*n`rs5-1I^*X7?kj)XMzY!qt$LAkD@9h^`6OvMf03|kN9z|Je;}VWM zxMbq{5Wt@j>238pfaq$HeOC`nr z@aNKtRnuKC5pWZ@GCeKPhF8iLHTL6oOJczFm)~P75i)^4WLFm*{>a-aoSgFA_5L0R z6=o$K)(r%P(bLxna)Mjb&P5p>cZ8=9_0tG7Nm4Pm!D6QRs?@o&)@LMU#+9*E@9I+t zd?3IvsHw#RrAY#b5&!|<0DK+%O_>zwVL%~6xFL8%%;S4|4GRPNsv9qk#zpDN7naW} zXB&j9=YWIFMFk-eiHj@`fm?|L;PnvNp3dZZ6H=$R<8@oFa{#q306%^(s-12k2)Pdi zIH(_v=OT8r=Z%u>_Ck6vS=_yN<@{uFq3-Z)JZiy6G1{aczkzi6=YwGC#U&(!b{v*u zX-%2weiCvC5CB%T?OncGFM<8Rd)3(<*D(1;{zkO9!)t|VM@%#vwi#TD;DGC=xCV#2 z5SlwixyMVdj~447sMJsMbmY+^(+U=H=cL3Ef4)V4?ZdTnNC;N*_%bp=(V%bZOTs*@ zk8dlgJzB0dQj?J6@Jv(|Z9txHXrJt|jY7gFg%nEwxOVt$u5+zlsY!>YFj9TP`J7BE zu3FD3EM1JEQFtYDp{tn>>sB&&p&>Xv*I8JDb+>!I@SF0cLcd(Ui{R>lo@1SL@h(NW zlzH!Litqtm2}E|gF#qev3JR)CboPm6NMa7C++R^PT^47WEPAcA#VS?t-?_%!kHkA6 zuzSV7(&9pn67mv&>*a_b5zg054g6NgMoKDy$o5GDF>t1Y8qcYE+}*&S?nhrbi`|Ml zNK-`lpNS8FNFkq@#tLn2b|~3v;L*0Dz3{DA1vOWXo-BdDT$K*nR1%V1a7pM8CM6I8 z8-Fd|-{|k?+w>=z1WJf8UZ2P9_Ywmkd%s$IxKeuTUU}3;Eodd^(A?3Cj=>F0Ff|x+ zcx{j4RI6~&T(sn}`JXl931vkz81>qBCNi3ZZm}>z!_X!v6j(V#;oPCb0Sw6^y>h9o z-)sEpG)JQxg$fjw%D9`!CgUr{tRuNh?5UOnMZsnmgc^Dvj+%-Fqpp{Vy-`d<$;`Un z;Zxr$*Ss_l52VmM^AHAVe??D*R!;$~r#{#s=Hy;}`24nC)jMkh-pnu(<1HeAs+!EG z^L!sKQPIIFF*xNpMuC?4-b;S%iUGAV#kuf<(^^cPSYSsb^K({KlAu10!j=0?5st5z zI2>6V&rrBhtv@cSX2|ouFF`d+6-#<;R^8=Fd;Mvq6OTQOKq$;#Ly^hCT}C&j%(3M8 zxRax1Sq zt}4jCN>8*x0k)Lyq+&C@jRuc&z95;J=Bd#u<0zvJ6bl=Y#;E^WPt0+ub)$peV8Z-4 zP#qOW{BGWTe2&~0wd)?Ou?2XBsNex)xPASME*sTeJ=cp2pQ(%D0mB&*?tqo$D&Qf06Ve@ghXdz{KfaF1;{UL}NasgUQ1DMX>JBrO z#?X7&bAE85QleaTk?*0 z&kA|kOJ_t(>A&6{tN|zslDAbnc!(z$uecF1!p%+PRbzn0n5UC8`Uq@Rm5Moke;$wm ze*6qq`n-wZEs{k_?mzv+tHD^;2eu7=T-KeWl>$S`Ng=g0D4=8E5~&hj429f5Cj(#@ zUAE4?5GMYdyrwxXRdLng2BTCwRogaRQcM6^o#;Xg-?K& z8p4h@$>VbVx2c!k$KW3yVSb@6TA#@nF5QsTT3uUfRvHIANhGF9JTl{vZwAZPg3OG#t3Yogyr6iM3_mFYB=)rMd_H^;X(~4-Ep;H79@#fXathLXOjUaT zIjXH=YWY|O|D-x1Gz11T6=_&wbd^EJbB>M<#*NVI+FDC-!78ux#tWBB>Q~z!MHywz zP`t%PAF}j2eW`D_=V4wCyBaNKW(;_in)HUyI?Wi8w;V<%19(MQ#Z!$W zq8JdvgCD-pv=)l8LZF>~=Tep`>QY(jvAeQ!b;+wihKhH1N}V4^5SqVU%rN+L?= zlb8d_^t`Idt7~i4ES;@a+%wtyKm~BjE&+r{`jZ=;gp*vu<8Xvm>M>Kk5oaL#*d!@5 zCMp6Y^viUXmg8gZreaIduvLX-72kJiN}1s8PYakN(7&Mv|A4(b5Mm;gVPslwb{{aA zL-26&l%%c)Ua6${{^UAe6RfVvo7_NS*I`u;E2E-)q__&ukUYw2(4A6~ab?y(1kzNv z1jc4nuwKc9RX27l4uImI&;tA)0INV$zXbzCl&-GsC5I0m`?Qv{wtD5-M!k0xf;XH_ zoXk)Msss!(!w5wHgek8&$A*~B$Xm-00ZLW}z-GNX`%JSp2fX3W7j#CLj2I?TL^MIw z5iFodLXx)iu35YGPliWF*5>)hLIAUXs(^tyMO5)-hy^GDX0a1_6h*U$4IEKZks?zB zLkT!F+EhxHV+69{%&os`(;wfpdGizXI`u16`5z|c@_VF+W+ z`-~6*0iX%4a1%w*?ISjyMsE?%OoEt!uW_-zcf*06o)6r$aqH*COIlyDcH`+hfT?0; zud(B&TyG$1lZ?&1bqP04L{V+5^IY;#pV8VnUfTWqcmB=t6)V26)Ga&UT?G?|U?6_l z4>JG^0f@s`-eO|Pbao40fhdZiTayU|u>dFnfX94|f$rW7Jr^$3`^{TE7fPn zeF!*J%x>qd(}n<02do4J2zC?o*539rmIf#)f~b)D{1Q*%+DgywdhXvWU%vPoOO`J? zAkvA%j~h|cR18C!cpjbReAiKvv5AC<*hJubSNB85P8|PGbza94^^#Z!MnG|?5}JC< z?c8M+@ZOVUIV#$?5>AWjS+-*7-<>^s`u#n9{Yx%^>s@M7JvM!jD2kd$lYR_q(zhMG{jA8V$@3hady-V~zJ^PL z!P-C@fQiz+XxaH~54`J-R^7SzU|Q`YNm4LR$OD9#jUj?G)^a(q$K$QYFaSgZCyJOM zriiPuY~_|yTerXKk6YUoj^YJBJe-zGRx&)^XNZ7V05i7t`r^o9E<^ zE9-ixG`THPxp6W*H~#y(L9@?sqN+HjGziW)R;^rp>YnWn{BhD+9W^|od0$#8`z!Tc zc@1o~#NN5LCB2cn8LuA)HcYw=CIfEXcOEr`q?m-tk!3Ynl9Il-|M?$#`Q;Qm7E+xBm{ooV*{oPAkqJYI=MK>oF zg(!;NCX@9(CCdUWiPK|8kN()fV+ViH2M-99c^xOUt!mzsEc0_{0&rncsZ{26BEl>L z>X++%+W-NyrIb9s``J(QU+h}q5`X~2A&^lNT}M2Yjoy4#(@S}PC-Fk0-}Uqcry$En@ZESAkJxWWoVM%QS&%4QYV-M#7SSJvu)Q)`}cgj zr~CX8RRN4wWHv3aA>>VCye9UhFU+2JelLpNBv#~_ZE0jSR@8fsQ{}}M4}7#1N()xr zbO2sp zpU{d^12&nryS`6lmSsZhnK4Jrg?()FhS2G`?)St1F@%8Pi*=rlED#aQV9BBt-`Ki! z`(x#@8_u$v%K;E+d@&T7cRrhFx*4p5u zIf4fXF!B7Et!Q!l${S5g5vDN^-hL+6OEX_lA&Q!XO$6jRXEKDzgd%x1ygl=vZ>vFtTi@?MJ(w`T73-GpV{9$iQ;)yoQKPYwYkv1dHt*H~D+J zTAF~*1J1q5^AwzOMMP!R107L8Ri_@CRxTxVc<*0BqsFWC$x!S%p~$t{VpEB8i$rtY zZ0A!a$<@O}&8F(Lis6(ZwOaR*Jt!VTrkB>!B9z2sSMAb zx9YT*;r%r`n9#t@#cGxMi?*C(-y|clJj zHG$Z`5xuVADKZ%WpL_Bw!{-@Es02f>4=agxO z$U-9sB2uhD!5p9nN?Y1CG_TrTJ9hNYXU=w=UMM1{3Z0#un1y&S^Cp?>y`g{#q^Xi; zyrSR(S(cG!IT8dFhoVShnYgW(2cP>Q!3RPPSuK#d6hXkI(%422lUUTE=$0T%O49_9 zK(HLdz+f!*Ek_R>`S^m)&O>YOSpBq{_|TI&huC#5-#!Ohq^HlpG56+~5~0Bq%uPf| zllGx`9o5>AV@E&J)pdShqK=RUQ~)3M<+r+`aYGaGEHCPLwNgP*#H6uq+%5uw`9QUj zU?Jc{P!XIe7&uWdLy+Pz!F#Hm35HQgQfh;Pv+h2`rZWBK#bGIPT-<*|v#{CwstX8) z8aRV$>S%Y?l4pGjvf2Qew6f!&AOFLpt2X|ieO_l>R6syQvDj@Qn!#ugKv7B9zWsr3 zu3mlTmu#%O)PfQM3=Z}n5->bQz)Z1t2L25f40cfx%R+lD%Y@? z-&MJCJI>$}MX#3tSI>n7wQK;Bz-Sn1={|pEL6+qN6E<(!@rNr{-}!^KwncR##Y{jP zMjS_Wy>eHtmr8SW$7GWc0ZqAk+oRuHx%SR4jg8sT5Ikz0P#eJE5yISR2fM}1sQ)O5 zCOA=2mjHs#0_H)cPr)|rq($Nq^33?cpMGKI|NKAw?uUNx%(E*dPk>ZXK}Dx(__4!B zmjC|m{lSO6{KYTr^tq?AT1C(+nRU^rG{oVob5;D6N3UTlodF)C5y2y7fT7|!c4Y64 z1N-;>&e+&kD>%l3j@fw2XdaYW<}owUG$Bb6BwpJ!x-P*Ce1JR)ESkT(YstcuFL`f_ zdhD7^ijAvL^eVM}a&5+S7-^bv?C7x_M-CtPo$(T_&Lxy387r6DM-x|N za4^SA5K(;md%K2B%ra_os1u^e_3sNNHlgxo_sr*kYzc&7y2rn_*eh>KYZ+0KKi>~dF-n@f)6-_tmdz+#RiEAFP}Jb=aGX) z9z1dM_(D~vBo(0XJq66e{+ISId~xr-2M@pa(p`8%jjN)_b;Gp0&QHPddVW)yd1A!o zeAm%iK$zs5qH2VYkyac?Korb8r%oSQm*;~!=e2kI<@}E2=bWoz=1>(>t$4185WHb# z$dx627=4YT$ZdLNT8d0i)D+C2k|LLqxRj1c$JqFoU$y7CUB5k=4_6cC2zd@6;JwGp z08ouRI&OrS6`9z;`@j>Ae{);8TrSne;hAT?zg+-=AOd0n0mLZQ82B8_2U@k2k=n@A z{2i%+1n@PZGfmKXnU=bv);Eme2pLFFEI05_aTM!BiZq^YV0j=BMFKb!LLgDa$>icuojdfJzF%2MFLM-oN)bgSA1D1Vq5R&4|xES(e3pQ*>Ln(UBmk4ge8Dgo*L+ z8D>`GQbY5)@$vf3WlL87WwkQ@oFO2BI)@LSnqVgQz_i9^n`IJ++p?lDJDupgAyBuH zVTj#sb7sqom@q351yh27h%2^5m6oJDR;vxHdiMKI{q}IJR&`Fv^Ndi``+RDss;V%H zIE?iTCZ^X0NHpPZ{_1bH<-?<;dF@r6|IzO4l~l4kGo=OupZo~$T=v4?I zSaHDbLq?Jcc|O3vVDI7)@6{!amNwUO=iQtCbp6InXYHy#1~I!$igxs-o8CLXWGc=H z0|OV>y6v97T(oe-cLw^hEqRuaqzUS@F(zCU3xV9{gm~8QHB;3hAp}GefI|n4Y;V!l zAsZiObaZU(!Gp)aX7QWX+`FfvA^wVi4@ zj|C|t3KAd@nK)=^+=mAYvO$mlsZ$iFBuX||!;v5X)Bq0}pw^cc+Y$o8B&)5 zoPy5-qL3sBl}d#WzzkF!>KYMM)G3v;f)76S2#V&E5JGWKZ)Ov{I0DWYxxcu0G#^s4 zKzmy0S-on*pDtXu>a0kD2^h0P!tL^@{S9L_*|1!n)3cn5O$#$+dCtxU@Bhn=g&p7N z9~{_{qS!!C48}$kL?Q=xdsmEF^?21hOyWHG9)0Y11Z6(k$e? zLYkz_Mqc{?2_$B-!Dg|+1`IgZ*qFuOU6$q1=+2!d&)E8G2yHgrtFiv?JKr6RJTsDf zX70IX`HvrPh}0ON0{&Kj0LJy=og!d-788;LbM6NWJ3tgga1PVCMu=fgwzisfgwrX* z;1g05_Zn`9KGML5=3}eUJ-Yiz^F2B06 za`*J8C{b4!ht(e2uBd=d@tfQTP(Zi>k@JuMK*YxRm-VQEIbuLjX#VqW$xXF1oEEY} zG9rVCNrNg9;*z&gDjV5ERaJYk{fZJUu`nm9Z*bKJ_j>r=rri@e2S?@Zy@~Zl>r*G5 z;VDi_8Fbj^Z5Ij)H{=q6@NY{2tXTf}ga_|gc-QT>-TTlVe*cH7+FKQ|D|;hKjDk}( zqcuCW*SQuxxbU_G^B;WVf%|?n{a{U9QcwvZ7zm=Z(aflL`K4E{zIVaHa|>1%xu1LX z#cO8GSn!aqjfq?V)~;Ng_1Ghi&6;`h?1lF)SUBh7zkWJW5+!hEmbWbX$MPYs{o$qS zX3xIs{`>B}`@wq_+&`1(+(I~v@3ds`U-EwY{0lcNn0MF0JLleY&l_*Nbt&QI_mD(l z7&)S78dh921u&0goTKYn03r^v2nGxYAy8G-7&+%?ZEF&D?Jm8#a?iHuF>zKMgd--# z)gJ4N2c4&YvDr{U= zoGXi_<3UwSUawWFzL;>|{SV$XbH@CK9)0B3R|PwRA|+N>EEX_kdj3kbmb>nq|DU(r zH~-#8?p|>J^sn|-CRud>LNABPGfzB!^}TmJFt@m{$o=dyzq#h2d+vKk?eL2t0X|!{ zD(le)7S5V+^UQ@0%zt#wmn*&)>GuN?p->se+Wd_}o_zdQ*Dbhf!Tqym%nsQMch6M( zJ_}RLsLiLJe4MxN(Z_GPdw$5^m^JsF-@Wk1OH~DsB?+-k8BSR??1Elmc7~(WaDYfu z#OaCtdnfh7M`Q#)EVv=&WTS%eE>S??H--BV@01{d<7nN1NuofM+%aQcQ8cEhj6)Qi zkYp!_D1w7^r?!%aQ)A$ixt%gF0E7~#Mr58sRXM0d)X?3wtF86eh4lya{ygA2Cdrf` zR^o=vhJ`D}-vKnjrhO8!Fs=eU%=LvEH;%P{>X%Nre8=cf*=4@=4(!~qGZz4Q8rXdC z<=U*zmaVv^dVgJ9_K2)9UDd6PjZMStk^>eZ8U{^!JH)r%Tr|C{)i>BKJC9^!WK@T` zDxE0^0;rXOil(DM@hfrOCU4S;e|&yLV^d>}!{P98&aq-ee%8{D|K~DY{;q%N9BevTp4G@^+D{ZZQT3S+?v2JxyMse}Rj4ee)h7=bTXB4g9l(DI> zc#s)cq=*D%A~-$Jrzv!J&KIGC#2*%?3^+v&D6MFzKQM_0I+QaeOnik3k|s+|qtw)= z0IG`atS=sJ^~#UG9_i1f@ed7--Vg*XV1R;?uXjZd0E(&_wj@BoI0doVv>xqhYdw15 z;RAbq-Wi(j9ew6|1r%!EMzy3%B5saT0*>(iYwef$V>#3G3op22hiBY`GNO~vzSX&0 zg;@qlft8;ZWPR|_hu5e!Cvjhif_q1i{Q|(z*D?8?R44di3aEm&+c_bawCF4>xChk zA?R16zkmAajfbkbYz9D60=9SmykuH!Rdvp&>`@yonml=3Qet8gB@_|`mi>KM&KF;N zaizDp&2ho`lRtM49lqUWl>$sPOIX?({d8l&=8S^1g&Avm$@;bHGS;qHlTo&P+aOg{ zar&Zv-bWFue*lAngHQlaLAZ)|Swd^`F&sTo=V@ze_6Qd4;+m08*5Gm_myS#sRAi4$ z>hvlmb2<^JS%D@I*Pc7IfNFEt9RRU3#3ZDZ4jwwH)UR@ILct?CcWOWYg6`7J?y#R9UjR zho;6ODJcnpV1du)Pp_$}Nk8oE$VnNlFJ;8;10~?BZ`~R1&fMU}c4Tsi;Ja$1dV)@w zEo8gPD!>uYf{w~PWm9cLagWU!f|!^Xbf>ST*VNXgmu)M^$sK>*QpTB&kpAq0?u#Ef z#gtM&QGiVwHf6N?ys=So)XrTM6{!JLMSN^*eT%m_ZP~KrV;{Kx?tH?5qlbmtLYNdc6g!w!KL5GDBTz>iG zg$c=WQ00JT0cq`MPvSw2&6~DNEGj9Q5MWBQBuAmCwK)z17&1Ji+2M??JAC9w#uHCJ zJwG!ubH{bpURRJgD!aw60OwCWzhXmS;iT&Q)uU(6oIU8`DHm_Lb=s|)2>}yDiZR*Q zO^g5h)>9xSD22(_;WxjRPlcJTKTy125uCQ*z4#3%y1<|X+Z;Q~il(L|#=0}dXTt7q zfNLD>?d|EINNW1_l8redb1zsbP~wv$hgrTA4vm=n8U!S~S~bBUOUvW%_09|(108+J zRgT}_1O(lkwg>|Yb~-BeZJQcr7u>GY6ePvR!fB7e(dOp#{RfVvZ!TP$GvmbmDBmgMcvUTG2^0Eod&8^W^3q`=M#DN1Nhi5h?#KqTD?W@Xo`j@|)pD}bu z$Y!{vU{uc77GJ9$mtJ&9#jdg)lj;xGkAC8pPYfC}I(O60Zn$ByBhktHeqdzwh^9AR zfBh*!`uJ`^MKkM&gM(6WK=bOH5=2T=BKYng2KgT2K&(SX)!wqH$w^N4xUpFnJu(X- zl|Xcggy=X-7(W^|NppV{T2#iz%HRg0HA6Qd{ieSMbo8Kq*Vmp3x_=Vxqs|PGC1UVz z?Af(#YD#i~+v6FJgd`WDcX-niPd)Xgw6wH6A-!;}{&MxD&p!9;bWt+vfjc@oZGZb{>BPUh^I=H- z)<@oa``wA}fBew|uL4jB;DkqrMkDCIAga04>n3rQs02y~WD%&WD4Uv|n&KWjIKy~u zidNC6DR;SCNXr<6wA560WkvbaSceEz@dJ#3@PA@B4zQjm-yUYT*g^nZ&;=0m!ocQ^ z;vk0fF@6Y#ED}KVVehW;si`iPJ1cVpQqz(lNsR`51_m!WZxxuY2@F?-D@+wNYP` zBdR%LNLuX~d7i={!-m%M+$#$oet5~0ODxUmseD7}`P5jIIA5DDk{SPO;``(8W z7ytLW6W@FHuM?Mk@{b83C8uFIbpLMe6uJKgFbDui6d_T9$~`+hl0@8@!v}%t4DGFL zAes(Qu!0f+f~I2J*lfr)>fT#X?vW@pjs@>K1#=#8Vn*=8g7gUIhN10iY4pTJOYWhA z(_pojB$+b-LcU}qp^&8mVS1VCy^QZ3;+_E%MmuE2Lx#F z`+%XthSXRDy{ptM&DW|zmVjgRM^X)=Ca8v!bTlmpo6U+K(cy?E0Og2Jj^_y}vCTmQ zF=W`_<~wH0$e(-X-2Az7=jC7Vqbtf4RRyJh(;;ei+;Q8w7oLCqB{|Ao<5xPZt5&WY zrzi}n3Z$o{xBcqbr$3l?*SxnZ7NS;HSEp~-xHW}Ppyt24P3h0t(52b-;G6*jx)$mFak8@M-Y>w7`M$vuZ;x^h%SbaK z_@sM|x7lp4Q7fQo80OAELVUEly}iK$ut*2LQv}Wd5Ho9{w7hi8$WbG9&z(1S(X6?% z7Tqy-=AwCb-}yEZG=&K~=F7F~hKM3CI6bY_9%aMsUAxl&Kme=&PXqv~l|mGOjKPCy zSTNX?J(dOnFwRhaFA1F=)`iV8*C)E8&c2%^KlwCMGmLyl_GO z%sF%O7u-89f9g-KEth07(;_~}q0O3e$GYGC{>7JK6XI$prPjiA>&J-%a5@NvW(;Zj z-EW@!;O1#Jy=4=icC`D_x0mfm@hN~`SEOAPJM%Vf-k4WxNKxLV&4rEOXbgFF2JyEV#cbi5%VaPE0$SFK&Y21gr@x*vb) ziJyfWOw7n2Si+Arsf z&Z@2a>MIwqP|TY*Z{x=Gn^M=TSv@`{CwG5JN=i$N-Oht*0IA8z9TKH@XYu=aUT=F; z*68g0k|Ys})e5F+dO~7iCjexP%4&P@#oxZ(SMLD+b@vfBe!BsqClQ>!Am9)wK$wb# zg9kk0#tem~1`z=7MSe+4jw2lqARsL@9#z#xJ+jD46-6;JKp279|AI5~Nb;Rc&H>hG z#f3JTLPY;X#Sx9#wZKjWNIMI`{0KuClr`df2#og88EjpfUiWr~s*b>YPqZytZ< z8HYuJa7Oo-3AsDBm6S}}zGHjtlqna~W@cwq9jZS(V%xSYmpA>cA!+~qn!y?i+9?&# zHE$CNTzJ8SRiA&p5;Zk7?u8FM{j(^$P5bJrYPSvo$q^lXY-r$sRfNr92Pn*dDg`dO zY)ZlMWy`PMxOL;Cju$%QoH04IN9vEb)PRZ^x6jyEvUN-9x^?Tvk8ls)?;bj=r9)A8 zo6iTG2ptOJSoHckd0gXBIitty*El0qQH0;;(_>vRoqnbu!=2pr-0z=$T~UsEc9Fgu zUBI{FcH@NN+u%fdpW)PkfN;`pv&AB}{r~{s2#ez9CXYc6w*fZ^Mq3&iT~0@|=^Y0T z34=vfVL_m4+t^2RAU4{GrenukO!Y(YE9MkONSE|$w%rK+?GTPOQf_v?;EDo~06JG( zu0$s+#MH}^gG24~x+Ian;h+#HF+C>Xp6UbJ$IA%=Q&nu*Qk-jx5?e35Y;p}hu1v~v zR^E1<671f$cZ}DsST4Teva)n{Mr|i&)}rmDp2YOjy)nr#q1Or&JqSMsvL~dsk2xb} zeL!G(gSRoe#ozA889z2()in4u)g%i8hr$#Dcn}tmz^AHUTm=WiRoDNheA49emdSRT zUQw~@ybnJ3@E2A4_MIQ->~wMt5I|^bY|Q%PlTU7V?X}nDaL(gLXJ-}Pa_h~T{eA^L zU%OONw(ac2ix=Pi_S=hYwL9cvmtA_<(h(zvws9PX?(fM?(teSXfwTaN;Isob4AgLU z3Dxg~2o5S}t~iI?*nctzI!BCCMljg!0#q>79})#%3?c|b8d*GkYg3zZ2!a6U5j*Lh zfiY(2ngqbY6jy3|EGz;C(K!$r0TNz(S#%Cdx4o(=?JiLyaL5uQDuQqxp6|obzq9WD zKVbw!RilN)Rn8Ry|(!xm8kQfb-tvtNDl_1j;6^Q~Ls5@L`2Y}$=W z6H}7fM2Q;L@hc1*y@YV^(|El@P6HDDfot9W+v3}K$jLWxZuE(Wb5Kf*(XaU6bV^1< z$0AVZOn`-0Ab>#^R6t8ITreW$BIO{2L1ji7(tI&6jmkEt+q6q1<{0&eawFY*5d ze%zy&fZ-J41a^5*mhj*s4}R=$IH0J!7ojEv=RmG!!lBpSdHX3U0$_kc5<8#x&0~w} z>s#!0hdp3-h)iXGC;>j73O^WBA8_0JIcsj5aZ_Qt*Jn+PkM~nTFm1*yrII9?XBP>c zcx zrA5xjNcV!6=a3x|?wB>ZV2+4_hK80Xn{ z%!co+KYh=sLRI~6iXu4oBg#TSbet6CdmI)a2*QJgb3>#KGiyWTp^<=75>epq78BKt zu^)tk$SF=RCj7)_B?W;b$q)&Juk|pX1z;68gwQB}13I7!Fh;@D)iAeKw8I7hZnl;u zVz*7o!<|`r;Rl-g`&0h*_lMKzgx}}KV~;=fF}mCM`}}^$4jB~Y96TY9dpB_$22amdj%j%Y{I3FQSK z_=b!JCpboWpNjC)qx|CE4TPVlIUM{X6EEp=3;_*$u|axU3Z#$TbFlE)j(gwS;yuTQ z-79@udm<$WbohiLP2OStj`lHVPuA0XZ2GaYAeLe;Go@NU%9R(-7@B8qnoobvoAM-9@hEqXN6f@FAdkjGaPzr|= z|I6OjKDlw6cRpw|8nc7JJFqWYayg(ViRP}}R?$UgTe5X0`9tc;ANU8v_w7=-i_51d zQsS$M>%J&g<$oY@t{k7gT<$)wR8CdyeDC46n;f0FQGNMg{lrE!ZNp&1fU3V9Go+C%fsa!3QGUo+LMqTzH@kAK5$_#od}7* zJumk@Y=|5H2~8QBYL4NN|Qkn)zXy9E$ zfON=S-NtYg=xDl=yOGVSR~KhCD)RAEX4IJ&FFJ7+-&RTu%Eo>2>75%N2IW;XDEr`t zK2WrJP)=uzfe>2Zm*{yZ@%>h6E|^9Nm|@_4*VprpU&CPSM0k8Q}h8Hq!zMI^0%Sx=p3E zp}cT+%R_+Ueky~?IK}TnyB-z9A)XuL*TKAMfZ?kke}Pm=TUjKwuC1EPz+-lH-N@p? zC&wGj#*FJ$PDf+3k{d6~k4}tTXti3=i`TDDrk^|wmSKU~(e9{XS7FBLmH=o+V{mct zD&!}Q&1J`rTw){Jv{6~N*B8n!L^=>Hj*dDJh&cINej%OBR1{^PSPFb0al!-WpBzoY z1SKRWHK<5K&-3+n5gpP`!w_*9?ztarsE7}AupVTEH@7eh-+#NFJw010Xk1|xz7Kpi zdY7haNwom3hzuDw){6EtG|>0BU+314=v_gnLLh^oM}@%cR?CfSZ*3jl+FY689zPu; z$x14jn;*|lU5G^^(FMnuOeQU`k|yj50kYkOZi&VSGOLT9T!D#+<8uikbBPdxZf#cV zjkS#zSj>nTX2OZFs8bxvEf5;1P-fyXUqbc(a|G4zZm-}ohf5=pVL(tnz@Y}-A?;OK z2Kr0gwkHSu^m7#6gGA;`2n8U6Zi&7JV6d)WqwkChz#>pUq2aSAiB=XYmT83-;!0{E zpnnD6uszO|-o}F<0AdZKGX;R{_3Q$|2-bneSU4>(%An?IVTOkw3I(5sz)C1+_mDNX zo(raFgy63b3io7E6g-c7Dga86!TA|}Ev>+(Y3Fn8BKshgKINv5cacNJEA0<~QiGeg zMS=m)GavWTzmyVdoPklO*JE;L$BV2jtsZaGwr5(tcRCt{N;a9CKRz*aVIxYT&eG;& zGM~a626A^7`La?HMn*<(n-B`lwG9|Qa&m4Yk-RiPImBQfLpN`wsdtD$CR{g*5UoRmveeDT6-qw$r2E&7S^=qsG( z+1l7XzFn)#aKE`ntFcOYk5+RNlNX|~c=XER>ZFw%g`8zTd#8oTs!68}@x%xk-;{{J z#~)vX(c&X}v|7Bh+uos#X2ULjc#?PnP0(E>KjTuh^k_z-LsDr`|~sQUM_p`D$pwVFrQ-rkM)IBV`OA z+z$CT9?t?Wflvs+FM`K}5yZ&D0rYVcLrC>;LgINimuP%U?;t<|AOp|QMd9&SOv{9B zF-(TXcw7T4O5Kn#SnynoTKHO|2FCCnYBhoFK>r)Y#TLBKazgK(y#6@|5xLXy5a77a z%Mii#R*4-CBEv>WpS2rnR1zuj7Ht(zSthJ6FHfzmUZ3{-=5&lvw^+!QPuQim;%2<= z2@Vm;;IWw}=g$A~=QAHWi>0w#64GWIXoP^3N?ivbYS}UUT7@Q%}zcAYj{% zor5FZIie&~Yt_u=`iAZMo?WSIy$A#%W-9Ffvz)@%5hs($R8ZORJ;<0APLf>m0JRV9 zULEeSqCQ7SH1FFIn#o8gc=rCRYuq0Q<+OWZk7RHwK@kK93cdleMUX=R4OIK>?Tx9G z<(27uZ;eDE<}wQ96HiUQl}S$4g-_68n1Zpn#g&B_XQfg){a6OC83BNOqZn^-h_eW+ zEU$vxg@y4+dkz$Xk!<1I=*01JrfEXGTF5>xm5gAI7>fmL`aLJ#NoBPy+?@?*QBbQ5o=mA%s|Up$ z{b9NLMFAWjTp21EipX0|@-|p-a?<%UhzbD%YoFh*u1>A&@q6EIOjGE%xn!nnPffj* zNSJj>DfpfTg(Ic8bbeR;E#e$>|dJ`w>! zBGB}AVYfqI{^C{eeOP$vi7(6nvmjH1b6j}ml=MJ|dWL(x-P+l)&%J-{#StSOF-_Bn z#Vu!iqU1nKRw$)F!;n>lAdCXE`s3%8#izc6jB0q2R`r0yqzqDV;L$*C+wYuw8hwfM zwu^N?Nm6>}&qRjH2?|sIdZ__-a}~&ezUw2%p=H8{%gWzRB?9+(`Trl*{%i+E;yqT2 z2gHRKN&Rrt9AMCWpQxZ3v}F)A+!YfMHH13q)mF`EugDMJ40Q~+p{=;|v`~Q6Fze*-i>C*d9u)T#W z%kqvD-F}N=aK#X>kbR7qDqWL0I%03x3=Ax zYP~TH5!%Y63-j6h_`I1KsY=B`H)#R^1L=zp0Xw@D>&oTxXJXPXJ$n2Y6!Ll4l@jXp zIyegpu*3O+{rHn-lZ8h-*F(;T9z)o_N;51KsP|2;maSB`>}I2CyR|Lb7>PwvNy9Oi z=@dqfIfN!El%~`o*Z|Wh5JAtG9@=ni2_O; zxZrS+ZU7)qN)8n+^#0!8DUe~f$!+>&4GJ!yXDeEp86*0=3IS3`1cs%$YqP^}%j`hX zqK6(FpO-S=<3-ecfYx0L4iuZB7+UWDSYSK-}(1n`})g& z|D~_K;Hb~o!$jT25#-QJaI}xIRp0v~K>Fh@gYQDm`(1v!$M3hdw`N?oJ}n}&mChFC zbGiI{(lV<6Bn$~aPXV9^hRB_Ub@gKTOjP-$lcfn5%cr3&6u9m#tZcYYZ?+Z+N9?n? ziKCt`6cB3Qy-CTn0fo>Iz;|6YyVt&5uh;B)qh=dMJd#W%9fKLp_~@uZ8Lb$>ifg_? zBfxDzSmF3Y09_6q)!#?q_s;^TBZ}S;JSSB@-&SzoyBgLfx5K{&jhdue54Ml}92P?F z;(!?RU{Z?oKNkr=J=vXuy8FpJ_TaepNze%>EuRoA8-23;lfU@p@BQ8mJV50kz%f|v zF(aV^0LK8h(K|#G*24h~RJEig#z<%4;)U`|)Ay!hQP{Oo>3J)cDJN3tEz_`YaQdDC zLb}Qt05Aof?}BA9U_=2`96q^Jo~>-G%ti?mJG&8x(b#68cw}z$XlYI=1{mQ^4Qw5B z9tK3eg%k*SNPa^pPB8!_1T;M_+h{cGjg1YPx411k?FePe86BT=%v92`5>`dOThbpz zOz?AHW+379sRnn3LbD3+^FRO`ib@dh*#I1x-Uh*qUVXQp9A$943df-qL@3rbnEFBC zoCE2(C}RM=??J=cn&7R*%+})4biy3jO{Q}5%t)29#fdFSO~CM`KtK?fQJrdmkj7_eWXutd7&hRQa6(85FlOQ`U` z_v_h4b;E9WExWeev}xRo82cU`BZia9k2)hGX2mou9S#O!kS+9qlWM>pDg1<^ob=E; z)iu!IM&+T_5<+l49(zXshdSV2b5{V4z`~=Ik^|tS8jOP`@=$<73u8BT3{kfTa40S4 z_6uf6j~v=k#lH7f-+QGkMEkWrdHtP(8j@6cjvHErShjBN!toH`_&gSMa4RI-UQmkw|;u>iqc`(R8Ot6n2xT%zP%3FI&m{mT9CwC<0vjTZdsH_?1xb zamiN+8S2B8OBZI>*EePvix&CLJ`ay?77N9>u_L89NR5M33`7uSYMN#k%AySvfW@Ey zDT9LI9)R?LyY;N+dv>GY+0A`^-;P9RoH_a8n6vLK7auVzs2q^PcsBIUp*{UUmFk-@ z@jvO47kYDl-IoBzpMU$$zwyeyd*$61{>^U!;83^BAc*R>+EYpc1y3C?MuqPL&*^=G z=()pva2xfBmgmo`tz4fr&G>F6l|X)<%uj4lW&+WP?=iGNa30LJ0JKXZQXs$IUSFQw z-dLLT8nt4SP=I!PbM(luxzZ!2=3Jj+h!jRVYWcP=bPM^V(EY7FHWVh__56CaR;$`A zuW8q7uFc}{h-HpAvG|B{^pVG$b_Xf}Z4N>}!!zRra=8dSUv=q~aY>KdMee#c(x9gp z{&v&6T;a6z8v{57k0E5(qC~P6Y``6NK7faV9IEF9MFC>p{qA>P>2x~nKl{^fzZ2#) zy9v)9TpD`l{^4PHVgG+t00)6jmjB;FfTO?s_5vKbP(9|fWw4unB8>Is0<#aJ*F~r> z0`0?rQGt|!)m!roybeP_okL}NY1D00X0|Jp8R!tm=SSzwbb3CM&21pFko_*LA^Yi9 zP{Mwt>V_qSsGf81FF02ps}XWF9A*r!2jPCSjQSpjhS$h)-?iP^s@?QzwraN{sbtb2 z(Wp}>78eS+TvZVUeE%aO34}3?f{J?=f{qmoM(yjhG81WJY+a! zhvKWILtsF<%r~^$>F^dZ%x?#KN1ux&IA8TLlAh5(`vf%=Dz;6pk!`qj+i!TbTdUX| zB_nAo;S};&C!0wuL};W+nThM}3q^q|-7cdPto<#?af~c2U74-cH)lP+R*ZlIE0Nwz z#`AObiBoerw$uO-fE-fw2tt@6qYEZUoDU4s1nhbt!L%rFA5dw@WDJlpcqcgTa2zj& z0Z^;?DA<`M!+oB|!C*AVc|oDa5E8C9Vp#ybuY1Teb^mQ__^9Y8rT5o70jU%N&zG2p zt5%T#ptRpU-aod>48VI6LVp)RAh61%0*TuOCIzc(p(hx&mBRM%I-$3^Vd!UbUEQu* z6FRO|;yvQAT`I`qNd7!wyPU6BocwN zRh&;HM(2}>{05;6C@}(yC&5}_-2*+U9_S#PKh>dvltSf;^?|5rNWRk$R#5$U2u#yN zK)dPIvfStP_SU*x-QKdJq!TITvQC7wokF3okjalCzo$kDJfUzN#IeZ*n8vC%a6?+JMqXI7ZOC*>_KPG6h5!cz$^rh%8{hfH*S`MB zPrveSzq}wp-T^>;2RXP7AjTvB|6SJw!w3vu$kQbzerAl}@94RMz`pj%RGUNWh=D#OE+fJP!G#&Rt>PIe45v-WSX@Azwo|LI|BiR7kvb z$QLQac657G^Ks8TU=YJ=cXL~4y5Pb65!!2<0_~kcX+R+g?^(~EA^*pAJP(tG>JTYk z!04zI@N__Wwk!gkt5Ov_Jh4f|Xh?~s=D`&wJ$IOa?fP`(4D&ky^700{M2037JG z{1D(cr2G~G92AHO2BwbpMuJvKfG<3}al_CGkyLt{5(eD&dp#5|+(Zd<2@SI&_>ER! z-^H)Cy*cgiN-USp&rghvmyJYnm2}kF{ zzw2!;Pt{C;0|O5QH_lsGui@F1?TX!KdZkWVb*ya4F_T#*o6R{R39G7t0BAs$zkZTJ z?8gaP*RNhVlVq}VbTkj?bQ@mObMB;ioQbkc=MCy~lj2{S=*A50J+ylty|;lneA5iQxJ zBaqD}@V!;G8?d@m-Dj=~kDi`BOUhDi-72(V0jA4&^9Scu-n z^RzNAfSC;MOZW&PAfup#Bha|A%c=h8q50v~uyOmrqOQ#;a{ z&74d@vCo0+1~yB|MSE+-Z}Nb`SXuG^X#+bue|WW6+j?FB3Q$@dI)elz=ddHL0}89D&+&`9#V~I zSV$vM0@gQ_JS`UhQJN+NM_TPBpz#~-9>3q1sn$29cXwN{T+W)$6*A?xkyr)D0U;Jp zY7No`QGEe(Vf_5zlr$uHC%M&dhCvHy_zUu@g&YGV_JPXgQP3t%3$0`aVGDEv01* zw=|C)9zp;ltkGiwt6QOHZA8>@iJIRt^mgLVbgS8|t%_ZDUAy5oOEDJf7>4DC%H36f z1HH36Ex#$H4Hr@dMuE`S3L#Go9iY)D6((85I!yH2bu_2?7%wmy{N-D3eYIMz7hZe) zwYNtMLlSc1e8EHGNNC6)2*8AGhXw{pZpdV;E0+Ykqul}cZ1sX*3^KoAr8Mtl} zix7HV4#TB1;1U82YirxaYybJxHzmH2i?9Q zp!-FEVUQp(tES0c{QMWEe)02v+)I`CMET{HU%q0POao2#(gQ3Ur4KH^@i56Kz&&Dg zQmgh-AwW^c7;xdE4`%D`$}Hcl7l86~%L8;CVrNW*Vs&e(!UM1v$)r3WcK3hTazk zFAs4y>$Bh--W!Vb4&HFDUXIcPVi^0v4iL+#W~^ehaQyN2g%nV&R&%X}Yj3YRrH!R4 zFR@sxlTM|aWGdn0^ZD}fCl}8otwd?&)Z?(b(}Fg%fs!aBQYK74aT+dPzFc~L{{1tL zKl}0z0m}oO+v%QADAGe;_HO}{`M`Y_HkX%YFKn#MCI~Gy>Mbzh$<5;U@wsGre9o|P z0LloK=0cx~p5?+M)ZAKbv$8qeaNQZTBS*{;t32_@skgJa{4%53a*1atqC-3g(=?|7 zk$=FI8~=xN8)6(iF5bfzC6@=nX1bwYDy)05sP-jSrO5QnKt7imc~=ZrW}-S(n5YUa z-X|cS=~Z&IYSnJKZfSjO?xjw<-AN@aCznk-BZXY~;{3TYQ=V^b3li$$T`*+Fc1 zJU<4dF&nO2zFzv|Lix;7zw^Z(s=lSi^!*!w@FY+e=>-9Nygv?l%zK{p4og`Ocp7v8 z5&+AjpjqT%U{0t{9}(kcDb^p+c8sA3l}u>u)t%3_ONZs(m;X9 z02Zz+6hHc~{CqB3xXd{U1Obqv`v-uaP*n*mGE$154-p7KE0^yHZAl>vl`h_Fftg5v z@HwukqO?U!gUb}cj>AF}0vDdo(Iwh4O}v)pX)5%&7TyfjW6=^C2NbmDkEb4T3YOK+zW*=6nBM35eRFf?FChUJ`+ zKnDEUZk{ZL5Oot3et3G&aD})~iU%DYh(Mke$yx4bbt-qHN-4ZAd=F~dTe%(1?X?xB zv~um@OGb=!(&?m=OeLLsE?Zt+Dxb+(taSR+2@pFCAgTqiXcV$m9MUr<;o=piR6hUS znd#Xt{*WjZdZylAoL9pz2#JkY$z=JMJ^gk%om=KgATRJy zTZA526rVlh=|hun6FL|GIdt6})d$gq#tU+*d7CI0DFc+$xzM;22vQRxTOG5D)iHqg zrIg?`y}jqH?&s_(eekPayp%|=PSQ#_X2NvFMvLVSKls&|N2cu3qbE;*K^3&yyU-SG zh{mGuyHC%;(&BPy@k;s3Gr#+lAJ#y@-IPy#Un})W-bl=8Fa#Q~NWpQ{6RtgTu|31o z$8ymFY;-Zn0B``Jzt=bqS1oz(z4yK>c2zXmp+D*xj0Eo1z=7u?uz*TF$|4Y4TWGn& zGN_hAdZrrL1Hf2TaDor8va(z(pTF?@o+0%pq?8{Q>Hrxuz1qg2Vz6!iNBoNw_jTm4FfC(AQ@1|+s{x*iqweiL! zA-L=;KCdT(_krz%+p6n@(L=UMgp`ZzS|;gwnBYoowJi?+__LpV;mXykPfkruEg1$w zz{>Rmt|)h}ivsn)YD^D3IPOwWhu}s`2`Cs8yvn-u(WMX07)GRIm&SmZ06+vZxq{0J zO>mo?g;S?apUtH69_Ku~R+OmBN97Nv8;!;^rO{L-ohoP3*>WbAS!9%f$0cw@fihEv z1W*dDTSH-ju^_$=5IOC4LRE)(aHt{ON%{pN6@LGsJvJLyW7nD+n6vvGi$Q=!tmM>k0 zMB(J$jwDCt!o-RB|90}^Q*(kC zAcM@^yG=jxcW?jb`G5H7KRwmj5xJ-lZ$5JJ#7D2b`mG-eDPVnNHTl=y|H0S(g}p0* zkD^NRUsYFCAL%=E=O*bS3|7*Rx>5yai!i~|ZpN10I=opE+{W}RKH5uJ5F zbQBp5!2=wJRd75xq973n3FN*bxkyNNr#tDhx{j@S)ilI}1$J?NI{Ns1ba%ZvUtYcM zd*Ao}{!cJ2lNpvLjXK@n%{Se&e{OkkpLm%M-rsM1Z|^(hnc3DBvw6xuRaI3v9b)8j zuDRy3fBwKpY${zjj{Jj&0ko>+S7}6P#EkU9^6%Ah)ntINwns4C$1U6t?v*ugt7J(OBSe zx{Nx5#+#jOZT|lC^N&8ae%XVrl&O>IXjV?C8)vw{HFNK)|n4$Q86kt8v|O>kmFGDk|yPwe$6o z#-^r>kr8K{R$~aHrlfS-w&b=$sp)2~IK1q6`(0~g<)`IYnVBsrh1_+b`uOZ?t`VMT z?%b9&tJnNmr_+WuY#uLk=Vh2eE|-r+sg?e9e_Hnv9VTez@b3^D-=uPW^dJyAL9HcV#Nkx8wKOe` zQZkl|6eVcnlH&9G0KVuN1V7DpXHP5Gtv1GZoMJRI%tM3WjJ~0{A;&W|nnRF+zSn9R zqqW*bqe0(;CM7-w!Qu&o%#>150$hX?dR){EZJ5lV!Eu*2gTCT^IMFIV(bNd^pNov2 z%!T+tw;xf8Cj+EiyffTKpqLn0GG`-LY5DEb)Q9?c4@Sr^R+#cN-ODEk#If&q36)C0Xi@~y(HrBnB0Ry;FD_WN%>jE zSB00QMGt)Wjsu*Fq;f@&3=+x!EpHn}77}4}Ap<}=!8_(KjyPN?K7p`Qtsv-7&|5Tf zMhW(U$rt~7Auc`rnnfUjT9EDfJxj_eLFlZ@k%a)xp z>+9+Z&JLe7k|gEL%gb-BSh*6}45Kc$X7iRU*SlQqWS`$d#>XZM&cA;C{<(8X`)CH> z)g7-}o12=;)6&vfj8k+22M<)1V>~XucHXt0-Mr|g8ZlV#%+r6my}P~3$}l|W4BBC9 zp0)j__ucdH+kbu6diayd@@ZKaEpi3vsy$UVdsbQ5;qR5tZQB0Ij_XF9?l`BzVbbgM zgE`jh=4H#49zEC2Vl(|^)0Ua_O$`Mj&Jm+tuk$8OO>ADYc=6F^pL%vV?GNb`1VyW~ zD%XOW=6`tY_1ATc*MKczDrmx3{eR+5JL_iY)ZfOBtFJCd9pY+UL`0&3wj#sklQRA@mcF=`osn!;20bZ_P%#@{`18WHy0&71 zREF}b`8A$U0OMH>6K`S6;imrh*fSNuAgzs#k8O>OOK{dz9WUL!aq|i$NN=_km-gF- zhLwJA(A-ehfCc@58PQXw*hk$X#`iz^aN#xOa~tE#F~P)ygznDf&TNdwvD~ce*63LC z8IA@R6C%f>Zjbro$&>0obEiGoSl``7NytK9y@Y$_R;;v7R<<- z(Pg!z4vTrJe_p?FVcp64VuHd$rL$(#2qbeD%W;@a6Gf*8QHX%wucJu0CnGJr*=RJ4 z0>_B?xCo`eF%;~5dv9)C?a76TDD_a;tT`XZLY&UwvLmb06cb0snd5o~hX!;qlJp3M zM6*t<9TgqCr@MR7;?42iqQatmO$`khM-CjCL2?kdcg=m31P&0i2b7@^+T7OMg7@|J z8584^95@h+oR9-46Ok(+;QZFI&&$2*gflWLkyeqNDou>coh0eB8VAyI!T0ha*;SsDl>39nwSBdBCzPa2TK>@JoTgAokThOK(U0;)49L?JUCzeYL*W;~C3gL$pDm)HEkrGCq>4 zG^gcCHIMXTB;9X=zO$5X2Zdgo$W? zvqLoX%+r6Y@Or%3_{4;1efso%C8boJ=|5w3+U*z+Fhiq? zvX2dq8b93o_l4!(D{G84n}P|kaozo$J=uhC(2VKDttx%g8A@yuhg<2jkDBXF)ZiR} z83{`6P$`s*)8$t5_4X$VbD*}ug1p+AEXuKD$uR*~KcQ zGGr?#tnqri7>41P-k_snW8-_z_6_MYYKc>kV{VTte^A>3$t0S9sD=(wj5WvqmW#pypU@nlako&9~<7 zYin=IIQIGR88RFXq**E|IR-$h(J4plBj$SdDLlk*Mx9pcFinX;;A7;pLW0AgPd`gM zSXp`9jG3hev$Cx&l+NRpV~(@KX5cY){eP}sis2YTVkCLGrL*LdeFyuN-L<67ImF1H z`_qOBnhsL4O3IG(_4OsxovNSx`fIOwSFc%Fm6VidKS5INAWth|%&}(@6XVXHv?H|& zji=w0?;IRoS-~#>No;R#uqouc#bnljLP;P;R_a)%)@rwA;t-<^+TaXAJNl82i2<;&v z27D&9N{J@mq>MyuIj&&b1r(Ev3Fl~l2)76>3I6R(R{8R(84?jJ18#w=)u>Wf(vlKE z7UBTsWvFd=o(GI&00RyRaxV64IGnrkmzKk?4jPO*$A->a;Ag=BBS@1a9mNVd!0)c28dH3D-O9+h6n&QlT zk3RLtPVro?Dm3(`hYpwjeb0OI=FTnKA;SS=gba9=)jhEKfz7!&xo7|Nx4*3z80t@` zI&viC)*mctUAg=x)s_1`S%71h?3P=8ct~s1(daJ_lHNYom`nZ8!w+rBFUTE44l0_1 z=hi*@B7(oF0SK0$_U}1x!{?tI&&?`KJ=oLJZ#Yq1Q%qn4+68fJ@grJ3MS~j*LK>af)N<9Y3j~cwkY^HvteI7v(RT zRo1X;=gwTUR^wc@?9NJ*f?i?JT67_YUfDJHU z4~(jR^~;Ag%_u1zWEcRJrWInOO{q|T!{JuE`R1YCc?hX)<$90zr8z4fxUm+ zBRH4}oKCuGy3N+}U%US{gyUpPc6L_lZHpGwih1n%DGFe|^J#qZ%DEKG@VnpHQEO9E zAxoS|LT&^@0N4d97tkReNeaCfmRCN~Mu(gSgVz8~@UBz@20!0`kS zmvm5^Cttiey8TM2D!Hp754whg~^0@C?p;&wO%VFhz0^MJk)Q~YSfnWGz&t+V88=# zJn%dR;l_oW3=0H2%@((Pz!nH{Y$y;kB_zZjm=dk;_OqgGss=!4q6jWllkm z{=d97l|CnIz0$&6@%Av+3nz+%{@^go#9@;iE!Ks(tXKv}xrn?5Q)G3zi`vo5<)Syx zQGKWT3^m89i$#=3#oZO#=FXWpKp<3B1)C2tC4=>a8 z^>yWMzw`FIIde*OU>FwW$m4ZCTeWI)ZnpL8lfQkUqN}?rp}M*{<;I0KwywH&MRiTp z@dX%0$bN9+Er%3FB`xY_gGvJwhXKuT>WYecHsuxA1}O?h&$#xLoJMCS%n2sT4uUj6`x_YE}SQM&6f z|2>tXh*J#Ed8L)mIPiGA2Cvr#iHS*$TW?)dr-~w2CV;r#K~HJ?GiT0dc<1!)Tsc8H z@4NTzN{LSd;PEFO->Fp-;PG(ablN)~{`J3P3nR*+Y4@}7JC z>Bx&OygKXs_ujj{v#m3oW1#M}H(oFGdc9FOIo8@$t12qn+In=4J^uSO4fTx$!fC3m zojs?g_VW`%t=^6pYgSh4txFc6G=2jA_Rd`{S-$nNyQ@_YG*uKv5}+d@5eW|45)%_a ztJVM;3IWE$1;PO-MkKXrNQl*deWcHpH$C%IdQQ$BtvRJ@j8X6$p@~Yfjc#kue;@xlxv3An5ax3WbFBV(Ac?yi)`TS`~-}3IGW}Ga*P% z&uA$WoEspe*dXLsV`H=V`Ss7=@QVi@`O&cxM@u+fG!7i3P%YHe$B+aGBuR}GPR|*j z84f%?S~Bj$9b^Dbw-da+F$u8&(mfD_#92WJGJDp{CZ$3__n+yr-uLr+AK3Krrm_*I zn;>uiyB(1d1IMwTQmRl}AlePI!i!t62E9JC za>eo^Kma5rB#+^on7121oV#wvNDLt(VbtY{{msMwar@@KY`Gr8WFmQ=!DysF+$l<< z1G$_Mj*-xwDnx_^z|h~aA?X`mh{*dd>HYw?oqe{cNk-6VLi_0 zTlVz)Q|Y;azMnF+%g?EJ2DHF{3ZV};0tCTb_}cM0{NIelq(BkZ{0b9I!Zt z(s+1LpNk?3px+orT(}%2sssG%8P&wki3|f?9PY1z7Qc95r0KUPVWbEHAdxL|h&mKT zhWc#DNePIc9i5wH0pmD9cq9ZbHf0b}6HU<5RcEs#$DYc}F5D9no7%;aDxL;n{0cjg zbK?q0Qzw^+y##H)RLe~MD{`Gn*u___`BC2^(6;~p?gPMB-~k5~wJ>#o6A(v&0f`XD zB&kBFDyXmHf$;rNNW$|8)c>!vG&MKHAheiTGgewuJV4Wk7b?PKqqeZ&#x@h~V2N2yeT#gf`oSdf1faY-o^qY9-`OkETKDPFTwNF3wqvIz&FTrqL)Wsxl z0PU@9G2$wSJkN~f=UE5N5v)U)G}Q0&g3lL3HYkqBJSBcGyUT}kr-H&^*37adjaE}=L??;WZ?JvQ7Wk9+>o47zA>+2<4doUz4-hKON4aMB?N|x zK^zJ=={WYk*}J~qII1iB-5+yjc0FG2ZsPm~VyB5@iYh>)RUayWL{R%s-U<(`Xw;TK z(n?Jbja%BLjg(5|4IvR#`3sBbI+XfeL99@66Nm7Xs5DyN|M?TQa+uSgBiwtd*sMB zJMo<%^ki~;aiSCFIS%TV>Kg{1 zeCk`jJ9_ki*u)6@pyKxSs0ZOFp5T*gIJ=dE|%pC_vye4tXG7>0} z2lHSCU2YM8=~YUCD+iE8817_zAsyT#(+Y>VqEm*afXNe_T*#W&j-jEztO6p=I{;#q z!UzTpMpC0pvRcAKFG*S!SgJRqguhNxDfRd|#IK7URA5!4v zy1-1mvG)c{3W8(ZfxN&A6O$s0Yc$&;L+J_^7I0$x=f=K(lf%f1i7oKm>2sBi&NMke?%DD*ws^#nD8KfcP zV>V`{W>~5|6GOtV%k^6rQ!tT4=yOPB*V6IsgZ2avz;iyb>oQ9UX$b+rm@YaJk|al$ zTihgqb|4vJkje^{V;0L&LE^tmTZ>XjLU2LtN&rdE(}KF$^b_CMfuUn5IdWsUV z(->+tn@G&}Jt7)?W%#xJXP$ZXvB`@U?&vObEpFY~H^rDll#znA+kuRXNtAqa$5xP; zOHhR;6A&VabwcnJQnTf9F_-_p^GjctIXHOm==SZ~NBy>68hPXOT~9y#^lna4?!Z!G z5hd5ndWBNr_{eDI@S$HnIx;eHe>-Ti+itz>BiptSCfArL%P=rlmW6Up4-uDQS%nUg zk{@9h#g$60VT@sDXy`r;Qg|U^^CS-Hsjfj75dnJMmBxjD6c+t0AbHRV5l2z5e%<=n zZT_GizYh2<2d z>oc`gX5?BEPB?B1K=pcQ{52Hwx z!&ZikpZV8L%kG*weP#kqp$F~IKv)Xk45kC7lJe^SPN5sgYkJpgnC?hH4sf12*B#sX z>N*G$$>YjD|MBixBGUCKQ9;ga{rdGa0GOSdy=7VN{p{HICS^HL%BmCVcNjs_XSj4f zaexvVeyfGZ&;o+)gT;l#$l?mqwYrT=qRqB!YOP@cP}w{b1SYA_xF`AjzwyA=UwrCk z`;Twmwqs03nn+X|p4X}P=&L99WJYn7wuCs9rsXj#&Vl6%y43byb26nsow zs=IHz{zl*1Z=KkJELh&W<(7pbM}G6dzrMFYDIktnWN{0z);5QP z-vD0z^UK@jYO~et+qS*G|3~|WI;|@wlCheY<2rQxVGvMqLr8|jc`pmXlK*Rjp`oDT z!2ScrEvc4jwdvcRf8kGe>x|XCR+~ZR91vznmBf^i^i-&^;30Y4)-AVAJC=hu7V?qr ze0O-?<9mk(2Y)#H{qOx?IEoN^9`O-GF$1I}R6^M2XEJ<-%VeM6=1O3%A~OcLe+qmL zlK7cD80{g7d=@mDqJC)_78kVmzS8LFxup`{o^agorN+{LQmHCRb*+;t8<0dbkdFal zGQh0P2ONfQ`Ml3LRdB&@;?7bM0G1aP27(!OdTe}W$kfz@saY6EK-l1p0;E6~MSzKs z%y+^nBuXk!#qR0aOnrbOjl*<63$&~F9*$4j_)3`k;POzLF~AtcL3RTQ9P{{;0HaB2 zH}K|@3PCzBkJ`!C0v)5mMH1U7+VQS`g+Y~5>xT%>FEIg=_1P|WtANNZTxBY zGBhDEgX^zB=2wEt4E&Sen&;2C%;TIQ`Fjw#cpQ0b?ChzX)#|#b4@SokONnL>!o&t~ z0)q}X=I54RA`24}H566P^v9DE1IBoe(!gjxXW-|A>*xFJ?kd-XPzc+)GCDfGmXnk( zpfVZ%YPni-Q~{IcCU1cOoFd2Ahhv-CtpMdprS5xx%qkO_UMp2Iqx;bYz~K}Nnbfp` zl1{|ANFLnUQp(Fz&&u6Bbl#*~<^!+1`r19hQvBYp-TUJH0|$=x-_}3YYBb?k1&S;B zxAxT)w=gqZuXI$_)+z<8d{3v~L~TC=!0hGN{mhwhclg!U``&ry-7O6dSZn}WHf~%v z^z*?Ne)8ntF=kls(fGvXQ=_Lg7y}fY?uZ0W+L0XuK)EXM(n~LIi*!`&yS4xQgHJp; z^vJg#IicGcx)lPMl1v$vi#2Y);~_{5&!z5Diduy5G1RGf^r zpy@|NyNIQQB?Tat!M)M8+Ml?r-ZTH7TF!Dz#CR~NRtYC151$?#7$z-Bi7qQfr|IsDPM4Fd~R3@-5+;Kmd~fN%#s13HjR1 zCVTJuMl+~)(+{U(z44j(v6~ro_uY4&-RF6qPX~Y@cE;H`Bb?X493O(=5e(*g4B|yn zyq}G{onIK*26-1LDh$vYCd2yfb|1G{>juzR z2gWpdU^crTuWoK!gmbEy7|C(cOT0bl$#a1L0u56Biwe&lyL6#4SyodUUs8546|IHe zeDjckBstFc`T6LxXUj5R*OSd{9UW;-iUt{b_QJ(Iz+MD9O#z3^3Owl+p7#rI;Fe_p z|6v=`jnOe`8t%wyWEq14Y(fPD|T84ZTdxY2B1qCac}5 z(cBBT(|jkkyuAGVD^*oF$WU>t>*S;^AS5W*j3O@<7axQ+w>Br7K6NG+d6T##&#$L<5Jty2a2s2OqS1X| z?+-x|`2PL<{gI&*M|k*&gpQoUhig!D*sZ3f0~7aD>#-tBlAaJz7lZb(a^hrM$asyT zLf{7EzMI!ga0#ft*uzerIrH|-#-=SrMOE8A|NLLs78}Dw^BNl)tA^JAik{x2&d#ol zPTE1jfj|Z9Wl5}`JCWY*NvPE@gn#v;R1?hGuwbKiTKP72=uPe^otxF{JqF##;XY2Q3}fq>^Wt?ed8=F z&f9j}ZebFVUroQUv_xqq_49zs_XT!1w|2^jJ-Pxo$5yiyC`axAiYBx%aa$TEr*&EV z{T(?jhl%GaLWW%dTA2PoqtH*FU*Q!zK!yXX{r$A$9Y6k7Azd;!&=;A40cBqbQ%`7) z^LPRVIo3!Xj%vele>Jfj0ytePaJV49`v{Ht>DjEVu9h6uZRerZz7SqR4*6u=?;opJ zy#OVaks*X}&`@Suur9f{Fca3>+jHE>FbOd+n{TX`8SS`63xpy8ddUF?f{Q@#fDhjf z=nY2Tpjhq3jhh-_0m>}(*l3Q`Y~=Y02v77T0_GL|4=8pFFzrd-IR_&RHAv2$K7Hm` z`K9XQ>vfIsWo4IB0i**54k-9Mp3}Iv5dH7d1sQc$8#nj$_NEC1Lh#z_ueGlcc?=7z z+l~2@fm=_ja|%aHI&5~2vx7v&k^nUq{!dX+QO2Fy&7sI~=wbkNjM*G^)P5GpG#p(S z5guVi5t|cZ6LEF&x|EKV_Pyv>gFzo^H`@g}cO=if0>_QceW9%ESXpUh@)hZo_zM@x z@VIxTq)fxKPBd2^oN0@NAM z_*qEsymoY7Dch5$X$J-Mr8)8C^6IT4Dnmd}P!Jp!DkbnBR3^Kc@Y!eo$VCx$1dr=C zF{TZI(}?r}bRHCuilb4yEp&03uMOU_6FGw%$MTNVASaLFuHwMR_~?4_VT7p5<;D&} zxQlfSlgWg22t;o9`|z7by5Th(8tr7*-#-24+ZC7Vwwy2eX4|P#r?P3v!9@oqZA(@o zxuH}llWyH^*=U?wB8eBlgZ*su(!lZTM6Sm7PF--XT7UAfM~A^JT6u0D9PI7QUNq|R zqQXPlW1^!Q^m+sS`co(bngdn=GCz+5MzaMN=2l?k>PSWWrmY2Qd<0-f(VA~vHi!Y^ z@LG-uK>S}CHCB;Vc|>0k$MQ1ppiSa5s7tJ{kO0UM~u`0djBR=2ii zU>JFdab$t#Lv_E}in!m8171M6ps`lvQDlf|S z$?$YPhx#4Nv*zS_iD4LTe{X_t3zefi*^|1_Jb%&J_MqUX2I!>$=9LG4Bsreza!_ci z1MTB0@c06tQr&~R8m36!v8#aZw1SbYrhLM&Bo5>gIN#UX?)9xSNFxqm7WVht$~NjXdF$4$Yv2BAdNGH?r#8kVN;OjkZD&s}(9g^RnsEWjMFHL1 z4Cw6Y1zN2^8yA-$Lb!fBwBRDk@?`ZpOAbhg2vgAkJI;2EO2v5idq5u&f_$094 z7SwJWje}}rz|<125ZIl*yE9B2Hmg#pQj1HzIpizAxvuy-#UZ%3yufO`R`26_~LdBsA z`}gmcMn$YQq5Bf}@#!rI3C)a~wbxv&K61VBdg5!p-ldC-iB>L|me*ERRlF4vvQ8Hs z5k6tH*tnJDE^-dDP4q%VNi-Y zoWFhJAt4*a%quHFRaI5*O-<=U*tlz-7RD8qC^djH_)UKR)DvE<~I`LLBISE38gB5X68w*~6%rrXCk-xm47Bln$5b-_j zQVHhKKz_!aH#e~w|9iN^Q}DKrB>@SyG}fP3HzOPw8P3*Cjps#1Mztqx-C0aCKGdf8 zBq{WIYwz|9gZm~55L_W(Tm+bzod$!0{a}7}SsNX@S;{3uwjH~67w||HC`T3fi?h>k zPI0d9kBi!Pb~*oaXB&cGafN9>{#1O5|9I4>N4-I8z-pNlj*Z;S9v>ad^YdTZ9vl+c zfKm?}NG^C5w2$ehE(j~*23o@+*dUHqB&X~t0IUNH^tI$O=4G*nAiSx+81Cm)%k8_1 z(h(Tmy&wH_8QjjB#Lh7Su)+~lPxd{{Xddhi(w?{_shD>1sb6f_CRI;QYTLWpfyH71 z)|C}tvOug@!Qik8==Ag2*qAL+4&h@&3urdzhk1J{&134*SD+ z;gdgpEDetkk1$RqP$sL+uDM#1J36k~#1|l)A=-TSNKTorpKwXhugE-KT9RwBntU>T zwMYJL?m?x^0X#C2AOK7|#WLAqaR8Ew7U~R&;6UjYn78(4Wp?_BM6<)g!>J7o4TsRh zZFU=$kqqPX$}<{nGGEW=76|zB+9^%at(%P*J9ees_V*XrY<5d@O>K1|l8Yx!d@PNR zj~iK9eh}E&){GVD6%}%GwUSD5-M1D=4=%8rG(-z3%E*!nV zur9%Uz7-lO)`f{fC;WuI+=8#Zd;`gJD7UfEhNkGp7R`K5x+^w*pxR~` zd(za~w#u!J8W7%`NN5l;E<3R)!10# z)!N#3TH9I=!Zl2UX=MfHiT`H*{_&XD*fE>c8dOnU@!stGoCv+QFX;uR#-ZiE$cHG& zBh)FKk7MXrzM=;#hD?%M zefK4$HC+`azm!?eUsEdUJeWoX{p`gD?JIA8KEIHv>mB^R&vRs8jAwe{<31C6qN`={vH*L$8L1lpqC zm?!W!;8d# z_h6%FiEV|o%WK`S;>!wQ330J7LI~q20uzh~mXL(7ALX`R24eMVS(% z#FeT9*Ks%9r_VXv)8``kGEeOtLmu&q+s?2rvD)cRWVq1626wsVs}-x$Eyok{@_aHO zFDxbGB+{kD1$k*9B|DvdxyNi@;bR+I0P{2$S>vqskmdTIOYFJhpL+CUL+^`cIWO@m zGC5`|NM%ZEL9T^bJfd?5sKq~gyIL8joItH-b4FJ6pPxlOlI4b6QM;jgRJ?Y}6ZV9^ z>kPzqVH-r~au)R&&IjEdwDFE>cOB`^d(G14eSOlk;gR&9!{-RZQ4bn{n8*pqJZwOQ zyX_JzU)&fMt^F3NZy+nAyWtj`4 zWX>++IXC$FfIB#vzO2ylfd9j=d|_ZX{pIA0tPg-59|xe$87^MzwJn<*f@tt3h$n$P zBogl%)>PMhK_Z!ul6*b@WTi4&uwb-IZyLR!3iZ>c%=;)(0I%fHx8Cvpbt$wJ;9);3 z4|B#5|F%KtR|s_atZaPB6&SL z>IISw{UBVz@kQ7e`lBo#KbT?FG);aZ>piForI`Gl7=xjS^^ThpYetk|Tp@#^ zBdQI0t-Flu&QFZ7Lw1Fk^W4V~v>&p9E! z%9)48S0*2PEhiVglaq@n*w3Vr0+y-FWc&(0*OJ@cQ@wO$iq4Nl_8thKk5y8zFF=J#CBotx441Z z_LV7rP=5SvLVhxzlIJi-XOj%#$!D^CDlA_$yH~uS4bB_dg8Ui8Wl@U>{{A}r{q&Pv zy*DnRk41o_$_{^D6Ym``ZfYD}Q(qm&91ecQ9Iu|Q2iXFq`(Dhi0QAxg-S2lT*!A5H z#GZSP!`_(}oqQq-U%LfAg19G&6tVx{xZBayXHJ{?2P9M9Ey>hvN#C1@I)pfM9<(B$ z8BZ4Bqwu$bL$F*OaEZ3*#i@rgSv?<>;9Dx-Nn=wD2h2P28|1S+5$1kYBz1VAD8wKVx(TOXw?$gFGY) z`FP^<@BgN{$QMTxeiCfOw$TwN8t|R^{*~iJ*F>mf06z7D(in}83Vx-pNo6Gt__vCk3Bul%F@z#-w((i@ljy!~D_T2ZdOtgAsKSq4S} z+mc$Qb7k~;#1^_N@AXQ~KFSN&620EKy7s*7-G-x@k58R)z1MUs)6&!ooHA|Me_7aR zUS3{o*S)JfeeT>Dw%s3GD!6bcHovZ^Xd1Cy?ayPsJJwt%gO7R{)sa%mOz2U&_MIOz zAD{VT?EQ~Uv>m~gzScjqx*D6BGEI%mgkM&B#8Mqf(2l;>&Iv7Q zbqpKyHF#b)rqU9hd(y6Jeh=s6&y1Zsek!+L0B71`hjOGFI)E{7h36+3mjYV^6z%Z}fE{xZBbTT=ni)X~?MFZZD1jr3|Uy6>W) zfn?q*(`p#4-Zbe@SJ=bY=QM?KzIAnVrEMRp8)r_RbshiUL`K~aMvB>>z8+US)QP+* z0j)GKd^R5Ht>n;^TuXBCal4Eaicin}b?n3Azt4TYnZqiIvLge}jI~v@==DXTd;0+J zq4`iXzC_vUDm*l?tg; z2qA$HzcQE~8@k)-nc2pk*$ZE|hl#!-eB*tHeSqDa*ty%6@H22lgfG^ZD3vYb(t7OkNhw>!o~R8&#Q%D>9Y@8p*!&-ox6b@C16x}ep2 zD)W62=#Y5O=6!qtb!%B&ZJYP!=>_7~eX#TN&0TH7u_pjqP3^JO9t#||njjAd8#Bj8 z#lE9_=?9aC;VY#}I^ccC9&^DcT`_;G@s-MjU?+-?40fV`&x2S)L8oQ|ZKn@;+&J~k z>~9u1{#O_yqEiyv!vV*pmFElL?hp$0=!@LjPFdG`dAzEfCE>Y%iQw3^FF=f;Sp3GC zFc`Nl|K;(Yw6=X|Cd`6(`3-CdLsX2V)M7{rsmKD{5V((+iMTp>-@YwB5rx<1;F90Q zdrjxzc?d?_F(dbY2Dcbeav8UFj66F}Pfe!3c=>$6gHO@q^yFfvKUC)N!Wc@30!9#J z9E>6jzN0PI0oF?^Q7-xOW91+B7$w^n;eUVrmw*4KJAb(IKi|)PzrpZ%?XvaDFqyt% z>xwxg#}YGn-SRrtbe?|`o*m@#eLGv}A9!VQyq{R=3Wg7uaBT|hx>nfK4l?Nl#pjFL z-u}QI4C%04ZlY}d2pv`Hsq2%oi``w3O1WGX+ZCvZs-=pa&F(Fj^aPEMjV*Sn;W8CC z2F6FhPJ%Fs=pOT=+g@G*S5e#bSKNf(&3J_`t*|cJDwQ2a81pAs#tWK@wt;W6hzK)L zzHr!=+RFS;qaHMQ>+7We@B1I-pV%do>R0#!S@A1@E#A=q>vIfX_5m7!cE~s+1&An^Rkk%!1|WHB%i~x z%f$oFu44NGYpRbn?_ChBn#+IHGJ;G=Y{}xc?{=R4$3Oq+Pp9Ztbo`wX9Hiwv<{Bu# z)&;ZdJDA`AWLn}^zp5bHFq}mzh|7)k zTk7i{TxHmg%0-Go;RxgrdM(@mAWH%UJWUCq?H3_9FihqkXVP;?NK?U^0W~eyE}{Ar zWEf?bfO8_p$JM&;74nrCuIl@ww|`)n5(4FtGQTW~xJs~SKZ45%JVPe(smQbT?#*4Z zQkfg+9$XrVjjtBVCU^wFM1jErD+~eMAmj)^7)j%AZcxToPjJBZRGU(O`^VM z5CE{53lZ(MiaJc++WL!oDTv;YsHz^ z$l#MmcMtFTs?+}6!ZvYb8~Wu(gQtQmRIlef*}e4LgZ-nq*tL(A^L$D&5 z1ra~tw{Q=}LoxrIKpr5NtZqqe$c$0=A7YZO8%Zmm!t>^Q68U>8;{pA$8R**sxBHu`?-Hk0 zIf|IVrI=8zCp?&p^@Mk73YuUHG z_4Zz=d@?gJKJ_FP8(9Wnn%d#9z+RANNGk-$5;e_om@KxO{ClzG*~)C*-OFsv^<9fC zjg8(|EmxSB%wq;80hdaGfVU`x6UG7;Hc{J`AaB!X{7VX{v|+OTNh?O>kN=IgtKLT+wwXlyAI>Rna+x=aJ=idsM%Nhj(Ui+ec% zZpIaS1q4UC=_rL0`mqQGeV3n5M$<6Bh_HHQ_)=@H@10aDGo#lho`eR5m%)1+G}3l5 zAU^khNk%$-AMW^)Rmi8F@5yo`e;s1H>U5yti%w)a%L~mC_&Y>=y&o2bW z7lOmh>>=#<4#%Jc0jmt<@*aQ^Mj-$@qS%981?}fIXAci{?<;C>ZEAA%X#?RJk4#KD zAQmTni=uEuN0w2>)MK?ey}TG2f4Erq>=QY9KvvEAhBS zJL`5B-LF7urU}3%jY^4$BoS%ARUTJLaA4Lr1alv5(x!Cm| zjXs~x&c0b&zwZy~YuB$&JoT&L8X;nZ3^%P*W5Pf?fLayU6Rm-;E(ATwfJlKonV4U7 zO$E>u1Qv#H3V(MyvlZKT`|5!jAnB=_GmjgrQCAcqf!H~mcBu*y0AtB6xOF)2&r5K$ zwiQPkKu&_0$;)XVL=2?bS1Q3+9BRFLIEkfdX$JG-YEu_oG2|!;6j!$~X zRu5O!BES(MCK2Ug!I?aY_Ms3JFnj+n#qnw9zRK}wp#R2GP4BN!3j(%Gw1`4rq8ZW@ zFg|SX6EWL}tlz!@F>INlEfZ(x!?5sbg3Mu z_Y+6MpnxpfyO{FcJ+}h!Vt&PP{IMfva<%j72@VSg4ylEv@Uj?(2*Vhw^Q#IILdwgT z<@L$Sci+$Dr|IdhpLSrS2C+#yWA1TO;;p!EH?Cv%q)K?E(EJJz!WCYpnasum?wKHc zYx=j3J=h*YO~6U&q(ogzFortyOZiF0e@TJ^3;YIx^;!~8Z6)z zlwhabIC#wO;2BW~$D)eVbW#WgS-4!x$F_FfJqSm8(&2FQaZu~7W28cSDzTi@-s7l( z94XsDBn!q+EDC%@1V<}oK>3&n3mF(&4xu61p4%gwsw(K{;Baj?k;{e zV<$&UX~k>&|55Sn366Gew}vA>1EKIy1jqTu7lPvp!GS*W{|dCZ->$s%GqL@f9MY zk}yp(S~F|N>r--r14Bvf@+qllVPsOpX4IQBRq&@FI501_YH5ALU4Ju=5gDDi`PHNJc6!P>t0YcoIm!(hq0Y`|t~=D5?C$AJVnvWe3_F4slk4MG zOK?E;6@=kAlVE6{sm=9-RXcOPe)s@5@*th&L`4C~^8yFnmD=d8( zN_m>94#a|GT0*$_P(&3ggM19eS9_3@3-5kE`%up{pV8<9Fl;*?0t%M|16_y zHl4`lwi2vvMQM$puC8#dr*|-^cXh42-dK6qp?G|;{^6zW?rRx}?YdDxATkUK1fmZJ z8ko7@ixV6oFieniO@Xa&4SMR`Twj|n9UqVW!?$yfatGO|LSdV0gs~{J%Z8F09=(z5 z4D|4}>JX>UR*9rs8OAMXh`jwW1P87|~k1TdP56DRp;s=DMmQ7mP z#IXGw1NKAyU_xnuK#Pe`S+Dc{zP-LVUp1`Jn^Uuo6h$$1chZS!t(d5pg=p=xigdjz z7m37@eSL#TMb%KnPJy$5*ARgkmIsbK4F;osO?VCN4Wgt z4J0QgZmlGjpY!^x_{PU3mqI2`+J-cPS}?~wZzT0#*Gg(*>!Al>UY~f0@v`(-~ST2BvhUZS#leY7kj*KR{u6%$Q_RU?z`VV+D>Pt^0{21fzP6LSWg4z z1_rM4e0C>wJq$4jvJ)`>|I}`5k5(7a;6RrqINB2!l+wDzmcWQ|t%)zp^%`fMQ-^u>pV`cWhjMwMzA6^nUrk9lx#bm;F4zl@LEeC7>A z8Wjs83lkY@>nva1NmYEzU~NG*;`1gxgfU?4MQ8#*pehXQ?Yy0~%%k9$S)B@YhU50+ zFc8pe>&4)LXmfKDv9q((_^q!NJ%Rp;Gz(0jK>y(WJ5l+j%HDEp2LRum83X z2>7`}nNe_+i;;&5l_!Y1$U?`*#lvuS|I0{p_*qx?V8h^`K{1B1@|ff#t<6Yr0Syj$ zBJ5ffq4tW|QTq1b!OmPH8j9*#0O`RnQdN!Dr-e4tJIJJ-RD5D`(HH2dFuUDg@`(rz zCd);b81M)WSF7Z-H!H~nZXr4z(u1hGyBofLE|-JvZ<=OG3q@a@5xwKa$P&wFpMb=_Qa>Br;$7w z1ie~GqxxA#YUZ177Fk27fI2L4CgwsszaYWU3^46h9tZ>zs?!EC%KKXGAhqD@sK=ub z9S!wgL$(lEtJP3ue-BlS`k@l&eHkCS`RufT8Wj4o)h^E%EShJC*Qe&xqs)*yjTXm= zxCN+P0NbA6_$Uzyv$h0>JX-g$N`m8ZghA`~za+tdf2sh~)QrE_+_-|Ht$>alSFf5q zk)s7I`Pcti(1Ut>i1(#PPXz1_6pxRQVN}oocPpj(^_L?f)6Y6N-W$}hAs{1G+O-MU z^W;RfX@R44OQ&?50(tlI-}iS?)24M4H0!0QP)LhwfdI#Q9me~bQAVk)ZFEwlsmZCC z#fCRfp-cr0J0Jp1X*TL`;pgYD5&!K>_@z`Js~Fq$b$XMyW4x2 z%{lIADcaQ)vTdyZ@x)z7a{Nr8GcG@IP1(hcK#a>ziklXbb}-uY?{*t5{_W3ydHDM~ zcandczrWUw;1F5{7Syp(I@Z=#mlp;j-SLRtiF!goE){p6z3e{P&g|Nnd#S!y{FOzu zj=}i&^Lm4$f>?QV=b{;%M7=s;cw)_=WIkGM-S{NQ9LDpLo;GWRphZun0v(O`#6S#n zdKKis3aXxZ(3`bw(^LJ3w#_GQPay#D(9(XT ze2OK`Ihwjwh4=rB+ed|iIltc*o%~<+&c3;ABT3^A8iN4{zDpuyNfaqa)>~{PF)p>a z+PbR!4*JUX-|f}q_L5tzV>^zN_(c-+PKhKq80=t3PhrV5ZSP7+ZR}?Kil8k~Akc%S z+34xn+yXKcz2E%Lw{YCt^K~`$ylGV!o6~> zxm3ksy@XoXN0BoG3$xhST*Ja_DR{c~-7ciSuV)g_qIZMCpPub*t~G+y#W^g@`KaVA z?~fj#>gQp|=kV3eHWsSI;Lrd2%`Rv17heINC`IT- zsrx_vWw+#0u(7s`VCf#>{tY~4VR62S&(@nLdQ`tUJzk9mA^{kfSAvB0Bh76&EScj! zYA!n*6Bofa6^0{ZegyPxL!mvt_O>OL^4i zT+Ea>avVxiUHtCLZB&aac=DJ3--V38NSJH&U7E?A43pZr5++SB`+4H!pG zj(0MQ{T`X|KZK#cIr>-UJI(o-+JAf{vx8@Qf7&Go(8Rc( zK9*#5`%?wsC;N@rN1NcFA*0g!NSB129=!p%thJU zAt7_V?%V{x0LBFl+XtcR#=-sj%kX*XqY~9z1rE80Ix&i@gfF(fKr!bA$7=iu$V}jj zA;fMsD<>Ibin)Ur;n@%0g|*pyu(sNQ1A=Ee3L73vNsw~|wzn2h@C?-jAC*24Ktf@9-kAD;F(&+sOVVgW7(lB5Glt`s-0L|jLd2ycjjZHfE1>06J&(f zuMfhsaw8i*iNU4*KV}hJ<|AmX!*`3p#mQwj3`OYgbwvT_4N?J<2*MbXdO0z*O`)ep zXg!Lep4!i!Lzf{~TBxCv%y@KgE)Z@3EC%Z_^yxU;wp-MIe7f!PhtD~0H7Wi zqrX30Ad8NJQb=!4zBZ4E^oU8sNrkou`#(PpT`y4;5i{Ucs-pl)Y#sL%xQ#qdl-@6) zlp6$39{+a;h!31%D#n*iO>IRZt0+(`dZ5Q0J z;4y)cXX{w6;4^hRzYT{m;+t5+XyJ4+$&K5;u_2~2{pa69Pv6F;>W$koiGNl5=v{ym zjG!~RuMhV_H7!L8*~P^fJlD~yrnp3aOfcw2paf_%8tHOTA!iKQ=q*x~5rxSwg90Sq z&xx|t42%dzuaCmb&27XYK@txDIWWl+*C9mxYxKKUsFsU5IMSWB3E&ELmpOB@EG%?$ zua^fugh6Wsi2x`ec#emnUxZB#gc$AxV;s$96UQefVY)3T`!i zBykKW1T2}rb2v(cBBFjD_gB|&{OV;G^?Kk8@OU=hp&?VfF6-Vj+38#|n0KMEX+Wa{ z$obhtxE8F!v2EnI3lT*bdWePc)!r#S+g`!d*JlJy}VzWc1$5+#P;) z!v~LXLKbb=B>+=4DwCnhjg_i=Xqq6X@K z5GeqIeq@{2c?usAo`RbxEavV6goX$sB(gAI7(gfl5jqlRU-fHA;=yw(NXQ1rGLXX% zCkY(SMP;^x!Qi5nem3X^r^p6+LqM9_GT-<0@${gu<66%35Cf1F!FF7nUv&^CfJF?w z{s1unp6{c5abCL-J(v|?O{LwK3Xq%*{)WGOkN`$VO$3rRi24^b*Gu5JR+=!4s4r)**>^c(pa$% z$10-RvB1>pfK?$_982{O)M%#`i|5Tw9(73v$I+>szQgh@!_&cb*SOVQ^; zpxf)z9G4*>pc{1o+cH=zfs>0-C|iiSN9cFkHOfSzlOm0&=X?5{1=5Val?M*GiQrnI z<|hKl^))OJ>vJMx3|ImQ3H=&mp*mAWV#%6rxW+K@Cm3YPWO=XI-EpI74+4mdAO!&1 zmNoyc?44n6;z$gJpYb>$DbPiGoBjX4?!KL_+ZGCmZ-2Py}s5X@+B~0 zL~J?EODkv<1tX{g>4_|8&fy!fY1dq>R-Ler2ro;6OL_2i`GPm>-=*GgzRmpn{5O4n zAGS#NxYCPbl^SuU_5n%#DX6d^x_RH&{HQNDir{@CES>2N_%Kv5(@ z1!RH3gaiT$92G;!#DF9F{Y|Hpv)QbuNN7=NuY*Rf$S6KIO_e!3+;mPf;Bhl> z-c=$x8BrTWj@{L|#XO6B@$;>s)9oEc90m^%II?>{@4^3p5^A(-nEW_fTP zKa)DtCe&^KIEL0Wr(@q;Z+EfwBo!$K6a*)xBlxoW%69jKzW)*V6F=h4x&BlAlu9bE zzETPt%g|{xkn;nY29$!NLM54YeN8_m%nQ28xQyMgzvuq`mfdcLW580&NdbW=PX}t4 z7_J85fkY?>fuKPI1QIAhO@Fj56``%x?Dr=ur$-!1BV#dgm07ndaw;@+)rs@$j0i{| zc)%oou|Xg+)6{e9zf5O@k!o)Usk`1>#UBIoHcp>1?|&GGp2oy#_l?aT-#et4)?*-Z zy&e+m3|_!y&U7|?=$Knqt02Wm7@7+zi5&G)hAQK=(2pmY)v9Bv*~FK*&7Y6YeDtZ` zT>sk!2a~J^Txhf*I{G-0Q(WY3e;g;T?Do8L z)DDxQOiDGwFj5kjcrc`qoBa<445|b;b>%dZ)w%WWv*9j2CsMa4tZ2k(HAN!RtoZ1W zOwOHcPeYIAL_w&v!2xlAcd|LgVTlrZnWWGUJ%pCYZX{QVDx8M9nCKB;PRzWYJaCrD zPwRTVBQn?kWnL@hCGIk~7sv`gRST*{FEe7N+# zb^OS2(w_eRf6%jOlR8aeS8ycD5(P=5_$Ij6Ej0&$D9WlNOH}>3JokY5Kw&Vu*qNQ3 zoxNH=!`LJ?N=UeePh9-XoMqCIP=JAD2!>pP`dh z!p!U}x`RFd{xrG!girYN4jh9a0S?1pTSe$slcVMV40<3RvIWHR7!ERdfL!6>u+clG^Q0W4Why;|))5P(MJ3R4Hk7x_~FE zWv3l1$FLc}Wr3uIDitQTI3yK&V42I9nOPY1fi4^vPJ#s%jx4f2f(Q8+u-|B7W~6`O z2-g0uf_Nmni694$=`&O_NxRhtc@aPgA}^?*1tADas2?>EmdZ(yQ$u{tUT+p&xe9t- z#0nrE$38(AmM(Aa$zEdoyj%?iW=44?N?PqEJQ(=LbZ=&>b%b&$ zO5}I+HWMc^!87)KoM*<8Xr!Y~Zvf9{;E%b8usBXx-mzAvExy)SoydE0p1q#TjwccbOS7%HirVPInqL&V^y|)Wyr3sX$eBN{i zIBR5#HF7TyfjQ9o`}^V;s6a^seDe1c5Nf--SX*7w#-tPGciQJZ5z^FRaqaVwKKDU> zC~cj2BZ6Ubz4_!zFsapU!Easp5ENgFN za5Z^BuJyZL=~uh^FrI=D`Em(7f-A;=0K0n$KD+aU1~F1=r@umaDtJU#SzOm!n>F}; z2`Z@O{q=+hLU1&Lmm{6eEiLJrl#dF&D_~q7^s$@44;XfWCzBKcA&O@7?%p2y=|Hx0 zs&WaL2ceZK#K!I>dstmx)2T62PByY{oOMr9qDsT*J?E| z%Q%0EDJ&fOl4Vfuv=A_BCI&3Te%=IpBImN~Qb94X_sb*yBsqcv)jcYFK0_AKOc_BK zqM!D#vsZ&pvzkzbH4K}I&A1)+KX)vaSC;jw&28zctjf9FJh4w+5D9#RPWlFIak$$fqZ*T92!{9sxPzV)CKnC?j z8@ovzLu2EwAN*MxV^FD9p_mI9i+fxEn}6^o=Acu1oEf6eW*bkQeyfv%!}#@X4aUi2 zQ3hn^F)Xpj{)7G}(%~@vY;|2T@j0E6Kvp;zroYY>_o80H{M?Feb_Vgw?Ha%#jK~*2 zg)?HLjR7_`HnCr;$B)1Ji?(uK0u!c-;<*`sPy$@*qkv30$l~WOUW(xx!V|+sVFXpK z;HcZh%grrxdujam$s=uG^Y#{_cY{HLGkabIO!8f1z5nQ;KI*6OkH5S?dziub3aKNZ zd>{JQ_|GdG9<<{}kDh9PraUn57$KK#+Qs6^s_v(VH{#bwhlDVigMklXC4IG%ruc0m zMx)t_Kfm`UZIHjwglVD}2Uz4)SYQ8A_j)$|?UzjqdJga+7z?2zmh1D47@b}ke|7(X z&Kn&{T~q{>0lW_m4h!Et^uibLs`uv!-Xbnu>G}vVHm)}Cr>STO{WQgcM~`&7+mE-l z_s}0?AP!~K*&N$@3$dj?K6{3AFo>6zRx}Z&jd-MtuM42bxtR|9~R}B0B%=xNZhYaS9#8-hco7-*ltiiH|4azAJ&e zGAsq6%YNpNIl|xn@e{hkES_Cn(@@a`^H#cXd6iOFT3XcIZYSQ}*@Yh{I4_WPS5XDz zN0KS=bWmGE>a$KqA0_Pth5>9?VC`f!v3m`vw)fjwz{~Mhd8$bKk zuSf?TJW|Ip3UU11lE|87Ui`(q`x>Bg$0@pWM&DK1KN2|~e)CY*59%YGzCfotgwGKM zsg*wJz%m}Z*w{SIHj2Nzdq)F+F}P(A9zK4e`)L}#*m#Lnrw7T}GMUhU(CcJ)_RDiL z+r9YSSNAkCf!RXrJ&m2ZO;+GglXAN)|B;DyO+|Aszw`e$@T(+3{#I4;t{B*}=iGbG@1A?^ zIUZR8k4FMgg!%-6{H>wrYN~)Ad_M>2Orbvc@$;mG?Gkrx?5alYY^dV~rHDI4UUxGo zFq-4GI)AO*_a= zZP97xxG+u17qRW{yf>CuUd=sZ4i}uwfvOoy=S9e7HklJ<0kXJ&gTeQsdbuK)COMTI zJOttqQa&h|ODO^oc_7#p8e3UeaW8iXTHU{e(+t}+r6V-G>P>V$? zJp0sF;~-i@Ov2B)mMR7UL5gk_OL%tvDXeX5f?6S*GTBXdF!2P|Gx=O!@8ugiJ8Hw5 zpLP`gequGz15gzlNcQ-m_}LC#h^@fV>IN890W_lu_3-cr18nQLeD3{^KDuF2097Mk z($k(yDFC%o*x4be=RfEkTTO4~=H`=i-Z&s<#IGkFJZ8Gz#2#-TsvCO(Sd0~SG?3&I zIuh(A{vXs}dkc1c?(M)SUMJhp$4KN0vfbSh@_Elh)7d1zOaV$-4Ghx>`Md^m zY`!Y0YOcM*vQO%(wfD5i2s6Z(Ztv_ITTHFwCZ}d0vyp?MR$=x@Wqg)lY9<;#| zwzDx`5p+`p0w$|;z3LFf4o#x}O{xrdKuAd{`j)dbzBL8(X} z5{W}LyN!JxW9EvTyIVRJ>5Pnd^B_4U-ez z$ivj^JR})zdH4K>H|(_Jud$hwJ7Spp%Ba1gBbwVO;-^b#SY>=VTwc(t0&J-UJeg-0 zD!-NMxzKx~$ng{K1f{RL5n@8HF#V2w`(Ky?VTNiY|g z8rCZ)bosMCggeglD2c^19>0B`e0yu0#8WHS-QrgySx&9u?4aD@5xm|2&?XXaGCJvg zl-=1(eShJ&y}f-+cKgyT{*bb=TEI8Qr^xMl({FCE^=-lx60|AIWT^ueM5bEjwGVBe#uPmh2@y*Fu^4)_Ol3dxu4wp|s zvWLktGw5-*2!5~kaK}8IL1w>$uIqqAk%60?YaX93&71n%@Z?px!zZzDxT5vuR8)u5hHbRNG8GZ1 zx(>uNK{pA+lc{0NAfaD$_lBLG7KKGY;JXhdNu82R^M1y^OZKPYiPWIW=@zW=vZtZ* zM%MWc3OW#~!lUVj!+Q=#=+dPx!Y(gr^u~akI3>$4tss)6iN1`Rx_DFH?vP(zqk44TM2>>21-Najiw?K5D=a4 zQtF$9U1slF(!M}INv&mU`xH-Puqd`ESAPA+umib+_aEIGK~6&eR3G!wON}Q*oPP3T zN{9+3)uF9TX87sJuvUi9FE4)`?hJjR#A9iEi{Yp57=B8utYVMPuQ+9QYISXWPgw#@W zptM`+y7J}kM};bnyW>EJA{|64mn32LF4^Olcr-QSba}|7zR#}{Q+mN}9|ik(0BypA zH-KQf#bqSRFZGR9s}72g%m)i0CO4WM*~1OFTNWLUpD_kD5QBvt`E8yAYUVKadMSYeYCA&Y}XD^8n`^1Lz$Z3enj|17N6K7yJ80_i6&= z$0#V5Czq`xN<7j>a8Sp>!rTzlDAWJt>!RESI-y|N`iFzUY__by(!F`G3u<#gpELf@ zkIfC|0de57fztz9ySc857kfwDE*Guy1dJGuR$nne1_U*OIO6fxP*re}ZZ@XaxAvGa zk!c|v^t@-<%g&=s*x{P+2aXy7qD0{7LS&#ut6dknSzq0gDTgN#<(1)dwa5XHt`l(7 zz!6O*hICpZy`TN&I@Gy037{kL!&maLj#es! z5>W>vQ9C~m2k;1iOOhOO(b$miU-qu;H;(EKuZQv4Y)k|}YOyLuRe@ZH*I;g{RQgcm z%?}k)RsRWntknNtO05<{(}-4T6A0L~z;1%mjkBzm#WAbJO_R+s*_h3+aUcoAYh2rj z$M#-kXLfeB-}%k)S$h^cM3e_AHu*F&XU?4So!?!VOQfCF?%j`s{H^XsQEhI^-dSnu za5+nCKHe?}S+tRCzuWGo=tlVZzed?L9ErFsZ{{u8+zPgQsJ-zWV~6aRt`TvI#%`do zMUg1oRh1~ni;ZZ!<9N;;)Jq~G0MJd_R_&h#pnnIk)Nt8Kl$kzxH|n;;NN3fW=nmK3`OC8TV`IDi0YJSKQxs9GcSb;pT z!|SK!R)5pEq}tokvco#i^)%`yHj3=AXM2NRN_;}cL(*U8A_<KZbu>-p0me*8udJ*~5&EztCFM(YI!YyaK@h@m@uC7bdj4^^;WCc=COLo`7CkUh{o^<2vjV zbt&w0NArD-W5dQAmY@9M`zN>@)x5vyLMqkUy5m0U(fv<^T>Wo++DgQD(xt=x)a}&c z;c}zBioT9$<@QQ#H)b^0>U_uJ-9hNT*|8<6naJ364UpviP_@k!|2g&5hXsZZu;;;wfFu9zHfEx{$Z%Ct&Ob55-S(;yE`766?W_h83HUue3QAM(OVj0 zmA!$RxD2~@EDP1?tVV$uAY8z?jqlFe<8o8SD)u5|M2Uc z9@F>T?|=5Af8dB@Ol2KWt+E-JFGqwU@p(;&Xf-9AsVb8*H6=P-RbpxEt3cXN;_2JU zTainnuMEWXGv{vgCseelCe9U=iRrwH3mQHkK%u$ot* zX%qcxbsiellf}AbbnF{+%t7)DV?Cjap~OC^fv1Zw02yHXiZT?-jQ(*TtiPwu^~W*C zB$J&$UVyl347d6Y55AK-`j7V$ld0QEJcV=WsuEKnYw!X$@H8<8FkQj?HEaoxZ`HMp z>2-kTMx;%WaU8mzx(2RE$VJ0-OvkuxbmGeB;em1e%%z3?==5#$1s?#i1F)Yq0F$Ls-9%C*z~-#E05{^3X+(^z3w`2hP3buBtJ-85$4vG> zm_Y+qY)`7_tARWC$5dSzJbiKWPlFTschXb!Cyc4>4d^e_G0vp4!D zNp9e)8FhdM02vXW|CPSK4n}fgifarG(}lJUgQK_w3<7-DgNlHN`2^0J#Te$lNt0qCwRy(yT*FZlh^B?T z()z+_7Qcl}i8TX)2k{j!w*<|v8C!ukZ4YlA^RBD19rzjrNJdeWWCn;eV*LOeZ|;vV zz9r!Lbs>(=&DMk+O@6{`ndkgzmcMoQQeGJdT^K$5YD9lO1)opn*|{x{XSp8n;y-lWM22WDzo;n#kqJ@+`q5AN^8jP7gZNpUZMwkga%3|oEa)p7lOCNp7M~Fn|H^65c1Gi)&yAI z=CV}bAB+#xTs)6xK(;FKH1z+q0r_}P+ZJKfptu=l$H}UaSg)IB7{B%WXb5<6t&qLQ z7b(Ov8k^e*n`0aBIOwrGuPtt04+z{j--|p^&u_-oXdI7pHUW^_GT2YKb@UW#=ebbC z{q5@s8lUV7TW0fr9v^SmNJY0^lZN#xh`$JpD40i@fcZwI$Cf(mVKCE%^x+K_)QUkmXi;&z^n5^Ye4Tg{7O_g|$V-k=75&&>h(t zxH2%g%6I%%RS@KNn*e_2!M4iuG|VpW1sk7@J7MM3#r7{|Z}dF8_eUcwyS`_X9A=xu zQvh111LsQRs@?VEQ^SkP3&G1-wcBwD&==hq!n6f&W_H`k<%GYDWVd=Y5M25FHjDe1 zY@^x2>oW`O`pT`IeS01qxqs&_L)fLqUTp>$kXn5$Z4cNFJowP?T0sxae)efMWXXMj z!EqrwWHk0Y6VD*UqEl}w~!6DSMS{%@7;4@wA5FY*>!B+ zV&jrb3#DbeYY$t^ecIFh&<{rL4eTjylu-r;_hHWdtHYjXuEs=CGT5< zp9|Oz`8jVIzPor_swTU#Bg`-lwKTwQ2Zca_^+=P%x`7HSJ%^JF3z`A|HVc%xau zP_m(#W?`MHS?}dbZ(5dqd2_?Td$P;Om-7&#gr|<&M2AmL>rQoB=~}`CB+CTm$SKH^ z9b>u%1$Dc5V|nRz=YQBc(Ld?E9}pr1F&H7)6XrX26XqZJ zdtf_tb^Md_Z*HdNFK^`*t}>?#TgsGBmAd}ykvn;pa~(@O>9o?BM&{GM_==a5rh>TRS`%+$a#R4C}% z%}Q?Tc1u(9eW^BD01!N0nM)Q&66SH*f#(y+7@v*EN%x zmpQC2fwh0|-S58kKmO;pZjX&j#OeN1mvQnh+Rv%d-{n+};GcfapmI7TyVJ5vT6Rxa zXqrKNOhlTUU9EAe3*2Xa*#FrNaJVZpNoxfgPz$hC&mE*ifKg<)MTUg%C&nt zIpwC3UhFW`3<$OflJi_s1KZTeh@D8SwS&MR9S0FI2uK2+;~fWCRe|X_ymtf3Sb;-p zO`4g0e5bp&Yba9RlCf-o9Iwii7eESzD99m-4Myvk?t8hN%+0Osxeg8M&2dh;Fv^M7 zUC6YNy!{i9*z==uy2c~7J{HMcfl$zds$xc3TN$|%uL})DB9ROl&6m;!hV_nx zBS!z_zI!`L?xvYnI&7u_a0=Lv!{0Mt+sa8pdFoaIZoTNM!>2{Eua7v+6!I$=aHwxe zYfIC2&YzcugrJns3=0faS%tlpZ~zc^<3d;4J=4tH+)9sjnEDEWv<5-Y!PGYiR5>re zb|imb5+3<-OL2@>2BpE03Z}UUmYG9YZb-|EGk4nCFAPOPEg8?85@Mb-(sXn|6F`DM zAa1m`cHC2TayRD}W;#UCal$f4Ij2pLG_XMj0E1*oU|nHL5Y9WAr0=01Kn&Z{wlr|c zEf^VT1>3W+sbMG@jbvzz^-Ju9!*c@ofit?hd+!;0dpA{OqeIg-sQx^sfJOW&Bu8%$ zk3?Wp4yfL~Cf3m_7nwy4T2M4Vl1!)nBkfD8D>HYR8_y1jLQ96(p^|Re!m0AF66=gJ zov2rua&t%B=ny!pKOi|a#wJJAZA*t7C(VMDrPaD$`_=#WjnDt;SAGYM*)AX0RbT${ zm%s6!zxKu#O%r9$yP$0od9w82+&+c8>-aJPA}Z?zOE%^g<{Cyv#;&cbuE}`K$v64X zk;*9@k&X+L19F@xDEIKgkGh|xhOcdBvSG_$pel}iIH9**ec<%^R1W9ZFHM!wOkbMH zJ`~va_P4+NuU~)tOTYcb*S`M7?|^ju07}Cs z60oJ^z}7Ya4Ae&@1}j_NPyz2%%>YSgG~~p^d%N4&o4M>_ zhpw%G01nn$G~i>FN&|Bu+j_wYYrae~oojTmYaICvj*Vgfpn`$+B(JSXYs=GjV&V8u zeWVrf9w@j^n8#UkKOW1|sVSiD=Q#s6N4%%1sPo%P9lE-PEF$Lf23TeWN_gcgy|cUl zZaKkGo6-QD{3kU>wiL@j(vb?1ivCkmJd8H9CUcS(H(E%1n%-Gw-!fe_vA!|m+}X~1 zc>m2@W}bKyKzA^jh~sns(1G)CpH;+Bk5{_ZB$-HvpA8WKc$7;Bd9@t;T%NjfzN=$M z3wy+Xng4RGxh@$YDRfq=T?i;2DG*`8&Zp(C}!3ZDys_g=cq~6AeSL`i6{V+Q4{P zmR%V?9X_4q-q_(gFLvM4_q3bYjl~X2&yepVBANKzHZ=gJJ-o>c_JYEmZ&{Q*)sq9Q zr2i6>e3hD_w3VK{)7l&z3f0zRNXEp^iwb4Oh{JoauXbO(m)l;xncJT2u*^-ze?roL zV}>`e;Z6LoQo$3WGj+f9m9Ku|*S_%j@9-2%0U9V9TE6P5zxAKK@!Mbh+824wTO0CE zL#KZTznp%N+fo`Yc40d zjDY{gkzI+Pj7|nbZ6fZZjRLNW;2518y1w_`PkO)gt?&HXU;p(tzVhFG_xHZ$ulnqc z_kUrxikAd(Pw6#gyW1NBQ|YAv4i4h}qN5y#Is)@>V`FUEbc_@)f_-AW|H<&X?HYxk z7^KK@V>GISgVDQ7a|^ddR~Bvv)qGqx42VYSvQ5qHsc@_zMMb#xl6|PKkvWz}2GZ1X zkk2avJIdyOrtQQJSrMXPDJ$>?>C4@n_eG&G?PPRN)ZSZ9Z@{4KSxePhKk;%wi9!(tJ6O{5a7-6>I&z+|qQV)Jg*nFpvmlE4e4_S6l?W!4AO zOnLyg{kZL?nKL~U3J-_FvFTtiLW2kf_9yMajl^Ml0+rbqYf-{A+}*{c*;`Lmo??3n z@%{Z>h{a;rrY1R68*NI_P>~vyIXsmCN7;ufMXxngfz7Pbo|yr4FBcC~`{3}<)Fa{8 zaL2jUX+zh*v<0l6QBfs0m++ai&jAKSlvl34a`)N9#I5z!^bM|xix-PUun)OxysjnH z*d(OrJ@7A*4adCwHAsX$+npt|K@tE|U4cZ28 zjr9tJz;J|RowgB}Kx@gd4V74^=I-p|{H@9Hi5no*Gh`=&Hmi$^1DVX`fU&csIOPp%LPB7 z+OTrrT*uvwwXO53EB3%@dT{`CGVZv8KHHydXlhAG!AMF9MV@>6j7>y+)yvir1wfEi zAgg2t_Vk^Btg;n%t`bE-mjc1zt_z*hx?v)pJjwMm;Kgfb-=5mq8U<$p?=COQ-`ZNu z+|Z4^cpxAG=c~@vq5R`0f59dI`ouEn3eFvv;nCD}*vsbzFcS*<>u!9%=!YUJ?$rjR z;nr4p+P1i(_VesY<0Y!)dmg}?mY*TAns=79k5+gCv zbb%KEijIc)K&TQ<+AR{K&vlHDY&v%$+lzY+R#-*oAz9gOee4$pe9HrCqTqO?esaDF z`GOY!I9hj2_m$0}oy_PHgi^m0tEyn9Z~zDU2Ow}fND>dMY=CDU@%nN*(tr9l>v;Q^ zc)WUbq36ELDqZ)w=jXXi6F}eFi}rMP5BFZ~UD#Mp#~(j={3|olGoSn3AAe8%{D1hu z1NgcB*k0B~(8+$JOb!*4t&M@*&Gdkev(SDpI0VqE#o%yDQ~fk^^erg5_L-}QPh=~C z63RXZ@mQl0sfD}qOH;STA5Y%kFd}Q)hamU^*}BFA+WfOA0FeepC-&5`xg*hf13!zh zHY_6tdwV+r%C>^~z89~mqJ0;$@%niBQdiskpb$-KiVnaBUA#NCKLZsi9A}vH0)Pg- zO5erqyAzXBw+hz54b!sXQn(g)zdsv|#ZvKjJS7SdFsVEm%u{{2GTS5y0`Y4YI;cu| zU~_$LfP=%hQ4kTA5VrEc1?4B!N3kFQE|kQSi`vmM(jkuTAJb}1C}-CbOmy*2h^ z>V_bSaXoK9tS*{uZf;IR!i_273y#&1biK^a;lQ;aF5YV@>?)aog0?fTo6W?9Lk0m6 z@e^%mLwyN9B?&DL)q*2k>_3-P`>8;>`nnwy%DUk=L^ zOC?nR63%;*7n02o@23Y?K^xF_m3Se)1ES>DIn#a&0=rQ(!0* zs8zbpT|m5FKA-l@4`jE}1K2=ux~_=66#AxtnkeBtg%8~3^zepUK`#_T!3|wkusyQ_ zd6d7pm5E2BYP{w^$2aE;w_T8@bB0FsK7CHh4I2m|G&MFTA)dRtv9Nq=F1L20=s%1b z=05nUge<;+FV&K0O9iC}IDvmhOx|7`o~VxFfg7ZBvZ+l4c63MobEN;4g)$PV^~R<~ zv{T_}+jDWt_Q!Z$$J{32AY2<%E?sK7J2x|WYi(`(2DUZ&rUD%Lsudj`G6?u`{HHoRk4ewjkjl^F zIa&c=moJs z=lZ%!vmZX@P;6>u^7_c|hpn9#UK^~g3F;Pm(Z)0Uu_(0DfkY5^3-mmbCZ0|uvs5|{fgB@*ptdfU3Y2c=j{M@4m=d7&IWsPv%dD4!xN&Oc37`w!(a zjrGvhkG!H`SzTUAY-d&yn=A8m@g{N5C&u((Bm(S|84a6eJzS%|vn4Ig%qKUOHF@Om zGgw<*C&wUCFC|`ituLXeyS+WVR|mQ3kj~ixcy_}ZfZ5K0QlN^KCC!dcB$sAZ29HFlYnlK}mA!S!tU)MnMkCZVniSrCwpTOsl+XT%Vj6ZEb44Fc@lx>9owlI@zd4OAKt+;M(-eU2RvIotaCnuk6UF zk4Is3WgR#_2kq@=5?$SDqNR1Sx3|B4&>slt&&}g_Aji`$wT`3BOo~)9OPA)yA19-+ z8o66;fV!*gVD4$KyQ9Q*4fFcq{CI0a`=vpFW4cBBIdZ8Olp&|z`Ip}{q=o7E+Qv1zw@J9>Ht`Kk!^Ri4_9d7BcI>dn(1K+b7i*QJHo`Q*mR zmYhmGh1JzntiKKCI?lwpdfKjUXE$2=uMG^^zNl{7!tpjd*&ke={Y0jKAADA!(D(kx z1Nq^@aoXUM6&VDBV&Y%^$}cC{&YtOQZ7mMQ>g#moaap>b1};L-`R?{vO`4f}kPOvI zvfP${Yp+<->By45( z&?%{fNF-d>f2H+$asNSUZ{IHs9srMhHApGSZZ*r9JbH#Be|8{^kEW81bs=m5na=wN zF!{vTv$@3KZm#!Cpl8tMuhE?VCXV=_3Vf9P#(513s58jVAp>4;pKAe75QhPTB9s*l zCK6*Mfkt9HXd0m0cycCrnql;oP2lyM7l<$n1~I&z99TEVN?9Tz9P?7>H~I)wB1knM z;=y7Ty)lBZQa`nk8XEA~Dp1?HZ*`^_vRuy9I~yplQO)ys&CwDqWR-#-yinpXD3#8e zjH7bMuj1)g`rG|(7&hszDA4azZ@Sj)-_#`3H+gCUn+91t@oX_K!-sC>j!!LFHr>k; z?m)TCr)L?4g+~F829_Co&IWw*zyIF%Z66#05Wh>ini?A(e)>zOv*!Td=Q6-y1Mdy; zk-PyIWf~On(#+_`$uQdd{wo)NqfIOKp$HJ$$ST(-#~!z~v|k+bSA})XNtv&>>jJcbQ z^H9j=rG>ePWKi_U*ZR6qXB$A*b*CRE*4Nh)YfJOJ=liY=7OQG?QIH(l;_~JV0!WW| z3TiPTuub&!9wnoaD0j9sLvw#;2|v-^Yld}wVS2Rn%*9s*@j4x)d#d9uiacdHsJrN! zO{9{E`bN2}sR2UKTBxoLKxRu#;0t0Bv+8DV*Tud;cF5^A84r;L8!ngLV|e;fbg!KmK>ueKTf9(?D(=OuEb}WzhG&Mfnnn1jlBK5k0Mn#YapI#UMwoCu0 zjkj|-X?bBf+1OAohopLvzayKit*ylJ@^WH6yWZQ?``RG*C7t9!{gRO#IV#h3Ga>+t z-5qHh`D|?n%XLk4P}kKC0nrCqAs3sTTe?0unriL2bZwCLaabPb1x&o`1FsKwB@;g( z2NMnozUBOG-+^e$yIyfdLpl=y@AdPgPgxwcQTZi8~8o)A1s?7lSUuaIm;eZc#wz$zS&yqTNbR9h21t>441!_}RaFuNFc_mT6?3kkO=2B<*PX08@3~aImyO4x&WfNaD(cuCEtd<50@YO% zfw0)nY>%lfAc|!fdO-CB&(}TvJ9GK8Q8z{VjjzA)hnG8hHoo|U-}qhTFG2vHRs028 z=<)N*`Ab!f(HgYzr|&15;{my+vxQREYJ)t413VqCUhRfxog~jMO(q$$%0r9gP2>TA zf=aTmu$=ta`w!$dzxM;!+)zQu7GS^NhlRN`{OHgB5{6S_^6KhFlHR+|2z)Be;2DMj zGjpTKNUdM)>u!S!ZB1aCyHG6bL09`(=F|?x9>D0MXY$nWSh6V=`Q)@x?(g5aVbi`C%L|Li z58i(y-~Zl^VKbeFovZ~cUkyvMS$KQsuV7?&OkP`APKrF`m=k}`J%Eh7J9}+tF#T*a zStnJ=ul4speJB7mJO?$^0yNge05b)kJ{FVHo100)H1T@lv>lbHd@(4(EVgIr(TM!R zKYIt3=M=E502B{Im>8LZxBvWIc<{kP9HfpU@$yqYhjz(1(=`P?e)vH$(G-%e^t3}` zOoSrJuPWe!ctaRE+FBr58<00v=93m)E6{zP@Br884+#P+Ow1)mA3u|S@c-Y1&2=4o zb{GnI4(29T;YUAw7vB5Hd-BsKkCMPFSN1eeq}sEx`b${eqSK!q4$D9M{t&FpZ9s9q z3VfE+H|F8pxBeQQeDp*fAD&2h;q%Jr8}51L5Vh?L1`eJ)8I#}n(R+|h8<5}efu(WS zA53`bPksy!K71@sJ)2BYCe;gP3mN@0OdURc{82Iyua|qf&qF*K0^gwpHG&_S>Z8zp zwgqZKVR>m~G0Di05l%OjGy^HZ^z01E|0&AUW;&rWZ^TR->-eEj5@JU2U@3`KaF zsWuG#)cGfo2Y5R2DB08ylP`3h11TsX2_V(*NF4l&U+#z6058u?jwUI^*42N%4d5#} z^{qHlK*#yH<(fbE{qO#(*FXRDFa7&FU;eLO|LTAFjgQ{{sKeop{T+8#9voGj=Rfa$ zeWg1g2}wvu9tng5P<*4~!C1R9tFFa3V{K}7Mz_ZCVgwWf6cA8xT*YF>Ydp$Z*HuSr z*By7qTTnKfNjMX7K|=2Pf~3>kdENbv{k>nmYC;!E)$Tv*bl0~Uy5ZIP{=UE8_xOB| z7XrFky8~M{KXLQ2TYtN8%{}+8eeszWu3_R}Of4buZI3+hv-N8?uiU?9zw+<{+kd{| zj{7$b4~9iH2Aju}>EDS@j=W)7(83!2@*f{Be)xe$?%uF=^ZI9h|Liq_#WK9fqy5Ag z@tLQdTe@!TmOFp*>)SUyxapzWo_qG~%g@RYkR=x+PJ%I&Kva%a9n0Uc@v({rH*Q|F zdilK@9^CTqFLr-bQy3iADey5lJ}KRI&-#^{);+weyJgV#_@mozUVhu^_0Md7X(?;4 zVk~Gvj{su>G3NcZ-@kJGng>>_xMTH}Rm<;P^X&GguhTUhS}2AuKmN4z;Rm;kn{VccJWqp*)C?5)79#67ee~~1;Dmfn|4tuYNPeTv()nHvxB)m7RT+Vd zNlnubi^sqB6F5@ALtTrY>trK2^M2(L5;Xh0GJHOne7eXwNtio_=ui)*40JYDq{+B| z{-jPfAss9q!>JZKaB?X>xM(qQ(lcRcQFu5D`7`|}otuXlB%tUbegt6KG^asw`eTq; zIMq)YwRb&TEfpk-s4OfiMoG~u=-MPC&cv*l>6kya5Lp4A(sr_`0uOL8TfH|{f;gSXAD9FiHI>@y(EkgMFHhq_v571Dz zry?)Qt&|n#!S7;`=J-!(E)f?kDuoTkpCZ7I)8c!cx<}rb5rO2>z9Nwz@spY>l-yip z0kOk58R=kRF}OJng#{71##ryzKZEmT!hfbuX*hnk z!qg&E$%x-{`)N*9%8&+tuMHM{DH(gkNyE7{}Lkq0wRC1 zmjXVC$REfg_iFo=={`|uZE2{W;05a>?rdUB=)I4J(Kt$Tdk^($+%kGEZgW%*IHW>oOgr)9I|0j;@A^Y+~;(UbK+N$%72H z2bmrh(!CO{zI-tP9+v2p+6tS0HpRb9DG*8|Wi6W+YOe!s9-{+iJa4`F*0r1Ne{}h> zTUKsyMEQLe|6`ES6+PS7nNV{FQm5Bv~7M^TD{`Fl@F|aa9MB1fba3G+i$*i#rpM+ zKKT2k!7*J7cmZ7l1j64de|+!Ct(*UO#rk_UY*};n#x+kq@zQm?lQj9{qg|!U!MVNIQ*{s{gTqR5U4zOy zk8e#~dfv$h_V;(HtQA!j5XJ0~0oKrvLH^(qMHt~IM7U5gdoBb)SBA#gRMU)5MS39x zohGvAYHm^oI{KAE`;Q|Wv;f8hixDsp3d5h41s-l3Ja8OCy~E1HcrUqEI*c$8?4%43 z>1u0Nhlhrh)`lkdTyF3#7IDtRl*T{{3BZ($LzPD`PWt1!Po7YL3xF`9OqKV*Xs=q| zT&L96wZP-bOehUjLM*}|9+n{Ud8ppgM3iepX{tY|vb4`OsS%PIUrz!YCWZ$4Rlk=b z4rwWvcm%v|z{LvS;(%nzNcUtQFE<|y%P6G3PffaHDUS2>@7=PD*5($qx2sz@SXGTk zPyM={na2c^U4PwT}2h|Ke$vn-@g;z2V4vira zpF$iu7#Nuf_X2hwA(9cVR1KKk?($$rae^nizyAYXT5z`G=w&Y#u zfG*)6*&Cw+W6I=YzsmCwz>zF`!|hHgj~B(?PzUNs`l4GkJA8@2HGaM-?$bBEFM*R z4-K4b)~#Sfr}R*@)CGKfFLpu1O_gdMS0mAcs#t)dZI~9IOm{i&RWxVYwGm8 z#J8`%`uYvWj~%}%Co5;@nxFjr7qfC^b&&mUK?f#IYtr*izp!kmZ$P>FiX{hq?zEBi zmd+)Adgni{V4dm%D{iKbkBw)4`N`+kx3_gH?)-B^X9iYKc&q3`2SznIo&Z& zo_&~PzqhMt9+B+#LI^Oxi4qvm1x6Ae2po7$$D%S4{J5ZWHXNe+{X4uMnnknE+L^I- z)nq0}Fftdc0r-S8$dDj&ER0ByCQcSDEQZKi%D_Ok8Z&jkskShu+fdr($rIhwPwjnq zX)y)d8C|yn8u(<%4s_^u>P6+?c|#$=wW^yM+-@GpY5O5|NO73i=y93I|;Gjx_-1C9YRDTfv$(8V*T)Y8Uu;8-&Cr*IG zbF@NmUilpO(j?_%OQY%l%xCSK=_Vv60Unl5WH9@OJ5&ZS5`gCt045V&-UY!-+@DT# zs$ce!jP_!1g#YfI7L^8$$y6$vRH7_zOHiYgrK7|Bs$IEJT$l@=WFitCg%&5jK?lQu z4k|Cqn*kRSQ%1W^spl;Fgen(UDOmbNF30QjwSM+k&wTYlt2BP8OTCOei3GP)0K(Sr`1H@%tPealmwX$ z(HgXQcZHK$nB`fS`pqlMr~zwxN_HmVrm&QC?C6ze`j)S{qe<+6)M%^28Y^9D{xC(tVEn zWfNK`A^*4|e@SFfQaBTWIi>WsHK?*PGXpTsPmcUY`rB3Bu=i>fyoCRx{EawZMZv^F z_yW{E6F-IUPr$^Jc zQT=z`*R+9@j78gnsm~G$0|Ml@;LquZ8E zj0FjByWpUgv_K!MKD^|;w?Di>2Zye{d`VSvLsR)jAO88LP8T8Eyu=W{ zHailU%6abD7jKz36ZDxnBMc1;Usn0e?)jl{AQsW_*dtFZJydh}y3-@08FPx}9?d5< zpS1QcL~Qu{v%RG|KG|^-Z}7s8m;7WmJ7vlry!F9NU2VMqs?L&Nm<~AA(k&<3(+=$3 zQ&6}6NI`v-O*NE`?K@mhx9>_>I*+!p8a2s+xmXbA^)oeIBdl|M3kOV zG!r}*1H+my;!(s2>G3$MXdH+eh($t}nH@kZ8luMO+m}aoN}z$$q-V0FtsSD^CYRt6 zWyF$*m}$VD9zZl^0hWkeUw?z>R78b--eIH8BzqIRou|~fN*=r(4x(sLls6uW!-&yd zS4aYnG`}0g$}F5AhTM!LkYyGZZqYeI0=>p#C!tMRaPxk!ItRuwXgM>vT}%d}5EwV= z>l)DB)}#UJ&x{!Hj`7V#+qO^x*! z?(b1Au>G7K${1PCA+^1|o$wi;ft_XOlxIV?5b$Rs9ucUsv}?z1Xxfy@gZ@8fkdWxy zr&F@ZvvewXPfv$hSX4m1i#ugwcIMhg+k_0A0lu;Bt9TRFIG0$dJnF+JyivntdAR=~3&Bo`4Y* zz%nu<(E~y9fMo^5;}*SNm*7Kl;|U`FM%6?Rj;}*eY|&AoJOvIy7#|r?>+9+e4NbvC z__s_BmSw@?NhAE*nH1X*&OzeUb0WuTGt~O9O@zKIg9S2;P?b&QG!cy z+s*?u*m^VuuZu?!S@R%qI7}@B$2m=zHkWMopgr!VhlkbUwT+mXGzkA5%DYL(4jRKr z`DdZ_SPMEk+bRD%ZxTYvi>H8zN#1>ZgK9&43nC%A-;{+*_Je^y&wrMG1`JIE0}uAw zt#GF&)KDl0S>`Wjng$1L{g+F41{l_&dXE@h#K~t|j}m#E1~7%9**OSKjH=Us7|Iu$ zGNs%yEnr$+HX7CfS~x-++&OKx-}(==>(;FP;%|QR!*(qKeDvr4`e9Uyc}j}rHmqEJ zTP4Zbd>WmK;z-Sri|Lb>09a8AGAF_7_D;R_>Z?z_{MsL03Zx^(yAxtHQvz9&f)gSv ziy>E-91dF=H|F1n=3cIKPvn~Qnand;2o^H2TZ<+bdsv;&Vc5I4DVGsl%CBy|zRZ<`XmdQmzTJ0hmU#%8|q?MN4m3Fm{xv#m?)6?B^ zx;y9lPFHL0c(qHF|FO($o$a~ZGiT0szVCeR^PR8#kG)^H=gWKVz2~02_k8ugbG!Gx zd-s0po8S7S{u5LB6_dgDU%ls^Up>2Yc6x4Z?y1{uf7{}#S%IhaqjN9JZ{5BL-KdQr+M*W681hM$ zcyL@FB1z$<3YYKLrj_`m`7j6&sRSz9;NB!7j~$b%x^~qrZM+U^e(vi&(94j;DQpeH zkUPW?a0@wh>5P-sD)G69WZTBmIg0Bb!JIsCOzRR`Nk1St%JNC%;FhNul5WJ;*{NyG zA5P9EDgca(8Z0A?Gny}M-#)|J4~58yZxk&>8t1en0C9T_b5j!(lqvNmD|_X7Gu2^V z^XB98J9kYpPwGbGpy)ve!OfN=_fzISS6{LVEj?FMLoJD-0%mGi|LJ4Q@0*&}ZJV1a z_561K|CkVMG&sf&uRJOx{?dmd!A>;YrDuf^*%w( zcd&EoCaf=MhgcRBvZ)Bb6m(zAcd4tqbo}W2&(;^9jJRz z%cq3(59yxogug`3)scD1-0MPYuTb;4OSju>&yh$d6f0TD$A1xGs4r0$LHs^PVs!UH2yu$;NP(& z(^8`Q8>wsSe|82<9Z*CP0NF+d*T$E@|C!@Q=6B4J47C~m(9PgKM@9N3!y!#|7REL- zn_4&Lf}=$d{Nh?>U0CL1kQM#89a`oNRVz%BsZ!|1G20h5jW^3_z3c3l8U5K8=PBbU zQAybcP-KP;6y}KIwfTvODttXw34tuii1+EM;zky8W*|`^TUD+PmL=`{Td;TYLA z5Mp0*`4xvg_u0>U>2+6M`*7CF@zhU#dI{0q$x|oCbe7d_s&RA29eeNn-QWGdUwr)I z`@Z|pkL-Jpe({lohkk{0gg5-!%@4lsJ+~dWet!4k$b@+0`;S~Rc+!%TV7x!@zysI* z&#!%L@7-Ve;@-Qz_;UNom%ps<-M#nQ4?OToLGX8woz^dgljHAysOInZ@`t>JutA<& zCT!Q$|7W~t&1V0!2kAKo#R_~UYYbGJ>6;=|?w@ldDf(IC)Tz@*)DTjYajlGAO5S;i zUXq)IBy1h|S=N6?jas$J#u2z^*TB(HbZSDyYSe2kl5Pif4%os+o=ON|vEq^2A>v+0 z87K6-;U>xyNz&g@7a-gu1HxY3ICCb1gJBJ~!>OQBCQwv#sy>E}kX&?Ud36P89yDN) zGG+16ZR_+KeZ|pSPc`(BS?KfxJhuuVVirtk8l#)1sMIRxge{z2IScqsuUBZ}gNl#<5?xEnH8^*pn%Gij}9!_fjH zL8_k%J$4T*!hv)kbR*}?P$gxBC25~)NKzuDTc&1}__54Yg2ovl>4lBvxi&nj4&+?0 z6c8CZtF~;J)<$}OEFIDUxraCn8e9$Ds_AAGhVn-IOU7}6PWwz_bZnCzPnQk(`p_`e z1KpQ!0ip+KLBP|rGK?^c8`Q-GD?b%E?U70wK`TQT2zb6jG_0E$NWC_~3R*65oIZC3 z`cn-c;%B2(7Xc9vD|$r@4Hcr-Yc-n9CLHM@%LVr*WTx*cj8AUS26%`l_H-n%jVNgs z@cX(+C^cAvga0dv$GJ3)#@Vx{^_YAhO*DS&0v1V1AFs9bwI#g{5_n$L$jYL#jHDvN zD$-qP7)8*i)NH6chF|qiA09%d6T%X9QAA6@cS3BgDX7-zMpb`LWs<18G$2YEDD{d6 zagsEeXDM4{1R`^wlp=a%1zHyx)Xut4_ftbl<3CY^|8>T{IqGd=Ey=ZY1y@$-kH*=h zCQ&eK;UN1c8&V1KY>~*LHgEegE4JL=mWXZ<`djFzCvf554{C%x0uHk}PiD@Q<&0 ziFowzFc3ySH-@#m+TKJCnuUiS-TfEed+0iaw4Q1B*OpettUjlwfjxutE!_5ww>(Pi zm9|hR8b8Gf&_3dw2bxN=4>LVu~KWdS4q< z80I&YHOA}F77|VhAhnP&Z;^nq*zjowOEfu+>>@|>M(YV5vnPdYjE;`Ok~v}(=xYUG zqL4`sNQ8cFGM`3l3$Dr=^xeXt+b^5Tg6C3YjWMqZ6{akcB^*GJC>2Hlr(yRp)ao`Y zC)WL`!oZP*qa-TUhF@m-7_Q1&U>YM;TjN~cNhz2?*VGsYu8nRxgkSODX;^YQYA~30~rkd;~^mlBc6**TQklC!*X(ov9Mh#cFFg|q8xuvMGKS=8_l8sjjBts$jD{IeH+L7sP7_)LWVudi)q!f%ubD7sxXK5dJfR|7w+FV1SX@ zFjOZ&u4SYpBctLzt(e8#`D*09zQGm4T-|*v)Uo4RRQ$EZ1lrL(Sly_3&I2 zsnT`@^$|h!mm03_pm3R;H}Wk>ULhgJWuszOA%)BI%=pjEIDD%Hm3NTz6g-!TUw0a& z@;k|OpKDR@cOdl@MHa*w5k_OU;vFMMT@*1sYb7Q4*6g%+}AHiqWA|QA;CE z*y-px4&CEt*Iaewp)l;+{NRJ%ed}ZUAKCq;Ti&?;rW^n1bJB%&@SWaF^P^8D+wzBh z@W;2>o)2O@%gvQBS%|N0tPpo|yzOmo*{?IAdMIjhVX#tP)}K+$sx~G!k00N*eJUW? zd)4JvA3O5nBd=d-F72do`7ZPprJrqDc(|yytF)-shlR?Aw9yO>`lV0=l1sQ{mlc^$EGb4?IexS z3D+gf(F-SzZ%%p)^_P-G_d(cwM&})!BJ` z?(A40XG+>5dXbjIzB~6ls_*JHcsgKT5p^Gi)cQUXB?-u3xE6%Gj)`n+N${GjmQ>u> zt-6Jw_z&rr_+LN=2N6sdk#aW#k>$uaRm~8#zF{I7%Hn&q`Utx5(Si6-zwKOFyX<96 zdI@`3Q&mR%IrT}1(!0!`&+`;XH)J6oT~43hP=u>m9G>28wIHR9Or$0y%p5UPjy2OQ z7b$ytTdjaA9Fx#bF6O3_5}hbw=8$GtsfZ!Vd0};fE;FyVw~joZlwKl!lad{&!3h95 zK^sY$!12a)7o1~`0%RU%ij*TXooE?B*uHp<5DQkz%x9iMr3yk{VJYL)w{0+I7DcoK zJ;ZSU#o&>_IH>Ha@`M$~F%Dmxa=z859ep zRNuBO7W6cBzSjvOIIfFc92sNUP79->Z!)v~h)$_Y^LY6;Y>70e_DYh%P(!9dQY4sH2+J+t(eD{zqoC$y zRK#gpGQ=s^N+eMC%xzXoMudb79F& z2SQemli)pe?D!BFNNw#UhyqjW>R;db*2hPOhnF9H^szT+2hG-Re*2qmKYQ-%Uw-IA zw;k-MuC?A?!?wA(giax#bvQo0X}^>fEo))<$P2!~@D`C-Zpu<9g@50>^?;+$?2u)h z)i(xy#rIQ=s#mI#di&o0TikiyefPY>ab&n-*RE$qM~BrjPd_tWuh+|hVk%1sm)sY< zKL5op-SXt&Lwhzgww#*VI(sZmqmdIYobbJ>&(5o`7oKM?dGSsdtm&g9$$Ejb4FJ_D zkB@chb~j@jSd@)7IuUrD?Ak)C=xmA;qZ1=dSC;*j#7C+3hYuZ|dhYq7Gb&Cv%A0M# zZ-Uuv+ncxC{LfBoD0RbEt2_qqt6%wF*FS#Xuim_C`>rQ`=i?v0zt>f{a@<$7b0h0N z0=STsoj5{eqy{qC?KCHjVQ42W<~9WzQq|!R1aX3kW$yZ}%ZB4>s|(Bak&1*TS5UXC z2MZ&sbMBpGVH9>Kid@Li!noNWl6^!$L~{P(b@m+_t#!@kxEO8~Nh$EnIw=)igJzZq zJPwg_0b|?td2R&%44*KN3;6?ZR@W8ec726!3v%Wk$|@#pZ55^!k~v;Sx+waoRQGMIrN2>aPRX z)St^Zv>j>mEe)u}3dDt1a5oM?JUPvj?k{28qo2NWWpqj^l-o(dfi0u_DV}GRDb7ax zw>178%dGdpU4)1{)djzInXePgU!nImynfGq zm~jZYFq~pz9hINg(w>}{RXznn}VK{jaba^7C!mwl;tL&06LU7=XjW)goX+_JLu?sZwM=GF?_G zMFH7j`=v@=z4HGTev1mdhNRa_I$ciJatlSrhJw(I85J3m`bj%T;JLMu;0BL796VK{ z;#Zq9Gc$en9S9*Yc*gVG%rqHf+^;O}_eI!T?vo6<=GuBhER75$-C&9n2@XK9a8|;@ zS`hPRGcG*jz9JH>K8{@(9cpfw9fcCB$n1cXT9s4uy~>43dFzhoV)OJQTshXXtWh@J zl75@4Fftu)sJU(Hb~eTwGKO=>tyF64p8ia#BiUo9R-NXB8J7_T$Y|mD&8fKwWEMF^ zLK48me4-El5#OKPI*DrCYa*lXy5~E_vq)o?@T6?gRu7~xBvMxB>|9YR@DKE0W2qgY zHagx^=-WckXW`O6z7}rN;rdu}dU^|G29(APM@oo6^2Qq#EJ5QF!Xfs3q2`}eqg@f1A^tWktSigyx zo-)|wAmTKJuu^?LH28PNn<(*Lrb3rjg1MKmr- zB4bn#{vEg3*2;lMyPT~7)rAy<|Ad?1aSJqC8vkPxjQ_#3@62e9eL6oCEhPB2=n+-dV??A3w2&o;5a4 zo~zcYXoZ3N*uVY2!oH90UHCV@^WKFIefW-rZj3x)XB|0M6f$-Msy^jang*+QZ}rvS zu$cDNv^Eh$<_m{^dU%!$i-}DWE5sHb{N8tVXCk$3`Smw_=aYBsd!Vtoaa3uTyGf^{ zYv~bJAfrUk`n2~S+<(1SapO<@r%&DY;g9THa4X(gwLXNRz#m-OEonl3pIc62Hx4ZR z`^qaXTk2&oI&nDmKz6=+mIdk6nyrBNuaA^czbQM(j*6x@ z(=4?z5S==-HZSr6Y*-ZXd6jDT2$y9s^HGrkg4TLMed-1*x3rN^uQn~$V(u%mjWt8E z%s4oPG!I#B1;_=_QgXh=&(_-{??;+621{x=VZlFyzB2zP_@_c{yR1L8ItiRgo%NgxZS%FH zMbsZ}L2!hE6eNw4vWYxnCq<1ZVEK zn*LysA)2v~Klq9g6BrPV5T5JkIar3R3{J9MSk8eZ5XTY{(O%z|4)?32HZHo{eHthpMjArmG1B=eXL zrxcK4{l$NBhNE_FHP)NyHq{pyM^ySu@`a!?ro3||~D3;5P zQ{907p2mM>%Q85Wb0C876riT(s7$GnS=k2hpTS2}>pN@hHKZE;ybu4hK8gB-qo9aZ zgAle;*Zo%6S(rpD$4XwDSud}Dzoz?K3E3Wzxhk98*MxqiZ315ZfGnMt#7m0P>~!0B z{)VIHza7xrdCdQmt#o7lNAt-r(vPl(Z8&=FGo@Ijj!sN;$419u*LTFBA0OU?!gzn; z&=a$gin32{ZWW*~4gcCL|K#~U{laHIf8(#*__rT1ynWJ=~iX|A&9O&U51#vQ=udttg{>b%ywGw~& zGoQZigLi&#VRF;tTC8IDLq%pB{S%C99+eq?YVO$?^W>?y>7`n|ie9e9o;!MEG7OC_ z5UeY7yU42b%1V?5dYmIGAH4Hj3m^N$dl%k+=Q|hPc+1U)2bE#pci9nha+_2P2&RqiEt z6%YOA18;0>^P(nLKVv+vUM|J}*!&vA@v&Ac} zxPlj|B~#O1hO%#12|v5y%FD2Mva!hCw1IG|Ieyc$sp%byr_Zb+=ajQTC>PF+!oX!k z;-%9o+Hl^nsEYDf7kx>IsjV}MJFl2S&kB&ruwZtkU%^r9E^IHyHS<@)a)uZAjBt>G zkf5-gOOO7fhUK-dy^d1r%8UbULNUy?G}~3Ky7~%i)^qf8tROZ<8#JF+USgaZGUA9u zn#IWSl;;sv#O<=Hc42bU_@bofwX*uDcwo^=ICgb$X=#bP`5Za&`;J_)a)W<3LpXW1 zh4C$O8g6zboOgj2flwBt(=*!_FVV%}vfK!};wd%GSm>!Xq!;6L^RI#LdwQ(?D=xJx z<0v3261E)DG|)mf&f$0!O_oDQAxq_quC}b`Iw(sR-#oLJu&ee0HVPL9_2Jb<7B744 zE+_<)k_?F0j9Fx)2Ovoe{;$^f7qX^ls|satUHY;LIJJz!j~f2j9gDkOb178Lu(RM~ zg+Tm&?!Gj-jq^J6VlWsi9D*cBa9;o}A|;ZN3CXhK?b+`+uX;(8h0fBZ^?QBiy`)J_ z)Asa7&uLH3N!!!JvC}3_;zUgyJFyehc4RZQV<&dwSaMujab1mMSqmkR9PR`OE+9Ar z27|$%_ud&zVOWv-vkt)TU;qq1eBXEPcklh~dU^ia;0;`!e^8+{69tFSUzHRg9yBy6 zyZ4OPZp=RCZd5dI)u5&ql+aQyo|#V;_%p`hd=u8LywO9=*Sb-9DDKTtrUO1dt~?d z%jMj@bk`RTe&_!0?mhbQi6+tSg_?*ARpEd}Q~tmmA9x+DZu(McvF)$E^!Il>bolXI z4?i+C^2NKqc2KuWZ$JhpItNb9O3LtaVCOW!WaWlyvBTjx9%p%2UQh0N>e**U9{Q)T zJ*Uo{x=!$W;F^8APmr)v*Ibv8H2yzbG9`L~tfw)kL6LSzxB z&mFsalBg)0s;;Yo`yc%7?|lE^ClZf5{*!_4Km4O>Nf~qPb^BjND;FGn>7|?QJM_Tq z$B&=vyZ;}*cf$kU{lN{qohv{}hoMjW_HQfS`p%(4_Z>QP=$@~C_0ZS8YPY|?_p68Q z{>oj4{^BqH>=Gl?(;Z>sJ75T4K8HfTla% zy1II#ACCOw3%K%)<>B$M{8U03N^4$I-@@Z8FWX(gpxjC-Z7to(^3o<)Y*D4=fr#Ym8Io%VPYWdO*FC&d&Z|@`k>c7X5r0}H zSTIb2!C>X@Gk=<2LHVQ+`91Jlt~y@bwD?|i|A4?IBlow0Qm@@RiM<KfXyZ=Pw{_)JGWCisVx1sub+VZ+}as$v}CM)M>1BMvX6)=}PURXBX) z9pG=`{3AI3)EdFoOZ48^_Z%vPzkz)QM939PSV1@m-hcv*3~$(Yip`}}F0Qt;^(ynp z^{e3@kD1N{y#EEMEM2L)|H~8Za#wXo|5RKnkg9R*9Qx-exb%r^}`p0WeFt?oO zot?u2CyQ1QzWcy~AAR!2PmSFFz~O6-AAjXmAI`5m-gaJ)_^1T;-1~P2|KWRw_rCtd z$tKH7VR}W#S~-ox+}jWQ&)35dS>MWM+WzK?cil1e%!|8z@J~;TeCaE9A6!}2y{1JZ zq~LfCV!OO1S5aMCWnL8O`R-OTxa_{a~2ANs+A2bNPyT_i{RN_i!= zl{Y;_(X{yow=$;Vv0R=rlDH;`hMXy{SAhGzedu={JMyChj&I=6$B$e~`0`r^-}^GH z{n1xny6Nxk{rc@s{`7^uhYmk-!;z;RyP3R-w*p9yV%U0#&$<{*A^x$n| zxcQCO6ue7^{hxafMz$a$O=pVg+3{HrC7H~2U;@V`^7UFa5C3}h5@GVjnD#>zIR}p=;Jo*t>U+8f|J+E;D+og5MjC)vg{1 zuHdUy7wCXn@PO%|BfbR&c}gI{=L|qC=`7GaBy52oP`p(+aj49q?+|{rI4j*dy4C$R z?q%ghu9$(mwN2rOP$Z><--2szNI+*_w;JysRt!sGOAGfWlnW*z?8NV5v2OLY+inB$ zQ|FjW(Zq4-V3jnSPX_j2t^9$3U1~>1%n^9RD>irFyq-;{IN77_y><{hUdnT@38K$} zUR5DvRb$WIVwzjhzn^|J3iv@YA z%2D#cn-epTF$J}uC63JV?E(ZJ@UihL5d27^A64SCo;U5qvF33tx1ea{K=K2<@@M<6 z+YPZ;yBh1neys|3g>t!11ok4*vKEeaM9Jg|>csQ{tfn`?B)3Qa#0QH7h(Zxyd~zD{ zMNnHix)ebS*-8huy=8qF_EIPUvA*5Pj^P1y=jHkHdkN>?pu`8d)$4HnB{7fv(fqf;7a+n<;Y%i5f5SD<+lT$d zdlkV6w~}alJk;`LSL(TZ&yF3t6!Z{c`~u))p$vPEHwOhP0|Kt?_3zmSy9S5USa-it z>9HV)0s1Az)xO?cO1=OH|0HZ~{FI+)sB)lbKy@blRK4oLmQqNwPVMRvC z<0t$Aa9Cr`s^g=MX%b_hBze!SlapQAARoU`)}O;YQAW~bI(2h!Jqv2nGg8` zp~7vq-}=+vdf$Nw5bfW}7xcz|J9*;3x4!+Y&m4Q@=uP#l_2ZxT{ZBkaf>3+Bar@JM z_^F56yE_)oUOY4O_)nhr*o*)2i}$B<>5f21^sJ_{By_QWNOj%>X3n-yXc-n&7Ge*C zfZg2M^4Ve*#3~Vb27Asu`_Io@|H3a{_^@8o1HHStU%BIxAAFMzF8}?#x4tg;OUvr~ zYq#f(e86_?7Ral{b*uII0dhE=0_4GP=+Ni?^z&m)&CzpOZoBrU z&p&(c@h6Ua{KCZe4iYLp`MV!G{l5+zc*Zo%(z$czZv4mlzw=3SN4*(c_QRqCS5&SU z6nl>iL}!nS-1u5I*`nrn7m4n^D#tGzyCnG}3ejs%t*i`Rx->C7Ii(IOCzT#}mp&?3 zle1R^Xh!9;X8P3E&Rl>jl{O3p$-<7!$BC8GS`OYga}jc;SMBQTXM=`tl^>u3V@M_i zWQVe;5p7OF-V~5-3Sg9gl3}vTxuzFjd}ygDnT{{%+6Uum~jSDWlC;3GT$PhsVd{WD+^uK}+Vdin+kF>T5viTw^q?V9& zTWW7N@;#cZSZ)9^!7bfxNzm4{3vr-;mEq@c?p_|BAhME=*I3i@K(stxlvIKNc`rzz zFa%`TW%R<^8$+@M5AXTBPgPEhQ`!TN{8bcULVK3?u4a_rHLR?+UGS-0@qU)k$~SC? zeo*VT|i1Ur9e2H_S~TiOR0_IlQEbFPTo9NcxQH32lW#+0pss2+dg zJmdi3gX1hvxEjkwe$b00A?@be;zjks(4&t(^0DWRKKK5O%vwhg@@xt!lnQKNG_8UgmMYh}o{{B^=cZ>( zx?p8iXLtPEi^q;$|M-uOe0W>m4(#2Zc;$cp{s-QqbJR!f_{i&MU|GH}HNNMi<1gL3 z|2_MU1*-yCtoj&x?q|;rg=Jvgozry=PpzsJOZ#rvcMOdYS(G6TPRvd=?A$%@k~ipq zS6_ei_QkbDD(d9q39{IL0RcN#iiHhjAM%!9zWljA{Onj?|BiDQl3RQ9=nDrQKK#(f zr__lZkp=+{pr^)vyX}@|ER4NZ&YrsQher;7^5_5Ziz>_i#vxQ}*EMkVFie6HboLBQdl@ zHQqHi77o{Gre(OUX%@JNvE16`ocN8dN$4!-GM0=S9UoV*2KW@LET?&V^$pc9G!%yc zJOuXb*f|yo2C!e7X&EB-@>Y)n(d3%kdVWJ5fAil)Yh-`Cx2qGP^${);nM$p}VseGt z)zto7BV)l(R5OXG8;6%`&n9s@=&Yc~dzBq{`dr$Mcyg2k!gpfP`?$Ez7f0=SEAG9*=j$aPCcXsv@^awmdAZtf>RT zdvLs74Z{e)s8pU<6&5`cK;p8QtJv>_(Ti`6$1j|ogq8UWNIpNvkq`{;?T6OxMs?@# z?lGUQS^E#dX}W}$g=rF8oVfm+wu1O{X;ht1{Cm|BHgsibzq`o|<+ttN?K zz_Gf0ncSb7ztoxkW%#eia|r(_g#Y<7=V5Iv4O?4V(9zb+@NesER0k6yyax5+m`L>DbX6ZHS2RZ-LsfXR!18eG|4Ynb}~%15V&raXhHFOPzA_n8}j7jo1@h}BR&{wfSM{l^Ii&FnORr?qbR5y-F;(KHBn7BobbOZ zb0?0K4~Jz=uAI%R$#c`^M}vM(yrZQBYN`XAw{l~B9g-{Su%6AUJp)5y{_1+%p8>qz zfRGSk7+E4G2;~z(NU|*(>D08mynJrdFF~9_{=(sE4*NuboV_d3o4PtMbiPvP8Ye>K zjT>+ii<*K9CL8xDe-O^UfHKMSoH7~+l;SPT&75Ze_Z=)PF2VH7G~@~b^155b1fjEQ^Fyc1;;K9~H9ktE$}z4Us;XohFNLL~k>96a zVNFx<;64VPDy=r$$jVH?t(0rJ`QG^Ta!vqU0}sOgjgzmAHe%V-)+oWhhC?3K5my(J z{{er0Bu=<`1-0R2MKf@SQ!cwCPpPLyqmf{|z9tMc;W|3NQ%PEwUtUFAz&+KuV=P?T ziv5XBI4|&PC4DOAPXSYdZEY3T_RMHN^2FoaZBQlq*)uY;okvAX2J&W5jl~AW!qxQ^ z_$9o}oL9)L%kwki2>y2rx@w|I{>k$P z-LmJeEy?P%J^x5;7;5EON>sAe$G}p1$ERuS|PiVn)PDIEIah@2S~}M2SYL zXF<;_%99f(M(gXV;+TiYt)i1cxg?1&N~d*o*RJcw{D@NqDfmpzQR41@8Xx_Z#Y>%a zO2d^PnlJd)*4Cf1nRu9^bk$wwV@&h3tKx#ovEMw`&d@ddJknkT0ro!#rN+VkD^{mL7SCmY~ z1h$y`It2$d0StQ2n)%tenZzcRShS!REflzPXsQ`Q2q>I`Hi5q8RHvGoyOg%J9c;T)~dqTAhpjoD46|a1l@Y;N;M(u`_Q{Uw*<)2_^@4>kO+jD z@CTp%+!wz0;J5!;5-1@ql_Fh*>4~$6)bet|EO?{jVku+J4RWh&LeC9NH(U#WX~9($ z9GYo=B#ShD9a723#PZB^qNrO@{vXMginKK;@$N2#m_3MLS17d~2CoHM3!HEPhM9o# z*E1+Mq!aV=RHwZV706O*dJtFJmG15x3K4LVO_olycxB4gvfah@IKEZqEaTx&1Xh-k zi8(A$moIEbNtpB@e#PQ(rKzP2@hb!2+K4NZGrTOz3HuVr{4253ox9Vwz@JGthlRO|iOuzugqhDpJr4dy8ULe-5U`bQ zrsxRKPP2ZU5!xgrfWZmsmKLTG8>>r+Ts9pg|FBT73ip1C5^cx*N*eu8Er@{--cM^r zLKuS%*Tzkd$1o(C6rfX@b8WD25@H6f8>X8Bh0EAF6+TRZg%FMnH5q?cAwbNQ|CjAs zPRZZL9(m+CRGhUJ3KsYs;oI_>>>hsGdvE>KzU%fcNC8grN-!@|l1Q9c-p#P@Sht84 z$+FCeA6cjZa6Qya=YErgH%AyT47%p=NtTV5;3OuMurZ`0e9up}04ViOaHQnGd@YF* z_5-fc)V(%cB?qsy{gIn6)m3nq!WCkXtx7s4R=jsvf?HP9Rlw*b!^E=eafD=m?7KS2 zm{_KR&pPWsi315AEm&Q;nAl#KOyo10QL?;;LiMTo#&)H#HI6jYWN$AJ9VL0CK*`tK z7>*K{ydi332`*hco!Hn&Cf1Y7Q9A4if|RNy+DsNv?9*TY)3!W@#SlZtkPJ7}l&!BO z^__u8Ex^RYIqYveky=@eVmvq{s7>L4U+L)VLmCodS;UkaGUp^!lpF$Wirl9=0h5|V z_-BG77_halkXXestLgM+l&c{iy>Du1Mp>dwkt7-6FR~%0^5N#7Fh!ewNaQX*o!Ce% zB(f+!fv14@6G~OrM3oi{Au$ZcV$F)CD=RqMlm|p>bc@&16xLyG@ls+P`KZ??Mhk`s zL4Sb97>#x)fqza)ih585jRBQw2c(Ja8UO6SCZvr}ghYe+*gTkBB}ix8-iQsGF0($+qt z2x0_SVdi>1QmQOZbULxEtt7TG>rq(_K+e*U-*qa{=3Yg@`5P7=?j8Bb?Xyx$b;C(Tt{kDUVrF@n z)?hxNZR6Ss29**`)im}fjm>>1pWBLLL3BE@LgjL*%ReJw0krfAs8c5rnGG!0oM9e{ z>sg2E*{*cNx)seZ82$p$co46m;3921dk?ZFsm$|#Baz)&LwO%7;8X{}$QM)XDC>vCKm=gD6IF)JyU>I`wSxF=sl!3XqiNqYrP@U>a%8F*`EqAx zuL7pbVL}Etma5C^X8t>SSF>tI5roT5QMAo4j5q#d;YN`_vUCwm0=|MPSGp82_yn#* z$;uZH6vY=Xi@41LxN{#|1W}NfTn;B=(>9&fTVEA(hI4=X*$9%exZLwIHC?D={ECQEGe;Flj>ee}~&{`6?$@$Z>mpF8UA(%a)Q7ThCbuT`(rFm;-Q zHghErfo<+T*Z{jrDZtWQ0hO0Rtr7to3^#{yfGlFhG2-Nf_;Vl}qjjt}->q+My>{>3 zy%(R_!@H*?(e-QBzPoz$+RyA=oSVZ!!x+h%CxDqEz%q;{C6F|TzX#Fuo10;MY61F? z=7pZqbdUQv&t{<*HE+OY3$cOUHXSoCv^77rTTudOt`ixKBgm0TsU-M4$ee|Uuwzaq zIF@fbr`^v3&bTWbc1RL|_u>V#wki;bc-RQg=?TH{FJJ#D!LckU{6FkX4P({iso_3XGP_(kmEdrS!r96ISuyFv-D2{WT&XGGb6hcQY!bpr1c$z{edq> zeU8Z;(No!wwp|?3(&C#-gi{DIb#v|-n%zG`s(Y?K4wp;qX}oG^fDUbv7Ny~C&u zGRNmb57yQ;XKS_`6H&_>5I%y1-b=YRo!0AS*LRyksD^HdvTK{iWL;DQa=+ZO$`^NWSx(02v8 z+T3mqSc3PpmBoj8XZUU8bSA;U@B!DK8`WHhA3r{K2jReS`AMYJ8Fu(%Z1JS@qJCr+r&mTZ-p?Yu$!N)Gh7 zRGoP^_wC!?Ui|&Ha-RA*JcXR_Xuv=4aIe?jxPJHIrB@!RrR(B*;!lLPBsfOFI9U+2 z{CC0qiSV2I_aD$SjaETo%q1m4Fh+ez3^X4qF(g(+sun|15X9m*+U*O?5}ZYL-a>!X z7o9G7*5d@%zgFu8!1~G)A`!D4azQ~%^6m}t`14N*j{R-pGR9X*hQ1Kdb{!n^{C^=h zivGm{Qx{$hc%Lb@Oc5l2+9ZHQvP$A)G1c(*M1ms(wX0vR)*QjBVl~L!X&gubqpPAQ zmXJWccYy&jrIGUlPH>lz<;Wc(-kGb3E@Wg2P`i z5p0@9Ca~u@n{Rf4Ody;%$%QI#Qbmu&q|W{)xa)cyQv z>4ros@-kv5R&#-RQ#5mXjL6gCpaM2T*R>{Q^5Sxyr)nQg1p)id}`Mb(3gC5pWwLp$)|6=^zsWo zzWvTy->dGhPav~->yDYUkT32nZV$&I9~5HqzWsBxErNSR%#lDl`-fG>S;G;&h3N_S z)Y-m+Ne!C<^qy@VScfZozV}3}dH%?}vwvIJKk%w^1Mg3>zw56UXPw5a&P(A3^VMz#_U+|u zo_4mpIf6h!2baSrZZ*LX;}EI#4f6g5qCcuH06Ut`|3MCDI~U|4X#jb#^8aAxTM@jq zt>a&zkT(?B&kKwhtz&})JJzwp<9f51aI09B^xE0nTNdsyVjS+<3(liJ;ADqH@tiAA zvY3R=8NLCM!12;>`p%s@7mtdN=Xbtwj>w_^%9Sg3FJHd&&l3NO#?#6Vp*gEsewY zgy8s-y{lP`A_&5rk7isVghg@|@qxU0&{K}yyr?%3y!Zkh{JHu%K7{uW{9_r)T4AQB zEx+yVnapAWAqAVw^lblBRo8F#^js%!f+K^s@RS`p1(iX0JKOF*z$|*0VrE#ZRtWTz z6gGAiFs?}Rv!{ryXD{bNy`bDysAnI)CLsI?H1t7tkaq3rh$R3EpI51Ms(mrR7e)us=VDZ*>bv{oUGEt z_kIX~2S<7c7FR={rDhCIPuJ<<{AWtt7<5XnLm;?buM;5t>bnto;#aoScMQ*Dcj%ng zG#5sr>nl7~Ml%rf78gZ!Sr3UGt8e%x=l@Xh>-K9U1?(881k8DV#h=n381s;UaH|p)Zw=2g4fMNRo z0Gho|yC%G4UK<7=toPSV4Zqt%v}QsMdV(qJ??o~pHW|0?d2=^M`yX|lwQGI);>Avi z;eoe=g@{34c{$8}R&A4Jw;yp;F)RBOndHMH2O&-m(Hiiqa;O1QTlEJNOmRIL{CAw%`|$^qn8Nw9;q94aJ+l;@WK6WPo6&h zI_yTR@}K=F=5YkRrxDwR_5eG}q}U7iBfgK?@%OVv%&8-9y3_?1YMf(s#keck#7ptt zj-fy`pBY)Op@nx4n(N3v*a(1))9vqpyoZ^U7pwf&TOQ1XuFNqS9!~b0g1d z3tS?c0CykGsj~oA_O+qAF`|m6Eb@9;vvb9q{tPGGdL40kb_sM&g>OSC9xSUBt_zi9y4E5cs=)0aS_@6* z7m|Q3t&a29d%sD)?G(iB_;}bBEMkucB=~uo_ttA$VM-~RL+dMn5p3ttuuW2tG}l8t zgn*+;C9N|M;AEz{L5YsnpY5Ha?e^|=jCWQpD<;a93QYxJUZGwOo}J+yn6Db^)W`e%x?plt9n!^U~_0XPPZ_EFr~tE zm&7mmd!Y?w`-#@?rEp*N5)(~8v=z}YpK^3DD~JPUDxu^r2;<)#=U(6>6@P4|98nSx z6Zk77>8C-P_Y^|EB>SliRo0p&+aoJoIW49^rtdB0e^Ig5@yD`^EAwvtc)5eTjQ=>C z|I_V)=Bb1kAw-9H@~@LLMEc9#x%@N{MPdA#lS`?H2?>c|W1@mP7wnM#fQ2hpK2V6p zC@v}*)C3lY8juzc*pTQ_B%;yi&X}-}kf=L0kSL9;zzArNM@!r59mAxl?X(?fXQs@Q z`)j^5nM|j1U+3I8_c8g{KN9u^H_Y4iv;hXg_OCxCNN;zLxQCxnndYLu-#)%*hxQIe< zXs0T~*wVuH{YR<~t*L;@Ikedwbu60yZ3qI!l|N7zr`$UEvEJ2y?gFq-G1hep*+AqnO8$|}eECRyvs|&LBJ_Xrh zPsldAM7DWWGCHUz3hcvt`4i$e^)-#oFaPxWB#`NRBu76#tLz zZ8v)hnU505E+d2rS3@al2DNpD!MR{Xpf_-?z!v>HVj19%9CZU}f85}SQ}p88ZfGd)um z-HeqmV(?)59IkzPl2_}Bef4oYudlO`9r}em(D5mHxF&1- zhjaas^>CMsF6ZYVi1Z>&081Q9d?Mi)*sj zk6M^suE{>T#|>pS4SZQS>5<{TJKib}Q z`)yxO@8dS#ttY;g<|#D-<_dNKB@9voQzwZ6~)VEEM4i@vt@w$4_6 z@8HQuh?g)zK~NMZDxe~cprR~Vi9{lim_`LiPU4VAB$8~%0Edm(ADQNwbP>y3vHAD* zkK78K@`(#jlK!%Hudz{7Q5?Yk_s;BlyFif&@d27vKmr;Gfz%g)4-y+AC2FE3DjKW> z0!@$*R6vBHeGm~E3rLK?Xn7gI2lz;&1dAdh25aR}h|rc65NW%mkKLI$SD`IwNeh&v zWv6?7$w~IZ%+B32lbxA+&)n(m?UU>%>@z|ed3()vL6_}>unF|LCB9Ayt=b`VxGtgz*+s}8zOpR9Ln_@*x2zf)Jv2^k22lhy9QD=+b%KNSZM>0T_!Nu`wQgjaS){6ktJ0w4wLX zN)E;@(+exZNJjUgDzSQf5wqu_a z{kY@%$#dttp0R9cPU^AJ(|t4xYSoJDT(|D9Tv9{k+wbIO%y^;j*8aZGj91e(WlW#7 zZbk0W{M08WZ_}m3uSI)C85Y!#23M4o-xlAePwl$3 zEAz6JW#t9@eZ!~9Du*3CQqd1Rz=R1Up~#Ls8jLZLz`ICSW*Vx|3^B-vjt~i2EEx)HJ45X!}?|yOW zOB)mKy8A$!*Lx<;=aW?x6{EI(@#RBacguK{5Rj_*bHjPS>jWMgJN$%0m-u8|L2~Kg z!-E}~4kK*z5A+2ZngGKvFO^G39Vk0dK0sLnvPk7*t$HFiXL*V)gym2I#||AC09?HS zfvz)JzgsC1{{tjof}gz)!5Cv*67k$^LMc*hmyg9(c2}cecZrj`%GL=6EqPvfxP_H59hDWf7IcD zkUF5G66YHl5Hdp2QczL{Tpp(q8lbs!INiWcg*!(ync+av(8QAWKX~)Q)TdInyF4yv z4h?WNSBAKKZdF@*4kicGXpcDSCJU;N#P2Z0EX2-U1%Au&fG3eW{W$VZ=0sery+&~x~um31zcTr*D=;Q~E z`s01Ue}iZH&7HsSB0c{(_985{cG^fXS=XN_UePe=wQ$dq6dOnZ4 zxZEGycNdS#fp;#f2=3gQnCj|2F~9I>v9GjL%8!j-FXr;O*{^o}*vnTh3IiAV-<`kI z|HkvT%;NHgE(ed>cMDUe&YqqxzMt-!o}0-d@ZTRiy#M@YKD)fUvUqZKZe~a_LKlZG zzul8$}uDWw4Lt|CH6B!EZ|=y6FY)$CgN9DC?Ltiv(?XQ9obyA+TPCM9N^(!duA90#%_(421f=bO)i80fD?>d8Cu#bPgmF1I?8M1 zAm4So5=IfMvyI==?Ifc>l0Ye?l-g4o42L9|OiU@&yhs3Q@d!r?FI_3sEQq!WfsH}f z83F`AJTiuTPjAn9Rgka&1VC&ZtaIRyK@3>$5LYa$_i1~S?byh)u{bXPW2c|Z%;?(M0Boe=~AVn*Zr3~&GkAqR(2N~s14puupZl-ipHIFwTV z6a8@y5kc5#Kun0D5WF3rsMr{62ppQUP7FBlaN+<6$RHhKy#+`B28hyI>18c4$p2{*~y$^A3Ab3Vm^ zbdzd2fpm3#&{b}*SS*-EQ|o|jjL{&5I!+Vqz|Y;EslbH`Hgj)-^^m17F@ zL*r>gMC5)p;t4t5IXLcCc-ZNiQM8p9pa74uI$Xhv?T-SM1I=R*D zoZ2*}GB+J)NN5v~0Js{j&{~9M+zJf5s$2t zo;f%oA|fK<>{;i(XvdkKendR1wv!EGZcW~s4YA2CZRM_5+{kP)Grdq$3bV$Va&?V} zct16Ev!PBeyYI~kDiLwV-tVOkatj`DviuykSZEF)X1n{2lLTl_J>=ByP+RA8Q-6y$ z)ac#)X$%Pw5pkbNr#QnzM4W+hy;MDse^e1?%0L$z+RDT8!5m|ZfF*Eg@C4&Hp$3|u ztza;;sWFZt6;V}rwOX+lDxOTGuJ>WH6f7$Y0vi1F^3RWc{rQ(qU;gppV=*85atW=$ z)EXFUs1l2Xz+#Z72u}?fto~b30oLc!7=WRI8#|0OXD^x3OF93cAR;18)8<_B92sax zaB*?b$E%5mh}a_qj)-_{R>K&8S}Ov+{QSEgzxeFi=l}lw&+>9u&|bmszrFb6o3Flp z{=@e_y=L!zUZRSk0FHm(@p^sE47w{?*vi_s5~4q#XxXM+VTwZ9prRmD76@eoLTxIE zpjGZ%w9#^5yQqkMT8lzlCKQcgkLR5;!MtH`5kiJgc|P#qaN(S{I}gsgmwPhy9_Kx2 zs0~Eo0wDn>LYkzcNq|6gO%u=*L}B^!Qro-NZ#$MgE$`O=aqLOgsnu{e2UKfjxhr2* znkKK`I68IbZb$4rf)M){3E;Av`g_D}uPs*4h^SnF8qxn?_HB$YW@kk9WiZB=9pu<0 zL>-%{*m*}|exGhRA5GJg93Ft?Tr<+pkgdfY*XYRQ^8ko|1jRW=vXQUbDj+N&|fm^%GsEMy|PTHF}(ms3FG-~CT#J2;Fn ze?*iz4N6c5p-efHX>Dyq6$A(y*|8Lf1QD2>n>{#O9O}J&^VYHZQ}+%J^c9B&`v=Z0 zJbu#d057n(xVY!S#mil%PIrz>OiUhku7P}-RO0YNGB`wQM#ogI)=9y?+$}L=(g3x+? z!*g-wYUc9%&v|&VNWw3K;E7v|v6W+mCIu_>vz`0>!3M6JwOmMYr7L^QC&=vYkVu=q zi9vv>st`h8a`IF9-8U9l@Or%v0x%39F_ZAcC*tcy-@Yq-_~6m*x#XNjpVjl*ue2X| zH9V?G04?WQ>Y^jD0?ilnMx(K^7tddo+azESKqhdzr?>RU;L|;+89k)AHGTATbbD7v zSMBHVS+8x_uAr7DHE#g3(}rT{6mUzQjE%exx3#t%`#3gH7z*cqNF)-gdv5d`=x63WTTpYQWWZufMea z{^NpV(g-PvwCj)8pKorCG-`ohoQR-E2}wZpzN(>$9lLIwi8Mv7wq7_}RIq7Sl^)mK zn|HQW@2wg-wEu9oV!5!Ts3dmjVnbua&a$y<9bJ`X%916UO9msSPF$|3Ie6XU_F!P3 zzY-1+0m2kQLa~YP6Zt=N0W!uITM7xl<_;Cc7+VYn98OWXoO3W!!s*QpTB>qAd<4Lj zD`DFJkVvI~3_~}dKv~e1EYoYh>L2%ewYku$U~1!r!Z$`T1v0F>=`T}xdeXq!HS5Q= zl@-So0XrPdkC`UHEj@q)OanMtTlcK5x3Bms`*!aeM-j$x{5#Li&8;2Bw)_$sh(uDj zAxcAosCelKq~KpbLP3^L3P3`#DJY-`5(Nznl{+MmXrf3o&_q~~pg=+b(nN4^;B@EB zz3k3Do5*o&U6PA^Qr`1?M!#Zrwax6#6p!Zl@{4a?5!_hOFX?yl+35+$`w^!OO6X(| z1X|73ycQLe$}^vR{?&=~^h{I`Z($LHZPuD%9ts^&K~#y|GKp+78dIWdxw3I(3LtSwSAe8S@UF&qND+b5 zgHL=c3Z=E#PWrJ(67RX57<)IK9~_@RRdGH+6u$rNhhwMSTmIne*>i7S{QKfkyV;tI zv7pkDUJu6VDe9D1_CcT*p@@aAAE?tUI`z%0bwDevEj+vU$MZ*y{N)@1Aj-aoLaY?$ zTxHv;F~*oZIcG;Wj4@^iD{$;Xp6BE-CjmJBJZ$0?o1(6Yso5-Dp`kidEg2&@V0H;I$kdX{|Q*<{fg8>;SqPrPJJft(B z-LE?Q^yAORk^Z7UmAMHG?rc-Rvqw>`&fYSC<nzG;bh70uJZcCL*YSAc#Oj ziLevBbqKq8;&)?XjCopl0II686CB1Eb2nDt*q`w<(CI*@r%X==R3Ugl#IqOC!Nfe0 zWjSf^ppf?f1@9qvkC)MBR`!hSyJ#U#%SU}8DfgNv50u7;igNtL7k-tRaN)xG%gf8B z-+$-SyQlxTeCfG^(-YOJuf6`80G=8l1paF_=T@$>rW>BOqK_PSt4@O8GI&|n*9yB7YLw`UXizteyOJQ~B1tCJoLmTO0ZSIyX z*tj!0K0W(PAhxkfr3OLZ?*re%FwAK#GvE2~o1WfdXU_I^B&HK(il!h`U-v#(w=L#U z6q^gKojQ5?#QE<2qm%JOb;>fqg^g4Sa2M)E%9_Qqq32t#-+B;=#XeNnJdMcMyDg)U zsDDR8C^l;uj+r(B7yJ9#XYDyp)Be4$Rkw=a(UFD=m-^bzb@v>(a`kf8z_o$D+QH#C z%mvWcF(HJIeEIFQ0?=P#2_fXSsNh%vuU7}>0=fni=?tkEKxF_IKSt^0e3nZ0sPO3; zqz!-r8V8sSu!UnG0Wd%;L_$D9{<+MMzY4?8s5!}AM}-FY&j=~OBtvJ%@mE!wD_<6P z)Qs&|-U7F(It=E)wwAlW+KOqW0RrEk=^Dz`t&L_J;lw}3%b8o14SN~~gWIc;g{w8u zdN_O!E{A6zN~e-vN;XxMk3s>gxiq{!pe@`ww5mu?P9{DDpFACG?(FKkv9V&q$FG)A zV$PX*$$G!ld|=<>i~>IVW+a%LnJ#E-+Bs3bd)Ix3Nf8-~1fvt-oAOK+BD5TJeCOfi;MZ1(!f-)zbMgms3j_Z>_9pIutmPE zv*q3%iChd|dFL3tV0~xr?t|l~?>mma_j|wlX>~fuvTE6~T*VJ9AvFfORBeh4=?qV% zxDO;wIw25}(iU1;n6zUznRePgk^r5A6gugoL#Go++Gz+3u?aRY5O8sUV2BeY4|Qxy zW{fkoFxZmL(rUH(-FNHWo*qs}wUk5&j(@M6&+P5pO4_}-8{K_w@3-DhjRQbbC>AZ6 zfEdb~H~;k$J5^S*2UU{B9$JxxoO{$dnhT(JmI z%2SE`P{yzf512HxXQRmpQb;qj5wm)`791S`Nm`kFDiBy=aIoe)B z#?>xYiB7k@jKvAo&f=za~NRz z_H7q__2DfWrL6U9FM8+BzxcCT?!EWk&;7$a_k8B=4}9R-|5&)N_0aKSuP?v*j?etb z(e76pEg_6R67jrCE>qSm7wE0&(<8;BtUH}*4GR7L|#h>`_)bF_N96RPHJ5KpO& z!4XK#kHO)2p6At2KxO=LAURU}zYEXvyy^IYW0oWhkW`o{Q4pY|P~`hBzuf-#wjCRC zL7Lut(;t8S)?04cwRYY4Jq=9_!|fdlN>~5xmECuI;*TYAS}fI7S@|lm_kJ{msWO{`Bp4zW;mQdHGk9;o%}mKsk@7RFYGn-qvFRLmUlr z{Ph!y{(IN6m;KeIP1k+t!N->O_9lVI?7yO-)qtsFrgYNupdEhD2j9u>Pvc5B%-lf9zjx{_~r6V1+nwFkxM)sZ8QfCS-Iy+?ykAeEn$)lPutB zGTTR_h*Z8$O%PDapB2UPJnw8)TkvNBAwBC}e0!ef&4w>HW=IX9jLXV`nZ22F3IY#r z*}5(o9+Z_Aod42=ot-@=N`3T231Sr$NKj%;*!XE|Tcm3mU?|yFgZyCuK!+e1pc|;AlY9tlv@*(9op*%c-%~^CL#bPKA zCX4U?xBK4rwXHi=#e+_Y1w$M=esl&w_(@QuLe%iqBGj0o;1LC*)GVuWyqSMG&ZGi! znjOIr#Sx`bv4s#7aGIb~R8^oL)#a(mk10~~v$dI%Gt9Wuk*fbl&htFatEDpe!xTkD z13wV8=Xu_g{5z_-p*3+vNCfJd8-~KB;)&~TykVzWC^R=?LW@%+cCNCHhL-v54RQ0r zmZNbp%-;Xm+sY^rWU2v1Md;~y&3@{xyVrl~+uvOUV&Wl35(T&+gQ1>yaJX{RMp{+` zWnNt`zUR8;rh=MhULJ~UwR4d5{7z66Eh(Ktw2w6}N zp(2iBM8LUZZ0?+^Y@3Jyz^Ow-FeY0TBV?qyj-bj|oKsXK+t$LQhkyfdpoxRTq0V6~ zDC2`wf~m=@DUb?PbAEmt(V1m3t>pAXYBRn-B~G;xF{Tm~sV-X(&>1}|$9~V`>ua6n zj70!aJ59I8Qx+*1fpQw8r1(+sJ!;xXlV*7>)C=ONwQ)^ zgoxN=6V7045(eS}YWZN)D$~2w)ThQ<8GAszU%21e{Fc!)z#ZPL(u@Me*ITyTeOHLAAgGB zp_9}XiVR0Xoa`UqUF+6y{SDW!apPJV8X*Y4=HdD05Amf39^w8kY^UdFGH>gbw_f~? z^Ui&wwLVNl$%uf0FfNW`thEHG21ETZR>L#|Fb1PpN#GPnKm<@KluV*Ybq>Wsh$^V7 z-DfeN&fpRUVRpN#B%#=pl@+2;upyy^IEK&|;yA&I#R#Z_fhfV+tWdEQMvJ4wDPdTs z6g38e2@R^?R8duo2mtCpQBXku5h}My_4gwN098Oh$UCeQP{>G*%j5H@n!pO+*sg%b>Lvro;`ayMqCnKcIl;uQ>fed^v;gMhYvTS0RXv_inhgzdf)rr z_jJAR!t?Fl{m%E>0u=*6nx+m-6(yw{KpMdMtFPRD-uV~25f%iamb0+qIHSp=%Q}k} zsMAR`4bJehX?dRKd2=o+!|_LOc%FBLI8(b=UvQj8!G>eaJF2KE0HT5diBpON0}ce} z+TY#U^V-q&`Hjv0%if*GM^&DC0RO%3dFRZTH7i+62oNL&1la;2OIfV4D2fXxqJYbF zp%zneLiS81GiT0u&wFmjgeZvI zdiD02%ln$iKI!D1$00 zV}2h9IF27LK|w(QxMkq@vExt}MI>B{q1O+rX9XooarMEvZXvhyfOihW47$JbEz>(r&=k_i6z3Kyj6qm~# zaxjL7Y0#qGMXt>ox7OZ#^G(a|nLP2}@#Ce=`5$~ZI6b3%{SBkX9Mwab)wE6g{Et5# z(UgG57&Cgz*2I`Nz4%CRY~Jd%IpJ_)Qd!xlxM`0(vKaz4H-Llt55=!qp4ZRgb=UOm z-M^~z#0mep)f@VrI8lHW4;V(?mwcj6*|*{Gc>{^Y+U(Zrt35DT*r;3=*f) z2@4jO!(oT@FoA6$J~<)K<%;Yo0TluQj9ywFA&M`w#glr0|B;I}CAJ_ysXStpBuSFK zii$6KJP{iZwoRyL!)FeXBwZ3{8$8aJ365`zQc%#=o)ShVgham^ALo8N+_pHfx?Qm? z9EO03b5KU%^?N}n#lFuzO9SPuXw9O44WPWT3iCh8#flZHP<(Jd8tbajvv)Vlm@yq4 zJ30XiaJdNJ1W+GB?fUIFQd9`VqoN{YWBH~M96nSG-E!k($%)j;iYm7!Rtt!h{u7)F zoKb$dLff)wbB?BIff+M?JvS$(Z>``QJ9q9*oc+R!cP(GJa>T&FgAYCNo;cHF=1>mX8;ADI2cr?COT&(9)0=cmp`eksfClNG;iIS^p8IJ@Wz!(mk$_y-Ss6f zI6O|5?F!QuZGvF!rQ@zU(9#_ z-Fv3P!2lQlR0f0$)a@%o)%Kl;7r^n5iNCDKM_$osG!h>iE)}L(=R0|_B&L0rlm^p; z?R9GaqYwZ>dV~c+4Qi}EF5I;u3WZk$*{$L`?SxPk)sd$Vwf!e zFseXxFc3n7&*O@CTrQ{#xbE5!rMq|TDn7LTKvsQCjazkShD&wYh8{svQX@8ZLGGYK z`wwScd+mrVkN#-dHkYPZpK7rVS@wA3m67q3J!OI&xlQqGq}zHmm1Px35Vh^QW6uxDec=ga>3#C zGlW8b$|#tsL2yWyINP!bp+rtmkt9iyE+{a ztootmQu%#T@69#2FqsAjoQp#s7z{=eBf9PfY)WkbVxuW2h#<{PMJ+ReV4w;Q{o4eL zy1qYLDgX|E0I&g+RpRj00x*k0VSW@Is=@Yy6BSI{^ncvW_7y!a7|Tp$HHB^lPRJE1gH&! zgW=W@t-+uH2oS-A${Y@1a?4g#)_hgGzP>L0z4zW5abVwp%uyppZhh#X2lJhp#sNT8 z0f52goW#c@)C?Oubc=&h^4Hu2Ju53}-4qOlZa^UflmLWMfDnWl8{NBh?@8L8Uy!nS z)8^Ej`TLSSFE4kg8UrZ60WdcMb2^A&nlNCIuw}yQj_$9fP6usiaLQ$JT- zk|ase*P~~G5)jKKkR(ZxE=VRgz7zD~LD@OcdZQE?W1s>!u=lfeAJ6~zHpQWc+b7)q zantgY3a^*KFwla5f;Hb8ItQf;6cnLGoq3&J5(!$+>o`Q1K$rv&7JM-Z9+`F*emZS3 zVl^9z6#`TM5d#R>C|$V;F%btE;K911Re0y``6vrG!5kha#D+x$3?hggF_{noDq{d| z=@}sa&7p~3|MJ(%`}OX(S#Q)6mMvL6cIH#hJTU2wNe|DO`Rve>C#pQUZh&(ERZ~G3 zg=Lx`HsGKXjG`$RR1FA+b-H(NVW-B1dhay@`WGc9wKMwl?NefN%dz+$pI#XX3Ftb& z2m=KHv4yi}cVY7GJq5|zw{1^*=bd-^965S8D?UD9Pdsw$Xl9q} ztYZ`I9KSO*-fIa62zoZbz@fkaW)rJ_->XYTUO#%vXZ!YbTeRSB*$M&mI9+x$anw?7 zWdlc!9P7Af;lgneSP}mF*R3NBFlPa33 zf%9nP4#gS#ocP8l03z@OaZY^K1pQ~?>pvyuqu;YQpE&OZac&6k3rFkrK=jANR|5iP z*bsyga>4z}vJOd-B#8=!GZe^VxFku^MacxmzaC>~rfJcW{7oA-ro8^z8&egBL%nJ2 zO`i-LG^kkBRD=vb)9@8uulmJEQ=6K>`k>u8qa%h4>W9>1H`=Fa7OH`J1;6d*UZQyR)*Q$_3Cbt;Zrz zKtTjr86lvdv7T*MzxFD(+g0DYcb}8b%zS$Af<=EFs_S9pXz`&=B_$<3ad!7Y*tM0_ z89#aKv4@}h`I8SnJ8RYh%a;6OxZf93+Ek&jmJn)kBbo&Acs%t$M4}oh7UQMnwDC%anr^gO_d|b=T^FIRj2;>e<%my+3%FFbh>vsQ_1Audty}+$EnD8jTW>s$3Agry zR{<2K1~iy}K>!0Vckjp1T?G)7!}MzSbjN<|C<{P%y`WA&5Dvu_P&tKaIrKz-f=(#2 zg%D6FAVf6EPFAbySLdfR1R`2;QeybdJ8n7hlj+mfz46McbNlx0lYi>-vh?+N>(X$B z_@dB&+7y7&T30KD%hO?k(SFf_ur{V-` zVF9oZ9rx<>`s3;x0@mq;y7P0#9NXi45_K<<%B3^)A9~1So9Ix8bx9| z4L-jEFacs(fC0em1sWm{2TM>|Z~!#oK#0X+@zz4D*ti|SCU6h~nqoj9BDy5QW}rd| zcs#y3g-{y;&A1WW|BfBoQfB||#d~MXdUgoT;DFz+Li4zdw6wHxg;3Z6j*DJppg^D@ zsN}6(lWkgDZ3qR@t7~f0`sDQ8^1|%d^CsUnWtk9Qd8<};3kD3R4hC)sD1TTdArJvTXUXYfhDwyD0^1TYyqZydIC;f8fCChaP@#b>`)r_Z~TNq}!Z1 zbB9(|)jL4}m&*lJbHe3u!4xKf1~BTDv4^kdmUWQZmMa);^x3ckzQphMHvb-?HmJv?n*PXB9;3jt`F21+Rm1I@u0`^xXh zC<7M)pcErVjw)j=XIM7`-g@&Ry!WTS4ZcUgcA|iwgtlkva_!$>)p3!7~r4)xIk;)fU5^wUFB3A zHCwi99r)a==Y}s`wK{Ffw!(HzV_>^3U%qSzajk-~+UoRo=gsM7S|Ey31vf1cY-}Wvh)(+S?NL8@@{~>O)6x&` z*s-JA+i$*+Q*}B(L*XF8dLwEAwS-dv!{A6xiHVH5arFL__Nm7dhXU2566ydfSkSqS zrX))2s?}?fijyUqP`?v;xc{39dHh7RG=sEFEqZhgfMA-nPkO!@jBuP>$D(Hm|wux*qDoK*`wJwDO$9F|g zd~*WOGy!g`Fm^t%REc$Q*inbp_$?jt8`E(tMmTyMMv1+L9RFvxsZ!cPfPq%!A zQqx4rW$iI~#0X3rcQby_KL@ZZI5jV*TeF5-Kdg`tSZEI0 zaBM?f-jLtUdT#2kX8gzf3l}UH4@$`0lkWaBvrCsc0f2Lkxy7lWj5rqoP=`@H# zF+&Cr3;`~$Cvwxx16HF=#ao7)_m$0Wp>%t4#?84T$dFt~3;&egq&(lb)a1t6HiVK?nps7|MO zx~d{&?b@~1&Y3&!*7xSlxpiLC{lY~HuRnU^Xw2DVMTP-5Rku(b8W*;(ER)+RW6cRH zNjevWZCeDgahxPcl5`%5ws|o?lB7$Qpnz!O83Km?=P14)K)-S|8ua2n9G!XsFh=pw z{M_!F)^EJU>2L?9KQ?_{c6N3(Wv$~vTPG_}PynKJpBF?aOaXh;&13eIo;sPygL=&A zKmhN|%SBP)KJ@C=1=;P>(9Yq21`Vex8nEx^No?AC0LM>P!sYS8&*D)R76=PBToHoP zr^5(y7xajQEBjuxf8g+I$}9pKU=WN0f}u74LV=vC`&Rxj=T9Hx=H_&**Z#1$L&r{yng-|qn5qGc**$vnsBC)Qx&FBLAk#EhgxeV%(kiC^^s!G;Qj)8# z?ApCv)zCcp)vKya_gqZ5cS>Q;UOmfW+9d=N6B6|M?whmvxj|3>4B!C9-*Ly`E3&#)Q_4hIT3R?MIn_`c>bi=`itUzZfe;GjaDbZz zarxaw&z?PNHB|){92CHS0RzgNPIYN~YJ6ko&Yi#ASX$ZB%ODV zd0rI5`w^)>CD znfc7`E^D9E2=?EXu^5Jc-~zb|b9=2`vGS%Ee@xwj5B}S{?pJlKYwow9GJpcy0CZi4 z+pV2D6N9zf1Fgvq+WI)^rP;q9v~uanA#Un$YLp;YQw0yBNc6bjqkzpRf+jm<_Pug8I%JpOJf*iUrNeE zdxiu9I=o&D6j77`fuI2cqWO6y0EX!Mq$;5Ev)|hSOr56f(e66<#-B1OUU( zK{XAG0nnrS3+M*iUKP<*9~>-N1=HHZRkVJpqK^#`eQipk&odg`Mx}smaBvzO^U9mI zYVG8iI8p_}%W-A+Uzf!JDgJG*F7~ z3=<5@0H#iP=;?Rozx5k~atO*>N6JwVeUsm$5=mV2%F(yY$e#atZ9l{N?U(B?tX#S* zD}O_N-~m+4ncs~vtPW$ z6YH^j|Ha<@yvR{R0UZC<>zdlx&14cI7{sG`lHfr^JqbC8!9z5X+`UBbVn9UEe?SmK z2uR3DlpG{p14-~8cnhLuB?^)#!LaHkW7AXp`juce-5D}jC41RT>T~Jpg8DTxP}8rf zyT`ks)`c>ok*BVeB-HP{|IU|_Ae08*T=@D$t!lUL;XUQqGhZA!dqzl20>FC@2&#%p zP&fgEx-g!8{;5j`UpV-amw;J&!Ho^$ik0%l@z*b1yL#=xUoQWAV14}$ziV}hIpHrY z*w7j?N5aua!Z~4OWd%#d-;JUU)}vC+Zo+7c7E--(A3gStL1YkRPX*A2SdtQu@5CR}@ znH^`_2RLMllR#NP_x)frAW+V$N8@_U1{>5jOI)JYG>Z2lcI}?bO(9Gns^CTiX%1I^ z`}L7Nwq*&yD2ld$MiqdfNDAoLlA3_MkDk36ai(}h6^+fgci4$*LJbmhP`u^MR z4%D$3`O%n4Ar%El9E%KdfE0)yaigwS-TMHpkn+_dFQ0qu_|YHh1~Z1>h7BJihC)XW zOboHx!$}4UX^|mq!X1hDJI10^SZu{WSY%s!wo2bu!w~eY_E=e7RmuJ@XU<`H+i{j< zS+?B5f2f4zwTmpvwz0`%LRCc&;IYTqX|{cUBc&99mAf5M2*ZW&$0tAhq@Q36FqZP6 zEmv0X`>eeU<)c$4KL|mH@z$+})+Qx%b;kC*4j?v9XtBfONS3#X=)N4 zqzg7E3drrzA_K#at}h^L##lz#lq|2sU}$%f+a82}*t^>h$*wXF;Q!~jr>ko^{gNyi zVcaCUWYRN}khs~f%kGASWOr89s2GeI-%tcKf~ZI^%HW6o5X6Weh+lm9;0HxvL`214 zFwBQBng~WQaVD9J86uLH4}rlx&e4dyqD(*x)tQ7GI1WN?%?l7ond259>aU|dCoh{jtz&tWiBLd8G% zo9{M}nDI|=sMG+=VKc0(i&3dm(JlsRXcZ0Z)L)2Zod&I`6f1Rw0nn-<20()%2Y{+} zYJphnnL1&yFH3KR7$ZVOkw-&N1r#up)XKJ%s=`cB&F7k*_|(TAUR*qQ_7@L4c+(Rn zPc23%=0!}<$JF5Ne%Wg;d+w$iZ+z^IJKy>Hf4+Kuy}K?+Za~z$o!l6p=aU?O?m{`4 zPLg9AR>2vTJeiQYU*e+ zeRV|-D>K#dO@acg;+2LnV1OY4+MSeWClER*kN$ZSefQ;-16|)oSbJNvq5u@_^;N8I z8x_bSN&(30Io|rVBhSD2tw(-#@`*FQeE7t#uRL?+PuD#4^y$~VQmf5gvTx1+ynOiD z#XsMC^UbFZ9zOj1!osEXOJ6gKXeenJrm?jVhGBHzb*;}7+rqYSA!CKM-xnM5g3YYA z8$}Og3WPS`Zcr#sT8W7EG{c1uK+vMLw~KWX(RivxcG3abe;BgC)mYRveIV2RuT5dvS+T?rpeUL4jbJdKQmr62KovN2?SWSgEFO3~ z#`w4b&=6n-#8}qz2$cX;Afk+c?NnP|JYyNIeACsh*>(Fh`f0uE)NQ6d^^R+c&N z;#nkU{1Y5`{si{T+=>ep%XWR0EQiyAzd+SB(H-jODhf0%}ZU5bZEkg}DnSR1*==Z~+ED1P%bo#0C-VBDMZe z`i8DC?d_F6Yx%h+kf5>uh&}QjuY0~wc@Ztz7f{>UkU?ALdE5U0m=5kN)2=`}dRr<= zI=XAMc37FVfL6+7TW9C1Krn==0s&a5FC$bG%k?@|R+eFi&;TYkXb28{-4UKaAf8Ch zn23mWjP@Of1t?rBi8F8_nnY>=KpBI{j#dDeQZyca>Cv-DP!eb3jVU}-ZQ?CzU8`hh zY-O7iriMNvhW}}AVnc`Rk~q8qgX)I6R1s0KkqH+w^e`yQfM~I`YgW^IuEjf!l7orh!Byb58#M*DaiZu0Cimn4%S$(n}zs z31a|6SYwokh}NS30@^gV7d&JT(e5w>3=yU|OzS{TIRk?tLcQ_G8?T%FJrb5wcHm9d z&Hr+$nmxK=5f&q6t0^smy2pl&(1lR|VrbdBLyZz;1~lpoR4dcYs`x}idzqE70fz`u zI(;Rg2@-qP$j~wr3Rr|nazSfa2AQWo%mHQjjA>wCvHPG$Tr#4;Pd6 zw@}kEP%@1$MJwX2*UL5Sj=eakCJycpufRQc_erenx!-FdBI;!*ML^M_fU5MK2q<(d zFd|rwl!z{dPBGEx0;`$F<1d~%`PC!W&rVEoBiRug=N)_3yNYALBLIH$vxook`hD}S zIaEY>y&L94F=rO05n|s_!L~Rlz%UZ0DO`jEhE4eXi%SA|fK1R5x7vK_)m7c4+ZqAGz-E zC%y?HBBBuvU4Pd{ue$mJ-vAL24Y!x4s1QwpsRER+DFj)mz04#P5fP2lTweBIfrY7w zh=^!%z2VSDcyXMtL;v)tyWX&PH-{V(5z$D84}A2)Hyr#lr!*1~jkHHsQ6ZWXZp?3_ zEZ0nnjCI|Ji0A@12XGJ(jlwA^M2S<$LFp<&E)5lCsfdVZB+JYVb!Iq-h=$?_4x;3l zL{P%ALIed997IGkTH$WOAsj?R!!W@?Gzl~VrAxgK7)Njr5zz)DxEK>0L_|X{!9hf{ z+gza#*5Du_qKzm|y@`lMVhs)=qFtpf;_e*5K}19&1&AA~j1mzI#}OPvM7zxe!liJC zh-d>Mt^gApL`3Uif`f=?_o)hyF~LDZL?ap8!2|~p(J)MK5E1P*aj38c2N4kw5z*!` z!9hec2Gj*$4GtnA+JK2WM{p1kjld$KM9IrMg3?vNIhis}Q6VCt(JFY!#gz#TA|fK1 zT>oln++rA4TBHA94Qs~H+mbCVkcmCJh zrE|A8n~j^?Wxv4pLu3{M45KN!u|3;wzWrzgX0T$f#e3iX9vu757jemS6KEEIE1Fta zyHyy(0Tsa-F?2KYb^CY08f)D;N&-VSb@UM5+UwtX|Kr^r=-h7z$eV(n{P^csUC!}= z_rDvNEJKk)JfLJf&nM#O=I$5w_fJ>~gotQIxDNfycK7zJLEFcR6AwLt$Num*KKI$X z(ac|fAcvyuB5#-B0(2fL#{Stq`=9Xs#Q{Z&`!bL{YvRv_*-L&~tG)Q6xnswEB}+@m zpG+oQgX8S+JahrJriGx(vJN8F}XoR zwBu~u5b?E8)wRe}F*TJz6;REvy0VJxWmqFNGD?OH_Rs#=|D^YC?T}d$TLkQJKp`=%IP!r{QVjm2}?G?Q9E_&j;r?n zEe11#n`7U;8RX46GUQN1h-+s`idg6QM9{;T!cZCanaPG{RFU%Y`@Oc4}su!5l2o49N zc;=b!O}iX50dhBpOhg$Gq7GMH@QyKYKz(qUNQbq8(?*Dh2mp92Afnx8{n7V_JZ(jF zW(L#K)6iydwEpzd-%D+I>!cDKwNp>to7c|W8O>l*id-EZtFpz`=+6)D9)|k`NCs=ycY>cCc&|C>hv9RVfv^wi%xZF;}r&_%*t4g z7+e5LDql)OL`1ByL_{fDU0nqLR4NrzG+;hVAARZ6sbp$$B$41ad;DxwRlkxq8qJg`ji)(K!zG;NcTVm;W+`+q=z0t7-WK3cp--PHh2mF+K8-fbez z_G$n}6<*iI_H>n1u5X{r&lQV7%gawvhN?L)62OPe* z$oYKsZna!#a&{&FXhlTq+?F<2Q3e3mD7L8pXhMEpTMq4!+pQ|A)k5>x?42(zn$HiK zAK<@l-n^R4rq7=I@90>E#j}52zj>v` zH6L)y=Vz~N>+=eZoCr8AB}MJeQloTVa$QH0lJW%ZpZcC{MVf6Y0DzmeGxqf%9Kbk5 zeKl{*X0y-N;x&}ce>!`u#x*~;rt;-543b1sCX7V$Z%gbPr8U@6hHL^30D$&vS1f%i zSo8;=Wl`EEB44U;&0k3^hv7Nl27p%N&NdZi$RS0THn0GI!=e5;o6*QB%o1Y-k<;goC4d52u|DrfWyWVaFBKbXj?=l(V_TP(mpVT`SI`w70000dtB-5%egX~vXpCJdTaiqq z0002Mj~h+E!AcDPZKCf60001RA4U^!0ORE7Wg*zO*`=gm8~^|Sa2I0>IO^N#W*-o6 z7saa|0002Myd2LRx9tNp6@ryYQvwLgauZ~y=R01qr9WV6~2Kqs7=>MJtnYqS6W z06=H9D>&HB2ml8VZ~(wjMFdSo0RT6O2<0RsaQbY^Wl2(` zq$nxq#Q^{S0Q^s53OF{LlC#@0c>$ajSLjMaJo@xnU)95@y>)ygsTv+%>*}hac8kZ4 z*Wa~H?eXLJ0)SiTX0{|D0DwDn!!JbyN5ujFt`!k97zKcX2si+s1;-0FqSp1pD>`cD zeyKZi-ah4LeAkSx7~f-z&nY?E9UqV1b>qA5m1x@)Ob^9nUCAU62Y`n%RpTlo5q4vQ z98z(TO7phI#70RjJv!%3R$ZHMq#V*9NuI8!dgqr=L@Sk+n#ATlp2|uMno3HQQfVn9 zMOe}&Nu{-vJm1`Eqjr9_q*$pml{J?<-F$B)sT671gVqj@PqEU(THp6-T%O92+uu1< zim-f(@!5kSy)(Ylf9#suj+-zPMVBuzB!Olc_5c4cQPfcqF!-D*#6oFl8MT^@A`M&O z#SfdM#d*M%mGWQtMt@dEzR}+!pCj`b$$bxeFy%u4CVct5f5o?A&L8>vCR8VUx$}>F zPwr0;JX3!oUtY_7gc*PDG=EdR#oq_`8~YylOaug@jB6hiyWHSdvSi7U*?fuvjwMSz zdt|wS_2jXDFp1iC|8bUC250uh00m1+Oe-^gKFkeI}m#pQFG*cJ+P~4Qoq8PuR~vq ziS@c5$%Uk6oVE{q;Z44}-XVQ~)jMD8I@TLA_>k05szByT#v`&B{3&7ZT57_$h;ZU^ zJy6#-zJN2iFW&kJQfdZ1LpyHPR7*PDBU_ z9tC|3`z#g&y?Ihp6nuale1~3q0zs2anqw^Mj9FmgVD{k6jjq*`d`D zyc0&wjg0g*M@ zNlGFej*q|My~m5Aw1yz9xxbmw*L@NNPQWj0ELmtvkg;fO*)96ayr-%vdc73qJpjfU zj4@cV&-V5sthKDKuX7%)HH9f^X?FWLGiD4%1G+c5;oPYvA9~NS^>7=#uW5JM5O6__ z-(029!LOf}VT{A7B2Ck94xDBS(z+zu%)+>pQp@ENhqgB4D|E?&tt{NH5&}+K=n$YZ zO}5~@dz#PH{rxhZAB1=bIO}{ukfzTTC2^ds_1T{`00r0bPD2vpOOim zKfJ`D5H$yghazKLPL;o$*YzeD&pK9LlBpI$u=KH!``0A_z5M?NRx zl2BL5zGaY;*`La9zL%KE1wQ0AUqYnk_`?x+Cit-UXC7ugTm`q9kFPKC4P6a?^#|dP zlMDWW&jozqyZ4Ll$FyH8`jpY%yCX~#5x*sW&@|21cbD+TK=6r#v*Y(Kz*mSAkjY=y zjeKkNy9Q5=Tl=5>^rF8@`F6n<{;-KJp|be97Joy{;d<^Tc$ytLh{MFmwJL9i(h@U`7^H6J}f(;X2 zwT8^q{(iD|_BxUzRTTd2jjWn(^{kd3lU+O(UIH)>7SF*eFj(*&80&y=z(N8WB!n=K z5YA#@;34gbW%h4osxr<+dlkBx>h99eGhH*&Y<$w`tE{TbIC(l+s?3gvd}jaaRR6o; zFY_yZU;wCV=6AyU!r@{$$J&C~hE%*)xub+ZVesy|@ABZm1HSdnJE-q5+Y)=>CRl+m&bH?ePIL$l zEC3TNRsb9l1rX3pz``og#_(!$5p?!~wuN9%?;QY(ag>N*%Sq(p{RJ~4L{>EX38Y}V z+)IDjfw6!IfEEITqw?2>clS;DTGgS0SOe{*3&bqr}YbH2E#%=jkI@Ts_)$yTyIO-{1QOzy8&4Ar{6t z+?jdilgVTlcW9}vDnwju+W)BSV7 z>T4=|1rzn3<5*~YOIy!U#1^r|!*L)?gh8++;tYmd<8h5RVV?_9c(yAe)qSPZc68s3 zZRlS9kO}#k3S;2ukA9Z&p8kfMBAj}?JZ^`-rThty9r2ecf2?-gpJ3ovEa}VF^oOhb zrHWW8H}At^EC+rfMkm~(n>ezb}T>D$d4=eX=H;#G4j*rs{DWju@D^mervn? zt>;($503nPRp(Itgr_2P_*zdNB2_+B`8{|4yXvpJmA`l@KN$Hj^Shn=hE`I(tMzOM z$F(h)wlo$z;M1J?vhe-y{eVCH@h=c{bL7tc*K#tMOeXUN$7C{@ya;2;hGl)(SderK z89dp2oR3)zf5dW6U@IifRaEa!Q$c~BB zVSXu+xZKw9cI&g$`_$(%yCFcvsq!mdSMlo=soIw1Ho?&FDLiYb&f}*2?|=2TK%~l- zQZv8X%&-0qT(u2FwHFaESXx6e-g@ineDJ})=hx!NWHR|bVXnb3nY`xAuUoG-FLMNk zUm9M%+}pBS_o(kVKR+Yv43EyfKfxQA7CgK@ZwRoVMnJt6=0pR+=q4;+6M_g<4-7*D zAg~>nLy*TWXQqSN00=y-t4M|KX0AfWaQM<$@iZ7n`p>Ig6w4QhWgBaI`P!O|VV zAUbQ>ZO8yy2@_3A`ExT!T6wX0O@I>-3DK zw*?Sh`Gp72VPM$sH}XC151B!=ydWHR0Yd4O^wuzlfN;zWjFDwvifWlUAyHUB@#6V) za}-eLJn{npU_Q)601#P8uarkWG7FdKXXxW==@F zY#u)R53Oz3@0`E=^*vf_=p7^-taV|4QS<4uMplq<_#aVMO_4|fJixMgRuWOwhOR{^ z3jjwvJd% zmA9cQcxY>U3Yt4F6%#;?+Su)a*1pP* zfAm9s_nV(%vB#DgU4bFOS3oE$gb5uCV_&j5!ond1GT~ezmbzKth-=7ppT3`408O;1%L4M{2822yU$eSF?`G7Ri zj2fx2x)C_k`<+wMi5itdc-{191Rg?joY>?G%6>1r!IS+%dRILL^UN#Ytk2>sY=h36j(#IhJK)#|DbaQsy+35n= zS9t$nDR1h&|h_^YEh&Y0Cw>eFNK|h-?o9bc6r0cRwLg)^Qxi-{0@^ zn`dVBU#mq2=@NAE7*=b zL~s=>6QTsH+RH?tIDtiVFusfoT+uwIDH&AmqETdsWZ)4uM=T=dbK|j<4sj7O8{^;qUaV>F0Jc0b@>)=JvHBNs?q`S{c8+SIz=Q zk|fC;#?9MZR8)lJ*45Qbv=R+XLLP7GN@6I6I5W>7x=@sgg+BHl{E8>HJjbRj+u5}F z88&Qun%Cdh!`Sr(SyrRjG|v8Vk=?uZar*Q*kP1aK6hqxmKrxiX=uE&Q@bmdU82s#O zzC7_A6VnbTOG9x2jaX&x$47Yk-B0-Sw=0+gW{I=p#I==K6O#p(N2l1k?=Xjtp1=q! z8CSGYLqnCxLKyz(LTesQ4W9?eC}NrZBuG{*5usYGAd=x$r7>=EItMKk6~W!{w8)Vp zNpfqeV}T>>)JT%#&SmbXD$B~Xm1eUfuVysk2=_nG57K}+1uRRzW}>)ub70^&yLNrV zr7KXxE-JM(INf~l`M2zREhdW3 zYd1MM*5pP58m1HxOmu{X}tQczVarWzbck|h5s)!;~y|0fr))Jf%z=I+cARlrzIA*(PoJwdge@zTy0K}v7~ z3=_r05C9ZBkY#oDA2>p&-o@H`?q%E7jr7z5$B!N7`;$X#-TD-s0M?#HA1QY

6KHkpeKxbD}6tXpdJg)SHMK04_=)dAkj*ijsMa%nfA>!3mWpy3+eTD~0$7e(PT7EKqoYjO7>{pwgvTCz zkcS_-kLPzh!OO31XZ`whSSD=S@dBR?{l(tB$5eUWaU6f2=W?zf#dV=}G2Pm!>9#b@ zTo#vIUE8IaC2Hc@WgSK*vm3QqhIbq)C?E;~MaC*#BC`dt6^FGNb>b{oTkp!j0v^E1 z9Xy-^oXc~bOVg94^^acC@JCC0UdbmpImweemp`6gzE7UdU8{<1C1PE2EN;wq|+ze`ARMYlzAvUGJJe_fhS_2J7LtbT`-lw5p%2Z14h zP*BI}up&F{gtc)Ll)k}&B^hMq??lxknmyetT%5sQ{*g<4V=pUn%9uTW4asYYx$(g; z7VCZJnm|Z_2G1}rtS(~CpO%xDw2sXDa=HgWvsk(AZsKpr%NY(x2-XP{ZrjJIWw{WJ z11$#08iOHfM2HX&og6%Qg{0I1e*fHB)@HrN$vO|=aCCnOYA&wa@RGW2C%>JQ!ZQmu zk-4>!{yPG??uzF1LvQnZ>Q*)sR#ETn<%P6uOn+u6*`==&*6mjw zcSuK&U4%jgBiK3L)WgzsWz3wH&is@DN-IyHkBeu>5O{I%25L`S=gy$Ux$}*@l#)YR z>o6GBFY2@!b?22~7+)BR{`JN%#&*o}H=1Z*F%SU(9f!^S*?m5IUcNdDpEAcACX;DQ z7^A(HV`#u(GMP-@EQVo>V!$!_n~oq@&@~-V6c`sb9`641>&N{M!bbr_UBDqr#K(@q zVY5kR&&TTYbWWZ* z!;SVfydy#G1T|jXQO=>aP9w@LG)<((tI^sy#N}%qUfHpiOV=9+DPasl$8L8L7zq;$ zS$M1VJq{l~M`w?hS+nM#s2W~>h?^aL8d`d(c%z2;vlr<1XOc*dw|q`X7lcaYuH@zboUKWTX%^SYqGFd z#}ib9=zpGDJ}zEsWpn<^G~eoCP?0!ZcbOx{&Ja-~y1NG$^!fpitTr0l%?u7j@COXs z&0XAV_fvP)%_}?iQCD|9dL0f_SF>wxIgRf(5eTXD3=DJVSUsEaO3@4v$>E@(rGwP8 zY~1el=#yyo`z`F-zn|iNm!PRCUAKGCLprg}SiJpS+B_ZjeIauRV7jMy`}z58#x8{C&~0{OqR>v!gVFvOT#>crb=gP@%r=BItG$ zRVENp@QwI*@BIIn{KE&C{fFr|<1_-{0c6pF(|R9GH+#t2z8kD|RxDY>l!@OaE;a_6 zGX`un3_<6S3Gr0yE@sY*Cm<5x+Eq6J6-HDmuT>wV*BfN&)T!($+s5|7Y$RJe&8>Z$ z_+KrL{b({dx$BW_3c3(vO?nCi+cqMKK?FIBZbT5U5f~PDwelz~TO4zrn#RFh*(CjO zIujElIy&3&20~Q)_ZX@qGWp^ADa~8O=FDZd93mHQc&K{wBo6be9I1YF+xdU4wJr{fK$?V`pI8YTAa(HlO`gdVlv&UTuv8J76mNfPdbafY`8J{ zl2LO_`yqSx@)Bhf#&P_6-uKMgJLAkdsnf-4CXJUaS}9qs3KFYLDHIkNQ5n(3f)=%C zkpx{X3?%qL>ZnB{B~z?mWSs&Jda@* z#xE_O0*7H3#?qs;LMhF^lJV0x0T(|5ZzrZeOVAcj2wH#=K!GA)Yx+(e_0|+NvPdUHJRWCy`V;dDY3euB6AXqK z9T`CjC@Jv>I2vJPaf246tHSu%IV?NJ{PzSxOD5lcCY2UQ8RSTJ2Qg1^yk|edLwD%v z?#9mxUcMPG+^ci%E~?5xY-*??-cU>N+Db+zCdt`0!nV+PMSOh?bv5Nwu8z>w+RSV+ z!N}_|>_CuMX_#=4#0fY6G}cxV^Fn0vkn*$S(6qEQbLG-G`c51oT;$++9s@T9Xxv2JTR6q3tI-z4nigpg>h5yIy0QwRYC+U4Sf%RGPf1W;HCl%>eY9F~TFvJi`Lq)jIMjZ?jyoIiV* z@v$-9P5xl-?t|>A>pPCWf4}oP=iGDmKJ0F?8v-N}9wa=Zw3a%JDNG2`7EB@t7-(sN zf@25)JJz;56{BR(f^ElfpxVs%SD&!LAJoE7A4r6>7@=y_D6%G+2Tb<)?mhROr{9A+ zH<%fM%s3-aR?chYGrRYXz30sCxo2j-=lA=5Cwb`MoxS41)6eW?W8!1{3@r*YIY~N0 zU*uDy8MWGCcJ0{3e{X+;XTQ0dEOi(Z?Of2Vr%2zSi-fq_MFl=f&pMqvn?d+ptP8;u zcu4l`-A`@~kOozrerhM1uU$pQW`tpg=LaN7j+CIg9hw9EG%JuLIm)Zh?HVRp38P~z zWMzQIAAg+fUwW9Vo8j^rxP<8`g|;B1W2QZc@@s?@59@OJssYv|GzOcb9YbrnL!fHJ z?G8df5IT&Ms34@sHI=ZzPhOnF_f_vb92tXygZRGB!x7D?XiQ1LwEY@BlxNsJPPBv0@HkEGq<^fML{cwKxFe1CwE{S$ol^IzbF zJqOwQ{P$6^f#;f#IaE+Z;5-had{T9*67yXpw^+CvoLxt5hn@1#WKMtLElemrAA5 z>x8ooAq393U(<+d2`&U19kYVtCBk9>CnQO#5q?CR78DqkoO%+gE?&->E7$h=Z3r)9 zd}4}$T7&rm{bWT>RIibyDV-$Yo4bF=-S>QgukL(~w=G}EhyL<*-unB0fb#2T9Ux=~ zQc-U<=q4QmIS37abkJ_ipd{!bX8H2-s7HeF@iG48KOQ+UfdmP{_99-<@XsQ!m?ERz z7lAY6X~KmUUdU~?-_1w1+{4zbALhP~Z)M#z>(EwU0b>kON@}$u6I7Cqn9n8k__`>zpw3(H5*>HWq6w z&KQifXlF6AQBwB$oJi&Mj@L~x0zV{*B80O@G>H7ASbRU?qg(Fd$?ebLsTvzMe}F%^ zZarZb;s+IKwRuF<0RTMDBw0bV)=xJ}Ns@TZH4Q73 zUTe-75IM*c(17jbmwrm==EgqtQmIt>O;p}}OQli?Udst8zrv2wmL3~`3trxX!%9LU z3ADs>U{Tmgoxk7qIo56ZD4+Y{ZeE-YIWShRW7o4x#giD@;p7EP=)??!HH05Ao#Z&> z(Hx%7$e{zsMwO1~a?4*_&)Y6sO1%lzz~I0lJXIqI>tv}xc^(LjWHt_jlSE-ip0`wZ?lZCW>?hsT5y%Za353 zJa+#7K5n@AHoms&+e9*8(ZCSCQ9QZx|0u!%x+dbg-yNYI_3?Y>Eklumu;3(GD9mgu zs`pwtK3P{#`Rdo1uyeMfda3kkPbQDvZ={}$J+4c!g^&OUDJYdnrP3>v1&&gwRC;~+ zwG8od~4S(LYec<)fW+} zoO*x2va?U2&o_K^`xm+S=35vY9p|*umQa{3wLYKw@B0}4^qEhxXXIOC$tZhAzQcnL zewrl7G5HJ>Gk8wpA(0|L3DtXD3mhje?5E;oT)k!$L(PCVj``FB|A-YJ(S$a|cPRi) z03yeuOXz7D6@@Sve{}H$NSpBN|L)+%_1ALGhwozJ#tm%S_8@ykeu&8p&AtlD&ODWD zdX!Jze=qm{?Z=4YF20KJq@rH0Gk>tjinpGF(lHNw>H$9Z!P~j(?yc0` z{@s_dpdQQ~YZo_Mzlob}+)Qh9f}y%%%_YkTD9~w}z)NS7ql7|OM<_JD%u!NfYyrTs zvz8+Bn9lS;uHUepFMavT*sM#@nLv@^yByC8a3a93L@YdEA)zol`NX3<`pCcY(7%3` zD9rHvoO|#6IBA;lr&q5f?~L)p6OVD@O&fXd``^dz@4dkPd~FxbiP<<-u3SzOXr9{s zUu@pAvG?}`d34oJFGtBax#zZ2`o&3{1Bb%8Dw-;|;5e+jkjE_ZmRMVUmP(~k=~cZk z3LNt1WzLMLDV2UH<<5volm*~gm8S8(Y?%jlO0qX!QYPj)zE zXpqYWRC`ZHh08B3q*;B}|KX!1M*W{|WXn1_{2U&c0a?Tk37VNYp>#tTi4T6G2N+ADhhu0 z+{N7afg2dENu~~tV6zF%J?l+ux${nhvj~&2YQ;HR^N#bFr^Y#a;0Ls(Ti_H{C_n-7 zm_mo-mBl*yvy=so(%gr{*ocA!T=A}3aJB|6z#_5YH5`ZNBmmBem$oyOt2aueQt5bl z-QQ(ro`1nrtSgtpmVVtmEu6--Hqw(pkhY#SbSq4lH?*68d%Ww1TffkTD326%wF#E(m+HSBMoLJ&83I zCF}fXPnSl0n0Z4DjEyN=8)O$Nb3lTr;mHa~lA@G{=lcL;Sw@m)NTmn@e>MT8&~)1| z^XJdUIfu>*oYn|OkFX9Y#F6)qg2EQ$u0RTfb(Pr^_$sF_3h8!^G;Y;JJe!Pxc|&AL zO6UgwbmA^v;G=?oRy$^La+1DAli}fEiaf>H9N~U86hVV^AZ+h^^E{_ktD=o&CT>x! z*GM~AZ|lh9_zcriZB9L7DK>AT^&t=%&#(5*De~tt)5^hCXf&%>IfWAm2!W6SYd~vF zRIO6vImTLqCo#?;>};F_W5~2V(ooftSnGPgDy z!a3Lb{Z}d#oRnCt0SG)r+Kq|h4oZpMgqt{tQNF?xU<-{W1RjoVmiB&LNe{3{EC52d zV+wV4?mr_bm0pD{G*&do5z~B0Xj)0nVG)$QiZTYHV4Gw2uM(WlGSe6U9Ij#+5Rn8-QnE`l#d^OO4zWd=9zWVwb?(V*&*C#wPD=RB2ua*z|ps;w@eewCL))3Y#Dl021D<2ViL(Tr9 z^VHG;Ri2MC;sQTMQd*DVuG3C+>D5^ z-$zW1Tt>RSCj`SRv%4NBrI7Ln!0qjp7z^Y1jQ4;CF&e=MP6VwJ#S|Zf0mwBYX1D+) zok(S&T4jIzj)z~*Twiaf`G9Jolt9Uqe(1=WFk9H|gw5uLIc0*MIj2XgDp%Vpl!C({ z=4gV6DZ8tIN2!IPO7I=sg(sym z+hI%h$)1$|u)Cm|>3v6)LMavRJ1)1Lz8}!4IG4B_BDGX72+`xz+IQbv?5I^SGn^@Z zkN%mUv1VOadE*G6ILROh6-7`S%0I-*SmE5OUK^~etgO6g-pFi3-fWthm6etME7FRo zL!4k{|GJ-=r-VqL?<1-OOn~s0yYHn`v?{05u`TZJAHOH|GY^L!K}OK@@?3D9AWEK| znU4?Dbi%ug<}CpDNGC43N{kC> zd_?O)%?n*Lo(?~8v+tXYyd2pKLf1p+D)aQjcJR%{MendWvgwWae2=FPypr+>N5L$k zO&pn9{rUL-PTB4ToK#9p)VeUu2aJ(vdCxT86S_jm3;kw;6QkCVYGeCfu^%yc0+$%) zW3%7&0ZH2D^W^yyLrf?{k-y4#ue41;dha|k1Z5t2PW z__55~?%cd7mYcV{+cRohusNc|59gHa3qJm6!q|~Dv$2YAUp6has9unnnKW~8e#ZHW z|4_Z;C{@h2948@4^W=1cCC5ypJWp5c za}A?(W$<7bB`Ob_$}yMm3Ew?_!nfai&F7ze%A|r(?x;isrqdI4=QCb1IZae|kb`zW z!RV8+r74m)q|*8c0XXggj0guDV?9cl zHxUUJNQn>-MnnMM5k!CmNQMOqt~cX#0D{`$0;i23rz5Oerygszb+SxDeie@+1ppyO zCh*{GglqX8_llIk#2!Pe>|@jtdpoj{^M>s_14fInv0p34g6=v=hb1cS=QESRAPij0 zF3RyKUw-ukfBx}1nH>rTz`_7~rzI+X|MM?D{P+`3pZ?6I{y$1o27|%~@ zD4=q)(!R(Ln@)M|BGA=&=BtV(=Dlk6eMB!cT`AhJOl#W(b-FS&_hS;xrLAaobL&29 z8iFSB-iEEQ`-XL%2JB^NU$b88Ie70%KVIY;c>TJjHMU+~wXh}_io>Lk16`71Bs~Tn zG_Tpao83sxDvaa*=TvpK$1|hRkSGhpA|Q5%n}HQbzy%-y3l?k;n?yok#RULs#Ld7u ztk?od0vV6pU3Cu9tGIhQ>9&WNc2C#%`B{%jwk5mTYFE8=-mgbbpOQ7w^#kv|_Xsoq z>CwSvW)tTEhuMiL`H^D^_AWB2yMJgLhLK@4GV332F#OC&9f?Yu`u zO4+jc*#)5%scX6Z2wr^s%k}I3@`#J57eb;O*-oLkEkjnG3ysJ6)mq;KHIM%Zwz|%tSLc5JH9mK&fH3S zONKi}RP6j+J4eLq5-qRSxTv@#;)_i7c5ikx5n{IJfq*>c`R7pM3<#+HfJM8lqK3OB z%xvPO(V=nrXJ}@2@)DFla7@e9l77}PjL&)hTi@6&5|AxBOtKnpugxPa%%I5{8CF;1 z2z|W6kACe)W@bB8aDM(6 zl&JqN^q+z*K?4@YL4J?_UYDxODfW+!J|*pS2esZwFhu7UOGkaP0r@&!mW?vOFTCNw!+gkl!9?4;5wo6q}6`(m$iE;o92kKZ$ zAU#mp%L&yhsd1>gDZH$em85pQN@H@72! zsu2hx&-niLehk$EK@>y<&~o?@$V!h)HnWME#*;8-N_ z=+P5a!;;xd1ch>hN&pX!HZ!}45`d@$k#ndX6i@*I2o9+#xu%fo&}L@4cm#*p+pFCE znS_x-6313m%x1H8R1}NFjA8^leb3D7X2~YevZaE%5Ryl5n3>(=eib-p$O8ObRkbVBqrN8IWwLAlaW=DYuU#Quq#TX45gz zbuZllHZyw-U*0A*3d9j8dG?=Ana$>`mK}fl>&H+%O$AhV2Ng53JuWYw6AXkd`SV}? z2pWh=#Gz~#H#Tc4Z=vQ;JybuP z%e$G`Q6!tdlP6ze%z>DF&b#l;K}*p3`v>2(ud28v2{SX>)5na$p1lNKTckc4?lCuYAtd>hMPydEvW_Ajyisf<%z&MU977Jda;sA2{ zsGQ8hftlHqr#w&VY|YG0MFo`tAPOWMeV*dO^G8&TD6W{z2hiYUXwA%SA&L2-r>O-O z&kCvsVx8CI;)a>oD{z6s%`P0Sz=t&@j1ez3w9wBs3`+Rm+LUt-QRq<@fKWYH1Rhba7)c&K@j)fI8#( zGobp(>=0mPW|J;(#IE=zWcP;O{im(6h!7|_CP`31RiRkX&&$346QY8s%|m;srRg(U zmdhox|FL)fx={l`9LK*iYdg7v6hKLXXd;@t01rZipr+wXkZ5@ZL_?RBhCda82Bm-~ z4Ty*+5kz;kcYdH#$cZRX3XO9apQ}v3F;%OyI~8UGC{4)2kyNJYhiqa>MMb zLeuagVJF67=06N0rG&!hx=dX+REkMJAP;052wYJL9W&0BmT*rfjH>!u?C|+n9v4MX z6m#4~MP9x{7MG5xEV1T+B+MK|0OF!ZqN)<@cubuV%PZFy@9Y2pQ0B~eBxlNLhF91d z1#O#1sU~p+0x{v@{~Wz9Kmc*Vrq7Rg{{_h}#}3B}M1}~=4OwQ~2aVN8 z9Z@=d&ZWKWZLSV)FdB7#V!zCrMNt$BVm=BSMNt$p$lZ~IC%^(^U;#Mi&CKX?hkH%# zo&DVrNfju7zML7KVJ0TRoCyo2op&7E$uzVK`7vsF@%$z4-hO0j^E;?PQIQS06l4!1 z9U1$4E=D}Ppy0qF7U2&C2{-6h(2IOH|-+P^qjJMKODFWB{Z9GcJlG+OA`Hu)@!A zX6wr)tG92K;>J9YBcE>O&1!lQy;o$0ynesIlc&%4_H~!GGnSj{C@+B;vP4UevjE5v zXU0xwZ>dxNpjeFjKnkbM6)wPAuo0g=@9<$`o%L65c>L%gch`QicPDU`on@WJf6w#2 z=iIHT_v{NHWQ8n5lL#ZYp`d~=iIK!WFrX;7vZ%OZ& z#2tt%ffz9%Bmt5@=uU5SZ{2&(J@4}jpZlrqvWhCYJ6+vXxBLBmKL1a3b=5iVsj5@w zzUQg;yzdi;00K(Q9xfo3N1m>AA(U83AQf+U+na%!L&?nnFwf5}Wm%Rj@2DwoEZKR< z!wIu2TV;xyAR@4sD~FUAF$$x)rYxrUnVKq!v(wu#m?DoYC1PlWKP#}T>L{#86-~3kI zeB z08kNDhcV_QSQ9+vb#^9*345u7h)@ki-16Q(WBaZlPDE`k{_p<{vNyK!p+=Z{>xOte z&QhNya=#fX?Fh5~bM{ZM4S4FILy+d(%0(D``I;mq=E zVZ=~pj*b%$rl!~P_y6#5r06U-pT-fz1Po|h4{QjY6pC#HK+wb;W7Y5mP z_AnV|(f5Du-$YDXeCY3QrykXKssUw8>O6X5LKqSEHi;&lyTnJ5fLd!HEi3un_;CmiVMpI2}?(1QTzZSa|tXTK_o1SeBGe? zo3La=_K_vpaakC2KN5VYEId9bs8h+-M|KfHF<+DxKnEZLkeX}_GXZZhvSWGPS>b|l#JmI|>Hr3=xByr#ZcGY~m^U$+cwV|S%d+h2 znV3hQ^CY8LmSvCmW;PR>BEp7F2djpZ8c-F$F?04)p3VOt zi3ltv2F{qeVkpeb+fa-0lRtMoFL>d#oO9OcOcfEeA;}eyg5VK+e!^IhJ^K?tApf}5 zCNadp6con9^N(w-a|4%zE|`Pk&=C=2@(Yt>S(dGJxxkTSS+)|R%*0R!JD>^boX5(6 zq9_>jhZIFX%7S_@0Aau7Td;#9vhNY_fQyo(r1FBhKlcc)c+Kni#wTCE%U*mHXPtfu ziG(_+3+|44!d>zZoE0JtF043r!`Gq z=d5+s?3|tC%9Wj*9a7}Kt3zUh`E?Y`Ck(PU)^$!JxWRgiBlt4bI8sC6Yj3(@cZWv% zBQ5G#YY&u8tFQ4zuWWdrFnm_2U*8$Jo9b>Hjr;Mq+? z)9_zr>>xm+51S)YcdXO|0(C4SpCc5MH!P875GIF%%h=XZ|Xov=@IIi*67M>s2qLWv1D9JZ6tE%TPvl{zwzLp4JneLvP~Cg{%|2+m$_ zPDQSLa$-JaPm-$P+r|=i*+W?M-L>GH>!K z7EP2}!2^`kg25VcIr>k$eJA3;mY?2q#p@4`iu$NO9Uc+)@Ffh$a}Kx&&9lug<*Wkl)5?MMnbwaIu0N3L*7 zjB*BOKl@U^@a1LSaj%KsYW&0Zq+vkPTp^1%MPO|TGZnnXN0zbV4Sdmnyjnh@33wlP z2?LnE-Ye@^URkZ&D#no?k_KBt5JE}P?}g*^|7;l<|J8kl0<3dvBsA2JojOCC^q78d z(&Bl>H0G}(SxNxDj!GIldXw%;q}E9IyUPQMBAlpS4OSS;>DAzXfIP$_i%zP=J+8eB5j;I(hxw7*~f%^v@t|F)L-7=n}bRi@%_mQPXZCj?&N z!&{mz=Uw=N1_DPO3$>OO=g|TWF^1HqRa-=@oX@tXbJ*N)neHt^#vH*-n#szRmhO2+ zsVJO0Haw`ZZWO)oxtn$7lH&$g+7c+lC7Pj#lDO$(bZho0`3xn;#N1zWzBvH_OT7vhRucS3p#!dW!_UE)>4yY5gc=mnmrGuA=JczLsG-c4Eo9P z=8LVq3hOyqeFk+^#o>DuUH4w>iH=;`G*}C+kL8T5AP!3T6emKphXBfYW)gf$1Ekp& z+;nSM>Jyt8r05zV?GSw6VN$`yiDrkjH`hcDQiBeH+n}3*+e}+9qY<-Nh`*7%vp_ihWZy> zS4i~cAXy+Zr9HKn^uh(?Wn z%HTQDOioxzGr*;S9TupftN;}(X{d-idcIxEFK|}ms!15{kHZ*wnUnlozawb9Z}_lf zh+R-?zb5p9ws}pAgpc2If9yRgCIe1#Yv=ui*6-?HwFM8)yxk|mD{A)b^px*N$co$# zlSbbI7Yse%ESM?tCS2Hkh{Z28+395S<^l)|Z;w~6(~#6LqK{xK)L}6h%B9fti4uv; z0j4bNQ$IxMWG-QQR zYGGPAvYMVdBt{d48gYr0e4(7ug&+)%i(~#5mK4Jm&*e(7IY;`QG9(QsmIy%@J$oSn z!(Wf?ee`cI_NN%~L=j@}DQoO~6S*hE(zM&3X!Y-z#g)scX-K9svbsdoV=N!X&%K2P zvau#j!FCacw+LD8Rxk33)%=^I+!GS;V99)L6@Yp_3hW0FM+#%~a-vbI$2*l- zo@YYG?T7)jWP~+)50S6ter6U#l|4~$7Q z9O_w{kP@>!9c&E^7Dgyghp)I6_t+GR#BO0}AS}EOfAM^+ZqNGrmh<7FbKlaMe@l0w zHAIoUDFDPU_W9S+e0Bdr9>F`HG>qNfhM9_qKD#kAElrHO1v_i6cGY{t=sL&$knCmI zc4JuleWqg?%fy{t|Ngq8@Az%z{349xEnd9sGNm_Q(`Ph#~}dF7Nu@b($5j3o4KQ+IO_ zElxp%Sg2utV+Rt^7XtGF+(?8@Xqy^q=^(Y?d83#(MF?YutRb=_D3P+#y-qHpq#j+Y z#%uv~UwapuTu7|4e1*y`22-p&Cn_m+=fAv#{e2m4@p`R()%LDOQTIIZf1oqPjVHDm z{LsEB_-zs1{vvjxBTa`U67kzoU4%-pa<%s5mj4Sb#lwvMwyOOz)^Ty1nI&TTg+xln zRnCwNz~ah5v0e^rDCdkuNQQ zz#s??ECjVINS;uRwx&7S@{8bWv>8m}an%Indj67*oEApo``d)N7M{K1(NM8^F>oBR zWsM~MQlLF~)_LCcs=D~}(_nU<9@lqxFJApf16N9Gu6Hp{UFG^=z(ErJ?0J=d5EI89 zp>kfxd+l=ns^Z*Bh&~5a*rVIW;ko?sg+j}M)aRtOk)+ep-&TeNRJn&J_IMfY)yKRc z!5bYAG>aUj0~UexI$YG+5>hFjgDIst>2^gr0Q5R1P(wA|tt|1sY$6gE-KK;t9Po(K z>++e~J3avpSyAM#IO$zP%%JfnmwT&oneJ>Ch#=bXmxnjv*K8FHSIKV?0mdcFY#&kW z&K^byJpZw`MJ&7wzi%3yEy?yFeoaHP3+7Y90ITN*36u{C{F^ni_MoI~yw64|Wh!PE zt}c@7*q|@@F`9OGmcOwPGqc|`;X_BlFP*hHFYYJ4LUD@o%e;AQ`}d5hgex*3r|i*G zJdUb}pZ%dWbbDKDl1Wmt$V^bAaMM}IR9S=wyN%u+!Q#0`s#;163^3H{;MHja!TD=#~~w5{S!!Y(Rohr+BqtP zHUt?Z0mi}S_?<2lh%TYN0N3Qlu9$_;YqA=<59|705*Awp8_ufY=QKzc%SqA2uts#- zJljJYLz@>e$q|Vi32T}c0>a+mLfHaPBc;{+NPF1Po(mp=`J;7^4^PDhdX%k@L`t3NGQWJIYxh;X{r=5Fo_97Zn$TZ_HuVq#rE+YxIZ*Xw z1=H_lj{j;}du@HOc|p2OHyWww_f;ffju*a)tuSJfEPig47wV_s@K52I&6#k zsRV<-?d*(A1L|;CjoJR^$Z3W4MD5liz0u8J|3?$@wdRb|FFrb7IVv_6clg!#Fp6dI zq|~o5QZhr~7`t9`UO{s#Nz0Nb=;h=SEhj#UH7Mz&m2N%!HU#U;mVp_ZO1Ksbjyyj<#dTClk>>4ahNk zwckv^`ni~R1p)!_$Pe9vAz`o4EIES$QFkrfE7TBfOD&nQuR=1xiE)ClAenrAh6>4C z2^1Hn{se?2E8##1th5a}e4c_I-Yt_`EL|=Xd?R(d_EP(8nei5;^(TX$_>$a?izXL) z!G{>kSOyp0{x-tqVn#KQAkhK(VNF?vZXIW(36Sn4aSr)EKeLOBStGz^3I}TV3 zT^~JM`qK#1e8y1dGr=D2VOreeT~4q=ofzcaj?A?T)_maER!O5!nvFICWk!(z!FH*AJZD4=bs z37K124|&ZWzj{uoUh5bdw*L^h6JUzTwuv1WQa~uB0iZT6fiq3535eV2ygDtBL6`Un z2s5bJ4bjn@Yl-MHU*mvM2j$@>BOHy*L3Y@s1j)3N-V0e%wb}2__3Q;pncdi<+!E?W z?e&Le%x*3MR5C#d;%{&bFJmFI)(MMEJ`%-F*m(j8R=($o5??PMjckM;#}; z)kDL{gDSs3Ki4?bjNf|V$S`Rl){nIx03Z{#JYA|AFYYcoA}GYt!$DEiN55~>k;V__zfW&koA6r_SJI@z9ZIH~jmwptSVYfp9fOsDpAb#cvJ-1O;He;N*56)@GSN%?dOcg=|jsL zZf`QH4^*(O&@7e(i_SSjML|6l)+DEr9L8$tvHQ0K`GZ$s&CBxj@QqP{FsYvW=I*4te$i9nBLK0My3Wt z0C})dGF$rr>O1&W&8`C!*Lvdf&c@vQD#Dr1;1)^4*m&~HzVrIG9p@Jv3T4x+)0GAXYMu4=mry=jIL z19XbF0pZdoyC7Lv6xm?98M1>9#v{qBu096CjhF+vk!ax|&A|Rr2H#{wc9E>8aerQl z=bN^dONv)sk5xa4%6wC4dNm)=6LP?^;*TK3w#^ryRY$1rcf0NK`nJ<@HIU-Dk?$dp za6B`3bzMiEEI+_A!n^H$zvL5xG2sz4E*zzRKkwo8MhWP7c?^LYUi=TgYVQz`jGlJrIt9XPLQUb*wuV$i5}?43q1t{iG|LzD z^jS!mY7@d}3e=ZO>QM$;^AMvW!i|d^OCi>)B_W*ExX_~`IZmv7aNN(z*@7lKnc?Io z^)@?#ttS@MU_5d!WU-543dvtG<#VzOgcup0UNLX6_#Du`Ex9s%IX1XyZt?0qw3=bb zBkqo68xbvZb(%>hp@Z@vf(+V}~?C6eeO`S|Kcee$TNB?B@>IqcRmA${7Z zj}rvcr3oBZaK?UOm}W{@(ERYk_8&BaD068Oa$~_kudkF@<5*hY_%8l?Vv@C80oN>) ztZ%^IaaB^u<~K3ARX8QDX^?!32_+(OC(!$?BJ?h_dSG@@nqxNXWrE*eqRN1qM~a}9 zEgL%-l?mq~qm%k)MK#*Okg_YE_w%fmyZ5IK>k1%Q;4HkkpM65JLj7uY)oH!{?MuqE zHR_z&WpnV?-qBK7Jo`W+-_wi|S%XiCER0OFS>uT7&}*MBzVN^CWzEwal?BR!wH_yp z-dRVw45D+vQ5!MSw4aqf#J+%M@G zp>B@I;M_Zk{S%rJC z6c2)kb(n>+sqc*+b!s+t{nT83ve04cbYh#CM$xHiNvNY@!Ig5TZUQ~hn3Dop0F*+o z=#xzx?+iZ)8-wIn7^!dtP)bm?DZ_wWKXWlwF*xFhuS3u_fs-Y1i+e~GNEK4)Wddl8_+rNaRJHtsRRua-2FAE~6 z_PaM+z#0~~_77_Q8TCz3I06Uyl}+|TNAY)URGs7Io1G5l41pW?l4H1Kw=wbdOZEUb ztUc*Y!3CVlmz0Z#;GqT_0WxW>3v&=gO()C_=SVsgXRwY0DcAQgB6HCOb-~s4rjD6= z^igMI-MHspJ;vAdi!Y=csy}K8xgOil+Y}-4Pdrc7@|N-3onE`shoccxFumqM)+3#| zn1Pfr%CLmz4!x8NgXknSz4(MybYkUjuY5IpuhkfjTU zlKlA?TF*|g;xr#tHM8tw_%_(TG!TOZtKQ4yekC9{A#%+Ew5@0#aXGi`Os1E?d?mpK zGU`ydI1210^7H& zq9qI-9lQ4yl>tY7nqP7dik_Op1A3KN&?&EBO(iCD4t}o=mlOLr`i+>PeVg8?XSKA3 z%05F4!{{#&Cko##YR}iA{vGH)2%-cNZf6?@dKr?|BmG+L4a+p)9J0_=akj{w*$&H4 zPuto#7T#U$*uNSuIC*s4Q4q#T%Y`FfktoFleXX@kZ~{@m@2FMHsfCH zrXCH2ab1@swPOwRsYH0vHBM}?+)fly+cV$Z+zFlc&MzuEd2HTN?>ER&`&~SYwX532 zG5=_P`b5fB#eFt{b>-~8arZ7wA664_9*H^)s*7Xk%x{F=lJhp|;V?iQ1rd=2N^T%2 zYr1$k#`JAtd4vak&SDCs*MWu4ofC*Og~4ZHz&|=Ye__|sn(`1G*`Wo2>NGif?(g1_ zWx%`W+y%#H@)n5<@LtE1Z-VL4%2tXT#;o?y5; zy<|aF`JXcr?xLH*=)zT5V4}HQH|=)`wVxMMbL1SOUWsuB4Qsz##Q8-(-*0T~DYAEU z22MJLOVNnxv?xGf{?c$4gTfn!&BLAheXUz`WZxksjgqt}rzjQP)_p)Dy(@64 z33p}re$9_$$!e)M8td3G!0xw~sGmby{tx&GkBCo~jlUwgc38E1l+p=A;L0*<83_@g znoW;_;4)JBSaKJC{rvr5?mqYr;gO|5bfr_J!Gfml)d|Z(EroX|d&gV(_XFv0k!O9? zUOO(mx?ufXW>oh7bTXg6SE&;4b$~MQ+Fi?_}3kfcg);A z$%+B}Jm-ro!Mx3M!rCEfh^mFut|<5X(^vi=hhbxzMLVz-(KBK$HX*9M-oV ztYx?rEn}p=^iX!fVlUZ_CnX|cc~*E8q1vwrY^L}<(WkcEX}WI3^GZ8%VY9F?aKIOA zitP1+vsoQ=oU6X4!Xk~^U&c?Ue#6t>-a@5441v*a=;W+JuK^qn>YHVQ?>BgUYFZ${ zd=r%=hFf78m*6PmY>Z2R3w$JQrDbt!gARM^WB%1i1p=)&ug%P2_;Jv;z>}5);xlG= zO;6T~`DHW-PmymKn(P^49{!@;1bk{La5NU(uXQ!vU0K=EXUHqg`4-;x7Xfp^$){{% zwO#Am&{r4z@qbYyfiv8L0U?j3DtBad6=@UIQ{?x?vAPHnmR!!1f);rwX7_5A0e_4Y zDUGp+hgd-xHO{D{M_ddbE|Vw((rN)Qp`z0CAY#|0IaQcUB?x>u6KtpLDC|KvdN+WA z3y%Y`cAjVXr7tEM2Vdp0Xp0V=Nf!#-^rB;Kht!9$${hvyC$xK)Aajw}&OiWZ0ewss z3)Nr$jbDwhb}g`-ZKiGCP)O0s4&!rXM42mt>N}>Lst>3;Q%Ko2V2=T}-*JE@pLQKb zUd5$=K*5Ep@s&?*eco%={Uq=3@RK%PQ}m$-PL^&7gk}WF*uxJ$jpegr;$VvYngrGh zFQ%QI4){1WQVL>x5K89Wh}#MrfZnb?gYvnn)*RWyoF*HcD^bapi7kS*;*5PrsV3Rs z<<=49zPx& zD_dsFMo+k?SpYW6Y;ljDD!+j5KDiB`u^WgpI+iTdKm)Mr9WzLyr0Q7b!?hzRhb<J5TigiP4zHU&h!V{hGmb8d!cj}NB{be|+lHUZ|{`!J5vj}Aq_sTtqXEp&vH=Q3b z;+-RrzklY*aWtu;GVqB8rND-G{y4UvfEoj8LajPtZgP%0G^M>_jpObCUXayUw6TM2`h3j66A!vk9mIB<_R- zoRuID$(hPudx6Z3Q3A1dylBDTia|Tk8g%8jf z=a<>`mfwU2_;4`&2?&H^76@m=rNTm7W)=lGiBB^ZT121d+;(+V$K!)O z_jx|eLFgAj3tcs2u!SzGD0{~eOn%u$@d`*y4#xuurt}d~)+3R|A>_RD7E{@FUc#%6 z-O_=&OG>t@_3WX0xYp$I!Q)^XBL2|B9_V)TnH6+JiEr)>ru&ad%*Hc)g>nOx%0`HM z;Ar&mfpzxWHY8XTrIwk0sZAbG?r6Z0?a#>3u1myigY zH1tXJ(Z2fs!@iNA;9$YyhJwre$I6Wtu3q$MD%(Ll8K~80b`dsuT?;-PT%LI!6lWWnIb*?Tf5UEmL&ox{lee2xK3K;qzrexAZte)v>Cg&0BvhxVrc z`WkF_ zrWlhs{&Ct-2P1)j2_qLX=5)umkq3!kU%u~Yb_8*TyAo=i%qapBikH^^F6JFpK;2wR zoBMOQ*&dQ@`_&(IPJI4ms<@S#V963!5Xi^Oi35q$x$DxG()M;8N<%2p%|AikV~XB) z!;~nsI*^#9Q%D}^YiAP=8X$;S9?1pJAEXGt)Rp%3!t(%nnJ#{hW%qHmo4x&>nY#q* zh-W4PMlHOC+Pjq2pP5_Hv+*%22QK-JD-qIcGs50NZuyQ)4`FGZZ38fQqOe1|!i<1# zhh>up?Bt6K2=uQYo}ARX2MAokpVDkfG#FbGX2$=l8i|%-(bR%!FEV*kTOSNR`Zu|z za$toOAdex3n;>^^u?cP6=KU{0dMtv-KTgVULsw@_k$a)=@gO%}(p~p>c@{Yr+_zs7 zEhmiO>(m33!v6?mMPa9M56UVF;R;)XrGlVwfY{(-C0Mwu%@QO6&bmI%f(drA^~PATrKjiw5rNKax~<(3~q z5_83w#Fj!fxf@gIqH>qmX6VK0j^p5rY?~&2I6P}kHyLz2Bn>d zQ5aVDNp+dAY;s8mmXs$=!494df?>dKxmA-EVL&#w;trxR+>u4k*c6Yc(B0YFB!eLR zlgk%R>wC80X`5x(qiCAJb;<+uKPOZn1NePIkh-E-j?XAgBHxgyMstZ61XwInq>;Cb zdjV?YYRA>tD$c)HNEC1^`?E!H3?C`hLy}0;fTL|Kk;vgHLqyIiT!dO8heO2|bty)p zt5SWrOczcV<5V?iBtqy^BI%6wh=f0gFVGp{DDi3Kpev+8SCB%c68SMD(_GOaPMnVG zVP#`8%HMtq*w6H!E6#fI#5L1bg^?ypYHjztfM=isATn4?(Ob#LJnR;~5l}oI7{Rc1 zyhRekkBpY6bz;^bg-@w>iK3oib&F#b0N6PtY!ZlwIxwk1E>al;zU}=5qELmHl`_Cz z<14dTWj})BiLDpD@uBvApsYxd_%Yp(CiM5_iI&}Os^i}(^cs_FwyV?U^M5GxIlVQX zTFG}x^BA!05((L@p4tRS5h^)R!(Mk5+pN-JGQveJ)>@iY++Cho|2o}jpKq0w8%}f= zp(YUPGk$`h-bYlIi-N6J>gSw-OWw6^eG12ljYW~q>2J6gneZW}cujl{8RiOtIgT3= zOD!>!Mvn6`olL8w^{Ky348xMrv4YM@r*T@PYrVB|Kty+w0dQbye{8l#iHr#RO+!bs zG=L=jVA%e=Rz1nK5xz{$WKfiK)}0|ED=K3bxybc{Uf!_C?oQ)ZSYeybqjtxI65Dg- z#%?5kYl4;j1vd+;$`JBi&=!wiy_FM1rC^xG0>%;o4#Gm3w;2Z2C^9?8x!H|V#6l{T z)I*mm-BB=6+9o8S3o4c(I5lHs5)VeJI@|}A`2gZ3I3M#|ZuI&!tS!>7thG5at1h+%q%H$ z87i~=;|;6GvC*4|C1Nrol1tJ**!%B?eqt^wWJ*QP01g-=x+V*K)fTB=WlZ=41WV0s zXg>FB8o06CGV|YS4sH=o{2bZ8@Y(HG)Q|6-6laD_2N5>H*nLMvp(6dF7pw#bj_u2J zftv2cCiE)^st}F>8d?n|Xouy5nZ>7&M4MvG;j)Q# zr;*Bc52W|Yd-2{oXp6<2;*ZZK8S_eWoF+dZ@jP3C1qzPUKnG~?95L7{z4qePM{LX{ zt|QBK{e>yp^UCQrU!gdI6B5nGSgdY!XBjYutpr_k@rS_Q0eySKP&tC1?R&}p6X-g+ zux|}l2K2W-mMjMe{ntO}Fl)X3I`w4Qo~?M>sGC6 z=N^o66F+-2qqhB(*0Vp_&hNfHrICVVU*Q=()H4W4A zSF=JzEYIJBDv)UIT$@K(@uzI-Nya?}3IF8rZK_J~T3C@o(;e%{suzFH z6taiaD$CR&p*Fo%x3zR!Oa{{T#}VPCt!CRL5!VLH47M+_7y}q9bKl5)*=q`;>TTHS zIR;5Pyd;dcCw%WZwr*x}x_K82Cq(bR!`afV*GVA{j9T~5IrIIthFSnjP1^q;0_#7! z650DLIKz`xN2qr4fecRjBBN(@mnT!$ZklIr{+v~bRx)ZQGR`e=XiuG^l@5+N5Ia5otIo6G(l&G< z%X#kB9>g_gbc{?}8WM)ucmdO7!`iXV%)C<32qDpbYL-fMnl?~vGmkzby9RHc1VvlS>LmU2B|BMOr3LC6$NmK~c zUMxfnUsT91dc=rxR4?EsEt7C*S)^~&vvme~)vTTL3=af3e|-PEIT$)-n;&pgE*JpA zD&Mweiwhudl9u%YAtA`83V z5key@@kBP%jC!``ghQ|_KN&0}S>%tKk-wYKPXUFC=wl%A1ObXhPK?EwSDtiV{wOXzF#P)d z)EiIFK111n8s2wVWGYe(o8z>GG*exLx(EXCcYYuRrD1?a#K108PwL!P!i%8~k5uh)d-$cDv!FWoJ^MTkFT7Kj#ql4J7+AP z_tDhXgo6+hOKV(UN1^qmkllin-%1pry7S3ZJE`!WFV890#8Y3+zf$ox^M;(?F*vHL z^_!Ix=YJ$dgId)cskUtI zyz5u#DUPSMY+I4q?eU82Z+PBI@`(9C{a{(-Eso+qq+s9~>wzKIJy1oBzcUxd;y+51 z{~seVk%fA@46iwtR{PaIhaiH~0JH#SmPQ`}fVzp3Q^MIza#5ijx1iPXs)0>@+vp4%^O550agZ000CLJI6OyY~8BQ5sIY4?U1gTD^fq;nkcmhj5+ zt!Cl<$0!BN*(B5hf6H_3!BI4qw#a=e>aUT8;-CgpZ6QRzqQhL2lJhn_4Lu$mF7_!} zh*}Lipyk2u;$d~kO$CT&^DZaNt)n|ONmy%sPF2rOe$ z_|jMR(`(fVx;5~URcoI(C&qX+SN38KOPPJ@BtVBqV#7|Pl;d1CTb3bskCA6#A zgwWy!p;Scm8=oPGSr9c8gfeZSY%r#$fx`I>YipdJtIkReno(k-*xOTaR7BF6t6D6W zb~1Gp!3m$q_C@vuZ}#_1Ojn(c2_EX>{3H8Hrz}U z+SEUk#}I-+?+utE%@7qB)jpT&p=vXXJ9LfwnqL6R0LYj6NNZ6YZc#86Ynxwz$`eTQ znVDYJVt;sa2Rro@rbtF^?tFP!#*u~s1 zdoNi`{V$N~?tbJuxK*sM7r6b6BdIqVBYQ}*Uy@29qx&Or7LS;J<2!f9Wu*T^lT}t^ zvkAyJ@}s0ZcV%Gw!->`TuIl@9j^oi!Z4Pnbs~fb5-PY>~SY^QCeHsVwryNU^0*J-| z$X^$%7q}<(6%U&N3}qF)juVs!o;mws_u3DOa`uSm=I-R%(#U~k4s`cxkpHQJV&)K6 zj%Wen+(nxGSE&bqgcY^TmC62qcr>X#NK>C;*bu(#rII zdlWhRO|SmR7rjrfXRY*yDQpm_Yf5`VDG_?OQa=t)peckTC@=tak5Y`pRszb>4bQ?_ z0iXyl_&8A(S5zU?dtU(zqO(jFuxePH|7V@rfvi^Pbqy<+me*B8*kB7Qjha9_NTchoz#qiEEUEd zCPk@&md1j?%*u&^r@v%vNJ1TF@+-xqM^ctZeChdcf)iW<(bQ z7;wa{wmz6b(+7D)sE;i1QsavFS+wU&pEjeN-bUoXWGztIk~542x& zqY0ih?l|VC;UnnLU?VWnYD^)xoVV|Fqxqv!sjG&zbUa~*UH{E7TewPMnf!$xz@=Tn zj6^-F)0Selg8#5DevRHh_7@Pkb!6=j^m)e90g9qj7JfUHcdROtZ`c`s@n&za!zAhX z2%%w6m-qkjC^%ka1=k4Np;Fa{qJr5+s-b2|bEplY3%3;)YP5*2%roY!G(>c;}f>qE= zUG*1~qkh}1SX?`049!?{N}#&|5ZJNGJ9kc*LmYSi*=gbJR&3(!SjcI@oLwsZff70= z?u!s>N+%WQK}>}+LT=R;L~0YGYf4oSH|jxn4rsE3tcbZI!FIv_cePvfbr)eYr-sOu zYblh^s#yc{mq!_`^YwmXB1`x!*8layipx$<%zr`j<&?~$-l~==%2Z0OZKUj5S{+LZ zhCKUAMDf*ZaVCTVQ8AS;w~;|5Fk+kg;!6ltcR`#_ksV15OoVdl<|F%Vhu_0}Kzgj) z5OjCynX)mZp-iRl6K9snAx0*Y@$$-JOvBFqD}iwGldAm+D$+{6Bg$EGBB(@hW48Vy zp^I5EOeIss5Jheo2D#Xj{@}bHD_qlHAwXK^U=#6vo%Us^>ALE5X=sgk$xEW$^Pb>w z)k=Ke^zX*_Li-ypfRw}J&ngE@)CY2^kb+r?B-dsXOgQ%W90@$d|MC&Ku}*j-W)`7z zEGYmMoVJEWk)7g-lFe0!B=ICr_*a1`o*C-^5FRMmSKB&z)!ugEXH9+U+Ud}CgbE#&r-%vfS|*!1W&`-y@c_GIEJ7f-cCmB#AxEuQbEHbWq)KEldo0De*v=Q^G5`}tbB{1A`G}I z&+nf|xXYQKTfoInN+tHM`LEH~UJMD$pk04Rtf~IZNJlUG%XU3uB&>40i!$H8dSUmA zDe+edeV2d7Y7T+K0LcS^caHEASO(LN9(|lJPHHTl*~7467uS)26BX*kN03_W z^>9m|6a`rbrw4&s!?8C*2?_>-6_T3yW5esByaiG?(#U5RG)PyVK{NN~JbEyW-Ql88(oWJ6+{+BKjG(-#^aJD!Yf?z*x(dMQS zsYr62=3~nVL1h?q6aa97NirGb(R99X5krH4y(}s;lSM`nrfWEw;57XDu)NSd)TAni z*Q=%-O>K6T1VWedWqX=4g4NPsg5ls^g$HzD+3FguE6>E*q%)qWBxq<43%Cq5mDQYO?sCK~F6Q|NlWuR4)T=g_~^fSnJjw?aLI3XX>QnlStH)|v{cI2Z4=&f{w5P4X$_Q-;PiSAZ;pCCGN*aapF(7Wb9SZe*@VZdQ%>7@2Fz*Fp z2!mR+iC|31Dw^Bo;W4kbSQEM|r$j%VZD3~qed2tEAdi6ntMXw)bydX{(Q$DGzlybp z_b9#skb81#{cD21LwL*9zXM|P_`cMVL!fZR6}xl3|M*$!-rOB0s7soyE(j@D@SuZo z{RY(Jd7%oC;|%W%@?3oH%AiO1AT=2rgmlT2VI93GLyMHs*SnULby!6)LCw>$@?~i} zntP>w<2jUn9(*6>}N)h6@e7oc%AQ;C+ev!h!te|g0$PIy0 z;s5>Vx_s5a>ifTu>K!8UuguWG7&|>kzFeUihT}>78pzGMbp6M9yE$jCgjP<=~s;;D1d*!wUXkVoq!lpGIKoSOFh5qBM=R zhw+mnCM%vOHO;UpaD4oLfmte3T+KBFh)5vHbxnztx2&|RWk)J1g__g2&B0L=ety&Cb3!(yTOXmajY5TiQNnyUTiwj>K~p>MCSB<{ z8XcvEabPf;IoFES`5RFrWKdSlL#!|KXJLp-zgM6c{9-ox*PZA(3|!gsV{m7zQDKvN>J&spl=S#IXj^O zeY84TMq13y&iBum{CvazueYy?ilb}V9bh0>aMwYC1{f?19^Bnsl0bmq!C`QBhhQN< zu;3cp-Q5}7EkJNM^M3N5bNAn!TD|&euin+QYfE=kJ&!XnBm=2bR|r)_diq97boT5{ zma%JpiO7${)R=m6kj~87DJ;wsfhf`7(rGUz%E!LY_+j7qsm{hx3s;XHB1BKi)LVS$ zS^HP|^b#p5Y=C(s%2OKwi*s)qLPIV)e@@}uBV zeW8{0l51z3jfpzGrsVcpB1x>P)dZ67)jD_2H*0-=07W3yRjSA^#k6u*GYh4*cjhl1 zHYrK%l9Eb8_ViI}yOl;URa^*;-?toE+Kl{Hvz-XA9`M#S#82i%C(%QJnf4E+qMZ+| zQL9@rGTlMx%w;JF_drAxqF(VLO?B+l#T`w$+=V}@jxjAtk-U28Qs*@X6e|G%1}}F>qCV#| zzR&yiEiW4~k6T*?m^}IXRygm%O-jSQbb3GIDXmVpGOo1wWUN2^y&3sdIx~wy~bdS`%dh>2E^YZbRNhm~c%kxX4Mb3qfImHoQ_WJGX^Pj!n zkzga2HQs5a6jYy%nGY?+(%|~H?q6@I*>-(T*YUoNwlQpfmgw@DtHt_fr6qJ-5ww4S zc_yRKlj~LM0p#YdH4Ac8_nWhG$(gjG(?eyT|n(wlWP|3=&S2r@ksO#-)V;XL_)Ko&HF@{sBmg&%`t!U}hbg#ePRI z)+PuB>Qo^kpAmBdMI%YX0(m(b&dN%h$JT7*-nle4zN6#`bF~{o!Z_6IY&Kqd-76Bg zRQN90ib>PiJPZ}3`tm*NhNz6}YJdR$EP9@xFZ7b5?*tiz|mdE1jQhpdKt^m|kLrrONNTi_mtnsbJW03yC#q0+57;h86{&&`1|} z_SS8hHxjHcNP^giFpmgX#1;K#9fE*1fr&T-{Y9t0LSMszNMt$H%V3+$T+4@Sq;oa_ zpN|B;e0%qaEUW}(iq&lq2+1!BBI!gAqtgW1+|!EBKicA`sjJVOdA?4z(#J)7-`iTf z_zOVSCmV%;C>tlZvkMcq^F-3)=DbnNc+E_Is42&p3j~^x$Y=&HNSVV?Bi_HB5o0|? z2H*E4HM@_|Hha+d@}TE+bdR(|ir?b9_&ruH2J(`X`jX za+pJ&cE@hae(Ve>J_p62I7uL(spq7-J0-mcM9UO|bc)Cx#ss=4@$lm1=61dpJ8ddQ z=PdvI{|p3QW(wbc$PkcaI5jf;4EluqEr)<) z+;;f0iQjHD{PCxGk1doLndcKY*Rw|`@M{pX6GE8(>D3Peon9lb#-Ss0 zO^rb|w|`WY+3pEV8xA)$u-)?g4kOn}4rk%Mbj~arjL0x*GCbabr_RtvCBw`+`6n?u zDHZdRI4urk{ayN`XLCP)JAeC&2NVY!sve|H5I^HdI>w{iC|JuXw%r3gx7#h79T^!3 z4Z+^^+iDY)@^QFSS<7%%>2c=>F;h~;;Cai50f68y;Lb`*B8qh@D+ed`>vMg-t&a^y zMB%ExF&~POkm58)b?3#ASOGYwtzn}?CnXo7&f-_JxhCsCpB38f>nhHBIfTd8*X~(G zpC?t^H>YIo`sUk5jMaZg_QVR4O;|t2!;xQ^yG9XKiP9#D0?+TGGYs4Q;Bk202pYO? zB1EBaAiT|+qq~BoGet;uKf;48+Srb6mDxpmI4PiTGm`zAq%JsrP!z8P-7LOHmW}?v zLdmjopXZEms(?AWX=IskXaqQ>;UM+HQ7OU-kOQ|NXukZQ_>)7y8D7Df^p&6W%V7mw zSi{*ZG&jvQ4h+LgvoA_vh9VT&LwN}3YsZ)BwEFkYm#$RLaD&Z+^6$1N%}F>bbhW;< zGY8%jo!Ajw5bh%+(~;H7Fj{gRsUmhaGH}#h&q6jaM{TaLsKjBZ#n zcHFwo@P7QDa(Oo{EE5+l!yz&P4>_UPtv2;uAKAmE>Ymv{G;lBO#Pqni3yGFziO_6B zo*uak+q~2JUk2BHA4$KKG`qbyF0TZ@BK%F4>bso8qN6LGT7 zpVu9 zWAzKiwLE$snnO3penF|bbZuxRVEaA)qP(AH_W;80+HmGha%-?r0@>(W$+kNA7bK@%IH zvcy8%v)Ei-Mvy+)lr&)7a^b1#;=GgFd;LY)#*o8AD3o|S$5dTq0w4n~L(s#?p|n0s z;QG$bFV-79p5uD4@g#$Z!socL>A`aaD8{*pWwBpx$-_t>&p3j(xuW}vG6akw6h(&>hTU+ri@=){DX?C-_8# zfBW<)xQEeapgIwhBF(SmGt)4o6Qkuw3zlSgH8d@rx`h6-G2Z&BE$$G~0SaPrDTXGu zO%c2NI^_K9B%5Pd;EU*Z5Sl_LqT|ins;$@;&a5kC;(=8x60B`aZ!G_;RhP`4UvWr% zQ2O*RxJKG6t1fBwcw>BX?8y`wALd2N!1BxM#|C<#`R0q6`On|}#AuAxrXUn^Q+kq& z-%RlI*3|C)AGC3 zr@Q!S?hca531$|5IDd?ul_CF7?PT*aJ_Xy6A8Tvz2!^GFCC7lIdCHS%wcZN&-?O{<)oU-u3hwtY>ubjv|F`Ru~XUIk~Udgiv8EQbkr zuMt-Hp@I-0vZ1nmK_qcW;Hdy+j{CvL?_p!@*-|^U5-XsM2~!yNcg9(rhK=9HR7X46 z0Af{4!7*x|MF~&(JSWuJd@3b*UsIluU1wI@hR)5h5y6vJ^w;JvQ;0j@Cy25!z`{h{ z)AraJ`dwzrRgbkUx?jx(W1Ra|0&~ksiaGj#LQL$s5JW-(q=0?pTCFwpF4>CYJrgjPh*0Pv>RV z5}>Pj2(rw|Z4Ev_2wE|jo_4ag+=o2lyrq%f{IL2+ktnI2E&9;1^*BT^eWN;BvD*-F zN6K&wlP*v%{)MOD;J5YizB6&DNXh|0|GmLIcq36obZfO?eeZd?&||Oc@{4Fy@5Tu^ zPZozWjIkH~H=uC+*6ECvL*xa~vYrZXgmVT^4IPbUFb=cd zJ6?3hdPrtn=Q^U)DsZE_X=ku^DX1Q6#EXZr3;s2&DzuHl4S6V7(dLV*dLnhic@K_5 z-c1x|d=MxvXDwhPzp?x#L^Liomx=33$4_8ReUh|8_ zI6hT%T6d=X8rtBBQ;f;3?OZ#iIfZg3Hkr2Z`1k>Gwg}W;QYwa8Fd~|W87&DNd9zob z&N_HWd^Wb-aUTZi4tz-WzRX@s_xMtET=>a(3^v2F&b|CON-tm|MFv#qjT%x-Oz$#r zI^z+IZY=Y|{G8VKyeT9h?ORT-4Ovr2er<_vYSHLU{{8h+qi8-&nMh|w?Wj$TRjP1! zLW*+2$!O_##z|_(!MiyH?(QVEZ~XPviW#tPb)V)flO@;frwpf6IwsiLN1m@EE(6pC z2FEi5^b|Ga{@M?4Y&U$nv|-NYWgp{?YR5$dK4W`c1vp?E!E|YV-UVVnazE6LmFjSi zkduG->>gKRsZwpmHp9xD6#XNTx3;{8bLNN>&FCukfD7Zz58Yc{V$N%iZ;aSETwGjT z9dm4cTqebr7sHqpjG`B2*5CAbe;OXs#eBe`7U|kmLVB)XsVhO!3#9dcvn8K)lc55? z2Lq7psiw5AU1K~i=S#zD3HMLSizk2Go&3pJI4Wv;yq4>Cjs41Gw4J(2O}QPK&>8$F z4y9>-55htHxSwu6mTZzMqsM-z*5jYsYS`lNjk{2}(j%{P|1I*xbh=rYRF8R?`*f@; zI{!!MXE(fDlo`?_kv3?l!^4=c>+#x{|AtseByZceraO;F=V&uF#CJzvk0aLUt$VFz&->IYja1*@ds4l5 zXFzm;Zr#gWWZBd=*{iaAb~&pZahgJ`uV&Z3L=VI(+`s0FpP)5-;GaH^91 z+PW)1H$+0P2K&tTOrJrJJ3UHCZBo|l!8?KROmI+n4qgy$@$$DOJK14%3YllVpm7tD zK9QJ$vF$`E3H$)W)%g8l*>dCjlClV_a8j;WMyWNMiFy0dnNq=#y z7g{^gRWC?VmuH6GMv5Y+dn)`sn7>wT^uvFCBkl)`>Co$8=t*$y-#lvTEC6~q5Pa5*f*Csl3 zp_+yW2>rg$h%k4FearD!K16MRBZOllh=idq zX=yJSD1%bf=kU0(UVXeobzct+ATKu(-wvKGG+|`YV@lPlElOR>R@PqiMhZm<_4sto zWZ%X)IJv>y;{G|#j0F9WcK0=ckU%RwPW&^bJTl@b!NUJew!* zA^n9p&=JKD6;7`m%oFLj8<026?vy1F1%~hhxnLa$NpMhi7xEIIgPk7fKUpsR_F{}y z;=Q`6uQ?gc*-^+@9Vufa#$S?aVT1kZT|Ov~2>m#8_4f4R(+QvR4e{ybJ)uI?+Elx} zXyP7z2zHM77akS$D2T`(lsh>HpBcXp52DBfDaF5r8-6RvMxl7AWh+!4Sqp_pbbwQv zVV;~f>%OAhp`o~lZ7)v`=|VcN?Lm#lZ5eDomtSoMKDBN<)2bPrgy{4d9tq;{Jj`2$ z5pIY)XC#hTeCK!&j_| zUpMg3Luzp`B4DjqJ{ zYcHq4`GYhR6f}_7l^PFx&I(#>MVfQg#{;oN`i2OH8?RFcYwPCB=<{LfT}(2A0WL94 zhoscP<5lr=6hb^bznwkiDhwpfW`)0gt)E!XRlz|w7oyCv1)>B@Oz>A^LGZaGBrn3o-dct+?24w6Do0~Jt6Uq5T%hw{ICNMxdLuhd0(ohfG9~-cLs+Z@?%HVI-7HCI6YT zCDvLp9gfU@P=c(8(_1$kd!V z;B#6I%;Q2HYa{SolRyH=}hMkJ3exc}-9{<;;WRigtD35QR3%ryY9UbKo z;)ZAOz5!Z7RR>;d0}L~fklq-W52vU&Z4cQSR?gVG9GOudrKsp8W%( zVq&=NcS%Fw@J78uT3^R~u?t$Z?u@(^L@V350`n^D>5Ozn>DY*i2K(~o5(FZhv2ba0 zQgh?n!rcEKPns>Eho$Ylt|_UQ?(k9}kfJZZL-gw|j9F^JjNuyd=<(7wAX}_<;VvA@ zENE>_#;5D&e;mT0)_p*D_vIGn>B)=K_lV62p5eb*pAvG8z%^RkqI17)G?JIt zODRl*fE(4nDXQNKinGU8u9=~?-PBc=zlFanJ^C8XHv1K3FO8j1-M?-Xj%<859iOZ- zr3&Q0zDV`=xiaLCee4^g^32--osG8TWSv%ILLu^G8;kZj3BWV;+-(5~FV?LSAoI>wVb}vc0}W z<>KoOj zlHcyQBj`blnIW_)D&1MRUH|+A7iZX};whO<#-u=3NS=j;I|{8hDKyoX1mqG!3V(xy zK@DX*>mwUdO3J*dVj>~GK=kevRubSA!dqm)&Tj_Vj$dyHR7CH1vM~6x=Y~IW5kyKw z1P4(Hx`Hp}n2zRs;$p@aGFjtzX>uVHaX;Wy7610bVz(j9-k?YYsBhQyL}hF%;MAO^ zPYR#$%pw3WkPwLhlpH7j8-TzSjw9fp3+S3KwH41qyI}Ay8qmyrU;mRdBP3s>1A}mr z24rqQdEwklg^5M?$pKA`VzagP?&BE2Qu_Ruo!5nPK$a$EaV*63Sm~erM6dZ&dza&Q zT`8d&Vwb^ep;~idT92)2y!lrs=W5Y?;`E$YxD${=q?AhRsL?Z8> z3qAM&|6198v)*|T;}J*_D&{bT7m9G#wY|RB97xO@!xXc%e$({RO`0>KaT|mi7`F|h z$rk?sr%}U8czFk-hN)e^#IQHTIDRm4u#A*XUqj8SzD$OBsm6)4U_Ta-{%k5Hy`PHZ zGm0wZ4fH2y{0_qGe*hP4X7X^h>4VefOYW?N!m|4f<-y&P2 zqX|tGfVSjk8A*VDx){D60xST$w6OlFxvAHC`+;@+{K$U(x7Q67pYQrB!b8p9&U;kE z?Q47E-Q-{9Vz@W3(BJDr(IWpdALNG{9-~=^d>=Kxr~5keU1gQCI+IZUW7U&@w+Jg=h2 zf~%ddu%w?KZaB(~n#E_>GKBL$hB2Y|eNmC=O^*to|5$n|mELlUp9VN24(b)~W)&RiNz#beHnLUQJx(Y8* zrqHUZ5$(4YDAZv1L1(iQ84LTxw8Vf)sAW8{F!s0OC2_fN>qsLR>58L2eLiI;dqbeo zKgU|QYhEqVw_0ovnZUq{&iH8%Lh0efAH7!m{C&mRX)WMI*-!aRH+C2u+qwjb!5!%% z{On+U&Ad_KVAI$74ZqoQdVwfxJ}1g~hy zaw=X1cD*~rqq=|QOfyu%F;|Iew`-)~=hA_$sDVP}i0=q6_jYy2oH;qs3H?y!w0QmBR)%svSWCyHu|a zt|4lZnm1yq-PId!}Nxyhfr( zaRxcr+^1BZT+>L6fEo!ryFd5_VVeC)5pl|~E}Bo_VPM(7%8ufP3jy2!-2T6fs7PVY zZH`gmvB;4hmC;J^SzG_4q^I>)-FX#02$zc=M5E0F!fTuV5hB@Frn>0q;d;5`ud}f^ zjJy@QzqLmWHB@+=y&L-_iny@8ZfWa78KqGLMEx#LQH0p><0c~kpzQM#%BbSuABF7O zcM${tozs0dH?GlA>7Z}|NIq!jhW$%qBe9xe_61f#CBtuc%J1|;qTTF8!4xM{RIYH+ zSp=-BVToTGYj{>QBS0Lg5%Uqm$>D>demKy}Kk{f4*cs+Xd|Px}-sW-X-^c5V9BOOV zcQuzq%vxGH{u5VnCggiQ$LN#$@;}fN|B@m$@`US4%k-YBUI*uzyXmFf3K(EviJ4>C zTkuDU+05HPkn-S&1@q;C+-38vcuUUM^(*C)md66;XG1~TARI*wkutr}^FPA`nfW{-t%Fe58?ydHy zTRMLf?;J6_$wfOgc6h&J5pk{_)(;jrv?It`yU_BD8~=;tG84S!*A|Fn8P k@iM;#{$Jbwe{DbkY-{&(woHIM{L`(Rl(J;GxM{%u0a}9kZU6uP diff --git a/kakarot-ssj/tsconfig.json b/kakarot-ssj/tsconfig.json index e9aac3373..7556e1d4b 100644 --- a/kakarot-ssj/tsconfig.json +++ b/kakarot-ssj/tsconfig.json @@ -16,7 +16,7 @@ "forceConsistentCasingInFileNames": true, "allowJs": true, "types": [ - "bun-types", // add Bun global - ], - }, + "bun-types" // add Bun global + ] + } } diff --git a/kakarot0/docs/CODE_OF_CONDUCT.md b/kakarot0/docs/CODE_OF_CONDUCT.md index 6e5e83668..e9d212b08 100644 --- a/kakarot0/docs/CODE_OF_CONDUCT.md +++ b/kakarot0/docs/CODE_OF_CONDUCT.md @@ -6,7 +6,7 @@ In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to make participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and -expression, level of experience, education, socio-economic status, nationality, +expression, level of experience, education, socioeconomic status, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards diff --git a/kakarot0/docs/img/codespaces.png b/kakarot0/docs/img/codespaces.png index ea9e1e06bfdf243e9300eaad544c94e9d7c4a85e..19bef80404b716c545ba60ee8531ce72a5a7716a 100644 GIT binary patch delta 20573 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 Tk674KafQZMAEnoTaK!!xFzn+- From 19664045dc5a7d0ff18e87434c99b68956aaebc8 Mon Sep 17 00:00:00 2001 From: Oba Date: Tue, 1 Oct 2024 12:17:26 +0200 Subject: [PATCH 06/56] ci: fix path ssj --- .github/workflows/kakarot-ssj/ef-tests.yml | 8 ++++---- .github/workflows/kakarot0/ci.yml | 2 +- Makefile | 6 ++++-- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/.github/workflows/kakarot-ssj/ef-tests.yml b/.github/workflows/kakarot-ssj/ef-tests.yml index 5957d20fc..10e358657 100644 --- a/.github/workflows/kakarot-ssj/ef-tests.yml +++ b/.github/workflows/kakarot-ssj/ef-tests.yml @@ -26,21 +26,21 @@ jobs: ~/.cargo/registry/index/ ~/.cargo/registry/cache/ ~/.cargo/git/db/ - target/ + kakarot-ssj/target/ ./libcairo_native_runtime.a key: ${{ runner.os }}-cairo-native-${{ hashFiles('**/Cargo.lock', 'scripts/setup_cairo_native.sh') }} - name: Make setup script executable - run: chmod +x ./scripts/setup_cairo_native.sh + run: chmod +x ./kakarot-ssj/scripts/setup_cairo_native.sh - name: Setup Cairo Native run: | if [[ "${{ steps.cache-cairo-native.outputs.cache-hit }}" == 'true' ]]; then - sudo ./scripts/setup_cairo_native.sh -s + sudo ./kakarot-ssj/scripts/setup_cairo_native.sh -s else - sudo ./scripts/setup_cairo_native.sh + sudo ./kakarot-ssj/scripts/setup_cairo_native.sh fi - name: Set Environment Variables diff --git a/.github/workflows/kakarot0/ci.yml b/.github/workflows/kakarot0/ci.yml index 0209316b4..eca4cfb6d 100644 --- a/.github/workflows/kakarot0/ci.yml +++ b/.github/workflows/kakarot0/ci.yml @@ -32,7 +32,7 @@ jobs: with: filters: | src: - - 'src/**' + - 'kakarot0/src/**' kakarot_scripts: - 'kakarot_scripts/**' solidity: diff --git a/Makefile b/Makefile index 9f91533b6..437ba395a 100644 --- a/Makefile +++ b/Makefile @@ -11,11 +11,13 @@ KATANA_VERSION = v1.0.0-alpha.14 BUILD_DIR = build SSJ_DIR = $(BUILD_DIR)/ssj - build-ssj: @echo "Building Kakarot SSJ" @mkdir -p $(SSJ_DIR) - @cd kakarot-ssj && scarb build && cp -r target/dev/contracts* ../$(SSJ_DIR) + @cd kakarot-ssj && scarb build -p contracts && find target/dev -type f -name '*contracts*' | grep -vE 'test|mock|Mock' | xargs -I {} cp {} ../$(SSJ_DIR) + +test-unit-ssj: + @cd kakarot-ssj && scarb test build: build-ssj uv run compile From 4d8450d6385cbb26fce16847ae664770b13245f6 Mon Sep 17 00:00:00 2001 From: Oba Date: Tue, 1 Oct 2024 14:51:13 +0200 Subject: [PATCH 07/56] ci: trigger respective workflow on filtered paths --- .github/workflows/kakarot-ssj/ci.yml | 2 ++ .github/workflows/kakarot-ssj/test.yml | 5 ++++- .github/workflows/kakarot0/ci.yml | 4 +++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/kakarot-ssj/ci.yml b/.github/workflows/kakarot-ssj/ci.yml index 9dc03d85a..fb108566c 100644 --- a/.github/workflows/kakarot-ssj/ci.yml +++ b/.github/workflows/kakarot-ssj/ci.yml @@ -4,6 +4,8 @@ on: push: branches: - main + paths: + - kakarot-ssj/** env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/kakarot-ssj/test.yml b/.github/workflows/kakarot-ssj/test.yml index 4fc91e845..5b90825fc 100644 --- a/.github/workflows/kakarot-ssj/test.yml +++ b/.github/workflows/kakarot-ssj/test.yml @@ -2,7 +2,10 @@ name: CI permissions: read-all -on: [pull_request] +on: + pull_request: + paths: + - kakarot-ssj/** concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/.github/workflows/kakarot0/ci.yml b/.github/workflows/kakarot0/ci.yml index eca4cfb6d..dad799561 100644 --- a/.github/workflows/kakarot0/ci.yml +++ b/.github/workflows/kakarot0/ci.yml @@ -4,7 +4,9 @@ on: push: branches: - main - pull_request: {} + pull_request: + paths: + - kakarot0/** env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 19cd3735e153e0e89081c7f3e8aed931f44a26da Mon Sep 17 00:00:00 2001 From: Oba Date: Tue, 1 Oct 2024 15:15:13 +0200 Subject: [PATCH 08/56] ci: move files to workflows folder --- .github/workflows/{kakarot0/ci.yml => kakarot0-ci.yml} | 0 .../nightly-fuzzing.yml => kakarot0-nightly-fuzzing.yml} | 0 .../{kakarot0/release.yml => kakarot0-release.yml} | 0 .../trunk-check.yaml => kakarot0-trunk-check.yaml} | 0 .../{kakarot0/update-rpc.yml => kakarot0-update-rpc.yml} | 0 .github/workflows/{kakarot-ssj/build.yml => ssj-build.yml} | 0 .github/workflows/{kakarot-ssj/ci.yml => ssj-ci.yml} | 6 +++--- .../{kakarot-ssj/ef-tests.yml => ssj-ef-tests.yml} | 0 .../workflows/{kakarot-ssj/release.yml => ssj-release.yml} | 0 .github/workflows/{kakarot-ssj/test.yml => ssj-test.yml} | 6 +++--- .../{kakarot-ssj/tests-unit.yml => ssj-tests-unit.yml} | 0 .../{kakarot-ssj/trunk-check.yaml => ssj-trunk-check.yaml} | 0 12 files changed, 6 insertions(+), 6 deletions(-) rename .github/workflows/{kakarot0/ci.yml => kakarot0-ci.yml} (100%) rename .github/workflows/{kakarot0/nightly-fuzzing.yml => kakarot0-nightly-fuzzing.yml} (100%) rename .github/workflows/{kakarot0/release.yml => kakarot0-release.yml} (100%) rename .github/workflows/{kakarot0/trunk-check.yaml => kakarot0-trunk-check.yaml} (100%) rename .github/workflows/{kakarot0/update-rpc.yml => kakarot0-update-rpc.yml} (100%) rename .github/workflows/{kakarot-ssj/build.yml => ssj-build.yml} (100%) rename .github/workflows/{kakarot-ssj/ci.yml => ssj-ci.yml} (92%) rename .github/workflows/{kakarot-ssj/ef-tests.yml => ssj-ef-tests.yml} (100%) rename .github/workflows/{kakarot-ssj/release.yml => ssj-release.yml} (100%) rename .github/workflows/{kakarot-ssj/test.yml => ssj-test.yml} (69%) rename .github/workflows/{kakarot-ssj/tests-unit.yml => ssj-tests-unit.yml} (100%) rename .github/workflows/{kakarot-ssj/trunk-check.yaml => ssj-trunk-check.yaml} (100%) diff --git a/.github/workflows/kakarot0/ci.yml b/.github/workflows/kakarot0-ci.yml similarity index 100% rename from .github/workflows/kakarot0/ci.yml rename to .github/workflows/kakarot0-ci.yml diff --git a/.github/workflows/kakarot0/nightly-fuzzing.yml b/.github/workflows/kakarot0-nightly-fuzzing.yml similarity index 100% rename from .github/workflows/kakarot0/nightly-fuzzing.yml rename to .github/workflows/kakarot0-nightly-fuzzing.yml diff --git a/.github/workflows/kakarot0/release.yml b/.github/workflows/kakarot0-release.yml similarity index 100% rename from .github/workflows/kakarot0/release.yml rename to .github/workflows/kakarot0-release.yml diff --git a/.github/workflows/kakarot0/trunk-check.yaml b/.github/workflows/kakarot0-trunk-check.yaml similarity index 100% rename from .github/workflows/kakarot0/trunk-check.yaml rename to .github/workflows/kakarot0-trunk-check.yaml diff --git a/.github/workflows/kakarot0/update-rpc.yml b/.github/workflows/kakarot0-update-rpc.yml similarity index 100% rename from .github/workflows/kakarot0/update-rpc.yml rename to .github/workflows/kakarot0-update-rpc.yml diff --git a/.github/workflows/kakarot-ssj/build.yml b/.github/workflows/ssj-build.yml similarity index 100% rename from .github/workflows/kakarot-ssj/build.yml rename to .github/workflows/ssj-build.yml diff --git a/.github/workflows/kakarot-ssj/ci.yml b/.github/workflows/ssj-ci.yml similarity index 92% rename from .github/workflows/kakarot-ssj/ci.yml rename to .github/workflows/ssj-ci.yml index fb108566c..f9f7737be 100644 --- a/.github/workflows/kakarot-ssj/ci.yml +++ b/.github/workflows/ssj-ci.yml @@ -18,17 +18,17 @@ permissions: read-all jobs: build: - uses: ./.github/workflows/kakarot-ssj/build.yml + uses: ./.github/workflows/ssj-build.yml with: artifact-name: kakarot-ssj-build tests-unit: - uses: ./.github/workflows/kakarot-ssj/tests-unit.yml + uses: ./.github/workflows/ssj-tests-unit.yml with: run-fmt-check: false ef-tests: - uses: ./.github/workflows/kakarot-ssj/ef-tests.yml + uses: ./.github/workflows/ssj-ef-tests.yml needs: [build] with: artifact-name: kakarot-ssj-build diff --git a/.github/workflows/kakarot-ssj/ef-tests.yml b/.github/workflows/ssj-ef-tests.yml similarity index 100% rename from .github/workflows/kakarot-ssj/ef-tests.yml rename to .github/workflows/ssj-ef-tests.yml diff --git a/.github/workflows/kakarot-ssj/release.yml b/.github/workflows/ssj-release.yml similarity index 100% rename from .github/workflows/kakarot-ssj/release.yml rename to .github/workflows/ssj-release.yml diff --git a/.github/workflows/kakarot-ssj/test.yml b/.github/workflows/ssj-test.yml similarity index 69% rename from .github/workflows/kakarot-ssj/test.yml rename to .github/workflows/ssj-test.yml index 5b90825fc..513c5742b 100644 --- a/.github/workflows/kakarot-ssj/test.yml +++ b/.github/workflows/ssj-test.yml @@ -13,17 +13,17 @@ concurrency: jobs: build: - uses: ./.github/workflows/kakarot-ssj/build.yml + uses: ./.github/workflows/ssj-build.yml with: artifact-name: kakarot-ssj-build tests-unit: - uses: ./.github/workflows/kakarot-ssj/tests-unit.yml + uses: ./.github/workflows/ssj-tests-unit.yml with: run-fmt-check: true ef-tests: - uses: ./.github/workflows/kakarot-ssj/ef-tests.yml + uses: ./.github/workflows/ssj-ef-tests.yml needs: [build] with: artifact-name: kakarot-ssj-build diff --git a/.github/workflows/kakarot-ssj/tests-unit.yml b/.github/workflows/ssj-tests-unit.yml similarity index 100% rename from .github/workflows/kakarot-ssj/tests-unit.yml rename to .github/workflows/ssj-tests-unit.yml diff --git a/.github/workflows/kakarot-ssj/trunk-check.yaml b/.github/workflows/ssj-trunk-check.yaml similarity index 100% rename from .github/workflows/kakarot-ssj/trunk-check.yaml rename to .github/workflows/ssj-trunk-check.yaml From 06700f6b85699428cbd90cdb8605a10e86dca971 Mon Sep 17 00:00:00 2001 From: Oba Date: Tue, 1 Oct 2024 15:28:16 +0200 Subject: [PATCH 09/56] ci: rename ssj github jobs --- .github/workflows/ssj-build.yml | 2 +- .github/workflows/ssj-ci.yml | 12 ++++++------ .github/workflows/ssj-test.yml | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ssj-build.yml b/.github/workflows/ssj-build.yml index 7cca4d20d..9a6ee0a6a 100644 --- a/.github/workflows/ssj-build.yml +++ b/.github/workflows/ssj-build.yml @@ -10,7 +10,7 @@ on: permissions: read-all jobs: - build: + ssj-build: runs-on: ubuntu-latest env: CI_COMMIT_MESSAGE: CI Formatting Auto Commit diff --git a/.github/workflows/ssj-ci.yml b/.github/workflows/ssj-ci.yml index f9f7737be..aeb1927c7 100644 --- a/.github/workflows/ssj-ci.yml +++ b/.github/workflows/ssj-ci.yml @@ -17,25 +17,25 @@ concurrency: permissions: read-all jobs: - build: + ssj-build: uses: ./.github/workflows/ssj-build.yml with: artifact-name: kakarot-ssj-build - tests-unit: + ssj-tests-unit: uses: ./.github/workflows/ssj-tests-unit.yml with: run-fmt-check: false - ef-tests: + ssj-ef-tests: uses: ./.github/workflows/ssj-ef-tests.yml - needs: [build] + needs: [ssj-build] with: artifact-name: kakarot-ssj-build - resources: + ssj-resources: runs-on: ubuntu-latest - needs: [ef-tests] + needs: [ssj-ef-tests] steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/ssj-test.yml b/.github/workflows/ssj-test.yml index 513c5742b..3b2382068 100644 --- a/.github/workflows/ssj-test.yml +++ b/.github/workflows/ssj-test.yml @@ -12,18 +12,18 @@ concurrency: cancel-in-progress: true jobs: - build: + ssj-build: uses: ./.github/workflows/ssj-build.yml with: artifact-name: kakarot-ssj-build - tests-unit: + ssj-tests-unit: uses: ./.github/workflows/ssj-tests-unit.yml with: run-fmt-check: true - ef-tests: + ssj-ef-tests: uses: ./.github/workflows/ssj-ef-tests.yml - needs: [build] + needs: [ssj-build] with: artifact-name: kakarot-ssj-build From a0c0baa28a191a1a6b0b7af311b94f76239e4765 Mon Sep 17 00:00:00 2001 From: Oba Date: Tue, 1 Oct 2024 15:42:12 +0200 Subject: [PATCH 10/56] ci: concurrency by name --- .github/workflows/kakarot0-ci.yml | 4 ++-- .github/workflows/kakarot0-nightly-fuzzing.yml | 2 +- .github/workflows/kakarot0-release.yml | 2 +- .github/workflows/kakarot0-trunk-check.yaml | 4 ++-- .github/workflows/kakarot0-update-rpc.yml | 2 +- .github/workflows/ssj-ci.yml | 4 ++-- .github/workflows/ssj-ef-tests.yml | 2 +- .github/workflows/ssj-release.yml | 2 +- .github/workflows/ssj-test.yml | 2 +- .github/workflows/ssj-trunk-check.yaml | 2 +- 10 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/kakarot0-ci.yml b/.github/workflows/kakarot0-ci.yml index dad799561..3aabed849 100644 --- a/.github/workflows/kakarot0-ci.yml +++ b/.github/workflows/kakarot0-ci.yml @@ -1,4 +1,4 @@ -name: CI +name: kakarot0-CI on: push: @@ -12,7 +12,7 @@ env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} concurrency: - group: ${{ github.workflow }}-${{ github.ref }} + group: kakarot0-${{ github.ref }} cancel-in-progress: true permissions: read-all diff --git a/.github/workflows/kakarot0-nightly-fuzzing.yml b/.github/workflows/kakarot0-nightly-fuzzing.yml index 9083bd3cd..143692bd8 100644 --- a/.github/workflows/kakarot0-nightly-fuzzing.yml +++ b/.github/workflows/kakarot0-nightly-fuzzing.yml @@ -1,4 +1,4 @@ -name: NIGHTLY-FUZZING +name: kakarot0-NIGHTLY-FUZZING on: schedule: diff --git a/.github/workflows/kakarot0-release.yml b/.github/workflows/kakarot0-release.yml index dca8189d5..57dd68618 100644 --- a/.github/workflows/kakarot0-release.yml +++ b/.github/workflows/kakarot0-release.yml @@ -1,5 +1,5 @@ # trunk-ignore-all(checkov/CKV2_GHA_1) -name: Release +name: kakarot0-Release on: release: diff --git a/.github/workflows/kakarot0-trunk-check.yaml b/.github/workflows/kakarot0-trunk-check.yaml index 0adad3aa0..7d730f72c 100644 --- a/.github/workflows/kakarot0-trunk-check.yaml +++ b/.github/workflows/kakarot0-trunk-check.yaml @@ -1,9 +1,9 @@ -name: Trunk +name: kakarot0-Trunk on: [pull_request] concurrency: - group: ${{ github.workflow }}-${{ github.ref }} + group: kakarot0-${{ github.ref }} cancel-in-progress: true permissions: read-all diff --git a/.github/workflows/kakarot0-update-rpc.yml b/.github/workflows/kakarot0-update-rpc.yml index 3a59bfb50..bd08633ac 100644 --- a/.github/workflows/kakarot0-update-rpc.yml +++ b/.github/workflows/kakarot0-update-rpc.yml @@ -1,4 +1,4 @@ -name: Update Submodule +name: kakarot0 Update Submodule on: release: diff --git a/.github/workflows/ssj-ci.yml b/.github/workflows/ssj-ci.yml index aeb1927c7..7aa78af29 100644 --- a/.github/workflows/ssj-ci.yml +++ b/.github/workflows/ssj-ci.yml @@ -1,4 +1,4 @@ -name: CI +name: SSJ-CI on: push: @@ -11,7 +11,7 @@ env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} concurrency: - group: ${{ github.workflow }}-${{ github.ref }} + group: ssj-${{ github.ref }} cancel-in-progress: true permissions: read-all diff --git a/.github/workflows/ssj-ef-tests.yml b/.github/workflows/ssj-ef-tests.yml index 10e358657..61580709d 100644 --- a/.github/workflows/ssj-ef-tests.yml +++ b/.github/workflows/ssj-ef-tests.yml @@ -1,4 +1,4 @@ -name: EF-Tests +name: SSJ-EF-Tests on: workflow_call: diff --git a/.github/workflows/ssj-release.yml b/.github/workflows/ssj-release.yml index 122c07080..ef4a9d679 100644 --- a/.github/workflows/ssj-release.yml +++ b/.github/workflows/ssj-release.yml @@ -1,5 +1,5 @@ # trunk-ignore-all(checkov/CKV2_GHA_1) -name: Release +name: SSJ-Release on: release: diff --git a/.github/workflows/ssj-test.yml b/.github/workflows/ssj-test.yml index 3b2382068..56eae5d9a 100644 --- a/.github/workflows/ssj-test.yml +++ b/.github/workflows/ssj-test.yml @@ -1,4 +1,4 @@ -name: CI +name: SSJ-CI permissions: read-all diff --git a/.github/workflows/ssj-trunk-check.yaml b/.github/workflows/ssj-trunk-check.yaml index 2e0216311..2ef8f845d 100644 --- a/.github/workflows/ssj-trunk-check.yaml +++ b/.github/workflows/ssj-trunk-check.yaml @@ -1,4 +1,4 @@ -name: Trunk +name: SSJ-Trunk on: [pull_request] From c02b9752d43eef0b2d8b54fdd19d40e279254407 Mon Sep 17 00:00:00 2001 From: Oba Date: Tue, 1 Oct 2024 15:50:54 +0200 Subject: [PATCH 11/56] ci: cd into ssj --- .github/workflows/ssj-build.yml | 2 +- .github/workflows/ssj-tests-unit.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ssj-build.yml b/.github/workflows/ssj-build.yml index 9a6ee0a6a..a5dc9a0ed 100644 --- a/.github/workflows/ssj-build.yml +++ b/.github/workflows/ssj-build.yml @@ -23,7 +23,7 @@ jobs: uses: software-mansion/setup-scarb@v1 - name: Build contracts - run: scarb build -p contracts + run: cd kakarot-ssj/ && scarb build -p contracts - name: Upload artifacts uses: actions/upload-artifact@v3 diff --git a/.github/workflows/ssj-tests-unit.yml b/.github/workflows/ssj-tests-unit.yml index 2ff0ef28d..4594c21ab 100644 --- a/.github/workflows/ssj-tests-unit.yml +++ b/.github/workflows/ssj-tests-unit.yml @@ -20,7 +20,7 @@ jobs: - name: Run format check if: inputs.run-fmt-check - run: scarb fmt --check + run: cd kakarot-ssj && scarb fmt --check - name: Run tests - run: scarb test + run: cd kakarot-ssj && scarb test From 4b1083faebd41d25c05e6488ed07697ade9ee7f7 Mon Sep 17 00:00:00 2001 From: Oba Date: Tue, 1 Oct 2024 15:57:38 +0200 Subject: [PATCH 12/56] ci: supply tool-versions scarb --- .github/workflows/ssj-build.yml | 2 ++ .github/workflows/ssj-release.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.github/workflows/ssj-build.yml b/.github/workflows/ssj-build.yml index a5dc9a0ed..cf0375e34 100644 --- a/.github/workflows/ssj-build.yml +++ b/.github/workflows/ssj-build.yml @@ -21,6 +21,8 @@ jobs: - name: Set up Scarb uses: software-mansion/setup-scarb@v1 + with: + tool-version: ./.tool-versions - name: Build contracts run: cd kakarot-ssj/ && scarb build -p contracts diff --git a/.github/workflows/ssj-release.yml b/.github/workflows/ssj-release.yml index ef4a9d679..2e96834e0 100644 --- a/.github/workflows/ssj-release.yml +++ b/.github/workflows/ssj-release.yml @@ -13,6 +13,8 @@ jobs: uses: actions/checkout@v4 - name: Set up Scarb uses: software-mansion/setup-scarb@v1 + with: + tool-version: ./.tool-versions - name: Build contracts run: | scarb build -p contracts From 719d29f8b8d72b16bc064e4dac1631edfd33d37b Mon Sep 17 00:00:00 2001 From: Oba Date: Tue, 1 Oct 2024 16:00:16 +0200 Subject: [PATCH 13/56] ci: typo --- .github/workflows/ssj-build.yml | 2 +- .github/workflows/ssj-release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ssj-build.yml b/.github/workflows/ssj-build.yml index cf0375e34..f35cb2c0f 100644 --- a/.github/workflows/ssj-build.yml +++ b/.github/workflows/ssj-build.yml @@ -22,7 +22,7 @@ jobs: - name: Set up Scarb uses: software-mansion/setup-scarb@v1 with: - tool-version: ./.tool-versions + tool-versions: ./.tool-versions - name: Build contracts run: cd kakarot-ssj/ && scarb build -p contracts diff --git a/.github/workflows/ssj-release.yml b/.github/workflows/ssj-release.yml index 2e96834e0..12f342dfb 100644 --- a/.github/workflows/ssj-release.yml +++ b/.github/workflows/ssj-release.yml @@ -14,7 +14,7 @@ jobs: - name: Set up Scarb uses: software-mansion/setup-scarb@v1 with: - tool-version: ./.tool-versions + tool-versions: ./.tool-versions - name: Build contracts run: | scarb build -p contracts From 6a57f76e44f3c0b666fb25e012958ce8f0a69a9e Mon Sep 17 00:00:00 2001 From: Oba Date: Tue, 1 Oct 2024 16:03:25 +0200 Subject: [PATCH 14/56] ci: use ssj tool-versions --- .github/workflows/ssj-build.yml | 2 +- .github/workflows/ssj-release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ssj-build.yml b/.github/workflows/ssj-build.yml index f35cb2c0f..ec24da61f 100644 --- a/.github/workflows/ssj-build.yml +++ b/.github/workflows/ssj-build.yml @@ -22,7 +22,7 @@ jobs: - name: Set up Scarb uses: software-mansion/setup-scarb@v1 with: - tool-versions: ./.tool-versions + tool-versions: ./kakarot-ssj/.tool-versions - name: Build contracts run: cd kakarot-ssj/ && scarb build -p contracts diff --git a/.github/workflows/ssj-release.yml b/.github/workflows/ssj-release.yml index 12f342dfb..ac31ddea3 100644 --- a/.github/workflows/ssj-release.yml +++ b/.github/workflows/ssj-release.yml @@ -14,7 +14,7 @@ jobs: - name: Set up Scarb uses: software-mansion/setup-scarb@v1 with: - tool-versions: ./.tool-versions + tool-versions: ./kakarot-ssj/.tool-versions - name: Build contracts run: | scarb build -p contracts From b0ea84bff8e0d241d36989b403084515316e6c65 Mon Sep 17 00:00:00 2001 From: Oba Date: Tue, 1 Oct 2024 16:09:16 +0200 Subject: [PATCH 15/56] ci: install python and use tool-versions ssj --- .github/workflows/ssj-tests-unit.yml | 2 ++ .github/workflows/ssj-trunk-check.yaml | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/.github/workflows/ssj-tests-unit.yml b/.github/workflows/ssj-tests-unit.yml index 4594c21ab..7452989a0 100644 --- a/.github/workflows/ssj-tests-unit.yml +++ b/.github/workflows/ssj-tests-unit.yml @@ -17,6 +17,8 @@ jobs: - uses: actions/checkout@v4 - uses: foundry-rs/setup-snfoundry@v3 - uses: software-mansion/setup-scarb@v1 + with: + tool-versions: ./kakarot-ssj/.tool-versions - name: Run format check if: inputs.run-fmt-check diff --git a/.github/workflows/ssj-trunk-check.yaml b/.github/workflows/ssj-trunk-check.yaml index 2ef8f845d..1462cfa98 100644 --- a/.github/workflows/ssj-trunk-check.yaml +++ b/.github/workflows/ssj-trunk-check.yaml @@ -20,5 +20,12 @@ jobs: - name: Checkout uses: actions/checkout@v3 + - name: Set up Python 3.10.14 + uses: actions/setup-python@v5 + with: + python-version: 3.10.14 + cache: pip + - run: pip install cairo-lang==0.13.1 sympy==1.11.1 + - name: Trunk Check uses: trunk-io/trunk-action@v1 From fd4c456fd6c65521459c5fcf26796f94631d38b4 Mon Sep 17 00:00:00 2001 From: Oba Date: Tue, 1 Oct 2024 16:18:13 +0200 Subject: [PATCH 16/56] ci: fix path ssj-build --- .github/workflows/ssj-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ssj-build.yml b/.github/workflows/ssj-build.yml index ec24da61f..638f5338c 100644 --- a/.github/workflows/ssj-build.yml +++ b/.github/workflows/ssj-build.yml @@ -31,4 +31,4 @@ jobs: uses: actions/upload-artifact@v3 with: name: ${{ inputs.artifact-name }} - path: target/dev + path: kakarot-ssj/target/dev From 98d0701ae48a32e3e32356d9d3e9ae592601a7db Mon Sep 17 00:00:00 2001 From: Oba Date: Tue, 1 Oct 2024 17:21:43 +0200 Subject: [PATCH 17/56] chore: unified devcontainer --- .devcontainer/devcontainer.json | 5 +++-- kakarot-ssj/.devcontainer/devcontainer.json | 10 ---------- 2 files changed, 3 insertions(+), 12 deletions(-) delete mode 100644 kakarot-ssj/.devcontainer/devcontainer.json diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index b03713d5c..e291ba4f8 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -21,14 +21,15 @@ "ms-python.vscode-pylance", "starkware.cairo", "ericglau.cairo-ls", - "trunk.io" + "trunk.io", + "starkware.cairo1" ] } }, // Use 'forwardPorts' to make a list of ports inside the container available locally. // "forwardPorts": [], // Use 'postCreateCommand' to run commands after the container is created. - "postCreateCommand": "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && curl -L https://foundry.paradigm.xyz | bash && /home/vscode/.foundry/bin/foundryup && make setup", + "postCreateCommand": "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && curl -L https://foundry.paradigm.xyz | bash && /home/vscode/.foundry/bin/foundryup && curl -LsSf https://astral.sh/uv/install.sh | sh && . $HOME/.cargo/env && uv venv && make setup && curl --proto '=https' --tlsv1.2 -sSf https://docs.swmansion.com/scarb/install.sh | sh", // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. "remoteUser": "vscode", "features": { diff --git a/kakarot-ssj/.devcontainer/devcontainer.json b/kakarot-ssj/.devcontainer/devcontainer.json deleted file mode 100644 index 8ce21e6b3..000000000 --- a/kakarot-ssj/.devcontainer/devcontainer.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "Kakarot SSJ", - "image": "mcr.microsoft.com/devcontainers/base:jammy", - "customizations": { - "vscode": { - "extensions": ["starkware.cairo1"] - } - }, - "postCreateCommand": "curl --proto '=https' --tlsv1.2 -sSf https://docs.swmansion.com/scarb/install.sh | sh" -} From 7a859316007769aea14b5fed074046ed9a789265 Mon Sep 17 00:00:00 2001 From: Oba Date: Tue, 1 Oct 2024 17:34:15 +0200 Subject: [PATCH 18/56] chore: deployer docker use uv --- docker/deployer/Dockerfile | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/docker/deployer/Dockerfile b/docker/deployer/Dockerfile index 895f9eed6..de4c17db6 100644 --- a/docker/deployer/Dockerfile +++ b/docker/deployer/Dockerfile @@ -14,14 +14,13 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ git \ && rm -rf /var/lib/apt/lists/* -ENV POETRY_NO_INTERACTION=1 \ - POETRY_VIRTUALENVS_IN_PROJECT=1 \ - POETRY_VIRTUALENVS_CREATE=1 \ - VIRTUAL_ENV=/app/kakarot/.venv \ +ENV VIRTUAL_ENV=/app/kakarot/.venv \ PATH="/app/kakarot/.venv/bin:/root/.local/bin:$PATH" RUN --mount=type=cache,target=/root/.cache \ - curl -sSL https://install.python-poetry.org | python3 - + curl -LsSf https://astral.sh/uv/install.sh | sh + +RUN uv venv WORKDIR /app/kakarot @@ -52,20 +51,11 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ ARG GITHUB_TOKEN ENV GITHUB_TOKEN=${GITHUB_TOKEN} -# install dependencies -COPY poetry.lock . COPY pyproject.toml . COPY kakarot_scripts ./kakarot_scripts COPY README.md . COPY tests ./tests -RUN --mount=type=cache,target=/root/.cache \ - poetry install - -# split install in two steps to leverage docker cache -COPY . . - - # Install asdf for multiple scarb versions RUN git clone --depth 1 https://github.com/asdf-vm/asdf.git "$HOME/.asdf" && \ echo ". $HOME/.asdf/asdf.sh" >> "$HOME/.bashrc" && \ @@ -90,19 +80,16 @@ COPY --from=builder /app/kakarot/tests ./tests/ # Cairo Smart contracts are used in deploy_kakarot.py # To limit the probability of this Dockerfile to break, we copy the entire src and not individual files -COPY --from=builder /app/kakarot/src ./src/ +COPY --from=builder /app/kakarot/kakarot0/src ./src/ # Default Solidity contracts are also used in deploy_kakarot.py COPY --from=builder /app/kakarot/solidity_contracts ./solidity_contracts/ COPY --from=builder /app/kakarot/Makefile . -COPY --from=builder /app/kakarot/poetry.lock . +COPY --from=builder /app/kakarot/uv.lock . COPY --from=builder /app/kakarot/pyproject.toml . COPY --from=builder /app/kakarot/foundry.toml . COPY --from=builder /app/kakarot/README.md . -RUN --mount=type=cache,target=/root/.cache \ - poetry install --without dev - # Deploy kakarot -CMD ["python", "kakarot_scripts/deploy_kakarot.py"] +CMD ["uv", "run", "python", "kakarot_scripts/deploy_kakarot.py"] From a521056bafd07e9ea2e663a56813820364831ecc Mon Sep 17 00:00:00 2001 From: Oba Date: Tue, 1 Oct 2024 17:24:53 +0200 Subject: [PATCH 19/56] chore: move zellic audit to kakarot0 folder --- .../Kakarot EVM - Zellic Audit Report.pdf | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename audits/{ => kakarot0}/Kakarot EVM - Zellic Audit Report.pdf (100%) diff --git a/audits/Kakarot EVM - Zellic Audit Report.pdf b/audits/kakarot0/Kakarot EVM - Zellic Audit Report.pdf similarity index 100% rename from audits/Kakarot EVM - Zellic Audit Report.pdf rename to audits/kakarot0/Kakarot EVM - Zellic Audit Report.pdf From 8bb0a866bca0073a7102ddd774294bdee9714bdd Mon Sep 17 00:00:00 2001 From: Oba Date: Tue, 1 Oct 2024 17:48:00 +0200 Subject: [PATCH 20/56] chore: update devcontainer --- .devcontainer/devcontainer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index e291ba4f8..acb5ad2e4 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -12,8 +12,8 @@ "python.formatting.blackPath": "/usr/local/py-utils/bin/black", "python.formatting.yapfPath": "/usr/local/py-utils/bin/yapf", "editor.defaultFormatter": "trunk.io", - "cairols.sourceDir": "src", - "cairols.cairoPath": ["src", "tests"] + "cairols.sourceDir": "kakarot0/src", + "cairols.cairoPath": ["kakarot0/src", "tests"] }, // Add the IDs of extensions you want installed when the container is created. "extensions": [ From 9915c2521c6f198d32f939eb506525de4de084e4 Mon Sep 17 00:00:00 2001 From: Oba Date: Wed, 2 Oct 2024 10:52:38 +0200 Subject: [PATCH 21/56] chore: fix dockerfile --- docker/deployer/Dockerfile | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/docker/deployer/Dockerfile b/docker/deployer/Dockerfile index de4c17db6..52b396336 100644 --- a/docker/deployer/Dockerfile +++ b/docker/deployer/Dockerfile @@ -18,9 +18,10 @@ ENV VIRTUAL_ENV=/app/kakarot/.venv \ PATH="/app/kakarot/.venv/bin:/root/.local/bin:$PATH" RUN --mount=type=cache,target=/root/.cache \ - curl -LsSf https://astral.sh/uv/install.sh | sh + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y -RUN uv venv +RUN --mount=type=cache,target=/root/.cache \ +curl -LsSf https://astral.sh/uv/install.sh | sh WORKDIR /app/kakarot @@ -51,22 +52,20 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ ARG GITHUB_TOKEN ENV GITHUB_TOKEN=${GITHUB_TOKEN} -COPY pyproject.toml . -COPY kakarot_scripts ./kakarot_scripts -COPY README.md . -COPY tests ./tests +COPY . . + +SHELL ["/bin/bash", "-c"] +RUN source "$HOME/.cargo/env" && uv venv && uv pip install -e . # Install asdf for multiple scarb versions RUN git clone --depth 1 https://github.com/asdf-vm/asdf.git "$HOME/.asdf" && \ echo ". $HOME/.asdf/asdf.sh" >> "$HOME/.bashrc" && \ echo ". $HOME/.asdf/asdf.sh" >> "$HOME/.profile" -SHELL ["/bin/bash", "-c"] -RUN source "$HOME/.asdf/asdf.sh" && asdf plugin add scarb && asdf install scarb 0.7.0 && asdf install scarb 2.6.5 - +RUN source "$HOME/.asdf/asdf.sh" && asdf plugin add scarb && asdf install scarb 0.7.0 && asdf install scarb 2.6.5 && asdf install scarb 2.8.3 RUN --mount=type=cache,target=/root/.cache \ - source "$HOME/.asdf/asdf.sh" && make fetch-ssj-artifacts && make build && make build-sol + source "$HOME/.asdf/asdf.sh" && source "$HOME/.cargo/env" && make build-ssj && make build && make build-sol ############################################ @@ -77,6 +76,7 @@ FROM base as deployer COPY --from=builder /app/kakarot/build ./build/ COPY --from=builder /app/kakarot/kakarot_scripts/ ./kakarot_scripts/ COPY --from=builder /app/kakarot/tests ./tests/ +COPY --from=builder /app/kakarot/.venv ./.venv # Cairo Smart contracts are used in deploy_kakarot.py # To limit the probability of this Dockerfile to break, we copy the entire src and not individual files @@ -92,4 +92,4 @@ COPY --from=builder /app/kakarot/foundry.toml . COPY --from=builder /app/kakarot/README.md . # Deploy kakarot -CMD ["uv", "run", "python", "kakarot_scripts/deploy_kakarot.py"] +CMD ["uv", "run", "deploy"] From 5d8a9b5283e71d7878682539eb7741020277f66a Mon Sep 17 00:00:00 2001 From: Oba Date: Wed, 2 Oct 2024 10:53:23 +0200 Subject: [PATCH 22/56] chore: remove unecessary target --- Makefile | 3 --- 1 file changed, 3 deletions(-) diff --git a/Makefile b/Makefile index 437ba395a..8c7a848b3 100644 --- a/Makefile +++ b/Makefile @@ -16,9 +16,6 @@ build-ssj: @mkdir -p $(SSJ_DIR) @cd kakarot-ssj && scarb build -p contracts && find target/dev -type f -name '*contracts*' | grep -vE 'test|mock|Mock' | xargs -I {} cp {} ../$(SSJ_DIR) -test-unit-ssj: - @cd kakarot-ssj && scarb test - build: build-ssj uv run compile From df04d2fe3828328eb5796f44361b2eee98a1b086 Mon Sep 17 00:00:00 2001 From: Oba Date: Wed, 2 Oct 2024 11:00:16 +0200 Subject: [PATCH 23/56] refactor: move cairo1_contracts to root --- .trunk/trunk.yaml | 2 +- .../mock_pragma/.gitignore | 0 .../mock_pragma/.tool-versions | 0 .../mock_pragma/Scarb.lock | 0 .../mock_pragma/Scarb.toml | 0 .../mock_pragma/src/lib.cairo | 0 .../mock_pragma/src/mock_pragma_oracle.cairo | 0 .../cairo1_contracts => cairo1_contracts}/token/.gitignore | 0 .../cairo1_contracts => cairo1_contracts}/token/.tool-versions | 0 .../cairo1_contracts => cairo1_contracts}/token/Scarb.lock | 0 .../cairo1_contracts => cairo1_contracts}/token/Scarb.toml | 0 .../cairo1_contracts => cairo1_contracts}/token/src/lib.cairo | 0 .../token/src/starknet_token.cairo | 0 .../cairo1_contracts => cairo1_contracts}/utils/.gitignore | 0 .../cairo1_contracts => cairo1_contracts}/utils/.tool-versions | 0 .../cairo1_contracts => cairo1_contracts}/utils/Scarb.lock | 0 .../cairo1_contracts => cairo1_contracts}/utils/Scarb.toml | 0 .../utils/src/benchmark_cairo_calls.cairo | 0 .../cairo1_contracts => cairo1_contracts}/utils/src/lib.cairo | 0 .../utils/src/universal_library_caller.cairo | 0 kakarot_scripts/constants.py | 2 +- 21 files changed, 2 insertions(+), 2 deletions(-) rename {kakarot0/cairo1_contracts => cairo1_contracts}/mock_pragma/.gitignore (100%) rename {kakarot0/cairo1_contracts => cairo1_contracts}/mock_pragma/.tool-versions (100%) rename {kakarot0/cairo1_contracts => cairo1_contracts}/mock_pragma/Scarb.lock (100%) rename {kakarot0/cairo1_contracts => cairo1_contracts}/mock_pragma/Scarb.toml (100%) rename {kakarot0/cairo1_contracts => cairo1_contracts}/mock_pragma/src/lib.cairo (100%) rename {kakarot0/cairo1_contracts => cairo1_contracts}/mock_pragma/src/mock_pragma_oracle.cairo (100%) rename {kakarot0/cairo1_contracts => cairo1_contracts}/token/.gitignore (100%) rename {kakarot0/cairo1_contracts => cairo1_contracts}/token/.tool-versions (100%) rename {kakarot0/cairo1_contracts => cairo1_contracts}/token/Scarb.lock (100%) rename {kakarot0/cairo1_contracts => cairo1_contracts}/token/Scarb.toml (100%) rename {kakarot0/cairo1_contracts => cairo1_contracts}/token/src/lib.cairo (100%) rename {kakarot0/cairo1_contracts => cairo1_contracts}/token/src/starknet_token.cairo (100%) rename {kakarot0/cairo1_contracts => cairo1_contracts}/utils/.gitignore (100%) rename {kakarot0/cairo1_contracts => cairo1_contracts}/utils/.tool-versions (100%) rename {kakarot0/cairo1_contracts => cairo1_contracts}/utils/Scarb.lock (100%) rename {kakarot0/cairo1_contracts => cairo1_contracts}/utils/Scarb.toml (100%) rename {kakarot0/cairo1_contracts => cairo1_contracts}/utils/src/benchmark_cairo_calls.cairo (100%) rename {kakarot0/cairo1_contracts => cairo1_contracts}/utils/src/lib.cairo (100%) rename {kakarot0/cairo1_contracts => cairo1_contracts}/utils/src/universal_library_caller.cairo (100%) diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index dc05dbbd1..7dca4f9e6 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -72,7 +72,7 @@ lint: - logs* - lib* - resources* - - kakarot0/cairo1_contracts + - cairo1_contracts - tests/ef_tests/test_data - .katana/messaging_config.json - deployments diff --git a/kakarot0/cairo1_contracts/mock_pragma/.gitignore b/cairo1_contracts/mock_pragma/.gitignore similarity index 100% rename from kakarot0/cairo1_contracts/mock_pragma/.gitignore rename to cairo1_contracts/mock_pragma/.gitignore diff --git a/kakarot0/cairo1_contracts/mock_pragma/.tool-versions b/cairo1_contracts/mock_pragma/.tool-versions similarity index 100% rename from kakarot0/cairo1_contracts/mock_pragma/.tool-versions rename to cairo1_contracts/mock_pragma/.tool-versions diff --git a/kakarot0/cairo1_contracts/mock_pragma/Scarb.lock b/cairo1_contracts/mock_pragma/Scarb.lock similarity index 100% rename from kakarot0/cairo1_contracts/mock_pragma/Scarb.lock rename to cairo1_contracts/mock_pragma/Scarb.lock diff --git a/kakarot0/cairo1_contracts/mock_pragma/Scarb.toml b/cairo1_contracts/mock_pragma/Scarb.toml similarity index 100% rename from kakarot0/cairo1_contracts/mock_pragma/Scarb.toml rename to cairo1_contracts/mock_pragma/Scarb.toml diff --git a/kakarot0/cairo1_contracts/mock_pragma/src/lib.cairo b/cairo1_contracts/mock_pragma/src/lib.cairo similarity index 100% rename from kakarot0/cairo1_contracts/mock_pragma/src/lib.cairo rename to cairo1_contracts/mock_pragma/src/lib.cairo diff --git a/kakarot0/cairo1_contracts/mock_pragma/src/mock_pragma_oracle.cairo b/cairo1_contracts/mock_pragma/src/mock_pragma_oracle.cairo similarity index 100% rename from kakarot0/cairo1_contracts/mock_pragma/src/mock_pragma_oracle.cairo rename to cairo1_contracts/mock_pragma/src/mock_pragma_oracle.cairo diff --git a/kakarot0/cairo1_contracts/token/.gitignore b/cairo1_contracts/token/.gitignore similarity index 100% rename from kakarot0/cairo1_contracts/token/.gitignore rename to cairo1_contracts/token/.gitignore diff --git a/kakarot0/cairo1_contracts/token/.tool-versions b/cairo1_contracts/token/.tool-versions similarity index 100% rename from kakarot0/cairo1_contracts/token/.tool-versions rename to cairo1_contracts/token/.tool-versions diff --git a/kakarot0/cairo1_contracts/token/Scarb.lock b/cairo1_contracts/token/Scarb.lock similarity index 100% rename from kakarot0/cairo1_contracts/token/Scarb.lock rename to cairo1_contracts/token/Scarb.lock diff --git a/kakarot0/cairo1_contracts/token/Scarb.toml b/cairo1_contracts/token/Scarb.toml similarity index 100% rename from kakarot0/cairo1_contracts/token/Scarb.toml rename to cairo1_contracts/token/Scarb.toml diff --git a/kakarot0/cairo1_contracts/token/src/lib.cairo b/cairo1_contracts/token/src/lib.cairo similarity index 100% rename from kakarot0/cairo1_contracts/token/src/lib.cairo rename to cairo1_contracts/token/src/lib.cairo diff --git a/kakarot0/cairo1_contracts/token/src/starknet_token.cairo b/cairo1_contracts/token/src/starknet_token.cairo similarity index 100% rename from kakarot0/cairo1_contracts/token/src/starknet_token.cairo rename to cairo1_contracts/token/src/starknet_token.cairo diff --git a/kakarot0/cairo1_contracts/utils/.gitignore b/cairo1_contracts/utils/.gitignore similarity index 100% rename from kakarot0/cairo1_contracts/utils/.gitignore rename to cairo1_contracts/utils/.gitignore diff --git a/kakarot0/cairo1_contracts/utils/.tool-versions b/cairo1_contracts/utils/.tool-versions similarity index 100% rename from kakarot0/cairo1_contracts/utils/.tool-versions rename to cairo1_contracts/utils/.tool-versions diff --git a/kakarot0/cairo1_contracts/utils/Scarb.lock b/cairo1_contracts/utils/Scarb.lock similarity index 100% rename from kakarot0/cairo1_contracts/utils/Scarb.lock rename to cairo1_contracts/utils/Scarb.lock diff --git a/kakarot0/cairo1_contracts/utils/Scarb.toml b/cairo1_contracts/utils/Scarb.toml similarity index 100% rename from kakarot0/cairo1_contracts/utils/Scarb.toml rename to cairo1_contracts/utils/Scarb.toml diff --git a/kakarot0/cairo1_contracts/utils/src/benchmark_cairo_calls.cairo b/cairo1_contracts/utils/src/benchmark_cairo_calls.cairo similarity index 100% rename from kakarot0/cairo1_contracts/utils/src/benchmark_cairo_calls.cairo rename to cairo1_contracts/utils/src/benchmark_cairo_calls.cairo diff --git a/kakarot0/cairo1_contracts/utils/src/lib.cairo b/cairo1_contracts/utils/src/lib.cairo similarity index 100% rename from kakarot0/cairo1_contracts/utils/src/lib.cairo rename to cairo1_contracts/utils/src/lib.cairo diff --git a/kakarot0/cairo1_contracts/utils/src/universal_library_caller.cairo b/cairo1_contracts/utils/src/universal_library_caller.cairo similarity index 100% rename from kakarot0/cairo1_contracts/utils/src/universal_library_caller.cairo rename to cairo1_contracts/utils/src/universal_library_caller.cairo diff --git a/kakarot_scripts/constants.py b/kakarot_scripts/constants.py index a92df0a55..2729c8237 100644 --- a/kakarot_scripts/constants.py +++ b/kakarot_scripts/constants.py @@ -219,7 +219,7 @@ class ChainId(IntEnum): 16, ) CAIRO_ZERO_DIR = Path("kakarot0/src") -CAIRO_DIR = Path("kakarot0/cairo1_contracts") +CAIRO_DIR = Path("cairo1_contracts") TESTS_DIR = Path("tests") CONTRACTS = { From f8587fb619cb4f35d317a88ce630749b6ee5ffdc Mon Sep 17 00:00:00 2001 From: Oba Date: Wed, 2 Oct 2024 11:13:24 +0200 Subject: [PATCH 24/56] chore: update kakarot-ssj blockchain-tests-skip --- kakarot-ssj/blockchain-tests-skip.yml | 9323 ++----------------------- 1 file changed, 618 insertions(+), 8705 deletions(-) diff --git a/kakarot-ssj/blockchain-tests-skip.yml b/kakarot-ssj/blockchain-tests-skip.yml index 2cabb317a..564479755 100644 --- a/kakarot-ssj/blockchain-tests-skip.yml +++ b/kakarot-ssj/blockchain-tests-skip.yml @@ -1,8730 +1,643 @@ -# List of test directories to completely skip -# trunk-ignore(yamllint/empty-values) -directories: - -# List of file names to be skipped -# The first level corresponds to the directory, the second to the list of file names to ignore. -# trunk-ignore(yamllint/empty-values) -filename: - -# Keeping some skipped tests because of a probable memory leak somewhere -# causing cargo test to just crash at some point -regex: - eip4895_withdrawals: - - .* - eip4844_blobs: - - .* - eip4788_beacon_root: - - .* - eip7516_blobgasfee: - - .* - stEIP4844-blobtransactions: - - .* - stMemoryStressTest: - - mload32bitBound_return.* # ef-tests #565 - - CREATE_Bounds.* # ef-tests #565 - - CREATE2_Bounds.* # ef-tests #565 - - CALL_Bounds.* # ef-tests #565 - - CALLCODE_Bounds.* # ef-tests #565 - - DELEGATECALL_Bounds.* # ef-tests #565 - - static_CALL_Bounds.* # ef-tests #565 - stZeroKnowledge: - - .*ecmul.* - stZeroKnowledge2: - - .*ecadd.* - - .*ecmul.* - testname: + stEIP1153-transientStorage: + - transStorageOK_d3g0v0_Cancun + eip198_modexp_precompile: + - modexp__fork_Cancun_minus_blockchain_test_minus_EIP_minus_198_minus_case3_minus_raw_minus_input_minus_out_minus_of_minus_gas + initcode: + - contract_creating_tx__fork_Cancun_minus_blockchain_test_minus_over_limit_ones + - contract_creating_tx__fork_Cancun_minus_blockchain_test_minus_over_limit_zeros + stEIP3651-warmcoinbase: + - coinbaseWarmAccountCallGasFail_d0g0v0_Cancun vmIOandFlowOperations: - - gas_d0g0v0_Shanghai - - pc_d0g0v0_Shanghai - - pc_d1g0v0_Shanghai - - jump_d5g0v0_Shanghai - - jumpi_d9g0v0_Shanghai - stEIP3860-limitmeterinitcode: - - create2InitCodeSizeLimit_d1g0v0_Shanghai - - create2InitCodeSizeLimit_d0g0v0_Shanghai - - createInitCodeSizeLimit_d0g0v0_Shanghai - - creationTxInitCodeSizeLimit_d0g0v0_Shanghai - vmTests: - - blockInfo_d0g0v0_Shanghai - - blockInfo_d1g0v0_Shanghai - - blockInfo_d2g0v0_Shanghai - - blockInfo_d3g0v0_Shanghai - - blockInfo_d4g0v0_Shanghai - - calldatasize_d0g0v0_Shanghai - - calldatasize_d10g0v0_Shanghai - - calldatasize_d11g0v0_Shanghai - - calldatasize_d12g0v0_Shanghai - - calldatasize_d13g0v0_Shanghai - - calldatasize_d14g0v0_Shanghai - - calldatasize_d15g0v0_Shanghai - - calldatasize_d16g0v0_Shanghai - - calldatasize_d17g0v0_Shanghai - - calldatasize_d18g0v0_Shanghai - - calldatasize_d19g0v0_Shanghai - - calldatasize_d1g0v0_Shanghai - - calldatasize_d2g0v0_Shanghai - - calldatasize_d3g0v0_Shanghai - - calldatasize_d4g0v0_Shanghai - - calldatasize_d5g0v0_Shanghai - - calldatasize_d6g0v0_Shanghai - - calldatasize_d7g0v0_Shanghai - - calldatasize_d8g0v0_Shanghai - - calldatasize_d9g0v0_Shanghai - - envInfo_d0g0v0_Shanghai - - envInfo_d1g0v0_Shanghai - - envInfo_d2g0v0_Shanghai - - envInfo_d3g0v0_Shanghai - - envInfo_d4g0v0_Shanghai - - envInfo_d5g0v0_Shanghai - - envInfo_d6g0v0_Shanghai - - envInfo_d7g0v0_Shanghai - - envInfo_d8g0v0_Shanghai - - envInfo_d9g0v0_Shanghai - - random_d4g0v0_Shanghai - - random_d3g0v0_Shanghai - - sha3_d0g0v0_Shanghai - - sha3_d10g0v0_Shanghai - - sha3_d11g0v0_Shanghai - - sha3_d12g0v0_Shanghai - - sha3_d13g0v0_Shanghai - - sha3_d15g0v0_Shanghai - - sha3_d14g0v0_Shanghai - - sha3_d16g0v0_Shanghai - - sha3_d1g0v0_Shanghai - - sha3_d2g0v0_Shanghai - - sha3_d3g0v0_Shanghai - - sha3_d4g0v0_Shanghai - - sha3_d5g0v0_Shanghai - - sha3_d6g0v0_Shanghai - - sha3_d7g0v0_Shanghai - - sha3_d8g0v0_Shanghai - - sha3_d9g0v0_Shanghai - stEIP3855-push0: - - push0_d2g0v0_Shanghai - - push0_d1g0v0_Shanghai - vmArithmeticTest: - - expPower256_d0g0v0_Shanghai - - expPower256Of256_d0g0v0_Shanghai - - twoOps_d0g0v0_Shanghai - stArgsZeroOneBalance: - - callNonConst_d0g0v1_Shanghai - - calldatacopyNonConst_d0g0v1_Shanghai - - expNonConst_d0g0v0_Shanghai - - sha3NonConst_d0g0v0_Shanghai - - sha3NonConst_d0g0v1_Shanghai + - jump_d5g0v0_Cancun + - jumpi_d19g0v0_Cancun + - jumpi_d21g0v0_Cancun + - jumpi_d9g0v0_Cancun + vmLogTest: + - log0_d0g0v0_Cancun + - log1_d0g0v0_Cancun + - log2_d0g0v0_Cancun + - log3_d0g0v0_Cancun + - log4_d0g0v0_Cancun vmPerformance: - - loopExp_d10g0v0_Shanghai - - loopExp_d2g0v0_Shanghai - - loopExp_d11g0v0_Shanghai - - loopExp_d0g0v0_Shanghai - - loopExp_d1g0v0_Shanghai - - loopExp_d14g0v0_Shanghai - - loopExp_d3g0v0_Shanghai - - loopExp_d4g0v0_Shanghai - - loopExp_d9g0v0_Shanghai - - loopExp_d5g0v0_Shanghai - - loopMul_d0g0v0_Shanghai - - loopMul_d2g0v0_Shanghai - - loopMul_d1g0v0_Shanghai - - performanceTester_d1g0v0_Shanghai - - performanceTester_d0g0v0_Shanghai - - performanceTester_d3g0v0_Shanghai - - performanceTester_d2g0v0_Shanghai - - performanceTester_d4g0v0_Shanghai + - loopExp_d2g0v0_Cancun + - performanceTester_d0g0v0_Cancun + - performanceTester_d2g0v0_Cancun + - performanceTester_d3g0v0_Cancun + vmTests: + - blockInfo_d2g0v0_Cancun stBadOpcode: - - badOpcodes_d110g0v0_Shanghai - - invalidAddr_d41g0v0_Shanghai - - invalidAddr_d43g0v0_Shanghai - - invalidAddr_d45g0v0_Shanghai - - invalidAddr_d47g0v0_Shanghai - - invalidAddr_d49g0v0_Shanghai - - invalidDiffPlaces_d0g0v0_Shanghai - - invalidDiffPlaces_d10g0v0_Shanghai - - invalidDiffPlaces_d11g0v0_Shanghai - - invalidDiffPlaces_d12g0v0_Shanghai - - invalidDiffPlaces_d13g0v0_Shanghai - - invalidDiffPlaces_d14g0v0_Shanghai - - invalidDiffPlaces_d15g0v0_Shanghai - - invalidAddr_d71g0v0_Shanghai - - invalidAddr_d73g0v0_Shanghai - - invalidAddr_d75g0v0_Shanghai - - invalidAddr_d77g0v0_Shanghai - - invalidAddr_d79g0v0_Shanghai - - invalidDiffPlaces_d16g0v0_Shanghai - - invalidDiffPlaces_d1g0v0_Shanghai - - invalidDiffPlaces_d17g0v0_Shanghai - - invalidDiffPlaces_d18g0v0_Shanghai - - invalidDiffPlaces_d2g0v0_Shanghai - - invalidDiffPlaces_d3g0v0_Shanghai - - invalidDiffPlaces_d4g0v0_Shanghai - - invalidDiffPlaces_d19g0v0_Shanghai - - invalidDiffPlaces_d21g0v0_Shanghai - - invalidDiffPlaces_d5g0v0_Shanghai - - invalidDiffPlaces_d20g0v0_Shanghai - - invalidDiffPlaces_d22g0v0_Shanghai - - invalidDiffPlaces_d6g0v0_Shanghai - - invalidDiffPlaces_d23g0v0_Shanghai - - measureGas_d1g0v0_Shanghai - - invalidDiffPlaces_d7g0v0_Shanghai - - invalidDiffPlaces_d8g0v0_Shanghai - - invalidDiffPlaces_d9g0v0_Shanghai - - measureGas_d6g0v0_Shanghai - - measureGas_d7g0v0_Shanghai - - opc0CDiffPlaces_d0g0v0_Shanghai - - measureGas_d8g0v0_Shanghai - - invalidDiffPlaces_d24g0v0_Shanghai - - measureGas_d0g0v0_Shanghai - - measureGas_d9g0v0_Shanghai - - invalidDiffPlaces_d25g0v0_Shanghai - - invalidDiffPlaces_d26g0v0_Shanghai - - invalidDiffPlaces_d28g0v0_Shanghai - - invalidDiffPlaces_d27g0v0_Shanghai - - invalidDiffPlaces_d29g0v0_Shanghai - - invalidDiffPlaces_d30g0v0_Shanghai - - opc0CDiffPlaces_d1g0v0_Shanghai - - invalidDiffPlaces_d31g0v0_Shanghai - - invalidDiffPlaces_d32g0v0_Shanghai - - opc0CDiffPlaces_d10g0v0_Shanghai - - opc0CDiffPlaces_d11g0v0_Shanghai - - invalidDiffPlaces_d33g0v0_Shanghai - - opc0CDiffPlaces_d2g0v0_Shanghai - - opc0CDiffPlaces_d12g0v0_Shanghai - - opc0CDiffPlaces_d14g0v0_Shanghai - - opc0CDiffPlaces_d13g0v0_Shanghai - - invalidDiffPlaces_d34g0v0_Shanghai - - opc0CDiffPlaces_d15g0v0_Shanghai - - opc0DDiffPlaces_d0g0v0_Shanghai - - opc0CDiffPlaces_d16g0v0_Shanghai - - opc0CDiffPlaces_d3g0v0_Shanghai - - opc0CDiffPlaces_d17g0v0_Shanghai - - opc0CDiffPlaces_d4g0v0_Shanghai - - opc0CDiffPlaces_d18g0v0_Shanghai - - opc0CDiffPlaces_d19g0v0_Shanghai - - opc0CDiffPlaces_d5g0v0_Shanghai - - opc0CDiffPlaces_d21g0v0_Shanghai - - opc0CDiffPlaces_d6g0v0_Shanghai - - opc0CDiffPlaces_d8g0v0_Shanghai - - opc0CDiffPlaces_d20g0v0_Shanghai - - opc0CDiffPlaces_d7g0v0_Shanghai - - opc0CDiffPlaces_d22g0v0_Shanghai - - opc0DDiffPlaces_d10g0v0_Shanghai - - opc0CDiffPlaces_d23g0v0_Shanghai - - opc0CDiffPlaces_d9g0v0_Shanghai - - opc0CDiffPlaces_d24g0v0_Shanghai - - opc0DDiffPlaces_d12g0v0_Shanghai - - opc0DDiffPlaces_d1g0v0_Shanghai - - opc0DDiffPlaces_d11g0v0_Shanghai - - opc0CDiffPlaces_d25g0v0_Shanghai - - opc0CDiffPlaces_d26g0v0_Shanghai - - opc0CDiffPlaces_d32g0v0_Shanghai - - opc0DDiffPlaces_d13g0v0_Shanghai - - opc0CDiffPlaces_d29g0v0_Shanghai - - opc0CDiffPlaces_d27g0v0_Shanghai - - opc0CDiffPlaces_d28g0v0_Shanghai - - opc0CDiffPlaces_d30g0v0_Shanghai - - opc0CDiffPlaces_d31g0v0_Shanghai - - opc0DDiffPlaces_d14g0v0_Shanghai - - opc0DDiffPlaces_d15g0v0_Shanghai - - opc0DDiffPlaces_d2g0v0_Shanghai - - opc0CDiffPlaces_d33g0v0_Shanghai - - opc0DDiffPlaces_d16g0v0_Shanghai - - opc0CDiffPlaces_d34g0v0_Shanghai - - opc0DDiffPlaces_d17g0v0_Shanghai - - opc0EDiffPlaces_d0g0v0_Shanghai - - opc0DDiffPlaces_d18g0v0_Shanghai - - opc0DDiffPlaces_d3g0v0_Shanghai - - opc0DDiffPlaces_d19g0v0_Shanghai - - opc0DDiffPlaces_d4g0v0_Shanghai - - opc0DDiffPlaces_d20g0v0_Shanghai - - opc0DDiffPlaces_d5g0v0_Shanghai - - opc0DDiffPlaces_d21g0v0_Shanghai - - opc0DDiffPlaces_d6g0v0_Shanghai - - opc0DDiffPlaces_d22g0v0_Shanghai - - opc0DDiffPlaces_d7g0v0_Shanghai - - opc0DDiffPlaces_d23g0v0_Shanghai - - opc0DDiffPlaces_d8g0v0_Shanghai - - opc0DDiffPlaces_d9g0v0_Shanghai - - opc0EDiffPlaces_d10g0v0_Shanghai - - opc0EDiffPlaces_d11g0v0_Shanghai - - opc0EDiffPlaces_d1g0v0_Shanghai - - opc0DDiffPlaces_d24g0v0_Shanghai - - opc0EDiffPlaces_d12g0v0_Shanghai - - opc0DDiffPlaces_d26g0v0_Shanghai - - opc0DDiffPlaces_d25g0v0_Shanghai - - opc0DDiffPlaces_d28g0v0_Shanghai - - opc0EDiffPlaces_d13g0v0_Shanghai - - opc0DDiffPlaces_d27g0v0_Shanghai - - opc0EDiffPlaces_d14g0v0_Shanghai - - opc0DDiffPlaces_d29g0v0_Shanghai - - opc0EDiffPlaces_d15g0v0_Shanghai - - opc0DDiffPlaces_d30g0v0_Shanghai - - opc0EDiffPlaces_d16g0v0_Shanghai - - opc0DDiffPlaces_d31g0v0_Shanghai - - opc0DDiffPlaces_d32g0v0_Shanghai - - opc0EDiffPlaces_d2g0v0_Shanghai - - opc0DDiffPlaces_d33g0v0_Shanghai - - opc0DDiffPlaces_d34g0v0_Shanghai - - opc0EDiffPlaces_d17g0v0_Shanghai - - opc0EDiffPlaces_d18g0v0_Shanghai - - opc0EDiffPlaces_d19g0v0_Shanghai - - opc0EDiffPlaces_d3g0v0_Shanghai - - opc0EDiffPlaces_d21g0v0_Shanghai - - opc0FDiffPlaces_d0g0v0_Shanghai - - opc0EDiffPlaces_d20g0v0_Shanghai - - opc0EDiffPlaces_d4g0v0_Shanghai - - opc0EDiffPlaces_d5g0v0_Shanghai - - opc0EDiffPlaces_d22g0v0_Shanghai - - opc0EDiffPlaces_d6g0v0_Shanghai - - opc0EDiffPlaces_d23g0v0_Shanghai - - opc0EDiffPlaces_d7g0v0_Shanghai - - opc0EDiffPlaces_d8g0v0_Shanghai - - opc0EDiffPlaces_d9g0v0_Shanghai - - opc0FDiffPlaces_d1g0v0_Shanghai - - opc0EDiffPlaces_d24g0v0_Shanghai - - opc0FDiffPlaces_d10g0v0_Shanghai - - opc0FDiffPlaces_d11g0v0_Shanghai - - opc0EDiffPlaces_d26g0v0_Shanghai - - opc0EDiffPlaces_d25g0v0_Shanghai - - opc0EDiffPlaces_d28g0v0_Shanghai - - opc0FDiffPlaces_d12g0v0_Shanghai - - opc0EDiffPlaces_d27g0v0_Shanghai - - opc0FDiffPlaces_d13g0v0_Shanghai - - opc0EDiffPlaces_d29g0v0_Shanghai - - opc0FDiffPlaces_d14g0v0_Shanghai - - opc0EDiffPlaces_d32g0v0_Shanghai - - opc0FDiffPlaces_d15g0v0_Shanghai - - opc0EDiffPlaces_d30g0v0_Shanghai - - opc0EDiffPlaces_d31g0v0_Shanghai - - opc0EDiffPlaces_d33g0v0_Shanghai - - opc0FDiffPlaces_d2g0v0_Shanghai - - opc0FDiffPlaces_d16g0v0_Shanghai - - opc0EDiffPlaces_d34g0v0_Shanghai - - opc0FDiffPlaces_d17g0v0_Shanghai - - opc0FDiffPlaces_d18g0v0_Shanghai - - opc0FDiffPlaces_d3g0v0_Shanghai - - opc0FDiffPlaces_d19g0v0_Shanghai - - opc0FDiffPlaces_d20g0v0_Shanghai - - opc0FDiffPlaces_d4g0v0_Shanghai - - opc0FDiffPlaces_d21g0v0_Shanghai - - opc1EDiffPlaces_d0g0v0_Shanghai - - opc0FDiffPlaces_d22g0v0_Shanghai - - opc0FDiffPlaces_d23g0v0_Shanghai - - opc0FDiffPlaces_d5g0v0_Shanghai - - opc0FDiffPlaces_d6g0v0_Shanghai - - opc0FDiffPlaces_d7g0v0_Shanghai - - opc0FDiffPlaces_d8g0v0_Shanghai - - opc0FDiffPlaces_d24g0v0_Shanghai - - opc1EDiffPlaces_d1g0v0_Shanghai - - opc0FDiffPlaces_d9g0v0_Shanghai - - opc1EDiffPlaces_d10g0v0_Shanghai - - opc0FDiffPlaces_d25g0v0_Shanghai - - opc1EDiffPlaces_d11g0v0_Shanghai - - opc0FDiffPlaces_d26g0v0_Shanghai - - opc1EDiffPlaces_d12g0v0_Shanghai - - opc0FDiffPlaces_d27g0v0_Shanghai - - opc1EDiffPlaces_d13g0v0_Shanghai - - opc0FDiffPlaces_d28g0v0_Shanghai - - opc1EDiffPlaces_d14g0v0_Shanghai - - opc1EDiffPlaces_d15g0v0_Shanghai - - opc0FDiffPlaces_d30g0v0_Shanghai - - opc0FDiffPlaces_d29g0v0_Shanghai - - opc0FDiffPlaces_d33g0v0_Shanghai - - opc0FDiffPlaces_d32g0v0_Shanghai - - opc1EDiffPlaces_d2g0v0_Shanghai - - opc0FDiffPlaces_d31g0v0_Shanghai - - opc1EDiffPlaces_d16g0v0_Shanghai - - opc0FDiffPlaces_d34g0v0_Shanghai - - opc1EDiffPlaces_d17g0v0_Shanghai - - opc1EDiffPlaces_d18g0v0_Shanghai - - opc1EDiffPlaces_d21g0v0_Shanghai - - opc1EDiffPlaces_d19g0v0_Shanghai - - opc1EDiffPlaces_d3g0v0_Shanghai - - opc1EDiffPlaces_d20g0v0_Shanghai - - opc1FDiffPlaces_d0g0v0_Shanghai - - opc1EDiffPlaces_d23g0v0_Shanghai - - opc1EDiffPlaces_d4g0v0_Shanghai - - opc1EDiffPlaces_d22g0v0_Shanghai - - opc1EDiffPlaces_d5g0v0_Shanghai - - opc1EDiffPlaces_d6g0v0_Shanghai - - opc1EDiffPlaces_d7g0v0_Shanghai - - opc1EDiffPlaces_d8g0v0_Shanghai - - opc1EDiffPlaces_d24g0v0_Shanghai - - opc1EDiffPlaces_d9g0v0_Shanghai - - opc1FDiffPlaces_d1g0v0_Shanghai - - opc1EDiffPlaces_d25g0v0_Shanghai - - opc1FDiffPlaces_d10g0v0_Shanghai - - opc1FDiffPlaces_d11g0v0_Shanghai - - opc1EDiffPlaces_d26g0v0_Shanghai - - opc1FDiffPlaces_d12g0v0_Shanghai - - opc1EDiffPlaces_d27g0v0_Shanghai - - opc1FDiffPlaces_d13g0v0_Shanghai - - opc1FDiffPlaces_d14g0v0_Shanghai - - opc1EDiffPlaces_d28g0v0_Shanghai - - opc1FDiffPlaces_d15g0v0_Shanghai - - opc1EDiffPlaces_d30g0v0_Shanghai - - opc1EDiffPlaces_d29g0v0_Shanghai - - opc1EDiffPlaces_d31g0v0_Shanghai - - opc1EDiffPlaces_d32g0v0_Shanghai - - opc1FDiffPlaces_d16g0v0_Shanghai - - opc1FDiffPlaces_d2g0v0_Shanghai - - opc1FDiffPlaces_d17g0v0_Shanghai - - opc1EDiffPlaces_d33g0v0_Shanghai - - opc1EDiffPlaces_d34g0v0_Shanghai - - opc1FDiffPlaces_d18g0v0_Shanghai - - opc1FDiffPlaces_d19g0v0_Shanghai - - opc1FDiffPlaces_d20g0v0_Shanghai - - opc1FDiffPlaces_d3g0v0_Shanghai - - opc1FDiffPlaces_d21g0v0_Shanghai - - opc21DiffPlaces_d0g0v0_Shanghai - - opc1FDiffPlaces_d22g0v0_Shanghai - - opc1FDiffPlaces_d4g0v0_Shanghai - - opc1FDiffPlaces_d23g0v0_Shanghai - - opc1FDiffPlaces_d5g0v0_Shanghai - - opc1FDiffPlaces_d6g0v0_Shanghai - - opc1FDiffPlaces_d7g0v0_Shanghai - - opc1FDiffPlaces_d24g0v0_Shanghai - - opc1FDiffPlaces_d8g0v0_Shanghai - - opc1FDiffPlaces_d9g0v0_Shanghai - - opc21DiffPlaces_d1g0v0_Shanghai - - opc1FDiffPlaces_d25g0v0_Shanghai - - opc21DiffPlaces_d10g0v0_Shanghai - - opc21DiffPlaces_d11g0v0_Shanghai - - opc1FDiffPlaces_d26g0v0_Shanghai - - opc21DiffPlaces_d12g0v0_Shanghai - - opc21DiffPlaces_d13g0v0_Shanghai - - opc1FDiffPlaces_d27g0v0_Shanghai - - opc21DiffPlaces_d14g0v0_Shanghai - - opc1FDiffPlaces_d29g0v0_Shanghai - - opc1FDiffPlaces_d28g0v0_Shanghai - - opc21DiffPlaces_d15g0v0_Shanghai - - opc21DiffPlaces_d16g0v0_Shanghai - - opc1FDiffPlaces_d30g0v0_Shanghai - - opc1FDiffPlaces_d31g0v0_Shanghai - - opc1FDiffPlaces_d32g0v0_Shanghai - - opc21DiffPlaces_d2g0v0_Shanghai - - opc1FDiffPlaces_d33g0v0_Shanghai - - opc21DiffPlaces_d17g0v0_Shanghai - - opc1FDiffPlaces_d34g0v0_Shanghai - - opc21DiffPlaces_d18g0v0_Shanghai - - opc21DiffPlaces_d3g0v0_Shanghai - - opc21DiffPlaces_d19g0v0_Shanghai - - opc22DiffPlaces_d0g0v0_Shanghai - - opc21DiffPlaces_d21g0v0_Shanghai - - opc21DiffPlaces_d22g0v0_Shanghai - - opc21DiffPlaces_d4g0v0_Shanghai - - opc21DiffPlaces_d20g0v0_Shanghai - - opc21DiffPlaces_d23g0v0_Shanghai - - opc21DiffPlaces_d5g0v0_Shanghai - - opc21DiffPlaces_d6g0v0_Shanghai - - opc21DiffPlaces_d7g0v0_Shanghai - - opc21DiffPlaces_d8g0v0_Shanghai - - opc21DiffPlaces_d24g0v0_Shanghai - - opc21DiffPlaces_d9g0v0_Shanghai - - opc22DiffPlaces_d1g0v0_Shanghai - - opc22DiffPlaces_d10g0v0_Shanghai - - opc21DiffPlaces_d25g0v0_Shanghai - - opc21DiffPlaces_d26g0v0_Shanghai - - opc22DiffPlaces_d11g0v0_Shanghai - - opc22DiffPlaces_d12g0v0_Shanghai - - opc22DiffPlaces_d13g0v0_Shanghai - - opc22DiffPlaces_d14g0v0_Shanghai - - opc21DiffPlaces_d27g0v0_Shanghai - - opc21DiffPlaces_d28g0v0_Shanghai - - opc22DiffPlaces_d15g0v0_Shanghai - - opc21DiffPlaces_d29g0v0_Shanghai - - opc21DiffPlaces_d30g0v0_Shanghai - - opc21DiffPlaces_d31g0v0_Shanghai - - opc21DiffPlaces_d32g0v0_Shanghai - - opc22DiffPlaces_d2g0v0_Shanghai - - opc22DiffPlaces_d16g0v0_Shanghai - - opc21DiffPlaces_d33g0v0_Shanghai - - opc21DiffPlaces_d34g0v0_Shanghai - - opc22DiffPlaces_d17g0v0_Shanghai - - opc22DiffPlaces_d18g0v0_Shanghai - - opc22DiffPlaces_d19g0v0_Shanghai - - opc22DiffPlaces_d3g0v0_Shanghai - - opc23DiffPlaces_d0g0v0_Shanghai - - opc22DiffPlaces_d21g0v0_Shanghai - - opc22DiffPlaces_d22g0v0_Shanghai - - opc22DiffPlaces_d4g0v0_Shanghai - - opc22DiffPlaces_d20g0v0_Shanghai - - opc22DiffPlaces_d23g0v0_Shanghai - - opc22DiffPlaces_d5g0v0_Shanghai - - opc22DiffPlaces_d6g0v0_Shanghai - - opc22DiffPlaces_d7g0v0_Shanghai - - opc22DiffPlaces_d8g0v0_Shanghai - - opc22DiffPlaces_d24g0v0_Shanghai - - opc22DiffPlaces_d9g0v0_Shanghai - - opc23DiffPlaces_d1g0v0_Shanghai - - opc23DiffPlaces_d10g0v0_Shanghai - - opc22DiffPlaces_d25g0v0_Shanghai - - opc23DiffPlaces_d11g0v0_Shanghai - - opc22DiffPlaces_d26g0v0_Shanghai - - opc23DiffPlaces_d12g0v0_Shanghai - - opc23DiffPlaces_d13g0v0_Shanghai - - opc22DiffPlaces_d27g0v0_Shanghai - - opc22DiffPlaces_d28g0v0_Shanghai - - opc23DiffPlaces_d14g0v0_Shanghai - - opc22DiffPlaces_d29g0v0_Shanghai - - opc23DiffPlaces_d15g0v0_Shanghai - - opc22DiffPlaces_d30g0v0_Shanghai - - opc22DiffPlaces_d31g0v0_Shanghai - - opc22DiffPlaces_d32g0v0_Shanghai - - opc23DiffPlaces_d16g0v0_Shanghai - - opc23DiffPlaces_d2g0v0_Shanghai - - opc22DiffPlaces_d34g0v0_Shanghai - - opc22DiffPlaces_d33g0v0_Shanghai - - opc23DiffPlaces_d17g0v0_Shanghai - - opc23DiffPlaces_d18g0v0_Shanghai - - opc23DiffPlaces_d19g0v0_Shanghai - - opc23DiffPlaces_d3g0v0_Shanghai - - opc24DiffPlaces_d0g0v0_Shanghai - - opc23DiffPlaces_d20g0v0_Shanghai - - opc23DiffPlaces_d4g0v0_Shanghai - - opc23DiffPlaces_d21g0v0_Shanghai - - opc23DiffPlaces_d22g0v0_Shanghai - - opc23DiffPlaces_d23g0v0_Shanghai - - opc23DiffPlaces_d5g0v0_Shanghai - - opc23DiffPlaces_d6g0v0_Shanghai - - opc23DiffPlaces_d7g0v0_Shanghai - - opc23DiffPlaces_d8g0v0_Shanghai - - opc23DiffPlaces_d24g0v0_Shanghai - - opc23DiffPlaces_d9g0v0_Shanghai - - opc24DiffPlaces_d1g0v0_Shanghai - - opc24DiffPlaces_d10g0v0_Shanghai - - opc23DiffPlaces_d25g0v0_Shanghai - - opc23DiffPlaces_d26g0v0_Shanghai - - opc24DiffPlaces_d11g0v0_Shanghai - - opc24DiffPlaces_d12g0v0_Shanghai - - opc23DiffPlaces_d27g0v0_Shanghai - - opc24DiffPlaces_d13g0v0_Shanghai - - opc23DiffPlaces_d28g0v0_Shanghai - - opc24DiffPlaces_d14g0v0_Shanghai - - opc24DiffPlaces_d15g0v0_Shanghai - - opc23DiffPlaces_d29g0v0_Shanghai - - opc23DiffPlaces_d30g0v0_Shanghai - - opc24DiffPlaces_d16g0v0_Shanghai - - opc23DiffPlaces_d32g0v0_Shanghai - - opc24DiffPlaces_d2g0v0_Shanghai - - opc23DiffPlaces_d31g0v0_Shanghai - - opc23DiffPlaces_d33g0v0_Shanghai - - opc23DiffPlaces_d34g0v0_Shanghai - - opc24DiffPlaces_d17g0v0_Shanghai - - opc24DiffPlaces_d18g0v0_Shanghai - - opc24DiffPlaces_d19g0v0_Shanghai - - opc24DiffPlaces_d3g0v0_Shanghai - - opc25DiffPlaces_d0g0v0_Shanghai - - opc24DiffPlaces_d21g0v0_Shanghai - - opc24DiffPlaces_d4g0v0_Shanghai - - opc24DiffPlaces_d20g0v0_Shanghai - - opc24DiffPlaces_d22g0v0_Shanghai - - opc24DiffPlaces_d23g0v0_Shanghai - - opc24DiffPlaces_d5g0v0_Shanghai - - opc24DiffPlaces_d6g0v0_Shanghai - - opc24DiffPlaces_d7g0v0_Shanghai - - opc24DiffPlaces_d8g0v0_Shanghai - - opc24DiffPlaces_d24g0v0_Shanghai - - opc24DiffPlaces_d9g0v0_Shanghai - - opc24DiffPlaces_d25g0v0_Shanghai - - opc25DiffPlaces_d1g0v0_Shanghai - - opc25DiffPlaces_d10g0v0_Shanghai - - opc24DiffPlaces_d26g0v0_Shanghai - - opc25DiffPlaces_d11g0v0_Shanghai - - opc25DiffPlaces_d12g0v0_Shanghai - - opc24DiffPlaces_d27g0v0_Shanghai - - opc25DiffPlaces_d13g0v0_Shanghai - - opc24DiffPlaces_d28g0v0_Shanghai - - opc25DiffPlaces_d14g0v0_Shanghai - - opc24DiffPlaces_d29g0v0_Shanghai - - opc25DiffPlaces_d15g0v0_Shanghai - - opc25DiffPlaces_d16g0v0_Shanghai - - opc24DiffPlaces_d30g0v0_Shanghai - - opc24DiffPlaces_d31g0v0_Shanghai - - opc24DiffPlaces_d32g0v0_Shanghai - - opc25DiffPlaces_d2g0v0_Shanghai - - opc24DiffPlaces_d33g0v0_Shanghai - - opc25DiffPlaces_d17g0v0_Shanghai - - opc24DiffPlaces_d34g0v0_Shanghai - - opc25DiffPlaces_d18g0v0_Shanghai - - opc25DiffPlaces_d3g0v0_Shanghai - - opc26DiffPlaces_d0g0v0_Shanghai - - opc25DiffPlaces_d19g0v0_Shanghai - - opc25DiffPlaces_d21g0v0_Shanghai - - opc25DiffPlaces_d4g0v0_Shanghai - - opc25DiffPlaces_d20g0v0_Shanghai - - opc25DiffPlaces_d22g0v0_Shanghai - - opc25DiffPlaces_d5g0v0_Shanghai - - opc25DiffPlaces_d23g0v0_Shanghai - - opc25DiffPlaces_d6g0v0_Shanghai - - opc25DiffPlaces_d7g0v0_Shanghai - - opc25DiffPlaces_d8g0v0_Shanghai - - opc25DiffPlaces_d9g0v0_Shanghai - - opc25DiffPlaces_d24g0v0_Shanghai - - opc26DiffPlaces_d1g0v0_Shanghai - - opc26DiffPlaces_d10g0v0_Shanghai - - opc25DiffPlaces_d25g0v0_Shanghai - - opc26DiffPlaces_d11g0v0_Shanghai - - opc25DiffPlaces_d26g0v0_Shanghai - - opc26DiffPlaces_d12g0v0_Shanghai - - opc25DiffPlaces_d27g0v0_Shanghai - - opc26DiffPlaces_d13g0v0_Shanghai - - opc25DiffPlaces_d28g0v0_Shanghai - - opc26DiffPlaces_d14g0v0_Shanghai - - opc26DiffPlaces_d15g0v0_Shanghai - - opc25DiffPlaces_d29g0v0_Shanghai - - opc26DiffPlaces_d16g0v0_Shanghai - - opc25DiffPlaces_d30g0v0_Shanghai - - opc25DiffPlaces_d31g0v0_Shanghai - - opc25DiffPlaces_d32g0v0_Shanghai - - opc26DiffPlaces_d2g0v0_Shanghai - - opc25DiffPlaces_d33g0v0_Shanghai - - opc25DiffPlaces_d34g0v0_Shanghai - - opc26DiffPlaces_d17g0v0_Shanghai - - opc26DiffPlaces_d18g0v0_Shanghai - - opc26DiffPlaces_d19g0v0_Shanghai - - opc26DiffPlaces_d3g0v0_Shanghai - - opc27DiffPlaces_d0g0v0_Shanghai - - opc26DiffPlaces_d21g0v0_Shanghai - - opc26DiffPlaces_d4g0v0_Shanghai - - opc26DiffPlaces_d20g0v0_Shanghai - - opc26DiffPlaces_d22g0v0_Shanghai - - opc26DiffPlaces_d23g0v0_Shanghai - - opc26DiffPlaces_d5g0v0_Shanghai - - opc26DiffPlaces_d6g0v0_Shanghai - - opc26DiffPlaces_d7g0v0_Shanghai - - opc26DiffPlaces_d8g0v0_Shanghai - - opc26DiffPlaces_d24g0v0_Shanghai - - opc26DiffPlaces_d9g0v0_Shanghai - - opc27DiffPlaces_d1g0v0_Shanghai - - opc26DiffPlaces_d25g0v0_Shanghai - - opc27DiffPlaces_d10g0v0_Shanghai - - opc26DiffPlaces_d26g0v0_Shanghai - - opc27DiffPlaces_d11g0v0_Shanghai - - opc27DiffPlaces_d12g0v0_Shanghai - - opc26DiffPlaces_d27g0v0_Shanghai - - opc27DiffPlaces_d13g0v0_Shanghai - - opc26DiffPlaces_d28g0v0_Shanghai - - opc27DiffPlaces_d14g0v0_Shanghai - - opc26DiffPlaces_d29g0v0_Shanghai - - opc27DiffPlaces_d15g0v0_Shanghai - - opc27DiffPlaces_d16g0v0_Shanghai - - opc26DiffPlaces_d30g0v0_Shanghai - - opc26DiffPlaces_d31g0v0_Shanghai - - opc27DiffPlaces_d2g0v0_Shanghai - - opc26DiffPlaces_d33g0v0_Shanghai - - opc26DiffPlaces_d32g0v0_Shanghai - - opc26DiffPlaces_d34g0v0_Shanghai - - opc27DiffPlaces_d17g0v0_Shanghai - - opc27DiffPlaces_d18g0v0_Shanghai - - opc27DiffPlaces_d19g0v0_Shanghai - - opc27DiffPlaces_d3g0v0_Shanghai - - opc28DiffPlaces_d0g0v0_Shanghai - - opc27DiffPlaces_d21g0v0_Shanghai - - opc27DiffPlaces_d4g0v0_Shanghai - - opc27DiffPlaces_d20g0v0_Shanghai - - opc27DiffPlaces_d22g0v0_Shanghai - - opc27DiffPlaces_d5g0v0_Shanghai - - opc27DiffPlaces_d23g0v0_Shanghai - - opc27DiffPlaces_d6g0v0_Shanghai - - opc27DiffPlaces_d7g0v0_Shanghai - - opc27DiffPlaces_d8g0v0_Shanghai - - opc27DiffPlaces_d9g0v0_Shanghai - - opc27DiffPlaces_d24g0v0_Shanghai - - opc28DiffPlaces_d1g0v0_Shanghai - - opc27DiffPlaces_d25g0v0_Shanghai - - opc28DiffPlaces_d10g0v0_Shanghai - - opc28DiffPlaces_d11g0v0_Shanghai - - opc27DiffPlaces_d26g0v0_Shanghai - - opc28DiffPlaces_d12g0v0_Shanghai - - opc27DiffPlaces_d27g0v0_Shanghai - - opc28DiffPlaces_d13g0v0_Shanghai - - opc28DiffPlaces_d14g0v0_Shanghai - - opc27DiffPlaces_d28g0v0_Shanghai - - opc28DiffPlaces_d15g0v0_Shanghai - - opc27DiffPlaces_d29g0v0_Shanghai - - opc27DiffPlaces_d30g0v0_Shanghai - - opc28DiffPlaces_d16g0v0_Shanghai - - opc27DiffPlaces_d31g0v0_Shanghai - - opc28DiffPlaces_d2g0v0_Shanghai - - opc27DiffPlaces_d32g0v0_Shanghai - - opc27DiffPlaces_d33g0v0_Shanghai - - opc27DiffPlaces_d34g0v0_Shanghai - - opc28DiffPlaces_d17g0v0_Shanghai - - opc28DiffPlaces_d18g0v0_Shanghai - - opc28DiffPlaces_d19g0v0_Shanghai - - opc28DiffPlaces_d3g0v0_Shanghai - - opc28DiffPlaces_d21g0v0_Shanghai - - opc29DiffPlaces_d0g0v0_Shanghai - - opc28DiffPlaces_d20g0v0_Shanghai - - opc28DiffPlaces_d22g0v0_Shanghai - - opc28DiffPlaces_d4g0v0_Shanghai - - opc28DiffPlaces_d23g0v0_Shanghai - - opc28DiffPlaces_d5g0v0_Shanghai - - opc28DiffPlaces_d6g0v0_Shanghai - - opc28DiffPlaces_d7g0v0_Shanghai - - opc28DiffPlaces_d8g0v0_Shanghai - - opc28DiffPlaces_d24g0v0_Shanghai - - opc28DiffPlaces_d9g0v0_Shanghai - - opc29DiffPlaces_d1g0v0_Shanghai - - opc28DiffPlaces_d25g0v0_Shanghai - - opc29DiffPlaces_d10g0v0_Shanghai - - opc28DiffPlaces_d26g0v0_Shanghai - - opc29DiffPlaces_d11g0v0_Shanghai - - opc29DiffPlaces_d12g0v0_Shanghai - - opc28DiffPlaces_d27g0v0_Shanghai - - opc29DiffPlaces_d13g0v0_Shanghai - - opc28DiffPlaces_d28g0v0_Shanghai - - opc29DiffPlaces_d14g0v0_Shanghai - - opc28DiffPlaces_d29g0v0_Shanghai - - opc29DiffPlaces_d15g0v0_Shanghai - - opc29DiffPlaces_d16g0v0_Shanghai - - opc28DiffPlaces_d30g0v0_Shanghai - - opc29DiffPlaces_d2g0v0_Shanghai - - opc28DiffPlaces_d31g0v0_Shanghai - - opc28DiffPlaces_d32g0v0_Shanghai - - opc28DiffPlaces_d33g0v0_Shanghai - - opc28DiffPlaces_d34g0v0_Shanghai - - opc29DiffPlaces_d17g0v0_Shanghai - - opc29DiffPlaces_d18g0v0_Shanghai - - opc29DiffPlaces_d3g0v0_Shanghai - - opc29DiffPlaces_d19g0v0_Shanghai - - opc29DiffPlaces_d21g0v0_Shanghai - - opc29DiffPlaces_d4g0v0_Shanghai - - opc2ADiffPlaces_d0g0v0_Shanghai - - opc29DiffPlaces_d20g0v0_Shanghai - - opc29DiffPlaces_d22g0v0_Shanghai - - opc29DiffPlaces_d5g0v0_Shanghai - - opc29DiffPlaces_d23g0v0_Shanghai - - opc29DiffPlaces_d6g0v0_Shanghai - - opc29DiffPlaces_d7g0v0_Shanghai - - opc29DiffPlaces_d8g0v0_Shanghai - - opc29DiffPlaces_d24g0v0_Shanghai - - opc29DiffPlaces_d9g0v0_Shanghai - - opc2ADiffPlaces_d1g0v0_Shanghai - - opc29DiffPlaces_d25g0v0_Shanghai - - opc2ADiffPlaces_d10g0v0_Shanghai - - opc29DiffPlaces_d26g0v0_Shanghai - - opc2ADiffPlaces_d11g0v0_Shanghai - - opc2ADiffPlaces_d12g0v0_Shanghai - - opc29DiffPlaces_d27g0v0_Shanghai - - opc2ADiffPlaces_d13g0v0_Shanghai - - opc29DiffPlaces_d28g0v0_Shanghai - - opc2ADiffPlaces_d14g0v0_Shanghai - - opc29DiffPlaces_d29g0v0_Shanghai - - opc2ADiffPlaces_d15g0v0_Shanghai - - opc29DiffPlaces_d30g0v0_Shanghai - - opc2ADiffPlaces_d16g0v0_Shanghai - - opc2ADiffPlaces_d2g0v0_Shanghai - - opc29DiffPlaces_d31g0v0_Shanghai - - opc29DiffPlaces_d33g0v0_Shanghai - - opc29DiffPlaces_d32g0v0_Shanghai - - opc29DiffPlaces_d34g0v0_Shanghai - - opc2ADiffPlaces_d17g0v0_Shanghai - - opc2ADiffPlaces_d18g0v0_Shanghai - - opc2ADiffPlaces_d19g0v0_Shanghai - - opc2ADiffPlaces_d3g0v0_Shanghai - - opc2ADiffPlaces_d21g0v0_Shanghai - - opc2BDiffPlaces_d0g0v0_Shanghai - - opc2ADiffPlaces_d4g0v0_Shanghai - - opc2ADiffPlaces_d20g0v0_Shanghai - - opc2ADiffPlaces_d22g0v0_Shanghai - - opc2ADiffPlaces_d23g0v0_Shanghai - - opc2ADiffPlaces_d5g0v0_Shanghai - - opc2ADiffPlaces_d6g0v0_Shanghai - - opc2ADiffPlaces_d7g0v0_Shanghai - - opc2ADiffPlaces_d8g0v0_Shanghai - - opc2ADiffPlaces_d24g0v0_Shanghai - - opc2ADiffPlaces_d9g0v0_Shanghai - - opc2ADiffPlaces_d25g0v0_Shanghai - - opc2BDiffPlaces_d1g0v0_Shanghai - - opc2BDiffPlaces_d10g0v0_Shanghai - - opc2ADiffPlaces_d26g0v0_Shanghai - - opc2BDiffPlaces_d11g0v0_Shanghai - - opc2BDiffPlaces_d12g0v0_Shanghai - - opc2ADiffPlaces_d27g0v0_Shanghai - - opc2BDiffPlaces_d13g0v0_Shanghai - - opc2ADiffPlaces_d28g0v0_Shanghai - - opc2BDiffPlaces_d14g0v0_Shanghai - - opc2ADiffPlaces_d29g0v0_Shanghai - - opc2BDiffPlaces_d15g0v0_Shanghai - - opc2ADiffPlaces_d31g0v0_Shanghai - - opc2BDiffPlaces_d16g0v0_Shanghai - - opc2ADiffPlaces_d30g0v0_Shanghai - - opc2BDiffPlaces_d2g0v0_Shanghai - - opc2ADiffPlaces_d32g0v0_Shanghai - - opc2ADiffPlaces_d33g0v0_Shanghai - - opc2ADiffPlaces_d34g0v0_Shanghai - - opc2BDiffPlaces_d17g0v0_Shanghai - - opc2BDiffPlaces_d18g0v0_Shanghai - - opc2BDiffPlaces_d3g0v0_Shanghai - - opc2BDiffPlaces_d19g0v0_Shanghai - - opc2BDiffPlaces_d21g0v0_Shanghai - - opc2BDiffPlaces_d4g0v0_Shanghai - - opc2CDiffPlaces_d0g0v0_Shanghai - - opc2BDiffPlaces_d22g0v0_Shanghai - - opc2BDiffPlaces_d20g0v0_Shanghai - - opc2BDiffPlaces_d23g0v0_Shanghai - - opc2BDiffPlaces_d5g0v0_Shanghai - - opc2BDiffPlaces_d6g0v0_Shanghai - - opc2BDiffPlaces_d7g0v0_Shanghai - - opc2BDiffPlaces_d8g0v0_Shanghai - - opc2BDiffPlaces_d24g0v0_Shanghai - - opc2BDiffPlaces_d9g0v0_Shanghai - - opc2CDiffPlaces_d1g0v0_Shanghai - - opc2BDiffPlaces_d25g0v0_Shanghai - - opc2CDiffPlaces_d10g0v0_Shanghai - - opc2CDiffPlaces_d11g0v0_Shanghai - - opc2BDiffPlaces_d26g0v0_Shanghai - - opc2CDiffPlaces_d12g0v0_Shanghai - - opc2BDiffPlaces_d27g0v0_Shanghai - - opc2CDiffPlaces_d13g0v0_Shanghai - - opc2BDiffPlaces_d28g0v0_Shanghai - - opc2CDiffPlaces_d14g0v0_Shanghai - - opc2BDiffPlaces_d29g0v0_Shanghai - - opc2CDiffPlaces_d15g0v0_Shanghai - - opc2BDiffPlaces_d30g0v0_Shanghai - - opc2CDiffPlaces_d16g0v0_Shanghai - - opc2BDiffPlaces_d31g0v0_Shanghai - - opc2CDiffPlaces_d2g0v0_Shanghai - - opc2BDiffPlaces_d32g0v0_Shanghai - - opc2BDiffPlaces_d33g0v0_Shanghai - - opc2BDiffPlaces_d34g0v0_Shanghai - - opc2CDiffPlaces_d17g0v0_Shanghai - - opc2CDiffPlaces_d18g0v0_Shanghai - - opc2CDiffPlaces_d19g0v0_Shanghai - - opc2CDiffPlaces_d3g0v0_Shanghai - - opc2CDiffPlaces_d21g0v0_Shanghai - - opc2DDiffPlaces_d0g0v0_Shanghai - - opc2CDiffPlaces_d20g0v0_Shanghai - - opc2CDiffPlaces_d22g0v0_Shanghai - - opc2CDiffPlaces_d4g0v0_Shanghai - - opc2CDiffPlaces_d23g0v0_Shanghai - - opc2CDiffPlaces_d5g0v0_Shanghai - - opc2CDiffPlaces_d6g0v0_Shanghai - - opc2CDiffPlaces_d7g0v0_Shanghai - - opc2CDiffPlaces_d8g0v0_Shanghai - - opc2CDiffPlaces_d24g0v0_Shanghai - - opc2CDiffPlaces_d9g0v0_Shanghai - - opc2DDiffPlaces_d1g0v0_Shanghai - - opc2CDiffPlaces_d25g0v0_Shanghai - - opc2DDiffPlaces_d10g0v0_Shanghai - - opc2CDiffPlaces_d26g0v0_Shanghai - - opc2DDiffPlaces_d11g0v0_Shanghai - - opc2DDiffPlaces_d12g0v0_Shanghai - - opc2CDiffPlaces_d27g0v0_Shanghai - - opc2DDiffPlaces_d13g0v0_Shanghai - - opc2CDiffPlaces_d28g0v0_Shanghai - - opc2DDiffPlaces_d14g0v0_Shanghai - - opc2DDiffPlaces_d15g0v0_Shanghai - - opc2CDiffPlaces_d29g0v0_Shanghai - - opc2DDiffPlaces_d16g0v0_Shanghai - - opc2CDiffPlaces_d30g0v0_Shanghai - - opc2CDiffPlaces_d31g0v0_Shanghai - - opc2DDiffPlaces_d2g0v0_Shanghai - - opc2CDiffPlaces_d32g0v0_Shanghai - - opc2CDiffPlaces_d33g0v0_Shanghai - - opc2CDiffPlaces_d34g0v0_Shanghai - - opc2DDiffPlaces_d17g0v0_Shanghai - - opc2DDiffPlaces_d18g0v0_Shanghai - - opc2DDiffPlaces_d3g0v0_Shanghai - - opc2DDiffPlaces_d19g0v0_Shanghai - - opc2EDiffPlaces_d0g0v0_Shanghai - - opc2DDiffPlaces_d21g0v0_Shanghai - - opc2DDiffPlaces_d4g0v0_Shanghai - - opc2DDiffPlaces_d20g0v0_Shanghai - - opc2DDiffPlaces_d22g0v0_Shanghai - - opc2DDiffPlaces_d5g0v0_Shanghai - - opc2DDiffPlaces_d23g0v0_Shanghai - - opc2DDiffPlaces_d6g0v0_Shanghai - - opc2DDiffPlaces_d7g0v0_Shanghai - - opc2DDiffPlaces_d8g0v0_Shanghai - - opc2DDiffPlaces_d24g0v0_Shanghai - - opc2DDiffPlaces_d9g0v0_Shanghai - - opc2EDiffPlaces_d1g0v0_Shanghai - - opc2DDiffPlaces_d25g0v0_Shanghai - - opc2EDiffPlaces_d10g0v0_Shanghai - - opc2DDiffPlaces_d26g0v0_Shanghai - - opc2EDiffPlaces_d11g0v0_Shanghai - - opc2EDiffPlaces_d12g0v0_Shanghai - - opc2DDiffPlaces_d27g0v0_Shanghai - - opc2EDiffPlaces_d13g0v0_Shanghai - - opc2DDiffPlaces_d28g0v0_Shanghai - - opc2EDiffPlaces_d14g0v0_Shanghai - - opc2DDiffPlaces_d29g0v0_Shanghai - - opc2EDiffPlaces_d15g0v0_Shanghai - - opc2DDiffPlaces_d30g0v0_Shanghai - - opc2DDiffPlaces_d31g0v0_Shanghai - - opc2EDiffPlaces_d16g0v0_Shanghai - - opc2DDiffPlaces_d32g0v0_Shanghai - - opc2EDiffPlaces_d2g0v0_Shanghai - - opc2DDiffPlaces_d33g0v0_Shanghai - - opc2DDiffPlaces_d34g0v0_Shanghai - - opc2EDiffPlaces_d17g0v0_Shanghai - - opc2EDiffPlaces_d18g0v0_Shanghai - - opc2EDiffPlaces_d19g0v0_Shanghai - - opc2EDiffPlaces_d3g0v0_Shanghai - - opc2EDiffPlaces_d21g0v0_Shanghai - - opc2FDiffPlaces_d0g0v0_Shanghai - - opc2EDiffPlaces_d20g0v0_Shanghai - - opc2EDiffPlaces_d22g0v0_Shanghai - - opc2EDiffPlaces_d4g0v0_Shanghai - - opc2EDiffPlaces_d23g0v0_Shanghai - - opc2EDiffPlaces_d5g0v0_Shanghai - - opc2EDiffPlaces_d6g0v0_Shanghai - - opc2EDiffPlaces_d7g0v0_Shanghai - - opc2EDiffPlaces_d8g0v0_Shanghai - - opc2EDiffPlaces_d24g0v0_Shanghai - - opc2EDiffPlaces_d9g0v0_Shanghai - - opc2EDiffPlaces_d25g0v0_Shanghai - - opc2FDiffPlaces_d1g0v0_Shanghai - - opc2FDiffPlaces_d10g0v0_Shanghai - - opc2EDiffPlaces_d26g0v0_Shanghai - - opc2FDiffPlaces_d11g0v0_Shanghai - - opc2FDiffPlaces_d12g0v0_Shanghai - - opc2EDiffPlaces_d27g0v0_Shanghai - - opc2FDiffPlaces_d13g0v0_Shanghai - - opc2FDiffPlaces_d14g0v0_Shanghai - - opc2EDiffPlaces_d28g0v0_Shanghai - - opc2EDiffPlaces_d29g0v0_Shanghai - - opc2FDiffPlaces_d15g0v0_Shanghai - - opc2EDiffPlaces_d30g0v0_Shanghai - - opc2EDiffPlaces_d31g0v0_Shanghai - - opc2FDiffPlaces_d16g0v0_Shanghai - - opc2EDiffPlaces_d32g0v0_Shanghai - - opc2EDiffPlaces_d33g0v0_Shanghai - - opc2FDiffPlaces_d2g0v0_Shanghai - - opc2EDiffPlaces_d34g0v0_Shanghai - - opc2FDiffPlaces_d17g0v0_Shanghai - - opc2FDiffPlaces_d18g0v0_Shanghai - - opc2FDiffPlaces_d3g0v0_Shanghai - - opc2FDiffPlaces_d19g0v0_Shanghai - - opc2FDiffPlaces_d4g0v0_Shanghai - - opc2FDiffPlaces_d21g0v0_Shanghai - - opc49DiffPlaces_d0g0v0_Shanghai - - opc2FDiffPlaces_d20g0v0_Shanghai - - opc2FDiffPlaces_d22g0v0_Shanghai - - opc2FDiffPlaces_d23g0v0_Shanghai - - opc2FDiffPlaces_d5g0v0_Shanghai - - opc2FDiffPlaces_d6g0v0_Shanghai - - opc2FDiffPlaces_d7g0v0_Shanghai - - opc2FDiffPlaces_d8g0v0_Shanghai - - opc2FDiffPlaces_d24g0v0_Shanghai - - opc2FDiffPlaces_d9g0v0_Shanghai - - opc2FDiffPlaces_d25g0v0_Shanghai - - opc49DiffPlaces_d1g0v0_Shanghai - - opc49DiffPlaces_d10g0v0_Shanghai - - opc2FDiffPlaces_d26g0v0_Shanghai - - opc49DiffPlaces_d11g0v0_Shanghai - - opc49DiffPlaces_d12g0v0_Shanghai - - opc2FDiffPlaces_d27g0v0_Shanghai - - opc49DiffPlaces_d13g0v0_Shanghai - - opc2FDiffPlaces_d28g0v0_Shanghai - - opc2FDiffPlaces_d29g0v0_Shanghai - - opc49DiffPlaces_d14g0v0_Shanghai - - opc49DiffPlaces_d15g0v0_Shanghai - - opc2FDiffPlaces_d30g0v0_Shanghai - - opc2FDiffPlaces_d31g0v0_Shanghai - - opc49DiffPlaces_d2g0v0_Shanghai - - opc49DiffPlaces_d16g0v0_Shanghai - - opc2FDiffPlaces_d33g0v0_Shanghai - - opc2FDiffPlaces_d32g0v0_Shanghai - - opc2FDiffPlaces_d34g0v0_Shanghai - - opc49DiffPlaces_d17g0v0_Shanghai - - opc49DiffPlaces_d18g0v0_Shanghai - - opc49DiffPlaces_d19g0v0_Shanghai - - opc49DiffPlaces_d3g0v0_Shanghai - - opc49DiffPlaces_d21g0v0_Shanghai - - opc4ADiffPlaces_d0g0v0_Shanghai - - opc49DiffPlaces_d4g0v0_Shanghai - - opc49DiffPlaces_d20g0v0_Shanghai - - opc49DiffPlaces_d22g0v0_Shanghai - - opc49DiffPlaces_d23g0v0_Shanghai - - opc49DiffPlaces_d5g0v0_Shanghai - - opc49DiffPlaces_d6g0v0_Shanghai - - opc49DiffPlaces_d7g0v0_Shanghai - - opc49DiffPlaces_d8g0v0_Shanghai - - opc49DiffPlaces_d24g0v0_Shanghai - - opc49DiffPlaces_d9g0v0_Shanghai - - opc49DiffPlaces_d25g0v0_Shanghai - - opc4ADiffPlaces_d1g0v0_Shanghai - - opc4ADiffPlaces_d10g0v0_Shanghai - - opc4ADiffPlaces_d11g0v0_Shanghai - - opc49DiffPlaces_d26g0v0_Shanghai - - opc4ADiffPlaces_d12g0v0_Shanghai - - opc49DiffPlaces_d27g0v0_Shanghai - - opc4ADiffPlaces_d13g0v0_Shanghai - - opc49DiffPlaces_d28g0v0_Shanghai - - opc4ADiffPlaces_d14g0v0_Shanghai - - opc49DiffPlaces_d29g0v0_Shanghai - - opc4ADiffPlaces_d15g0v0_Shanghai - - opc49DiffPlaces_d30g0v0_Shanghai - - opc4ADiffPlaces_d16g0v0_Shanghai - - opc49DiffPlaces_d31g0v0_Shanghai - - opc4ADiffPlaces_d2g0v0_Shanghai - - opc49DiffPlaces_d32g0v0_Shanghai - - opc49DiffPlaces_d33g0v0_Shanghai - - opc49DiffPlaces_d34g0v0_Shanghai - - opc4ADiffPlaces_d17g0v0_Shanghai - - opc4ADiffPlaces_d18g0v0_Shanghai - - opc4ADiffPlaces_d3g0v0_Shanghai - - opc4ADiffPlaces_d19g0v0_Shanghai - - opc4ADiffPlaces_d21g0v0_Shanghai - - opc4BDiffPlaces_d0g0v0_Shanghai - - opc4ADiffPlaces_d20g0v0_Shanghai - - opc4ADiffPlaces_d4g0v0_Shanghai - - opc4ADiffPlaces_d22g0v0_Shanghai - - opc4ADiffPlaces_d23g0v0_Shanghai - - opc4ADiffPlaces_d5g0v0_Shanghai - - opc4ADiffPlaces_d6g0v0_Shanghai - - opc4ADiffPlaces_d7g0v0_Shanghai - - opc4ADiffPlaces_d8g0v0_Shanghai - - opc4ADiffPlaces_d9g0v0_Shanghai - - opc4ADiffPlaces_d24g0v0_Shanghai - - opc4BDiffPlaces_d1g0v0_Shanghai - - opc4ADiffPlaces_d25g0v0_Shanghai - - opc4BDiffPlaces_d10g0v0_Shanghai - - opc4BDiffPlaces_d11g0v0_Shanghai - - opc4ADiffPlaces_d26g0v0_Shanghai - - opc4BDiffPlaces_d12g0v0_Shanghai - - opc4BDiffPlaces_d13g0v0_Shanghai - - opc4ADiffPlaces_d27g0v0_Shanghai - - opc4BDiffPlaces_d14g0v0_Shanghai - - opc4ADiffPlaces_d28g0v0_Shanghai - - opc4ADiffPlaces_d29g0v0_Shanghai - - opc4BDiffPlaces_d15g0v0_Shanghai - - opc4BDiffPlaces_d16g0v0_Shanghai - - opc4ADiffPlaces_d30g0v0_Shanghai - - opc4ADiffPlaces_d31g0v0_Shanghai - - opc4BDiffPlaces_d2g0v0_Shanghai - - opc4ADiffPlaces_d32g0v0_Shanghai - - opc4ADiffPlaces_d33g0v0_Shanghai - - opc4ADiffPlaces_d34g0v0_Shanghai - - opc4BDiffPlaces_d17g0v0_Shanghai - - opc4BDiffPlaces_d18g0v0_Shanghai - - opc4BDiffPlaces_d19g0v0_Shanghai - - opc4BDiffPlaces_d3g0v0_Shanghai - - opc4BDiffPlaces_d21g0v0_Shanghai - - opc4CDiffPlaces_d0g0v0_Shanghai - - opc4BDiffPlaces_d20g0v0_Shanghai - - opc4BDiffPlaces_d4g0v0_Shanghai - - opc4BDiffPlaces_d22g0v0_Shanghai - - opc4BDiffPlaces_d5g0v0_Shanghai - - opc4BDiffPlaces_d23g0v0_Shanghai - - opc4BDiffPlaces_d6g0v0_Shanghai - - opc4BDiffPlaces_d7g0v0_Shanghai - - opc4BDiffPlaces_d8g0v0_Shanghai - - opc4BDiffPlaces_d24g0v0_Shanghai - - opc4BDiffPlaces_d9g0v0_Shanghai - - opc4BDiffPlaces_d25g0v0_Shanghai - - opc4CDiffPlaces_d1g0v0_Shanghai - - opc4CDiffPlaces_d10g0v0_Shanghai - - opc4CDiffPlaces_d11g0v0_Shanghai - - opc4BDiffPlaces_d26g0v0_Shanghai - - opc4BDiffPlaces_d27g0v0_Shanghai - - opc4CDiffPlaces_d12g0v0_Shanghai - - opc4CDiffPlaces_d13g0v0_Shanghai - - opc4BDiffPlaces_d28g0v0_Shanghai - - opc4CDiffPlaces_d14g0v0_Shanghai - - opc4CDiffPlaces_d15g0v0_Shanghai - - opc4BDiffPlaces_d29g0v0_Shanghai - - opc4CDiffPlaces_d16g0v0_Shanghai - - opc4BDiffPlaces_d30g0v0_Shanghai - - opc4BDiffPlaces_d31g0v0_Shanghai - - opc4BDiffPlaces_d32g0v0_Shanghai - - opc4BDiffPlaces_d33g0v0_Shanghai - - opc4CDiffPlaces_d2g0v0_Shanghai - - opc4BDiffPlaces_d34g0v0_Shanghai - - opc4CDiffPlaces_d17g0v0_Shanghai - - opc4CDiffPlaces_d18g0v0_Shanghai - - opc4CDiffPlaces_d19g0v0_Shanghai - - opc4CDiffPlaces_d3g0v0_Shanghai - - opc4CDiffPlaces_d4g0v0_Shanghai - - opc4DDiffPlaces_d0g0v0_Shanghai - - opc4CDiffPlaces_d21g0v0_Shanghai - - opc4CDiffPlaces_d20g0v0_Shanghai - - opc4CDiffPlaces_d22g0v0_Shanghai - - opc4CDiffPlaces_d23g0v0_Shanghai - - opc4CDiffPlaces_d5g0v0_Shanghai - - opc4CDiffPlaces_d6g0v0_Shanghai - - opc4CDiffPlaces_d7g0v0_Shanghai - - opc4CDiffPlaces_d8g0v0_Shanghai - - opc4CDiffPlaces_d24g0v0_Shanghai - - opc4CDiffPlaces_d9g0v0_Shanghai - - opc4DDiffPlaces_d1g0v0_Shanghai - - opc4CDiffPlaces_d25g0v0_Shanghai - - opc4DDiffPlaces_d10g0v0_Shanghai - - opc4CDiffPlaces_d26g0v0_Shanghai - - opc4DDiffPlaces_d11g0v0_Shanghai - - opc4DDiffPlaces_d12g0v0_Shanghai - - opc4CDiffPlaces_d27g0v0_Shanghai - - opc4DDiffPlaces_d13g0v0_Shanghai - - opc4CDiffPlaces_d28g0v0_Shanghai - - opc4DDiffPlaces_d14g0v0_Shanghai - - opc4CDiffPlaces_d29g0v0_Shanghai - - opc4DDiffPlaces_d15g0v0_Shanghai - - opc4DDiffPlaces_d16g0v0_Shanghai - - opc4CDiffPlaces_d30g0v0_Shanghai - - opc4CDiffPlaces_d31g0v0_Shanghai - - opc4DDiffPlaces_d2g0v0_Shanghai - - opc4CDiffPlaces_d32g0v0_Shanghai - - opc4CDiffPlaces_d33g0v0_Shanghai - - opc4CDiffPlaces_d34g0v0_Shanghai - - opc4DDiffPlaces_d17g0v0_Shanghai - - opc4DDiffPlaces_d18g0v0_Shanghai - - opc4DDiffPlaces_d19g0v0_Shanghai - - opc4DDiffPlaces_d3g0v0_Shanghai - - opc4DDiffPlaces_d21g0v0_Shanghai - - opc4EDiffPlaces_d0g0v0_Shanghai - - opc4DDiffPlaces_d20g0v0_Shanghai - - opc4DDiffPlaces_d4g0v0_Shanghai - - opc4DDiffPlaces_d22g0v0_Shanghai - - opc4DDiffPlaces_d23g0v0_Shanghai - - opc4DDiffPlaces_d5g0v0_Shanghai - - opc4DDiffPlaces_d6g0v0_Shanghai - - opc4DDiffPlaces_d7g0v0_Shanghai - - opc4DDiffPlaces_d8g0v0_Shanghai - - opc4DDiffPlaces_d24g0v0_Shanghai - - opc4DDiffPlaces_d9g0v0_Shanghai - - opc4DDiffPlaces_d25g0v0_Shanghai - - opc4EDiffPlaces_d1g0v0_Shanghai - - opc4EDiffPlaces_d10g0v0_Shanghai - - opc4DDiffPlaces_d26g0v0_Shanghai - - opc4EDiffPlaces_d11g0v0_Shanghai - - opc4EDiffPlaces_d12g0v0_Shanghai - - opc4DDiffPlaces_d27g0v0_Shanghai - - opc4EDiffPlaces_d13g0v0_Shanghai - - opc4DDiffPlaces_d28g0v0_Shanghai - - opc4EDiffPlaces_d14g0v0_Shanghai - - opc4DDiffPlaces_d29g0v0_Shanghai - - opc4EDiffPlaces_d15g0v0_Shanghai - - opc4EDiffPlaces_d16g0v0_Shanghai - - opc4DDiffPlaces_d30g0v0_Shanghai - - opc4DDiffPlaces_d31g0v0_Shanghai - - opc4EDiffPlaces_d2g0v0_Shanghai - - opc4DDiffPlaces_d32g0v0_Shanghai - - opc4DDiffPlaces_d33g0v0_Shanghai - - opc4DDiffPlaces_d34g0v0_Shanghai - - opc4EDiffPlaces_d17g0v0_Shanghai - - opc4EDiffPlaces_d18g0v0_Shanghai - - opc4EDiffPlaces_d19g0v0_Shanghai - - opc4EDiffPlaces_d3g0v0_Shanghai - - opc4FDiffPlaces_d0g0v0_Shanghai - - opc4EDiffPlaces_d21g0v0_Shanghai - - opc4EDiffPlaces_d20g0v0_Shanghai - - opc4EDiffPlaces_d4g0v0_Shanghai - - opc4EDiffPlaces_d22g0v0_Shanghai - - opc4EDiffPlaces_d23g0v0_Shanghai - - opc4EDiffPlaces_d5g0v0_Shanghai - - opc4EDiffPlaces_d6g0v0_Shanghai - - opc4EDiffPlaces_d7g0v0_Shanghai - - opc4EDiffPlaces_d8g0v0_Shanghai - - opc4EDiffPlaces_d9g0v0_Shanghai - - opc4EDiffPlaces_d24g0v0_Shanghai - - opc4FDiffPlaces_d1g0v0_Shanghai - - opc4EDiffPlaces_d25g0v0_Shanghai - - opc4FDiffPlaces_d10g0v0_Shanghai - - opc4FDiffPlaces_d11g0v0_Shanghai - - opc4EDiffPlaces_d26g0v0_Shanghai - - opc4FDiffPlaces_d12g0v0_Shanghai - - opc4EDiffPlaces_d27g0v0_Shanghai - - opc4FDiffPlaces_d13g0v0_Shanghai - - opc4EDiffPlaces_d28g0v0_Shanghai - - opc4FDiffPlaces_d14g0v0_Shanghai - - opc4EDiffPlaces_d29g0v0_Shanghai - - opc4FDiffPlaces_d15g0v0_Shanghai - - opc4EDiffPlaces_d30g0v0_Shanghai - - opc4EDiffPlaces_d31g0v0_Shanghai - - opc4FDiffPlaces_d16g0v0_Shanghai - - opc4EDiffPlaces_d32g0v0_Shanghai - - opc4FDiffPlaces_d2g0v0_Shanghai - - opc4EDiffPlaces_d33g0v0_Shanghai - - opc4EDiffPlaces_d34g0v0_Shanghai - - opc4FDiffPlaces_d17g0v0_Shanghai - - opc4FDiffPlaces_d18g0v0_Shanghai - - opc4FDiffPlaces_d19g0v0_Shanghai - - opc4FDiffPlaces_d3g0v0_Shanghai - - opc4FDiffPlaces_d21g0v0_Shanghai - - opc5CDiffPlaces_d0g0v0_Shanghai - - opc4FDiffPlaces_d20g0v0_Shanghai - - opc4FDiffPlaces_d4g0v0_Shanghai - - opc4FDiffPlaces_d22g0v0_Shanghai - - opc4FDiffPlaces_d5g0v0_Shanghai - - opc4FDiffPlaces_d23g0v0_Shanghai - - opc4FDiffPlaces_d6g0v0_Shanghai - - opc4FDiffPlaces_d7g0v0_Shanghai - - opc4FDiffPlaces_d8g0v0_Shanghai - - opc4FDiffPlaces_d24g0v0_Shanghai - - opc4FDiffPlaces_d9g0v0_Shanghai - - opc5CDiffPlaces_d1g0v0_Shanghai - - opc4FDiffPlaces_d25g0v0_Shanghai - - opc5CDiffPlaces_d10g0v0_Shanghai - - opc5CDiffPlaces_d11g0v0_Shanghai - - opc4FDiffPlaces_d26g0v0_Shanghai - - opc5CDiffPlaces_d12g0v0_Shanghai - - opc4FDiffPlaces_d27g0v0_Shanghai - - opc5CDiffPlaces_d13g0v0_Shanghai - - opc4FDiffPlaces_d28g0v0_Shanghai - - opc5CDiffPlaces_d14g0v0_Shanghai - - opc5CDiffPlaces_d15g0v0_Shanghai - - opc4FDiffPlaces_d29g0v0_Shanghai - - opc4FDiffPlaces_d30g0v0_Shanghai - - opc5CDiffPlaces_d16g0v0_Shanghai - - opc4FDiffPlaces_d31g0v0_Shanghai - - opc5CDiffPlaces_d2g0v0_Shanghai - - opc4FDiffPlaces_d32g0v0_Shanghai - - opc4FDiffPlaces_d33g0v0_Shanghai - - opc4FDiffPlaces_d34g0v0_Shanghai - - opc5CDiffPlaces_d17g0v0_Shanghai - - opc5CDiffPlaces_d18g0v0_Shanghai - - opc5CDiffPlaces_d19g0v0_Shanghai - - opc5CDiffPlaces_d3g0v0_Shanghai - - opc5DDiffPlaces_d0g0v0_Shanghai - - opc5CDiffPlaces_d21g0v0_Shanghai - - opc5CDiffPlaces_d4g0v0_Shanghai - - opc5CDiffPlaces_d20g0v0_Shanghai - - opc5CDiffPlaces_d22g0v0_Shanghai - - opc5CDiffPlaces_d5g0v0_Shanghai - - opc5CDiffPlaces_d23g0v0_Shanghai - - opc5CDiffPlaces_d6g0v0_Shanghai - - opc5CDiffPlaces_d7g0v0_Shanghai - - opc5CDiffPlaces_d8g0v0_Shanghai - - opc5CDiffPlaces_d9g0v0_Shanghai - - opc5CDiffPlaces_d24g0v0_Shanghai - - opc5DDiffPlaces_d1g0v0_Shanghai - - opc5DDiffPlaces_d10g0v0_Shanghai - - opc5CDiffPlaces_d26g0v0_Shanghai - - opc5CDiffPlaces_d25g0v0_Shanghai - - opc5DDiffPlaces_d11g0v0_Shanghai - - opc5DDiffPlaces_d12g0v0_Shanghai - - opc5DDiffPlaces_d13g0v0_Shanghai - - opc5CDiffPlaces_d27g0v0_Shanghai - - opc5CDiffPlaces_d28g0v0_Shanghai - - opc5DDiffPlaces_d14g0v0_Shanghai - - opc5CDiffPlaces_d29g0v0_Shanghai - - opc5DDiffPlaces_d15g0v0_Shanghai - - opc5DDiffPlaces_d16g0v0_Shanghai - - opc5CDiffPlaces_d30g0v0_Shanghai - - opc5DDiffPlaces_d2g0v0_Shanghai - - opc5CDiffPlaces_d32g0v0_Shanghai - - opc5CDiffPlaces_d31g0v0_Shanghai - - opc5CDiffPlaces_d33g0v0_Shanghai - - opc5CDiffPlaces_d34g0v0_Shanghai - - opc5DDiffPlaces_d17g0v0_Shanghai - - opc5DDiffPlaces_d18g0v0_Shanghai - - opc5DDiffPlaces_d19g0v0_Shanghai - - opc5DDiffPlaces_d3g0v0_Shanghai - - opc5EDiffPlaces_d0g0v0_Shanghai - - opc5DDiffPlaces_d21g0v0_Shanghai - - opc5DDiffPlaces_d20g0v0_Shanghai - - opc5DDiffPlaces_d4g0v0_Shanghai - - opc5DDiffPlaces_d22g0v0_Shanghai - - opc5DDiffPlaces_d5g0v0_Shanghai - - opc5DDiffPlaces_d23g0v0_Shanghai - - opc5DDiffPlaces_d6g0v0_Shanghai - - opc5DDiffPlaces_d7g0v0_Shanghai - - opc5DDiffPlaces_d8g0v0_Shanghai - - opc5DDiffPlaces_d24g0v0_Shanghai - - opc5DDiffPlaces_d9g0v0_Shanghai - - opc5DDiffPlaces_d25g0v0_Shanghai - - opc5EDiffPlaces_d1g0v0_Shanghai - - opc5EDiffPlaces_d10g0v0_Shanghai - - opc5DDiffPlaces_d26g0v0_Shanghai - - opc5EDiffPlaces_d11g0v0_Shanghai - - opc5EDiffPlaces_d12g0v0_Shanghai - - opc5DDiffPlaces_d27g0v0_Shanghai - - opc5EDiffPlaces_d13g0v0_Shanghai - - opc5DDiffPlaces_d28g0v0_Shanghai - - opc5EDiffPlaces_d14g0v0_Shanghai - - opc5EDiffPlaces_d15g0v0_Shanghai - - opc5DDiffPlaces_d29g0v0_Shanghai - - opc5EDiffPlaces_d16g0v0_Shanghai - - opc5DDiffPlaces_d30g0v0_Shanghai - - opc5DDiffPlaces_d31g0v0_Shanghai - - opc5EDiffPlaces_d2g0v0_Shanghai - - opc5DDiffPlaces_d32g0v0_Shanghai - - opc5DDiffPlaces_d34g0v0_Shanghai - - opc5DDiffPlaces_d33g0v0_Shanghai - - opc5EDiffPlaces_d17g0v0_Shanghai - - opc5EDiffPlaces_d18g0v0_Shanghai - - opc5EDiffPlaces_d19g0v0_Shanghai - - opc5EDiffPlaces_d3g0v0_Shanghai - - opc5EDiffPlaces_d4g0v0_Shanghai - - opc5EDiffPlaces_d21g0v0_Shanghai - - opcA5DiffPlaces_d0g0v0_Shanghai - - opc5EDiffPlaces_d20g0v0_Shanghai - - opc5EDiffPlaces_d22g0v0_Shanghai - - opc5EDiffPlaces_d5g0v0_Shanghai - - opc5EDiffPlaces_d23g0v0_Shanghai - - opc5EDiffPlaces_d6g0v0_Shanghai - - opc5EDiffPlaces_d7g0v0_Shanghai - - opc5EDiffPlaces_d8g0v0_Shanghai - - opc5EDiffPlaces_d24g0v0_Shanghai - - opc5EDiffPlaces_d9g0v0_Shanghai - - opc5EDiffPlaces_d25g0v0_Shanghai - - opcA5DiffPlaces_d1g0v0_Shanghai - - opcA5DiffPlaces_d10g0v0_Shanghai - - opcA5DiffPlaces_d11g0v0_Shanghai - - opc5EDiffPlaces_d26g0v0_Shanghai - - opcA5DiffPlaces_d12g0v0_Shanghai - - opc5EDiffPlaces_d27g0v0_Shanghai - - opcA5DiffPlaces_d13g0v0_Shanghai - - opc5EDiffPlaces_d28g0v0_Shanghai - - opcA5DiffPlaces_d14g0v0_Shanghai - - opc5EDiffPlaces_d29g0v0_Shanghai - - opcA5DiffPlaces_d15g0v0_Shanghai - - opc5EDiffPlaces_d30g0v0_Shanghai - - opcA5DiffPlaces_d16g0v0_Shanghai - - opc5EDiffPlaces_d31g0v0_Shanghai - - opcA5DiffPlaces_d2g0v0_Shanghai - - opc5EDiffPlaces_d32g0v0_Shanghai - - opc5EDiffPlaces_d33g0v0_Shanghai - - opc5EDiffPlaces_d34g0v0_Shanghai - - opcA5DiffPlaces_d17g0v0_Shanghai - - opcA5DiffPlaces_d18g0v0_Shanghai - - opcA5DiffPlaces_d19g0v0_Shanghai - - opcA5DiffPlaces_d3g0v0_Shanghai - - opcA5DiffPlaces_d21g0v0_Shanghai - - opcA6DiffPlaces_d0g0v0_Shanghai - - opcA5DiffPlaces_d20g0v0_Shanghai - - opcA5DiffPlaces_d4g0v0_Shanghai - - opcA5DiffPlaces_d22g0v0_Shanghai - - opcA5DiffPlaces_d23g0v0_Shanghai - - opcA5DiffPlaces_d5g0v0_Shanghai - - opcA5DiffPlaces_d6g0v0_Shanghai - - opcA5DiffPlaces_d7g0v0_Shanghai - - opcA5DiffPlaces_d8g0v0_Shanghai - - opcA5DiffPlaces_d24g0v0_Shanghai - - opcA5DiffPlaces_d9g0v0_Shanghai - - opcA6DiffPlaces_d1g0v0_Shanghai - - opcA5DiffPlaces_d25g0v0_Shanghai - - opcA6DiffPlaces_d10g0v0_Shanghai - - opcA6DiffPlaces_d11g0v0_Shanghai - - opcA5DiffPlaces_d26g0v0_Shanghai - - opcA6DiffPlaces_d12g0v0_Shanghai - - opcA5DiffPlaces_d27g0v0_Shanghai - - opcA6DiffPlaces_d13g0v0_Shanghai - - opcA5DiffPlaces_d28g0v0_Shanghai - - opcA6DiffPlaces_d14g0v0_Shanghai - - opcA5DiffPlaces_d29g0v0_Shanghai - - opcA6DiffPlaces_d15g0v0_Shanghai - - opcA6DiffPlaces_d16g0v0_Shanghai - - opcA5DiffPlaces_d30g0v0_Shanghai - - opcA5DiffPlaces_d31g0v0_Shanghai - - opcA5DiffPlaces_d32g0v0_Shanghai - - opcA6DiffPlaces_d2g0v0_Shanghai - - opcA5DiffPlaces_d34g0v0_Shanghai - - opcA5DiffPlaces_d33g0v0_Shanghai - - opcA6DiffPlaces_d17g0v0_Shanghai - - opcA6DiffPlaces_d18g0v0_Shanghai - - opcA6DiffPlaces_d19g0v0_Shanghai - - opcA6DiffPlaces_d3g0v0_Shanghai - - opcA7DiffPlaces_d0g0v0_Shanghai - - opcA6DiffPlaces_d21g0v0_Shanghai - - opcA6DiffPlaces_d20g0v0_Shanghai - - opcA6DiffPlaces_d4g0v0_Shanghai - - opcA6DiffPlaces_d22g0v0_Shanghai - - opcA6DiffPlaces_d23g0v0_Shanghai - - opcA6DiffPlaces_d5g0v0_Shanghai - - opcA6DiffPlaces_d6g0v0_Shanghai - - opcA6DiffPlaces_d7g0v0_Shanghai - - opcA6DiffPlaces_d8g0v0_Shanghai - - opcA6DiffPlaces_d9g0v0_Shanghai - - opcA6DiffPlaces_d24g0v0_Shanghai - - opcA7DiffPlaces_d1g0v0_Shanghai - - opcA6DiffPlaces_d25g0v0_Shanghai - - opcA7DiffPlaces_d10g0v0_Shanghai - - opcA7DiffPlaces_d11g0v0_Shanghai - - opcA6DiffPlaces_d26g0v0_Shanghai - - opcA7DiffPlaces_d12g0v0_Shanghai - - opcA6DiffPlaces_d27g0v0_Shanghai - - opcA7DiffPlaces_d13g0v0_Shanghai - - opcA6DiffPlaces_d28g0v0_Shanghai - - opcA7DiffPlaces_d14g0v0_Shanghai - - opcA6DiffPlaces_d29g0v0_Shanghai - - opcA7DiffPlaces_d15g0v0_Shanghai - - opcA6DiffPlaces_d30g0v0_Shanghai - - opcA7DiffPlaces_d16g0v0_Shanghai - - opcA6DiffPlaces_d31g0v0_Shanghai - - opcA7DiffPlaces_d2g0v0_Shanghai - - opcA6DiffPlaces_d32g0v0_Shanghai - - opcA6DiffPlaces_d33g0v0_Shanghai - - opcA6DiffPlaces_d34g0v0_Shanghai - - opcA7DiffPlaces_d17g0v0_Shanghai - - opcA7DiffPlaces_d18g0v0_Shanghai - - opcA7DiffPlaces_d19g0v0_Shanghai - - opcA7DiffPlaces_d3g0v0_Shanghai - - opcA7DiffPlaces_d21g0v0_Shanghai - - opcA8DiffPlaces_d0g0v0_Shanghai - - opcA7DiffPlaces_d4g0v0_Shanghai - - opcA7DiffPlaces_d20g0v0_Shanghai - - opcA7DiffPlaces_d22g0v0_Shanghai - - opcA7DiffPlaces_d23g0v0_Shanghai - - opcA7DiffPlaces_d5g0v0_Shanghai - - opcA7DiffPlaces_d6g0v0_Shanghai - - opcA7DiffPlaces_d7g0v0_Shanghai - - opcA7DiffPlaces_d8g0v0_Shanghai - - opcA7DiffPlaces_d24g0v0_Shanghai - - opcA7DiffPlaces_d9g0v0_Shanghai - - opcA8DiffPlaces_d1g0v0_Shanghai - - opcA7DiffPlaces_d25g0v0_Shanghai - - opcA8DiffPlaces_d10g0v0_Shanghai - - opcA8DiffPlaces_d11g0v0_Shanghai - - opcA7DiffPlaces_d26g0v0_Shanghai - - opcA8DiffPlaces_d12g0v0_Shanghai - - opcA7DiffPlaces_d27g0v0_Shanghai - - opcA8DiffPlaces_d13g0v0_Shanghai - - opcA7DiffPlaces_d28g0v0_Shanghai - - opcA8DiffPlaces_d14g0v0_Shanghai - - opcA7DiffPlaces_d29g0v0_Shanghai - - opcA8DiffPlaces_d15g0v0_Shanghai - - opcA8DiffPlaces_d16g0v0_Shanghai - - opcA7DiffPlaces_d30g0v0_Shanghai - - opcA7DiffPlaces_d31g0v0_Shanghai - - opcA8DiffPlaces_d2g0v0_Shanghai - - opcA7DiffPlaces_d32g0v0_Shanghai - - opcA7DiffPlaces_d33g0v0_Shanghai - - opcA7DiffPlaces_d34g0v0_Shanghai - - opcA8DiffPlaces_d17g0v0_Shanghai - - opcA8DiffPlaces_d18g0v0_Shanghai - - opcA8DiffPlaces_d3g0v0_Shanghai - - opcA8DiffPlaces_d19g0v0_Shanghai - - opcA8DiffPlaces_d21g0v0_Shanghai - - opcA9DiffPlaces_d0g0v0_Shanghai - - opcA8DiffPlaces_d4g0v0_Shanghai - - opcA8DiffPlaces_d20g0v0_Shanghai - - opcA8DiffPlaces_d22g0v0_Shanghai - - opcA8DiffPlaces_d5g0v0_Shanghai - - opcA8DiffPlaces_d23g0v0_Shanghai - - opcA8DiffPlaces_d6g0v0_Shanghai - - opcA8DiffPlaces_d7g0v0_Shanghai - - opcA8DiffPlaces_d8g0v0_Shanghai - - opcA8DiffPlaces_d9g0v0_Shanghai - - opcA8DiffPlaces_d24g0v0_Shanghai - - opcA9DiffPlaces_d1g0v0_Shanghai - - opcA8DiffPlaces_d25g0v0_Shanghai - - opcA9DiffPlaces_d10g0v0_Shanghai - - opcA8DiffPlaces_d26g0v0_Shanghai - - opcA9DiffPlaces_d11g0v0_Shanghai - - opcA9DiffPlaces_d12g0v0_Shanghai - - opcA8DiffPlaces_d27g0v0_Shanghai - - opcA9DiffPlaces_d13g0v0_Shanghai - - opcA9DiffPlaces_d14g0v0_Shanghai - - opcA8DiffPlaces_d28g0v0_Shanghai - - opcA9DiffPlaces_d15g0v0_Shanghai - - opcA8DiffPlaces_d29g0v0_Shanghai - - opcA9DiffPlaces_d16g0v0_Shanghai - - opcA8DiffPlaces_d30g0v0_Shanghai - - opcA8DiffPlaces_d31g0v0_Shanghai - - opcA8DiffPlaces_d32g0v0_Shanghai - - opcA9DiffPlaces_d2g0v0_Shanghai - - opcA8DiffPlaces_d33g0v0_Shanghai - - opcA8DiffPlaces_d34g0v0_Shanghai - - opcA9DiffPlaces_d17g0v0_Shanghai - - opcA9DiffPlaces_d18g0v0_Shanghai - - opcA9DiffPlaces_d19g0v0_Shanghai - - opcA9DiffPlaces_d3g0v0_Shanghai - - opcA9DiffPlaces_d21g0v0_Shanghai - - opcA9DiffPlaces_d20g0v0_Shanghai - - opcAADiffPlaces_d0g0v0_Shanghai - - opcA9DiffPlaces_d4g0v0_Shanghai - - opcA9DiffPlaces_d22g0v0_Shanghai - - opcA9DiffPlaces_d23g0v0_Shanghai - - opcA9DiffPlaces_d5g0v0_Shanghai - - opcA9DiffPlaces_d6g0v0_Shanghai - - opcA9DiffPlaces_d7g0v0_Shanghai - - opcA9DiffPlaces_d8g0v0_Shanghai - - opcA9DiffPlaces_d9g0v0_Shanghai - - opcA9DiffPlaces_d24g0v0_Shanghai - - opcAADiffPlaces_d1g0v0_Shanghai - - opcA9DiffPlaces_d25g0v0_Shanghai - - opcAADiffPlaces_d10g0v0_Shanghai - - opcA9DiffPlaces_d26g0v0_Shanghai - - opcAADiffPlaces_d11g0v0_Shanghai - - opcAADiffPlaces_d12g0v0_Shanghai - - opcA9DiffPlaces_d27g0v0_Shanghai - - opcAADiffPlaces_d13g0v0_Shanghai - - opcA9DiffPlaces_d28g0v0_Shanghai - - opcAADiffPlaces_d14g0v0_Shanghai - - opcA9DiffPlaces_d29g0v0_Shanghai - - opcAADiffPlaces_d15g0v0_Shanghai - - opcAADiffPlaces_d16g0v0_Shanghai - - opcA9DiffPlaces_d30g0v0_Shanghai - - opcA9DiffPlaces_d32g0v0_Shanghai - - opcAADiffPlaces_d2g0v0_Shanghai - - opcA9DiffPlaces_d31g0v0_Shanghai - - opcA9DiffPlaces_d33g0v0_Shanghai - - opcA9DiffPlaces_d34g0v0_Shanghai - - opcAADiffPlaces_d17g0v0_Shanghai - - opcAADiffPlaces_d18g0v0_Shanghai - - opcAADiffPlaces_d19g0v0_Shanghai - - opcAADiffPlaces_d3g0v0_Shanghai - - opcAADiffPlaces_d21g0v0_Shanghai - - opcABDiffPlaces_d0g0v0_Shanghai - - opcAADiffPlaces_d4g0v0_Shanghai - - opcAADiffPlaces_d22g0v0_Shanghai - - opcAADiffPlaces_d20g0v0_Shanghai - - opcAADiffPlaces_d5g0v0_Shanghai - - opcAADiffPlaces_d23g0v0_Shanghai - - opcAADiffPlaces_d6g0v0_Shanghai - - opcAADiffPlaces_d7g0v0_Shanghai - - opcAADiffPlaces_d8g0v0_Shanghai - - opcAADiffPlaces_d9g0v0_Shanghai - - opcAADiffPlaces_d24g0v0_Shanghai - - opcABDiffPlaces_d1g0v0_Shanghai - - opcAADiffPlaces_d25g0v0_Shanghai - - opcABDiffPlaces_d10g0v0_Shanghai - - opcAADiffPlaces_d26g0v0_Shanghai - - opcABDiffPlaces_d11g0v0_Shanghai - - opcABDiffPlaces_d12g0v0_Shanghai - - opcAADiffPlaces_d27g0v0_Shanghai - - opcABDiffPlaces_d13g0v0_Shanghai - - opcAADiffPlaces_d28g0v0_Shanghai - - opcABDiffPlaces_d14g0v0_Shanghai - - opcAADiffPlaces_d29g0v0_Shanghai - - opcABDiffPlaces_d15g0v0_Shanghai - - opcAADiffPlaces_d30g0v0_Shanghai - - opcAADiffPlaces_d31g0v0_Shanghai - - opcABDiffPlaces_d16g0v0_Shanghai - - opcABDiffPlaces_d2g0v0_Shanghai - - opcAADiffPlaces_d32g0v0_Shanghai - - opcAADiffPlaces_d33g0v0_Shanghai - - opcAADiffPlaces_d34g0v0_Shanghai - - opcABDiffPlaces_d17g0v0_Shanghai - - opcABDiffPlaces_d18g0v0_Shanghai - - opcABDiffPlaces_d19g0v0_Shanghai - - opcABDiffPlaces_d3g0v0_Shanghai - - opcABDiffPlaces_d21g0v0_Shanghai - - opcACDiffPlaces_d0g0v0_Shanghai - - opcABDiffPlaces_d4g0v0_Shanghai - - opcABDiffPlaces_d20g0v0_Shanghai - - opcABDiffPlaces_d22g0v0_Shanghai - - opcABDiffPlaces_d23g0v0_Shanghai - - opcABDiffPlaces_d5g0v0_Shanghai - - opcABDiffPlaces_d6g0v0_Shanghai - - opcABDiffPlaces_d7g0v0_Shanghai - - opcABDiffPlaces_d8g0v0_Shanghai - - opcABDiffPlaces_d9g0v0_Shanghai - - opcABDiffPlaces_d24g0v0_Shanghai - - opcACDiffPlaces_d1g0v0_Shanghai - - opcABDiffPlaces_d25g0v0_Shanghai - - opcACDiffPlaces_d10g0v0_Shanghai - - opcACDiffPlaces_d11g0v0_Shanghai - - opcABDiffPlaces_d26g0v0_Shanghai - - opcACDiffPlaces_d12g0v0_Shanghai - - opcABDiffPlaces_d27g0v0_Shanghai - - opcACDiffPlaces_d13g0v0_Shanghai - - opcABDiffPlaces_d28g0v0_Shanghai - - opcACDiffPlaces_d14g0v0_Shanghai - - opcABDiffPlaces_d29g0v0_Shanghai - - opcACDiffPlaces_d15g0v0_Shanghai - - opcACDiffPlaces_d16g0v0_Shanghai - - opcABDiffPlaces_d30g0v0_Shanghai - - opcABDiffPlaces_d31g0v0_Shanghai - - opcACDiffPlaces_d2g0v0_Shanghai - - opcABDiffPlaces_d32g0v0_Shanghai - - opcABDiffPlaces_d33g0v0_Shanghai - - opcABDiffPlaces_d34g0v0_Shanghai - - opcACDiffPlaces_d17g0v0_Shanghai - - opcACDiffPlaces_d18g0v0_Shanghai - - opcACDiffPlaces_d19g0v0_Shanghai - - opcACDiffPlaces_d3g0v0_Shanghai - - opcADDiffPlaces_d0g0v0_Shanghai - - opcACDiffPlaces_d21g0v0_Shanghai - - opcACDiffPlaces_d4g0v0_Shanghai - - opcACDiffPlaces_d20g0v0_Shanghai - - opcACDiffPlaces_d22g0v0_Shanghai - - opcACDiffPlaces_d5g0v0_Shanghai - - opcACDiffPlaces_d23g0v0_Shanghai - - opcACDiffPlaces_d6g0v0_Shanghai - - opcACDiffPlaces_d7g0v0_Shanghai - - opcACDiffPlaces_d8g0v0_Shanghai - - opcACDiffPlaces_d24g0v0_Shanghai - - opcACDiffPlaces_d9g0v0_Shanghai - - opcADDiffPlaces_d1g0v0_Shanghai - - opcACDiffPlaces_d25g0v0_Shanghai - - opcADDiffPlaces_d10g0v0_Shanghai - - opcACDiffPlaces_d26g0v0_Shanghai - - opcADDiffPlaces_d11g0v0_Shanghai - - opcADDiffPlaces_d12g0v0_Shanghai - - opcACDiffPlaces_d27g0v0_Shanghai - - opcADDiffPlaces_d13g0v0_Shanghai - - opcACDiffPlaces_d28g0v0_Shanghai - - opcADDiffPlaces_d14g0v0_Shanghai - - opcACDiffPlaces_d29g0v0_Shanghai - - opcADDiffPlaces_d15g0v0_Shanghai - - opcADDiffPlaces_d16g0v0_Shanghai - - opcACDiffPlaces_d30g0v0_Shanghai - - opcACDiffPlaces_d31g0v0_Shanghai - - opcACDiffPlaces_d32g0v0_Shanghai - - opcADDiffPlaces_d2g0v0_Shanghai - - opcACDiffPlaces_d33g0v0_Shanghai - - opcACDiffPlaces_d34g0v0_Shanghai - - opcADDiffPlaces_d17g0v0_Shanghai - - opcADDiffPlaces_d18g0v0_Shanghai - - opcADDiffPlaces_d19g0v0_Shanghai - - opcADDiffPlaces_d3g0v0_Shanghai - - opcAEDiffPlaces_d0g0v0_Shanghai - - opcADDiffPlaces_d21g0v0_Shanghai - - opcADDiffPlaces_d4g0v0_Shanghai - - opcADDiffPlaces_d20g0v0_Shanghai - - opcADDiffPlaces_d22g0v0_Shanghai - - opcADDiffPlaces_d5g0v0_Shanghai - - opcADDiffPlaces_d23g0v0_Shanghai - - opcADDiffPlaces_d6g0v0_Shanghai - - opcADDiffPlaces_d7g0v0_Shanghai - - opcADDiffPlaces_d8g0v0_Shanghai - - opcADDiffPlaces_d24g0v0_Shanghai - - opcADDiffPlaces_d9g0v0_Shanghai - - opcADDiffPlaces_d25g0v0_Shanghai - - opcAEDiffPlaces_d1g0v0_Shanghai - - opcAEDiffPlaces_d10g0v0_Shanghai - - opcADDiffPlaces_d26g0v0_Shanghai - - opcAEDiffPlaces_d11g0v0_Shanghai - - opcAEDiffPlaces_d12g0v0_Shanghai - - opcADDiffPlaces_d27g0v0_Shanghai - - opcAEDiffPlaces_d13g0v0_Shanghai - - opcADDiffPlaces_d28g0v0_Shanghai - - opcAEDiffPlaces_d14g0v0_Shanghai - - opcADDiffPlaces_d29g0v0_Shanghai - - opcAEDiffPlaces_d15g0v0_Shanghai - - opcAEDiffPlaces_d16g0v0_Shanghai - - opcADDiffPlaces_d30g0v0_Shanghai - - opcAEDiffPlaces_d2g0v0_Shanghai - - opcADDiffPlaces_d32g0v0_Shanghai - - opcADDiffPlaces_d31g0v0_Shanghai - - opcADDiffPlaces_d33g0v0_Shanghai - - opcADDiffPlaces_d34g0v0_Shanghai - - opcAEDiffPlaces_d17g0v0_Shanghai - - opcAEDiffPlaces_d18g0v0_Shanghai - - opcAEDiffPlaces_d19g0v0_Shanghai - - opcAEDiffPlaces_d3g0v0_Shanghai - - opcAEDiffPlaces_d21g0v0_Shanghai - - opcAFDiffPlaces_d0g0v0_Shanghai - - opcAEDiffPlaces_d4g0v0_Shanghai - - opcAEDiffPlaces_d20g0v0_Shanghai - - opcAEDiffPlaces_d22g0v0_Shanghai - - opcAEDiffPlaces_d5g0v0_Shanghai - - opcAEDiffPlaces_d23g0v0_Shanghai - - opcAEDiffPlaces_d6g0v0_Shanghai - - opcAEDiffPlaces_d7g0v0_Shanghai - - opcAEDiffPlaces_d8g0v0_Shanghai - - opcAEDiffPlaces_d24g0v0_Shanghai - - opcAEDiffPlaces_d9g0v0_Shanghai - - opcAEDiffPlaces_d25g0v0_Shanghai - - opcAFDiffPlaces_d1g0v0_Shanghai - - opcAFDiffPlaces_d10g0v0_Shanghai - - opcAEDiffPlaces_d26g0v0_Shanghai - - opcAFDiffPlaces_d11g0v0_Shanghai - - opcAFDiffPlaces_d12g0v0_Shanghai - - opcAFDiffPlaces_d13g0v0_Shanghai - - opcAEDiffPlaces_d27g0v0_Shanghai - - opcAEDiffPlaces_d28g0v0_Shanghai - - opcAFDiffPlaces_d14g0v0_Shanghai - - opcAEDiffPlaces_d29g0v0_Shanghai - - opcAFDiffPlaces_d15g0v0_Shanghai - - opcAEDiffPlaces_d30g0v0_Shanghai - - opcAFDiffPlaces_d16g0v0_Shanghai - - opcAEDiffPlaces_d31g0v0_Shanghai - - opcAFDiffPlaces_d2g0v0_Shanghai - - opcAEDiffPlaces_d32g0v0_Shanghai - - opcAEDiffPlaces_d33g0v0_Shanghai - - opcAEDiffPlaces_d34g0v0_Shanghai - - opcAFDiffPlaces_d17g0v0_Shanghai - - opcAFDiffPlaces_d18g0v0_Shanghai - - opcAFDiffPlaces_d19g0v0_Shanghai - - opcAFDiffPlaces_d3g0v0_Shanghai - - opcAFDiffPlaces_d21g0v0_Shanghai - - opcB0DiffPlaces_d0g0v0_Shanghai - - opcAFDiffPlaces_d4g0v0_Shanghai - - opcAFDiffPlaces_d20g0v0_Shanghai - - opcAFDiffPlaces_d22g0v0_Shanghai - - opcAFDiffPlaces_d23g0v0_Shanghai - - opcAFDiffPlaces_d5g0v0_Shanghai - - opcAFDiffPlaces_d6g0v0_Shanghai - - opcAFDiffPlaces_d7g0v0_Shanghai - - opcAFDiffPlaces_d8g0v0_Shanghai - - opcAFDiffPlaces_d9g0v0_Shanghai - - opcAFDiffPlaces_d24g0v0_Shanghai - - opcAFDiffPlaces_d25g0v0_Shanghai - - opcB0DiffPlaces_d1g0v0_Shanghai - - opcB0DiffPlaces_d10g0v0_Shanghai - - opcB0DiffPlaces_d11g0v0_Shanghai - - opcAFDiffPlaces_d26g0v0_Shanghai - - opcB0DiffPlaces_d12g0v0_Shanghai - - opcB0DiffPlaces_d13g0v0_Shanghai - - opcAFDiffPlaces_d27g0v0_Shanghai - - opcAFDiffPlaces_d28g0v0_Shanghai - - opcB0DiffPlaces_d14g0v0_Shanghai - - opcAFDiffPlaces_d29g0v0_Shanghai - - opcB0DiffPlaces_d15g0v0_Shanghai - - opcAFDiffPlaces_d30g0v0_Shanghai - - opcB0DiffPlaces_d16g0v0_Shanghai - - opcAFDiffPlaces_d31g0v0_Shanghai - - opcB0DiffPlaces_d2g0v0_Shanghai - - opcAFDiffPlaces_d32g0v0_Shanghai - - opcAFDiffPlaces_d33g0v0_Shanghai - - opcAFDiffPlaces_d34g0v0_Shanghai - - opcB0DiffPlaces_d17g0v0_Shanghai - - opcB0DiffPlaces_d18g0v0_Shanghai - - opcB0DiffPlaces_d3g0v0_Shanghai - - opcB0DiffPlaces_d19g0v0_Shanghai - - opcB1DiffPlaces_d0g0v0_Shanghai - - opcB0DiffPlaces_d21g0v0_Shanghai - - opcB0DiffPlaces_d20g0v0_Shanghai - - opcB0DiffPlaces_d4g0v0_Shanghai - - opcB0DiffPlaces_d22g0v0_Shanghai - - opcB0DiffPlaces_d5g0v0_Shanghai - - opcB0DiffPlaces_d23g0v0_Shanghai - - opcB0DiffPlaces_d6g0v0_Shanghai - - opcB0DiffPlaces_d7g0v0_Shanghai - - opcB0DiffPlaces_d8g0v0_Shanghai - - opcB0DiffPlaces_d24g0v0_Shanghai - - opcB0DiffPlaces_d9g0v0_Shanghai - - opcB0DiffPlaces_d25g0v0_Shanghai - - opcB1DiffPlaces_d1g0v0_Shanghai - - opcB1DiffPlaces_d10g0v0_Shanghai - - opcB1DiffPlaces_d11g0v0_Shanghai - - opcB0DiffPlaces_d26g0v0_Shanghai - - opcB1DiffPlaces_d12g0v0_Shanghai - - opcB0DiffPlaces_d27g0v0_Shanghai - - opcB1DiffPlaces_d13g0v0_Shanghai - - opcB0DiffPlaces_d28g0v0_Shanghai - - opcB1DiffPlaces_d14g0v0_Shanghai - - opcB0DiffPlaces_d29g0v0_Shanghai - - opcB1DiffPlaces_d15g0v0_Shanghai - - opcB1DiffPlaces_d16g0v0_Shanghai - - opcB0DiffPlaces_d30g0v0_Shanghai - - opcB0DiffPlaces_d31g0v0_Shanghai - - opcB0DiffPlaces_d32g0v0_Shanghai - - opcB1DiffPlaces_d2g0v0_Shanghai - - opcB0DiffPlaces_d33g0v0_Shanghai - - opcB0DiffPlaces_d34g0v0_Shanghai - - opcB1DiffPlaces_d17g0v0_Shanghai - - opcB1DiffPlaces_d18g0v0_Shanghai - - opcB1DiffPlaces_d19g0v0_Shanghai - - opcB1DiffPlaces_d3g0v0_Shanghai - - opcB1DiffPlaces_d21g0v0_Shanghai - - opcB1DiffPlaces_d4g0v0_Shanghai - - opcB2DiffPlaces_d0g0v0_Shanghai - - opcB1DiffPlaces_d22g0v0_Shanghai - - opcB1DiffPlaces_d20g0v0_Shanghai - - opcB1DiffPlaces_d5g0v0_Shanghai - - opcB1DiffPlaces_d23g0v0_Shanghai - - opcB1DiffPlaces_d6g0v0_Shanghai - - opcB1DiffPlaces_d7g0v0_Shanghai - - opcB1DiffPlaces_d8g0v0_Shanghai - - opcB1DiffPlaces_d24g0v0_Shanghai - - opcB1DiffPlaces_d9g0v0_Shanghai - - opcB1DiffPlaces_d25g0v0_Shanghai - - opcB2DiffPlaces_d1g0v0_Shanghai - - opcB2DiffPlaces_d10g0v0_Shanghai - - opcB2DiffPlaces_d11g0v0_Shanghai - - opcB1DiffPlaces_d26g0v0_Shanghai - - opcB2DiffPlaces_d12g0v0_Shanghai - - opcB1DiffPlaces_d27g0v0_Shanghai - - opcB2DiffPlaces_d13g0v0_Shanghai - - opcB1DiffPlaces_d28g0v0_Shanghai - - opcB2DiffPlaces_d14g0v0_Shanghai - - opcB1DiffPlaces_d29g0v0_Shanghai - - opcB2DiffPlaces_d15g0v0_Shanghai - - opcB1DiffPlaces_d30g0v0_Shanghai - - opcB2DiffPlaces_d16g0v0_Shanghai - - opcB1DiffPlaces_d31g0v0_Shanghai - - opcB1DiffPlaces_d32g0v0_Shanghai - - opcB2DiffPlaces_d2g0v0_Shanghai - - opcB1DiffPlaces_d33g0v0_Shanghai - - opcB1DiffPlaces_d34g0v0_Shanghai - - opcB2DiffPlaces_d17g0v0_Shanghai - - opcB2DiffPlaces_d18g0v0_Shanghai - - opcB2DiffPlaces_d19g0v0_Shanghai - - opcB2DiffPlaces_d3g0v0_Shanghai - - opcB2DiffPlaces_d21g0v0_Shanghai - - opcB3DiffPlaces_d0g0v0_Shanghai - - opcB2DiffPlaces_d20g0v0_Shanghai - - opcB2DiffPlaces_d4g0v0_Shanghai - - opcB2DiffPlaces_d22g0v0_Shanghai - - opcB2DiffPlaces_d23g0v0_Shanghai - - opcB2DiffPlaces_d5g0v0_Shanghai - - opcB2DiffPlaces_d6g0v0_Shanghai - - opcB2DiffPlaces_d7g0v0_Shanghai - - opcB2DiffPlaces_d8g0v0_Shanghai - - opcB2DiffPlaces_d24g0v0_Shanghai - - opcB2DiffPlaces_d9g0v0_Shanghai - - opcB3DiffPlaces_d1g0v0_Shanghai - - opcB2DiffPlaces_d25g0v0_Shanghai - - opcB3DiffPlaces_d10g0v0_Shanghai - - opcB2DiffPlaces_d26g0v0_Shanghai - - opcB3DiffPlaces_d11g0v0_Shanghai - - opcB3DiffPlaces_d12g0v0_Shanghai - - opcB2DiffPlaces_d27g0v0_Shanghai - - opcB3DiffPlaces_d13g0v0_Shanghai - - opcB2DiffPlaces_d28g0v0_Shanghai - - opcB3DiffPlaces_d14g0v0_Shanghai - - opcB3DiffPlaces_d15g0v0_Shanghai - - opcB2DiffPlaces_d29g0v0_Shanghai - - opcB2DiffPlaces_d30g0v0_Shanghai - - opcB2DiffPlaces_d31g0v0_Shanghai - - opcB3DiffPlaces_d16g0v0_Shanghai - - opcB2DiffPlaces_d32g0v0_Shanghai - - opcB3DiffPlaces_d2g0v0_Shanghai - - opcB2DiffPlaces_d33g0v0_Shanghai - - opcB2DiffPlaces_d34g0v0_Shanghai - - opcB3DiffPlaces_d17g0v0_Shanghai - - opcB3DiffPlaces_d18g0v0_Shanghai - - opcB3DiffPlaces_d19g0v0_Shanghai - - opcB3DiffPlaces_d3g0v0_Shanghai - - opcB3DiffPlaces_d21g0v0_Shanghai - - opcB4DiffPlaces_d0g0v0_Shanghai - - opcB3DiffPlaces_d4g0v0_Shanghai - - opcB3DiffPlaces_d20g0v0_Shanghai - - opcB3DiffPlaces_d22g0v0_Shanghai - - opcB3DiffPlaces_d5g0v0_Shanghai - - opcB3DiffPlaces_d23g0v0_Shanghai - - opcB3DiffPlaces_d6g0v0_Shanghai - - opcB3DiffPlaces_d7g0v0_Shanghai - - opcB3DiffPlaces_d8g0v0_Shanghai - - opcB3DiffPlaces_d9g0v0_Shanghai - - opcB3DiffPlaces_d24g0v0_Shanghai - - opcB4DiffPlaces_d1g0v0_Shanghai - - opcB3DiffPlaces_d25g0v0_Shanghai - - opcB4DiffPlaces_d10g0v0_Shanghai - - opcB4DiffPlaces_d11g0v0_Shanghai - - opcB3DiffPlaces_d26g0v0_Shanghai - - opcB4DiffPlaces_d12g0v0_Shanghai - - opcB3DiffPlaces_d27g0v0_Shanghai - - opcB4DiffPlaces_d13g0v0_Shanghai - - opcB4DiffPlaces_d14g0v0_Shanghai - - opcB3DiffPlaces_d28g0v0_Shanghai - - opcB4DiffPlaces_d15g0v0_Shanghai - - opcB3DiffPlaces_d29g0v0_Shanghai - - opcB3DiffPlaces_d30g0v0_Shanghai - - opcB4DiffPlaces_d16g0v0_Shanghai - - opcB3DiffPlaces_d31g0v0_Shanghai - - opcB4DiffPlaces_d2g0v0_Shanghai - - opcB3DiffPlaces_d32g0v0_Shanghai - - opcB3DiffPlaces_d33g0v0_Shanghai - - opcB3DiffPlaces_d34g0v0_Shanghai - - opcB4DiffPlaces_d17g0v0_Shanghai - - opcB4DiffPlaces_d18g0v0_Shanghai - - opcB4DiffPlaces_d19g0v0_Shanghai - - opcB4DiffPlaces_d3g0v0_Shanghai - - opcB5DiffPlaces_d0g0v0_Shanghai - - opcB4DiffPlaces_d21g0v0_Shanghai - - opcB4DiffPlaces_d20g0v0_Shanghai - - opcB4DiffPlaces_d4g0v0_Shanghai - - opcB4DiffPlaces_d22g0v0_Shanghai - - opcB4DiffPlaces_d5g0v0_Shanghai - - opcB4DiffPlaces_d23g0v0_Shanghai - - opcB4DiffPlaces_d6g0v0_Shanghai - - opcB4DiffPlaces_d7g0v0_Shanghai - - opcB4DiffPlaces_d8g0v0_Shanghai - - opcB4DiffPlaces_d24g0v0_Shanghai - - opcB4DiffPlaces_d9g0v0_Shanghai - - opcB4DiffPlaces_d25g0v0_Shanghai - - opcB5DiffPlaces_d1g0v0_Shanghai - - opcB5DiffPlaces_d10g0v0_Shanghai - - opcB5DiffPlaces_d11g0v0_Shanghai - - opcB4DiffPlaces_d26g0v0_Shanghai - - opcB5DiffPlaces_d12g0v0_Shanghai - - opcB4DiffPlaces_d27g0v0_Shanghai - - opcB5DiffPlaces_d13g0v0_Shanghai - - opcB4DiffPlaces_d28g0v0_Shanghai - - opcB5DiffPlaces_d14g0v0_Shanghai - - opcB4DiffPlaces_d29g0v0_Shanghai - - opcB5DiffPlaces_d15g0v0_Shanghai - - opcB4DiffPlaces_d30g0v0_Shanghai - - opcB5DiffPlaces_d16g0v0_Shanghai - - opcB4DiffPlaces_d31g0v0_Shanghai - - opcB4DiffPlaces_d32g0v0_Shanghai - - opcB5DiffPlaces_d2g0v0_Shanghai - - opcB4DiffPlaces_d33g0v0_Shanghai - - opcB4DiffPlaces_d34g0v0_Shanghai - - opcB5DiffPlaces_d17g0v0_Shanghai - - opcB5DiffPlaces_d18g0v0_Shanghai - - opcB5DiffPlaces_d19g0v0_Shanghai - - opcB5DiffPlaces_d3g0v0_Shanghai - - opcB6DiffPlaces_d0g0v0_Shanghai - - opcB5DiffPlaces_d21g0v0_Shanghai - - opcB5DiffPlaces_d4g0v0_Shanghai - - opcB5DiffPlaces_d20g0v0_Shanghai - - opcB5DiffPlaces_d22g0v0_Shanghai - - opcB5DiffPlaces_d5g0v0_Shanghai - - opcB5DiffPlaces_d23g0v0_Shanghai - - opcB5DiffPlaces_d6g0v0_Shanghai - - opcB5DiffPlaces_d7g0v0_Shanghai - - opcB5DiffPlaces_d8g0v0_Shanghai - - opcB5DiffPlaces_d24g0v0_Shanghai - - opcB5DiffPlaces_d9g0v0_Shanghai - - opcB5DiffPlaces_d25g0v0_Shanghai - - opcB6DiffPlaces_d1g0v0_Shanghai - - opcB6DiffPlaces_d10g0v0_Shanghai - - opcB6DiffPlaces_d11g0v0_Shanghai - - opcB5DiffPlaces_d26g0v0_Shanghai - - opcB6DiffPlaces_d12g0v0_Shanghai - - opcB5DiffPlaces_d27g0v0_Shanghai - - opcB6DiffPlaces_d13g0v0_Shanghai - - opcB5DiffPlaces_d28g0v0_Shanghai - - opcB6DiffPlaces_d14g0v0_Shanghai - - opcB5DiffPlaces_d29g0v0_Shanghai - - opcB6DiffPlaces_d15g0v0_Shanghai - - opcB5DiffPlaces_d30g0v0_Shanghai - - opcB5DiffPlaces_d31g0v0_Shanghai - - opcB6DiffPlaces_d16g0v0_Shanghai - - opcB6DiffPlaces_d2g0v0_Shanghai - - opcB5DiffPlaces_d32g0v0_Shanghai - - opcB5DiffPlaces_d33g0v0_Shanghai - - opcB5DiffPlaces_d34g0v0_Shanghai - - opcB6DiffPlaces_d17g0v0_Shanghai - - opcB6DiffPlaces_d18g0v0_Shanghai - - opcB6DiffPlaces_d19g0v0_Shanghai - - opcB6DiffPlaces_d3g0v0_Shanghai - - opcB6DiffPlaces_d21g0v0_Shanghai - - opcB7DiffPlaces_d0g0v0_Shanghai - - opcB6DiffPlaces_d4g0v0_Shanghai - - opcB6DiffPlaces_d22g0v0_Shanghai - - opcB6DiffPlaces_d20g0v0_Shanghai - - opcB6DiffPlaces_d5g0v0_Shanghai - - opcB6DiffPlaces_d23g0v0_Shanghai - - opcB6DiffPlaces_d6g0v0_Shanghai - - opcB6DiffPlaces_d7g0v0_Shanghai - - opcB6DiffPlaces_d8g0v0_Shanghai - - opcB6DiffPlaces_d9g0v0_Shanghai - - opcB6DiffPlaces_d24g0v0_Shanghai - - opcB6DiffPlaces_d25g0v0_Shanghai - - opcB7DiffPlaces_d1g0v0_Shanghai - - opcB7DiffPlaces_d10g0v0_Shanghai - - opcB6DiffPlaces_d26g0v0_Shanghai - - opcB7DiffPlaces_d11g0v0_Shanghai - - opcB7DiffPlaces_d12g0v0_Shanghai - - opcB6DiffPlaces_d27g0v0_Shanghai - - opcB7DiffPlaces_d13g0v0_Shanghai - - opcB6DiffPlaces_d28g0v0_Shanghai - - opcB7DiffPlaces_d14g0v0_Shanghai - - opcB6DiffPlaces_d29g0v0_Shanghai - - opcB7DiffPlaces_d15g0v0_Shanghai - - opcB6DiffPlaces_d30g0v0_Shanghai - - opcB7DiffPlaces_d16g0v0_Shanghai - - opcB6DiffPlaces_d31g0v0_Shanghai - - opcB7DiffPlaces_d2g0v0_Shanghai - - opcB6DiffPlaces_d32g0v0_Shanghai - - opcB6DiffPlaces_d33g0v0_Shanghai - - opcB6DiffPlaces_d34g0v0_Shanghai - - opcB7DiffPlaces_d17g0v0_Shanghai - - opcB7DiffPlaces_d18g0v0_Shanghai - - opcB7DiffPlaces_d19g0v0_Shanghai - - opcB7DiffPlaces_d3g0v0_Shanghai - - opcB7DiffPlaces_d21g0v0_Shanghai - - opcB7DiffPlaces_d4g0v0_Shanghai - - opcB8DiffPlaces_d0g0v0_Shanghai - - opcB7DiffPlaces_d20g0v0_Shanghai - - opcB7DiffPlaces_d22g0v0_Shanghai - - opcB7DiffPlaces_d5g0v0_Shanghai - - opcB7DiffPlaces_d23g0v0_Shanghai - - opcB7DiffPlaces_d6g0v0_Shanghai - - opcB7DiffPlaces_d7g0v0_Shanghai - - opcB7DiffPlaces_d8g0v0_Shanghai - - opcB7DiffPlaces_d24g0v0_Shanghai - - opcB7DiffPlaces_d9g0v0_Shanghai - - opcB7DiffPlaces_d25g0v0_Shanghai - - opcB8DiffPlaces_d1g0v0_Shanghai - - opcB8DiffPlaces_d10g0v0_Shanghai - - opcB7DiffPlaces_d26g0v0_Shanghai - - opcB8DiffPlaces_d11g0v0_Shanghai - - opcB8DiffPlaces_d12g0v0_Shanghai - - opcB7DiffPlaces_d27g0v0_Shanghai - - opcB8DiffPlaces_d13g0v0_Shanghai - - opcB7DiffPlaces_d28g0v0_Shanghai - - opcB8DiffPlaces_d14g0v0_Shanghai - - opcB7DiffPlaces_d29g0v0_Shanghai - - opcB8DiffPlaces_d15g0v0_Shanghai - - opcB8DiffPlaces_d16g0v0_Shanghai - - opcB7DiffPlaces_d30g0v0_Shanghai - - opcB7DiffPlaces_d31g0v0_Shanghai - - opcB8DiffPlaces_d2g0v0_Shanghai - - opcB7DiffPlaces_d32g0v0_Shanghai - - opcB7DiffPlaces_d33g0v0_Shanghai - - opcB7DiffPlaces_d34g0v0_Shanghai - - opcB8DiffPlaces_d17g0v0_Shanghai - - opcB8DiffPlaces_d18g0v0_Shanghai - - opcB8DiffPlaces_d19g0v0_Shanghai - - opcB8DiffPlaces_d3g0v0_Shanghai - - opcB8DiffPlaces_d21g0v0_Shanghai - - opcB9DiffPlaces_d0g0v0_Shanghai - - opcB8DiffPlaces_d4g0v0_Shanghai - - opcB8DiffPlaces_d20g0v0_Shanghai - - opcB8DiffPlaces_d22g0v0_Shanghai - - opcB8DiffPlaces_d23g0v0_Shanghai - - opcB8DiffPlaces_d5g0v0_Shanghai - - opcB8DiffPlaces_d6g0v0_Shanghai - - opcB8DiffPlaces_d7g0v0_Shanghai - - opcB8DiffPlaces_d8g0v0_Shanghai - - opcB8DiffPlaces_d24g0v0_Shanghai - - opcB8DiffPlaces_d9g0v0_Shanghai - - opcB8DiffPlaces_d25g0v0_Shanghai - - opcB9DiffPlaces_d1g0v0_Shanghai - - opcB9DiffPlaces_d10g0v0_Shanghai - - opcB9DiffPlaces_d11g0v0_Shanghai - - opcB8DiffPlaces_d26g0v0_Shanghai - - opcB9DiffPlaces_d12g0v0_Shanghai - - opcB8DiffPlaces_d27g0v0_Shanghai - - opcB9DiffPlaces_d13g0v0_Shanghai - - opcB8DiffPlaces_d28g0v0_Shanghai - - opcB9DiffPlaces_d14g0v0_Shanghai - - opcB8DiffPlaces_d29g0v0_Shanghai - - opcB9DiffPlaces_d15g0v0_Shanghai - - opcB9DiffPlaces_d16g0v0_Shanghai - - opcB8DiffPlaces_d30g0v0_Shanghai - - opcB8DiffPlaces_d31g0v0_Shanghai - - opcB9DiffPlaces_d2g0v0_Shanghai - - opcB8DiffPlaces_d32g0v0_Shanghai - - opcB8DiffPlaces_d33g0v0_Shanghai - - opcB8DiffPlaces_d34g0v0_Shanghai - - opcB9DiffPlaces_d17g0v0_Shanghai - - opcB9DiffPlaces_d18g0v0_Shanghai - - opcB9DiffPlaces_d19g0v0_Shanghai - - opcB9DiffPlaces_d3g0v0_Shanghai - - opcB9DiffPlaces_d21g0v0_Shanghai - - opcBADiffPlaces_d0g0v0_Shanghai - - opcB9DiffPlaces_d20g0v0_Shanghai - - opcB9DiffPlaces_d4g0v0_Shanghai - - opcB9DiffPlaces_d22g0v0_Shanghai - - opcB9DiffPlaces_d23g0v0_Shanghai - - opcB9DiffPlaces_d5g0v0_Shanghai - - opcB9DiffPlaces_d6g0v0_Shanghai - - opcB9DiffPlaces_d7g0v0_Shanghai - - opcB9DiffPlaces_d8g0v0_Shanghai - - opcB9DiffPlaces_d24g0v0_Shanghai - - opcB9DiffPlaces_d9g0v0_Shanghai - - opcBADiffPlaces_d1g0v0_Shanghai - - opcB9DiffPlaces_d25g0v0_Shanghai - - opcBADiffPlaces_d10g0v0_Shanghai - - opcBADiffPlaces_d11g0v0_Shanghai - - opcB9DiffPlaces_d26g0v0_Shanghai - - opcBADiffPlaces_d12g0v0_Shanghai - - opcBADiffPlaces_d13g0v0_Shanghai - - opcB9DiffPlaces_d27g0v0_Shanghai - - opcB9DiffPlaces_d28g0v0_Shanghai - - opcBADiffPlaces_d14g0v0_Shanghai - - opcB9DiffPlaces_d29g0v0_Shanghai - - opcBADiffPlaces_d15g0v0_Shanghai - - opcBADiffPlaces_d16g0v0_Shanghai - - opcB9DiffPlaces_d30g0v0_Shanghai - - opcB9DiffPlaces_d31g0v0_Shanghai - - opcBADiffPlaces_d2g0v0_Shanghai - - opcB9DiffPlaces_d32g0v0_Shanghai - - opcB9DiffPlaces_d33g0v0_Shanghai - - opcB9DiffPlaces_d34g0v0_Shanghai - - opcBADiffPlaces_d17g0v0_Shanghai - - opcBADiffPlaces_d18g0v0_Shanghai - - opcBADiffPlaces_d19g0v0_Shanghai - - opcBADiffPlaces_d3g0v0_Shanghai - - opcBBDiffPlaces_d0g0v0_Shanghai - - opcBADiffPlaces_d21g0v0_Shanghai - - opcBADiffPlaces_d20g0v0_Shanghai - - opcBADiffPlaces_d4g0v0_Shanghai - - opcBADiffPlaces_d22g0v0_Shanghai - - opcBADiffPlaces_d23g0v0_Shanghai - - opcBADiffPlaces_d5g0v0_Shanghai - - opcBADiffPlaces_d6g0v0_Shanghai - - opcBADiffPlaces_d7g0v0_Shanghai - - opcBADiffPlaces_d8g0v0_Shanghai - - opcBADiffPlaces_d9g0v0_Shanghai - - opcBADiffPlaces_d24g0v0_Shanghai - - opcBADiffPlaces_d25g0v0_Shanghai - - opcBBDiffPlaces_d1g0v0_Shanghai - - opcBBDiffPlaces_d10g0v0_Shanghai - - opcBBDiffPlaces_d11g0v0_Shanghai - - opcBADiffPlaces_d26g0v0_Shanghai - - opcBBDiffPlaces_d12g0v0_Shanghai - - opcBADiffPlaces_d27g0v0_Shanghai - - opcBBDiffPlaces_d13g0v0_Shanghai - - opcBADiffPlaces_d28g0v0_Shanghai - - opcBBDiffPlaces_d14g0v0_Shanghai - - opcBBDiffPlaces_d15g0v0_Shanghai - - opcBADiffPlaces_d29g0v0_Shanghai - - opcBBDiffPlaces_d16g0v0_Shanghai - - opcBADiffPlaces_d30g0v0_Shanghai - - opcBBDiffPlaces_d2g0v0_Shanghai - - opcBADiffPlaces_d31g0v0_Shanghai - - opcBADiffPlaces_d32g0v0_Shanghai - - opcBADiffPlaces_d33g0v0_Shanghai - - opcBADiffPlaces_d34g0v0_Shanghai - - opcBBDiffPlaces_d17g0v0_Shanghai - - opcBBDiffPlaces_d18g0v0_Shanghai - - opcBBDiffPlaces_d19g0v0_Shanghai - - opcBBDiffPlaces_d3g0v0_Shanghai - - opcBCDiffPlaces_d0g0v0_Shanghai - - opcBBDiffPlaces_d21g0v0_Shanghai - - opcBBDiffPlaces_d20g0v0_Shanghai - - opcBBDiffPlaces_d4g0v0_Shanghai - - opcBBDiffPlaces_d22g0v0_Shanghai - - opcBBDiffPlaces_d5g0v0_Shanghai - - opcBBDiffPlaces_d23g0v0_Shanghai - - opcBBDiffPlaces_d6g0v0_Shanghai - - opcBBDiffPlaces_d7g0v0_Shanghai - - opcBBDiffPlaces_d8g0v0_Shanghai - - opcBBDiffPlaces_d9g0v0_Shanghai - - opcBBDiffPlaces_d24g0v0_Shanghai - - opcBCDiffPlaces_d1g0v0_Shanghai - - opcBBDiffPlaces_d25g0v0_Shanghai - - opcBCDiffPlaces_d10g0v0_Shanghai - - opcBCDiffPlaces_d11g0v0_Shanghai - - opcBBDiffPlaces_d26g0v0_Shanghai - - opcBCDiffPlaces_d12g0v0_Shanghai - - opcBBDiffPlaces_d27g0v0_Shanghai - - opcBCDiffPlaces_d13g0v0_Shanghai - - opcBBDiffPlaces_d28g0v0_Shanghai - - opcBCDiffPlaces_d14g0v0_Shanghai - - opcBBDiffPlaces_d29g0v0_Shanghai - - opcBCDiffPlaces_d15g0v0_Shanghai - - opcBBDiffPlaces_d30g0v0_Shanghai - - opcBBDiffPlaces_d31g0v0_Shanghai - - opcBCDiffPlaces_d16g0v0_Shanghai - - opcBBDiffPlaces_d32g0v0_Shanghai - - opcBCDiffPlaces_d2g0v0_Shanghai - - opcBBDiffPlaces_d33g0v0_Shanghai - - opcBBDiffPlaces_d34g0v0_Shanghai - - opcBCDiffPlaces_d17g0v0_Shanghai - - opcBCDiffPlaces_d18g0v0_Shanghai - - opcBCDiffPlaces_d3g0v0_Shanghai - - opcBCDiffPlaces_d19g0v0_Shanghai - - opcBCDiffPlaces_d21g0v0_Shanghai - - opcBDDiffPlaces_d0g0v0_Shanghai - - opcBCDiffPlaces_d4g0v0_Shanghai - - opcBCDiffPlaces_d22g0v0_Shanghai - - opcBCDiffPlaces_d20g0v0_Shanghai - - opcBCDiffPlaces_d23g0v0_Shanghai - - opcBCDiffPlaces_d5g0v0_Shanghai - - opcBCDiffPlaces_d6g0v0_Shanghai - - opcBCDiffPlaces_d7g0v0_Shanghai - - opcBCDiffPlaces_d8g0v0_Shanghai - - opcBCDiffPlaces_d24g0v0_Shanghai - - opcBCDiffPlaces_d9g0v0_Shanghai - - opcBCDiffPlaces_d25g0v0_Shanghai - - opcBDDiffPlaces_d1g0v0_Shanghai - - opcBDDiffPlaces_d10g0v0_Shanghai - - opcBCDiffPlaces_d26g0v0_Shanghai - - opcBDDiffPlaces_d11g0v0_Shanghai - - opcBDDiffPlaces_d12g0v0_Shanghai - - opcBCDiffPlaces_d27g0v0_Shanghai - - opcBDDiffPlaces_d13g0v0_Shanghai - - opcBCDiffPlaces_d28g0v0_Shanghai - - opcBDDiffPlaces_d14g0v0_Shanghai - - opcBCDiffPlaces_d29g0v0_Shanghai - - opcBDDiffPlaces_d15g0v0_Shanghai - - opcBCDiffPlaces_d30g0v0_Shanghai - - opcBCDiffPlaces_d31g0v0_Shanghai - - opcBDDiffPlaces_d16g0v0_Shanghai - - opcBDDiffPlaces_d2g0v0_Shanghai - - opcBCDiffPlaces_d32g0v0_Shanghai - - opcBCDiffPlaces_d33g0v0_Shanghai - - opcBCDiffPlaces_d34g0v0_Shanghai - - opcBDDiffPlaces_d17g0v0_Shanghai - - opcBDDiffPlaces_d18g0v0_Shanghai - - opcBDDiffPlaces_d19g0v0_Shanghai - - opcBDDiffPlaces_d3g0v0_Shanghai - - opcBDDiffPlaces_d21g0v0_Shanghai - - opcBEDiffPlaces_d0g0v0_Shanghai - - opcBDDiffPlaces_d4g0v0_Shanghai - - opcBDDiffPlaces_d20g0v0_Shanghai - - opcBDDiffPlaces_d22g0v0_Shanghai - - opcBDDiffPlaces_d5g0v0_Shanghai - - opcBDDiffPlaces_d23g0v0_Shanghai - - opcBDDiffPlaces_d6g0v0_Shanghai - - opcBDDiffPlaces_d7g0v0_Shanghai - - opcBDDiffPlaces_d8g0v0_Shanghai - - opcBDDiffPlaces_d24g0v0_Shanghai - - opcBDDiffPlaces_d9g0v0_Shanghai - - opcBEDiffPlaces_d1g0v0_Shanghai - - opcBDDiffPlaces_d25g0v0_Shanghai - - opcBEDiffPlaces_d10g0v0_Shanghai - - opcBDDiffPlaces_d26g0v0_Shanghai - - opcBEDiffPlaces_d11g0v0_Shanghai - - opcBEDiffPlaces_d12g0v0_Shanghai - - opcBDDiffPlaces_d27g0v0_Shanghai - - opcBEDiffPlaces_d13g0v0_Shanghai - - opcBDDiffPlaces_d28g0v0_Shanghai - - opcBEDiffPlaces_d14g0v0_Shanghai - - opcBDDiffPlaces_d29g0v0_Shanghai - - opcBEDiffPlaces_d15g0v0_Shanghai - - opcBEDiffPlaces_d16g0v0_Shanghai - - opcBDDiffPlaces_d30g0v0_Shanghai - - opcBDDiffPlaces_d31g0v0_Shanghai - - opcBDDiffPlaces_d32g0v0_Shanghai - - opcBEDiffPlaces_d2g0v0_Shanghai - - opcBDDiffPlaces_d33g0v0_Shanghai - - opcBDDiffPlaces_d34g0v0_Shanghai - - opcBEDiffPlaces_d17g0v0_Shanghai - - opcBEDiffPlaces_d18g0v0_Shanghai - - opcBEDiffPlaces_d19g0v0_Shanghai - - opcBEDiffPlaces_d3g0v0_Shanghai - - opcBEDiffPlaces_d21g0v0_Shanghai - - opcBFDiffPlaces_d0g0v0_Shanghai - - opcBEDiffPlaces_d4g0v0_Shanghai - - opcBEDiffPlaces_d20g0v0_Shanghai - - opcBEDiffPlaces_d22g0v0_Shanghai - - opcBEDiffPlaces_d5g0v0_Shanghai - - opcBEDiffPlaces_d23g0v0_Shanghai - - opcBEDiffPlaces_d6g0v0_Shanghai - - opcBEDiffPlaces_d7g0v0_Shanghai - - opcBEDiffPlaces_d8g0v0_Shanghai - - opcBEDiffPlaces_d24g0v0_Shanghai - - opcBEDiffPlaces_d9g0v0_Shanghai - - opcBEDiffPlaces_d25g0v0_Shanghai - - opcBFDiffPlaces_d1g0v0_Shanghai - - opcBFDiffPlaces_d10g0v0_Shanghai - - opcBFDiffPlaces_d11g0v0_Shanghai - - opcBEDiffPlaces_d26g0v0_Shanghai - - opcBFDiffPlaces_d12g0v0_Shanghai - - opcBEDiffPlaces_d27g0v0_Shanghai - - opcBFDiffPlaces_d13g0v0_Shanghai - - opcBEDiffPlaces_d28g0v0_Shanghai - - opcBFDiffPlaces_d14g0v0_Shanghai - - opcBFDiffPlaces_d15g0v0_Shanghai - - opcBEDiffPlaces_d29g0v0_Shanghai - - opcBEDiffPlaces_d30g0v0_Shanghai - - opcBFDiffPlaces_d16g0v0_Shanghai - - opcBEDiffPlaces_d31g0v0_Shanghai - - opcBEDiffPlaces_d32g0v0_Shanghai - - opcBFDiffPlaces_d2g0v0_Shanghai - - opcBEDiffPlaces_d33g0v0_Shanghai - - opcBEDiffPlaces_d34g0v0_Shanghai - - opcBFDiffPlaces_d17g0v0_Shanghai - - opcBFDiffPlaces_d18g0v0_Shanghai - - opcBFDiffPlaces_d19g0v0_Shanghai - - opcBFDiffPlaces_d3g0v0_Shanghai - - opcBFDiffPlaces_d21g0v0_Shanghai - - opcC0DiffPlaces_d0g0v0_Shanghai - - opcBFDiffPlaces_d4g0v0_Shanghai - - opcBFDiffPlaces_d20g0v0_Shanghai - - opcBFDiffPlaces_d22g0v0_Shanghai - - opcBFDiffPlaces_d5g0v0_Shanghai - - opcBFDiffPlaces_d23g0v0_Shanghai - - opcBFDiffPlaces_d6g0v0_Shanghai - - opcBFDiffPlaces_d7g0v0_Shanghai - - opcBFDiffPlaces_d8g0v0_Shanghai - - opcBFDiffPlaces_d24g0v0_Shanghai - - opcBFDiffPlaces_d9g0v0_Shanghai - - opcBFDiffPlaces_d25g0v0_Shanghai - - opcC0DiffPlaces_d1g0v0_Shanghai - - opcC0DiffPlaces_d10g0v0_Shanghai - - opcBFDiffPlaces_d26g0v0_Shanghai - - opcC0DiffPlaces_d11g0v0_Shanghai - - opcC0DiffPlaces_d12g0v0_Shanghai - - opcBFDiffPlaces_d27g0v0_Shanghai - - opcC0DiffPlaces_d13g0v0_Shanghai - - opcBFDiffPlaces_d28g0v0_Shanghai - - opcC0DiffPlaces_d14g0v0_Shanghai - - opcBFDiffPlaces_d29g0v0_Shanghai - - opcC0DiffPlaces_d15g0v0_Shanghai - - opcC0DiffPlaces_d16g0v0_Shanghai - - opcBFDiffPlaces_d31g0v0_Shanghai - - opcBFDiffPlaces_d30g0v0_Shanghai - - opcBFDiffPlaces_d32g0v0_Shanghai - - opcC0DiffPlaces_d2g0v0_Shanghai - - opcBFDiffPlaces_d34g0v0_Shanghai - - opcBFDiffPlaces_d33g0v0_Shanghai - - opcC0DiffPlaces_d17g0v0_Shanghai - - opcC0DiffPlaces_d18g0v0_Shanghai - - opcC0DiffPlaces_d19g0v0_Shanghai - - opcC0DiffPlaces_d3g0v0_Shanghai - - opcC0DiffPlaces_d21g0v0_Shanghai - - opcC1DiffPlaces_d0g0v0_Shanghai - - opcC0DiffPlaces_d4g0v0_Shanghai - - opcC0DiffPlaces_d20g0v0_Shanghai - - opcC0DiffPlaces_d22g0v0_Shanghai - - opcC0DiffPlaces_d5g0v0_Shanghai - - opcC0DiffPlaces_d23g0v0_Shanghai - - opcC0DiffPlaces_d6g0v0_Shanghai - - opcC0DiffPlaces_d7g0v0_Shanghai - - opcC0DiffPlaces_d8g0v0_Shanghai - - opcC0DiffPlaces_d24g0v0_Shanghai - - opcC0DiffPlaces_d9g0v0_Shanghai - - opcC1DiffPlaces_d1g0v0_Shanghai - - opcC0DiffPlaces_d25g0v0_Shanghai - - opcC1DiffPlaces_d10g0v0_Shanghai - - opcC1DiffPlaces_d11g0v0_Shanghai - - opcC0DiffPlaces_d26g0v0_Shanghai - - opcC1DiffPlaces_d12g0v0_Shanghai - - opcC0DiffPlaces_d27g0v0_Shanghai - - opcC1DiffPlaces_d13g0v0_Shanghai - - opcC0DiffPlaces_d28g0v0_Shanghai - - opcC1DiffPlaces_d14g0v0_Shanghai - - opcC0DiffPlaces_d29g0v0_Shanghai - - opcC1DiffPlaces_d15g0v0_Shanghai - - opcC0DiffPlaces_d30g0v0_Shanghai - - opcC0DiffPlaces_d31g0v0_Shanghai - - opcC1DiffPlaces_d16g0v0_Shanghai - - opcC1DiffPlaces_d2g0v0_Shanghai - - opcC0DiffPlaces_d32g0v0_Shanghai - - opcC0DiffPlaces_d33g0v0_Shanghai - - opcC0DiffPlaces_d34g0v0_Shanghai - - opcC1DiffPlaces_d17g0v0_Shanghai - - opcC1DiffPlaces_d18g0v0_Shanghai - - opcC1DiffPlaces_d19g0v0_Shanghai - - opcC1DiffPlaces_d3g0v0_Shanghai - - opcC1DiffPlaces_d21g0v0_Shanghai - - opcC1DiffPlaces_d4g0v0_Shanghai - - opcC2DiffPlaces_d0g0v0_Shanghai - - opcC1DiffPlaces_d20g0v0_Shanghai - - opcC1DiffPlaces_d22g0v0_Shanghai - - opcC1DiffPlaces_d23g0v0_Shanghai - - opcC1DiffPlaces_d5g0v0_Shanghai - - opcC1DiffPlaces_d6g0v0_Shanghai - - opcC1DiffPlaces_d7g0v0_Shanghai - - opcC1DiffPlaces_d8g0v0_Shanghai - - opcC1DiffPlaces_d9g0v0_Shanghai - - opcC1DiffPlaces_d24g0v0_Shanghai - - opcC2DiffPlaces_d1g0v0_Shanghai - - opcC1DiffPlaces_d25g0v0_Shanghai - - opcC2DiffPlaces_d10g0v0_Shanghai - - opcC2DiffPlaces_d11g0v0_Shanghai - - opcC1DiffPlaces_d26g0v0_Shanghai - - opcC2DiffPlaces_d12g0v0_Shanghai - - opcC1DiffPlaces_d27g0v0_Shanghai - - opcC2DiffPlaces_d13g0v0_Shanghai - - opcC2DiffPlaces_d14g0v0_Shanghai - - opcC1DiffPlaces_d28g0v0_Shanghai - - opcC2DiffPlaces_d15g0v0_Shanghai - - opcC1DiffPlaces_d29g0v0_Shanghai - - opcC1DiffPlaces_d30g0v0_Shanghai - - opcC2DiffPlaces_d16g0v0_Shanghai - - opcC1DiffPlaces_d31g0v0_Shanghai - - opcC2DiffPlaces_d2g0v0_Shanghai - - opcC1DiffPlaces_d32g0v0_Shanghai - - opcC1DiffPlaces_d33g0v0_Shanghai - - opcC1DiffPlaces_d34g0v0_Shanghai - - opcC2DiffPlaces_d17g0v0_Shanghai - - opcC2DiffPlaces_d18g0v0_Shanghai - - opcC2DiffPlaces_d19g0v0_Shanghai - - opcC2DiffPlaces_d3g0v0_Shanghai - - opcC2DiffPlaces_d21g0v0_Shanghai - - opcC3DiffPlaces_d0g0v0_Shanghai - - opcC2DiffPlaces_d4g0v0_Shanghai - - opcC2DiffPlaces_d20g0v0_Shanghai - - opcC2DiffPlaces_d22g0v0_Shanghai - - opcC2DiffPlaces_d23g0v0_Shanghai - - opcC2DiffPlaces_d5g0v0_Shanghai - - opcC2DiffPlaces_d6g0v0_Shanghai - - opcC2DiffPlaces_d7g0v0_Shanghai - - opcC2DiffPlaces_d8g0v0_Shanghai - - opcC2DiffPlaces_d24g0v0_Shanghai - - opcC2DiffPlaces_d9g0v0_Shanghai - - opcC3DiffPlaces_d1g0v0_Shanghai - - opcC2DiffPlaces_d25g0v0_Shanghai - - opcC3DiffPlaces_d10g0v0_Shanghai - - opcC3DiffPlaces_d11g0v0_Shanghai - - opcC2DiffPlaces_d26g0v0_Shanghai - - opcC3DiffPlaces_d12g0v0_Shanghai - - opcC2DiffPlaces_d27g0v0_Shanghai - - opcC3DiffPlaces_d13g0v0_Shanghai - - opcC2DiffPlaces_d28g0v0_Shanghai - - opcC3DiffPlaces_d14g0v0_Shanghai - - opcC3DiffPlaces_d15g0v0_Shanghai - - opcC2DiffPlaces_d29g0v0_Shanghai - - opcC2DiffPlaces_d30g0v0_Shanghai - - opcC3DiffPlaces_d16g0v0_Shanghai - - opcC2DiffPlaces_d31g0v0_Shanghai - - opcC2DiffPlaces_d32g0v0_Shanghai - - opcC3DiffPlaces_d2g0v0_Shanghai - - opcC2DiffPlaces_d33g0v0_Shanghai - - opcC2DiffPlaces_d34g0v0_Shanghai - - opcC3DiffPlaces_d17g0v0_Shanghai - - opcC3DiffPlaces_d18g0v0_Shanghai - - opcC3DiffPlaces_d3g0v0_Shanghai - - opcC3DiffPlaces_d19g0v0_Shanghai - - opcC4DiffPlaces_d0g0v0_Shanghai - - opcC3DiffPlaces_d21g0v0_Shanghai - - opcC3DiffPlaces_d4g0v0_Shanghai - - opcC3DiffPlaces_d20g0v0_Shanghai - - opcC3DiffPlaces_d22g0v0_Shanghai - - opcC3DiffPlaces_d5g0v0_Shanghai - - opcC3DiffPlaces_d23g0v0_Shanghai - - opcC3DiffPlaces_d6g0v0_Shanghai - - opcC3DiffPlaces_d7g0v0_Shanghai - - opcC3DiffPlaces_d8g0v0_Shanghai - - opcC3DiffPlaces_d9g0v0_Shanghai - - opcC3DiffPlaces_d24g0v0_Shanghai - - opcC3DiffPlaces_d25g0v0_Shanghai - - opcC4DiffPlaces_d1g0v0_Shanghai - - opcC4DiffPlaces_d10g0v0_Shanghai - - opcC4DiffPlaces_d11g0v0_Shanghai - - opcC3DiffPlaces_d26g0v0_Shanghai - - opcC4DiffPlaces_d12g0v0_Shanghai - - opcC3DiffPlaces_d27g0v0_Shanghai - - opcC4DiffPlaces_d13g0v0_Shanghai - - opcC3DiffPlaces_d28g0v0_Shanghai - - opcC4DiffPlaces_d14g0v0_Shanghai - - opcC3DiffPlaces_d29g0v0_Shanghai - - opcC4DiffPlaces_d15g0v0_Shanghai - - opcC3DiffPlaces_d30g0v0_Shanghai - - opcC4DiffPlaces_d16g0v0_Shanghai - - opcC3DiffPlaces_d31g0v0_Shanghai - - opcC4DiffPlaces_d2g0v0_Shanghai - - opcC3DiffPlaces_d32g0v0_Shanghai - - opcC3DiffPlaces_d33g0v0_Shanghai - - opcC3DiffPlaces_d34g0v0_Shanghai - - opcC4DiffPlaces_d17g0v0_Shanghai - - opcC4DiffPlaces_d18g0v0_Shanghai - - opcC4DiffPlaces_d19g0v0_Shanghai - - opcC4DiffPlaces_d3g0v0_Shanghai - - opcC4DiffPlaces_d21g0v0_Shanghai - - opcC5DiffPlaces_d0g0v0_Shanghai - - opcC4DiffPlaces_d4g0v0_Shanghai - - opcC4DiffPlaces_d20g0v0_Shanghai - - opcC4DiffPlaces_d22g0v0_Shanghai - - opcC4DiffPlaces_d5g0v0_Shanghai - - opcC4DiffPlaces_d23g0v0_Shanghai - - opcC4DiffPlaces_d6g0v0_Shanghai - - opcC4DiffPlaces_d7g0v0_Shanghai - - opcC4DiffPlaces_d8g0v0_Shanghai - - opcC4DiffPlaces_d24g0v0_Shanghai - - opcC4DiffPlaces_d9g0v0_Shanghai - - opcC4DiffPlaces_d25g0v0_Shanghai - - opcC5DiffPlaces_d1g0v0_Shanghai - - opcC5DiffPlaces_d10g0v0_Shanghai - - opcC5DiffPlaces_d11g0v0_Shanghai - - opcC4DiffPlaces_d26g0v0_Shanghai - - opcC5DiffPlaces_d12g0v0_Shanghai - - opcC4DiffPlaces_d27g0v0_Shanghai - - opcC5DiffPlaces_d13g0v0_Shanghai - - opcC4DiffPlaces_d28g0v0_Shanghai - - opcC5DiffPlaces_d14g0v0_Shanghai - - opcC4DiffPlaces_d29g0v0_Shanghai - - opcC5DiffPlaces_d15g0v0_Shanghai - - opcC5DiffPlaces_d16g0v0_Shanghai - - opcC4DiffPlaces_d31g0v0_Shanghai - - opcC4DiffPlaces_d30g0v0_Shanghai - - opcC5DiffPlaces_d2g0v0_Shanghai - - opcC4DiffPlaces_d32g0v0_Shanghai - - opcC4DiffPlaces_d33g0v0_Shanghai - - opcC4DiffPlaces_d34g0v0_Shanghai - - opcC5DiffPlaces_d17g0v0_Shanghai - - opcC5DiffPlaces_d18g0v0_Shanghai - - opcC5DiffPlaces_d3g0v0_Shanghai - - opcC5DiffPlaces_d19g0v0_Shanghai - - opcC5DiffPlaces_d21g0v0_Shanghai - - opcC6DiffPlaces_d0g0v0_Shanghai - - opcC5DiffPlaces_d20g0v0_Shanghai - - opcC5DiffPlaces_d4g0v0_Shanghai - - opcC5DiffPlaces_d22g0v0_Shanghai - - opcC5DiffPlaces_d5g0v0_Shanghai - - opcC5DiffPlaces_d23g0v0_Shanghai - - opcC5DiffPlaces_d6g0v0_Shanghai - - opcC5DiffPlaces_d7g0v0_Shanghai - - opcC5DiffPlaces_d8g0v0_Shanghai - - opcC5DiffPlaces_d24g0v0_Shanghai - - opcC5DiffPlaces_d9g0v0_Shanghai - - opcC5DiffPlaces_d25g0v0_Shanghai - - opcC6DiffPlaces_d1g0v0_Shanghai - - opcC6DiffPlaces_d10g0v0_Shanghai - - opcC6DiffPlaces_d11g0v0_Shanghai - - opcC5DiffPlaces_d26g0v0_Shanghai - - opcC6DiffPlaces_d12g0v0_Shanghai - - opcC6DiffPlaces_d13g0v0_Shanghai - - opcC5DiffPlaces_d27g0v0_Shanghai - - opcC5DiffPlaces_d28g0v0_Shanghai - - opcC6DiffPlaces_d14g0v0_Shanghai - - opcC5DiffPlaces_d29g0v0_Shanghai - - opcC6DiffPlaces_d15g0v0_Shanghai - - opcC5DiffPlaces_d31g0v0_Shanghai - - opcC5DiffPlaces_d30g0v0_Shanghai - - opcC6DiffPlaces_d16g0v0_Shanghai - - opcC5DiffPlaces_d32g0v0_Shanghai - - opcC6DiffPlaces_d2g0v0_Shanghai - - opcC5DiffPlaces_d33g0v0_Shanghai - - opcC5DiffPlaces_d34g0v0_Shanghai - - opcC6DiffPlaces_d17g0v0_Shanghai - - opcC6DiffPlaces_d18g0v0_Shanghai - - opcC6DiffPlaces_d19g0v0_Shanghai - - opcC6DiffPlaces_d3g0v0_Shanghai - - opcC6DiffPlaces_d21g0v0_Shanghai - - opcC7DiffPlaces_d0g0v0_Shanghai - - opcC6DiffPlaces_d20g0v0_Shanghai - - opcC6DiffPlaces_d4g0v0_Shanghai - - opcC6DiffPlaces_d22g0v0_Shanghai - - opcC6DiffPlaces_d5g0v0_Shanghai - - opcC6DiffPlaces_d23g0v0_Shanghai - - opcC6DiffPlaces_d6g0v0_Shanghai - - opcC6DiffPlaces_d7g0v0_Shanghai - - opcC6DiffPlaces_d8g0v0_Shanghai - - opcC6DiffPlaces_d9g0v0_Shanghai - - opcC6DiffPlaces_d24g0v0_Shanghai - - opcC6DiffPlaces_d25g0v0_Shanghai - - opcC7DiffPlaces_d1g0v0_Shanghai - - opcC7DiffPlaces_d10g0v0_Shanghai - - opcC6DiffPlaces_d26g0v0_Shanghai - - opcC7DiffPlaces_d11g0v0_Shanghai - - opcC7DiffPlaces_d12g0v0_Shanghai - - opcC6DiffPlaces_d27g0v0_Shanghai - - opcC7DiffPlaces_d13g0v0_Shanghai - - opcC6DiffPlaces_d28g0v0_Shanghai - - opcC7DiffPlaces_d14g0v0_Shanghai - - opcC7DiffPlaces_d15g0v0_Shanghai - - opcC6DiffPlaces_d29g0v0_Shanghai - - opcC6DiffPlaces_d30g0v0_Shanghai - - opcC7DiffPlaces_d16g0v0_Shanghai - - opcC6DiffPlaces_d31g0v0_Shanghai - - opcC7DiffPlaces_d2g0v0_Shanghai - - opcC6DiffPlaces_d32g0v0_Shanghai - - opcC6DiffPlaces_d33g0v0_Shanghai - - opcC6DiffPlaces_d34g0v0_Shanghai - - opcC7DiffPlaces_d17g0v0_Shanghai - - opcC7DiffPlaces_d18g0v0_Shanghai - - opcC7DiffPlaces_d19g0v0_Shanghai - - opcC7DiffPlaces_d3g0v0_Shanghai - - opcC7DiffPlaces_d21g0v0_Shanghai - - opcC8DiffPlaces_d0g0v0_Shanghai - - opcC7DiffPlaces_d20g0v0_Shanghai - - opcC7DiffPlaces_d4g0v0_Shanghai - - opcC7DiffPlaces_d22g0v0_Shanghai - - opcC7DiffPlaces_d23g0v0_Shanghai - - opcC7DiffPlaces_d5g0v0_Shanghai - - opcC7DiffPlaces_d6g0v0_Shanghai - - opcC7DiffPlaces_d7g0v0_Shanghai - - opcC7DiffPlaces_d8g0v0_Shanghai - - opcC7DiffPlaces_d9g0v0_Shanghai - - opcC7DiffPlaces_d24g0v0_Shanghai - - opcC7DiffPlaces_d25g0v0_Shanghai - - opcC8DiffPlaces_d1g0v0_Shanghai - - opcC8DiffPlaces_d10g0v0_Shanghai - - opcC7DiffPlaces_d26g0v0_Shanghai - - opcC8DiffPlaces_d11g0v0_Shanghai - - opcC8DiffPlaces_d12g0v0_Shanghai - - opcC7DiffPlaces_d27g0v0_Shanghai - - opcC8DiffPlaces_d13g0v0_Shanghai - - opcC7DiffPlaces_d28g0v0_Shanghai - - opcC8DiffPlaces_d14g0v0_Shanghai - - opcC7DiffPlaces_d29g0v0_Shanghai - - opcC8DiffPlaces_d15g0v0_Shanghai - - opcC8DiffPlaces_d16g0v0_Shanghai - - opcC7DiffPlaces_d31g0v0_Shanghai - - opcC7DiffPlaces_d30g0v0_Shanghai - - opcC8DiffPlaces_d2g0v0_Shanghai - - opcC7DiffPlaces_d32g0v0_Shanghai - - opcC7DiffPlaces_d33g0v0_Shanghai - - opcC7DiffPlaces_d34g0v0_Shanghai - - opcC8DiffPlaces_d17g0v0_Shanghai - - opcC8DiffPlaces_d18g0v0_Shanghai - - opcC8DiffPlaces_d19g0v0_Shanghai - - opcC8DiffPlaces_d3g0v0_Shanghai - - opcC8DiffPlaces_d21g0v0_Shanghai - - opcC8DiffPlaces_d4g0v0_Shanghai - - opcC9DiffPlaces_d0g0v0_Shanghai - - opcC8DiffPlaces_d20g0v0_Shanghai - - opcC8DiffPlaces_d22g0v0_Shanghai - - opcC8DiffPlaces_d5g0v0_Shanghai - - opcC8DiffPlaces_d23g0v0_Shanghai - - opcC8DiffPlaces_d6g0v0_Shanghai - - opcC8DiffPlaces_d7g0v0_Shanghai - - opcC8DiffPlaces_d8g0v0_Shanghai - - opcC8DiffPlaces_d24g0v0_Shanghai - - opcC8DiffPlaces_d9g0v0_Shanghai - - opcC8DiffPlaces_d25g0v0_Shanghai - - opcC9DiffPlaces_d1g0v0_Shanghai - - opcC9DiffPlaces_d10g0v0_Shanghai - - opcC9DiffPlaces_d11g0v0_Shanghai - - opcC8DiffPlaces_d26g0v0_Shanghai - - opcC9DiffPlaces_d12g0v0_Shanghai - - opcC8DiffPlaces_d27g0v0_Shanghai - - opcC9DiffPlaces_d13g0v0_Shanghai - - opcC8DiffPlaces_d28g0v0_Shanghai - - opcC9DiffPlaces_d14g0v0_Shanghai - - opcC9DiffPlaces_d15g0v0_Shanghai - - opcC8DiffPlaces_d29g0v0_Shanghai - - opcC9DiffPlaces_d16g0v0_Shanghai - - opcC8DiffPlaces_d30g0v0_Shanghai - - opcC8DiffPlaces_d31g0v0_Shanghai - - opcC8DiffPlaces_d32g0v0_Shanghai - - opcC9DiffPlaces_d2g0v0_Shanghai - - opcC8DiffPlaces_d33g0v0_Shanghai - - opcC8DiffPlaces_d34g0v0_Shanghai - - opcC9DiffPlaces_d17g0v0_Shanghai - - opcC9DiffPlaces_d18g0v0_Shanghai - - opcC9DiffPlaces_d3g0v0_Shanghai - - opcC9DiffPlaces_d19g0v0_Shanghai - - opcC9DiffPlaces_d21g0v0_Shanghai - - opcCADiffPlaces_d0g0v0_Shanghai - - opcC9DiffPlaces_d4g0v0_Shanghai - - opcC9DiffPlaces_d20g0v0_Shanghai - - opcC9DiffPlaces_d22g0v0_Shanghai - - opcC9DiffPlaces_d5g0v0_Shanghai - - opcC9DiffPlaces_d23g0v0_Shanghai - - opcC9DiffPlaces_d6g0v0_Shanghai - - opcC9DiffPlaces_d7g0v0_Shanghai - - opcC9DiffPlaces_d8g0v0_Shanghai - - opcC9DiffPlaces_d24g0v0_Shanghai - - opcC9DiffPlaces_d9g0v0_Shanghai - - opcC9DiffPlaces_d25g0v0_Shanghai - - opcCADiffPlaces_d1g0v0_Shanghai - - opcCADiffPlaces_d10g0v0_Shanghai - - opcC9DiffPlaces_d26g0v0_Shanghai - - opcCADiffPlaces_d11g0v0_Shanghai - - opcCADiffPlaces_d12g0v0_Shanghai - - opcC9DiffPlaces_d27g0v0_Shanghai - - opcCADiffPlaces_d13g0v0_Shanghai - - opcC9DiffPlaces_d28g0v0_Shanghai - - opcCADiffPlaces_d14g0v0_Shanghai - - opcC9DiffPlaces_d29g0v0_Shanghai - - opcCADiffPlaces_d15g0v0_Shanghai - - opcCADiffPlaces_d16g0v0_Shanghai - - opcC9DiffPlaces_d30g0v0_Shanghai - - opcC9DiffPlaces_d31g0v0_Shanghai - - opcCADiffPlaces_d2g0v0_Shanghai - - opcC9DiffPlaces_d32g0v0_Shanghai - - opcC9DiffPlaces_d33g0v0_Shanghai - - opcC9DiffPlaces_d34g0v0_Shanghai - - opcCADiffPlaces_d17g0v0_Shanghai - - opcCADiffPlaces_d18g0v0_Shanghai - - opcCADiffPlaces_d19g0v0_Shanghai - - opcCADiffPlaces_d3g0v0_Shanghai - - opcCADiffPlaces_d21g0v0_Shanghai - - opcCBDiffPlaces_d0g0v0_Shanghai - - opcCADiffPlaces_d20g0v0_Shanghai - - opcCADiffPlaces_d22g0v0_Shanghai - - opcCADiffPlaces_d4g0v0_Shanghai - - opcCADiffPlaces_d23g0v0_Shanghai - - opcCADiffPlaces_d5g0v0_Shanghai - - opcCADiffPlaces_d6g0v0_Shanghai - - opcCADiffPlaces_d7g0v0_Shanghai - - opcCADiffPlaces_d8g0v0_Shanghai - - opcCADiffPlaces_d24g0v0_Shanghai - - opcCADiffPlaces_d9g0v0_Shanghai - - opcCADiffPlaces_d25g0v0_Shanghai - - opcCBDiffPlaces_d1g0v0_Shanghai - - opcCBDiffPlaces_d10g0v0_Shanghai - - opcCBDiffPlaces_d11g0v0_Shanghai - - opcCADiffPlaces_d26g0v0_Shanghai - - opcCBDiffPlaces_d12g0v0_Shanghai - - opcCADiffPlaces_d27g0v0_Shanghai - - opcCBDiffPlaces_d13g0v0_Shanghai - - opcCADiffPlaces_d28g0v0_Shanghai - - opcCBDiffPlaces_d14g0v0_Shanghai - - opcCADiffPlaces_d29g0v0_Shanghai - - opcCBDiffPlaces_d15g0v0_Shanghai - - opcCADiffPlaces_d30g0v0_Shanghai - - opcCADiffPlaces_d31g0v0_Shanghai - - opcCBDiffPlaces_d16g0v0_Shanghai - - opcCBDiffPlaces_d2g0v0_Shanghai - - opcCADiffPlaces_d32g0v0_Shanghai - - opcCADiffPlaces_d34g0v0_Shanghai - - opcCADiffPlaces_d33g0v0_Shanghai - - opcCBDiffPlaces_d17g0v0_Shanghai - - opcCBDiffPlaces_d18g0v0_Shanghai - - opcCBDiffPlaces_d3g0v0_Shanghai - - opcCBDiffPlaces_d19g0v0_Shanghai - - opcCBDiffPlaces_d21g0v0_Shanghai - - opcCCDiffPlaces_d0g0v0_Shanghai - - opcCBDiffPlaces_d4g0v0_Shanghai - - opcCBDiffPlaces_d20g0v0_Shanghai - - opcCBDiffPlaces_d22g0v0_Shanghai - - opcCBDiffPlaces_d5g0v0_Shanghai - - opcCBDiffPlaces_d23g0v0_Shanghai - - opcCBDiffPlaces_d6g0v0_Shanghai - - opcCBDiffPlaces_d7g0v0_Shanghai - - opcCBDiffPlaces_d8g0v0_Shanghai - - opcCBDiffPlaces_d9g0v0_Shanghai - - opcCBDiffPlaces_d24g0v0_Shanghai - - opcCCDiffPlaces_d1g0v0_Shanghai - - opcCBDiffPlaces_d25g0v0_Shanghai - - opcCCDiffPlaces_d10g0v0_Shanghai - - opcCCDiffPlaces_d11g0v0_Shanghai - - opcCBDiffPlaces_d26g0v0_Shanghai - - opcCCDiffPlaces_d12g0v0_Shanghai - - opcCBDiffPlaces_d27g0v0_Shanghai - - opcCCDiffPlaces_d13g0v0_Shanghai - - opcCBDiffPlaces_d28g0v0_Shanghai - - opcCCDiffPlaces_d14g0v0_Shanghai - - opcCBDiffPlaces_d29g0v0_Shanghai - - opcCCDiffPlaces_d15g0v0_Shanghai - - opcCCDiffPlaces_d16g0v0_Shanghai - - opcCBDiffPlaces_d30g0v0_Shanghai - - opcCBDiffPlaces_d31g0v0_Shanghai - - opcCCDiffPlaces_d2g0v0_Shanghai - - opcCBDiffPlaces_d32g0v0_Shanghai - - opcCBDiffPlaces_d33g0v0_Shanghai - - opcCBDiffPlaces_d34g0v0_Shanghai - - opcCCDiffPlaces_d17g0v0_Shanghai - - opcCCDiffPlaces_d18g0v0_Shanghai - - opcCCDiffPlaces_d19g0v0_Shanghai - - opcCCDiffPlaces_d3g0v0_Shanghai - - opcCCDiffPlaces_d21g0v0_Shanghai - - opcCDDiffPlaces_d0g0v0_Shanghai - - opcCCDiffPlaces_d4g0v0_Shanghai - - opcCCDiffPlaces_d20g0v0_Shanghai - - opcCCDiffPlaces_d22g0v0_Shanghai - - opcCCDiffPlaces_d5g0v0_Shanghai - - opcCCDiffPlaces_d23g0v0_Shanghai - - opcCCDiffPlaces_d6g0v0_Shanghai - - opcCCDiffPlaces_d7g0v0_Shanghai - - opcCCDiffPlaces_d8g0v0_Shanghai - - opcCCDiffPlaces_d24g0v0_Shanghai - - opcCCDiffPlaces_d9g0v0_Shanghai - - opcCDDiffPlaces_d1g0v0_Shanghai - - opcCCDiffPlaces_d25g0v0_Shanghai - - opcCDDiffPlaces_d10g0v0_Shanghai - - opcCDDiffPlaces_d11g0v0_Shanghai - - opcCCDiffPlaces_d26g0v0_Shanghai - - opcCDDiffPlaces_d12g0v0_Shanghai - - opcCCDiffPlaces_d27g0v0_Shanghai - - opcCDDiffPlaces_d13g0v0_Shanghai - - opcCCDiffPlaces_d28g0v0_Shanghai - - opcCDDiffPlaces_d14g0v0_Shanghai - - opcCCDiffPlaces_d29g0v0_Shanghai - - opcCDDiffPlaces_d15g0v0_Shanghai - - opcCDDiffPlaces_d16g0v0_Shanghai - - opcCCDiffPlaces_d30g0v0_Shanghai - - opcCDDiffPlaces_d2g0v0_Shanghai - - opcCCDiffPlaces_d31g0v0_Shanghai - - opcCCDiffPlaces_d32g0v0_Shanghai - - opcCCDiffPlaces_d33g0v0_Shanghai - - opcCCDiffPlaces_d34g0v0_Shanghai - - opcCDDiffPlaces_d17g0v0_Shanghai - - opcCDDiffPlaces_d18g0v0_Shanghai - - opcCDDiffPlaces_d19g0v0_Shanghai - - opcCDDiffPlaces_d3g0v0_Shanghai - - opcCDDiffPlaces_d21g0v0_Shanghai - - opcCEDiffPlaces_d0g0v0_Shanghai - - opcCDDiffPlaces_d4g0v0_Shanghai - - opcCDDiffPlaces_d20g0v0_Shanghai - - opcCDDiffPlaces_d22g0v0_Shanghai - - opcCDDiffPlaces_d23g0v0_Shanghai - - opcCDDiffPlaces_d5g0v0_Shanghai - - opcCDDiffPlaces_d6g0v0_Shanghai - - opcCDDiffPlaces_d7g0v0_Shanghai - - opcCDDiffPlaces_d8g0v0_Shanghai - - opcCDDiffPlaces_d24g0v0_Shanghai - - opcCDDiffPlaces_d9g0v0_Shanghai - - opcCDDiffPlaces_d25g0v0_Shanghai - - opcCEDiffPlaces_d1g0v0_Shanghai - - opcCEDiffPlaces_d10g0v0_Shanghai - - opcCDDiffPlaces_d26g0v0_Shanghai - - opcCEDiffPlaces_d11g0v0_Shanghai - - opcCEDiffPlaces_d12g0v0_Shanghai - - opcCDDiffPlaces_d27g0v0_Shanghai - - opcCEDiffPlaces_d13g0v0_Shanghai - - opcCDDiffPlaces_d28g0v0_Shanghai - - opcCEDiffPlaces_d14g0v0_Shanghai - - opcCDDiffPlaces_d29g0v0_Shanghai - - opcCEDiffPlaces_d15g0v0_Shanghai - - opcCDDiffPlaces_d30g0v0_Shanghai - - opcCEDiffPlaces_d16g0v0_Shanghai - - opcCDDiffPlaces_d31g0v0_Shanghai - - opcCEDiffPlaces_d2g0v0_Shanghai - - opcCDDiffPlaces_d32g0v0_Shanghai - - opcCDDiffPlaces_d33g0v0_Shanghai - - opcCDDiffPlaces_d34g0v0_Shanghai - - opcCEDiffPlaces_d17g0v0_Shanghai - - opcCEDiffPlaces_d18g0v0_Shanghai - - opcCEDiffPlaces_d19g0v0_Shanghai - - opcCEDiffPlaces_d3g0v0_Shanghai - - opcCEDiffPlaces_d21g0v0_Shanghai - - opcCFDiffPlaces_d0g0v0_Shanghai - - opcCEDiffPlaces_d4g0v0_Shanghai - - opcCEDiffPlaces_d20g0v0_Shanghai - - opcCEDiffPlaces_d22g0v0_Shanghai - - opcCEDiffPlaces_d5g0v0_Shanghai - - opcCEDiffPlaces_d23g0v0_Shanghai - - opcCEDiffPlaces_d6g0v0_Shanghai - - opcCEDiffPlaces_d7g0v0_Shanghai - - opcCEDiffPlaces_d8g0v0_Shanghai - - opcCEDiffPlaces_d24g0v0_Shanghai - - opcCEDiffPlaces_d9g0v0_Shanghai - - opcCEDiffPlaces_d25g0v0_Shanghai - - opcCFDiffPlaces_d1g0v0_Shanghai - - opcCFDiffPlaces_d10g0v0_Shanghai - - opcCEDiffPlaces_d26g0v0_Shanghai - - opcCFDiffPlaces_d11g0v0_Shanghai - - opcCFDiffPlaces_d12g0v0_Shanghai - - opcCEDiffPlaces_d27g0v0_Shanghai - - opcCFDiffPlaces_d13g0v0_Shanghai - - opcCEDiffPlaces_d28g0v0_Shanghai - - opcCFDiffPlaces_d14g0v0_Shanghai - - opcCEDiffPlaces_d29g0v0_Shanghai - - opcCFDiffPlaces_d15g0v0_Shanghai - - opcCFDiffPlaces_d16g0v0_Shanghai - - opcCEDiffPlaces_d30g0v0_Shanghai - - opcCEDiffPlaces_d31g0v0_Shanghai - - opcCFDiffPlaces_d2g0v0_Shanghai - - opcCEDiffPlaces_d32g0v0_Shanghai - - opcCEDiffPlaces_d33g0v0_Shanghai - - opcCEDiffPlaces_d34g0v0_Shanghai - - opcCFDiffPlaces_d17g0v0_Shanghai - - opcCFDiffPlaces_d18g0v0_Shanghai - - opcCFDiffPlaces_d19g0v0_Shanghai - - opcCFDiffPlaces_d3g0v0_Shanghai - - opcD0DiffPlaces_d0g0v0_Shanghai - - opcCFDiffPlaces_d21g0v0_Shanghai - - opcCFDiffPlaces_d4g0v0_Shanghai - - opcCFDiffPlaces_d20g0v0_Shanghai - - opcCFDiffPlaces_d22g0v0_Shanghai - - opcCFDiffPlaces_d5g0v0_Shanghai - - opcCFDiffPlaces_d23g0v0_Shanghai - - opcCFDiffPlaces_d6g0v0_Shanghai - - opcCFDiffPlaces_d7g0v0_Shanghai - - opcCFDiffPlaces_d8g0v0_Shanghai - - opcCFDiffPlaces_d24g0v0_Shanghai - - opcCFDiffPlaces_d9g0v0_Shanghai - - opcCFDiffPlaces_d25g0v0_Shanghai - - opcD0DiffPlaces_d1g0v0_Shanghai - - opcD0DiffPlaces_d10g0v0_Shanghai - - opcD0DiffPlaces_d11g0v0_Shanghai - - opcCFDiffPlaces_d26g0v0_Shanghai - - opcD0DiffPlaces_d12g0v0_Shanghai - - opcCFDiffPlaces_d27g0v0_Shanghai - - opcD0DiffPlaces_d13g0v0_Shanghai - - opcCFDiffPlaces_d28g0v0_Shanghai - - opcD0DiffPlaces_d14g0v0_Shanghai - - opcCFDiffPlaces_d29g0v0_Shanghai - - opcD0DiffPlaces_d15g0v0_Shanghai - - opcD0DiffPlaces_d16g0v0_Shanghai - - opcCFDiffPlaces_d30g0v0_Shanghai - - opcCFDiffPlaces_d31g0v0_Shanghai - - opcD0DiffPlaces_d2g0v0_Shanghai - - opcCFDiffPlaces_d32g0v0_Shanghai - - opcCFDiffPlaces_d33g0v0_Shanghai - - opcCFDiffPlaces_d34g0v0_Shanghai - - opcD0DiffPlaces_d17g0v0_Shanghai - - opcD0DiffPlaces_d18g0v0_Shanghai - - opcD0DiffPlaces_d19g0v0_Shanghai - - opcD0DiffPlaces_d3g0v0_Shanghai - - opcD1DiffPlaces_d0g0v0_Shanghai - - opcD0DiffPlaces_d21g0v0_Shanghai - - opcD0DiffPlaces_d4g0v0_Shanghai - - opcD0DiffPlaces_d20g0v0_Shanghai - - opcD0DiffPlaces_d22g0v0_Shanghai - - opcD0DiffPlaces_d5g0v0_Shanghai - - opcD0DiffPlaces_d23g0v0_Shanghai - - opcD0DiffPlaces_d6g0v0_Shanghai - - opcD0DiffPlaces_d7g0v0_Shanghai - - opcD0DiffPlaces_d8g0v0_Shanghai - - opcD0DiffPlaces_d9g0v0_Shanghai - - opcD0DiffPlaces_d24g0v0_Shanghai - - opcD1DiffPlaces_d1g0v0_Shanghai - - opcD0DiffPlaces_d25g0v0_Shanghai - - opcD1DiffPlaces_d10g0v0_Shanghai - - opcD1DiffPlaces_d11g0v0_Shanghai - - opcD0DiffPlaces_d26g0v0_Shanghai - - opcD1DiffPlaces_d12g0v0_Shanghai - - opcD0DiffPlaces_d27g0v0_Shanghai - - opcD1DiffPlaces_d13g0v0_Shanghai - - opcD0DiffPlaces_d28g0v0_Shanghai - - opcD1DiffPlaces_d14g0v0_Shanghai - - opcD0DiffPlaces_d29g0v0_Shanghai - - opcD1DiffPlaces_d15g0v0_Shanghai - - opcD0DiffPlaces_d30g0v0_Shanghai - - opcD1DiffPlaces_d16g0v0_Shanghai - - opcD0DiffPlaces_d31g0v0_Shanghai - - opcD1DiffPlaces_d2g0v0_Shanghai - - opcD0DiffPlaces_d32g0v0_Shanghai - - opcD0DiffPlaces_d33g0v0_Shanghai - - opcD0DiffPlaces_d34g0v0_Shanghai - - opcD1DiffPlaces_d17g0v0_Shanghai - - opcD1DiffPlaces_d18g0v0_Shanghai - - opcD1DiffPlaces_d19g0v0_Shanghai - - opcD1DiffPlaces_d3g0v0_Shanghai - - opcD1DiffPlaces_d21g0v0_Shanghai - - opcD2DiffPlaces_d0g0v0_Shanghai - - opcD1DiffPlaces_d4g0v0_Shanghai - - opcD1DiffPlaces_d20g0v0_Shanghai - - opcD1DiffPlaces_d22g0v0_Shanghai - - opcD1DiffPlaces_d5g0v0_Shanghai - - opcD1DiffPlaces_d23g0v0_Shanghai - - opcD1DiffPlaces_d6g0v0_Shanghai - - opcD1DiffPlaces_d7g0v0_Shanghai - - opcD1DiffPlaces_d8g0v0_Shanghai - - opcD1DiffPlaces_d9g0v0_Shanghai - - opcD1DiffPlaces_d24g0v0_Shanghai - - opcD1DiffPlaces_d25g0v0_Shanghai - - opcD2DiffPlaces_d1g0v0_Shanghai - - opcD2DiffPlaces_d10g0v0_Shanghai - - opcD1DiffPlaces_d26g0v0_Shanghai - - opcD2DiffPlaces_d11g0v0_Shanghai - - opcD2DiffPlaces_d12g0v0_Shanghai - - opcD1DiffPlaces_d27g0v0_Shanghai - - opcD2DiffPlaces_d13g0v0_Shanghai - - opcD1DiffPlaces_d28g0v0_Shanghai - - opcD2DiffPlaces_d14g0v0_Shanghai - - opcD1DiffPlaces_d29g0v0_Shanghai - - opcD2DiffPlaces_d15g0v0_Shanghai - - opcD1DiffPlaces_d30g0v0_Shanghai - - opcD2DiffPlaces_d16g0v0_Shanghai - - opcD1DiffPlaces_d31g0v0_Shanghai - - opcD2DiffPlaces_d2g0v0_Shanghai - - opcD1DiffPlaces_d32g0v0_Shanghai - - opcD1DiffPlaces_d33g0v0_Shanghai - - opcD1DiffPlaces_d34g0v0_Shanghai - - opcD2DiffPlaces_d17g0v0_Shanghai - - opcD2DiffPlaces_d18g0v0_Shanghai - - opcD2DiffPlaces_d19g0v0_Shanghai - - opcD2DiffPlaces_d3g0v0_Shanghai - - opcD2DiffPlaces_d21g0v0_Shanghai - - opcD3DiffPlaces_d0g0v0_Shanghai - - opcD2DiffPlaces_d4g0v0_Shanghai - - opcD2DiffPlaces_d20g0v0_Shanghai - - opcD2DiffPlaces_d22g0v0_Shanghai - - opcD2DiffPlaces_d23g0v0_Shanghai - - opcD2DiffPlaces_d5g0v0_Shanghai - - opcD2DiffPlaces_d6g0v0_Shanghai - - opcD2DiffPlaces_d7g0v0_Shanghai - - opcD2DiffPlaces_d8g0v0_Shanghai - - opcD2DiffPlaces_d24g0v0_Shanghai - - opcD2DiffPlaces_d9g0v0_Shanghai - - opcD2DiffPlaces_d25g0v0_Shanghai - - opcD3DiffPlaces_d1g0v0_Shanghai - - opcD3DiffPlaces_d10g0v0_Shanghai - - opcD3DiffPlaces_d11g0v0_Shanghai - - opcD2DiffPlaces_d26g0v0_Shanghai - - opcD3DiffPlaces_d12g0v0_Shanghai - - opcD2DiffPlaces_d27g0v0_Shanghai - - opcD3DiffPlaces_d13g0v0_Shanghai - - opcD2DiffPlaces_d28g0v0_Shanghai - - opcD3DiffPlaces_d14g0v0_Shanghai - - opcD3DiffPlaces_d15g0v0_Shanghai - - opcD2DiffPlaces_d29g0v0_Shanghai - - opcD3DiffPlaces_d16g0v0_Shanghai - - opcD2DiffPlaces_d30g0v0_Shanghai - - opcD2DiffPlaces_d31g0v0_Shanghai - - opcD3DiffPlaces_d2g0v0_Shanghai - - opcD2DiffPlaces_d32g0v0_Shanghai - - opcD2DiffPlaces_d33g0v0_Shanghai - - opcD2DiffPlaces_d34g0v0_Shanghai - - opcD3DiffPlaces_d17g0v0_Shanghai - - opcD3DiffPlaces_d18g0v0_Shanghai - - opcD3DiffPlaces_d19g0v0_Shanghai - - opcD3DiffPlaces_d3g0v0_Shanghai - - opcD3DiffPlaces_d21g0v0_Shanghai - - opcD4DiffPlaces_d0g0v0_Shanghai - - opcD3DiffPlaces_d20g0v0_Shanghai - - opcD3DiffPlaces_d4g0v0_Shanghai - - opcD3DiffPlaces_d22g0v0_Shanghai - - opcD3DiffPlaces_d23g0v0_Shanghai - - opcD3DiffPlaces_d5g0v0_Shanghai - - opcD3DiffPlaces_d6g0v0_Shanghai - - opcD3DiffPlaces_d7g0v0_Shanghai - - opcD3DiffPlaces_d8g0v0_Shanghai - - opcD3DiffPlaces_d24g0v0_Shanghai - - opcD3DiffPlaces_d9g0v0_Shanghai - - opcD3DiffPlaces_d25g0v0_Shanghai - - opcD4DiffPlaces_d1g0v0_Shanghai - - opcD4DiffPlaces_d10g0v0_Shanghai - - opcD4DiffPlaces_d11g0v0_Shanghai - - opcD3DiffPlaces_d26g0v0_Shanghai - - opcD4DiffPlaces_d12g0v0_Shanghai - - opcD3DiffPlaces_d27g0v0_Shanghai - - opcD4DiffPlaces_d13g0v0_Shanghai - - opcD3DiffPlaces_d28g0v0_Shanghai - - opcD4DiffPlaces_d14g0v0_Shanghai - - opcD4DiffPlaces_d15g0v0_Shanghai - - opcD3DiffPlaces_d29g0v0_Shanghai - - opcD3DiffPlaces_d30g0v0_Shanghai - - opcD4DiffPlaces_d16g0v0_Shanghai - - opcD3DiffPlaces_d31g0v0_Shanghai - - opcD4DiffPlaces_d2g0v0_Shanghai - - opcD3DiffPlaces_d32g0v0_Shanghai - - opcD3DiffPlaces_d33g0v0_Shanghai - - opcD3DiffPlaces_d34g0v0_Shanghai - - opcD4DiffPlaces_d17g0v0_Shanghai - - opcD4DiffPlaces_d18g0v0_Shanghai - - opcD4DiffPlaces_d19g0v0_Shanghai - - opcD4DiffPlaces_d3g0v0_Shanghai - - opcD5DiffPlaces_d0g0v0_Shanghai - - opcD4DiffPlaces_d21g0v0_Shanghai - - opcD4DiffPlaces_d4g0v0_Shanghai - - opcD4DiffPlaces_d20g0v0_Shanghai - - opcD4DiffPlaces_d22g0v0_Shanghai - - opcD4DiffPlaces_d5g0v0_Shanghai - - opcD4DiffPlaces_d23g0v0_Shanghai - - opcD4DiffPlaces_d6g0v0_Shanghai - - opcD4DiffPlaces_d7g0v0_Shanghai - - opcD4DiffPlaces_d8g0v0_Shanghai - - opcD4DiffPlaces_d9g0v0_Shanghai - - opcD4DiffPlaces_d24g0v0_Shanghai - - opcD5DiffPlaces_d1g0v0_Shanghai - - opcD4DiffPlaces_d25g0v0_Shanghai - - opcD5DiffPlaces_d10g0v0_Shanghai - - opcD5DiffPlaces_d11g0v0_Shanghai - - opcD4DiffPlaces_d26g0v0_Shanghai - - opcD5DiffPlaces_d12g0v0_Shanghai - - opcD4DiffPlaces_d27g0v0_Shanghai - - opcD5DiffPlaces_d13g0v0_Shanghai - - opcD4DiffPlaces_d28g0v0_Shanghai - - opcD5DiffPlaces_d14g0v0_Shanghai - - opcD4DiffPlaces_d29g0v0_Shanghai - - opcD5DiffPlaces_d15g0v0_Shanghai - - opcD4DiffPlaces_d30g0v0_Shanghai - - opcD5DiffPlaces_d16g0v0_Shanghai - - opcD4DiffPlaces_d31g0v0_Shanghai - - opcD5DiffPlaces_d2g0v0_Shanghai - - opcD4DiffPlaces_d32g0v0_Shanghai - - opcD4DiffPlaces_d33g0v0_Shanghai - - opcD4DiffPlaces_d34g0v0_Shanghai - - opcD5DiffPlaces_d17g0v0_Shanghai - - opcD5DiffPlaces_d18g0v0_Shanghai - - opcD5DiffPlaces_d19g0v0_Shanghai - - opcD5DiffPlaces_d3g0v0_Shanghai - - opcD6DiffPlaces_d0g0v0_Shanghai - - opcD5DiffPlaces_d21g0v0_Shanghai - - opcD5DiffPlaces_d4g0v0_Shanghai - - opcD5DiffPlaces_d20g0v0_Shanghai - - opcD5DiffPlaces_d22g0v0_Shanghai - - opcD5DiffPlaces_d23g0v0_Shanghai - - opcD5DiffPlaces_d5g0v0_Shanghai - - opcD5DiffPlaces_d6g0v0_Shanghai - - opcD5DiffPlaces_d7g0v0_Shanghai - - opcD5DiffPlaces_d8g0v0_Shanghai - - opcD5DiffPlaces_d24g0v0_Shanghai - - opcD5DiffPlaces_d9g0v0_Shanghai - - opcD5DiffPlaces_d25g0v0_Shanghai - - opcD6DiffPlaces_d1g0v0_Shanghai - - opcD6DiffPlaces_d10g0v0_Shanghai - - opcD6DiffPlaces_d11g0v0_Shanghai - - opcD5DiffPlaces_d26g0v0_Shanghai - - opcD6DiffPlaces_d12g0v0_Shanghai - - opcD5DiffPlaces_d27g0v0_Shanghai - - opcD6DiffPlaces_d13g0v0_Shanghai - - opcD5DiffPlaces_d28g0v0_Shanghai - - opcD6DiffPlaces_d14g0v0_Shanghai - - opcD5DiffPlaces_d29g0v0_Shanghai - - opcD6DiffPlaces_d15g0v0_Shanghai - - opcD6DiffPlaces_d16g0v0_Shanghai - - opcD5DiffPlaces_d30g0v0_Shanghai - - opcD5DiffPlaces_d31g0v0_Shanghai - - opcD6DiffPlaces_d2g0v0_Shanghai - - opcD5DiffPlaces_d32g0v0_Shanghai - - opcD5DiffPlaces_d33g0v0_Shanghai - - opcD5DiffPlaces_d34g0v0_Shanghai - - opcD6DiffPlaces_d17g0v0_Shanghai - - opcD6DiffPlaces_d18g0v0_Shanghai - - opcD6DiffPlaces_d3g0v0_Shanghai - - opcD6DiffPlaces_d19g0v0_Shanghai - - opcD6DiffPlaces_d21g0v0_Shanghai - - opcD6DiffPlaces_d4g0v0_Shanghai - - opcD7DiffPlaces_d0g0v0_Shanghai - - opcD6DiffPlaces_d20g0v0_Shanghai - - opcD6DiffPlaces_d22g0v0_Shanghai - - opcD6DiffPlaces_d5g0v0_Shanghai - - opcD6DiffPlaces_d23g0v0_Shanghai - - opcD6DiffPlaces_d6g0v0_Shanghai - - opcD6DiffPlaces_d7g0v0_Shanghai - - opcD6DiffPlaces_d8g0v0_Shanghai - - opcD6DiffPlaces_d24g0v0_Shanghai - - opcD6DiffPlaces_d9g0v0_Shanghai - - opcD7DiffPlaces_d1g0v0_Shanghai - - opcD6DiffPlaces_d25g0v0_Shanghai - - opcD7DiffPlaces_d10g0v0_Shanghai - - opcD7DiffPlaces_d11g0v0_Shanghai - - opcD6DiffPlaces_d26g0v0_Shanghai - - opcD7DiffPlaces_d12g0v0_Shanghai - - opcD7DiffPlaces_d13g0v0_Shanghai - - opcD6DiffPlaces_d27g0v0_Shanghai - - opcD6DiffPlaces_d28g0v0_Shanghai - - opcD7DiffPlaces_d14g0v0_Shanghai - - opcD7DiffPlaces_d15g0v0_Shanghai - - opcD6DiffPlaces_d29g0v0_Shanghai - - opcD6DiffPlaces_d30g0v0_Shanghai - - opcD6DiffPlaces_d31g0v0_Shanghai - - opcD7DiffPlaces_d16g0v0_Shanghai - - opcD7DiffPlaces_d2g0v0_Shanghai - - opcD6DiffPlaces_d32g0v0_Shanghai - - opcD6DiffPlaces_d33g0v0_Shanghai - - opcD6DiffPlaces_d34g0v0_Shanghai - - opcD7DiffPlaces_d17g0v0_Shanghai - - opcD7DiffPlaces_d18g0v0_Shanghai - - opcD7DiffPlaces_d19g0v0_Shanghai - - opcD7DiffPlaces_d3g0v0_Shanghai - - opcD7DiffPlaces_d21g0v0_Shanghai - - opcD8DiffPlaces_d0g0v0_Shanghai - - opcD7DiffPlaces_d4g0v0_Shanghai - - opcD7DiffPlaces_d20g0v0_Shanghai - - opcD7DiffPlaces_d22g0v0_Shanghai - - opcD7DiffPlaces_d5g0v0_Shanghai - - opcD7DiffPlaces_d23g0v0_Shanghai - - opcD7DiffPlaces_d6g0v0_Shanghai - - opcD7DiffPlaces_d7g0v0_Shanghai - - opcD7DiffPlaces_d8g0v0_Shanghai - - opcD7DiffPlaces_d24g0v0_Shanghai - - opcD7DiffPlaces_d9g0v0_Shanghai - - opcD8DiffPlaces_d1g0v0_Shanghai - - opcD7DiffPlaces_d25g0v0_Shanghai - - opcD8DiffPlaces_d10g0v0_Shanghai - - opcD8DiffPlaces_d11g0v0_Shanghai - - opcD7DiffPlaces_d26g0v0_Shanghai - - opcD8DiffPlaces_d12g0v0_Shanghai - - opcD7DiffPlaces_d27g0v0_Shanghai - - opcD8DiffPlaces_d13g0v0_Shanghai - - opcD7DiffPlaces_d28g0v0_Shanghai - - opcD8DiffPlaces_d14g0v0_Shanghai - - opcD7DiffPlaces_d29g0v0_Shanghai - - opcD8DiffPlaces_d15g0v0_Shanghai - - opcD8DiffPlaces_d16g0v0_Shanghai - - opcD7DiffPlaces_d30g0v0_Shanghai - - opcD7DiffPlaces_d31g0v0_Shanghai - - opcD8DiffPlaces_d2g0v0_Shanghai - - opcD7DiffPlaces_d32g0v0_Shanghai - - opcD7DiffPlaces_d33g0v0_Shanghai - - opcD7DiffPlaces_d34g0v0_Shanghai - - opcD8DiffPlaces_d17g0v0_Shanghai - - opcD8DiffPlaces_d18g0v0_Shanghai - - opcD8DiffPlaces_d19g0v0_Shanghai - - opcD8DiffPlaces_d3g0v0_Shanghai - - opcD8DiffPlaces_d21g0v0_Shanghai - - opcD9DiffPlaces_d0g0v0_Shanghai - - opcD8DiffPlaces_d4g0v0_Shanghai - - opcD8DiffPlaces_d20g0v0_Shanghai - - opcD8DiffPlaces_d22g0v0_Shanghai - - opcD8DiffPlaces_d5g0v0_Shanghai - - opcD8DiffPlaces_d23g0v0_Shanghai - - opcD8DiffPlaces_d6g0v0_Shanghai - - opcD8DiffPlaces_d7g0v0_Shanghai - - opcD8DiffPlaces_d8g0v0_Shanghai - - opcD8DiffPlaces_d24g0v0_Shanghai - - opcD8DiffPlaces_d9g0v0_Shanghai - - opcD8DiffPlaces_d25g0v0_Shanghai - - opcD9DiffPlaces_d1g0v0_Shanghai - - opcD9DiffPlaces_d10g0v0_Shanghai - - opcD8DiffPlaces_d26g0v0_Shanghai - - opcD9DiffPlaces_d11g0v0_Shanghai - - opcD9DiffPlaces_d12g0v0_Shanghai - - opcD8DiffPlaces_d27g0v0_Shanghai - - opcD9DiffPlaces_d13g0v0_Shanghai - - opcD8DiffPlaces_d28g0v0_Shanghai - - opcD9DiffPlaces_d14g0v0_Shanghai - - opcD8DiffPlaces_d29g0v0_Shanghai - - opcD9DiffPlaces_d15g0v0_Shanghai - - opcD8DiffPlaces_d30g0v0_Shanghai - - opcD9DiffPlaces_d16g0v0_Shanghai - - opcD8DiffPlaces_d31g0v0_Shanghai - - opcD9DiffPlaces_d2g0v0_Shanghai - - opcD8DiffPlaces_d32g0v0_Shanghai - - opcD8DiffPlaces_d33g0v0_Shanghai - - opcD8DiffPlaces_d34g0v0_Shanghai - - opcD9DiffPlaces_d17g0v0_Shanghai - - opcD9DiffPlaces_d18g0v0_Shanghai - - opcD9DiffPlaces_d19g0v0_Shanghai - - opcD9DiffPlaces_d3g0v0_Shanghai - - opcD9DiffPlaces_d21g0v0_Shanghai - - opcDADiffPlaces_d0g0v0_Shanghai - - opcD9DiffPlaces_d4g0v0_Shanghai - - opcD9DiffPlaces_d20g0v0_Shanghai - - opcD9DiffPlaces_d22g0v0_Shanghai - - opcD9DiffPlaces_d5g0v0_Shanghai - - opcD9DiffPlaces_d23g0v0_Shanghai - - opcD9DiffPlaces_d6g0v0_Shanghai - - opcD9DiffPlaces_d7g0v0_Shanghai - - opcD9DiffPlaces_d8g0v0_Shanghai - - opcD9DiffPlaces_d9g0v0_Shanghai - - opcD9DiffPlaces_d24g0v0_Shanghai - - opcD9DiffPlaces_d25g0v0_Shanghai - - opcDADiffPlaces_d1g0v0_Shanghai - - opcDADiffPlaces_d10g0v0_Shanghai - - opcDADiffPlaces_d11g0v0_Shanghai - - opcD9DiffPlaces_d26g0v0_Shanghai - - opcDADiffPlaces_d12g0v0_Shanghai - - opcD9DiffPlaces_d27g0v0_Shanghai - - opcDADiffPlaces_d13g0v0_Shanghai - - opcD9DiffPlaces_d28g0v0_Shanghai - - opcDADiffPlaces_d14g0v0_Shanghai - - opcD9DiffPlaces_d29g0v0_Shanghai - - opcDADiffPlaces_d15g0v0_Shanghai - - opcD9DiffPlaces_d30g0v0_Shanghai - - opcDADiffPlaces_d16g0v0_Shanghai - - opcD9DiffPlaces_d31g0v0_Shanghai - - opcD9DiffPlaces_d32g0v0_Shanghai - - opcDADiffPlaces_d2g0v0_Shanghai - - opcD9DiffPlaces_d33g0v0_Shanghai - - opcD9DiffPlaces_d34g0v0_Shanghai - - opcDADiffPlaces_d17g0v0_Shanghai - - opcDADiffPlaces_d18g0v0_Shanghai - - opcDADiffPlaces_d19g0v0_Shanghai - - opcDADiffPlaces_d3g0v0_Shanghai - - opcDADiffPlaces_d21g0v0_Shanghai - - opcDBDiffPlaces_d0g0v0_Shanghai - - opcDADiffPlaces_d20g0v0_Shanghai - - opcDADiffPlaces_d4g0v0_Shanghai - - opcDADiffPlaces_d22g0v0_Shanghai - - opcDADiffPlaces_d5g0v0_Shanghai - - opcDADiffPlaces_d23g0v0_Shanghai - - opcDADiffPlaces_d6g0v0_Shanghai - - opcDADiffPlaces_d7g0v0_Shanghai - - opcDADiffPlaces_d8g0v0_Shanghai - - opcDADiffPlaces_d9g0v0_Shanghai - - opcDADiffPlaces_d24g0v0_Shanghai - - opcDADiffPlaces_d25g0v0_Shanghai - - opcDBDiffPlaces_d1g0v0_Shanghai - - opcDBDiffPlaces_d10g0v0_Shanghai - - opcDADiffPlaces_d26g0v0_Shanghai - - opcDBDiffPlaces_d11g0v0_Shanghai - - opcDBDiffPlaces_d12g0v0_Shanghai - - opcDBDiffPlaces_d13g0v0_Shanghai - - opcDADiffPlaces_d27g0v0_Shanghai - - opcDADiffPlaces_d28g0v0_Shanghai - - opcDBDiffPlaces_d14g0v0_Shanghai - - opcDADiffPlaces_d29g0v0_Shanghai - - opcDBDiffPlaces_d15g0v0_Shanghai - - opcDADiffPlaces_d30g0v0_Shanghai - - opcDADiffPlaces_d31g0v0_Shanghai - - opcDBDiffPlaces_d16g0v0_Shanghai - - opcDBDiffPlaces_d2g0v0_Shanghai - - opcDADiffPlaces_d32g0v0_Shanghai - - opcDADiffPlaces_d33g0v0_Shanghai - - opcDADiffPlaces_d34g0v0_Shanghai - - opcDBDiffPlaces_d17g0v0_Shanghai - - opcDBDiffPlaces_d18g0v0_Shanghai - - opcDBDiffPlaces_d19g0v0_Shanghai - - opcDBDiffPlaces_d3g0v0_Shanghai - - opcDBDiffPlaces_d21g0v0_Shanghai - - opcDCDiffPlaces_d0g0v0_Shanghai - - opcDBDiffPlaces_d20g0v0_Shanghai - - opcDBDiffPlaces_d4g0v0_Shanghai - - opcDBDiffPlaces_d22g0v0_Shanghai - - opcDBDiffPlaces_d5g0v0_Shanghai - - opcDBDiffPlaces_d23g0v0_Shanghai - - opcDBDiffPlaces_d6g0v0_Shanghai - - opcDBDiffPlaces_d7g0v0_Shanghai - - opcDBDiffPlaces_d8g0v0_Shanghai - - opcDBDiffPlaces_d24g0v0_Shanghai - - opcDBDiffPlaces_d9g0v0_Shanghai - - opcDBDiffPlaces_d25g0v0_Shanghai - - opcDCDiffPlaces_d1g0v0_Shanghai - - opcDCDiffPlaces_d10g0v0_Shanghai - - opcDCDiffPlaces_d11g0v0_Shanghai - - opcDBDiffPlaces_d26g0v0_Shanghai - - opcDCDiffPlaces_d12g0v0_Shanghai - - opcDBDiffPlaces_d27g0v0_Shanghai - - opcDCDiffPlaces_d13g0v0_Shanghai - - opcDBDiffPlaces_d28g0v0_Shanghai - - opcDCDiffPlaces_d14g0v0_Shanghai - - opcDBDiffPlaces_d29g0v0_Shanghai - - opcDCDiffPlaces_d15g0v0_Shanghai - - opcDBDiffPlaces_d31g0v0_Shanghai - - opcDBDiffPlaces_d30g0v0_Shanghai - - opcDCDiffPlaces_d16g0v0_Shanghai - - opcDBDiffPlaces_d32g0v0_Shanghai - - opcDCDiffPlaces_d2g0v0_Shanghai - - opcDBDiffPlaces_d33g0v0_Shanghai - - opcDBDiffPlaces_d34g0v0_Shanghai - - opcDCDiffPlaces_d17g0v0_Shanghai - - opcDCDiffPlaces_d18g0v0_Shanghai - - opcDCDiffPlaces_d19g0v0_Shanghai - - opcDCDiffPlaces_d3g0v0_Shanghai - - opcDCDiffPlaces_d21g0v0_Shanghai - - opcDDDiffPlaces_d0g0v0_Shanghai - - opcDCDiffPlaces_d4g0v0_Shanghai - - opcDCDiffPlaces_d20g0v0_Shanghai - - opcDCDiffPlaces_d22g0v0_Shanghai - - opcDCDiffPlaces_d5g0v0_Shanghai - - opcDCDiffPlaces_d23g0v0_Shanghai - - opcDCDiffPlaces_d6g0v0_Shanghai - - opcDCDiffPlaces_d7g0v0_Shanghai - - opcDCDiffPlaces_d8g0v0_Shanghai - - opcDCDiffPlaces_d9g0v0_Shanghai - - opcDCDiffPlaces_d24g0v0_Shanghai - - opcDCDiffPlaces_d25g0v0_Shanghai - - opcDDDiffPlaces_d1g0v0_Shanghai - - opcDDDiffPlaces_d10g0v0_Shanghai - - opcDDDiffPlaces_d11g0v0_Shanghai - - opcDCDiffPlaces_d26g0v0_Shanghai - - opcDDDiffPlaces_d12g0v0_Shanghai - - opcDCDiffPlaces_d27g0v0_Shanghai - - opcDDDiffPlaces_d13g0v0_Shanghai - - opcDCDiffPlaces_d28g0v0_Shanghai - - opcDDDiffPlaces_d14g0v0_Shanghai - - opcDCDiffPlaces_d29g0v0_Shanghai - - opcDDDiffPlaces_d15g0v0_Shanghai - - opcDCDiffPlaces_d30g0v0_Shanghai - - opcDDDiffPlaces_d16g0v0_Shanghai - - opcDCDiffPlaces_d31g0v0_Shanghai - - opcDDDiffPlaces_d2g0v0_Shanghai - - opcDCDiffPlaces_d32g0v0_Shanghai - - opcDCDiffPlaces_d33g0v0_Shanghai - - opcDCDiffPlaces_d34g0v0_Shanghai - - opcDDDiffPlaces_d17g0v0_Shanghai - - opcDDDiffPlaces_d18g0v0_Shanghai - - opcDDDiffPlaces_d19g0v0_Shanghai - - opcDDDiffPlaces_d3g0v0_Shanghai - - opcDEDiffPlaces_d0g0v0_Shanghai - - opcDDDiffPlaces_d21g0v0_Shanghai - - opcDDDiffPlaces_d4g0v0_Shanghai - - opcDDDiffPlaces_d20g0v0_Shanghai - - opcDDDiffPlaces_d22g0v0_Shanghai - - opcDDDiffPlaces_d5g0v0_Shanghai - - opcDDDiffPlaces_d23g0v0_Shanghai - - opcDDDiffPlaces_d6g0v0_Shanghai - - opcDDDiffPlaces_d7g0v0_Shanghai - - opcDDDiffPlaces_d8g0v0_Shanghai - - opcDDDiffPlaces_d24g0v0_Shanghai - - opcDDDiffPlaces_d9g0v0_Shanghai - - opcDDDiffPlaces_d25g0v0_Shanghai - - opcDEDiffPlaces_d1g0v0_Shanghai - - opcDEDiffPlaces_d10g0v0_Shanghai - - opcDEDiffPlaces_d11g0v0_Shanghai - - opcDDDiffPlaces_d26g0v0_Shanghai - - opcDEDiffPlaces_d12g0v0_Shanghai - - opcDDDiffPlaces_d27g0v0_Shanghai - - opcDEDiffPlaces_d13g0v0_Shanghai - - opcDDDiffPlaces_d28g0v0_Shanghai - - opcDEDiffPlaces_d14g0v0_Shanghai - - opcDDDiffPlaces_d29g0v0_Shanghai - - opcDEDiffPlaces_d15g0v0_Shanghai - - opcDDDiffPlaces_d30g0v0_Shanghai - - opcDEDiffPlaces_d16g0v0_Shanghai - - opcDDDiffPlaces_d31g0v0_Shanghai - - opcDEDiffPlaces_d2g0v0_Shanghai - - opcDDDiffPlaces_d32g0v0_Shanghai - - opcDDDiffPlaces_d33g0v0_Shanghai - - opcDDDiffPlaces_d34g0v0_Shanghai - - opcDEDiffPlaces_d17g0v0_Shanghai - - opcDEDiffPlaces_d18g0v0_Shanghai - - opcDEDiffPlaces_d19g0v0_Shanghai - - opcDEDiffPlaces_d3g0v0_Shanghai - - opcDEDiffPlaces_d21g0v0_Shanghai - - opcDFDiffPlaces_d0g0v0_Shanghai - - opcDEDiffPlaces_d20g0v0_Shanghai - - opcDEDiffPlaces_d4g0v0_Shanghai - - opcDEDiffPlaces_d22g0v0_Shanghai - - opcDEDiffPlaces_d5g0v0_Shanghai - - opcDEDiffPlaces_d23g0v0_Shanghai - - opcDEDiffPlaces_d6g0v0_Shanghai - - opcDEDiffPlaces_d7g0v0_Shanghai - - opcDEDiffPlaces_d8g0v0_Shanghai - - opcDEDiffPlaces_d24g0v0_Shanghai - - opcDEDiffPlaces_d9g0v0_Shanghai - - opcDEDiffPlaces_d25g0v0_Shanghai - - opcDFDiffPlaces_d1g0v0_Shanghai - - opcDFDiffPlaces_d10g0v0_Shanghai - - opcDFDiffPlaces_d11g0v0_Shanghai - - opcDEDiffPlaces_d26g0v0_Shanghai - - opcDFDiffPlaces_d12g0v0_Shanghai - - opcDEDiffPlaces_d27g0v0_Shanghai - - opcDFDiffPlaces_d13g0v0_Shanghai - - opcDEDiffPlaces_d28g0v0_Shanghai - - opcDFDiffPlaces_d14g0v0_Shanghai - - opcDEDiffPlaces_d29g0v0_Shanghai - - opcDFDiffPlaces_d15g0v0_Shanghai - - opcDEDiffPlaces_d30g0v0_Shanghai - - opcDFDiffPlaces_d16g0v0_Shanghai - - opcDEDiffPlaces_d31g0v0_Shanghai - - opcDEDiffPlaces_d32g0v0_Shanghai - - opcDFDiffPlaces_d2g0v0_Shanghai - - opcDEDiffPlaces_d33g0v0_Shanghai - - opcDEDiffPlaces_d34g0v0_Shanghai - - opcDFDiffPlaces_d17g0v0_Shanghai - - opcDFDiffPlaces_d18g0v0_Shanghai - - opcDFDiffPlaces_d19g0v0_Shanghai - - opcDFDiffPlaces_d3g0v0_Shanghai - - opcDFDiffPlaces_d21g0v0_Shanghai - - opcE0DiffPlaces_d0g0v0_Shanghai - - opcDFDiffPlaces_d4g0v0_Shanghai - - opcDFDiffPlaces_d20g0v0_Shanghai - - opcDFDiffPlaces_d22g0v0_Shanghai - - opcDFDiffPlaces_d5g0v0_Shanghai - - opcDFDiffPlaces_d23g0v0_Shanghai - - opcDFDiffPlaces_d6g0v0_Shanghai - - opcDFDiffPlaces_d7g0v0_Shanghai - - opcDFDiffPlaces_d8g0v0_Shanghai - - opcDFDiffPlaces_d9g0v0_Shanghai - - opcDFDiffPlaces_d24g0v0_Shanghai - - opcDFDiffPlaces_d25g0v0_Shanghai - - opcE0DiffPlaces_d1g0v0_Shanghai - - opcE0DiffPlaces_d10g0v0_Shanghai - - opcE0DiffPlaces_d11g0v0_Shanghai - - opcDFDiffPlaces_d26g0v0_Shanghai - - opcE0DiffPlaces_d12g0v0_Shanghai - - opcDFDiffPlaces_d27g0v0_Shanghai - - opcE0DiffPlaces_d13g0v0_Shanghai - - opcDFDiffPlaces_d28g0v0_Shanghai - - opcE0DiffPlaces_d14g0v0_Shanghai - - opcDFDiffPlaces_d29g0v0_Shanghai - - opcE0DiffPlaces_d15g0v0_Shanghai - - opcE0DiffPlaces_d16g0v0_Shanghai - - opcDFDiffPlaces_d30g0v0_Shanghai - - opcDFDiffPlaces_d31g0v0_Shanghai - - opcE0DiffPlaces_d2g0v0_Shanghai - - opcDFDiffPlaces_d32g0v0_Shanghai - - opcDFDiffPlaces_d33g0v0_Shanghai - - opcDFDiffPlaces_d34g0v0_Shanghai - - opcE0DiffPlaces_d17g0v0_Shanghai - - opcE0DiffPlaces_d18g0v0_Shanghai - - opcE0DiffPlaces_d19g0v0_Shanghai - - opcE0DiffPlaces_d3g0v0_Shanghai - - opcE0DiffPlaces_d21g0v0_Shanghai - - opcE1DiffPlaces_d0g0v0_Shanghai - - opcE0DiffPlaces_d4g0v0_Shanghai - - opcE0DiffPlaces_d20g0v0_Shanghai - - opcE0DiffPlaces_d22g0v0_Shanghai - - opcE0DiffPlaces_d5g0v0_Shanghai - - opcE0DiffPlaces_d23g0v0_Shanghai - - opcE0DiffPlaces_d6g0v0_Shanghai - - opcE0DiffPlaces_d7g0v0_Shanghai - - opcE0DiffPlaces_d8g0v0_Shanghai - - opcE0DiffPlaces_d24g0v0_Shanghai - - opcE0DiffPlaces_d9g0v0_Shanghai - - opcE0DiffPlaces_d25g0v0_Shanghai - - opcE1DiffPlaces_d1g0v0_Shanghai - - opcE1DiffPlaces_d10g0v0_Shanghai - - opcE0DiffPlaces_d26g0v0_Shanghai - - opcE1DiffPlaces_d11g0v0_Shanghai - - opcE1DiffPlaces_d12g0v0_Shanghai - - opcE0DiffPlaces_d27g0v0_Shanghai - - opcE1DiffPlaces_d13g0v0_Shanghai - - opcE0DiffPlaces_d28g0v0_Shanghai - - opcE1DiffPlaces_d14g0v0_Shanghai - - opcE0DiffPlaces_d29g0v0_Shanghai - - opcE1DiffPlaces_d15g0v0_Shanghai - - opcE0DiffPlaces_d30g0v0_Shanghai - - opcE0DiffPlaces_d31g0v0_Shanghai - - opcE1DiffPlaces_d16g0v0_Shanghai - - opcE0DiffPlaces_d32g0v0_Shanghai - - opcE1DiffPlaces_d2g0v0_Shanghai - - opcE0DiffPlaces_d33g0v0_Shanghai - - opcE0DiffPlaces_d34g0v0_Shanghai - - opcE1DiffPlaces_d17g0v0_Shanghai - - opcE1DiffPlaces_d18g0v0_Shanghai - - opcE1DiffPlaces_d19g0v0_Shanghai - - opcE1DiffPlaces_d3g0v0_Shanghai - - opcE1DiffPlaces_d21g0v0_Shanghai - - opcE2DiffPlaces_d0g0v0_Shanghai - - opcE1DiffPlaces_d4g0v0_Shanghai - - opcE1DiffPlaces_d20g0v0_Shanghai - - opcE1DiffPlaces_d22g0v0_Shanghai - - opcE1DiffPlaces_d5g0v0_Shanghai - - opcE1DiffPlaces_d23g0v0_Shanghai - - opcE1DiffPlaces_d6g0v0_Shanghai - - opcE1DiffPlaces_d7g0v0_Shanghai - - opcE1DiffPlaces_d8g0v0_Shanghai - - opcE1DiffPlaces_d9g0v0_Shanghai - - opcE1DiffPlaces_d24g0v0_Shanghai - - opcE1DiffPlaces_d25g0v0_Shanghai - - opcE2DiffPlaces_d1g0v0_Shanghai - - opcE2DiffPlaces_d10g0v0_Shanghai - - opcE2DiffPlaces_d11g0v0_Shanghai - - opcE1DiffPlaces_d26g0v0_Shanghai - - opcE2DiffPlaces_d12g0v0_Shanghai - - opcE1DiffPlaces_d27g0v0_Shanghai - - opcE2DiffPlaces_d13g0v0_Shanghai - - opcE1DiffPlaces_d28g0v0_Shanghai - - opcE2DiffPlaces_d14g0v0_Shanghai - - opcE1DiffPlaces_d29g0v0_Shanghai - - opcE2DiffPlaces_d15g0v0_Shanghai - - opcE1DiffPlaces_d30g0v0_Shanghai - - opcE1DiffPlaces_d31g0v0_Shanghai - - opcE2DiffPlaces_d16g0v0_Shanghai - - opcE2DiffPlaces_d2g0v0_Shanghai - - opcE1DiffPlaces_d32g0v0_Shanghai - - opcE1DiffPlaces_d33g0v0_Shanghai - - opcE1DiffPlaces_d34g0v0_Shanghai - - opcE2DiffPlaces_d17g0v0_Shanghai - - opcE2DiffPlaces_d18g0v0_Shanghai - - opcE2DiffPlaces_d19g0v0_Shanghai - - opcE2DiffPlaces_d3g0v0_Shanghai - - opcE2DiffPlaces_d21g0v0_Shanghai - - opcE3DiffPlaces_d0g0v0_Shanghai - - opcE2DiffPlaces_d4g0v0_Shanghai - - opcE2DiffPlaces_d20g0v0_Shanghai - - opcE2DiffPlaces_d22g0v0_Shanghai - - opcE2DiffPlaces_d5g0v0_Shanghai - - opcE2DiffPlaces_d23g0v0_Shanghai - - opcE2DiffPlaces_d6g0v0_Shanghai - - opcE2DiffPlaces_d7g0v0_Shanghai - - opcE2DiffPlaces_d8g0v0_Shanghai - - opcE2DiffPlaces_d24g0v0_Shanghai - - opcE2DiffPlaces_d9g0v0_Shanghai - - opcE3DiffPlaces_d1g0v0_Shanghai - - opcE2DiffPlaces_d25g0v0_Shanghai - - opcE3DiffPlaces_d10g0v0_Shanghai - - opcE2DiffPlaces_d26g0v0_Shanghai - - opcE3DiffPlaces_d11g0v0_Shanghai - - opcE3DiffPlaces_d12g0v0_Shanghai - - opcE2DiffPlaces_d27g0v0_Shanghai - - opcE3DiffPlaces_d13g0v0_Shanghai - - opcE2DiffPlaces_d28g0v0_Shanghai - - opcE3DiffPlaces_d14g0v0_Shanghai - - opcE2DiffPlaces_d29g0v0_Shanghai - - opcE3DiffPlaces_d15g0v0_Shanghai - - opcE3DiffPlaces_d16g0v0_Shanghai - - opcE2DiffPlaces_d30g0v0_Shanghai - - opcE2DiffPlaces_d31g0v0_Shanghai - - opcE2DiffPlaces_d32g0v0_Shanghai - - opcE3DiffPlaces_d2g0v0_Shanghai - - opcE2DiffPlaces_d33g0v0_Shanghai - - opcE2DiffPlaces_d34g0v0_Shanghai - - opcE3DiffPlaces_d17g0v0_Shanghai - - opcE3DiffPlaces_d18g0v0_Shanghai - - opcE3DiffPlaces_d19g0v0_Shanghai - - opcE3DiffPlaces_d3g0v0_Shanghai - - opcE4DiffPlaces_d0g0v0_Shanghai - - opcE3DiffPlaces_d21g0v0_Shanghai - - opcE3DiffPlaces_d20g0v0_Shanghai - - opcE3DiffPlaces_d4g0v0_Shanghai - - opcE3DiffPlaces_d22g0v0_Shanghai - - opcE3DiffPlaces_d5g0v0_Shanghai - - opcE3DiffPlaces_d23g0v0_Shanghai - - opcE3DiffPlaces_d6g0v0_Shanghai - - opcE3DiffPlaces_d7g0v0_Shanghai - - opcE3DiffPlaces_d8g0v0_Shanghai - - opcE3DiffPlaces_d9g0v0_Shanghai - - opcE3DiffPlaces_d24g0v0_Shanghai - - opcE3DiffPlaces_d25g0v0_Shanghai - - opcE4DiffPlaces_d1g0v0_Shanghai - - opcE4DiffPlaces_d10g0v0_Shanghai - - opcE4DiffPlaces_d11g0v0_Shanghai - - opcE3DiffPlaces_d26g0v0_Shanghai - - opcE4DiffPlaces_d12g0v0_Shanghai - - opcE3DiffPlaces_d27g0v0_Shanghai - - opcE4DiffPlaces_d13g0v0_Shanghai - - opcE3DiffPlaces_d28g0v0_Shanghai - - opcE4DiffPlaces_d14g0v0_Shanghai - - opcE3DiffPlaces_d29g0v0_Shanghai - - opcE4DiffPlaces_d15g0v0_Shanghai - - opcE3DiffPlaces_d30g0v0_Shanghai - - opcE4DiffPlaces_d16g0v0_Shanghai - - opcE3DiffPlaces_d31g0v0_Shanghai - - opcE4DiffPlaces_d2g0v0_Shanghai - - opcE3DiffPlaces_d32g0v0_Shanghai - - opcE3DiffPlaces_d33g0v0_Shanghai - - opcE3DiffPlaces_d34g0v0_Shanghai - - opcE4DiffPlaces_d17g0v0_Shanghai - - opcE4DiffPlaces_d18g0v0_Shanghai - - opcE4DiffPlaces_d19g0v0_Shanghai - - opcE4DiffPlaces_d3g0v0_Shanghai - - opcE4DiffPlaces_d21g0v0_Shanghai - - opcE5DiffPlaces_d0g0v0_Shanghai - - opcE4DiffPlaces_d20g0v0_Shanghai - - opcE4DiffPlaces_d4g0v0_Shanghai - - opcE4DiffPlaces_d22g0v0_Shanghai - - opcE4DiffPlaces_d23g0v0_Shanghai - - opcE4DiffPlaces_d5g0v0_Shanghai - - opcE4DiffPlaces_d6g0v0_Shanghai - - opcE4DiffPlaces_d7g0v0_Shanghai - - opcE4DiffPlaces_d8g0v0_Shanghai - - opcE4DiffPlaces_d24g0v0_Shanghai - - opcE4DiffPlaces_d9g0v0_Shanghai - - opcE4DiffPlaces_d25g0v0_Shanghai - - opcE5DiffPlaces_d1g0v0_Shanghai - - opcE5DiffPlaces_d10g0v0_Shanghai - - opcE5DiffPlaces_d11g0v0_Shanghai - - opcE4DiffPlaces_d26g0v0_Shanghai - - opcE5DiffPlaces_d12g0v0_Shanghai - - opcE4DiffPlaces_d27g0v0_Shanghai - - opcE5DiffPlaces_d13g0v0_Shanghai - - opcE4DiffPlaces_d28g0v0_Shanghai - - opcE5DiffPlaces_d14g0v0_Shanghai - - opcE4DiffPlaces_d29g0v0_Shanghai - - opcE5DiffPlaces_d15g0v0_Shanghai - - opcE5DiffPlaces_d16g0v0_Shanghai - - opcE4DiffPlaces_d31g0v0_Shanghai - - opcE4DiffPlaces_d30g0v0_Shanghai - - opcE4DiffPlaces_d32g0v0_Shanghai - - opcE5DiffPlaces_d2g0v0_Shanghai - - opcE4DiffPlaces_d33g0v0_Shanghai - - opcE4DiffPlaces_d34g0v0_Shanghai - - opcE5DiffPlaces_d17g0v0_Shanghai - - opcE5DiffPlaces_d18g0v0_Shanghai - - opcE5DiffPlaces_d19g0v0_Shanghai - - opcE5DiffPlaces_d3g0v0_Shanghai - - opcE6DiffPlaces_d0g0v0_Shanghai - - opcE5DiffPlaces_d21g0v0_Shanghai - - opcE5DiffPlaces_d4g0v0_Shanghai - - opcE5DiffPlaces_d20g0v0_Shanghai - - opcE5DiffPlaces_d22g0v0_Shanghai - - opcE5DiffPlaces_d5g0v0_Shanghai - - opcE5DiffPlaces_d23g0v0_Shanghai - - opcE5DiffPlaces_d6g0v0_Shanghai - - opcE5DiffPlaces_d7g0v0_Shanghai - - opcE5DiffPlaces_d8g0v0_Shanghai - - opcE5DiffPlaces_d24g0v0_Shanghai - - opcE5DiffPlaces_d9g0v0_Shanghai - - opcE5DiffPlaces_d25g0v0_Shanghai - - opcE6DiffPlaces_d1g0v0_Shanghai - - opcE6DiffPlaces_d10g0v0_Shanghai - - opcE6DiffPlaces_d11g0v0_Shanghai - - opcE5DiffPlaces_d26g0v0_Shanghai - - opcE6DiffPlaces_d12g0v0_Shanghai - - opcE6DiffPlaces_d13g0v0_Shanghai - - opcE5DiffPlaces_d27g0v0_Shanghai - - opcE5DiffPlaces_d28g0v0_Shanghai - - opcE6DiffPlaces_d14g0v0_Shanghai - - opcE5DiffPlaces_d29g0v0_Shanghai - - opcE6DiffPlaces_d15g0v0_Shanghai - - opcE5DiffPlaces_d30g0v0_Shanghai - - opcE6DiffPlaces_d16g0v0_Shanghai - - opcE5DiffPlaces_d31g0v0_Shanghai - - opcE6DiffPlaces_d2g0v0_Shanghai - - opcE5DiffPlaces_d32g0v0_Shanghai - - opcE5DiffPlaces_d33g0v0_Shanghai - - opcE5DiffPlaces_d34g0v0_Shanghai - - opcE6DiffPlaces_d17g0v0_Shanghai - - opcE6DiffPlaces_d18g0v0_Shanghai - - opcE6DiffPlaces_d19g0v0_Shanghai - - opcE6DiffPlaces_d3g0v0_Shanghai - - opcE6DiffPlaces_d21g0v0_Shanghai - - opcE7DiffPlaces_d0g0v0_Shanghai - - opcE6DiffPlaces_d20g0v0_Shanghai - - opcE6DiffPlaces_d4g0v0_Shanghai - - opcE6DiffPlaces_d22g0v0_Shanghai - - opcE6DiffPlaces_d23g0v0_Shanghai - - opcE6DiffPlaces_d5g0v0_Shanghai - - opcE6DiffPlaces_d6g0v0_Shanghai - - opcE6DiffPlaces_d7g0v0_Shanghai - - opcE6DiffPlaces_d8g0v0_Shanghai - - opcE6DiffPlaces_d24g0v0_Shanghai - - opcE6DiffPlaces_d9g0v0_Shanghai - - opcE6DiffPlaces_d25g0v0_Shanghai - - opcE7DiffPlaces_d1g0v0_Shanghai - - opcE7DiffPlaces_d10g0v0_Shanghai - - opcE7DiffPlaces_d11g0v0_Shanghai - - opcE6DiffPlaces_d26g0v0_Shanghai - - opcE7DiffPlaces_d12g0v0_Shanghai - - opcE6DiffPlaces_d27g0v0_Shanghai - - opcE7DiffPlaces_d13g0v0_Shanghai - - opcE6DiffPlaces_d28g0v0_Shanghai - - opcE7DiffPlaces_d14g0v0_Shanghai - - opcE6DiffPlaces_d29g0v0_Shanghai - - opcE7DiffPlaces_d15g0v0_Shanghai - - opcE7DiffPlaces_d16g0v0_Shanghai - - opcE6DiffPlaces_d30g0v0_Shanghai - - opcE6DiffPlaces_d31g0v0_Shanghai - - opcE6DiffPlaces_d32g0v0_Shanghai - - opcE7DiffPlaces_d2g0v0_Shanghai - - opcE6DiffPlaces_d33g0v0_Shanghai - - opcE6DiffPlaces_d34g0v0_Shanghai - - opcE7DiffPlaces_d17g0v0_Shanghai - - opcE7DiffPlaces_d18g0v0_Shanghai - - opcE7DiffPlaces_d19g0v0_Shanghai - - opcE7DiffPlaces_d3g0v0_Shanghai - - opcE7DiffPlaces_d21g0v0_Shanghai - - opcE8DiffPlaces_d0g0v0_Shanghai - - opcE7DiffPlaces_d4g0v0_Shanghai - - opcE7DiffPlaces_d20g0v0_Shanghai - - opcE7DiffPlaces_d22g0v0_Shanghai - - opcE7DiffPlaces_d5g0v0_Shanghai - - opcE7DiffPlaces_d23g0v0_Shanghai - - opcE7DiffPlaces_d6g0v0_Shanghai - - opcE7DiffPlaces_d7g0v0_Shanghai - - opcE7DiffPlaces_d8g0v0_Shanghai - - opcE7DiffPlaces_d24g0v0_Shanghai - - opcE7DiffPlaces_d9g0v0_Shanghai - - opcE8DiffPlaces_d1g0v0_Shanghai - - opcE7DiffPlaces_d25g0v0_Shanghai - - opcE8DiffPlaces_d10g0v0_Shanghai - - opcE8DiffPlaces_d11g0v0_Shanghai - - opcE7DiffPlaces_d26g0v0_Shanghai - - opcE8DiffPlaces_d12g0v0_Shanghai - - opcE7DiffPlaces_d27g0v0_Shanghai - - opcE8DiffPlaces_d13g0v0_Shanghai - - opcE7DiffPlaces_d28g0v0_Shanghai - - opcE8DiffPlaces_d14g0v0_Shanghai - - opcE8DiffPlaces_d15g0v0_Shanghai - - opcE7DiffPlaces_d29g0v0_Shanghai - - opcE7DiffPlaces_d30g0v0_Shanghai - - opcE8DiffPlaces_d16g0v0_Shanghai - - opcE7DiffPlaces_d31g0v0_Shanghai - - opcE8DiffPlaces_d2g0v0_Shanghai - - opcE7DiffPlaces_d32g0v0_Shanghai - - opcE7DiffPlaces_d33g0v0_Shanghai - - opcE7DiffPlaces_d34g0v0_Shanghai - - opcE8DiffPlaces_d17g0v0_Shanghai - - opcE8DiffPlaces_d18g0v0_Shanghai - - opcE8DiffPlaces_d19g0v0_Shanghai - - opcE8DiffPlaces_d3g0v0_Shanghai - - opcE9DiffPlaces_d0g0v0_Shanghai - - opcE8DiffPlaces_d21g0v0_Shanghai - - opcE8DiffPlaces_d20g0v0_Shanghai - - opcE8DiffPlaces_d4g0v0_Shanghai - - opcE8DiffPlaces_d22g0v0_Shanghai - - opcE8DiffPlaces_d5g0v0_Shanghai - - opcE8DiffPlaces_d23g0v0_Shanghai - - opcE8DiffPlaces_d6g0v0_Shanghai - - opcE8DiffPlaces_d7g0v0_Shanghai - - opcE8DiffPlaces_d8g0v0_Shanghai - - opcE8DiffPlaces_d9g0v0_Shanghai - - opcE8DiffPlaces_d24g0v0_Shanghai - - opcE8DiffPlaces_d25g0v0_Shanghai - - opcE9DiffPlaces_d1g0v0_Shanghai - - opcE9DiffPlaces_d10g0v0_Shanghai - - opcE9DiffPlaces_d11g0v0_Shanghai - - opcE8DiffPlaces_d26g0v0_Shanghai - - opcE9DiffPlaces_d12g0v0_Shanghai - - opcE8DiffPlaces_d27g0v0_Shanghai - - opcE9DiffPlaces_d13g0v0_Shanghai - - opcE8DiffPlaces_d28g0v0_Shanghai - - opcE9DiffPlaces_d14g0v0_Shanghai - - opcE8DiffPlaces_d29g0v0_Shanghai - - opcE9DiffPlaces_d15g0v0_Shanghai - - opcE8DiffPlaces_d30g0v0_Shanghai - - opcE9DiffPlaces_d16g0v0_Shanghai - - opcE8DiffPlaces_d31g0v0_Shanghai - - opcE9DiffPlaces_d2g0v0_Shanghai - - opcE8DiffPlaces_d32g0v0_Shanghai - - opcE8DiffPlaces_d33g0v0_Shanghai - - opcE8DiffPlaces_d34g0v0_Shanghai - - opcE9DiffPlaces_d17g0v0_Shanghai - - opcE9DiffPlaces_d18g0v0_Shanghai - - opcE9DiffPlaces_d19g0v0_Shanghai - - opcE9DiffPlaces_d3g0v0_Shanghai - - opcE9DiffPlaces_d21g0v0_Shanghai - - opcEADiffPlaces_d0g0v0_Shanghai - - opcE9DiffPlaces_d4g0v0_Shanghai - - opcE9DiffPlaces_d20g0v0_Shanghai - - opcE9DiffPlaces_d22g0v0_Shanghai - - opcE9DiffPlaces_d5g0v0_Shanghai - - opcE9DiffPlaces_d23g0v0_Shanghai - - opcE9DiffPlaces_d6g0v0_Shanghai - - opcE9DiffPlaces_d7g0v0_Shanghai - - opcE9DiffPlaces_d8g0v0_Shanghai - - opcE9DiffPlaces_d24g0v0_Shanghai - - opcE9DiffPlaces_d9g0v0_Shanghai - - opcE9DiffPlaces_d25g0v0_Shanghai - - opcEADiffPlaces_d1g0v0_Shanghai - - opcEADiffPlaces_d10g0v0_Shanghai - - opcEADiffPlaces_d11g0v0_Shanghai - - opcE9DiffPlaces_d26g0v0_Shanghai - - opcEADiffPlaces_d12g0v0_Shanghai - - opcE9DiffPlaces_d27g0v0_Shanghai - - opcEADiffPlaces_d13g0v0_Shanghai - - opcE9DiffPlaces_d28g0v0_Shanghai - - opcEADiffPlaces_d14g0v0_Shanghai - - opcE9DiffPlaces_d29g0v0_Shanghai - - opcEADiffPlaces_d15g0v0_Shanghai - - opcE9DiffPlaces_d30g0v0_Shanghai - - opcEADiffPlaces_d16g0v0_Shanghai - - opcE9DiffPlaces_d32g0v0_Shanghai - - opcE9DiffPlaces_d31g0v0_Shanghai - - opcEADiffPlaces_d2g0v0_Shanghai - - opcE9DiffPlaces_d33g0v0_Shanghai - - opcE9DiffPlaces_d34g0v0_Shanghai - - opcEADiffPlaces_d17g0v0_Shanghai - - opcEADiffPlaces_d18g0v0_Shanghai - - opcEADiffPlaces_d19g0v0_Shanghai - - opcEADiffPlaces_d3g0v0_Shanghai - - opcEADiffPlaces_d21g0v0_Shanghai - - opcEADiffPlaces_d4g0v0_Shanghai - - opcEBDiffPlaces_d0g0v0_Shanghai - - opcEADiffPlaces_d20g0v0_Shanghai - - opcEADiffPlaces_d22g0v0_Shanghai - - opcEADiffPlaces_d5g0v0_Shanghai - - opcEADiffPlaces_d23g0v0_Shanghai - - opcEADiffPlaces_d6g0v0_Shanghai - - opcEADiffPlaces_d7g0v0_Shanghai - - opcEADiffPlaces_d8g0v0_Shanghai - - opcEADiffPlaces_d24g0v0_Shanghai - - opcEADiffPlaces_d9g0v0_Shanghai - - opcEADiffPlaces_d25g0v0_Shanghai - - opcEBDiffPlaces_d1g0v0_Shanghai - - opcEBDiffPlaces_d10g0v0_Shanghai - - opcEADiffPlaces_d26g0v0_Shanghai - - opcEBDiffPlaces_d11g0v0_Shanghai - - opcEBDiffPlaces_d12g0v0_Shanghai - - opcEADiffPlaces_d27g0v0_Shanghai - - opcEBDiffPlaces_d13g0v0_Shanghai - - opcEADiffPlaces_d28g0v0_Shanghai - - opcEBDiffPlaces_d14g0v0_Shanghai - - opcEADiffPlaces_d29g0v0_Shanghai - - opcEBDiffPlaces_d15g0v0_Shanghai - - opcEADiffPlaces_d30g0v0_Shanghai - - opcEADiffPlaces_d31g0v0_Shanghai - - opcEBDiffPlaces_d16g0v0_Shanghai - - opcEBDiffPlaces_d2g0v0_Shanghai - - opcEADiffPlaces_d32g0v0_Shanghai - - opcEADiffPlaces_d34g0v0_Shanghai - - opcEADiffPlaces_d33g0v0_Shanghai - - opcEBDiffPlaces_d17g0v0_Shanghai - - opcEBDiffPlaces_d18g0v0_Shanghai - - opcEBDiffPlaces_d19g0v0_Shanghai - - opcEBDiffPlaces_d3g0v0_Shanghai - - opcEBDiffPlaces_d21g0v0_Shanghai - - opcECDiffPlaces_d0g0v0_Shanghai - - opcEBDiffPlaces_d4g0v0_Shanghai - - opcEBDiffPlaces_d20g0v0_Shanghai - - opcEBDiffPlaces_d22g0v0_Shanghai - - opcEBDiffPlaces_d5g0v0_Shanghai - - opcEBDiffPlaces_d23g0v0_Shanghai - - opcEBDiffPlaces_d6g0v0_Shanghai - - opcEBDiffPlaces_d7g0v0_Shanghai - - opcEBDiffPlaces_d8g0v0_Shanghai - - opcEBDiffPlaces_d24g0v0_Shanghai - - opcEBDiffPlaces_d9g0v0_Shanghai - - opcEBDiffPlaces_d25g0v0_Shanghai - - opcECDiffPlaces_d1g0v0_Shanghai - - opcECDiffPlaces_d10g0v0_Shanghai - - opcEBDiffPlaces_d26g0v0_Shanghai - - opcECDiffPlaces_d11g0v0_Shanghai - - opcECDiffPlaces_d12g0v0_Shanghai - - opcEBDiffPlaces_d27g0v0_Shanghai - - opcECDiffPlaces_d13g0v0_Shanghai - - opcEBDiffPlaces_d28g0v0_Shanghai - - opcECDiffPlaces_d14g0v0_Shanghai - - opcEBDiffPlaces_d29g0v0_Shanghai - - opcECDiffPlaces_d15g0v0_Shanghai - - opcECDiffPlaces_d16g0v0_Shanghai - - opcEBDiffPlaces_d30g0v0_Shanghai - - opcEBDiffPlaces_d31g0v0_Shanghai - - opcEBDiffPlaces_d32g0v0_Shanghai - - opcECDiffPlaces_d2g0v0_Shanghai - - opcEBDiffPlaces_d33g0v0_Shanghai - - opcEBDiffPlaces_d34g0v0_Shanghai - - opcECDiffPlaces_d17g0v0_Shanghai - - opcECDiffPlaces_d18g0v0_Shanghai - - opcECDiffPlaces_d19g0v0_Shanghai - - opcECDiffPlaces_d3g0v0_Shanghai - - opcECDiffPlaces_d21g0v0_Shanghai - - opcEDDiffPlaces_d0g0v0_Shanghai - - opcECDiffPlaces_d4g0v0_Shanghai - - opcECDiffPlaces_d20g0v0_Shanghai - - opcECDiffPlaces_d22g0v0_Shanghai - - opcECDiffPlaces_d5g0v0_Shanghai - - opcECDiffPlaces_d23g0v0_Shanghai - - opcECDiffPlaces_d6g0v0_Shanghai - - opcECDiffPlaces_d7g0v0_Shanghai - - opcECDiffPlaces_d8g0v0_Shanghai - - opcECDiffPlaces_d24g0v0_Shanghai - - opcECDiffPlaces_d9g0v0_Shanghai - - opcEDDiffPlaces_d1g0v0_Shanghai - - opcECDiffPlaces_d25g0v0_Shanghai - - opcEDDiffPlaces_d10g0v0_Shanghai - - opcEDDiffPlaces_d11g0v0_Shanghai - - opcECDiffPlaces_d26g0v0_Shanghai - - opcEDDiffPlaces_d12g0v0_Shanghai - - opcECDiffPlaces_d27g0v0_Shanghai - - opcEDDiffPlaces_d13g0v0_Shanghai - - opcECDiffPlaces_d28g0v0_Shanghai - - opcEDDiffPlaces_d14g0v0_Shanghai - - opcECDiffPlaces_d29g0v0_Shanghai - - opcEDDiffPlaces_d15g0v0_Shanghai - - opcEDDiffPlaces_d16g0v0_Shanghai - - opcECDiffPlaces_d31g0v0_Shanghai - - opcECDiffPlaces_d30g0v0_Shanghai - - opcEDDiffPlaces_d2g0v0_Shanghai - - opcECDiffPlaces_d32g0v0_Shanghai - - opcECDiffPlaces_d33g0v0_Shanghai - - opcECDiffPlaces_d34g0v0_Shanghai - - opcEDDiffPlaces_d17g0v0_Shanghai - - opcEDDiffPlaces_d18g0v0_Shanghai - - opcEDDiffPlaces_d19g0v0_Shanghai - - opcEDDiffPlaces_d3g0v0_Shanghai - - opcEDDiffPlaces_d21g0v0_Shanghai - - opcEEDiffPlaces_d0g0v0_Shanghai - - opcEDDiffPlaces_d4g0v0_Shanghai - - opcEDDiffPlaces_d20g0v0_Shanghai - - opcEDDiffPlaces_d22g0v0_Shanghai - - opcEDDiffPlaces_d5g0v0_Shanghai - - opcEDDiffPlaces_d23g0v0_Shanghai - - opcEDDiffPlaces_d6g0v0_Shanghai - - opcEDDiffPlaces_d7g0v0_Shanghai - - opcEDDiffPlaces_d8g0v0_Shanghai - - opcEDDiffPlaces_d9g0v0_Shanghai - - opcEDDiffPlaces_d24g0v0_Shanghai - - opcEDDiffPlaces_d25g0v0_Shanghai - - opcEEDiffPlaces_d1g0v0_Shanghai - - opcEEDiffPlaces_d10g0v0_Shanghai - - opcEDDiffPlaces_d26g0v0_Shanghai - - opcEEDiffPlaces_d11g0v0_Shanghai - - opcEEDiffPlaces_d12g0v0_Shanghai - - opcEDDiffPlaces_d27g0v0_Shanghai - - opcEEDiffPlaces_d13g0v0_Shanghai - - opcEDDiffPlaces_d28g0v0_Shanghai - - opcEEDiffPlaces_d14g0v0_Shanghai - - opcEDDiffPlaces_d29g0v0_Shanghai - - opcEEDiffPlaces_d15g0v0_Shanghai - - opcEEDiffPlaces_d16g0v0_Shanghai - - opcEDDiffPlaces_d30g0v0_Shanghai - - opcEDDiffPlaces_d31g0v0_Shanghai - - opcEEDiffPlaces_d2g0v0_Shanghai - - opcEDDiffPlaces_d32g0v0_Shanghai - - opcEDDiffPlaces_d33g0v0_Shanghai - - opcEDDiffPlaces_d34g0v0_Shanghai - - opcEEDiffPlaces_d17g0v0_Shanghai - - opcEEDiffPlaces_d18g0v0_Shanghai - - opcEEDiffPlaces_d3g0v0_Shanghai - - opcEEDiffPlaces_d19g0v0_Shanghai - - opcEEDiffPlaces_d21g0v0_Shanghai - - opcEFDiffPlaces_d0g0v0_Shanghai - - opcEEDiffPlaces_d20g0v0_Shanghai - - opcEEDiffPlaces_d4g0v0_Shanghai - - opcEEDiffPlaces_d22g0v0_Shanghai - - opcEEDiffPlaces_d5g0v0_Shanghai - - opcEEDiffPlaces_d23g0v0_Shanghai - - opcEEDiffPlaces_d6g0v0_Shanghai - - opcEEDiffPlaces_d7g0v0_Shanghai - - opcEEDiffPlaces_d8g0v0_Shanghai - - opcEEDiffPlaces_d24g0v0_Shanghai - - opcEEDiffPlaces_d9g0v0_Shanghai - - opcEFDiffPlaces_d1g0v0_Shanghai - - opcEEDiffPlaces_d25g0v0_Shanghai - - opcEFDiffPlaces_d10g0v0_Shanghai - - opcEFDiffPlaces_d11g0v0_Shanghai - - opcEEDiffPlaces_d26g0v0_Shanghai - - opcEFDiffPlaces_d12g0v0_Shanghai - - opcEEDiffPlaces_d27g0v0_Shanghai - - opcEFDiffPlaces_d13g0v0_Shanghai - - opcEEDiffPlaces_d28g0v0_Shanghai - - opcEFDiffPlaces_d14g0v0_Shanghai - - opcEEDiffPlaces_d29g0v0_Shanghai - - opcEFDiffPlaces_d15g0v0_Shanghai - - opcEFDiffPlaces_d16g0v0_Shanghai - - opcEEDiffPlaces_d30g0v0_Shanghai - - opcEEDiffPlaces_d31g0v0_Shanghai - - opcEFDiffPlaces_d2g0v0_Shanghai - - opcEEDiffPlaces_d32g0v0_Shanghai - - opcEEDiffPlaces_d33g0v0_Shanghai - - opcEEDiffPlaces_d34g0v0_Shanghai - - opcEFDiffPlaces_d17g0v0_Shanghai - - opcEFDiffPlaces_d18g0v0_Shanghai - - opcEFDiffPlaces_d19g0v0_Shanghai - - opcEFDiffPlaces_d3g0v0_Shanghai - - opcEFDiffPlaces_d21g0v0_Shanghai - - opcF6DiffPlaces_d0g0v0_Shanghai - - opcEFDiffPlaces_d4g0v0_Shanghai - - opcEFDiffPlaces_d20g0v0_Shanghai - - opcEFDiffPlaces_d22g0v0_Shanghai - - opcEFDiffPlaces_d23g0v0_Shanghai - - opcEFDiffPlaces_d5g0v0_Shanghai - - opcEFDiffPlaces_d6g0v0_Shanghai - - opcEFDiffPlaces_d7g0v0_Shanghai - - opcEFDiffPlaces_d8g0v0_Shanghai - - opcEFDiffPlaces_d24g0v0_Shanghai - - opcEFDiffPlaces_d9g0v0_Shanghai - - opcF6DiffPlaces_d1g0v0_Shanghai - - opcEFDiffPlaces_d25g0v0_Shanghai - - opcF6DiffPlaces_d10g0v0_Shanghai - - opcF6DiffPlaces_d11g0v0_Shanghai - - opcEFDiffPlaces_d26g0v0_Shanghai - - opcF6DiffPlaces_d12g0v0_Shanghai - - opcF6DiffPlaces_d13g0v0_Shanghai - - opcEFDiffPlaces_d27g0v0_Shanghai - - opcEFDiffPlaces_d28g0v0_Shanghai - - opcF6DiffPlaces_d14g0v0_Shanghai - - opcF6DiffPlaces_d15g0v0_Shanghai - - opcEFDiffPlaces_d29g0v0_Shanghai - - opcF6DiffPlaces_d16g0v0_Shanghai - - opcEFDiffPlaces_d30g0v0_Shanghai - - opcEFDiffPlaces_d31g0v0_Shanghai - - opcF6DiffPlaces_d2g0v0_Shanghai - - opcEFDiffPlaces_d32g0v0_Shanghai - - opcEFDiffPlaces_d33g0v0_Shanghai - - opcEFDiffPlaces_d34g0v0_Shanghai - - opcF6DiffPlaces_d17g0v0_Shanghai - - opcF6DiffPlaces_d18g0v0_Shanghai - - opcF6DiffPlaces_d19g0v0_Shanghai - - opcF6DiffPlaces_d3g0v0_Shanghai - - opcF7DiffPlaces_d0g0v0_Shanghai - - opcF6DiffPlaces_d21g0v0_Shanghai - - opcF6DiffPlaces_d20g0v0_Shanghai - - opcF6DiffPlaces_d4g0v0_Shanghai - - opcF6DiffPlaces_d22g0v0_Shanghai - - opcF6DiffPlaces_d5g0v0_Shanghai - - opcF6DiffPlaces_d23g0v0_Shanghai - - opcF6DiffPlaces_d6g0v0_Shanghai - - opcF6DiffPlaces_d7g0v0_Shanghai - - opcF6DiffPlaces_d8g0v0_Shanghai - - opcF6DiffPlaces_d24g0v0_Shanghai - - opcF6DiffPlaces_d9g0v0_Shanghai - - opcF6DiffPlaces_d25g0v0_Shanghai - - opcF7DiffPlaces_d1g0v0_Shanghai - - opcF7DiffPlaces_d10g0v0_Shanghai - - opcF7DiffPlaces_d11g0v0_Shanghai - - opcF6DiffPlaces_d26g0v0_Shanghai - - opcF7DiffPlaces_d12g0v0_Shanghai - - opcF6DiffPlaces_d27g0v0_Shanghai - - opcF7DiffPlaces_d13g0v0_Shanghai - - opcF6DiffPlaces_d28g0v0_Shanghai - - opcF7DiffPlaces_d14g0v0_Shanghai - - opcF6DiffPlaces_d29g0v0_Shanghai - - opcF7DiffPlaces_d15g0v0_Shanghai - - opcF6DiffPlaces_d30g0v0_Shanghai - - opcF6DiffPlaces_d31g0v0_Shanghai - - opcF7DiffPlaces_d16g0v0_Shanghai - - opcF7DiffPlaces_d2g0v0_Shanghai - - opcF6DiffPlaces_d32g0v0_Shanghai - - opcF6DiffPlaces_d33g0v0_Shanghai - - opcF6DiffPlaces_d34g0v0_Shanghai - - opcF7DiffPlaces_d17g0v0_Shanghai - - opcF7DiffPlaces_d18g0v0_Shanghai - - opcF7DiffPlaces_d19g0v0_Shanghai - - opcF7DiffPlaces_d3g0v0_Shanghai - - opcF7DiffPlaces_d21g0v0_Shanghai - - opcF8DiffPlaces_d0g0v0_Shanghai - - opcF7DiffPlaces_d20g0v0_Shanghai - - opcF7DiffPlaces_d4g0v0_Shanghai - - opcF7DiffPlaces_d22g0v0_Shanghai - - opcF7DiffPlaces_d5g0v0_Shanghai - - opcF7DiffPlaces_d23g0v0_Shanghai - - opcF7DiffPlaces_d6g0v0_Shanghai - - opcF7DiffPlaces_d7g0v0_Shanghai - - opcF7DiffPlaces_d8g0v0_Shanghai - - opcF7DiffPlaces_d24g0v0_Shanghai - - opcF7DiffPlaces_d9g0v0_Shanghai - - opcF7DiffPlaces_d25g0v0_Shanghai - - opcF8DiffPlaces_d1g0v0_Shanghai - - opcF8DiffPlaces_d10g0v0_Shanghai - - opcF7DiffPlaces_d26g0v0_Shanghai - - opcF8DiffPlaces_d11g0v0_Shanghai - - opcF8DiffPlaces_d12g0v0_Shanghai - - opcF7DiffPlaces_d27g0v0_Shanghai - - opcF8DiffPlaces_d13g0v0_Shanghai - - opcF7DiffPlaces_d28g0v0_Shanghai - - opcF8DiffPlaces_d14g0v0_Shanghai - - opcF7DiffPlaces_d29g0v0_Shanghai - - opcF8DiffPlaces_d15g0v0_Shanghai - - opcF7DiffPlaces_d30g0v0_Shanghai - - opcF7DiffPlaces_d31g0v0_Shanghai - - opcF8DiffPlaces_d16g0v0_Shanghai - - opcF7DiffPlaces_d32g0v0_Shanghai - - opcF8DiffPlaces_d2g0v0_Shanghai - - opcF7DiffPlaces_d33g0v0_Shanghai - - opcF7DiffPlaces_d34g0v0_Shanghai - - opcF8DiffPlaces_d17g0v0_Shanghai - - opcF8DiffPlaces_d18g0v0_Shanghai - - opcF8DiffPlaces_d19g0v0_Shanghai - - opcF8DiffPlaces_d3g0v0_Shanghai - - opcF8DiffPlaces_d21g0v0_Shanghai - - opcF9DiffPlaces_d0g0v0_Shanghai - - opcF8DiffPlaces_d4g0v0_Shanghai - - opcF8DiffPlaces_d20g0v0_Shanghai - - opcF8DiffPlaces_d22g0v0_Shanghai - - opcF8DiffPlaces_d5g0v0_Shanghai - - opcF8DiffPlaces_d23g0v0_Shanghai - - opcF8DiffPlaces_d6g0v0_Shanghai - - opcF8DiffPlaces_d7g0v0_Shanghai - - opcF8DiffPlaces_d8g0v0_Shanghai - - opcF8DiffPlaces_d9g0v0_Shanghai - - opcF8DiffPlaces_d24g0v0_Shanghai - - opcF9DiffPlaces_d1g0v0_Shanghai - - opcF8DiffPlaces_d25g0v0_Shanghai - - opcF9DiffPlaces_d10g0v0_Shanghai - - opcF9DiffPlaces_d11g0v0_Shanghai - - opcF8DiffPlaces_d26g0v0_Shanghai - - opcF9DiffPlaces_d12g0v0_Shanghai - - opcF8DiffPlaces_d27g0v0_Shanghai - - opcF9DiffPlaces_d13g0v0_Shanghai - - opcF8DiffPlaces_d28g0v0_Shanghai - - opcF9DiffPlaces_d14g0v0_Shanghai - - opcF8DiffPlaces_d29g0v0_Shanghai - - opcF9DiffPlaces_d15g0v0_Shanghai - - opcF8DiffPlaces_d30g0v0_Shanghai - - opcF9DiffPlaces_d16g0v0_Shanghai - - opcF8DiffPlaces_d31g0v0_Shanghai - - opcF9DiffPlaces_d2g0v0_Shanghai - - opcF8DiffPlaces_d32g0v0_Shanghai - - opcF8DiffPlaces_d33g0v0_Shanghai - - opcF8DiffPlaces_d34g0v0_Shanghai - - opcF9DiffPlaces_d17g0v0_Shanghai - - opcF9DiffPlaces_d18g0v0_Shanghai - - opcF9DiffPlaces_d19g0v0_Shanghai - - opcF9DiffPlaces_d3g0v0_Shanghai - - opcFBDiffPlaces_d0g0v0_Shanghai - - opcF9DiffPlaces_d21g0v0_Shanghai - - opcF9DiffPlaces_d20g0v0_Shanghai - - opcF9DiffPlaces_d4g0v0_Shanghai - - opcF9DiffPlaces_d22g0v0_Shanghai - - opcF9DiffPlaces_d5g0v0_Shanghai - - opcF9DiffPlaces_d23g0v0_Shanghai - - opcF9DiffPlaces_d6g0v0_Shanghai - - opcF9DiffPlaces_d7g0v0_Shanghai - - opcF9DiffPlaces_d8g0v0_Shanghai - - opcF9DiffPlaces_d24g0v0_Shanghai - - opcF9DiffPlaces_d9g0v0_Shanghai - - opcF9DiffPlaces_d25g0v0_Shanghai - - opcFBDiffPlaces_d1g0v0_Shanghai - - opcFBDiffPlaces_d10g0v0_Shanghai - - opcFBDiffPlaces_d11g0v0_Shanghai - - opcF9DiffPlaces_d26g0v0_Shanghai - - opcFBDiffPlaces_d12g0v0_Shanghai - - opcF9DiffPlaces_d27g0v0_Shanghai - - opcFBDiffPlaces_d13g0v0_Shanghai - - opcF9DiffPlaces_d28g0v0_Shanghai - - opcFBDiffPlaces_d14g0v0_Shanghai - - opcF9DiffPlaces_d29g0v0_Shanghai - - opcFBDiffPlaces_d15g0v0_Shanghai - - opcF9DiffPlaces_d30g0v0_Shanghai - - opcFBDiffPlaces_d16g0v0_Shanghai - - opcF9DiffPlaces_d31g0v0_Shanghai - - opcFBDiffPlaces_d2g0v0_Shanghai - - opcF9DiffPlaces_d32g0v0_Shanghai - - opcF9DiffPlaces_d33g0v0_Shanghai - - opcF9DiffPlaces_d34g0v0_Shanghai - - opcFBDiffPlaces_d17g0v0_Shanghai - - opcFBDiffPlaces_d18g0v0_Shanghai - - opcFBDiffPlaces_d19g0v0_Shanghai - - opcFBDiffPlaces_d3g0v0_Shanghai - - opcFBDiffPlaces_d21g0v0_Shanghai - - opcFCDiffPlaces_d0g0v0_Shanghai - - opcFBDiffPlaces_d4g0v0_Shanghai - - opcFBDiffPlaces_d20g0v0_Shanghai - - opcFBDiffPlaces_d22g0v0_Shanghai - - opcFBDiffPlaces_d23g0v0_Shanghai - - opcFBDiffPlaces_d5g0v0_Shanghai - - opcFBDiffPlaces_d6g0v0_Shanghai - - opcFBDiffPlaces_d7g0v0_Shanghai - - opcFBDiffPlaces_d8g0v0_Shanghai - - opcFBDiffPlaces_d24g0v0_Shanghai - - opcFBDiffPlaces_d9g0v0_Shanghai - - opcFCDiffPlaces_d1g0v0_Shanghai - - opcFBDiffPlaces_d25g0v0_Shanghai - - opcFCDiffPlaces_d10g0v0_Shanghai - - opcFBDiffPlaces_d26g0v0_Shanghai - - opcFCDiffPlaces_d11g0v0_Shanghai - - opcFCDiffPlaces_d12g0v0_Shanghai - - opcFBDiffPlaces_d27g0v0_Shanghai - - opcFCDiffPlaces_d13g0v0_Shanghai - - opcFBDiffPlaces_d28g0v0_Shanghai - - opcFCDiffPlaces_d14g0v0_Shanghai - - opcFBDiffPlaces_d29g0v0_Shanghai - - opcFCDiffPlaces_d15g0v0_Shanghai - - opcFBDiffPlaces_d30g0v0_Shanghai - - opcFCDiffPlaces_d16g0v0_Shanghai - - opcFBDiffPlaces_d31g0v0_Shanghai - - opcFCDiffPlaces_d2g0v0_Shanghai - - opcFBDiffPlaces_d32g0v0_Shanghai - - opcFBDiffPlaces_d33g0v0_Shanghai - - opcFBDiffPlaces_d34g0v0_Shanghai - - opcFCDiffPlaces_d17g0v0_Shanghai - - opcFCDiffPlaces_d18g0v0_Shanghai - - opcFCDiffPlaces_d19g0v0_Shanghai - - opcFCDiffPlaces_d3g0v0_Shanghai - - opcFCDiffPlaces_d21g0v0_Shanghai - - opcFEDiffPlaces_d0g0v0_Shanghai - - opcFCDiffPlaces_d4g0v0_Shanghai - - opcFCDiffPlaces_d20g0v0_Shanghai - - opcFCDiffPlaces_d22g0v0_Shanghai - - opcFCDiffPlaces_d5g0v0_Shanghai - - opcFCDiffPlaces_d23g0v0_Shanghai - - opcFCDiffPlaces_d6g0v0_Shanghai - - opcFCDiffPlaces_d7g0v0_Shanghai - - opcFCDiffPlaces_d8g0v0_Shanghai - - opcFCDiffPlaces_d24g0v0_Shanghai - - opcFCDiffPlaces_d9g0v0_Shanghai - - opcFEDiffPlaces_d1g0v0_Shanghai - - opcFCDiffPlaces_d25g0v0_Shanghai - - opcFEDiffPlaces_d10g0v0_Shanghai - - opcFCDiffPlaces_d26g0v0_Shanghai - - opcFEDiffPlaces_d11g0v0_Shanghai - - opcFEDiffPlaces_d12g0v0_Shanghai - - opcFEDiffPlaces_d13g0v0_Shanghai - - opcFCDiffPlaces_d27g0v0_Shanghai - - opcFCDiffPlaces_d28g0v0_Shanghai - - opcFEDiffPlaces_d14g0v0_Shanghai - - opcFCDiffPlaces_d29g0v0_Shanghai - - opcFEDiffPlaces_d15g0v0_Shanghai - - opcFEDiffPlaces_d16g0v0_Shanghai - - opcFCDiffPlaces_d30g0v0_Shanghai - - opcFCDiffPlaces_d31g0v0_Shanghai - - opcFEDiffPlaces_d2g0v0_Shanghai - - opcFCDiffPlaces_d32g0v0_Shanghai - - opcFCDiffPlaces_d33g0v0_Shanghai - - opcFCDiffPlaces_d34g0v0_Shanghai - - opcFEDiffPlaces_d17g0v0_Shanghai - - opcFEDiffPlaces_d18g0v0_Shanghai - - opcFEDiffPlaces_d19g0v0_Shanghai - - opcFEDiffPlaces_d3g0v0_Shanghai - - opcFEDiffPlaces_d21g0v0_Shanghai - - opcFEDiffPlaces_d20g0v0_Shanghai - - opcFEDiffPlaces_d4g0v0_Shanghai - - opcFEDiffPlaces_d22g0v0_Shanghai - - opcFEDiffPlaces_d5g0v0_Shanghai - - opcFEDiffPlaces_d23g0v0_Shanghai - - opcFEDiffPlaces_d6g0v0_Shanghai - - opcFEDiffPlaces_d7g0v0_Shanghai - - opcFEDiffPlaces_d8g0v0_Shanghai - - opcFEDiffPlaces_d24g0v0_Shanghai - - opcFEDiffPlaces_d9g0v0_Shanghai - - opcFEDiffPlaces_d25g0v0_Shanghai - - opcFEDiffPlaces_d26g0v0_Shanghai - - opcFEDiffPlaces_d27g0v0_Shanghai - - opcFEDiffPlaces_d28g0v0_Shanghai - - opcFEDiffPlaces_d29g0v0_Shanghai - - opcFEDiffPlaces_d30g0v0_Shanghai - - opcFEDiffPlaces_d31g0v0_Shanghai - - opcFEDiffPlaces_d32g0v0_Shanghai - - opcFEDiffPlaces_d33g0v0_Shanghai - - opcFEDiffPlaces_d34g0v0_Shanghai - - operationDiffGas_d6g0v0_Shanghai - - operationDiffGas_d1g0v0_Shanghai - - operationDiffGas_d0g0v0_Shanghai - - operationDiffGas_d7g0v0_Shanghai - - operationDiffGas_d8g0v0_Shanghai - - operationDiffGas_d9g0v0_Shanghai - stAttackTest: - - CrashingTransaction_d0g0v0_Shanghai - - ContractCreationSpam_d0g0v0_Shanghai - stBugs: - - randomStatetestDEFAULT_minus_Tue_07_58_41_minus_15153_minus_575192_d0g0v0_Shanghai - stCallCodes: - - callcode_checkPC_d0g0v0_Shanghai - - callcodeDynamicCode_d2g0v0_Shanghai - - callcodeDynamicCode_d3g0v0_Shanghai - - callcallcall_ABCB_RECURSIVE_d0g0v0_Shanghai - - callcallcallcode_ABCB_RECURSIVE_d0g0v0_Shanghai - - callcallcodecall_ABCB_RECURSIVE_d0g0v0_Shanghai - - callcallcodecallcode_ABCB_RECURSIVE_d0g0v0_Shanghai - - callcodecallcall_ABCB_RECURSIVE_d0g0v0_Shanghai - - callcodecallcallcode_ABCB_RECURSIVE_d0g0v0_Shanghai - - callcodecallcodecall_ABCB_RECURSIVE_d0g0v0_Shanghai - - callcodecallcodecallcode_ABCB_RECURSIVE_d0g0v0_Shanghai + - invalidDiffPlaces_d34g0v0_Cancun + - opc0CDiffPlaces_d34g0v0_Cancun + - opc0DDiffPlaces_d34g0v0_Cancun + - opc0EDiffPlaces_d34g0v0_Cancun + - opc0FDiffPlaces_d34g0v0_Cancun + - opc1EDiffPlaces_d34g0v0_Cancun + - opc1FDiffPlaces_d34g0v0_Cancun + - opc21DiffPlaces_d34g0v0_Cancun + - opc22DiffPlaces_d34g0v0_Cancun + - opc23DiffPlaces_d34g0v0_Cancun + - opc24DiffPlaces_d34g0v0_Cancun + - opc25DiffPlaces_d34g0v0_Cancun + - opc26DiffPlaces_d34g0v0_Cancun + - opc27DiffPlaces_d34g0v0_Cancun + - opc28DiffPlaces_d34g0v0_Cancun + - opc29DiffPlaces_d34g0v0_Cancun + - opc2ADiffPlaces_d34g0v0_Cancun + - opc2BDiffPlaces_d34g0v0_Cancun + - opc2CDiffPlaces_d34g0v0_Cancun + - opc2DDiffPlaces_d34g0v0_Cancun + - opc2EDiffPlaces_d34g0v0_Cancun + - opc2FDiffPlaces_d34g0v0_Cancun + - opc49DiffPlaces_d34g0v0_Cancun + - opc4ADiffPlaces_d34g0v0_Cancun + - opc4BDiffPlaces_d34g0v0_Cancun + - opc4CDiffPlaces_d34g0v0_Cancun + - opc4DDiffPlaces_d34g0v0_Cancun + - opc4EDiffPlaces_d34g0v0_Cancun + - opc4FDiffPlaces_d34g0v0_Cancun + - opc5CDiffPlaces_d34g0v0_Cancun + - opc5DDiffPlaces_d34g0v0_Cancun + - opc5EDiffPlaces_d34g0v0_Cancun + - opc5FDiffPlaces_d34g0v0_Cancun + - opcA5DiffPlaces_d34g0v0_Cancun + - opcA6DiffPlaces_d34g0v0_Cancun + - opcA7DiffPlaces_d34g0v0_Cancun + - opcA8DiffPlaces_d34g0v0_Cancun + - opcA9DiffPlaces_d34g0v0_Cancun + - opcAADiffPlaces_d34g0v0_Cancun + - opcABDiffPlaces_d34g0v0_Cancun + - opcACDiffPlaces_d34g0v0_Cancun + - opcADDiffPlaces_d34g0v0_Cancun + - opcAEDiffPlaces_d34g0v0_Cancun + - opcAFDiffPlaces_d34g0v0_Cancun + - opcB0DiffPlaces_d34g0v0_Cancun + - opcB1DiffPlaces_d34g0v0_Cancun + - opcB2DiffPlaces_d34g0v0_Cancun + - opcB3DiffPlaces_d34g0v0_Cancun + - opcB4DiffPlaces_d34g0v0_Cancun + - opcB5DiffPlaces_d34g0v0_Cancun + - opcB6DiffPlaces_d34g0v0_Cancun + - opcB7DiffPlaces_d34g0v0_Cancun + - opcB8DiffPlaces_d34g0v0_Cancun + - opcB9DiffPlaces_d34g0v0_Cancun + - opcBADiffPlaces_d34g0v0_Cancun + - opcBBDiffPlaces_d34g0v0_Cancun + - opcBCDiffPlaces_d34g0v0_Cancun + - opcBDDiffPlaces_d34g0v0_Cancun + - opcBEDiffPlaces_d34g0v0_Cancun + - opcBFDiffPlaces_d34g0v0_Cancun + - opcC0DiffPlaces_d34g0v0_Cancun + - opcC1DiffPlaces_d34g0v0_Cancun + - opcC2DiffPlaces_d34g0v0_Cancun + - opcC3DiffPlaces_d34g0v0_Cancun + - opcC4DiffPlaces_d34g0v0_Cancun + - opcC5DiffPlaces_d34g0v0_Cancun + - opcC6DiffPlaces_d34g0v0_Cancun + - opcC7DiffPlaces_d34g0v0_Cancun + - opcC8DiffPlaces_d34g0v0_Cancun + - opcC9DiffPlaces_d34g0v0_Cancun + - opcCADiffPlaces_d34g0v0_Cancun + - opcCBDiffPlaces_d34g0v0_Cancun + - opcCCDiffPlaces_d34g0v0_Cancun + - opcCDDiffPlaces_d34g0v0_Cancun + - opcCEDiffPlaces_d34g0v0_Cancun + - opcCFDiffPlaces_d34g0v0_Cancun + - opcD0DiffPlaces_d34g0v0_Cancun + - opcD1DiffPlaces_d34g0v0_Cancun + - opcD2DiffPlaces_d34g0v0_Cancun + - opcD3DiffPlaces_d34g0v0_Cancun + - opcD4DiffPlaces_d34g0v0_Cancun + - opcD5DiffPlaces_d34g0v0_Cancun + - opcD6DiffPlaces_d34g0v0_Cancun + - opcD7DiffPlaces_d34g0v0_Cancun + - opcD8DiffPlaces_d34g0v0_Cancun + - opcD9DiffPlaces_d34g0v0_Cancun + - opcDADiffPlaces_d34g0v0_Cancun + - opcDBDiffPlaces_d34g0v0_Cancun + - opcDCDiffPlaces_d34g0v0_Cancun + - opcDDDiffPlaces_d34g0v0_Cancun + - opcDEDiffPlaces_d34g0v0_Cancun + - opcDFDiffPlaces_d34g0v0_Cancun + - opcE0DiffPlaces_d34g0v0_Cancun + - opcE1DiffPlaces_d34g0v0_Cancun + - opcE2DiffPlaces_d34g0v0_Cancun + - opcE3DiffPlaces_d34g0v0_Cancun + - opcE4DiffPlaces_d34g0v0_Cancun + - opcE5DiffPlaces_d34g0v0_Cancun + - opcE6DiffPlaces_d34g0v0_Cancun + - opcE7DiffPlaces_d34g0v0_Cancun + - opcE8DiffPlaces_d34g0v0_Cancun + - opcE9DiffPlaces_d34g0v0_Cancun + - opcEADiffPlaces_d34g0v0_Cancun + - opcEBDiffPlaces_d34g0v0_Cancun + - opcECDiffPlaces_d34g0v0_Cancun + - opcEDDiffPlaces_d34g0v0_Cancun + - opcEEDiffPlaces_d34g0v0_Cancun + - opcEFDiffPlaces_d34g0v0_Cancun + - opcF6DiffPlaces_d34g0v0_Cancun + - opcF7DiffPlaces_d34g0v0_Cancun + - opcF8DiffPlaces_d34g0v0_Cancun + - opcF9DiffPlaces_d34g0v0_Cancun + - opcFBDiffPlaces_d34g0v0_Cancun + - opcFCDiffPlaces_d34g0v0_Cancun + - opcFEDiffPlaces_d34g0v0_Cancun + - operationDiffGas_d0g0v0_Cancun + - operationDiffGas_d1g0v0_Cancun + stEIP3860-limitmeterinitcode: + - creationTxInitCodeSizeLimit_d1g0v0_Cancun stCallCreateCallCodeTest: - - callOutput3Fail_d0g0v0_Shanghai - - callOutput3partialFail_d0g0v0_Shanghai - - callcodeOutput3Fail_d0g0v0_Shanghai - - callcodeOutput3partialFail_d0g0v0_Shanghai - - contractCreationMakeCallThatAskMoreGasThenTransactionProvided_d0g1v0_Shanghai - - createNameRegistratorPreStore1NotEnoughGas_d0g0v0_Shanghai - - createInitFailUndefinedInstruction_d0g0v0_Shanghai - - createJS_NoCollision_d0g0v0_Shanghai - - CallRecursiveBombPreCall_d0g0v0_Shanghai - - Call1024BalanceTooLow_d0g0v0_Shanghai - - Callcode1024BalanceTooLow_d0g0v0_Shanghai - - Call1024OOG_d0g2v0_Shanghai - - Call1024OOG_d0g0v0_Shanghai - - Call1024OOG_d0g1v0_Shanghai - - Call1024OOG_d0g3v0_Shanghai - - Callcode1024OOG_d0g0v0_Shanghai - - Callcode1024OOG_d0g1v0_Shanghai - - createInitFailStackSizeLargerThan1024_d0g0v0_Shanghai - - Call1024PreCalls_d0g1v0_Shanghai - - Call1024PreCalls_d0g0v0_Shanghai - stChainId: - - chainId_d0g0v0_Shanghai + - Call1024BalanceTooLow_d0g0v0_Cancun + - CallRecursiveBombPreCall_d0g0v0_Cancun + - Callcode1024BalanceTooLow_d0g0v0_Cancun + - createInitFailStackSizeLargerThan1024_d0g0v0_Cancun stCreate2: - - CREATE2_Suicide_d0g0v0_Shanghai - - CREATE2_Suicide_d10g0v0_Shanghai - - CREATE2_Suicide_d11g0v0_Shanghai - - CREATE2_Suicide_d2g0v0_Shanghai - - CREATE2_Suicide_d1g0v0_Shanghai - - CREATE2_Suicide_d4g0v0_Shanghai - - CREATE2_Suicide_d3g0v0_Shanghai - - CREATE2_Suicide_d6g0v0_Shanghai - - CREATE2_Suicide_d5g0v0_Shanghai - - CREATE2_Suicide_d7g0v0_Shanghai - - CREATE2_Suicide_d8g0v0_Shanghai - - CREATE2_Suicide_d9g0v0_Shanghai - - Create2OOGFromCallRefunds_d18g0v0_Shanghai - - Create2OOGafterInitCodeReturndataSize_d0g0v0_Shanghai - - Create2OOGFromCallRefunds_d21g0v0_Shanghai - - Create2OOGafterInitCode_d0g0v0_Shanghai - - Create2OOGafterInitCode_d0g1v0_Shanghai - - Create2OOGafterInitCodeRevert2_d0g0v0_Shanghai - - Create2OOGafterInitCodeRevert_d0g0v0_Shanghai - - CreateMessageRevertedOOGInInit_d0g0v0_Shanghai - - CreateMessageReverted_d0g0v0_Shanghai - - CreateMessageRevertedOOGInInit_d0g1v0_Shanghai - - create2InitCodes_d0g0v0_Shanghai - - RevertInCreateInInitCreate2_d0g0v0_Shanghai - - create2InitCodes_d1g0v0_Shanghai - - create2InitCodes_d3g0v0_Shanghai - - create2InitCodes_d2g0v0_Shanghai - - create2InitCodes_d4g0v0_Shanghai - - create2InitCodes_d7g0v0_Shanghai - - create2InitCodes_d5g0v0_Shanghai - - create2InitCodes_d8g0v0_Shanghai - - create2InitCodes_d6g0v0_Shanghai - - create2callPrecompiles_d1g0v0_Shanghai - - create2callPrecompiles_d2g0v0_Shanghai - - create2callPrecompiles_d3g0v0_Shanghai - - create2callPrecompiles_d5g0v0_Shanghai - - create2callPrecompiles_d0g0v0_Shanghai - - create2collisionBalance_d0g0v0_Shanghai - - create2collisionBalance_d3g0v0_Shanghai - - create2collisionBalance_d1g0v0_Shanghai - - create2collisionBalance_d2g0v0_Shanghai - - create2callPrecompiles_d4g0v0_Shanghai - - create2collisionCode2_d0g0v0_Shanghai - - create2collisionCode2_d1g0v0_Shanghai - - create2checkFieldsInInitcode_d7g0v0_Shanghai - - create2collisionCode_d0g0v0_Shanghai - - create2collisionCode_d1g0v0_Shanghai - - create2collisionCode_d2g0v0_Shanghai - - create2collisionNonce_d0g0v0_Shanghai - - create2callPrecompiles_d6g0v0_Shanghai - - create2collisionNonce_d1g0v0_Shanghai - - create2collisionNonce_d2g0v0_Shanghai - - create2checkFieldsInInitcode_d6g0v0_Shanghai - - create2collisionSelfdestructed2_d0g0v0_Shanghai - - create2checkFieldsInInitcode_d5g0v0_Shanghai - - create2noCash_d2g0v0_Shanghai - - create2collisionSelfdestructedOOG_d0g0v0_Shanghai - - create2collisionSelfdestructed2_d1g0v0_Shanghai - - create2collisionSelfdestructedOOG_d1g0v0_Shanghai - - create2collisionSelfdestructedOOG_d2g0v0_Shanghai - - create2collisionStorage_d0g0v0_Shanghai - - create2collisionSelfdestructed_d0g0v0_Shanghai - - create2collisionSelfdestructed_d1g0v0_Shanghai - - create2collisionStorage_d1g0v0_Shanghai - - create2collisionSelfdestructed_d2g0v0_Shanghai - - create2callPrecompiles_d7g0v0_Shanghai - - create2collisionStorage_d2g0v0_Shanghai - - Create2OnDepth1023_d0g0v0_Shanghai - - Create2OnDepth1024_d0g0v0_Shanghai - stCallDelegateCodesCallCodeHomestead: - - callcallcallcode_ABCB_RECURSIVE_d0g0v0_Shanghai - - callcallcodecall_ABCB_RECURSIVE_d0g0v0_Shanghai - - callcallcodecallcode_ABCB_RECURSIVE_d0g0v0_Shanghai - - callcodecallcall_ABCB_RECURSIVE_d0g0v0_Shanghai - - callcodecallcallcode_ABCB_RECURSIVE_d0g0v0_Shanghai - - callcodecallcodecall_ABCB_RECURSIVE_d0g0v0_Shanghai - - callcodecallcodecallcode_ABCB_RECURSIVE_d0g0v0_Shanghai - stCallDelegateCodesHomestead: - - callcallcallcode_ABCB_RECURSIVE_d0g0v0_Shanghai - - callcallcodecall_ABCB_RECURSIVE_d0g0v0_Shanghai - - callcallcodecallcode_ABCB_RECURSIVE_d0g0v0_Shanghai - - callcodecallcall_ABCB_RECURSIVE_d0g0v0_Shanghai - - callcodecallcallcode_ABCB_RECURSIVE_d0g0v0_Shanghai - - callcodecallcodecall_ABCB_RECURSIVE_d0g0v0_Shanghai - - callcodecallcodecallcode_ABCB_RECURSIVE_d0g0v0_Shanghai + - Create2OnDepth1023_d0g0v0_Cancun + - Create2OnDepth1024_d0g0v0_Cancun + - create2callPrecompiles_d2g0v0_Cancun stCreateTest: - - CREATE_EContractCreateEContractInInit_Tr_d0g0v0_Shanghai - - CREATE_EContractCreateNEContractInInitOOG_Tr_d0g0v0_Shanghai - - CREATE_EmptyContractWithBalance_d0g0v0_Shanghai - - CREATE_EContractCreateNEContractInInit_Tr_d0g0v0_Shanghai - - CREATE_EmptyContractAndCallIt_0wei_d0g0v0_Shanghai - - CREATE_EmptyContractAndCallIt_1wei_d0g0v0_Shanghai - - CREATE_EContract_ThenCALLToNonExistentAcc_d0g0v0_Shanghai - - CREATE_EmptyContract_d0g0v0_Shanghai - - CREATE_EmptyContractWithStorage_d0g0v0_Shanghai - - CREATE_empty000CreateinInitCode_Transaction_d0g0v0_Shanghai - - CREATE_EmptyContractWithStorageAndCallIt_0wei_d0g0v0_Shanghai - - CREATE_EmptyContractWithStorageAndCallIt_1wei_d0g0v0_Shanghai - - CodeInConstructor_d0g0v0_Shanghai - - CodeInConstructor_d1g0v0_Shanghai - - CreateCollisionToEmpty_d0g0v0_Shanghai - - CreateCollisionToEmpty_d0g0v1_Shanghai - - CreateCollisionToEmpty_d1g0v0_Shanghai - - CreateCollisionToEmpty_d1g0v1_Shanghai - - CreateCollisionToEmpty_d2g0v0_Shanghai - - CreateCollisionToEmpty_d2g0v1_Shanghai - - CreateCollisionResults_d0g0v0_Shanghai - - CreateOOGFromCallRefunds_d18g0v0_Shanghai - - CreateCollisionResults_d1g0v0_Shanghai - - CreateOOGFromCallRefunds_d21g0v0_Shanghai - - CreateOOGFromEOARefunds_d18g0v0_Shanghai - - CreateOOGFromEOARefunds_d21g0v0_Shanghai - - CreateOOGafterInitCodeReturndata2_d0g0v0_Shanghai - - CreateOOGafterInitCodeRevert2_d1g0v0_Shanghai - - CreateAddressWarmAfterFail_d7g0v0_Shanghai - - CreateTransactionHighNonce_d0g0v0_Shanghai - - CreateTransactionHighNonce_d0g0v1_Shanghai - - TransactionCollisionToEmpty_d0g0v0_Shanghai - - TransactionCollisionToEmpty_d0g0v1_Shanghai - - CreateAddressWarmAfterFail_d7g0v1_Shanghai - - CreateResults_d10g0v0_Shanghai - - CreateResults_d12g0v0_Shanghai - - CreateResults_d14g0v0_Shanghai - - CreateResults_d16g0v0_Shanghai - - CreateResults_d11g0v0_Shanghai - - CreateResults_d13g0v0_Shanghai - - CreateResults_d15g0v0_Shanghai - - CreateResults_d0g0v0_Shanghai - - CreateResults_d17g0v0_Shanghai - - createLargeResult_d0g0v0_Shanghai - - CreateResults_d1g0v0_Shanghai - - CreateResults_d2g0v0_Shanghai - - CreateResults_d3g0v0_Shanghai - - createLargeResult_d2g0v0_Shanghai - - CreateResults_d4g0v0_Shanghai - - createLargeResult_d1g0v0_Shanghai - - createLargeResult_d3g0v0_Shanghai - - CreateResults_d8g0v0_Shanghai - - CreateResults_d9g0v0_Shanghai - - CreateOOGafterMaxCodesize_d2g0v0_Shanghai - - CreateResults_d5g0v0_Shanghai - - CreateOOGafterMaxCodesize_d0g0v0_Shanghai - - CreateOOGafterMaxCodesize_d5g0v0_Shanghai - - CreateResults_d6g0v0_Shanghai - - CreateOOGafterMaxCodesize_d1g0v0_Shanghai - - CreateOOGafterMaxCodesize_d3g0v0_Shanghai - - CreateResults_d7g0v0_Shanghai - - createLargeResult_d8g0v0_Shanghai - - createLargeResult_d9g0v0_Shanghai - - createLargeResult_d10g0v0_Shanghai - - createLargeResult_d11g0v0_Shanghai - - createLargeResult_d6g0v0_Shanghai - - createLargeResult_d12g0v0_Shanghai - - createLargeResult_d7g0v0_Shanghai - - createLargeResult_d13g0v0_Shanghai - - createLargeResult_d14g0v0_Shanghai - - createLargeResult_d15g0v0_Shanghai - - createLargeResult_d4g0v0_Shanghai - - createLargeResult_d5g0v0_Shanghai - stDelegatecallTestHomestead: - - callOutput3partialFail_d0g0v0_Shanghai - - delegatecodeDynamicCode_d0g0v0_Shanghai - - Call1024BalanceTooLow_d0g0v0_Shanghai - - CallRecursiveBombPreCall_d0g0v0_Shanghai - - Call1024OOG_d0g0v0_Shanghai - - Call1024OOG_d0g1v0_Shanghai - - Delegatecall1024_d0g0v0_Shanghai - - Delegatecall1024OOG_d0g0v0_Shanghai - - Call1024PreCalls_d0g1v0_Shanghai - - Call1024PreCalls_d0g2v0_Shanghai + - CreateOOGafterMaxCodesize_d2g0v0_Cancun stEIP150Specific: - - CreateAndGasInsideCreate_d0g0v0_Shanghai - - SuicideToExistingContract_d0g0v0_Shanghai - - SuicideToNotExistingContract_d0g0v0_Shanghai - - Transaction64Rule_integerBoundaries_d10g0v0_Shanghai - - Transaction64Rule_integerBoundaries_d11g0v0_Shanghai - - NewGasPriceForCodes_d0g0v0_Shanghai + - Transaction64Rule_integerBoundaries_d0g0v0_Cancun + - Transaction64Rule_integerBoundaries_d10g0v0_Cancun + - Transaction64Rule_integerBoundaries_d11g0v0_Cancun + - Transaction64Rule_integerBoundaries_d1g0v0_Cancun + - Transaction64Rule_integerBoundaries_d2g0v0_Cancun + - Transaction64Rule_integerBoundaries_d3g0v0_Cancun + - Transaction64Rule_integerBoundaries_d4g0v0_Cancun + - Transaction64Rule_integerBoundaries_d5g0v0_Cancun + - Transaction64Rule_integerBoundaries_d6g0v0_Cancun + - Transaction64Rule_integerBoundaries_d7g0v0_Cancun + - Transaction64Rule_integerBoundaries_d8g0v0_Cancun + - Transaction64Rule_integerBoundaries_d9g0v0_Cancun + stDelegatecallTestHomestead: + - Call1024BalanceTooLow_d0g0v0_Cancun + - CallRecursiveBombPreCall_d0g0v0_Cancun + - Delegatecall1024_d0g0v0_Cancun stEIP150singleCodeGasPrices: - - RawCallGasValueTransferAsk_d0g0v0_Shanghai - - RawCallGasValueTransfer_d0g0v0_Shanghai - - RawCallCodeGasMemoryAsk_d0g0v0_Shanghai - - RawCallCodeGasMemory_d0g0v0_Shanghai - - RawCallCodeGasValueTransferMemory_d0g0v0_Shanghai - - RawCallCodeGasValueTransferMemoryAsk_d0g0v0_Shanghai - - RawCreateGasValueTransfer_d0g0v0_Shanghai - - RawCreateGas_d0g0v0_Shanghai - - RawCallGasValueTransferMemory_d0g0v0_Shanghai - - RawCallGasValueTransferMemoryAsk_d0g0v0_Shanghai - - RawCallMemoryGasAsk_d0g0v0_Shanghai - - RawCallMemoryGas_d0g0v0_Shanghai - - RawExtCodeCopyGas_d0g0v0_Shanghai - - RawCreateFailGasValueTransfer2_d0g0v0_Shanghai - - eip2929OOG_d0g0v0_Shanghai - - RawCreateGasMemory_d0g0v0_Shanghai - - RawCreateGasValueTransferMemory_d0g0v0_Shanghai - - RawExtCodeCopyMemoryGas_d0g0v0_Shanghai - - RawDelegateCallGasMemoryAsk_d0g0v0_Shanghai - - RawDelegateCallGasMemory_d0g0v0_Shanghai - - eip2929_d0g0v0_Shanghai - - eip2929_d10g0v0_Shanghai - - eip2929_d11g0v0_Shanghai - - eip2929_d12g0v0_Shanghai - - eip2929_d14g0v0_Shanghai - - eip2929_d13g0v0_Shanghai - - eip2929_d15g0v0_Shanghai - - eip2929_d16g0v0_Shanghai - - eip2929_d17g0v0_Shanghai - - eip2929_d18g0v0_Shanghai - - eip2929_d19g0v0_Shanghai - - eip2929_d1g0v0_Shanghai - - eip2929_d21g0v0_Shanghai - - eip2929_d20g0v0_Shanghai - - eip2929_d22g0v0_Shanghai - - eip2929_d23g0v0_Shanghai - - eip2929_d24g0v0_Shanghai - - eip2929_d25g0v0_Shanghai - - eip2929_d26g0v0_Shanghai - - eip2929_d27g0v0_Shanghai - - eip2929_d28g0v0_Shanghai - - eip2929_d29g0v0_Shanghai - - eip2929_d2g0v0_Shanghai - - eip2929_d30g0v0_Shanghai - - eip2929_minus_ff_d0g0v0_Shanghai - - eip2929_minus_ff_d2g0v0_Shanghai - - eip2929_minus_ff_d1g0v0_Shanghai - - eip2929_minus_ff_d4g0v0_Shanghai - - eip2929_minus_ff_d3g0v0_Shanghai - - eip2929_d31g0v0_Shanghai - - eip2929_minus_ff_d5g0v0_Shanghai - - eip2929_d33g0v0_Shanghai - - eip2929_minus_ff_d6g0v0_Shanghai - - eip2929_d32g0v0_Shanghai - - eip2929_minus_ff_d7g0v0_Shanghai - - eip2929_minus_ff_d8g0v0_Shanghai - - eip2929_d34g0v0_Shanghai - - eip2929_d35g0v0_Shanghai - - eip2929_d36g0v0_Shanghai - - eip2929_d37g0v0_Shanghai - - eip2929_d3g0v0_Shanghai - - eip2929_d4g0v0_Shanghai - - eip2929_d5g0v0_Shanghai - - eip2929_d7g0v0_Shanghai - - eip2929_d6g0v0_Shanghai - - eip2929_d8g0v0_Shanghai - - eip2929_d9g0v0_Shanghai - - gasCostBerlin_d0g0v0_Shanghai - - gasCostBerlin_d100g0v0_Shanghai - - gasCostBerlin_d101g0v0_Shanghai - - gasCostBerlin_d102g0v0_Shanghai - - gasCostBerlin_d103g0v0_Shanghai - - gasCostBerlin_d104g0v0_Shanghai - - gasCostBerlin_d105g0v0_Shanghai - - gasCostBerlin_d106g0v0_Shanghai - - gasCostBerlin_d107g0v0_Shanghai - - gasCostBerlin_d108g0v0_Shanghai - - gasCostBerlin_d109g0v0_Shanghai - - gasCostBerlin_d10g0v0_Shanghai - - gasCostBerlin_d11g0v0_Shanghai - - gasCostBerlin_d12g0v0_Shanghai - - gasCostBerlin_d13g0v0_Shanghai - - gasCostBerlin_d14g0v0_Shanghai - - gasCostBerlin_d15g0v0_Shanghai - - gasCostBerlin_d17g0v0_Shanghai - - gasCostBerlin_d18g0v0_Shanghai - - gasCostBerlin_d16g0v0_Shanghai - - gasCostBerlin_d19g0v0_Shanghai - - gasCostBerlin_d1g0v0_Shanghai - - gasCostBerlin_d20g0v0_Shanghai - - gasCostBerlin_d21g0v0_Shanghai - - gasCostBerlin_d22g0v0_Shanghai - - gasCostBerlin_d23g0v0_Shanghai - - gasCostBerlin_d24g0v0_Shanghai - - gasCostBerlin_d25g0v0_Shanghai - - gasCostBerlin_d26g0v0_Shanghai - - gasCostBerlin_d27g0v0_Shanghai - - gasCostBerlin_d29g0v0_Shanghai - - gasCostBerlin_d28g0v0_Shanghai - - gasCostBerlin_d2g0v0_Shanghai - - gasCostBerlin_d30g0v0_Shanghai - - gasCostBerlin_d31g0v0_Shanghai - - gasCostBerlin_d32g0v0_Shanghai - - gasCostBerlin_d33g0v0_Shanghai - - gasCostBerlin_d34g0v0_Shanghai - - gasCostBerlin_d35g0v0_Shanghai - - gasCostBerlin_d36g0v0_Shanghai - - gasCostBerlin_d37g0v0_Shanghai - - gasCostBerlin_d38g0v0_Shanghai - - gasCostBerlin_d39g0v0_Shanghai - - gasCostBerlin_d3g0v0_Shanghai - - gasCostBerlin_d40g0v0_Shanghai - - gasCostBerlin_d41g0v0_Shanghai - - gasCostBerlin_d42g0v0_Shanghai - - gasCostBerlin_d44g0v0_Shanghai - - gasCostBerlin_d43g0v0_Shanghai - - gasCostBerlin_d45g0v0_Shanghai - - gasCostBerlin_d46g0v0_Shanghai - - gasCostBerlin_d47g0v0_Shanghai - - gasCostBerlin_d48g0v0_Shanghai - - gasCostBerlin_d49g0v0_Shanghai - - gasCostBerlin_d4g0v0_Shanghai - - gasCostBerlin_d50g0v0_Shanghai - - gasCostBerlin_d51g0v0_Shanghai - - gasCostBerlin_d52g0v0_Shanghai - - gasCostBerlin_d53g0v0_Shanghai - - gasCostBerlin_d54g0v0_Shanghai - - gasCostBerlin_d55g0v0_Shanghai - - gasCostBerlin_d57g0v0_Shanghai - - gasCostBerlin_d56g0v0_Shanghai - - gasCostBerlin_d58g0v0_Shanghai - - gasCostBerlin_d59g0v0_Shanghai - - gasCostBerlin_d5g0v0_Shanghai - - gasCostBerlin_d60g0v0_Shanghai - - gasCostBerlin_d61g0v0_Shanghai - - gasCostBerlin_d62g0v0_Shanghai - - gasCostBerlin_d63g0v0_Shanghai - - gasCostBerlin_d64g0v0_Shanghai - - gasCostBerlin_d66g0v0_Shanghai - - gasCostBerlin_d67g0v0_Shanghai - - gasCostBerlin_d65g0v0_Shanghai - - gasCostBerlin_d69g0v0_Shanghai - - gasCostBerlin_d6g0v0_Shanghai - - gasCostBerlin_d68g0v0_Shanghai - - gasCostBerlin_d70g0v0_Shanghai - - gasCostBerlin_d71g0v0_Shanghai - - gasCostBerlin_d72g0v0_Shanghai - - gasCostBerlin_d74g0v0_Shanghai - - gasCostBerlin_d76g0v0_Shanghai - - gasCostBerlin_d73g0v0_Shanghai - - gasCostBerlin_d77g0v0_Shanghai - - gasCostBerlin_d75g0v0_Shanghai - - gasCostExp_d0g0v0_Shanghai - - gasCostBerlin_d78g0v0_Shanghai - - gasCostExp_d1g0v0_Shanghai - - gasCostExp_d2g0v0_Shanghai - - gasCostBerlin_d79g0v0_Shanghai - - gasCostExp_d3g0v0_Shanghai - - gasCostExp_d4g0v0_Shanghai - - gasCostExp_d5g0v0_Shanghai - - gasCostExp_d6g0v0_Shanghai - - gasCostExp_d7g0v0_Shanghai - - gasCostExp_d8g0v0_Shanghai - - gasCostBerlin_d7g0v0_Shanghai - - gasCostMemSeg_d0g0v0_Shanghai - - gasCostJump_d0g0v0_Shanghai - - gasCostJump_d1g0v0_Shanghai - - gasCostJump_d2g0v0_Shanghai - - gasCostBerlin_d80g0v0_Shanghai - - gasCostMemSeg_d10g0v0_Shanghai - - gasCostMemSeg_d11g0v0_Shanghai - - gasCostMemSeg_d12g0v0_Shanghai - - gasCostMemSeg_d13g0v0_Shanghai - - gasCostMemSeg_d14g0v0_Shanghai - - gasCostMemSeg_d15g0v0_Shanghai - - gasCostBerlin_d81g0v0_Shanghai - - gasCostMemSeg_d1g0v0_Shanghai - - gasCostMemSeg_d16g0v0_Shanghai - - gasCostMemSeg_d17g0v0_Shanghai - - gasCostMemSeg_d18g0v0_Shanghai - - gasCostMemSeg_d19g0v0_Shanghai - - gasCostMemSeg_d2g0v0_Shanghai - - gasCostMemSeg_d20g0v0_Shanghai - - gasCostMemSeg_d21g0v0_Shanghai - - gasCostMemSeg_d22g0v0_Shanghai - - gasCostMemSeg_d23g0v0_Shanghai - - gasCostMemSeg_d24g0v0_Shanghai - - gasCostMemSeg_d25g0v0_Shanghai - - gasCostMemSeg_d26g0v0_Shanghai - - gasCostMemSeg_d27g0v0_Shanghai - - gasCostMemSeg_d28g0v0_Shanghai - - gasCostMemSeg_d29g0v0_Shanghai - - gasCostMemSeg_d3g0v0_Shanghai - - gasCostMemSeg_d31g0v0_Shanghai - - gasCostMemSeg_d32g0v0_Shanghai - - gasCostMemSeg_d33g0v0_Shanghai - - gasCostMemSeg_d34g0v0_Shanghai - - gasCostMemSeg_d36g0v0_Shanghai - - gasCostMemSeg_d37g0v0_Shanghai - - gasCostMemSeg_d38g0v0_Shanghai - - gasCostMemSeg_d39g0v0_Shanghai - - gasCostMemSeg_d41g0v0_Shanghai - - gasCostMemSeg_d4g0v0_Shanghai - - gasCostMemSeg_d42g0v0_Shanghai - - gasCostMemSeg_d43g0v0_Shanghai - - gasCostMemSeg_d44g0v0_Shanghai - - gasCostMemSeg_d46g0v0_Shanghai - - gasCostMemSeg_d47g0v0_Shanghai - - gasCostMemSeg_d48g0v0_Shanghai - - gasCostMemSeg_d49g0v0_Shanghai - - gasCostMemSeg_d5g0v0_Shanghai - - gasCostBerlin_d83g0v0_Shanghai - - gasCostBerlin_d82g0v0_Shanghai - - gasCostBerlin_d84g0v0_Shanghai - - gasCostMemSeg_d6g0v0_Shanghai - - gasCostMemSeg_d7g0v0_Shanghai - - gasCostMemSeg_d8g0v0_Shanghai - - gasCostBerlin_d85g0v0_Shanghai - - gasCostMemSeg_d9g0v0_Shanghai - - gasCostBerlin_d86g0v0_Shanghai - - gasCostMemSeg_d51g0v0_Shanghai - - gasCostBerlin_d87g0v0_Shanghai - - gasCostMemSeg_d52g0v0_Shanghai - - gasCostMemSeg_d53g0v0_Shanghai - - gasCostBerlin_d88g0v0_Shanghai - - gasCostBerlin_d89g0v0_Shanghai - - gasCostMemSeg_d54g0v0_Shanghai - - gasCostBerlin_d8g0v0_Shanghai - - gasCostBerlin_d90g0v0_Shanghai - - gasCostBerlin_d91g0v0_Shanghai - - gasCostBerlin_d92g0v0_Shanghai - - gasCostBerlin_d93g0v0_Shanghai - - gasCostBerlin_d94g0v0_Shanghai - - gasCostBerlin_d95g0v0_Shanghai - - gasCostBerlin_d98g0v0_Shanghai - - gasCostBerlin_d96g0v0_Shanghai - - gasCostBerlin_d97g0v0_Shanghai - - gasCostMemory_d0g0v0_Shanghai - - gasCostBerlin_d9g0v0_Shanghai - - gasCostBerlin_d99g0v0_Shanghai - - gasCostMemory_d10g0v0_Shanghai - - gasCostMemory_d11g0v0_Shanghai - - gasCostMemory_d14g0v0_Shanghai - - gasCostMemory_d12g0v0_Shanghai - - gasCostMemory_d13g0v0_Shanghai - - gasCostMemory_d15g0v0_Shanghai - - gasCostMemory_d17g0v0_Shanghai - - gasCostMemory_d16g0v0_Shanghai - - gasCostMemory_d19g0v0_Shanghai - - gasCostMemory_d18g0v0_Shanghai - - gasCostMemory_d1g0v0_Shanghai - - gasCostMemory_d20g0v0_Shanghai - - gasCostMemory_d23g0v0_Shanghai - - gasCostMemory_d21g0v0_Shanghai - - gasCostMemory_d22g0v0_Shanghai - - gasCostMemory_d24g0v0_Shanghai - - gasCostMemory_d25g0v0_Shanghai - - gasCostMemory_d26g0v0_Shanghai - - gasCostMemory_d27g0v0_Shanghai - - gasCostMemory_d28g0v0_Shanghai - - gasCostMemory_d29g0v0_Shanghai - - gasCostMemory_d2g0v0_Shanghai - - gasCostMemory_d30g0v0_Shanghai - - gasCostMemory_d31g0v0_Shanghai - - gasCostMemory_d32g0v0_Shanghai - - gasCostMemory_d33g0v0_Shanghai - - gasCostMemory_d34g0v0_Shanghai - - gasCostMemory_d35g0v0_Shanghai - - gasCostMemory_d3g0v0_Shanghai - - gasCostMemory_d36g0v0_Shanghai - - gasCostMemory_d37g0v0_Shanghai - - gasCostMemory_d38g0v0_Shanghai - - gasCostMemory_d39g0v0_Shanghai - - gasCostMemory_d40g0v0_Shanghai - - gasCostMemory_d41g0v0_Shanghai - - gasCostMemory_d42g0v0_Shanghai - - gasCostMemory_d43g0v0_Shanghai - - gasCostMemory_d44g0v0_Shanghai - - gasCostMemory_d45g0v0_Shanghai - - gasCostMemory_d47g0v0_Shanghai - - gasCostMemory_d46g0v0_Shanghai - - gasCostMemory_d4g0v0_Shanghai - - gasCostMemory_d48g0v0_Shanghai - - gasCostReturn_d0g0v0_Shanghai - - gasCostMemory_d49g0v0_Shanghai - - gasCostMemory_d50g0v0_Shanghai - - gasCostMemory_d51g0v0_Shanghai - - gasCostMemory_d52g0v0_Shanghai - - gasCostMemory_d53g0v0_Shanghai - - gasCostMemory_d5g0v0_Shanghai - - gasCostMemory_d54g0v0_Shanghai - - gasCostMemory_d55g0v0_Shanghai - - gasCostMemory_d56g0v0_Shanghai - - gasCostMemory_d57g0v0_Shanghai - - gasCostMemory_d58g0v0_Shanghai - - gasCostMemory_d59g0v0_Shanghai - - gasCostMemory_d60g0v0_Shanghai - - gasCostMemory_d6g0v0_Shanghai - - gasCostMemory_d61g0v0_Shanghai - - gasCostMemory_d62g0v0_Shanghai - - gasCostMemory_d63g0v0_Shanghai - - gasCostMemory_d64g0v0_Shanghai - - gasCostMemory_d65g0v0_Shanghai - - gasCostMemory_d8g0v0_Shanghai - - gasCostMemory_d7g0v0_Shanghai - - gasCostMemory_d9g0v0_Shanghai - - gasCostMemory_d66g0v0_Shanghai - - gasCostMemory_d67g0v0_Shanghai - - gasCostMemory_d68g0v0_Shanghai - - gasCostMemory_d69g0v0_Shanghai - - gasCostMemory_d70g0v0_Shanghai - - gasCostMemory_d71g0v0_Shanghai - - gasCostMemory_d72g0v0_Shanghai - - gasCostMemory_d73g0v0_Shanghai - - gasCostMemory_d74g0v0_Shanghai + - gasCostJump_d0g0v0_Cancun + - gasCostJump_d1g0v0_Cancun + - gasCostJump_d2g0v0_Cancun + - gasCostReturn_d0g0v0_Cancun stEIP1559: - - baseFeeDiffPlaces_d0g0v0_Shanghai - - baseFeeDiffPlaces_d1g0v0_Shanghai - - baseFeeDiffPlaces_d10g0v0_Shanghai - - baseFeeDiffPlaces_d2g0v0_Shanghai - - baseFeeDiffPlaces_d11g0v0_Shanghai - - baseFeeDiffPlaces_d12g0v0_Shanghai - - baseFeeDiffPlaces_d3g0v0_Shanghai - - baseFeeDiffPlaces_d13g0v0_Shanghai - - baseFeeDiffPlaces_d4g0v0_Shanghai - - baseFeeDiffPlaces_d14g0v0_Shanghai - - baseFeeDiffPlaces_d15g0v0_Shanghai - - baseFeeDiffPlaces_d5g0v0_Shanghai - - baseFeeDiffPlaces_d6g0v0_Shanghai - - baseFeeDiffPlaces_d16g0v0_Shanghai - - baseFeeDiffPlaces_d7g0v0_Shanghai - - baseFeeDiffPlaces_d17g0v0_Shanghai - - baseFeeDiffPlaces_d18g0v0_Shanghai - - baseFeeDiffPlaces_d19g0v0_Shanghai - - gasPriceDiffPlaces_d0g0v0_Shanghai - - baseFeeDiffPlaces_d20g0v0_Shanghai - - baseFeeDiffPlaces_d8g0v0_Shanghai - - baseFeeDiffPlaces_d21g0v0_Shanghai - - baseFeeDiffPlaces_d9g0v0_Shanghai - - baseFeeDiffPlaces_d22g0v0_Shanghai - - gasPriceDiffPlaces_d1g0v0_Shanghai - - baseFeeDiffPlaces_d24g0v0_Shanghai - - baseFeeDiffPlaces_d23g0v0_Shanghai - - gasPriceDiffPlaces_d10g0v0_Shanghai - - baseFeeDiffPlaces_d25g0v0_Shanghai - - baseFeeDiffPlaces_d26g0v0_Shanghai - - gasPriceDiffPlaces_d11g0v0_Shanghai - - gasPriceDiffPlaces_d12g0v0_Shanghai - - baseFeeDiffPlaces_d28g0v0_Shanghai - - baseFeeDiffPlaces_d27g0v0_Shanghai - - baseFeeDiffPlaces_d29g0v0_Shanghai - - baseFeeDiffPlaces_d30g0v0_Shanghai - - gasPriceDiffPlaces_d13g0v0_Shanghai - - baseFeeDiffPlaces_d32g0v0_Shanghai - - baseFeeDiffPlaces_d31g0v0_Shanghai - - baseFeeDiffPlaces_d33g0v0_Shanghai - - intrinsic_d0g0v0_Shanghai - - intrinsic_d0g10v0_Shanghai - - gasPriceDiffPlaces_d14g0v0_Shanghai - - baseFeeDiffPlaces_d34g0v0_Shanghai - - intrinsic_d0g11v0_Shanghai - - intrinsic_d0g12v0_Shanghai - - intrinsic_d0g13v0_Shanghai - - intrinsic_d0g14v0_Shanghai - - gasPriceDiffPlaces_d15g0v0_Shanghai - - intrinsic_d0g15v0_Shanghai - - intrinsic_d0g16v0_Shanghai - - intrinsic_d0g17v0_Shanghai - - intrinsic_d0g18v0_Shanghai - - intrinsic_d0g19v0_Shanghai - - intrinsic_d0g1v0_Shanghai - - intrinsic_d0g20v0_Shanghai - - intrinsic_d0g21v0_Shanghai - - intrinsic_d0g22v0_Shanghai - - intrinsic_d0g23v0_Shanghai - - intrinsic_d0g24v0_Shanghai - - intrinsic_d0g25v0_Shanghai - - gasPriceDiffPlaces_d16g0v0_Shanghai - - intrinsic_d0g26v0_Shanghai - - intrinsic_d0g27v0_Shanghai - - intrinsic_d0g29v0_Shanghai - - intrinsic_d0g28v0_Shanghai - - intrinsic_d0g2v0_Shanghai - - intrinsic_d0g30v0_Shanghai - - intrinsic_d0g31v0_Shanghai - - intrinsic_d0g32v0_Shanghai - - intrinsic_d0g33v0_Shanghai - - intrinsic_d0g34v0_Shanghai - - gasPriceDiffPlaces_d17g0v0_Shanghai - - intrinsic_d0g35v0_Shanghai - - intrinsic_d0g36v0_Shanghai - - intrinsic_d0g37v0_Shanghai - - intrinsic_d0g38v0_Shanghai - - intrinsic_d0g39v0_Shanghai - - intrinsic_d0g3v0_Shanghai - - intrinsic_d0g40v0_Shanghai - - intrinsic_d0g41v0_Shanghai - - intrinsic_d0g42v0_Shanghai - - intrinsic_d0g43v0_Shanghai - - intrinsic_d0g44v0_Shanghai - - intrinsic_d0g45v0_Shanghai - - intrinsic_d0g46v0_Shanghai - - intrinsic_d0g47v0_Shanghai - - intrinsic_d0g48v0_Shanghai - - gasPriceDiffPlaces_d2g0v0_Shanghai - - intrinsic_d0g49v0_Shanghai - - intrinsic_d0g4v0_Shanghai - - gasPriceDiffPlaces_d18g0v0_Shanghai - - intrinsic_d0g50v0_Shanghai - - intrinsic_d0g51v0_Shanghai - - intrinsic_d0g52v0_Shanghai - - intrinsic_d0g53v0_Shanghai - - intrinsic_d0g54v0_Shanghai - - intrinsic_d0g55v0_Shanghai - - intrinsic_d0g56v0_Shanghai - - intrinsic_d0g5v0_Shanghai - - intrinsic_d0g57v0_Shanghai - - gasPriceDiffPlaces_d19g0v0_Shanghai - - intrinsic_d0g6v0_Shanghai - - intrinsic_d0g7v0_Shanghai - - intrinsic_d0g8v0_Shanghai - - intrinsic_d10g0v0_Shanghai - - intrinsic_d0g9v0_Shanghai - - intrinsic_d10g10v0_Shanghai - - intrinsic_d10g11v0_Shanghai - - intrinsic_d10g12v0_Shanghai - - intrinsic_d10g13v0_Shanghai - - intrinsic_d10g14v0_Shanghai - - intrinsic_d10g15v0_Shanghai - - intrinsic_d10g16v0_Shanghai - - intrinsic_d10g17v0_Shanghai - - intrinsic_d10g18v0_Shanghai - - intrinsic_d10g19v0_Shanghai - - intrinsic_d10g1v0_Shanghai - - intrinsic_d10g20v0_Shanghai - - intrinsic_d10g21v0_Shanghai - - intrinsic_d10g22v0_Shanghai - - intrinsic_d10g23v0_Shanghai - - intrinsic_d10g24v0_Shanghai - - intrinsic_d10g25v0_Shanghai - - intrinsic_d10g26v0_Shanghai - - intrinsic_d10g29v0_Shanghai - - intrinsic_d10g27v0_Shanghai - - intrinsic_d10g28v0_Shanghai - - gasPriceDiffPlaces_d20g0v0_Shanghai - - intrinsic_d10g2v0_Shanghai - - intrinsic_d10g30v0_Shanghai - - intrinsic_d10g31v0_Shanghai - - intrinsic_d10g32v0_Shanghai - - intrinsic_d10g33v0_Shanghai - - intrinsic_d10g34v0_Shanghai - - intrinsic_d10g35v0_Shanghai - - intrinsic_d10g36v0_Shanghai - - intrinsic_d10g39v0_Shanghai - - intrinsic_d10g37v0_Shanghai - - intrinsic_d10g38v0_Shanghai - - intrinsic_d10g3v0_Shanghai - - intrinsic_d10g40v0_Shanghai - - intrinsic_d10g41v0_Shanghai - - intrinsic_d10g42v0_Shanghai - - intrinsic_d10g43v0_Shanghai - - intrinsic_d10g44v0_Shanghai - - intrinsic_d10g45v0_Shanghai - - intrinsic_d10g46v0_Shanghai - - intrinsic_d10g48v0_Shanghai - - intrinsic_d10g47v0_Shanghai - - intrinsic_d10g49v0_Shanghai - - intrinsic_d10g50v0_Shanghai - - intrinsic_d10g4v0_Shanghai - - intrinsic_d10g51v0_Shanghai - - intrinsic_d10g52v0_Shanghai - - intrinsic_d10g53v0_Shanghai - - intrinsic_d10g54v0_Shanghai - - intrinsic_d10g55v0_Shanghai - - gasPriceDiffPlaces_d3g0v0_Shanghai - - intrinsic_d10g5v0_Shanghai - - intrinsic_d10g56v0_Shanghai - - intrinsic_d10g57v0_Shanghai - - intrinsic_d10g6v0_Shanghai - - intrinsic_d10g7v0_Shanghai - - intrinsic_d10g8v0_Shanghai - - intrinsic_d10g9v0_Shanghai - - intrinsic_d11g0v0_Shanghai - - intrinsic_d11g10v0_Shanghai - - intrinsic_d11g11v0_Shanghai - - intrinsic_d11g12v0_Shanghai - - intrinsic_d11g13v0_Shanghai - - intrinsic_d11g14v0_Shanghai - - intrinsic_d11g15v0_Shanghai - - intrinsic_d11g16v0_Shanghai - - intrinsic_d11g17v0_Shanghai - - intrinsic_d11g18v0_Shanghai - - intrinsic_d11g19v0_Shanghai - - intrinsic_d11g1v0_Shanghai - - gasPriceDiffPlaces_d4g0v0_Shanghai - - intrinsic_d11g20v0_Shanghai - - intrinsic_d11g21v0_Shanghai - - intrinsic_d11g22v0_Shanghai - - intrinsic_d11g23v0_Shanghai - - intrinsic_d11g24v0_Shanghai - - intrinsic_d11g25v0_Shanghai - - intrinsic_d11g26v0_Shanghai - - intrinsic_d11g27v0_Shanghai - - intrinsic_d11g29v0_Shanghai - - intrinsic_d11g28v0_Shanghai - - intrinsic_d11g30v0_Shanghai - - intrinsic_d11g2v0_Shanghai - - intrinsic_d11g31v0_Shanghai - - intrinsic_d11g32v0_Shanghai - - gasPriceDiffPlaces_d5g0v0_Shanghai - - intrinsic_d11g33v0_Shanghai - - gasPriceDiffPlaces_d21g0v0_Shanghai - - intrinsic_d11g34v0_Shanghai - - intrinsic_d11g36v0_Shanghai - - intrinsic_d11g35v0_Shanghai - - intrinsic_d11g37v0_Shanghai - - intrinsic_d11g39v0_Shanghai - - intrinsic_d11g38v0_Shanghai - - intrinsic_d11g3v0_Shanghai - - intrinsic_d11g40v0_Shanghai - - intrinsic_d11g41v0_Shanghai - - intrinsic_d11g42v0_Shanghai - - intrinsic_d11g43v0_Shanghai - - intrinsic_d11g44v0_Shanghai - - intrinsic_d11g45v0_Shanghai - - intrinsic_d11g46v0_Shanghai - - intrinsic_d11g47v0_Shanghai - - intrinsic_d11g48v0_Shanghai - - intrinsic_d11g49v0_Shanghai - - gasPriceDiffPlaces_d22g0v0_Shanghai - - intrinsic_d11g4v0_Shanghai - - intrinsic_d11g54v0_Shanghai - - gasPriceDiffPlaces_d6g0v0_Shanghai - - intrinsic_d11g50v0_Shanghai - - intrinsic_d11g51v0_Shanghai - - intrinsic_d11g52v0_Shanghai - - intrinsic_d11g53v0_Shanghai - - intrinsic_d11g55v0_Shanghai - - intrinsic_d11g56v0_Shanghai - - intrinsic_d11g5v0_Shanghai - - intrinsic_d11g57v0_Shanghai - - intrinsic_d11g6v0_Shanghai - - intrinsic_d11g7v0_Shanghai - - gasPriceDiffPlaces_d7g0v0_Shanghai - - intrinsic_d11g8v0_Shanghai - - intrinsic_d11g9v0_Shanghai - - intrinsic_d12g0v0_Shanghai - - intrinsic_d12g10v0_Shanghai - - intrinsic_d12g13v0_Shanghai - - intrinsic_d12g12v0_Shanghai - - intrinsic_d12g11v0_Shanghai - - intrinsic_d12g15v0_Shanghai - - intrinsic_d12g14v0_Shanghai - - intrinsic_d12g16v0_Shanghai - - intrinsic_d12g17v0_Shanghai - - intrinsic_d12g18v0_Shanghai - - intrinsic_d12g19v0_Shanghai - - intrinsic_d12g1v0_Shanghai - - intrinsic_d12g20v0_Shanghai - - intrinsic_d12g21v0_Shanghai - - intrinsic_d12g22v0_Shanghai - - gasPriceDiffPlaces_d8g0v0_Shanghai - - intrinsic_d12g23v0_Shanghai - - intrinsic_d12g24v0_Shanghai - - intrinsic_d12g25v0_Shanghai - - gasPriceDiffPlaces_d24g0v0_Shanghai - - intrinsic_d12g26v0_Shanghai - - intrinsic_d12g29v0_Shanghai - - gasPriceDiffPlaces_d23g0v0_Shanghai - - intrinsic_d12g28v0_Shanghai - - intrinsic_d12g27v0_Shanghai - - intrinsic_d12g2v0_Shanghai - - intrinsic_d12g30v0_Shanghai - - intrinsic_d12g33v0_Shanghai - - intrinsic_d12g31v0_Shanghai - - intrinsic_d12g32v0_Shanghai - - intrinsic_d12g34v0_Shanghai - - intrinsic_d12g35v0_Shanghai - - intrinsic_d12g36v0_Shanghai - - intrinsic_d12g37v0_Shanghai - - intrinsic_d12g38v0_Shanghai - - intrinsic_d12g39v0_Shanghai - - intrinsic_d12g3v0_Shanghai - - gasPriceDiffPlaces_d9g0v0_Shanghai - - intrinsic_d12g40v0_Shanghai - - intrinsic_d12g41v0_Shanghai - - intrinsic_d12g42v0_Shanghai - - intrinsic_d12g43v0_Shanghai - - intrinsic_d12g44v0_Shanghai - - intrinsic_d12g45v0_Shanghai - - intrinsic_d12g46v0_Shanghai - - intrinsic_d12g47v0_Shanghai - - intrinsic_d12g48v0_Shanghai - - intrinsic_d12g49v0_Shanghai - - intrinsic_d12g4v0_Shanghai - - intrinsic_d12g50v0_Shanghai - - intrinsic_d12g51v0_Shanghai - - intrinsic_d12g52v0_Shanghai - - intrinsic_d12g53v0_Shanghai - - intrinsic_d12g54v0_Shanghai - - intrinsic_d12g55v0_Shanghai - - intrinsic_d12g56v0_Shanghai - - intrinsic_d12g57v0_Shanghai - - intrinsic_d12g5v0_Shanghai - - intrinsic_d12g6v0_Shanghai - - intrinsic_d12g8v0_Shanghai - - intrinsic_d12g7v0_Shanghai - - intrinsic_d12g9v0_Shanghai - - intrinsic_d13g0v0_Shanghai - - intrinsic_d13g10v0_Shanghai - - intrinsic_d13g11v0_Shanghai - - intrinsic_d13g13v0_Shanghai - - intrinsic_d13g14v0_Shanghai - - intrinsic_d13g12v0_Shanghai - - intrinsic_d13g15v0_Shanghai - - intrinsic_d13g1v0_Shanghai - - gasPriceDiffPlaces_d25g0v0_Shanghai - - intrinsic_d13g16v0_Shanghai - - intrinsic_d13g17v0_Shanghai - - intrinsic_d13g20v0_Shanghai - - intrinsic_d13g19v0_Shanghai - - intrinsic_d13g18v0_Shanghai - - intrinsic_d13g21v0_Shanghai - - intrinsic_d13g22v0_Shanghai - - intrinsic_d13g23v0_Shanghai - - intrinsic_d13g24v0_Shanghai - - intrinsic_d13g25v0_Shanghai - - intrinsic_d13g26v0_Shanghai - - intrinsic_d13g27v0_Shanghai - - intrinsic_d13g28v0_Shanghai - - intrinsic_d13g29v0_Shanghai - - intrinsic_d13g2v0_Shanghai - - intrinsic_d13g30v0_Shanghai - - intrinsic_d13g31v0_Shanghai - - intrinsic_d13g34v0_Shanghai - - intrinsic_d13g32v0_Shanghai - - intrinsic_d13g33v0_Shanghai - - intrinsic_d13g35v0_Shanghai - - intrinsic_d13g36v0_Shanghai - - intrinsic_d13g39v0_Shanghai - - intrinsic_d13g37v0_Shanghai - - intrinsic_d13g38v0_Shanghai - - intrinsic_d13g3v0_Shanghai - - intrinsic_d13g40v0_Shanghai - - intrinsic_d13g41v0_Shanghai - - intrinsic_d13g42v0_Shanghai - - intrinsic_d13g43v0_Shanghai - - intrinsic_d13g44v0_Shanghai - - intrinsic_d13g45v0_Shanghai - - intrinsic_d13g46v0_Shanghai - - intrinsic_d13g47v0_Shanghai - - intrinsic_d13g48v0_Shanghai - - intrinsic_d13g49v0_Shanghai - - intrinsic_d13g4v0_Shanghai - - intrinsic_d13g50v0_Shanghai - - intrinsic_d13g52v0_Shanghai - - intrinsic_d13g51v0_Shanghai - - intrinsic_d13g53v0_Shanghai - - intrinsic_d13g54v0_Shanghai - - intrinsic_d13g55v0_Shanghai - - intrinsic_d13g56v0_Shanghai - - intrinsic_d13g5v0_Shanghai - - intrinsic_d13g57v0_Shanghai - - intrinsic_d13g6v0_Shanghai - - intrinsic_d13g8v0_Shanghai - - intrinsic_d13g7v0_Shanghai - - intrinsic_d13g9v0_Shanghai - - intrinsic_d14g0v0_Shanghai - - intrinsic_d14g10v0_Shanghai - - intrinsic_d14g11v0_Shanghai - - intrinsic_d14g12v0_Shanghai - - intrinsic_d14g13v0_Shanghai - - intrinsic_d14g14v0_Shanghai - - intrinsic_d14g15v0_Shanghai - - intrinsic_d14g16v0_Shanghai - - gasPriceDiffPlaces_d26g0v0_Shanghai - - intrinsic_d14g17v0_Shanghai - - intrinsic_d14g18v0_Shanghai - - intrinsic_d14g19v0_Shanghai - - intrinsic_d14g1v0_Shanghai - - intrinsic_d14g20v0_Shanghai - - intrinsic_d14g21v0_Shanghai - - intrinsic_d14g22v0_Shanghai - - intrinsic_d14g23v0_Shanghai - - intrinsic_d14g24v0_Shanghai - - intrinsic_d14g25v0_Shanghai - - intrinsic_d14g2v0_Shanghai - - intrinsic_d14g26v0_Shanghai - - intrinsic_d14g29v0_Shanghai - - intrinsic_d14g27v0_Shanghai - - intrinsic_d14g28v0_Shanghai - - intrinsic_d14g30v0_Shanghai - - intrinsic_d14g31v0_Shanghai - - intrinsic_d14g32v0_Shanghai - - intrinsic_d14g34v0_Shanghai - - intrinsic_d14g33v0_Shanghai - - intrinsic_d14g35v0_Shanghai - - intrinsic_d14g36v0_Shanghai - - intrinsic_d14g39v0_Shanghai - - intrinsic_d14g38v0_Shanghai - - intrinsic_d14g37v0_Shanghai - - intrinsic_d14g3v0_Shanghai - - intrinsic_d14g40v0_Shanghai - - intrinsic_d14g41v0_Shanghai - - intrinsic_d14g44v0_Shanghai - - intrinsic_d14g42v0_Shanghai - - intrinsic_d14g43v0_Shanghai - - intrinsic_d14g45v0_Shanghai - - intrinsic_d14g46v0_Shanghai - - intrinsic_d14g49v0_Shanghai - - intrinsic_d14g48v0_Shanghai - - intrinsic_d14g47v0_Shanghai - - intrinsic_d14g50v0_Shanghai - - intrinsic_d14g4v0_Shanghai - - intrinsic_d14g51v0_Shanghai - - intrinsic_d15g0v0_Shanghai - - intrinsic_d15g10v0_Shanghai - - intrinsic_d15g11v0_Shanghai - - intrinsic_d15g12v0_Shanghai - - intrinsic_d15g13v0_Shanghai - - intrinsic_d14g52v0_Shanghai - - intrinsic_d15g14v0_Shanghai - - intrinsic_d15g15v0_Shanghai - - intrinsic_d15g16v0_Shanghai - - intrinsic_d15g17v0_Shanghai - - intrinsic_d15g18v0_Shanghai - - intrinsic_d15g19v0_Shanghai - - intrinsic_d15g1v0_Shanghai - - intrinsic_d15g20v0_Shanghai - - intrinsic_d14g53v0_Shanghai - - intrinsic_d14g54v0_Shanghai - - intrinsic_d14g55v0_Shanghai - - intrinsic_d14g57v0_Shanghai - - intrinsic_d14g56v0_Shanghai - - intrinsic_d14g5v0_Shanghai - - intrinsic_d15g21v0_Shanghai - - intrinsic_d15g22v0_Shanghai - - intrinsic_d14g7v0_Shanghai - - intrinsic_d15g23v0_Shanghai - - intrinsic_d15g25v0_Shanghai - - intrinsic_d14g6v0_Shanghai - - intrinsic_d15g24v0_Shanghai - - intrinsic_d15g29v0_Shanghai - - intrinsic_d15g26v0_Shanghai - - intrinsic_d15g27v0_Shanghai - - intrinsic_d14g9v0_Shanghai - - intrinsic_d15g28v0_Shanghai - - intrinsic_d14g8v0_Shanghai - - gasPriceDiffPlaces_d27g0v0_Shanghai - - intrinsic_d15g2v0_Shanghai - - intrinsic_d15g30v0_Shanghai - - intrinsic_d15g34v0_Shanghai - - intrinsic_d15g31v0_Shanghai - - intrinsic_d15g33v0_Shanghai - - intrinsic_d15g32v0_Shanghai - - gasPriceDiffPlaces_d28g0v0_Shanghai - - intrinsic_d15g35v0_Shanghai - - intrinsic_d15g36v0_Shanghai - - intrinsic_d15g39v0_Shanghai - - intrinsic_d15g37v0_Shanghai - - intrinsic_d15g3v0_Shanghai - - intrinsic_d15g38v0_Shanghai - - intrinsic_d15g40v0_Shanghai - - intrinsic_d15g44v0_Shanghai - - intrinsic_d15g41v0_Shanghai - - intrinsic_d15g42v0_Shanghai - - intrinsic_d15g43v0_Shanghai - - intrinsic_d15g48v0_Shanghai - - intrinsic_d15g46v0_Shanghai - - intrinsic_d15g49v0_Shanghai - - intrinsic_d15g47v0_Shanghai - - intrinsic_d15g45v0_Shanghai - - intrinsic_d15g4v0_Shanghai - - intrinsic_d15g50v0_Shanghai - - intrinsic_d15g51v0_Shanghai - - intrinsic_d15g52v0_Shanghai - - intrinsic_d15g54v0_Shanghai - - intrinsic_d15g53v0_Shanghai - - intrinsic_d15g55v0_Shanghai - - intrinsic_d15g56v0_Shanghai - - intrinsic_d15g5v0_Shanghai - - intrinsic_d15g57v0_Shanghai - - intrinsic_d15g6v0_Shanghai - - intrinsic_d15g7v0_Shanghai - - intrinsic_d15g8v0_Shanghai - - intrinsic_d15g9v0_Shanghai - - gasPriceDiffPlaces_d29g0v0_Shanghai - - intrinsic_d16g0v0_Shanghai - - intrinsic_d16g10v0_Shanghai - - intrinsic_d16g11v0_Shanghai - - intrinsic_d16g12v0_Shanghai - - intrinsic_d16g13v0_Shanghai - - intrinsic_d16g14v0_Shanghai - - intrinsic_d16g15v0_Shanghai - - intrinsic_d16g16v0_Shanghai - - intrinsic_d16g17v0_Shanghai - - intrinsic_d16g19v0_Shanghai - - intrinsic_d16g1v0_Shanghai - - intrinsic_d16g20v0_Shanghai - - intrinsic_d16g18v0_Shanghai - - intrinsic_d16g22v0_Shanghai - - intrinsic_d16g21v0_Shanghai - - intrinsic_d16g29v0_Shanghai - - intrinsic_d16g23v0_Shanghai - - gasPriceDiffPlaces_d30g0v0_Shanghai - - intrinsic_d16g24v0_Shanghai - - intrinsic_d16g25v0_Shanghai - - intrinsic_d16g26v0_Shanghai - - intrinsic_d16g27v0_Shanghai - - intrinsic_d16g28v0_Shanghai - - intrinsic_d16g2v0_Shanghai - - intrinsic_d16g30v0_Shanghai - - intrinsic_d16g31v0_Shanghai - - intrinsic_d16g32v0_Shanghai - - intrinsic_d16g33v0_Shanghai - - intrinsic_d16g34v0_Shanghai - - intrinsic_d16g35v0_Shanghai - - intrinsic_d16g36v0_Shanghai - - intrinsic_d16g37v0_Shanghai - - intrinsic_d16g39v0_Shanghai - - intrinsic_d16g44v0_Shanghai - - intrinsic_d16g38v0_Shanghai - - intrinsic_d16g40v0_Shanghai - - intrinsic_d16g3v0_Shanghai - - intrinsic_d16g41v0_Shanghai - - intrinsic_d16g42v0_Shanghai - - intrinsic_d16g43v0_Shanghai - - intrinsic_d16g45v0_Shanghai - - intrinsic_d16g46v0_Shanghai - - intrinsic_d16g49v0_Shanghai - - intrinsic_d16g47v0_Shanghai - - intrinsic_d16g48v0_Shanghai - - intrinsic_d16g4v0_Shanghai - - intrinsic_d16g50v0_Shanghai - - intrinsic_d16g52v0_Shanghai - - intrinsic_d16g51v0_Shanghai - - intrinsic_d16g54v0_Shanghai - - intrinsic_d16g53v0_Shanghai - - gasPriceDiffPlaces_d31g0v0_Shanghai - - intrinsic_d16g55v0_Shanghai - - intrinsic_d16g5v0_Shanghai - - intrinsic_d16g56v0_Shanghai - - intrinsic_d16g57v0_Shanghai - - intrinsic_d16g6v0_Shanghai - - intrinsic_d16g7v0_Shanghai - - gasPriceDiffPlaces_d32g0v0_Shanghai - - intrinsic_d16g8v0_Shanghai - - intrinsic_d16g9v0_Shanghai - - intrinsic_d17g0v0_Shanghai - - intrinsic_d17g10v0_Shanghai - - intrinsic_d17g11v0_Shanghai - - intrinsic_d17g12v0_Shanghai - - intrinsic_d17g15v0_Shanghai - - intrinsic_d17g14v0_Shanghai - - intrinsic_d17g13v0_Shanghai - - intrinsic_d17g16v0_Shanghai - - intrinsic_d17g20v0_Shanghai - - intrinsic_d17g18v0_Shanghai - - intrinsic_d17g17v0_Shanghai - - intrinsic_d17g19v0_Shanghai - - intrinsic_d17g1v0_Shanghai - - intrinsic_d17g25v0_Shanghai - - intrinsic_d17g21v0_Shanghai - - intrinsic_d17g22v0_Shanghai - - intrinsic_d17g23v0_Shanghai - - intrinsic_d17g24v0_Shanghai - - intrinsic_d17g26v0_Shanghai - - intrinsic_d17g27v0_Shanghai - - gasPriceDiffPlaces_d33g0v0_Shanghai - - intrinsic_d17g29v0_Shanghai - - intrinsic_d17g28v0_Shanghai - - intrinsic_d17g2v0_Shanghai - - intrinsic_d17g30v0_Shanghai - - intrinsic_d17g31v0_Shanghai - - gasPriceDiffPlaces_d34g0v0_Shanghai - - intrinsic_d17g32v0_Shanghai - - intrinsic_d17g34v0_Shanghai - - intrinsic_d17g33v0_Shanghai - - intrinsic_d17g35v0_Shanghai - - intrinsic_d17g36v0_Shanghai - - intrinsic_d17g37v0_Shanghai - - intrinsic_d17g38v0_Shanghai - - intrinsic_d17g39v0_Shanghai - - intrinsic_d17g44v0_Shanghai - - intrinsic_d17g3v0_Shanghai - - intrinsic_d17g40v0_Shanghai - - intrinsic_d17g41v0_Shanghai - - intrinsic_d17g42v0_Shanghai - - intrinsic_d17g43v0_Shanghai - - intrinsic_d17g45v0_Shanghai - - intrinsic_d17g46v0_Shanghai - - intrinsic_d17g47v0_Shanghai - - intrinsic_d17g48v0_Shanghai - - intrinsic_d17g49v0_Shanghai - - intrinsic_d17g4v0_Shanghai - - intrinsic_d17g52v0_Shanghai - - intrinsic_d17g50v0_Shanghai - - intrinsic_d17g51v0_Shanghai - - intrinsic_d17g54v0_Shanghai - - intrinsic_d17g53v0_Shanghai - - intrinsic_d17g55v0_Shanghai - - intrinsic_d17g56v0_Shanghai - - intrinsic_d17g5v0_Shanghai - - intrinsic_d17g57v0_Shanghai - - intrinsic_d17g6v0_Shanghai - - intrinsic_d17g7v0_Shanghai - - intrinsic_d17g8v0_Shanghai - - intrinsic_d17g9v0_Shanghai - - intrinsic_d18g0v0_Shanghai - - intrinsic_d18g10v0_Shanghai - - intrinsic_d18g11v0_Shanghai - - intrinsic_d18g13v0_Shanghai - - intrinsic_d18g12v0_Shanghai - - intrinsic_d18g14v0_Shanghai - - intrinsic_d18g15v0_Shanghai - - intrinsic_d18g16v0_Shanghai - - intrinsic_d18g17v0_Shanghai - - intrinsic_d18g19v0_Shanghai - - intrinsic_d18g18v0_Shanghai - - intrinsic_d18g1v0_Shanghai - - intrinsic_d18g20v0_Shanghai - - intrinsic_d18g21v0_Shanghai - - intrinsic_d18g22v0_Shanghai - - intrinsic_d18g25v0_Shanghai - - intrinsic_d18g24v0_Shanghai - - intrinsic_d18g23v0_Shanghai - - intrinsic_d18g29v0_Shanghai - - intrinsic_d18g26v0_Shanghai - - intrinsic_d18g27v0_Shanghai - - intrinsic_d18g28v0_Shanghai - - intrinsic_d18g2v0_Shanghai - - intrinsic_d18g30v0_Shanghai - - intrinsic_d18g31v0_Shanghai - - intrinsic_d18g34v0_Shanghai - - intrinsic_d18g32v0_Shanghai - - intrinsic_d18g33v0_Shanghai - - intrinsic_d18g35v0_Shanghai - - intrinsic_d18g36v0_Shanghai - - intrinsic_d18g37v0_Shanghai - - intrinsic_d18g38v0_Shanghai - - intrinsic_d18g39v0_Shanghai - - intrinsic_d18g3v0_Shanghai - - intrinsic_d18g40v0_Shanghai - - intrinsic_d18g44v0_Shanghai - - intrinsic_d18g41v0_Shanghai - - intrinsic_d18g42v0_Shanghai - - intrinsic_d18g43v0_Shanghai - - intrinsic_d18g45v0_Shanghai - - intrinsic_d18g47v0_Shanghai - - intrinsic_d18g46v0_Shanghai - - intrinsic_d18g48v0_Shanghai - - intrinsic_d18g49v0_Shanghai - - intrinsic_d18g4v0_Shanghai - - intrinsic_d18g50v0_Shanghai - - intrinsic_d18g51v0_Shanghai - - intrinsic_d18g52v0_Shanghai - - intrinsic_d18g54v0_Shanghai - - intrinsic_d18g53v0_Shanghai - - intrinsic_d18g55v0_Shanghai - - intrinsic_d18g5v0_Shanghai - - intrinsic_d18g57v0_Shanghai - - intrinsic_d18g56v0_Shanghai - - intrinsic_d18g6v0_Shanghai - - intrinsic_d18g7v0_Shanghai - - intrinsic_d18g8v0_Shanghai - - intrinsic_d18g9v0_Shanghai - - intrinsic_d19g0v0_Shanghai - - intrinsic_d19g10v0_Shanghai - - intrinsic_d19g12v0_Shanghai - - intrinsic_d19g11v0_Shanghai - - intrinsic_d19g13v0_Shanghai - - intrinsic_d19g14v0_Shanghai - - intrinsic_d19g15v0_Shanghai - - intrinsic_d19g16v0_Shanghai - - intrinsic_d19g17v0_Shanghai - - intrinsic_d19g18v0_Shanghai - - intrinsic_d19g20v0_Shanghai - - intrinsic_d19g19v0_Shanghai - - intrinsic_d19g1v0_Shanghai - - intrinsic_d19g21v0_Shanghai - - intrinsic_d19g22v0_Shanghai - - intrinsic_d19g23v0_Shanghai - - intrinsic_d19g25v0_Shanghai - - intrinsic_d19g24v0_Shanghai - - intrinsic_d19g29v0_Shanghai - - intrinsic_d19g27v0_Shanghai - - intrinsic_d19g26v0_Shanghai - - intrinsic_d19g28v0_Shanghai - - intrinsic_d19g2v0_Shanghai - - intrinsic_d19g30v0_Shanghai - - intrinsic_d19g34v0_Shanghai - - intrinsic_d19g31v0_Shanghai - - intrinsic_d19g32v0_Shanghai - - intrinsic_d19g33v0_Shanghai - - intrinsic_d19g35v0_Shanghai - - intrinsic_d19g36v0_Shanghai - - intrinsic_d19g37v0_Shanghai - - intrinsic_d19g38v0_Shanghai - - intrinsic_d19g39v0_Shanghai - - intrinsic_d19g3v0_Shanghai - - intrinsic_d19g40v0_Shanghai - - intrinsic_d19g41v0_Shanghai - - intrinsic_d19g42v0_Shanghai - - intrinsic_d19g43v0_Shanghai - - intrinsic_d1g0v0_Shanghai - - intrinsic_d1g10v0_Shanghai - - intrinsic_d1g11v0_Shanghai - - intrinsic_d1g12v0_Shanghai - - intrinsic_d1g13v0_Shanghai - - intrinsic_d1g14v0_Shanghai - - intrinsic_d19g44v0_Shanghai - - intrinsic_d19g45v0_Shanghai - - intrinsic_d1g15v0_Shanghai - - intrinsic_d19g46v0_Shanghai - - intrinsic_d1g16v0_Shanghai - - intrinsic_d19g47v0_Shanghai - - intrinsic_d19g48v0_Shanghai - - intrinsic_d19g49v0_Shanghai - - intrinsic_d19g4v0_Shanghai - - intrinsic_d1g17v0_Shanghai - - intrinsic_d1g18v0_Shanghai - - intrinsic_d1g19v0_Shanghai - - intrinsic_d19g50v0_Shanghai - - intrinsic_d19g51v0_Shanghai - - intrinsic_d19g55v0_Shanghai - - intrinsic_d19g53v0_Shanghai - - intrinsic_d19g54v0_Shanghai - - intrinsic_d19g5v0_Shanghai - - intrinsic_d19g52v0_Shanghai - - intrinsic_d19g56v0_Shanghai - - intrinsic_d19g57v0_Shanghai - - intrinsic_d1g1v0_Shanghai - - intrinsic_d1g20v0_Shanghai - - intrinsic_d19g6v0_Shanghai - - intrinsic_d1g21v0_Shanghai - - intrinsic_d19g8v0_Shanghai - - intrinsic_d19g7v0_Shanghai - - intrinsic_d1g22v0_Shanghai - - intrinsic_d19g9v0_Shanghai - - intrinsic_d1g23v0_Shanghai - - intrinsic_d1g25v0_Shanghai - - intrinsic_d1g24v0_Shanghai - - intrinsic_d1g26v0_Shanghai - - intrinsic_d1g27v0_Shanghai - - intrinsic_d1g29v0_Shanghai - - intrinsic_d1g28v0_Shanghai - - intrinsic_d1g2v0_Shanghai - - intrinsic_d1g30v0_Shanghai - - intrinsic_d1g31v0_Shanghai - - intrinsic_d1g32v0_Shanghai - - intrinsic_d1g33v0_Shanghai - - intrinsic_d1g34v0_Shanghai - - intrinsic_d1g35v0_Shanghai - - intrinsic_d1g36v0_Shanghai - - intrinsic_d1g37v0_Shanghai - - intrinsic_d1g38v0_Shanghai - - intrinsic_d1g39v0_Shanghai - - intrinsic_d1g40v0_Shanghai - - intrinsic_d1g44v0_Shanghai - - intrinsic_d1g3v0_Shanghai - - intrinsic_d1g43v0_Shanghai - - intrinsic_d1g41v0_Shanghai - - intrinsic_d1g42v0_Shanghai - - intrinsic_d1g45v0_Shanghai - - intrinsic_d1g46v0_Shanghai - - intrinsic_d1g47v0_Shanghai - - intrinsic_d1g48v0_Shanghai - - intrinsic_d1g4v0_Shanghai - - intrinsic_d1g49v0_Shanghai - - intrinsic_d1g50v0_Shanghai - - intrinsic_d1g51v0_Shanghai - - intrinsic_d1g54v0_Shanghai - - intrinsic_d1g52v0_Shanghai - - intrinsic_d1g53v0_Shanghai - - intrinsic_d1g55v0_Shanghai - - intrinsic_d1g56v0_Shanghai - - intrinsic_d1g57v0_Shanghai - - intrinsic_d20g0v0_Shanghai - - intrinsic_d20g10v0_Shanghai - - intrinsic_d1g5v0_Shanghai - - intrinsic_d20g11v0_Shanghai - - intrinsic_d20g12v0_Shanghai - - intrinsic_d1g6v0_Shanghai - - intrinsic_d20g15v0_Shanghai - - intrinsic_d20g13v0_Shanghai - - intrinsic_d20g14v0_Shanghai - - intrinsic_d20g16v0_Shanghai - - intrinsic_d1g7v0_Shanghai - - intrinsic_d20g20v0_Shanghai - - intrinsic_d20g17v0_Shanghai - - intrinsic_d20g18v0_Shanghai - - intrinsic_d1g8v0_Shanghai - - intrinsic_d20g25v0_Shanghai - - intrinsic_d20g1v0_Shanghai - - intrinsic_d20g19v0_Shanghai - - intrinsic_d1g9v0_Shanghai - - intrinsic_d20g21v0_Shanghai - - intrinsic_d20g23v0_Shanghai - - intrinsic_d20g22v0_Shanghai - - intrinsic_d20g24v0_Shanghai - - intrinsic_d20g29v0_Shanghai - - intrinsic_d20g26v0_Shanghai - - intrinsic_d20g27v0_Shanghai - - intrinsic_d20g28v0_Shanghai - - intrinsic_d20g30v0_Shanghai - - intrinsic_d20g2v0_Shanghai - - intrinsic_d20g31v0_Shanghai - - intrinsic_d20g32v0_Shanghai - - intrinsic_d20g34v0_Shanghai - - intrinsic_d20g33v0_Shanghai - - intrinsic_d20g35v0_Shanghai - - intrinsic_d20g36v0_Shanghai - - intrinsic_d20g39v0_Shanghai - - intrinsic_d20g37v0_Shanghai - - intrinsic_d20g38v0_Shanghai - - intrinsic_d20g3v0_Shanghai - - intrinsic_d20g40v0_Shanghai - - intrinsic_d20g44v0_Shanghai - - intrinsic_d20g49v0_Shanghai - - intrinsic_d20g41v0_Shanghai - - intrinsic_d20g42v0_Shanghai - - intrinsic_d20g45v0_Shanghai - - intrinsic_d20g43v0_Shanghai - - intrinsic_d20g46v0_Shanghai - - intrinsic_d20g54v0_Shanghai - - intrinsic_d20g48v0_Shanghai - - intrinsic_d20g47v0_Shanghai - - intrinsic_d20g50v0_Shanghai - - intrinsic_d20g4v0_Shanghai - - intrinsic_d20g52v0_Shanghai - - intrinsic_d20g51v0_Shanghai - - intrinsic_d20g53v0_Shanghai - - intrinsic_d20g5v0_Shanghai - - intrinsic_d20g55v0_Shanghai - - intrinsic_d20g56v0_Shanghai - - intrinsic_d20g57v0_Shanghai - - intrinsic_d20g6v0_Shanghai - - intrinsic_d20g7v0_Shanghai - - intrinsic_d20g8v0_Shanghai - - intrinsic_d20g9v0_Shanghai - - intrinsic_d21g0v0_Shanghai - - intrinsic_d21g10v0_Shanghai - - intrinsic_d21g11v0_Shanghai - - intrinsic_d21g12v0_Shanghai - - intrinsic_d21g15v0_Shanghai - - intrinsic_d21g13v0_Shanghai - - intrinsic_d21g14v0_Shanghai - - intrinsic_d21g16v0_Shanghai - - intrinsic_d21g25v0_Shanghai - - intrinsic_d21g17v0_Shanghai - - intrinsic_d21g18v0_Shanghai - - intrinsic_d21g19v0_Shanghai - - intrinsic_d21g20v0_Shanghai - - intrinsic_d21g1v0_Shanghai - - intrinsic_d21g29v0_Shanghai - - intrinsic_d21g22v0_Shanghai - - intrinsic_d21g23v0_Shanghai - - intrinsic_d21g21v0_Shanghai - - intrinsic_d21g26v0_Shanghai - - intrinsic_d21g27v0_Shanghai - - intrinsic_d21g24v0_Shanghai - - intrinsic_d21g28v0_Shanghai - - intrinsic_d21g34v0_Shanghai - - intrinsic_d21g2v0_Shanghai - - intrinsic_d21g30v0_Shanghai - - intrinsic_d21g31v0_Shanghai - - intrinsic_d21g32v0_Shanghai - - intrinsic_d21g33v0_Shanghai - - intrinsic_d21g35v0_Shanghai - - intrinsic_d21g36v0_Shanghai - - intrinsic_d21g37v0_Shanghai - - intrinsic_d21g38v0_Shanghai - - intrinsic_d21g39v0_Shanghai - - intrinsic_d21g3v0_Shanghai - - intrinsic_d21g40v0_Shanghai - - intrinsic_d21g44v0_Shanghai - - intrinsic_d21g41v0_Shanghai - - intrinsic_d21g42v0_Shanghai - - intrinsic_d21g43v0_Shanghai - - intrinsic_d21g49v0_Shanghai - - intrinsic_d21g45v0_Shanghai - - intrinsic_d21g54v0_Shanghai - - intrinsic_d21g48v0_Shanghai - - intrinsic_d21g46v0_Shanghai - - intrinsic_d21g47v0_Shanghai - - intrinsic_d21g4v0_Shanghai - - intrinsic_d21g51v0_Shanghai - - intrinsic_d21g50v0_Shanghai - - intrinsic_d21g5v0_Shanghai - - intrinsic_d21g52v0_Shanghai - - intrinsic_d21g53v0_Shanghai - - intrinsic_d21g56v0_Shanghai - - intrinsic_d21g55v0_Shanghai - - intrinsic_d21g57v0_Shanghai - - intrinsic_d21g6v0_Shanghai - - intrinsic_d21g8v0_Shanghai - - intrinsic_d21g7v0_Shanghai - - intrinsic_d22g0v0_Shanghai - - intrinsic_d21g9v0_Shanghai - - intrinsic_d22g10v0_Shanghai - - intrinsic_d22g11v0_Shanghai - - intrinsic_d22g12v0_Shanghai - - intrinsic_d22g13v0_Shanghai - - intrinsic_d22g14v0_Shanghai - - intrinsic_d22g15v0_Shanghai - - intrinsic_d22g16v0_Shanghai - - intrinsic_d22g17v0_Shanghai - - intrinsic_d22g18v0_Shanghai - - intrinsic_d22g19v0_Shanghai - - intrinsic_d22g1v0_Shanghai - - intrinsic_d22g20v0_Shanghai - - intrinsic_d22g25v0_Shanghai - - intrinsic_d22g29v0_Shanghai - - intrinsic_d22g21v0_Shanghai - - intrinsic_d22g22v0_Shanghai - - intrinsic_d22g23v0_Shanghai - - intrinsic_d22g24v0_Shanghai - - intrinsic_d22g28v0_Shanghai - - intrinsic_d22g26v0_Shanghai - - intrinsic_d22g34v0_Shanghai - - intrinsic_d22g27v0_Shanghai - - intrinsic_d22g2v0_Shanghai - - intrinsic_d22g30v0_Shanghai - - intrinsic_d22g31v0_Shanghai - - intrinsic_d22g39v0_Shanghai - - intrinsic_d22g32v0_Shanghai - - intrinsic_d22g33v0_Shanghai - - intrinsic_d22g35v0_Shanghai - - intrinsic_d22g36v0_Shanghai - - intrinsic_d22g37v0_Shanghai - - intrinsic_d22g38v0_Shanghai - - intrinsic_d22g3v0_Shanghai - - intrinsic_d22g40v0_Shanghai - - intrinsic_d22g41v0_Shanghai - - intrinsic_d22g42v0_Shanghai - - intrinsic_d22g43v0_Shanghai - - intrinsic_d22g44v0_Shanghai - - intrinsic_d22g45v0_Shanghai - - intrinsic_d22g49v0_Shanghai - - intrinsic_d22g46v0_Shanghai - - intrinsic_d22g48v0_Shanghai - - intrinsic_d22g47v0_Shanghai - - intrinsic_d22g4v0_Shanghai - - intrinsic_d22g54v0_Shanghai - - intrinsic_d22g52v0_Shanghai - - intrinsic_d22g50v0_Shanghai - - intrinsic_d22g51v0_Shanghai - - intrinsic_d22g5v0_Shanghai - - intrinsic_d22g53v0_Shanghai - - intrinsic_d22g55v0_Shanghai - - intrinsic_d22g56v0_Shanghai - - intrinsic_d22g6v0_Shanghai - - intrinsic_d22g7v0_Shanghai - - intrinsic_d22g57v0_Shanghai - - intrinsic_d22g8v0_Shanghai - - intrinsic_d22g9v0_Shanghai - - intrinsic_d23g0v0_Shanghai - - intrinsic_d23g10v0_Shanghai - - intrinsic_d23g11v0_Shanghai - - intrinsic_d23g15v0_Shanghai - - intrinsic_d23g12v0_Shanghai - - intrinsic_d23g13v0_Shanghai - - intrinsic_d23g14v0_Shanghai - - intrinsic_d23g16v0_Shanghai - - intrinsic_d23g17v0_Shanghai - - intrinsic_d23g18v0_Shanghai - - intrinsic_d23g19v0_Shanghai - - intrinsic_d23g1v0_Shanghai - - intrinsic_d23g20v0_Shanghai - - intrinsic_d23g21v0_Shanghai - - intrinsic_d23g22v0_Shanghai - - intrinsic_d23g25v0_Shanghai - - intrinsic_d23g23v0_Shanghai - - intrinsic_d23g29v0_Shanghai - - intrinsic_d23g26v0_Shanghai - - intrinsic_d23g24v0_Shanghai - - intrinsic_d23g27v0_Shanghai - - intrinsic_d23g2v0_Shanghai - - intrinsic_d23g28v0_Shanghai - - intrinsic_d23g30v0_Shanghai - - intrinsic_d23g34v0_Shanghai - - intrinsic_d23g31v0_Shanghai - - intrinsic_d23g32v0_Shanghai - - intrinsic_d23g33v0_Shanghai - - intrinsic_d23g35v0_Shanghai - - intrinsic_d23g38v0_Shanghai - - intrinsic_d23g36v0_Shanghai - - intrinsic_d23g37v0_Shanghai - - intrinsic_d23g39v0_Shanghai - - intrinsic_d23g3v0_Shanghai - - intrinsic_d23g40v0_Shanghai - - intrinsic_d23g41v0_Shanghai - - intrinsic_d23g44v0_Shanghai - - intrinsic_d23g42v0_Shanghai - - intrinsic_d23g45v0_Shanghai - - intrinsic_d23g43v0_Shanghai - - intrinsic_d23g46v0_Shanghai - - intrinsic_d23g47v0_Shanghai - - intrinsic_d23g48v0_Shanghai - - intrinsic_d23g49v0_Shanghai - - intrinsic_d23g4v0_Shanghai - - intrinsic_d23g50v0_Shanghai - - intrinsic_d23g52v0_Shanghai - - intrinsic_d23g54v0_Shanghai - - intrinsic_d23g51v0_Shanghai - - intrinsic_d23g53v0_Shanghai - - intrinsic_d23g5v0_Shanghai - - intrinsic_d23g55v0_Shanghai - - intrinsic_d23g56v0_Shanghai - - intrinsic_d23g6v0_Shanghai - - intrinsic_d23g57v0_Shanghai - - intrinsic_d23g7v0_Shanghai - - intrinsic_d23g8v0_Shanghai - - intrinsic_d23g9v0_Shanghai - - intrinsic_d24g0v0_Shanghai - - intrinsic_d24g10v0_Shanghai - - intrinsic_d24g11v0_Shanghai - - intrinsic_d24g12v0_Shanghai - - intrinsic_d24g14v0_Shanghai - - intrinsic_d24g13v0_Shanghai - - intrinsic_d24g15v0_Shanghai - - intrinsic_d24g16v0_Shanghai - - intrinsic_d24g17v0_Shanghai - - intrinsic_d24g18v0_Shanghai - - intrinsic_d24g1v0_Shanghai - - intrinsic_d24g19v0_Shanghai - - intrinsic_d24g20v0_Shanghai - - intrinsic_d24g21v0_Shanghai - - intrinsic_d24g22v0_Shanghai - - intrinsic_d24g23v0_Shanghai - - intrinsic_d24g24v0_Shanghai - - intrinsic_d24g25v0_Shanghai - - intrinsic_d24g26v0_Shanghai - - intrinsic_d24g27v0_Shanghai - - intrinsic_d24g29v0_Shanghai - - intrinsic_d24g28v0_Shanghai - - intrinsic_d24g30v0_Shanghai - - intrinsic_d24g2v0_Shanghai - - intrinsic_d24g34v0_Shanghai - - intrinsic_d24g31v0_Shanghai - - intrinsic_d24g32v0_Shanghai - - intrinsic_d24g33v0_Shanghai - - intrinsic_d24g36v0_Shanghai - - intrinsic_d24g35v0_Shanghai - - intrinsic_d24g37v0_Shanghai - - intrinsic_d24g38v0_Shanghai - - intrinsic_d24g39v0_Shanghai - - intrinsic_d24g3v0_Shanghai - - intrinsic_d24g40v0_Shanghai - - intrinsic_d25g0v0_Shanghai - - intrinsic_d24g41v0_Shanghai - - intrinsic_d24g42v0_Shanghai - - intrinsic_d24g43v0_Shanghai - - intrinsic_d25g10v0_Shanghai - - intrinsic_d25g11v0_Shanghai - - intrinsic_d25g13v0_Shanghai - - intrinsic_d25g12v0_Shanghai - - intrinsic_d24g44v0_Shanghai - - intrinsic_d25g14v0_Shanghai - - intrinsic_d24g45v0_Shanghai - - intrinsic_d24g46v0_Shanghai - - intrinsic_d24g49v0_Shanghai - - intrinsic_d24g47v0_Shanghai - - intrinsic_d24g48v0_Shanghai - - intrinsic_d24g4v0_Shanghai - - intrinsic_d25g15v0_Shanghai - - intrinsic_d24g50v0_Shanghai - - intrinsic_d24g51v0_Shanghai - - intrinsic_d25g16v0_Shanghai - - intrinsic_d24g54v0_Shanghai - - intrinsic_d24g52v0_Shanghai - - intrinsic_d24g53v0_Shanghai - - intrinsic_d25g17v0_Shanghai - - intrinsic_d25g19v0_Shanghai - - intrinsic_d25g18v0_Shanghai - - intrinsic_d25g1v0_Shanghai - - intrinsic_d25g20v0_Shanghai - - intrinsic_d25g22v0_Shanghai - - intrinsic_d25g21v0_Shanghai - - intrinsic_d25g23v0_Shanghai - - intrinsic_d25g25v0_Shanghai - - intrinsic_d25g24v0_Shanghai - - intrinsic_d24g55v0_Shanghai - - intrinsic_d25g26v0_Shanghai - - intrinsic_d25g29v0_Shanghai - - intrinsic_d25g27v0_Shanghai - - intrinsic_d25g28v0_Shanghai - - intrinsic_d24g56v0_Shanghai - - intrinsic_d25g2v0_Shanghai - - intrinsic_d25g30v0_Shanghai - - intrinsic_d24g57v0_Shanghai - - intrinsic_d24g5v0_Shanghai - - intrinsic_d25g31v0_Shanghai - - intrinsic_d25g32v0_Shanghai - - intrinsic_d24g6v0_Shanghai - - intrinsic_d25g33v0_Shanghai - - intrinsic_d25g34v0_Shanghai - - intrinsic_d24g7v0_Shanghai - - intrinsic_d24g8v0_Shanghai - - intrinsic_d24g9v0_Shanghai - - intrinsic_d25g39v0_Shanghai - - intrinsic_d25g35v0_Shanghai - - intrinsic_d25g36v0_Shanghai - - intrinsic_d25g37v0_Shanghai - - intrinsic_d25g38v0_Shanghai - - intrinsic_d25g40v0_Shanghai - - intrinsic_d25g3v0_Shanghai - - intrinsic_d25g41v0_Shanghai - - intrinsic_d25g42v0_Shanghai - - intrinsic_d25g44v0_Shanghai - - intrinsic_d25g43v0_Shanghai - - intrinsic_d25g45v0_Shanghai - - intrinsic_d25g46v0_Shanghai - - intrinsic_d25g47v0_Shanghai - - intrinsic_d25g48v0_Shanghai - - intrinsic_d25g49v0_Shanghai - - intrinsic_d25g4v0_Shanghai - - intrinsic_d25g50v0_Shanghai - - intrinsic_d25g51v0_Shanghai - - intrinsic_d25g54v0_Shanghai - - intrinsic_d25g5v0_Shanghai - - intrinsic_d25g52v0_Shanghai - - intrinsic_d25g53v0_Shanghai - - intrinsic_d25g55v0_Shanghai - - intrinsic_d25g57v0_Shanghai - - intrinsic_d25g56v0_Shanghai - - intrinsic_d25g6v0_Shanghai - - intrinsic_d25g7v0_Shanghai - - intrinsic_d25g9v0_Shanghai - - intrinsic_d25g8v0_Shanghai - - intrinsic_d26g0v0_Shanghai - - intrinsic_d26g10v0_Shanghai - - intrinsic_d26g11v0_Shanghai - - intrinsic_d26g15v0_Shanghai - - intrinsic_d26g12v0_Shanghai - - intrinsic_d26g13v0_Shanghai - - intrinsic_d26g14v0_Shanghai - - intrinsic_d26g16v0_Shanghai - - intrinsic_d26g17v0_Shanghai - - intrinsic_d26g18v0_Shanghai - - intrinsic_d26g19v0_Shanghai - - intrinsic_d26g1v0_Shanghai - - intrinsic_d26g20v0_Shanghai - - intrinsic_d26g21v0_Shanghai - - intrinsic_d26g22v0_Shanghai - - intrinsic_d26g25v0_Shanghai - - intrinsic_d26g24v0_Shanghai - - intrinsic_d26g23v0_Shanghai - - intrinsic_d26g29v0_Shanghai - - intrinsic_d26g26v0_Shanghai - - intrinsic_d26g27v0_Shanghai - - intrinsic_d26g28v0_Shanghai - - intrinsic_d26g34v0_Shanghai - - intrinsic_d26g30v0_Shanghai - - intrinsic_d26g2v0_Shanghai - - intrinsic_d26g31v0_Shanghai - - intrinsic_d26g32v0_Shanghai - - intrinsic_d26g35v0_Shanghai - - intrinsic_d26g33v0_Shanghai - - intrinsic_d26g36v0_Shanghai - - intrinsic_d26g37v0_Shanghai - - intrinsic_d26g38v0_Shanghai - - intrinsic_d26g39v0_Shanghai - - intrinsic_d26g3v0_Shanghai - - intrinsic_d26g44v0_Shanghai - - intrinsic_d26g40v0_Shanghai - - intrinsic_d26g41v0_Shanghai - - intrinsic_d26g43v0_Shanghai - - intrinsic_d26g42v0_Shanghai - - intrinsic_d26g45v0_Shanghai - - intrinsic_d26g46v0_Shanghai - - intrinsic_d26g47v0_Shanghai - - intrinsic_d26g48v0_Shanghai - - intrinsic_d26g49v0_Shanghai - - intrinsic_d26g4v0_Shanghai - - intrinsic_d26g50v0_Shanghai - - intrinsic_d26g51v0_Shanghai - - intrinsic_d26g54v0_Shanghai - - intrinsic_d26g52v0_Shanghai - - intrinsic_d26g53v0_Shanghai - - intrinsic_d26g5v0_Shanghai - - intrinsic_d26g55v0_Shanghai - - intrinsic_d26g56v0_Shanghai - - intrinsic_d26g57v0_Shanghai - - intrinsic_d26g6v0_Shanghai - - intrinsic_d26g8v0_Shanghai - - intrinsic_d26g7v0_Shanghai - - intrinsic_d26g9v0_Shanghai - - intrinsic_d27g0v0_Shanghai - - intrinsic_d27g10v0_Shanghai - - intrinsic_d27g11v0_Shanghai - - intrinsic_d27g12v0_Shanghai - - intrinsic_d27g13v0_Shanghai - - intrinsic_d27g14v0_Shanghai - - intrinsic_d27g15v0_Shanghai - - intrinsic_d27g16v0_Shanghai - - intrinsic_d27g17v0_Shanghai - - intrinsic_d27g18v0_Shanghai - - intrinsic_d27g1v0_Shanghai - - intrinsic_d27g19v0_Shanghai - - intrinsic_d27g20v0_Shanghai - - intrinsic_d27g21v0_Shanghai - - intrinsic_d27g22v0_Shanghai - - intrinsic_d27g23v0_Shanghai - - intrinsic_d27g25v0_Shanghai - - intrinsic_d27g24v0_Shanghai - - intrinsic_d27g29v0_Shanghai - - intrinsic_d27g28v0_Shanghai - - intrinsic_d27g26v0_Shanghai - - intrinsic_d27g27v0_Shanghai - - intrinsic_d27g2v0_Shanghai - - intrinsic_d27g30v0_Shanghai - - intrinsic_d27g31v0_Shanghai - - intrinsic_d27g34v0_Shanghai - - intrinsic_d27g32v0_Shanghai - - intrinsic_d27g33v0_Shanghai - - intrinsic_d27g39v0_Shanghai - - intrinsic_d27g35v0_Shanghai - - intrinsic_d27g36v0_Shanghai - - intrinsic_d27g38v0_Shanghai - - intrinsic_d27g3v0_Shanghai - - intrinsic_d27g37v0_Shanghai - - intrinsic_d27g40v0_Shanghai - - intrinsic_d27g41v0_Shanghai - - intrinsic_d27g42v0_Shanghai - - intrinsic_d27g43v0_Shanghai - - intrinsic_d27g44v0_Shanghai - - intrinsic_d27g45v0_Shanghai - - intrinsic_d27g46v0_Shanghai - - intrinsic_d27g47v0_Shanghai - - intrinsic_d27g48v0_Shanghai - - intrinsic_d27g49v0_Shanghai - - intrinsic_d27g4v0_Shanghai - - intrinsic_d27g54v0_Shanghai - - intrinsic_d27g50v0_Shanghai - - intrinsic_d27g51v0_Shanghai - - intrinsic_d27g52v0_Shanghai - - intrinsic_d27g53v0_Shanghai - - intrinsic_d27g55v0_Shanghai - - intrinsic_d27g5v0_Shanghai - - intrinsic_d27g57v0_Shanghai - - intrinsic_d27g56v0_Shanghai - - intrinsic_d27g6v0_Shanghai - - intrinsic_d27g7v0_Shanghai - - intrinsic_d27g8v0_Shanghai - - intrinsic_d27g9v0_Shanghai - - intrinsic_d28g0v0_Shanghai - - intrinsic_d28g10v0_Shanghai - - intrinsic_d28g11v0_Shanghai - - intrinsic_d28g15v0_Shanghai - - intrinsic_d28g12v0_Shanghai - - intrinsic_d28g14v0_Shanghai - - intrinsic_d28g16v0_Shanghai - - intrinsic_d28g13v0_Shanghai - - intrinsic_d28g17v0_Shanghai - - intrinsic_d28g18v0_Shanghai - - intrinsic_d28g19v0_Shanghai - - intrinsic_d28g20v0_Shanghai - - intrinsic_d28g1v0_Shanghai - - intrinsic_d28g21v0_Shanghai - - intrinsic_d28g22v0_Shanghai - - intrinsic_d28g23v0_Shanghai - - intrinsic_d28g24v0_Shanghai - - intrinsic_d28g25v0_Shanghai - - intrinsic_d28g29v0_Shanghai - - intrinsic_d28g26v0_Shanghai - - intrinsic_d28g27v0_Shanghai - - intrinsic_d28g28v0_Shanghai - - intrinsic_d28g30v0_Shanghai - - intrinsic_d28g2v0_Shanghai - - intrinsic_d28g31v0_Shanghai - - intrinsic_d28g32v0_Shanghai - - intrinsic_d28g34v0_Shanghai - - intrinsic_d28g33v0_Shanghai - - intrinsic_d28g35v0_Shanghai - - intrinsic_d28g36v0_Shanghai - - intrinsic_d28g37v0_Shanghai - - intrinsic_d28g38v0_Shanghai - - intrinsic_d28g39v0_Shanghai - - intrinsic_d28g3v0_Shanghai - - intrinsic_d28g40v0_Shanghai - - intrinsic_d28g44v0_Shanghai - - intrinsic_d28g41v0_Shanghai - - intrinsic_d28g42v0_Shanghai - - intrinsic_d28g43v0_Shanghai - - intrinsic_d28g45v0_Shanghai - - intrinsic_d28g46v0_Shanghai - - intrinsic_d28g49v0_Shanghai - - intrinsic_d28g47v0_Shanghai - - intrinsic_d28g48v0_Shanghai - - intrinsic_d28g4v0_Shanghai - - intrinsic_d28g50v0_Shanghai - - intrinsic_d28g54v0_Shanghai - - intrinsic_d28g51v0_Shanghai - - intrinsic_d28g53v0_Shanghai - - intrinsic_d28g52v0_Shanghai - - intrinsic_d28g55v0_Shanghai - - intrinsic_d28g56v0_Shanghai - - intrinsic_d28g5v0_Shanghai - - intrinsic_d28g57v0_Shanghai - - intrinsic_d28g6v0_Shanghai - - intrinsic_d28g7v0_Shanghai - - intrinsic_d28g8v0_Shanghai - - intrinsic_d28g9v0_Shanghai - - intrinsic_d29g0v0_Shanghai - - intrinsic_d29g10v0_Shanghai - - intrinsic_d29g11v0_Shanghai - - intrinsic_d29g12v0_Shanghai - - intrinsic_d29g13v0_Shanghai - - intrinsic_d29g14v0_Shanghai - - intrinsic_d29g15v0_Shanghai - - intrinsic_d29g16v0_Shanghai - - intrinsic_d29g17v0_Shanghai - - intrinsic_d29g18v0_Shanghai - - intrinsic_d29g19v0_Shanghai - - intrinsic_d29g1v0_Shanghai - - intrinsic_d29g20v0_Shanghai - - intrinsic_d29g21v0_Shanghai - - intrinsic_d29g22v0_Shanghai - - intrinsic_d29g25v0_Shanghai - - intrinsic_d29g23v0_Shanghai - - intrinsic_d29g24v0_Shanghai - - intrinsic_d29g26v0_Shanghai - - intrinsic_d29g27v0_Shanghai - - intrinsic_d29g29v0_Shanghai - - intrinsic_d29g28v0_Shanghai - - intrinsic_d29g2v0_Shanghai - - intrinsic_d29g30v0_Shanghai - - intrinsic_d29g34v0_Shanghai - - intrinsic_d29g31v0_Shanghai - - intrinsic_d29g32v0_Shanghai - - intrinsic_d29g33v0_Shanghai - - intrinsic_d29g35v0_Shanghai - - intrinsic_d29g36v0_Shanghai - - intrinsic_d29g38v0_Shanghai - - intrinsic_d29g37v0_Shanghai - - intrinsic_d29g39v0_Shanghai - - intrinsic_d29g3v0_Shanghai - - intrinsic_d29g40v0_Shanghai - - intrinsic_d29g41v0_Shanghai - - intrinsic_d29g43v0_Shanghai - - intrinsic_d29g42v0_Shanghai - - intrinsic_d2g0v0_Shanghai - - intrinsic_d2g10v0_Shanghai - - intrinsic_d2g11v0_Shanghai - - intrinsic_d2g12v0_Shanghai - - intrinsic_d2g13v0_Shanghai - - intrinsic_d29g44v0_Shanghai - - intrinsic_d2g14v0_Shanghai - - intrinsic_d29g45v0_Shanghai - - intrinsic_d29g46v0_Shanghai - - intrinsic_d29g47v0_Shanghai - - intrinsic_d29g49v0_Shanghai - - intrinsic_d29g48v0_Shanghai - - intrinsic_d29g4v0_Shanghai - - intrinsic_d29g50v0_Shanghai - - intrinsic_d2g15v0_Shanghai - - intrinsic_d29g51v0_Shanghai - - intrinsic_d29g54v0_Shanghai - - intrinsic_d29g52v0_Shanghai - - intrinsic_d29g53v0_Shanghai - - intrinsic_d2g16v0_Shanghai - - intrinsic_d29g55v0_Shanghai - - intrinsic_d2g17v0_Shanghai - - intrinsic_d2g18v0_Shanghai - - intrinsic_d29g5v0_Shanghai - - intrinsic_d29g56v0_Shanghai - - intrinsic_d29g57v0_Shanghai - - intrinsic_d29g6v0_Shanghai - - intrinsic_d2g19v0_Shanghai - - intrinsic_d2g1v0_Shanghai - - intrinsic_d29g7v0_Shanghai - - intrinsic_d2g20v0_Shanghai - - intrinsic_d29g8v0_Shanghai - - intrinsic_d2g21v0_Shanghai - - intrinsic_d29g9v0_Shanghai - - intrinsic_d2g22v0_Shanghai - - intrinsic_d2g25v0_Shanghai - - intrinsic_d2g24v0_Shanghai - - intrinsic_d2g23v0_Shanghai - - intrinsic_d2g26v0_Shanghai - - intrinsic_d2g27v0_Shanghai - - intrinsic_d2g29v0_Shanghai - - intrinsic_d2g28v0_Shanghai - - intrinsic_d2g2v0_Shanghai - - intrinsic_d2g30v0_Shanghai - - intrinsic_d2g31v0_Shanghai - - intrinsic_d2g32v0_Shanghai - - intrinsic_d2g33v0_Shanghai - - intrinsic_d2g34v0_Shanghai - - intrinsic_d2g35v0_Shanghai - - intrinsic_d2g37v0_Shanghai - - intrinsic_d2g36v0_Shanghai - - intrinsic_d2g38v0_Shanghai - - intrinsic_d2g39v0_Shanghai - - intrinsic_d2g3v0_Shanghai - - intrinsic_d2g40v0_Shanghai - - intrinsic_d2g41v0_Shanghai - - intrinsic_d2g42v0_Shanghai - - intrinsic_d2g43v0_Shanghai - - intrinsic_d2g44v0_Shanghai - - intrinsic_d2g46v0_Shanghai - - intrinsic_d2g45v0_Shanghai - - intrinsic_d2g47v0_Shanghai - - intrinsic_d2g49v0_Shanghai - - intrinsic_d2g48v0_Shanghai - - intrinsic_d2g50v0_Shanghai - - intrinsic_d2g4v0_Shanghai - - intrinsic_d2g51v0_Shanghai - - intrinsic_d2g52v0_Shanghai - - intrinsic_d2g53v0_Shanghai - - intrinsic_d2g54v0_Shanghai - - intrinsic_d2g55v0_Shanghai - - intrinsic_d2g56v0_Shanghai - - intrinsic_d2g5v0_Shanghai - - intrinsic_d2g57v0_Shanghai - - intrinsic_d2g6v0_Shanghai - - intrinsic_d2g8v0_Shanghai - - intrinsic_d2g7v0_Shanghai - - intrinsic_d2g9v0_Shanghai - - intrinsic_d3g0v0_Shanghai - - intrinsic_d3g10v0_Shanghai - - intrinsic_d3g11v0_Shanghai - - intrinsic_d3g13v0_Shanghai - - intrinsic_d3g12v0_Shanghai - - intrinsic_d3g14v0_Shanghai - - intrinsic_d3g15v0_Shanghai - - intrinsic_d3g16v0_Shanghai - - intrinsic_d3g17v0_Shanghai - - intrinsic_d3g18v0_Shanghai - - intrinsic_d3g19v0_Shanghai - - intrinsic_d3g1v0_Shanghai - - intrinsic_d3g20v0_Shanghai - - intrinsic_d3g21v0_Shanghai - - intrinsic_d3g22v0_Shanghai - - intrinsic_d3g25v0_Shanghai - - intrinsic_d3g23v0_Shanghai - - intrinsic_d3g24v0_Shanghai - - intrinsic_d3g27v0_Shanghai - - intrinsic_d3g26v0_Shanghai - - intrinsic_d3g29v0_Shanghai - - intrinsic_d3g28v0_Shanghai - - intrinsic_d3g30v0_Shanghai - - intrinsic_d3g2v0_Shanghai - - intrinsic_d3g31v0_Shanghai - - intrinsic_d3g32v0_Shanghai - - intrinsic_d3g33v0_Shanghai - - intrinsic_d3g34v0_Shanghai - - intrinsic_d3g35v0_Shanghai - - intrinsic_d3g36v0_Shanghai - - intrinsic_d3g37v0_Shanghai - - intrinsic_d3g38v0_Shanghai - - intrinsic_d3g39v0_Shanghai - - intrinsic_d3g3v0_Shanghai - - intrinsic_d3g40v0_Shanghai - - intrinsic_d3g41v0_Shanghai - - intrinsic_d3g42v0_Shanghai - - intrinsic_d3g43v0_Shanghai - - intrinsic_d3g44v0_Shanghai - - intrinsic_d3g45v0_Shanghai - - intrinsic_d3g46v0_Shanghai - - intrinsic_d3g47v0_Shanghai - - intrinsic_d3g49v0_Shanghai - - intrinsic_d3g48v0_Shanghai - - intrinsic_d3g4v0_Shanghai - - intrinsic_d3g50v0_Shanghai - - intrinsic_d3g51v0_Shanghai - - intrinsic_d3g52v0_Shanghai - - intrinsic_d3g54v0_Shanghai - - intrinsic_d3g53v0_Shanghai - - intrinsic_d3g55v0_Shanghai - - intrinsic_d3g56v0_Shanghai - - intrinsic_d3g57v0_Shanghai - - intrinsic_d3g5v0_Shanghai - - intrinsic_d3g6v0_Shanghai - - intrinsic_d3g7v0_Shanghai - - intrinsic_d3g8v0_Shanghai - - intrinsic_d3g9v0_Shanghai - - intrinsic_d4g0v0_Shanghai - - intrinsic_d4g10v0_Shanghai - - intrinsic_d4g11v0_Shanghai - - intrinsic_d4g12v0_Shanghai - - intrinsic_d4g13v0_Shanghai - - intrinsic_d4g14v0_Shanghai - - intrinsic_d4g15v0_Shanghai - - intrinsic_d4g16v0_Shanghai - - intrinsic_d4g17v0_Shanghai - - intrinsic_d4g18v0_Shanghai - - intrinsic_d4g19v0_Shanghai - - intrinsic_d4g1v0_Shanghai - - intrinsic_d4g20v0_Shanghai - - intrinsic_d4g21v0_Shanghai - - intrinsic_d4g22v0_Shanghai - - intrinsic_d4g23v0_Shanghai - - intrinsic_d4g25v0_Shanghai - - intrinsic_d4g24v0_Shanghai - - intrinsic_d4g29v0_Shanghai - - intrinsic_d4g26v0_Shanghai - - intrinsic_d4g27v0_Shanghai - - intrinsic_d4g28v0_Shanghai - - intrinsic_d4g2v0_Shanghai - - intrinsic_d4g30v0_Shanghai - - intrinsic_d4g32v0_Shanghai - - intrinsic_d4g31v0_Shanghai - - intrinsic_d4g34v0_Shanghai - - intrinsic_d4g33v0_Shanghai - - intrinsic_d4g35v0_Shanghai - - intrinsic_d4g36v0_Shanghai - - intrinsic_d4g37v0_Shanghai - - intrinsic_d4g38v0_Shanghai - - intrinsic_d5g0v0_Shanghai - - intrinsic_d5g10v0_Shanghai - - intrinsic_d4g39v0_Shanghai - - intrinsic_d5g11v0_Shanghai - - intrinsic_d5g12v0_Shanghai - - intrinsic_d4g3v0_Shanghai - - intrinsic_d5g13v0_Shanghai - - intrinsic_d4g40v0_Shanghai - - intrinsic_d4g41v0_Shanghai - - intrinsic_d5g14v0_Shanghai - - intrinsic_d4g42v0_Shanghai - - intrinsic_d4g43v0_Shanghai - - intrinsic_d5g15v0_Shanghai - - intrinsic_d4g44v0_Shanghai - - intrinsic_d5g16v0_Shanghai - - intrinsic_d4g45v0_Shanghai - - intrinsic_d4g46v0_Shanghai - - intrinsic_d5g17v0_Shanghai - - intrinsic_d5g18v0_Shanghai - - intrinsic_d5g1v0_Shanghai - - intrinsic_d5g19v0_Shanghai - - intrinsic_d5g20v0_Shanghai - - intrinsic_d4g48v0_Shanghai - - intrinsic_d4g47v0_Shanghai - - intrinsic_d4g49v0_Shanghai - - intrinsic_d4g4v0_Shanghai - - intrinsic_d5g21v0_Shanghai - - intrinsic_d4g50v0_Shanghai - - intrinsic_d5g22v0_Shanghai - - intrinsic_d5g23v0_Shanghai - - intrinsic_d5g25v0_Shanghai - - intrinsic_d5g24v0_Shanghai - - intrinsic_d4g51v0_Shanghai - - intrinsic_d4g54v0_Shanghai - - intrinsic_d4g52v0_Shanghai - - intrinsic_d4g53v0_Shanghai - - intrinsic_d4g5v0_Shanghai - - intrinsic_d4g56v0_Shanghai - - intrinsic_d4g55v0_Shanghai - - intrinsic_d4g57v0_Shanghai - - intrinsic_d4g6v0_Shanghai - - intrinsic_d4g7v0_Shanghai - - intrinsic_d4g8v0_Shanghai - - intrinsic_d5g26v0_Shanghai - - intrinsic_d4g9v0_Shanghai - - intrinsic_d5g29v0_Shanghai - - intrinsic_d5g27v0_Shanghai - - intrinsic_d5g28v0_Shanghai - - intrinsic_d5g34v0_Shanghai - - intrinsic_d5g30v0_Shanghai - - intrinsic_d5g2v0_Shanghai - - intrinsic_d5g31v0_Shanghai - - intrinsic_d5g32v0_Shanghai - - intrinsic_d5g33v0_Shanghai - - intrinsic_d5g36v0_Shanghai - - intrinsic_d5g35v0_Shanghai - - intrinsic_d5g37v0_Shanghai - - intrinsic_d5g39v0_Shanghai - - intrinsic_d5g38v0_Shanghai - - intrinsic_d5g3v0_Shanghai - - intrinsic_d5g41v0_Shanghai - - intrinsic_d5g40v0_Shanghai - - intrinsic_d5g42v0_Shanghai - - intrinsic_d5g43v0_Shanghai - - intrinsic_d5g44v0_Shanghai - - intrinsic_d5g45v0_Shanghai - - intrinsic_d5g47v0_Shanghai - - intrinsic_d5g46v0_Shanghai - - intrinsic_d5g48v0_Shanghai - - intrinsic_d5g49v0_Shanghai - - intrinsic_d5g4v0_Shanghai - - intrinsic_d5g50v0_Shanghai - - intrinsic_d5g51v0_Shanghai - - intrinsic_d5g52v0_Shanghai - - intrinsic_d5g53v0_Shanghai - - intrinsic_d5g54v0_Shanghai - - intrinsic_d5g55v0_Shanghai - - intrinsic_d5g57v0_Shanghai - - intrinsic_d5g5v0_Shanghai - - intrinsic_d5g56v0_Shanghai - - intrinsic_d5g6v0_Shanghai - - intrinsic_d5g7v0_Shanghai - - intrinsic_d5g8v0_Shanghai - - intrinsic_d5g9v0_Shanghai - - intrinsic_d6g0v0_Shanghai - - intrinsic_d6g10v0_Shanghai - - intrinsic_d6g11v0_Shanghai - - intrinsic_d6g12v0_Shanghai - - intrinsic_d6g13v0_Shanghai - - intrinsic_d6g15v0_Shanghai - - intrinsic_d6g14v0_Shanghai - - intrinsic_d6g16v0_Shanghai - - intrinsic_d6g17v0_Shanghai - - intrinsic_d6g18v0_Shanghai - - intrinsic_d6g19v0_Shanghai - - intrinsic_d6g20v0_Shanghai - - intrinsic_d6g1v0_Shanghai - - intrinsic_d6g21v0_Shanghai - - intrinsic_d6g22v0_Shanghai - - intrinsic_d6g23v0_Shanghai - - intrinsic_d6g25v0_Shanghai - - intrinsic_d6g24v0_Shanghai - - intrinsic_d6g29v0_Shanghai - - intrinsic_d6g27v0_Shanghai - - intrinsic_d6g26v0_Shanghai - - intrinsic_d6g28v0_Shanghai - - intrinsic_d6g2v0_Shanghai - - intrinsic_d6g30v0_Shanghai - - intrinsic_d6g31v0_Shanghai - - intrinsic_d6g34v0_Shanghai - - intrinsic_d6g32v0_Shanghai - - intrinsic_d6g33v0_Shanghai - - intrinsic_d6g35v0_Shanghai - - intrinsic_d6g36v0_Shanghai - - intrinsic_d6g37v0_Shanghai - - intrinsic_d6g38v0_Shanghai - - intrinsic_d6g39v0_Shanghai - - intrinsic_d6g3v0_Shanghai - - intrinsic_d6g40v0_Shanghai - - intrinsic_d6g41v0_Shanghai - - intrinsic_d6g42v0_Shanghai - - intrinsic_d6g44v0_Shanghai - - intrinsic_d6g43v0_Shanghai - - intrinsic_d6g46v0_Shanghai - - intrinsic_d6g45v0_Shanghai - - intrinsic_d6g47v0_Shanghai - - intrinsic_d6g48v0_Shanghai - - intrinsic_d6g49v0_Shanghai - - intrinsic_d6g4v0_Shanghai - - intrinsic_d6g50v0_Shanghai - - intrinsic_d6g51v0_Shanghai - - intrinsic_d6g54v0_Shanghai - - intrinsic_d6g53v0_Shanghai - - intrinsic_d6g52v0_Shanghai - - intrinsic_d6g55v0_Shanghai - - intrinsic_d6g56v0_Shanghai - - intrinsic_d6g57v0_Shanghai - - intrinsic_d6g5v0_Shanghai - - intrinsic_d6g6v0_Shanghai - - intrinsic_d6g7v0_Shanghai - - intrinsic_d6g8v0_Shanghai - - intrinsic_d6g9v0_Shanghai - - intrinsic_d7g0v0_Shanghai - - intrinsic_d7g10v0_Shanghai - - intrinsic_d7g11v0_Shanghai - - intrinsic_d7g12v0_Shanghai - - intrinsic_d7g13v0_Shanghai - - intrinsic_d7g14v0_Shanghai - - intrinsic_d7g15v0_Shanghai - - intrinsic_d7g16v0_Shanghai - - intrinsic_d7g18v0_Shanghai - - intrinsic_d7g17v0_Shanghai - - intrinsic_d7g19v0_Shanghai - - intrinsic_d7g20v0_Shanghai - - intrinsic_d7g1v0_Shanghai - - intrinsic_d7g21v0_Shanghai - - intrinsic_d7g23v0_Shanghai - - intrinsic_d7g22v0_Shanghai - - intrinsic_d7g24v0_Shanghai - - intrinsic_d7g25v0_Shanghai - - intrinsic_d7g26v0_Shanghai - - intrinsic_d7g29v0_Shanghai - - intrinsic_d7g27v0_Shanghai - - intrinsic_d7g28v0_Shanghai - - intrinsic_d7g2v0_Shanghai - - intrinsic_d7g34v0_Shanghai - - intrinsic_d7g30v0_Shanghai - - intrinsic_d7g31v0_Shanghai - - intrinsic_d7g32v0_Shanghai - - intrinsic_d7g33v0_Shanghai - - intrinsic_d7g35v0_Shanghai - - intrinsic_d7g36v0_Shanghai - - intrinsic_d7g38v0_Shanghai - - intrinsic_d7g37v0_Shanghai - - intrinsic_d7g39v0_Shanghai - - intrinsic_d7g3v0_Shanghai - - intrinsic_d7g40v0_Shanghai - - intrinsic_d7g41v0_Shanghai - - intrinsic_d7g42v0_Shanghai - - intrinsic_d7g43v0_Shanghai - - intrinsic_d7g44v0_Shanghai - - intrinsic_d7g45v0_Shanghai - - intrinsic_d7g46v0_Shanghai - - intrinsic_d7g47v0_Shanghai - - intrinsic_d7g48v0_Shanghai - - intrinsic_d7g49v0_Shanghai - - intrinsic_d7g4v0_Shanghai - - intrinsic_d7g50v0_Shanghai - - intrinsic_d7g51v0_Shanghai - - intrinsic_d7g52v0_Shanghai - - intrinsic_d7g54v0_Shanghai - - intrinsic_d7g53v0_Shanghai - - intrinsic_d7g55v0_Shanghai - - intrinsic_d7g56v0_Shanghai - - intrinsic_d7g5v0_Shanghai - - intrinsic_d7g57v0_Shanghai - - intrinsic_d7g6v0_Shanghai - - intrinsic_d7g7v0_Shanghai - - intrinsic_d7g8v0_Shanghai - - intrinsic_d7g9v0_Shanghai - - intrinsic_d8g0v0_Shanghai - - intrinsic_d8g10v0_Shanghai - - intrinsic_d8g11v0_Shanghai - - intrinsic_d8g12v0_Shanghai - - intrinsic_d8g15v0_Shanghai - - intrinsic_d8g13v0_Shanghai - - intrinsic_d8g14v0_Shanghai - - intrinsic_d8g16v0_Shanghai - - intrinsic_d8g17v0_Shanghai - - intrinsic_d8g18v0_Shanghai - - intrinsic_d8g19v0_Shanghai - - intrinsic_d8g1v0_Shanghai - - intrinsic_d8g20v0_Shanghai - - intrinsic_d8g21v0_Shanghai - - intrinsic_d8g22v0_Shanghai - - intrinsic_d8g25v0_Shanghai - - intrinsic_d8g24v0_Shanghai - - intrinsic_d8g23v0_Shanghai - - intrinsic_d8g29v0_Shanghai - - intrinsic_d8g26v0_Shanghai - - intrinsic_d8g27v0_Shanghai - - intrinsic_d8g28v0_Shanghai - - intrinsic_d8g2v0_Shanghai - - intrinsic_d8g30v0_Shanghai - - intrinsic_d8g32v0_Shanghai - - intrinsic_d8g34v0_Shanghai - - intrinsic_d8g31v0_Shanghai - - intrinsic_d8g33v0_Shanghai - - intrinsic_d8g35v0_Shanghai - - intrinsic_d8g36v0_Shanghai - - intrinsic_d8g37v0_Shanghai - - intrinsic_d8g38v0_Shanghai - - intrinsic_d8g39v0_Shanghai - - intrinsic_d8g3v0_Shanghai - - intrinsic_d8g40v0_Shanghai - - intrinsic_d8g41v0_Shanghai - - intrinsic_d8g42v0_Shanghai - - intrinsic_d8g44v0_Shanghai - - intrinsic_d8g43v0_Shanghai - - intrinsic_d8g45v0_Shanghai - - intrinsic_d8g46v0_Shanghai - - intrinsic_d8g47v0_Shanghai - - intrinsic_d8g48v0_Shanghai - - intrinsic_d8g49v0_Shanghai - - intrinsic_d8g4v0_Shanghai - - intrinsic_d8g50v0_Shanghai - - intrinsic_d8g51v0_Shanghai - - intrinsic_d8g54v0_Shanghai - - intrinsic_d8g52v0_Shanghai - - intrinsic_d8g53v0_Shanghai - - intrinsic_d8g5v0_Shanghai - - intrinsic_d8g57v0_Shanghai - - intrinsic_d8g56v0_Shanghai - - intrinsic_d8g55v0_Shanghai - - intrinsic_d8g6v0_Shanghai - - intrinsic_d8g7v0_Shanghai - - intrinsic_d8g8v0_Shanghai - - intrinsic_d8g9v0_Shanghai - - intrinsic_d9g0v0_Shanghai - - intrinsic_d9g10v0_Shanghai - - intrinsic_d9g11v0_Shanghai - - intrinsic_d9g12v0_Shanghai - - intrinsic_d9g13v0_Shanghai - - intrinsic_d9g14v0_Shanghai - - intrinsic_d9g15v0_Shanghai - - intrinsic_d9g16v0_Shanghai - - intrinsic_d9g17v0_Shanghai - - intrinsic_d9g18v0_Shanghai - - intrinsic_d9g19v0_Shanghai - - intrinsic_d9g20v0_Shanghai - - intrinsic_d9g1v0_Shanghai - - intrinsic_d9g21v0_Shanghai - - intrinsic_d9g22v0_Shanghai - - intrinsic_d9g23v0_Shanghai - - intrinsic_d9g24v0_Shanghai - - intrinsic_d9g25v0_Shanghai - - intrinsic_d9g26v0_Shanghai - - intrinsic_d9g29v0_Shanghai - - intrinsic_d9g27v0_Shanghai - - intrinsic_d9g28v0_Shanghai - - intrinsic_d9g30v0_Shanghai - - intrinsic_d9g2v0_Shanghai - - intrinsic_d9g34v0_Shanghai - - intrinsic_d9g31v0_Shanghai - - intrinsic_d9g32v0_Shanghai - - intrinsic_d9g33v0_Shanghai - - intrinsic_d9g35v0_Shanghai - - intrinsic_d9g37v0_Shanghai - - intrinsic_d9g36v0_Shanghai - - intrinsic_d9g38v0_Shanghai - - intrinsic_d9g39v0_Shanghai - - lowGasLimit_d0g0v0_Shanghai - - lowFeeCap_d0g0v0_Shanghai - - intrinsic_d9g3v0_Shanghai - - intrinsic_d9g40v0_Shanghai - - lowGasLimit_d0g3v0_Shanghai - - lowGasLimit_d0g1v0_Shanghai - - intrinsic_d9g41v0_Shanghai - - intrinsic_d9g42v0_Shanghai - - lowGasPriceOldTypes_d0g0v0_Shanghai - - lowGasLimit_d0g2v0_Shanghai - - intrinsic_d9g43v0_Shanghai - - intrinsic_d9g44v0_Shanghai - - intrinsic_d9g45v0_Shanghai - - lowGasPriceOldTypes_d1g0v0_Shanghai - - intrinsic_d9g46v0_Shanghai - - intrinsic_d9g49v0_Shanghai - - intrinsic_d9g48v0_Shanghai - - intrinsic_d9g47v0_Shanghai - - outOfFundsOldTypes_d0g0v0_Shanghai - - intrinsic_d9g4v0_Shanghai - - outOfFundsOldTypes_d0g1v0_Shanghai - - outOfFundsOldTypes_d1g1v0_Shanghai - - outOfFundsOldTypes_d0g0v1_Shanghai - - outOfFundsOldTypes_d1g0v0_Shanghai - - intrinsic_d9g50v0_Shanghai - - intrinsic_d9g52v0_Shanghai - - intrinsic_d9g51v0_Shanghai - - outOfFundsOldTypes_d0g1v1_Shanghai - - intrinsic_d9g53v0_Shanghai - - outOfFundsOldTypes_d1g0v1_Shanghai - - outOfFunds_d0g1v0_Shanghai - - outOfFundsOldTypes_d1g1v1_Shanghai - - outOfFunds_d0g0v0_Shanghai - - intrinsic_d9g54v0_Shanghai - - outOfFunds_d0g0v1_Shanghai - - intrinsic_d9g55v0_Shanghai - - intrinsic_d9g56v0_Shanghai - - senderBalance_d0g0v0_Shanghai - - intrinsic_d9g5v0_Shanghai - - intrinsic_d9g57v0_Shanghai - - intrinsic_d9g6v0_Shanghai - - intrinsic_d9g7v0_Shanghai - - intrinsic_d9g8v0_Shanghai - - tipTooHigh_d0g0v0_Shanghai - - outOfFunds_d0g1v1_Shanghai - - intrinsic_d9g9v0_Shanghai - - transactionIntinsicBug_d0g0v0_Shanghai - - typeTwoBerlin_d0g0v0_Shanghai - - valCausesOOF_d0g0v1_Shanghai - - valCausesOOF_d0g2v0_Shanghai - - valCausesOOF_d0g2v1_Shanghai - - valCausesOOF_d1g0v1_Shanghai - - valCausesOOF_d0g0v0_Shanghai - - valCausesOOF_d0g1v0_Shanghai - - valCausesOOF_d0g1v1_Shanghai - - valCausesOOF_d1g2v1_Shanghai - - valCausesOOF_d1g2v0_Shanghai - - valCausesOOF_d1g0v0_Shanghai - - valCausesOOF_d1g1v0_Shanghai - - valCausesOOF_d1g1v1_Shanghai - stEIP158Specific: - - CALL_OneVCallSuicide_d0g0v0_Shanghai - - CALL_ZeroVCallSuicide_d0g0v0_Shanghai - - EXP_Empty_d0g0v0_Shanghai - - vitalikTransactionTest_d0g0v0_Shanghai - stEIP2930: - - addressOpcodes_d11g0v0_Shanghai - - addressOpcodes_d14g0v0_Shanghai - - addressOpcodes_d19g0v0_Shanghai - - addressOpcodes_d17g0v0_Shanghai - - addressOpcodes_d21g0v0_Shanghai - - addressOpcodes_d13g0v0_Shanghai - - addressOpcodes_d23g0v0_Shanghai - - addressOpcodes_d29g0v0_Shanghai - - addressOpcodes_d26g0v0_Shanghai - - addressOpcodes_d2g0v0_Shanghai - - addressOpcodes_d1g0v0_Shanghai - - addressOpcodes_d35g0v0_Shanghai - - addressOpcodes_d31g0v0_Shanghai - - addressOpcodes_d25g0v0_Shanghai - - addressOpcodes_d10g0v0_Shanghai - - addressOpcodes_d0g0v0_Shanghai - - addressOpcodes_d12g0v0_Shanghai - - addressOpcodes_d18g0v0_Shanghai - - addressOpcodes_d15g0v0_Shanghai - - addressOpcodes_d16g0v0_Shanghai - - addressOpcodes_d20g0v0_Shanghai - - addressOpcodes_d22g0v0_Shanghai - - addressOpcodes_d24g0v0_Shanghai - - addressOpcodes_d28g0v0_Shanghai - - addressOpcodes_d33g0v0_Shanghai - - addressOpcodes_d27g0v0_Shanghai - - addressOpcodes_d30g0v0_Shanghai - - addressOpcodes_d34g0v0_Shanghai - - coinbaseT01_d0g0v0_Shanghai - - addressOpcodes_d36g0v0_Shanghai - - coinbaseT01_d2g0v0_Shanghai - - coinbaseT01_d1g0v0_Shanghai - - coinbaseT2_d0g0v0_Shanghai - - coinbaseT2_d1g0v0_Shanghai - - addressOpcodes_d32g0v0_Shanghai - - manualCreate_d2g0v0_Shanghai - - storageCosts_d0g0v0_Shanghai - - addressOpcodes_d37g0v0_Shanghai - - storageCosts_d10g0v0_Shanghai - - storageCosts_d11g0v0_Shanghai - - addressOpcodes_d38g0v0_Shanghai - - storageCosts_d18g0v0_Shanghai - - storageCosts_d12g0v0_Shanghai - - storageCosts_d19g0v0_Shanghai - - storageCosts_d13g0v0_Shanghai - - storageCosts_d14g0v0_Shanghai - - storageCosts_d20g0v0_Shanghai - - storageCosts_d21g0v0_Shanghai - - storageCosts_d15g0v0_Shanghai - - storageCosts_d16g0v0_Shanghai - - storageCosts_d17g0v0_Shanghai - - storageCosts_d1g0v0_Shanghai - - storageCosts_d23g0v0_Shanghai - - storageCosts_d22g0v0_Shanghai - - storageCosts_d24g0v0_Shanghai - - storageCosts_d26g0v0_Shanghai - - storageCosts_d25g0v0_Shanghai - - storageCosts_d27g0v0_Shanghai - - storageCosts_d28g0v0_Shanghai - - storageCosts_d29g0v0_Shanghai - - storageCosts_d2g0v0_Shanghai - - storageCosts_d30g0v0_Shanghai - - storageCosts_d31g0v0_Shanghai - - storageCosts_d3g0v0_Shanghai - - storageCosts_d4g0v0_Shanghai - - storageCosts_d5g0v0_Shanghai - - addressOpcodes_d41g0v0_Shanghai - - addressOpcodes_d5g0v0_Shanghai - - addressOpcodes_d43g0v0_Shanghai - - addressOpcodes_d7g0v0_Shanghai - - storageCosts_d32g0v0_Shanghai - - addressOpcodes_d45g0v0_Shanghai - - addressOpcodes_d47g0v0_Shanghai - - storageCosts_d34g0v0_Shanghai - - storageCosts_d33g0v0_Shanghai - - addressOpcodes_d9g0v0_Shanghai - - storageCosts_d6g0v0_Shanghai - - addressOpcodes_d3g0v0_Shanghai - - storageCosts_d7g0v0_Shanghai - - storageCosts_d9g0v0_Shanghai - - storageCosts_d8g0v0_Shanghai - - addressOpcodes_d39g0v0_Shanghai - - addressOpcodes_d4g0v0_Shanghai - - addressOpcodes_d40g0v0_Shanghai - - addressOpcodes_d42g0v0_Shanghai - - addressOpcodes_d44g0v0_Shanghai - - addressOpcodes_d6g0v0_Shanghai - - addressOpcodes_d46g0v0_Shanghai - - storageCosts_d35g0v0_Shanghai - - addressOpcodes_d8g0v0_Shanghai - - variedContext_d11g0v0_Shanghai - - variedContext_d10g0v0_Shanghai - - variedContext_d16g0v0_Shanghai - - variedContext_d13g0v0_Shanghai - - variedContext_d12g0v0_Shanghai - - variedContext_d18g0v0_Shanghai - - variedContext_d14g0v0_Shanghai - - variedContext_d15g0v0_Shanghai - - variedContext_d0g0v0_Shanghai - - variedContext_d1g0v0_Shanghai - - variedContext_d34g0v0_Shanghai - - variedContext_d2g0v0_Shanghai - - variedContext_d22g0v0_Shanghai - - variedContext_d3g0v0_Shanghai - - variedContext_d4g0v0_Shanghai - - variedContext_d26g0v0_Shanghai - - variedContext_d6g0v0_Shanghai - - variedContext_d7g0v0_Shanghai - - variedContext_d8g0v0_Shanghai - - variedContext_d5g0v0_Shanghai - - variedContext_d9g0v0_Shanghai - - variedContext_d30g0v0_Shanghai - - variedContext_d24g0v0_Shanghai - - variedContext_d28g0v0_Shanghai - - variedContext_d32g0v0_Shanghai - - variedContext_d21g0v0_Shanghai - - variedContext_d20g0v0_Shanghai - stExample: - - invalidTr_d0g0v0_Shanghai - - eip1559_d0g0v0_Shanghai - - basefeeExample_d0g0v0_Shanghai - - mergeTest_d0g0v0_Shanghai - - solidityExample_d0g0v0_Shanghai + - baseFeeDiffPlaces_d34g0v0_Cancun + - gasPriceDiffPlaces_d34g0v0_Cancun stExtCodeHash: - - extCodeCopyBounds_d0g0v0_Shanghai - - extCodeHashDynamicArgument_d1g0v0_Shanghai - - extCodeHashInInitCode_d1g0v0_Shanghai - - dynamicAccountOverwriteEmpty_d0g0v0_Shanghai - - extCodeHashSubcallSuicide_d0g0v0_Shanghai - - extcodehashEmpty_d0g0v0_Shanghai - - extcodehashEmpty_d2g0v0_Shanghai - - extcodehashEmpty_d1g0v0_Shanghai - - extcodehashEmpty_d3g0v0_Shanghai - - extcodehashEmpty_d4g0v0_Shanghai - - extcodehashEmpty_d5g0v0_Shanghai - - extcodehashEmpty_d6g0v0_Shanghai - - extcodehashEmpty_d7g0v0_Shanghai - - extcodehashEmpty_d8g0v0_Shanghai - - extCodeHashSubcallOOG_d4g0v0_Shanghai - - extcodehashEmpty_d9g0v0_Shanghai - - extCodeHashMaxCodeSize_d0g0v0_Shanghai - stInitCodeTest: - - CallContractToCreateContractWhichWouldCreateContractInInitCode_d0g0v0_Shanghai - - OutOfGasPrefundedContractCreation_d0g0v0_Shanghai - - OutOfGasPrefundedContractCreation_d0g2v0_Shanghai - - CallRecursiveContract_d0g0v0_Shanghai - stMemExpandingEIP150Calls: - - CreateAndGasInsideCreateWithMemExpandingCalls_d0g0v0_Shanghai - - CallGoesOOGOnSecondLevelWithMemExpandingCalls_d0g0v0_Shanghai - - NewGasPriceForCodesWithMemExpandingCalls_d0g0v0_Shanghai - stMemoryStressTest: - - RETURN_Bounds_d0g1v0_Shanghai - - RETURN_Bounds_d0g2v0_Shanghai - - DUP_Bounds_d0g0v0_Shanghai - - DUP_Bounds_d0g1v0_Shanghai - - DUP_Bounds_d0g2v0_Shanghai + - extCodeHashDynamicArgument_d1g0v0_Cancun stMemoryTest: - - bufferSrcOffset_d10g0v0_Shanghai - - bufferSrcOffset_d12g0v0_Shanghai - - bufferSrcOffset_d18g0v0_Shanghai - - bufferSrcOffset_d16g0v0_Shanghai - - bufferSrcOffset_d17g0v0_Shanghai - - bufferSrcOffset_d13g0v0_Shanghai - - bufferSrcOffset_d14g0v0_Shanghai - - bufferSrcOffset_d19g0v0_Shanghai - - bufferSrcOffset_d20g0v0_Shanghai - - bufferSrcOffset_d21g0v0_Shanghai - - bufferSrcOffset_d22g0v0_Shanghai - - bufferSrcOffset_d23g0v0_Shanghai - - bufferSrcOffset_d36g0v0_Shanghai - - bufferSrcOffset_d37g0v0_Shanghai - - bufferSrcOffset_d38g0v0_Shanghai - - bufferSrcOffset_d43g0v0_Shanghai - - bufferSrcOffset_d45g0v0_Shanghai - - bufferSrcOffset_d44g0v0_Shanghai - - bufferSrcOffset_d46g0v0_Shanghai - - bufferSrcOffset_d47g0v0_Shanghai - - bufferSrcOffset_d60g0v0_Shanghai - - bufferSrcOffset_d61g0v0_Shanghai - - bufferSrcOffset_d62g0v0_Shanghai - - bufferSrcOffset_d67g0v0_Shanghai - - bufferSrcOffset_d68g0v0_Shanghai - - bufferSrcOffset_d70g0v0_Shanghai - - bufferSrcOffset_d69g0v0_Shanghai - - bufferSrcOffset_d71g0v0_Shanghai - - bufferSrcOffset_d8g0v0_Shanghai - - bufferSrcOffset_d9g0v0_Shanghai - - buffer_d0g0v0_Shanghai - - buffer_d108g0v0_Shanghai - - buffer_d109g0v0_Shanghai - - buffer_d111g0v0_Shanghai - - buffer_d112g0v0_Shanghai - - buffer_d123g0v0_Shanghai - - buffer_d124g0v0_Shanghai - - buffer_d126g0v0_Shanghai - - buffer_d127g0v0_Shanghai - - buffer_d138g0v0_Shanghai - - buffer_d139g0v0_Shanghai - - buffer_d142g0v0_Shanghai - - buffer_d141g0v0_Shanghai - - buffer_d153g0v0_Shanghai - - buffer_d154g0v0_Shanghai - - buffer_d156g0v0_Shanghai - - buffer_d157g0v0_Shanghai - - buffer_d168g0v0_Shanghai - - buffer_d169g0v0_Shanghai - - buffer_d16g0v0_Shanghai - - buffer_d171g0v0_Shanghai - - buffer_d172g0v0_Shanghai - - buffer_d17g0v0_Shanghai - - buffer_d183g0v0_Shanghai - - buffer_d184g0v0_Shanghai - - buffer_d186g0v0_Shanghai - - buffer_d187g0v0_Shanghai - - buffer_d198g0v0_Shanghai - - buffer_d1g0v0_Shanghai - - buffer_d199g0v0_Shanghai - - buffer_d19g0v0_Shanghai - - buffer_d202g0v0_Shanghai - - buffer_d201g0v0_Shanghai - - buffer_d20g0v0_Shanghai - - buffer_d213g0v0_Shanghai - - buffer_d214g0v0_Shanghai - - buffer_d216g0v0_Shanghai - - buffer_d217g0v0_Shanghai - - buffer_d228g0v0_Shanghai - - buffer_d229g0v0_Shanghai - - buffer_d231g0v0_Shanghai - - buffer_d232g0v0_Shanghai - - buffer_d243g0v0_Shanghai - - buffer_d244g0v0_Shanghai - - buffer_d246g0v0_Shanghai - - buffer_d247g0v0_Shanghai - - buffer_d258g0v0_Shanghai - - buffer_d259g0v0_Shanghai - - buffer_d261g0v0_Shanghai - - buffer_d262g0v0_Shanghai - - buffer_d273g0v0_Shanghai - - buffer_d274g0v0_Shanghai - - buffer_d276g0v0_Shanghai - - buffer_d277g0v0_Shanghai - - buffer_d288g0v0_Shanghai - - buffer_d289g0v0_Shanghai - - buffer_d291g0v0_Shanghai - - buffer_d292g0v0_Shanghai - - buffer_d303g0v0_Shanghai - - buffer_d304g0v0_Shanghai - - buffer_d306g0v0_Shanghai - - buffer_d307g0v0_Shanghai - - buffer_d318g0v0_Shanghai - - buffer_d319g0v0_Shanghai - - buffer_d31g0v0_Shanghai - - buffer_d320g0v0_Shanghai - - buffer_d321g0v0_Shanghai - - buffer_d322g0v0_Shanghai - - buffer_d323g0v0_Shanghai - - buffer_d324g0v0_Shanghai - - buffer_d325g0v0_Shanghai - - buffer_d326g0v0_Shanghai - - buffer_d327g0v0_Shanghai - - buffer_d328g0v0_Shanghai - - buffer_d329g0v0_Shanghai - - buffer_d32g0v0_Shanghai - - buffer_d330g0v0_Shanghai - - buffer_d331g0v0_Shanghai - - buffer_d332g0v0_Shanghai - - buffer_d333g0v0_Shanghai - - buffer_d334g0v0_Shanghai - - buffer_d335g0v0_Shanghai - - buffer_d336g0v0_Shanghai - - buffer_d337g0v0_Shanghai - - buffer_d338g0v0_Shanghai - - buffer_d339g0v0_Shanghai - - buffer_d340g0v0_Shanghai - - buffer_d341g0v0_Shanghai - - buffer_d342g0v0_Shanghai - - buffer_d343g0v0_Shanghai - - buffer_d344g0v0_Shanghai - - buffer_d345g0v0_Shanghai - - buffer_d346g0v0_Shanghai - - buffer_d347g0v0_Shanghai - - buffer_d35g0v0_Shanghai - - buffer_d34g0v0_Shanghai - - buffer_d3g0v0_Shanghai - - buffer_d46g0v0_Shanghai - - buffer_d47g0v0_Shanghai - - buffer_d4g0v0_Shanghai - - buffer_d49g0v0_Shanghai - - buffer_d50g0v0_Shanghai - - buffer_d62g0v0_Shanghai - - buffer_d65g0v0_Shanghai - - buffer_d6g0v0_Shanghai - - callDataCopyOffset_d0g0v0_Shanghai - - codecopy_dejavu2_d0g0v0_Shanghai - - oog_d0g0v0_Shanghai - - buffer_d76g0v0_Shanghai - - memCopySelf_d0g0v0_Shanghai - - buffer_d77g0v0_Shanghai - - buffer_d79g0v0_Shanghai - - oog_d30g0v0_Shanghai - - buffer_d80g0v0_Shanghai - - oog_d9g0v0_Shanghai - - buffer_d93g0v0_Shanghai - - buffer_d94g0v0_Shanghai - - buffer_d96g0v0_Shanghai - - buffer_d97g0v0_Shanghai - - stackLimitGas_1023_d0g0v0_Shanghai - - stackLimitGas_1024_d0g0v0_Shanghai - - stackLimitPush31_1024_d0g0v0_Shanghai - - stackLimitPush31_1023_d0g0v0_Shanghai - - stackLimitPush32_1023_d0g0v0_Shanghai - - stackLimitPush32_1024_d0g0v0_Shanghai - stNonZeroCallsTest: - - NonZeroValue_CALL_ToNonNonZeroBalance_d0g0v0_Shanghai + - stackLimitGas_1023_d0g0v0_Cancun + - stackLimitGas_1024_d0g0v0_Cancun + - stackLimitGas_1025_d0g0v0_Cancun + - stackLimitPush31_1023_d0g0v0_Cancun + - stackLimitPush31_1024_d0g0v0_Cancun + - stackLimitPush31_1025_d0g0v0_Cancun + - stackLimitPush32_1023_d0g0v0_Cancun + - stackLimitPush32_1024_d0g0v0_Cancun + - stackLimitPush32_1025_d0g0v0_Cancun stPreCompiledContracts2: - - CALLBlake2f_d4g0v0_Shanghai - - CALLBlake2f_d4g1v0_Shanghai - - CALLBlake2f_d4g2v0_Shanghai - - CALLBlake2f_d5g0v0_Shanghai - - CALLBlake2f_d4g3v0_Shanghai - - CALLBlake2f_d5g2v0_Shanghai - - CALLBlake2f_d5g1v0_Shanghai - - CALLBlake2f_d6g1v0_Shanghai - - CALLBlake2f_d5g3v0_Shanghai - - CALLBlake2f_d6g0v0_Shanghai - - CALLBlake2f_d6g2v0_Shanghai - - CALLBlake2f_d6g3v0_Shanghai - - CALLBlake2f_d7g0v0_Shanghai - - CALLBlake2f_d7g1v0_Shanghai - - CALLBlake2f_d7g2v0_Shanghai - - CALLBlake2f_d7g3v0_Shanghai - - CALLBlake2f_d8g0v0_Shanghai - - CALLBlake2f_d8g2v0_Shanghai - - CALLBlake2f_d8g1v0_Shanghai - - CALLBlake2f_d8g3v0_Shanghai - - CALLBlake2f_d9g0v0_Shanghai - - CALLCODEBlake2f_d4g0v0_Shanghai - - CALLCODEBlake2f_d4g1v0_Shanghai - - CALLCODEBlake2f_d4g2v0_Shanghai - - CALLCODEBlake2f_d4g3v0_Shanghai - - CALLCODEBlake2f_d5g0v0_Shanghai - - CALLCODEBlake2f_d5g1v0_Shanghai - - CALLCODEBlake2f_d5g2v0_Shanghai - - CALLCODEBlake2f_d5g3v0_Shanghai - - CALLCODEBlake2f_d6g0v0_Shanghai - - CALLCODEBlake2f_d6g1v0_Shanghai - - CALLCODEBlake2f_d6g2v0_Shanghai - - CALLCODEBlake2f_d6g3v0_Shanghai - - CALLCODEBlake2f_d7g0v0_Shanghai - - CALLCODEBlake2f_d7g1v0_Shanghai - - CALLCODEBlake2f_d7g3v0_Shanghai - - CALLCODEBlake2f_d7g2v0_Shanghai - - CALLCODEBlake2f_d8g0v0_Shanghai - - CALLCODEBlake2f_d8g1v0_Shanghai - - CALLCODEBlake2f_d8g3v0_Shanghai - - CALLCODEBlake2f_d8g2v0_Shanghai - - CALLCODEBlake2f_d9g0v0_Shanghai - - CALLCODEEcrecover0_completeReturnValue_d0g0v0_Shanghai - - CALLCODEEcrecover0_NoGas_d0g0v0_Shanghai - - CALLCODEEcrecover0_d0g0v0_Shanghai - - CALLCODEEcrecover0_gas3000_d0g0v0_Shanghai - - CALLCODEEcrecover0_overlappingInputOutput_d0g0v0_Shanghai - - CALLCODEEcrecover3_d0g0v0_Shanghai - - CALLCODEEcrecoverH_prefixed0_d0g0v0_Shanghai - - CALLCODEEcrecoverS_prefixed0_d0g0v0_Shanghai - - CALLCODEEcrecoverV_prefixed0_d0g0v0_Shanghai - - CALLCODERipemd160_1_d0g0v0_Shanghai - - CALLCODERipemd160_2_d0g0v0_Shanghai - - CALLCODERipemd160_3_postfixed0_d0g0v0_Shanghai - - CALLCODERipemd160_3_d0g0v0_Shanghai - - CALLCODERipemd160_3_prefixed0_d0g0v0_Shanghai - - CALLCODESha256_0_d0g0v0_Shanghai - - CALLCODESha256_1_d0g0v0_Shanghai - - CALLCODERipemd160_4_d0g0v0_Shanghai - - CALLCODESha256_1_nonzeroValue_d0g0v0_Shanghai - - CALLCODESha256_2_d0g0v0_Shanghai - - CALLCODESha256_3_d0g0v0_Shanghai - - CALLCODESha256_3_postfix0_d0g0v0_Shanghai - - CALLCODESha256_3_prefix0_d0g0v0_Shanghai - - CALLCODESha256_4_d0g0v0_Shanghai - - CALLCODESha256_4_gas99_d0g0v0_Shanghai - - CallEcrecover0_0input_d0g0v0_Shanghai - - CallEcrecover0_completeReturnValue_d0g0v0_Shanghai - - CallEcrecover0_Gas2999_d0g0v0_Shanghai - - CallEcrecover0_d0g0v0_Shanghai - - CallEcrecover0_NoGas_d0g0v0_Shanghai - - CallEcrecover0_gas3000_d0g0v0_Shanghai - - CallEcrecover0_overlappingInputOutput_d0g0v0_Shanghai - - CallEcrecover1_d0g0v0_Shanghai - - CallEcrecoverInvalidSignature_d0g0v0_Shanghai - - CallEcrecover2_d0g0v0_Shanghai - - CallEcrecover80_d0g0v0_Shanghai - - CallEcrecover3_d0g0v0_Shanghai - - CallEcrecoverH_prefixed0_d0g0v0_Shanghai - - CallEcrecoverCheckLengthWrongV_d0g0v0_Shanghai - - CallEcrecoverCheckLength_d0g0v0_Shanghai - - CallEcrecoverR_prefixed0_d0g0v0_Shanghai - - CallEcrecoverS_prefixed0_d0g0v0_Shanghai - - CallEcrecoverUnrecoverableKey_d0g0v0_Shanghai - - CallEcrecoverV_prefixed0_d0g0v0_Shanghai - - CallEcrecover_Overflow_d0g0v0_Shanghai - - CallEcrecover_Overflow_d1g0v0_Shanghai - - CallIdentitiy_1_d0g0v0_Shanghai - - CallIdentitiy_0_d0g0v0_Shanghai - - CallIdentity_1_nonzeroValue_d0g0v0_Shanghai - - CallIdentity_2_d0g0v0_Shanghai - - CallIdentity_3_d0g0v0_Shanghai - - CallIdentity_4_d0g0v0_Shanghai - - CallEcrecover_Overflow_d2g0v0_Shanghai - - CallIdentity_4_gas18_d0g0v0_Shanghai - - CallIdentity_4_gas17_d0g0v0_Shanghai - - CallEcrecover_Overflow_d3g0v0_Shanghai - - CallEcrecover_Overflow_d4g0v0_Shanghai - - CallRipemd160_0_d0g0v0_Shanghai - - CallEcrecover_Overflow_d5g0v0_Shanghai - - CallIdentity_6_inputShorterThanOutput_d0g0v0_Shanghai - - CallRipemd160_1_d0g0v0_Shanghai - - CallEcrecover_Overflow_d6g0v0_Shanghai - - CallEcrecover_Overflow_d7g0v0_Shanghai - - CallRipemd160_2_d0g0v0_Shanghai - - CallRipemd160_3_d0g0v0_Shanghai - - CallRipemd160_3_postfixed0_d0g0v0_Shanghai - - CallRipemd160_3_prefixed0_d0g0v0_Shanghai - - CallRipemd160_4_d0g0v0_Shanghai - - CallRipemd160_4_gas719_d0g0v0_Shanghai - - CallSha256_1_d0g0v0_Shanghai - - CallSha256_0_d0g0v0_Shanghai - - CallSha256_1_nonzeroValue_d0g0v0_Shanghai - - CallSha256_2_d0g0v0_Shanghai - - CallSha256_3_d0g0v0_Shanghai - - CallSha256_3_postfix0_d0g0v0_Shanghai - - CallSha256_3_prefix0_d0g0v0_Shanghai - - CallSha256_4_d0g0v0_Shanghai - - CallSha256_4_gas99_d0g0v0_Shanghai - - ecrecoverWeirdV_d0g0v0_Shanghai - - ecrecoverWeirdV_d10g0v0_Shanghai - - ecrecoverWeirdV_d11g0v0_Shanghai - - ecrecoverWeirdV_d12g0v0_Shanghai - - ecrecoverWeirdV_d13g0v0_Shanghai - - ecrecoverWeirdV_d14g0v0_Shanghai - - ecrecoverWeirdV_d15g0v0_Shanghai - - ecrecoverWeirdV_d18g0v0_Shanghai - - ecrecoverWeirdV_d16g0v0_Shanghai - - ecrecoverWeirdV_d17g0v0_Shanghai - - ecrecoverWeirdV_d19g0v0_Shanghai - - ecrecoverWeirdV_d1g0v0_Shanghai - - ecrecoverWeirdV_d20g0v0_Shanghai - - ecrecoverWeirdV_d21g0v0_Shanghai - - ecrecoverWeirdV_d22g0v0_Shanghai - - ecrecoverWeirdV_d23g0v0_Shanghai - - ecrecoverWeirdV_d24g0v0_Shanghai - - ecrecoverWeirdV_d25g0v0_Shanghai - - ecrecoverWeirdV_d26g0v0_Shanghai - - ecrecoverWeirdV_d28g0v0_Shanghai - - ecrecoverWeirdV_d27g0v0_Shanghai - - ecrecoverWeirdV_d2g0v0_Shanghai - - ecrecoverWeirdV_d29g0v0_Shanghai - - ecrecoverWeirdV_d30g0v0_Shanghai - - ecrecoverWeirdV_d32g0v0_Shanghai - - ecrecoverWeirdV_d31g0v0_Shanghai - - ecrecoverWeirdV_d33g0v0_Shanghai - - ecrecoverWeirdV_d35g0v0_Shanghai - - ecrecoverWeirdV_d34g0v0_Shanghai - - ecrecoverWeirdV_d3g0v0_Shanghai - - ecrecoverWeirdV_d4g0v0_Shanghai - - ecrecoverWeirdV_d5g0v0_Shanghai - - ecrecoverWeirdV_d6g0v0_Shanghai - - ecrecoverWeirdV_d8g0v0_Shanghai - - ecrecoverWeirdV_d7g0v0_Shanghai - - ecrecoverWeirdV_d9g0v0_Shanghai - - modexp_0_0_0_20500_d0g1v0_Shanghai - - modexp_0_0_0_20500_d0g2v0_Shanghai - - modexp_0_0_0_20500_d0g3v0_Shanghai - - modexp_0_0_0_22000_d0g0v0_Shanghai - - modexp_0_0_0_22000_d0g2v0_Shanghai - - modexp_0_0_0_22000_d0g1v0_Shanghai - - modexp_0_0_0_25000_d0g3v0_Shanghai - - modexp_0_0_0_22000_d0g3v0_Shanghai - - modexp_0_0_0_25000_d0g0v0_Shanghai - - modexp_0_0_0_25000_d0g1v0_Shanghai - - modexp_0_0_0_25000_d0g2v0_Shanghai - - modexp_0_0_0_35000_d0g0v0_Shanghai - - modexp_0_0_0_35000_d0g1v0_Shanghai - - modexp_0_0_0_35000_d0g3v0_Shanghai - - modexp_0_0_0_35000_d0g2v0_Shanghai - - CALLCODEIdentity_5_d0g0v0_Shanghai - - CALLCODERipemd160_5_d0g0v0_Shanghai - - CALLCODESha256_5_d0g0v0_Shanghai - - CallIdentity_5_d0g0v0_Shanghai - - CallRipemd160_5_d0g0v0_Shanghai - - CallSha256_5_d0g0v0_Shanghai - - ecrecoverShortBuff_d0g0v0_Shanghai + - CALLCODERipemd160_0_d0g0v0_Cancun + - CALLCODERipemd160_1_d0g0v0_Cancun + - CALLCODERipemd160_2_d0g0v0_Cancun + - CALLCODERipemd160_3_d0g0v0_Cancun + - CALLCODERipemd160_3_postfixed0_d0g0v0_Cancun + - CALLCODERipemd160_3_prefixed0_d0g0v0_Cancun + - CALLCODERipemd160_4_d0g0v0_Cancun + - CALLCODERipemd160_4_gas719_d0g0v0_Cancun + - CallRipemd160_0_d0g0v0_Cancun + - CallRipemd160_1_d0g0v0_Cancun + - CallRipemd160_2_d0g0v0_Cancun + - CallRipemd160_3_d0g0v0_Cancun + - CallRipemd160_3_postfixed0_d0g0v0_Cancun + - CallRipemd160_3_prefixed0_d0g0v0_Cancun + - CallRipemd160_4_d0g0v0_Cancun + - CallRipemd160_4_gas719_d0g0v0_Cancun + - ecrecoverShortBuff_d0g0v0_Cancun + - modexpRandomInput_d2g0v0_Cancun + - modexpRandomInput_d2g1v0_Cancun stPreCompiledContracts: - - blake2B_d0g0v0_Shanghai - - blake2B_d1g0v0_Shanghai - - blake2B_d2g0v0_Shanghai - - delegatecall09Undefined_d0g0v0_Shanghai - - blake2B_d3g0v0_Shanghai - - blake2B_d4g0v0_Shanghai - - blake2B_d5g0v0_Shanghai - - idPrecomps_d0g0v0_Shanghai - - blake2B_d6g0v0_Shanghai - - blake2B_d10g0v0_Shanghai - - blake2B_d11g0v0_Shanghai - - blake2B_d7g0v0_Shanghai - - blake2B_d8g0v0_Shanghai - - blake2B_d12g0v0_Shanghai - - blake2B_d13g0v0_Shanghai - - blake2B_d14g0v0_Shanghai - - blake2B_d15g0v0_Shanghai - - blake2B_d9g0v0_Shanghai - - idPrecomps_d1g0v0_Shanghai - - blake2B_d17g0v0_Shanghai - - blake2B_d18g0v0_Shanghai - - blake2B_d19g0v0_Shanghai - - blake2B_d23g0v0_Shanghai - - blake2B_d21g0v0_Shanghai - - blake2B_d16g0v0_Shanghai - - blake2B_d20g0v0_Shanghai - - blake2B_d24g0v0_Shanghai - - blake2B_d25g0v0_Shanghai - - blake2B_d22g0v0_Shanghai - - idPrecomps_d2g0v0_Shanghai - - idPrecomps_d3g0v0_Shanghai - - idPrecomps_d4g0v0_Shanghai - - idPrecomps_d5g0v0_Shanghai - - idPrecomps_d6g0v0_Shanghai - - idPrecomps_d7g0v0_Shanghai - - idPrecomps_d8g0v0_Shanghai - - identity_to_bigger_d0g0v0_Shanghai - - identity_to_smaller_d0g0v0_Shanghai - - modexpTests_d0g0v0_Shanghai - - modexpTests_d100g0v0_Shanghai - - modexpTests_d101g0v0_Shanghai - - modexpTests_d102g0v0_Shanghai - - modexpTests_d103g0v0_Shanghai - - modexpTests_d104g0v0_Shanghai - - modexpTests_d106g0v0_Shanghai - - modexpTests_d105g0v0_Shanghai - - modexpTests_d107g0v0_Shanghai - - modexpTests_d108g0v0_Shanghai - - modexpTests_d109g0v0_Shanghai - - modexpTests_d10g0v0_Shanghai - - modexpTests_d110g0v0_Shanghai - - modexpTests_d111g0v0_Shanghai - - modexpTests_d112g0v0_Shanghai - - modexpTests_d113g0v0_Shanghai - - modexpTests_d114g0v0_Shanghai - - modexpTests_d115g0v0_Shanghai - - modexpTests_d116g0v0_Shanghai - - modexpTests_d117g0v0_Shanghai - - modexpTests_d118g0v0_Shanghai - - modexpTests_d11g0v0_Shanghai - - modexpTests_d120g0v0_Shanghai - - modexpTests_d119g0v0_Shanghai - - modexpTests_d121g0v0_Shanghai - - modexpTests_d122g0v0_Shanghai - - modexpTests_d123g0v0_Shanghai - - modexpTests_d124g0v0_Shanghai - - modexpTests_d125g0v0_Shanghai - - modexpTests_d126g0v0_Shanghai - - modexpTests_d12g0v0_Shanghai - - modexpTests_d13g0v0_Shanghai - - modexpTests_d14g0v0_Shanghai - - modexpTests_d15g0v0_Shanghai - - modexpTests_d16g0v0_Shanghai - - modexpTests_d18g0v0_Shanghai - - modexpTests_d17g0v0_Shanghai - - modexpTests_d19g0v0_Shanghai - - modexpTests_d1g0v0_Shanghai - - modexpTests_d20g0v0_Shanghai - - modexpTests_d21g0v0_Shanghai - - modexpTests_d22g0v0_Shanghai - - modexpTests_d24g0v0_Shanghai - - modexpTests_d23g0v0_Shanghai - - modexpTests_d25g0v0_Shanghai - - modexpTests_d26g0v0_Shanghai - - modexpTests_d27g0v0_Shanghai - - modexpTests_d29g0v0_Shanghai - - modexpTests_d28g0v0_Shanghai - - modexpTests_d2g0v0_Shanghai - - modexpTests_d30g0v0_Shanghai - - modexpTests_d31g0v0_Shanghai - - modexpTests_d32g0v0_Shanghai - - modexpTests_d33g0v0_Shanghai - - modexpTests_d34g0v0_Shanghai - - modexpTests_d36g0v0_Shanghai - - modexpTests_d35g0v0_Shanghai - - modexpTests_d38g0v0_Shanghai - - modexpTests_d37g0v0_Shanghai - - modexpTests_d39g0v0_Shanghai - - modexpTests_d3g0v0_Shanghai - - modexpTests_d40g0v0_Shanghai - - modexpTests_d41g0v0_Shanghai - - modexpTests_d42g0v0_Shanghai - - modexpTests_d43g0v0_Shanghai - - modexpTests_d44g0v0_Shanghai - - modexpTests_d45g0v0_Shanghai - - modexpTests_d46g0v0_Shanghai - - modexpTests_d47g0v0_Shanghai - - modexpTests_d48g0v0_Shanghai - - modexpTests_d49g0v0_Shanghai - - modexpTests_d4g0v0_Shanghai - - modexpTests_d50g0v0_Shanghai - - modexpTests_d51g0v0_Shanghai - - modexpTests_d52g0v0_Shanghai - - modexpTests_d53g0v0_Shanghai - - modexpTests_d54g0v0_Shanghai - - modexpTests_d55g0v0_Shanghai - - modexpTests_d56g0v0_Shanghai - - modexpTests_d57g0v0_Shanghai - - modexpTests_d59g0v0_Shanghai - - modexpTests_d58g0v0_Shanghai - - modexpTests_d5g0v0_Shanghai - - modexpTests_d60g0v0_Shanghai - - modexpTests_d61g0v0_Shanghai - - modexpTests_d62g0v0_Shanghai - - modexpTests_d64g0v0_Shanghai - - modexpTests_d63g0v0_Shanghai - - modexpTests_d65g0v0_Shanghai - - modexpTests_d66g0v0_Shanghai - - modexpTests_d67g0v0_Shanghai - - modexpTests_d68g0v0_Shanghai - - modexpTests_d69g0v0_Shanghai - - modexpTests_d6g0v0_Shanghai - - modexpTests_d70g0v0_Shanghai - - modexpTests_d71g0v0_Shanghai - - modexpTests_d72g0v0_Shanghai - - modexpTests_d73g0v0_Shanghai - - modexpTests_d74g0v0_Shanghai - - modexpTests_d75g0v0_Shanghai - - modexpTests_d76g0v0_Shanghai - - modexpTests_d77g0v0_Shanghai - - modexpTests_d78g0v0_Shanghai - - modexpTests_d79g0v0_Shanghai - - modexpTests_d7g0v0_Shanghai - - modexpTests_d81g0v0_Shanghai - - modexpTests_d80g0v0_Shanghai - - modexpTests_d82g0v0_Shanghai - - modexpTests_d83g0v0_Shanghai - - modexpTests_d84g0v0_Shanghai - - modexpTests_d86g0v0_Shanghai - - modexpTests_d85g0v0_Shanghai - - modexpTests_d87g0v0_Shanghai - - modexpTests_d88g0v0_Shanghai - - modexpTests_d89g0v0_Shanghai - - modexpTests_d8g0v0_Shanghai - - modexpTests_d90g0v0_Shanghai - - modexpTests_d91g0v0_Shanghai - - modexpTests_d93g0v0_Shanghai - - modexpTests_d92g0v0_Shanghai - - modexpTests_d94g0v0_Shanghai - - modexpTests_d95g0v0_Shanghai - - modexpTests_d96g0v0_Shanghai - - modexpTests_d97g0v0_Shanghai - - modexpTests_d98g0v0_Shanghai - - modexpTests_d99g0v0_Shanghai - - modexp_d0g0v0_Shanghai - - modexpTests_d9g0v0_Shanghai - - modexp_d0g1v0_Shanghai - - modexp_d0g2v0_Shanghai - - modexp_d0g3v0_Shanghai - - modexp_d11g0v0_Shanghai - - modexp_d11g1v0_Shanghai - - modexp_d11g2v0_Shanghai - - modexp_d11g3v0_Shanghai - - modexp_d14g0v0_Shanghai - - modexp_d14g1v0_Shanghai - - modexp_d14g2v0_Shanghai - - modexp_d14g3v0_Shanghai - - modexp_d16g1v0_Shanghai - - modexp_d16g2v0_Shanghai - - modexp_d16g0v0_Shanghai - - modexp_d17g0v0_Shanghai - - modexp_d16g3v0_Shanghai - - modexp_d17g1v0_Shanghai - - modexp_d17g2v0_Shanghai - - modexp_d17g3v0_Shanghai - - modexp_d25g0v0_Shanghai - - modexp_d25g2v0_Shanghai - - modexp_d25g1v0_Shanghai - - modexp_d25g3v0_Shanghai - - modexp_d26g0v0_Shanghai - - modexp_d26g1v0_Shanghai - - modexp_d26g2v0_Shanghai - - modexp_d26g3v0_Shanghai - - modexp_d32g1v0_Shanghai - - modexp_d32g2v0_Shanghai - - modexp_d32g0v0_Shanghai - - modexp_d27g1v0_Shanghai - - modexp_d31g0v0_Shanghai - - modexp_d31g1v0_Shanghai - - modexp_d31g2v0_Shanghai - - modexp_d31g3v0_Shanghai - - modexp_d27g3v0_Shanghai - - modexp_d32g3v0_Shanghai - - modexp_d27g0v0_Shanghai - - modexp_d33g0v0_Shanghai - - modexp_d27g2v0_Shanghai - - modexp_d33g2v0_Shanghai - - modexp_d33g1v0_Shanghai - - modexp_d33g3v0_Shanghai - - modexp_d34g0v0_Shanghai - - modexp_d34g1v0_Shanghai - - modexp_d34g2v0_Shanghai - - modexp_d34g3v0_Shanghai - - modexp_d35g0v0_Shanghai - - modexp_d35g1v0_Shanghai - - modexp_d35g2v0_Shanghai - - modexp_d35g3v0_Shanghai - - modexp_d4g0v0_Shanghai - - modexp_d4g1v0_Shanghai - - modexp_d4g2v0_Shanghai - - modexp_d4g3v0_Shanghai - - modexp_d3g0v0_Shanghai - - modexp_d3g1v0_Shanghai - - modexp_d3g3v0_Shanghai - - modexp_d3g2v0_Shanghai - - modexp_d6g0v0_Shanghai - - modexp_d6g1v0_Shanghai - - modexp_d6g2v0_Shanghai - - modexp_d7g0v0_Shanghai - - modexp_d7g1v0_Shanghai - - modexp_d7g2v0_Shanghai - - modexp_d6g3v0_Shanghai - - modexp_d7g3v0_Shanghai - - precompsEIP2929_d10g0v0_Shanghai - - precompsEIP2929_d11g0v0_Shanghai - - precompsEIP2929_d106g0v0_Shanghai - - precompsEIP2929_d18g0v0_Shanghai - - precompsEIP2929_d19g0v0_Shanghai - - precompsEIP2929_d20g0v0_Shanghai - - precompsEIP2929_d21g0v0_Shanghai - - precompsEIP2929_d22g0v0_Shanghai - - precompsEIP2929_d23g0v0_Shanghai - - precompsEIP2929_d24g0v0_Shanghai - - precompsEIP2929_d25g0v0_Shanghai - - precompsEIP2929_d26g0v0_Shanghai - - precompsEIP2929_d270g0v0_Shanghai - - precompsEIP2929_d271g0v0_Shanghai - - precompsEIP2929_d272g0v0_Shanghai - - precompsEIP2929_d273g0v0_Shanghai - - precompsEIP2929_d274g0v0_Shanghai - - precompsEIP2929_d275g0v0_Shanghai - - precompsEIP2929_d276g0v0_Shanghai - - precompsEIP2929_d277g0v0_Shanghai - - precompsEIP2929_d278g0v0_Shanghai - - precompsEIP2929_d288g0v0_Shanghai - - precompsEIP2929_d289g0v0_Shanghai - - precompsEIP2929_d290g0v0_Shanghai - - precompsEIP2929_d291g0v0_Shanghai - - precompsEIP2929_d292g0v0_Shanghai - - precompsEIP2929_d293g0v0_Shanghai - - precompsEIP2929_d294g0v0_Shanghai - - precompsEIP2929_d295g0v0_Shanghai - - precompsEIP2929_d296g0v0_Shanghai - - precompsEIP2929_d306g0v0_Shanghai - - precompsEIP2929_d307g0v0_Shanghai - - precompsEIP2929_d308g0v0_Shanghai - - precompsEIP2929_d309g0v0_Shanghai - - precompsEIP2929_d310g0v0_Shanghai - - precompsEIP2929_d311g0v0_Shanghai - - precompsEIP2929_d312g0v0_Shanghai - - precompsEIP2929_d313g0v0_Shanghai - - precompsEIP2929_d314g0v0_Shanghai - - precompsEIP2929_d34g0v0_Shanghai - - precompsEIP2929_d36g0v0_Shanghai - - precompsEIP2929_d37g0v0_Shanghai - - precompsEIP2929_d38g0v0_Shanghai - - precompsEIP2929_d3g0v0_Shanghai - - precompsEIP2929_d39g0v0_Shanghai - - precompsEIP2929_d40g0v0_Shanghai - - precompsEIP2929_d41g0v0_Shanghai - - precompsEIP2929_d42g0v0_Shanghai - - precompsEIP2929_d43g0v0_Shanghai - - precompsEIP2929_d44g0v0_Shanghai - - precompsEIP2929_d4g0v0_Shanghai - - precompsEIP2929_d54g0v0_Shanghai - - precompsEIP2929_d55g0v0_Shanghai - - precompsEIP2929_d56g0v0_Shanghai - - precompsEIP2929_d5g0v0_Shanghai - - precompsEIP2929_d57g0v0_Shanghai - - precompsEIP2929_d58g0v0_Shanghai - - precompsEIP2929_d59g0v0_Shanghai - - precompsEIP2929_d60g0v0_Shanghai - - precompsEIP2929_d61g0v0_Shanghai - - precompsEIP2929_d62g0v0_Shanghai - - precompsEIP2929_d6g0v0_Shanghai - - precompsEIP2929_d7g0v0_Shanghai - - precompsEIP2929_d72g0v0_Shanghai - - precompsEIP2929_d73g0v0_Shanghai - - precompsEIP2929_d74g0v0_Shanghai - - precompsEIP2929_d75g0v0_Shanghai - - precompsEIP2929_d77g0v0_Shanghai - - precompsEIP2929_d76g0v0_Shanghai - - precompsEIP2929_d8g0v0_Shanghai - - precompsEIP2929_d78g0v0_Shanghai - - precompsEIP2929_d79g0v0_Shanghai - - precompsEIP2929_d80g0v0_Shanghai - - sec80_d0g0v0_Shanghai - - precompsEIP2929_d90g0v0_Shanghai - - precompsEIP2929_d91g0v0_Shanghai - - precompsEIP2929_d70g0v0_Shanghai - - precompsEIP2929_d92g0v0_Shanghai - - precompsEIP2929_d9g0v0_Shanghai - - precompsEIP2929_d93g0v0_Shanghai - - precompsEIP2929_d94g0v0_Shanghai - - precompsEIP2929_d95g0v0_Shanghai - - precompsEIP2929_d98g0v0_Shanghai - - precompsEIP2929_d96g0v0_Shanghai - - precompsEIP2929_d97g0v0_Shanghai - stRandom2: - - 201503110226PYTHON_DUP6_d0g0v0_Shanghai - - randomStatetest389_d0g0v0_Shanghai - - randomStatetest396_d0g0v0_Shanghai - - randomStatetest409_d0g0v0_Shanghai - - randomStatetest417_d0g0v0_Shanghai - - randomStatetest415_d0g0v0_Shanghai - - randomStatetest428_d0g0v0_Shanghai - - randomStatetest416_d0g0v0_Shanghai - - randomStatetest420_d0g0v0_Shanghai - - randomStatetest435_d0g0v0_Shanghai - - randomStatetest437_d0g0v0_Shanghai - - randomStatetest446_d0g0v0_Shanghai - - randomStatetest450_d0g0v0_Shanghai - - randomStatetest466_d0g0v0_Shanghai - - randomStatetest471_d0g0v0_Shanghai - - randomStatetest473_d0g0v0_Shanghai - - randomStatetest475_d0g0v0_Shanghai - - randomStatetest478_d0g0v0_Shanghai - - randomStatetest508_d0g0v0_Shanghai - - randomStatetest501_d0g0v0_Shanghai - - randomStatetest519_d0g0v0_Shanghai - - randomStatetest531_d0g0v0_Shanghai - - randomStatetest525_d0g0v0_Shanghai - - randomStatetest521_d0g0v0_Shanghai - - randomStatetest541_d0g0v0_Shanghai - - randomStatetest539_d0g0v0_Shanghai - - randomStatetest542_d0g0v0_Shanghai - - randomStatetest558_d0g0v0_Shanghai - - randomStatetest577_d0g0v0_Shanghai - - randomStatetest572_d0g0v0_Shanghai - - randomStatetest571_d0g0v0_Shanghai - - randomStatetest578_d0g0v0_Shanghai - - randomStatetest387_d0g0v0_Shanghai - - randomStatetest581_d0g0v0_Shanghai - - randomStatetest584_d0g0v0_Shanghai - - randomStatetest592_d0g0v0_Shanghai - - randomStatetest605_d0g0v0_Shanghai - - randomStatetest609_d0g0v0_Shanghai - - randomStatetest624_d0g0v0_Shanghai - - randomStatetest615_d0g0v0_Shanghai - - randomStatetest628_d0g0v0_Shanghai - - randomStatetest638_d0g0v0_Shanghai - - randomStatetest645_d0g0v0_Shanghai - - randomStatetest644_d0g0v0_Shanghai - - randomStatetest506_d0g0v0_Shanghai - - randomStatetest397_d0g0v0_Shanghai - - randomStatetest588_d0g0v0_Shanghai - - randomStatetest410_d0g0v0_Shanghai - - randomStatetest418_d0g0v0_Shanghai - - randomStatetest433_d0g0v0_Shanghai - - randomStatetest448_d0g0v0_Shanghai - - randomStatetest456_d0g0v0_Shanghai - - randomStatetest469_d0g0v0_Shanghai - - randomStatetest476_d0g0v0_Shanghai - - randomStatetest458_d0g0v0_Shanghai - - randomStatetest467_d0g0v0_Shanghai - - randomStatetest579_d0g0v0_Shanghai - - randomStatetest536_d0g0v0_Shanghai - - randomStatetest547_d0g0v0_Shanghai - - randomStatetest560_d0g0v0_Shanghai - - randomStatetest582_d0g0v0_Shanghai - - randomStatetest583_d0g0v0_Shanghai - - randomStatetest554_d0g0v0_Shanghai - - randomStatetest589_d0g0v0_Shanghai - - randomStatetest636_d0g0v0_Shanghai - - randomStatetest639_d0g0v0_Shanghai - - randomStatetest650_d0g0v0_Shanghai + - idPrecomps_d2g0v0_Cancun + - idPrecomps_d7g0v0_Cancun + - idPrecomps_d9g0v0_Cancun + - precompsEIP2929Cancun_d110g0v0_Cancun + - precompsEIP2929Cancun_d117g0v0_Cancun + - precompsEIP2929Cancun_d128g0v0_Cancun + - precompsEIP2929Cancun_d12g0v0_Cancun + - precompsEIP2929Cancun_d135g0v0_Cancun + - precompsEIP2929Cancun_d146g0v0_Cancun + - precompsEIP2929Cancun_d151g0v0_Cancun + - precompsEIP2929Cancun_d153g0v0_Cancun + - precompsEIP2929Cancun_d164g0v0_Cancun + - precompsEIP2929Cancun_d169g0v0_Cancun + - precompsEIP2929Cancun_d171g0v0_Cancun + - precompsEIP2929Cancun_d182g0v0_Cancun + - precompsEIP2929Cancun_d189g0v0_Cancun + - precompsEIP2929Cancun_d200g0v0_Cancun + - precompsEIP2929Cancun_d207g0v0_Cancun + - precompsEIP2929Cancun_d20g0v0_Cancun + - precompsEIP2929Cancun_d218g0v0_Cancun + - precompsEIP2929Cancun_d225g0v0_Cancun + - precompsEIP2929Cancun_d236g0v0_Cancun + - precompsEIP2929Cancun_d241g0v0_Cancun + - precompsEIP2929Cancun_d243g0v0_Cancun + - precompsEIP2929Cancun_d254g0v0_Cancun + - precompsEIP2929Cancun_d261g0v0_Cancun + - precompsEIP2929Cancun_d272g0v0_Cancun + - precompsEIP2929Cancun_d279g0v0_Cancun + - precompsEIP2929Cancun_d27g0v0_Cancun + - precompsEIP2929Cancun_d290g0v0_Cancun + - precompsEIP2929Cancun_d295g0v0_Cancun + - precompsEIP2929Cancun_d297g0v0_Cancun + - precompsEIP2929Cancun_d308g0v0_Cancun + - precompsEIP2929Cancun_d315g0v0_Cancun + - precompsEIP2929Cancun_d38g0v0_Cancun + - precompsEIP2929Cancun_d43g0v0_Cancun + - precompsEIP2929Cancun_d45g0v0_Cancun + - precompsEIP2929Cancun_d56g0v0_Cancun + - precompsEIP2929Cancun_d5g0v0_Cancun + - precompsEIP2929Cancun_d61g0v0_Cancun + - precompsEIP2929Cancun_d63g0v0_Cancun + - precompsEIP2929Cancun_d74g0v0_Cancun + - precompsEIP2929Cancun_d81g0v0_Cancun + - precompsEIP2929Cancun_d92g0v0_Cancun + - precompsEIP2929Cancun_d99g0v0_Cancun stQuadraticComplexityTest: - - Call1MB1024Calldepth_d0g1v0_Shanghai - - Call20KbytesContract50_1_d0g1v0_Shanghai - - Call20KbytesContract50_2_d0g1v0_Shanghai - - Call20KbytesContract50_3_d0g1v0_Shanghai - - Return50000_d0g1v0_Shanghai - - Return50000_2_d0g1v0_Shanghai + - Call20KbytesContract50_1_d0g0v0_Cancun + - Call20KbytesContract50_2_d0g0v0_Cancun + - Call20KbytesContract50_3_d0g0v0_Cancun + - Call20KbytesContract50_3_d0g1v0_Cancun + stRandom2: + - randomStatetest415_d0g0v0_Cancun + - randomStatetest418_d0g0v0_Cancun + - randomStatetest433_d0g0v0_Cancun + - randomStatetest450_d0g0v0_Cancun + - randomStatetest458_d0g0v0_Cancun + - randomStatetest467_d0g0v0_Cancun + - randomStatetest469_d0g0v0_Cancun + - randomStatetest541_d0g0v0_Cancun + - randomStatetest547_d0g0v0_Cancun + - randomStatetest554_d0g0v0_Cancun + - randomStatetest560_d0g0v0_Cancun + - randomStatetest583_d0g0v0_Cancun + - randomStatetest636_d0g0v0_Cancun + - randomStatetest639_d0g0v0_Cancun + - randomStatetest645_d0g0v0_Cancun + - randomStatetest645_d0g0v1_Cancun stRandom: - - randomStatetest100_d0g0v0_Shanghai - - randomStatetest0_d0g0v0_Shanghai - - randomStatetest107_d0g0v0_Shanghai - - randomStatetest116_d0g0v0_Shanghai - - randomStatetest124_d0g0v0_Shanghai - - randomStatetest143_d0g0v0_Shanghai - - randomStatetest139_d0g0v0_Shanghai - - randomStatetest145_d0g0v0_Shanghai - - randomStatetest144_d0g0v0_Shanghai - - randomStatetest14_d0g0v0_Shanghai - - randomStatetest153_d0g0v0_Shanghai - - randomStatetest157_d0g0v0_Shanghai - - randomStatetest150_d0g0v0_Shanghai - - randomStatetest164_d0g0v0_Shanghai - - randomStatetest174_d0g0v0_Shanghai - - randomStatetest176_d0g0v0_Shanghai - - randomStatetest173_d0g0v0_Shanghai - - randomStatetest184_d0g0v0_Shanghai - - randomStatetest178_d0g0v0_Shanghai - - randomStatetest199_d0g0v0_Shanghai - - randomStatetest195_d0g0v0_Shanghai - - randomStatetest197_d0g0v0_Shanghai - - randomStatetest196_d0g0v0_Shanghai - - randomStatetest207_d0g0v0_Shanghai - - randomStatetest201_d0g0v0_Shanghai - - randomStatetest202_d0g0v0_Shanghai - - randomStatetest204_d0g0v0_Shanghai - - randomStatetest209_d0g0v0_Shanghai - - randomStatetest210_d0g0v0_Shanghai - - randomStatetest228_d0g0v0_Shanghai - - randomStatetest222_d0g0v0_Shanghai - - randomStatetest244_d0g0v0_Shanghai - - randomStatetest236_d0g0v0_Shanghai - - randomStatetest246_d0g0v0_Shanghai - - randomStatetest252_d0g0v0_Shanghai - - randomStatetest248_d0g0v0_Shanghai - - randomStatetest251_d0g0v0_Shanghai - - randomStatetest249_d0g0v0_Shanghai - - randomStatetest25_d0g0v0_Shanghai - - randomStatetest26_d0g0v0_Shanghai - - randomStatetest273_d0g0v0_Shanghai - - randomStatetest271_d0g0v0_Shanghai - - randomStatetest270_d0g0v0_Shanghai - - randomStatetest27_d0g0v0_Shanghai - - randomStatetest288_d0g0v0_Shanghai - - randomStatetest283_d0g0v0_Shanghai - - randomStatetest17_d0g0v0_Shanghai - - randomStatetest290_d0g0v0_Shanghai - - randomStatetest30_d0g0v0_Shanghai - - randomStatetest308_d0g0v0_Shanghai - - randomStatetest312_d0g0v0_Shanghai - - randomStatetest108_d0g0v0_Shanghai - - randomStatetest325_d0g0v0_Shanghai - - randomStatetest111_d0g0v0_Shanghai - - randomStatetest138_d0g0v0_Shanghai - - randomStatetest345_d0g0v0_Shanghai - - randomStatetest349_d0g0v0_Shanghai - - randomStatetest351_d0g0v0_Shanghai - - randomStatetest347_d0g0v0_Shanghai - - randomStatetest362_d0g0v0_Shanghai - - randomStatetest367_d0g0v0_Shanghai - - randomStatetest368_d0g0v0_Shanghai - - randomStatetest379_d0g0v0_Shanghai - - randomStatetest371_d0g0v0_Shanghai - - randomStatetest376_d0g0v0_Shanghai - - randomStatetest154_d0g0v0_Shanghai - - randomStatetest151_d0g0v0_Shanghai - - randomStatetest159_d0g0v0_Shanghai - - randomStatetest383_d0g0v0_Shanghai - - randomStatetest39_d0g0v0_Shanghai - - randomStatetest3_d0g0v0_Shanghai - - randomStatetest45_d0g0v0_Shanghai - - randomStatetest163_d0g0v0_Shanghai - - randomStatetest43_d0g0v0_Shanghai - - randomStatetest66_d0g0v0_Shanghai - - randomStatetest185_d0g0v0_Shanghai - - randomStatetest78_d0g0v0_Shanghai - - randomStatetest88_d0g0v0_Shanghai - - randomStatetest85_d0g0v0_Shanghai - - randomStatetest98_d0g0v0_Shanghai - - randomStatetest354_d0g0v0_Shanghai - - randomStatetest357_d0g0v0_Shanghai - - randomStatetest205_d0g0v0_Shanghai - - randomStatetest211_d0g0v0_Shanghai - - randomStatetest365_d0g0v0_Shanghai - - randomStatetest260_d0g0v0_Shanghai - - randomStatetest285_d0g0v0_Shanghai - - randomStatetest326_d0g0v0_Shanghai - - randomStatetest306_d0g0v0_Shanghai - - randomStatetest335_d0g0v0_Shanghai - - randomStatetest336_d0g0v0_Shanghai - - randomStatetest341_d0g0v0_Shanghai - - randomStatetest36_d0g0v0_Shanghai - - randomStatetest384_d0g0v0_Shanghai - - randomStatetest48_d0g0v0_Shanghai - - randomStatetest4_d0g0v0_Shanghai - - randomStatetest53_d0g0v0_Shanghai - stRefundTest: - - refundSuicide50procentCap_d1g0v0_Shanghai - - refund_CallToSuicideTwice_d1g0v0_Shanghai - - refund_multimpleSuicide_d0g0v0_Shanghai + - randomStatetest111_d0g0v0_Cancun + - randomStatetest124_d0g0v0_Cancun + - randomStatetest14_d0g0v0_Cancun + - randomStatetest150_d0g0v0_Cancun + - randomStatetest154_d0g0v0_Cancun + - randomStatetest178_d0g0v0_Cancun + - randomStatetest211_d0g0v0_Cancun + - randomStatetest260_d0g0v0_Cancun + - randomStatetest306_d0g0v0_Cancun + - randomStatetest308_d0g0v0_Cancun + - randomStatetest343_d0g0v0_Cancun stReturnDataTest: - - call_ecrec_success_empty_then_returndatasize_d0g0v0_Shanghai - - clearReturnBuffer_d100g0v0_Shanghai - - clearReturnBuffer_d101g0v0_Shanghai - - clearReturnBuffer_d106g0v0_Shanghai - - clearReturnBuffer_d102g0v0_Shanghai - - clearReturnBuffer_d103g0v0_Shanghai - - clearReturnBuffer_d107g0v0_Shanghai - - clearReturnBuffer_d108g0v0_Shanghai - - clearReturnBuffer_d109g0v0_Shanghai - - clearReturnBuffer_d112g0v0_Shanghai - - clearReturnBuffer_d104g0v0_Shanghai - - clearReturnBuffer_d105g0v0_Shanghai - - clearReturnBuffer_d113g0v0_Shanghai - - clearReturnBuffer_d110g0v0_Shanghai - - clearReturnBuffer_d111g0v0_Shanghai - - clearReturnBuffer_d114g0v0_Shanghai - - clearReturnBuffer_d115g0v0_Shanghai - - clearReturnBuffer_d116g0v0_Shanghai - - clearReturnBuffer_d10g0v0_Shanghai - - clearReturnBuffer_d117g0v0_Shanghai - - clearReturnBuffer_d120g0v0_Shanghai - - clearReturnBuffer_d121g0v0_Shanghai - - clearReturnBuffer_d123g0v0_Shanghai - - clearReturnBuffer_d122g0v0_Shanghai - - clearReturnBuffer_d0g0v0_Shanghai - - clearReturnBuffer_d118g0v0_Shanghai - - clearReturnBuffer_d119g0v0_Shanghai - - clearReturnBuffer_d124g0v0_Shanghai - - clearReturnBuffer_d127g0v0_Shanghai - - clearReturnBuffer_d126g0v0_Shanghai - - clearReturnBuffer_d128g0v0_Shanghai - - clearReturnBuffer_d129g0v0_Shanghai - - clearReturnBuffer_d125g0v0_Shanghai - - clearReturnBuffer_d130g0v0_Shanghai - - clearReturnBuffer_d131g0v0_Shanghai - - clearReturnBuffer_d134g0v0_Shanghai - - clearReturnBuffer_d11g0v0_Shanghai - - clearReturnBuffer_d135g0v0_Shanghai - - clearReturnBuffer_d136g0v0_Shanghai - - clearReturnBuffer_d137g0v0_Shanghai - - clearReturnBuffer_d132g0v0_Shanghai - - clearReturnBuffer_d133g0v0_Shanghai - - clearReturnBuffer_d138g0v0_Shanghai - - clearReturnBuffer_d139g0v0_Shanghai - - clearReturnBuffer_d12g0v0_Shanghai - - clearReturnBuffer_d140g0v0_Shanghai - - clearReturnBuffer_d141g0v0_Shanghai - - clearReturnBuffer_d142g0v0_Shanghai - - clearReturnBuffer_d143g0v0_Shanghai - - clearReturnBuffer_d13g0v0_Shanghai - - clearReturnBuffer_d144g0v0_Shanghai - - clearReturnBuffer_d145g0v0_Shanghai - - clearReturnBuffer_d148g0v0_Shanghai - - clearReturnBuffer_d149g0v0_Shanghai - - clearReturnBuffer_d14g0v0_Shanghai - - clearReturnBuffer_d150g0v0_Shanghai - - clearReturnBuffer_d151g0v0_Shanghai - - clearReturnBuffer_d146g0v0_Shanghai - - clearReturnBuffer_d147g0v0_Shanghai - - clearReturnBuffer_d152g0v0_Shanghai - - clearReturnBuffer_d154g0v0_Shanghai - - clearReturnBuffer_d153g0v0_Shanghai - - clearReturnBuffer_d15g0v0_Shanghai - - clearReturnBuffer_d155g0v0_Shanghai - - clearReturnBuffer_d156g0v0_Shanghai - - clearReturnBuffer_d157g0v0_Shanghai - - clearReturnBuffer_d158g0v0_Shanghai - - clearReturnBuffer_d159g0v0_Shanghai - - clearReturnBuffer_d162g0v0_Shanghai - - clearReturnBuffer_d163g0v0_Shanghai - - clearReturnBuffer_d164g0v0_Shanghai - - clearReturnBuffer_d160g0v0_Shanghai - - clearReturnBuffer_d28g0v0_Shanghai - - clearReturnBuffer_d165g0v0_Shanghai - - clearReturnBuffer_d161g0v0_Shanghai - - clearReturnBuffer_d29g0v0_Shanghai - - clearReturnBuffer_d30g0v0_Shanghai - - clearReturnBuffer_d31g0v0_Shanghai - - clearReturnBuffer_d166g0v0_Shanghai - - clearReturnBuffer_d32g0v0_Shanghai - - clearReturnBuffer_d1g0v0_Shanghai - - clearReturnBuffer_d16g0v0_Shanghai - - clearReturnBuffer_d17g0v0_Shanghai - - clearReturnBuffer_d33g0v0_Shanghai - - clearReturnBuffer_d37g0v0_Shanghai - - clearReturnBuffer_d167g0v0_Shanghai - - clearReturnBuffer_d18g0v0_Shanghai - - clearReturnBuffer_d19g0v0_Shanghai - - clearReturnBuffer_d38g0v0_Shanghai - - clearReturnBuffer_d39g0v0_Shanghai - - clearReturnBuffer_d23g0v0_Shanghai - - clearReturnBuffer_d24g0v0_Shanghai - - clearReturnBuffer_d25g0v0_Shanghai - - clearReturnBuffer_d34g0v0_Shanghai - - clearReturnBuffer_d35g0v0_Shanghai - - clearReturnBuffer_d20g0v0_Shanghai - - clearReturnBuffer_d2g0v0_Shanghai - - clearReturnBuffer_d42g0v0_Shanghai - - clearReturnBuffer_d21g0v0_Shanghai - - clearReturnBuffer_d43g0v0_Shanghai - - clearReturnBuffer_d44g0v0_Shanghai - - clearReturnBuffer_d45g0v0_Shanghai - - clearReturnBuffer_d40g0v0_Shanghai - - clearReturnBuffer_d46g0v0_Shanghai - - clearReturnBuffer_d41g0v0_Shanghai - - clearReturnBuffer_d26g0v0_Shanghai - - clearReturnBuffer_d27g0v0_Shanghai - - clearReturnBuffer_d47g0v0_Shanghai - - clearReturnBuffer_d51g0v0_Shanghai - - clearReturnBuffer_d52g0v0_Shanghai - - clearReturnBuffer_d3g0v0_Shanghai - - clearReturnBuffer_d53g0v0_Shanghai - - clearReturnBuffer_d56g0v0_Shanghai - - clearReturnBuffer_d57g0v0_Shanghai - - clearReturnBuffer_d48g0v0_Shanghai - - clearReturnBuffer_d49g0v0_Shanghai - - clearReturnBuffer_d58g0v0_Shanghai - - clearReturnBuffer_d59g0v0_Shanghai - - clearReturnBuffer_d54g0v0_Shanghai - - clearReturnBuffer_d61g0v0_Shanghai - - clearReturnBuffer_d60g0v0_Shanghai - - clearReturnBuffer_d55g0v0_Shanghai - - clearReturnBuffer_d65g0v0_Shanghai - - clearReturnBuffer_d66g0v0_Shanghai - - clearReturnBuffer_d67g0v0_Shanghai - - clearReturnBuffer_d4g0v0_Shanghai - - clearReturnBuffer_d62g0v0_Shanghai - - clearReturnBuffer_d63g0v0_Shanghai - - clearReturnBuffer_d70g0v0_Shanghai - - clearReturnBuffer_d71g0v0_Shanghai - - clearReturnBuffer_d72g0v0_Shanghai - - clearReturnBuffer_d73g0v0_Shanghai - - clearReturnBuffer_d74g0v0_Shanghai - - clearReturnBuffer_d5g0v0_Shanghai - - clearReturnBuffer_d75g0v0_Shanghai - - clearReturnBuffer_d68g0v0_Shanghai - - clearReturnBuffer_d69g0v0_Shanghai - - clearReturnBuffer_d85g0v0_Shanghai - - clearReturnBuffer_d84g0v0_Shanghai - - create_callprecompile_returndatasize_d0g0v0_Shanghai - - modexp_modsize0_returndatasize_d1g0v0_Shanghai - - clearReturnBuffer_d78g0v0_Shanghai - - clearReturnBuffer_d79g0v0_Shanghai - - clearReturnBuffer_d86g0v0_Shanghai - - modexp_modsize0_returndatasize_d2g0v0_Shanghai - - clearReturnBuffer_d87g0v0_Shanghai - - clearReturnBuffer_d88g0v0_Shanghai - - clearReturnBuffer_d89g0v0_Shanghai - - modexp_modsize0_returndatasize_d3g0v0_Shanghai - - clearReturnBuffer_d92g0v0_Shanghai - - clearReturnBuffer_d80g0v0_Shanghai - - clearReturnBuffer_d76g0v0_Shanghai - - clearReturnBuffer_d77g0v0_Shanghai - - clearReturnBuffer_d93g0v0_Shanghai - - clearReturnBuffer_d81g0v0_Shanghai - - returndatasize_after_failing_callcode_d0g0v0_Shanghai - - returndatasize_after_failing_staticcall_d0g0v0_Shanghai - - returndatasize_after_failing_delegatecall_d0g0v0_Shanghai - - clearReturnBuffer_d90g0v0_Shanghai - - returndatasize_bug_d0g0v0_Shanghai - - clearReturnBuffer_d91g0v0_Shanghai - - clearReturnBuffer_d82g0v0_Shanghai - - clearReturnBuffer_d83g0v0_Shanghai - - clearReturnBuffer_d95g0v0_Shanghai - - clearReturnBuffer_d94g0v0_Shanghai - - clearReturnBuffer_d6g0v0_Shanghai - - clearReturnBuffer_d99g0v0_Shanghai - - clearReturnBuffer_d98g0v0_Shanghai - - clearReturnBuffer_d96g0v0_Shanghai - - clearReturnBuffer_d97g0v0_Shanghai - - clearReturnBuffer_d7g0v0_Shanghai - - clearReturnBuffer_d9g0v0_Shanghai - - returndatasize_after_oog_after_deeper_d0g0v0_Shanghai - - revertRetDataSize_d10g0v0_Shanghai - - revertRetDataSize_d16g0v0_Shanghai - - revertRetDataSize_d0g0v0_Shanghai - - revertRetDataSize_d28g0v0_Shanghai - - revertRetDataSize_d1g0v0_Shanghai - - revertRetDataSize_d22g0v0_Shanghai - - revertRetDataSize_d25g0v0_Shanghai - - revertRetDataSize_d26g0v0_Shanghai - - revertRetDataSize_d24g0v0_Shanghai - - revertRetDataSize_d13g0v0_Shanghai - - revertRetDataSize_d14g0v0_Shanghai - - revertRetDataSize_d2g0v0_Shanghai - - revertRetDataSize_d15g0v0_Shanghai - - revertRetDataSize_d34g0v0_Shanghai - - revertRetDataSize_d12g0v0_Shanghai - - revertRetDataSize_d27g0v0_Shanghai - - tooLongReturnDataCopy_d0g0v0_Shanghai - - tooLongReturnDataCopy_d11g0v0_Shanghai - - revertRetDataSize_d20g0v0_Shanghai - - tooLongReturnDataCopy_d10g0v0_Shanghai - - revertRetDataSize_d19g0v0_Shanghai - - tooLongReturnDataCopy_d13g0v0_Shanghai - - revertRetDataSize_d21g0v0_Shanghai - - revertRetDataSize_d18g0v0_Shanghai - - tooLongReturnDataCopy_d12g0v0_Shanghai - - tooLongReturnDataCopy_d16g0v0_Shanghai - - tooLongReturnDataCopy_d18g0v0_Shanghai - - tooLongReturnDataCopy_d14g0v0_Shanghai - - tooLongReturnDataCopy_d15g0v0_Shanghai - - tooLongReturnDataCopy_d17g0v0_Shanghai - - tooLongReturnDataCopy_d1g0v0_Shanghai - - tooLongReturnDataCopy_d19g0v0_Shanghai - - tooLongReturnDataCopy_d20g0v0_Shanghai - - tooLongReturnDataCopy_d21g0v0_Shanghai - - tooLongReturnDataCopy_d22g0v0_Shanghai - - tooLongReturnDataCopy_d23g0v0_Shanghai - - tooLongReturnDataCopy_d4g0v0_Shanghai - - tooLongReturnDataCopy_d6g0v0_Shanghai - - tooLongReturnDataCopy_d2g0v0_Shanghai - - tooLongReturnDataCopy_d8g0v0_Shanghai - - tooLongReturnDataCopy_d9g0v0_Shanghai - - tooLongReturnDataCopy_d3g0v0_Shanghai - - tooLongReturnDataCopy_d5g0v0_Shanghai - - tooLongReturnDataCopy_d7g0v0_Shanghai - - revertRetDataSize_d3g0v0_Shanghai - - revertRetDataSize_d4g0v0_Shanghai - - revertRetDataSize_d6g0v0_Shanghai - - revertRetDataSize_d7g0v0_Shanghai - - revertRetDataSize_d8g0v0_Shanghai - - revertRetDataSize_d9g0v0_Shanghai - stRecursiveCreate: - - recursiveCreate_d0g0v0_Shanghai + - modexp_modsize0_returndatasize_d4g0v0_Cancun + - revertRetDataSize_d0g0v0_Cancun + - revertRetDataSize_d10g0v0_Cancun + - revertRetDataSize_d11g0v0_Cancun + - revertRetDataSize_d12g0v0_Cancun + - revertRetDataSize_d13g0v0_Cancun + - revertRetDataSize_d14g0v0_Cancun + - revertRetDataSize_d15g0v0_Cancun + - revertRetDataSize_d16g0v0_Cancun + - revertRetDataSize_d17g0v0_Cancun + - revertRetDataSize_d18g0v0_Cancun + - revertRetDataSize_d19g0v0_Cancun + - revertRetDataSize_d1g0v0_Cancun + - revertRetDataSize_d20g0v0_Cancun + - revertRetDataSize_d21g0v0_Cancun + - revertRetDataSize_d22g0v0_Cancun + - revertRetDataSize_d23g0v0_Cancun + - revertRetDataSize_d24g0v0_Cancun + - revertRetDataSize_d25g0v0_Cancun + - revertRetDataSize_d26g0v0_Cancun + - revertRetDataSize_d27g0v0_Cancun + - revertRetDataSize_d28g0v0_Cancun + - revertRetDataSize_d29g0v0_Cancun + - revertRetDataSize_d2g0v0_Cancun + - revertRetDataSize_d30g0v0_Cancun + - revertRetDataSize_d31g0v0_Cancun + - revertRetDataSize_d32g0v0_Cancun + - revertRetDataSize_d33g0v0_Cancun + - revertRetDataSize_d34g0v0_Cancun + - revertRetDataSize_d35g0v0_Cancun + - revertRetDataSize_d3g0v0_Cancun + - revertRetDataSize_d4g0v0_Cancun + - revertRetDataSize_d5g0v0_Cancun + - revertRetDataSize_d6g0v0_Cancun + - revertRetDataSize_d7g0v0_Cancun + - revertRetDataSize_d8g0v0_Cancun + - revertRetDataSize_d9g0v0_Cancun stRevertTest: - - RevertDepthCreateOOG_d0g0v0_Shanghai - - RevertDepthCreateOOG_d0g0v1_Shanghai - - RevertDepthCreateOOG_d0g1v0_Shanghai - - RevertDepthCreateOOG_d0g1v1_Shanghai - - RevertDepthCreateOOG_d1g0v0_Shanghai - - RevertDepthCreateOOG_d1g0v1_Shanghai - - RevertInCreateInInit_d0g0v0_Shanghai - - RevertOpcodeCreate_d0g1v0_Shanghai - - RevertOpcodeMultipleSubCalls_d0g3v1_Shanghai - - RevertOpcodeMultipleSubCalls_d1g3v1_Shanghai - - RevertOpcodeMultipleSubCalls_d0g2v1_Shanghai - - RevertOpcodeMultipleSubCalls_d1g2v1_Shanghai - - RevertOpcodeMultipleSubCalls_d2g3v1_Shanghai - - RevertOpcodeMultipleSubCalls_d3g3v1_Shanghai - - RevertOpcodeMultipleSubCalls_d2g2v1_Shanghai - - RevertOpcodeMultipleSubCalls_d3g2v1_Shanghai - - RevertPrefoundEmpty_d0g0v0_Shanghai - - RevertPrefound_d0g0v0_Shanghai - - LoopCallsThenRevert_d0g0v0_Shanghai - - LoopDelegateCallsDepthThenRevert_d0g0v0_Shanghai - - LoopCallsDepthThenRevert_d0g0v0_Shanghai - - LoopCallsDepthThenRevert3_d0g0v0_Shanghai - - LoopCallsDepthThenRevert2_d0g0v0_Shanghai - - RevertRemoteSubCallStorageOOG_d0g0v0_Shanghai - stSLoadTest: - - sloadGasCost_d0g0v0_Shanghai + - LoopCallsDepthThenRevert2_d0g0v0_Cancun + - LoopCallsDepthThenRevert3_d0g0v0_Cancun + - LoopCallsThenRevert_d0g0v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d10g1v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d10g2v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d15g2v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d18g1v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d18g2v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d23g2v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d26g1v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d26g2v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d2g1v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d2g2v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d31g2v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d7g2v0_Cancun + - RevertPrecompiledTouch_Paris_d0g0v0_Cancun + - RevertPrecompiledTouch_Paris_d1g0v0_Cancun + - RevertPrecompiledTouch_Paris_d2g0v0_Cancun + - RevertPrecompiledTouch_Paris_d3g0v0_Cancun + - RevertPrecompiledTouch_nonce_d0g0v0_Cancun + - RevertPrecompiledTouch_nonce_d1g0v0_Cancun + - RevertPrecompiledTouch_nonce_d2g0v0_Cancun + - RevertPrecompiledTouch_nonce_d3g0v0_Cancun + - RevertPrecompiledTouch_noncestorage_d0g0v0_Cancun + - RevertPrecompiledTouch_noncestorage_d1g0v0_Cancun + - RevertPrecompiledTouch_noncestorage_d2g0v0_Cancun + - RevertPrecompiledTouch_noncestorage_d3g0v0_Cancun + - RevertPrecompiledTouch_storage_Paris_d0g0v0_Cancun + - RevertPrecompiledTouch_storage_Paris_d1g0v0_Cancun + - RevertPrecompiledTouch_storage_Paris_d2g0v0_Cancun + - RevertPrecompiledTouch_storage_Paris_d3g0v0_Cancun + - costRevert_d0g0v0_Cancun + - costRevert_d14g0v0_Cancun + - costRevert_d21g0v0_Cancun + - costRevert_d7g0v0_Cancun + - stateRevert_d0g0v0_Cancun stSStoreTest: - - InitCollisionNonZeroNonce_d1g0v0_Shanghai - - InitCollision_d1g0v0_Shanghai - - sstore_0to0_d3g1v0_Shanghai - - InitCollisionNonZeroNonce_d3g0v0_Shanghai - - InitCollision_d3g0v0_Shanghai - - sstore_0to0_d0g1v0_Shanghai - - sstore_0to0_d1g1v0_Shanghai - - sstore_0to0_d2g1v0_Shanghai - - sstore_0to0to0_d3g1v0_Shanghai - - sstore_0to0_d4g0v0_Shanghai - - sstore_0to0to0_d0g1v0_Shanghai - - sstore_0to0_d4g1v0_Shanghai - - sstore_0to0to0_d1g1v0_Shanghai - - sstore_0to0to0_d2g1v0_Shanghai - - sstore_0to0toX_d3g1v0_Shanghai - - sstore_0to0to0_d4g1v0_Shanghai - - sstore_0to0to0_d4g0v0_Shanghai - - sstore_0to0toX_d0g1v0_Shanghai - - sstore_0to0toX_d1g1v0_Shanghai - - sstore_0to0toX_d2g1v0_Shanghai - - sstore_0toX_d3g1v0_Shanghai - - sstore_0to0toX_d4g0v0_Shanghai - - sstore_0toX_d0g1v0_Shanghai - - sstore_0to0toX_d4g1v0_Shanghai - - sstore_0toX_d1g1v0_Shanghai - - sstore_0toX_d2g1v0_Shanghai - - sstore_0toXto0_d3g1v0_Shanghai - - sstore_0toXto0_d0g1v0_Shanghai - - sstore_0toXto0_d1g1v0_Shanghai - - sstore_0toX_d4g0v0_Shanghai - - sstore_0toXto0_d2g1v0_Shanghai - - sstore_0toX_d4g1v0_Shanghai - - sstore_0toXto0toX_d3g1v0_Shanghai - - sstore_0toXto0toX_d0g1v0_Shanghai - - sstore_0toXto0toX_d1g1v0_Shanghai - - sstore_0toXto0_d4g0v0_Shanghai - - sstore_0toXto0_d4g1v0_Shanghai - - sstore_0toXto0toX_d2g1v0_Shanghai - - sstore_0toXtoX_d3g1v0_Shanghai - - sstore_0toXtoX_d0g1v0_Shanghai - - sstore_0toXtoX_d1g1v0_Shanghai - - sstore_0toXto0toX_d4g0v0_Shanghai - - sstore_0toXto0toX_d4g1v0_Shanghai - - sstore_0toXtoX_d2g1v0_Shanghai - - sstore_0toXtoY_d3g1v0_Shanghai - - sstore_0toXtoY_d0g1v0_Shanghai - - sstore_0toXtoY_d1g1v0_Shanghai - - sstore_0toXtoX_d4g0v0_Shanghai - - sstore_0toXtoY_d2g1v0_Shanghai - - sstore_0toXtoX_d4g1v0_Shanghai - - sstore_Xto0_d3g1v0_Shanghai - - sstore_Xto0_d0g1v0_Shanghai - - sstore_Xto0_d1g1v0_Shanghai - - sstore_0toXtoY_d4g0v0_Shanghai - - sstore_0toXtoY_d4g1v0_Shanghai - - sstore_Xto0_d2g1v0_Shanghai - - sstore_Xto0to0_d3g1v0_Shanghai - - sstore_Xto0to0_d0g1v0_Shanghai - - sstore_Xto0_d4g0v0_Shanghai - - sstore_Xto0to0_d1g1v0_Shanghai - - sstore_Xto0_d4g1v0_Shanghai - - sstore_Xto0to0_d2g1v0_Shanghai - - sstore_Xto0toX_d3g1v0_Shanghai - - sstore_Xto0toX_d0g1v0_Shanghai - - sstore_Xto0toX_d1g1v0_Shanghai - - sstore_Xto0toX_d2g1v0_Shanghai - - sstore_Xto0to0_d4g0v0_Shanghai - - sstore_Xto0to0_d4g1v0_Shanghai - - sstore_Xto0toXto0_d3g1v0_Shanghai - - sstore_Xto0toX_d4g0v0_Shanghai - - sstore_Xto0toXto0_d0g1v0_Shanghai - - sstore_Xto0toXto0_d1g1v0_Shanghai - - sstore_Xto0toXto0_d2g1v0_Shanghai - - sstore_Xto0toX_d4g1v0_Shanghai - - sstore_Xto0toY_d3g1v0_Shanghai - - sstore_Xto0toY_d0g1v0_Shanghai - - sstore_Xto0toY_d1g1v0_Shanghai - - sstore_Xto0toY_d2g1v0_Shanghai - - sstore_Xto0toXto0_d4g0v0_Shanghai - - sstore_Xto0toXto0_d4g1v0_Shanghai - - sstore_XtoX_d3g1v0_Shanghai - - sstore_Xto0toY_d4g0v0_Shanghai - - sstore_XtoX_d0g1v0_Shanghai - - sstore_Xto0toY_d4g1v0_Shanghai - - sstore_XtoX_d1g1v0_Shanghai - - sstore_XtoX_d2g1v0_Shanghai - - sstore_XtoXto0_d3g1v0_Shanghai - - sstore_XtoXto0_d0g1v0_Shanghai - - sstore_XtoX_d4g0v0_Shanghai - - sstore_XtoX_d4g1v0_Shanghai - - sstore_XtoXto0_d1g1v0_Shanghai - - sstore_XtoXto0_d2g1v0_Shanghai - - sstore_XtoXtoX_d3g1v0_Shanghai - - sstore_XtoXtoX_d0g1v0_Shanghai - - sstore_XtoXto0_d4g0v0_Shanghai - - sstore_XtoXto0_d4g1v0_Shanghai - - sstore_XtoXtoX_d2g1v0_Shanghai - - sstore_XtoXtoX_d1g1v0_Shanghai - - sstore_XtoXtoY_d3g1v0_Shanghai - - sstore_XtoXtoY_d0g1v0_Shanghai - - sstore_XtoXtoX_d4g0v0_Shanghai - - sstore_XtoXtoY_d1g1v0_Shanghai - - sstore_XtoXtoX_d4g1v0_Shanghai - - sstore_XtoXtoY_d2g1v0_Shanghai - - sstore_XtoY_d3g1v0_Shanghai - - sstore_XtoY_d0g1v0_Shanghai - - sstore_XtoXtoY_d4g0v0_Shanghai - - sstore_XtoY_d1g1v0_Shanghai - - sstore_XtoY_d2g1v0_Shanghai - - sstore_XtoXtoY_d4g1v0_Shanghai - - sstore_XtoYto0_d3g1v0_Shanghai - - sstore_XtoY_d4g0v0_Shanghai - - sstore_XtoYto0_d0g1v0_Shanghai - - sstore_XtoYto0_d1g1v0_Shanghai - - sstore_XtoYto0_d2g1v0_Shanghai - - sstore_XtoY_d4g1v0_Shanghai - - sstore_XtoYtoX_d3g1v0_Shanghai - - sstore_XtoYtoX_d0g1v0_Shanghai - - sstore_XtoYtoX_d1g1v0_Shanghai - - sstore_XtoYto0_d4g0v0_Shanghai - - sstore_XtoYto0_d4g1v0_Shanghai - - sstore_XtoYtoX_d2g1v0_Shanghai - - sstore_XtoYtoY_d3g1v0_Shanghai - - sstore_XtoYtoY_d0g1v0_Shanghai - - sstore_XtoYtoX_d4g0v0_Shanghai - - sstore_XtoYtoY_d1g1v0_Shanghai - - sstore_XtoYtoX_d4g1v0_Shanghai - - sstore_XtoYtoY_d2g1v0_Shanghai - - sstore_XtoYtoZ_d3g1v0_Shanghai - - sstore_XtoYtoZ_d0g1v0_Shanghai - - sstore_changeFromExternalCallInInitCode_d12g0v0_Shanghai - - sstore_XtoYtoY_d4g0v0_Shanghai - - sstore_XtoYtoZ_d1g1v0_Shanghai - - sstore_XtoYtoY_d4g1v0_Shanghai - - sstore_XtoYtoZ_d2g1v0_Shanghai - - sstore_gasLeft_d0g0v0_Shanghai - - sstore_gasLeft_d1g0v0_Shanghai - - sstore_changeFromExternalCallInInitCode_d13g0v0_Shanghai - - sstore_changeFromExternalCallInInitCode_d1g0v0_Shanghai - - sstore_gasLeft_d4g0v0_Shanghai - - sstore_gasLeft_d3g0v0_Shanghai - - sstore_gasLeft_d6g0v0_Shanghai - - sstore_gasLeft_d7g0v0_Shanghai - - sstore_changeFromExternalCallInInitCode_d5g0v0_Shanghai - - sstore_XtoYtoZ_d4g0v0_Shanghai - - sstore_changeFromExternalCallInInitCode_d15g0v0_Shanghai - - sstore_changeFromExternalCallInInitCode_d9g0v0_Shanghai - - sstore_XtoYtoZ_d4g1v0_Shanghai - - sstore_changeFromExternalCallInInitCode_d11g0v0_Shanghai - - sstore_changeFromExternalCallInInitCode_d3g0v0_Shanghai - - sstore_changeFromExternalCallInInitCode_d7g0v0_Shanghai + - SstoreCallToSelfSubRefundBelowZero_d0g0v0_Cancun stSelfBalance: - - diffPlaces_d0g0v0_Shanghai - - diffPlaces_d1g0v0_Shanghai - - diffPlaces_d2g0v0_Shanghai - - diffPlaces_d3g0v0_Shanghai - - diffPlaces_d4g0v0_Shanghai - - diffPlaces_d5g0v0_Shanghai - - diffPlaces_d6g0v0_Shanghai - - diffPlaces_d10g0v0_Shanghai - - diffPlaces_d11g0v0_Shanghai - - diffPlaces_d12g0v0_Shanghai - - diffPlaces_d13g0v0_Shanghai - - diffPlaces_d14g0v0_Shanghai - - diffPlaces_d15g0v0_Shanghai - - diffPlaces_d16g0v0_Shanghai - - diffPlaces_d17g0v0_Shanghai - - diffPlaces_d7g0v0_Shanghai - - diffPlaces_d18g0v0_Shanghai - - diffPlaces_d19g0v0_Shanghai - - diffPlaces_d20g0v0_Shanghai - - diffPlaces_d8g0v0_Shanghai - - diffPlaces_d21g0v0_Shanghai - - diffPlaces_d9g0v0_Shanghai - - diffPlaces_d22g0v0_Shanghai - - diffPlaces_d24g0v0_Shanghai - - diffPlaces_d23g0v0_Shanghai - - diffPlaces_d25g0v0_Shanghai - - diffPlaces_d26g0v0_Shanghai - - diffPlaces_d28g0v0_Shanghai - - diffPlaces_d27g0v0_Shanghai - - diffPlaces_d31g0v0_Shanghai - - diffPlaces_d30g0v0_Shanghai - - diffPlaces_d29g0v0_Shanghai - - diffPlaces_d32g0v0_Shanghai - - diffPlaces_d33g0v0_Shanghai - - diffPlaces_d34g0v0_Shanghai - stShift: - - sar_2_xor_255_256_d0g0v0_Shanghai - - sar_2_xor_255_minus_1_256_d0g0v0_Shanghai - - sar_2_xor_256_minus_1_256_d0g0v0_Shanghai - - shiftSignedCombinations_d0g0v0_Shanghai - - shiftCombinations_d0g0v0_Shanghai + - diffPlaces_d34g0v0_Cancun stSolidityTest: - - TestCryptographicFunctions_d0g0v0_Shanghai - - TestStructuresAndVariabless_d0g0v0_Shanghai - - SelfDestruct_d2g0v0_Shanghai - - SelfDestruct_d1g0v0_Shanghai - - SelfDestruct_d0g0v0_Shanghai - - RecursiveCreateContractsCreate4Contracts_d0g0v0_Shanghai - - RecursiveCreateContracts_d0g0v0_Shanghai + - CallInfiniteLoop_d0g0v0_Cancun + - TestCryptographicFunctions_d0g0v0_Cancun stSpecialTest: - - eoaEmpty_d0g0v1_Shanghai - - eoaEmpty_d1g0v1_Shanghai - - eoaEmpty_d0g0v0_Shanghai - - eoaEmpty_d0g1v0_Shanghai - - sha3_deja_d0g0v0_Shanghai - - makeMoney_d0g0v0_Shanghai - - eoaEmpty_d0g1v1_Shanghai - - eoaEmpty_d1g0v0_Shanghai - - eoaEmpty_d1g1v0_Shanghai - - eoaEmpty_d1g1v1_Shanghai - - selfdestructEIP2929_d0g0v0_Shanghai - - JUMPDEST_AttackwithJump_d0g0v0_Shanghai - - JUMPDEST_Attack_d0g0v0_Shanghai - - deploymentError_d0g0v0_Shanghai - - block504980_d0g0v0_Shanghai - - tx_e1c174e2_d0g0v0_Shanghai - stStackTests: - - stackOverflowM1DUP_d0g0v0_Shanghai - - stackOverflowM1DUP_d10g0v0_Shanghai - - stackOverflowM1DUP_d11g0v0_Shanghai - - stackOverflowM1DUP_d12g0v0_Shanghai - - stackOverflowM1DUP_d13g0v0_Shanghai - - stackOverflowM1DUP_d14g0v0_Shanghai - - stackOverflowM1DUP_d15g0v0_Shanghai - - stackOverflowM1DUP_d1g0v0_Shanghai - - stackOverflowM1DUP_d2g0v0_Shanghai - - stackOverflowM1DUP_d3g0v0_Shanghai - - stackOverflowM1DUP_d4g0v0_Shanghai - - stackOverflowM1DUP_d5g0v0_Shanghai - - stackOverflowM1DUP_d6g0v0_Shanghai - - stackOverflowM1DUP_d7g0v0_Shanghai - - stackOverflowM1DUP_d8g0v0_Shanghai - - stackOverflowM1DUP_d9g0v0_Shanghai - - stackOverflowM1PUSH_d0g0v0_Shanghai - - stackOverflowM1PUSH_d1g0v0_Shanghai - - stackOverflowM1PUSH_d11g0v0_Shanghai - - stackOverflowM1PUSH_d10g0v0_Shanghai - - stackOverflowM1PUSH_d12g0v0_Shanghai - - stackOverflowM1PUSH_d13g0v0_Shanghai - - stackOverflowM1PUSH_d14g0v0_Shanghai - - stackOverflowM1PUSH_d16g0v0_Shanghai - - stackOverflowM1PUSH_d17g0v0_Shanghai - - stackOverflowM1PUSH_d15g0v0_Shanghai - - stackOverflowM1PUSH_d18g0v0_Shanghai - - stackOverflowM1PUSH_d19g0v0_Shanghai - - stackOverflowM1PUSH_d20g0v0_Shanghai - - stackOverflowM1PUSH_d21g0v0_Shanghai - - stackOverflowM1PUSH_d22g0v0_Shanghai - - stackOverflowM1PUSH_d24g0v0_Shanghai - - stackOverflowM1PUSH_d23g0v0_Shanghai - - stackOverflowM1PUSH_d25g0v0_Shanghai - - stackOverflowM1PUSH_d26g0v0_Shanghai - - stackOverflowM1PUSH_d27g0v0_Shanghai - - stackOverflowM1PUSH_d28g0v0_Shanghai - - stackOverflowM1PUSH_d29g0v0_Shanghai - - stackOverflowM1PUSH_d2g0v0_Shanghai - - stackOverflowM1PUSH_d3g0v0_Shanghai - - stackOverflowM1PUSH_d4g0v0_Shanghai - - stackOverflowM1PUSH_d5g0v0_Shanghai - - stackOverflowM1PUSH_d30g0v0_Shanghai - - stackOverflowM1PUSH_d6g0v0_Shanghai - - stackOverflowM1PUSH_d7g0v0_Shanghai - - stackOverflowM1PUSH_d9g0v0_Shanghai - - stackOverflowM1PUSH_d8g0v0_Shanghai - - stackOverflowM1_d0g0v0_Shanghai - - stackOverflowM1_d10g0v0_Shanghai - - stackOverflowM1_d11g0v0_Shanghai - - stackOverflowM1_d12g0v0_Shanghai - - stackOverflowM1_d15g0v0_Shanghai - - stackOverflowM1_d13g0v0_Shanghai - - stackOverflowM1_d14g0v0_Shanghai - - stackOverflowM1_d1g0v0_Shanghai - - stackOverflowM1_d4g0v0_Shanghai - - stackOverflowM1_d2g0v0_Shanghai - - stackOverflowM1_d3g0v0_Shanghai - - stackOverflowM1_d5g0v0_Shanghai - - stackOverflowM1_d6g0v0_Shanghai - - stackOverflowM1_d7g0v0_Shanghai - - stackOverflowM1_d8g0v0_Shanghai - - stackOverflowM1_d9g0v0_Shanghai - - stackOverflowPUSH_d17g0v0_Shanghai - - stackOverflowPUSH_d18g0v0_Shanghai - - stackOverflowPUSH_d19g0v0_Shanghai - - stackOverflowPUSH_d20g0v0_Shanghai - - stackOverflowPUSH_d21g0v0_Shanghai - - stackOverflowPUSH_d23g0v0_Shanghai - - stackOverflowPUSH_d22g0v0_Shanghai - - stackOverflowPUSH_d24g0v0_Shanghai - - stackOverflowPUSH_d25g0v0_Shanghai - - stackOverflowSWAP_d0g0v0_Shanghai - - stackOverflowPUSH_d26g0v0_Shanghai - - stackOverflowPUSH_d27g0v0_Shanghai - - stackOverflowPUSH_d28g0v0_Shanghai - - stackOverflowPUSH_d29g0v0_Shanghai - - stackOverflowPUSH_d30g0v0_Shanghai - - stacksanitySWAP_d0g0v0_Shanghai + - JUMPDEST_Attack_d0g0v0_Cancun + - JUMPDEST_AttackwithJump_d0g0v0_Cancun + - block504980_d0g0v0_Cancun + - selfdestructEIP2929_d0g0v0_Cancun + - sha3_deja_d0g0v0_Cancun + stShift: + - shiftCombinations_d0g0v0_Cancun + - shiftSignedCombinations_d0g0v0_Cancun stStaticCall: - - StaticcallToPrecompileFromCalledContract_d0g0v0_Shanghai - - StaticcallToPrecompileFromTransaction_d0g0v0_Shanghai - - static_CREATE_EmptyContractAndCallIt_0wei_d0g0v0_Shanghai - - static_CREATE_EmptyContractWithStorageAndCallIt_0wei_d0g0v0_Shanghai - - StaticcallToPrecompileFromContractInitialization_d0g0v0_Shanghai - - static_ABAcalls2_d1g0v0_Shanghai - - static_ABAcalls1_d1g0v0_Shanghai - - static_ABAcalls1_d0g0v0_Shanghai - - static_Call1024BalanceTooLow2_d1g0v0_Shanghai - - static_Call1024BalanceTooLow_d1g0v0_Shanghai - - static_CallContractToCreateContractOOGBonusGas_d0g1v0_Shanghai - - static_CallEcrecover0_0input_d1g0v0_Shanghai - - static_CallEcrecover0_0input_d2g0v0_Shanghai - - static_CallEcrecover0_0input_d3g0v0_Shanghai - - static_CallEcrecover0_0input_d4g0v0_Shanghai - - static_Call1024OOG_d1g0v0_Shanghai - - static_CallEcrecover0_0input_d5g0v0_Shanghai - - static_CallEcrecover0_0input_d6g0v0_Shanghai - - static_CallEcrecover0_0input_d7g0v0_Shanghai - - static_CallEcrecover0_0input_d8g0v0_Shanghai - - static_CallEcrecover0_Gas2999_d0g0v0_Shanghai - - static_CallEcrecover0_NoGas_d0g0v0_Shanghai - - static_ABAcallsSuicide1_d1g0v0_Shanghai - - static_CallEcrecover0_completeReturnValue_d0g0v0_Shanghai - - static_CallEcrecover0_d0g0v0_Shanghai - - static_CallEcrecover0_gas3000_d0g0v0_Shanghai - - static_CallEcrecover0_overlappingInputOutput_d0g0v0_Shanghai - - static_CallEcrecover1_d0g0v0_Shanghai - - static_CallEcrecover2_d0g0v0_Shanghai - - static_CallEcrecover3_d0g0v0_Shanghai - - static_CallEcrecover80_d0g0v0_Shanghai - - static_CallEcrecoverCheckLengthWrongV_d0g0v0_Shanghai - - static_CallEcrecoverH_prefixed0_d0g0v0_Shanghai - - static_CallEcrecoverCheckLength_d0g0v0_Shanghai - - static_CallEcrecoverR_prefixed0_d0g0v0_Shanghai - - static_CallEcrecoverS_prefixed0_d0g0v0_Shanghai - - static_Call1024PreCalls2_d1g0v0_Shanghai - - static_CallEcrecoverV_prefixed0_d0g0v0_Shanghai - - static_CallIdentitiy_1_d0g0v0_Shanghai - - static_CallIdentity_2_d0g0v0_Shanghai - - static_CallIdentity_1_nonzeroValue_d0g0v0_Shanghai - - static_CallIdentity_3_d0g0v0_Shanghai - - static_CallIdentity_4_d0g0v0_Shanghai - - static_CallIdentity_4_gas17_d0g0v0_Shanghai - - static_CallIdentity_4_gas18_d0g0v0_Shanghai - - static_Call1024PreCalls2_d0g0v0_Shanghai - - static_CallRipemd160_1_d0g0v0_Shanghai - - static_Call1024PreCalls3_d1g0v0_Shanghai - - static_CallRipemd160_2_d0g0v0_Shanghai - - static_Call10_d0g0v0_Shanghai - - static_CallRipemd160_3_d0g0v0_Shanghai - - static_Call1024PreCalls_d1g0v0_Shanghai - - static_Call10_d1g0v0_Shanghai - - static_CallRipemd160_3_postfixed0_d0g0v0_Shanghai - - static_CallRipemd160_3_prefixed0_d0g0v0_Shanghai - - static_CallRipemd160_4_d0g0v0_Shanghai - - static_CallRipemd160_4_gas719_d0g0v0_Shanghai - - static_CallSha256_1_d0g0v0_Shanghai - - static_Call1MB1024Calldepth_d0g0v0_Shanghai - - static_CallSha256_1_nonzeroValue_d0g0v0_Shanghai - - static_CallSha256_2_d0g0v0_Shanghai - - static_CallSha256_3_d0g0v0_Shanghai - - static_CallSha256_3_postfix0_d0g0v0_Shanghai - - static_CallSha256_3_prefix0_d0g0v0_Shanghai - - static_CallSha256_4_d0g0v0_Shanghai - - static_CallSha256_4_gas99_d0g0v0_Shanghai - - static_Call1MB1024Calldepth_d1g0v0_Shanghai - - static_Call50000_ecrec_d0g0v0_Shanghai - - static_Call50000_ecrec_d1g0v0_Shanghai - - static_Call50000_identity2_d0g0v0_Shanghai - - static_Call50000_d0g0v0_Shanghai - - static_Call50000_identity2_d1g0v0_Shanghai - - static_Call50000_d1g0v0_Shanghai - - static_Call50000_identity_d0g0v0_Shanghai - - static_Call50000_rip160_d0g0v0_Shanghai - - static_Call50000_identity_d1g0v0_Shanghai - - static_Call50000_rip160_d1g0v0_Shanghai - - static_RETURN_BoundsOOG_d1g0v0_Shanghai - - static_RETURN_Bounds_d0g0v0_Shanghai - - static_CallRecursiveBomb0_d0g0v0_Shanghai - - static_callOutput3Fail_d0g0v0_Shanghai - - static_callOutput3_d0g0v0_Shanghai - - static_CallRecursiveBombPreCall2_d0g0v0_Shanghai - - static_CallRecursiveBomb1_d0g0v0_Shanghai - - static_callOutput3partialFail_d0g0v0_Shanghai - - static_CallRecursiveBomb2_d0g0v0_Shanghai - - static_callOutput3partial_d0g0v0_Shanghai - - static_Call50000bytesContract50_1_d0g0v0_Shanghai - - static_Call50000bytesContract50_1_d1g0v0_Shanghai - - static_CallRecursiveBombPreCall_d0g0v0_Shanghai - - static_Call50000bytesContract50_2_d0g0v0_Shanghai - - static_Call50000bytesContract50_2_d1g0v0_Shanghai - - static_CallRecursiveBomb0_OOG_atMaxCallDepth_d0g0v0_Shanghai - - static_Call50000bytesContract50_3_d0g0v0_Shanghai - - static_Call50000bytesContract50_3_d1g0v0_Shanghai - - static_CallIdentity_5_d0g0v0_Shanghai - - static_CallRipemd160_5_d0g0v0_Shanghai - - static_CallSha256_5_d0g0v0_Shanghai - - static_LoopCallsThenRevert_d0g0v0_Shanghai - - static_LoopCallsThenRevert_d0g1v0_Shanghai - - static_callcall_00_OOGE_1_d1g0v0_Shanghai - - static_callcallcallcode_001_OOGE_d0g0v0_Shanghai - - static_callcallcallcode_001_OOGE_2_d1g0v0_Shanghai - - static_callcallcall_000_OOGMBefore_d0g0v0_Shanghai - - static_Return50000_2_d0g0v0_Shanghai - - static_callCreate2_d2g0v0_Shanghai - - static_callcallcall_000_OOGMAfter2_d0g0v0_Shanghai - - static_callcallcallcode_001_OOGMAfter2_d1g0v0_Shanghai - - static_callcallcallcode_001_OOGMAfter_2_d1g0v0_Shanghai - - static_callcallcallcode_001_OOGMAfter_3_d1g0v0_Shanghai - - static_callcallcodecall_010_OOGE_2_d1g0v0_Shanghai - - static_callcode_checkPC_d0g0v0_Shanghai - - static_callcallcallcode_001_OOGMBefore2_d1g0v0_Shanghai - - static_callcallcallcode_001_OOGMAfter_d1g0v0_Shanghai - - static_callChangeRevert_d1g0v0_Shanghai - - static_callcallcallcode_001_OOGMBefore_d0g0v0_Shanghai - - static_callcallcodecall_010_OOGE_d0g0v0_Shanghai - - static_callcallcodecall_010_OOGMAfter2_d0g0v0_Shanghai - - static_callcallcodecall_010_OOGMAfter_2_d1g0v0_Shanghai - - static_callcallcodecall_010_OOGMAfter_3_d1g0v0_Shanghai - - static_callcallcodecall_010_OOGMAfter_d1g0v0_Shanghai - - static_callcallcodecall_010_OOGMBefore2_d0g0v0_Shanghai - - static_callcallcodecall_010_OOGMBefore_d1g0v0_Shanghai - - static_callcallcodecallcode_011_OOGMAfter2_d1g0v0_Shanghai - - static_callcallcodecallcode_011_OOGMAfter_1_d1g0v0_Shanghai - - static_callcallcodecallcode_011_OOGMAfter_2_d1g0v0_Shanghai - - static_callcallcodecallcode_011_OOGMAfter_d1g0v0_Shanghai - - static_callcallcodecallcode_011_OOGMBefore2_d1g0v0_Shanghai - - static_callcallcodecallcode_011_OOGMBefore_d1g0v0_Shanghai - - static_callcodecallcall_100_OOGMAfter2_d0g0v0_Shanghai - - static_callcodecallcall_100_OOGMAfter2_d0g0v1_Shanghai - - static_callcodecallcall_100_OOGMBefore2_d0g0v0_Shanghai - - static_callcodecallcall_100_OOGMAfter_3_d0g0v1_Shanghai - - static_callcodecallcall_100_OOGMAfter_2_d0g0v0_Shanghai - - static_callcodecallcall_100_OOGMAfter_3_d0g0v0_Shanghai - - static_callcodecallcall_100_OOGMAfter_d0g0v0_Shanghai - - static_callcodecallcall_100_OOGMBefore2_d0g0v1_Shanghai - - static_callcodecallcallcode_101_OOGE_d0g0v0_Shanghai - - static_callcodecallcall_100_OOGMBefore_d0g0v0_Shanghai - - static_contractCreationMakeCallThatAskMoreGasThenTransactionProvided_d0g0v0_Shanghai - - static_callcodecallcallcode_101_OOGMAfter2_d0g0v0_Shanghai - - static_callcodecallcallcode_101_OOGMAfter_1_d0g0v0_Shanghai - - static_callcodecallcallcode_101_OOGMAfter2_d0g0v1_Shanghai - - static_callcodecallcallcode_101_OOGMAfter_3_d0g0v0_Shanghai - - static_callcodecallcallcode_101_OOGMBefore2_d0g0v0_Shanghai - - static_callcodecallcallcode_101_OOGMBefore_d0g0v0_Shanghai - - static_callcodecallcallcode_101_OOGMBefore2_d0g0v1_Shanghai - - static_callcodecallcallcode_101_OOGMAfter_d0g0v0_Shanghai - - static_makeMoney_d0g0v0_Shanghai - - static_callcodecallcodecall_110_OOGMAfter_2_d0g0v0_Shanghai - - static_callcodecallcodecall_110_OOGMAfter2_d0g0v0_Shanghai - - static_callcodecallcodecall_110_OOGMAfter2_d0g0v1_Shanghai - - static_callcodecallcodecall_110_OOGMAfter2_d0g0v2_Shanghai - - static_callcodecallcodecall_110_OOGMAfter_d0g0v0_Shanghai - - static_callcodecallcodecall_110_OOGMBefore2_d0g0v1_Shanghai - - static_callcodecallcodecall_110_OOGMBefore2_d0g0v2_Shanghai - - static_callcodecallcodecall_110_OOGMBefore_d0g0v0_Shanghai - - static_callcodecallcodecall_110_OOGMAfter_3_d0g0v0_Shanghai - - static_contractCreationMakeCallThatAskMoreGasThenTransactionProvided_d2g0v0_Shanghai - - static_contractCreationOOGdontLeaveEmptyContractViaTransaction_d0g0v0_Shanghai - stStaticFlagEnabled: - - CallWithNOTZeroValueToPrecompileFromContractInitialization_d0g0v0_Shanghai - - CallWithNOTZeroValueToPrecompileFromContractInitialization_d1g0v0_Shanghai - - CallWithNOTZeroValueToPrecompileFromContractInitialization_d2g0v0_Shanghai - - CallWithNOTZeroValueToPrecompileFromContractInitialization_d3g0v0_Shanghai - - CallWithNOTZeroValueToPrecompileFromContractInitialization_d6g0v0_Shanghai - - CallWithNOTZeroValueToPrecompileFromContractInitialization_d4g0v0_Shanghai - - CallWithNOTZeroValueToPrecompileFromContractInitialization_d5g0v0_Shanghai - - CallWithNOTZeroValueToPrecompileFromContractInitialization_d7g0v0_Shanghai - - CallWithZeroValueToPrecompileFromTransaction_d0g0v0_Shanghai - - CallWithZeroValueToPrecompileFromCalledContract_d0g0v0_Shanghai - - DelegatecallToPrecompileFromTransaction_d0g0v0_Shanghai - - DelegatecallToPrecompileFromCalledContract_d0g0v0_Shanghai - - CallWithZeroValueToPrecompileFromContractInitialization_d0g0v0_Shanghai - - CallcodeToPrecompileFromTransaction_d0g0v0_Shanghai - - CallcodeToPrecompileFromCalledContract_d0g0v0_Shanghai - - DelegatecallToPrecompileFromContractInitialization_d0g0v0_Shanghai - - CallcodeToPrecompileFromContractInitialization_d0g0v0_Shanghai + - static_Call1024BalanceTooLow2_d1g0v0_Cancun + - static_Call1024BalanceTooLow_d1g0v0_Cancun + - static_Call1024PreCalls2_d0g0v0_Cancun + - static_Call1024PreCalls2_d1g0v0_Cancun + - static_Call1024PreCalls3_d1g0v0_Cancun + - static_Call1024PreCalls_d1g0v0_Cancun + - static_Call50000bytesContract50_3_d0g0v0_Cancun + - static_Call50000bytesContract50_3_d1g0v0_Cancun + - static_CallEcrecover0_0input_d3g0v0_Cancun + - static_CallEcrecover0_0input_d8g0v0_Cancun + - static_CallGoesOOGOnSecondLevel2_d1g0v0_Cancun + - static_CallRecursiveBomb0_OOG_atMaxCallDepth_d0g0v0_Cancun + - static_CallRecursiveBombPreCall2_d0g0v0_Cancun + - static_CallRecursiveBombPreCall_d0g0v0_Cancun + - static_CallRipemd160_1_d0g0v0_Cancun + - static_CallRipemd160_2_d0g0v0_Cancun + - static_CallRipemd160_3_d0g0v0_Cancun + - static_CallRipemd160_3_postfixed0_d0g0v0_Cancun + - static_CallRipemd160_3_prefixed0_d0g0v0_Cancun + - static_CallRipemd160_4_d0g0v0_Cancun + - static_CallRipemd160_4_gas719_d0g0v0_Cancun + - static_LoopCallsDepthThenRevert2_d0g0v0_Cancun + - static_LoopCallsDepthThenRevert3_d0g0v0_Cancun + - static_callChangeRevert_d1g0v0_Cancun + - static_callCreate2_d2g0v0_Cancun + - static_callcallcall_000_OOGMAfter2_d0g0v0_Cancun + - static_callcallcall_000_OOGMBefore_d0g0v0_Cancun + - static_callcallcallcode_001_OOGE_2_d1g0v0_Cancun + - static_callcallcallcode_001_OOGE_d0g0v0_Cancun + - static_callcallcallcode_001_OOGMAfter2_d1g0v0_Cancun + - static_callcallcallcode_001_OOGMAfter_3_d1g0v0_Cancun + - static_callcallcallcode_001_OOGMAfter_d1g0v0_Cancun + - static_callcallcallcode_001_OOGMBefore2_d1g0v0_Cancun + - static_callcallcallcode_001_OOGMBefore_d0g0v0_Cancun + - static_callcallcodecall_010_OOGE_2_d1g0v0_Cancun + - static_callcallcodecall_010_OOGE_d0g0v0_Cancun + - static_callcallcodecall_010_OOGMAfter_2_d1g0v0_Cancun + - static_callcallcodecall_010_OOGMAfter_3_d1g0v0_Cancun + - static_callcallcodecall_010_OOGMAfter_d1g0v0_Cancun + - static_callcallcodecall_010_OOGMBefore2_d0g0v0_Cancun + - static_callcallcodecall_010_OOGMBefore_d1g0v0_Cancun + - static_callcodecallcall_100_OOGMAfter2_d0g0v0_Cancun + - static_callcodecallcall_100_OOGMAfter2_d0g0v1_Cancun + - static_callcodecallcall_100_OOGMAfter_2_d0g0v0_Cancun + - static_callcodecallcallcode_101_OOGE_d0g0v0_Cancun + - static_callcodecallcallcode_101_OOGMAfter_1_d0g0v0_Cancun stSystemOperationsTest: - - ABAcalls0_d0g0v0_Shanghai - - ABAcallsSuicide0_d0g0v0_Shanghai - - ABAcallsSuicide1_d0g0v0_Shanghai - - CallToNameRegistratorNotMuchMemory0_d0g0v0_Shanghai - - CallToNameRegistratorNotMuchMemory1_d0g0v0_Shanghai - - callerAccountBalance_d0g0v0_Shanghai - - createNameRegistratorZeroMem2_d0g0v0_Shanghai - - createWithInvalidOpcode_d0g0v0_Shanghai - - ABAcallsSuicide1_d1g0v0_Shanghai - - doubleSelfdestructTouch_d0g0v2_Shanghai - - extcodecopy_d0g0v0_Shanghai - - doubleSelfdestructTest_d0g0v0_Shanghai - - doubleSelfdestructTest_d5g0v0_Shanghai - - doubleSelfdestructTest_d2g0v0_Shanghai - - doubleSelfdestructTest_d1g0v0_Shanghai - - doubleSelfdestructTest_d4g0v0_Shanghai - - doubleSelfdestructTest_d6g0v0_Shanghai - - testRandomTest_d0g0v0_Shanghai - - multiSelfdestruct_d0g0v0_Shanghai - - multiSelfdestruct_d1g0v0_Shanghai - - multiSelfdestruct_d2g0v0_Shanghai - - ABAcalls3_d0g0v0_Shanghai - - multiSelfdestruct_d3g0v0_Shanghai - - multiSelfdestruct_d4g0v0_Shanghai - - suicideSendEtherPostDeath_d0g0v0_Shanghai - - ABAcalls2_d0g0v0_Shanghai - - CallRecursiveBomb0_d0g0v0_Shanghai - - CallRecursiveBomb1_d0g0v0_Shanghai - - ABAcalls1_d0g0v0_Shanghai - - CallRecursiveBomb2_d0g0v0_Shanghai - - CallRecursiveBomb3_d0g0v0_Shanghai - - CallRecursiveBomb0_OOG_atMaxCallDepth_d0g0v0_Shanghai - - Call10_d0g0v0_Shanghai - - CallRecursiveBombLog2_d0g0v0_Shanghai - - CallRecursiveBombLog_d0g0v0_Shanghai - stTimeConsuming: - - CALLBlake2f_MaxRounds_d0g0v0_Shanghai - - static_Call50000_sha256_d1g0v0_Shanghai - - static_Call50000_sha256_d0g0v0_Shanghai - stTransactionTest: - - HighGasPrice_d0g0v0_Shanghai - - InternalCallHittingGasLimit2_d0g0v0_Shanghai - - Opcodes_TransactionInit_d120g0v0_Shanghai - - Opcodes_TransactionInit_d23g0v0_Shanghai - - ValueOverflow_d0g0v0_Shanghai - - OverflowGasRequire2_d0g0v0_Shanghai - - SuicidesAndInternlCallSuicidesBonusGasAtCall_d0g0v0_Shanghai - - PointAtInfinityECRecover_d0g0v0_Shanghai - - SuicidesAndInternlCallSuicidesSuccess_d0g0v0_Shanghai - - SuicidesAndInternlCallSuicidesSuccess_d1g0v0_Shanghai - - StoreGasOnCreate_d0g0v0_Shanghai - stWalletTest: - - multiOwnedRemoveOwner_d0g0v0_Shanghai - - multiOwnedIsOwnerFalse_d0g0v0_Shanghai - - multiOwnedIsOwnerTrue_d0g0v0_Shanghai - - multiOwnedConstructionCorrect_d0g0v0_Shanghai - - multiOwnedConstructionNotEnoughGasPartial_d0g1v0_Shanghai - - dayLimitConstruction_d0g0v0_Shanghai - - dayLimitConstructionPartial_d0g0v0_Shanghai - - dayLimitConstruction_d0g1v0_Shanghai - - multiOwnedRemoveOwnerByNonOwner_d0g0v0_Shanghai - - multiOwnedRemoveOwner_mySelf_d0g0v0_Shanghai - - multiOwnedRemoveOwner_ownerIsNotOwner_d0g0v0_Shanghai - - multiOwnedRevokeNothing_d0g0v0_Shanghai - - multiOwnedAddOwner_d0g0v0_Shanghai - - multiOwnedAddOwnerAddMyself_d0g0v0_Shanghai - - dayLimitResetSpentToday_d0g0v0_Shanghai - - multiOwnedChangeRequirementTo0_d0g0v0_Shanghai - - multiOwnedChangeRequirementTo2_d0g0v0_Shanghai - - multiOwnedChangeRequirementTo1_d0g0v0_Shanghai - - dayLimitSetDailyLimitNoData_d0g0v0_Shanghai - - dayLimitSetDailyLimit_d0g0v0_Shanghai - - multiOwnedChangeOwner_fromNotOwner_d0g0v0_Shanghai - - multiOwnedChangeOwnerNoArgument_d0g0v0_Shanghai - - multiOwnedChangeOwner_d0g0v0_Shanghai - - multiOwnedChangeOwner_toIsOwner_d0g0v0_Shanghai - - walletChangeRequirementRemovePendingTransaction_d0g0v0_Shanghai - - walletAddOwnerRemovePendingTransaction_d0g0v0_Shanghai - - walletChangeOwnerRemovePendingTransaction_d0g0v0_Shanghai - - walletConfirm_d0g0v0_Shanghai - - walletConstructionOOG_d0g1v0_Shanghai - - walletConstructionPartial_d0g0v0_Shanghai - - walletConstruction_d0g1v0_Shanghai - - walletConstruction_d0g0v0_Shanghai - - walletRemoveOwnerRemovePendingTransaction_d0g0v0_Shanghai - - walletExecuteOverDailyLimitOnlyOneOwner_d0g0v0_Shanghai - - walletExecuteOverDailyLimitOnlyOneOwnerNew_d0g0v0_Shanghai - - walletExecuteOverDailyLimitMultiOwner_d0g0v0_Shanghai - - walletKillNotByOwner_d0g0v0_Shanghai - - walletExecuteUnderDailyLimit_d0g0v0_Shanghai - - walletKill_d0g0v0_Shanghai - - walletKillToWallet_d0g0v0_Shanghai - stZeroKnowledge2: - - ecadd_0_minus_0_0_minus_0_21000_0_d0g1v0_Shanghai - - ecadd_0_minus_0_0_minus_0_21000_0_d0g3v0_Shanghai - - ecadd_0_minus_0_0_minus_0_21000_0_d0g2v0_Shanghai - - ecadd_0_minus_0_0_minus_0_21000_128_d0g1v0_Shanghai - - ecadd_0_minus_0_0_minus_0_21000_128_d0g2v0_Shanghai - - ecadd_0_minus_0_0_minus_0_21000_128_d0g3v0_Shanghai - - ecadd_0_minus_0_0_minus_0_21000_192_d0g1v0_Shanghai - - ecadd_0_minus_0_0_minus_0_21000_64_d0g1v0_Shanghai - - ecadd_0_minus_0_0_minus_0_21000_192_d0g2v0_Shanghai - - ecadd_0_minus_0_0_minus_0_21000_192_d0g3v0_Shanghai - - ecadd_0_minus_0_0_minus_0_21000_64_d0g2v0_Shanghai - - ecadd_0_minus_0_0_minus_0_21000_64_d0g3v0_Shanghai - - ecadd_0_minus_0_0_minus_0_21000_80_d0g1v0_Shanghai - - ecadd_0_minus_0_0_minus_0_21000_80_d0g2v0_Shanghai - - ecadd_0_minus_0_0_minus_0_21000_80_d0g3v0_Shanghai - - ecadd_0_minus_0_0_minus_0_25000_128_d0g0v0_Shanghai - - ecadd_0_minus_0_0_minus_0_25000_128_d0g1v0_Shanghai - - ecadd_0_minus_0_0_minus_0_25000_128_d0g2v0_Shanghai - - ecadd_0_minus_0_0_minus_0_25000_128_d0g3v0_Shanghai - - ecadd_0_minus_0_1_minus_2_21000_128_d0g1v0_Shanghai - - ecadd_0_minus_0_1_minus_2_21000_128_d0g2v0_Shanghai - - ecadd_0_minus_0_1_minus_2_21000_128_d0g3v0_Shanghai - - ecadd_0_minus_0_1_minus_2_21000_192_d0g1v0_Shanghai - - ecadd_0_minus_0_1_minus_2_25000_128_d0g0v0_Shanghai - - ecadd_0_minus_0_1_minus_2_25000_128_d0g1v0_Shanghai - - ecadd_0_minus_0_1_minus_2_21000_192_d0g2v0_Shanghai - - ecadd_0_minus_0_1_minus_2_21000_192_d0g3v0_Shanghai - - ecadd_0_minus_0_1_minus_2_25000_128_d0g2v0_Shanghai - - ecadd_0_minus_0_1_minus_2_25000_128_d0g3v0_Shanghai - - ecadd_1145_minus_3932_1145_minus_4651_21000_192_d0g1v0_Shanghai - - ecadd_1145_minus_3932_1145_minus_4651_21000_192_d0g2v0_Shanghai - - ecadd_1145_minus_3932_1145_minus_4651_21000_192_d0g3v0_Shanghai - - ecadd_1145_minus_3932_1145_minus_4651_25000_192_d0g1v0_Shanghai - - ecadd_1145_minus_3932_1145_minus_4651_25000_192_d0g0v0_Shanghai - - ecadd_1145_minus_3932_1145_minus_4651_25000_192_d0g2v0_Shanghai - - ecadd_1145_minus_3932_1145_minus_4651_25000_192_d0g3v0_Shanghai - - ecadd_1145_minus_3932_2969_minus_1336_21000_128_d0g2v0_Shanghai - - ecadd_1145_minus_3932_2969_minus_1336_21000_128_d0g1v0_Shanghai - - ecadd_1145_minus_3932_2969_minus_1336_21000_128_d0g3v0_Shanghai - - ecadd_1145_minus_3932_2969_minus_1336_25000_128_d0g0v0_Shanghai - - ecadd_1145_minus_3932_2969_minus_1336_25000_128_d0g1v0_Shanghai - - ecadd_1145_minus_3932_2969_minus_1336_25000_128_d0g3v0_Shanghai - - ecadd_1145_minus_3932_2969_minus_1336_25000_128_d0g2v0_Shanghai - - ecadd_1_minus_2_0_minus_0_21000_128_d0g1v0_Shanghai - - ecadd_1_minus_2_0_minus_0_21000_128_d0g2v0_Shanghai - - ecadd_1_minus_2_0_minus_0_21000_128_d0g3v0_Shanghai - - ecadd_1_minus_2_0_minus_0_21000_192_d0g1v0_Shanghai - - ecadd_1_minus_2_0_minus_0_21000_192_d0g2v0_Shanghai - - ecadd_1_minus_2_0_minus_0_21000_64_d0g1v0_Shanghai - - ecadd_1_minus_2_0_minus_0_21000_192_d0g3v0_Shanghai - - ecadd_1_minus_2_0_minus_0_21000_64_d0g2v0_Shanghai - - ecadd_1_minus_2_0_minus_0_21000_64_d0g3v0_Shanghai - - ecadd_1_minus_2_1_minus_2_21000_128_d0g1v0_Shanghai - - ecadd_1_minus_2_1_minus_2_21000_128_d0g2v0_Shanghai - - ecadd_1_minus_2_1_minus_2_21000_128_d0g3v0_Shanghai - - ecadd_1_minus_2_1_minus_2_21000_192_d0g1v0_Shanghai - - ecadd_1_minus_2_1_minus_2_21000_192_d0g2v0_Shanghai - - ecadd_1_minus_2_1_minus_2_25000_128_d0g0v0_Shanghai - - ecadd_1_minus_2_1_minus_2_21000_192_d0g3v0_Shanghai - - ecadd_1_minus_2_1_minus_2_25000_128_d0g1v0_Shanghai - - ecadd_1_minus_2_1_minus_2_25000_128_d0g2v0_Shanghai - - ecadd_1_minus_2_1_minus_2_25000_128_d0g3v0_Shanghai - - ecmul_0_minus_0_0_21000_0_d0g1v0_Shanghai - - ecmul_0_minus_0_0_21000_0_d0g3v0_Shanghai - - ecmul_0_minus_0_0_21000_0_d0g2v0_Shanghai - - ecmul_0_minus_0_0_21000_128_d0g1v0_Shanghai - - ecmul_0_minus_0_0_21000_128_d0g2v0_Shanghai - - ecmul_0_minus_0_0_21000_40_d0g1v0_Shanghai - - ecmul_0_minus_0_0_21000_128_d0g3v0_Shanghai - - ecmul_0_minus_0_0_21000_40_d0g2v0_Shanghai - - ecmul_0_minus_0_0_21000_40_d0g3v0_Shanghai - - ecmul_0_minus_0_0_21000_64_d0g1v0_Shanghai - - ecmul_0_minus_0_0_21000_64_d0g2v0_Shanghai - - ecmul_0_minus_0_0_21000_64_d0g3v0_Shanghai - - ecmul_0_minus_0_0_21000_80_d0g1v0_Shanghai - - ecmul_0_minus_0_0_21000_80_d0g2v0_Shanghai - - ecmul_0_minus_0_0_21000_80_d0g3v0_Shanghai - - ecmul_0_minus_0_0_21000_96_d0g2v0_Shanghai - - ecmul_0_minus_0_0_21000_96_d0g1v0_Shanghai - - ecmul_0_minus_0_0_21000_96_d0g3v0_Shanghai - - ecmul_0_minus_0_0_28000_96_d0g1v0_Shanghai - - ecmul_0_minus_0_0_28000_96_d0g2v0_Shanghai - - ecmul_0_minus_0_0_28000_96_d0g3v0_Shanghai - - ecmul_0_minus_0_1_21000_96_d0g2v0_Shanghai - - ecmul_0_minus_0_1_21000_96_d0g1v0_Shanghai - - ecmul_0_minus_0_1_21000_128_d0g1v0_Shanghai - - ecmul_0_minus_0_1_21000_96_d0g3v0_Shanghai - - ecmul_0_minus_0_1_21000_128_d0g2v0_Shanghai - - ecmul_0_minus_0_1_21000_128_d0g3v0_Shanghai - - ecmul_0_minus_0_2_21000_128_d0g1v0_Shanghai - - ecmul_0_minus_0_2_21000_128_d0g2v0_Shanghai - - ecmul_0_minus_0_2_21000_128_d0g3v0_Shanghai - - ecmul_0_minus_0_2_21000_96_d0g1v0_Shanghai - - ecmul_0_minus_0_2_21000_96_d0g2v0_Shanghai - - ecmul_0_minus_0_2_21000_96_d0g3v0_Shanghai - - ecmul_0_minus_0_2_28000_96_d0g1v0_Shanghai - - ecmul_0_minus_0_2_28000_96_d0g2v0_Shanghai - - ecmul_0_minus_0_2_28000_96_d0g3v0_Shanghai - - ecmul_0_minus_0_340282366920938463463374607431768211456_21000_80_d0g1v0_Shanghai - - ecmul_0_minus_0_340282366920938463463374607431768211456_21000_80_d0g3v0_Shanghai - - ecmul_0_minus_0_340282366920938463463374607431768211456_21000_80_d0g2v0_Shanghai - - ecmul_0_minus_0_340282366920938463463374607431768211456_21000_128_d0g1v0_Shanghai - - ecmul_0_minus_0_340282366920938463463374607431768211456_21000_128_d0g2v0_Shanghai - - ecmul_0_minus_0_340282366920938463463374607431768211456_21000_128_d0g3v0_Shanghai - - ecmul_0_minus_0_340282366920938463463374607431768211456_21000_96_d0g1v0_Shanghai - - ecmul_0_minus_0_340282366920938463463374607431768211456_21000_96_d0g2v0_Shanghai - - ecmul_0_minus_0_340282366920938463463374607431768211456_21000_96_d0g3v0_Shanghai - - ecmul_0_minus_0_340282366920938463463374607431768211456_28000_96_d0g1v0_Shanghai - - ecmul_0_minus_0_340282366920938463463374607431768211456_28000_96_d0g2v0_Shanghai - - ecmul_0_minus_0_340282366920938463463374607431768211456_28000_96_d0g3v0_Shanghai - - ecmul_0_minus_0_5616_21000_128_d0g1v0_Shanghai - - ecmul_0_minus_0_5616_21000_128_d0g2v0_Shanghai - - ecmul_0_minus_0_5616_21000_128_d0g3v0_Shanghai - - ecmul_0_minus_0_5616_21000_96_d0g1v0_Shanghai - - ecmul_0_minus_0_5616_21000_96_d0g2v0_Shanghai - - ecmul_0_minus_0_5616_21000_96_d0g3v0_Shanghai - - ecmul_0_minus_0_5616_28000_96_d0g1v0_Shanghai - - ecmul_0_minus_0_5616_28000_96_d0g2v0_Shanghai - - ecmul_0_minus_0_5616_28000_96_d0g3v0_Shanghai - - ecmul_0_minus_0_5617_21000_128_d0g1v0_Shanghai - - ecmul_0_minus_0_5617_21000_128_d0g2v0_Shanghai - - ecmul_0_minus_0_5617_21000_128_d0g3v0_Shanghai - - ecmul_0_minus_0_5617_21000_96_d0g1v0_Shanghai - - ecmul_0_minus_0_5617_21000_96_d0g2v0_Shanghai - - ecmul_0_minus_0_5617_21000_96_d0g3v0_Shanghai - - ecmul_0_minus_0_5617_28000_96_d0g1v0_Shanghai - - ecmul_0_minus_0_5617_28000_96_d0g2v0_Shanghai - - ecmul_0_minus_0_5617_28000_96_d0g3v0_Shanghai - - ecmul_0_minus_0_9935_21000_128_d0g1v0_Shanghai - - ecmul_0_minus_0_9935_21000_128_d0g2v0_Shanghai - - ecmul_0_minus_0_9935_21000_128_d0g3v0_Shanghai - - ecmul_0_minus_0_9935_21000_96_d0g1v0_Shanghai - - ecmul_0_minus_0_9935_21000_96_d0g2v0_Shanghai - - ecmul_0_minus_0_9935_21000_96_d0g3v0_Shanghai - - ecmul_0_minus_0_9_21000_128_d0g1v0_Shanghai - - ecmul_0_minus_0_9_21000_128_d0g2v0_Shanghai - - ecmul_0_minus_0_9_21000_128_d0g3v0_Shanghai - - ecmul_0_minus_0_9_21000_96_d0g1v0_Shanghai - - ecmul_0_minus_0_9_21000_96_d0g2v0_Shanghai - - ecmul_0_minus_0_9_21000_96_d0g3v0_Shanghai - - ecmul_0_minus_0_9_28000_96_d0g1v0_Shanghai - - ecmul_0_minus_0_9_28000_96_d0g2v0_Shanghai - - ecmul_0_minus_0_9_28000_96_d0g3v0_Shanghai - - ecmul_1_minus_2_0_21000_64_d0g1v0_Shanghai - - ecmul_1_minus_2_0_21000_64_d0g2v0_Shanghai - - ecmul_1_minus_2_0_21000_64_d0g3v0_Shanghai - - ecmul_1_minus_2_0_21000_128_d0g1v0_Shanghai - - ecmul_1_minus_2_0_21000_128_d0g2v0_Shanghai - - ecmul_1_minus_2_0_21000_128_d0g3v0_Shanghai - - ecmul_1_minus_2_0_21000_80_d0g1v0_Shanghai - - ecmul_1_minus_2_0_21000_80_d0g2v0_Shanghai - - ecmul_1_minus_2_0_21000_80_d0g3v0_Shanghai - - ecmul_1_minus_2_0_21000_96_d0g1v0_Shanghai - - ecmul_1_minus_2_0_21000_96_d0g2v0_Shanghai - - ecmul_1_minus_2_0_21000_96_d0g3v0_Shanghai - - ecmul_1_minus_2_1_21000_128_d0g1v0_Shanghai - - ecmul_1_minus_2_1_21000_128_d0g2v0_Shanghai - - ecmul_1_minus_2_1_21000_96_d0g1v0_Shanghai - - ecmul_1_minus_2_1_21000_128_d0g3v0_Shanghai - - ecmul_1_minus_2_1_21000_96_d0g2v0_Shanghai - - ecmul_1_minus_2_1_21000_96_d0g3v0_Shanghai - - ecmul_1_minus_2_1_28000_96_d0g1v0_Shanghai - - ecmul_1_minus_2_1_28000_96_d0g3v0_Shanghai - - ecmul_1_minus_2_1_28000_96_d0g2v0_Shanghai - - ecmul_1_minus_2_2_21000_128_d0g1v0_Shanghai - - ecmul_1_minus_2_2_21000_128_d0g2v0_Shanghai - - ecmul_1_minus_2_2_21000_96_d0g1v0_Shanghai - - ecmul_1_minus_2_2_21000_128_d0g3v0_Shanghai - - ecmul_1_minus_2_2_21000_96_d0g2v0_Shanghai - - ecmul_1_minus_2_2_21000_96_d0g3v0_Shanghai + - CallRecursiveBomb0_OOG_atMaxCallDepth_d0g0v0_Cancun stZeroKnowledge: - - ecmul_1_minus_2_2_28000_96_d0g2v0_Shanghai - - ecmul_1_minus_2_2_28000_96_d0g1v0_Shanghai - - ecmul_1_minus_2_2_28000_96_d0g3v0_Shanghai - - ecmul_1_minus_2_2_28000_96_d0g4v0_Shanghai - - ecmul_1_minus_2_340282366920938463463374607431768211456_21000_80_d0g1v0_Shanghai - - ecmul_1_minus_2_340282366920938463463374607431768211456_21000_80_d0g2v0_Shanghai - - ecmul_1_minus_2_340282366920938463463374607431768211456_21000_128_d0g1v0_Shanghai - - ecmul_1_minus_2_340282366920938463463374607431768211456_21000_128_d0g2v0_Shanghai - - ecmul_1_minus_2_340282366920938463463374607431768211456_21000_128_d0g3v0_Shanghai - - ecmul_1_minus_2_340282366920938463463374607431768211456_21000_80_d0g3v0_Shanghai - - ecmul_1_minus_2_340282366920938463463374607431768211456_21000_96_d0g1v0_Shanghai - - ecmul_1_minus_2_340282366920938463463374607431768211456_21000_96_d0g2v0_Shanghai - - ecmul_1_minus_2_340282366920938463463374607431768211456_21000_96_d0g3v0_Shanghai - - ecmul_1_minus_2_340282366920938463463374607431768211456_28000_96_d0g1v0_Shanghai - - ecmul_1_minus_2_340282366920938463463374607431768211456_28000_96_d0g2v0_Shanghai - - ecmul_1_minus_2_340282366920938463463374607431768211456_28000_96_d0g3v0_Shanghai - - ecmul_1_minus_2_5616_21000_96_d0g1v0_Shanghai - - ecmul_1_minus_2_5616_21000_128_d0g1v0_Shanghai - - ecmul_1_minus_2_5616_21000_96_d0g2v0_Shanghai - - ecmul_1_minus_2_5616_21000_128_d0g2v0_Shanghai - - ecmul_1_minus_2_5616_21000_128_d0g3v0_Shanghai - - ecmul_1_minus_2_5616_21000_96_d0g3v0_Shanghai - - ecmul_1_minus_2_5617_21000_128_d0g1v0_Shanghai - - ecmul_1_minus_2_5617_21000_128_d0g2v0_Shanghai - - ecmul_1_minus_2_5617_21000_128_d0g3v0_Shanghai - - ecmul_1_minus_2_5617_21000_96_d0g1v0_Shanghai - - ecmul_1_minus_2_5617_21000_96_d0g2v0_Shanghai - - ecmul_1_minus_2_5617_21000_96_d0g3v0_Shanghai - - ecmul_1_minus_2_616_28000_96_d0g1v0_Shanghai - - ecmul_1_minus_2_616_28000_96_d0g2v0_Shanghai - - ecmul_1_minus_2_616_28000_96_d0g3v0_Shanghai - - ecmul_1_minus_2_616_28000_96_d0g4v0_Shanghai - - ecmul_1_minus_2_9935_21000_96_d0g1v0_Shanghai - - ecmul_1_minus_2_9935_21000_128_d0g1v0_Shanghai - - ecmul_1_minus_2_9935_21000_128_d0g2v0_Shanghai - - ecmul_1_minus_2_9935_21000_128_d0g3v0_Shanghai - - ecmul_1_minus_2_9935_21000_96_d0g2v0_Shanghai - - ecmul_1_minus_2_9935_21000_96_d0g3v0_Shanghai - - ecmul_1_minus_2_9935_28000_96_d0g1v0_Shanghai - - ecmul_1_minus_2_9935_28000_96_d0g2v0_Shanghai - - ecmul_1_minus_2_9935_28000_96_d0g3v0_Shanghai - - ecmul_1_minus_2_9_21000_128_d0g1v0_Shanghai - - ecmul_1_minus_2_9_21000_128_d0g2v0_Shanghai - - ecmul_1_minus_2_9_21000_96_d0g1v0_Shanghai - - ecmul_1_minus_2_9_21000_128_d0g3v0_Shanghai - - ecmul_1_minus_2_9_21000_96_d0g2v0_Shanghai - - ecmul_1_minus_2_9_21000_96_d0g3v0_Shanghai - - ecmul_1_minus_2_9_28000_96_d0g1v0_Shanghai - - ecmul_1_minus_2_9_28000_96_d0g2v0_Shanghai - - ecmul_1_minus_2_9_28000_96_d0g3v0_Shanghai - - ecmul_7827_minus_6598_0_21000_64_d0g1v0_Shanghai - - ecmul_7827_minus_6598_0_21000_64_d0g2v0_Shanghai - - ecmul_7827_minus_6598_0_21000_64_d0g3v0_Shanghai - - ecmul_7827_minus_6598_0_21000_128_d0g1v0_Shanghai - - ecmul_7827_minus_6598_0_21000_128_d0g2v0_Shanghai - - ecmul_7827_minus_6598_0_21000_128_d0g3v0_Shanghai - - ecmul_7827_minus_6598_0_21000_80_d0g1v0_Shanghai - - ecmul_7827_minus_6598_0_21000_80_d0g2v0_Shanghai - - ecmul_7827_minus_6598_0_21000_80_d0g3v0_Shanghai - - ecmul_7827_minus_6598_0_21000_96_d0g1v0_Shanghai - - ecmul_7827_minus_6598_0_21000_96_d0g2v0_Shanghai - - ecmul_7827_minus_6598_0_21000_96_d0g3v0_Shanghai - - ecmul_7827_minus_6598_1456_21000_128_d0g1v0_Shanghai - - ecmul_7827_minus_6598_1456_21000_80_d0g1v0_Shanghai - - ecmul_7827_minus_6598_1456_21000_128_d0g2v0_Shanghai - - ecmul_7827_minus_6598_1456_21000_80_d0g2v0_Shanghai - - ecmul_7827_minus_6598_1456_21000_128_d0g3v0_Shanghai - - ecmul_7827_minus_6598_1456_21000_80_d0g3v0_Shanghai - - ecmul_7827_minus_6598_1456_21000_96_d0g1v0_Shanghai - - ecmul_7827_minus_6598_1456_21000_96_d0g3v0_Shanghai - - ecmul_7827_minus_6598_1456_21000_96_d0g2v0_Shanghai - - ecmul_7827_minus_6598_1456_28000_96_d0g1v0_Shanghai - - ecmul_7827_minus_6598_1456_28000_96_d0g2v0_Shanghai - - ecmul_7827_minus_6598_1456_28000_96_d0g3v0_Shanghai - - ecmul_7827_minus_6598_1_21000_96_d0g1v0_Shanghai - - ecmul_7827_minus_6598_1_21000_128_d0g1v0_Shanghai - - ecmul_7827_minus_6598_1_21000_128_d0g2v0_Shanghai - - ecmul_7827_minus_6598_1_21000_128_d0g3v0_Shanghai - - ecmul_7827_minus_6598_1_21000_96_d0g2v0_Shanghai - - ecmul_7827_minus_6598_1_21000_96_d0g3v0_Shanghai - - ecmul_7827_minus_6598_1_28000_96_d0g1v0_Shanghai - - ecmul_7827_minus_6598_1_28000_96_d0g3v0_Shanghai - - ecmul_7827_minus_6598_1_28000_96_d0g2v0_Shanghai - - ecmul_7827_minus_6598_2_21000_128_d0g1v0_Shanghai - - ecmul_7827_minus_6598_2_21000_128_d0g2v0_Shanghai - - ecmul_7827_minus_6598_2_21000_96_d0g1v0_Shanghai - - ecmul_7827_minus_6598_2_21000_128_d0g3v0_Shanghai - - ecmul_7827_minus_6598_2_21000_96_d0g2v0_Shanghai - - ecmul_7827_minus_6598_2_21000_96_d0g3v0_Shanghai - - ecmul_7827_minus_6598_2_28000_96_d0g1v0_Shanghai - - ecmul_7827_minus_6598_2_28000_96_d0g2v0_Shanghai - - ecmul_7827_minus_6598_2_28000_96_d0g3v0_Shanghai - - ecmul_7827_minus_6598_5616_21000_96_d0g1v0_Shanghai - - ecmul_7827_minus_6598_5616_21000_128_d0g1v0_Shanghai - - ecmul_7827_minus_6598_5616_21000_128_d0g2v0_Shanghai - - ecmul_7827_minus_6598_5616_21000_128_d0g3v0_Shanghai - - ecmul_7827_minus_6598_5616_21000_96_d0g3v0_Shanghai - - ecmul_7827_minus_6598_5616_21000_96_d0g2v0_Shanghai - - ecmul_7827_minus_6598_5616_28000_96_d0g1v0_Shanghai - - ecmul_7827_minus_6598_5616_28000_96_d0g2v0_Shanghai - - ecmul_7827_minus_6598_5616_28000_96_d0g3v0_Shanghai - - ecmul_7827_minus_6598_5617_21000_96_d0g1v0_Shanghai - - ecmul_7827_minus_6598_5617_21000_96_d0g2v0_Shanghai - - ecmul_7827_minus_6598_5617_21000_96_d0g3v0_Shanghai - - ecmul_7827_minus_6598_5617_21000_128_d0g1v0_Shanghai - - ecmul_7827_minus_6598_5617_21000_128_d0g2v0_Shanghai - - ecmul_7827_minus_6598_9935_21000_128_d0g2v0_Shanghai - - ecmul_7827_minus_6598_9935_21000_128_d0g3v0_Shanghai - - ecmul_7827_minus_6598_9935_21000_96_d0g2v0_Shanghai - - ecmul_7827_minus_6598_9935_21000_96_d0g3v0_Shanghai - - ecmul_7827_minus_6598_9935_28000_96_d0g2v0_Shanghai - - ecmul_7827_minus_6598_9935_28000_96_d0g1v0_Shanghai - - ecmul_7827_minus_6598_9935_28000_96_d0g3v0_Shanghai - - ecmul_7827_minus_6598_9_21000_96_d0g1v0_Shanghai - - ecmul_7827_minus_6598_9_21000_96_d0g2v0_Shanghai - - ecmul_7827_minus_6598_9_21000_128_d0g1v0_Shanghai - - ecmul_7827_minus_6598_9_21000_128_d0g2v0_Shanghai - - ecmul_7827_minus_6598_9_21000_96_d0g3v0_Shanghai - - ecmul_7827_minus_6598_9_21000_128_d0g3v0_Shanghai - - ecmul_7827_minus_6598_9_28000_96_d0g1v0_Shanghai - - ecmul_7827_minus_6598_9_28000_96_d0g3v0_Shanghai - - ecmul_7827_minus_6598_9_28000_96_d0g2v0_Shanghai - - ecpairing_empty_data_d0g0v0_Shanghai - - ecpairing_empty_data_d0g3v0_Shanghai - - ecpairing_empty_data_insufficient_gas_d0g2v0_Shanghai - - ecpairing_one_point_fail_d0g0v0_Shanghai - - ecpairing_one_point_with_g1_zero_d0g0v0_Shanghai - - ecpairing_three_point_fail_1_d0g0v0_Shanghai - - ecpairing_two_point_fail_1_d0g0v0_Shanghai - - ecpairing_two_point_fail_2_d0g0v0_Shanghai - - ecpairing_two_point_match_1_d0g0v0_Shanghai - - ecpairing_two_point_match_5_d0g0v0_Shanghai - - pairingTest_d0g0v0_Shanghai - - pairingTest_d1g0v0_Shanghai - - pointAddTrunc_d0g1v0_Shanghai - - pointAddTrunc_d0g0v0_Shanghai - - pointAddTrunc_d0g2v0_Shanghai - - pairingTest_d2g0v0_Shanghai - - pairingTest_d3g0v0_Shanghai - - pointAddTrunc_d2g0v0_Shanghai - - pointAddTrunc_d2g1v0_Shanghai - - pointAddTrunc_d2g2v0_Shanghai - - pointAddTrunc_d3g0v0_Shanghai - - pointAddTrunc_d3g1v0_Shanghai - - pointAddTrunc_d3g2v0_Shanghai - - pairingTest_d4g0v0_Shanghai - - pointAddTrunc_d7g0v0_Shanghai - - pointAddTrunc_d7g1v0_Shanghai - - pointAddTrunc_d7g2v0_Shanghai - - pointAddTrunc_d8g0v0_Shanghai - - pointAddTrunc_d8g1v0_Shanghai - - pointAddTrunc_d8g2v0_Shanghai - - pointAddTrunc_d9g0v0_Shanghai - - pointAddTrunc_d9g1v0_Shanghai - - pointAddTrunc_d9g2v0_Shanghai - - pointAdd_d0g0v0_Shanghai - - pointAdd_d0g1v0_Shanghai - - pointAdd_d0g2v0_Shanghai - - pointAdd_d3g0v0_Shanghai - - pointAdd_d3g1v0_Shanghai - - pointAdd_d3g2v0_Shanghai - - pointAdd_d4g0v0_Shanghai - - pointAdd_d4g1v0_Shanghai - - pointAdd_d4g2v0_Shanghai - - pointAdd_d7g1v0_Shanghai - - pointAdd_d7g0v0_Shanghai - - pointAdd_d7g2v0_Shanghai - - pointAdd_d8g0v0_Shanghai - - pointAdd_d8g1v0_Shanghai - - pointAdd_d8g2v0_Shanghai - - pointAdd_d9g0v0_Shanghai - - pointAdd_d9g1v0_Shanghai - - pointAdd_d9g2v0_Shanghai - - pointMulAdd2_d10g0v0_Shanghai - - pointMulAdd2_d11g0v0_Shanghai - - pointMulAdd2_d13g0v0_Shanghai - - pointMulAdd2_d14g0v0_Shanghai - - pointMulAdd2_d15g0v0_Shanghai - - pointMulAdd2_d16g0v0_Shanghai - - pointMulAdd2_d17g0v0_Shanghai - - pointMulAdd2_d17g3v0_Shanghai - - pointMulAdd2_d18g0v0_Shanghai - - pointMulAdd2_d19g0v0_Shanghai - - pointMulAdd2_d20g0v0_Shanghai - - pointMulAdd2_d21g0v0_Shanghai - - pointMulAdd2_d21g3v0_Shanghai - - pointMulAdd2_d22g0v0_Shanghai - - pointMulAdd2_d23g0v0_Shanghai - - pointMulAdd2_d24g0v0_Shanghai - - pointMulAdd2_d25g0v0_Shanghai - - pointMulAdd2_d27g0v0_Shanghai - - pointMulAdd2_d28g0v0_Shanghai - - pointMulAdd2_d29g0v0_Shanghai - - pointMulAdd2_d30g0v0_Shanghai - - pointMulAdd2_d30g3v0_Shanghai - - pointMulAdd2_d31g0v0_Shanghai - - pointMulAdd2_d32g0v0_Shanghai - - pointMulAdd2_d33g0v0_Shanghai - - pointMulAdd2_d34g0v0_Shanghai - - pointMulAdd2_d35g0v0_Shanghai - - pointMulAdd2_d34g3v0_Shanghai - - pointMulAdd2_d36g0v0_Shanghai - - pointMulAdd2_d37g0v0_Shanghai - - pointMulAdd_d0g0v0_Shanghai - - pointMulAdd_d1g0v0_Shanghai - - pointMulAdd_d4g0v0_Shanghai - - pointMulAdd_d7g3v0_Shanghai - - pointMulAdd_d3g0v0_Shanghai - - pointMulAdd_d7g0v0_Shanghai - - pointMulAdd_d6g0v0_Shanghai - - pointMulAdd_d5g0v0_Shanghai + - ecpairing_bad_length_191_d0g0v0_Cancun + - ecpairing_bad_length_191_d0g1v0_Cancun + - ecpairing_bad_length_191_d0g2v0_Cancun + - ecpairing_bad_length_191_d0g3v0_Cancun + - ecpairing_bad_length_193_d0g0v0_Cancun + - ecpairing_bad_length_193_d0g1v0_Cancun + - ecpairing_bad_length_193_d0g2v0_Cancun + - ecpairing_bad_length_193_d0g3v0_Cancun + - ecpairing_empty_data_d0g1v0_Cancun + - ecpairing_empty_data_d0g2v0_Cancun + - ecpairing_empty_data_insufficient_gas_d0g0v0_Cancun + - ecpairing_empty_data_insufficient_gas_d0g1v0_Cancun + - ecpairing_inputs_d100g0v0_Cancun + - ecpairing_inputs_d101g0v0_Cancun + - ecpairing_inputs_d102g0v0_Cancun + - ecpairing_inputs_d103g0v0_Cancun + - ecpairing_inputs_d104g0v0_Cancun + - ecpairing_inputs_d105g0v0_Cancun + - ecpairing_inputs_d106g0v0_Cancun + - ecpairing_inputs_d107g0v0_Cancun + - ecpairing_inputs_d108g0v0_Cancun + - ecpairing_inputs_d109g0v0_Cancun + - ecpairing_inputs_d110g0v0_Cancun + - ecpairing_inputs_d111g0v0_Cancun + - ecpairing_inputs_d112g0v0_Cancun + - ecpairing_inputs_d113g0v0_Cancun + - ecpairing_inputs_d114g0v0_Cancun + - ecpairing_inputs_d115g0v0_Cancun + - ecpairing_inputs_d116g0v0_Cancun + - ecpairing_inputs_d117g0v0_Cancun + - ecpairing_inputs_d118g0v0_Cancun + - ecpairing_inputs_d119g0v0_Cancun + - ecpairing_inputs_d120g0v0_Cancun + - ecpairing_inputs_d121g0v0_Cancun + - ecpairing_inputs_d122g0v0_Cancun + - ecpairing_inputs_d123g0v0_Cancun + - ecpairing_inputs_d124g0v0_Cancun + - ecpairing_inputs_d125g0v0_Cancun + - ecpairing_inputs_d126g0v0_Cancun + - ecpairing_inputs_d127g0v0_Cancun + - ecpairing_inputs_d128g0v0_Cancun + - ecpairing_inputs_d129g0v0_Cancun + - ecpairing_inputs_d130g0v0_Cancun + - ecpairing_inputs_d131g0v0_Cancun + - ecpairing_inputs_d132g0v0_Cancun + - ecpairing_inputs_d133g0v0_Cancun + - ecpairing_inputs_d134g0v0_Cancun + - ecpairing_inputs_d135g0v0_Cancun + - ecpairing_inputs_d136g0v0_Cancun + - ecpairing_inputs_d137g0v0_Cancun + - ecpairing_inputs_d138g0v0_Cancun + - ecpairing_inputs_d139g0v0_Cancun + - ecpairing_inputs_d140g0v0_Cancun + - ecpairing_inputs_d141g0v0_Cancun + - ecpairing_inputs_d142g0v0_Cancun + - ecpairing_inputs_d143g0v0_Cancun + - ecpairing_inputs_d38g0v0_Cancun + - ecpairing_inputs_d39g0v0_Cancun + - ecpairing_inputs_d40g0v0_Cancun + - ecpairing_inputs_d41g0v0_Cancun + - ecpairing_inputs_d42g0v0_Cancun + - ecpairing_inputs_d43g0v0_Cancun + - ecpairing_inputs_d44g0v0_Cancun + - ecpairing_inputs_d45g0v0_Cancun + - ecpairing_inputs_d46g0v0_Cancun + - ecpairing_inputs_d47g0v0_Cancun + - ecpairing_inputs_d48g0v0_Cancun + - ecpairing_inputs_d49g0v0_Cancun + - ecpairing_inputs_d50g0v0_Cancun + - ecpairing_inputs_d51g0v0_Cancun + - ecpairing_inputs_d52g0v0_Cancun + - ecpairing_inputs_d53g0v0_Cancun + - ecpairing_inputs_d54g0v0_Cancun + - ecpairing_inputs_d55g0v0_Cancun + - ecpairing_inputs_d56g0v0_Cancun + - ecpairing_inputs_d57g0v0_Cancun + - ecpairing_inputs_d58g0v0_Cancun + - ecpairing_inputs_d59g0v0_Cancun + - ecpairing_inputs_d60g0v0_Cancun + - ecpairing_inputs_d61g0v0_Cancun + - ecpairing_inputs_d62g0v0_Cancun + - ecpairing_inputs_d63g0v0_Cancun + - ecpairing_inputs_d64g0v0_Cancun + - ecpairing_inputs_d65g0v0_Cancun + - ecpairing_inputs_d66g0v0_Cancun + - ecpairing_inputs_d67g0v0_Cancun + - ecpairing_inputs_d68g0v0_Cancun + - ecpairing_inputs_d69g0v0_Cancun + - ecpairing_inputs_d70g0v0_Cancun + - ecpairing_inputs_d71g0v0_Cancun + - ecpairing_inputs_d72g0v0_Cancun + - ecpairing_inputs_d73g0v0_Cancun + - ecpairing_inputs_d74g0v0_Cancun + - ecpairing_inputs_d75g0v0_Cancun + - ecpairing_inputs_d76g0v0_Cancun + - ecpairing_inputs_d77g0v0_Cancun + - ecpairing_inputs_d78g0v0_Cancun + - ecpairing_inputs_d79g0v0_Cancun + - ecpairing_inputs_d80g0v0_Cancun + - ecpairing_inputs_d81g0v0_Cancun + - ecpairing_inputs_d82g0v0_Cancun + - ecpairing_inputs_d83g0v0_Cancun + - ecpairing_inputs_d84g0v0_Cancun + - ecpairing_inputs_d85g0v0_Cancun + - ecpairing_inputs_d86g0v0_Cancun + - ecpairing_inputs_d87g0v0_Cancun + - ecpairing_inputs_d88g0v0_Cancun + - ecpairing_inputs_d89g0v0_Cancun + - ecpairing_inputs_d90g0v0_Cancun + - ecpairing_inputs_d91g0v0_Cancun + - ecpairing_inputs_d92g0v0_Cancun + - ecpairing_inputs_d93g0v0_Cancun + - ecpairing_inputs_d94g0v0_Cancun + - ecpairing_inputs_d95g0v0_Cancun + - ecpairing_inputs_d96g0v0_Cancun + - ecpairing_inputs_d97g0v0_Cancun + - ecpairing_inputs_d98g0v0_Cancun + - ecpairing_inputs_d99g0v0_Cancun + - ecpairing_one_point_fail_d0g1v0_Cancun + - ecpairing_one_point_fail_d0g2v0_Cancun + - ecpairing_one_point_insufficient_gas_d0g0v0_Cancun + - ecpairing_one_point_insufficient_gas_d0g1v0_Cancun + - ecpairing_one_point_insufficient_gas_d0g2v0_Cancun + - ecpairing_one_point_not_in_subgroup_d0g0v0_Cancun + - ecpairing_one_point_not_in_subgroup_d0g1v0_Cancun + - ecpairing_one_point_not_in_subgroup_d0g2v0_Cancun + - ecpairing_one_point_not_in_subgroup_d0g3v0_Cancun + - ecpairing_one_point_with_g1_zero_d0g1v0_Cancun + - ecpairing_one_point_with_g1_zero_d0g2v0_Cancun + - ecpairing_one_point_with_g2_zero_and_g1_invalid_d0g0v0_Cancun + - ecpairing_one_point_with_g2_zero_and_g1_invalid_d0g1v0_Cancun + - ecpairing_one_point_with_g2_zero_and_g1_invalid_d0g2v0_Cancun + - ecpairing_one_point_with_g2_zero_and_g1_invalid_d0g3v0_Cancun + - ecpairing_one_point_with_g2_zero_d0g1v0_Cancun + - ecpairing_perturb_g2_by_curve_order_d0g0v0_Cancun + - ecpairing_perturb_g2_by_curve_order_d0g1v0_Cancun + - ecpairing_perturb_g2_by_curve_order_d0g2v0_Cancun + - ecpairing_perturb_g2_by_curve_order_d0g3v0_Cancun + - ecpairing_perturb_g2_by_field_modulus_again_d0g0v0_Cancun + - ecpairing_perturb_g2_by_field_modulus_again_d0g1v0_Cancun + - ecpairing_perturb_g2_by_field_modulus_again_d0g2v0_Cancun + - ecpairing_perturb_g2_by_field_modulus_again_d0g3v0_Cancun + - ecpairing_perturb_g2_by_field_modulus_d0g0v0_Cancun + - ecpairing_perturb_g2_by_field_modulus_d0g1v0_Cancun + - ecpairing_perturb_g2_by_field_modulus_d0g2v0_Cancun + - ecpairing_perturb_g2_by_field_modulus_d0g3v0_Cancun + - ecpairing_perturb_g2_by_one_d0g0v0_Cancun + - ecpairing_perturb_g2_by_one_d0g1v0_Cancun + - ecpairing_perturb_g2_by_one_d0g2v0_Cancun + - ecpairing_perturb_g2_by_one_d0g3v0_Cancun + - ecpairing_perturb_zeropoint_by_curve_order_d0g0v0_Cancun + - ecpairing_perturb_zeropoint_by_curve_order_d0g1v0_Cancun + - ecpairing_perturb_zeropoint_by_curve_order_d0g2v0_Cancun + - ecpairing_perturb_zeropoint_by_curve_order_d0g3v0_Cancun + - ecpairing_perturb_zeropoint_by_field_modulus_d0g0v0_Cancun + - ecpairing_perturb_zeropoint_by_field_modulus_d0g1v0_Cancun + - ecpairing_perturb_zeropoint_by_field_modulus_d0g2v0_Cancun + - ecpairing_perturb_zeropoint_by_field_modulus_d0g3v0_Cancun + - ecpairing_perturb_zeropoint_by_one_d0g0v0_Cancun + - ecpairing_perturb_zeropoint_by_one_d0g1v0_Cancun + - ecpairing_perturb_zeropoint_by_one_d0g2v0_Cancun + - ecpairing_perturb_zeropoint_by_one_d0g3v0_Cancun + - ecpairing_three_point_fail_1_d0g1v0_Cancun + - ecpairing_three_point_fail_1_d0g2v0_Cancun + - ecpairing_three_point_fail_1_d0g3v0_Cancun + - ecpairing_three_point_match_1_d0g1v0_Cancun + - ecpairing_three_point_match_1_d0g2v0_Cancun + - ecpairing_two_point_fail_1_d0g1v0_Cancun + - ecpairing_two_point_fail_1_d0g2v0_Cancun + - ecpairing_two_point_fail_2_d0g1v0_Cancun + - ecpairing_two_point_fail_2_d0g2v0_Cancun + - ecpairing_two_point_fail_2_d0g3v0_Cancun + - ecpairing_two_point_match_1_d0g1v0_Cancun + - ecpairing_two_point_match_1_d0g2v0_Cancun + - ecpairing_two_point_match_1_d0g3v0_Cancun + - ecpairing_two_point_match_2_d0g1v0_Cancun + - ecpairing_two_point_match_2_d0g2v0_Cancun + - ecpairing_two_point_match_3_d0g1v0_Cancun + - ecpairing_two_point_match_3_d0g2v0_Cancun + - ecpairing_two_point_match_4_d0g1v0_Cancun + - ecpairing_two_point_match_4_d0g2v0_Cancun + - ecpairing_two_point_match_5_d0g1v0_Cancun + - ecpairing_two_point_match_5_d0g2v0_Cancun + - ecpairing_two_point_match_5_d0g3v0_Cancun + - ecpairing_two_point_oog_d0g1v0_Cancun + - ecpairing_two_point_oog_d0g2v0_Cancun + - ecpairing_two_points_with_one_g2_zero_d0g1v0_Cancun + - ecpairing_two_points_with_one_g2_zero_d0g2v0_Cancun + - pairingTest_d0g1v0_Cancun + - pairingTest_d0g2v0_Cancun + - pairingTest_d0g3v0_Cancun + - pairingTest_d1g1v0_Cancun + - pairingTest_d1g2v0_Cancun + - pairingTest_d1g3v0_Cancun + - pairingTest_d2g1v0_Cancun + - pairingTest_d2g2v0_Cancun + - pairingTest_d2g3v0_Cancun + - pairingTest_d3g1v0_Cancun + - pairingTest_d3g2v0_Cancun + - pairingTest_d3g3v0_Cancun + - pairingTest_d4g1v0_Cancun + - pairingTest_d4g2v0_Cancun + - pairingTest_d4g3v0_Cancun + - pairingTest_d5g1v0_Cancun + - pairingTest_d5g2v0_Cancun + - pairingTest_d5g3v0_Cancun From a187dafe02eeaab68ca7bd11b5c490560078cb2b Mon Sep 17 00:00:00 2001 From: Oba Date: Wed, 2 Oct 2024 11:18:43 +0200 Subject: [PATCH 25/56] ci: fix skip file ef-test ssj --- .github/workflows/ssj-ef-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ssj-ef-tests.yml b/.github/workflows/ssj-ef-tests.yml index 61580709d..c16585f06 100644 --- a/.github/workflows/ssj-ef-tests.yml +++ b/.github/workflows/ssj-ef-tests.yml @@ -61,7 +61,7 @@ jobs: uses: actions/checkout@v4 with: sparse-checkout: | - blockchain-tests-skip.yml + ./kakarot-ssj/blockchain-tests-skip.yml sparse-checkout-cone-mode: false path: skip-file From 19f1e08b2e831a42f4f83afaabcd8980446832a3 Mon Sep 17 00:00:00 2001 From: Oba Date: Wed, 2 Oct 2024 13:00:28 +0200 Subject: [PATCH 26/56] refactor: rename folder for cairo and cairo_zero --- .devcontainer/devcontainer.json | 4 ++-- .github/workflows/kakarot0-ci.yml | 8 ++++---- .github/workflows/kakarot0-nightly-fuzzing.yml | 2 +- .github/workflows/kakarot0-release.yml | 2 +- .github/workflows/kakarot0-trunk-check.yaml | 4 ++-- .github/workflows/kakarot0-update-rpc.yml | 2 +- .github/workflows/ssj-build.yml | 6 +++--- .github/workflows/ssj-ci.yml | 6 +++--- .github/workflows/ssj-ef-tests.yml | 10 +++++----- .github/workflows/ssj-release.yml | 4 ++-- .github/workflows/ssj-test.yml | 6 +++--- .github/workflows/ssj-tests-unit.yml | 6 +++--- .trunk/trunk.yaml | 2 +- Makefile | 2 +- .../kakarot-ssj}/.all-contributorsrc | 0 {kakarot-ssj => cairo/kakarot-ssj}/.codespellrc | 0 {kakarot-ssj => cairo/kakarot-ssj}/.env.example | 0 {kakarot-ssj => cairo/kakarot-ssj}/.gitignore | 0 .../kakarot-ssj}/.markdownlint.json | 0 {kakarot-ssj => cairo/kakarot-ssj}/.prettierrc.json | 0 {kakarot-ssj => cairo/kakarot-ssj}/.tool-versions | 0 .../kakarot-ssj}/.trunk/.gitignore | 0 .../kakarot-ssj}/.trunk/configs/.isort.cfg | 0 .../kakarot-ssj}/.trunk/configs/.shellcheckrc | 0 .../kakarot-ssj}/.trunk/configs/.yamllint.yaml | 0 .../kakarot-ssj}/.trunk/configs/ruff.toml | 0 .../kakarot-ssj}/.trunk/trunk.yaml | 0 {kakarot-ssj => cairo/kakarot-ssj}/LICENSE | 0 {kakarot-ssj => cairo/kakarot-ssj}/Makefile | 0 {kakarot-ssj => cairo/kakarot-ssj}/README.md | 0 {kakarot-ssj => cairo/kakarot-ssj}/Scarb.lock | 0 {kakarot-ssj => cairo/kakarot-ssj}/Scarb.toml | 0 .../kakarot-ssj}/blockchain-tests-skip.yml | 0 {kakarot-ssj => cairo/kakarot-ssj}/bun.lockb | Bin .../crates/alexandria_data_structures}/.gitignore | 0 .../crates/alexandria_data_structures/Scarb.toml | 0 .../crates/alexandria_data_structures/src/lib.cairo | 0 .../crates/alexandria_data_structures/src/vec.cairo | 0 .../kakarot-ssj}/crates/contracts/Scarb.toml | 0 .../crates/contracts/src/account_contract.cairo | 0 .../crates/contracts/src/cairo1_helpers.cairo | 0 .../crates/contracts/src/components.cairo | 0 .../crates/contracts/src/components/ownable.cairo | 0 .../contracts/src/components/upgradeable.cairo | 0 .../kakarot-ssj}/crates/contracts/src/errors.cairo | 0 .../crates/contracts/src/kakarot_core.cairo | 0 .../crates/contracts/src/kakarot_core/eth_rpc.cairo | 0 .../contracts/src/kakarot_core/interface.cairo | 0 .../crates/contracts/src/kakarot_core/kakarot.cairo | 0 .../kakarot-ssj}/crates/contracts/src/lib.cairo | 0 .../src/mocks/cairo1_helpers_fixture.cairo | 0 .../kakarot-ssj}/crates/contracts/src/storage.cairo | 0 .../src/test_contracts/test_upgradeable.cairo | 0 .../crates/contracts/src/test_data.cairo | 0 .../crates/contracts/src/test_utils.cairo | 0 .../contracts/src/uninitialized_account.cairo | 0 .../kakarot-ssj}/crates/contracts/tests/lib.cairo | 0 .../contracts/tests/test_account_contract.cairo | 0 .../contracts/tests/test_cairo1_helpers.cairo | 0 .../tests/test_execution_from_outside.cairo | 0 .../crates/contracts/tests/test_kakarot_core.cairo | 0 .../crates/contracts/tests/test_ownable.cairo | 0 .../kakarot-ssj/crates/evm}/.gitignore | 0 .../kakarot-ssj}/crates/evm/Scarb.toml | 0 .../kakarot-ssj}/crates/evm/src/backend.cairo | 0 .../crates/evm/src/backend/starknet_backend.cairo | 0 .../crates/evm/src/backend/validation.cairo | 0 .../kakarot-ssj}/crates/evm/src/call_helpers.cairo | 0 .../crates/evm/src/create_helpers.cairo | 0 .../kakarot-ssj}/crates/evm/src/errors.cairo | 0 .../kakarot-ssj}/crates/evm/src/gas.cairo | 0 .../kakarot-ssj}/crates/evm/src/instructions.cairo | 0 .../evm/src/instructions/block_information.cairo | 0 .../src/instructions/comparison_operations.cairo | 0 .../src/instructions/duplication_operations.cairo | 0 .../instructions/environmental_information.cairo | 0 .../evm/src/instructions/exchange_operations.cairo | 0 .../evm/src/instructions/logging_operations.cairo | 0 .../evm/src/instructions/memory_operations.cairo | 0 .../evm/src/instructions/push_operations.cairo | 0 .../crates/evm/src/instructions/sha3.cairo | 0 .../stop_and_arithmetic_operations.cairo | 0 .../evm/src/instructions/system_operations.cairo | 0 .../kakarot-ssj}/crates/evm/src/interpreter.cairo | 0 .../kakarot-ssj}/crates/evm/src/lib.cairo | 0 .../kakarot-ssj}/crates/evm/src/memory.cairo | 0 .../kakarot-ssj}/crates/evm/src/model.cairo | 0 .../kakarot-ssj}/crates/evm/src/model/account.cairo | 0 .../kakarot-ssj}/crates/evm/src/model/vm.cairo | 0 .../kakarot-ssj}/crates/evm/src/precompiles.cairo | 0 .../crates/evm/src/precompiles/blake2f.cairo | 0 .../crates/evm/src/precompiles/ec_operations.cairo | 0 .../evm/src/precompiles/ec_operations/ec_add.cairo | 0 .../evm/src/precompiles/ec_operations/ec_mul.cairo | 0 .../crates/evm/src/precompiles/ec_recover.cairo | 0 .../crates/evm/src/precompiles/identity.cairo | 0 .../crates/evm/src/precompiles/modexp.cairo | 0 .../crates/evm/src/precompiles/p256verify.cairo | 0 .../crates/evm/src/precompiles/sha256.cairo | 0 .../kakarot-ssj}/crates/evm/src/stack.cairo | 0 .../kakarot-ssj}/crates/evm/src/state.cairo | 0 .../kakarot-ssj}/crates/evm/src/test_data.cairo | 0 .../evm/src/test_data/test_data_blake2f.cairo | 0 .../crates/evm/src/test_data/test_data_modexp.cairo | 0 .../kakarot-ssj}/crates/evm/src/test_utils.cairo | 0 .../kakarot-ssj}/crates/openzeppelin/Scarb.toml | 0 .../kakarot-ssj}/crates/openzeppelin/src/lib.cairo | 0 .../crates/openzeppelin/src/token.cairo | 0 .../crates/openzeppelin/src/token/erc20.cairo | 0 .../crates/openzeppelin/src/token/erc20/erc20.cairo | 0 .../openzeppelin/src/token/erc20/interface.cairo | 0 .../kakarot-ssj}/crates/snforge_utils/.gitignore | 0 .../kakarot-ssj}/crates/snforge_utils/Scarb.toml | 0 .../crates/snforge_utils/src/contracts.cairo | 0 .../kakarot-ssj}/crates/snforge_utils/src/lib.cairo | 0 .../kakarot-ssj/crates}/utils/.gitignore | 0 .../kakarot-ssj}/crates/utils/Scarb.toml | 0 .../kakarot-ssj}/crates/utils/src/address.cairo | 0 .../kakarot-ssj}/crates/utils/src/constants.cairo | 0 .../kakarot-ssj}/crates/utils/src/crypto.cairo | 0 .../crates/utils/src/crypto/blake2_compress.cairo | 0 .../crates/utils/src/crypto/modexp.cairo | 0 .../crates/utils/src/crypto/modexp/arith.cairo | 0 .../crates/utils/src/crypto/modexp/lib.cairo | 0 .../crates/utils/src/crypto/modexp/mpnat.cairo | 0 .../kakarot-ssj}/crates/utils/src/errors.cairo | 0 .../crates/utils/src/eth_transaction.cairo | 0 .../crates/utils/src/eth_transaction/common.cairo | 0 .../crates/utils/src/eth_transaction/eip1559.cairo | 0 .../crates/utils/src/eth_transaction/eip2930.cairo | 0 .../crates/utils/src/eth_transaction/legacy.cairo | 0 .../utils/src/eth_transaction/transaction.cairo | 0 .../crates/utils/src/eth_transaction/tx_type.cairo | 0 .../kakarot-ssj}/crates/utils/src/felt_vec.cairo | 0 .../kakarot-ssj}/crates/utils/src/fmt.cairo | 0 .../kakarot-ssj}/crates/utils/src/helpers.cairo | 0 .../kakarot-ssj}/crates/utils/src/i256.cairo | 0 .../kakarot-ssj}/crates/utils/src/lib.cairo | 0 .../kakarot-ssj}/crates/utils/src/math.cairo | 0 .../kakarot-ssj}/crates/utils/src/rlp.cairo | 0 .../crates/utils/src/serialization.cairo | 0 .../kakarot-ssj}/crates/utils/src/set.cairo | 0 .../kakarot-ssj}/crates/utils/src/test_data.cairo | 0 .../kakarot-ssj}/crates/utils/src/traits.cairo | 0 .../crates/utils/src/traits/array.cairo | 0 .../crates/utils/src/traits/bytes.cairo | 0 .../crates/utils/src/traits/eth_address.cairo | 0 .../crates/utils/src/traits/integer.cairo | 0 .../kakarot-ssj}/crates/utils/src/utils.cairo | 0 .../kakarot-ssj}/docs/CODE_OF_CONDUCT.md | 0 .../kakarot-ssj}/docs/CONTRIBUTING.md | 0 {kakarot-ssj => cairo/kakarot-ssj}/docs/SECURITY.md | 0 .../kakarot-ssj}/docs/general/account_state.png | Bin .../kakarot-ssj}/docs/general/contract_bytecode.md | 0 .../kakarot-ssj}/docs/general/contract_storage.md | 0 .../kakarot-ssj}/docs/general/local_state.md | 0 .../kakarot-ssj}/docs/general/machine.md | 0 .../kakarot-ssj}/docs/general/volition.png | Bin .../kakarot-ssj}/docs/img/kakarot_github_banner.png | Bin .../kakarot-ssj}/package-lock.json | 0 {kakarot-ssj => cairo/kakarot-ssj}/package.json | 0 {kakarot-ssj => cairo/kakarot-ssj}/rust-toolchain | 0 .../kakarot-ssj}/scripts/compare_snapshot.py | 0 .../kakarot-ssj}/scripts/compute_create_address.ts | 0 .../kakarot-ssj}/scripts/compute_rlp_encoding.ts | 0 .../scripts/compute_starknet_address.ts | 0 .../scripts/data/input_access_list_tx.json | 0 .../scripts/data/input_eip1559_y_parity_false.json | 0 .../scripts/data/input_eip_2930_counter_inc_tx.json | 0 .../kakarot-ssj}/scripts/data/input_fee_tx.json | 0 .../scripts/data/input_legacy_deploy_tx.json | 0 .../kakarot-ssj}/scripts/data/input_legacy_tx.json | 0 .../kakarot-ssj}/scripts/filter_tests.py | 0 .../kakarot-ssj}/scripts/find_selectory.py | 0 .../kakarot-ssj}/scripts/gas_debug_call.py | 0 .../kakarot-ssj}/scripts/gen_snapshot.py | 0 .../kakarot-ssj}/scripts/install_hook.sh | 0 .../kakarot-ssj}/scripts/run_filtered_tests.py | 0 .../kakarot-ssj}/scripts/setup_cairo_native.sh | 0 {kakarot-ssj => cairo/kakarot-ssj}/tsconfig.json | 0 .../mock_pragma}/.gitignore | 0 .../mock_pragma/.tool-versions | 0 {cairo1_contracts => cairo}/mock_pragma/Scarb.lock | 0 {cairo1_contracts => cairo}/mock_pragma/Scarb.toml | 0 .../mock_pragma/src/lib.cairo | 0 .../mock_pragma/src/mock_pragma_oracle.cairo | 0 {kakarot-ssj/crates/evm => cairo/token}/.gitignore | 0 {cairo1_contracts => cairo}/token/.tool-versions | 0 {cairo1_contracts => cairo}/token/Scarb.lock | 0 {cairo1_contracts => cairo}/token/Scarb.toml | 0 {cairo1_contracts => cairo}/token/src/lib.cairo | 0 .../token/src/starknet_token.cairo | 0 {kakarot-ssj/crates => cairo}/utils/.gitignore | 0 {cairo1_contracts => cairo}/utils/.tool-versions | 0 {cairo1_contracts => cairo}/utils/Scarb.lock | 0 {cairo1_contracts => cairo}/utils/Scarb.toml | 0 .../utils/src/benchmark_cairo_calls.cairo | 0 {cairo1_contracts => cairo}/utils/src/lib.cairo | 0 .../utils/src/universal_library_caller.cairo | 0 {kakarot0/src => cairo_zero}/backend/starknet.cairo | 0 {kakarot0/src => cairo_zero}/kakarot/account.cairo | 0 .../kakarot/accounts/account_contract.cairo | 0 .../kakarot/accounts/library.cairo | 0 .../src => cairo_zero}/kakarot/accounts/model.cairo | 0 .../kakarot/accounts/uninitialized_account.cairo | 0 .../src => cairo_zero}/kakarot/constants.cairo | 0 {kakarot0/src => cairo_zero}/kakarot/errors.cairo | 0 {kakarot0/src => cairo_zero}/kakarot/eth_rpc.cairo | 0 {kakarot0/src => cairo_zero}/kakarot/events.cairo | 0 {kakarot0/src => cairo_zero}/kakarot/evm.cairo | 0 {kakarot0/src => cairo_zero}/kakarot/gas.cairo | 0 .../kakarot/instructions/block_information.cairo | 0 .../instructions/duplication_operations.cairo | 0 .../instructions/environmental_information.cairo | 0 .../kakarot/instructions/exchange_operations.cairo | 0 .../kakarot/instructions/logging_operations.cairo | 0 .../kakarot/instructions/memory_operations.cairo | 0 .../kakarot/instructions/push_operations.cairo | 0 .../kakarot/instructions/sha3.cairo | 0 .../instructions/stop_and_math_operations.cairo | 0 .../kakarot/instructions/system_operations.cairo | 0 .../kakarot/interfaces/interfaces.cairo | 0 .../src => cairo_zero}/kakarot/interpreter.cairo | 0 {kakarot0/src => cairo_zero}/kakarot/kakarot.cairo | 0 {kakarot0/src => cairo_zero}/kakarot/library.cairo | 0 {kakarot0/src => cairo_zero}/kakarot/memory.cairo | 0 {kakarot0/src => cairo_zero}/kakarot/model.cairo | 0 .../kakarot/precompiles/blake2f.cairo | 0 .../kakarot/precompiles/ec_recover.cairo | 0 .../kakarot/precompiles/identity.cairo | 0 .../kakarot/precompiles/kakarot_precompiles.cairo | 0 .../kakarot/precompiles/p256verify.cairo | 0 .../kakarot/precompiles/precompiles.cairo | 0 .../kakarot/precompiles/precompiles_helpers.cairo | 0 .../kakarot/precompiles/ripemd160.cairo | 0 .../kakarot/precompiles/sha256.cairo | 0 {kakarot0/src => cairo_zero}/kakarot/stack.cairo | 0 {kakarot0/src => cairo_zero}/kakarot/state.cairo | 0 {kakarot0/src => cairo_zero}/kakarot/storages.cairo | 0 .../src => cairo_zero}/openzeppelin/ERC20.cairo | 0 .../utils/OpenzeppelinAccount.cairo | 0 {kakarot0/src => cairo_zero}/utils/array.cairo | 0 {kakarot0/src => cairo_zero}/utils/bytes.cairo | 0 {kakarot0/src => cairo_zero}/utils/dict.cairo | 0 .../src => cairo_zero}/utils/eth_transaction.cairo | 0 {kakarot0/src => cairo_zero}/utils/maths.cairo | 0 {kakarot0/src => cairo_zero}/utils/rlp.cairo | 0 {kakarot0/src => cairo_zero}/utils/signature.cairo | 0 {kakarot0/src => cairo_zero}/utils/uint256.cairo | 0 {kakarot0/src => cairo_zero}/utils/utils.cairo | 0 docker/deployer/Dockerfile | 2 +- {kakarot0/docs => docs}/CODE_OF_CONDUCT.md | 0 {kakarot0/docs => docs}/CONTRIBUTING.md | 0 {kakarot0/docs => docs}/SECURITY.md | 0 {kakarot0/docs => docs}/general/accounts.md | 0 .../docs => docs}/general/cairo_precompiles.md | 0 .../docs => docs}/general/decode_a_cairo_trace.md | 0 .../docs => docs}/general/kakarot_components.md | 0 {kakarot0/docs => docs}/img/architecture.png | Bin {kakarot0/docs => docs}/img/codespaces.png | Bin {kakarot0/docs => docs}/img/core_evm_diagram.png | Bin .../docs => docs}/img/kakarot_github_banner.png | Bin kakarot_scripts/constants.py | 6 +++--- pyproject.toml | 2 +- tests/fixtures/starknet.py | 2 +- 265 files changed, 38 insertions(+), 38 deletions(-) rename {kakarot-ssj => cairo/kakarot-ssj}/.all-contributorsrc (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/.codespellrc (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/.env.example (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/.gitignore (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/.markdownlint.json (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/.prettierrc.json (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/.tool-versions (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/.trunk/.gitignore (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/.trunk/configs/.isort.cfg (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/.trunk/configs/.shellcheckrc (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/.trunk/configs/.yamllint.yaml (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/.trunk/configs/ruff.toml (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/.trunk/trunk.yaml (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/LICENSE (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/Makefile (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/README.md (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/Scarb.lock (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/Scarb.toml (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/blockchain-tests-skip.yml (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/bun.lockb (100%) rename {cairo1_contracts/mock_pragma => cairo/kakarot-ssj/crates/alexandria_data_structures}/.gitignore (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/alexandria_data_structures/Scarb.toml (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/alexandria_data_structures/src/lib.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/alexandria_data_structures/src/vec.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/contracts/Scarb.toml (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/contracts/src/account_contract.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/contracts/src/cairo1_helpers.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/contracts/src/components.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/contracts/src/components/ownable.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/contracts/src/components/upgradeable.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/contracts/src/errors.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/contracts/src/kakarot_core.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/contracts/src/kakarot_core/eth_rpc.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/contracts/src/kakarot_core/interface.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/contracts/src/kakarot_core/kakarot.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/contracts/src/lib.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/contracts/src/mocks/cairo1_helpers_fixture.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/contracts/src/storage.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/contracts/src/test_contracts/test_upgradeable.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/contracts/src/test_data.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/contracts/src/test_utils.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/contracts/src/uninitialized_account.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/contracts/tests/lib.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/contracts/tests/test_account_contract.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/contracts/tests/test_cairo1_helpers.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/contracts/tests/test_execution_from_outside.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/contracts/tests/test_kakarot_core.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/contracts/tests/test_ownable.cairo (100%) rename {cairo1_contracts/token => cairo/kakarot-ssj/crates/evm}/.gitignore (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/Scarb.toml (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/backend.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/backend/starknet_backend.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/backend/validation.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/call_helpers.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/create_helpers.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/errors.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/gas.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/instructions.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/instructions/block_information.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/instructions/comparison_operations.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/instructions/duplication_operations.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/instructions/environmental_information.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/instructions/exchange_operations.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/instructions/logging_operations.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/instructions/memory_operations.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/instructions/push_operations.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/instructions/sha3.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/instructions/stop_and_arithmetic_operations.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/instructions/system_operations.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/interpreter.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/lib.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/memory.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/model.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/model/account.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/model/vm.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/precompiles.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/precompiles/blake2f.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/precompiles/ec_operations.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/precompiles/ec_operations/ec_add.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/precompiles/ec_operations/ec_mul.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/precompiles/ec_recover.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/precompiles/identity.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/precompiles/modexp.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/precompiles/p256verify.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/precompiles/sha256.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/stack.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/state.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/test_data.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/test_data/test_data_blake2f.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/test_data/test_data_modexp.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/evm/src/test_utils.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/openzeppelin/Scarb.toml (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/openzeppelin/src/lib.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/openzeppelin/src/token.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/openzeppelin/src/token/erc20.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/openzeppelin/src/token/erc20/erc20.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/openzeppelin/src/token/erc20/interface.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/snforge_utils/.gitignore (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/snforge_utils/Scarb.toml (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/snforge_utils/src/contracts.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/snforge_utils/src/lib.cairo (100%) rename {cairo1_contracts => cairo/kakarot-ssj/crates}/utils/.gitignore (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/utils/Scarb.toml (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/utils/src/address.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/utils/src/constants.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/utils/src/crypto.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/utils/src/crypto/blake2_compress.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/utils/src/crypto/modexp.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/utils/src/crypto/modexp/arith.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/utils/src/crypto/modexp/lib.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/utils/src/crypto/modexp/mpnat.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/utils/src/errors.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/utils/src/eth_transaction.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/utils/src/eth_transaction/common.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/utils/src/eth_transaction/eip1559.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/utils/src/eth_transaction/eip2930.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/utils/src/eth_transaction/legacy.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/utils/src/eth_transaction/transaction.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/utils/src/eth_transaction/tx_type.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/utils/src/felt_vec.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/utils/src/fmt.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/utils/src/helpers.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/utils/src/i256.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/utils/src/lib.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/utils/src/math.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/utils/src/rlp.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/utils/src/serialization.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/utils/src/set.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/utils/src/test_data.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/utils/src/traits.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/utils/src/traits/array.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/utils/src/traits/bytes.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/utils/src/traits/eth_address.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/utils/src/traits/integer.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/crates/utils/src/utils.cairo (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/docs/CODE_OF_CONDUCT.md (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/docs/CONTRIBUTING.md (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/docs/SECURITY.md (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/docs/general/account_state.png (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/docs/general/contract_bytecode.md (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/docs/general/contract_storage.md (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/docs/general/local_state.md (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/docs/general/machine.md (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/docs/general/volition.png (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/docs/img/kakarot_github_banner.png (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/package-lock.json (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/package.json (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/rust-toolchain (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/scripts/compare_snapshot.py (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/scripts/compute_create_address.ts (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/scripts/compute_rlp_encoding.ts (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/scripts/compute_starknet_address.ts (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/scripts/data/input_access_list_tx.json (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/scripts/data/input_eip1559_y_parity_false.json (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/scripts/data/input_eip_2930_counter_inc_tx.json (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/scripts/data/input_fee_tx.json (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/scripts/data/input_legacy_deploy_tx.json (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/scripts/data/input_legacy_tx.json (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/scripts/filter_tests.py (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/scripts/find_selectory.py (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/scripts/gas_debug_call.py (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/scripts/gen_snapshot.py (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/scripts/install_hook.sh (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/scripts/run_filtered_tests.py (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/scripts/setup_cairo_native.sh (100%) rename {kakarot-ssj => cairo/kakarot-ssj}/tsconfig.json (100%) rename {kakarot-ssj/crates/alexandria_data_structures => cairo/mock_pragma}/.gitignore (100%) rename {cairo1_contracts => cairo}/mock_pragma/.tool-versions (100%) rename {cairo1_contracts => cairo}/mock_pragma/Scarb.lock (100%) rename {cairo1_contracts => cairo}/mock_pragma/Scarb.toml (100%) rename {cairo1_contracts => cairo}/mock_pragma/src/lib.cairo (100%) rename {cairo1_contracts => cairo}/mock_pragma/src/mock_pragma_oracle.cairo (100%) rename {kakarot-ssj/crates/evm => cairo/token}/.gitignore (100%) rename {cairo1_contracts => cairo}/token/.tool-versions (100%) rename {cairo1_contracts => cairo}/token/Scarb.lock (100%) rename {cairo1_contracts => cairo}/token/Scarb.toml (100%) rename {cairo1_contracts => cairo}/token/src/lib.cairo (100%) rename {cairo1_contracts => cairo}/token/src/starknet_token.cairo (100%) rename {kakarot-ssj/crates => cairo}/utils/.gitignore (100%) rename {cairo1_contracts => cairo}/utils/.tool-versions (100%) rename {cairo1_contracts => cairo}/utils/Scarb.lock (100%) rename {cairo1_contracts => cairo}/utils/Scarb.toml (100%) rename {cairo1_contracts => cairo}/utils/src/benchmark_cairo_calls.cairo (100%) rename {cairo1_contracts => cairo}/utils/src/lib.cairo (100%) rename {cairo1_contracts => cairo}/utils/src/universal_library_caller.cairo (100%) rename {kakarot0/src => cairo_zero}/backend/starknet.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/account.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/accounts/account_contract.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/accounts/library.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/accounts/model.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/accounts/uninitialized_account.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/constants.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/errors.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/eth_rpc.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/events.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/evm.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/gas.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/instructions/block_information.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/instructions/duplication_operations.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/instructions/environmental_information.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/instructions/exchange_operations.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/instructions/logging_operations.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/instructions/memory_operations.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/instructions/push_operations.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/instructions/sha3.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/instructions/stop_and_math_operations.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/instructions/system_operations.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/interfaces/interfaces.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/interpreter.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/kakarot.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/library.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/memory.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/model.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/precompiles/blake2f.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/precompiles/ec_recover.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/precompiles/identity.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/precompiles/kakarot_precompiles.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/precompiles/p256verify.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/precompiles/precompiles.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/precompiles/precompiles_helpers.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/precompiles/ripemd160.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/precompiles/sha256.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/stack.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/state.cairo (100%) rename {kakarot0/src => cairo_zero}/kakarot/storages.cairo (100%) rename {kakarot0/src => cairo_zero}/openzeppelin/ERC20.cairo (100%) rename {kakarot0/src => cairo_zero}/utils/OpenzeppelinAccount.cairo (100%) rename {kakarot0/src => cairo_zero}/utils/array.cairo (100%) rename {kakarot0/src => cairo_zero}/utils/bytes.cairo (100%) rename {kakarot0/src => cairo_zero}/utils/dict.cairo (100%) rename {kakarot0/src => cairo_zero}/utils/eth_transaction.cairo (100%) rename {kakarot0/src => cairo_zero}/utils/maths.cairo (100%) rename {kakarot0/src => cairo_zero}/utils/rlp.cairo (100%) rename {kakarot0/src => cairo_zero}/utils/signature.cairo (100%) rename {kakarot0/src => cairo_zero}/utils/uint256.cairo (100%) rename {kakarot0/src => cairo_zero}/utils/utils.cairo (100%) rename {kakarot0/docs => docs}/CODE_OF_CONDUCT.md (100%) rename {kakarot0/docs => docs}/CONTRIBUTING.md (100%) rename {kakarot0/docs => docs}/SECURITY.md (100%) rename {kakarot0/docs => docs}/general/accounts.md (100%) rename {kakarot0/docs => docs}/general/cairo_precompiles.md (100%) rename {kakarot0/docs => docs}/general/decode_a_cairo_trace.md (100%) rename {kakarot0/docs => docs}/general/kakarot_components.md (100%) rename {kakarot0/docs => docs}/img/architecture.png (100%) rename {kakarot0/docs => docs}/img/codespaces.png (100%) rename {kakarot0/docs => docs}/img/core_evm_diagram.png (100%) rename {kakarot0/docs => docs}/img/kakarot_github_banner.png (100%) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index acb5ad2e4..4ba48f266 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -12,8 +12,8 @@ "python.formatting.blackPath": "/usr/local/py-utils/bin/black", "python.formatting.yapfPath": "/usr/local/py-utils/bin/yapf", "editor.defaultFormatter": "trunk.io", - "cairols.sourceDir": "kakarot0/src", - "cairols.cairoPath": ["kakarot0/src", "tests"] + "cairols.sourceDir": "cairo_zero", + "cairols.cairoPath": ["cairo_zero", "tests"] }, // Add the IDs of extensions you want installed when the container is created. "extensions": [ diff --git a/.github/workflows/kakarot0-ci.yml b/.github/workflows/kakarot0-ci.yml index 3aabed849..423e1f130 100644 --- a/.github/workflows/kakarot0-ci.yml +++ b/.github/workflows/kakarot0-ci.yml @@ -1,4 +1,4 @@ -name: kakarot0-CI +name: cairo-zero-CI on: push: @@ -6,13 +6,13 @@ on: - main pull_request: paths: - - kakarot0/** + - cairo_zero/** env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} concurrency: - group: kakarot0-${{ github.ref }} + group: cairo-zero-${{ github.ref }} cancel-in-progress: true permissions: read-all @@ -34,7 +34,7 @@ jobs: with: filters: | src: - - 'kakarot0/src/**' + - 'cairo_zero/**' kakarot_scripts: - 'kakarot_scripts/**' solidity: diff --git a/.github/workflows/kakarot0-nightly-fuzzing.yml b/.github/workflows/kakarot0-nightly-fuzzing.yml index 143692bd8..c1cbcac83 100644 --- a/.github/workflows/kakarot0-nightly-fuzzing.yml +++ b/.github/workflows/kakarot0-nightly-fuzzing.yml @@ -1,4 +1,4 @@ -name: kakarot0-NIGHTLY-FUZZING +name: cairo-zero-NIGHTLY-FUZZING on: schedule: diff --git a/.github/workflows/kakarot0-release.yml b/.github/workflows/kakarot0-release.yml index 57dd68618..bc29c36ff 100644 --- a/.github/workflows/kakarot0-release.yml +++ b/.github/workflows/kakarot0-release.yml @@ -1,5 +1,5 @@ # trunk-ignore-all(checkov/CKV2_GHA_1) -name: kakarot0-Release +name: cairo-zero-Release on: release: diff --git a/.github/workflows/kakarot0-trunk-check.yaml b/.github/workflows/kakarot0-trunk-check.yaml index 7d730f72c..12de8f20e 100644 --- a/.github/workflows/kakarot0-trunk-check.yaml +++ b/.github/workflows/kakarot0-trunk-check.yaml @@ -1,9 +1,9 @@ -name: kakarot0-Trunk +name: cairo-zero-Trunk on: [pull_request] concurrency: - group: kakarot0-${{ github.ref }} + group: cairo-zero-${{ github.ref }} cancel-in-progress: true permissions: read-all diff --git a/.github/workflows/kakarot0-update-rpc.yml b/.github/workflows/kakarot0-update-rpc.yml index bd08633ac..23c6e2621 100644 --- a/.github/workflows/kakarot0-update-rpc.yml +++ b/.github/workflows/kakarot0-update-rpc.yml @@ -1,4 +1,4 @@ -name: kakarot0 Update Submodule +name: cairo-zero Update Submodule on: release: diff --git a/.github/workflows/ssj-build.yml b/.github/workflows/ssj-build.yml index 638f5338c..00353104f 100644 --- a/.github/workflows/ssj-build.yml +++ b/.github/workflows/ssj-build.yml @@ -22,13 +22,13 @@ jobs: - name: Set up Scarb uses: software-mansion/setup-scarb@v1 with: - tool-versions: ./kakarot-ssj/.tool-versions + tool-versions: ./cairo/kakarot-ssj/.tool-versions - name: Build contracts - run: cd kakarot-ssj/ && scarb build -p contracts + run: cd cairo/kakarot-ssj/ && scarb build -p contracts - name: Upload artifacts uses: actions/upload-artifact@v3 with: name: ${{ inputs.artifact-name }} - path: kakarot-ssj/target/dev + path: cairo/kakarot-ssj/target/dev diff --git a/.github/workflows/ssj-ci.yml b/.github/workflows/ssj-ci.yml index 7aa78af29..82e485376 100644 --- a/.github/workflows/ssj-ci.yml +++ b/.github/workflows/ssj-ci.yml @@ -5,7 +5,7 @@ on: branches: - main paths: - - kakarot-ssj/** + - cairo/kakarot-ssj/** env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -20,7 +20,7 @@ jobs: ssj-build: uses: ./.github/workflows/ssj-build.yml with: - artifact-name: kakarot-ssj-build + artifact-name: ssj-build ssj-tests-unit: uses: ./.github/workflows/ssj-tests-unit.yml @@ -31,7 +31,7 @@ jobs: uses: ./.github/workflows/ssj-ef-tests.yml needs: [ssj-build] with: - artifact-name: kakarot-ssj-build + artifact-name: ssj-build ssj-resources: runs-on: ubuntu-latest diff --git a/.github/workflows/ssj-ef-tests.yml b/.github/workflows/ssj-ef-tests.yml index c16585f06..288c98489 100644 --- a/.github/workflows/ssj-ef-tests.yml +++ b/.github/workflows/ssj-ef-tests.yml @@ -26,21 +26,21 @@ jobs: ~/.cargo/registry/index/ ~/.cargo/registry/cache/ ~/.cargo/git/db/ - kakarot-ssj/target/ + cairo/kakarot-ssj/target/ ./libcairo_native_runtime.a key: ${{ runner.os }}-cairo-native-${{ hashFiles('**/Cargo.lock', 'scripts/setup_cairo_native.sh') }} - name: Make setup script executable - run: chmod +x ./kakarot-ssj/scripts/setup_cairo_native.sh + run: chmod +x ./cairo/kakarot-ssj/scripts/setup_cairo_native.sh - name: Setup Cairo Native run: | if [[ "${{ steps.cache-cairo-native.outputs.cache-hit }}" == 'true' ]]; then - sudo ./kakarot-ssj/scripts/setup_cairo_native.sh -s + sudo ./cairo/kakarot-ssj/scripts/setup_cairo_native.sh -s else - sudo ./kakarot-ssj/scripts/setup_cairo_native.sh + sudo ./cairo/kakarot-ssj/scripts/setup_cairo_native.sh fi - name: Set Environment Variables @@ -61,7 +61,7 @@ jobs: uses: actions/checkout@v4 with: sparse-checkout: | - ./kakarot-ssj/blockchain-tests-skip.yml + ./cairo/kakarot-ssj/blockchain-tests-skip.yml sparse-checkout-cone-mode: false path: skip-file diff --git a/.github/workflows/ssj-release.yml b/.github/workflows/ssj-release.yml index ac31ddea3..c007b0bee 100644 --- a/.github/workflows/ssj-release.yml +++ b/.github/workflows/ssj-release.yml @@ -14,12 +14,12 @@ jobs: - name: Set up Scarb uses: software-mansion/setup-scarb@v1 with: - tool-versions: ./kakarot-ssj/.tool-versions + tool-versions: ./cairo/kakarot-ssj/.tool-versions - name: Build contracts run: | scarb build -p contracts - name: Zip dev artifacts - run: zip -rj kakarot-ssj-build.zip target/dev + run: zip -rj kakarot-ssj-build.zip cairo/kakarot-ssj/target/dev - name: Upload artifacts to release uses: svenstaro/upload-release-action@v2 with: diff --git a/.github/workflows/ssj-test.yml b/.github/workflows/ssj-test.yml index 56eae5d9a..2ea127ea1 100644 --- a/.github/workflows/ssj-test.yml +++ b/.github/workflows/ssj-test.yml @@ -5,7 +5,7 @@ permissions: read-all on: pull_request: paths: - - kakarot-ssj/** + - cairo/kakarot-ssj/** concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -15,7 +15,7 @@ jobs: ssj-build: uses: ./.github/workflows/ssj-build.yml with: - artifact-name: kakarot-ssj-build + artifact-name: ssj-build ssj-tests-unit: uses: ./.github/workflows/ssj-tests-unit.yml @@ -26,4 +26,4 @@ jobs: uses: ./.github/workflows/ssj-ef-tests.yml needs: [ssj-build] with: - artifact-name: kakarot-ssj-build + artifact-name: ssj-build diff --git a/.github/workflows/ssj-tests-unit.yml b/.github/workflows/ssj-tests-unit.yml index 7452989a0..ab9068492 100644 --- a/.github/workflows/ssj-tests-unit.yml +++ b/.github/workflows/ssj-tests-unit.yml @@ -18,11 +18,11 @@ jobs: - uses: foundry-rs/setup-snfoundry@v3 - uses: software-mansion/setup-scarb@v1 with: - tool-versions: ./kakarot-ssj/.tool-versions + tool-versions: ./cairo/kakarot-ssj/.tool-versions - name: Run format check if: inputs.run-fmt-check - run: cd kakarot-ssj && scarb fmt --check + run: cd cairo/kakarot-ssj && scarb fmt --check - name: Run tests - run: cd kakarot-ssj && scarb test + run: cd cairo/kakarot-ssj && scarb test diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index 7dca4f9e6..348b0b6af 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -76,7 +76,7 @@ lint: - tests/ef_tests/test_data - .katana/messaging_config.json - deployments - - kakarot-ssj + - cairo/kakarot-ssj - linters: [solidity] paths: - solidity_contracts/src/UniswapV2/**/*.sol diff --git a/Makefile b/Makefile index 8c7a848b3..a73d5946a 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ SSJ_DIR = $(BUILD_DIR)/ssj build-ssj: @echo "Building Kakarot SSJ" @mkdir -p $(SSJ_DIR) - @cd kakarot-ssj && scarb build -p contracts && find target/dev -type f -name '*contracts*' | grep -vE 'test|mock|Mock' | xargs -I {} cp {} ../$(SSJ_DIR) + @cd cairo/kakarot-ssj && scarb build -p contracts && find target/dev -type f -name '*contracts*' | grep -vE 'test|mock|Mock' | xargs -I {} cp {} ../../$(SSJ_DIR) build: build-ssj uv run compile diff --git a/kakarot-ssj/.all-contributorsrc b/cairo/kakarot-ssj/.all-contributorsrc similarity index 100% rename from kakarot-ssj/.all-contributorsrc rename to cairo/kakarot-ssj/.all-contributorsrc diff --git a/kakarot-ssj/.codespellrc b/cairo/kakarot-ssj/.codespellrc similarity index 100% rename from kakarot-ssj/.codespellrc rename to cairo/kakarot-ssj/.codespellrc diff --git a/kakarot-ssj/.env.example b/cairo/kakarot-ssj/.env.example similarity index 100% rename from kakarot-ssj/.env.example rename to cairo/kakarot-ssj/.env.example diff --git a/kakarot-ssj/.gitignore b/cairo/kakarot-ssj/.gitignore similarity index 100% rename from kakarot-ssj/.gitignore rename to cairo/kakarot-ssj/.gitignore diff --git a/kakarot-ssj/.markdownlint.json b/cairo/kakarot-ssj/.markdownlint.json similarity index 100% rename from kakarot-ssj/.markdownlint.json rename to cairo/kakarot-ssj/.markdownlint.json diff --git a/kakarot-ssj/.prettierrc.json b/cairo/kakarot-ssj/.prettierrc.json similarity index 100% rename from kakarot-ssj/.prettierrc.json rename to cairo/kakarot-ssj/.prettierrc.json diff --git a/kakarot-ssj/.tool-versions b/cairo/kakarot-ssj/.tool-versions similarity index 100% rename from kakarot-ssj/.tool-versions rename to cairo/kakarot-ssj/.tool-versions diff --git a/kakarot-ssj/.trunk/.gitignore b/cairo/kakarot-ssj/.trunk/.gitignore similarity index 100% rename from kakarot-ssj/.trunk/.gitignore rename to cairo/kakarot-ssj/.trunk/.gitignore diff --git a/kakarot-ssj/.trunk/configs/.isort.cfg b/cairo/kakarot-ssj/.trunk/configs/.isort.cfg similarity index 100% rename from kakarot-ssj/.trunk/configs/.isort.cfg rename to cairo/kakarot-ssj/.trunk/configs/.isort.cfg diff --git a/kakarot-ssj/.trunk/configs/.shellcheckrc b/cairo/kakarot-ssj/.trunk/configs/.shellcheckrc similarity index 100% rename from kakarot-ssj/.trunk/configs/.shellcheckrc rename to cairo/kakarot-ssj/.trunk/configs/.shellcheckrc diff --git a/kakarot-ssj/.trunk/configs/.yamllint.yaml b/cairo/kakarot-ssj/.trunk/configs/.yamllint.yaml similarity index 100% rename from kakarot-ssj/.trunk/configs/.yamllint.yaml rename to cairo/kakarot-ssj/.trunk/configs/.yamllint.yaml diff --git a/kakarot-ssj/.trunk/configs/ruff.toml b/cairo/kakarot-ssj/.trunk/configs/ruff.toml similarity index 100% rename from kakarot-ssj/.trunk/configs/ruff.toml rename to cairo/kakarot-ssj/.trunk/configs/ruff.toml diff --git a/kakarot-ssj/.trunk/trunk.yaml b/cairo/kakarot-ssj/.trunk/trunk.yaml similarity index 100% rename from kakarot-ssj/.trunk/trunk.yaml rename to cairo/kakarot-ssj/.trunk/trunk.yaml diff --git a/kakarot-ssj/LICENSE b/cairo/kakarot-ssj/LICENSE similarity index 100% rename from kakarot-ssj/LICENSE rename to cairo/kakarot-ssj/LICENSE diff --git a/kakarot-ssj/Makefile b/cairo/kakarot-ssj/Makefile similarity index 100% rename from kakarot-ssj/Makefile rename to cairo/kakarot-ssj/Makefile diff --git a/kakarot-ssj/README.md b/cairo/kakarot-ssj/README.md similarity index 100% rename from kakarot-ssj/README.md rename to cairo/kakarot-ssj/README.md diff --git a/kakarot-ssj/Scarb.lock b/cairo/kakarot-ssj/Scarb.lock similarity index 100% rename from kakarot-ssj/Scarb.lock rename to cairo/kakarot-ssj/Scarb.lock diff --git a/kakarot-ssj/Scarb.toml b/cairo/kakarot-ssj/Scarb.toml similarity index 100% rename from kakarot-ssj/Scarb.toml rename to cairo/kakarot-ssj/Scarb.toml diff --git a/kakarot-ssj/blockchain-tests-skip.yml b/cairo/kakarot-ssj/blockchain-tests-skip.yml similarity index 100% rename from kakarot-ssj/blockchain-tests-skip.yml rename to cairo/kakarot-ssj/blockchain-tests-skip.yml diff --git a/kakarot-ssj/bun.lockb b/cairo/kakarot-ssj/bun.lockb similarity index 100% rename from kakarot-ssj/bun.lockb rename to cairo/kakarot-ssj/bun.lockb diff --git a/cairo1_contracts/mock_pragma/.gitignore b/cairo/kakarot-ssj/crates/alexandria_data_structures/.gitignore similarity index 100% rename from cairo1_contracts/mock_pragma/.gitignore rename to cairo/kakarot-ssj/crates/alexandria_data_structures/.gitignore diff --git a/kakarot-ssj/crates/alexandria_data_structures/Scarb.toml b/cairo/kakarot-ssj/crates/alexandria_data_structures/Scarb.toml similarity index 100% rename from kakarot-ssj/crates/alexandria_data_structures/Scarb.toml rename to cairo/kakarot-ssj/crates/alexandria_data_structures/Scarb.toml diff --git a/kakarot-ssj/crates/alexandria_data_structures/src/lib.cairo b/cairo/kakarot-ssj/crates/alexandria_data_structures/src/lib.cairo similarity index 100% rename from kakarot-ssj/crates/alexandria_data_structures/src/lib.cairo rename to cairo/kakarot-ssj/crates/alexandria_data_structures/src/lib.cairo diff --git a/kakarot-ssj/crates/alexandria_data_structures/src/vec.cairo b/cairo/kakarot-ssj/crates/alexandria_data_structures/src/vec.cairo similarity index 100% rename from kakarot-ssj/crates/alexandria_data_structures/src/vec.cairo rename to cairo/kakarot-ssj/crates/alexandria_data_structures/src/vec.cairo diff --git a/kakarot-ssj/crates/contracts/Scarb.toml b/cairo/kakarot-ssj/crates/contracts/Scarb.toml similarity index 100% rename from kakarot-ssj/crates/contracts/Scarb.toml rename to cairo/kakarot-ssj/crates/contracts/Scarb.toml diff --git a/kakarot-ssj/crates/contracts/src/account_contract.cairo b/cairo/kakarot-ssj/crates/contracts/src/account_contract.cairo similarity index 100% rename from kakarot-ssj/crates/contracts/src/account_contract.cairo rename to cairo/kakarot-ssj/crates/contracts/src/account_contract.cairo diff --git a/kakarot-ssj/crates/contracts/src/cairo1_helpers.cairo b/cairo/kakarot-ssj/crates/contracts/src/cairo1_helpers.cairo similarity index 100% rename from kakarot-ssj/crates/contracts/src/cairo1_helpers.cairo rename to cairo/kakarot-ssj/crates/contracts/src/cairo1_helpers.cairo diff --git a/kakarot-ssj/crates/contracts/src/components.cairo b/cairo/kakarot-ssj/crates/contracts/src/components.cairo similarity index 100% rename from kakarot-ssj/crates/contracts/src/components.cairo rename to cairo/kakarot-ssj/crates/contracts/src/components.cairo diff --git a/kakarot-ssj/crates/contracts/src/components/ownable.cairo b/cairo/kakarot-ssj/crates/contracts/src/components/ownable.cairo similarity index 100% rename from kakarot-ssj/crates/contracts/src/components/ownable.cairo rename to cairo/kakarot-ssj/crates/contracts/src/components/ownable.cairo diff --git a/kakarot-ssj/crates/contracts/src/components/upgradeable.cairo b/cairo/kakarot-ssj/crates/contracts/src/components/upgradeable.cairo similarity index 100% rename from kakarot-ssj/crates/contracts/src/components/upgradeable.cairo rename to cairo/kakarot-ssj/crates/contracts/src/components/upgradeable.cairo diff --git a/kakarot-ssj/crates/contracts/src/errors.cairo b/cairo/kakarot-ssj/crates/contracts/src/errors.cairo similarity index 100% rename from kakarot-ssj/crates/contracts/src/errors.cairo rename to cairo/kakarot-ssj/crates/contracts/src/errors.cairo diff --git a/kakarot-ssj/crates/contracts/src/kakarot_core.cairo b/cairo/kakarot-ssj/crates/contracts/src/kakarot_core.cairo similarity index 100% rename from kakarot-ssj/crates/contracts/src/kakarot_core.cairo rename to cairo/kakarot-ssj/crates/contracts/src/kakarot_core.cairo diff --git a/kakarot-ssj/crates/contracts/src/kakarot_core/eth_rpc.cairo b/cairo/kakarot-ssj/crates/contracts/src/kakarot_core/eth_rpc.cairo similarity index 100% rename from kakarot-ssj/crates/contracts/src/kakarot_core/eth_rpc.cairo rename to cairo/kakarot-ssj/crates/contracts/src/kakarot_core/eth_rpc.cairo diff --git a/kakarot-ssj/crates/contracts/src/kakarot_core/interface.cairo b/cairo/kakarot-ssj/crates/contracts/src/kakarot_core/interface.cairo similarity index 100% rename from kakarot-ssj/crates/contracts/src/kakarot_core/interface.cairo rename to cairo/kakarot-ssj/crates/contracts/src/kakarot_core/interface.cairo diff --git a/kakarot-ssj/crates/contracts/src/kakarot_core/kakarot.cairo b/cairo/kakarot-ssj/crates/contracts/src/kakarot_core/kakarot.cairo similarity index 100% rename from kakarot-ssj/crates/contracts/src/kakarot_core/kakarot.cairo rename to cairo/kakarot-ssj/crates/contracts/src/kakarot_core/kakarot.cairo diff --git a/kakarot-ssj/crates/contracts/src/lib.cairo b/cairo/kakarot-ssj/crates/contracts/src/lib.cairo similarity index 100% rename from kakarot-ssj/crates/contracts/src/lib.cairo rename to cairo/kakarot-ssj/crates/contracts/src/lib.cairo diff --git a/kakarot-ssj/crates/contracts/src/mocks/cairo1_helpers_fixture.cairo b/cairo/kakarot-ssj/crates/contracts/src/mocks/cairo1_helpers_fixture.cairo similarity index 100% rename from kakarot-ssj/crates/contracts/src/mocks/cairo1_helpers_fixture.cairo rename to cairo/kakarot-ssj/crates/contracts/src/mocks/cairo1_helpers_fixture.cairo diff --git a/kakarot-ssj/crates/contracts/src/storage.cairo b/cairo/kakarot-ssj/crates/contracts/src/storage.cairo similarity index 100% rename from kakarot-ssj/crates/contracts/src/storage.cairo rename to cairo/kakarot-ssj/crates/contracts/src/storage.cairo diff --git a/kakarot-ssj/crates/contracts/src/test_contracts/test_upgradeable.cairo b/cairo/kakarot-ssj/crates/contracts/src/test_contracts/test_upgradeable.cairo similarity index 100% rename from kakarot-ssj/crates/contracts/src/test_contracts/test_upgradeable.cairo rename to cairo/kakarot-ssj/crates/contracts/src/test_contracts/test_upgradeable.cairo diff --git a/kakarot-ssj/crates/contracts/src/test_data.cairo b/cairo/kakarot-ssj/crates/contracts/src/test_data.cairo similarity index 100% rename from kakarot-ssj/crates/contracts/src/test_data.cairo rename to cairo/kakarot-ssj/crates/contracts/src/test_data.cairo diff --git a/kakarot-ssj/crates/contracts/src/test_utils.cairo b/cairo/kakarot-ssj/crates/contracts/src/test_utils.cairo similarity index 100% rename from kakarot-ssj/crates/contracts/src/test_utils.cairo rename to cairo/kakarot-ssj/crates/contracts/src/test_utils.cairo diff --git a/kakarot-ssj/crates/contracts/src/uninitialized_account.cairo b/cairo/kakarot-ssj/crates/contracts/src/uninitialized_account.cairo similarity index 100% rename from kakarot-ssj/crates/contracts/src/uninitialized_account.cairo rename to cairo/kakarot-ssj/crates/contracts/src/uninitialized_account.cairo diff --git a/kakarot-ssj/crates/contracts/tests/lib.cairo b/cairo/kakarot-ssj/crates/contracts/tests/lib.cairo similarity index 100% rename from kakarot-ssj/crates/contracts/tests/lib.cairo rename to cairo/kakarot-ssj/crates/contracts/tests/lib.cairo diff --git a/kakarot-ssj/crates/contracts/tests/test_account_contract.cairo b/cairo/kakarot-ssj/crates/contracts/tests/test_account_contract.cairo similarity index 100% rename from kakarot-ssj/crates/contracts/tests/test_account_contract.cairo rename to cairo/kakarot-ssj/crates/contracts/tests/test_account_contract.cairo diff --git a/kakarot-ssj/crates/contracts/tests/test_cairo1_helpers.cairo b/cairo/kakarot-ssj/crates/contracts/tests/test_cairo1_helpers.cairo similarity index 100% rename from kakarot-ssj/crates/contracts/tests/test_cairo1_helpers.cairo rename to cairo/kakarot-ssj/crates/contracts/tests/test_cairo1_helpers.cairo diff --git a/kakarot-ssj/crates/contracts/tests/test_execution_from_outside.cairo b/cairo/kakarot-ssj/crates/contracts/tests/test_execution_from_outside.cairo similarity index 100% rename from kakarot-ssj/crates/contracts/tests/test_execution_from_outside.cairo rename to cairo/kakarot-ssj/crates/contracts/tests/test_execution_from_outside.cairo diff --git a/kakarot-ssj/crates/contracts/tests/test_kakarot_core.cairo b/cairo/kakarot-ssj/crates/contracts/tests/test_kakarot_core.cairo similarity index 100% rename from kakarot-ssj/crates/contracts/tests/test_kakarot_core.cairo rename to cairo/kakarot-ssj/crates/contracts/tests/test_kakarot_core.cairo diff --git a/kakarot-ssj/crates/contracts/tests/test_ownable.cairo b/cairo/kakarot-ssj/crates/contracts/tests/test_ownable.cairo similarity index 100% rename from kakarot-ssj/crates/contracts/tests/test_ownable.cairo rename to cairo/kakarot-ssj/crates/contracts/tests/test_ownable.cairo diff --git a/cairo1_contracts/token/.gitignore b/cairo/kakarot-ssj/crates/evm/.gitignore similarity index 100% rename from cairo1_contracts/token/.gitignore rename to cairo/kakarot-ssj/crates/evm/.gitignore diff --git a/kakarot-ssj/crates/evm/Scarb.toml b/cairo/kakarot-ssj/crates/evm/Scarb.toml similarity index 100% rename from kakarot-ssj/crates/evm/Scarb.toml rename to cairo/kakarot-ssj/crates/evm/Scarb.toml diff --git a/kakarot-ssj/crates/evm/src/backend.cairo b/cairo/kakarot-ssj/crates/evm/src/backend.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/backend.cairo rename to cairo/kakarot-ssj/crates/evm/src/backend.cairo diff --git a/kakarot-ssj/crates/evm/src/backend/starknet_backend.cairo b/cairo/kakarot-ssj/crates/evm/src/backend/starknet_backend.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/backend/starknet_backend.cairo rename to cairo/kakarot-ssj/crates/evm/src/backend/starknet_backend.cairo diff --git a/kakarot-ssj/crates/evm/src/backend/validation.cairo b/cairo/kakarot-ssj/crates/evm/src/backend/validation.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/backend/validation.cairo rename to cairo/kakarot-ssj/crates/evm/src/backend/validation.cairo diff --git a/kakarot-ssj/crates/evm/src/call_helpers.cairo b/cairo/kakarot-ssj/crates/evm/src/call_helpers.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/call_helpers.cairo rename to cairo/kakarot-ssj/crates/evm/src/call_helpers.cairo diff --git a/kakarot-ssj/crates/evm/src/create_helpers.cairo b/cairo/kakarot-ssj/crates/evm/src/create_helpers.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/create_helpers.cairo rename to cairo/kakarot-ssj/crates/evm/src/create_helpers.cairo diff --git a/kakarot-ssj/crates/evm/src/errors.cairo b/cairo/kakarot-ssj/crates/evm/src/errors.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/errors.cairo rename to cairo/kakarot-ssj/crates/evm/src/errors.cairo diff --git a/kakarot-ssj/crates/evm/src/gas.cairo b/cairo/kakarot-ssj/crates/evm/src/gas.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/gas.cairo rename to cairo/kakarot-ssj/crates/evm/src/gas.cairo diff --git a/kakarot-ssj/crates/evm/src/instructions.cairo b/cairo/kakarot-ssj/crates/evm/src/instructions.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/instructions.cairo rename to cairo/kakarot-ssj/crates/evm/src/instructions.cairo diff --git a/kakarot-ssj/crates/evm/src/instructions/block_information.cairo b/cairo/kakarot-ssj/crates/evm/src/instructions/block_information.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/instructions/block_information.cairo rename to cairo/kakarot-ssj/crates/evm/src/instructions/block_information.cairo diff --git a/kakarot-ssj/crates/evm/src/instructions/comparison_operations.cairo b/cairo/kakarot-ssj/crates/evm/src/instructions/comparison_operations.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/instructions/comparison_operations.cairo rename to cairo/kakarot-ssj/crates/evm/src/instructions/comparison_operations.cairo diff --git a/kakarot-ssj/crates/evm/src/instructions/duplication_operations.cairo b/cairo/kakarot-ssj/crates/evm/src/instructions/duplication_operations.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/instructions/duplication_operations.cairo rename to cairo/kakarot-ssj/crates/evm/src/instructions/duplication_operations.cairo diff --git a/kakarot-ssj/crates/evm/src/instructions/environmental_information.cairo b/cairo/kakarot-ssj/crates/evm/src/instructions/environmental_information.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/instructions/environmental_information.cairo rename to cairo/kakarot-ssj/crates/evm/src/instructions/environmental_information.cairo diff --git a/kakarot-ssj/crates/evm/src/instructions/exchange_operations.cairo b/cairo/kakarot-ssj/crates/evm/src/instructions/exchange_operations.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/instructions/exchange_operations.cairo rename to cairo/kakarot-ssj/crates/evm/src/instructions/exchange_operations.cairo diff --git a/kakarot-ssj/crates/evm/src/instructions/logging_operations.cairo b/cairo/kakarot-ssj/crates/evm/src/instructions/logging_operations.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/instructions/logging_operations.cairo rename to cairo/kakarot-ssj/crates/evm/src/instructions/logging_operations.cairo diff --git a/kakarot-ssj/crates/evm/src/instructions/memory_operations.cairo b/cairo/kakarot-ssj/crates/evm/src/instructions/memory_operations.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/instructions/memory_operations.cairo rename to cairo/kakarot-ssj/crates/evm/src/instructions/memory_operations.cairo diff --git a/kakarot-ssj/crates/evm/src/instructions/push_operations.cairo b/cairo/kakarot-ssj/crates/evm/src/instructions/push_operations.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/instructions/push_operations.cairo rename to cairo/kakarot-ssj/crates/evm/src/instructions/push_operations.cairo diff --git a/kakarot-ssj/crates/evm/src/instructions/sha3.cairo b/cairo/kakarot-ssj/crates/evm/src/instructions/sha3.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/instructions/sha3.cairo rename to cairo/kakarot-ssj/crates/evm/src/instructions/sha3.cairo diff --git a/kakarot-ssj/crates/evm/src/instructions/stop_and_arithmetic_operations.cairo b/cairo/kakarot-ssj/crates/evm/src/instructions/stop_and_arithmetic_operations.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/instructions/stop_and_arithmetic_operations.cairo rename to cairo/kakarot-ssj/crates/evm/src/instructions/stop_and_arithmetic_operations.cairo diff --git a/kakarot-ssj/crates/evm/src/instructions/system_operations.cairo b/cairo/kakarot-ssj/crates/evm/src/instructions/system_operations.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/instructions/system_operations.cairo rename to cairo/kakarot-ssj/crates/evm/src/instructions/system_operations.cairo diff --git a/kakarot-ssj/crates/evm/src/interpreter.cairo b/cairo/kakarot-ssj/crates/evm/src/interpreter.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/interpreter.cairo rename to cairo/kakarot-ssj/crates/evm/src/interpreter.cairo diff --git a/kakarot-ssj/crates/evm/src/lib.cairo b/cairo/kakarot-ssj/crates/evm/src/lib.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/lib.cairo rename to cairo/kakarot-ssj/crates/evm/src/lib.cairo diff --git a/kakarot-ssj/crates/evm/src/memory.cairo b/cairo/kakarot-ssj/crates/evm/src/memory.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/memory.cairo rename to cairo/kakarot-ssj/crates/evm/src/memory.cairo diff --git a/kakarot-ssj/crates/evm/src/model.cairo b/cairo/kakarot-ssj/crates/evm/src/model.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/model.cairo rename to cairo/kakarot-ssj/crates/evm/src/model.cairo diff --git a/kakarot-ssj/crates/evm/src/model/account.cairo b/cairo/kakarot-ssj/crates/evm/src/model/account.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/model/account.cairo rename to cairo/kakarot-ssj/crates/evm/src/model/account.cairo diff --git a/kakarot-ssj/crates/evm/src/model/vm.cairo b/cairo/kakarot-ssj/crates/evm/src/model/vm.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/model/vm.cairo rename to cairo/kakarot-ssj/crates/evm/src/model/vm.cairo diff --git a/kakarot-ssj/crates/evm/src/precompiles.cairo b/cairo/kakarot-ssj/crates/evm/src/precompiles.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/precompiles.cairo rename to cairo/kakarot-ssj/crates/evm/src/precompiles.cairo diff --git a/kakarot-ssj/crates/evm/src/precompiles/blake2f.cairo b/cairo/kakarot-ssj/crates/evm/src/precompiles/blake2f.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/precompiles/blake2f.cairo rename to cairo/kakarot-ssj/crates/evm/src/precompiles/blake2f.cairo diff --git a/kakarot-ssj/crates/evm/src/precompiles/ec_operations.cairo b/cairo/kakarot-ssj/crates/evm/src/precompiles/ec_operations.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/precompiles/ec_operations.cairo rename to cairo/kakarot-ssj/crates/evm/src/precompiles/ec_operations.cairo diff --git a/kakarot-ssj/crates/evm/src/precompiles/ec_operations/ec_add.cairo b/cairo/kakarot-ssj/crates/evm/src/precompiles/ec_operations/ec_add.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/precompiles/ec_operations/ec_add.cairo rename to cairo/kakarot-ssj/crates/evm/src/precompiles/ec_operations/ec_add.cairo diff --git a/kakarot-ssj/crates/evm/src/precompiles/ec_operations/ec_mul.cairo b/cairo/kakarot-ssj/crates/evm/src/precompiles/ec_operations/ec_mul.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/precompiles/ec_operations/ec_mul.cairo rename to cairo/kakarot-ssj/crates/evm/src/precompiles/ec_operations/ec_mul.cairo diff --git a/kakarot-ssj/crates/evm/src/precompiles/ec_recover.cairo b/cairo/kakarot-ssj/crates/evm/src/precompiles/ec_recover.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/precompiles/ec_recover.cairo rename to cairo/kakarot-ssj/crates/evm/src/precompiles/ec_recover.cairo diff --git a/kakarot-ssj/crates/evm/src/precompiles/identity.cairo b/cairo/kakarot-ssj/crates/evm/src/precompiles/identity.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/precompiles/identity.cairo rename to cairo/kakarot-ssj/crates/evm/src/precompiles/identity.cairo diff --git a/kakarot-ssj/crates/evm/src/precompiles/modexp.cairo b/cairo/kakarot-ssj/crates/evm/src/precompiles/modexp.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/precompiles/modexp.cairo rename to cairo/kakarot-ssj/crates/evm/src/precompiles/modexp.cairo diff --git a/kakarot-ssj/crates/evm/src/precompiles/p256verify.cairo b/cairo/kakarot-ssj/crates/evm/src/precompiles/p256verify.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/precompiles/p256verify.cairo rename to cairo/kakarot-ssj/crates/evm/src/precompiles/p256verify.cairo diff --git a/kakarot-ssj/crates/evm/src/precompiles/sha256.cairo b/cairo/kakarot-ssj/crates/evm/src/precompiles/sha256.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/precompiles/sha256.cairo rename to cairo/kakarot-ssj/crates/evm/src/precompiles/sha256.cairo diff --git a/kakarot-ssj/crates/evm/src/stack.cairo b/cairo/kakarot-ssj/crates/evm/src/stack.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/stack.cairo rename to cairo/kakarot-ssj/crates/evm/src/stack.cairo diff --git a/kakarot-ssj/crates/evm/src/state.cairo b/cairo/kakarot-ssj/crates/evm/src/state.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/state.cairo rename to cairo/kakarot-ssj/crates/evm/src/state.cairo diff --git a/kakarot-ssj/crates/evm/src/test_data.cairo b/cairo/kakarot-ssj/crates/evm/src/test_data.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/test_data.cairo rename to cairo/kakarot-ssj/crates/evm/src/test_data.cairo diff --git a/kakarot-ssj/crates/evm/src/test_data/test_data_blake2f.cairo b/cairo/kakarot-ssj/crates/evm/src/test_data/test_data_blake2f.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/test_data/test_data_blake2f.cairo rename to cairo/kakarot-ssj/crates/evm/src/test_data/test_data_blake2f.cairo diff --git a/kakarot-ssj/crates/evm/src/test_data/test_data_modexp.cairo b/cairo/kakarot-ssj/crates/evm/src/test_data/test_data_modexp.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/test_data/test_data_modexp.cairo rename to cairo/kakarot-ssj/crates/evm/src/test_data/test_data_modexp.cairo diff --git a/kakarot-ssj/crates/evm/src/test_utils.cairo b/cairo/kakarot-ssj/crates/evm/src/test_utils.cairo similarity index 100% rename from kakarot-ssj/crates/evm/src/test_utils.cairo rename to cairo/kakarot-ssj/crates/evm/src/test_utils.cairo diff --git a/kakarot-ssj/crates/openzeppelin/Scarb.toml b/cairo/kakarot-ssj/crates/openzeppelin/Scarb.toml similarity index 100% rename from kakarot-ssj/crates/openzeppelin/Scarb.toml rename to cairo/kakarot-ssj/crates/openzeppelin/Scarb.toml diff --git a/kakarot-ssj/crates/openzeppelin/src/lib.cairo b/cairo/kakarot-ssj/crates/openzeppelin/src/lib.cairo similarity index 100% rename from kakarot-ssj/crates/openzeppelin/src/lib.cairo rename to cairo/kakarot-ssj/crates/openzeppelin/src/lib.cairo diff --git a/kakarot-ssj/crates/openzeppelin/src/token.cairo b/cairo/kakarot-ssj/crates/openzeppelin/src/token.cairo similarity index 100% rename from kakarot-ssj/crates/openzeppelin/src/token.cairo rename to cairo/kakarot-ssj/crates/openzeppelin/src/token.cairo diff --git a/kakarot-ssj/crates/openzeppelin/src/token/erc20.cairo b/cairo/kakarot-ssj/crates/openzeppelin/src/token/erc20.cairo similarity index 100% rename from kakarot-ssj/crates/openzeppelin/src/token/erc20.cairo rename to cairo/kakarot-ssj/crates/openzeppelin/src/token/erc20.cairo diff --git a/kakarot-ssj/crates/openzeppelin/src/token/erc20/erc20.cairo b/cairo/kakarot-ssj/crates/openzeppelin/src/token/erc20/erc20.cairo similarity index 100% rename from kakarot-ssj/crates/openzeppelin/src/token/erc20/erc20.cairo rename to cairo/kakarot-ssj/crates/openzeppelin/src/token/erc20/erc20.cairo diff --git a/kakarot-ssj/crates/openzeppelin/src/token/erc20/interface.cairo b/cairo/kakarot-ssj/crates/openzeppelin/src/token/erc20/interface.cairo similarity index 100% rename from kakarot-ssj/crates/openzeppelin/src/token/erc20/interface.cairo rename to cairo/kakarot-ssj/crates/openzeppelin/src/token/erc20/interface.cairo diff --git a/kakarot-ssj/crates/snforge_utils/.gitignore b/cairo/kakarot-ssj/crates/snforge_utils/.gitignore similarity index 100% rename from kakarot-ssj/crates/snforge_utils/.gitignore rename to cairo/kakarot-ssj/crates/snforge_utils/.gitignore diff --git a/kakarot-ssj/crates/snforge_utils/Scarb.toml b/cairo/kakarot-ssj/crates/snforge_utils/Scarb.toml similarity index 100% rename from kakarot-ssj/crates/snforge_utils/Scarb.toml rename to cairo/kakarot-ssj/crates/snforge_utils/Scarb.toml diff --git a/kakarot-ssj/crates/snforge_utils/src/contracts.cairo b/cairo/kakarot-ssj/crates/snforge_utils/src/contracts.cairo similarity index 100% rename from kakarot-ssj/crates/snforge_utils/src/contracts.cairo rename to cairo/kakarot-ssj/crates/snforge_utils/src/contracts.cairo diff --git a/kakarot-ssj/crates/snforge_utils/src/lib.cairo b/cairo/kakarot-ssj/crates/snforge_utils/src/lib.cairo similarity index 100% rename from kakarot-ssj/crates/snforge_utils/src/lib.cairo rename to cairo/kakarot-ssj/crates/snforge_utils/src/lib.cairo diff --git a/cairo1_contracts/utils/.gitignore b/cairo/kakarot-ssj/crates/utils/.gitignore similarity index 100% rename from cairo1_contracts/utils/.gitignore rename to cairo/kakarot-ssj/crates/utils/.gitignore diff --git a/kakarot-ssj/crates/utils/Scarb.toml b/cairo/kakarot-ssj/crates/utils/Scarb.toml similarity index 100% rename from kakarot-ssj/crates/utils/Scarb.toml rename to cairo/kakarot-ssj/crates/utils/Scarb.toml diff --git a/kakarot-ssj/crates/utils/src/address.cairo b/cairo/kakarot-ssj/crates/utils/src/address.cairo similarity index 100% rename from kakarot-ssj/crates/utils/src/address.cairo rename to cairo/kakarot-ssj/crates/utils/src/address.cairo diff --git a/kakarot-ssj/crates/utils/src/constants.cairo b/cairo/kakarot-ssj/crates/utils/src/constants.cairo similarity index 100% rename from kakarot-ssj/crates/utils/src/constants.cairo rename to cairo/kakarot-ssj/crates/utils/src/constants.cairo diff --git a/kakarot-ssj/crates/utils/src/crypto.cairo b/cairo/kakarot-ssj/crates/utils/src/crypto.cairo similarity index 100% rename from kakarot-ssj/crates/utils/src/crypto.cairo rename to cairo/kakarot-ssj/crates/utils/src/crypto.cairo diff --git a/kakarot-ssj/crates/utils/src/crypto/blake2_compress.cairo b/cairo/kakarot-ssj/crates/utils/src/crypto/blake2_compress.cairo similarity index 100% rename from kakarot-ssj/crates/utils/src/crypto/blake2_compress.cairo rename to cairo/kakarot-ssj/crates/utils/src/crypto/blake2_compress.cairo diff --git a/kakarot-ssj/crates/utils/src/crypto/modexp.cairo b/cairo/kakarot-ssj/crates/utils/src/crypto/modexp.cairo similarity index 100% rename from kakarot-ssj/crates/utils/src/crypto/modexp.cairo rename to cairo/kakarot-ssj/crates/utils/src/crypto/modexp.cairo diff --git a/kakarot-ssj/crates/utils/src/crypto/modexp/arith.cairo b/cairo/kakarot-ssj/crates/utils/src/crypto/modexp/arith.cairo similarity index 100% rename from kakarot-ssj/crates/utils/src/crypto/modexp/arith.cairo rename to cairo/kakarot-ssj/crates/utils/src/crypto/modexp/arith.cairo diff --git a/kakarot-ssj/crates/utils/src/crypto/modexp/lib.cairo b/cairo/kakarot-ssj/crates/utils/src/crypto/modexp/lib.cairo similarity index 100% rename from kakarot-ssj/crates/utils/src/crypto/modexp/lib.cairo rename to cairo/kakarot-ssj/crates/utils/src/crypto/modexp/lib.cairo diff --git a/kakarot-ssj/crates/utils/src/crypto/modexp/mpnat.cairo b/cairo/kakarot-ssj/crates/utils/src/crypto/modexp/mpnat.cairo similarity index 100% rename from kakarot-ssj/crates/utils/src/crypto/modexp/mpnat.cairo rename to cairo/kakarot-ssj/crates/utils/src/crypto/modexp/mpnat.cairo diff --git a/kakarot-ssj/crates/utils/src/errors.cairo b/cairo/kakarot-ssj/crates/utils/src/errors.cairo similarity index 100% rename from kakarot-ssj/crates/utils/src/errors.cairo rename to cairo/kakarot-ssj/crates/utils/src/errors.cairo diff --git a/kakarot-ssj/crates/utils/src/eth_transaction.cairo b/cairo/kakarot-ssj/crates/utils/src/eth_transaction.cairo similarity index 100% rename from kakarot-ssj/crates/utils/src/eth_transaction.cairo rename to cairo/kakarot-ssj/crates/utils/src/eth_transaction.cairo diff --git a/kakarot-ssj/crates/utils/src/eth_transaction/common.cairo b/cairo/kakarot-ssj/crates/utils/src/eth_transaction/common.cairo similarity index 100% rename from kakarot-ssj/crates/utils/src/eth_transaction/common.cairo rename to cairo/kakarot-ssj/crates/utils/src/eth_transaction/common.cairo diff --git a/kakarot-ssj/crates/utils/src/eth_transaction/eip1559.cairo b/cairo/kakarot-ssj/crates/utils/src/eth_transaction/eip1559.cairo similarity index 100% rename from kakarot-ssj/crates/utils/src/eth_transaction/eip1559.cairo rename to cairo/kakarot-ssj/crates/utils/src/eth_transaction/eip1559.cairo diff --git a/kakarot-ssj/crates/utils/src/eth_transaction/eip2930.cairo b/cairo/kakarot-ssj/crates/utils/src/eth_transaction/eip2930.cairo similarity index 100% rename from kakarot-ssj/crates/utils/src/eth_transaction/eip2930.cairo rename to cairo/kakarot-ssj/crates/utils/src/eth_transaction/eip2930.cairo diff --git a/kakarot-ssj/crates/utils/src/eth_transaction/legacy.cairo b/cairo/kakarot-ssj/crates/utils/src/eth_transaction/legacy.cairo similarity index 100% rename from kakarot-ssj/crates/utils/src/eth_transaction/legacy.cairo rename to cairo/kakarot-ssj/crates/utils/src/eth_transaction/legacy.cairo diff --git a/kakarot-ssj/crates/utils/src/eth_transaction/transaction.cairo b/cairo/kakarot-ssj/crates/utils/src/eth_transaction/transaction.cairo similarity index 100% rename from kakarot-ssj/crates/utils/src/eth_transaction/transaction.cairo rename to cairo/kakarot-ssj/crates/utils/src/eth_transaction/transaction.cairo diff --git a/kakarot-ssj/crates/utils/src/eth_transaction/tx_type.cairo b/cairo/kakarot-ssj/crates/utils/src/eth_transaction/tx_type.cairo similarity index 100% rename from kakarot-ssj/crates/utils/src/eth_transaction/tx_type.cairo rename to cairo/kakarot-ssj/crates/utils/src/eth_transaction/tx_type.cairo diff --git a/kakarot-ssj/crates/utils/src/felt_vec.cairo b/cairo/kakarot-ssj/crates/utils/src/felt_vec.cairo similarity index 100% rename from kakarot-ssj/crates/utils/src/felt_vec.cairo rename to cairo/kakarot-ssj/crates/utils/src/felt_vec.cairo diff --git a/kakarot-ssj/crates/utils/src/fmt.cairo b/cairo/kakarot-ssj/crates/utils/src/fmt.cairo similarity index 100% rename from kakarot-ssj/crates/utils/src/fmt.cairo rename to cairo/kakarot-ssj/crates/utils/src/fmt.cairo diff --git a/kakarot-ssj/crates/utils/src/helpers.cairo b/cairo/kakarot-ssj/crates/utils/src/helpers.cairo similarity index 100% rename from kakarot-ssj/crates/utils/src/helpers.cairo rename to cairo/kakarot-ssj/crates/utils/src/helpers.cairo diff --git a/kakarot-ssj/crates/utils/src/i256.cairo b/cairo/kakarot-ssj/crates/utils/src/i256.cairo similarity index 100% rename from kakarot-ssj/crates/utils/src/i256.cairo rename to cairo/kakarot-ssj/crates/utils/src/i256.cairo diff --git a/kakarot-ssj/crates/utils/src/lib.cairo b/cairo/kakarot-ssj/crates/utils/src/lib.cairo similarity index 100% rename from kakarot-ssj/crates/utils/src/lib.cairo rename to cairo/kakarot-ssj/crates/utils/src/lib.cairo diff --git a/kakarot-ssj/crates/utils/src/math.cairo b/cairo/kakarot-ssj/crates/utils/src/math.cairo similarity index 100% rename from kakarot-ssj/crates/utils/src/math.cairo rename to cairo/kakarot-ssj/crates/utils/src/math.cairo diff --git a/kakarot-ssj/crates/utils/src/rlp.cairo b/cairo/kakarot-ssj/crates/utils/src/rlp.cairo similarity index 100% rename from kakarot-ssj/crates/utils/src/rlp.cairo rename to cairo/kakarot-ssj/crates/utils/src/rlp.cairo diff --git a/kakarot-ssj/crates/utils/src/serialization.cairo b/cairo/kakarot-ssj/crates/utils/src/serialization.cairo similarity index 100% rename from kakarot-ssj/crates/utils/src/serialization.cairo rename to cairo/kakarot-ssj/crates/utils/src/serialization.cairo diff --git a/kakarot-ssj/crates/utils/src/set.cairo b/cairo/kakarot-ssj/crates/utils/src/set.cairo similarity index 100% rename from kakarot-ssj/crates/utils/src/set.cairo rename to cairo/kakarot-ssj/crates/utils/src/set.cairo diff --git a/kakarot-ssj/crates/utils/src/test_data.cairo b/cairo/kakarot-ssj/crates/utils/src/test_data.cairo similarity index 100% rename from kakarot-ssj/crates/utils/src/test_data.cairo rename to cairo/kakarot-ssj/crates/utils/src/test_data.cairo diff --git a/kakarot-ssj/crates/utils/src/traits.cairo b/cairo/kakarot-ssj/crates/utils/src/traits.cairo similarity index 100% rename from kakarot-ssj/crates/utils/src/traits.cairo rename to cairo/kakarot-ssj/crates/utils/src/traits.cairo diff --git a/kakarot-ssj/crates/utils/src/traits/array.cairo b/cairo/kakarot-ssj/crates/utils/src/traits/array.cairo similarity index 100% rename from kakarot-ssj/crates/utils/src/traits/array.cairo rename to cairo/kakarot-ssj/crates/utils/src/traits/array.cairo diff --git a/kakarot-ssj/crates/utils/src/traits/bytes.cairo b/cairo/kakarot-ssj/crates/utils/src/traits/bytes.cairo similarity index 100% rename from kakarot-ssj/crates/utils/src/traits/bytes.cairo rename to cairo/kakarot-ssj/crates/utils/src/traits/bytes.cairo diff --git a/kakarot-ssj/crates/utils/src/traits/eth_address.cairo b/cairo/kakarot-ssj/crates/utils/src/traits/eth_address.cairo similarity index 100% rename from kakarot-ssj/crates/utils/src/traits/eth_address.cairo rename to cairo/kakarot-ssj/crates/utils/src/traits/eth_address.cairo diff --git a/kakarot-ssj/crates/utils/src/traits/integer.cairo b/cairo/kakarot-ssj/crates/utils/src/traits/integer.cairo similarity index 100% rename from kakarot-ssj/crates/utils/src/traits/integer.cairo rename to cairo/kakarot-ssj/crates/utils/src/traits/integer.cairo diff --git a/kakarot-ssj/crates/utils/src/utils.cairo b/cairo/kakarot-ssj/crates/utils/src/utils.cairo similarity index 100% rename from kakarot-ssj/crates/utils/src/utils.cairo rename to cairo/kakarot-ssj/crates/utils/src/utils.cairo diff --git a/kakarot-ssj/docs/CODE_OF_CONDUCT.md b/cairo/kakarot-ssj/docs/CODE_OF_CONDUCT.md similarity index 100% rename from kakarot-ssj/docs/CODE_OF_CONDUCT.md rename to cairo/kakarot-ssj/docs/CODE_OF_CONDUCT.md diff --git a/kakarot-ssj/docs/CONTRIBUTING.md b/cairo/kakarot-ssj/docs/CONTRIBUTING.md similarity index 100% rename from kakarot-ssj/docs/CONTRIBUTING.md rename to cairo/kakarot-ssj/docs/CONTRIBUTING.md diff --git a/kakarot-ssj/docs/SECURITY.md b/cairo/kakarot-ssj/docs/SECURITY.md similarity index 100% rename from kakarot-ssj/docs/SECURITY.md rename to cairo/kakarot-ssj/docs/SECURITY.md diff --git a/kakarot-ssj/docs/general/account_state.png b/cairo/kakarot-ssj/docs/general/account_state.png similarity index 100% rename from kakarot-ssj/docs/general/account_state.png rename to cairo/kakarot-ssj/docs/general/account_state.png diff --git a/kakarot-ssj/docs/general/contract_bytecode.md b/cairo/kakarot-ssj/docs/general/contract_bytecode.md similarity index 100% rename from kakarot-ssj/docs/general/contract_bytecode.md rename to cairo/kakarot-ssj/docs/general/contract_bytecode.md diff --git a/kakarot-ssj/docs/general/contract_storage.md b/cairo/kakarot-ssj/docs/general/contract_storage.md similarity index 100% rename from kakarot-ssj/docs/general/contract_storage.md rename to cairo/kakarot-ssj/docs/general/contract_storage.md diff --git a/kakarot-ssj/docs/general/local_state.md b/cairo/kakarot-ssj/docs/general/local_state.md similarity index 100% rename from kakarot-ssj/docs/general/local_state.md rename to cairo/kakarot-ssj/docs/general/local_state.md diff --git a/kakarot-ssj/docs/general/machine.md b/cairo/kakarot-ssj/docs/general/machine.md similarity index 100% rename from kakarot-ssj/docs/general/machine.md rename to cairo/kakarot-ssj/docs/general/machine.md diff --git a/kakarot-ssj/docs/general/volition.png b/cairo/kakarot-ssj/docs/general/volition.png similarity index 100% rename from kakarot-ssj/docs/general/volition.png rename to cairo/kakarot-ssj/docs/general/volition.png diff --git a/kakarot-ssj/docs/img/kakarot_github_banner.png b/cairo/kakarot-ssj/docs/img/kakarot_github_banner.png similarity index 100% rename from kakarot-ssj/docs/img/kakarot_github_banner.png rename to cairo/kakarot-ssj/docs/img/kakarot_github_banner.png diff --git a/kakarot-ssj/package-lock.json b/cairo/kakarot-ssj/package-lock.json similarity index 100% rename from kakarot-ssj/package-lock.json rename to cairo/kakarot-ssj/package-lock.json diff --git a/kakarot-ssj/package.json b/cairo/kakarot-ssj/package.json similarity index 100% rename from kakarot-ssj/package.json rename to cairo/kakarot-ssj/package.json diff --git a/kakarot-ssj/rust-toolchain b/cairo/kakarot-ssj/rust-toolchain similarity index 100% rename from kakarot-ssj/rust-toolchain rename to cairo/kakarot-ssj/rust-toolchain diff --git a/kakarot-ssj/scripts/compare_snapshot.py b/cairo/kakarot-ssj/scripts/compare_snapshot.py similarity index 100% rename from kakarot-ssj/scripts/compare_snapshot.py rename to cairo/kakarot-ssj/scripts/compare_snapshot.py diff --git a/kakarot-ssj/scripts/compute_create_address.ts b/cairo/kakarot-ssj/scripts/compute_create_address.ts similarity index 100% rename from kakarot-ssj/scripts/compute_create_address.ts rename to cairo/kakarot-ssj/scripts/compute_create_address.ts diff --git a/kakarot-ssj/scripts/compute_rlp_encoding.ts b/cairo/kakarot-ssj/scripts/compute_rlp_encoding.ts similarity index 100% rename from kakarot-ssj/scripts/compute_rlp_encoding.ts rename to cairo/kakarot-ssj/scripts/compute_rlp_encoding.ts diff --git a/kakarot-ssj/scripts/compute_starknet_address.ts b/cairo/kakarot-ssj/scripts/compute_starknet_address.ts similarity index 100% rename from kakarot-ssj/scripts/compute_starknet_address.ts rename to cairo/kakarot-ssj/scripts/compute_starknet_address.ts diff --git a/kakarot-ssj/scripts/data/input_access_list_tx.json b/cairo/kakarot-ssj/scripts/data/input_access_list_tx.json similarity index 100% rename from kakarot-ssj/scripts/data/input_access_list_tx.json rename to cairo/kakarot-ssj/scripts/data/input_access_list_tx.json diff --git a/kakarot-ssj/scripts/data/input_eip1559_y_parity_false.json b/cairo/kakarot-ssj/scripts/data/input_eip1559_y_parity_false.json similarity index 100% rename from kakarot-ssj/scripts/data/input_eip1559_y_parity_false.json rename to cairo/kakarot-ssj/scripts/data/input_eip1559_y_parity_false.json diff --git a/kakarot-ssj/scripts/data/input_eip_2930_counter_inc_tx.json b/cairo/kakarot-ssj/scripts/data/input_eip_2930_counter_inc_tx.json similarity index 100% rename from kakarot-ssj/scripts/data/input_eip_2930_counter_inc_tx.json rename to cairo/kakarot-ssj/scripts/data/input_eip_2930_counter_inc_tx.json diff --git a/kakarot-ssj/scripts/data/input_fee_tx.json b/cairo/kakarot-ssj/scripts/data/input_fee_tx.json similarity index 100% rename from kakarot-ssj/scripts/data/input_fee_tx.json rename to cairo/kakarot-ssj/scripts/data/input_fee_tx.json diff --git a/kakarot-ssj/scripts/data/input_legacy_deploy_tx.json b/cairo/kakarot-ssj/scripts/data/input_legacy_deploy_tx.json similarity index 100% rename from kakarot-ssj/scripts/data/input_legacy_deploy_tx.json rename to cairo/kakarot-ssj/scripts/data/input_legacy_deploy_tx.json diff --git a/kakarot-ssj/scripts/data/input_legacy_tx.json b/cairo/kakarot-ssj/scripts/data/input_legacy_tx.json similarity index 100% rename from kakarot-ssj/scripts/data/input_legacy_tx.json rename to cairo/kakarot-ssj/scripts/data/input_legacy_tx.json diff --git a/kakarot-ssj/scripts/filter_tests.py b/cairo/kakarot-ssj/scripts/filter_tests.py similarity index 100% rename from kakarot-ssj/scripts/filter_tests.py rename to cairo/kakarot-ssj/scripts/filter_tests.py diff --git a/kakarot-ssj/scripts/find_selectory.py b/cairo/kakarot-ssj/scripts/find_selectory.py similarity index 100% rename from kakarot-ssj/scripts/find_selectory.py rename to cairo/kakarot-ssj/scripts/find_selectory.py diff --git a/kakarot-ssj/scripts/gas_debug_call.py b/cairo/kakarot-ssj/scripts/gas_debug_call.py similarity index 100% rename from kakarot-ssj/scripts/gas_debug_call.py rename to cairo/kakarot-ssj/scripts/gas_debug_call.py diff --git a/kakarot-ssj/scripts/gen_snapshot.py b/cairo/kakarot-ssj/scripts/gen_snapshot.py similarity index 100% rename from kakarot-ssj/scripts/gen_snapshot.py rename to cairo/kakarot-ssj/scripts/gen_snapshot.py diff --git a/kakarot-ssj/scripts/install_hook.sh b/cairo/kakarot-ssj/scripts/install_hook.sh similarity index 100% rename from kakarot-ssj/scripts/install_hook.sh rename to cairo/kakarot-ssj/scripts/install_hook.sh diff --git a/kakarot-ssj/scripts/run_filtered_tests.py b/cairo/kakarot-ssj/scripts/run_filtered_tests.py similarity index 100% rename from kakarot-ssj/scripts/run_filtered_tests.py rename to cairo/kakarot-ssj/scripts/run_filtered_tests.py diff --git a/kakarot-ssj/scripts/setup_cairo_native.sh b/cairo/kakarot-ssj/scripts/setup_cairo_native.sh similarity index 100% rename from kakarot-ssj/scripts/setup_cairo_native.sh rename to cairo/kakarot-ssj/scripts/setup_cairo_native.sh diff --git a/kakarot-ssj/tsconfig.json b/cairo/kakarot-ssj/tsconfig.json similarity index 100% rename from kakarot-ssj/tsconfig.json rename to cairo/kakarot-ssj/tsconfig.json diff --git a/kakarot-ssj/crates/alexandria_data_structures/.gitignore b/cairo/mock_pragma/.gitignore similarity index 100% rename from kakarot-ssj/crates/alexandria_data_structures/.gitignore rename to cairo/mock_pragma/.gitignore diff --git a/cairo1_contracts/mock_pragma/.tool-versions b/cairo/mock_pragma/.tool-versions similarity index 100% rename from cairo1_contracts/mock_pragma/.tool-versions rename to cairo/mock_pragma/.tool-versions diff --git a/cairo1_contracts/mock_pragma/Scarb.lock b/cairo/mock_pragma/Scarb.lock similarity index 100% rename from cairo1_contracts/mock_pragma/Scarb.lock rename to cairo/mock_pragma/Scarb.lock diff --git a/cairo1_contracts/mock_pragma/Scarb.toml b/cairo/mock_pragma/Scarb.toml similarity index 100% rename from cairo1_contracts/mock_pragma/Scarb.toml rename to cairo/mock_pragma/Scarb.toml diff --git a/cairo1_contracts/mock_pragma/src/lib.cairo b/cairo/mock_pragma/src/lib.cairo similarity index 100% rename from cairo1_contracts/mock_pragma/src/lib.cairo rename to cairo/mock_pragma/src/lib.cairo diff --git a/cairo1_contracts/mock_pragma/src/mock_pragma_oracle.cairo b/cairo/mock_pragma/src/mock_pragma_oracle.cairo similarity index 100% rename from cairo1_contracts/mock_pragma/src/mock_pragma_oracle.cairo rename to cairo/mock_pragma/src/mock_pragma_oracle.cairo diff --git a/kakarot-ssj/crates/evm/.gitignore b/cairo/token/.gitignore similarity index 100% rename from kakarot-ssj/crates/evm/.gitignore rename to cairo/token/.gitignore diff --git a/cairo1_contracts/token/.tool-versions b/cairo/token/.tool-versions similarity index 100% rename from cairo1_contracts/token/.tool-versions rename to cairo/token/.tool-versions diff --git a/cairo1_contracts/token/Scarb.lock b/cairo/token/Scarb.lock similarity index 100% rename from cairo1_contracts/token/Scarb.lock rename to cairo/token/Scarb.lock diff --git a/cairo1_contracts/token/Scarb.toml b/cairo/token/Scarb.toml similarity index 100% rename from cairo1_contracts/token/Scarb.toml rename to cairo/token/Scarb.toml diff --git a/cairo1_contracts/token/src/lib.cairo b/cairo/token/src/lib.cairo similarity index 100% rename from cairo1_contracts/token/src/lib.cairo rename to cairo/token/src/lib.cairo diff --git a/cairo1_contracts/token/src/starknet_token.cairo b/cairo/token/src/starknet_token.cairo similarity index 100% rename from cairo1_contracts/token/src/starknet_token.cairo rename to cairo/token/src/starknet_token.cairo diff --git a/kakarot-ssj/crates/utils/.gitignore b/cairo/utils/.gitignore similarity index 100% rename from kakarot-ssj/crates/utils/.gitignore rename to cairo/utils/.gitignore diff --git a/cairo1_contracts/utils/.tool-versions b/cairo/utils/.tool-versions similarity index 100% rename from cairo1_contracts/utils/.tool-versions rename to cairo/utils/.tool-versions diff --git a/cairo1_contracts/utils/Scarb.lock b/cairo/utils/Scarb.lock similarity index 100% rename from cairo1_contracts/utils/Scarb.lock rename to cairo/utils/Scarb.lock diff --git a/cairo1_contracts/utils/Scarb.toml b/cairo/utils/Scarb.toml similarity index 100% rename from cairo1_contracts/utils/Scarb.toml rename to cairo/utils/Scarb.toml diff --git a/cairo1_contracts/utils/src/benchmark_cairo_calls.cairo b/cairo/utils/src/benchmark_cairo_calls.cairo similarity index 100% rename from cairo1_contracts/utils/src/benchmark_cairo_calls.cairo rename to cairo/utils/src/benchmark_cairo_calls.cairo diff --git a/cairo1_contracts/utils/src/lib.cairo b/cairo/utils/src/lib.cairo similarity index 100% rename from cairo1_contracts/utils/src/lib.cairo rename to cairo/utils/src/lib.cairo diff --git a/cairo1_contracts/utils/src/universal_library_caller.cairo b/cairo/utils/src/universal_library_caller.cairo similarity index 100% rename from cairo1_contracts/utils/src/universal_library_caller.cairo rename to cairo/utils/src/universal_library_caller.cairo diff --git a/kakarot0/src/backend/starknet.cairo b/cairo_zero/backend/starknet.cairo similarity index 100% rename from kakarot0/src/backend/starknet.cairo rename to cairo_zero/backend/starknet.cairo diff --git a/kakarot0/src/kakarot/account.cairo b/cairo_zero/kakarot/account.cairo similarity index 100% rename from kakarot0/src/kakarot/account.cairo rename to cairo_zero/kakarot/account.cairo diff --git a/kakarot0/src/kakarot/accounts/account_contract.cairo b/cairo_zero/kakarot/accounts/account_contract.cairo similarity index 100% rename from kakarot0/src/kakarot/accounts/account_contract.cairo rename to cairo_zero/kakarot/accounts/account_contract.cairo diff --git a/kakarot0/src/kakarot/accounts/library.cairo b/cairo_zero/kakarot/accounts/library.cairo similarity index 100% rename from kakarot0/src/kakarot/accounts/library.cairo rename to cairo_zero/kakarot/accounts/library.cairo diff --git a/kakarot0/src/kakarot/accounts/model.cairo b/cairo_zero/kakarot/accounts/model.cairo similarity index 100% rename from kakarot0/src/kakarot/accounts/model.cairo rename to cairo_zero/kakarot/accounts/model.cairo diff --git a/kakarot0/src/kakarot/accounts/uninitialized_account.cairo b/cairo_zero/kakarot/accounts/uninitialized_account.cairo similarity index 100% rename from kakarot0/src/kakarot/accounts/uninitialized_account.cairo rename to cairo_zero/kakarot/accounts/uninitialized_account.cairo diff --git a/kakarot0/src/kakarot/constants.cairo b/cairo_zero/kakarot/constants.cairo similarity index 100% rename from kakarot0/src/kakarot/constants.cairo rename to cairo_zero/kakarot/constants.cairo diff --git a/kakarot0/src/kakarot/errors.cairo b/cairo_zero/kakarot/errors.cairo similarity index 100% rename from kakarot0/src/kakarot/errors.cairo rename to cairo_zero/kakarot/errors.cairo diff --git a/kakarot0/src/kakarot/eth_rpc.cairo b/cairo_zero/kakarot/eth_rpc.cairo similarity index 100% rename from kakarot0/src/kakarot/eth_rpc.cairo rename to cairo_zero/kakarot/eth_rpc.cairo diff --git a/kakarot0/src/kakarot/events.cairo b/cairo_zero/kakarot/events.cairo similarity index 100% rename from kakarot0/src/kakarot/events.cairo rename to cairo_zero/kakarot/events.cairo diff --git a/kakarot0/src/kakarot/evm.cairo b/cairo_zero/kakarot/evm.cairo similarity index 100% rename from kakarot0/src/kakarot/evm.cairo rename to cairo_zero/kakarot/evm.cairo diff --git a/kakarot0/src/kakarot/gas.cairo b/cairo_zero/kakarot/gas.cairo similarity index 100% rename from kakarot0/src/kakarot/gas.cairo rename to cairo_zero/kakarot/gas.cairo diff --git a/kakarot0/src/kakarot/instructions/block_information.cairo b/cairo_zero/kakarot/instructions/block_information.cairo similarity index 100% rename from kakarot0/src/kakarot/instructions/block_information.cairo rename to cairo_zero/kakarot/instructions/block_information.cairo diff --git a/kakarot0/src/kakarot/instructions/duplication_operations.cairo b/cairo_zero/kakarot/instructions/duplication_operations.cairo similarity index 100% rename from kakarot0/src/kakarot/instructions/duplication_operations.cairo rename to cairo_zero/kakarot/instructions/duplication_operations.cairo diff --git a/kakarot0/src/kakarot/instructions/environmental_information.cairo b/cairo_zero/kakarot/instructions/environmental_information.cairo similarity index 100% rename from kakarot0/src/kakarot/instructions/environmental_information.cairo rename to cairo_zero/kakarot/instructions/environmental_information.cairo diff --git a/kakarot0/src/kakarot/instructions/exchange_operations.cairo b/cairo_zero/kakarot/instructions/exchange_operations.cairo similarity index 100% rename from kakarot0/src/kakarot/instructions/exchange_operations.cairo rename to cairo_zero/kakarot/instructions/exchange_operations.cairo diff --git a/kakarot0/src/kakarot/instructions/logging_operations.cairo b/cairo_zero/kakarot/instructions/logging_operations.cairo similarity index 100% rename from kakarot0/src/kakarot/instructions/logging_operations.cairo rename to cairo_zero/kakarot/instructions/logging_operations.cairo diff --git a/kakarot0/src/kakarot/instructions/memory_operations.cairo b/cairo_zero/kakarot/instructions/memory_operations.cairo similarity index 100% rename from kakarot0/src/kakarot/instructions/memory_operations.cairo rename to cairo_zero/kakarot/instructions/memory_operations.cairo diff --git a/kakarot0/src/kakarot/instructions/push_operations.cairo b/cairo_zero/kakarot/instructions/push_operations.cairo similarity index 100% rename from kakarot0/src/kakarot/instructions/push_operations.cairo rename to cairo_zero/kakarot/instructions/push_operations.cairo diff --git a/kakarot0/src/kakarot/instructions/sha3.cairo b/cairo_zero/kakarot/instructions/sha3.cairo similarity index 100% rename from kakarot0/src/kakarot/instructions/sha3.cairo rename to cairo_zero/kakarot/instructions/sha3.cairo diff --git a/kakarot0/src/kakarot/instructions/stop_and_math_operations.cairo b/cairo_zero/kakarot/instructions/stop_and_math_operations.cairo similarity index 100% rename from kakarot0/src/kakarot/instructions/stop_and_math_operations.cairo rename to cairo_zero/kakarot/instructions/stop_and_math_operations.cairo diff --git a/kakarot0/src/kakarot/instructions/system_operations.cairo b/cairo_zero/kakarot/instructions/system_operations.cairo similarity index 100% rename from kakarot0/src/kakarot/instructions/system_operations.cairo rename to cairo_zero/kakarot/instructions/system_operations.cairo diff --git a/kakarot0/src/kakarot/interfaces/interfaces.cairo b/cairo_zero/kakarot/interfaces/interfaces.cairo similarity index 100% rename from kakarot0/src/kakarot/interfaces/interfaces.cairo rename to cairo_zero/kakarot/interfaces/interfaces.cairo diff --git a/kakarot0/src/kakarot/interpreter.cairo b/cairo_zero/kakarot/interpreter.cairo similarity index 100% rename from kakarot0/src/kakarot/interpreter.cairo rename to cairo_zero/kakarot/interpreter.cairo diff --git a/kakarot0/src/kakarot/kakarot.cairo b/cairo_zero/kakarot/kakarot.cairo similarity index 100% rename from kakarot0/src/kakarot/kakarot.cairo rename to cairo_zero/kakarot/kakarot.cairo diff --git a/kakarot0/src/kakarot/library.cairo b/cairo_zero/kakarot/library.cairo similarity index 100% rename from kakarot0/src/kakarot/library.cairo rename to cairo_zero/kakarot/library.cairo diff --git a/kakarot0/src/kakarot/memory.cairo b/cairo_zero/kakarot/memory.cairo similarity index 100% rename from kakarot0/src/kakarot/memory.cairo rename to cairo_zero/kakarot/memory.cairo diff --git a/kakarot0/src/kakarot/model.cairo b/cairo_zero/kakarot/model.cairo similarity index 100% rename from kakarot0/src/kakarot/model.cairo rename to cairo_zero/kakarot/model.cairo diff --git a/kakarot0/src/kakarot/precompiles/blake2f.cairo b/cairo_zero/kakarot/precompiles/blake2f.cairo similarity index 100% rename from kakarot0/src/kakarot/precompiles/blake2f.cairo rename to cairo_zero/kakarot/precompiles/blake2f.cairo diff --git a/kakarot0/src/kakarot/precompiles/ec_recover.cairo b/cairo_zero/kakarot/precompiles/ec_recover.cairo similarity index 100% rename from kakarot0/src/kakarot/precompiles/ec_recover.cairo rename to cairo_zero/kakarot/precompiles/ec_recover.cairo diff --git a/kakarot0/src/kakarot/precompiles/identity.cairo b/cairo_zero/kakarot/precompiles/identity.cairo similarity index 100% rename from kakarot0/src/kakarot/precompiles/identity.cairo rename to cairo_zero/kakarot/precompiles/identity.cairo diff --git a/kakarot0/src/kakarot/precompiles/kakarot_precompiles.cairo b/cairo_zero/kakarot/precompiles/kakarot_precompiles.cairo similarity index 100% rename from kakarot0/src/kakarot/precompiles/kakarot_precompiles.cairo rename to cairo_zero/kakarot/precompiles/kakarot_precompiles.cairo diff --git a/kakarot0/src/kakarot/precompiles/p256verify.cairo b/cairo_zero/kakarot/precompiles/p256verify.cairo similarity index 100% rename from kakarot0/src/kakarot/precompiles/p256verify.cairo rename to cairo_zero/kakarot/precompiles/p256verify.cairo diff --git a/kakarot0/src/kakarot/precompiles/precompiles.cairo b/cairo_zero/kakarot/precompiles/precompiles.cairo similarity index 100% rename from kakarot0/src/kakarot/precompiles/precompiles.cairo rename to cairo_zero/kakarot/precompiles/precompiles.cairo diff --git a/kakarot0/src/kakarot/precompiles/precompiles_helpers.cairo b/cairo_zero/kakarot/precompiles/precompiles_helpers.cairo similarity index 100% rename from kakarot0/src/kakarot/precompiles/precompiles_helpers.cairo rename to cairo_zero/kakarot/precompiles/precompiles_helpers.cairo diff --git a/kakarot0/src/kakarot/precompiles/ripemd160.cairo b/cairo_zero/kakarot/precompiles/ripemd160.cairo similarity index 100% rename from kakarot0/src/kakarot/precompiles/ripemd160.cairo rename to cairo_zero/kakarot/precompiles/ripemd160.cairo diff --git a/kakarot0/src/kakarot/precompiles/sha256.cairo b/cairo_zero/kakarot/precompiles/sha256.cairo similarity index 100% rename from kakarot0/src/kakarot/precompiles/sha256.cairo rename to cairo_zero/kakarot/precompiles/sha256.cairo diff --git a/kakarot0/src/kakarot/stack.cairo b/cairo_zero/kakarot/stack.cairo similarity index 100% rename from kakarot0/src/kakarot/stack.cairo rename to cairo_zero/kakarot/stack.cairo diff --git a/kakarot0/src/kakarot/state.cairo b/cairo_zero/kakarot/state.cairo similarity index 100% rename from kakarot0/src/kakarot/state.cairo rename to cairo_zero/kakarot/state.cairo diff --git a/kakarot0/src/kakarot/storages.cairo b/cairo_zero/kakarot/storages.cairo similarity index 100% rename from kakarot0/src/kakarot/storages.cairo rename to cairo_zero/kakarot/storages.cairo diff --git a/kakarot0/src/openzeppelin/ERC20.cairo b/cairo_zero/openzeppelin/ERC20.cairo similarity index 100% rename from kakarot0/src/openzeppelin/ERC20.cairo rename to cairo_zero/openzeppelin/ERC20.cairo diff --git a/kakarot0/src/utils/OpenzeppelinAccount.cairo b/cairo_zero/utils/OpenzeppelinAccount.cairo similarity index 100% rename from kakarot0/src/utils/OpenzeppelinAccount.cairo rename to cairo_zero/utils/OpenzeppelinAccount.cairo diff --git a/kakarot0/src/utils/array.cairo b/cairo_zero/utils/array.cairo similarity index 100% rename from kakarot0/src/utils/array.cairo rename to cairo_zero/utils/array.cairo diff --git a/kakarot0/src/utils/bytes.cairo b/cairo_zero/utils/bytes.cairo similarity index 100% rename from kakarot0/src/utils/bytes.cairo rename to cairo_zero/utils/bytes.cairo diff --git a/kakarot0/src/utils/dict.cairo b/cairo_zero/utils/dict.cairo similarity index 100% rename from kakarot0/src/utils/dict.cairo rename to cairo_zero/utils/dict.cairo diff --git a/kakarot0/src/utils/eth_transaction.cairo b/cairo_zero/utils/eth_transaction.cairo similarity index 100% rename from kakarot0/src/utils/eth_transaction.cairo rename to cairo_zero/utils/eth_transaction.cairo diff --git a/kakarot0/src/utils/maths.cairo b/cairo_zero/utils/maths.cairo similarity index 100% rename from kakarot0/src/utils/maths.cairo rename to cairo_zero/utils/maths.cairo diff --git a/kakarot0/src/utils/rlp.cairo b/cairo_zero/utils/rlp.cairo similarity index 100% rename from kakarot0/src/utils/rlp.cairo rename to cairo_zero/utils/rlp.cairo diff --git a/kakarot0/src/utils/signature.cairo b/cairo_zero/utils/signature.cairo similarity index 100% rename from kakarot0/src/utils/signature.cairo rename to cairo_zero/utils/signature.cairo diff --git a/kakarot0/src/utils/uint256.cairo b/cairo_zero/utils/uint256.cairo similarity index 100% rename from kakarot0/src/utils/uint256.cairo rename to cairo_zero/utils/uint256.cairo diff --git a/kakarot0/src/utils/utils.cairo b/cairo_zero/utils/utils.cairo similarity index 100% rename from kakarot0/src/utils/utils.cairo rename to cairo_zero/utils/utils.cairo diff --git a/docker/deployer/Dockerfile b/docker/deployer/Dockerfile index 52b396336..55cadaf4f 100644 --- a/docker/deployer/Dockerfile +++ b/docker/deployer/Dockerfile @@ -80,7 +80,7 @@ COPY --from=builder /app/kakarot/.venv ./.venv # Cairo Smart contracts are used in deploy_kakarot.py # To limit the probability of this Dockerfile to break, we copy the entire src and not individual files -COPY --from=builder /app/kakarot/kakarot0/src ./src/ +COPY --from=builder /app/kakarot/cairo_zero/ ./cairo_zero/ # Default Solidity contracts are also used in deploy_kakarot.py COPY --from=builder /app/kakarot/solidity_contracts ./solidity_contracts/ diff --git a/kakarot0/docs/CODE_OF_CONDUCT.md b/docs/CODE_OF_CONDUCT.md similarity index 100% rename from kakarot0/docs/CODE_OF_CONDUCT.md rename to docs/CODE_OF_CONDUCT.md diff --git a/kakarot0/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md similarity index 100% rename from kakarot0/docs/CONTRIBUTING.md rename to docs/CONTRIBUTING.md diff --git a/kakarot0/docs/SECURITY.md b/docs/SECURITY.md similarity index 100% rename from kakarot0/docs/SECURITY.md rename to docs/SECURITY.md diff --git a/kakarot0/docs/general/accounts.md b/docs/general/accounts.md similarity index 100% rename from kakarot0/docs/general/accounts.md rename to docs/general/accounts.md diff --git a/kakarot0/docs/general/cairo_precompiles.md b/docs/general/cairo_precompiles.md similarity index 100% rename from kakarot0/docs/general/cairo_precompiles.md rename to docs/general/cairo_precompiles.md diff --git a/kakarot0/docs/general/decode_a_cairo_trace.md b/docs/general/decode_a_cairo_trace.md similarity index 100% rename from kakarot0/docs/general/decode_a_cairo_trace.md rename to docs/general/decode_a_cairo_trace.md diff --git a/kakarot0/docs/general/kakarot_components.md b/docs/general/kakarot_components.md similarity index 100% rename from kakarot0/docs/general/kakarot_components.md rename to docs/general/kakarot_components.md diff --git a/kakarot0/docs/img/architecture.png b/docs/img/architecture.png similarity index 100% rename from kakarot0/docs/img/architecture.png rename to docs/img/architecture.png diff --git a/kakarot0/docs/img/codespaces.png b/docs/img/codespaces.png similarity index 100% rename from kakarot0/docs/img/codespaces.png rename to docs/img/codespaces.png diff --git a/kakarot0/docs/img/core_evm_diagram.png b/docs/img/core_evm_diagram.png similarity index 100% rename from kakarot0/docs/img/core_evm_diagram.png rename to docs/img/core_evm_diagram.png diff --git a/kakarot0/docs/img/kakarot_github_banner.png b/docs/img/kakarot_github_banner.png similarity index 100% rename from kakarot0/docs/img/kakarot_github_banner.png rename to docs/img/kakarot_github_banner.png diff --git a/kakarot_scripts/constants.py b/kakarot_scripts/constants.py index 2729c8237..038a61423 100644 --- a/kakarot_scripts/constants.py +++ b/kakarot_scripts/constants.py @@ -218,8 +218,8 @@ class ChainId(IntEnum): or "0x20eB005C0b9c906691F885eca5895338E15c36De", # Defaults to faucet on appchain sepolia 16, ) -CAIRO_ZERO_DIR = Path("kakarot0/src") -CAIRO_DIR = Path("cairo1_contracts") +CAIRO_ZERO_DIR = Path("cairo_zero") +CAIRO_DIR = Path("cairo") TESTS_DIR = Path("tests") CONTRACTS = { @@ -227,7 +227,7 @@ class ChainId(IntEnum): for p in ( list(CAIRO_ZERO_DIR.glob("**/*.cairo")) + list(TESTS_DIR.glob("**/*.cairo")) - + list(CAIRO_DIR.glob("**/*.cairo")) + + [x for x in list(CAIRO_DIR.glob("**/*.cairo")) if "kakarot-ssj" not in str(x)] ) } diff --git a/pyproject.toml b/pyproject.toml index 5030e833e..f5adb40b8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -191,7 +191,7 @@ check-filenames = '' check-hidden = '' [tool.bandit] -exclude_dirs = ["tests", "kakarot0/tests"] +exclude_dirs = ["tests"] [build-system] requires = ["hatchling"] diff --git a/tests/fixtures/starknet.py b/tests/fixtures/starknet.py index 13ec06542..a6989314a 100644 --- a/tests/fixtures/starknet.py +++ b/tests/fixtures/starknet.py @@ -38,7 +38,7 @@ def cairo_compile(path): - module_reader = get_module_reader(cairo_path=["kakarot0/src"]) + module_reader = get_module_reader(cairo_path=["cairo_zero"]) pass_manager = starknet_pass_manager( prime=DEFAULT_PRIME, From 2e1970fb30917b960912a63f4c49b2d941fb328d Mon Sep 17 00:00:00 2001 From: Oba Date: Wed, 2 Oct 2024 13:20:53 +0200 Subject: [PATCH 27/56] update ssj --- .../crates/contracts/src/cairo1_helpers.cairo | 2 +- .../contracts/src/kakarot_core/eth_rpc.cairo | 1 - .../src/kakarot_core/interface.cairo | 4 +- .../crates/evm/src/call_helpers.cairo | 2 +- .../crates/evm/src/create_helpers.cairo | 2 +- .../src/instructions/block_information.cairo | 8 +- .../instructions/comparison_operations.cairo | 9 +- .../environmental_information.cairo | 17 +- .../src/instructions/logging_operations.cairo | 4 +- .../src/instructions/memory_operations.cairo | 17 +- .../crates/evm/src/instructions/sha3.cairo | 6 +- .../src/instructions/system_operations.cairo | 18 +- .../crates/evm/src/interpreter.cairo | 4 +- cairo/kakarot-ssj/crates/evm/src/memory.cairo | 2 +- cairo/kakarot-ssj/crates/evm/src/stack.cairo | 3 +- .../crates/utils/src/constants.cairo | 261 ++++++++++++++++++ .../utils/src/crypto/blake2_compress.cairo | 2 +- .../utils/src/crypto/modexp/arith.cairo | 24 +- .../utils/src/crypto/modexp/mpnat.cairo | 11 +- cairo/kakarot-ssj/crates/utils/src/math.cairo | 38 +-- .../crates/utils/src/traits/bytes.cairo | 19 +- .../crates/utils/src/traits/eth_address.cairo | 8 +- .../crates/utils/src/traits/integer.cairo | 4 +- .../docs/general/account_state.png | Bin 131560 -> 132360 bytes .../docs/general/contract_storage.md | 6 +- cairo/kakarot-ssj/docs/general/volition.png | Bin 192120 -> 192376 bytes .../kakarot-ssj/scripts/setup_cairo_native.sh | 1 + 27 files changed, 377 insertions(+), 96 deletions(-) diff --git a/cairo/kakarot-ssj/crates/contracts/src/cairo1_helpers.cairo b/cairo/kakarot-ssj/crates/contracts/src/cairo1_helpers.cairo index 4bd3b89d2..1a22b9721 100644 --- a/cairo/kakarot-ssj/crates/contracts/src/cairo1_helpers.cairo +++ b/cairo/kakarot-ssj/crates/contracts/src/cairo1_helpers.cairo @@ -88,7 +88,7 @@ pub trait IHelpers { /// * The recovered Ethereum address. fn recover_eth_address(self: @T, msg_hash: u256, signature: Signature) -> (bool, EthAddress); - /// Performs signature verification in the secp256r1 ellipitic curve. + /// Performs signature verification in the secp256r1 elliptic curve. /// /// # Arguments /// diff --git a/cairo/kakarot-ssj/crates/contracts/src/kakarot_core/eth_rpc.cairo b/cairo/kakarot-ssj/crates/contracts/src/kakarot_core/eth_rpc.cairo index c824fb4f6..8e98b20e4 100644 --- a/cairo/kakarot-ssj/crates/contracts/src/kakarot_core/eth_rpc.cairo +++ b/cairo/kakarot-ssj/crates/contracts/src/kakarot_core/eth_rpc.cairo @@ -134,7 +134,6 @@ pub impl EthRPC< fn eth_get_transaction_count(self: @TContractState, address: EthAddress) -> u64 { let kakarot_state = KakarotState::get_state(); let starknet_address = kakarot_state.get_starknet_address(address); - println!("starknet_address: {:?}", starknet_address); let account = IAccountDispatcher { contract_address: starknet_address }; let nonce = account.get_nonce(); nonce diff --git a/cairo/kakarot-ssj/crates/contracts/src/kakarot_core/interface.cairo b/cairo/kakarot-ssj/crates/contracts/src/kakarot_core/interface.cairo index aa5e8e9fa..4bce029d5 100644 --- a/cairo/kakarot-ssj/crates/contracts/src/kakarot_core/interface.cairo +++ b/cairo/kakarot-ssj/crates/contracts/src/kakarot_core/interface.cairo @@ -9,7 +9,7 @@ pub trait IKakarotCore { /// Gets the native token used by the Kakarot smart contract fn get_native_token(self: @TContractState) -> ContractAddress; - /// Deterministically computes a Starknet address for an given EVM address + /// Deterministically computes a Starknet address for a given EVM address /// The address is computed as the Starknet address corresponding to the deployment of an EOA, /// Using its EVM address as salt, and KakarotCore as deployer. fn compute_starknet_address(self: @TContractState, evm_address: EthAddress) -> ContractAddress; @@ -59,7 +59,7 @@ pub trait IExtendedKakarotCore { /// Gets the native token used by the Kakarot smart contract fn get_native_token(self: @TContractState) -> ContractAddress; - /// Deterministically computes a Starknet address for an given EVM address + /// Deterministically computes a Starknet address for a given EVM address /// The address is computed as the Starknet address corresponding to the deployment of an EOA, /// Using its EVM address as salt, and KakarotCore as deployer. fn compute_starknet_address(self: @TContractState, evm_address: EthAddress) -> ContractAddress; diff --git a/cairo/kakarot-ssj/crates/evm/src/call_helpers.cairo b/cairo/kakarot-ssj/crates/evm/src/call_helpers.cairo index 61e67031d..26088d43c 100644 --- a/cairo/kakarot-ssj/crates/evm/src/call_helpers.cairo +++ b/cairo/kakarot-ssj/crates/evm/src/call_helpers.cairo @@ -107,7 +107,7 @@ pub impl CallHelpersImpl of CallHelpers { self.stack.push(0)?; }, ExecutionResultStatus::Exception => { - // If the call has halted exceptionnaly, + // If the call has halted exceptionally, // the return_data is emptied, and nothing is stored in memory self.return_data = [].span(); self.stack.push(0)?; diff --git a/cairo/kakarot-ssj/crates/evm/src/create_helpers.cairo b/cairo/kakarot-ssj/crates/evm/src/create_helpers.cairo index 28e8dc40b..3b8c39eca 100644 --- a/cairo/kakarot-ssj/crates/evm/src/create_helpers.cairo +++ b/cairo/kakarot-ssj/crates/evm/src/create_helpers.cairo @@ -40,7 +40,7 @@ pub impl CreateHelpersImpl of CreateHelpers { fn prepare_create(ref self: VM, create_type: CreateType) -> Result { let value = self.stack.pop()?; let offset = self.stack.pop_saturating_usize()?; - let size = self.stack.pop_usize()?; + let size = self.stack.pop_usize()?; // Any size bigger than a usize would MemoryOOG. let memory_expansion = gas::memory_expansion(self.memory.size(), [(offset, size)].span())?; self.memory.ensure_length(memory_expansion.new_size); diff --git a/cairo/kakarot-ssj/crates/evm/src/instructions/block_information.cairo b/cairo/kakarot-ssj/crates/evm/src/instructions/block_information.cairo index f5e61db79..3f834a917 100644 --- a/cairo/kakarot-ssj/crates/evm/src/instructions/block_information.cairo +++ b/cairo/kakarot-ssj/crates/evm/src/instructions/block_information.cairo @@ -1,5 +1,6 @@ //! Block Information. +use core::num::traits::SaturatingAdd; use core::starknet::SyscallResultTrait; use core::starknet::syscalls::get_block_hash_syscall; @@ -20,7 +21,9 @@ pub impl BlockInformation of BlockInformationTrait { fn exec_blockhash(ref self: VM) -> Result<(), EVMError> { self.charge_gas(gas::BLOCKHASH)?; - let block_number = self.stack.pop_u64()?; + // Saturate to MAX_U64 to avoid a revert when the hash requested is too big. It should just + // push 0. + let block_number = self.stack.pop_saturating_u64()?; let current_block = self.env.block_number; // If input block number is lower than current_block - 256, return 0 @@ -31,7 +34,8 @@ pub impl BlockInformation of BlockInformationTrait { // TODO: monitor the changes in the `get_block_hash_syscall` syscall. // source: // https://docs.starknet.io/documentation/architecture_and_concepts/Smart_Contracts/system-calls-cairo1/#get_block_hash - if block_number + 10 > current_block || block_number + 256 < current_block { + if block_number.saturating_add(10) > current_block + || block_number.saturating_add(256) < current_block { return self.stack.push(0); } diff --git a/cairo/kakarot-ssj/crates/evm/src/instructions/comparison_operations.cairo b/cairo/kakarot-ssj/crates/evm/src/instructions/comparison_operations.cairo index e6f6e84b4..b040f21b0 100644 --- a/cairo/kakarot-ssj/crates/evm/src/instructions/comparison_operations.cairo +++ b/cairo/kakarot-ssj/crates/evm/src/instructions/comparison_operations.cairo @@ -132,6 +132,7 @@ pub impl ComparisonAndBitwiseOperations of ComparisonAndBitwiseOperationsTrait { if i > 31 { return self.stack.push(0); } + let i: usize = i.try_into().unwrap(); // Safe because i <= 31 // Right shift value by offset bits and then take the least significant byte. let result = x.shr((31 - i) * 8) & 0xFF; @@ -150,7 +151,7 @@ pub impl ComparisonAndBitwiseOperations of ComparisonAndBitwiseOperationsTrait { if shift > 255 { return self.stack.push(0); } - + let shift: usize = shift.try_into().unwrap(); // Safe because shift <= 255 let result = val.wrapping_shl(shift); self.stack.push(result) } @@ -163,6 +164,11 @@ pub impl ComparisonAndBitwiseOperations of ComparisonAndBitwiseOperationsTrait { let shift = *popped[0]; let value = *popped[1]; + // if shift is bigger than 255 return 0 + if shift > 255 { + return self.stack.push(0); + } + let shift: usize = shift.try_into().unwrap(); // Safe because shift <= 255 let result = value.wrapping_shr(shift); self.stack.push(result) } @@ -187,6 +193,7 @@ pub impl ComparisonAndBitwiseOperations of ComparisonAndBitwiseOperationsTrait { if (shift >= 256) { self.stack.push(sign) } else { + let shift: usize = shift.try_into().unwrap(); // Safe because shift <= 256 // XORing with sign before and after the shift propagates the sign bit of the operation let result = (sign ^ value.value).shr(shift) ^ sign; self.stack.push(result) diff --git a/cairo/kakarot-ssj/crates/evm/src/instructions/environmental_information.cairo b/cairo/kakarot-ssj/crates/evm/src/instructions/environmental_information.cairo index d675193ff..9da876792 100644 --- a/cairo/kakarot-ssj/crates/evm/src/instructions/environmental_information.cairo +++ b/cairo/kakarot-ssj/crates/evm/src/instructions/environmental_information.cairo @@ -72,7 +72,8 @@ pub impl EnvironmentInformationImpl of EnvironmentInformationTrait { fn exec_calldataload(ref self: VM) -> Result<(), EVMError> { self.charge_gas(gas::VERYLOW)?; - let offset: usize = self.stack.pop_usize()?; + // Don't error out if the offset is too big. It should just push 0. + let offset: usize = self.stack.pop_saturating_usize()?; let calldata = self.message().data; let calldata_len = calldata.len(); @@ -113,7 +114,7 @@ pub impl EnvironmentInformationImpl of EnvironmentInformationTrait { fn exec_calldatacopy(ref self: VM) -> Result<(), EVMError> { let dest_offset = self.stack.pop_saturating_usize()?; let offset = self.stack.pop_saturating_usize()?; - let size = self.stack.pop_usize()?; + let size = self.stack.pop_usize()?; // Any size bigger than a usize would MemoryOOG. let words_size = bytes_32_words_size(size).into(); let copy_gas_cost = gas::COPY * words_size; @@ -143,7 +144,7 @@ pub impl EnvironmentInformationImpl of EnvironmentInformationTrait { fn exec_codecopy(ref self: VM) -> Result<(), EVMError> { let dest_offset = self.stack.pop_saturating_usize()?; let offset = self.stack.pop_saturating_usize()?; - let size = self.stack.pop_usize()?; + let size = self.stack.pop_usize()?; // Any size bigger than a usize would MemoryOOG. let words_size = bytes_32_words_size(size).into(); let copy_gas_cost = gas::COPY * words_size; @@ -192,7 +193,7 @@ pub impl EnvironmentInformationImpl of EnvironmentInformationTrait { let evm_address = self.stack.pop_eth_address()?; let dest_offset = self.stack.pop_saturating_usize()?; let offset = self.stack.pop_saturating_usize()?; - let size = self.stack.pop_usize()?; + let size = self.stack.pop_usize()?; // Any size bigger than a usize would MemoryOOG. // GAS let words_size = bytes_32_words_size(size).into(); @@ -229,7 +230,7 @@ pub impl EnvironmentInformationImpl of EnvironmentInformationTrait { fn exec_returndatacopy(ref self: VM) -> Result<(), EVMError> { let dest_offset = self.stack.pop_saturating_usize()?; let offset = self.stack.pop_saturating_usize()?; - let size = self.stack.pop_usize()?; + let size = self.stack.pop_usize()?; // Any size bigger than a usize would MemoryOOG. let return_data: Span = self.return_data(); let (last_returndata_index, overflow) = offset.overflowing_add(size); @@ -549,7 +550,7 @@ mod tests { #[test] - fn test_calldataload_with_offset_conversion_error() { + fn test_calldataload_with_offset_bigger_usize_succeeds() { // Given let calldata = u256_to_bytes_array( 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF @@ -562,8 +563,8 @@ mod tests { let result = vm.exec_calldataload(); // Then - assert!(result.is_err()); - assert_eq!(result.unwrap_err(), EVMError::TypeConversionError(TYPE_CONVERSION_ERROR)); + assert!(result.is_ok()); + assert_eq!(vm.stack.pop().unwrap(), 0); } // ************************************************************************* diff --git a/cairo/kakarot-ssj/crates/evm/src/instructions/logging_operations.cairo b/cairo/kakarot-ssj/crates/evm/src/instructions/logging_operations.cairo index 6e8b1cd4a..12c86a30d 100644 --- a/cairo/kakarot-ssj/crates/evm/src/instructions/logging_operations.cairo +++ b/cairo/kakarot-ssj/crates/evm/src/instructions/logging_operations.cairo @@ -61,11 +61,13 @@ fn exec_log_i(ref self: VM, topics_len: u8) -> Result<(), EVMError> { // TODO(optimization): check benefits of n `pop` instead of `pop_n` let offset = self.stack.pop_saturating_usize()?; - let size = self.stack.pop_usize()?; + let size = self.stack.pop_usize()?; // Any size bigger than a usize would MemoryOOG. let topics: Array = self.stack.pop_n(topics_len.into())?; let memory_expansion = gas::memory_expansion(self.memory.size(), [(offset, size)].span())?; self.memory.ensure_length(memory_expansion.new_size); + + // TODO: avoid addition overflows here. We should use checked arithmetic. self .charge_gas( gas::LOG diff --git a/cairo/kakarot-ssj/crates/evm/src/instructions/memory_operations.cairo b/cairo/kakarot-ssj/crates/evm/src/instructions/memory_operations.cairo index 0248a7b35..fc2d81b61 100644 --- a/cairo/kakarot-ssj/crates/evm/src/instructions/memory_operations.cairo +++ b/cairo/kakarot-ssj/crates/evm/src/instructions/memory_operations.cairo @@ -36,7 +36,9 @@ pub impl MemoryOperation of MemoryOperationTrait { /// MLOAD operation. /// Load word from memory and push to stack. fn exec_mload(ref self: VM) -> Result<(), EVMError> { - let offset: usize = self.stack.pop_usize()?; + let offset: usize = self + .stack + .pop_usize()?; // Any offset bigger than a usize would MemoryOOG. let memory_expansion = gas::memory_expansion(self.memory.size(), [(offset, 32)].span())?; self.memory.ensure_length(memory_expansion.new_size); @@ -50,7 +52,9 @@ pub impl MemoryOperation of MemoryOperationTrait { /// Save word to memory. /// # Specification: https://www.evm.codes/#52?fork=shanghai fn exec_mstore(ref self: VM) -> Result<(), EVMError> { - let offset: usize = self.stack.pop_usize()?; + let offset: usize = self + .stack + .pop_usize()?; // Any offset bigger than a usize would MemoryOOG. let value: u256 = self.stack.pop()?; let memory_expansion = gas::memory_expansion(self.memory.size(), [(offset, 32)].span())?; self.memory.ensure_length(memory_expansion.new_size); @@ -64,7 +68,7 @@ pub impl MemoryOperation of MemoryOperationTrait { /// Save single byte to memory /// # Specification: https://www.evm.codes/#53?fork=shanghai fn exec_mstore8(ref self: VM) -> Result<(), EVMError> { - let offset = self.stack.pop_saturating_usize()?; + let offset = self.stack.pop_usize()?; // Any offset bigger than a usize would MemoryOOG. let value = self.stack.pop()?; let value: u8 = (value.low & 0xFF).try_into().unwrap(); @@ -188,7 +192,9 @@ pub impl MemoryOperation of MemoryOperationTrait { /// The new pc target has to be a JUMPDEST opcode. /// # Specification: https://www.evm.codes/#57?fork=shanghai fn exec_jumpi(ref self: VM) -> Result<(), EVMError> { - let index = self.stack.pop_usize()?; + let index = self + .stack + .pop_saturating_usize()?; // Saturate because if b is 0, we skip the jump but don't want to fail here. let b = self.stack.pop()?; self.charge_gas(gas::HIGH)?; @@ -280,7 +286,7 @@ pub impl MemoryOperation of MemoryOperationTrait { fn exec_mcopy(ref self: VM) -> Result<(), EVMError> { let dest_offset = self.stack.pop_saturating_usize()?; let source_offset = self.stack.pop_saturating_usize()?; - let size = self.stack.pop_usize()?; + let size = self.stack.pop_usize()?; // Any size bigger than a usize would MemoryOOG. let words_size = bytes_32_words_size(size).into(); let copy_gas_cost = gas::COPY * words_size; @@ -288,6 +294,7 @@ pub impl MemoryOperation of MemoryOperationTrait { self.memory.size(), [(max(dest_offset, source_offset), size)].span() )?; self.memory.ensure_length(memory_expansion.new_size); + //TODO: handle add overflows self.charge_gas(gas::VERYLOW + copy_gas_cost + memory_expansion.expansion_cost)?; if size == 0 { diff --git a/cairo/kakarot-ssj/crates/evm/src/instructions/sha3.cairo b/cairo/kakarot-ssj/crates/evm/src/instructions/sha3.cairo index 28f740398..622abf23f 100644 --- a/cairo/kakarot-ssj/crates/evm/src/instructions/sha3.cairo +++ b/cairo/kakarot-ssj/crates/evm/src/instructions/sha3.cairo @@ -23,8 +23,10 @@ pub impl Sha3Impl of Sha3Trait { /// /// # Specification: https://www.evm.codes/#20?fork=shanghai fn exec_sha3(ref self: VM) -> Result<(), EVMError> { - let offset: usize = self.stack.pop_usize()?; - let mut size: usize = self.stack.pop_usize()?; + let offset: usize = self.stack.pop_saturating_usize()?; + let mut size: usize = self + .stack + .pop_usize()?; // Any size bigger than a usize would MemoryOOG. let words_size = bytes_32_words_size(size).into(); let word_gas_cost = gas::KECCAK256WORD * words_size; diff --git a/cairo/kakarot-ssj/crates/evm/src/instructions/system_operations.cairo b/cairo/kakarot-ssj/crates/evm/src/instructions/system_operations.cairo index fcfb1a633..5511b6017 100644 --- a/cairo/kakarot-ssj/crates/evm/src/instructions/system_operations.cairo +++ b/cairo/kakarot-ssj/crates/evm/src/instructions/system_operations.cairo @@ -30,9 +30,9 @@ pub impl SystemOperations of SystemOperationsTrait { let to = self.stack.pop_eth_address()?; let value = self.stack.pop()?; let args_offset = self.stack.pop_saturating_usize()?; - let args_size = self.stack.pop_usize()?; + let args_size = self.stack.pop_usize()?; // Any size bigger than a usize would MemoryOOG. let ret_offset = self.stack.pop_saturating_usize()?; - let ret_size = self.stack.pop_usize()?; + let ret_size = self.stack.pop_usize()?; // Any size bigger than a usize would MemoryOOG. // GAS let memory_expansion = gas::memory_expansion( @@ -109,9 +109,9 @@ pub impl SystemOperations of SystemOperationsTrait { let code_address = self.stack.pop_eth_address()?; let value = self.stack.pop()?; let args_offset = self.stack.pop_saturating_usize()?; - let args_size = self.stack.pop_usize()?; + let args_size = self.stack.pop_usize()?; // Any size bigger than a usize would MemoryOOG. let ret_offset = self.stack.pop_saturating_usize()?; - let ret_size = self.stack.pop_usize()?; + let ret_size = self.stack.pop_usize()?; // Any size bigger than a usize would MemoryOOG. let to = self.message().target.evm; @@ -193,9 +193,9 @@ pub impl SystemOperations of SystemOperationsTrait { let gas = self.stack.pop_saturating_u64()?; let code_address = self.stack.pop_eth_address()?; let args_offset = self.stack.pop_saturating_usize()?; - let args_size = self.stack.pop_usize()?; + let args_size = self.stack.pop_usize()?; // Any size bigger than a usize would MemoryOOG. let ret_offset = self.stack.pop_saturating_usize()?; - let ret_size = self.stack.pop_usize()?; + let ret_size = self.stack.pop_usize()?; // Any size bigger than a usize would MemoryOOG. // GAS let memory_expansion = gas::memory_expansion( @@ -246,9 +246,9 @@ pub impl SystemOperations of SystemOperationsTrait { let gas = self.stack.pop_saturating_u64()?; let to = self.stack.pop_eth_address()?; let args_offset = self.stack.pop_saturating_usize()?; - let args_size = self.stack.pop_usize()?; + let args_size = self.stack.pop_usize()?; // Any size bigger than a usize would MemoryOOG. let ret_offset = self.stack.pop_saturating_usize()?; - let ret_size = self.stack.pop_usize()?; + let ret_size = self.stack.pop_usize()?; // Any size bigger than a usize would MemoryOOG. // GAS let memory_expansion = gas::memory_expansion( @@ -293,7 +293,7 @@ pub impl SystemOperations of SystemOperationsTrait { /// # Specification: https://www.evm.codes/#fd?fork=shanghai fn exec_revert(ref self: VM) -> Result<(), EVMError> { let offset = self.stack.pop_saturating_usize()?; - let size = self.stack.pop_usize()?; + let size = self.stack.pop_usize()?; // Any size bigger than a usize would MemoryOOG. let memory_expansion = gas::memory_expansion(self.memory.size(), [(offset, size)].span())?; self.memory.ensure_length(memory_expansion.new_size); diff --git a/cairo/kakarot-ssj/crates/evm/src/interpreter.cairo b/cairo/kakarot-ssj/crates/evm/src/interpreter.cairo index a17d06317..ccf14cda7 100644 --- a/cairo/kakarot-ssj/crates/evm/src/interpreter.cairo +++ b/cairo/kakarot-ssj/crates/evm/src/interpreter.cairo @@ -19,7 +19,7 @@ use crate::model::account::{Account, AccountTrait}; use crate::model::vm::{VM, VMTrait}; use crate::model::{ Message, Environment, Transfer, ExecutionSummary, ExecutionResult, ExecutionResultTrait, - ExecutionResultStatus, AddressTrait, TransactionResult, TransactionResultTrait, Address + ExecutionResultStatus, AddressTrait, TransactionResult, Address }; use crate::precompiles::Precompiles; use crate::precompiles::eth_precompile_addresses; @@ -108,7 +108,7 @@ pub impl EVMImpl of EVMTrait { let mut sender_account = env.state.get_account(origin.evm); // Charge the intrinsic gas to the sender so that it's not available for the execution - // of the transaction but don't trigger any actual transfer, as only the actual consumde + // of the transaction but don't trigger any actual transfer, as only the actual consumed // gas is charged at the end of the transaction sender_account.set_balance(sender_account.balance() - max_fee.into()); diff --git a/cairo/kakarot-ssj/crates/evm/src/memory.cairo b/cairo/kakarot-ssj/crates/evm/src/memory.cairo index 9659045c8..fb3fc11ac 100644 --- a/cairo/kakarot-ssj/crates/evm/src/memory.cairo +++ b/cairo/kakarot-ssj/crates/evm/src/memory.cairo @@ -89,7 +89,7 @@ impl MemoryImpl of MemoryTrait { // First erase byte value at offset, then set the new value using bitwise ops let word: u128 = self.items.get(chunk_index.into()); - let new_word = (word & ~mask) | (value.into().shl(right_offset.into() * 8)); + let new_word = (word & ~mask) | (value.into().shl(right_offset * 8)); self.items.insert(chunk_index.into(), new_word); } diff --git a/cairo/kakarot-ssj/crates/evm/src/stack.cairo b/cairo/kakarot-ssj/crates/evm/src/stack.cairo index 506e87d9f..74ddcba68 100644 --- a/cairo/kakarot-ssj/crates/evm/src/stack.cairo +++ b/cairo/kakarot-ssj/crates/evm/src/stack.cairo @@ -186,7 +186,8 @@ impl StackImpl of StackTrait { Result::Ok(item.low) } - /// Calls `Stack::pop` and converts it to usize + /// Calls `Stack::pop` and converts it to an EthAddress + /// If the value is bigger than an EthAddress, it will be truncated to keep the lower 160 bits. /// /// # Errors /// diff --git a/cairo/kakarot-ssj/crates/utils/src/constants.cairo b/cairo/kakarot-ssj/crates/utils/src/constants.cairo index 78ce66bb3..0b4b1c676 100644 --- a/cairo/kakarot-ssj/crates/utils/src/constants.cairo +++ b/cairo/kakarot-ssj/crates/utils/src/constants.cairo @@ -210,6 +210,267 @@ pub const POW_2: [ 0x80000000000000000000000000000000 ]; +pub const POW_2_256: [ + u256 + ; 256] = [ + 0x1, + 0x2, + 0x4, + 0x8, + 0x10, + 0x20, + 0x40, + 0x80, + 0x100, + 0x200, + 0x400, + 0x800, + 0x1000, + 0x2000, + 0x4000, + 0x8000, + 0x10000, + 0x20000, + 0x40000, + 0x80000, + 0x100000, + 0x200000, + 0x400000, + 0x800000, + 0x1000000, + 0x2000000, + 0x4000000, + 0x8000000, + 0x10000000, + 0x20000000, + 0x40000000, + 0x80000000, + 0x100000000, + 0x200000000, + 0x400000000, + 0x800000000, + 0x1000000000, + 0x2000000000, + 0x4000000000, + 0x8000000000, + 0x10000000000, + 0x20000000000, + 0x40000000000, + 0x80000000000, + 0x100000000000, + 0x200000000000, + 0x400000000000, + 0x800000000000, + 0x1000000000000, + 0x2000000000000, + 0x4000000000000, + 0x8000000000000, + 0x10000000000000, + 0x20000000000000, + 0x40000000000000, + 0x80000000000000, + 0x100000000000000, + 0x200000000000000, + 0x400000000000000, + 0x800000000000000, + 0x1000000000000000, + 0x2000000000000000, + 0x4000000000000000, + 0x8000000000000000, + 0x10000000000000000, + 0x20000000000000000, + 0x40000000000000000, + 0x80000000000000000, + 0x100000000000000000, + 0x200000000000000000, + 0x400000000000000000, + 0x800000000000000000, + 0x1000000000000000000, + 0x2000000000000000000, + 0x4000000000000000000, + 0x8000000000000000000, + 0x10000000000000000000, + 0x20000000000000000000, + 0x40000000000000000000, + 0x80000000000000000000, + 0x100000000000000000000, + 0x200000000000000000000, + 0x400000000000000000000, + 0x800000000000000000000, + 0x1000000000000000000000, + 0x2000000000000000000000, + 0x4000000000000000000000, + 0x8000000000000000000000, + 0x10000000000000000000000, + 0x20000000000000000000000, + 0x40000000000000000000000, + 0x80000000000000000000000, + 0x100000000000000000000000, + 0x200000000000000000000000, + 0x400000000000000000000000, + 0x800000000000000000000000, + 0x1000000000000000000000000, + 0x2000000000000000000000000, + 0x4000000000000000000000000, + 0x8000000000000000000000000, + 0x10000000000000000000000000, + 0x20000000000000000000000000, + 0x40000000000000000000000000, + 0x80000000000000000000000000, + 0x100000000000000000000000000, + 0x200000000000000000000000000, + 0x400000000000000000000000000, + 0x800000000000000000000000000, + 0x1000000000000000000000000000, + 0x2000000000000000000000000000, + 0x4000000000000000000000000000, + 0x8000000000000000000000000000, + 0x10000000000000000000000000000, + 0x20000000000000000000000000000, + 0x40000000000000000000000000000, + 0x80000000000000000000000000000, + 0x100000000000000000000000000000, + 0x200000000000000000000000000000, + 0x400000000000000000000000000000, + 0x800000000000000000000000000000, + 0x1000000000000000000000000000000, + 0x2000000000000000000000000000000, + 0x4000000000000000000000000000000, + 0x8000000000000000000000000000000, + 0x10000000000000000000000000000000, + 0x20000000000000000000000000000000, + 0x40000000000000000000000000000000, + 0x80000000000000000000000000000000, + 0x100000000000000000000000000000000, + 0x200000000000000000000000000000000, + 0x400000000000000000000000000000000, + 0x800000000000000000000000000000000, + 0x1000000000000000000000000000000000, + 0x2000000000000000000000000000000000, + 0x4000000000000000000000000000000000, + 0x8000000000000000000000000000000000, + 0x10000000000000000000000000000000000, + 0x20000000000000000000000000000000000, + 0x40000000000000000000000000000000000, + 0x80000000000000000000000000000000000, + 0x100000000000000000000000000000000000, + 0x200000000000000000000000000000000000, + 0x400000000000000000000000000000000000, + 0x800000000000000000000000000000000000, + 0x1000000000000000000000000000000000000, + 0x2000000000000000000000000000000000000, + 0x4000000000000000000000000000000000000, + 0x8000000000000000000000000000000000000, + 0x10000000000000000000000000000000000000, + 0x20000000000000000000000000000000000000, + 0x40000000000000000000000000000000000000, + 0x80000000000000000000000000000000000000, + 0x100000000000000000000000000000000000000, + 0x200000000000000000000000000000000000000, + 0x400000000000000000000000000000000000000, + 0x800000000000000000000000000000000000000, + 0x1000000000000000000000000000000000000000, + 0x2000000000000000000000000000000000000000, + 0x4000000000000000000000000000000000000000, + 0x8000000000000000000000000000000000000000, + 0x10000000000000000000000000000000000000000, + 0x20000000000000000000000000000000000000000, + 0x40000000000000000000000000000000000000000, + 0x80000000000000000000000000000000000000000, + 0x100000000000000000000000000000000000000000, + 0x200000000000000000000000000000000000000000, + 0x400000000000000000000000000000000000000000, + 0x800000000000000000000000000000000000000000, + 0x1000000000000000000000000000000000000000000, + 0x2000000000000000000000000000000000000000000, + 0x4000000000000000000000000000000000000000000, + 0x8000000000000000000000000000000000000000000, + 0x10000000000000000000000000000000000000000000, + 0x20000000000000000000000000000000000000000000, + 0x40000000000000000000000000000000000000000000, + 0x80000000000000000000000000000000000000000000, + 0x100000000000000000000000000000000000000000000, + 0x200000000000000000000000000000000000000000000, + 0x400000000000000000000000000000000000000000000, + 0x800000000000000000000000000000000000000000000, + 0x1000000000000000000000000000000000000000000000, + 0x2000000000000000000000000000000000000000000000, + 0x4000000000000000000000000000000000000000000000, + 0x8000000000000000000000000000000000000000000000, + 0x10000000000000000000000000000000000000000000000, + 0x20000000000000000000000000000000000000000000000, + 0x40000000000000000000000000000000000000000000000, + 0x80000000000000000000000000000000000000000000000, + 0x100000000000000000000000000000000000000000000000, + 0x200000000000000000000000000000000000000000000000, + 0x400000000000000000000000000000000000000000000000, + 0x800000000000000000000000000000000000000000000000, + 0x1000000000000000000000000000000000000000000000000, + 0x2000000000000000000000000000000000000000000000000, + 0x4000000000000000000000000000000000000000000000000, + 0x8000000000000000000000000000000000000000000000000, + 0x10000000000000000000000000000000000000000000000000, + 0x20000000000000000000000000000000000000000000000000, + 0x40000000000000000000000000000000000000000000000000, + 0x80000000000000000000000000000000000000000000000000, + 0x100000000000000000000000000000000000000000000000000, + 0x200000000000000000000000000000000000000000000000000, + 0x400000000000000000000000000000000000000000000000000, + 0x800000000000000000000000000000000000000000000000000, + 0x1000000000000000000000000000000000000000000000000000, + 0x2000000000000000000000000000000000000000000000000000, + 0x4000000000000000000000000000000000000000000000000000, + 0x8000000000000000000000000000000000000000000000000000, + 0x10000000000000000000000000000000000000000000000000000, + 0x20000000000000000000000000000000000000000000000000000, + 0x40000000000000000000000000000000000000000000000000000, + 0x80000000000000000000000000000000000000000000000000000, + 0x100000000000000000000000000000000000000000000000000000, + 0x200000000000000000000000000000000000000000000000000000, + 0x400000000000000000000000000000000000000000000000000000, + 0x800000000000000000000000000000000000000000000000000000, + 0x1000000000000000000000000000000000000000000000000000000, + 0x2000000000000000000000000000000000000000000000000000000, + 0x4000000000000000000000000000000000000000000000000000000, + 0x8000000000000000000000000000000000000000000000000000000, + 0x10000000000000000000000000000000000000000000000000000000, + 0x20000000000000000000000000000000000000000000000000000000, + 0x40000000000000000000000000000000000000000000000000000000, + 0x80000000000000000000000000000000000000000000000000000000, + 0x100000000000000000000000000000000000000000000000000000000, + 0x200000000000000000000000000000000000000000000000000000000, + 0x400000000000000000000000000000000000000000000000000000000, + 0x800000000000000000000000000000000000000000000000000000000, + 0x1000000000000000000000000000000000000000000000000000000000, + 0x2000000000000000000000000000000000000000000000000000000000, + 0x4000000000000000000000000000000000000000000000000000000000, + 0x8000000000000000000000000000000000000000000000000000000000, + 0x10000000000000000000000000000000000000000000000000000000000, + 0x20000000000000000000000000000000000000000000000000000000000, + 0x40000000000000000000000000000000000000000000000000000000000, + 0x80000000000000000000000000000000000000000000000000000000000, + 0x100000000000000000000000000000000000000000000000000000000000, + 0x200000000000000000000000000000000000000000000000000000000000, + 0x400000000000000000000000000000000000000000000000000000000000, + 0x800000000000000000000000000000000000000000000000000000000000, + 0x1000000000000000000000000000000000000000000000000000000000000, + 0x2000000000000000000000000000000000000000000000000000000000000, + 0x4000000000000000000000000000000000000000000000000000000000000, + 0x8000000000000000000000000000000000000000000000000000000000000, + 0x10000000000000000000000000000000000000000000000000000000000000, + 0x20000000000000000000000000000000000000000000000000000000000000, + 0x40000000000000000000000000000000000000000000000000000000000000, + 0x80000000000000000000000000000000000000000000000000000000000000, + 0x100000000000000000000000000000000000000000000000000000000000000, + 0x200000000000000000000000000000000000000000000000000000000000000, + 0x400000000000000000000000000000000000000000000000000000000000000, + 0x800000000000000000000000000000000000000000000000000000000000000, + 0x1000000000000000000000000000000000000000000000000000000000000000, + 0x2000000000000000000000000000000000000000000000000000000000000000, + 0x4000000000000000000000000000000000000000000000000000000000000000, + 0x8000000000000000000000000000000000000000000000000000000000000000, +]; + pub const POW_2_0: u128 = 0x1; pub const POW_2_8: u128 = 0x100; pub const POW_2_16: u128 = 0x10000; diff --git a/cairo/kakarot-ssj/crates/utils/src/crypto/blake2_compress.cairo b/cairo/kakarot-ssj/crates/utils/src/crypto/blake2_compress.cairo index e008e7271..fe20466ef 100644 --- a/cairo/kakarot-ssj/crates/utils/src/crypto/blake2_compress.cairo +++ b/cairo/kakarot-ssj/crates/utils/src/crypto/blake2_compress.cairo @@ -54,7 +54,7 @@ fn rotate_right(value: u64, n: u32) -> u64 { let bits = BitSize::::bits(); // The number of bits in a u64 let n = n % bits; // Ensure n is less than 64 - let res = value.wrapping_shr(n.into()) | value.wrapping_shl((bits - n).into()); + let res = value.wrapping_shr(n) | value.wrapping_shl((bits - n)); res } } diff --git a/cairo/kakarot-ssj/crates/utils/src/crypto/modexp/arith.cairo b/cairo/kakarot-ssj/crates/utils/src/crypto/modexp/arith.cairo index d82bf2f61..d302048a8 100644 --- a/cairo/kakarot-ssj/crates/utils/src/crypto/modexp/arith.cairo +++ b/cairo/kakarot-ssj/crates/utils/src/crypto/modexp/arith.cairo @@ -300,7 +300,7 @@ pub fn mod_inv(x: Word) -> Word { break; } - let mask: u64 = 1_u64.shl(i.into()) - 1; + let mask: u64 = 1_u64.shl(i) - 1; let xy = x.wrapping_mul(y) & mask; let q = (mask + 1) / 2; if xy >= q { @@ -310,7 +310,7 @@ pub fn mod_inv(x: Word) -> Word { }; let xy = x.wrapping_mul(y); - let q = 1_u64.wrapping_shl((WORD_BITS - 1).into()); + let q = 1_u64.wrapping_shl((WORD_BITS - 1)); if xy >= q { y += q; } @@ -415,7 +415,7 @@ pub fn borrowing_sub(x: Word, y: Word, borrow: bool) -> (Word, bool) { /// The double word obtained by joining `hi` and `lo` pub fn join_as_double(hi: Word, lo: Word) -> DoubleWord { let hi: DoubleWord = hi.into(); - (hi.shl(WORD_BITS.into())).into() + lo.into() + hi.shl(WORD_BITS).into() + lo.into() } /// Computes `x^2`, storing the result in `out`. @@ -457,14 +457,14 @@ fn big_sq(ref x: MPNat, ref out: Felt252Vec) { } out.set(i + j, res.as_u64()); - c = new_c + res.shr(WORD_BITS.into()); + c = new_c + res.shr(WORD_BITS); j += 1; }; let (sum, carry) = carrying_add(out[i + s], c.as_u64(), false); out.set(i + s, sum); - out.set(i + s + 1, (c.shr(WORD_BITS.into()) + (carry.into())).as_u64()); + out.set(i + s + 1, (c.shr(WORD_BITS) + (carry.into())).as_u64()); i += 1; } @@ -482,8 +482,8 @@ pub fn in_place_shl(ref a: Felt252Vec, shift: u32) -> Word { } let mut a_digit = a[i]; - let carry = a_digit.wrapping_shr(carry_shift.into()); - a_digit = a_digit.wrapping_shl(shift.into()) | c; + let carry = a_digit.wrapping_shr(carry_shift); + a_digit = a_digit.wrapping_shl(shift) | c; a.set(i, a_digit); c = carry; @@ -508,8 +508,8 @@ pub fn in_place_shr(ref a: Felt252Vec, shift: u32) -> Word { let j = i - 1; let mut a_digit = a[j]; - let borrow = a_digit.wrapping_shl(borrow_shift.into()); - a_digit = a_digit.wrapping_shr(shift.into()) | b; + let borrow = a_digit.wrapping_shl(borrow_shift); + a_digit = a_digit.wrapping_shr(shift) | b; a.set(j, a_digit); b = borrow; @@ -574,7 +574,7 @@ pub fn in_place_mul_sub(ref a: Felt252Vec, ref x: Felt252Vec, y: Wor + offset_carry.into() - ((x_digit.into()) * (y.into())); - let new_offset_carry = (offset_sum.shr(WORD_BITS.into())).as_u64(); + let new_offset_carry = (offset_sum.shr(WORD_BITS)).as_u64(); let new_x = offset_sum.as_u64(); offset_carry = new_offset_carry; a.set(i, new_x); @@ -661,7 +661,7 @@ mod tests { let mut result = mp_nat_to_u128(ref x); let mask = BASE.wrapping_pow(x.digits.len().into()).wrapping_sub(1); - assert_eq!(result, n.wrapping_shl(shift.into()) & mask); + assert_eq!(result, n.wrapping_shl(shift) & mask); } fn check_in_place_shr(n: u128, shift: u32) { @@ -669,7 +669,7 @@ mod tests { in_place_shr(ref x.digits, shift); let mut result = mp_nat_to_u128(ref x); - assert_eq!(result, n.wrapping_shr(shift.into())); + assert_eq!(result, n.wrapping_shr(shift)); } fn check_mod_inv(n: Word) { diff --git a/cairo/kakarot-ssj/crates/utils/src/crypto/modexp/mpnat.cairo b/cairo/kakarot-ssj/crates/utils/src/crypto/modexp/mpnat.cairo index 5f461837f..6cd2d7fff 100644 --- a/cairo/kakarot-ssj/crates/utils/src/crypto/modexp/mpnat.cairo +++ b/cairo/kakarot-ssj/crates/utils/src/crypto/modexp/mpnat.cairo @@ -323,7 +323,7 @@ pub impl MPNatTraitImpl of MPNatTrait { in_place_shr(ref b.digits, 1); - res.digits.set(wordpos, res.digits[wordpos] | (x.shl(bitpos.into()))); + res.digits.set(wordpos, res.digits[wordpos] | (x.shl(bitpos))); bitpos += 1; if bitpos == WORD_BITS { @@ -404,7 +404,7 @@ pub impl MPNatTraitImpl of MPNatTrait { let mut digits = Felt252VecImpl::new(); digits.expand(trailing_zeros + 1).unwrap(); let mut tmp = MPNat { digits }; - tmp.digits.set(trailing_zeros, 1_u64.shl(additional_zero_bits.into())); + tmp.digits.set(trailing_zeros, 1_u64.shl(additional_zero_bits)); tmp }; @@ -415,7 +415,7 @@ pub impl MPNatTraitImpl of MPNatTrait { digits.expand(num_digits).unwrap(); let mut tmp = MPNat { digits }; if additional_zero_bits > 0 { - tmp.digits.set(0, modulus.digits[trailing_zeros].shr(additional_zero_bits.into())); + tmp.digits.set(0, modulus.digits[trailing_zeros].shr(additional_zero_bits)); let mut i = 1; loop { if i == num_digits { @@ -429,10 +429,9 @@ pub impl MPNatTraitImpl of MPNatTrait { i - 1, tmp.digits[i - 1] - + (d & power_of_two_mask) - .shl((WORD_BITS - additional_zero_bits).into()) + + (d & power_of_two_mask).shl(WORD_BITS - additional_zero_bits) ); - tmp.digits.set(i, d.shr(additional_zero_bits.into())); + tmp.digits.set(i, d.shr(additional_zero_bits)); i += 1; }; diff --git a/cairo/kakarot-ssj/crates/utils/src/math.cairo b/cairo/kakarot-ssj/crates/utils/src/math.cairo index 6e77fdbc9..ec1344b2d 100644 --- a/cairo/kakarot-ssj/crates/utils/src/math.cairo +++ b/cairo/kakarot-ssj/crates/utils/src/math.cairo @@ -1,5 +1,5 @@ use core::integer::{u512}; -use core::num::traits::{Zero, One, BitSize, OverflowingAdd, OverflowingMul}; +use core::num::traits::{Zero, One, BitSize, OverflowingAdd, OverflowingMul, Bounded}; use core::panic_with_felt252; use core::traits::{BitAnd}; @@ -203,7 +203,7 @@ pub trait Bitshift { /// /// Panics if the shift is greater than 255. /// Panics if the result overflows the type T. - fn shl(self: T, shift: T) -> T; + fn shl(self: T, shift: usize) -> T; /// Shift a number right by a given number of bits. /// @@ -219,7 +219,7 @@ pub trait Bitshift { /// # Panics /// /// Panics if the shift is greater than 255. - fn shr(self: T, shift: T) -> T; + fn shr(self: T, shift: usize) -> T; } impl BitshiftImpl< @@ -236,24 +236,26 @@ impl BitshiftImpl< +PartialOrd, +BitSize, +TryInto, + +TryInto, + +TryInto, > of Bitshift { - fn shl(self: T, shift: T) -> T { + fn shl(self: T, shift: usize) -> T { // if we shift by more than nb_bits of T, the result is 0 // we early return to save gas and prevent unexpected behavior - if shift > BitSize::::bits().try_into().unwrap() - One::one() { + if shift > BitSize::::bits() - One::one() { panic_with_felt252('mul Overflow'); } let two = One::one() + One::one(); - self * two.pow(shift) + self * two.pow(shift.try_into().expect('mul Overflow')) } - fn shr(self: T, shift: T) -> T { + fn shr(self: T, shift: usize) -> T { // early return to save gas if shift > nb_bits of T - if shift > BitSize::::bits().try_into().unwrap() - One::one() { + if shift > BitSize::::bits() - One::one() { panic_with_felt252('mul Overflow'); } let two = One::one() + One::one(); - self / two.pow(shift) + self / two.pow(shift.try_into().expect('mul Overflow')) } } @@ -270,7 +272,7 @@ pub trait WrappingBitshift { /// # Returns /// /// The result of shifting `self` left by `shift` bits, wrapped if necessary - fn wrapping_shl(self: T, shift: T) -> T; + fn wrapping_shl(self: T, shift: usize) -> T; /// Shift a number right by a given number of bits. /// If the shift is greater than 255, the result is 0. @@ -283,7 +285,7 @@ pub trait WrappingBitshift { /// # Returns /// /// The result of shifting `self` right by `shift` bits, or 0 if shift > 255 - fn wrapping_shr(self: T, shift: T) -> T; + fn wrapping_shr(self: T, shift: usize) -> T; } pub impl WrappingBitshiftImpl< @@ -300,21 +302,25 @@ pub impl WrappingBitshiftImpl< +OverflowingMul, +WrappingExponentiation, +BitSize, + +Bounded, +TryInto, + +TryInto, + +TryInto, + +Into > of WrappingBitshift { - fn wrapping_shl(self: T, shift: T) -> T { + fn wrapping_shl(self: T, shift: usize) -> T { let two = One::::one() + One::::one(); - let (result, _) = self.overflowing_mul(two.wrapping_pow(shift)); + let (result, _) = self.overflowing_mul(two.wrapping_pow(shift.try_into().unwrap())); result } - fn wrapping_shr(self: T, shift: T) -> T { + fn wrapping_shr(self: T, shift: usize) -> T { let two = One::::one() + One::::one(); - if shift > BitSize::::bits().try_into().unwrap() - One::one() { + if shift > BitSize::::bits() - One::one() { return Zero::zero(); } - self / two.pow(shift) + self / two.pow(shift.try_into().unwrap()) } } diff --git a/cairo/kakarot-ssj/crates/utils/src/traits/bytes.cairo b/cairo/kakarot-ssj/crates/utils/src/traits/bytes.cairo index 6cec31aee..1499597d5 100644 --- a/cairo/kakarot-ssj/crates/utils/src/traits/bytes.cairo +++ b/cairo/kakarot-ssj/crates/utils/src/traits/bytes.cairo @@ -50,7 +50,7 @@ pub impl U8SpanExImpl of U8SpanExTrait { Option::Some(byte) => { let byte: u64 = (*byte.unbox()).into(); // Accumulate pending_word in a little endian manner - byte.shl(8_u64 * byte_counter.into()) + byte.shl(8_u32 * byte_counter.into()) }, Option::None => { break; }, }; @@ -69,7 +69,7 @@ pub impl U8SpanExImpl of U8SpanExTrait { last_input_word += match self.get(full_u64_word_count * 8 + byte_counter.into()) { Option::Some(byte) => { let byte: u64 = (*byte.unbox()).into(); - byte.shl(8_u64 * byte_counter.into()) + byte.shl(8_u32 * byte_counter.into()) }, Option::None => { break; }, }; @@ -246,17 +246,13 @@ pub impl ToBytesImpl< fn to_be_bytes(self: T) -> Span { let bytes_used = self.bytes_used(); - let one = One::::one(); - let two = one + one; - let eight = two * two * two; - // 0xFF let mask = Bounded::::MAX.into(); let mut bytes: Array = Default::default(); for i in 0 ..bytes_used { - let val = Bitshift::::shr(self, eight * (bytes_used - i - 1).into()); + let val = Bitshift::::shr(self, 8_u32 * (bytes_used.into() - i.into() - 1)); bytes.append((val & mask).try_into().unwrap()); }; @@ -270,9 +266,6 @@ pub impl ToBytesImpl< fn to_le_bytes(mut self: T) -> Span { let bytes_used = self.bytes_used(); - let one = One::::one(); - let two = one + one; - let eight = two * two * two; // 0xFF let mask = Bounded::::MAX.into(); @@ -281,7 +274,7 @@ pub impl ToBytesImpl< for i in 0 ..bytes_used { - let val = self.shr(eight * i.into()); + let val = self.shr(8_u32 * i.into()); bytes.append((val & mask).try_into().unwrap()); }; @@ -526,7 +519,7 @@ pub impl ByteArrayExt of ByteArrayExTrait { Option::Some(byte) => { let byte: u64 = byte.into(); // Accumulate pending_word in a little endian manner - byte.shl(8_u64 * byte_counter.into()) + byte.shl(8_u32 * byte_counter.into()) }, Option::None => { break; }, }; @@ -546,7 +539,7 @@ pub impl ByteArrayExt of ByteArrayExTrait { last_input_word += match self.at(full_u64_word_count * 8 + byte_counter.into()) { Option::Some(byte) => { let byte: u64 = byte.into(); - byte.shl(8_u64 * byte_counter.into()) + byte.shl(8_u32 * byte_counter.into()) }, Option::None => { break; }, }; diff --git a/cairo/kakarot-ssj/crates/utils/src/traits/eth_address.cairo b/cairo/kakarot-ssj/crates/utils/src/traits/eth_address.cairo index 9f0122b29..d039f1de4 100644 --- a/cairo/kakarot-ssj/crates/utils/src/traits/eth_address.cairo +++ b/cairo/kakarot-ssj/crates/utils/src/traits/eth_address.cairo @@ -4,18 +4,18 @@ use crate::traits::EthAddressIntoU256; #[generate_trait] pub impl EthAddressExImpl of EthAddressExTrait { + const BYTES_USED: u8 = 20; /// Converts an EthAddress to an array of bytes. /// /// # Returns /// /// * `Array` - A 20-byte array representation of the EthAddress. fn to_bytes(self: EthAddress) -> Array { - let bytes_used: u256 = 20; let value: u256 = self.into(); let mut bytes: Array = Default::default(); for i in 0 - ..bytes_used { - let val = value.shr(8 * (bytes_used - i - 1)); + ..Self::BYTES_USED { + let val = value.shr(8_u32 * (Self::BYTES_USED.into() - i.into() - 1)); bytes.append((val & 0xFF).try_into().unwrap()); }; @@ -42,7 +42,7 @@ pub impl EthAddressExImpl of EthAddressExTrait { for i in 0 ..len { let byte: u256 = (*input.at(i)).into(); - result += byte.shl((8 * (offset - i)).into()); + result += byte.shl((8 * (offset - i))); }; result.try_into() } diff --git a/cairo/kakarot-ssj/crates/utils/src/traits/integer.cairo b/cairo/kakarot-ssj/crates/utils/src/traits/integer.cairo index ebd00f99e..d038336b8 100644 --- a/cairo/kakarot-ssj/crates/utils/src/traits/integer.cairo +++ b/cairo/kakarot-ssj/crates/utils/src/traits/integer.cairo @@ -186,11 +186,9 @@ pub impl BitsUsedImpl< if self == Zero::zero() { return 0; } - let two: T = One::one() + One::one(); - let eight: T = two * two * two; let bytes_used = self.bytes_used(); - let last_byte = self.shr(eight * (bytes_used.into() - One::one())); + let last_byte = self.shr(8_u32 * (bytes_used.into() - One::one())); // safe unwrap since we know at most 8 bits are used let bits_used: u8 = bits_used_internal::bits_used_in_byte(last_byte.try_into().unwrap()); diff --git a/cairo/kakarot-ssj/docs/general/account_state.png b/cairo/kakarot-ssj/docs/general/account_state.png index 0df32c4762faaed95ebb6839ade3c836f8924928..4386b900a41a4e3db705041d68ab14e5130ad653 100644 GIT binary patch literal 132360 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∨p{dGWX;mf&C7K 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%0A9y#gqZfcw@Z7MS}^SlG^kHS)!Vx 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 VbiXW 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 Jk$4&KzW}>@_qPB5 diff --git a/cairo/kakarot-ssj/docs/general/contract_storage.md b/cairo/kakarot-ssj/docs/general/contract_storage.md index 042907767..b77599022 100644 --- a/cairo/kakarot-ssj/docs/general/contract_storage.md +++ b/cairo/kakarot-ssj/docs/general/contract_storage.md @@ -75,7 +75,7 @@ As Kakarot is a contract that is deployed on Starknet and is not a client that can directly manipulate a storage database, our approach differs from one of a traditional client. We do not directly manipulate tries. Instead, we have access to contracts storage on the Starknet blockchain, that we can query using -syscalls to read and update the value of a of a storage slot. +syscalls to read and update the value of a storage slot. There are two different ways of handling Storage in Kakarot. @@ -105,7 +105,7 @@ This design has some limitations: - We perform a `call_contract_syscall` for each SLOAD/SSTORE operation that is committed to Starknet, which has an extra overhead compared to directly - modifying the current contract's storage . Given that only KakarotCore can + modifying the current contract's storage. Given that only KakarotCore can modify the storage of a Kakarot contract, we could directly store the whole world state in the main Kakarot contract storage. - It adds external entrypoints with admin rights to read and write from storage @@ -171,7 +171,7 @@ compatibility with Starknet. ### Tracking and reverting storage changes The storage mechanism presented in the [Local State](./local_state.md) section -enable us to revert storage changes by using a concept similar to Geth's +enables us to revert storage changes by using a concept similar to Geth's journal. Each storage change will be stored in a `StateChangeLog` implemented using a `Felt252Dict` data structure, that will associate each modified storage address to its new value. This allows us to perform three things: diff --git a/cairo/kakarot-ssj/docs/general/volition.png b/cairo/kakarot-ssj/docs/general/volition.png index bc76e843b937cc4fd39672ec0577eb98d3a93c7c..d254f23146763edfb12c1f5a6e7c10246dee16e8 100644 GIT binary patch literal 192376 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
RxD-L)=UV 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 Dsp$ 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

;i%L-Y z8)NAI@^*QBeI%Krl50?XVU9o|a0rXVR~l0RG3ax%>#^`mqiciqrHXy8N{)vH=gEz+ zLeTiqOtMf&XDG@B+}I;3mTdC#05wf*e8}-F1*||dIu9*lh5|6~xR+iOKXgvpk#19) zCgNd3Hk$N{$SD!Aw1%^&IPUxVNp`SIch<}MK*XbZj?k9D2*0)qcZ6^6!;|DY|V9zeeClF+j0u~F*fW?>pz`ko>@U*!? zXlkHE7Es4>1{=;fq}_Y<7&ZqihpUX`;=@-7-GRfJ) +-q(Lx3-R6>*UsE2M8-1ve0tQy7Gk29l?gykesZ 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 Idbn2fr~tJNDn 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 diff --git a/cairo/kakarot-ssj/scripts/setup_cairo_native.sh b/cairo/kakarot-ssj/scripts/setup_cairo_native.sh index 8b74c612c..1cf59c891 100755 --- a/cairo/kakarot-ssj/scripts/setup_cairo_native.sh +++ b/cairo/kakarot-ssj/scripts/setup_cairo_native.sh @@ -119,6 +119,7 @@ install_cairo_native_runtime() { git clone https://github.com/lambdaclass/cairo_native.git pushd ./cairo_native || exit 1 + git fetch make deps make runtime cp libcairo_native_runtime.a ../libcairo_native_runtime.a From f355e8bc49bf6a3e4062e326e1e2eccdb3e445b0 Mon Sep 17 00:00:00 2001 From: Oba Date: Wed, 2 Oct 2024 13:26:44 +0200 Subject: [PATCH 28/56] chore: fix trunk --- .trunk/trunk.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index 348b0b6af..cbac54477 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -72,11 +72,10 @@ lint: - logs* - lib* - resources* - - cairo1_contracts - tests/ef_tests/test_data - .katana/messaging_config.json - deployments - - cairo/kakarot-ssj + - cairo/** - linters: [solidity] paths: - solidity_contracts/src/UniswapV2/**/*.sol From 3d210345e976658b1ae8af64e818ac16ae45a3cd Mon Sep 17 00:00:00 2001 From: Oba Date: Wed, 2 Oct 2024 13:31:22 +0200 Subject: [PATCH 29/56] chore: rename audit folder --- .../Kakarot EVM - Zellic Audit Report.pdf | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename audits/{kakarot0 => cairo_zero}/Kakarot EVM - Zellic Audit Report.pdf (100%) diff --git a/audits/kakarot0/Kakarot EVM - Zellic Audit Report.pdf b/audits/cairo_zero/Kakarot EVM - Zellic Audit Report.pdf similarity index 100% rename from audits/kakarot0/Kakarot EVM - Zellic Audit Report.pdf rename to audits/cairo_zero/Kakarot EVM - Zellic Audit Report.pdf From 943aa36e0c2d635fc79bb2b0366a6de1f39d4fa1 Mon Sep 17 00:00:00 2001 From: Oba Date: Wed, 2 Oct 2024 13:54:15 +0200 Subject: [PATCH 30/56] ci: rename workflows file and fix sparse-checkout --- .github/workflows/{kakarot0-ci.yml => cairo-zero-ci.yml} | 0 ...arot0-nightly-fuzzing.yml => cairo-zero-nightly-fuzzing.yml} | 0 .../workflows/{kakarot0-release.yml => cairo-zero-release.yml} | 0 .../{kakarot0-trunk-check.yaml => cairo-zero-trunk-check.yaml} | 0 .../{kakarot0-update-rpc.yml => cairo-zero-update-rpc.yml} | 0 .github/workflows/ssj-ef-tests.yml | 2 +- 6 files changed, 1 insertion(+), 1 deletion(-) rename .github/workflows/{kakarot0-ci.yml => cairo-zero-ci.yml} (100%) rename .github/workflows/{kakarot0-nightly-fuzzing.yml => cairo-zero-nightly-fuzzing.yml} (100%) rename .github/workflows/{kakarot0-release.yml => cairo-zero-release.yml} (100%) rename .github/workflows/{kakarot0-trunk-check.yaml => cairo-zero-trunk-check.yaml} (100%) rename .github/workflows/{kakarot0-update-rpc.yml => cairo-zero-update-rpc.yml} (100%) diff --git a/.github/workflows/kakarot0-ci.yml b/.github/workflows/cairo-zero-ci.yml similarity index 100% rename from .github/workflows/kakarot0-ci.yml rename to .github/workflows/cairo-zero-ci.yml diff --git a/.github/workflows/kakarot0-nightly-fuzzing.yml b/.github/workflows/cairo-zero-nightly-fuzzing.yml similarity index 100% rename from .github/workflows/kakarot0-nightly-fuzzing.yml rename to .github/workflows/cairo-zero-nightly-fuzzing.yml diff --git a/.github/workflows/kakarot0-release.yml b/.github/workflows/cairo-zero-release.yml similarity index 100% rename from .github/workflows/kakarot0-release.yml rename to .github/workflows/cairo-zero-release.yml diff --git a/.github/workflows/kakarot0-trunk-check.yaml b/.github/workflows/cairo-zero-trunk-check.yaml similarity index 100% rename from .github/workflows/kakarot0-trunk-check.yaml rename to .github/workflows/cairo-zero-trunk-check.yaml diff --git a/.github/workflows/kakarot0-update-rpc.yml b/.github/workflows/cairo-zero-update-rpc.yml similarity index 100% rename from .github/workflows/kakarot0-update-rpc.yml rename to .github/workflows/cairo-zero-update-rpc.yml diff --git a/.github/workflows/ssj-ef-tests.yml b/.github/workflows/ssj-ef-tests.yml index 288c98489..3d2bd04a2 100644 --- a/.github/workflows/ssj-ef-tests.yml +++ b/.github/workflows/ssj-ef-tests.yml @@ -61,7 +61,7 @@ jobs: uses: actions/checkout@v4 with: sparse-checkout: | - ./cairo/kakarot-ssj/blockchain-tests-skip.yml + cairo/kakarot-ssj/blockchain-tests-skip.yml sparse-checkout-cone-mode: false path: skip-file From 9fd50a73f87e12668cabe78794ffeef75842d180 Mon Sep 17 00:00:00 2001 From: Oba Date: Wed, 2 Oct 2024 14:09:56 +0200 Subject: [PATCH 31/56] ci: fix concurrency --- .github/workflows/cairo-zero-ci.yml | 2 +- .github/workflows/cairo-zero-trunk-check.yaml | 2 +- .github/workflows/ssj-ci.yml | 2 +- .github/workflows/ssj-test.yml | 2 +- .github/workflows/ssj-trunk-check.yaml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/cairo-zero-ci.yml b/.github/workflows/cairo-zero-ci.yml index 423e1f130..98413d8b1 100644 --- a/.github/workflows/cairo-zero-ci.yml +++ b/.github/workflows/cairo-zero-ci.yml @@ -12,7 +12,7 @@ env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} concurrency: - group: cairo-zero-${{ github.ref }} + group: cairo-zero-${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true permissions: read-all diff --git a/.github/workflows/cairo-zero-trunk-check.yaml b/.github/workflows/cairo-zero-trunk-check.yaml index 12de8f20e..872ee6d27 100644 --- a/.github/workflows/cairo-zero-trunk-check.yaml +++ b/.github/workflows/cairo-zero-trunk-check.yaml @@ -3,7 +3,7 @@ name: cairo-zero-Trunk on: [pull_request] concurrency: - group: cairo-zero-${{ github.ref }} + group: cairo-zero-${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true permissions: read-all diff --git a/.github/workflows/ssj-ci.yml b/.github/workflows/ssj-ci.yml index 82e485376..441ec550a 100644 --- a/.github/workflows/ssj-ci.yml +++ b/.github/workflows/ssj-ci.yml @@ -11,7 +11,7 @@ env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} concurrency: - group: ssj-${{ github.ref }} + group: ssj-${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true permissions: read-all diff --git a/.github/workflows/ssj-test.yml b/.github/workflows/ssj-test.yml index 2ea127ea1..b3dc169c7 100644 --- a/.github/workflows/ssj-test.yml +++ b/.github/workflows/ssj-test.yml @@ -8,7 +8,7 @@ on: - cairo/kakarot-ssj/** concurrency: - group: ${{ github.workflow }}-${{ github.ref }} + group: ssj-${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: diff --git a/.github/workflows/ssj-trunk-check.yaml b/.github/workflows/ssj-trunk-check.yaml index 1462cfa98..ec0864d84 100644 --- a/.github/workflows/ssj-trunk-check.yaml +++ b/.github/workflows/ssj-trunk-check.yaml @@ -3,7 +3,7 @@ name: SSJ-Trunk on: [pull_request] concurrency: - group: ${{ github.workflow }}-${{ github.ref }} + group: ssj-${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true permissions: read-all From c1b76a755f05d362eca6b00fec6e7f6c3ce3f2dd Mon Sep 17 00:00:00 2001 From: Oba Date: Wed, 2 Oct 2024 14:39:54 +0200 Subject: [PATCH 32/56] ci: fix skip file ssj ef-tests --- .github/workflows/ssj-ef-tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ssj-ef-tests.yml b/.github/workflows/ssj-ef-tests.yml index 3d2bd04a2..7a270d5c3 100644 --- a/.github/workflows/ssj-ef-tests.yml +++ b/.github/workflows/ssj-ef-tests.yml @@ -61,13 +61,13 @@ jobs: uses: actions/checkout@v4 with: sparse-checkout: | - cairo/kakarot-ssj/blockchain-tests-skip.yml + ./cairo/kakarot-ssj/blockchain-tests-skip.yml sparse-checkout-cone-mode: false path: skip-file - name: Setup ef-tests run: | - mv skip-file/blockchain-tests-skip.yml ef-tests/blockchain-tests-skip.yml + mv skip-file/cairo/kakarot-ssj/blockchain-tests-skip.yml ef-tests/blockchain-tests-skip.yml cd ef-tests mkdir -p build/common make setup setup-kakarot-v0 From 45221d3a2693d661151248318dc35a06c20ec27a Mon Sep 17 00:00:00 2001 From: Oba Date: Wed, 2 Oct 2024 14:42:44 +0200 Subject: [PATCH 33/56] chore: update ssj --- .../crates/evm/src/create_helpers.cairo | 17 +++++-- cairo/kakarot-ssj/crates/evm/src/gas.cairo | 3 +- .../instructions/duplication_operations.cairo | 3 +- .../environmental_information.cairo | 51 ++++++++++++++----- .../src/instructions/logging_operations.cairo | 16 +++--- .../src/instructions/memory_operations.cairo | 25 ++++++--- .../crates/evm/src/instructions/sha3.cairo | 9 +++- .../stop_and_arithmetic_operations.cairo | 8 ++- .../src/instructions/system_operations.cairo | 12 ++++- .../crates/evm/src/interpreter.cairo | 2 +- .../crates/evm/src/precompiles/identity.cairo | 5 +- .../evm/src/precompiles/p256verify.cairo | 34 ++----------- .../crates/evm/src/precompiles/sha256.cairo | 5 +- .../crates/utils/src/helpers.cairo | 3 -- 14 files changed, 118 insertions(+), 75 deletions(-) diff --git a/cairo/kakarot-ssj/crates/evm/src/create_helpers.cairo b/cairo/kakarot-ssj/crates/evm/src/create_helpers.cairo index 3b8c39eca..14c3d435c 100644 --- a/cairo/kakarot-ssj/crates/evm/src/create_helpers.cairo +++ b/cairo/kakarot-ssj/crates/evm/src/create_helpers.cairo @@ -1,4 +1,5 @@ use core::num::traits::Bounded; +use core::num::traits::CheckedAdd; use core::num::traits::Zero; use core::starknet::EthAddress; use crate::errors::{ensure, EVMError}; @@ -18,7 +19,6 @@ use utils::set::SetTrait; use utils::traits::{ BoolIntoNumeric, EthAddressIntoU256, U256TryIntoResult, SpanU8TryIntoResultEthAddress }; - /// Helper struct to prepare CREATE and CREATE2 opcodes #[derive(Drop)] pub struct CreateArgs { @@ -46,13 +46,20 @@ pub impl CreateHelpersImpl of CreateHelpers { self.memory.ensure_length(memory_expansion.new_size); let init_code_gas = gas::init_code_cost(size); let charged_gas = match create_type { - CreateType::Create => gas::CREATE + memory_expansion.expansion_cost + init_code_gas, + CreateType::Create => gas::CREATE + .checked_add(memory_expansion.expansion_cost) + .ok_or(EVMError::OutOfGas)? + .checked_add(init_code_gas) + .ok_or(EVMError::OutOfGas)?, CreateType::Create2 => { let calldata_words = bytes_32_words_size(size); gas::CREATE - + gas::KECCAK256WORD * calldata_words.into() - + memory_expansion.expansion_cost - + init_code_gas + .checked_add(gas::KECCAK256WORD * calldata_words.into()) + .ok_or(EVMError::OutOfGas)? + .checked_add(memory_expansion.expansion_cost) + .ok_or(EVMError::OutOfGas)? + .checked_add(init_code_gas) + .ok_or(EVMError::OutOfGas)? }, }; self.charge_gas(charged_gas)?; diff --git a/cairo/kakarot-ssj/crates/evm/src/gas.cairo b/cairo/kakarot-ssj/crates/evm/src/gas.cairo index fa359bd2e..9454410ae 100644 --- a/cairo/kakarot-ssj/crates/evm/src/gas.cairo +++ b/cairo/kakarot-ssj/crates/evm/src/gas.cairo @@ -4,6 +4,7 @@ use crate::errors::EVMError; use utils::eth_transaction::common::TxKindTrait; use utils::eth_transaction::eip2930::{AccessListItem}; use utils::eth_transaction::transaction::{Transaction, TransactionTrait}; +use utils::helpers::bytes_32_words_size; use utils::helpers; //! Gas costs for EVM operations @@ -153,7 +154,7 @@ pub fn calculate_message_call_gas( /// * `total_gas_cost` - The gas cost for storing data in memory. pub fn calculate_memory_gas_cost(size_in_bytes: usize) -> u64 { let _512: NonZero = 512_u64.try_into().unwrap(); - let size_in_words = (size_in_bytes + 31) / 32; + let size_in_words = bytes_32_words_size(size_in_bytes); let linear_cost = size_in_words.into() * MEMORY; let (q0, r0) = DivRem::div_rem(size_in_words.into(), _512); diff --git a/cairo/kakarot-ssj/crates/evm/src/instructions/duplication_operations.cairo b/cairo/kakarot-ssj/crates/evm/src/instructions/duplication_operations.cairo index 5752279ba..a69796598 100644 --- a/cairo/kakarot-ssj/crates/evm/src/instructions/duplication_operations.cairo +++ b/cairo/kakarot-ssj/crates/evm/src/instructions/duplication_operations.cairo @@ -8,8 +8,9 @@ use crate::stack::StackTrait; /// Generic DUP operation #[inline(always)] -fn exec_dup_i(ref self: VM, i: u8) -> Result<(), EVMError> { +fn exec_dup_i(ref self: VM, i: NonZero) -> Result<(), EVMError> { self.charge_gas(gas::VERYLOW)?; + let i: u8 = i.into(); let item = self.stack.peek_at((i - 1).into())?; self.stack.push(item) } diff --git a/cairo/kakarot-ssj/crates/evm/src/instructions/environmental_information.cairo b/cairo/kakarot-ssj/crates/evm/src/instructions/environmental_information.cairo index 9da876792..22d47d8a7 100644 --- a/cairo/kakarot-ssj/crates/evm/src/instructions/environmental_information.cairo +++ b/cairo/kakarot-ssj/crates/evm/src/instructions/environmental_information.cairo @@ -1,5 +1,6 @@ use core::num::traits::OverflowingAdd; use core::num::traits::Zero; +use core::num::traits::{CheckedAdd, CheckedSub}; use crate::errors::{ensure, EVMError}; use crate::gas; use crate::memory::MemoryTrait; @@ -79,12 +80,17 @@ pub impl EnvironmentInformationImpl of EnvironmentInformationTrait { let calldata_len = calldata.len(); // All bytes after the end of the calldata are set to 0. - if offset >= calldata_len { - return self.stack.push(0); - } + let bytes_len = match calldata_len.checked_sub(offset) { + Option::None => { return self.stack.push(0); }, + Option::Some(remaining_len) => { + if remaining_len == 0 { + return self.stack.push(0); + } + core::cmp::min(32, remaining_len) + } + }; // Slice the calldata - let bytes_len = core::cmp::min(32, calldata_len - offset); let sliced = calldata.slice(offset, bytes_len); let mut data_to_load: u256 = sliced @@ -122,7 +128,13 @@ pub impl EnvironmentInformationImpl of EnvironmentInformationTrait { self.memory.size(), [(dest_offset, size)].span() )?; self.memory.ensure_length(memory_expansion.new_size); - self.charge_gas(gas::VERYLOW + copy_gas_cost + memory_expansion.expansion_cost)?; + + let total_cost = gas::VERYLOW + .checked_add(copy_gas_cost) + .ok_or(EVMError::OutOfGas)? + .checked_add(memory_expansion.expansion_cost) + .ok_or(EVMError::OutOfGas)?; + self.charge_gas(total_cost)?; let calldata: Span = self.message().data; copy_bytes_to_memory(ref self, calldata, dest_offset, offset, size); @@ -152,7 +164,13 @@ pub impl EnvironmentInformationImpl of EnvironmentInformationTrait { self.memory.size(), [(dest_offset, size)].span() )?; self.memory.ensure_length(memory_expansion.new_size); - self.charge_gas(gas::VERYLOW + copy_gas_cost + memory_expansion.expansion_cost)?; + + let total_cost = gas::VERYLOW + .checked_add(copy_gas_cost) + .ok_or(EVMError::OutOfGas)? + .checked_add(memory_expansion.expansion_cost) + .ok_or(EVMError::OutOfGas)?; + self.charge_gas(total_cost)?; let bytecode: Span = self.message().code; @@ -208,7 +226,12 @@ pub impl EnvironmentInformationImpl of EnvironmentInformationTrait { self.accessed_addresses.add(evm_address); gas::COLD_ACCOUNT_ACCESS_COST }; - self.charge_gas(access_gas_cost + copy_gas_cost + memory_expansion.expansion_cost)?; + let total_cost = access_gas_cost + .checked_add(copy_gas_cost) + .ok_or(EVMError::OutOfGas)? + .checked_add(memory_expansion.expansion_cost) + .ok_or(EVMError::OutOfGas)?; + self.charge_gas(total_cost)?; let bytecode = self.env.state.get_account(evm_address).code; copy_bytes_to_memory(ref self, bytecode, dest_offset, offset, size); @@ -246,7 +269,12 @@ pub impl EnvironmentInformationImpl of EnvironmentInformationTrait { self.memory.size(), [(dest_offset, size)].span() )?; self.memory.ensure_length(memory_expansion.new_size); - self.charge_gas(gas::VERYLOW + copy_gas_cost + memory_expansion.expansion_cost)?; + let total_cost = gas::VERYLOW + .checked_add(copy_gas_cost) + .ok_or(EVMError::OutOfGas)? + .checked_add(memory_expansion.expansion_cost) + .ok_or(EVMError::OutOfGas)?; + self.charge_gas(total_cost)?; let data_to_copy: Span = return_data.slice(offset, size); self.memory.store_n(data_to_copy, dest_offset); @@ -287,10 +315,9 @@ pub impl EnvironmentInformationImpl of EnvironmentInformationTrait { fn copy_bytes_to_memory( ref self: VM, bytes: Span, dest_offset: usize, offset: usize, size: usize ) { - let bytes_slice = if offset < bytes.len() { - bytes.slice(offset, core::cmp::min(size, bytes.len() - offset)) - } else { - [].span() + let bytes_slice = match bytes.len().checked_sub(offset) { + Option::Some(remaining) => bytes.slice(offset, core::cmp::min(size, remaining)), + Option::None => [].span() }; self.memory.store_padded_segment(dest_offset, size, bytes_slice); diff --git a/cairo/kakarot-ssj/crates/evm/src/instructions/logging_operations.cairo b/cairo/kakarot-ssj/crates/evm/src/instructions/logging_operations.cairo index 12c86a30d..4be7153b5 100644 --- a/cairo/kakarot-ssj/crates/evm/src/instructions/logging_operations.cairo +++ b/cairo/kakarot-ssj/crates/evm/src/instructions/logging_operations.cairo @@ -1,5 +1,6 @@ //! Logging Operations. +use core::num::traits::CheckedAdd; use crate::errors::{EVMError, ensure}; use crate::gas; use crate::memory::MemoryTrait; @@ -68,13 +69,14 @@ fn exec_log_i(ref self: VM, topics_len: u8) -> Result<(), EVMError> { self.memory.ensure_length(memory_expansion.new_size); // TODO: avoid addition overflows here. We should use checked arithmetic. - self - .charge_gas( - gas::LOG - + topics_len.into() * gas::LOGTOPIC - + size.into() * gas::LOGDATA - + memory_expansion.expansion_cost - )?; + let total_cost = gas::LOG + .checked_add(topics_len.into() * gas::LOGTOPIC) + .ok_or(EVMError::OutOfGas)? + .checked_add(size.into() * gas::LOGDATA) + .ok_or(EVMError::OutOfGas)? + .checked_add(memory_expansion.expansion_cost) + .ok_or(EVMError::OutOfGas)?; + self.charge_gas(total_cost)?; let mut data: Array = Default::default(); self.memory.load_n(size, ref data, offset); diff --git a/cairo/kakarot-ssj/crates/evm/src/instructions/memory_operations.cairo b/cairo/kakarot-ssj/crates/evm/src/instructions/memory_operations.cairo index fc2d81b61..4386d275b 100644 --- a/cairo/kakarot-ssj/crates/evm/src/instructions/memory_operations.cairo +++ b/cairo/kakarot-ssj/crates/evm/src/instructions/memory_operations.cairo @@ -1,4 +1,5 @@ use core::cmp::max; +use core::num::traits::CheckedAdd; use crate::backend::starknet_backend::fetch_original_storage; //! Stack Memory Storage and Flow Operations. use crate::errors::{EVMError, ensure}; @@ -9,7 +10,6 @@ use crate::stack::StackTrait; use crate::state::StateTrait; use utils::helpers::bytes_32_words_size; use utils::set::SetTrait; - #[inline(always)] fn jump(ref self: VM, index: usize) -> Result<(), EVMError> { match self.message().code.get(index) { @@ -42,7 +42,10 @@ pub impl MemoryOperation of MemoryOperationTrait { let memory_expansion = gas::memory_expansion(self.memory.size(), [(offset, 32)].span())?; self.memory.ensure_length(memory_expansion.new_size); - self.charge_gas(gas::VERYLOW + memory_expansion.expansion_cost)?; + let total_cost = gas::VERYLOW + .checked_add(memory_expansion.expansion_cost) + .ok_or(EVMError::OutOfGas)?; + self.charge_gas(total_cost)?; let result = self.memory.load(offset); self.stack.push(result) @@ -58,7 +61,10 @@ pub impl MemoryOperation of MemoryOperationTrait { let value: u256 = self.stack.pop()?; let memory_expansion = gas::memory_expansion(self.memory.size(), [(offset, 32)].span())?; self.memory.ensure_length(memory_expansion.new_size); - self.charge_gas(gas::VERYLOW + memory_expansion.expansion_cost)?; + let total_cost = gas::VERYLOW + .checked_add(memory_expansion.expansion_cost) + .ok_or(EVMError::OutOfGas)?; + self.charge_gas(total_cost)?; self.memory.store(value, offset); Result::Ok(()) @@ -74,7 +80,10 @@ pub impl MemoryOperation of MemoryOperationTrait { let memory_expansion = gas::memory_expansion(self.memory.size(), [(offset, 1)].span())?; self.memory.ensure_length(memory_expansion.new_size); - self.charge_gas(gas::VERYLOW + memory_expansion.expansion_cost)?; + let total_cost = gas::VERYLOW + .checked_add(memory_expansion.expansion_cost) + .ok_or(EVMError::OutOfGas)?; + self.charge_gas(total_cost)?; self.memory.store_byte(value, offset); @@ -294,8 +303,12 @@ pub impl MemoryOperation of MemoryOperationTrait { self.memory.size(), [(max(dest_offset, source_offset), size)].span() )?; self.memory.ensure_length(memory_expansion.new_size); - //TODO: handle add overflows - self.charge_gas(gas::VERYLOW + copy_gas_cost + memory_expansion.expansion_cost)?; + let total_cost = gas::VERYLOW + .checked_add(copy_gas_cost) + .ok_or(EVMError::OutOfGas)? + .checked_add(memory_expansion.expansion_cost) + .ok_or(EVMError::OutOfGas)?; + self.charge_gas(total_cost)?; if size == 0 { return Result::Ok(()); diff --git a/cairo/kakarot-ssj/crates/evm/src/instructions/sha3.cairo b/cairo/kakarot-ssj/crates/evm/src/instructions/sha3.cairo index 622abf23f..73b3d99b9 100644 --- a/cairo/kakarot-ssj/crates/evm/src/instructions/sha3.cairo +++ b/cairo/kakarot-ssj/crates/evm/src/instructions/sha3.cairo @@ -1,6 +1,7 @@ use core::cmp::min; //! SHA3. use core::keccak::{cairo_keccak}; +use core::num::traits::CheckedAdd; // Internal imports use crate::errors::EVMError; @@ -11,7 +12,6 @@ use crate::stack::StackTrait; use utils::helpers::bytes_32_words_size; use utils::traits::array::ArrayExtTrait; use utils::traits::integer::U256Trait; - #[generate_trait] pub impl Sha3Impl of Sha3Trait { /// SHA3 operation : Hashes n bytes in memory at a given offset in memory @@ -32,7 +32,12 @@ pub impl Sha3Impl of Sha3Trait { let word_gas_cost = gas::KECCAK256WORD * words_size; let memory_expansion = gas::memory_expansion(self.memory.size(), [(offset, size)].span())?; self.memory.ensure_length(memory_expansion.new_size); - self.charge_gas(gas::KECCAK256 + word_gas_cost + memory_expansion.expansion_cost)?; + let total_cost = gas::KECCAK256 + .checked_add(word_gas_cost) + .ok_or(EVMError::OutOfGas)? + .checked_add(memory_expansion.expansion_cost) + .ok_or(EVMError::OutOfGas)?; + self.charge_gas(total_cost)?; let mut to_hash: Array = Default::default(); diff --git a/cairo/kakarot-ssj/crates/evm/src/instructions/stop_and_arithmetic_operations.cairo b/cairo/kakarot-ssj/crates/evm/src/instructions/stop_and_arithmetic_operations.cairo index 9f302aee2..54b9da66b 100644 --- a/cairo/kakarot-ssj/crates/evm/src/instructions/stop_and_arithmetic_operations.cairo +++ b/cairo/kakarot-ssj/crates/evm/src/instructions/stop_and_arithmetic_operations.cairo @@ -1,6 +1,7 @@ //! Stop and Arithmetic Operations. use core::integer::{u512_safe_div_rem_by_u256}; use core::math::u256_mul_mod_n; +use core::num::traits::CheckedAdd; use core::num::traits::{OverflowingAdd, OverflowingMul, OverflowingSub}; use crate::errors::EVMError; use crate::gas; @@ -164,7 +165,6 @@ pub impl StopAndArithmeticOperations of StopAndArithmeticOperationsTrait { let result: u256 = match TryInto::>::try_into(n) { Option::Some(nonzero_n) => { - // This is more gas efficient than computing (a mod N) + (b mod N) mod N let sum = u256_wide_add(a, b); let (_, r) = u512_safe_div_rem_by_u256(sum, nonzero_n); r @@ -204,7 +204,10 @@ pub impl StopAndArithmeticOperations of StopAndArithmeticOperationsTrait { // Gas let bytes_used = exponent.bytes_used(); - self.charge_gas(gas::EXP + gas::EXP_GAS_PER_BYTE * bytes_used.into())?; + let total_cost = gas::EXP + .checked_add(gas::EXP_GAS_PER_BYTE * bytes_used.into()) + .ok_or(EVMError::OutOfGas)?; + self.charge_gas(total_cost)?; let result = base.wrapping_pow(exponent); @@ -238,6 +241,7 @@ pub impl StopAndArithmeticOperations of StopAndArithmeticOperationsTrait { let result = if b < 32 { let s = 8 * b + 7; + //TODO: use POW_2 table for optimization let two_pow_s = 2.pow(s); // Get v, the t-th bit of x. To do this we bitshift x by s bits to the right and apply a // mask to get the last bit. diff --git a/cairo/kakarot-ssj/crates/evm/src/instructions/system_operations.cairo b/cairo/kakarot-ssj/crates/evm/src/instructions/system_operations.cairo index 5511b6017..65b95d75d 100644 --- a/cairo/kakarot-ssj/crates/evm/src/instructions/system_operations.cairo +++ b/cairo/kakarot-ssj/crates/evm/src/instructions/system_operations.cairo @@ -66,7 +66,11 @@ pub impl SystemOperations of SystemOperationsTrait { memory_expansion.expansion_cost, access_gas_cost + transfer_gas_cost + create_gas_cost )?; - self.charge_gas(message_call_gas.cost + memory_expansion.expansion_cost)?; + let total_cost = message_call_gas + .cost + .checked_add(memory_expansion.expansion_cost) + .ok_or(EVMError::OutOfGas)?; + self.charge_gas(total_cost)?; // Only the transfer gas is left to charge. let read_only = self.message().read_only; @@ -213,7 +217,11 @@ pub impl SystemOperations of SystemOperationsTrait { let message_call_gas = gas::calculate_message_call_gas( 0, gas, self.gas_left(), memory_expansion.expansion_cost, access_gas_cost )?; - self.charge_gas(message_call_gas.cost + memory_expansion.expansion_cost)?; + let total_cost = message_call_gas + .cost + .checked_add(memory_expansion.expansion_cost) + .ok_or(EVMError::OutOfGas)?; + self.charge_gas(total_cost)?; self .generic_call( diff --git a/cairo/kakarot-ssj/crates/evm/src/interpreter.cairo b/cairo/kakarot-ssj/crates/evm/src/interpreter.cairo index ccf14cda7..793f0eef9 100644 --- a/cairo/kakarot-ssj/crates/evm/src/interpreter.cairo +++ b/cairo/kakarot-ssj/crates/evm/src/interpreter.cairo @@ -1,6 +1,6 @@ use contracts::kakarot_core::KakarotCore; use contracts::kakarot_core::interface::IKakarotCore; -use core::num::traits::{Bounded, Zero}; +use core::num::traits::Zero; use core::ops::SnapshotDeref; use core::starknet::EthAddress; use core::starknet::storage::{StoragePointerReadAccess}; diff --git a/cairo/kakarot-ssj/crates/evm/src/precompiles/identity.cairo b/cairo/kakarot-ssj/crates/evm/src/precompiles/identity.cairo index 7bd38806e..e84ceaf80 100644 --- a/cairo/kakarot-ssj/crates/evm/src/precompiles/identity.cairo +++ b/cairo/kakarot-ssj/crates/evm/src/precompiles/identity.cairo @@ -1,6 +1,7 @@ use core::starknet::EthAddress; use crate::errors::EVMError; use crate::precompiles::Precompile; +use utils::helpers::bytes_32_words_size; const BASE_COST: u64 = 15; const COST_PER_WORD: u64 = 3; @@ -12,8 +13,8 @@ pub impl Identity of Precompile { } fn exec(input: Span) -> Result<(u64, Span), EVMError> { - let data_word_size = ((input.len() + 31) / 32).into(); - let gas = BASE_COST + data_word_size * COST_PER_WORD; + let data_word_size = bytes_32_words_size(input.len()); + let gas = BASE_COST + data_word_size.into() * COST_PER_WORD; return Result::Ok((gas, input)); } diff --git a/cairo/kakarot-ssj/crates/evm/src/precompiles/p256verify.cairo b/cairo/kakarot-ssj/crates/evm/src/precompiles/p256verify.cairo index fd5efe49f..f0bbc4948 100644 --- a/cairo/kakarot-ssj/crates/evm/src/precompiles/p256verify.cairo +++ b/cairo/kakarot-ssj/crates/evm/src/precompiles/p256verify.cairo @@ -57,35 +57,11 @@ pub impl P256Verify of Precompile { return Result::Ok((gas, [].span())); } - let message_hash = input.slice(0, 32); - let message_hash = match message_hash.from_be_bytes() { - Option::Some(message_hash) => message_hash, - Option::None => { return Result::Ok((gas, [].span())); } - }; - - let r: Option = input.slice(32, 32).from_be_bytes(); - let r = match r { - Option::Some(r) => r, - Option::None => { return Result::Ok((gas, [].span())); } - }; - - let s: Option = input.slice(64, 32).from_be_bytes(); - let s = match s { - Option::Some(s) => s, - Option::None => { return Result::Ok((gas, [].span())); } - }; - - let x: Option = input.slice(96, 32).from_be_bytes(); - let x = match x { - Option::Some(x) => x, - Option::None => { return Result::Ok((gas, [].span())); } - }; - - let y: Option = input.slice(128, 32).from_be_bytes(); - let y = match y { - Option::Some(y) => y, - Option::None => { return Result::Ok((gas, [].span())); } - }; + let message_hash: u256 = input.slice(0, 32).from_be_bytes().unwrap(); + let r: u256 = input.slice(32, 32).from_be_bytes().unwrap(); + let s: u256 = input.slice(64, 32).from_be_bytes().unwrap(); + let x: u256 = input.slice(96, 32).from_be_bytes().unwrap(); + let y: u256 = input.slice(128, 32).from_be_bytes().unwrap(); let public_key: Option = Secp256Trait::secp256_ec_new_syscall(x, y) .unwrap_syscall(); diff --git a/cairo/kakarot-ssj/crates/evm/src/precompiles/sha256.cairo b/cairo/kakarot-ssj/crates/evm/src/precompiles/sha256.cairo index af9174531..60be11a69 100644 --- a/cairo/kakarot-ssj/crates/evm/src/precompiles/sha256.cairo +++ b/cairo/kakarot-ssj/crates/evm/src/precompiles/sha256.cairo @@ -2,6 +2,7 @@ use core::sha256::compute_sha256_u32_array; use core::starknet::EthAddress; use crate::errors::EVMError; use crate::precompiles::Precompile; +use utils::helpers::bytes_32_words_size; use utils::math::Bitshift; use utils::traits::bytes::{FromBytes, ToBytes}; @@ -15,8 +16,8 @@ pub impl Sha256 of Precompile { } fn exec(mut input: Span) -> Result<(u64, Span), EVMError> { - let data_word_size = ((input.len() + 31) / 32).into(); - let gas = BASE_COST + data_word_size * COST_PER_WORD; + let data_word_size = bytes_32_words_size(input.len()); + let gas = BASE_COST + data_word_size.into() * COST_PER_WORD; let mut sha256_input: Array = array![]; while let Option::Some(bytes4) = input.multi_pop_front::<4>() { diff --git a/cairo/kakarot-ssj/crates/utils/src/helpers.cairo b/cairo/kakarot-ssj/crates/utils/src/helpers.cairo index 94e99eafd..0c84cb933 100644 --- a/cairo/kakarot-ssj/crates/utils/src/helpers.cairo +++ b/cairo/kakarot-ssj/crates/utils/src/helpers.cairo @@ -8,11 +8,8 @@ use core::panic_with_felt252; use core::pedersen::PedersenTrait; use core::starknet::{EthAddress, ContractAddress, ClassHash}; use core::traits::TryInto; -use core::traits::{DivRem}; use crate::constants::{CONTRACT_ADDRESS_PREFIX, MAX_ADDRESS}; use crate::constants::{POW_2, POW_256_1, POW_256_REV}; -use crate::math::{Bitshift, WrappingBitshift}; - use crate::traits::array::{ArrayExtTrait}; use crate::traits::{U256TryIntoContractAddress, EthAddressIntoU256, BoolIntoNumeric}; From dd433be59dcdb7c88a112f623d290625ee6c8f47 Mon Sep 17 00:00:00 2001 From: Oba Date: Wed, 2 Oct 2024 15:57:20 +0200 Subject: [PATCH 34/56] ci: sparse checkout --- .github/workflows/ssj-ef-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ssj-ef-tests.yml b/.github/workflows/ssj-ef-tests.yml index 7a270d5c3..2814f2c7d 100644 --- a/.github/workflows/ssj-ef-tests.yml +++ b/.github/workflows/ssj-ef-tests.yml @@ -61,7 +61,7 @@ jobs: uses: actions/checkout@v4 with: sparse-checkout: | - ./cairo/kakarot-ssj/blockchain-tests-skip.yml + cairo/kakarot-ssj/ sparse-checkout-cone-mode: false path: skip-file From 54c4f02fc33b1e41bb6321245f468f9119bedc76 Mon Sep 17 00:00:00 2001 From: Oba Date: Wed, 2 Oct 2024 16:41:46 +0200 Subject: [PATCH 35/56] fix: add missing mandatory fields --- cairo/kakarot-ssj/blockchain-tests-skip.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/cairo/kakarot-ssj/blockchain-tests-skip.yml b/cairo/kakarot-ssj/blockchain-tests-skip.yml index 564479755..9d145f2fb 100644 --- a/cairo/kakarot-ssj/blockchain-tests-skip.yml +++ b/cairo/kakarot-ssj/blockchain-tests-skip.yml @@ -1,3 +1,12 @@ +# List of test directories to completely skip +# trunk-ignore(yamllint/empty-values) +directories: + +# List of file names to be skipped +# The first level corresponds to the directory, the second to the list of file names to ignore. +# trunk-ignore(yamllint/empty-values) +filename: + testname: stEIP1153-transientStorage: - transStorageOK_d3g0v0_Cancun From fbcc5c57110060ee96518ca5e26a693f18ce2132 Mon Sep 17 00:00:00 2001 From: Oba Date: Wed, 2 Oct 2024 22:54:09 +0200 Subject: [PATCH 36/56] fix: add missing mandatory fields --- cairo/kakarot-ssj/blockchain-tests-skip.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cairo/kakarot-ssj/blockchain-tests-skip.yml b/cairo/kakarot-ssj/blockchain-tests-skip.yml index 9d145f2fb..3587bde25 100644 --- a/cairo/kakarot-ssj/blockchain-tests-skip.yml +++ b/cairo/kakarot-ssj/blockchain-tests-skip.yml @@ -7,6 +7,10 @@ directories: # trunk-ignore(yamllint/empty-values) filename: +# Keeping some skipped tests because of a probable memory leak somewhere +# causing cargo test to just crash at some point +regex: + testname: stEIP1153-transientStorage: - transStorageOK_d3g0v0_Cancun From e6a2dd012f3cfdd4a60d96a016af1bec2f18fd82 Mon Sep 17 00:00:00 2001 From: Oba Date: Thu, 3 Oct 2024 08:57:42 +0200 Subject: [PATCH 37/56] fix: add missing mandatory fields --- cairo/kakarot-ssj/blockchain-tests-skip.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cairo/kakarot-ssj/blockchain-tests-skip.yml b/cairo/kakarot-ssj/blockchain-tests-skip.yml index 3587bde25..a7e2c2ff0 100644 --- a/cairo/kakarot-ssj/blockchain-tests-skip.yml +++ b/cairo/kakarot-ssj/blockchain-tests-skip.yml @@ -10,6 +10,14 @@ filename: # Keeping some skipped tests because of a probable memory leak somewhere # causing cargo test to just crash at some point regex: + eip4895_withdrawals: + - .* + eip4844_blobs: + - .* + eip4788_beacon_root: + - .* + stEIP4844-blobtransactions: + - .* testname: stEIP1153-transientStorage: From b48c7ed0d434894ecf9ea86420f1914eb2f6b125 Mon Sep 17 00:00:00 2001 From: Oba Date: Thu, 3 Oct 2024 09:46:33 +0200 Subject: [PATCH 38/56] chore: merge .env.example --- .env.example | 4 ++++ cairo/kakarot-ssj/.env.example | 5 ----- cairo/kakarot-ssj/scripts/compute_rlp_encoding.ts | 6 +++--- 3 files changed, 7 insertions(+), 8 deletions(-) delete mode 100644 cairo/kakarot-ssj/.env.example diff --git a/.env.example b/.env.example index 9381ce47e..80cc4030d 100644 --- a/.env.example +++ b/.env.example @@ -52,3 +52,7 @@ HYPOTHESIS_PROFILE=dev VOYAGER_API_URL= VOYAGER_API_KEY= + +# Private key to sign transactions for RLP scripts/compute_rlp_encoding.ts +# Warning: Do not use this key in production systems +PRIVATE_KEY_RLP_SCRIPT=0x6be0067ba259624aa28f796b703e7d095925a470b17786767bd09aaa3fc2ceea diff --git a/cairo/kakarot-ssj/.env.example b/cairo/kakarot-ssj/.env.example deleted file mode 100644 index 0cf3d0a25..000000000 --- a/cairo/kakarot-ssj/.env.example +++ /dev/null @@ -1,5 +0,0 @@ -# A Github token to download the CI artifacts -GITHUB_TOKEN= -# Private key to sign transactions for RLP scripts/compute_rlp_encoding.ts -# Warning: Do not use this key in production systems -PRIVATE_KEY=0x6be0067ba259624aa28f796b703e7d095925a470b17786767bd09aaa3fc2ceea diff --git a/cairo/kakarot-ssj/scripts/compute_rlp_encoding.ts b/cairo/kakarot-ssj/scripts/compute_rlp_encoding.ts index 692922397..a556f0b33 100644 --- a/cairo/kakarot-ssj/scripts/compute_rlp_encoding.ts +++ b/cairo/kakarot-ssj/scripts/compute_rlp_encoding.ts @@ -24,14 +24,14 @@ const main = async () => { const { Transaction, Wallet } = ethers; const { decodeRlp, getBytes } = ethers; - if (!process.env.PRIVATE_KEY) { + if (!process.env.PRIVATE_KEY_RLP_SCRIPT) { console.log( - "missing private key in environment, please provide PRIVATE_KEY environment variable", + "missing private key in environment, please provide PRIVATE_KEY_RLP_SCRIPT environment variable", ); process.exit(1); } - const wallet = new Wallet(process.env.PRIVATE_KEY); + const wallet = new Wallet(process.env.PRIVATE_KEY_RLP_SCRIPT); console.log("address of the wallet is", wallet.address); let tx_type = parseInt( From e0a216fd5a0a6caa93ed37039cb622eeac704c55 Mon Sep 17 00:00:00 2001 From: Oba Date: Thu, 3 Oct 2024 10:14:38 +0200 Subject: [PATCH 39/56] chore: merge .gitignore --- .gitignore | 9 +++++++++ cairo/kakarot-ssj/.gitignore | 10 ---------- 2 files changed, 9 insertions(+), 10 deletions(-) delete mode 100644 cairo/kakarot-ssj/.gitignore diff --git a/.gitignore b/.gitignore index 9dd674473..9669a74f8 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,12 @@ profile*.png *.memory *.air_private_input.json *.air_public_input.json + +cairo/kakarot-ssj/.DS_Store +cairo/kakarot-ssj/.idea/ +cairo/kakarot-ssj/node_modules/ +cairo/kakarot-ssj/*.snfoundry_cache +cairo/kakarot-ssj/target +cairo/kakarot-ssj/cache/ +cairo/kakarot-ssj/scripts/libcairo_native_runtime.a +cairo/kakarot-ssj/scripts/__pycache__ diff --git a/cairo/kakarot-ssj/.gitignore b/cairo/kakarot-ssj/.gitignore deleted file mode 100644 index 1fa41de69..000000000 --- a/cairo/kakarot-ssj/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -.DS_Store -.env -target -.idea/ -node_modules/ -*.snfoundry_cache -cache/ - -scripts/libcairo_native_runtime.a -scripts/__pycache__ From 20e337ecede2da34476cc71ef6aa5593d0bac56b Mon Sep 17 00:00:00 2001 From: Oba Date: Thu, 3 Oct 2024 10:20:23 +0200 Subject: [PATCH 40/56] chore: remove unecessary rust-toolchain --- cairo/kakarot-ssj/rust-toolchain | 1 - 1 file changed, 1 deletion(-) delete mode 100644 cairo/kakarot-ssj/rust-toolchain diff --git a/cairo/kakarot-ssj/rust-toolchain b/cairo/kakarot-ssj/rust-toolchain deleted file mode 100644 index dbd41264a..000000000 --- a/cairo/kakarot-ssj/rust-toolchain +++ /dev/null @@ -1 +0,0 @@ -1.81.0 From c0792f5b653f5fc06a3af8b7ad166ebd197ab424 Mon Sep 17 00:00:00 2001 From: Oba Date: Thu, 3 Oct 2024 10:38:36 +0200 Subject: [PATCH 41/56] chore: remove unecessary files ssj --- .codespellignore | 1 + .../.markdownlint.json => .markdownlint.json | 0 .../.prettierrc.json => .prettierrc.json | 0 cairo/kakarot-ssj/.codespellrc | 2 - cairo/kakarot-ssj/.trunk/.gitignore | 9 --- .../2024-10-03-08-37-51.653.yaml | 14 ++++ cairo/kakarot-ssj/.trunk/configs/.isort.cfg | 2 - .../kakarot-ssj/.trunk/configs/.shellcheckrc | 7 -- .../kakarot-ssj/.trunk/configs/.yamllint.yaml | 10 --- cairo/kakarot-ssj/.trunk/configs/ruff.toml | 5 -- cairo/kakarot-ssj/.trunk/trunk.yaml | 74 ------------------- cairo/kakarot-ssj/LICENSE | 21 ------ cairo/kakarot-ssj/scripts/filter_tests.py | 4 + 13 files changed, 19 insertions(+), 130 deletions(-) rename cairo/kakarot-ssj/.markdownlint.json => .markdownlint.json (100%) rename cairo/kakarot-ssj/.prettierrc.json => .prettierrc.json (100%) delete mode 100644 cairo/kakarot-ssj/.codespellrc delete mode 100644 cairo/kakarot-ssj/.trunk/.gitignore create mode 100644 cairo/kakarot-ssj/.trunk/actions/trunk-single-player-auto-on-upgrade/2024-10-03-08-37-51.653.yaml delete mode 100644 cairo/kakarot-ssj/.trunk/configs/.isort.cfg delete mode 100644 cairo/kakarot-ssj/.trunk/configs/.shellcheckrc delete mode 100644 cairo/kakarot-ssj/.trunk/configs/.yamllint.yaml delete mode 100644 cairo/kakarot-ssj/.trunk/configs/ruff.toml delete mode 100644 cairo/kakarot-ssj/.trunk/trunk.yaml delete mode 100644 cairo/kakarot-ssj/LICENSE diff --git a/.codespellignore b/.codespellignore index 75829846c..b044176f4 100644 --- a/.codespellignore +++ b/.codespellignore @@ -1,3 +1,4 @@ keypair astroid uvloop +crate diff --git a/cairo/kakarot-ssj/.markdownlint.json b/.markdownlint.json similarity index 100% rename from cairo/kakarot-ssj/.markdownlint.json rename to .markdownlint.json diff --git a/cairo/kakarot-ssj/.prettierrc.json b/.prettierrc.json similarity index 100% rename from cairo/kakarot-ssj/.prettierrc.json rename to .prettierrc.json diff --git a/cairo/kakarot-ssj/.codespellrc b/cairo/kakarot-ssj/.codespellrc deleted file mode 100644 index 8511d3f6f..000000000 --- a/cairo/kakarot-ssj/.codespellrc +++ /dev/null @@ -1,2 +0,0 @@ -[codespell] -ignore-words-list = crate diff --git a/cairo/kakarot-ssj/.trunk/.gitignore b/cairo/kakarot-ssj/.trunk/.gitignore deleted file mode 100644 index 15966d087..000000000 --- a/cairo/kakarot-ssj/.trunk/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -*out -*logs -*actions -*notifications -*tools -plugins -user_trunk.yaml -user.yaml -tmp diff --git a/cairo/kakarot-ssj/.trunk/actions/trunk-single-player-auto-on-upgrade/2024-10-03-08-37-51.653.yaml b/cairo/kakarot-ssj/.trunk/actions/trunk-single-player-auto-on-upgrade/2024-10-03-08-37-51.653.yaml new file mode 100644 index 000000000..425240302 --- /dev/null +++ b/cairo/kakarot-ssj/.trunk/actions/trunk-single-player-auto-on-upgrade/2024-10-03-08-37-51.653.yaml @@ -0,0 +1,14 @@ +action_id: trunk-single-player-auto-on-upgrade +date: 2024-10-03 08:37:51 +run: trunk on-upgrade --single-player-only -n --no-progress --allow-daemon-start=false --print-summary --scope=check,plugins,runtimes,tools +run_from: "" +trigger: schedule 24h+5m +result: + exit_code: 0 + out: "" + err: "" +timestamp: 1727944671 +full_timestamp: + nanos: 653699000 + seconds: 1727944671 +trunk_version: 1.22.4 diff --git a/cairo/kakarot-ssj/.trunk/configs/.isort.cfg b/cairo/kakarot-ssj/.trunk/configs/.isort.cfg deleted file mode 100644 index b9fb3f3e8..000000000 --- a/cairo/kakarot-ssj/.trunk/configs/.isort.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[settings] -profile=black diff --git a/cairo/kakarot-ssj/.trunk/configs/.shellcheckrc b/cairo/kakarot-ssj/.trunk/configs/.shellcheckrc deleted file mode 100644 index 8c7b1ada8..000000000 --- a/cairo/kakarot-ssj/.trunk/configs/.shellcheckrc +++ /dev/null @@ -1,7 +0,0 @@ -enable=all -source-path=SCRIPTDIR -disable=SC2154 - -# If you're having issues with shellcheck following source, disable the errors via: -# disable=SC1090 -# disable=SC1091 diff --git a/cairo/kakarot-ssj/.trunk/configs/.yamllint.yaml b/cairo/kakarot-ssj/.trunk/configs/.yamllint.yaml deleted file mode 100644 index 4d444662d..000000000 --- a/cairo/kakarot-ssj/.trunk/configs/.yamllint.yaml +++ /dev/null @@ -1,10 +0,0 @@ -rules: - quoted-strings: - required: only-when-needed - extra-allowed: ["{|}"] - empty-values: - forbid-in-block-mappings: true - forbid-in-flow-mappings: true - key-duplicates: {} - octal-values: - forbid-implicit-octal: true diff --git a/cairo/kakarot-ssj/.trunk/configs/ruff.toml b/cairo/kakarot-ssj/.trunk/configs/ruff.toml deleted file mode 100644 index 346b1d9aa..000000000 --- a/cairo/kakarot-ssj/.trunk/configs/ruff.toml +++ /dev/null @@ -1,5 +0,0 @@ -# Generic, formatter-friendly config. -select = ["B", "D3", "D4", "E", "F"] - -# Never enforce `E501` (line length violations). This should be handled by formatters. -ignore = ["E501"] diff --git a/cairo/kakarot-ssj/.trunk/trunk.yaml b/cairo/kakarot-ssj/.trunk/trunk.yaml deleted file mode 100644 index 420b66299..000000000 --- a/cairo/kakarot-ssj/.trunk/trunk.yaml +++ /dev/null @@ -1,74 +0,0 @@ -# This file controls the behavior of Trunk: https://docs.trunk.io/cli -# To learn more about the format of this file, see https://docs.trunk.io/reference/trunk-yaml -version: 0.1 -cli: - version: 1.19.0 -plugins: - sources: - - id: trunk - ref: v1.4.2 - uri: https://github.com/trunk-io/plugins -runtimes: - enabled: - - go@1.21.0 - - node@18.12.1 - - python@3.10.8 -lint: - files: - - name: cairo - extensions: - - cairo - - name: solidity - extensions: - - sol - definitions: - # - name: cairo - # files: [cairo] - # commands: - # - output: rewrite - # success_codes: [1] - # formatter: true - # run: scarb fmt -e stdout - # read_output_from: stdout - # run_linter_from: workspace - - name: solidity - files: [solidity] - commands: - - output: rewrite - success_codes: [0, 1] - formatter: true - run: forge fmt ${target} --check -r - read_output_from: stdout - run_linter_from: workspace - enabled: - - osv-scanner@1.6.2 - - trivy@0.49.0 - # DISABLED: https://github.com/software-mansion/scarb/issues/1534 - # - cairo@SYSTEM - - solidity@SYSTEM - - actionlint@1.6.26 - - black@24.1.1 - - checkov@3.2.5 - - codespell@2.2.6 - - git-diff-check - - hadolint@2.12.0 - - isort@5.13.2 - - markdownlint@0.39.0 - - oxipng@9.0.0 - - prettier@3.2.5 - - ruff@0.2.1 - - shellcheck@0.9.0 - - shfmt@3.6.0 - - taplo@0.8.1 - - yamllint@1.33.0 - disabled: - - trufflehog - - bandit - - terrascan -actions: - disabled: - - trunk-announce - - trunk-fmt-pre-commit - enabled: - - trunk-check-pre-push - - trunk-upgrade-available diff --git a/cairo/kakarot-ssj/LICENSE b/cairo/kakarot-ssj/LICENSE deleted file mode 100644 index 92c70adad..000000000 --- a/cairo/kakarot-ssj/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2022, Abdelhamid Bakhta - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/cairo/kakarot-ssj/scripts/filter_tests.py b/cairo/kakarot-ssj/scripts/filter_tests.py index 7d514b79a..0463df14c 100644 --- a/cairo/kakarot-ssj/scripts/filter_tests.py +++ b/cairo/kakarot-ssj/scripts/filter_tests.py @@ -26,6 +26,10 @@ def filter_file(file_path, filter_string): def replace_func(match): full_match = match.group(0) func_name = match.group(1) + + + + if filter_string.lower() in func_name.lower(): return full_match else: From 8487351311c96d399763b55b4d283c408c06b905 Mon Sep 17 00:00:00 2001 From: Oba Date: Thu, 3 Oct 2024 10:44:05 +0200 Subject: [PATCH 42/56] style: trunk fmt --- .trunk/trunk.yaml | 5 +- .../2024-10-03-08-37-51.653.yaml | 14 - cairo/kakarot-ssj/blockchain-tests-skip.yml | 1216 ++++++++--------- cairo/kakarot-ssj/docs/CODE_OF_CONDUCT.md | 2 +- .../docs/general/account_state.png | Bin 132360 -> 131560 bytes cairo/kakarot-ssj/docs/general/volition.png | Bin 192376 -> 192120 bytes cairo/kakarot-ssj/scripts/compare_snapshot.py | 7 - cairo/kakarot-ssj/scripts/filter_tests.py | 3 - cairo/kakarot-ssj/scripts/gen_snapshot.py | 4 - 9 files changed, 613 insertions(+), 638 deletions(-) delete mode 100644 cairo/kakarot-ssj/.trunk/actions/trunk-single-player-auto-on-upgrade/2024-10-03-08-37-51.653.yaml diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index cbac54477..d9c32a905 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -75,7 +75,10 @@ lint: - tests/ef_tests/test_data - .katana/messaging_config.json - deployments - - cairo/** + - cairo/mock_pragma + - cairo/token + - cairo/utils + - cairo/kakarot-ssj/crates - linters: [solidity] paths: - solidity_contracts/src/UniswapV2/**/*.sol diff --git a/cairo/kakarot-ssj/.trunk/actions/trunk-single-player-auto-on-upgrade/2024-10-03-08-37-51.653.yaml b/cairo/kakarot-ssj/.trunk/actions/trunk-single-player-auto-on-upgrade/2024-10-03-08-37-51.653.yaml deleted file mode 100644 index 425240302..000000000 --- a/cairo/kakarot-ssj/.trunk/actions/trunk-single-player-auto-on-upgrade/2024-10-03-08-37-51.653.yaml +++ /dev/null @@ -1,14 +0,0 @@ -action_id: trunk-single-player-auto-on-upgrade -date: 2024-10-03 08:37:51 -run: trunk on-upgrade --single-player-only -n --no-progress --allow-daemon-start=false --print-summary --scope=check,plugins,runtimes,tools -run_from: "" -trigger: schedule 24h+5m -result: - exit_code: 0 - out: "" - err: "" -timestamp: 1727944671 -full_timestamp: - nanos: 653699000 - seconds: 1727944671 -trunk_version: 1.22.4 diff --git a/cairo/kakarot-ssj/blockchain-tests-skip.yml b/cairo/kakarot-ssj/blockchain-tests-skip.yml index a7e2c2ff0..4b69f227c 100644 --- a/cairo/kakarot-ssj/blockchain-tests-skip.yml +++ b/cairo/kakarot-ssj/blockchain-tests-skip.yml @@ -21,644 +21,644 @@ regex: testname: stEIP1153-transientStorage: - - transStorageOK_d3g0v0_Cancun + - transStorageOK_d3g0v0_Cancun eip198_modexp_precompile: - - modexp__fork_Cancun_minus_blockchain_test_minus_EIP_minus_198_minus_case3_minus_raw_minus_input_minus_out_minus_of_minus_gas + - modexp__fork_Cancun_minus_blockchain_test_minus_EIP_minus_198_minus_case3_minus_raw_minus_input_minus_out_minus_of_minus_gas initcode: - - contract_creating_tx__fork_Cancun_minus_blockchain_test_minus_over_limit_ones - - contract_creating_tx__fork_Cancun_minus_blockchain_test_minus_over_limit_zeros + - contract_creating_tx__fork_Cancun_minus_blockchain_test_minus_over_limit_ones + - contract_creating_tx__fork_Cancun_minus_blockchain_test_minus_over_limit_zeros stEIP3651-warmcoinbase: - - coinbaseWarmAccountCallGasFail_d0g0v0_Cancun + - coinbaseWarmAccountCallGasFail_d0g0v0_Cancun vmIOandFlowOperations: - - jump_d5g0v0_Cancun - - jumpi_d19g0v0_Cancun - - jumpi_d21g0v0_Cancun - - jumpi_d9g0v0_Cancun + - jump_d5g0v0_Cancun + - jumpi_d19g0v0_Cancun + - jumpi_d21g0v0_Cancun + - jumpi_d9g0v0_Cancun vmLogTest: - - log0_d0g0v0_Cancun - - log1_d0g0v0_Cancun - - log2_d0g0v0_Cancun - - log3_d0g0v0_Cancun - - log4_d0g0v0_Cancun + - log0_d0g0v0_Cancun + - log1_d0g0v0_Cancun + - log2_d0g0v0_Cancun + - log3_d0g0v0_Cancun + - log4_d0g0v0_Cancun vmPerformance: - - loopExp_d2g0v0_Cancun - - performanceTester_d0g0v0_Cancun - - performanceTester_d2g0v0_Cancun - - performanceTester_d3g0v0_Cancun + - loopExp_d2g0v0_Cancun + - performanceTester_d0g0v0_Cancun + - performanceTester_d2g0v0_Cancun + - performanceTester_d3g0v0_Cancun vmTests: - - blockInfo_d2g0v0_Cancun + - blockInfo_d2g0v0_Cancun stBadOpcode: - - invalidDiffPlaces_d34g0v0_Cancun - - opc0CDiffPlaces_d34g0v0_Cancun - - opc0DDiffPlaces_d34g0v0_Cancun - - opc0EDiffPlaces_d34g0v0_Cancun - - opc0FDiffPlaces_d34g0v0_Cancun - - opc1EDiffPlaces_d34g0v0_Cancun - - opc1FDiffPlaces_d34g0v0_Cancun - - opc21DiffPlaces_d34g0v0_Cancun - - opc22DiffPlaces_d34g0v0_Cancun - - opc23DiffPlaces_d34g0v0_Cancun - - opc24DiffPlaces_d34g0v0_Cancun - - opc25DiffPlaces_d34g0v0_Cancun - - opc26DiffPlaces_d34g0v0_Cancun - - opc27DiffPlaces_d34g0v0_Cancun - - opc28DiffPlaces_d34g0v0_Cancun - - opc29DiffPlaces_d34g0v0_Cancun - - opc2ADiffPlaces_d34g0v0_Cancun - - opc2BDiffPlaces_d34g0v0_Cancun - - opc2CDiffPlaces_d34g0v0_Cancun - - opc2DDiffPlaces_d34g0v0_Cancun - - opc2EDiffPlaces_d34g0v0_Cancun - - opc2FDiffPlaces_d34g0v0_Cancun - - opc49DiffPlaces_d34g0v0_Cancun - - opc4ADiffPlaces_d34g0v0_Cancun - - opc4BDiffPlaces_d34g0v0_Cancun - - opc4CDiffPlaces_d34g0v0_Cancun - - opc4DDiffPlaces_d34g0v0_Cancun - - opc4EDiffPlaces_d34g0v0_Cancun - - opc4FDiffPlaces_d34g0v0_Cancun - - opc5CDiffPlaces_d34g0v0_Cancun - - opc5DDiffPlaces_d34g0v0_Cancun - - opc5EDiffPlaces_d34g0v0_Cancun - - opc5FDiffPlaces_d34g0v0_Cancun - - opcA5DiffPlaces_d34g0v0_Cancun - - opcA6DiffPlaces_d34g0v0_Cancun - - opcA7DiffPlaces_d34g0v0_Cancun - - opcA8DiffPlaces_d34g0v0_Cancun - - opcA9DiffPlaces_d34g0v0_Cancun - - opcAADiffPlaces_d34g0v0_Cancun - - opcABDiffPlaces_d34g0v0_Cancun - - opcACDiffPlaces_d34g0v0_Cancun - - opcADDiffPlaces_d34g0v0_Cancun - - opcAEDiffPlaces_d34g0v0_Cancun - - opcAFDiffPlaces_d34g0v0_Cancun - - opcB0DiffPlaces_d34g0v0_Cancun - - opcB1DiffPlaces_d34g0v0_Cancun - - opcB2DiffPlaces_d34g0v0_Cancun - - opcB3DiffPlaces_d34g0v0_Cancun - - opcB4DiffPlaces_d34g0v0_Cancun - - opcB5DiffPlaces_d34g0v0_Cancun - - opcB6DiffPlaces_d34g0v0_Cancun - - opcB7DiffPlaces_d34g0v0_Cancun - - opcB8DiffPlaces_d34g0v0_Cancun - - opcB9DiffPlaces_d34g0v0_Cancun - - opcBADiffPlaces_d34g0v0_Cancun - - opcBBDiffPlaces_d34g0v0_Cancun - - opcBCDiffPlaces_d34g0v0_Cancun - - opcBDDiffPlaces_d34g0v0_Cancun - - opcBEDiffPlaces_d34g0v0_Cancun - - opcBFDiffPlaces_d34g0v0_Cancun - - opcC0DiffPlaces_d34g0v0_Cancun - - opcC1DiffPlaces_d34g0v0_Cancun - - opcC2DiffPlaces_d34g0v0_Cancun - - opcC3DiffPlaces_d34g0v0_Cancun - - opcC4DiffPlaces_d34g0v0_Cancun - - opcC5DiffPlaces_d34g0v0_Cancun - - opcC6DiffPlaces_d34g0v0_Cancun - - opcC7DiffPlaces_d34g0v0_Cancun - - opcC8DiffPlaces_d34g0v0_Cancun - - opcC9DiffPlaces_d34g0v0_Cancun - - opcCADiffPlaces_d34g0v0_Cancun - - opcCBDiffPlaces_d34g0v0_Cancun - - opcCCDiffPlaces_d34g0v0_Cancun - - opcCDDiffPlaces_d34g0v0_Cancun - - opcCEDiffPlaces_d34g0v0_Cancun - - opcCFDiffPlaces_d34g0v0_Cancun - - opcD0DiffPlaces_d34g0v0_Cancun - - opcD1DiffPlaces_d34g0v0_Cancun - - opcD2DiffPlaces_d34g0v0_Cancun - - opcD3DiffPlaces_d34g0v0_Cancun - - opcD4DiffPlaces_d34g0v0_Cancun - - opcD5DiffPlaces_d34g0v0_Cancun - - opcD6DiffPlaces_d34g0v0_Cancun - - opcD7DiffPlaces_d34g0v0_Cancun - - opcD8DiffPlaces_d34g0v0_Cancun - - opcD9DiffPlaces_d34g0v0_Cancun - - opcDADiffPlaces_d34g0v0_Cancun - - opcDBDiffPlaces_d34g0v0_Cancun - - opcDCDiffPlaces_d34g0v0_Cancun - - opcDDDiffPlaces_d34g0v0_Cancun - - opcDEDiffPlaces_d34g0v0_Cancun - - opcDFDiffPlaces_d34g0v0_Cancun - - opcE0DiffPlaces_d34g0v0_Cancun - - opcE1DiffPlaces_d34g0v0_Cancun - - opcE2DiffPlaces_d34g0v0_Cancun - - opcE3DiffPlaces_d34g0v0_Cancun - - opcE4DiffPlaces_d34g0v0_Cancun - - opcE5DiffPlaces_d34g0v0_Cancun - - opcE6DiffPlaces_d34g0v0_Cancun - - opcE7DiffPlaces_d34g0v0_Cancun - - opcE8DiffPlaces_d34g0v0_Cancun - - opcE9DiffPlaces_d34g0v0_Cancun - - opcEADiffPlaces_d34g0v0_Cancun - - opcEBDiffPlaces_d34g0v0_Cancun - - opcECDiffPlaces_d34g0v0_Cancun - - opcEDDiffPlaces_d34g0v0_Cancun - - opcEEDiffPlaces_d34g0v0_Cancun - - opcEFDiffPlaces_d34g0v0_Cancun - - opcF6DiffPlaces_d34g0v0_Cancun - - opcF7DiffPlaces_d34g0v0_Cancun - - opcF8DiffPlaces_d34g0v0_Cancun - - opcF9DiffPlaces_d34g0v0_Cancun - - opcFBDiffPlaces_d34g0v0_Cancun - - opcFCDiffPlaces_d34g0v0_Cancun - - opcFEDiffPlaces_d34g0v0_Cancun - - operationDiffGas_d0g0v0_Cancun - - operationDiffGas_d1g0v0_Cancun + - invalidDiffPlaces_d34g0v0_Cancun + - opc0CDiffPlaces_d34g0v0_Cancun + - opc0DDiffPlaces_d34g0v0_Cancun + - opc0EDiffPlaces_d34g0v0_Cancun + - opc0FDiffPlaces_d34g0v0_Cancun + - opc1EDiffPlaces_d34g0v0_Cancun + - opc1FDiffPlaces_d34g0v0_Cancun + - opc21DiffPlaces_d34g0v0_Cancun + - opc22DiffPlaces_d34g0v0_Cancun + - opc23DiffPlaces_d34g0v0_Cancun + - opc24DiffPlaces_d34g0v0_Cancun + - opc25DiffPlaces_d34g0v0_Cancun + - opc26DiffPlaces_d34g0v0_Cancun + - opc27DiffPlaces_d34g0v0_Cancun + - opc28DiffPlaces_d34g0v0_Cancun + - opc29DiffPlaces_d34g0v0_Cancun + - opc2ADiffPlaces_d34g0v0_Cancun + - opc2BDiffPlaces_d34g0v0_Cancun + - opc2CDiffPlaces_d34g0v0_Cancun + - opc2DDiffPlaces_d34g0v0_Cancun + - opc2EDiffPlaces_d34g0v0_Cancun + - opc2FDiffPlaces_d34g0v0_Cancun + - opc49DiffPlaces_d34g0v0_Cancun + - opc4ADiffPlaces_d34g0v0_Cancun + - opc4BDiffPlaces_d34g0v0_Cancun + - opc4CDiffPlaces_d34g0v0_Cancun + - opc4DDiffPlaces_d34g0v0_Cancun + - opc4EDiffPlaces_d34g0v0_Cancun + - opc4FDiffPlaces_d34g0v0_Cancun + - opc5CDiffPlaces_d34g0v0_Cancun + - opc5DDiffPlaces_d34g0v0_Cancun + - opc5EDiffPlaces_d34g0v0_Cancun + - opc5FDiffPlaces_d34g0v0_Cancun + - opcA5DiffPlaces_d34g0v0_Cancun + - opcA6DiffPlaces_d34g0v0_Cancun + - opcA7DiffPlaces_d34g0v0_Cancun + - opcA8DiffPlaces_d34g0v0_Cancun + - opcA9DiffPlaces_d34g0v0_Cancun + - opcAADiffPlaces_d34g0v0_Cancun + - opcABDiffPlaces_d34g0v0_Cancun + - opcACDiffPlaces_d34g0v0_Cancun + - opcADDiffPlaces_d34g0v0_Cancun + - opcAEDiffPlaces_d34g0v0_Cancun + - opcAFDiffPlaces_d34g0v0_Cancun + - opcB0DiffPlaces_d34g0v0_Cancun + - opcB1DiffPlaces_d34g0v0_Cancun + - opcB2DiffPlaces_d34g0v0_Cancun + - opcB3DiffPlaces_d34g0v0_Cancun + - opcB4DiffPlaces_d34g0v0_Cancun + - opcB5DiffPlaces_d34g0v0_Cancun + - opcB6DiffPlaces_d34g0v0_Cancun + - opcB7DiffPlaces_d34g0v0_Cancun + - opcB8DiffPlaces_d34g0v0_Cancun + - opcB9DiffPlaces_d34g0v0_Cancun + - opcBADiffPlaces_d34g0v0_Cancun + - opcBBDiffPlaces_d34g0v0_Cancun + - opcBCDiffPlaces_d34g0v0_Cancun + - opcBDDiffPlaces_d34g0v0_Cancun + - opcBEDiffPlaces_d34g0v0_Cancun + - opcBFDiffPlaces_d34g0v0_Cancun + - opcC0DiffPlaces_d34g0v0_Cancun + - opcC1DiffPlaces_d34g0v0_Cancun + - opcC2DiffPlaces_d34g0v0_Cancun + - opcC3DiffPlaces_d34g0v0_Cancun + - opcC4DiffPlaces_d34g0v0_Cancun + - opcC5DiffPlaces_d34g0v0_Cancun + - opcC6DiffPlaces_d34g0v0_Cancun + - opcC7DiffPlaces_d34g0v0_Cancun + - opcC8DiffPlaces_d34g0v0_Cancun + - opcC9DiffPlaces_d34g0v0_Cancun + - opcCADiffPlaces_d34g0v0_Cancun + - opcCBDiffPlaces_d34g0v0_Cancun + - opcCCDiffPlaces_d34g0v0_Cancun + - opcCDDiffPlaces_d34g0v0_Cancun + - opcCEDiffPlaces_d34g0v0_Cancun + - opcCFDiffPlaces_d34g0v0_Cancun + - opcD0DiffPlaces_d34g0v0_Cancun + - opcD1DiffPlaces_d34g0v0_Cancun + - opcD2DiffPlaces_d34g0v0_Cancun + - opcD3DiffPlaces_d34g0v0_Cancun + - opcD4DiffPlaces_d34g0v0_Cancun + - opcD5DiffPlaces_d34g0v0_Cancun + - opcD6DiffPlaces_d34g0v0_Cancun + - opcD7DiffPlaces_d34g0v0_Cancun + - opcD8DiffPlaces_d34g0v0_Cancun + - opcD9DiffPlaces_d34g0v0_Cancun + - opcDADiffPlaces_d34g0v0_Cancun + - opcDBDiffPlaces_d34g0v0_Cancun + - opcDCDiffPlaces_d34g0v0_Cancun + - opcDDDiffPlaces_d34g0v0_Cancun + - opcDEDiffPlaces_d34g0v0_Cancun + - opcDFDiffPlaces_d34g0v0_Cancun + - opcE0DiffPlaces_d34g0v0_Cancun + - opcE1DiffPlaces_d34g0v0_Cancun + - opcE2DiffPlaces_d34g0v0_Cancun + - opcE3DiffPlaces_d34g0v0_Cancun + - opcE4DiffPlaces_d34g0v0_Cancun + - opcE5DiffPlaces_d34g0v0_Cancun + - opcE6DiffPlaces_d34g0v0_Cancun + - opcE7DiffPlaces_d34g0v0_Cancun + - opcE8DiffPlaces_d34g0v0_Cancun + - opcE9DiffPlaces_d34g0v0_Cancun + - opcEADiffPlaces_d34g0v0_Cancun + - opcEBDiffPlaces_d34g0v0_Cancun + - opcECDiffPlaces_d34g0v0_Cancun + - opcEDDiffPlaces_d34g0v0_Cancun + - opcEEDiffPlaces_d34g0v0_Cancun + - opcEFDiffPlaces_d34g0v0_Cancun + - opcF6DiffPlaces_d34g0v0_Cancun + - opcF7DiffPlaces_d34g0v0_Cancun + - opcF8DiffPlaces_d34g0v0_Cancun + - opcF9DiffPlaces_d34g0v0_Cancun + - opcFBDiffPlaces_d34g0v0_Cancun + - opcFCDiffPlaces_d34g0v0_Cancun + - opcFEDiffPlaces_d34g0v0_Cancun + - operationDiffGas_d0g0v0_Cancun + - operationDiffGas_d1g0v0_Cancun stEIP3860-limitmeterinitcode: - - creationTxInitCodeSizeLimit_d1g0v0_Cancun + - creationTxInitCodeSizeLimit_d1g0v0_Cancun stCallCreateCallCodeTest: - - Call1024BalanceTooLow_d0g0v0_Cancun - - CallRecursiveBombPreCall_d0g0v0_Cancun - - Callcode1024BalanceTooLow_d0g0v0_Cancun - - createInitFailStackSizeLargerThan1024_d0g0v0_Cancun + - Call1024BalanceTooLow_d0g0v0_Cancun + - CallRecursiveBombPreCall_d0g0v0_Cancun + - Callcode1024BalanceTooLow_d0g0v0_Cancun + - createInitFailStackSizeLargerThan1024_d0g0v0_Cancun stCreate2: - - Create2OnDepth1023_d0g0v0_Cancun - - Create2OnDepth1024_d0g0v0_Cancun - - create2callPrecompiles_d2g0v0_Cancun + - Create2OnDepth1023_d0g0v0_Cancun + - Create2OnDepth1024_d0g0v0_Cancun + - create2callPrecompiles_d2g0v0_Cancun stCreateTest: - - CreateOOGafterMaxCodesize_d2g0v0_Cancun + - CreateOOGafterMaxCodesize_d2g0v0_Cancun stEIP150Specific: - - Transaction64Rule_integerBoundaries_d0g0v0_Cancun - - Transaction64Rule_integerBoundaries_d10g0v0_Cancun - - Transaction64Rule_integerBoundaries_d11g0v0_Cancun - - Transaction64Rule_integerBoundaries_d1g0v0_Cancun - - Transaction64Rule_integerBoundaries_d2g0v0_Cancun - - Transaction64Rule_integerBoundaries_d3g0v0_Cancun - - Transaction64Rule_integerBoundaries_d4g0v0_Cancun - - Transaction64Rule_integerBoundaries_d5g0v0_Cancun - - Transaction64Rule_integerBoundaries_d6g0v0_Cancun - - Transaction64Rule_integerBoundaries_d7g0v0_Cancun - - Transaction64Rule_integerBoundaries_d8g0v0_Cancun - - Transaction64Rule_integerBoundaries_d9g0v0_Cancun + - Transaction64Rule_integerBoundaries_d0g0v0_Cancun + - Transaction64Rule_integerBoundaries_d10g0v0_Cancun + - Transaction64Rule_integerBoundaries_d11g0v0_Cancun + - Transaction64Rule_integerBoundaries_d1g0v0_Cancun + - Transaction64Rule_integerBoundaries_d2g0v0_Cancun + - Transaction64Rule_integerBoundaries_d3g0v0_Cancun + - Transaction64Rule_integerBoundaries_d4g0v0_Cancun + - Transaction64Rule_integerBoundaries_d5g0v0_Cancun + - Transaction64Rule_integerBoundaries_d6g0v0_Cancun + - Transaction64Rule_integerBoundaries_d7g0v0_Cancun + - Transaction64Rule_integerBoundaries_d8g0v0_Cancun + - Transaction64Rule_integerBoundaries_d9g0v0_Cancun stDelegatecallTestHomestead: - - Call1024BalanceTooLow_d0g0v0_Cancun - - CallRecursiveBombPreCall_d0g0v0_Cancun - - Delegatecall1024_d0g0v0_Cancun + - Call1024BalanceTooLow_d0g0v0_Cancun + - CallRecursiveBombPreCall_d0g0v0_Cancun + - Delegatecall1024_d0g0v0_Cancun stEIP150singleCodeGasPrices: - - gasCostJump_d0g0v0_Cancun - - gasCostJump_d1g0v0_Cancun - - gasCostJump_d2g0v0_Cancun - - gasCostReturn_d0g0v0_Cancun + - gasCostJump_d0g0v0_Cancun + - gasCostJump_d1g0v0_Cancun + - gasCostJump_d2g0v0_Cancun + - gasCostReturn_d0g0v0_Cancun stEIP1559: - - baseFeeDiffPlaces_d34g0v0_Cancun - - gasPriceDiffPlaces_d34g0v0_Cancun + - baseFeeDiffPlaces_d34g0v0_Cancun + - gasPriceDiffPlaces_d34g0v0_Cancun stExtCodeHash: - - extCodeHashDynamicArgument_d1g0v0_Cancun + - extCodeHashDynamicArgument_d1g0v0_Cancun stMemoryTest: - - stackLimitGas_1023_d0g0v0_Cancun - - stackLimitGas_1024_d0g0v0_Cancun - - stackLimitGas_1025_d0g0v0_Cancun - - stackLimitPush31_1023_d0g0v0_Cancun - - stackLimitPush31_1024_d0g0v0_Cancun - - stackLimitPush31_1025_d0g0v0_Cancun - - stackLimitPush32_1023_d0g0v0_Cancun - - stackLimitPush32_1024_d0g0v0_Cancun - - stackLimitPush32_1025_d0g0v0_Cancun + - stackLimitGas_1023_d0g0v0_Cancun + - stackLimitGas_1024_d0g0v0_Cancun + - stackLimitGas_1025_d0g0v0_Cancun + - stackLimitPush31_1023_d0g0v0_Cancun + - stackLimitPush31_1024_d0g0v0_Cancun + - stackLimitPush31_1025_d0g0v0_Cancun + - stackLimitPush32_1023_d0g0v0_Cancun + - stackLimitPush32_1024_d0g0v0_Cancun + - stackLimitPush32_1025_d0g0v0_Cancun stPreCompiledContracts2: - - CALLCODERipemd160_0_d0g0v0_Cancun - - CALLCODERipemd160_1_d0g0v0_Cancun - - CALLCODERipemd160_2_d0g0v0_Cancun - - CALLCODERipemd160_3_d0g0v0_Cancun - - CALLCODERipemd160_3_postfixed0_d0g0v0_Cancun - - CALLCODERipemd160_3_prefixed0_d0g0v0_Cancun - - CALLCODERipemd160_4_d0g0v0_Cancun - - CALLCODERipemd160_4_gas719_d0g0v0_Cancun - - CallRipemd160_0_d0g0v0_Cancun - - CallRipemd160_1_d0g0v0_Cancun - - CallRipemd160_2_d0g0v0_Cancun - - CallRipemd160_3_d0g0v0_Cancun - - CallRipemd160_3_postfixed0_d0g0v0_Cancun - - CallRipemd160_3_prefixed0_d0g0v0_Cancun - - CallRipemd160_4_d0g0v0_Cancun - - CallRipemd160_4_gas719_d0g0v0_Cancun - - ecrecoverShortBuff_d0g0v0_Cancun - - modexpRandomInput_d2g0v0_Cancun - - modexpRandomInput_d2g1v0_Cancun + - CALLCODERipemd160_0_d0g0v0_Cancun + - CALLCODERipemd160_1_d0g0v0_Cancun + - CALLCODERipemd160_2_d0g0v0_Cancun + - CALLCODERipemd160_3_d0g0v0_Cancun + - CALLCODERipemd160_3_postfixed0_d0g0v0_Cancun + - CALLCODERipemd160_3_prefixed0_d0g0v0_Cancun + - CALLCODERipemd160_4_d0g0v0_Cancun + - CALLCODERipemd160_4_gas719_d0g0v0_Cancun + - CallRipemd160_0_d0g0v0_Cancun + - CallRipemd160_1_d0g0v0_Cancun + - CallRipemd160_2_d0g0v0_Cancun + - CallRipemd160_3_d0g0v0_Cancun + - CallRipemd160_3_postfixed0_d0g0v0_Cancun + - CallRipemd160_3_prefixed0_d0g0v0_Cancun + - CallRipemd160_4_d0g0v0_Cancun + - CallRipemd160_4_gas719_d0g0v0_Cancun + - ecrecoverShortBuff_d0g0v0_Cancun + - modexpRandomInput_d2g0v0_Cancun + - modexpRandomInput_d2g1v0_Cancun stPreCompiledContracts: - - idPrecomps_d2g0v0_Cancun - - idPrecomps_d7g0v0_Cancun - - idPrecomps_d9g0v0_Cancun - - precompsEIP2929Cancun_d110g0v0_Cancun - - precompsEIP2929Cancun_d117g0v0_Cancun - - precompsEIP2929Cancun_d128g0v0_Cancun - - precompsEIP2929Cancun_d12g0v0_Cancun - - precompsEIP2929Cancun_d135g0v0_Cancun - - precompsEIP2929Cancun_d146g0v0_Cancun - - precompsEIP2929Cancun_d151g0v0_Cancun - - precompsEIP2929Cancun_d153g0v0_Cancun - - precompsEIP2929Cancun_d164g0v0_Cancun - - precompsEIP2929Cancun_d169g0v0_Cancun - - precompsEIP2929Cancun_d171g0v0_Cancun - - precompsEIP2929Cancun_d182g0v0_Cancun - - precompsEIP2929Cancun_d189g0v0_Cancun - - precompsEIP2929Cancun_d200g0v0_Cancun - - precompsEIP2929Cancun_d207g0v0_Cancun - - precompsEIP2929Cancun_d20g0v0_Cancun - - precompsEIP2929Cancun_d218g0v0_Cancun - - precompsEIP2929Cancun_d225g0v0_Cancun - - precompsEIP2929Cancun_d236g0v0_Cancun - - precompsEIP2929Cancun_d241g0v0_Cancun - - precompsEIP2929Cancun_d243g0v0_Cancun - - precompsEIP2929Cancun_d254g0v0_Cancun - - precompsEIP2929Cancun_d261g0v0_Cancun - - precompsEIP2929Cancun_d272g0v0_Cancun - - precompsEIP2929Cancun_d279g0v0_Cancun - - precompsEIP2929Cancun_d27g0v0_Cancun - - precompsEIP2929Cancun_d290g0v0_Cancun - - precompsEIP2929Cancun_d295g0v0_Cancun - - precompsEIP2929Cancun_d297g0v0_Cancun - - precompsEIP2929Cancun_d308g0v0_Cancun - - precompsEIP2929Cancun_d315g0v0_Cancun - - precompsEIP2929Cancun_d38g0v0_Cancun - - precompsEIP2929Cancun_d43g0v0_Cancun - - precompsEIP2929Cancun_d45g0v0_Cancun - - precompsEIP2929Cancun_d56g0v0_Cancun - - precompsEIP2929Cancun_d5g0v0_Cancun - - precompsEIP2929Cancun_d61g0v0_Cancun - - precompsEIP2929Cancun_d63g0v0_Cancun - - precompsEIP2929Cancun_d74g0v0_Cancun - - precompsEIP2929Cancun_d81g0v0_Cancun - - precompsEIP2929Cancun_d92g0v0_Cancun - - precompsEIP2929Cancun_d99g0v0_Cancun + - idPrecomps_d2g0v0_Cancun + - idPrecomps_d7g0v0_Cancun + - idPrecomps_d9g0v0_Cancun + - precompsEIP2929Cancun_d110g0v0_Cancun + - precompsEIP2929Cancun_d117g0v0_Cancun + - precompsEIP2929Cancun_d128g0v0_Cancun + - precompsEIP2929Cancun_d12g0v0_Cancun + - precompsEIP2929Cancun_d135g0v0_Cancun + - precompsEIP2929Cancun_d146g0v0_Cancun + - precompsEIP2929Cancun_d151g0v0_Cancun + - precompsEIP2929Cancun_d153g0v0_Cancun + - precompsEIP2929Cancun_d164g0v0_Cancun + - precompsEIP2929Cancun_d169g0v0_Cancun + - precompsEIP2929Cancun_d171g0v0_Cancun + - precompsEIP2929Cancun_d182g0v0_Cancun + - precompsEIP2929Cancun_d189g0v0_Cancun + - precompsEIP2929Cancun_d200g0v0_Cancun + - precompsEIP2929Cancun_d207g0v0_Cancun + - precompsEIP2929Cancun_d20g0v0_Cancun + - precompsEIP2929Cancun_d218g0v0_Cancun + - precompsEIP2929Cancun_d225g0v0_Cancun + - precompsEIP2929Cancun_d236g0v0_Cancun + - precompsEIP2929Cancun_d241g0v0_Cancun + - precompsEIP2929Cancun_d243g0v0_Cancun + - precompsEIP2929Cancun_d254g0v0_Cancun + - precompsEIP2929Cancun_d261g0v0_Cancun + - precompsEIP2929Cancun_d272g0v0_Cancun + - precompsEIP2929Cancun_d279g0v0_Cancun + - precompsEIP2929Cancun_d27g0v0_Cancun + - precompsEIP2929Cancun_d290g0v0_Cancun + - precompsEIP2929Cancun_d295g0v0_Cancun + - precompsEIP2929Cancun_d297g0v0_Cancun + - precompsEIP2929Cancun_d308g0v0_Cancun + - precompsEIP2929Cancun_d315g0v0_Cancun + - precompsEIP2929Cancun_d38g0v0_Cancun + - precompsEIP2929Cancun_d43g0v0_Cancun + - precompsEIP2929Cancun_d45g0v0_Cancun + - precompsEIP2929Cancun_d56g0v0_Cancun + - precompsEIP2929Cancun_d5g0v0_Cancun + - precompsEIP2929Cancun_d61g0v0_Cancun + - precompsEIP2929Cancun_d63g0v0_Cancun + - precompsEIP2929Cancun_d74g0v0_Cancun + - precompsEIP2929Cancun_d81g0v0_Cancun + - precompsEIP2929Cancun_d92g0v0_Cancun + - precompsEIP2929Cancun_d99g0v0_Cancun stQuadraticComplexityTest: - - Call20KbytesContract50_1_d0g0v0_Cancun - - Call20KbytesContract50_2_d0g0v0_Cancun - - Call20KbytesContract50_3_d0g0v0_Cancun - - Call20KbytesContract50_3_d0g1v0_Cancun + - Call20KbytesContract50_1_d0g0v0_Cancun + - Call20KbytesContract50_2_d0g0v0_Cancun + - Call20KbytesContract50_3_d0g0v0_Cancun + - Call20KbytesContract50_3_d0g1v0_Cancun stRandom2: - - randomStatetest415_d0g0v0_Cancun - - randomStatetest418_d0g0v0_Cancun - - randomStatetest433_d0g0v0_Cancun - - randomStatetest450_d0g0v0_Cancun - - randomStatetest458_d0g0v0_Cancun - - randomStatetest467_d0g0v0_Cancun - - randomStatetest469_d0g0v0_Cancun - - randomStatetest541_d0g0v0_Cancun - - randomStatetest547_d0g0v0_Cancun - - randomStatetest554_d0g0v0_Cancun - - randomStatetest560_d0g0v0_Cancun - - randomStatetest583_d0g0v0_Cancun - - randomStatetest636_d0g0v0_Cancun - - randomStatetest639_d0g0v0_Cancun - - randomStatetest645_d0g0v0_Cancun - - randomStatetest645_d0g0v1_Cancun + - randomStatetest415_d0g0v0_Cancun + - randomStatetest418_d0g0v0_Cancun + - randomStatetest433_d0g0v0_Cancun + - randomStatetest450_d0g0v0_Cancun + - randomStatetest458_d0g0v0_Cancun + - randomStatetest467_d0g0v0_Cancun + - randomStatetest469_d0g0v0_Cancun + - randomStatetest541_d0g0v0_Cancun + - randomStatetest547_d0g0v0_Cancun + - randomStatetest554_d0g0v0_Cancun + - randomStatetest560_d0g0v0_Cancun + - randomStatetest583_d0g0v0_Cancun + - randomStatetest636_d0g0v0_Cancun + - randomStatetest639_d0g0v0_Cancun + - randomStatetest645_d0g0v0_Cancun + - randomStatetest645_d0g0v1_Cancun stRandom: - - randomStatetest111_d0g0v0_Cancun - - randomStatetest124_d0g0v0_Cancun - - randomStatetest14_d0g0v0_Cancun - - randomStatetest150_d0g0v0_Cancun - - randomStatetest154_d0g0v0_Cancun - - randomStatetest178_d0g0v0_Cancun - - randomStatetest211_d0g0v0_Cancun - - randomStatetest260_d0g0v0_Cancun - - randomStatetest306_d0g0v0_Cancun - - randomStatetest308_d0g0v0_Cancun - - randomStatetest343_d0g0v0_Cancun + - randomStatetest111_d0g0v0_Cancun + - randomStatetest124_d0g0v0_Cancun + - randomStatetest14_d0g0v0_Cancun + - randomStatetest150_d0g0v0_Cancun + - randomStatetest154_d0g0v0_Cancun + - randomStatetest178_d0g0v0_Cancun + - randomStatetest211_d0g0v0_Cancun + - randomStatetest260_d0g0v0_Cancun + - randomStatetest306_d0g0v0_Cancun + - randomStatetest308_d0g0v0_Cancun + - randomStatetest343_d0g0v0_Cancun stReturnDataTest: - - modexp_modsize0_returndatasize_d4g0v0_Cancun - - revertRetDataSize_d0g0v0_Cancun - - revertRetDataSize_d10g0v0_Cancun - - revertRetDataSize_d11g0v0_Cancun - - revertRetDataSize_d12g0v0_Cancun - - revertRetDataSize_d13g0v0_Cancun - - revertRetDataSize_d14g0v0_Cancun - - revertRetDataSize_d15g0v0_Cancun - - revertRetDataSize_d16g0v0_Cancun - - revertRetDataSize_d17g0v0_Cancun - - revertRetDataSize_d18g0v0_Cancun - - revertRetDataSize_d19g0v0_Cancun - - revertRetDataSize_d1g0v0_Cancun - - revertRetDataSize_d20g0v0_Cancun - - revertRetDataSize_d21g0v0_Cancun - - revertRetDataSize_d22g0v0_Cancun - - revertRetDataSize_d23g0v0_Cancun - - revertRetDataSize_d24g0v0_Cancun - - revertRetDataSize_d25g0v0_Cancun - - revertRetDataSize_d26g0v0_Cancun - - revertRetDataSize_d27g0v0_Cancun - - revertRetDataSize_d28g0v0_Cancun - - revertRetDataSize_d29g0v0_Cancun - - revertRetDataSize_d2g0v0_Cancun - - revertRetDataSize_d30g0v0_Cancun - - revertRetDataSize_d31g0v0_Cancun - - revertRetDataSize_d32g0v0_Cancun - - revertRetDataSize_d33g0v0_Cancun - - revertRetDataSize_d34g0v0_Cancun - - revertRetDataSize_d35g0v0_Cancun - - revertRetDataSize_d3g0v0_Cancun - - revertRetDataSize_d4g0v0_Cancun - - revertRetDataSize_d5g0v0_Cancun - - revertRetDataSize_d6g0v0_Cancun - - revertRetDataSize_d7g0v0_Cancun - - revertRetDataSize_d8g0v0_Cancun - - revertRetDataSize_d9g0v0_Cancun + - modexp_modsize0_returndatasize_d4g0v0_Cancun + - revertRetDataSize_d0g0v0_Cancun + - revertRetDataSize_d10g0v0_Cancun + - revertRetDataSize_d11g0v0_Cancun + - revertRetDataSize_d12g0v0_Cancun + - revertRetDataSize_d13g0v0_Cancun + - revertRetDataSize_d14g0v0_Cancun + - revertRetDataSize_d15g0v0_Cancun + - revertRetDataSize_d16g0v0_Cancun + - revertRetDataSize_d17g0v0_Cancun + - revertRetDataSize_d18g0v0_Cancun + - revertRetDataSize_d19g0v0_Cancun + - revertRetDataSize_d1g0v0_Cancun + - revertRetDataSize_d20g0v0_Cancun + - revertRetDataSize_d21g0v0_Cancun + - revertRetDataSize_d22g0v0_Cancun + - revertRetDataSize_d23g0v0_Cancun + - revertRetDataSize_d24g0v0_Cancun + - revertRetDataSize_d25g0v0_Cancun + - revertRetDataSize_d26g0v0_Cancun + - revertRetDataSize_d27g0v0_Cancun + - revertRetDataSize_d28g0v0_Cancun + - revertRetDataSize_d29g0v0_Cancun + - revertRetDataSize_d2g0v0_Cancun + - revertRetDataSize_d30g0v0_Cancun + - revertRetDataSize_d31g0v0_Cancun + - revertRetDataSize_d32g0v0_Cancun + - revertRetDataSize_d33g0v0_Cancun + - revertRetDataSize_d34g0v0_Cancun + - revertRetDataSize_d35g0v0_Cancun + - revertRetDataSize_d3g0v0_Cancun + - revertRetDataSize_d4g0v0_Cancun + - revertRetDataSize_d5g0v0_Cancun + - revertRetDataSize_d6g0v0_Cancun + - revertRetDataSize_d7g0v0_Cancun + - revertRetDataSize_d8g0v0_Cancun + - revertRetDataSize_d9g0v0_Cancun stRevertTest: - - LoopCallsDepthThenRevert2_d0g0v0_Cancun - - LoopCallsDepthThenRevert3_d0g0v0_Cancun - - LoopCallsThenRevert_d0g0v0_Cancun - - RevertPrecompiledTouchExactOOG_Paris_d10g1v0_Cancun - - RevertPrecompiledTouchExactOOG_Paris_d10g2v0_Cancun - - RevertPrecompiledTouchExactOOG_Paris_d15g2v0_Cancun - - RevertPrecompiledTouchExactOOG_Paris_d18g1v0_Cancun - - RevertPrecompiledTouchExactOOG_Paris_d18g2v0_Cancun - - RevertPrecompiledTouchExactOOG_Paris_d23g2v0_Cancun - - RevertPrecompiledTouchExactOOG_Paris_d26g1v0_Cancun - - RevertPrecompiledTouchExactOOG_Paris_d26g2v0_Cancun - - RevertPrecompiledTouchExactOOG_Paris_d2g1v0_Cancun - - RevertPrecompiledTouchExactOOG_Paris_d2g2v0_Cancun - - RevertPrecompiledTouchExactOOG_Paris_d31g2v0_Cancun - - RevertPrecompiledTouchExactOOG_Paris_d7g2v0_Cancun - - RevertPrecompiledTouch_Paris_d0g0v0_Cancun - - RevertPrecompiledTouch_Paris_d1g0v0_Cancun - - RevertPrecompiledTouch_Paris_d2g0v0_Cancun - - RevertPrecompiledTouch_Paris_d3g0v0_Cancun - - RevertPrecompiledTouch_nonce_d0g0v0_Cancun - - RevertPrecompiledTouch_nonce_d1g0v0_Cancun - - RevertPrecompiledTouch_nonce_d2g0v0_Cancun - - RevertPrecompiledTouch_nonce_d3g0v0_Cancun - - RevertPrecompiledTouch_noncestorage_d0g0v0_Cancun - - RevertPrecompiledTouch_noncestorage_d1g0v0_Cancun - - RevertPrecompiledTouch_noncestorage_d2g0v0_Cancun - - RevertPrecompiledTouch_noncestorage_d3g0v0_Cancun - - RevertPrecompiledTouch_storage_Paris_d0g0v0_Cancun - - RevertPrecompiledTouch_storage_Paris_d1g0v0_Cancun - - RevertPrecompiledTouch_storage_Paris_d2g0v0_Cancun - - RevertPrecompiledTouch_storage_Paris_d3g0v0_Cancun - - costRevert_d0g0v0_Cancun - - costRevert_d14g0v0_Cancun - - costRevert_d21g0v0_Cancun - - costRevert_d7g0v0_Cancun - - stateRevert_d0g0v0_Cancun + - LoopCallsDepthThenRevert2_d0g0v0_Cancun + - LoopCallsDepthThenRevert3_d0g0v0_Cancun + - LoopCallsThenRevert_d0g0v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d10g1v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d10g2v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d15g2v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d18g1v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d18g2v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d23g2v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d26g1v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d26g2v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d2g1v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d2g2v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d31g2v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d7g2v0_Cancun + - RevertPrecompiledTouch_Paris_d0g0v0_Cancun + - RevertPrecompiledTouch_Paris_d1g0v0_Cancun + - RevertPrecompiledTouch_Paris_d2g0v0_Cancun + - RevertPrecompiledTouch_Paris_d3g0v0_Cancun + - RevertPrecompiledTouch_nonce_d0g0v0_Cancun + - RevertPrecompiledTouch_nonce_d1g0v0_Cancun + - RevertPrecompiledTouch_nonce_d2g0v0_Cancun + - RevertPrecompiledTouch_nonce_d3g0v0_Cancun + - RevertPrecompiledTouch_noncestorage_d0g0v0_Cancun + - RevertPrecompiledTouch_noncestorage_d1g0v0_Cancun + - RevertPrecompiledTouch_noncestorage_d2g0v0_Cancun + - RevertPrecompiledTouch_noncestorage_d3g0v0_Cancun + - RevertPrecompiledTouch_storage_Paris_d0g0v0_Cancun + - RevertPrecompiledTouch_storage_Paris_d1g0v0_Cancun + - RevertPrecompiledTouch_storage_Paris_d2g0v0_Cancun + - RevertPrecompiledTouch_storage_Paris_d3g0v0_Cancun + - costRevert_d0g0v0_Cancun + - costRevert_d14g0v0_Cancun + - costRevert_d21g0v0_Cancun + - costRevert_d7g0v0_Cancun + - stateRevert_d0g0v0_Cancun stSStoreTest: - - SstoreCallToSelfSubRefundBelowZero_d0g0v0_Cancun + - SstoreCallToSelfSubRefundBelowZero_d0g0v0_Cancun stSelfBalance: - - diffPlaces_d34g0v0_Cancun + - diffPlaces_d34g0v0_Cancun stSolidityTest: - - CallInfiniteLoop_d0g0v0_Cancun - - TestCryptographicFunctions_d0g0v0_Cancun + - CallInfiniteLoop_d0g0v0_Cancun + - TestCryptographicFunctions_d0g0v0_Cancun stSpecialTest: - - JUMPDEST_Attack_d0g0v0_Cancun - - JUMPDEST_AttackwithJump_d0g0v0_Cancun - - block504980_d0g0v0_Cancun - - selfdestructEIP2929_d0g0v0_Cancun - - sha3_deja_d0g0v0_Cancun + - JUMPDEST_Attack_d0g0v0_Cancun + - JUMPDEST_AttackwithJump_d0g0v0_Cancun + - block504980_d0g0v0_Cancun + - selfdestructEIP2929_d0g0v0_Cancun + - sha3_deja_d0g0v0_Cancun stShift: - - shiftCombinations_d0g0v0_Cancun - - shiftSignedCombinations_d0g0v0_Cancun + - shiftCombinations_d0g0v0_Cancun + - shiftSignedCombinations_d0g0v0_Cancun stStaticCall: - - static_Call1024BalanceTooLow2_d1g0v0_Cancun - - static_Call1024BalanceTooLow_d1g0v0_Cancun - - static_Call1024PreCalls2_d0g0v0_Cancun - - static_Call1024PreCalls2_d1g0v0_Cancun - - static_Call1024PreCalls3_d1g0v0_Cancun - - static_Call1024PreCalls_d1g0v0_Cancun - - static_Call50000bytesContract50_3_d0g0v0_Cancun - - static_Call50000bytesContract50_3_d1g0v0_Cancun - - static_CallEcrecover0_0input_d3g0v0_Cancun - - static_CallEcrecover0_0input_d8g0v0_Cancun - - static_CallGoesOOGOnSecondLevel2_d1g0v0_Cancun - - static_CallRecursiveBomb0_OOG_atMaxCallDepth_d0g0v0_Cancun - - static_CallRecursiveBombPreCall2_d0g0v0_Cancun - - static_CallRecursiveBombPreCall_d0g0v0_Cancun - - static_CallRipemd160_1_d0g0v0_Cancun - - static_CallRipemd160_2_d0g0v0_Cancun - - static_CallRipemd160_3_d0g0v0_Cancun - - static_CallRipemd160_3_postfixed0_d0g0v0_Cancun - - static_CallRipemd160_3_prefixed0_d0g0v0_Cancun - - static_CallRipemd160_4_d0g0v0_Cancun - - static_CallRipemd160_4_gas719_d0g0v0_Cancun - - static_LoopCallsDepthThenRevert2_d0g0v0_Cancun - - static_LoopCallsDepthThenRevert3_d0g0v0_Cancun - - static_callChangeRevert_d1g0v0_Cancun - - static_callCreate2_d2g0v0_Cancun - - static_callcallcall_000_OOGMAfter2_d0g0v0_Cancun - - static_callcallcall_000_OOGMBefore_d0g0v0_Cancun - - static_callcallcallcode_001_OOGE_2_d1g0v0_Cancun - - static_callcallcallcode_001_OOGE_d0g0v0_Cancun - - static_callcallcallcode_001_OOGMAfter2_d1g0v0_Cancun - - static_callcallcallcode_001_OOGMAfter_3_d1g0v0_Cancun - - static_callcallcallcode_001_OOGMAfter_d1g0v0_Cancun - - static_callcallcallcode_001_OOGMBefore2_d1g0v0_Cancun - - static_callcallcallcode_001_OOGMBefore_d0g0v0_Cancun - - static_callcallcodecall_010_OOGE_2_d1g0v0_Cancun - - static_callcallcodecall_010_OOGE_d0g0v0_Cancun - - static_callcallcodecall_010_OOGMAfter_2_d1g0v0_Cancun - - static_callcallcodecall_010_OOGMAfter_3_d1g0v0_Cancun - - static_callcallcodecall_010_OOGMAfter_d1g0v0_Cancun - - static_callcallcodecall_010_OOGMBefore2_d0g0v0_Cancun - - static_callcallcodecall_010_OOGMBefore_d1g0v0_Cancun - - static_callcodecallcall_100_OOGMAfter2_d0g0v0_Cancun - - static_callcodecallcall_100_OOGMAfter2_d0g0v1_Cancun - - static_callcodecallcall_100_OOGMAfter_2_d0g0v0_Cancun - - static_callcodecallcallcode_101_OOGE_d0g0v0_Cancun - - static_callcodecallcallcode_101_OOGMAfter_1_d0g0v0_Cancun + - static_Call1024BalanceTooLow2_d1g0v0_Cancun + - static_Call1024BalanceTooLow_d1g0v0_Cancun + - static_Call1024PreCalls2_d0g0v0_Cancun + - static_Call1024PreCalls2_d1g0v0_Cancun + - static_Call1024PreCalls3_d1g0v0_Cancun + - static_Call1024PreCalls_d1g0v0_Cancun + - static_Call50000bytesContract50_3_d0g0v0_Cancun + - static_Call50000bytesContract50_3_d1g0v0_Cancun + - static_CallEcrecover0_0input_d3g0v0_Cancun + - static_CallEcrecover0_0input_d8g0v0_Cancun + - static_CallGoesOOGOnSecondLevel2_d1g0v0_Cancun + - static_CallRecursiveBomb0_OOG_atMaxCallDepth_d0g0v0_Cancun + - static_CallRecursiveBombPreCall2_d0g0v0_Cancun + - static_CallRecursiveBombPreCall_d0g0v0_Cancun + - static_CallRipemd160_1_d0g0v0_Cancun + - static_CallRipemd160_2_d0g0v0_Cancun + - static_CallRipemd160_3_d0g0v0_Cancun + - static_CallRipemd160_3_postfixed0_d0g0v0_Cancun + - static_CallRipemd160_3_prefixed0_d0g0v0_Cancun + - static_CallRipemd160_4_d0g0v0_Cancun + - static_CallRipemd160_4_gas719_d0g0v0_Cancun + - static_LoopCallsDepthThenRevert2_d0g0v0_Cancun + - static_LoopCallsDepthThenRevert3_d0g0v0_Cancun + - static_callChangeRevert_d1g0v0_Cancun + - static_callCreate2_d2g0v0_Cancun + - static_callcallcall_000_OOGMAfter2_d0g0v0_Cancun + - static_callcallcall_000_OOGMBefore_d0g0v0_Cancun + - static_callcallcallcode_001_OOGE_2_d1g0v0_Cancun + - static_callcallcallcode_001_OOGE_d0g0v0_Cancun + - static_callcallcallcode_001_OOGMAfter2_d1g0v0_Cancun + - static_callcallcallcode_001_OOGMAfter_3_d1g0v0_Cancun + - static_callcallcallcode_001_OOGMAfter_d1g0v0_Cancun + - static_callcallcallcode_001_OOGMBefore2_d1g0v0_Cancun + - static_callcallcallcode_001_OOGMBefore_d0g0v0_Cancun + - static_callcallcodecall_010_OOGE_2_d1g0v0_Cancun + - static_callcallcodecall_010_OOGE_d0g0v0_Cancun + - static_callcallcodecall_010_OOGMAfter_2_d1g0v0_Cancun + - static_callcallcodecall_010_OOGMAfter_3_d1g0v0_Cancun + - static_callcallcodecall_010_OOGMAfter_d1g0v0_Cancun + - static_callcallcodecall_010_OOGMBefore2_d0g0v0_Cancun + - static_callcallcodecall_010_OOGMBefore_d1g0v0_Cancun + - static_callcodecallcall_100_OOGMAfter2_d0g0v0_Cancun + - static_callcodecallcall_100_OOGMAfter2_d0g0v1_Cancun + - static_callcodecallcall_100_OOGMAfter_2_d0g0v0_Cancun + - static_callcodecallcallcode_101_OOGE_d0g0v0_Cancun + - static_callcodecallcallcode_101_OOGMAfter_1_d0g0v0_Cancun stSystemOperationsTest: - - CallRecursiveBomb0_OOG_atMaxCallDepth_d0g0v0_Cancun + - CallRecursiveBomb0_OOG_atMaxCallDepth_d0g0v0_Cancun stZeroKnowledge: - - ecpairing_bad_length_191_d0g0v0_Cancun - - ecpairing_bad_length_191_d0g1v0_Cancun - - ecpairing_bad_length_191_d0g2v0_Cancun - - ecpairing_bad_length_191_d0g3v0_Cancun - - ecpairing_bad_length_193_d0g0v0_Cancun - - ecpairing_bad_length_193_d0g1v0_Cancun - - ecpairing_bad_length_193_d0g2v0_Cancun - - ecpairing_bad_length_193_d0g3v0_Cancun - - ecpairing_empty_data_d0g1v0_Cancun - - ecpairing_empty_data_d0g2v0_Cancun - - ecpairing_empty_data_insufficient_gas_d0g0v0_Cancun - - ecpairing_empty_data_insufficient_gas_d0g1v0_Cancun - - ecpairing_inputs_d100g0v0_Cancun - - ecpairing_inputs_d101g0v0_Cancun - - ecpairing_inputs_d102g0v0_Cancun - - ecpairing_inputs_d103g0v0_Cancun - - ecpairing_inputs_d104g0v0_Cancun - - ecpairing_inputs_d105g0v0_Cancun - - ecpairing_inputs_d106g0v0_Cancun - - ecpairing_inputs_d107g0v0_Cancun - - ecpairing_inputs_d108g0v0_Cancun - - ecpairing_inputs_d109g0v0_Cancun - - ecpairing_inputs_d110g0v0_Cancun - - ecpairing_inputs_d111g0v0_Cancun - - ecpairing_inputs_d112g0v0_Cancun - - ecpairing_inputs_d113g0v0_Cancun - - ecpairing_inputs_d114g0v0_Cancun - - ecpairing_inputs_d115g0v0_Cancun - - ecpairing_inputs_d116g0v0_Cancun - - ecpairing_inputs_d117g0v0_Cancun - - ecpairing_inputs_d118g0v0_Cancun - - ecpairing_inputs_d119g0v0_Cancun - - ecpairing_inputs_d120g0v0_Cancun - - ecpairing_inputs_d121g0v0_Cancun - - ecpairing_inputs_d122g0v0_Cancun - - ecpairing_inputs_d123g0v0_Cancun - - ecpairing_inputs_d124g0v0_Cancun - - ecpairing_inputs_d125g0v0_Cancun - - ecpairing_inputs_d126g0v0_Cancun - - ecpairing_inputs_d127g0v0_Cancun - - ecpairing_inputs_d128g0v0_Cancun - - ecpairing_inputs_d129g0v0_Cancun - - ecpairing_inputs_d130g0v0_Cancun - - ecpairing_inputs_d131g0v0_Cancun - - ecpairing_inputs_d132g0v0_Cancun - - ecpairing_inputs_d133g0v0_Cancun - - ecpairing_inputs_d134g0v0_Cancun - - ecpairing_inputs_d135g0v0_Cancun - - ecpairing_inputs_d136g0v0_Cancun - - ecpairing_inputs_d137g0v0_Cancun - - ecpairing_inputs_d138g0v0_Cancun - - ecpairing_inputs_d139g0v0_Cancun - - ecpairing_inputs_d140g0v0_Cancun - - ecpairing_inputs_d141g0v0_Cancun - - ecpairing_inputs_d142g0v0_Cancun - - ecpairing_inputs_d143g0v0_Cancun - - ecpairing_inputs_d38g0v0_Cancun - - ecpairing_inputs_d39g0v0_Cancun - - ecpairing_inputs_d40g0v0_Cancun - - ecpairing_inputs_d41g0v0_Cancun - - ecpairing_inputs_d42g0v0_Cancun - - ecpairing_inputs_d43g0v0_Cancun - - ecpairing_inputs_d44g0v0_Cancun - - ecpairing_inputs_d45g0v0_Cancun - - ecpairing_inputs_d46g0v0_Cancun - - ecpairing_inputs_d47g0v0_Cancun - - ecpairing_inputs_d48g0v0_Cancun - - ecpairing_inputs_d49g0v0_Cancun - - ecpairing_inputs_d50g0v0_Cancun - - ecpairing_inputs_d51g0v0_Cancun - - ecpairing_inputs_d52g0v0_Cancun - - ecpairing_inputs_d53g0v0_Cancun - - ecpairing_inputs_d54g0v0_Cancun - - ecpairing_inputs_d55g0v0_Cancun - - ecpairing_inputs_d56g0v0_Cancun - - ecpairing_inputs_d57g0v0_Cancun - - ecpairing_inputs_d58g0v0_Cancun - - ecpairing_inputs_d59g0v0_Cancun - - ecpairing_inputs_d60g0v0_Cancun - - ecpairing_inputs_d61g0v0_Cancun - - ecpairing_inputs_d62g0v0_Cancun - - ecpairing_inputs_d63g0v0_Cancun - - ecpairing_inputs_d64g0v0_Cancun - - ecpairing_inputs_d65g0v0_Cancun - - ecpairing_inputs_d66g0v0_Cancun - - ecpairing_inputs_d67g0v0_Cancun - - ecpairing_inputs_d68g0v0_Cancun - - ecpairing_inputs_d69g0v0_Cancun - - ecpairing_inputs_d70g0v0_Cancun - - ecpairing_inputs_d71g0v0_Cancun - - ecpairing_inputs_d72g0v0_Cancun - - ecpairing_inputs_d73g0v0_Cancun - - ecpairing_inputs_d74g0v0_Cancun - - ecpairing_inputs_d75g0v0_Cancun - - ecpairing_inputs_d76g0v0_Cancun - - ecpairing_inputs_d77g0v0_Cancun - - ecpairing_inputs_d78g0v0_Cancun - - ecpairing_inputs_d79g0v0_Cancun - - ecpairing_inputs_d80g0v0_Cancun - - ecpairing_inputs_d81g0v0_Cancun - - ecpairing_inputs_d82g0v0_Cancun - - ecpairing_inputs_d83g0v0_Cancun - - ecpairing_inputs_d84g0v0_Cancun - - ecpairing_inputs_d85g0v0_Cancun - - ecpairing_inputs_d86g0v0_Cancun - - ecpairing_inputs_d87g0v0_Cancun - - ecpairing_inputs_d88g0v0_Cancun - - ecpairing_inputs_d89g0v0_Cancun - - ecpairing_inputs_d90g0v0_Cancun - - ecpairing_inputs_d91g0v0_Cancun - - ecpairing_inputs_d92g0v0_Cancun - - ecpairing_inputs_d93g0v0_Cancun - - ecpairing_inputs_d94g0v0_Cancun - - ecpairing_inputs_d95g0v0_Cancun - - ecpairing_inputs_d96g0v0_Cancun - - ecpairing_inputs_d97g0v0_Cancun - - ecpairing_inputs_d98g0v0_Cancun - - ecpairing_inputs_d99g0v0_Cancun - - ecpairing_one_point_fail_d0g1v0_Cancun - - ecpairing_one_point_fail_d0g2v0_Cancun - - ecpairing_one_point_insufficient_gas_d0g0v0_Cancun - - ecpairing_one_point_insufficient_gas_d0g1v0_Cancun - - ecpairing_one_point_insufficient_gas_d0g2v0_Cancun - - ecpairing_one_point_not_in_subgroup_d0g0v0_Cancun - - ecpairing_one_point_not_in_subgroup_d0g1v0_Cancun - - ecpairing_one_point_not_in_subgroup_d0g2v0_Cancun - - ecpairing_one_point_not_in_subgroup_d0g3v0_Cancun - - ecpairing_one_point_with_g1_zero_d0g1v0_Cancun - - ecpairing_one_point_with_g1_zero_d0g2v0_Cancun - - ecpairing_one_point_with_g2_zero_and_g1_invalid_d0g0v0_Cancun - - ecpairing_one_point_with_g2_zero_and_g1_invalid_d0g1v0_Cancun - - ecpairing_one_point_with_g2_zero_and_g1_invalid_d0g2v0_Cancun - - ecpairing_one_point_with_g2_zero_and_g1_invalid_d0g3v0_Cancun - - ecpairing_one_point_with_g2_zero_d0g1v0_Cancun - - ecpairing_perturb_g2_by_curve_order_d0g0v0_Cancun - - ecpairing_perturb_g2_by_curve_order_d0g1v0_Cancun - - ecpairing_perturb_g2_by_curve_order_d0g2v0_Cancun - - ecpairing_perturb_g2_by_curve_order_d0g3v0_Cancun - - ecpairing_perturb_g2_by_field_modulus_again_d0g0v0_Cancun - - ecpairing_perturb_g2_by_field_modulus_again_d0g1v0_Cancun - - ecpairing_perturb_g2_by_field_modulus_again_d0g2v0_Cancun - - ecpairing_perturb_g2_by_field_modulus_again_d0g3v0_Cancun - - ecpairing_perturb_g2_by_field_modulus_d0g0v0_Cancun - - ecpairing_perturb_g2_by_field_modulus_d0g1v0_Cancun - - ecpairing_perturb_g2_by_field_modulus_d0g2v0_Cancun - - ecpairing_perturb_g2_by_field_modulus_d0g3v0_Cancun - - ecpairing_perturb_g2_by_one_d0g0v0_Cancun - - ecpairing_perturb_g2_by_one_d0g1v0_Cancun - - ecpairing_perturb_g2_by_one_d0g2v0_Cancun - - ecpairing_perturb_g2_by_one_d0g3v0_Cancun - - ecpairing_perturb_zeropoint_by_curve_order_d0g0v0_Cancun - - ecpairing_perturb_zeropoint_by_curve_order_d0g1v0_Cancun - - ecpairing_perturb_zeropoint_by_curve_order_d0g2v0_Cancun - - ecpairing_perturb_zeropoint_by_curve_order_d0g3v0_Cancun - - ecpairing_perturb_zeropoint_by_field_modulus_d0g0v0_Cancun - - ecpairing_perturb_zeropoint_by_field_modulus_d0g1v0_Cancun - - ecpairing_perturb_zeropoint_by_field_modulus_d0g2v0_Cancun - - ecpairing_perturb_zeropoint_by_field_modulus_d0g3v0_Cancun - - ecpairing_perturb_zeropoint_by_one_d0g0v0_Cancun - - ecpairing_perturb_zeropoint_by_one_d0g1v0_Cancun - - ecpairing_perturb_zeropoint_by_one_d0g2v0_Cancun - - ecpairing_perturb_zeropoint_by_one_d0g3v0_Cancun - - ecpairing_three_point_fail_1_d0g1v0_Cancun - - ecpairing_three_point_fail_1_d0g2v0_Cancun - - ecpairing_three_point_fail_1_d0g3v0_Cancun - - ecpairing_three_point_match_1_d0g1v0_Cancun - - ecpairing_three_point_match_1_d0g2v0_Cancun - - ecpairing_two_point_fail_1_d0g1v0_Cancun - - ecpairing_two_point_fail_1_d0g2v0_Cancun - - ecpairing_two_point_fail_2_d0g1v0_Cancun - - ecpairing_two_point_fail_2_d0g2v0_Cancun - - ecpairing_two_point_fail_2_d0g3v0_Cancun - - ecpairing_two_point_match_1_d0g1v0_Cancun - - ecpairing_two_point_match_1_d0g2v0_Cancun - - ecpairing_two_point_match_1_d0g3v0_Cancun - - ecpairing_two_point_match_2_d0g1v0_Cancun - - ecpairing_two_point_match_2_d0g2v0_Cancun - - ecpairing_two_point_match_3_d0g1v0_Cancun - - ecpairing_two_point_match_3_d0g2v0_Cancun - - ecpairing_two_point_match_4_d0g1v0_Cancun - - ecpairing_two_point_match_4_d0g2v0_Cancun - - ecpairing_two_point_match_5_d0g1v0_Cancun - - ecpairing_two_point_match_5_d0g2v0_Cancun - - ecpairing_two_point_match_5_d0g3v0_Cancun - - ecpairing_two_point_oog_d0g1v0_Cancun - - ecpairing_two_point_oog_d0g2v0_Cancun - - ecpairing_two_points_with_one_g2_zero_d0g1v0_Cancun - - ecpairing_two_points_with_one_g2_zero_d0g2v0_Cancun - - pairingTest_d0g1v0_Cancun - - pairingTest_d0g2v0_Cancun - - pairingTest_d0g3v0_Cancun - - pairingTest_d1g1v0_Cancun - - pairingTest_d1g2v0_Cancun - - pairingTest_d1g3v0_Cancun - - pairingTest_d2g1v0_Cancun - - pairingTest_d2g2v0_Cancun - - pairingTest_d2g3v0_Cancun - - pairingTest_d3g1v0_Cancun - - pairingTest_d3g2v0_Cancun - - pairingTest_d3g3v0_Cancun - - pairingTest_d4g1v0_Cancun - - pairingTest_d4g2v0_Cancun - - pairingTest_d4g3v0_Cancun - - pairingTest_d5g1v0_Cancun - - pairingTest_d5g2v0_Cancun - - pairingTest_d5g3v0_Cancun + - ecpairing_bad_length_191_d0g0v0_Cancun + - ecpairing_bad_length_191_d0g1v0_Cancun + - ecpairing_bad_length_191_d0g2v0_Cancun + - ecpairing_bad_length_191_d0g3v0_Cancun + - ecpairing_bad_length_193_d0g0v0_Cancun + - ecpairing_bad_length_193_d0g1v0_Cancun + - ecpairing_bad_length_193_d0g2v0_Cancun + - ecpairing_bad_length_193_d0g3v0_Cancun + - ecpairing_empty_data_d0g1v0_Cancun + - ecpairing_empty_data_d0g2v0_Cancun + - ecpairing_empty_data_insufficient_gas_d0g0v0_Cancun + - ecpairing_empty_data_insufficient_gas_d0g1v0_Cancun + - ecpairing_inputs_d100g0v0_Cancun + - ecpairing_inputs_d101g0v0_Cancun + - ecpairing_inputs_d102g0v0_Cancun + - ecpairing_inputs_d103g0v0_Cancun + - ecpairing_inputs_d104g0v0_Cancun + - ecpairing_inputs_d105g0v0_Cancun + - ecpairing_inputs_d106g0v0_Cancun + - ecpairing_inputs_d107g0v0_Cancun + - ecpairing_inputs_d108g0v0_Cancun + - ecpairing_inputs_d109g0v0_Cancun + - ecpairing_inputs_d110g0v0_Cancun + - ecpairing_inputs_d111g0v0_Cancun + - ecpairing_inputs_d112g0v0_Cancun + - ecpairing_inputs_d113g0v0_Cancun + - ecpairing_inputs_d114g0v0_Cancun + - ecpairing_inputs_d115g0v0_Cancun + - ecpairing_inputs_d116g0v0_Cancun + - ecpairing_inputs_d117g0v0_Cancun + - ecpairing_inputs_d118g0v0_Cancun + - ecpairing_inputs_d119g0v0_Cancun + - ecpairing_inputs_d120g0v0_Cancun + - ecpairing_inputs_d121g0v0_Cancun + - ecpairing_inputs_d122g0v0_Cancun + - ecpairing_inputs_d123g0v0_Cancun + - ecpairing_inputs_d124g0v0_Cancun + - ecpairing_inputs_d125g0v0_Cancun + - ecpairing_inputs_d126g0v0_Cancun + - ecpairing_inputs_d127g0v0_Cancun + - ecpairing_inputs_d128g0v0_Cancun + - ecpairing_inputs_d129g0v0_Cancun + - ecpairing_inputs_d130g0v0_Cancun + - ecpairing_inputs_d131g0v0_Cancun + - ecpairing_inputs_d132g0v0_Cancun + - ecpairing_inputs_d133g0v0_Cancun + - ecpairing_inputs_d134g0v0_Cancun + - ecpairing_inputs_d135g0v0_Cancun + - ecpairing_inputs_d136g0v0_Cancun + - ecpairing_inputs_d137g0v0_Cancun + - ecpairing_inputs_d138g0v0_Cancun + - ecpairing_inputs_d139g0v0_Cancun + - ecpairing_inputs_d140g0v0_Cancun + - ecpairing_inputs_d141g0v0_Cancun + - ecpairing_inputs_d142g0v0_Cancun + - ecpairing_inputs_d143g0v0_Cancun + - ecpairing_inputs_d38g0v0_Cancun + - ecpairing_inputs_d39g0v0_Cancun + - ecpairing_inputs_d40g0v0_Cancun + - ecpairing_inputs_d41g0v0_Cancun + - ecpairing_inputs_d42g0v0_Cancun + - ecpairing_inputs_d43g0v0_Cancun + - ecpairing_inputs_d44g0v0_Cancun + - ecpairing_inputs_d45g0v0_Cancun + - ecpairing_inputs_d46g0v0_Cancun + - ecpairing_inputs_d47g0v0_Cancun + - ecpairing_inputs_d48g0v0_Cancun + - ecpairing_inputs_d49g0v0_Cancun + - ecpairing_inputs_d50g0v0_Cancun + - ecpairing_inputs_d51g0v0_Cancun + - ecpairing_inputs_d52g0v0_Cancun + - ecpairing_inputs_d53g0v0_Cancun + - ecpairing_inputs_d54g0v0_Cancun + - ecpairing_inputs_d55g0v0_Cancun + - ecpairing_inputs_d56g0v0_Cancun + - ecpairing_inputs_d57g0v0_Cancun + - ecpairing_inputs_d58g0v0_Cancun + - ecpairing_inputs_d59g0v0_Cancun + - ecpairing_inputs_d60g0v0_Cancun + - ecpairing_inputs_d61g0v0_Cancun + - ecpairing_inputs_d62g0v0_Cancun + - ecpairing_inputs_d63g0v0_Cancun + - ecpairing_inputs_d64g0v0_Cancun + - ecpairing_inputs_d65g0v0_Cancun + - ecpairing_inputs_d66g0v0_Cancun + - ecpairing_inputs_d67g0v0_Cancun + - ecpairing_inputs_d68g0v0_Cancun + - ecpairing_inputs_d69g0v0_Cancun + - ecpairing_inputs_d70g0v0_Cancun + - ecpairing_inputs_d71g0v0_Cancun + - ecpairing_inputs_d72g0v0_Cancun + - ecpairing_inputs_d73g0v0_Cancun + - ecpairing_inputs_d74g0v0_Cancun + - ecpairing_inputs_d75g0v0_Cancun + - ecpairing_inputs_d76g0v0_Cancun + - ecpairing_inputs_d77g0v0_Cancun + - ecpairing_inputs_d78g0v0_Cancun + - ecpairing_inputs_d79g0v0_Cancun + - ecpairing_inputs_d80g0v0_Cancun + - ecpairing_inputs_d81g0v0_Cancun + - ecpairing_inputs_d82g0v0_Cancun + - ecpairing_inputs_d83g0v0_Cancun + - ecpairing_inputs_d84g0v0_Cancun + - ecpairing_inputs_d85g0v0_Cancun + - ecpairing_inputs_d86g0v0_Cancun + - ecpairing_inputs_d87g0v0_Cancun + - ecpairing_inputs_d88g0v0_Cancun + - ecpairing_inputs_d89g0v0_Cancun + - ecpairing_inputs_d90g0v0_Cancun + - ecpairing_inputs_d91g0v0_Cancun + - ecpairing_inputs_d92g0v0_Cancun + - ecpairing_inputs_d93g0v0_Cancun + - ecpairing_inputs_d94g0v0_Cancun + - ecpairing_inputs_d95g0v0_Cancun + - ecpairing_inputs_d96g0v0_Cancun + - ecpairing_inputs_d97g0v0_Cancun + - ecpairing_inputs_d98g0v0_Cancun + - ecpairing_inputs_d99g0v0_Cancun + - ecpairing_one_point_fail_d0g1v0_Cancun + - ecpairing_one_point_fail_d0g2v0_Cancun + - ecpairing_one_point_insufficient_gas_d0g0v0_Cancun + - ecpairing_one_point_insufficient_gas_d0g1v0_Cancun + - ecpairing_one_point_insufficient_gas_d0g2v0_Cancun + - ecpairing_one_point_not_in_subgroup_d0g0v0_Cancun + - ecpairing_one_point_not_in_subgroup_d0g1v0_Cancun + - ecpairing_one_point_not_in_subgroup_d0g2v0_Cancun + - ecpairing_one_point_not_in_subgroup_d0g3v0_Cancun + - ecpairing_one_point_with_g1_zero_d0g1v0_Cancun + - ecpairing_one_point_with_g1_zero_d0g2v0_Cancun + - ecpairing_one_point_with_g2_zero_and_g1_invalid_d0g0v0_Cancun + - ecpairing_one_point_with_g2_zero_and_g1_invalid_d0g1v0_Cancun + - ecpairing_one_point_with_g2_zero_and_g1_invalid_d0g2v0_Cancun + - ecpairing_one_point_with_g2_zero_and_g1_invalid_d0g3v0_Cancun + - ecpairing_one_point_with_g2_zero_d0g1v0_Cancun + - ecpairing_perturb_g2_by_curve_order_d0g0v0_Cancun + - ecpairing_perturb_g2_by_curve_order_d0g1v0_Cancun + - ecpairing_perturb_g2_by_curve_order_d0g2v0_Cancun + - ecpairing_perturb_g2_by_curve_order_d0g3v0_Cancun + - ecpairing_perturb_g2_by_field_modulus_again_d0g0v0_Cancun + - ecpairing_perturb_g2_by_field_modulus_again_d0g1v0_Cancun + - ecpairing_perturb_g2_by_field_modulus_again_d0g2v0_Cancun + - ecpairing_perturb_g2_by_field_modulus_again_d0g3v0_Cancun + - ecpairing_perturb_g2_by_field_modulus_d0g0v0_Cancun + - ecpairing_perturb_g2_by_field_modulus_d0g1v0_Cancun + - ecpairing_perturb_g2_by_field_modulus_d0g2v0_Cancun + - ecpairing_perturb_g2_by_field_modulus_d0g3v0_Cancun + - ecpairing_perturb_g2_by_one_d0g0v0_Cancun + - ecpairing_perturb_g2_by_one_d0g1v0_Cancun + - ecpairing_perturb_g2_by_one_d0g2v0_Cancun + - ecpairing_perturb_g2_by_one_d0g3v0_Cancun + - ecpairing_perturb_zeropoint_by_curve_order_d0g0v0_Cancun + - ecpairing_perturb_zeropoint_by_curve_order_d0g1v0_Cancun + - ecpairing_perturb_zeropoint_by_curve_order_d0g2v0_Cancun + - ecpairing_perturb_zeropoint_by_curve_order_d0g3v0_Cancun + - ecpairing_perturb_zeropoint_by_field_modulus_d0g0v0_Cancun + - ecpairing_perturb_zeropoint_by_field_modulus_d0g1v0_Cancun + - ecpairing_perturb_zeropoint_by_field_modulus_d0g2v0_Cancun + - ecpairing_perturb_zeropoint_by_field_modulus_d0g3v0_Cancun + - ecpairing_perturb_zeropoint_by_one_d0g0v0_Cancun + - ecpairing_perturb_zeropoint_by_one_d0g1v0_Cancun + - ecpairing_perturb_zeropoint_by_one_d0g2v0_Cancun + - ecpairing_perturb_zeropoint_by_one_d0g3v0_Cancun + - ecpairing_three_point_fail_1_d0g1v0_Cancun + - ecpairing_three_point_fail_1_d0g2v0_Cancun + - ecpairing_three_point_fail_1_d0g3v0_Cancun + - ecpairing_three_point_match_1_d0g1v0_Cancun + - ecpairing_three_point_match_1_d0g2v0_Cancun + - ecpairing_two_point_fail_1_d0g1v0_Cancun + - ecpairing_two_point_fail_1_d0g2v0_Cancun + - ecpairing_two_point_fail_2_d0g1v0_Cancun + - ecpairing_two_point_fail_2_d0g2v0_Cancun + - ecpairing_two_point_fail_2_d0g3v0_Cancun + - ecpairing_two_point_match_1_d0g1v0_Cancun + - ecpairing_two_point_match_1_d0g2v0_Cancun + - ecpairing_two_point_match_1_d0g3v0_Cancun + - ecpairing_two_point_match_2_d0g1v0_Cancun + - ecpairing_two_point_match_2_d0g2v0_Cancun + - ecpairing_two_point_match_3_d0g1v0_Cancun + - ecpairing_two_point_match_3_d0g2v0_Cancun + - ecpairing_two_point_match_4_d0g1v0_Cancun + - ecpairing_two_point_match_4_d0g2v0_Cancun + - ecpairing_two_point_match_5_d0g1v0_Cancun + - ecpairing_two_point_match_5_d0g2v0_Cancun + - ecpairing_two_point_match_5_d0g3v0_Cancun + - ecpairing_two_point_oog_d0g1v0_Cancun + - ecpairing_two_point_oog_d0g2v0_Cancun + - ecpairing_two_points_with_one_g2_zero_d0g1v0_Cancun + - ecpairing_two_points_with_one_g2_zero_d0g2v0_Cancun + - pairingTest_d0g1v0_Cancun + - pairingTest_d0g2v0_Cancun + - pairingTest_d0g3v0_Cancun + - pairingTest_d1g1v0_Cancun + - pairingTest_d1g2v0_Cancun + - pairingTest_d1g3v0_Cancun + - pairingTest_d2g1v0_Cancun + - pairingTest_d2g2v0_Cancun + - pairingTest_d2g3v0_Cancun + - pairingTest_d3g1v0_Cancun + - pairingTest_d3g2v0_Cancun + - pairingTest_d3g3v0_Cancun + - pairingTest_d4g1v0_Cancun + - pairingTest_d4g2v0_Cancun + - pairingTest_d4g3v0_Cancun + - pairingTest_d5g1v0_Cancun + - pairingTest_d5g2v0_Cancun + - pairingTest_d5g3v0_Cancun diff --git a/cairo/kakarot-ssj/docs/CODE_OF_CONDUCT.md b/cairo/kakarot-ssj/docs/CODE_OF_CONDUCT.md index 87324b14f..3e16aaa94 100644 --- a/cairo/kakarot-ssj/docs/CODE_OF_CONDUCT.md +++ b/cairo/kakarot-ssj/docs/CODE_OF_CONDUCT.md @@ -6,7 +6,7 @@ In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to make participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and -expression, level of experience, education, socio-economic status, nationality, +expression, level of experience, education, socioeconomic status, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards diff --git a/cairo/kakarot-ssj/docs/general/account_state.png b/cairo/kakarot-ssj/docs/general/account_state.png index 4386b900a41a4e3db705041d68ab14e5130ad653..0df32c4762faaed95ebb6839ade3c836f8924928 100644 GIT binary patch literal 131560 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 VbiXW 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 Jk$4&KzW}>@_qPB5 literal 132360 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∨p{dGWX;mf&C7K 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%0A9y#gqZfcw@Z7MS}^SlG^kHS)!Vx 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
RxD-L)=UV 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 Dsp$ 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

;i%L-Y z8)NAI@^*QBeI%Krl50?XVU9o|a0rXVR~l0RG3ax%>#^`mqiciqrHXy8N{)vH=gEz+ zLeTiqOtMf&XDG@B+}I;3mTdC#05wf*e8}-F1*||dIu9*lh5|6~xR+iOKXgvpk#19) zCgNd3Hk$N{$SD!Aw1%^&IPUxVNp`SIch<}MK*XbZj?k9D2*0)qcZ6^6!;|DY|V9zeeClF+j0u~F*fW?>pz`ko>@U*!? zXlkHE7Es4>1{=;fq}_Y<7&ZqihpUX`;=@-7-GRfJ) +-q(Lx3-R6>*UsE2M8-1ve0tQy7Gk29l?gykesZ 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 Idbn2fr~tJNDn zDME9M=ML7nrSXui*%qU;_yfHWpp|QXkQ>{tZ7xe!C_^L;<+D9MI2onXYXm%=EkLjA*l7Kq`$1cBJOR&R6;y_hTT zDbQt0ZS*tr!eY10X4$I{i*MF#n<+b;48!!?f9;vr{bN)dCe<9W_1CK;oU7`P%?6&v9c7vD@G46kgiU+Y1Ryk zHGTIiTT*d0`|H(~JlQLns-WA;2sg{W*Lw*d%M?0D{)ToyegNO*Odbpe!#^xe?5ihv z-o2si415Ye4)Ptaox$NJXB|JY%R z2U!fhVrdkISA0IY^?;45pMlthas%F-7)8T-x<~e{)rG1{T`sK|n`d>F==o!;e@{Zb z$mA~f+3jEnnF|+yd-`R;V5Xl`K8mCosdcffCOvSati(CB0vt*q0 zL3RpRziqv>8sK-hk4j-sDRz!ZO{jm2I1%@#8K3yy3EVWL3I)H8buIa?jowr}5UT8) zu-BtnzP>s8uylV8n8nUdNP<>&nl&+HWo1!TCX>EsA2ZVHCvd6@dBhM*d^zEn}IlV&B1S4&MnPwSP|;iQzPg z?_>y$f!I}A+I2ozA+^IXf?Xm4{>-_f7f*PPOF2B;lvgJ8nE4{uqdS91sHpTEcIPYdAenvO+g{n*Cvp5nB}t0wp#yHNbHOWwDE4 z2rp)n=ojfp7i|y2#jQiPqJDv~&6Fprmhc<~3jl8-BLoAf-6-T8l4r|zo*?DhS?;3( zlsx)_!Bxdl3p$rSPwb$}{Ar^PMp-~;aWJHhRd0Kl~Hd*A{!Nbdm(O^2~FMMkr*=R@>H5vj!R!(Vdd$6~u<<1UagUF01 zR0HT}k?HibGc$tg2lVLaWBYgf3Q2AI^jDiux_E$!_*$$WAudc4vx-6a*TrX#tbYzSp3>R~| zUBF}q)x}lS%o}djf`&pvlMvx8deKMW^yWzD)VOg6&(He+esZoaZxfCZ z%|ScJIr=Bc(&kcHLq>6{(0vjVY>yO5;oqux-$$=4Xtss^8&e5ODo!eTEUvt8O?9X# zJcx&6q?ybu4SE7XwHO;&-3&wUpsU!9iSbdnO0N>)SG$jZ$p7K?f#Q&X>!_VEBRGR2 zTcy&L0vF`%WlD|F>T&U(-m-=#0F|fcaUNNs4MD7V&xMaMiXfw+mMVh)TzvWw@mkvK z%`9s>yu=ZSVxb$uN6<13l*tCN3-7Hnkt@4*&H|t5e#2r|gDgRb{`fHhDt-2Si|l1+2Fm{$8PJKSCJb;l$pT=oOI=;Vg)acw|AxS3-8_?=6%2dy?RJg7 z@_(*m$Ioj{4i#dG&&F+8uA z7}GsYsD3coL5M&2$hEjB|MQ}nVS72rP z19^Ne>!>gKL%?HP+_o&y&9}1`6D+1|$mn+tp>$Xb0kZ%!^U8B{P~ua*j4X6#@uWD> zL{ftvQLOu5tHcF=!%h|J0kDLF+}IKSGPJ^Peq$|K)Nv+Al#5UobAj1KnhAU1i{4#>FJ-7vu5aZXc@G!jK69*?S#w{Sp>sRcsAGC z>%FhS2F<%kgC3E{$Vmal-C(^CJVVE5$UNp6H#A9{H+AN8aBS7@Z|Q!_&Ib4IwGm~E z(J9vc<1pavn5FtWT$__qU{55on{SheoB^jh4Fx-19+c8=D@%J#>TvAC8Ndk~sLR#) zHiE=rySLL_FiY6{IcBX@ZiR#5LPEWnsq!QgR}p&^L40Wt4kI=sw9dk8(t3m2#<|pg zt5Yc#$AI%F;H<}kG0}I1RnQ&H1B^ytaU_yvV zXLsr}2oEQV&6U~&{jHrD-0~mAKfWKhE(Gw2*6_6OSXs0P@=~TscLpcV4=a4s16L>R zeGk?@r>e~1t69-V+#yK#rqoAbk?Z5qQ~#<^8_=a1ysD)N`z5b6hP1yP2kw6@-9>A&Cz{j}-ik`t)~XTBejJKc z*V;@b&U)_iS#%?m^kV`7=rHw6thI^R+S;;KEJ&0&*eUm4}p^qOvO~z?%5X z-6Z@tmH;dd_V{C2X#4``*GHydwEt1=I&Q3ceVz8|t0H=(KHuQ)cX0RFdxAQ_#DM9G z>gBu|Zd9{^QYzO#pKyH00wHi`3$)r`mGN_BWc8}+N88f*R>gSDZfDI#KXmqN_>esw zn5R{v3|4juy&xVRXqgdfR&bKKYd!Hs6*gc7%UM)M*10M3Vf$0=3$PLMw$|urD-{_ zC#vrIu9_LPjfiD(Cc~2KwK%@#bP@(zuEEqqVVP@A`-U_y56juwc+YdV)lJ048|zfS z$%@wkqu9V~HxW^v0ecpm)!pfe>eu-Ed3Py~KIy(D9lixDNmZ}lM=Udl;sgg(*k!2A zhwacDHz(FrM3B`||1F>upV-$d1I26FP^{H zqHC}`ES^CX$qBC+Y@5BnUa4xad{hC8z*P}W#?;-cwQP8N1t+;3Rm&7NNd+7(Vq`qw zHuGZFGdJ{-o7)I%M9S#$WYd|@pRi_`fbmlC6wvhpHRZ<8OrI23IVpfF%>Sq z_l#Pz4&Gi|*|}_$V37lM>BCe8)$+U~_H07ud+&yrm!m%fGq8uPYj-`cC(N_w29~Y+ zA(Um}V)LZMFOsk4h}5CS{(}~Ws@5b73NuScJXU`ML`ozhgiwAm*Z)OT7ny%h+|&V? zDy%#Dzb*8!<*%~NOl6w9YHpZ9usNzIjLhzITxt*RGw!wHJ>li{KLB3rmi%zA6y}TU z;Ic`zwhO6DW-@UY5Bj+x=XYDl=X@1TQ0sqsO3G(=mj0FBbhUc^uI+;0^zhdbZ>}Dx zMf|F$X;}t==tY{q+XKDx8<4fCmZa-kN=Sb$O-CM zQYt^Vl#>}_Kto+JBfWT?n@+5(tTT=170cnos@}(+{??fZDSWS}NLMLsC6OK0`rB}? zBF!a7(GZiY62J*(Pxw&>t-XTCb}bI>C!-G2r-}xPZc~0-jYPe_yd!#6U5O=QS*~y4 zen-PKiHxHfo48#|V^F@@EM)rKye7QR$TPRZDT@&G4QisNYDCpYpR(x46|DY&bvF$z z;`nl_h`rE!S(t!4HH?wfRnk;+u7NfFy_8S7y1K^RoD!NDBvVuxznh2qQ@!{17ANhZ}ZlDI$VDSSuVZSNB?`(9{fvJwyKaXnulv|k$&Ab4ft z^MCG`sOl%;C~Lm+u(w9q8X3joDlPvCU=a$nZFCS-|E7yTAc^EZpHMpB1wp3@lY+-G zn;-+_vmm(nB@Y;JOy~!}DQY?tR50CLtf;P-I~6;SWR^%sW4TxNY}vB4?ZN@dYUTwI z8Yyop-U|V(K`}EA*d5R@g0546Br6^cd#g9=Lveg-A)gf-NRwOn!mxN3`qVK{1bI!p z$J9Uc;{EozL!$~Kk699eI#NaT*I%6K2gnHls~m2FythRl&=Jb!#A4Q1A^EL!$sFJ0;IP#JXOV*58*&m^1 z>psMOyUKN-^@Z)#evQSFY&FXNX|-$_VL>~_`{iwWL((tI3uawQm@X2^k+Ydpwyf*WF{d-9sT7Wngd_gFuT?YHHg_ zbw}IT!V0fbPP@yud~VL7^bOhJrFM6c3*U>2>(P;{-i#W5)W!9G?pd&a7XC$!u*+WD zLYU(`Uh{gp-j9fKJ>-c}P$uHoI1vodjsR`Gs9N z@e$@JIJ-s{&_KcDfBXkwA`vSLY9c%t@aLG4RQr_?Kp7mAn6_N*c@}Hl;&d9G%L>b6 z%}}(kzruyic!iZ+Ka7Y4>vUg#uiD?QD&EBV`^`aGPk&u?j_qdE=tVE*x{<#AIo*)d z|DOYS)APEZEnk9wCExVpqS&OW@D6?3?Olh?m)y1;aziLvK0CUMkl|YN>ssn>g!+(> z#6aWeJLrGpt;tJG%U-k8aZlcR2!S!Y5^ohaNBrfdbsz3|o6++`LYHijdUp=g($LWS zUbH6f@LA*Is>h1G-(5ql45ptywuIgYo}FJ_#O6mWJZp8={jXD-XFaZT2c2idS~H`N4?boRm<@H+b3YpsC_`n&y~4^0c*4Z=PUa#STTURRLF$-^FQ>azE zwv+iS7Zc@IHXSH|U}R4xfS$V&%eU;Qerus_G%2pZxKkbt#-B~QmJuaXKY8S}w##*! zE+S+{L6WV3gS~iPt#n;_|GMvD6!B;`1X3}iraM68oVzKYOGxlp;{79!10_|M69sN3 zpz;s}_;*4%T_^P?09r%lZQwh}1F>GrhoMv%fuD$7vK#)c^JPrtq7Cb-tBzNA>St%Y zL3fbiP2*7d%jzORL9S- zqE^^;&UR~x|8Tb@S4H7!<_3)$lG7Q@=?j#sWOeApXXo)`q-*LkJY=NMcku<~$X?}- z+s{+Wm0T=&pd|S*UhK^)=l$h?%Ro1%-1!lY@0uX@QTW+Xw({E?E?DhZYTsE z!_3tAl;D-r8At6)c(AY+4L#8V-^4`6>JG9d`&ZMgvYyOy-X?IwaR43^WON1nPZk^s zVY|?p77sP%-@?*ACAXmx-b4!R9!(<%(|Zdw@Vjc@HfOK+(+w7dB$8eCm-CMQ!!||3 z5}I7bJo?4^rmy(2dp60hVaDV=qBeU*jXrDc{hyBh%yJZMKRntK3gr3gv8ByPLHQL- zIgb-o*I_$3;_B!exL?sdOFu>^-bs{drA1rSPQH;o;$IwPimT zpYJcWdJOK6r@Y2u1m4oKPd8lo3Wr#$EG-+A2Xwk!Py_D+yL-o{`Lk)Hs@tD@-nMJr zQeWo~;9P8vNWo>JmTS{~=hGr5>w+1xUsutcYeRp;+Qvi;aXvy-R~s?l7oZ8H6MzeU zdHCOrbo=~9B&}QeghWNEzrw3&5gyyO>|=i)K^Xa!Gvjw7IwP%Yp*n$AP)O>8rTAc{gfO#Q+D(E2&1Z4&Zit_*twG7rXjaz)J;6E;ON@S z=%D#;7s2qXD&=_Pn%|`L@KY=lp!bjhNph9SA2zRtH%%u5U{n34&$U@hG5*_#Wmmp( z2J7R&rbRy@s7C{SS++mC65M28_@y=5x4()>n`<#zF8o2~TkWNI+q#(J=Bi*)*8;k8 zSqPJ}x3@&>s4s#z`8r!<;f6z_P4w6qu(hyJ!X;C-jB`$r|0F4hnDPEt{j4}~Ty5&_ zhh#EPl1v2nm7?nRQkdRIi7<-|^@$#z***|v9aUJZBw8LS>T!m8adzjPGQo9A?qh=# zDQ2Zz>L*o^@6_@9u=k7>>UlC?^=}$rJVTT7wReHr`CLi)d9JPfnm}lY-fLQ`ueU6| zwFatq2J`%PDUfZ|`gpZr%*&5lZ~TsU-LQTqcQ_uOYO_7V2wp`- ziG#I%u>`{}O_zT4c5GxX(nbk02<}-2dsP7>pdv5!5KdZh{uV zExqR2$qjX5+Nn83MW@+H50{am6F=535j;fB8KkKcB(9^u-*L+iCF3iIU2Z0Iu8iJy z%?!L|mRQ)PZYDnE{2EggN*t?#;V@Ws!2KjHATNUj;-)#9NJL-HnZnFxco-aULxPc+-u6!O7 z2NQBZR>+LA;T-F1v%Str!e5mfRyYLHGB^gWU|k@2OAS{4@W4t1)2Ln_Gu?Q63GC{Q zR1=iS+sK8fh~=|zpgYKH08@67I+In~)0R9!-hpS{?tqE0W;|+AbpRXa`MCEoubR`} zuf9@8muzV5T7pXJqBz$GSPghSGjKfS5P2r9XP|SN@6baBT~r97Ge*XN!zCDEWLNJ*%mqUwir*@i{Yp@ryxk7%hXBU+vz;Ey zc{kzzo!(S>2|^`!&d2iO@1w@ULcxo%h`$>WR`eBDW+=osz^T&6}Wm3j<>S zVBLquek>fS`TOJe1POqq9eM?lZzr)x@|ksC@A1D8v(F!;OSeLg>C#VTx=H@;*dS!) z3dIiTOAtdI$#H;_CpY67lDT*m-tpJu=i*{ob6s_Gx!94I)4u^UuAw0~xi4tV-L?cx zlfh{G@>u7590q7=Nw^SZ8;AHz6oeQw0?$E`Z%{XP_LL^UILL$i5W9Us18Kga?L5BP!oEE6jRIAl-5)LlKqE;RA|zC=--MzhHq2wL#6#T*-BX(+6_`OA@OYrQpO$mOokcw1jI#>Fak`HKl9HM6c#iN; z>8qEijlp|LNpBDQ!Rm+GX4{mizt{wR@B!sM?NTI~6V)F6{V$0*k?4hK9iCc%B6DiJ z%QwSlRUwDfwXb6xW1<%ieo*3(3Wpjd3Yje)xs{N{$#am8)TyfF+CPaY(=>Dj>e*3n zmW0T2RQqOm0G)3ES=i9@D1Z7t`-JgGW4oe$E?bGv)TY7K4Mq(LCgc~x28YnVz^Gw| zbin<VG{zv6Z(KKStt#1{TjL{N&wjq6a z@VK3uBNEbTpd_ZX+Y0A~kJ1HSsl#g9iV(745v1>Bp~A+nN08q@k3O{;O48lZgeiE* zdU2&Nh~=TkKUAaxj5k9NA>JkWwqM|lUBQ;CTz~^2>7_YXV82YRk zkx=A@^gKKT^+RVXhITKh__&s|bZWX~59&0G&VZEk-Qjbp#_)U_)goN)m8R2Nxgqqi zpav&H_$s$sv4zzE45%+G6Z%wIQK?}w{J<4fI#b%yMn*eaj1=xZuR1aXJNA9uM3!bX zeQeIsvO%H2JB5OmH`(l<=rJRHk>13y(a-4i(`&pO&1zh=JgrOWWhfJ@ZxIRm8?s3$)b4OT2ZisRdrVomeNS`$fPGeR3#oIUkBfb4j&= z30n{>ufI+YzSgxNT1Hf4@7KcjPO?n$1Gn3PUAUK<|6g_A{SMdnwXOH)qKz(EM2j-I zVRX?VNQfE{L@zVy5X2}M(R+y+A`!hrCq!>y^v>uEQKF1zKHu`b&%f}jb6xwVQ`TC0 z@3pV9_geQoCMo6mqxNf%QFc>b&u2{^vuJ|et(XiA4|H<-^tGcA`A9Ea!)fq_r zif6&o)$}y8Dc(P!3a`aJH+gN6>Gx`f;yZ`Lz=!Di`(0dAx~_5OsQ~FCm8n}I#qeKu zHaqA16SILv8IO4;+;&%qdU3evtU#}%jY6$g$^y-j*yg6_?qqNjqV=H7}06kLY01^7`;6^h}v2~g24ON&GdKgUkb7hbM-k!Ivs~sH?Y^B_QUTGqrC$Q=;0;Y z+y>@ad;n01oX_)hw`5Ije#lm1SxEV^b|uH;TqEf5P>bKHLYioMcq!h~xhOU8tLM*z z8+93%+p@c{_`T#?-kjUbs^3_Igmlcdf8+`w)0vBX(h0F}WVo-TQNZ_v<|a%Gg0vbo zOwXhW=67~_BbUN09Vm#i5Vo}I$8iB3F>T}lqO~+PL3@19HFb6BIv<62 zP+$(lgn+K>@2b!!=HGYUA&1`*9i9O&(=P&#yvxf8OMmn^funHo>3BH8IGLCPh{%Ze zFrrRb=6}{X;S+C-dxw0_XFs;! zum*YV8b;MDO0ZFVCJ|(fa*9vCpyPk7vrf~i{!liVx60S}g$wm~Q^eyIRT=$|)$c7mWiSLbRfC;lbe-vIn zE~dzEYVM`2l}>v6nS^=>)n-iFbn%Qj7omCa%VQD(l(2cDUppE0R^tn~?DL}}>QpC< zXZ^F^v!l(a!x|mph*X-+95vW!OaF#$<=4^4l9y8gPZhYxnqC?Aj~=h$THZY9-;k)l zn8G+nVb0VOpJlAx4<+sG9qO4-(;s} zmJWU(UMPBrp9IoECU_6d*M&cI13F;s1RrAoIF?(Mhy>`Fnu3eBwSa;ZMk6R5B4 z44m=yWlD*@z*8Zi+4kf_?>Z{?jk4cmo3SfyV8YYJ2m}aXe$XCqjL2e#RX*!5pN{aZ;zVo*HsczI3>Zh=&u9p_(_Fe)0lqR|92E&&khl1Zf5o-vB zSphX1q~5dMZji0DR>f_->nF_%6%6gZBz@)A($` z0RDu4j-5Y~(OH3;Nk0CCdPO@jFOWPt>`g1x2O6XFEf+bCqr|tpg{x0?f^@@}jM{I^ zc_}@*`*PWr#eM}Z5YyXd#wUM0Z_RxDuB@h>3H}#!aMwyrJn>s_6{Uec^?QwP+JJpTi)O zgXaIX-22>7Yw6q8`|N^|5oQ=QwY+c8A<+<08}W@!@8{`v%Vm)IBD-uIq7Z0q2`$(L(2dL$wb@uB@!Dt zUM(pq+CNFqP&Kq9c|WEM5C}k@!Ss;@yJOEh>Dk`AAmPF^j?k}HbSDTtE#diw-*+q7 z1<1~9hkgzu(F|Gs;=~e3$6s}u9&cd{y~fa4r5k3;_Cpm+hd;FQir@eEhR5!now(YN zlU4it)>IbN+oPZde52+!KLUY#cp7?eKKr)diy2HycZ%-mLaTRdHe42VD2#Nsbbvt8 z9%amf>8Gxzj!?WL;{7561IatTc2^dexKZAx=MK^`G8tJvLY?h6ahTM_o82bNWybgT z>M}u<*LqU^y2Z4Ss$l{#-`TQCY>k_&?VUXDsV(O(9q|vuqm{54hx^!aq z93k_a{o;Z9u6q#_u{OKyo1^iytibAJDRQqE^V=vJO1~C>cqJ)lRz9&Tq%oQAs%Sh~ z2uxNm+mydasXQ^O%uvwYgS3D#=2laE8CQ=v48LqwR3wWJNBPJbklw&wNpexxDJXZa zH9IYyPZ`j?%P1H!JLv+x-kxDfG%MQ`*0ma3_}C%>q88Jk?GiJQov%NMx~UhU*cq?B z8nDJv4Bgn4VtCzsn{*zYF$%y0a#6PP1J-iZzh`#MuXh=L;?_U@*s>E;UR51HRWnsE zS;srdqit8$c^*vVxc&NUaQDJ`&oT4S+<}N_Zu=|0a|&|g{ogbxoX6TyvcGlD^)f=L zAsCTFdLzJH3sS140h-J1W#>Vj`6fT=O=DNa6(dPzv`0ETlk}YxZ*H_*5$8L*iZBu) z5h6Rzg}>q5VEr+2#@3WYUr5Q1J;hI-3!LN{eV@2p?BYvF{b|9R2QFvWTxmXgCX}*% zMi4dg>Bz@#Xj`^Fwz6g5O!?dCP9KNImA>P*+b5OiA^n_^`8ka)G9@~@n$e|PuY(3c zMr&9Ws|8FvtMk^y5qgo+V4ia!Dg35|Q2gd&k_j_4L)WfOb0d0^3VFFZcu&L9ZefrT3VS-DuZwerP#j@BrxN|dH;r(pyv>e z-o?)|wUKm}i%QYyL}}$i(s=@*4psCGFu)lX#|*!hE+FxYlhch;kO)bO-)Kj0Oh^Cd ziCio_4-?Mri$7i*T5#KmaFNi8e(KT@pX#onyp!&IlidWs}5ljX(yvOfZBQO zMoJ*EVt#9yhkISlaG@0t*s|Y1)t2mP9}gC0SlX`q=)FoMsYCM`E2P9L^^ z^3qGgZiiDR!IBnq;tz zy^|%bp$x^($h!z!5u1WPMvdqTO4j9|!EO}0?ZJL<#MtTZr! zGfpcb0F-2clK-I(_RT^#TvV7j<5{YR$2oCC4npvF1q_tvEr3>MBmq)Fc%GCD9$>9&7FJ&@* zCb72&gzze>C_rf$L<6YZn@GYGN!STR*FYpfT%3uV{lvfcKJLFRy>3-8Qa3W8dOo8v zGkf(&Idkb-`Ni&V_2ZY1Cx@MVKjbtlZ|1e%ZDQ`IzK?&T7Gw3uhiMc}&T5>H|D^+K zf_dBJGcX)%kITh{;_w_?%uTCJ^cUT#5f&HGo&-UK_X)!R@e9hRl%aL(R(J%JPD2{XOVlpAr2!|%4g7zr*Q}!u=nT;zixGp=&7Q`?VQ|J z`zNb*t9I9lJlhFI8Mz#N$1ET*IiT`QW^RtUK{&Y>zE7{%$lsl5(V)|*ix%HaGHcjh zS)?BXs3gZbM8IfHg|C13g^8shi~6Cz!$MBJxWGtU;GN<|gEb5_8LzyWlk>&Kr3Z=g zx!a3oE%MUz`Wh|2-{5}tvw!8YP&lgthH>N5p^u2fH}EU1xedFj(%Wsx1JAOHse47T zO095m5+bh{sImOww;ZGo8wK2LWK?p~{EjjvW9O!1&v5Yl3mJQ(w5XcxKTBbVd44#+v1D-!J{=rAOrSFBtS$SrO? zMb@oRI5XoX#6qZDxdYxs#pV!F$89d@&;K z2!gd9E>Z(&QqRP#jGh_Z^I!$kb(T-c!@=sO6kp-)C&Aj*If2Dryb-Xr>L4XlV2E<9 z33yN^QKc!{Q0mlPKn&DH@3{tieBb+Kn zZ>2Pm=IjOtrN?mxe?GGi?`y9eAJ>Zdq6%?F60wjhNBAa+OIV^J>JZT&46-(Sf7AJ3Az+wnX?A>c z+SLN;9mt_uX%5mvTKXMcg%<0kO-wgalhR3)`4q47G8F&X>_zWJ8w(C-4}pP&js2jw z;Tqc^_0H#bAv8-5J%Z|E5A>W*D_n1|2HcEK?Q=6Qf;!MqmE7D*G*{7Q>p3dIp#r;+ z&W)>6;p-Q)p3urTfU-vYw*=$o@Mi)p8P&wm0E>n*@$ZhIGqRKl*UQ2`s-u?fEwAoA zOr!Q+-5#eS_{lWja9`A_ryy6vblF4dh+=;;JS;f-3K|z27>_=b#~;eE810H2j*I^Z z6-_=-pV$d__lt(#fwMP|5WwkZ9S$Uy{+D~P&2Pk9oI{%lWhtd(1dz~^D3L;cF}ZlM zWLck2pNR>;Yx=-+bOjrVwb}kEP_O~P&+Vn#>oQ8V7Q%Qjws8sW))L5^DvNLLuB1eBVcMyy3HL^r?!A)@Ur!@YtpWNst zHO#*9G}~ zdxBl=#|!L%zZx~!nnKRY0|Lr-W8+c{;U;oLIz1;M|DG0c;&o+2c$6LT)SE$QJW@Tr zP>6~|p+}+6c!VZZRhd=y$L}X5$1$rsU!5w3)aJS%YKGT}~1G6D=4)cj~ zov-&iUeOG?Wrd6_E zi;}mbwY9jK5K>Q|U;-cRv;EJwD)IZR)v?+!dJ^k4&P<43Y#jZzK6i|8MKMD4Fv+O8 zOc*H8tA6<7$Y8bx1;iGZ^Ldta>`s|Y&IdAHN4=kE-Ba}YbF{V5pOmfO8`s%-ROL10 z+>CmuFJ9WxkKoC_nSfsU<4z@R8py8VT$d~sN-15Ihlamy! zhhD>d_XA%R=uvb5+_(yklYa>=bJr?NHade})YeIRF24^1dhG+**jxbsxsE6f3a`Ph z4c|j<&35+Ydw-SYCA$8qK0mi`%AOqhA%EfFvCaAD>sQOF4T(c@80#rxePNp(wW_5E z-byxgG!8W*c_U7TS$UTi<$s4z(wiq0MiSSf$M3e%^=Q&o-laeMw!am2edOQ+O%6P2 zt(^E-Xd`3^%hbu)x4LQG(w^k zrv{=2d0K_lJgAqf_$Pj2U7t?gtxn?sq*{A8FPcL}M<_s><)3%8i!$1Rr=?w4ah6joNo?|rj=xpT=hm{b1yU~hWt zH*LbVQ=pwng7bH-l=89>#{U|%)fE8VJUyXA5uy>;V!jxj1o{U~JxLFaDTzZRKxH49 zf|&W=(c)1C!PjuKv=R(?6Xfh9dX!=>NOg!%ou3GlG~l1Q@MFk;R7ogCPXdx9wb{N1 zysyLFmo>y~gQGAELDurjz~V(vlJ5OsREnAOiSp=8jJjg1|8b|X@7@m%8*67F@+x=;s^ilbKNr zgSI-5Q>cf4Zt-5xBn^m!aU?-l=$c@mYNT2y4oC$T7fs4cislu5E|IsiREcgEZ37ux z(0;R=?Kk_@6tno_qRQ?knaGdYDEq$niT2h!AHKCOd&s2WSMXEEH+heVL3}8tTj4nn)pQd8&}1tI%%$HZg_=Y>_J}IqKq0)#wT8hy2i%?K?}Fdi+w zP5~hc>#nTg3F(usc(mS^$44_YM?7Sa!MwD_o0eL|3M~yadEk`tUyN^_pajx%evg)+ zHu`NdGxs|21x$c^?wwpfD(a+o&F9{e&gTb;U0+1ob&&7mANJ{%PSTSRlKrL4l6JNG zGnrIj5y+bJa`^LBf8$3(dO}*^BC-F3q*L{#%=A^eY2`dI=|*H}3r@fYwf&0%=vN{_ zggKxw6s#&#jEh&KtNIxWc^mPG2ccUu!L^jaDI}IVnpEb(rLRiMu@Xs!rlvMhL|pd2 zq@w((&0GskCPOP}1UpR#*G`S*cTO0goR$joKmmR0KT#4@FJSuvhZ?=#Np}$3vmkO@g;|L zkY_@%b(WkoyA#g|1UAUQMiJpL5d=7-io1iKh4SGfCIXx$`1cru=A$okWcztU)D0ly zGT)x7TQ6fF#EVITv}pO?E;i>(Z}Ckp`O*0@NAdK^9+N?>@o7^3JGW=u&qYnd_e5ci z6P@C8VI)g|J>IGBw!!J4_665npp;XSaIz?FZn_*6pa}q~nR3C7`qb=BqwJKQL&C81 z#Och4590AzK-~W~c{xpYw|Z`12v2x;l(r;q9Kh98FreLEelXRy5Q|B*SnIak0e)rUBG>@f_6DH7D3LsPy`^zrw zmAQEVHv;iK;f+$Um*@Xz-W_Y*iIOWVVSOvYl+rVa_UK}QN~EXW(NWXc@bJc4dWU7I@%l<$63w%>MXa=?D2JWP9D zIZY2y;CkHO^2Ea;J{()A_>TsTsTp@w9_cG2r01L$-#i6wSaox@vlQwai}kY?T>A%o*8ri zs`09B$jJZIKQzw^YNp}S9@aDu+8kH!E2pg5w`7b;5stEa#l%gzn* zTD|YboPv+o*jhD*r!b_H=hvx0XI74{#cCSsd)4ei;u|n#0@yNZtl;%LVg)p~ zxpUU-+k9QFyhYByCVG`JTq*SClz*f59~GQc?by;J+U-wjE(lbxP$b zwzdp$VJpC8@pQL2MZZog>OY*J5F=*GN5cFEPMB4)04^}^C;wK?`Tczxf)(6up9l`K z?!_B$BBn6E$_AL@b*F_Sm?w9o z1KbFMxa%oPuT{!2$~Iiy^tNOTxx?Qcy6C>~-xNRL)|5g%W&gKT5}k24cv@Z52$}lB zgHIq9-|+BI2)o-soJD=!D;}s=gcP@T-;@}rp@x#DR zzxB$y%LLIPmLkp>j-}i9mu4@*;solZ_w0Z=G2RD$tcT#tBAmwds@6I+l`K`^ZV!)h zUfJ6qCCtebEaY;#zdr*@s|w>VaQi)F^L=P7@NQIJdANM{^#8vuG0FO1L0$(RgwwZb zv-znd5~AHoe5@Zx$R)mS|2l|XbuQ<7(Rf0q&R7?>K^s-b+d8oWSj}vI__=IRz1wzkvF@bh i?^6bx|69@_dx_W99_qc@IdlAv=GyA|;BTrn@BRmen&emj literal 192376 zcmc$_V{oQT)G&C*wrwX9PHfvwCU!D$Cbn(cwry)-dtw`Rurts5ZPo79{@C3=+tt_(2#%s$ds0Z0s!y=mLejGQX(S6 zijH<>mNupUfMj^G29&1CIA)GcLY$yQz6?w^4C!~jBxG&CsTgu{95^(^kf36HVI*wL z4|)R;4KZ{cVoY=;din?ipplT678cyELpj)!j#{s4uboZcj_=I-@l?ChBp~ls0vYOI z!5QEW4BT)%3CM%PIF0kXiXRB?Bw?wbiCEct|G2l4tN1HN+)^|-sg@`f!CxA^muh84d>JrFsw ze3hj0SB>wPAR52wnv|eZQzIWbmVD$MzU-u=(&0oHLS#y(aI&d$n`^daa=q>;SAja@ zGV!s%8p(wTK)bQ{hABy>kh2M0#o{``Y1WwuLK#sJQZeBhiG&3Px5uNv^7DxxPlaID zAUjv&#StLY6Ar<>LI^p)=1%XwYl_h~@rz6u(Y`q0*VEUqEqhDJgR10zaYxRopBPsR zYu!pAs}Q$PqmqjYSHadB3(4!Y4VcS1VA45`NzjKUAK8I8(CcHP60eL#unhIr!+te% z1?0aPWj2CeNJ8){reP4#)*>xW9FE1mq$4ir+ar`^|1|0;s{)A&ZCxR##EpWf>W-EH4lR=JUDdUA70CzM7awF1;NTjDz!`&G|H(6{}~j91RF96 zG3N1_2Ysg>s`WYtVlw6tX+q}MhZc4($T=3gg1Sb%XWt}xgUu4)D|*~F68w5JKzaG~ z{EiIFHWa25?w1T9onH#!4Hp^`G@@osvxvmo?P=p61d08u<2r!fbh04a`G8S?&JGF< zIuEiPsFn&qy;abPf!I4Ehtr?qo)qPHR{7 zeDVB2Y+GY2m)2VXOufe2O!Qz|4(f#2Xn(UWWmB` zcIGn_fPXqLFi@h`$#5EQ@$47-6@Q(D0OrG;1j6YWM2CVk&ZX-?+}9d}>ox!2&&&kH zZqGl{N8kqLiwr&>h#m$tZa_N44_D*FoCa#<*Pe%-6liMjT@#7jzuJIm6%5f2(jGnw z)VyEJ9!D3-b@%KPgi%ny4T_%(T3EOY8evXC7FlM9&_NtKj1e_Rl(=4!B_YIwR9G}% zO7Mu}a17RjuK}W5=!r}sPG!u!2(3MsSI{GVWsC}4L`{)l5xQAeA|E~}Jf!gU1e^^m zI|{S#evaZqy9swIdbzOlcjSpn6P~v}q5(i<#Fw z(K_Jym3BG$(U8c2RDSTZ4NSK`-wkwTnChVMX86U!i%KuHbzkEa%1z)iT95)8^#Vo@ zoZS$gB#|jtQM!!Sh6OxO?HY>p6VN=E%6ma4*4%sA`~b| z@&x|zoIfHFqz;n7MauKs^R~*Yr?BOr4?>62A4!Y5FZ323R*Y|FdymCMyteXU@d<2r)0Mfl{p z6+ZH$Ra{g}EALdzE7dEOEA^DT%f;0jRgEj;RO!?!6?w{jNmVOkSJ@WNC?A*2D%YwC z6l@ps=Ls!fSECfim)2_ z`i8KdK#6_7FKi>EEI-?@YR`GFI^;40OngL~M4YtHMZ7fnEy^Y8Bf2qK11Fd1>U)0r zO9r&8dOBMsZ>jY{`h)J9wg+AJ&f;&jMOCAY;ikcd#`I>b0Il#fy++R?bf*yakXPD! z%zGa=w8(l)R(dN2Tb%?3oD{7TYx)iP9UUzl3N3~@t2z&}YV+xqZ!I;=J=P-4w~gsG zDnFg3Q!FOyrt7y1Jl7DLof;<_Dw{e@V%Ix2;4U~;U1P|j9`I@KwfGt)g@*l475^xn z-}EVsG7r=b)%V{XQb#J$6sE*l;XO`|Pt&YeW-esUWfTsIr$*W0eyp#}q@U}adQAtP zpigpQ8v0_0r}KjH9)+F* zrvq36tpkA~o5CfbS@0A=A)()pE{*W&+b?i``KC#%PSq{jC*QQ)JnkWpU62l;$QjSo z8yaiGbmLj#&_vmUfht{;B`ZA_R2Nc75Ji)Wh>og`@P-o*@Q}4I#9(sJ*lKKczWBWq z-@2mOppwHdgj_;wj1hR_H(@_FBqC zhC!~Ix!+@85$2c*S9U7f%`0J@e5NSSGN`Gj>4&90r&5;Hj375pH*I(Bo#q`}|#n>5I9r!s!ZG%W7hiUI@_{3T~Yg%SfCx-$J zBg1u=qDmT>%{0eMZpIEx16FcG2bHIs9$&jY{8-1LC*OpWOV}Jl&=tr%~;!gi|Inn=EkY$^4b3Ew2}^ zf4MbiYK<$Eg~R;nnnIp}PI`MrCS!$d$Ko^VHP#2_wYWvKSygwvxzDq|B=|+Re;`Ke zTjVmsoB9Y{r{a~Wp3y8!is-L>%^|osrjOUHZ`nB+7n>wbN&1GjF zklP`2cpn_gKUvmQdrlY3`j0Yogj*IhbksC#C~O(l-%ND&TUvIodzWlDR`q&5&Jp)w zuCnWSbgX%;tbXBKX=_I=OIvxmmR|LAQQ0dPXNzp5baQ)7KKpwoc+WnUUiLZ=zY9(Z zjr4bjq=Z%=E+D2Zkv%S)0r47eJMa?mcw&PHEG_SBxxE%|PhyNqMrmWMiS#`J9F0E1 z`;YdI{1Xcjy-QgX_^i?w9giQ{7FM*4wRvWOa=BdDUoKAB&2;X$a-BwJJhKHH{T=f6 z3V_3JzgnLLdpkdT+6KD|KNCiaM<#PpGr32dbK3S@4;PpED$Q%_YkzbRx_94;4@77F zDF3m=;m(n}HPQWe_G|8P*7azUVw0h>)Teg8XYb=oz~*ap<8s^kU1&G(DbxY!ns=Yy z(r?yRyH6j=^}cpEM6+qc1=7PXWc8q(3w&mftBJtfD*fxgCfe8))c zUtW;PY8p59uliTgURoYWB=P{z{Rb&gAyv2ai+=yV+Y5kS-bXoBIp{z1|Hovu;-j7k zy$^^{xZM?FED%$a9GJ=d;c6CHLKv)v9;_!i0l5IKWHB$-u$8nwTuDWgr?ATk%^y^| zTh6#E7JFc(1A!%D3BzF7OZ380YWh;|g!^yv^naT;rM%29#S1uc->aJ~!T+n$<}r2I z%JCzv^=Dn8ww6t5_3-n~7Ajm{#*9?~OYT@#)s4J7e`KY3`P{07Sao*k*|zh`s*kK1 zS!59M%KtQxx^;m%STRn8CF{%Ger~L0=lr{61C3-Tp)CGx*rl@bGvDU530AI4!D#Sy<88J z*lMD^sEKSZ%Z-=kwx&2MGJNTx`LFY7rNk!;Jjq0yYA;&#pT5ho-8S&OY?*dfpTLjF zLrny)f`&ooWh|_|42{ZgLXXlrE5uGgMov_&b%n)MqQ{TL#>(5!Re0~@8Sf(3$)^}v zFO!kaxxq~yp4WWSIkfK%P0hJ!@wM}X>z_{C#*Vva-G>^o?c$dD?`ET)TA2|8oH1WH ziJL8Ras5J21n+20SMA4UXb!SJg1*6$eh0VGZk}uEc!l%=u|*8nCGDS{lS0SOBH(U= ziAm0gFv#2n@*c&8G&$2WCH+1I({Hm+J+?17rY=rWKI_Bz2P7oFIb9%xDX>x)EPz-b zXU0;(kkK6xJjBw~@8e}B72yb>;phr_6(PHwz8Ea|y zSU)FlZc$8wFER6%#^hnT?X@RfWeV~DIdEc?rYT-@TYy6RM<}HCH$7^A1mX*FsVmjV3Q_tpGD z4$?Ul9*;7xpDeV?oSYS=Hpk?>XKGawb*xqQ8!;muHQz9C+`G zE^J#T44ZYTF>)(&?%KX9ecRHxcpAVu20E?XN6U1xK12*sg#WyM)PI^uYqcbX?ISc0 zBB+q2rwIGKdcEE0B#L5MyP7YehT9yTsE9@ta}bvzD=P`j?0TXNgMma3PYl^XOs-lk zf~koeFFovstq6rYxYxMB29vx_WS{#m9>}n><*9eI=D`k`mQxc2cl9&iP`urSd0*25 zq>jyWsElmRkuA?|$o^=`L33@Y@of9M(t7a4{=vg}Xrf^%T;e7@ABFukDd*0ZBR^VF z4q6#-i_E~CoGcDh<~o`cRI`S8IU(vhxrhSlGSXvW4$?vw z9cy}U_@}1xEXwL99vwtWQCu2SaApLBBwZ7UsqUr0BtC)D2+9vDS)h|n`IQOCdPfDWuHHOk|4 zNZBFfs0=4w@f?7+ozBGLd@5$Xpe$uknBWnCV1B~^Bd)xpx;2)A!IsVwBwbR)Pt01~ zt;x-RO4~WumHMt>`-?o|QR^UznEffyrSiSe)=1mWVj`2Z64l+(y9|XPi0AZG-G(gL z1$7+WBxfL}?IiZ`Iv38`5}w=pr>0EJwEz^D@9DT1-2wPz>bRE?4dz35k(U zoRJ8q#<7jnjA#uKsKHgJ1Z<ktIro4=_%R=2NbU*(*xRdiowXStqtb%=a^H=XwLU0R?YF+mj7xTr${w(qz?Svp z@xqfV?F^8zWiPq4UynYkZh;J(DKr|wD|xUd^)a!S5J#NKXtd}8Vvg7 z5Yhq#k;TQs>p((q#EElf2T`XNI+tfXqal8bfHMt1!%(6ZZrj=fVBI8ykGzXe$B$|7 zj*1DZU+Bw_@?Tq0cGPROgyAImg}sGI4oQJ;G+uS+qzMQd$VVUDskH)GE}k)r-7hn~bt+rk=D9!kk_9K~iKK8Z0iKLT5kV%entkmt z;{y@|)6<2<(A~ZU$Gt4KXnvw;`qH$Uf1uE$!s{^%Ug`241_@PXH{Hl8kO9mD1JXfh z;W%EfBcg;TNTyR!x+GA;EuJ2z;T>0fjDVZ|8z0W5XF-k%O{Fa{RHiOdKJ`{$3z)fY)I^OjMlbgm^dOZ5;C)#|wn(j;E08 z_VVc7P@FKT4ss|01H=dyaKHf>O<+vc*GA0v=IG&5@iDO5A3lazhK8o~dt6~E(D9wr z{)WS^Z%7m|xGOe9^xg^piGHvcOWuXZq(`r(k1^~iJMR`+RF8;H<0C$Qx?LG|!X1;Kv5E>kaS&iwS2>45w5Ctip4fVrVT2Cm;rhxN{Q&DL~HW6qZI?0s3BgGTRq z%GF^+IpUWo6)+Wqsbcn^#3DnAt7ZYH%hEnG!|jcB=;Sp2!;WWWos}stano7Kooh+< z=-01Cf@=VA5h$I)s1&DVsA$ArV%1GWt-H9oy|GT7=$-uWeT z(^r8mjOEsfF_~9i2WPWVUn(_?O3AS$#LXK&d}05azXt;Re+;h9&emkyT9k;z+O>rb z3Qo%!eB#A2mAaJ@%}_?F#L#zovGF|iG-!9t>kljBms<#m#*lV?uJ!i$V=$D^$9N_L zJp`rEh=-yLkpvNf-VPhr;|~33fE2zL%13tCqZiEJ=OqYq zI2ZPDwkz;aZhD%|v3)!xZTJ|Jw12*+%m)Wd@c^oY4FppOPZWF*ItDa1Dl7#oEI-H~ zPRIzt@7f3xi8yIiDOgDeA;RQBhr*%IKnf7=PxH!V3`*TCx;vdBl-UnD1s_M>@{L~h z2sUi=e1C6HL%{XVSWU$}GCcr8@*Oe2dvJpY{6>)-I6WNfbv5BuH3!)bGI!`_15l|) z;yM{ONfBUTy19c&BdvrKmZwU;=p{BQ$duBP7S54CzVD}G_Iy+~X|XZ*<-gha?B5Df zCTin3>?OSLgIhh6FR!QZ?nt_7GR}s60&O zH+qMAbudT(NC+ns#?*cVSy&wa50&-%5H1lBV-&;qG0cF4B2tl8dA`3M1Vk_7A1~5( zKX5<-0F4%>1R?J%m{>qpU+RY zc|*|!4TYFN7G?+pGH_SO(DI!C$_*S^5r7;C5)6vWu`j47i0p>VtI8P#I|N9D;#}>! z?vteC!9yZgcW`{#;$rmLw5ok?#s2ORV64cDEMUI88}TrKgp)n&(1C@f#nZUxmbzrR{B5I&Ij_p*-Bn}noeb3WZ?W$1SG0xW`U48kO_nKE4&b4 zpqGDElNLhO-B{HO4G96Kq#TLC=i{z-bbHA!4Gn3zLO?g#yML?m{$ds;lL3|H4N>fCWni^tR)&D`L0Z-`Rta%u>j)>Vx zc>8BJe>7Ch??{Nj z>7tf;R&>L4+uga>_iQNWY{MVvmlyQ^k#%TVJ|0a)mwOX$GJ@lGPPk=u#>|#CQ(e^c zSFUQ>Te^Q!cj+`ur3n#76G0HdmAA8y^d0axzzZCnbFsEO?`RR^JDkV>F#Zd7XOV|eAvAu}Uw6Cym!2^M8{Z+>ub|+PU>5l{=N(-@ zRVWKsheoxOu4=W^#cy=G_`k$5lPSQ)17xTm=3L2v$yR7O~anE>^qRG z45N@8i8BDAh`9l6ZQg?mfLicy%!M+bWo7qKxrv9GMrGrBglVeFFGjtFrzNi(EIECV zy@QwARwc0*KZposCbYyIP)wDTuvKWq`FTf~fblOfRk`mKnOgmlkN142X*8ITUn;zY zeN2FHc%j8y>1r!sDfW%~HP!PsjjEw^0U7V7<;MTC?|-Vs()8Ck0b^>ad2~vMi>gP& zq&@e?aGN*nob^xnS*4AuEdB0>^E0|7;NeH(69J3$Gn7n2=95C}g6ou&ox$kop-DyP z2IKn(-QJFCo9zzb%IVi?JqOX)YG!*@%VIW&eWCyFdAQz3D^04_jh(23pO;ekkW}rT z2{vcnVp5WtR~#~(CY`9q_eV5G+8^y7JUSS)9hc=EH&wLMo8y}~FlQIKPr0W4Is@S8 zs#p^B8dnk!qgw5>RvgVzOZliRjfT4eQ%5VT)!wD5y`qoneEykdS>1~@-M6DElMmd( zAL|Q0ggP6Iz8}?bI!&6M{<%Dmx8|r^t?pJ*KD|<2zJJBq#Q&jBwWY>e^C!j5IOL|y zw<<>AhbP98Pv#az6W4j+6YCQ}ce(}5PUk8@Ys`W#+rh*3aYwd}uKCuiZmG2*0dVoQ z6lhZ7a^J1;xY4R#ewKTc>4Wp6@H<7TvDcCK2Mq>2W+9V6 zqL~xdUv6(T9ur%c>f?Py1r6&7PDX3qM+_$X;trjp8PEztB52ar1P+_?yd>Q3yUG;p z67~Me@J}ZWp(LbIADi0pEHEq`65J$dp}qE}HylpF9)o2N1xhMAzWverV%_KIr}-8D zk>pnOS)?)6{d<-A%gA7N?u!`r6*IGU3&{ywsSXb1+*mVQsSlfm(gD6XoBq;?G-}-! zKY4o#IMo<6*KO`IBD|0eY7#?P^)eosuSuoWej4U5MM^nP=AlN(4A#rhbk9C=dzkmm z6xv6rng(X}2Z<%xj)(p2GogEsXGgI3%k=n4s{($I(@%faSR`KZK^h_5gBOREL29jx zq-k+?5qS<-oJ2_T0VF^>ASAE3pqf8OL?loIIwc?uT4}d)4dpTGcsvFdrSs5Nu-cW*NC(-(U^Exg|5|p z*Jwu;+blgap_q^~gM_ei9UW#P^Eq_T@5sM^ak_6%6nXv{S??ZNn5#E+v99H6sK2!r zzt!Aa-_(WfuEw54u~Q=}%L`0UHv^JpduFdpRoPtFe`D7PACGkB{-U-z8o47_!dqiG zMnY5AIhxGfxNCY~nbg2)>_WwBpf{t%j zpxS`_;JXa&nK8PZ|6Kis=Z)Z*k!hD>OTT><7MAg%&`j8-w4o>P+kJm^i&fzB_L*D) z>5+YzsNJKbIKQ{F_*T1K8^6Yvor=M?O^-cCi$MH{G_RksuWp}MMc1n3h-hy#$OTwlCsFn$N(CnIbT^! zcw0IMS=eY|<>U&+bl1t*sqjM463v>u7)AeViwW@^@vr$B;L?=Ktl#0+i=RT5&2%I+7 z^jqwz@V<{L(A@Ym=L{}UgY8&-cHYX3eys{PSwp3@d^t{5ZfQRso_nU!nltRO;6LTo zj?B8`_+wFPW=8w?W`G|N(AzH2vWH+(E!Cn<1?P(OmTF1pTs%i?*(8|(#oCS2z|C~S zfb-@l{62@L?X$v!IL^dPKE2M&^tba^lAwP_Q14Vy)KL7H>U`7eOQV=@-cPxyFqkDv z*-R+>?S(M8#>(EzFw2xo`T{@!poS4WyFAJ3QRI+zL*-PXok~(2gM>W<_0#o=Wz_`& z_SUK9@4Q9W1aMcZR}5gtRp(Pq9tu|5e8GJMm3o1SFpd7GHBiV$pxB3jOxfPBbb@&o zaiB~v(^Jl(6Kr%sRrJ9 zPW`GcCCop-g(rl%IBAJpP75#eI#SbJ#f~9ni2qgVEuZO3T*g*trdY=ptwba!Y9)?1 z1g9ED8i0)3tVHk~G|I_11Ym%_o;4Cj61}Etw(5?lm zYPvNv(+tPLaSWOg5rqevyG3?A48R!{?V}WZ&cBcWE%uw@CB-pl(LaogDyC2@uO!W{ z0+|_{dhAX}-$nsEg`On&Uj$w-XnzbpjT3TUbI0w?%>BT{*eO!ErIWR# z;npms27V9XuFRfX0g{@_Jdai-XDlXI@YOG! z9~MnLtfdYPi#;+R8gg9u7pG zOPM}#cpjtSO5lXt9s}8b$Tp3TD#PX%Urs&SC7w8p_xs7HU=AI{RmuJRUZTw0N^3}s zXc8WlN!J?+P_AqVOLc?y2%~#6>UtzDs~%1ycDodlGt=u$hgmbhtAk)1c;5{U_TDk? zd3HDdHaNwR!&K`bjDBCI869o01G+?d$VOSD8>c<1Hv^w)XZ_<%a$=tDL?~@sw}`BQ zopxGM0;^Gb<=gt0IM-;3t75j z(PP1% z#&-kuA4B$Su0d_06YVd-n3uK9nla`zl}?=>Rf`AiNqj5W{QiVCcJ750de{?uK*yEA zbfxOaN%3TX$+A0FvW5m0dTG0B7cj9jqZuWHS>|6Q>8zb*wAqIUr}Sb@iV}Eebr*M{ zDX{AvMp@btolD;@Rja9z`S|8aI#3=hMYyVA+?~~>wK}U*4_l&U#ut!s6ZduH!`&HU zRx-Oi=9&wRq%Kz%2H%oZX7Jd154A2YaZRl>nl-zO&GDC3-H=Z!v=q+gNeUwvj3eq( ztvvAgOcu)%3yntbFvRSJWRK$G{-v9p#IAyb|FADVG(mI#e4m}02{rY!lmjZD zXITEdpM&d?C=>}i^92?KpBVE?dXH;ll|k{1m_4x0Ad7WM%Jnq6v$x9?Mu(|aVDcpW zN&T|p7p8Yhxb=`q6zCgR-!uJiW0VpeG|=E2usw=7zz3u$q^czLL!mEEozJ_2oC|fE zDkanWgJ#Hh_2JP-7Td}Xd3?OD%Z;%6Lvx_k?BTgoLrc&&>J1^IZ$;W1grCK<$k@;_Ds3H zV37_P6yh)7{MQ>ZB15V~ztv~<$8)dsb*??4>CG+B0B7kmVPN#?C#XQ)Iy?L1*Yf(m zz8Q!xIEc&TRQ0>_mpBO0Et2Om5xIuiA;`PujQ3WpCkv|-8>DL(jbw+XhtH6H)zvrD zsQUMMgK}u*Z`l2LFqD#@Fz7Z-6BW&U)u671C>*;ru(Ta$DMri#gYwa!o zY(7m0qc7vG=Dt{ zHUdc>cwPFk+3%g+y+F}&84!??Z}c}ZfJc^d1h?cc76SmFZLvx@vBUCV=$biqbkWgtH`?Iz>A0I!X`=L3)3Md{UO$ zMq@aqBb$A;)gobvFR6o9H5QOC>-@?$PyS{|s!?#Y_Pmzr-(@L*g-B|DR^{UW6U5V9 z0#@zmq1=dp1b|Vl$2gzs1d7U|7CjTd)S5a>en_F$&Ffc~m9b&DZZ|{S2pSXp%QNOf zlpl&_FttmX>JcFzNMk(rpwMt{poU@M=t4Tr!ulE>jLspaP!Ru5E$xuIt&!N>w`4 zwc$ax~e*U?s;pv#` zZ9e~IKisn36**kl)Z6x&I_<9eVb{zaqK%%S$EvE?aGLe!dL;{|d6XAurK4KFWo@^2 z{}yAK>4Kte$}IAXqv2h}{8Nbla?p|fSDwJ5a zf?b~3Qq{XVuBTXQ*E47B_6su{99vU40pN@pwxpJiH>&gwB=KV^K} zyD*b=ZM7p|#RPWnoAu--rTBYKPfwh_6Mc9uDzh+9dGn=0I>dC={@&gJn>Yn|-@}1SNNr3-X%xBJp z)eHs0;suvRn1S;(QR+o(#1&<+Ev0-m>#8E+l7)AkiK-bI8$AKT7y^qCPz}^q*AzBN?APY%%J%N4+{Gl%v zx0_{s;s)1izF7d8E0Z55I#u+TpqRgy8y9LekL$OFpE$B95(cuCAgCS&U#%@yYfc-Z zPuE|e%%X^dT~0}>{CW5Vn8NI#>LpP$Uhs{-seFM;)t*mVEI(!Ycmd;im__OM@}N#< z1@mq=IK5~U+X{-M(gNz3ivfLD1rX`s1W`=oM7CelXUa5RWO=lGrhRx@{vD;cpPfHu zd7X4-d%S&n(Oim^Pk|G(S)@U@c}}03#TNY$X-ZSXfM5f%8{R<74&N^Vo#*Rb7j5~Z z04Twwq8=fxCS@>-4#K-fsvJox$DMxP_4IK!0kC9{iU9Nvx9WI+>WFO7wx1O)DZl21 z!1h#t9Rk+aiY;%8%1 z6qdu@l&IqHpg}60{}XyHrG$3}6;4lDJTXM%8-eNVy^^a2Ln$yrZm0AcuOCy0Qz%`Q z61Ol&nrYt<7VM^Eo!yKKQ}Pw3N&EN5Tul4jQDk!6)Oy~e@lL2>4L`D^`J|LGl<*$3 zHgc&CV*N3RaGY3L2#U(^xD?1u!T~qhh8Y2>F{R7_806YdVx*qyTqLhyo^$%5$)$NH zNsMIU0}%zj$LY|$|EwUjtN-9%h3Y=71%PxZ;ACfZ?1y87mz~iS8$NKKt%LIF7)y<`KNSt8H{Vbx@f4T4n-@&HW; zE>rNB5P|>&?J04VM*^7mJ3jJdceKP}Haai^rtmz7Oh6of+|mz*YCj*eOb}ctO^awu znuZ>;yg(OHxjbet5O_r>wNAdAQ#jw#*j-)d)SwL#4{-Rq-+=ZDV9o|fLO~mmjqGI4 zK5!Y6kFQH4A*L*&4Z|ovk5zznAf0ryP6=!%h4E8e4>Sc@)&Y<$&{eva7Thzqd@Y~_ zgiU7qJE4Gg8ef!gcRC*}i|=LA`ExaFhdv6^du~E_Xs9cWnxl5dFqZBT5wr`T7KOXKIyhpj&p!;Uy;EeTbeS!gjO3y zN3c=_OI6!44Wr^%8D=^Iy;hF}bTUl{Ig=}g+%=pj)Xykn1OgGsW+Bbe-X54Zyl)y< zK@dz_H8XoSag9qezKKp^J%~!qncy}1&+HweA8M=qCrnxO0Ghya2QSdLp;}gyHIO0j zoa5TG=a6+%|vts`ma?-`JGw(7w%-YSk@fWP(1wsH%6(-i8y61qPqaS3LBHyT-788mj4rI_8 z6UxLP%UK%(&zDcY3JjC#DPg^4O$C=)4+M%bKsxQ4WwA7N)5MJBHE7qLmpJ?ZHu%0w zQ(ht2#OF-6v**!Khbi%L7D3zq5`z>B_(s%;vA3UNMQhEa|M5NB|KfWB>@sZRVvxgw zDl{G#dyG5}H`6BADjbWfv~mP>@cutQFM(ib3jB3Gx935NV&2CtFtd9SHl;(&Uuvca z3D5q=<^mwie_t$tmBA}=eiS7H9)~l8fz{0^6sWDf_PY^IaB}?(e-ny=8ld31?G5zm zt}k?d>Lgn|>S9DVRT%ZAG@07am~Bi2STTVlqJ|NyIokg9RTK+TlZx46&h8*NZXmB3b-t$5q8*`N{&UQ^>&ohvLCHCLkmdTLHjckur63?dLZGYbNV=UI3!-dV zyi+!ga1dy>N4DQFcFq~~Tn2Ny4<EN*F*N|9J@z~3h zUf+Zuc3dW{)|tWpX^itgTsaC)#o38|AH>>nqiqF|7=1jx7chzAc4g1XPUmZgfcL2WHEByJ zhoe-pwpB4N5KJ+cP=uhqw}q$Gfx!q~Tr)RUh|b6z(M38e<}rD$e%pEB;d(7L2YgLP z&>%@e@K&CB#qoSy<)4mH$?5F-XJxt&=>^rOX%(9Rn1;Wmc^J(^&JYCom`vwstPYye z!D72WrUYS;6TZe0??j4@P@DUsi*F10mL{mJK&r1cx`As13%DYx`@}(M$xL}Tf(435 z2nUDrzm)kVCJZwD=N>w7PJ1cbumroI^rpeY5$N+Un1rE0nRIdizD83XLg^$RBxNZe z)!U`TWVu3H{ei9oH)9vKQF+Glcm@ltb#4;lcZGisrY9?)v_J|^jEW!2D#v~w`0>Sc zQ4xe(JT^;?ypQ--U0+L;E`%}L-qLt4%6P_B>}oeVDxv_OJHzS-M-7$QB@LC}0$yvu zpgwOYrs`a;k&tk1YVojKqh>5r;ujHHelnezB5+Q^#zFG@4p;&@D8lqJ8Q9M$yaxKv ze&AcWK>S%1AH=|JxPkXoUV1WwEev7G20=nb!3M_*s@!4n-9E$8?>ZNpIN-B^9x+C~ zWmuz+!A+1*8|0iF*DZsyIO3|&IrK;iWgDWv4dIZNk9r7Nf@x}fEt6M&x+L^+YNQ+% z$wD%WL)MNjfh-vb)Vd_;_OMcr+{Z^PsT{kHP5kZehIh*?sj`A*&u6AM1~5u6Lp7@~ z+J0~PUy|znza({?mCWECH7pcxed3^_nkGXW5g-E?VOBw2R_K!4N2Wpgc)qITk4m4S z-X)0Hr-*Yk=`3*WBt?%CG{jJKcUDGZgd&8QGoUQM2D`;JkWN#p0KWn6YhFQNd%toO zz;5w+m`#rPfJ}lfkBd;Qi+)*E;3RZ{pE}?qvE!UUDUKO>CAGtsKJde-MU57Kzy*R> zJS2KP`Q8`wi#!vGC-SkshAvg?eG_F#XD^yJqfdsh+i|^Vv4bPfLSlX3oLX(75PrV) zEi<~jaUU8)5_iBh19u>&Cuv*{`TSNN6%&Kl)anwYrPKX!>OGgXZO?WTKe~nwk*S0a zWqOpvsLBsotmG$7IOKplLR9tl@)!8gyu@1_Z8Z1(9Kj>+$UPZtvY0f_oY8F0hHoBp zFQgut zBHFtBj+C@T_jT~him4sWg`GNBF1iW|Ng!uYpOs1$%|PB!#>|U@xZS(L*n4lK3f|jg7205g266*Mf#ZpdIOl#zF-l}!?%sDbVj1> zZr^G?2ml~Y&h+!WY~p#o&Lf@>;TdT_zoOx>GtkDBV)E&DfGfh`ahW(qy~1xuHf zf?{&{cz}YHnmyJ>6&HP@oPHVc-@}ftTHpKA=Fg9D;a(oCZ=RhCw7Eqr?3U%)p7?$# zPV9Q$-VRR3p(K`kNzMP({)s)5TF9MS#JwZ$Vt1{f=J3uAs4m~1DLb<($yGbjDZjWZ zVv+v???*QXj|iyoJ3yA_5OEfkKD{}=J+1~coxIpgDxC$fvGTpM1EpsEwz!^fET?o_ zSaKE3ab}|op6BASjIPFSJF&ei{_P*d|5vHc_1DFAm>+cn=#6)0m4*2qSmN(wNnxsa zV8N2j4G?8QFh*o?li1g<^0f`F_t>`b0-Bsrw-Ptu*rizRz zH5+4rSUj$E>!Rr54)0SO8b)g9w;-E~$%>27-<&Z}w%W=Rhf?hi#5L~W`6HRFH1>rd zL>PonF3{Q>c@diMmO@n=XY+k@z6EXMBJOiKKz7s&PAs>j(7 zQY&j$*)fu?uzr^+qc6E{%ys`i&B&4tbLsPe@z%@dI3YVQBiWFqjxbt#!Z>vG$= zg&m7cL>A+r?D16ED)bs(fZ0_!;(y*BQP|MWGdI?~7*%`z&{7|7^q(NI=l!}lFk6XP z=D7-Y6#8#*@?_r=Nmv&~R@^MzZ$B?>AQ8D}U7$wqHW*VGs(&PBZh9yQOf>40l(8I5 zw7=F|?bZ#ry==uAdow;vK0n5K%dO_Fn&)~yt^FU0FTho1tPeCxyR2g(g--1`Tz)xh zx zZ@>Na+i$=9_S6{Rvoo&}QgBj3ESK zNQAyCM*V{TjM+{F0TkbSyZ-tG88Z6;4y~5A=uUDB zt1oIuOYFDbe*5jW-+ue;x8HvI?YI9J{^oBqu>3w33b)9R*$;4F#TyI(ed`rtj4{TT z{5peXD7?)WW72u9GIL(-u~eCX|w(r+<9dkjU8eVxLUw z?_Zyc%1_h&L!w>j>pQvqzb*FLZ~xT(dReL*AneOYEk93S{l^@QnXdm7y|MxXN)nU zkn>jx%ruDAq&|{SBnM!qfENNHqPA(qJ$qx!xMX*4TMDhZIZ~wXYDXbCGT|%mSJQTyL>4;j_M~EnW;t`=ry*POPOZ&@LpSU}XKT&R@SVB0m-yuH@jV>d$4tNq3N z_WxbjZ~qzz5ydNK0x0qvPRwqA!yFfaoldrFeL5o|lt<`?hlsG=!5tkQ{0iUf$QWbB zfGR&1F(~X>Mns7d`2r%r$(DzWPVSkfnC%4)z)t-;QJ`=zOw6Ht*<#GtP}q>~r?NAx zwmBwL*p44ByYSkb~vIYeEl026RI224i~ z5x{^gBW8$ETO!N8$ccKo95Yx5+7_??WPrG5n-u7@jr|?!M1W_Hd>x-50J5cuK#Ty2 z$}E(@_Sk9=+4Xdc0Yt4LVq02u3u8cFU%3P1D|;Qts@OjJNtxIR#9#myE`Zio){@!! z&8yFUdloZXzwZ9{cyw`LFfAP_i5s0auI(=j$C@Z%$Y(WBGp zKm{Q9{y8G2?3}yj45$<{Kp_Artj|!9%ucDj2#)r_p=%2&KA-h?#SEwss49%<06iZ8 z>DF=IYt^dCzgHnf!CaHk$cssEF-j=@<}fY3m@G#lV^TSSqad1_Eyt=ixJcpbu3A5o3Dh)|J_r z*|b)xrJJqR2gD2_Dhvz;gVarIumVfBH$GgNZ>Cd|we-`Ezf8aWYC7HA+I}AZ4i4It zGw-wY#+A7n)9HMDCY`I-)A^gX(y6KIX|r+nqi4T9f9Jh-BXBRkVLs(RRRuA33osGl zm@#bPD8j$&U0ZC^Rv7-{IF4fibep=dm6sx_4c1hew7qnQm+qmO)CVlBn^@qj5|o!A zU@)e^N;hDlbfAr~NgZ1+v`yOFlcr6R7J30R+Jd@C9T$~#T#5#R(x!=Xa&o-bj(S-e zK@mJ`_=`TBBzAtsKDNH!|Noz3oWPXB=`dNW7E`mW$>eMCna1wkOD^K-S?)#Ng_ zdIN>BtAzm~;V5(D@X^xt)=<&0Z;zLBgihsP>3hjJ=a|&FO(i*_|A`u{P@zJFiun)< zb*{8ptR|=3X6o(jTL%9EO-~0op3h*XblmUvuWYQhyj^+d=)09)A6wJj-u-GkiYZB7 zB%&|@j+v|5iWUR7?5!(3PLIjsbemlEX$D$?*|%=oT|`Ukrh*|XYlO#zAOIMRG!TO2 z;5y3!a2%B+4dDoS;x4eH@dzQgjZB28W{bl#lXq|a&Ekl%RhF7Lz&%A-Hy^jSnx03W zF<=Z(^JC3gNuN7fL+cLgJFr0xw9pLr9ll(5gTw4-Xg0fT?m_^1#(!D(v9Ve0>#M7( z&5nA9xv#tL73v|AfD02brsAuL((cagqPi2+C7pq;93xACFplBO>9e`klg(yJt<`L4 zuoe=W+C!0IDh^ea23i6|$GiA zPk2TG9OOUn9P+0R0%R&%5ejt_ggQHTyUot`bamw-K~RDL6js)qA(>2)LKxs&&*1VC zRka)44jZXXK{S5_66&mhV!%PFI27<>LL$B<*g#-QUJ1 zgByI!PqiC&@BDOo>E@l=to7bJnvya%v%85};L|;%w+>r#-WTQN#Rm=^EN*KHW3AKc!00b#(7l&9Z24fQsHfhqC#n{m$UvuWy|{KTyzcvf+bIKHj~l|6Jd4 zT9$h}?<933W%G3CR6$3_DcDO88`r@ScIosmr77YR6px%-I6Vg> zCdx?;BmngP(w`Zgm}E2}1qqaZ%fDaF!bnPh0B}YCyTg^YeaD{S^0NKKy}iBJ1OpI) zB%A7El2xd9hM->K&lrgG!UQ5?QHb6XAan6cAjUPa5Yp7#F|(K`?Va2Axh9M4y#yu{ zi4$P84Cpm_Flaf5PR0NsEZc@Op(6q*;Y?5 z_Ef&F6+wd$PABrShn&n7dF3;q;rj5+7q1WBST#B_y6Vp8{S0buNoQKpGwf22IBkuQ zGeZBli>q~_PCh<3ngD~=09S^FS0RDG9Lzf*Tk1QBGSW}9I(I@YP?&Ng^YY#p)QA+8 zoP^h3%N^7kD0ztOb4y>4oe`tK2pNl)DwP<7%r40#4@dJ4TL$vq%)dp6+S|0KgC&LxVNHJi5FyfUK!zrv0UgD_`1s^M>|Nb&99I?p z?VY=KXJ=>aO+u1~^utY3YLk-I#E?>nLM4iLi9`hw6si0HJVDaX&_+&3=?7XAgBz3@ zN)bYkQs_exglLgk5!45GvD5}q<0fwEe5~C#b#`aRcki4z!)ETt+u&H`p)X1IXaBUL z@%7$wKUTl9_ug{`V8AdiG&Fc_^~cuM(w#U})PsXtPE=O9psc;K=Ps_9JaKa1{PgTV zSPv@9)M*dNl#(q))~E6^33imbPjcy^i!MGgkl>KolB;^iROHWyl~r8 zkdA~S9OT^s%H=ZZ7aRVuSO0$h@UD@s=VIi7y6NOl03azNmSaZ)l>}za%&a+ma(ZC; zt?7Ze+Iy8Supt@%qw}us*HHyQYEkF@4~ID|Yls&^e*gCBu}`R+gzONL6O#iky5um8XY zB>i5Bga9QA$Z-yh`G%ckEIZ8JkF)u(5|^6YjqI)8{JXN-fe63d+@YZTaj8Apj|DyPKCTt*M=@4ZMA7YT%uz>5Avs(;UWJ z=`W$P5NGEUTMCw4{qLfS>j2l>0tbu#Au?Y1cZ+UzKkFf#Jf`{(E8dU|_%ar3$xj<578HAxQgv4=dDvb+xhMlh&N7If7KrW_xx zS_#hiD6LpEyMEJ#@r}2yAHT8hrim4m-ewdVXwBVaq_X6*gl@fq^dp6Hr=*3Hgc; zT^7qcg&t=`$`X{@Q47dDXY5^k86y9*4i#KN!w;J z3?`%`LuuLczNW?eCw4aos7OErfJ*>{W^w23YhT^=#(}3ttJ}Z3WB>5porhTgApwzT zfi)wl6BZg8uJVwD(7;vF_Dg8{LsCk6oe?3d4N|3bMOZ+S8;A=Au{4nB7zrofq1DcJ287XtnxOb?es6Gs*+B0a~pHCNiKFrOpy;$TX4ylBa(3gR$Ma zhev<1zgoTL^LNbH&%3odY>?+Wy;yipTZd9Ah|~rFna&g2Kfc73jXB{Zk^$XLxx z>ak}oL@2S3VqCC!8axjWNU2<9FIYlCrvKZa)nZp7!*a<}VQqv&vH&sl@3;FC0*VC{ z#Zk;Mm&fT-r~BTmUGk*0Ed^-<#a4q9I*S}iw#innSTjJ#PDa{3)!M*l0viBiY5juC zUWF{g2l(=~FTOGQ^Czl%e)#bI?GJzZu-0rfRXT_qAc_br-C9iMoxU1QZF7aSOHi9^ zU$Ll{fVo`81B?Mm`2rjUIEf(h0v$3WXy6 z@!D%&s5hFfrvRg^;5Wli{_({lo2u23`*uIF=UY3sKl$K~pLlNDu~+`NF$}a7dlvZX z%df0|^0ASxoSiy*yMjWF1Wvs^(9`d{P6*B*NA_jmo5y=x6> z>dNE)dvkMN{m*&6o|F4pUt9lc(n0!CkqL_e z_#OPW0ffD4>JP@4e(&}$6=3VGhTJ-bpqmx@npy7tf8^xU0v z_$kweOj;l;`R=<&YW{kCM}XZ<(h(dO8v~q$d!9ILKtX5nq%cp*%FY+wy;~NUotwA5 zQRR7O44}NSB6$D)jLp{0u9Yq)0Eg`hO^r=q3VE*RYSHBgty&lG&B=2jX=c9Y)QL+U zKOG<$!w}UR0In%OK!f}d zrKJmJV>k|P`uq3$a9*=>UiXE>q{NHAi;Y!(^2u*I_9gGR&h_O!p&~ok7!JKQ+ad?y z1SjcymM~)|^al$#$;rw8IP`UjEIj<3R?5phHarUVe)v9S z^y&CKN}u64Q{!WF$cdHSxDzHmCKK-1z9(VF_T;S@>C%m*cgmKN1Y=xxOps7nc0V{X zEo*a^wR`&kF*FPOhJh)pN zSD?7Ew!e3hg8>Q-=QE_4;Z<{y4l|AzlHmbBf-m9*2=JfZv0%Y`D|o=hFr>V!Is}_> z()9J(coMN#Bo$|gPUf6k&vF5R&z#mNKI3)+nk_yl%#un(vg{nu)1e6#jxqYZv$b>K z)k{~RGLEKg*}F42F*W5#T)~MmYoGKEaWIl{bkL3w`k-G?T^1yh%VREHDHNRlw(xxn zL+K*(Q!WywU2adK3{cE1Dm=fL^E;q0IXsD7E4m$~$SM&2JtZUIz|O;4b0qSOb(Iav z2`9B4jI0TQd5?6vX-5e`OoQ({UubUW4LE(OXx-kwWqh8NBH2_^RvQ8YUF3d_Z)AwG zg%#D6k-0L(dY!&4fR4z-m~>whWdX)w&DGYzxfo5i6pAy#yZrazc;rm##8&$@c8IHJ|u98h?nP?VdMD>{{*|1sle!sxnb z{yYp^lYmIl<6}sHsd)T~q#ex2EjTZ+O`07j8M?td~*EY3{u5R+JgULS3>J_xe(Sb~-HwQJ6u zFO1JPmKis@ge`66B^rY!Vt8nfO({vzMM8I%by;1lQqW>HhmZt8M`jckm8{B1mnYTU zQ*N-dSi>iWr}!Pl&QMi#V@&FS)NPG*IzEqwz3|qksH_Ne5iVe{FbG+(qW$gA6>TVs z1uQ_Is<>Bg9qgkM?SAC#SY59bM1e_{{iqC`lx676`n@rJKtwvz8 z^#o#U+(i+RqRZD;rDsTzD#|N2w6}GJkB`{-&CSiBwYAEal*5O&sp>SI@#1q!(bH|? z>-1VdOG}HuU^Ik3vj_eMj)@6c&Y8!>3D=8@V~qwwwB2qG8W|Z0HW&y_h4Gs(h>h${6o?^D2W@i_yV;moh4755! zl*w!s=#6^8h~4goVoWLuB|n$TML(V7H1*xNrf$+i)z{Stnp;c)OSjdJ!v$z-YhPmN zd=NoQO|w}T3mlUU=Li| z8Q9VOAlhIu3I?7G@Y&QBB?$UPA1}P{!i$$3sQWqftZ)F7gTojx0ZD)Psw^!lE$hoa ze|7rp)vNk|(q(jn0Ik=@=o(%Kc$ynwLjHd;=Z`+TB7o4hs*FuAz5)*KHD|(SpWUSX z%h_x;jE_4w^-5(BPS@okV8mnW$P|kcii=BPwK{$D;NW1;;NU>8PODpU?(Et4BS((L zIUGz%i^bZt#Aq-@APCC#@$rFaVj3Rx_bt;K3<6a{V+aly-~_;(lG0VjQ>97OrPUjH zEsw%S2JHOK=FZT&-VD7|qv)~Gf|_jL9K zJ+kx%t7|lCiq03sXQpOSJb;dxrQ~h5Q>iWlP|*_zfg#P~iWo@nPf)=AGouAWwOZ|>*?y>bR8=Vh^&VcS)9D0V9(l14Z=#A9UU=|}JsZCw298&Bx<7*i=D)RI zYWKcfr?`IHzKvTp{hPfjkB_3t)~9YQUA-iojSxTx1PGzo(dZBm5pZK<6&?<6d^76! z9*pA?9UVtOK_ZGGDsiHY&cL{^jDRzW%ZOtTSp`Ivq=6(PtXW7xl3uH;Yk76U+QU57;N3uAkLab?>bTIbWUgopV0)49scpDF8||46Ok_HI5w5;g;(6iOcE4m;ZP^ ztxDM+=X;m;>Dw(Jh=Ly}lS(iG^|f{BSlmq206zHOg96LQcSriFqC||$%*=X0;&r>r z4j4T;bE?Mk-n$zF1M>il0`6y2}&d={dMh{X-WVKSZO%di`F$k;W*&xYHIq6q5y>BV9dDdDh3W3 zTrS2s)SRuW&uMH3%D8k>2O}$^%TYvx(TEP)w(RJ~qD~qGNL7_px#$+b?*|ST-~~Y7 z;dB1;v(IjkB!MVl71Gnv0x78}El#HcYhNIElUDt8^|U|$AP`{H(*<6zl(+sr2;2{O zJ{Bl@XZ5Or+Sq3eJtOk1{W zzLDcNrznacHFnbwTz<2E|LD@P>I|TQa}1#4iJt58`RIKl6w43wRPzFazh68ktm_x6=>NH_A0&1(m zK@eN~{;WVKNLifSx?NExAp?#G9j-@cstU6gpmPxPg}^4;;urwCVYwUv^vg>LxZNp! zffwnqC#p}RgC&9_z`Aws7ARq*JGHsM8M5rCw`_ur_CgXxICiYk^T{U`4j=^7NYnt1 zGc-*HNtEb|JR!V^-hH$YK3@Q;t4}#MefG~=L`fuQ_hq|1V3!>&L?pBxNF<_2tKNBM zS}a}mI|bLT>%di6^&iltq2yZ*j{GaHDhErNn$E$w=H{H%=AcaNq6kLkPMJrM4U5PB z^Yef9V+0Pgk0IEzdv`8km{2eTeJtA)2q;i*;g-!MCAS0uexhnRaOhm(`4-JE!R~S* z<3?J$Zv8Y#5|Dk0is>h~7HU&9U60kr0uVS3cp98wDhX}rDH^O=v$~+6sj+)hk3vuh z8Sd1idV?6cD2otQ!*JqcmFIn{pr=afZL#N#K?%fXXzzD_z30Yrz9wgss3BhB@f_-4 z+P!=C=pzS@WGDdz?Kj$4#DjEhqKM2%h6@E63^TzrnNpjr;&+IB(g6h>U`jXy2E|{* z;04j(d7e64kUb-dvf0||Gl1}>?3C54tS*&^Q^Mh}71-FGCkTYHL{au1*q=uT0h1Uo zaPS~+NC`ng5|WTh_ucu@ob~@{nWSS;#vcU(tz&^K+!~x==?^=-XP@krrOTK8Y0{*h z9@J>QDuB%?f$WewumDK>M`$-7VcS?Pt`3IIqV$FV9n>b-f=F@X1py+8k|xQ_7|;H% zyGsUp2Jg(t&M7Z`x%jzfpMCbVqF0KRcJ11&kw?Q6!3x{^axk^_o_p@t`qn#d6uR8W z&AP79ac{l#){U#*T2Z*@sfFt>+LYBTEBLE>?_A;R>}Z;L$JEs;*T1;z`Bw^;Uo-BS zji#)DCTdXMRG)h4%$XDf3l2woEpdkqvMNZd=10kLE|9FmISpYYx4};kDyQks6JAaE0_|XjJs~ES0Dgs zX=%aV%(-txMrx;~SujhDAYhstBqyh|KEB|IWiP$7eCf~cxMMZp1q726NLk%w@&VXsE|&|w zM;NfVfHuu?YZW?PM2&(0_^j{T`j?f<3k5-J221dHUw_@0jqj~nTlm?O|M}_V*WWZ|W5iTIV=wKgCr+GBf$tG?&TQYdyJs*Ea_E`{NiJ7y z_Z}I6-2T1J*<{-}d}$AdLZqZ*bFL(@7x{t_Kk=e%vdgk%o6h999BhAbvIA;s>vPe` z!&^FXYjDn-dslSI>e6)kFMhuInW7h#6|a10`M8M_HnyrN__ZiBhr_8y zPn=8vhEu5Bizrd*Kp-4pSPP#aWo~eB^#wFQ!Ex@pe@;p6puRh^`gAUTuK1bf7A{-x z+DmV|u(VUJj7CF_f&yVUbm(9XbBf?OcsUZUCXHIiE#NZ@du_+k&AH;I0H=Xd+K)(JjO6I!H8GCHi=HZ zGvWVNaITyQajC7Tbw~oEej=0O{<(8E&3o*zwVg6kBQ6&@5`;*PUOkRTf{hlI_GIq&Pm(`_fGwU#d^X=cT^qD2a(P;?T>&ORoHhL9z*YOylu|?_uai|-n>WGcFK?=IEK^Z zjP&i>`v}CvOrsGXh~-qX2nxO4$ZM|IncbyJ08?$Q8#$^XyGQq9xF5l4C=|+!7cs+7 z7h%AP5KH6UBizTdqjQe!=Yhk+zV|N~bLL2J{qS3nF4M}}O~q68?LCxr zuKAoB9WdRyUva8y*Dihp?*altA@R2(Aqh#yNpqONI!h|6s0GWmsh7XH8!QA&9d04b^ZJIYnEi7Y}Nq- zavNTJ@!8@VZyrr?Mo0meHr1N1jPn&~k?w}ZhSWITF}Vw#H+Rw0dP!i#=2@G51@3>~ zzD6TtJ`GOd%Z+Y7f zV`(zy#t*FH!7gtwpkZFPpZ``PYnnjLr?j|QRE53VC%Yu@wfd#??`|0W?BZn;o_Ku8 z%qJH;HS55^1O2s#3Y=y@RM9w10ZeOOTcdde2@tM=`Pz4n$z@S6}y)2*B67zV2fh90fvy1`hPP zToSElPGX&54(vbJ<%MN`9J}!GrBmn6dvey(g@rThc00$I5jb{he7-ueWl(XhCJnt& z)lHM_*9}@I7BsdNR2;`jrJ?tE@uKAu7A-8C`NX`(XVsiO(;vYE)Asoz=tSZSgLc5- z2vHCmw6$*Qens{PffHyy`(SG@8Di@|K-b2qVAL2AbCdwvPdMPMtpMz6-130?2=L6+ z@h=o;12~f@6IN*+BZ(>LlA6&etuiUeMSm~8EGfyuTd`}`&OC?12Ei~=fcuoGnnoQP zBvBzfAqh#yk67BZ(biap2^j>?LJAnc5dXr{&rT~naG*ffHR{~>Nx_KE?)c@5y^02` zqnf6|#l+x#SjG&pAq7j_sc9{sp$#_%p8*EPq3uFeh%XQ% z7di%r@h|LHgQn|nwI^%(hk`-ifrpkBU&?E5tQr0K8>>e9T6{^k509%nQrWxitY0EP z+sEp8o&iT~yhKxNckJBJ7uULb=k7jsn**@>N^WkhH$G0Rfarm}hr7J6iywMpDLPA z_}KF^pPs*XR_Wfu{ml>n7bT!7I@cB)L7b-P8fE<`Y6LQ~G8Ko*0UBsD5YxY3zY_*x z1P!dYg_4pIX6Q>R#q?PuS`S-@;P9w5Ul!OwQxgEBfh z)s(dKO2#m8!LB`D<>3Xl@7R$S)mRM?Pyf6!LRf3rgd`*(m#$pq9P30E6%>P6<+veW zmcXPA3Iix2_%4vcgtWhvCaTG#)(IV5`7FFtO z(Jk5#Kz&$5b&*)X4!2s~{m%9|p+hAi1Y;suZiK6#1F#pLimU_-~3L67G- z;1(=;cKYd)r#xts1&#m$Dw9zR*!m2En#d4#_(&!lew#1?gCOOr9lLr&qYHY;CLPZ1Z7W1>9Ls4JpJK-#JN~F zZxe8M)7lEe#N*j@=mAjxPNNgy!KCv`NnvelLq34~tMkh~`tXxHbR1PxRQCoAc3N%w z`tX#_N?_!*qr6DRCPafoBm9IUBq5ih5aU8@5Cv0Y9W;Q`zvURx?s#-~1e$&JCC@x_ zdqaIw51Zr!o#V9W(`WpB!cWJQsT$C5h)c#azgQ{+`Id+pXN}9@m_~bNiXku?O;vYG zvJF{(&?PggNuz}+36zxV>hbQ|@6OV7!xl9Z2uGNG3Wb8msAQuUsO=ai@j4IWf+#-* z8vIQv_xzF zXgZ+O)Yc3>e&RTorcUvRD4{*laVuB_&-;$KaeSG>LEy?E!@Ont$_Al5JW_VF7XjE+ ze)w3gXv6@ND~Dg{#c@$Y9=N9#KR>4Lpc;JB0OcoGBxKL~DB};fRU$9CQNowXbX{RV!T)(dmJnDJ#cWLJueGB&@&cJB@ut_|E zg3JwCFe<75&@>R0-W1JX)>^|KmA$}YO#-BD5{&_osDgR3mU2-Dn?a!Yq?*bojtFrC z{8Rxy37mI!1jBv+UIW6JphgsM2rL?*T8c*SvrRjD`CD3TfJG#2G7Qce(4eV+#+rNU zFK^9Mm8i`w*`Z74t_Sb@#a$~Od|+;oXJFn=1TV;(;7w-aWQkof98y6C6JiFM0j`*l zT)XDO{FBuuJ<+I+Mpl_Nf=!|+KuO6?3apT2g2#OG_1B&h7hCUj*Nv>yL5uqReyFZGp6zP^ z-s%9-lZYI++|GuT3}gTW079w)b&U!TnjfeEA!@wsD60v<9R8-DfnXzGAZ`GL16&f@?)Y+V zuW&eM!5@*qxFn$GU;& zfWyXyZ2z9G_IUg)Ent^yXbyDN4em}3slk3@uY)oC%Arew)dJKt;6DLpd zjC~;~02%nDiUn5dlXw9!6+p5x$xna@#|eNtamyPFqY1#~htCqb(MTLmuaPDL$SSS} zZ~X;>F=4e_L=n%X_#qsMAO@irAoeQ{BSwuX4+eu8XeOMhsO=G`3)+=nv@7DL$^eLs*nrarrB5ci+@Sa{H&+I1bt<4k#1{Z6q`l+F?hrxKRS-lT z95y>OWLUSXxvp9I;Qi0@KHRu*3NML3L;*T=N;^Gj^swV-puXOFI0FlKs;Ww(HM8f; z`SgbILr)GE(65ntJw-5xk_D4P=`3U~$# z7{FHzuO`(WdT!zI}!D|!TS z2lVq|WKD^+Vmnq@nJo$;btd%a*6q-=$rDNk49sinoZcxI3i~+(Qz$k`0*7=y3TMWj zIR&ioB5|RJ0ywUzvjY*_9xbcNP(rE$3xA=(pZ)7OpWZlb)X5%KbZOT0sEM6V;;apF zfm_gI`=Y7}-qORp0T5KMPA=6ast2%s_5wH^&Q>D^E~8omD8k|iZdpo;WT|Xp4md3S z6-6f-1E{hL@%kJ1iSy7{Pkp*=X>Bn97>mS)&J@CW^vf~>KCUD|&FtE_G9@VmG}RQ> zu39s~VRvw%$Rm@cOp+4bjf5m5AwM2LM?6Nf((lC9WD9^+oyzsV3%YFv}n}H z(Nd>MpKSa*Z~fX0Q;>~-fA2eGWSt&AcGz(o&HZZP zlt~*VPPR0*9W-pnZe}|PoT)k8Hxyvp2X~5~S;f*T(B>MZZhQZO4~Ey*HOQi1gRVWg zc|-UtG{(lLsw&SmO@lH*`uFR9XySyMN(XuRG}_a7)>+LF;>o0L6RNRi`olI0qi@cBjCc|C;^jc#5~WG>f8OB5p){ zL{m>Cc0W{0O+sk56v-~a?tOcEJ7ji`(X>_`s~TXMI-P?}5?gUz5KE)gF%1Q`rU7^k ziX;la3k3Xr9}6@I0KP^VP-4tZzT=yWAh2hRYz$3j^;>YQvWqc`S^_?BBstZd+1Ztb zW`YDZ@x6EdHo}OS9RBVUj2vA?=)5kwm!pIv(*AVfr{*niCP{8KMXU$*F_=_~&5=P`mRfJ<0T}H>}?Ln?tP-6->DKwu%41(~&r#nbs#Uf#b2lx*tCN zx~!f2x=FXieIwnse?IZ>|`xgU&gVlK|z5&0h@L^5r*KjGl_x zzN&U<>7njEzuyIxq^75vQ*WERb>gInrIV+QFTHir^`$re^rq5@lP7L-r=~)Z+YMn= z6}N8R)+eMG6ch{`I>3wTawa=r`>w6mTWh5Zn4c6}<88ZrxJ3r3RTzshRgRWd_NuO~ zNjr18-u>DiUmed&BF71YIx)W3y2YCBzAT)b8Ds0jGmQi`?S7uz(>myYUr}YpSEVzJEQKO`|!ODO$|x@kdH=Ct{!o$Yt< zp%DHqXq07i)zD$ypmiZmk3z-K!y|%$0G<1oF<7A2;>IF6~VH zId}0N-xzOjI+jR1*bY$dA3I?PCdrLqj$wr%Ndg6YD}WU_2GZ~xiM zt&^u%7+~7?Qru3ow$rCg-Db0iAUka!Nuv1aryuue14l!K4faNL70@n!Uh?_%E|(p2 zU4?>zYrP;a7NXIv3@3q#imF~!$LrD>8zSyE-(EA`Fa=J-MR6i*{$l&E>SI+|24Sqy zsG+k0-j+g)!O=Ij&uL`w(l)MI#J#-u^>O9Zr`)nE8Q94VnWW)p7&et`8giySB7eEP zEZck3I}Dkr?$l(6M5FHF;=dHcy5OK=gLWe`coS-BPhY)o(aY0TzP)zTf8Y1;y^0b{ z;siWKf?@x|-j&Bjd0g??du?NzV6IXQ@2+>f_pT4j>5xF=sw5#Hh$Dm~1|PdVV~l~2 zq;!oUR4HvPsYs~^{R3506xSR!&f=H_46(7h9B~XvN>dRko7kAs>)mg!*Y{=}6H9IX zXjLgKJFA~({msmq_ukI;y`R3BZ@#%XS7-!MJMwQBLWnTG5i`0V6Lr)6EfDlGYIAe& zX6n1|?OE18FqlfZlaFKyY0Mtc*mFpHf+TI~#Cu|ii0?0UrS}WthwtxOcH%_4IuHoZ zYw-Exj@_PpMJAT<8%>>^oeRQ|*ygWGmoDY}BpjbBji-2ur~h{PwCC=Q<{rWI9a?%r zli_6n}Hi{P@%-_oC9E(4vZ0@N8!n3GWoS$R7+EZKFC zVXlC(Er*Y^o(Gr53oh%zZGMfZ9Q3BmU^Q(AgQgbDx~*Wh>;RLg4rZs9!fYMNShW3m z8`eK|PH?qe2J91f-iGjCzl#cX_Nz@LV6s+0rm+GtGMyY+qZ2fiGMHm4gV|Z-zRI0V z2T9MC4se~u{6uG{-j=_4Fx^@VGmRTTljY>l&Z~yvxQV9#6+&Od_ z`)fQMausbpbX0AtfSHC8NVi}cdnK&i`0**St9(aOgK0q>%rQG4BfE;{RM)n6`@nj~ z{$^cP73su}JGM18v~)*YEvQTLvExQN);Wj$Q{LKv zws*&nnN!uL$tp*AB~Y;XSD(AFjP&?}`~GfSPIU;u^_!7d2%4O-TkdY)@;$wnccU#^ z4mN1*<&bHq0Ij|ZvU0b8DzgOg7Vj8vZa&mJ$AEq@7lYR7fSR|CG_;}Yb&ikQGO{aR zmZb!8mcD+&?8i30cIdTXVQVrAAYWkyJo;Y!VmWRk0Xva z;`mpfxcqp*u70}4nr*dUG}nO6Q29MztWp<2?bhQ*Jni7hf1>`cdUF-%t<`|n`Y~kS zF@j2u^)t)BV6TNezrFrmJH>yxmiGD)LhQR&;PEGGL2ZAg1!IG$3bY#J0IE{R&E5{# zwmQ)2$~h;nW^MMp={j|=!wW8o8K*Hna{=lNd9{N-)|X;DFUMF}3@U_uRX`j~unrO| z!&CUnS`Q-w$)9SrG>qlb%IP3=Kc>lm&$w5#y@1c$x%YEDWb85|XV()-0*@5t-F_PWQOvz`1QjfL0)Z)EecbF*XZRK=%V^J>G! zE5UF9QoAvNAk3CA!;nhZn6y<*2%m6)+{@t=R3#@;+(!JS^2Qjs%y%c!^*CRdA4PteE(I1`Gqibz~DPe-H5-=Dvk6 z9jm})h}ah6{MxoLWkKG7w8%u3)eYluY^|qo8PDBA=Ccl0KJa{Y;BbWazPUAm^0*#D z5d*>;^wVY8dlnVIoe4sTCDE(})!oBQsz;Cn(ww+GfwoLt)}cT9g}9z8LmTbXeJe4O z{bVCP#(mfB1!Ok##6=8o_i%UC-tXdf`yn>r_d?$?SV-v$tH<|3+qXYK!aHE>5T0V!RL>c%ayZ zk#HbJPM03|9p%lf&9-7maHHT)an6u-`VZ1$)A=uS61=rm7vsbI`AD1hQOF)N{Kcb%HwgvZuWJ&?irhL*0Ub`yn_k|W0qr+LQ9?!m4%Nck}iXe_1|4$`>cc*lxg!D{l;g5 zyng;|Yz(k4a4&Y4lB?)!yL0TS7Y_!o58ImJjavl7<%DCINWM!x?~z39|A9u??l>X9 zAdx#yp%o{4hK64-hy0ai(r`ChSe5|umD+^tO&Z-Su+QpT2YA~q_h|wl{cmy616_O) zBRSL;bmZZ43ABW~+^+g6v21^IAaHt|Vn?!h`8R#_y>ptWXJhC6~azT?Mc;;W> zYEi8)0mAPR+Fy&MllyOv{8nkdCEgco=D`NWvZbZIs#GS{|JtXdR+dF&-{ejppKT^T z3PE_5OKGK%S0IX~rpq^0{xx=R&**6MGihXSWWTR)zR+48^S~?q>0PLp``8OFCm^C` zGwk1LEJgF+^UBl(5q#BwWsJJ!uEQvL?UV6T*^c^|wJrYUN+m7Tge`W%WD;#za0B4cAhOX6FWk*IzsaJ-_W zqhF0Du}Gayr|rW>ivnj{7I-)9Hb*@};WwP^_r#XSLg0uESo_tj74I-pTW$&nj&W?3_MxDGrw2wYxMqgXa~_~I_i z2H?h(i|Nz60||Kt;D$Y5D!40c<{_rHz*G6pPTKqw*bp&yz=mU7%m!q7#fE64eIWfBx9~;e8+}Ff>=- zma)AhEBp(KaPMYxvNz_r61a03y*NSE$wAb&V%xXifT!n7)7ixzvgovZ8#T?E*%3BU z+d1`$njM+yX1W=002d2;));j5=J9h*VFZn`#=^Ndz~or|{EuFAfQp%k!CT&G3Hq8I=cFbx#Mu zMWL?@ia5g9Ws$(3!}-;@zM>t01SW~bq7?ySBoq$iAQ~B&gTG?$(e^lmg0x;+>Na|ch|-*meY(jEgw%YVz@N-sAH(d4?YGaqWS1_vJy}0;D|z+W7c&f*K^g{Y z=gjd}%^9<3U;yRD1eeyNk>tl<$d3PVVKN36TY{*FZ{De2sv3vA7^k44JqmwFn zD2FNqb+<3B@@D$7-j3gq(onzu-OBY%>h!X(^7DD9DN>Z>KVp7;|MU_PxqX$84S$q1 zj9T_&O~KP#L6jJ-=_O7$1oS6ix4Xu9e-Me~5UeIVWw0bUTf4=;w-Cv5eUCRru+V$Q&0o@yLoL7;$ONm^I1=nhSLM=#vFP%0Qv zY%~$-?bCm?<0-Y>bRQw-p(uxVLFu3E*K5lZ$8*s#6e9IwTvjTDx0cAG$Koy~*@)o! zky7JgJrld9{7t!j=Cb~@-3JB z%b$yBmK>Dvq}3gA2m4cacj@t)uRV9xVaf}rH`aD$HFN6`JfAQ*>Yt;RR~MTrXzoZ3 zKY0xxdQLk{vRQR~^mfO*RxigdOWY)y^+P|RFY}9bihWL-*tGY}BTUrfzGCA07=&5w zA=p&fWpjWFt{HhBK+SrU76W`iy)w@6nWP)9WzwrTM~*b~#z{`@hS#WG$HgXaBdvHp z3l_9Ln;Na~;H%R%SyxNWDi$G2Da~6x3XkMz6px18wDYO# z+)Bx}*tWl+p-po&oA6nE9+CBGie>RgmGY|NK$KS=F3K9WB88Qs`UWl$b~O?*I{*#8 zTI9=DLWY6D&SgyI#F@HE6OWK}j?oacLROQnC&n!$2EH;Mnkv6-UVi&xccaF4_VG9C z9%jnI{-&SQE{sGYp!>^q^-J*h;U2Bjc{~K(-w8T)M}BcA zcv4bs^n~6GbW$NoRGNZdM^VIc50Pc`9?1bAU*ZMPG%F7y{~#PjDu-4%NIJ2kC>~C&YY4r&&2p~pwnU((S?Os&VQUsw380mZ^u)Gk(ic6o^k!6(r%_(- z&`QzHQM!5sWVGF%K{%U-(Av})`?xY;Y`;+9pzm(j;Qlm5=GWfKP9Eh{aTDL?9uvE` zsk;g>N!!XaK}59iFXL;(7ataVA@@?hkl1i!?wx)}!y zN6nb8sTGj+TP9$CTC-rBmsOcS_Cf5vbCp)5g}_795nc^T78jSbb(g~N;@FOjwifN5 zKt8%vM0dH1;_(Ao)5VRB65r)rJTA05PfZ=*rn0QDp?dwaSkY!h({}Slo^)SXRPIj# zk+25h{mVss7YRD7?-gf{S@Vz_7VGvFgt5ImG3&ag`Etx}=gF&LZZ?0Q;JBo*E(bCS z#zm?q`9Uf0KQ5QAfp>n?O|Z9jiap+sZ$O+_Vq}yXnFYTbq1Vfi;a&f*sn!65)VYkX zy&)LbYV5i*qaEI*NRaRQ$Jt1%;SNQAQW=n8Z8}s$`b%r5hKNRnm*Lc-t9izLiTCP# zTh@-fNPsy4q5?Y`z~&6f@*LKaM|+-Jrbf5JPv6EJ}3d=f8<4Od2QO9)>~(MpbsQ=K%2{PMoV4)*ltm+2N=LU zz7cl&a4te=$0qBr8{c~1#)HlGG1rc`rz;DhZKeisTnEwgpz}s8Pd%-n{!5mxoN}XW z$JX%T`eQqw?2cW7yWp?t_h?Oo;cot|JeS4v{*|5A?l$UAafeXn0zab@d?hS@spY&^6#)Gdjr?UH)^-S!im+1F@T|O=@JQ`)Z6;(`C z8P_d=!70iKB~U+}evEuiW$c4RquS-5#K*kBioy>hoKh7>?TZYu+s1G|x)DN&W9XB+ z>NnO7aZpe_qF6aKe>tB%Uzw5^-BO#o{|QplR0mFK&fl{$=>P>6XC|=Pf0Uk{^Y;n_ z96U4gQ1c&hPaOEK^xc#JiEXw#EZOgUoZqZ$HNqTie-w~Pa88VSxC+i{UulKM4GZc& zX#0tEA;P&x_jDk;=npW8V%G@?!wIH%q z{7zZO+uluN5V8Jd1pn0l9zQhKDA|Bb&5;JZu}}@D8gEi;*+}2Q8n6%qIpd+ z5%wHqi~`>I*9V6H4kXXRI&tN=IqErx*8T40oqhRYrTg`k{>&fz&f78}dtnJQrHF?% z^VBK45>!Nm`W-VmpEVNSy4jx61fOlZ3rl#$%oY(K$~tTWb3V*HbPQv z&o@=E#2|M^$K+5m-()E(AiZ83-CR2xYFP@A1tzdu&tmC>|CsTd=GNb$cz0lBdRN)< z0@7XGaOq?}G>6#W&Cg-)9Y}wVb90-Znm6uX?3O+bkBo7B<>xm; z!(;C0BNJo4TE-DJ;`KE@`W6>jb~XF2(x~I&N3A@mG$AE2X(Xh1y*0$~(>6>*RAy<3 z!7358Wqgj-IZgK}e_F4C5fl~b9i*o+BOW3DvRIZQvy=T`CETJ*SBg66rMK&A4S&wo z$6ZBD&(mJZoT1;x<3|^V*YGA$VKb6AIL)6sB3a}%M-x0#W6=~>`$>7paXqHzuk758 zN9;B^IO8YUQR;fG2q{MsZc~uo?#^Ix5_fzWo`D%%A)%fgCg98Pp@LfeRSEZqGY(OG zQ zsq=SLkEvdbZhuW9i-g!D$*>1#a=C8)!MD>yGND-1@!jb%P37;wLWOXOW{qDD=xJvu zHfO8H=lSKiW_mtL8EV^|5M(3%xx{rU2G_F1h4woHnKgl3A;E(DfHJ1Tqmx;c@+Cvo zcLU$^tOr7d*D1DUE9Om{%}wMP+n&f05++giQ{~bctZE{VL)}Yx6jPTE@K7>&xfQ00`|dkD;Cx&$U3hs-Dkdy^FX;8b!U1vfDEek>{QJkl#R9Ku_WKIG_;--n z{M}uns%!xd#}C_%uDYCy3k##=zYis61QTG?1*(m$qf1Zb$RSY;Y=5eW2&D!P#7_=u z0F*W;r^8)_nR!|RhoFfWJM!{%?&f+muo?~EkAX_Ygncv-Iagem7*FYj(=?T~3u7-o zw<9?>?EPm*2{Ad{{gSGYm}@3$YkEy_qG;61rsLgIfLJl5Bek?1RH1xqct^^K4eREW z(NSBO*+6(oo<+5yT{JJTA_%iVK;eXHMK9j?K`gbb;Fe~uiwWpD8qBS1C zfCwt(yx-Jd=+$fhWDV;846}hhAdcq0S8_CPlsspX|5sN06?ke3etNr{!=fWCx8q;6 zt-JCs{1V&X5@3_`zq>sCW5WMF{{NgjtIg{DOE&8r2j4ycZkRuVtN9lLxZS&dWnEX- za_E25k&^KK&rxw3d)~@&$*8cfyX!OdcZ%JPZ$5=%FjC_G^ONrx`;8P6MlyM8EK+?O78b@s zcE;l<0si|754kxx?jRdO2`3sFngwOfWh@doxxqM$)S#J}B*8PC03@n^FyohcVm@-a z1-MJ3*SikLn8gbTaq+>UF)sor{0nRQ=zGklSwTsuvlv6acn=aZf8$*im4-gF8z{?; z769=V&ifr0ssP?YFM;e+d7d#Y^g{M_hf2w>dyt>~tibKSTs_`&=q#Q$Z ze+yf&aGD0&!z60`BIJHYFgI^gPFtPRl4TxE1nrEXLDFC~ieB6Wkic@U+gx289JHCb zx28S{T5fsOcf%?<=g!;}3*Nr=kU-RzP3J-&$#xJ`UPbfv?+d3s)bpn62gurHXeN5C zAGhATj+8O4vL3qF4wV|fBz&MLqe}0op+TaezK|7}VcIL;(ql@-yIS1OKWSNeT3NmJ z@9&Rv%@|I1`n5RO+&v#g!J%T76r!1JcfG#~@^0PpU3`i&NVirzv|7+Pd01R)C?#z+ z` zwcZx=z$qm=|Hr#kNRx$Iwx)SgYm2}XnM=1TiWiVRoClCq{PHO;mrVla8ogjg7oYR1 znEd()>3z7!y3A~DR95D4hsWNct;fmbgxnE}FD)`rLGCA(-kW?8|HYCTn#-DMgBo?; zdN)6oZ<5A@y*=5;HFp;qVG)#t9>#&`YUdbJkl9n+KVlI>U%H4DDIIN={TQ4JXb5JGo4XYMbal9`pZ#gN%#v^Z{?gaz z<$V8g5W>!7L_#s2-QHV68<9_FAN3Jc%g9QOsy*8Zt>ll|rW5u#?r$LNn+Orq+L@O! zD((B_s~lU;45)t3`G}vudXUTnzt?#A)F+#bBc?864+jR;TTBzydncD=w&Tg_kL8|! zF@z_To;2g6fE@~~*t<_xwlpj1b?h&4LCd>}YBqmLRu`}FccI5TU9;~K11GPS_B?u5 zUJ}ZQpg4Sc+Hv7tI4-?C0Ge}kUsQ=6!^Fg95w{%0!k`JmrWyT-BM%|~G82swLhV~! zSbQ9-^T@|yFpW^r>Nr*IL!uK#DGC!h$=>5wUHDgyw9~&211B8%7F(CTYc@VF#|~TP z3Bj($GHPIOjm(^!oSxLF14UO?*Gg{b@uTkZOac<3j`*p4g0KD?wKzYcJy(jk@}AxA z6br^~hz1ulq?9owls{Bn@TG$N^Vm|uTdhr97CNw_W7HbZ^zUq`zNHuwmZ6B_1|>dp zvtYwhePwlqG6JC8%pbWIUBORdA5l~EqKlX~O$hPwvbEaSx@GaWa&A0EcD;I8(j)Ex zJ|-7el&3QbVaT31hC1n>Bj+=5Vl72}S4>E(8^nytK=M^F zXQ$-gKt$x1>PLL2(Vq77kxr1K){m`RIl-QVh%H* z^>R0BBsN7`U0s#e)6kIb$HiC3%xrV%a7#rc}F$a^mkYh05PBOgdT2upr9I1RnfjjE#kr6>u_ud4Tptv@PHp zIy4IA%e&bd9|IUPmtpqUyMEJqi+iFRajE{(%#}x-=l$q!DvAORez>)kEkDRyy#1Sw4)dv-RU_KVHQ$*on(@Tr%S(e=FJRv3j;T~~6!rsgvt7>>w0WZJ^6deG zLUT(CPK|PzKVI;kKgyC_QoAKVv=Qm8Wx2dtE|^@=z0M^HS<4>BvjHw!&yRC@=Ohx0 z#@>yC?go;>sMSP?Nxa{dKnpm3ADz98jEqk9 zw!9s);Pj?vXN}5wYFa1=#bzR*wl3-?J9q zJA?yA4{v*S_mjO?KkKYxv#uGrHXzZSd8KYccSS?_yj88sSu=B7KCHBxo1z8q86k^Y zR4%dsmU-coQkk)LR|26!GQqVL}k{ndKxFOf* zG+DXZ+oLii?H9d=RscL~?;q~n5Rs7noUUIR*~D25DNk5MdCXj2vrf~I0Z?Zy#sBfJ za{m@SIBQ0@1D41w(Hr65=3XUU&f&OK#j--Ldad)R-{9r7-7O>zV-l_pmxMvNO3muZ z`zVNp*!QSlCdLd8bp22RQu6~TMFM9Rljj*0JksQJcwHXvy|40g0!&9@-5Q&l9iMM1 zG^z*<8h_l_E4rZ=d&?se^66z|syY8Ks-++(-_cpOw_z<%K?`X>yA{YO2ZjvkkVrVi zZNMC{X1rZU{aO2FVIHB6B@)F*qT_7|sWg6|F}{lmSu|0GK&5(W`hC3d_BNb(`1ZvF z6(3PnvP(!IzIVj;L9@rJ%S*_yN_W{v@w85D<^w~gw9wB8TGHP?W*c7WBz?LbtySpD*8n5u`j{Sq#d7IiMTaPnkioUQO1u$$ysCde{L_Ts-#I zy|)ghDFh0VDJ;6HJ&r@;moYJ5gr_VpG?1}+Hh1=#Q@59goLrimm}*CPQX*=uP8Ifp z@A2*sy+3K{e@s;8Fr;F;Y|cM+Q8mcIL<0mhCu8fNjz$-%73;yKC98C?!8A({Ey#Wn zMTQ8BW;N$^frQZNbo@9zBwFhclS|uU$#LIb+xqzUto(F>0(x_+)UyC5n#};6&j^98 z4M9VO0xwfEA2;t5WJlSdmtOVjfi7wlD~BE2g1RhtTW^PcK3f=IA#wvfuj;SOE5(fMoh#Rt($b0IwF zpyy-mwfp&k<_pNK2k7^{KB3Q2Ly{8jb6mo*^qOf@Yq_QmYk$2D?9rTm&Cb4rX8htP z{)cd}GMdmK1xtc^uGLsIZ8(nH$Y9JGLS7kas>ti%t!Umlh?QNms7bVf+Gy`r9pVzC zsL{!8(T}c8edPgdq!O3$YIzwllsG!?a}E-}Y9HmMmMas#6T6SgD_`@@7=i1}R|U|z zl<=+QgeD7t=k3Xr&-I$3&rwd38u+{a`=p}KM+N9*DSHup0LJ{__(XOm3g49M8k^z1(=;}<>}AG#><#qX?;P=At9jjdx85K0y!@R(jD~Il?Q|%D z`a}J8YOtAfdG2FlL3^+{o`+?Ai+@*DJg*cxfj6;l6Na8TMAExYgC#=GgT=4Sf<-#n zKnue+knn8*PEL;||Jw0)Z1pdK{V! ziJCgzGfuGX$)?|NC}K)DiHGa1@4do&ywloL$)lnbTmKCyDm|h5wD%bT&i`8_7M9dC zDY(5Q!22<&Y(LK#*zRYPtpYVgygIhwGpfm41EA6^W!X($ju#5>eEFqG0zs2_b`dQ4 zDxjfa;|e2CNFfiu`ujtW!pT7P4V0;t{Hz2DKjgYFm+ij)FQ@`h6i-jzLJA znQV{!HVfaUfEv(y%d8_T#R?CVgKF$jvWD#G^B9WIqz};ML&v4>4a#QhtumdtpFkr1 z^AjO7DumhY2PRA;LkX?ew&T(g!pUK%;Ua>gDDkWX+x=#|zN_^s*)^ZeM$#<4ABVEAXC~niv`Ahd z;uRR+ALfO&+{U=s33u;x6B({|T^#`17GvtT2rj*?erC4wNF{s4528V8!G(R+0zfNe z7Q}t$g`t#z^q&!gD-0ii6_XgPM^qo;mAZtQrt<&`N7L;fSkf8x@~kX1hS|BJo4gy` za4DXDs~(~K1`INW2n4D?AG@B4onWWmmDh$lT+>Hn#p4BUo9&VlEG|B~NSnY+a3WI0 z(K=}Mi>pxW%~QwL-7JpZ)7#zEoa5T^i_2OLehrNa(`nrZ?+7IcB%g8#lJp!j+BNU5 zS@+5`E_@yF2tJ}tsRjM+nq`=XqY8TM?BA5gh~l40qQ{2jD5+$Atp{m~pdt=1ez6z- zb1~!ZABGyp`5j7XT@b9^#H9&xM~v?C0U#QB8-$-WX(Se^^cp_OY=B#!95x4$#>dmmo0HCwF*bph!X59vsXCKml%Bpn z{(Dv`UXzZ4;m`H3e}dr)Mzwk0(+*u5pqcyF)D*!d@?3}Jrt z4G$V?$6;dx=_F~*#no`_8MhHGM=CU!ANj|wG{c;qAU=8RJ1bm)( zXORf{6p?0>Yy?Mb1TgVO^PZOTa`QX<+ljwr(C)k}iG-^I%6=#A;&Mq!|001^4`nm;{e_GonsR_mz z9{fFWcBb3?V78xfm4;iDuHTU@V;|#?J+$g1w6fIUS2g8e2fdA^NeZAOF)1cmzgm_i zDqVbWj5>p+cTvaHTkHeSSs3s|&N?z+u$=_VB(VGoTghMwr8PfdCH?NE;&maZWxePTed9SE2=+RzQN(D-k(VV!WTX+ZycNrE;bho%kIkbOWNq*eYL+r38w)_=-3 zJZy1e=pe(;0|WeN-BEOGzdNtXZj$ODgE!t7Ir4(BR{;|#TMmbPuOx5ltqZXJ)<-Y> zCS9@Mx{(N#o!@OssKIe@k`Ze{GpL9q5twVlf%(+iP6|YV_t%$4-5`Er=R(Xt zEBk~fA$`Le70stxx9ix2gSZzA1@`+^yiT$YvT}$gGERsfwh@Z7ChHNU{k9I9Oy&`w zipba1U6+vfg9w4a+6&h@Z``-nfQS$<2(N`~f_M+KBO)g5cG@5!=#HbdfucwL%1Ss) zSwtoe&1xKvn|PW)V5G_x2k`Gxw@!-)6I-bJxe_lp5<~R7;B;iL$xMzryOL(##1rrh z?9t&&Nz<$Oj4u;!M7Dj0h>*>R291J?1N+i)_g`1&w;?@lffG zmYB>4H=XCNoD5|gQnmrJ$^fe@GjEg2+Ph!3`$;)MAE8V6gk`SYo~csjnM91?ItAhX&k=%v%>>4Jo)erq?PBBMkp^?& z-)#920g#_A3&>m4BFI(1B|NwEGTw?6@_sx1ZK#0;888%?g7Qh#iVFo!=vUd2(%Zas z_=Y&Qj)8XacW|yh={b*;_@N13BV1BKLDwgr(I5QrbJBpir=x#!aZ39OUY_x)h)Rj* z7uMNkJ8(jp93IcN6f`MTtZY5^ zB{QdKT*daF{D@8A3C}-9`aadhVma+bBw>g9J>GRr0^mBw^)$> z%ImrzVP;GW`E<5X6flX%YUUY5K%Ni@7e+eyUDYQd2!A8Wt@O~2*?%s%EPNDrBj3)TEsC?#Iz(w;` zAXg$GNXovm__70~KvZ$51$@eKvwgPPYmCA}mO$;T9(P$KjpMG{aXwVU7I!uw`1`mY z3cP3qB5Z7IxRrhG6a5pdo)ve%D}#Tu^Pm1e+{c>pyOd2Rc_P@UggY2j>09ew3=&v& z9m+jyVm%Op^>Dp#thOD99GBs`m!j00al~s8BkDBlp`Z1eE$`ReUM+rkul+@y!VV9~ zeF0z9h_sUvsOiAUos-1R?J!#e6A9Z?{ReUdquLgW_ip_eUvo|Zy@Nrx&C--|4`Osk zWF=M!d4GQyKqXoNxg#$eVE9}<*8tMYv19b?Wey9I1MmqlsWCzJbr%7+c{j@aw-5vE z;67~+s8pUbCrkPZUz+sa3X&d;<>50J^-H7*IQfDDHW7dCsM80c1hh9Edc-lLL}3a4 ziR`Dol#B51j46m#c^{UHTUJ9f7l*DL)+kcRQ@Lohzlyool4gJ>??2(Nxctp`!1?XE z4?{xPIce?D1RC52R#uwKcg5V^+Y~U<0#?Lq47)zt_icAqI^eAD+#1Y=chGQJ1#+cw zgwzpzj2y)X)PJ=KaQmZcGuDfi2XW9cR;TYou0`RD%zwqr`0W&R<(yvh)XFbxw{x_} zaR6l_!L2xqBh_3|WOC#pBYh&5?hVc4u$bwxK8Z-$(rPn#zzDJDW&S3OK5~ww17LC- zSSp}VidPc-wWLT58D=E;TVMuGNWKDCa0l#aJW}=X>6%b;esS8{@xzp8aiIuBm-r@w z1_i+?(yK%|nJF;YT1*n0W`vE(QEsAlepdE~Y@p{bvWf(&hH<(1c#VS;P_~3NNo_bG zVx~h8N;W*1L#k)&*u~H^xr)otmb}zjfQI&&I>8Q=!)Vu6JuUqgCdL=Lc3_7T3WEaLi7?| zFcRZi?(}se3?c;GK03^iNi3?uQ{dOw`Z}J{Z|(U_yd$i?oos;FzDAprtXwyxI`p1Ki4}iVh>q#998Ba*q`z3 z(mdg#U^0kzhQqpaVlmVgY?&vFN#N}$cIzXtr*42%pt9EgD* zm7m0JhI9aI{!07zX{rRUFrFHKLQB5J?`K_xHdlID6W*kDn>~9=>nN1aV2B!jN*Q?b zpUd_~Eqr{3Sv=n7*HU!2fw0~J1K{b1xe;HCzh^u=xJiyDI~?3F!fkMVrA>w_la9FI z1MD)qIB!+EavFGTu_li2e6PYIt4<9-@&6i6xi4ff@>sPMXus>Od=-7h#^GQ5VUHn! z#u`fSd6$q-IRPE9W11DwzTEvvW-c+H8xfQCx%oZx@r}KY-gd@Q;>vKA} zf1c(8`p!4a@*n`rs5-1I^*X7?kj)XMzY!qt$LAkD@9h^`6OvMf03|kN9z|Je;}VWM zxMbq{5Wt@j>238pfaq$HeOC`nr z@aNKtRnuKC5pWZ@GCeKPhF8iLHTL6oOJczFm)~P75i)^4WLFm*{>a-aoSgFA_5L0R z6=o$K)(r%P(bLxna)Mjb&P5p>cZ8=9_0tG7Nm4Pm!D6QRs?@o&)@LMU#+9*E@9I+t zd?3IvsHw#RrAY#b5&!|<0DK+%O_>zwVL%~6xFL8%%;S4|4GRPNsv9qk#zpDN7naW} zXB&j9=YWIFMFk-eiHj@`fm?|L;PnvNp3dZZ6H=$R<8@oFa{#q306%^(s-12k2)Pdi zIH(_v=OT8r=Z%u>_Ck6vS=_yN<@{uFq3-Z)JZiy6G1{aczkzi6=YwGC#U&(!b{v*u zX-%2weiCvC5CB%T?OncGFM<8Rd)3(<*D(1;{zkO9!)t|VM@%#vwi#TD;DGC=xCV#2 z5SlwixyMVdj~447sMJsMbmY+^(+U=H=cL3Ef4)V4?ZdTnNC;N*_%bp=(V%bZOTs*@ zk8dlgJzB0dQj?J6@Jv(|Z9txHXrJt|jY7gFg%nEwxOVt$u5+zlsY!>YFj9TP`J7BE zu3FD3EM1JEQFtYDp{tn>>sB&&p&>Xv*I8JDb+>!I@SF0cLcd(Ui{R>lo@1SL@h(NW zlzH!Litqtm2}E|gF#qev3JR)CboPm6NMa7C++R^PT^47WEPAcA#VS?t-?_%!kHkA6 zuzSV7(&9pn67mv&>*a_b5zg054g6NgMoKDy$o5GDF>t1Y8qcYE+}*&S?nhrbi`|Ml zNK-`lpNS8FNFkq@#tLn2b|~3v;L*0Dz3{DA1vOWXo-BdDT$K*nR1%V1a7pM8CM6I8 z8-Fd|-{|k?+w>=z1WJf8UZ2P9_Ywmkd%s$IxKeuTUU}3;Eodd^(A?3Cj=>F0Ff|x+ zcx{j4RI6~&T(sn}`JXl931vkz81>qBCNi3ZZm}>z!_X!v6j(V#;oPCb0Sw6^y>h9o z-)sEpG)JQxg$fjw%D9`!CgUr{tRuNh?5UOnMZsnmgc^Dvj+%-Fqpp{Vy-`d<$;`Un z;Zxr$*Ss_l52VmM^AHAVe??D*R!;$~r#{#s=Hy;}`24nC)jMkh-pnu(<1HeAs+!EG z^L!sKQPIIFF*xNpMuC?4-b;S%iUGAV#kuf<(^^cPSYSsb^K({KlAu10!j=0?5st5z zI2>6V&rrBhtv@cSX2|ouFF`d+6-#<;R^8=Fd;Mvq6OTQOKq$;#Ly^hCT}C&j%(3M8 zxRax1Sq zt}4jCN>8*x0k)Lyq+&C@jRuc&z95;J=Bd#u<0zvJ6bl=Y#;E^WPt0+ub)$peV8Z-4 zP#qOW{BGWTe2&~0wd)?Ou?2XBsNex)xPASME*sTeJ=cp2pQ(%D0mB&*?tqo$D&Qf06Ve@ghXdz{KfaF1;{UL}NasgUQ1DMX>JBrO z#?X7&bAE85QleaTk?*0 z&kA|kOJ_t(>A&6{tN|zslDAbnc!(z$uecF1!p%+PRbzn0n5UC8`Uq@Rm5Moke;$wm ze*6qq`n-wZEs{k_?mzv+tHD^;2eu7=T-KeWl>$S`Ng=g0D4=8E5~&hj429f5Cj(#@ zUAE4?5GMYdyrwxXRdLng2BTCwRogaRQcM6^o#;Xg-?K& z8p4h@$>VbVx2c!k$KW3yVSb@6TA#@nF5QsTT3uUfRvHIANhGF9JTl{vZwAZPg3OG#t3Yogyr6iM3_mFYB=)rMd_H^;X(~4-Ep;H79@#fXathLXOjUaT zIjXH=YWY|O|D-x1Gz11T6=_&wbd^EJbB>M<#*NVI+FDC-!78ux#tWBB>Q~z!MHywz zP`t%PAF}j2eW`D_=V4wCyBaNKW(;_in)HUyI?Wi8w;V<%19(MQ#Z!$W zq8JdvgCD-pv=)l8LZF>~=Tep`>QY(jvAeQ!b;+wihKhH1N}V4^5SqVU%rN+L?= zlb8d_^t`Idt7~i4ES;@a+%wtyKm~BjE&+r{`jZ=;gp*vu<8Xvm>M>Kk5oaL#*d!@5 zCMp6Y^viUXmg8gZreaIduvLX-72kJiN}1s8PYakN(7&Mv|A4(b5Mm;gVPslwb{{aA zL-26&l%%c)Ua6${{^UAe6RfVvo7_NS*I`u;E2E-)q__&ukUYw2(4A6~ab?y(1kzNv z1jc4nuwKc9RX27l4uImI&;tA)0INV$zXbzCl&-GsC5I0m`?Qv{wtD5-M!k0xf;XH_ zoXk)Msss!(!w5wHgek8&$A*~B$Xm-00ZLW}z-GNX`%JSp2fX3W7j#CLj2I?TL^MIw z5iFodLXx)iu35YGPliWF*5>)hLIAUXs(^tyMO5)-hy^GDX0a1_6h*U$4IEKZks?zB zLkT!F+EhxHV+69{%&os`(;wfpdGizXI`u16`5z|c@_VF+W+ z`-~6*0iX%4a1%w*?ISjyMsE?%OoEt!uW_-zcf*06o)6r$aqH*COIlyDcH`+hfT?0; zud(B&TyG$1lZ?&1bqP04L{V+5^IY;#pV8VnUfTWqcmB=t6)V26)Ga&UT?G?|U?6_l z4>JG^0f@s`-eO|Pbao40fhdZiTayU|u>dFnfX94|f$rW7Jr^$3`^{TE7fPn zeF!*J%x>qd(}n<02do4J2zC?o*539rmIf#)f~b)D{1Q*%+DgywdhXvWU%vPoOO`J? zAkvA%j~h|cR18C!cpjbReAiKvv5AC<*hJubSNB85P8|PGbza94^^#Z!MnG|?5}JC< z?c8M+@ZOVUIV#$?5>AWjS+-*7-<>^s`u#n9{Yx%^>s@M7JvM!jD2kd$lYR_q(zhMG{jA8V$@3hady-V~zJ^PL z!P-C@fQiz+XxaH~54`J-R^7SzU|Q`YNm4LR$OD9#jUj?G)^a(q$K$QYFaSgZCyJOM zriiPuY~_|yTerXKk6YUoj^YJBJe-zGRx&)^XNZ7V05i7t`r^o9E<^ zE9-ixG`THPxp6W*H~#y(L9@?sqN+HjGziW)R;^rp>YnWn{BhD+9W^|od0$#8`z!Tc zc@1o~#NN5LCB2cn8LuA)HcYw=CIfEXcOEr`q?m-tk!3Ynl9Il-|M?$#`Q;Qm7E+xBm{ooV*{oPAkqJYI=MK>oF zg(!;NCX@9(CCdUWiPK|8kN()fV+ViH2M-99c^xOUt!mzsEc0_{0&rncsZ{26BEl>L z>X++%+W-NyrIb9s``J(QU+h}q5`X~2A&^lNT}M2Yjoy4#(@S}PC-Fk0-}Uqcry$En@ZESAkJxWWoVM%QS&%4QYV-M#7SSJvu)Q)`}cgj zr~CX8RRN4wWHv3aA>>VCye9UhFU+2JelLpNBv#~_ZE0jSR@8fsQ{}}M4}7#1N()xr zbO2sp zpU{d^12&nryS`6lmSsZhnK4Jrg?()FhS2G`?)St1F@%8Pi*=rlED#aQV9BBt-`Ki! z`(x#@8_u$v%K;E+d@&T7cRrhFx*4p5u zIf4fXF!B7Et!Q!l${S5g5vDN^-hL+6OEX_lA&Q!XO$6jRXEKDzgd%x1ygl=vZ>vFtTi@?MJ(w`T73-GpV{9$iQ;)yoQKPYwYkv1dHt*H~D+J zTAF~*1J1q5^AwzOMMP!R107L8Ri_@CRxTxVc<*0BqsFWC$x!S%p~$t{VpEB8i$rtY zZ0A!a$<@O}&8F(Lis6(ZwOaR*Jt!VTrkB>!B9z2sSMAb zx9YT*;r%r`n9#t@#cGxMi?*C(-y|clJj zHG$Z`5xuVADKZ%WpL_Bw!{-@Es02f>4=agxO z$U-9sB2uhD!5p9nN?Y1CG_TrTJ9hNYXU=w=UMM1{3Z0#un1y&S^Cp?>y`g{#q^Xi; zyrSR(S(cG!IT8dFhoVShnYgW(2cP>Q!3RPPSuK#d6hXkI(%422lUUTE=$0T%O49_9 zK(HLdz+f!*Ek_R>`S^m)&O>YOSpBq{_|TI&huC#5-#!Ohq^HlpG56+~5~0Bq%uPf| zllGx`9o5>AV@E&J)pdShqK=RUQ~)3M<+r+`aYGaGEHCPLwNgP*#H6uq+%5uw`9QUj zU?Jc{P!XIe7&uWdLy+Pz!F#Hm35HQgQfh;Pv+h2`rZWBK#bGIPT-<*|v#{CwstX8) z8aRV$>S%Y?l4pGjvf2Qew6f!&AOFLpt2X|ieO_l>R6syQvDj@Qn!#ugKv7B9zWsr3 zu3mlTmu#%O)PfQM3=Z}n5->bQz)Z1t2L25f40cfx%R+lD%Y@? z-&MJCJI>$}MX#3tSI>n7wQK;Bz-Sn1={|pEL6+qN6E<(!@rNr{-}!^KwncR##Y{jP zMjS_Wy>eHtmr8SW$7GWc0ZqAk+oRuHx%SR4jg8sT5Ikz0P#eJE5yISR2fM}1sQ)O5 zCOA=2mjHs#0_H)cPr)|rq($Nq^33?cpMGKI|NKAw?uUNx%(E*dPk>ZXK}Dx(__4!B zmjC|m{lSO6{KYTr^tq?AT1C(+nRU^rG{oVob5;D6N3UTlodF)C5y2y7fT7|!c4Y64 z1N-;>&e+&kD>%l3j@fw2XdaYW<}owUG$Bb6BwpJ!x-P*Ce1JR)ESkT(YstcuFL`f_ zdhD7^ijAvL^eVM}a&5+S7-^bv?C7x_M-CtPo$(T_&Lxy387r6DM-x|N za4^SA5K(;md%K2B%ra_os1u^e_3sNNHlgxo_sr*kYzc&7y2rn_*eh>KYZ+0KKi>~dF-n@f)6-_tmdz+#RiEAFP}Jb=aGX) z9z1dM_(D~vBo(0XJq66e{+ISId~xr-2M@pa(p`8%jjN)_b;Gp0&QHPddVW)yd1A!o zeAm%iK$zs5qH2VYkyac?Korb8r%oSQm*;~!=e2kI<@}E2=bWoz=1>(>t$4185WHb# z$dx627=4YT$ZdLNT8d0i)D+C2k|LLqxRj1c$JqFoU$y7CUB5k=4_6cC2zd@6;JwGp z08ouRI&OrS6`9z;`@j>Ae{);8TrSne;hAT?zg+-=AOd0n0mLZQ82B8_2U@k2k=n@A z{2i%+1n@PZGfmKXnU=bv);Eme2pLFFEI05_aTM!BiZq^YV0j=BMFKb!LLgDa$>icuojdfJzF%2MFLM-oN)bgSA1D1Vq5R&4|xES(e3pQ*>Ln(UBmk4ge8Dgo*L+ z8D>`GQbY5)@$vf3WlL87WwkQ@oFO2BI)@LSnqVgQz_i9^n`IJ++p?lDJDupgAyBuH zVTj#sb7sqom@q351yh27h%2^5m6oJDR;vxHdiMKI{q}IJR&`Fv^Ndi``+RDss;V%H zIE?iTCZ^X0NHpPZ{_1bH<-?<;dF@r6|IzO4l~l4kGo=OupZo~$T=v4?I zSaHDbLq?Jcc|O3vVDI7)@6{!amNwUO=iQtCbp6InXYHy#1~I!$igxs-o8CLXWGc=H z0|OV>y6v97T(oe-cLw^hEqRuaqzUS@F(zCU3xV9{gm~8QHB;3hAp}GefI|n4Y;V!l zAsZiObaZU(!Gp)aX7QWX+`FfvA^wVi4@ zj|C|t3KAd@nK)=^+=mAYvO$mlsZ$iFBuX||!;v5X)Bq0}pw^cc+Y$o8B&)5 zoPy5-qL3sBl}d#WzzkF!>KYMM)G3v;f)76S2#V&E5JGWKZ)Ov{I0DWYxxcu0G#^s4 zKzmy0S-on*pDtXu>a0kD2^h0P!tL^@{S9L_*|1!n)3cn5O$#$+dCtxU@Bhn=g&p7N z9~{_{qS!!C48}$kL?Q=xdsmEF^?21hOyWHG9)0Y11Z6(k$e? zLYkz_Mqc{?2_$B-!Dg|+1`IgZ*qFuOU6$q1=+2!d&)E8G2yHgrtFiv?JKr6RJTsDf zX70IX`HvrPh}0ON0{&Kj0LJy=og!d-788;LbM6NWJ3tgga1PVCMu=fgwzisfgwrX* z;1g05_Zn`9KGML5=3}eUJ-Yiz^F2B06 za`*J8C{b4!ht(e2uBd=d@tfQTP(Zi>k@JuMK*YxRm-VQEIbuLjX#VqW$xXF1oEEY} zG9rVCNrNg9;*z&gDjV5ERaJYk{fZJUu`nm9Z*bKJ_j>r=rri@e2S?@Zy@~Zl>r*G5 z;VDi_8Fbj^Z5Ij)H{=q6@NY{2tXTf}ga_|gc-QT>-TTlVe*cH7+FKQ|D|;hKjDk}( zqcuCW*SQuxxbU_G^B;WVf%|?n{a{U9QcwvZ7zm=Z(aflL`K4E{zIVaHa|>1%xu1LX z#cO8GSn!aqjfq?V)~;Ng_1Ghi&6;`h?1lF)SUBh7zkWJW5+!hEmbWbX$MPYs{o$qS zX3xIs{`>B}`@wq_+&`1(+(I~v@3ds`U-EwY{0lcNn0MF0JLleY&l_*Nbt&QI_mD(l z7&)S78dh921u&0goTKYn03r^v2nGxYAy8G-7&+%?ZEF&D?Jm8#a?iHuF>zKMgd--# z)gJ4N2c4&YvDr{U= zoGXi_<3UwSUawWFzL;>|{SV$XbH@CK9)0B3R|PwRA|+N>EEX_kdj3kbmb>nq|DU(r zH~-#8?p|>J^sn|-CRud>LNABPGfzB!^}TmJFt@m{$o=dyzq#h2d+vKk?eL2t0X|!{ zD(le)7S5V+^UQ@0%zt#wmn*&)>GuN?p->se+Wd_}o_zdQ*Dbhf!Tqym%nsQMch6M( zJ_}RLsLiLJe4MxN(Z_GPdw$5^m^JsF-@Wk1OH~DsB?+-k8BSR??1Elmc7~(WaDYfu z#OaCtdnfh7M`Q#)EVv=&WTS%eE>S??H--BV@01{d<7nN1NuofM+%aQcQ8cEhj6)Qi zkYp!_D1w7^r?!%aQ)A$ixt%gF0E7~#Mr58sRXM0d)X?3wtF86eh4lya{ygA2Cdrf` zR^o=vhJ`D}-vKnjrhO8!Fs=eU%=LvEH;%P{>X%Nre8=cf*=4@=4(!~qGZz4Q8rXdC z<=U*zmaVv^dVgJ9_K2)9UDd6PjZMStk^>eZ8U{^!JH)r%Tr|C{)i>BKJC9^!WK@T` zDxE0^0;rXOil(DM@hfrOCU4S;e|&yLV^d>}!{P98&aq-ee%8{D|K~DY{;q%N9BevTp4G@^+D{ZZQT3S+?v2JxyMse}Rj4ee)h7=bTXB4g9l(DI> zc#s)cq=*D%A~-$Jrzv!J&KIGC#2*%?3^+v&D6MFzKQM_0I+QaeOnik3k|s+|qtw)= z0IG`atS=sJ^~#UG9_i1f@ed7--Vg*XV1R;?uXjZd0E(&_wj@BoI0doVv>xqhYdw15 z;RAbq-Wi(j9ew6|1r%!EMzy3%B5saT0*>(iYwef$V>#3G3op22hiBY`GNO~vzSX&0 zg;@qlft8;ZWPR|_hu5e!Cvjhif_q1i{Q|(z*D?8?R44di3aEm&+c_bawCF4>xChk zA?R16zkmAajfbkbYz9D60=9SmykuH!Rdvp&>`@yonml=3Qet8gB@_|`mi>KM&KF;N zaizDp&2ho`lRtM49lqUWl>$sPOIX?({d8l&=8S^1g&Avm$@;bHGS;qHlTo&P+aOg{ zar&Zv-bWFue*lAngHQlaLAZ)|Swd^`F&sTo=V@ze_6Qd4;+m08*5Gm_myS#sRAi4$ z>hvlmb2<^JS%D@I*Pc7IfNFEt9RRU3#3ZDZ4jwwH)UR@ILct?CcWOWYg6`7J?y#R9UjR zho;6ODJcnpV1du)Pp_$}Nk8oE$VnNlFJ;8;10~?BZ`~R1&fMU}c4Tsi;Ja$1dV)@w zEo8gPD!>uYf{w~PWm9cLagWU!f|!^Xbf>ST*VNXgmu)M^$sK>*QpTB&kpAq0?u#Ef z#gtM&QGiVwHf6N?ys=So)XrTM6{!JLMSN^*eT%m_ZP~KrV;{Kx?tH?5qlbmtLYNdc6g!w!KL5GDBTz>iG zg$c=WQ00JT0cq`MPvSw2&6~DNEGj9Q5MWBQBuAmCwK)z17&1Ji+2M??JAC9w#uHCJ zJwG!ubH{bpURRJgD!aw60OwCWzhXmS;iT&Q)uU(6oIU8`DHm_Lb=s|)2>}yDiZR*Q zO^g5h)>9xSD22(_;WxjRPlcJTKTy125uCQ*z4#3%y1<|X+Z;Q~il(L|#=0}dXTt7q zfNLD>?d|EINNW1_l8redb1zsbP~wv$hgrTA4vm=n8U!S~S~bBUOUvW%_09|(108+J zRgT}_1O(lkwg>|Yb~-BeZJQcr7u>GY6ePvR!fB7e(dOp#{RfVvZ!TP$GvmbmDBmgMcvUTG2^0Eod&8^W^3q`=M#DN1Nhi5h?#KqTD?W@Xo`j@|)pD}bu z$Y!{vU{uc77GJ9$mtJ&9#jdg)lj;xGkAC8pPYfC}I(O60Zn$ByBhktHeqdzwh^9AR zfBh*!`uJ`^MKkM&gM(6WK=bOH5=2T=BKYng2KgT2K&(SX)!wqH$w^N4xUpFnJu(X- zl|Xcggy=X-7(W^|NppV{T2#iz%HRg0HA6Qd{ieSMbo8Kq*Vmp3x_=Vxqs|PGC1UVz z?Af(#YD#i~+v6FJgd`WDcX-niPd)Xgw6wH6A-!;}{&MxD&p!9;bWt+vfjc@oZGZb{>BPUh^I=H- z)<@oa``wA}fBew|uL4jB;DkqrMkDCIAga04>n3rQs02y~WD%&WD4Uv|n&KWjIKy~u zidNC6DR;SCNXr<6wA560WkvbaSceEz@dJ#3@PA@B4zQjm-yUYT*g^nZ&;=0m!ocQ^ z;vk0fF@6Y#ED}KVVehW;si`iPJ1cVpQqz(lNsR`51_m!WZxxuY2@F?-D@+wNYP` zBdR%LNLuX~d7i={!-m%M+$#$oet5~0ODxUmseD7}`P5jIIA5DDk{SPO;``(8W z7ytLW6W@FHuM?Mk@{b83C8uFIbpLMe6uJKgFbDui6d_T9$~`+hl0@8@!v}%t4DGFL zAes(Qu!0f+f~I2J*lfr)>fT#X?vW@pjs@>K1#=#8Vn*=8g7gUIhN10iY4pTJOYWhA z(_pojB$+b-LcU}qp^&8mVS1VCy^QZ3;+_E%MmuE2Lx#F z`+%XthSXRDy{ptM&DW|zmVjgRM^X)=Ca8v!bTlmpo6U+K(cy?E0Og2Jj^_y}vCTmQ zF=W`_<~wH0$e(-X-2Az7=jC7Vqbtf4RRyJh(;;ei+;Q8w7oLCqB{|Ao<5xPZt5&WY zrzi}n3Z$o{xBcqbr$3l?*SxnZ7NS;HSEp~-xHW}Ppyt24P3h0t(52b-;G6*jx)$mFak8@M-Y>w7`M$vuZ;x^h%SbaK z_@sM|x7lp4Q7fQo80OAELVUEly}iK$ut*2LQv}Wd5Ho9{w7hi8$WbG9&z(1S(X6?% z7Tqy-=AwCb-}yEZG=&K~=F7F~hKM3CI6bY_9%aMsUAxl&Kme=&PXqv~l|mGOjKPCy zSTNX?J(dOnFwRhaFA1F=)`iV8*C)E8&c2%^KlwCMGmLyl_GO z%sF%O7u-89f9g-KEth07(;_~}q0O3e$GYGC{>7JK6XI$prPjiA>&J-%a5@NvW(;Zj z-EW@!;O1#Jy=4=icC`D_x0mfm@hN~`SEOAPJM%Vf-k4WxNKxLV&4rEOXbgFF2JyEV#cbi5%VaPE0$SFK&Y21gr@x*vb) ziJyfWOw7n2Si+Arsf z&Z@2a>MIwqP|TY*Z{x=Gn^M=TSv@`{CwG5JN=i$N-Oht*0IA8z9TKH@XYu=aUT=F; z*68g0k|Ys})e5F+dO~7iCjexP%4&P@#oxZ(SMLD+b@vfBe!BsqClQ>!Am9)wK$wb# zg9kk0#tem~1`z=7MSe+4jw2lqARsL@9#z#xJ+jD46-6;JKp279|AI5~Nb;Rc&H>hG z#f3JTLPY;X#Sx9#wZKjWNIMI`{0KuClr`df2#og88EjpfUiWr~s*b>YPqZytZ< z8HYuJa7Oo-3AsDBm6S}}zGHjtlqna~W@cwq9jZS(V%xSYmpA>cA!+~qn!y?i+9?&# zHE$CNTzJ8SRiA&p5;Zk7?u8FM{j(^$P5bJrYPSvo$q^lXY-r$sRfNr92Pn*dDg`dO zY)ZlMWy`PMxOL;Cju$%QoH04IN9vEb)PRZ^x6jyEvUN-9x^?Tvk8ls)?;bj=r9)A8 zo6iTG2ptOJSoHckd0gXBIitty*El0qQH0;;(_>vRoqnbu!=2pr-0z=$T~UsEc9Fgu zUBI{FcH@NN+u%fdpW)PkfN;`pv&AB}{r~{s2#ez9CXYc6w*fZ^Mq3&iT~0@|=^Y0T z34=vfVL_m4+t^2RAU4{GrenukO!Y(YE9MkONSE|$w%rK+?GTPOQf_v?;EDo~06JG( zu0$s+#MH}^gG24~x+Ian;h+#HF+C>Xp6UbJ$IA%=Q&nu*Qk-jx5?e35Y;p}hu1v~v zR^E1<671f$cZ}DsST4Teva)n{Mr|i&)}rmDp2YOjy)nr#q1Or&JqSMsvL~dsk2xb} zeL!G(gSRoe#ozA889z2()in4u)g%i8hr$#Dcn}tmz^AHUTm=WiRoDNheA49emdSRT zUQw~@ybnJ3@E2A4_MIQ->~wMt5I|^bY|Q%PlTU7V?X}nDaL(gLXJ-}Pa_h~T{eA^L zU%OONw(ac2ix=Pi_S=hYwL9cvmtA_<(h(zvws9PX?(fM?(teSXfwTaN;Isob4AgLU z3Dxg~2o5S}t~iI?*nctzI!BCCMljg!0#q>79})#%3?c|b8d*GkYg3zZ2!a6U5j*Lh zfiY(2ngqbY6jy3|EGz;C(K!$r0TNz(S#%Cdx4o(=?JiLyaL5uQDuQqxp6|obzq9WD zKVbw!RilN)Rn8Ry|(!xm8kQfb-tvtNDl_1j;6^Q~Ls5@L`2Y}$=W z6H}7fM2Q;L@hc1*y@YV^(|El@P6HDDfot9W+v3}K$jLWxZuE(Wb5Kf*(XaU6bV^1< z$0AVZOn`-0Ab>#^R6t8ITreW$BIO{2L1ji7(tI&6jmkEt+q6q1<{0&eawFY*5d ze%zy&fZ-J41a^5*mhj*s4}R=$IH0J!7ojEv=RmG!!lBpSdHX3U0$_kc5<8#x&0~w} z>s#!0hdp3-h)iXGC;>j73O^WBA8_0JIcsj5aZ_Qt*Jn+PkM~nTFm1*yrII9?XBP>c zcx zrA5xjNcV!6=a3x|?wB>ZV2+4_hK80Xn{ z%!co+KYh=sLRI~6iXu4oBg#TSbet6CdmI)a2*QJgb3>#KGiyWTp^<=75>epq78BKt zu^)tk$SF=RCj7)_B?W;b$q)&Juk|pX1z;68gwQB}13I7!Fh;@D)iAeKw8I7hZnl;u zVz*7o!<|`r;Rl-g`&0h*_lMKzgx}}KV~;=fF}mCM`}}^$4jB~Y96TY9dpB_$22amdj%j%Y{I3FQSK z_=b!JCpboWpNjC)qx|CE4TPVlIUM{X6EEp=3;_*$u|axU3Z#$TbFlE)j(gwS;yuTQ z-79@udm<$WbohiLP2OStj`lHVPuA0XZ2GaYAeLe;Go@NU%9R(-7@B8qnoobvoAM-9@hEqXN6f@FAdkjGaPzr|= z|I6OjKDlw6cRpw|8nc7JJFqWYayg(ViRP}}R?$UgTe5X0`9tc;ANU8v_w7=-i_51d zQsS$M>%J&g<$oY@t{k7gT<$)wR8CdyeDC46n;f0FQGNMg{lrE!ZNp&1fU3V9Go+C%fsa!3QGUo+LMqTzH@kAK5$_#od}7* zJumk@Y=|5H2~8QBYL4NN|Qkn)zXy9E$ zfON=S-NtYg=xDl=yOGVSR~KhCD)RAEX4IJ&FFJ7+-&RTu%Eo>2>75%N2IW;XDEr`t zK2WrJP)=uzfe>2Zm*{yZ@%>h6E|^9Nm|@_4*VprpU&CPSM0k8Q}h8Hq!zMI^0%Sx=p3E zp}cT+%R_+Ueky~?IK}TnyB-z9A)XuL*TKAMfZ?kke}Pm=TUjKwuC1EPz+-lH-N@p? zC&wGj#*FJ$PDf+3k{d6~k4}tTXti3=i`TDDrk^|wmSKU~(e9{XS7FBLmH=o+V{mct zD&!}Q&1J`rTw){Jv{6~N*B8n!L^=>Hj*dDJh&cINej%OBR1{^PSPFb0al!-WpBzoY z1SKRWHK<5K&-3+n5gpP`!w_*9?ztarsE7}AupVTEH@7eh-+#NFJw010Xk1|xz7Kpi zdY7haNwom3hzuDw){6EtG|>0BU+314=v_gnLLh^oM}@%cR?CfSZ*3jl+FY689zPu; z$x14jn;*|lU5G^^(FMnuOeQU`k|yj50kYkOZi&VSGOLT9T!D#+<8uikbBPdxZf#cV zjkS#zSj>nTX2OZFs8bxvEf5;1P-fyXUqbc(a|G4zZm-}ohf5=pVL(tnz@Y}-A?;OK z2Kr0gwkHSu^m7#6gGA;`2n8U6Zi&7JV6d)WqwkChz#>pUq2aSAiB=XYmT83-;!0{E zpnnD6uszO|-o}F<0AdZKGX;R{_3Q$|2-bneSU4>(%An?IVTOkw3I(5sz)C1+_mDNX zo(raFgy63b3io7E6g-c7Dga86!TA|}Ev>+(Y3Fn8BKshgKINv5cacNJEA0<~QiGeg zMS=m)GavWTzmyVdoPklO*JE;L$BV2jtsZaGwr5(tcRCt{N;a9CKRz*aVIxYT&eG;& zGM~a626A^7`La?HMn*<(n-B`lwG9|Qa&m4Yk-RiPImBQfLpN`wsdtD$CR{g*5UoRmveeDT6-qw$r2E&7S^=qsG( z+1l7XzFn)#aKE`ntFcOYk5+RNlNX|~c=XER>ZFw%g`8zTd#8oTs!68}@x%xk-;{{J z#~)vX(c&X}v|7Bh+uos#X2ULjc#?PnP0(E>KjTuh^k_z-LsDr`|~sQUM_p`D$pwVFrQ-rkM)IBV`OA z+z$CT9?t?Wflvs+FM`K}5yZ&D0rYVcLrC>;LgINimuP%U?;t<|AOp|QMd9&SOv{9B zF-(TXcw7T4O5Kn#SnynoTKHO|2FCCnYBhoFK>r)Y#TLBKazgK(y#6@|5xLXy5a77a z%Mii#R*4-CBEv>WpS2rnR1zuj7Ht(zSthJ6FHfzmUZ3{-=5&lvw^+!QPuQim;%2<= z2@Vm;;IWw}=g$A~=QAHWi>0w#64GWIXoP^3N?ivbYS}UUT7@Q%}zcAYj{% zor5FZIie&~Yt_u=`iAZMo?WSIy$A#%W-9Ffvz)@%5hs($R8ZORJ;<0APLf>m0JRV9 zULEeSqCQ7SH1FFIn#o8gc=rCRYuq0Q<+OWZk7RHwK@kK93cdleMUX=R4OIK>?Tx9G z<(27uZ;eDE<}wQ96HiUQl}S$4g-_68n1Zpn#g&B_XQfg){a6OC83BNOqZn^-h_eW+ zEU$vxg@y4+dkz$Xk!<1I=*01JrfEXGTF5>xm5gAI7>fmL`aLJ#NoBPy+?@?*QBbQ5o=mA%s|Up$ z{b9NLMFAWjTp21EipX0|@-|p-a?<%UhzbD%YoFh*u1>A&@q6EIOjGE%xn!nnPffj* zNSJj>DfpfTg(Ic8bbeR;E#e$>|dJ`w>! zBGB}AVYfqI{^C{eeOP$vi7(6nvmjH1b6j}ml=MJ|dWL(x-P+l)&%J-{#StSOF-_Bn z#Vu!iqU1nKRw$)F!;n>lAdCXE`s3%8#izc6jB0q2R`r0yqzqDV;L$*C+wYuw8hwfM zwu^N?Nm6>}&qRjH2?|sIdZ__-a}~&ezUw2%p=H8{%gWzRB?9+(`Trl*{%i+E;yqT2 z2gHRKN&Rrt9AMCWpQxZ3v}F)A+!YfMHH13q)mF`EugDMJ40Q~+p{=;|v`~Q6Fze*-i>C*d9u)T#W z%kqvD-F}N=aK#X>kbR7qDqWL0I%03x3=Ax zYP~TH5!%Y63-j6h_`I1KsY=B`H)#R^1L=zp0Xw@D>&oTxXJXPXJ$n2Y6!Ll4l@jXp zIyegpu*3O+{rHn-lZ8h-*F(;T9z)o_N;51KsP|2;maSB`>}I2CyR|Lb7>PwvNy9Oi z=@dqfIfN!El%~`o*Z|Wh5JAtG9@=ni2_O; zxZrS+ZU7)qN)8n+^#0!8DUe~f$!+>&4GJ!yXDeEp86*0=3IS3`1cs%$YqP^}%j`hX zqK6(FpO-S=<3-ecfYx0L4iuZB7+UWDSYSK-}(1n`})g& z|D~_K;Hb~o!$jT25#-QJaI}xIRp0v~K>Fh@gYQDm`(1v!$M3hdw`N?oJ}n}&mChFC zbGiI{(lV<6Bn$~aPXV9^hRB_Ub@gKTOjP-$lcfn5%cr3&6u9m#tZcYYZ?+Z+N9?n? ziKCt`6cB3Qy-CTn0fo>Iz;|6YyVt&5uh;B)qh=dMJd#W%9fKLp_~@uZ8Lb$>ifg_? zBfxDzSmF3Y09_6q)!#?q_s;^TBZ}S;JSSB@-&SzoyBgLfx5K{&jhdue54Ml}92P?F z;(!?RU{Z?oKNkr=J=vXuy8FpJ_TaepNze%>EuRoA8-23;lfU@p@BQ8mJV50kz%f|v zF(aV^0LK8h(K|#G*24h~RJEig#z<%4;)U`|)Ay!hQP{Oo>3J)cDJN3tEz_`YaQdDC zLb}Qt05Aof?}BA9U_=2`96q^Jo~>-G%ti?mJG&8x(b#68cw}z$XlYI=1{mQ^4Qw5B z9tK3eg%k*SNPa^pPB8!_1T;M_+h{cGjg1YPx411k?FePe86BT=%v92`5>`dOThbpz zOz?AHW+379sRnn3LbD3+^FRO`ib@dh*#I1x-Uh*qUVXQp9A$943df-qL@3rbnEFBC zoCE2(C}RM=??J=cn&7R*%+})4biy3jO{Q}5%t)29#fdFSO~CM`KtK?fQJrdmkj7_eWXutd7&hRQa6(85FlOQ`U` z_v_h4b;E9WExWeev}xRo82cU`BZia9k2)hGX2mou9S#O!kS+9qlWM>pDg1<^ob=E; z)iu!IM&+T_5<+l49(zXshdSV2b5{V4z`~=Ik^|tS8jOP`@=$<73u8BT3{kfTa40S4 z_6uf6j~v=k#lH7f-+QGkMEkWrdHtP(8j@6cjvHErShjBN!toH`_&gSMa4RI-UQmkw|;u>iqc`(R8Ot6n2xT%zP%3FI&m{mT9CwC<0vjTZdsH_?1xb zamiN+8S2B8OBZI>*EePvix&CLJ`ay?77N9>u_L89NR5M33`7uSYMN#k%AySvfW@Ey zDT9LI9)R?LyY;N+dv>GY+0A`^-;P9RoH_a8n6vLK7auVzs2q^PcsBIUp*{UUmFk-@ z@jvO47kYDl-IoBzpMU$$zwyeyd*$61{>^U!;83^BAc*R>+EYpc1y3C?MuqPL&*^=G z=()pva2xfBmgmo`tz4fr&G>F6l|X)<%uj4lW&+WP?=iGNa30LJ0JKXZQXs$IUSFQw z-dLLT8nt4SP=I!PbM(luxzZ!2=3Jj+h!jRVYWcP=bPM^V(EY7FHWVh__56CaR;$`A zuW8q7uFc}{h-HpAvG|B{^pVG$b_Xf}Z4N>}!!zRra=8dSUv=q~aY>KdMee#c(x9gp z{&v&6T;a6z8v{57k0E5(qC~P6Y``6NK7faV9IEF9MFC>p{qA>P>2x~nKl{^fzZ2#) zy9v)9TpD`l{^4PHVgG+t00)6jmjB;FfTO?s_5vKbP(9|fWw4unB8>Is0<#aJ*F~r> z0`0?rQGt|!)m!roybeP_okL}NY1D00X0|Jp8R!tm=SSzwbb3CM&21pFko_*LA^Yi9 zP{Mwt>V_qSsGf81FF02ps}XWF9A*r!2jPCSjQSpjhS$h)-?iP^s@?QzwraN{sbtb2 z(Wp}>78eS+TvZVUeE%aO34}3?f{J?=f{qmoM(yjhG81WJY+a! zhvKWILtsF<%r~^$>F^dZ%x?#KN1ux&IA8TLlAh5(`vf%=Dz;6pk!`qj+i!TbTdUX| zB_nAo;S};&C!0wuL};W+nThM}3q^q|-7cdPto<#?af~c2U74-cH)lP+R*ZlIE0Nwz z#`AObiBoerw$uO-fE-fw2tt@6qYEZUoDU4s1nhbt!L%rFA5dw@WDJlpcqcgTa2zj& z0Z^;?DA<`M!+oB|!C*AVc|oDa5E8C9Vp#ybuY1Teb^mQ__^9Y8rT5o70jU%N&zG2p zt5%T#ptRpU-aod>48VI6LVp)RAh61%0*TuOCIzc(p(hx&mBRM%I-$3^Vd!UbUEQu* z6FRO|;yvQAT`I`qNd7!wyPU6BocwN zRh&;HM(2}>{05;6C@}(yC&5}_-2*+U9_S#PKh>dvltSf;^?|5rNWRk$R#5$U2u#yN zK)dPIvfStP_SU*x-QKdJq!TITvQC7wokF3okjalCzo$kDJfUzN#IeZ*n8vC%a6?+JMqXI7ZOC*>_KPG6h5!cz$^rh%8{hfH*S`MB zPrveSzq}wp-T^>;2RXP7AjTvB|6SJw!w3vu$kQbzerAl}@94RMz`pj%RGUNWh=D#OE+fJP!G#&Rt>PIe45v-WSX@Azwo|LI|BiR7kvb z$QLQac657G^Ks8TU=YJ=cXL~4y5Pb65!!2<0_~kcX+R+g?^(~EA^*pAJP(tG>JTYk z!04zI@N__Wwk!gkt5Ov_Jh4f|Xh?~s=D`&wJ$IOa?fP`(4D&ky^700{M2037JG z{1D(cr2G~G92AHO2BwbpMuJvKfG<3}al_CGkyLt{5(eD&dp#5|+(Zd<2@SI&_>ER! z-^H)Cy*cgiN-USp&rghvmyJYnm2}kF{ zzw2!;Pt{C;0|O5QH_lsGui@F1?TX!KdZkWVb*ya4F_T#*o6R{R39G7t0BAs$zkZTJ z?8gaP*RNhVlVq}VbTkj?bQ@mObMB;ioQbkc=MCy~lj2{S=*A50J+ylty|;lneA5iQxJ zBaqD}@V!;G8?d@m-Dj=~kDi`BOUhDi-72(V0jA4&^9Scu-n z^RzNAfSC;MOZW&PAfup#Bha|A%c=h8q50v~uyOmrqOQ#;a{ z&74d@vCo0+1~yB|MSE+-Z}Nb`SXuG^X#+bue|WW6+j?FB3Q$@dI)elz=ddHL0}89D&+&`9#V~I zSV$vM0@gQ_JS`UhQJN+NM_TPBpz#~-9>3q1sn$29cXwN{T+W)$6*A?xkyr)D0U;Jp zY7No`QGEe(Vf_5zlr$uHC%M&dhCvHy_zUu@g&YGV_JPXgQP3t%3$0`aVGDEv01* zw=|C)9zp;ltkGiwt6QOHZA8>@iJIRt^mgLVbgS8|t%_ZDUAy5oOEDJf7>4DC%H36f z1HH36Ex#$H4Hr@dMuE`S3L#Go9iY)D6((85I!yH2bu_2?7%wmy{N-D3eYIMz7hZe) zwYNtMLlSc1e8EHGNNC6)2*8AGhXw{pZpdV;E0+Ykqul}cZ1sX*3^KoAr8Mtl} zix7HV4#TB1;1U82YirxaYybJxHzmH2i?9Q zp!-FEVUQp(tES0c{QMWEe)02v+)I`CMET{HU%q0POao2#(gQ3Ur4KH^@i56Kz&&Dg zQmgh-AwW^c7;xdE4`%D`$}Hcl7l86~%L8;CVrNW*Vs&e(!UM1v$)r3WcK3hTazk zFAs4y>$Bh--W!Vb4&HFDUXIcPVi^0v4iL+#W~^ehaQyN2g%nV&R&%X}Yj3YRrH!R4 zFR@sxlTM|aWGdn0^ZD}fCl}8otwd?&)Z?(b(}Fg%fs!aBQYK74aT+dPzFc~L{{1tL zKl}0z0m}oO+v%QADAGe;_HO}{`M`Y_HkX%YFKn#MCI~Gy>Mbzh$<5;U@wsGre9o|P z0LloK=0cx~p5?+M)ZAKbv$8qeaNQZTBS*{;t32_@skgJa{4%53a*1atqC-3g(=?|7 zk$=FI8~=xN8)6(iF5bfzC6@=nX1bwYDy)05sP-jSrO5QnKt7imc~=ZrW}-S(n5YUa z-X|cS=~Z&IYSnJKZfSjO?xjw<-AN@aCznk-BZXY~;{3TYQ=V^b3li$$T`*+Fc1 zJU<4dF&nO2zFzv|Lix;7zw^Z(s=lSi^!*!w@FY+e=>-9Nygv?l%zK{p4og`Ocp7v8 z5&+AjpjqT%U{0t{9}(kcDb^p+c8sA3l}u>u)t%3_ONZs(m;X9 z02Zz+6hHc~{CqB3xXd{U1Obqv`v-uaP*n*mGE$154-p7KE0^yHZAl>vl`h_Fftg5v z@HwukqO?U!gUb}cj>AF}0vDdo(Iwh4O}v)pX)5%&7TyfjW6=^C2NbmDkEb4T3YOK+zW*=6nBM35eRFf?FChUJ`+ zKnDEUZk{ZL5Oot3et3G&aD})~iU%DYh(Mke$yx4bbt-qHN-4ZAd=F~dTe%(1?X?xB zv~um@OGb=!(&?m=OeLLsE?Zt+Dxb+(taSR+2@pFCAgTqiXcV$m9MUr<;o=piR6hUS znd#Xt{*WjZdZylAoL9pz2#JkY$z=JMJ^gk%om=KgATRJy zTZA526rVlh=|hun6FL|GIdt6})d$gq#tU+*d7CI0DFc+$xzM;22vQRxTOG5D)iHqg zrIg?`y}jqH?&s_(eekPayp%|=PSQ#_X2NvFMvLVSKls&|N2cu3qbE;*K^3&yyU-SG zh{mGuyHC%;(&BPy@k;s3Gr#+lAJ#y@-IPy#Un})W-bl=8Fa#Q~NWpQ{6RtgTu|31o z$8ymFY;-Zn0B``Jzt=bqS1oz(z4yK>c2zXmp+D*xj0Eo1z=7u?uz*TF$|4Y4TWGn& zGN_hAdZrrL1Hf2TaDor8va(z(pTF?@o+0%pq?8{Q>Hrxuz1qg2Vz6!iNBoNw_jTm4FfC(AQ@1|+s{x*iqweiL! zA-L=;KCdT(_krz%+p6n@(L=UMgp`ZzS|;gwnBYoowJi?+__LpV;mXykPfkruEg1$w zz{>Rmt|)h}ivsn)YD^D3IPOwWhu}s`2`Cs8yvn-u(WMX07)GRIm&SmZ06+vZxq{0J zO>mo?g;S?apUtH69_Ku~R+OmBN97Nv8;!;^rO{L-ohoP3*>WbAS!9%f$0cw@fihEv z1W*dDTSH-ju^_$=5IOC4LRE)(aHt{ON%{pN6@LGsJvJLyW7nD+n6vvGi$Q=!tmM>k0 zMB(J$jwDCt!o-RB|90}^Q*(kC zAcM@^yG=jxcW?jb`G5H7KRwmj5xJ-lZ$5JJ#7D2b`mG-eDPVnNHTl=y|H0S(g}p0* zkD^NRUsYFCAL%=E=O*bS3|7*Rx>5yai!i~|ZpN10I=opE+{W}RKH5uJ5F zbQBp5!2=wJRd75xq973n3FN*bxkyNNr#tDhx{j@S)ilI}1$J?NI{Ns1ba%ZvUtYcM zd*Ao}{!cJ2lNpvLjXK@n%{Se&e{OkkpLm%M-rsM1Z|^(hnc3DBvw6xuRaI3v9b)8j zuDRy3fBwKpY${zjj{Jj&0ko>+S7}6P#EkU9^6%Ah)ntINwns4C$1U6t?v*ugt7J(OBSe zx{Nx5#+#jOZT|lC^N&8ae%XVrl&O>IXjV?C8)vw{HFNK)|n4$Q86kt8v|O>kmFGDk|yPwe$6o z#-^r>kr8K{R$~aHrlfS-w&b=$sp)2~IK1q6`(0~g<)`IYnVBsrh1_+b`uOZ?t`VMT z?%b9&tJnNmr_+WuY#uLk=Vh2eE|-r+sg?e9e_Hnv9VTez@b3^D-=uPW^dJyAL9HcV#Nkx8wKOe` zQZkl|6eVcnlH&9G0KVuN1V7DpXHP5Gtv1GZoMJRI%tM3WjJ~0{A;&W|nnRF+zSn9R zqqW*bqe0(;CM7-w!Qu&o%#>150$hX?dR){EZJ5lV!Eu*2gTCT^IMFIV(bNd^pNov2 z%!T+tw;xf8Cj+EiyffTKpqLn0GG`-LY5DEb)Q9?c4@Sr^R+#cN-ODEk#If&q36)C0Xi@~y(HrBnB0Ry;FD_WN%>jE zSB00QMGt)Wjsu*Fq;f@&3=+x!EpHn}77}4}Ap<}=!8_(KjyPN?K7p`Qtsv-7&|5Tf zMhW(U$rt~7Auc`rnnfUjT9EDfJxj_eLFlZ@k%a)xp z>+9+Z&JLe7k|gEL%gb-BSh*6}45Kc$X7iRU*SlQqWS`$d#>XZM&cA;C{<(8X`)CH> z)g7-}o12=;)6&vfj8k+22M<)1V>~XucHXt0-Mr|g8ZlV#%+r6my}P~3$}l|W4BBC9 zp0)j__ucdH+kbu6diayd@@ZKaEpi3vsy$UVdsbQ5;qR5tZQB0Ij_XF9?l`BzVbbgM zgE`jh=4H#49zEC2Vl(|^)0Ua_O$`Mj&Jm+tuk$8OO>ADYc=6F^pL%vV?GNb`1VyW~ zD%XOW=6`tY_1ATc*MKczDrmx3{eR+5JL_iY)ZfOBtFJCd9pY+UL`0&3wj#sklQRA@mcF=`osn!;20bZ_P%#@{`18WHy0&71 zREF}b`8A$U0OMH>6K`S6;imrh*fSNuAgzs#k8O>OOK{dz9WUL!aq|i$NN=_km-gF- zhLwJA(A-ehfCc@58PQXw*hk$X#`iz^aN#xOa~tE#F~P)ygznDf&TNdwvD~ce*63LC z8IA@R6C%f>Zjbro$&>0obEiGoSl``7NytK9y@Y$_R;;v7R<<- z(Pg!z4vTrJe_p?FVcp64VuHd$rL$(#2qbeD%W;@a6Gf*8QHX%wucJu0CnGJr*=RJ4 z0>_B?xCo`eF%;~5dv9)C?a76TDD_a;tT`XZLY&UwvLmb06cb0snd5o~hX!;qlJp3M zM6*t<9TgqCr@MR7;?42iqQatmO$`khM-CjCL2?kdcg=m31P&0i2b7@^+T7OMg7@|J z8584^95@h+oR9-46Ok(+;QZFI&&$2*gflWLkyeqNDou>coh0eB8VAyI!T0ha*;SsDl>39nwSBdBCzPa2TK>@JoTgAokThOK(U0;)49L?JUCzeYL*W;~C3gL$pDm)HEkrGCq>4 zG^gcCHIMXTB;9X=zO$5X2Zdgo$W? zvqLoX%+r6Y@Or%3_{4;1efso%C8boJ=|5w3+U*z+Fhiq? zvX2dq8b93o_l4!(D{G84n}P|kaozo$J=uhC(2VKDttx%g8A@yuhg<2jkDBXF)ZiR} z83{`6P$`s*)8$t5_4X$VbD*}ug1p+AEXuKD$uR*~KcQ zGGr?#tnqri7>41P-k_snW8-_z_6_MYYKc>kV{VTte^A>3$t0S9sD=(wj5WvqmW#pypU@nlako&9~<7 zYin=IIQIGR88RFXq**E|IR-$h(J4plBj$SdDLlk*Mx9pcFinX;;A7;pLW0AgPd`gM zSXp`9jG3hev$Cx&l+NRpV~(@KX5cY){eP}sis2YTVkCLGrL*LdeFyuN-L<67ImF1H z`_qOBnhsL4O3IG(_4OsxovNSx`fIOwSFc%Fm6VidKS5INAWth|%&}(@6XVXHv?H|& zji=w0?;IRoS-~#>No;R#uqouc#bnljLP;P;R_a)%)@rwA;t-<^+TaXAJNl82i2<;&v z27D&9N{J@mq>MyuIj&&b1r(Ev3Fl~l2)76>3I6R(R{8R(84?jJ18#w=)u>Wf(vlKE z7UBTsWvFd=o(GI&00RyRaxV64IGnrkmzKk?4jPO*$A->a;Ag=BBS@1a9mNVd!0)c28dH3D-O9+h6n&QlT zk3RLtPVro?Dm3(`hYpwjeb0OI=FTnKA;SS=gba9=)jhEKfz7!&xo7|Nx4*3z80t@` zI&viC)*mctUAg=x)s_1`S%71h?3P=8ct~s1(daJ_lHNYom`nZ8!w+rBFUTE44l0_1 z=hi*@B7(oF0SK0$_U}1x!{?tI&&?`KJ=oLJZ#Yq1Q%qn4+68fJ@grJ3MS~j*LK>af)N<9Y3j~cwkY^HvteI7v(RT zRo1X;=gwTUR^wc@?9NJ*f?i?JT67_YUfDJHU z4~(jR^~;Ag%_u1zWEcRJrWInOO{q|T!{JuE`R1YCc?hX)<$90zr8z4fxUm+ zBRH4}oKCuGy3N+}U%US{gyUpPc6L_lZHpGwih1n%DGFe|^J#qZ%DEKG@VnpHQEO9E zAxoS|LT&^@0N4d97tkReNeaCfmRCN~Mu(gSgVz8~@UBz@20!0`kS zmvm5^Cttiey8TM2D!Hp754whg~^0@C?p;&wO%VFhz0^MJk)Q~YSfnWGz&t+V88=# zJn%dR;l_oW3=0H2%@((Pz!nH{Y$y;kB_zZjm=dk;_OqgGss=!4q6jWllkm z{=d97l|CnIz0$&6@%Av+3nz+%{@^go#9@;iE!Ks(tXKv}xrn?5Q)G3zi`vo5<)Syx zQGKWT3^m89i$#=3#oZO#=FXWpKp<3B1)C2tC4=>a8 z^>yWMzw`FIIde*OU>FwW$m4ZCTeWI)ZnpL8lfQkUqN}?rp}M*{<;I0KwywH&MRiTp z@dX%0$bN9+Er%3FB`xY_gGvJwhXKuT>WYecHsuxA1}O?h&$#xLoJMCS%n2sT4uUj6`x_YE}SQM&6f z|2>tXh*J#Ed8L)mIPiGA2Cvr#iHS*$TW?)dr-~w2CV;r#K~HJ?GiT0dc<1!)Tsc8H z@4NTzN{LSd;PEFO->Fp-;PG(ablN)~{`J3P3nR*+Y4@}7JC z>Bx&OygKXs_ujj{v#m3oW1#M}H(oFGdc9FOIo8@$t12qn+In=4J^uSO4fTx$!fC3m zojs?g_VW`%t=^6pYgSh4txFc6G=2jA_Rd`{S-$nNyQ@_YG*uKv5}+d@5eW|45)%_a ztJVM;3IWE$1;PO-MkKXrNQl*deWcHpH$C%IdQQ$BtvRJ@j8X6$p@~Yfjc#kue;@xlxv3An5ax3WbFBV(Ac?yi)`TS`~-}3IGW}Ga*P% z&uA$WoEspe*dXLsV`H=V`Ss7=@QVi@`O&cxM@u+fG!7i3P%YHe$B+aGBuR}GPR|*j z84f%?S~Bj$9b^Dbw-da+F$u8&(mfD_#92WJGJDp{CZ$3__n+yr-uLr+AK3Krrm_*I zn;>uiyB(1d1IMwTQmRl}AlePI!i!t62E9JC za>eo^Kma5rB#+^on7121oV#wvNDLt(VbtY{{msMwar@@KY`Gr8WFmQ=!DysF+$l<< z1G$_Mj*-xwDnx_^z|h~aA?X`mh{*dd>HYw?oqe{cNk-6VLi_0 zTlVz)Q|Y;azMnF+%g?EJ2DHF{3ZV};0tCTb_}cM0{NIelq(BkZ{0b9I!Zt z(s+1LpNk?3px+orT(}%2sssG%8P&wki3|f?9PY1z7Qc95r0KUPVWbEHAdxL|h&mKT zhWc#DNePIc9i5wH0pmD9cq9ZbHf0b}6HU<5RcEs#$DYc}F5D9no7%;aDxL;n{0cjg zbK?q0Qzw^+y##H)RLe~MD{`Gn*u___`BC2^(6;~p?gPMB-~k5~wJ>#o6A(v&0f`XD zB&kBFDyXmHf$;rNNW$|8)c>!vG&MKHAheiTGgewuJV4Wk7b?PKqqeZ&#x@h~V2N2yeT#gf`oSdf1faY-o^qY9-`OkETKDPFTwNF3wqvIz&FTrqL)Wsxl z0PU@9G2$wSJkN~f=UE5N5v)U)G}Q0&g3lL3HYkqBJSBcGyUT}kr-H&^*37adjaE}=L??;WZ?JvQ7Wk9+>o47zA>+2<4doUz4-hKON4aMB?N|x zK^zJ=={WYk*}J~qII1iB-5+yjc0FG2ZsPm~VyB5@iYh>)RUayWL{R%s-U<(`Xw;TK z(n?Jbja%BLjg(5|4IvR#`3sBbI+XfeL99@66Nm7Xs5DyN|M?TQa+uSgBiwtd*sMB zJMo<%^ki~;aiSCFIS%TV>Kg{1 zeCk`jJ9_ki*u)6@pyKxSs0ZOFp5T*gIJ=dE|%pC_vye4tXG7>0} z2lHSCU2YM8=~YUCD+iE8817_zAsyT#(+Y>VqEm*afXNe_T*#W&j-jEztO6p=I{;#q z!UzTpMpC0pvRcAKFG*S!SgJRqguhNxDfRd|#IK7URA5!4v zy1-1mvG)c{3W8(ZfxN&A6O$s0Yc$&;L+J_^7I0$x=f=K(lf%f1i7oKm>2sBi&NMke?%DD*ws^#nD8KfcP zV>V`{W>~5|6GOtV%k^6rQ!tT4=yOPB*V6IsgZ2avz;iyb>oQ9UX$b+rm@YaJk|al$ zTihgqb|4vJkje^{V;0L&LE^tmTZ>XjLU2LtN&rdE(}KF$^b_CMfuUn5IdWsUV z(->+tn@G&}Jt7)?W%#xJXP$ZXvB`@U?&vObEpFY~H^rDll#znA+kuRXNtAqa$5xP; zOHhR;6A&VabwcnJQnTf9F_-_p^GjctIXHOm==SZ~NBy>68hPXOT~9y#^lna4?!Z!G z5hd5ndWBNr_{eDI@S$HnIx;eHe>-Ti+itz>BiptSCfArL%P=rlmW6Up4-uDQS%nUg zk{@9h#g$60VT@sDXy`r;Qg|U^^CS-Hsjfj75dnJMmBxjD6c+t0AbHRV5l2z5e%<=n zZT_GizYh2<2d z>oc`gX5?BEPB?B1K=pcQ{52Hwx z!&ZikpZV8L%kG*weP#kqp$F~IKv)Xk45kC7lJe^SPN5sgYkJpgnC?hH4sf12*B#sX z>N*G$$>YjD|MBixBGUCKQ9;ga{rdGa0GOSdy=7VN{p{HICS^HL%BmCVcNjs_XSj4f zaexvVeyfGZ&;o+)gT;l#$l?mqwYrT=qRqB!YOP@cP}w{b1SYA_xF`AjzwyA=UwrCk z`;Twmwqs03nn+X|p4X}P=&L99WJYn7wuCs9rsXj#&Vl6%y43byb26nsow zs=IHz{zl*1Z=KkJELh&W<(7pbM}G6dzrMFYDIktnWN{0z);5QP z-vD0z^UK@jYO~et+qS*G|3~|WI;|@wlCheY<2rQxVGvMqLr8|jc`pmXlK*Rjp`oDT z!2ScrEvc4jwdvcRf8kGe>x|XCR+~ZR91vznmBf^i^i-&^;30Y4)-AVAJC=hu7V?qr ze0O-?<9mk(2Y)#H{qOx?IEoN^9`O-GF$1I}R6^M2XEJ<-%VeM6=1O3%A~OcLe+qmL zlK7cD80{g7d=@mDqJC)_78kVmzS8LFxup`{o^agorN+{LQmHCRb*+;t8<0dbkdFal zGQh0P2ONfQ`Ml3LRdB&@;?7bM0G1aP27(!OdTe}W$kfz@saY6EK-l1p0;E6~MSzKs z%y+^nBuXk!#qR0aOnrbOjl*<63$&~F9*$4j_)3`k;POzLF~AtcL3RTQ9P{{;0HaB2 zH}K|@3PCzBkJ`!C0v)5mMH1U7+VQS`g+Y~5>xT%>FEIg=_1P|WtANNZTxBY zGBhDEgX^zB=2wEt4E&Sen&;2C%;TIQ`Fjw#cpQ0b?ChzX)#|#b4@SokONnL>!o&t~ z0)q}X=I54RA`24}H566P^v9DE1IBoe(!gjxXW-|A>*xFJ?kd-XPzc+)GCDfGmXnk( zpfVZ%YPni-Q~{IcCU1cOoFd2Ahhv-CtpMdprS5xx%qkO_UMp2Iqx;bYz~K}Nnbfp` zl1{|ANFLnUQp(Fz&&u6Bbl#*~<^!+1`r19hQvBYp-TUJH0|$=x-_}3YYBb?k1&S;B zxAxT)w=gqZuXI$_)+z<8d{3v~L~TC=!0hGN{mhwhclg!U``&ry-7O6dSZn}WHf~%v z^z*?Ne)8ntF=kls(fGvXQ=_Lg7y}fY?uZ0W+L0XuK)EXM(n~LIi*!`&yS4xQgHJp; z^vJg#IicGcx)lPMl1v$vi#2Y);~_{5&!z5Diduy5G1RGf^r zpy@|NyNIQQB?Tat!M)M8+Ml?r-ZTH7TF!Dz#CR~NRtYC151$?#7$z-Bi7qQfr|IsDPM4Fd~R3@-5+;Kmd~fN%#s13HjR1 zCVTJuMl+~)(+{U(z44j(v6~ro_uY4&-RF6qPX~Y@cE;H`Bb?X493O(=5e(*g4B|yn zyq}G{onIK*26-1LDh$vYCd2yfb|1G{>juzR z2gWpdU^crTuWoK!gmbEy7|C(cOT0bl$#a1L0u56Biwe&lyL6#4SyodUUs8546|IHe zeDjckBstFc`T6LxXUj5R*OSd{9UW;-iUt{b_QJ(Iz+MD9O#z3^3Owl+p7#rI;Fe_p z|6v=`jnOe`8t%wyWEq14Y(fPD|T84ZTdxY2B1qCac}5 z(cBBT(|jkkyuAGVD^*oF$WU>t>*S;^AS5W*j3O@<7axQ+w>Br7K6NG+d6T##&#$L<5Jty2a2s2OqS1X| z?+-x|`2PL<{gI&*M|k*&gpQoUhig!D*sZ3f0~7aD>#-tBlAaJz7lZb(a^hrM$asyT zLf{7EzMI!ga0#ft*uzerIrH|-#-=SrMOE8A|NLLs78}Dw^BNl)tA^JAik{x2&d#ol zPTE1jfj|Z9Wl5}`JCWY*NvPE@gn#v;R1?hGuwbKiTKP72=uPe^otxF{JqF##;XY2Q3}fq>^Wt?ed8=F z&f9j}ZebFVUroQUv_xqq_49zs_XT!1w|2^jJ-Pxo$5yiyC`axAiYBx%aa$TEr*&EV z{T(?jhl%GaLWW%dTA2PoqtH*FU*Q!zK!yXX{r$A$9Y6k7Azd;!&=;A40cBqbQ%`7) z^LPRVIo3!Xj%vele>Jfj0ytePaJV49`v{Ht>DjEVu9h6uZRerZz7SqR4*6u=?;opJ zy#OVaks*X}&`@Suur9f{Fca3>+jHE>FbOd+n{TX`8SS`63xpy8ddUF?f{Q@#fDhjf z=nY2Tpjhq3jhh-_0m>}(*l3Q`Y~=Y02v77T0_GL|4=8pFFzrd-IR_&RHAv2$K7Hm` z`K9XQ>vfIsWo4IB0i**54k-9Mp3}Iv5dH7d1sQc$8#nj$_NEC1Lh#z_ueGlcc?=7z z+l~2@fm=_ja|%aHI&5~2vx7v&k^nUq{!dX+QO2Fy&7sI~=wbkNjM*G^)P5GpG#p(S z5guVi5t|cZ6LEF&x|EKV_Pyv>gFzo^H`@g}cO=if0>_QceW9%ESXpUh@)hZo_zM@x z@VIxTq)fxKPBd2^oN0@NAM z_*qEsymoY7Dch5$X$J-Mr8)8C^6IT4Dnmd}P!Jp!DkbnBR3^Kc@Y!eo$VCx$1dr=C zF{TZI(}?r}bRHCuilb4yEp&03uMOU_6FGw%$MTNVASaLFuHwMR_~?4_VT7p5<;D&} zxQlfSlgWg22t;o9`|z7by5Th(8tr7*-#-24+ZC7Vwwy2eX4|P#r?P3v!9@oqZA(@o zxuH}llWyH^*=U?wB8eBlgZ*su(!lZTM6Sm7PF--XT7UAfM~A^JT6u0D9PI7QUNq|R zqQXPlW1^!Q^m+sS`co(bngdn=GCz+5MzaMN=2l?k>PSWWrmY2Qd<0-f(VA~vHi!Y^ z@LG-uK>S}CHCB;Vc|>0k$MQ1ppiSa5s7tJ{kO0UM~u`0djBR=2ii zU>JFdab$t#Lv_E}in!m8171M6ps`lvQDlf|S z$?$YPhx#4Nv*zS_iD4LTe{X_t3zefi*^|1_Jb%&J_MqUX2I!>$=9LG4Bsreza!_ci z1MTB0@c06tQr&~R8m36!v8#aZw1SbYrhLM&Bo5>gIN#UX?)9xSNFxqm7WVht$~NjXdF$4$Yv2BAdNGH?r#8kVN;OjkZD&s}(9g^RnsEWjMFHL1 z4Cw6Y1zN2^8yA-$Lb!fBwBRDk@?`ZpOAbhg2vgAkJI;2EO2v5idq5u&f_$094 z7SwJWje}}rz|<125ZIl*yE9B2Hmg#pQj1HzIpizAxvuy-#UZ%3yufO`R`26_~LdBsA z`}gmcMn$YQq5Bf}@#!rI3C)a~wbxv&K61VBdg5!p-ldC-iB>L|me*ERRlF4vvQ8Hs z5k6tH*tnJDE^-dDP4q%VNi-Y zoWFhJAt4*a%quHFRaI5*O-<=U*tlz-7RD8qC^djH_)UKR)DvE<~I`LLBISE38gB5X68w*~6%rrXCk-xm47Bln$5b-_j zQVHhKKz_!aH#e~w|9iN^Q}DKrB>@SyG}fP3HzOPw8P3*Cjps#1Mztqx-C0aCKGdf8 zBq{WIYwz|9gZm~55L_W(Tm+bzod$!0{a}7}SsNX@S;{3uwjH~67w||HC`T3fi?h>k zPI0d9kBi!Pb~*oaXB&cGafN9>{#1O5|9I4>N4-I8z-pNlj*Z;S9v>ad^YdTZ9vl+c zfKm?}NG^C5w2$ehE(j~*23o@+*dUHqB&X~t0IUNH^tI$O=4G*nAiSx+81Cm)%k8_1 z(h(Tmy&wH_8QjjB#Lh7Su)+~lPxd{{Xddhi(w?{_shD>1sb6f_CRI;QYTLWpfyH71 z)|C}tvOug@!Qik8==Ag2*qAL+4&h@&3urdzhk1J{&134*SD+ z;gdgpEDetkk1$RqP$sL+uDM#1J36k~#1|l)A=-TSNKTorpKwXhugE-KT9RwBntU>T zwMYJL?m?x^0X#C2AOK7|#WLAqaR8Ew7U~R&;6UjYn78(4Wp?_BM6<)g!>J7o4TsRh zZFU=$kqqPX$}<{nGGEW=76|zB+9^%at(%P*J9ees_V*XrY<5d@O>K1|l8Yx!d@PNR zj~iK9eh}E&){GVD6%}%GwUSD5-M1D=4=%8rG(-z3%E*!nV zur9%Uz7-lO)`f{fC;WuI+=8#Zd;`gJD7UfEhNkGp7R`K5x+^w*pxR~` zd(za~w#u!J8W7%`NN5l;E<3R)!10# z)!N#3TH9I=!Zl2UX=MfHiT`H*{_&XD*fE>c8dOnU@!stGoCv+QFX;uR#-ZiE$cHG& zBh)FKk7MXrzM=;#hD?%M zefK4$HC+`azm!?eUsEdUJeWoX{p`gD?JIA8KEIHv>mB^R&vRs8jAwe{<31C6qN`={vH*L$8L1lpqC zm?!W!;8d# z_h6%FiEV|o%WK`S;>!wQ330J7LI~q20uzh~mXL(7ALX`R24eMVS(% z#FeT9*Ks%9r_VXv)8``kGEeOtLmu&q+s?2rvD)cRWVq1626wsVs}-x$Eyok{@_aHO zFDxbGB+{kD1$k*9B|DvdxyNi@;bR+I0P{2$S>vqskmdTIOYFJhpL+CUL+^`cIWO@m zGC5`|NM%ZEL9T^bJfd?5sKq~gyIL8joItH-b4FJ6pPxlOlI4b6QM;jgRJ?Y}6ZV9^ z>kPzqVH-r~au)R&&IjEdwDFE>cOB`^d(G14eSOlk;gR&9!{-RZQ4bn{n8*pqJZwOQ zyX_JzU)&fMt^F3NZy+nAyWtj`4 zWX>++IXC$FfIB#vzO2ylfd9j=d|_ZX{pIA0tPg-59|xe$87^MzwJn<*f@tt3h$n$P zBogl%)>PMhK_Z!ul6*b@WTi4&uwb-IZyLR!3iZ>c%=;)(0I%fHx8Cvpbt$wJ;9);3 z4|B#5|F%KtR|s_atZaPB6&SL z>IISw{UBVz@kQ7e`lBo#KbT?FG);aZ>piForI`Gl7=xjS^^ThpYetk|Tp@#^ zBdQI0t-Flu&QFZ7Lw1Fk^W4V~v>&p9E! z%9)48S0*2PEhiVglaq@n*w3Vr0+y-FWc&(0*OJ@cQ@wO$iq4Nl_8thKk5y8zFF=J#CBotx441Z z_LV7rP=5SvLVhxzlIJi-XOj%#$!D^CDlA_$yH~uS4bB_dg8Ui8Wl@U>{{A}r{q&Pv zy*DnRk41o_$_{^D6Ym``ZfYD}Q(qm&91ecQ9Iu|Q2iXFq`(Dhi0QAxg-S2lT*!A5H z#GZSP!`_(}oqQq-U%LfAg19G&6tVx{xZBayXHJ{?2P9M9Ey>hvN#C1@I)pfM9<(B$ z8BZ4Bqwu$bL$F*OaEZ3*#i@rgSv?<>;9Dx-Nn=wD2h2P28|1S+5$1kYBz1VAD8wKVx(TOXw?$gFGY) z`FP^<@BgN{$QMTxeiCfOw$TwN8t|R^{*~iJ*F>mf06z7D(in}83Vx-pNo6Gt__vCk3Bul%F@z#-w((i@ljy!~D_T2ZdOtgAsKSq4S} z+mc$Qb7k~;#1^_N@AXQ~KFSN&620EKy7s*7-G-x@k58R)z1MUs)6&!ooHA|Me_7aR zUS3{o*S)JfeeT>Dw%s3GD!6bcHovZ^Xd1Cy?ayPsJJwt%gO7R{)sa%mOz2U&_MIOz zAD{VT?EQ~Uv>m~gzScjqx*D6BGEI%mgkM&B#8Mqf(2l;>&Iv7Q zbqpKyHF#b)rqU9hd(y6Jeh=s6&y1Zsek!+L0B71`hjOGFI)E{7h36+3mjYV^6z%Z}fE{xZBbTT=ni)X~?MFZZD1jr3|Uy6>W) zfn?q*(`p#4-Zbe@SJ=bY=QM?KzIAnVrEMRp8)r_RbshiUL`K~aMvB>>z8+US)QP+* z0j)GKd^R5Ht>n;^TuXBCal4Eaicin}b?n3Azt4TYnZqiIvLge}jI~v@==DXTd;0+J zq4`iXzC_vUDm*l?tg; z2qA$HzcQE~8@k)-nc2pk*$ZE|hl#!-eB*tHeSqDa*ty%6@H22lgfG^ZD3vYb(t7OkNhw>!o~R8&#Q%D>9Y@8p*!&-ox6b@C16x}ep2 zD)W62=#Y5O=6!qtb!%B&ZJYP!=>_7~eX#TN&0TH7u_pjqP3^JO9t#||njjAd8#Bj8 z#lE9_=?9aC;VY#}I^ccC9&^DcT`_;G@s-MjU?+-?40fV`&x2S)L8oQ|ZKn@;+&J~k z>~9u1{#O_yqEiyv!vV*pmFElL?hp$0=!@LjPFdG`dAzEfCE>Y%iQw3^FF=f;Sp3GC zFc`Nl|K;(Yw6=X|Cd`6(`3-CdLsX2V)M7{rsmKD{5V((+iMTp>-@YwB5rx<1;F90Q zdrjxzc?d?_F(dbY2Dcbeav8UFj66F}Pfe!3c=>$6gHO@q^yFfvKUC)N!Wc@30!9#J z9E>6jzN0PI0oF?^Q7-xOW91+B7$w^n;eUVrmw*4KJAb(IKi|)PzrpZ%?XvaDFqyt% z>xwxg#}YGn-SRrtbe?|`o*m@#eLGv}A9!VQyq{R=3Wg7uaBT|hx>nfK4l?Nl#pjFL z-u}QI4C%04ZlY}d2pv`Hsq2%oi``w3O1WGX+ZCvZs-=pa&F(Fj^aPEMjV*Sn;W8CC z2F6FhPJ%Fs=pOT=+g@G*S5e#bSKNf(&3J_`t*|cJDwQ2a81pAs#tWK@wt;W6hzK)L zzHr!=+RFS;qaHMQ>+7We@B1I-pV%do>R0#!S@A1@E#A=q>vIfX_5m7!cE~s+1&An^Rkk%!1|WHB%i~x z%f$oFu44NGYpRbn?_ChBn#+IHGJ;G=Y{}xc?{=R4$3Oq+Pp9Ztbo`wX9Hiwv<{Bu# z)&;ZdJDA`AWLn}^zp5bHFq}mzh|7)k zTk7i{TxHmg%0-Go;RxgrdM(@mAWH%UJWUCq?H3_9FihqkXVP;?NK?U^0W~eyE}{Ar zWEf?bfO8_p$JM&;74nrCuIl@ww|`)n5(4FtGQTW~xJs~SKZ45%JVPe(smQbT?#*4Z zQkfg+9$XrVjjtBVCU^wFM1jErD+~eMAmj)^7)j%AZcxToPjJBZRGU(O`^VM z5CE{53lZ(MiaJc++WL!oDTv;YsHz^ z$l#MmcMtFTs?+}6!ZvYb8~Wu(gQtQmRIlef*}e4LgZ-nq*tL(A^L$D&5 z1ra~tw{Q=}LoxrIKpr5NtZqqe$c$0=A7YZO8%Zmm!t>^Q68U>8;{pA$8R**sxBHu`?-Hk0 zIf|IVrI=8zCp?&p^@Mk73YuUHG z_4Zz=d@?gJKJ_FP8(9Wnn%d#9z+RANNGk-$5;e_om@KxO{ClzG*~)C*-OFsv^<9fC zjg8(|EmxSB%wq;80hdaGfVU`x6UG7;Hc{J`AaB!X{7VX{v|+OTNh?O>kN=IgtKLT+wwXlyAI>Rna+x=aJ=idsM%Nhj(Ui+ec% zZpIaS1q4UC=_rL0`mqQGeV3n5M$<6Bh_HHQ_)=@H@10aDGo#lho`eR5m%)1+G}3l5 zAU^khNk%$-AMW^)Rmi8F@5yo`e;s1H>U5yti%w)a%L~mC_&Y>=y&o2bW z7lOmh>>=#<4#%Jc0jmt<@*aQ^Mj-$@qS%981?}fIXAci{?<;C>ZEAA%X#?RJk4#KD zAQmTni=uEuN0w2>)MK?ey}TG2f4Erq>=QY9KvvEAhBS zJL`5B-LF7urU}3%jY^4$BoS%ARUTJLaA4Lr1alv5(x!Cm| zjXs~x&c0b&zwZy~YuB$&JoT&L8X;nZ3^%P*W5Pf?fLayU6Rm-;E(ATwfJlKonV4U7 zO$E>u1Qv#H3V(MyvlZKT`|5!jAnB=_GmjgrQCAcqf!H~mcBu*y0AtB6xOF)2&r5K$ zwiQPkKu&_0$;)XVL=2?bS1Q3+9BRFLIEkfdX$JG-YEu_oG2|!;6j!$~X zRu5O!BES(MCK2Ug!I?aY_Ms3JFnj+n#qnw9zRK}wp#R2GP4BN!3j(%Gw1`4rq8ZW@ zFg|SX6EWL}tlz!@F>INlEfZ(x!?5sbg3Mu z_Y+6MpnxpfyO{FcJ+}h!Vt&PP{IMfva<%j72@VSg4ylEv@Uj?(2*Vhw^Q#IILdwgT z<@L$Sci+$Dr|IdhpLSrS2C+#yWA1TO;;p!EH?Cv%q)K?E(EJJz!WCYpnasum?wKHc zYx=j3J=h*YO~6U&q(ogzFortyOZiF0e@TJ^3;YIx^;!~8Z6)z zlwhabIC#wO;2BW~$D)eVbW#WgS-4!x$F_FfJqSm8(&2FQaZu~7W28cSDzTi@-s7l( z94XsDBn!q+EDC%@1V<}oK>3&n3mF(&4xu61p4%gwsw(K{;Baj?k;{e zV<$&UX~k>&|55Sn366Gew}vA>1EKIy1jqTu7lPvp!GS*W{|dCZ->$s%GqL@f9MY zk}yp(S~F|N>r--r14Bvf@+qllVPsOpX4IQBRq&@FI501_YH5ALU4Ju=5gDDi`PHNJc6!P>t0YcoIm!(hq0Y`|t~=D5?C$AJVnvWe3_F4slk4MG zOK?E;6@=kAlVE6{sm=9-RXcOPe)s@5@*th&L`4C~^8yFnmD=d8( zN_m>94#a|GT0*$_P(&3ggM19eS9_3@3-5kE`%up{pV8<9Fl;*?0t%M|16_y zHl4`lwi2vvMQM$puC8#dr*|-^cXh42-dK6qp?G|;{^6zW?rRx}?YdDxATkUK1fmZJ z8ko7@ixV6oFieniO@Xa&4SMR`Twj|n9UqVW!?$yfatGO|LSdV0gs~{J%Z8F09=(z5 z4D|4}>JX>UR*9rs8OAMXh`jwW1P87|~k1TdP56DRp;s=DMmQ7mP z#IXGw1NKAyU_xnuK#Pe`S+Dc{zP-LVUp1`Jn^Uuo6h$$1chZS!t(d5pg=p=xigdjz z7m37@eSL#TMb%KnPJy$5*ARgkmIsbK4F;osO?VCN4Wgt z4J0QgZmlGjpY!^x_{PU3mqI2`+J-cPS}?~wZzT0#*Gg(*>!Al>UY~f0@v`(-~ST2BvhUZS#leY7kj*KR{u6%$Q_RU?z`VV+D>Pt^0{21fzP6LSWg4z z1_rM4e0C>wJq$4jvJ)`>|I}`5k5(7a;6RrqINB2!l+wDzmcWQ|t%)zp^%`fMQ-^u>pV`cWhjMwMzA6^nUrk9lx#bm;F4zl@LEeC7>A z8Wjs83lkY@>nva1NmYEzU~NG*;`1gxgfU?4MQ8#*pehXQ?Yy0~%%k9$S)B@YhU50+ zFc8pe>&4)LXmfKDv9q((_^q!NJ%Rp;Gz(0jK>y(WJ5l+j%HDEp2LRum83X z2>7`}nNe_+i;;&5l_!Y1$U?`*#lvuS|I0{p_*qx?V8h^`K{1B1@|ff#t<6Yr0Syj$ zBJ5ffq4tW|QTq1b!OmPH8j9*#0O`RnQdN!Dr-e4tJIJJ-RD5D`(HH2dFuUDg@`(rz zCd);b81M)WSF7Z-H!H~nZXr4z(u1hGyBofLE|-JvZ<=OG3q@a@5xwKa$P&wFpMb=_Qa>Br;$7w z1ie~GqxxA#YUZ177Fk27fI2L4CgwsszaYWU3^46h9tZ>zs?!EC%KKXGAhqD@sK=ub z9S!wgL$(lEtJP3ue-BlS`k@l&eHkCS`RufT8Wj4o)h^E%EShJC*Qe&xqs)*yjTXm= zxCN+P0NbA6_$Uzyv$h0>JX-g$N`m8ZghA`~za+tdf2sh~)QrE_+_-|Ht$>alSFf5q zk)s7I`Pcti(1Ut>i1(#PPXz1_6pxRQVN}oocPpj(^_L?f)6Y6N-W$}hAs{1G+O-MU z^W;RfX@R44OQ&?50(tlI-}iS?)24M4H0!0QP)LhwfdI#Q9me~bQAVk)ZFEwlsmZCC z#fCRfp-cr0J0Jp1X*TL`;pgYD5&!K>_@z`Js~Fq$b$XMyW4x2 z%{lIADcaQ)vTdyZ@x)z7a{Nr8GcG@IP1(hcK#a>ziklXbb}-uY?{*t5{_W3ydHDM~ zcandczrWUw;1F5{7Syp(I@Z=#mlp;j-SLRtiF!goE){p6z3e{P&g|Nnd#S!y{FOzu zj=}i&^Lm4$f>?QV=b{;%M7=s;cw)_=WIkGM-S{NQ9LDpLo;GWRphZun0v(O`#6S#n zdKKis3aXxZ(3`bw(^LJ3w#_GQPay#D(9(XT ze2OK`Ihwjwh4=rB+ed|iIltc*o%~<+&c3;ABT3^A8iN4{zDpuyNfaqa)>~{PF)p>a z+PbR!4*JUX-|f}q_L5tzV>^zN_(c-+PKhKq80=t3PhrV5ZSP7+ZR}?Kil8k~Akc%S z+34xn+yXKcz2E%Lw{YCt^K~`$ylGV!o6~> zxm3ksy@XoXN0BoG3$xhST*Ja_DR{c~-7ciSuV)g_qIZMCpPub*t~G+y#W^g@`KaVA z?~fj#>gQp|=kV3eHWsSI;Lrd2%`Rv17heINC`IT- zsrx_vWw+#0u(7s`VCf#>{tY~4VR62S&(@nLdQ`tUJzk9mA^{kfSAvB0Bh76&EScj! zYA!n*6Bofa6^0{ZegyPxL!mvt_O>OL^4i zT+Ea>avVxiUHtCLZB&aac=DJ3--V38NSJH&U7E?A43pZr5++SB`+4H!pG zj(0MQ{T`X|KZK#cIr>-UJI(o-+JAf{vx8@Qf7&Go(8Rc( zK9*#5`%?wsC;N@rN1NcFA*0g!NSB129=!p%thJU zAt7_V?%V{x0LBFl+XtcR#=-sj%kX*XqY~9z1rE80Ix&i@gfF(fKr!bA$7=iu$V}jj zA;fMsD<>Ibin)Ur;n@%0g|*pyu(sNQ1A=Ee3L73vNsw~|wzn2h@C?-jAC*24Ktf@9-kAD;F(&+sOVVgW7(lB5Glt`s-0L|jLd2ycjjZHfE1>06J&(f zuMfhsaw8i*iNU4*KV}hJ<|AmX!*`3p#mQwj3`OYgbwvT_4N?J<2*MbXdO0z*O`)ep zXg!Lep4!i!Lzf{~TBxCv%y@KgE)Z@3EC%Z_^yxU;wp-MIe7f!PhtD~0H7Wi zqrX30Ad8NJQb=!4zBZ4E^oU8sNrkou`#(PpT`y4;5i{Ucs-pl)Y#sL%xQ#qdl-@6) zlp6$39{+a;h!31%D#n*iO>IRZt0+(`dZ5Q0J z;4y)cXX{w6;4^hRzYT{m;+t5+XyJ4+$&K5;u_2~2{pa69Pv6F;>W$koiGNl5=v{ym zjG!~RuMhV_H7!L8*~P^fJlD~yrnp3aOfcw2paf_%8tHOTA!iKQ=q*x~5rxSwg90Sq z&xx|t42%dzuaCmb&27XYK@txDIWWl+*C9mxYxKKUsFsU5IMSWB3E&ELmpOB@EG%?$ zua^fugh6Wsi2x`ec#emnUxZB#gc$AxV;s$96UQefVY)3T`!i zBykKW1T2}rb2v(cBBFjD_gB|&{OV;G^?Kk8@OU=hp&?VfF6-Vj+38#|n0KMEX+Wa{ z$obhtxE8F!v2EnI3lT*bdWePc)!r#S+g`!d*JlJy}VzWc1$5+#P;) z!v~LXLKbb=B>+=4DwCnhjg_i=Xqq6X@K z5GeqIeq@{2c?usAo`RbxEavV6goX$sB(gAI7(gfl5jqlRU-fHA;=yw(NXQ1rGLXX% zCkY(SMP;^x!Qi5nem3X^r^p6+LqM9_GT-<0@${gu<66%35Cf1F!FF7nUv&^CfJF?w z{s1unp6{c5abCL-J(v|?O{LwK3Xq%*{)WGOkN`$VO$3rRi24^b*Gu5JR+=!4s4r)**>^c(pa$% z$10-RvB1>pfK?$_982{O)M%#`i|5Tw9(73v$I+>szQgh@!_&cb*SOVQ^; zpxf)z9G4*>pc{1o+cH=zfs>0-C|iiSN9cFkHOfSzlOm0&=X?5{1=5Val?M*GiQrnI z<|hKl^))OJ>vJMx3|ImQ3H=&mp*mAWV#%6rxW+K@Cm3YPWO=XI-EpI74+4mdAO!&1 zmNoyc?44n6;z$gJpYb>$DbPiGoBjX4?!KL_+ZGCmZ-2Py}s5X@+B~0 zL~J?EODkv<1tX{g>4_|8&fy!fY1dq>R-Ler2ro;6OL_2i`GPm>-=*GgzRmpn{5O4n zAGS#NxYCPbl^SuU_5n%#DX6d^x_RH&{HQNDir{@CES>2N_%Kv5(@ z1!RH3gaiT$92G;!#DF9F{Y|Hpv)QbuNN7=NuY*Rf$S6KIO_e!3+;mPf;Bhl> z-c=$x8BrTWj@{L|#XO6B@$;>s)9oEc90m^%II?>{@4^3p5^A(-nEW_fTP zKa)DtCe&^KIEL0Wr(@q;Z+EfwBo!$K6a*)xBlxoW%69jKzW)*V6F=h4x&BlAlu9bE zzETPt%g|{xkn;nY29$!NLM54YeN8_m%nQ28xQyMgzvuq`mfdcLW580&NdbW=PX}t4 z7_J85fkY?>fuKPI1QIAhO@Fj56``%x?Dr=ur$-!1BV#dgm07ndaw;@+)rs@$j0i{| zc)%oou|Xg+)6{e9zf5O@k!o)Usk`1>#UBIoHcp>1?|&GGp2oy#_l?aT-#et4)?*-Z zy&e+m3|_!y&U7|?=$Knqt02Wm7@7+zi5&G)hAQK=(2pmY)v9Bv*~FK*&7Y6YeDtZ` zT>sk!2a~J^Txhf*I{G-0Q(WY3e;g;T?Do8L z)DDxQOiDGwFj5kjcrc`qoBa<445|b;b>%dZ)w%WWv*9j2CsMa4tZ2k(HAN!RtoZ1W zOwOHcPeYIAL_w&v!2xlAcd|LgVTlrZnWWGUJ%pCYZX{QVDx8M9nCKB;PRzWYJaCrD zPwRTVBQn?kWnL@hCGIk~7sv`gRST*{FEe7N+# zb^OS2(w_eRf6%jOlR8aeS8ycD5(P=5_$Ij6Ej0&$D9WlNOH}>3JokY5Kw&Vu*qNQ3 zoxNH=!`LJ?N=UeePh9-XoMqCIP=JAD2!>pP`dh z!p!U}x`RFd{xrG!girYN4jh9a0S?1pTSe$slcVMV40<3RvIWHR7!ERdfL!6>u+clG^Q0W4Why;|))5P(MJ3R4Hk7x_~FE zWv3l1$FLc}Wr3uIDitQTI3yK&V42I9nOPY1fi4^vPJ#s%jx4f2f(Q8+u-|B7W~6`O z2-g0uf_Nmni694$=`&O_NxRhtc@aPgA}^?*1tADas2?>EmdZ(yQ$u{tUT+p&xe9t- z#0nrE$38(AmM(Aa$zEdoyj%?iW=44?N?PqEJQ(=LbZ=&>b%b&$ zO5}I+HWMc^!87)KoM*<8Xr!Y~Zvf9{;E%b8usBXx-mzAvExy)SoydE0p1q#TjwccbOS7%HirVPInqL&V^y|)Wyr3sX$eBN{i zIBR5#HF7TyfjQ9o`}^V;s6a^seDe1c5Nf--SX*7w#-tPGciQJZ5z^FRaqaVwKKDU> zC~cj2BZ6Ubz4_!zFsapU!Easp5ENgFN za5Z^BuJyZL=~uh^FrI=D`Em(7f-A;=0K0n$KD+aU1~F1=r@umaDtJU#SzOm!n>F}; z2`Z@O{q=+hLU1&Lmm{6eEiLJrl#dF&D_~q7^s$@44;XfWCzBKcA&O@7?%p2y=|Hx0 zs&WaL2ceZK#K!I>dstmx)2T62PByY{oOMr9qDsT*J?E| z%Q%0EDJ&fOl4Vfuv=A_BCI&3Te%=IpBImN~Qb94X_sb*yBsqcv)jcYFK0_AKOc_BK zqM!D#vsZ&pvzkzbH4K}I&A1)+KX)vaSC;jw&28zctjf9FJh4w+5D9#RPWlFIak$$fqZ*T92!{9sxPzV)CKnC?j z8@ovzLu2EwAN*MxV^FD9p_mI9i+fxEn}6^o=Acu1oEf6eW*bkQeyfv%!}#@X4aUi2 zQ3hn^F)Xpj{)7G}(%~@vY;|2T@j0E6Kvp;zroYY>_o80H{M?Feb_Vgw?Ha%#jK~*2 zg)?HLjR7_`HnCr;$B)1Ji?(uK0u!c-;<*`sPy$@*qkv30$l~WOUW(xx!V|+sVFXpK z;HcZh%grrxdujam$s=uG^Y#{_cY{HLGkabIO!8f1z5nQ;KI*6OkH5S?dziub3aKNZ zd>{JQ_|GdG9<<{}kDh9PraUn57$KK#+Qs6^s_v(VH{#bwhlDVigMklXC4IG%ruc0m zMx)t_Kfm`UZIHjwglVD}2Uz4)SYQ8A_j)$|?UzjqdJga+7z?2zmh1D47@b}ke|7(X z&Kn&{T~q{>0lW_m4h!Et^uibLs`uv!-Xbnu>G}vVHm)}Cr>STO{WQgcM~`&7+mE-l z_s}0?AP!~K*&N$@3$dj?K6{3AFo>6zRx}Z&jd-MtuM42bxtR|9~R}B0B%=xNZhYaS9#8-hco7-*ltiiH|4azAJ&e zGAsq6%YNpNIl|xn@e{hkES_Cn(@@a`^H#cXd6iOFT3XcIZYSQ}*@Yh{I4_WPS5XDz zN0KS=bWmGE>a$KqA0_Pth5>9?VC`f!v3m`vw)fjwz{~Mhd8$bKk zuSf?TJW|Ip3UU11lE|87Ui`(q`x>Bg$0@pWM&DK1KN2|~e)CY*59%YGzCfotgwGKM zsg*wJz%m}Z*w{SIHj2Nzdq)F+F}P(A9zK4e`)L}#*m#Lnrw7T}GMUhU(CcJ)_RDiL z+r9YSSNAkCf!RXrJ&m2ZO;+GglXAN)|B;DyO+|Aszw`e$@T(+3{#I4;t{B*}=iGbG@1A?^ zIUZR8k4FMgg!%-6{H>wrYN~)Ad_M>2Orbvc@$;mG?Gkrx?5alYY^dV~rHDI4UUxGo zFq-4GI)AO*_a= zZP97xxG+u17qRW{yf>CuUd=sZ4i}uwfvOoy=S9e7HklJ<0kXJ&gTeQsdbuK)COMTI zJOttqQa&h|ODO^oc_7#p8e3UeaW8iXTHU{e(+t}+r6V-G>P>V$? zJp0sF;~-i@Ov2B)mMR7UL5gk_OL%tvDXeX5f?6S*GTBXdF!2P|Gx=O!@8ugiJ8Hw5 zpLP`gequGz15gzlNcQ-m_}LC#h^@fV>IN890W_lu_3-cr18nQLeD3{^KDuF2097Mk z($k(yDFC%o*x4be=RfEkTTO4~=H`=i-Z&s<#IGkFJZ8Gz#2#-TsvCO(Sd0~SG?3&I zIuh(A{vXs}dkc1c?(M)SUMJhp$4KN0vfbSh@_Elh)7d1zOaV$-4Ghx>`Md^m zY`!Y0YOcM*vQO%(wfD5i2s6Z(Ztv_ITTHFwCZ}d0vyp?MR$=x@Wqg)lY9<;#| zwzDx`5p+`p0w$|;z3LFf4o#x}O{xrdKuAd{`j)dbzBL8(X} z5{W}LyN!JxW9EvTyIVRJ>5Pnd^B_4U-ez z$ivj^JR})zdH4K>H|(_Jud$hwJ7Spp%Ba1gBbwVO;-^b#SY>=VTwc(t0&J-UJeg-0 zD!-NMxzKx~$ng{K1f{RL5n@8HF#V2w`(Ky?VTNiY|g z8rCZ)bosMCggeglD2c^19>0B`e0yu0#8WHS-QrgySx&9u?4aD@5xm|2&?XXaGCJvg zl-=1(eShJ&y}f-+cKgyT{*bb=TEI8Qr^xMl({FCE^=-lx60|AIWT^ueM5bEjwGVBe#uPmh2@y*Fu^4)_Ol3dxu4wp|s zvWLktGw5-*2!5~kaK}8IL1w>$uIqqAk%60?YaX93&71n%@Z?px!zZzDxT5vuR8)u5hHbRNG8GZ1 zx(>uNK{pA+lc{0NAfaD$_lBLG7KKGY;JXhdNu82R^M1y^OZKPYiPWIW=@zW=vZtZ* zM%MWc3OW#~!lUVj!+Q=#=+dPx!Y(gr^u~akI3>$4tss)6iN1`Rx_DFH?vP(zqk44TM2>>21-Najiw?K5D=a4 zQtF$9U1slF(!M}INv&mU`xH-Puqd`ESAPA+umib+_aEIGK~6&eR3G!wON}Q*oPP3T zN{9+3)uF9TX87sJuvUi9FE4)`?hJjR#A9iEi{Yp57=B8utYVMPuQ+9QYISXWPgw#@W zptM`+y7J}kM};bnyW>EJA{|64mn32LF4^Olcr-QSba}|7zR#}{Q+mN}9|ik(0BypA zH-KQf#bqSRFZGR9s}72g%m)i0CO4WM*~1OFTNWLUpD_kD5QBvt`E8yAYUVKadMSYeYCA&Y}XD^8n`^1Lz$Z3enj|17N6K7yJ80_i6&= z$0#V5Czq`xN<7j>a8Sp>!rTzlDAWJt>!RESI-y|N`iFzUY__by(!F`G3u<#gpELf@ zkIfC|0de57fztz9ySc857kfwDE*Guy1dJGuR$nne1_U*OIO6fxP*re}ZZ@XaxAvGa zk!c|v^t@-<%g&=s*x{P+2aXy7qD0{7LS&#ut6dknSzq0gDTgN#<(1)dwa5XHt`l(7 zz!6O*hICpZy`TN&I@Gy037{kL!&maLj#es! z5>W>vQ9C~m2k;1iOOhOO(b$miU-qu;H;(EKuZQv4Y)k|}YOyLuRe@ZH*I;g{RQgcm z%?}k)RsRWntknNtO05<{(}-4T6A0L~z;1%mjkBzm#WAbJO_R+s*_h3+aUcoAYh2rj z$M#-kXLfeB-}%k)S$h^cM3e_AHu*F&XU?4So!?!VOQfCF?%j`s{H^XsQEhI^-dSnu za5+nCKHe?}S+tRCzuWGo=tlVZzed?L9ErFsZ{{u8+zPgQsJ-zWV~6aRt`TvI#%`do zMUg1oRh1~ni;ZZ!<9N;;)Jq~G0MJd_R_&h#pnnIk)Nt8Kl$kzxH|n;;NN3fW=nmK3`OC8TV`IDi0YJSKQxs9GcSb;pT z!|SK!R)5pEq}tokvco#i^)%`yHj3=AXM2NRN_;}cL(*U8A_<KZbu>-p0me*8udJ*~5&EztCFM(YI!YyaK@h@m@uC7bdj4^^;WCc=COLo`7CkUh{o^<2vjV zbt&w0NArD-W5dQAmY@9M`zN>@)x5vyLMqkUy5m0U(fv<^T>Wo++DgQD(xt=x)a}&c z;c}zBioT9$<@QQ#H)b^0>U_uJ-9hNT*|8<6naJ364UpviP_@k!|2g&5hXsZZu;;;wfFu9zHfEx{$Z%Ct&Ob55-S(;yE`766?W_h83HUue3QAM(OVj0 zmA!$RxD2~@EDP1?tVV$uAY8z?jqlFe<8o8SD)u5|M2Uc z9@F>T?|=5Af8dB@Ol2KWt+E-JFGqwU@p(;&Xf-9AsVb8*H6=P-RbpxEt3cXN;_2JU zTainnuMEWXGv{vgCseelCe9U=iRrwH3mQHkK%u$ot* zX%qcxbsiellf}AbbnF{+%t7)DV?Cjap~OC^fv1Zw02yHXiZT?-jQ(*TtiPwu^~W*C zB$J&$UVyl347d6Y55AK-`j7V$ld0QEJcV=WsuEKnYw!X$@H8<8FkQj?HEaoxZ`HMp z>2-kTMx;%WaU8mzx(2RE$VJ0-OvkuxbmGeB;em1e%%z3?==5#$1s?#i1F)Yq0F$Ls-9%C*z~-#E05{^3X+(^z3w`2hP3buBtJ-85$4vG> zm_Y+qY)`7_tARWC$5dSzJbiKWPlFTschXb!Cyc4>4d^e_G0vp4!D zNp9e)8FhdM02vXW|CPSK4n}fgifarG(}lJUgQK_w3<7-DgNlHN`2^0J#Te$lNt0qCwRy(yT*FZlh^B?T z()z+_7Qcl}i8TX)2k{j!w*<|v8C!ukZ4YlA^RBD19rzjrNJdeWWCn;eV*LOeZ|;vV zz9r!Lbs>(=&DMk+O@6{`ndkgzmcMoQQeGJdT^K$5YD9lO1)opn*|{x{XSp8n;y-lWM22WDzo;n#kqJ@+`q5AN^8jP7gZNpUZMwkga%3|oEa)p7lOCNp7M~Fn|H^65c1Gi)&yAI z=CV}bAB+#xTs)6xK(;FKH1z+q0r_}P+ZJKfptu=l$H}UaSg)IB7{B%WXb5<6t&qLQ z7b(Ov8k^e*n`0aBIOwrGuPtt04+z{j--|p^&u_-oXdI7pHUW^_GT2YKb@UW#=ebbC z{q5@s8lUV7TW0fr9v^SmNJY0^lZN#xh`$JpD40i@fcZwI$Cf(mVKCE%^x+K_)QUkmXi;&z^n5^Ye4Tg{7O_g|$V-k=75&&>h(t zxH2%g%6I%%RS@KNn*e_2!M4iuG|VpW1sk7@J7MM3#r7{|Z}dF8_eUcwyS`_X9A=xu zQvh111LsQRs@?VEQ^SkP3&G1-wcBwD&==hq!n6f&W_H`k<%GYDWVd=Y5M25FHjDe1 zY@^x2>oW`O`pT`IeS01qxqs&_L)fLqUTp>$kXn5$Z4cNFJowP?T0sxae)efMWXXMj z!EqrwWHk0Y6VD*UqEl}w~!6DSMS{%@7;4@wA5FY*>!B+ zV&jrb3#DbeYY$t^ecIFh&<{rL4eTjylu-r;_hHWdtHYjXuEs=CGT5< zp9|Oz`8jVIzPor_swTU#Bg`-lwKTwQ2Zca_^+=P%x`7HSJ%^JF3z`A|HVc%xau zP_m(#W?`MHS?}dbZ(5dqd2_?Td$P;Om-7&#gr|<&M2AmL>rQoB=~}`CB+CTm$SKH^ z9b>u%1$Dc5V|nRz=YQBc(Ld?E9}pr1F&H7)6XrX26XqZJ zdtf_tb^Md_Z*HdNFK^`*t}>?#TgsGBmAd}ykvn;pa~(@O>9o?BM&{GM_==a5rh>TRS`%+$a#R4C}% z%}Q?Tc1u(9eW^BD01!N0nM)Q&66SH*f#(y+7@v*EN%x zmpQC2fwh0|-S58kKmO;pZjX&j#OeN1mvQnh+Rv%d-{n+};GcfapmI7TyVJ5vT6Rxa zXqrKNOhlTUU9EAe3*2Xa*#FrNaJVZpNoxfgPz$hC&mE*ifKg<)MTUg%C&nt zIpwC3UhFW`3<$OflJi_s1KZTeh@D8SwS&MR9S0FI2uK2+;~fWCRe|X_ymtf3Sb;-p zO`4g0e5bp&Yba9RlCf-o9Iwii7eESzD99m-4Myvk?t8hN%+0Osxeg8M&2dh;Fv^M7 zUC6YNy!{i9*z==uy2c~7J{HMcfl$zds$xc3TN$|%uL})DB9ROl&6m;!hV_nx zBS!z_zI!`L?xvYnI&7u_a0=Lv!{0Mt+sa8pdFoaIZoTNM!>2{Eua7v+6!I$=aHwxe zYfIC2&YzcugrJns3=0faS%tlpZ~zc^<3d;4J=4tH+)9sjnEDEWv<5-Y!PGYiR5>re zb|imb5+3<-OL2@>2BpE03Z}UUmYG9YZb-|EGk4nCFAPOPEg8?85@Mb-(sXn|6F`DM zAa1m`cHC2TayRD}W;#UCal$f4Ij2pLG_XMj0E1*oU|nHL5Y9WAr0=01Kn&Z{wlr|c zEf^VT1>3W+sbMG@jbvzz^-Ju9!*c@ofit?hd+!;0dpA{OqeIg-sQx^sfJOW&Bu8%$ zk3?Wp4yfL~Cf3m_7nwy4T2M4Vl1!)nBkfD8D>HYR8_y1jLQ96(p^|Re!m0AF66=gJ zov2rua&t%B=ny!pKOi|a#wJJAZA*t7C(VMDrPaD$`_=#WjnDt;SAGYM*)AX0RbT${ zm%s6!zxKu#O%r9$yP$0od9w82+&+c8>-aJPA}Z?zOE%^g<{Cyv#;&cbuE}`K$v64X zk;*9@k&X+L19F@xDEIKgkGh|xhOcdBvSG_$pel}iIH9**ec<%^R1W9ZFHM!wOkbMH zJ`~va_P4+NuU~)tOTYcb*S`M7?|^ju07}Cs z60oJ^z}7Ya4Ae&@1}j_NPyz2%%>YSgG~~p^d%N4&o4M>_ zhpw%G01nn$G~i>FN&|Bu+j_wYYrae~oojTmYaICvj*Vgfpn`$+B(JSXYs=GjV&V8u zeWVrf9w@j^n8#UkKOW1|sVSiD=Q#s6N4%%1sPo%P9lE-PEF$Lf23TeWN_gcgy|cUl zZaKkGo6-QD{3kU>wiL@j(vb?1ivCkmJd8H9CUcS(H(E%1n%-Gw-!fe_vA!|m+}X~1 zc>m2@W}bKyKzA^jh~sns(1G)CpH;+Bk5{_ZB$-HvpA8WKc$7;Bd9@t;T%NjfzN=$M z3wy+Xng4RGxh@$YDRfq=T?i;2DG*`8&Zp(C}!3ZDys_g=cq~6AeSL`i6{V+Q4{P zmR%V?9X_4q-q_(gFLvM4_q3bYjl~X2&yepVBANKzHZ=gJJ-o>c_JYEmZ&{Q*)sq9Q zr2i6>e3hD_w3VK{)7l&z3f0zRNXEp^iwb4Oh{JoauXbO(m)l;xncJT2u*^-ze?roL zV}>`e;Z6LoQo$3WGj+f9m9Ku|*S_%j@9-2%0U9V9TE6P5zxAKK@!Mbh+824wTO0CE zL#KZTznp%N+fo`Yc40d zjDY{gkzI+Pj7|nbZ6fZZjRLNW;2518y1w_`PkO)gt?&HXU;p(tzVhFG_xHZ$ulnqc z_kUrxikAd(Pw6#gyW1NBQ|YAv4i4h}qN5y#Is)@>V`FUEbc_@)f_-AW|H<&X?HYxk z7^KK@V>GISgVDQ7a|^ddR~Bvv)qGqx42VYSvQ5qHsc@_zMMb#xl6|PKkvWz}2GZ1X zkk2avJIdyOrtQQJSrMXPDJ$>?>C4@n_eG&G?PPRN)ZSZ9Z@{4KSxePhKk;%wi9!(tJ6O{5a7-6>I&z+|qQV)Jg*nFpvmlE4e4_S6l?W!4AO zOnLyg{kZL?nKL~U3J-_FvFTtiLW2kf_9yMajl^Ml0+rbqYf-{A+}*{c*;`Lmo??3n z@%{Z>h{a;rrY1R68*NI_P>~vyIXsmCN7;ufMXxngfz7Pbo|yr4FBcC~`{3}<)Fa{8 zaL2jUX+zh*v<0l6QBfs0m++ai&jAKSlvl34a`)N9#I5z!^bM|xix-PUun)OxysjnH z*d(OrJ@7A*4adCwHAsX$+npt|K@tE|U4cZ28 zjr9tJz;J|RowgB}Kx@gd4V74^=I-p|{H@9Hi5no*Gh`=&Hmi$^1DVX`fU&csIOPp%LPB7 z+OTrrT*uvwwXO53EB3%@dT{`CGVZv8KHHydXlhAG!AMF9MV@>6j7>y+)yvir1wfEi zAgg2t_Vk^Btg;n%t`bE-mjc1zt_z*hx?v)pJjwMm;Kgfb-=5mq8U<$p?=COQ-`ZNu z+|Z4^cpxAG=c~@vq5R`0f59dI`ouEn3eFvv;nCD}*vsbzFcS*<>u!9%=!YUJ?$rjR z;nr4p+P1i(_VesY<0Y!)dmg}?mY*TAns=79k5+gCv zbb%KEijIc)K&TQ<+AR{K&vlHDY&v%$+lzY+R#-*oAz9gOee4$pe9HrCqTqO?esaDF z`GOY!I9hj2_m$0}oy_PHgi^m0tEyn9Z~zDU2Ow}fND>dMY=CDU@%nN*(tr9l>v;Q^ zc)WUbq36ELDqZ)w=jXXi6F}eFi}rMP5BFZ~UD#Mp#~(j={3|olGoSn3AAe8%{D1hu z1NgcB*k0B~(8+$JOb!*4t&M@*&Gdkev(SDpI0VqE#o%yDQ~fk^^erg5_L-}QPh=~C z63RXZ@mQl0sfD}qOH;STA5Y%kFd}Q)hamU^*}BFA+WfOA0FeepC-&5`xg*hf13!zh zHY_6tdwV+r%C>^~z89~mqJ0;$@%niBQdiskpb$-KiVnaBUA#NCKLZsi9A}vH0)Pg- zO5erqyAzXBw+hz54b!sXQn(g)zdsv|#ZvKjJS7SdFsVEm%u{{2GTS5y0`Y4YI;cu| zU~_$LfP=%hQ4kTA5VrEc1?4B!N3kFQE|kQSi`vmM(jkuTAJb}1C}-CbOmy*2h^ z>V_bSaXoK9tS*{uZf;IR!i_273y#&1biK^a;lQ;aF5YV@>?)aog0?fTo6W?9Lk0m6 z@e^%mLwyN9B?&DL)q*2k>_3-P`>8;>`nnwy%DUk=L^ zOC?nR63%;*7n02o@23Y?K^xF_m3Se)1ES>DIn#a&0=rQ(!0* zs8zbpT|m5FKA-l@4`jE}1K2=ux~_=66#AxtnkeBtg%8~3^zepUK`#_T!3|wkusyQ_ zd6d7pm5E2BYP{w^$2aE;w_T8@bB0FsK7CHh4I2m|G&MFTA)dRtv9Nq=F1L20=s%1b z=05nUge<;+FV&K0O9iC}IDvmhOx|7`o~VxFfg7ZBvZ+l4c63MobEN;4g)$PV^~R<~ zv{T_}+jDWt_Q!Z$$J{32AY2<%E?sK7J2x|WYi(`(2DUZ&rUD%Lsudj`G6?u`{HHoRk4ewjkjl^F zIa&c=moJs z=lZ%!vmZX@P;6>u^7_c|hpn9#UK^~g3F;Pm(Z)0Uu_(0DfkY5^3-mmbCZ0|uvs5|{fgB@*ptdfU3Y2c=j{M@4m=d7&IWsPv%dD4!xN&Oc37`w!(a zjrGvhkG!H`SzTUAY-d&yn=A8m@g{N5C&u((Bm(S|84a6eJzS%|vn4Ig%qKUOHF@Om zGgw<*C&wUCFC|`ituLXeyS+WVR|mQ3kj~ixcy_}ZfZ5K0QlN^KCC!dcB$sAZ29HFlYnlK}mA!S!tU)MnMkCZVniSrCwpTOsl+XT%Vj6ZEb44Fc@lx>9owlI@zd4OAKt+;M(-eU2RvIotaCnuk6UF zk4Is3WgR#_2kq@=5?$SDqNR1Sx3|B4&>slt&&}g_Aji`$wT`3BOo~)9OPA)yA19-+ z8o66;fV!*gVD4$KyQ9Q*4fFcq{CI0a`=vpFW4cBBIdZ8Olp&|z`Ip}{q=o7E+Qv1zw@J9>Ht`Kk!^Ri4_9d7BcI>dn(1K+b7i*QJHo`Q*mR zmYhmGh1JzntiKKCI?lwpdfKjUXE$2=uMG^^zNl{7!tpjd*&ke={Y0jKAADA!(D(kx z1Nq^@aoXUM6&VDBV&Y%^$}cC{&YtOQZ7mMQ>g#moaap>b1};L-`R?{vO`4f}kPOvI zvfP${Yp+<->By45( z&?%{fNF-d>f2H+$asNSUZ{IHs9srMhHApGSZZ*r9JbH#Be|8{^kEW81bs=m5na=wN zF!{vTv$@3KZm#!Cpl8tMuhE?VCXV=_3Vf9P#(513s58jVAp>4;pKAe75QhPTB9s*l zCK6*Mfkt9HXd0m0cycCrnql;oP2lyM7l<$n1~I&z99TEVN?9Tz9P?7>H~I)wB1knM z;=y7Ty)lBZQa`nk8XEA~Dp1?HZ*`^_vRuy9I~yplQO)ys&CwDqWR-#-yinpXD3#8e zjH7bMuj1)g`rG|(7&hszDA4azZ@Sj)-_#`3H+gCUn+91t@oX_K!-sC>j!!LFHr>k; z?m)TCr)L?4g+~F829_Co&IWw*zyIF%Z66#05Wh>ini?A(e)>zOv*!Td=Q6-y1Mdy; zk-PyIWf~On(#+_`$uQdd{wo)NqfIOKp$HJ$$ST(-#~!z~v|k+bSA})XNtv&>>jJcbQ z^H9j=rG>ePWKi_U*ZR6qXB$A*b*CRE*4Nh)YfJOJ=liY=7OQG?QIH(l;_~JV0!WW| z3TiPTuub&!9wnoaD0j9sLvw#;2|v-^Yld}wVS2Rn%*9s*@j4x)d#d9uiacdHsJrN! zO{9{E`bN2}sR2UKTBxoLKxRu#;0t0Bv+8DV*Tud;cF5^A84r;L8!ngLV|e;fbg!KmK>ueKTf9(?D(=OuEb}WzhG&Mfnnn1jlBK5k0Mn#YapI#UMwoCu0 zjkj|-X?bBf+1OAohopLvzayKit*ylJ@^WH6yWZQ?``RG*C7t9!{gRO#IV#h3Ga>+t z-5qHh`D|?n%XLk4P}kKC0nrCqAs3sTTe?0unriL2bZwCLaabPb1x&o`1FsKwB@;g( z2NMnozUBOG-+^e$yIyfdLpl=y@AdPgPgxwcQTZi8~8o)A1s?7lSUuaIm;eZc#wz$zS&yqTNbR9h21t>441!_}RaFuNFc_mT6?3kkO=2B<*PX08@3~aImyO4x&WfNaD(cuCEtd<50@YO% zfw0)nY>%lfAc|!fdO-CB&(}TvJ9GK8Q8z{VjjzA)hnG8hHoo|U-}qhTFG2vHRs028 z=<)N*`Ab!f(HgYzr|&15;{my+vxQREYJ)t413VqCUhRfxog~jMO(q$$%0r9gP2>TA zf=aTmu$=ta`w!$dzxM;!+)zQu7GS^NhlRN`{OHgB5{6S_^6KhFlHR+|2z)Be;2DMj zGjpTKNUdM)>u!S!ZB1aCyHG6bL09`(=F|?x9>D0MXY$nWSh6V=`Q)@x?(g5aVbi`C%L|Li z58i(y-~Zl^VKbeFovZ~cUkyvMS$KQsuV7?&OkP`APKrF`m=k}`J%Eh7J9}+tF#T*a zStnJ=ul4speJB7mJO?$^0yNge05b)kJ{FVHo100)H1T@lv>lbHd@(4(EVgIr(TM!R zKYIt3=M=E502B{Im>8LZxBvWIc<{kP9HfpU@$yqYhjz(1(=`P?e)vH$(G-%e^t3}` zOoSrJuPWe!ctaRE+FBr58<00v=93m)E6{zP@Br884+#P+Ow1)mA3u|S@c-Y1&2=4o zb{GnI4(29T;YUAw7vB5Hd-BsKkCMPFSN1eeq}sEx`b${eqSK!q4$D9M{t&FpZ9s9q z3VfE+H|F8pxBeQQeDp*fAD&2h;q%Jr8}51L5Vh?L1`eJ)8I#}n(R+|h8<5}efu(WS zA53`bPksy!K71@sJ)2BYCe;gP3mN@0OdURc{82Iyua|qf&qF*K0^gwpHG&_S>Z8zp zwgqZKVR>m~G0Di05l%OjGy^HZ^z01E|0&AUW;&rWZ^TR->-eEj5@JU2U@3`KaF zsWuG#)cGfo2Y5R2DB08ylP`3h11TsX2_V(*NF4l&U+#z6058u?jwUI^*42N%4d5#} z^{qHlK*#yH<(fbE{qO#(*FXRDFa7&FU;eLO|LTAFjgQ{{sKeop{T+8#9voGj=Rfa$ zeWg1g2}wvu9tng5P<*4~!C1R9tFFa3V{K}7Mz_ZCVgwWf6cA8xT*YF>Ydp$Z*HuSr z*By7qTTnKfNjMX7K|=2Pf~3>kdENbv{k>nmYC;!E)$Tv*bl0~Uy5ZIP{=UE8_xOB| z7XrFky8~M{KXLQ2TYtN8%{}+8eeszWu3_R}Of4buZI3+hv-N8?uiU?9zw+<{+kd{| zj{7$b4~9iH2Aju}>EDS@j=W)7(83!2@*f{Be)xe$?%uF=^ZI9h|Liq_#WK9fqy5Ag z@tLQdTe@!TmOFp*>)SUyxapzWo_qG~%g@RYkR=x+PJ%I&Kva%a9n0Uc@v({rH*Q|F zdilK@9^CTqFLr-bQy3iADey5lJ}KRI&-#^{);+weyJgV#_@mozUVhu^_0Md7X(?;4 zVk~Gvj{su>G3NcZ-@kJGng>>_xMTH}Rm<;P^X&GguhTUhS}2AuKmN4z;Rm;kn{VccJWqp*)C?5)79#67ee~~1;Dmfn|4tuYNPeTv()nHvxB)m7RT+Vd zNlnubi^sqB6F5@ALtTrY>trK2^M2(L5;Xh0GJHOne7eXwNtio_=ui)*40JYDq{+B| z{-jPfAss9q!>JZKaB?X>xM(qQ(lcRcQFu5D`7`|}otuXlB%tUbegt6KG^asw`eTq; zIMq)YwRb&TEfpk-s4OfiMoG~u=-MPC&cv*l>6kya5Lp4A(sr_`0uOL8TfH|{f;gSXAD9FiHI>@y(EkgMFHhq_v571Dz zry?)Qt&|n#!S7;`=J-!(E)f?kDuoTkpCZ7I)8c!cx<}rb5rO2>z9Nwz@spY>l-yip z0kOk58R=kRF}OJng#{71##ryzKZEmT!hfbuX*hnk z!qg&E$%x-{`)N*9%8&+tuMHM{DH(gkNyE7{}Lkq0wRC1 zmjXVC$REfg_iFo=={`|uZE2{W;05a>?rdUB=)I4J(Kt$Tdk^($+%kGEZgW%*IHW>oOgr)9I|0j;@A^Y+~;(UbK+N$%72H z2bmrh(!CO{zI-tP9+v2p+6tS0HpRb9DG*8|Wi6W+YOe!s9-{+iJa4`F*0r1Ne{}h> zTUKsyMEQLe|6`ES6+PS7nNV{FQm5Bv~7M^TD{`Fl@F|aa9MB1fba3G+i$*i#rpM+ zKKT2k!7*J7cmZ7l1j64de|+!Ct(*UO#rk_UY*};n#x+kq@zQm?lQj9{qg|!U!MVNIQ*{s{gTqR5U4zOy zk8e#~dfv$h_V;(HtQA!j5XJ0~0oKrvLH^(qMHt~IM7U5gdoBb)SBA#gRMU)5MS39x zohGvAYHm^oI{KAE`;Q|Wv;f8hixDsp3d5h41s-l3Ja8OCy~E1HcrUqEI*c$8?4%43 z>1u0Nhlhrh)`lkdTyF3#7IDtRl*T{{3BZ($LzPD`PWt1!Po7YL3xF`9OqKV*Xs=q| zT&L96wZP-bOehUjLM*}|9+n{Ud8ppgM3iepX{tY|vb4`OsS%PIUrz!YCWZ$4Rlk=b z4rwWvcm%v|z{LvS;(%nzNcUtQFE<|y%P6G3PffaHDUS2>@7=PD*5($qx2sz@SXGTk zPyM={na2c^U4PwT}2h|Ke$vn-@g;z2V4vira zpF$iu7#Nuf_X2hwA(9cVR1KKk?($$rae^nizyAYXT5z`G=w&Y#u zfG*)6*&Cw+W6I=YzsmCwz>zF`!|hHgj~B(?PzUNs`l4GkJA8@2HGaM-?$bBEFM*R z4-K4b)~#Sfr}R*@)CGKfFLpu1O_gdMS0mAcs#t)dZI~9IOm{i&RWxVYwGm8 z#J8`%`uYvWj~%}%Co5;@nxFjr7qfC^b&&mUK?f#IYtr*izp!kmZ$P>FiX{hq?zEBi zmd+)Adgni{V4dm%D{iKbkBw)4`N`+kx3_gH?)-B^X9iYKc&q3`2SznIo&Z& zo_&~PzqhMt9+B+#LI^Oxi4qvm1x6Ae2po7$$D%S4{J5ZWHXNe+{X4uMnnknE+L^I- z)nq0}Fftdc0r-S8$dDj&ER0ByCQcSDEQZKi%D_Ok8Z&jkskShu+fdr($rIhwPwjnq zX)y)d8C|yn8u(<%4s_^u>P6+?c|#$=wW^yM+-@GpY5O5|NO73i=y93I|;Gjx_-1C9YRDTfv$(8V*T)Y8Uu;8-&Cr*IG zbF@NmUilpO(j?_%OQY%l%xCSK=_Vv60Unl5WH9@OJ5&ZS5`gCt045V&-UY!-+@DT# zs$ce!jP_!1g#YfI7L^8$$y6$vRH7_zOHiYgrK7|Bs$IEJT$l@=WFitCg%&5jK?lQu z4k|Cqn*kRSQ%1W^spl;Fgen(UDOmbNF30QjwSM+k&wTYlt2BP8OTCOei3GP)0K(Sr`1H@%tPealmwX$ z(HgXQcZHK$nB`fS`pqlMr~zwxN_HmVrm&QC?C6ze`j)S{qe<+6)M%^28Y^9D{xC(tVEn zWfNK`A^*4|e@SFfQaBTWIi>WsHK?*PGXpTsPmcUY`rB3Bu=i>fyoCRx{EawZMZv^F z_yW{E6F-IUPr$^Jc zQT=z`*R+9@j78gnsm~G$0|Ml@;LquZ8E zj0FjByWpUgv_K!MKD^|;w?Di>2Zye{d`VSvLsR)jAO88LP8T8Eyu=W{ zHailU%6abD7jKz36ZDxnBMc1;Usn0e?)jl{AQsW_*dtFZJydh}y3-@08FPx}9?d5< zpS1QcL~Qu{v%RG|KG|^-Z}7s8m;7WmJ7vlry!F9NU2VMqs?L&Nm<~AA(k&<3(+=$3 zQ&6}6NI`v-O*NE`?K@mhx9>_>I*+!p8a2s+xmXbA^)oeIBdl|M3kOV zG!r}*1H+my;!(s2>G3$MXdH+eh($t}nH@kZ8luMO+m}aoN}z$$q-V0FtsSD^CYRt6 zWyF$*m}$VD9zZl^0hWkeUw?z>R78b--eIH8BzqIRou|~fN*=r(4x(sLls6uW!-&yd zS4aYnG`}0g$}F5AhTM!LkYyGZZqYeI0=>p#C!tMRaPxk!ItRuwXgM>vT}%d}5EwV= z>l)DB)}#UJ&x{!Hj`7V#+qO^x*! z?(b1Au>G7K${1PCA+^1|o$wi;ft_XOlxIV?5b$Rs9ucUsv}?z1Xxfy@gZ@8fkdWxy zr&F@ZvvewXPfv$hSX4m1i#ugwcIMhg+k_0A0lu;Bt9TRFIG0$dJnF+JyivntdAR=~3&Bo`4Y* zz%nu<(E~y9fMo^5;}*SNm*7Kl;|U`FM%6?Rj;}*eY|&AoJOvIy7#|r?>+9+e4NbvC z__s_BmSw@?NhAE*nH1X*&OzeUb0WuTGt~O9O@zKIg9S2;P?b&QG!cy z+s*?u*m^VuuZu?!S@R%qI7}@B$2m=zHkWMopgr!VhlkbUwT+mXGzkA5%DYL(4jRKr z`DdZ_SPMEk+bRD%ZxTYvi>H8zN#1>ZgK9&43nC%A-;{+*_Je^y&wrMG1`JIE0}uAw zt#GF&)KDl0S>`Wjng$1L{g+F41{l_&dXE@h#K~t|j}m#E1~7%9**OSKjH=Us7|Iu$ zGNs%yEnr$+HX7CfS~x-++&OKx-}(==>(;FP;%|QR!*(qKeDvr4`e9Uyc}j}rHmqEJ zTP4Zbd>WmK;z-Sri|Lb>09a8AGAF_7_D;R_>Z?z_{MsL03Zx^(yAxtHQvz9&f)gSv ziy>E-91dF=H|F1n=3cIKPvn~Qnand;2o^H2TZ<+bdsv;&Vc5I4DVGsl%CBy|zRZ<`XmdQmzTJ0hmU#%8|q?MN4m3Fm{xv#m?)6?B^ zx;y9lPFHL0c(qHF|FO($o$a~ZGiT0szVCeR^PR8#kG)^H=gWKVz2~02_k8ugbG!Gx zd-s0po8S7S{u5LB6_dgDU%ls^Up>2Yc6x4Z?y1{uf7{}#S%IhaqjN9JZ{5BL-KdQr+M*W681hM$ zcyL@FB1z$<3YYKLrj_`m`7j6&sRSz9;NB!7j~$b%x^~qrZM+U^e(vi&(94j;DQpeH zkUPW?a0@wh>5P-sD)G69WZTBmIg0Bb!JIsCOzRR`Nk1St%JNC%;FhNul5WJ;*{NyG zA5P9EDgca(8Z0A?Gny}M-#)|J4~58yZxk&>8t1en0C9T_b5j!(lqvNmD|_X7Gu2^V z^XB98J9kYpPwGbGpy)ve!OfN=_fzISS6{LVEj?FMLoJD-0%mGi|LJ4Q@0*&}ZJV1a z_561K|CkVMG&sf&uRJOx{?dmd!A>;YrDuf^*%w( zcd&EoCaf=MhgcRBvZ)Bb6m(zAcd4tqbo}W2&(;^9jJRz z%cq3(59yxogug`3)scD1-0MPYuTb;4OSju>&yh$d6f0TD$A1xGs4r0$LHs^PVs!UH2yu$;NP(& z(^8`Q8>wsSe|82<9Z*CP0NF+d*T$E@|C!@Q=6B4J47C~m(9PgKM@9N3!y!#|7REL- zn_4&Lf}=$d{Nh?>U0CL1kQM#89a`oNRVz%BsZ!|1G20h5jW^3_z3c3l8U5K8=PBbU zQAybcP-KP;6y}KIwfTvODttXw34tuii1+EM;zky8W*|`^TUD+PmL=`{Td;TYLA z5Mp0*`4xvg_u0>U>2+6M`*7CF@zhU#dI{0q$x|oCbe7d_s&RA29eeNn-QWGdUwr)I z`@Z|pkL-Jpe({lohkk{0gg5-!%@4lsJ+~dWet!4k$b@+0`;S~Rc+!%TV7x!@zysI* z&#!%L@7-Ve;@-Qz_;UNom%ps<-M#nQ4?OToLGX8woz^dgljHAysOInZ@`t>JutA<& zCT!Q$|7W~t&1V0!2kAKo#R_~UYYbGJ>6;=|?w@ldDf(IC)Tz@*)DTjYajlGAO5S;i zUXq)IBy1h|S=N6?jas$J#u2z^*TB(HbZSDyYSe2kl5Pif4%os+o=ON|vEq^2A>v+0 z87K6-;U>xyNz&g@7a-gu1HxY3ICCb1gJBJ~!>OQBCQwv#sy>E}kX&?Ud36P89yDN) zGG+16ZR_+KeZ|pSPc`(BS?KfxJhuuVVirtk8l#)1sMIRxge{z2IScqsuUBZ}gNl#<5?xEnH8^*pn%Gij}9!_fjH zL8_k%J$4T*!hv)kbR*}?P$gxBC25~)NKzuDTc&1}__54Yg2ovl>4lBvxi&nj4&+?0 z6c8CZtF~;J)<$}OEFIDUxraCn8e9$Ds_AAGhVn-IOU7}6PWwz_bZnCzPnQk(`p_`e z1KpQ!0ip+KLBP|rGK?^c8`Q-GD?b%E?U70wK`TQT2zb6jG_0E$NWC_~3R*65oIZC3 z`cn-c;%B2(7Xc9vD|$r@4Hcr-Yc-n9CLHM@%LVr*WTx*cj8AUS26%`l_H-n%jVNgs z@cX(+C^cAvga0dv$GJ3)#@Vx{^_YAhO*DS&0v1V1AFs9bwI#g{5_n$L$jYL#jHDvN zD$-qP7)8*i)NH6chF|qiA09%d6T%X9QAA6@cS3BgDX7-zMpb`LWs<18G$2YEDD{d6 zagsEeXDM4{1R`^wlp=a%1zHyx)Xut4_ftbl<3CY^|8>T{IqGd=Ey=ZY1y@$-kH*=h zCQ&eK;UN1c8&V1KY>~*LHgEegE4JL=mWXZ<`djFzCvf554{C%x0uHk}PiD@Q<&0 ziFowzFc3ySH-@#m+TKJCnuUiS-TfEed+0iaw4Q1B*OpettUjlwfjxutE!_5ww>(Pi zm9|hR8b8Gf&_3dw2bxN=4>LVu~KWdS4q< z80I&YHOA}F77|VhAhnP&Z;^nq*zjowOEfu+>>@|>M(YV5vnPdYjE;`Ok~v}(=xYUG zqL4`sNQ8cFGM`3l3$Dr=^xeXt+b^5Tg6C3YjWMqZ6{akcB^*GJC>2Hlr(yRp)ao`Y zC)WL`!oZP*qa-TUhF@m-7_Q1&U>YM;TjN~cNhz2?*VGsYu8nRxgkSODX;^YQYA~30~rkd;~^mlBc6**TQklC!*X(ov9Mh#cFFg|q8xuvMGKS=8_l8sjjBts$jD{IeH+L7sP7_)LWVudi)q!f%ubD7sxXK5dJfR|7w+FV1SX@ zFjOZ&u4SYpBctLzt(e8#`D*09zQGm4T-|*v)Uo4RRQ$EZ1lrL(Sly_3&I2 zsnT`@^$|h!mm03_pm3R;H}Wk>ULhgJWuszOA%)BI%=pjEIDD%Hm3NTz6g-!TUw0a& z@;k|OpKDR@cOdl@MHa*w5k_OU;vFMMT@*1sYb7Q4*6g%+}AHiqWA|QA;CE z*y-px4&CEt*Iaewp)l;+{NRJ%ed}ZUAKCq;Ti&?;rW^n1bJB%&@SWaF^P^8D+wzBh z@W;2>o)2O@%gvQBS%|N0tPpo|yzOmo*{?IAdMIjhVX#tP)}K+$sx~G!k00N*eJUW? zd)4JvA3O5nBd=d-F72do`7ZPprJrqDc(|yytF)-shlR?Aw9yO>`lV0=l1sQ{mlc^$EGb4?IexS z3D+gf(F-SzZ%%p)^_P-G_d(cwM&})!BJ` z?(A40XG+>5dXbjIzB~6ls_*JHcsgKT5p^Gi)cQUXB?-u3xE6%Gj)`n+N${GjmQ>u> zt-6Jw_z&rr_+LN=2N6sdk#aW#k>$uaRm~8#zF{I7%Hn&q`Utx5(Si6-zwKOFyX<96 zdI@`3Q&mR%IrT}1(!0!`&+`;XH)J6oT~43hP=u>m9G>28wIHR9Or$0y%p5UPjy2OQ z7b$ytTdjaA9Fx#bF6O3_5}hbw=8$GtsfZ!Vd0};fE;FyVw~joZlwKl!lad{&!3h95 zK^sY$!12a)7o1~`0%RU%ij*TXooE?B*uHp<5DQkz%x9iMr3yk{VJYL)w{0+I7DcoK zJ;ZSU#o&>_IH>Ha@`M$~F%Dmxa=z859ep zRNuBO7W6cBzSjvOIIfFc92sNUP79->Z!)v~h)$_Y^LY6;Y>70e_DYh%P(!9dQY4sH2+J+t(eD{zqoC$y zRK#gpGQ=s^N+eMC%xzXoMudb79F& z2SQemli)pe?D!BFNNw#UhyqjW>R;db*2hPOhnF9H^szT+2hG-Re*2qmKYQ-%Uw-IA zw;k-MuC?A?!?wA(giax#bvQo0X}^>fEo))<$P2!~@D`C-Zpu<9g@50>^?;+$?2u)h z)i(xy#rIQ=s#mI#di&o0TikiyefPY>ab&n-*RE$qM~BrjPd_tWuh+|hVk%1sm)sY< zKL5op-SXt&Lwhzgww#*VI(sZmqmdIYobbJ>&(5o`7oKM?dGSsdtm&g9$$Ejb4FJ_D zkB@chb~j@jSd@)7IuUrD?Ak)C=xmA;qZ1=dSC;*j#7C+3hYuZ|dhYq7Gb&Cv%A0M# zZ-Uuv+ncxC{LfBoD0RbEt2_qqt6%wF*FS#Xuim_C`>rQ`=i?v0zt>f{a@<$7b0h0N z0=STsoj5{eqy{qC?KCHjVQ42W<~9WzQq|!R1aX3kW$yZ}%ZB4>s|(Bak&1*TS5UXC z2MZ&sbMBpGVH9>Kid@Li!noNWl6^!$L~{P(b@m+_t#!@kxEO8~Nh$EnIw=)igJzZq zJPwg_0b|?td2R&%44*KN3;6?ZR@W8ec726!3v%Wk$|@#pZ55^!k~v;Sx+waoRQGMIrN2>aPRX z)St^Zv>j>mEe)u}3dDt1a5oM?JUPvj?k{28qo2NWWpqj^l-o(dfi0u_DV}GRDb7ax zw>178%dGdpU4)1{)djzInXePgU!nImynfGq zm~jZYFq~pz9hINg(w>}{RXznn}VK{jaba^7C!mwl;tL&06LU7=XjW)goX+_JLu?sZwM=GF?_G zMFH7j`=v@=z4HGTev1mdhNRa_I$ciJatlSrhJw(I85J3m`bj%T;JLMu;0BL796VK{ z;#Zq9Gc$en9S9*Yc*gVG%rqHf+^;O}_eI!T?vo6<=GuBhER75$-C&9n2@XK9a8|;@ zS`hPRGcG*jz9JH>K8{@(9cpfw9fcCB$n1cXT9s4uy~>43dFzhoV)OJQTshXXtWh@J zl75@4Fftu)sJU(Hb~eTwGKO=>tyF64p8ia#BiUo9R-NXB8J7_T$Y|mD&8fKwWEMF^ zLK48me4-El5#OKPI*DrCYa*lXy5~E_vq)o?@T6?gRu7~xBvMxB>|9YR@DKE0W2qgY zHagx^=-WckXW`O6z7}rN;rdu}dU^|G29(APM@oo6^2Qq#EJ5QF!Xfs3q2`}eqg@f1A^tWktSigyx zo-)|wAmTKJuu^?LH28PNn<(*Lrb3rjg1MKmr- zB4bn#{vEg3*2;lMyPT~7)rAy<|Ad?1aSJqC8vkPxjQ_#3@62e9eL6oCEhPB2=n+-dV??A3w2&o;5a4 zo~zcYXoZ3N*uVY2!oH90UHCV@^WKFIefW-rZj3x)XB|0M6f$-Msy^jang*+QZ}rvS zu$cDNv^Eh$<_m{^dU%!$i-}DWE5sHb{N8tVXCk$3`Smw_=aYBsd!Vtoaa3uTyGf^{ zYv~bJAfrUk`n2~S+<(1SapO<@r%&DY;g9THa4X(gwLXNRz#m-OEonl3pIc62Hx4ZR z`^qaXTk2&oI&nDmKz6=+mIdk6nyrBNuaA^czbQM(j*6x@ z(=4?z5S==-HZSr6Y*-ZXd6jDT2$y9s^HGrkg4TLMed-1*x3rN^uQn~$V(u%mjWt8E z%s4oPG!I#B1;_=_QgXh=&(_-{??;+621{x=VZlFyzB2zP_@_c{yR1L8ItiRgo%NgxZS%FH zMbsZ}L2!hE6eNw4vWYxnCq<1ZVEK zn*LysA)2v~Klq9g6BrPV5T5JkIar3R3{J9MSk8eZ5XTY{(O%z|4)?32HZHo{eHthpMjArmG1B=eXL zrxcK4{l$NBhNE_FHP)NyHq{pyM^ySu@`a!?ro3||~D3;5P zQ{907p2mM>%Q85Wb0C876riT(s7$GnS=k2hpTS2}>pN@hHKZE;ybu4hK8gB-qo9aZ zgAle;*Zo%6S(rpD$4XwDSud}Dzoz?K3E3Wzxhk98*MxqiZ315ZfGnMt#7m0P>~!0B z{)VIHza7xrdCdQmt#o7lNAt-r(vPl(Z8&=FGo@Ijj!sN;$419u*LTFBA0OU?!gzn; z&=a$gin32{ZWW*~4gcCL|K#~U{laHIf8(#*__rT1ynWJ=~iX|A&9O&U51#vQ=udttg{>b%ywGw~& zGoQZigLi&#VRF;tTC8IDLq%pB{S%C99+eq?YVO$?^W>?y>7`n|ie9e9o;!MEG7OC_ z5UeY7yU42b%1V?5dYmIGAH4Hj3m^N$dl%k+=Q|hPc+1U)2bE#pci9nha+_2P2&RqiEt z6%YOA18;0>^P(nLKVv+vUM|J}*!&vA@v&Ac} zxPlj|B~#O1hO%#12|v5y%FD2Mva!hCw1IG|Ieyc$sp%byr_Zb+=ajQTC>PF+!oX!k z;-%9o+Hl^nsEYDf7kx>IsjV}MJFl2S&kB&ruwZtkU%^r9E^IHyHS<@)a)uZAjBt>G zkf5-gOOO7fhUK-dy^d1r%8UbULNUy?G}~3Ky7~%i)^qf8tROZ<8#JF+USgaZGUA9u zn#IWSl;;sv#O<=Hc42bU_@bofwX*uDcwo^=ICgb$X=#bP`5Za&`;J_)a)W<3LpXW1 zh4C$O8g6zboOgj2flwBt(=*!_FVV%}vfK!};wd%GSm>!Xq!;6L^RI#LdwQ(?D=xJx z<0v3261E)DG|)mf&f$0!O_oDQAxq_quC}b`Iw(sR-#oLJu&ee0HVPL9_2Jb<7B744 zE+_<)k_?F0j9Fx)2Ovoe{;$^f7qX^ls|satUHY;LIJJz!j~f2j9gDkOb178Lu(RM~ zg+Tm&?!Gj-jq^J6VlWsi9D*cBa9;o}A|;ZN3CXhK?b+`+uX;(8h0fBZ^?QBiy`)J_ z)Asa7&uLH3N!!!JvC}3_;zUgyJFyehc4RZQV<&dwSaMujab1mMSqmkR9PR`OE+9Ar z27|$%_ud&zVOWv-vkt)TU;qq1eBXEPcklh~dU^ia;0;`!e^8+{69tFSUzHRg9yBy6 zyZ4OPZp=RCZd5dI)u5&ql+aQyo|#V;_%p`hd=u8LywO9=*Sb-9DDKTtrUO1dt~?d z%jMj@bk`RTe&_!0?mhbQi6+tSg_?*ARpEd}Q~tmmA9x+DZu(McvF)$E^!Il>bolXI z4?i+C^2NKqc2KuWZ$JhpItNb9O3LtaVCOW!WaWlyvBTjx9%p%2UQh0N>e**U9{Q)T zJ*Uo{x=!$W;F^8APmr)v*Ibv8H2yzbG9`L~tfw)kL6LSzxB z&mFsalBg)0s;;Yo`yc%7?|lE^ClZf5{*!_4Km4O>Nf~qPb^BjND;FGn>7|?QJM_Tq z$B&=vyZ;}*cf$kU{lN{qohv{}hoMjW_HQfS`p%(4_Z>QP=$@~C_0ZS8YPY|?_p68Q z{>oj4{^BqH>=Gl?(;Z>sJ75T4K8HfTla% zy1II#ACCOw3%K%)<>B$M{8U03N^4$I-@@Z8FWX(gpxjC-Z7to(^3o<)Y*D4=fr#Ym8Io%VPYWdO*FC&d&Z|@`k>c7X5r0}H zSTIb2!C>X@Gk=<2LHVQ+`91Jlt~y@bwD?|i|A4?IBlow0Qm@@RiM<KfXyZ=Pw{_)JGWCisVx1sub+VZ+}as$v}CM)M>1BMvX6)=}PURXBX) z9pG=`{3AI3)EdFoOZ48^_Z%vPzkz)QM939PSV1@m-hcv*3~$(Yip`}}F0Qt;^(ynp z^{e3@kD1N{y#EEMEM2L)|H~8Za#wXo|5RKnkg9R*9Qx-exb%r^}`p0WeFt?oO zot?u2CyQ1QzWcy~AAR!2PmSFFz~O6-AAjXmAI`5m-gaJ)_^1T;-1~P2|KWRw_rCtd z$tKH7VR}W#S~-ox+}jWQ&)35dS>MWM+WzK?cil1e%!|8z@J~;TeCaE9A6!}2y{1JZ zq~LfCV!OO1S5aMCWnL8O`R-OTxa_{a~2ANs+A2bNPyT_i{RN_i!= zl{Y;_(X{yow=$;Vv0R=rlDH;`hMXy{SAhGzedu={JMyChj&I=6$B$e~`0`r^-}^GH z{n1xny6Nxk{rc@s{`7^uhYmk-!;z;RyP3R-w*p9yV%U0#&$<{*A^x$n| zxcQCO6ue7^{hxafMz$a$O=pVg+3{HrC7H~2U;@V`^7UFa5C3}h5@GVjnD#>zIR}p=;Jo*t>U+8f|J+E;D+og5MjC)vg{1 zuHdUy7wCXn@PO%|BfbR&c}gI{=L|qC=`7GaBy52oP`p(+aj49q?+|{rI4j*dy4C$R z?q%ghu9$(mwN2rOP$Z><--2szNI+*_w;JysRt!sGOAGfWlnW*z?8NV5v2OLY+inB$ zQ|FjW(Zq4-V3jnSPX_j2t^9$3U1~>1%n^9RD>irFyq-;{IN77_y><{hUdnT@38K$} zUR5DvRb$WIVwzjhzn^|J3iv@YA z%2D#cn-epTF$J}uC63JV?E(ZJ@UihL5d27^A64SCo;U5qvF33tx1ea{K=K2<@@M<6 z+YPZ;yBh1neys|3g>t!11ok4*vKEeaM9Jg|>csQ{tfn`?B)3Qa#0QH7h(Zxyd~zD{ zMNnHix)ebS*-8huy=8qF_EIPUvA*5Pj^P1y=jHkHdkN>?pu`8d)$4HnB{7fv(fqf;7a+n<;Y%i5f5SD<+lT$d zdlkV6w~}alJk;`LSL(TZ&yF3t6!Z{c`~u))p$vPEHwOhP0|Kt?_3zmSy9S5USa-it z>9HV)0s1Az)xO?cO1=OH|0HZ~{FI+)sB)lbKy@blRK4oLmQqNwPVMRvC z<0t$Aa9Cr`s^g=MX%b_hBze!SlapQAARoU`)}O;YQAW~bI(2h!Jqv2nGg8` zp~7vq-}=+vdf$Nw5bfW}7xcz|J9*;3x4!+Y&m4Q@=uP#l_2ZxT{ZBkaf>3+Bar@JM z_^F56yE_)oUOY4O_)nhr*o*)2i}$B<>5f21^sJ_{By_QWNOj%>X3n-yXc-n&7Ge*C zfZg2M^4Ve*#3~Vb27Asu`_Io@|H3a{_^@8o1HHStU%BIxAAFMzF8}?#x4tg;OUvr~ zYq#f(e86_?7Ral{b*uII0dhE=0_4GP=+Ni?^z&m)&CzpOZoBrU z&p&(c@h6Ua{KCZe4iYLp`MV!G{l5+zc*Zo%(z$czZv4mlzw=3SN4*(c_QRqCS5&SU z6nl>iL}!nS-1u5I*`nrn7m4n^D#tGzyCnG}3ejs%t*i`Rx->C7Ii(IOCzT#}mp&?3 zle1R^Xh!9;X8P3E&Rl>jl{O3p$-<7!$BC8GS`OYga}jc;SMBQTXM=`tl^>u3V@M_i zWQVe;5p7OF-V~5-3Sg9gl3}vTxuzFjd}ygDnT{{%+6Uum~jSDWlC;3GT$PhsVd{WD+^uK}+Vdin+kF>T5viTw^q?V9& zTWW7N@;#cZSZ)9^!7bfxNzm4{3vr-;mEq@c?p_|BAhME=*I3i@K(stxlvIKNc`rzz zFa%`TW%R<^8$+@M5AXTBPgPEhQ`!TN{8bcULVK3?u4a_rHLR?+UGS-0@qU)k$~SC? zeo*VT|i1Ur9e2H_S~TiOR0_IlQEbFPTo9NcxQH32lW#+0pss2+dg zJmdi3gX1hvxEjkwe$b00A?@be;zjks(4&t(^0DWRKKK5O%vwhg@@xt!lnQKNG_8UgmMYh}o{{B^=cZ>( zx?p8iXLtPEi^q;$|M-uOe0W>m4(#2Zc;$cp{s-QqbJR!f_{i&MU|GH}HNNMi<1gL3 z|2_MU1*-yCtoj&x?q|;rg=Jvgozry=PpzsJOZ#rvcMOdYS(G6TPRvd=?A$%@k~ipq zS6_ei_QkbDD(d9q39{IL0RcN#iiHhjAM%!9zWljA{Onj?|BiDQl3RQ9=nDrQKK#(f zr__lZkp=+{pr^)vyX}@|ER4NZ&YrsQher;7^5_5Ziz>_i#vxQ}*EMkVFie6HboLBQdl@ zHQqHi77o{Gre(OUX%@JNvE16`ocN8dN$4!-GM0=S9UoV*2KW@LET?&V^$pc9G!%yc zJOuXb*f|yo2C!e7X&EB-@>Y)n(d3%kdVWJ5fAil)Yh-`Cx2qGP^${);nM$p}VseGt z)zto7BV)l(R5OXG8;6%`&n9s@=&Yc~dzBq{`dr$Mcyg2k!gpfP`?$Ez7f0=SEAG9*=j$aPCcXsv@^awmdAZtf>RT zdvLs74Z{e)s8pU<6&5`cK;p8QtJv>_(Ti`6$1j|ogq8UWNIpNvkq`{;?T6OxMs?@# z?lGUQS^E#dX}W}$g=rF8oVfm+wu1O{X;ht1{Cm|BHgsibzq`o|<+ttN?K zz_Gf0ncSb7ztoxkW%#eia|r(_g#Y<7=V5Iv4O?4V(9zb+@NesER0k6yyax5+m`L>DbX6ZHS2RZ-LsfXR!18eG|4Ynb}~%15V&raXhHFOPzA_n8}j7jo1@h}BR&{wfSM{l^Ii&FnORr?qbR5y-F;(KHBn7BobbOZ zb0?0K4~Jz=uAI%R$#c`^M}vM(yrZQBYN`XAw{l~B9g-{Su%6AUJp)5y{_1+%p8>qz zfRGSk7+E4G2;~z(NU|*(>D08mynJrdFF~9_{=(sE4*NuboV_d3o4PtMbiPvP8Ye>K zjT>+ii<*K9CL8xDe-O^UfHKMSoH7~+l;SPT&75Ze_Z=)PF2VH7G~@~b^155b1fjEQ^Fyc1;;K9~H9ktE$}z4Us;XohFNLL~k>96a zVNFx<;64VPDy=r$$jVH?t(0rJ`QG^Ta!vqU0}sOgjgzmAHe%V-)+oWhhC?3K5my(J z{{er0Bu=<`1-0R2MKf@SQ!cwCPpPLyqmf{|z9tMc;W|3NQ%PEwUtUFAz&+KuV=P?T ziv5XBI4|&PC4DOAPXSYdZEY3T_RMHN^2FoaZBQlq*)uY;okvAX2J&W5jl~AW!qxQ^ z_$9o}oL9)L%kwki2>y2rx@w|I{>k$P z-LmJeEy?P%J^x5;7;5EON>sAe$G}p1$ERuS|PiVn)PDIEIah@2S~}M2SYL zXF<;_%99f(M(gXV;+TiYt)i1cxg?1&N~d*o*RJcw{D@NqDfmpzQR41@8Xx_Z#Y>%a zO2d^PnlJd)*4Cf1nRu9^bk$wwV@&h3tKx#ovEMw`&d@ddJknkT0ro!#rN+VkD^{mL7SCmY~ z1h$y`It2$d0StQ2n)%tenZzcRShS!REflzPXsQ`Q2q>I`Hi5q8RHvGoyOg%J9c;T)~dqTAhpjoD46|a1l@Y;N;M(u`_Q{Uw*<)2_^@4>kO+jD z@CTp%+!wz0;J5!;5-1@ql_Fh*>4~$6)bet|EO?{jVku+J4RWh&LeC9NH(U#WX~9($ z9GYo=B#ShD9a723#PZB^qNrO@{vXMginKK;@$N2#m_3MLS17d~2CoHM3!HEPhM9o# z*E1+Mq!aV=RHwZV706O*dJtFJmG15x3K4LVO_olycxB4gvfah@IKEZqEaTx&1Xh-k zi8(A$moIEbNtpB@e#PQ(rKzP2@hb!2+K4NZGrTOz3HuVr{4253ox9Vwz@JGthlRO|iOuzugqhDpJr4dy8ULe-5U`bQ zrsxRKPP2ZU5!xgrfWZmsmKLTG8>>r+Ts9pg|FBT73ip1C5^cx*N*eu8Er@{--cM^r zLKuS%*Tzkd$1o(C6rfX@b8WD25@H6f8>X8Bh0EAF6+TRZg%FMnH5q?cAwbNQ|CjAs zPRZZL9(m+CRGhUJ3KsYs;oI_>>>hsGdvE>KzU%fcNC8grN-!@|l1Q9c-p#P@Sht84 z$+FCeA6cjZa6Qya=YErgH%AyT47%p=NtTV5;3OuMurZ`0e9up}04ViOaHQnGd@YF* z_5-fc)V(%cB?qsy{gIn6)m3nq!WCkXtx7s4R=jsvf?HP9Rlw*b!^E=eafD=m?7KS2 zm{_KR&pPWsi315AEm&Q;nAl#KOyo10QL?;;LiMTo#&)H#HI6jYWN$AJ9VL0CK*`tK z7>*K{ydi332`*hco!Hn&Cf1Y7Q9A4if|RNy+DsNv?9*TY)3!W@#SlZtkPJ7}l&!BO z^__u8Ex^RYIqYveky=@eVmvq{s7>L4U+L)VLmCodS;UkaGUp^!lpF$Wirl9=0h5|V z_-BG77_halkXXestLgM+l&c{iy>Du1Mp>dwkt7-6FR~%0^5N#7Fh!ewNaQX*o!Ce% zB(f+!fv14@6G~OrM3oi{Au$ZcV$F)CD=RqMlm|p>bc@&16xLyG@ls+P`KZ??Mhk`s zL4Sb97>#x)fqza)ih585jRBQw2c(Ja8UO6SCZvr}ghYe+*gTkBB}ix8-iQsGF0($+qt z2x0_SVdi>1QmQOZbULxEtt7TG>rq(_K+e*U-*qa{=3Yg@`5P7=?j8Bb?Xyx$b;C(Tt{kDUVrF@n z)?hxNZR6Ss29**`)im}fjm>>1pWBLLL3BE@LgjL*%ReJw0krfAs8c5rnGG!0oM9e{ z>sg2E*{*cNx)seZ82$p$co46m;3921dk?ZFsm$|#Baz)&LwO%7;8X{}$QM)XDC>vCKm=gD6IF)JyU>I`wSxF=sl!3XqiNqYrP@U>a%8F*`EqAx zuL7pbVL}Etma5C^X8t>SSF>tI5roT5QMAo4j5q#d;YN`_vUCwm0=|MPSGp82_yn#* z$;uZH6vY=Xi@41LxN{#|1W}NfTn;B=(>9&fTVEA(hI4=X*$9%exZLwIHC?D={ECQEGe;Flj>ee}~&{`6?$@$Z>mpF8UA(%a)Q7ThCbuT`(rFm;-Q zHghErfo<+T*Z{jrDZtWQ0hO0Rtr7to3^#{yfGlFhG2-Nf_;Vl}qjjt}->q+My>{>3 zy%(R_!@H*?(e-QBzPoz$+RyA=oSVZ!!x+h%CxDqEz%q;{C6F|TzX#Fuo10;MY61F? z=7pZqbdUQv&t{<*HE+OY3$cOUHXSoCv^77rTTudOt`ixKBgm0TsU-M4$ee|Uuwzaq zIF@fbr`^v3&bTWbc1RL|_u>V#wki;bc-RQg=?TH{FJJ#D!LckU{6FkX4P({iso_3XGP_(kmEdrS!r96ISuyFv-D2{WT&XGGb6hcQY!bpr1c$z{edq> zeU8Z;(No!wwp|?3(&C#-gi{DIb#v|-n%zG`s(Y?K4wp;qX}oG^fDUbv7Ny~C&u zGRNmb57yQ;XKS_`6H&_>5I%y1-b=YRo!0AS*LRyksD^HdvTK{iWL;DQa=+ZO$`^NWSx(02v8 z+T3mqSc3PpmBoj8XZUU8bSA;U@B!DK8`WHhA3r{K2jReS`AMYJ8Fu(%Z1JS@qJCr+r&mTZ-p?Yu$!N)Gh7 zRGoP^_wC!?Ui|&Ha-RA*JcXR_Xuv=4aIe?jxPJHIrB@!RrR(B*;!lLPBsfOFI9U+2 z{CC0qiSV2I_aD$SjaETo%q1m4Fh+ez3^X4qF(g(+sun|15X9m*+U*O?5}ZYL-a>!X z7o9G7*5d@%zgFu8!1~G)A`!D4azQ~%^6m}t`14N*j{R-pGR9X*hQ1Kdb{!n^{C^=h zivGm{Qx{$hc%Lb@Oc5l2+9ZHQvP$A)G1c(*M1ms(wX0vR)*QjBVl~L!X&gubqpPAQ zmXJWccYy&jrIGUlPH>lz<;Wc(-kGb3E@Wg2P`i z5p0@9Ca~u@n{Rf4Ody;%$%QI#Qbmu&q|W{)xa)cyQv z>4ros@-kv5R&#-RQ#5mXjL6gCpaM2T*R>{Q^5Sxyr)nQg1p)id}`Mb(3gC5pWwLp$)|6=^zsWo zzWvTy->dGhPav~->yDYUkT32nZV$&I9~5HqzWsBxErNSR%#lDl`-fG>S;G;&h3N_S z)Y-m+Ne!C<^qy@VScfZozV}3}dH%?}vwvIJKk%w^1Mg3>zw56UXPw5a&P(A3^VMz#_U+|u zo_4mpIf6h!2baSrZZ*LX;}EI#4f6g5qCcuH06Ut`|3MCDI~U|4X#jb#^8aAxTM@jq zt>a&zkT(?B&kKwhtz&})JJzwp<9f51aI09B^xE0nTNdsyVjS+<3(liJ;ADqH@tiAA zvY3R=8NLCM!12;>`p%s@7mtdN=Xbtwj>w_^%9Sg3FJHd&&l3NO#?#6Vp*gEsewY zgy8s-y{lP`A_&5rk7isVghg@|@qxU0&{K}yyr?%3y!Zkh{JHu%K7{uW{9_r)T4AQB zEx+yVnapAWAqAVw^lblBRo8F#^js%!f+K^s@RS`p1(iX0JKOF*z$|*0VrE#ZRtWTz z6gGAiFs?}Rv!{ryXD{bNy`bDysAnI)CLsI?H1t7tkaq3rh$R3EpI51Ms(mrR7e)us=VDZ*>bv{oUGEt z_kIX~2S<7c7FR={rDhCIPuJ<<{AWtt7<5XnLm;?buM;5t>bnto;#aoScMQ*Dcj%ng zG#5sr>nl7~Ml%rf78gZ!Sr3UGt8e%x=l@Xh>-K9U1?(881k8DV#h=n381s;UaH|p)Zw=2g4fMNRo z0Gho|yC%G4UK<7=toPSV4Zqt%v}QsMdV(qJ??o~pHW|0?d2=^M`yX|lwQGI);>Avi z;eoe=g@{34c{$8}R&A4Jw;yp;F)RBOndHMH2O&-m(Hiiqa;O1QTlEJNOmRIL{CAw%`|$^qn8Nw9;q94aJ+l;@WK6WPo6&h zI_yTR@}K=F=5YkRrxDwR_5eG}q}U7iBfgK?@%OVv%&8-9y3_?1YMf(s#keck#7ptt zj-fy`pBY)Op@nx4n(N3v*a(1))9vqpyoZ^U7pwf&TOQ1XuFNqS9!~b0g1d z3tS?c0CykGsj~oA_O+qAF`|m6Eb@9;vvb9q{tPGGdL40kb_sM&g>OSC9xSUBt_zi9y4E5cs=)0aS_@6* z7m|Q3t&a29d%sD)?G(iB_;}bBEMkucB=~uo_ttA$VM-~RL+dMn5p3ttuuW2tG}l8t zgn*+;C9N|M;AEz{L5YsnpY5Ha?e^|=jCWQpD<;a93QYxJUZGwOo}J+yn6Db^)W`e%x?plt9n!^U~_0XPPZ_EFr~tE zm&7mmd!Y?w`-#@?rEp*N5)(~8v=z}YpK^3DD~JPUDxu^r2;<)#=U(6>6@P4|98nSx z6Zk77>8C-P_Y^|EB>SliRo0p&+aoJoIW49^rtdB0e^Ig5@yD`^EAwvtc)5eTjQ=>C z|I_V)=Bb1kAw-9H@~@LLMEc9#x%@N{MPdA#lS`?H2?>c|W1@mP7wnM#fQ2hpK2V6p zC@v}*)C3lY8juzc*pTQ_B%;yi&X}-}kf=L0kSL9;zzArNM@!r59mAxl?X(?fXQs@Q z`)j^5nM|j1U+3I8_c8g{KN9u^H_Y4iv;hXg_OCxCNN;zLxQCxnndYLu-#)%*hxQIe< zXs0T~*wVuH{YR<~t*L;@Ikedwbu60yZ3qI!l|N7zr`$UEvEJ2y?gFq-G1hep*+AqnO8$|}eECRyvs|&LBJ_Xrh zPsldAM7DWWGCHUz3hcvt`4i$e^)-#oFaPxWB#`NRBu76#tLz zZ8v)hnU505E+d2rS3@al2DNpD!MR{Xpf_-?z!v>HVj19%9CZU}f85}SQ}p88ZfGd)um z-HeqmV(?)59IkzPl2_}Bef4oYudlO`9r}em(D5mHxF&1- zhjaas^>CMsF6ZYVi1Z>&081Q9d?Mi)*sj zk6M^suE{>T#|>pS4SZQS>5<{TJKib}Q z`)yxO@8dS#ttY;g<|#D-<_dNKB@9voQzwZ6~)VEEM4i@vt@w$4_6 z@8HQuh?g)zK~NMZDxe~cprR~Vi9{lim_`LiPU4VAB$8~%0Edm(ADQNwbP>y3vHAD* zkK78K@`(#jlK!%Hudz{7Q5?Yk_s;BlyFif&@d27vKmr;Gfz%g)4-y+AC2FE3DjKW> z0!@$*R6vBHeGm~E3rLK?Xn7gI2lz;&1dAdh25aR}h|rc65NW%mkKLI$SD`IwNeh&v zWv6?7$w~IZ%+B32lbxA+&)n(m?UU>%>@z|ed3()vL6_}>unF|LCB9Ayt=b`VxGtgz*+s}8zOpR9Ln_@*x2zf)Jv2^k22lhy9QD=+b%KNSZM>0T_!Nu`wQgjaS){6ktJ0w4wLX zN)E;@(+exZNJjUgDzSQf5wqu_a z{kY@%$#dttp0R9cPU^AJ(|t4xYSoJDT(|D9Tv9{k+wbIO%y^;j*8aZGj91e(WlW#7 zZbk0W{M08WZ_}m3uSI)C85Y!#23M4o-xlAePwl$3 zEAz6JW#t9@eZ!~9Du*3CQqd1Rz=R1Up~#Ls8jLZLz`ICSW*Vx|3^B-vjt~i2EEx)HJ45X!}?|yOW zOB)mKy8A$!*Lx<;=aW?x6{EI(@#RBacguK{5Rj_*bHjPS>jWMgJN$%0m-u8|L2~Kg z!-E}~4kK*z5A+2ZngGKvFO^G39Vk0dK0sLnvPk7*t$HFiXL*V)gym2I#||AC09?HS zfvz)JzgsC1{{tjof}gz)!5Cv*67k$^LMc*hmyg9(c2}cecZrj`%GL=6EqPvfxP_H59hDWf7IcD zkUF5G66YHl5Hdp2QczL{Tpp(q8lbs!INiWcg*!(ync+av(8QAWKX~)Q)TdInyF4yv z4h?WNSBAKKZdF@*4kicGXpcDSCJU;N#P2Z0EX2-U1%Au&fG3eW{W$VZ=0sery+&~x~um31zcTr*D=;Q~E z`s01Ue}iZH&7HsSB0c{(_985{cG^fXS=XN_UePe=wQ$dq6dOnZ4 zxZEGycNdS#fp;#f2=3gQnCj|2F~9I>v9GjL%8!j-FXr;O*{^o}*vnTh3IiAV-<`kI z|HkvT%;NHgE(ed>cMDUe&YqqxzMt-!o}0-d@ZTRiy#M@YKD)fUvUqZKZe~a_LKlZG zzul8$}uDWw4Lt|CH6B!EZ|=y6FY)$CgN9DC?Ltiv(?XQ9obyA+TPCM9N^(!duA90#%_(421f=bO)i80fD?>d8Cu#bPgmF1I?8M1 zAm4So5=IfMvyI==?Ifc>l0Ye?l-g4o42L9|OiU@&yhs3Q@d!r?FI_3sEQq!WfsH}f z83F`AJTiuTPjAn9Rgka&1VC&ZtaIRyK@3>$5LYa$_i1~S?byh)u{bXPW2c|Z%;?(M0Boe=~AVn*Zr3~&GkAqR(2N~s14puupZl-ipHIFwTV z6a8@y5kc5#Kun0D5WF3rsMr{62ppQUP7FBlaN+<6$RHhKy#+`B28hyI>18c4$p2{*~y$^A3Ab3Vm^ zbdzd2fpm3#&{b}*SS*-EQ|o|jjL{&5I!+Vqz|Y;EslbH`Hgj)-^^m17F@ zL*r>gMC5)p;t4t5IXLcCc-ZNiQM8p9pa74uI$Xhv?T-SM1I=R*D zoZ2*}GB+J)NN5v~0Js{j&{~9M+zJf5s$2t zo;f%oA|fK<>{;i(XvdkKendR1wv!EGZcW~s4YA2CZRM_5+{kP)Grdq$3bV$Va&?V} zct16Ev!PBeyYI~kDiLwV-tVOkatj`DviuykSZEF)X1n{2lLTl_J>=ByP+RA8Q-6y$ z)ac#)X$%Pw5pkbNr#QnzM4W+hy;MDse^e1?%0L$z+RDT8!5m|ZfF*Eg@C4&Hp$3|u ztza;;sWFZt6;V}rwOX+lDxOTGuJ>WH6f7$Y0vi1F^3RWc{rQ(qU;gppV=*85atW=$ z)EXFUs1l2Xz+#Z72u}?fto~b30oLc!7=WRI8#|0OXD^x3OF93cAR;18)8<_B92sax zaB*?b$E%5mh}a_qj)-_{R>K&8S}Ov+{QSEgzxeFi=l}lw&+>9u&|bmszrFb6o3Flp z{=@e_y=L!zUZRSk0FHm(@p^sE47w{?*vi_s5~4q#XxXM+VTwZ9prRmD76@eoLTxIE zpjGZ%w9#^5yQqkMT8lzlCKQcgkLR5;!MtH`5kiJgc|P#qaN(S{I}gsgmwPhy9_Kx2 zs0~Eo0wDn>LYkzcNq|6gO%u=*L}B^!Qro-NZ#$MgE$`O=aqLOgsnu{e2UKfjxhr2* znkKK`I68IbZb$4rf)M){3E;Av`g_D}uPs*4h^SnF8qxn?_HB$YW@kk9WiZB=9pu<0 zL>-%{*m*}|exGhRA5GJg93Ft?Tr<+pkgdfY*XYRQ^8ko|1jRW=vXQUbDj+N&|fm^%GsEMy|PTHF}(ms3FG-~CT#J2;Fn ze?*iz4N6c5p-efHX>Dyq6$A(y*|8Lf1QD2>n>{#O9O}J&^VYHZQ}+%J^c9B&`v=Z0 zJbu#d057n(xVY!S#mil%PIrz>OiUhku7P}-RO0YNGB`wQM#ogI)=9y?+$}L=(g3x+? z!*g-wYUc9%&v|&VNWw3K;E7v|v6W+mCIu_>vz`0>!3M6JwOmMYr7L^QC&=vYkVu=q zi9vv>st`h8a`IF9-8U9l@Or%v0x%39F_ZAcC*tcy-@Yq-_~6m*x#XNjpVjl*ue2X| zH9V?G04?WQ>Y^jD0?ilnMx(K^7tddo+azESKqhdzr?>RU;L|;+89k)AHGTATbbD7v zSMBHVS+8x_uAr7DHE#g3(}rT{6mUzQjE%exx3#t%`#3gH7z*cqNF)-gdv5d`=x63WTTpYQWWZufMea z{^NpV(g-PvwCj)8pKorCG-`ohoQR-E2}wZpzN(>$9lLIwi8Mv7wq7_}RIq7Sl^)mK zn|HQW@2wg-wEu9oV!5!Ts3dmjVnbua&a$y<9bJ`X%916UO9msSPF$|3Ie6XU_F!P3 zzY-1+0m2kQLa~YP6Zt=N0W!uITM7xl<_;Cc7+VYn98OWXoO3W!!s*QpTB>qAd<4Lj zD`DFJkVvI~3_~}dKv~e1EYoYh>L2%ewYku$U~1!r!Z$`T1v0F>=`T}xdeXq!HS5Q= zl@-So0XrPdkC`UHEj@q)OanMtTlcK5x3Bms`*!aeM-j$x{5#Li&8;2Bw)_$sh(uDj zAxcAosCelKq~KpbLP3^L3P3`#DJY-`5(Nznl{+MmXrf3o&_q~~pg=+b(nN4^;B@EB zz3k3Do5*o&U6PA^Qr`1?M!#Zrwax6#6p!Zl@{4a?5!_hOFX?yl+35+$`w^!OO6X(| z1X|73ycQLe$}^vR{?&=~^h{I`Z($LHZPuD%9ts^&K~#y|GKp+78dIWdxw3I(3LtSwSAe8S@UF&qND+b5 zgHL=c3Z=E#PWrJ(67RX57<)IK9~_@RRdGH+6u$rNhhwMSTmIne*>i7S{QKfkyV;tI zv7pkDUJu6VDe9D1_CcT*p@@aAAE?tUI`z%0bwDevEj+vU$MZ*y{N)@1Aj-aoLaY?$ zTxHv;F~*oZIcG;Wj4@^iD{$;Xp6BE-CjmJBJZ$0?o1(6Yso5-Dp`kidEg2&@V0H;I$kdX{|Q*<{fg8>;SqPrPJJft(B z-LE?Q^yAORk^Z7UmAMHG?rc-Rvqw>`&fYSC<nzG;bh70uJZcCL*YSAc#Oj ziLevBbqKq8;&)?XjCopl0II686CB1Eb2nDt*q`w<(CI*@r%X==R3Ugl#IqOC!Nfe0 zWjSf^ppf?f1@9qvkC)MBR`!hSyJ#U#%SU}8DfgNv50u7;igNtL7k-tRaN)xG%gf8B z-+$-SyQlxTeCfG^(-YOJuf6`80G=8l1paF_=T@$>rW>BOqK_PSt4@O8GI&|n*9yB7YLw`UXizteyOJQ~B1tCJoLmTO0ZSIyX z*tj!0K0W(PAhxkfr3OLZ?*re%FwAK#GvE2~o1WfdXU_I^B&HK(il!h`U-v#(w=L#U z6q^gKojQ5?#QE<2qm%JOb;>fqg^g4Sa2M)E%9_Qqq32t#-+B;=#XeNnJdMcMyDg)U zsDDR8C^l;uj+r(B7yJ9#XYDyp)Be4$Rkw=a(UFD=m-^bzb@v>(a`kf8z_o$D+QH#C z%mvWcF(HJIeEIFQ0?=P#2_fXSsNh%vuU7}>0=fni=?tkEKxF_IKSt^0e3nZ0sPO3; zqz!-r8V8sSu!UnG0Wd%;L_$D9{<+MMzY4?8s5!}AM}-FY&j=~OBtvJ%@mE!wD_<6P z)Qs&|-U7F(It=E)wwAlW+KOqW0RrEk=^Dz`t&L_J;lw}3%b8o14SN~~gWIc;g{w8u zdN_O!E{A6zN~e-vN;XxMk3s>gxiq{!pe@`ww5mu?P9{DDpFACG?(FKkv9V&q$FG)A zV$PX*$$G!ld|=<>i~>IVW+a%LnJ#E-+Bs3bd)Ix3Nf8-~1fvt-oAOK+BD5TJeCOfi;MZ1(!f-)zbMgms3j_Z>_9pIutmPE zv*q3%iChd|dFL3tV0~xr?t|l~?>mma_j|wlX>~fuvTE6~T*VJ9AvFfORBeh4=?qV% zxDO;wIw25}(iU1;n6zUznRePgk^r5A6gugoL#Go++Gz+3u?aRY5O8sUV2BeY4|Qxy zW{fkoFxZmL(rUH(-FNHWo*qs}wUk5&j(@M6&+P5pO4_}-8{K_w@3-DhjRQbbC>AZ6 zfEdb~H~;k$J5^S*2UU{B9$JxxoO{$dnhT(JmI z%2SE`P{yzf512HxXQRmpQb;qj5wm)`791S`Nm`kFDiBy=aIoe)B z#?>xYiB7k@jKvAo&f=za~NRz z_H7q__2DfWrL6U9FM8+BzxcCT?!EWk&;7$a_k8B=4}9R-|5&)N_0aKSuP?v*j?etb z(e76pEg_6R67jrCE>qSm7wE0&(<8;BtUH}*4GR7L|#h>`_)bF_N96RPHJ5KpO& z!4XK#kHO)2p6At2KxO=LAURU}zYEXvyy^IYW0oWhkW`o{Q4pY|P~`hBzuf-#wjCRC zL7Lut(;t8S)?04cwRYY4Jq=9_!|fdlN>~5xmECuI;*TYAS}fI7S@|lm_kJ{msWO{`Bp4zW;mQdHGk9;o%}mKsk@7RFYGn-qvFRLmUlr z{Ph!y{(IN6m;KeIP1k+t!N->O_9lVI?7yO-)qtsFrgYNupdEhD2j9u>Pvc5B%-lf9zjx{_~r6V1+nwFkxM)sZ8QfCS-Iy+?ykAeEn$)lPutB zGTTR_h*Z8$O%PDapB2UPJnw8)TkvNBAwBC}e0!ef&4w>HW=IX9jLXV`nZ22F3IY#r z*}5(o9+Z_Aod42=ot-@=N`3T231Sr$NKj%;*!XE|Tcm3mU?|yFgZyCuK!+e1pc|;AlY9tlv@*(9op*%c-%~^CL#bPKA zCX4U?xBK4rwXHi=#e+_Y1w$M=esl&w_(@QuLe%iqBGj0o;1LC*)GVuWyqSMG&ZGi! znjOIr#Sx`bv4s#7aGIb~R8^oL)#a(mk10~~v$dI%Gt9Wuk*fbl&htFatEDpe!xTkD z13wV8=Xu_g{5z_-p*3+vNCfJd8-~KB;)&~TykVzWC^R=?LW@%+cCNCHhL-v54RQ0r zmZNbp%-;Xm+sY^rWU2v1Md;~y&3@{xyVrl~+uvOUV&Wl35(T&+gQ1>yaJX{RMp{+` zWnNt`zUR8;rh=MhULJ~UwR4d5{7z66Eh(Ktw2w6}N zp(2iBM8LUZZ0?+^Y@3Jyz^Ow-FeY0TBV?qyj-bj|oKsXK+t$LQhkyfdpoxRTq0V6~ zDC2`wf~m=@DUb?PbAEmt(V1m3t>pAXYBRn-B~G;xF{Tm~sV-X(&>1}|$9~V`>ua6n zj70!aJ59I8Qx+*1fpQw8r1(+sJ!;xXlV*7>)C=ONwQ)^ zgoxN=6V7045(eS}YWZN)D$~2w)ThQ<8GAszU%21e{Fc!)z#ZPL(u@Me*ITyTeOHLAAgGB zp_9}XiVR0Xoa`UqUF+6y{SDW!apPJV8X*Y4=HdD05Amf39^w8kY^UdFGH>gbw_f~? z^Ui&wwLVNl$%uf0FfNW`thEHG21ETZR>L#|Fb1PpN#GPnKm<@KluV*Ybq>Wsh$^V7 z-DfeN&fpRUVRpN#B%#=pl@+2;upyy^IEK&|;yA&I#R#Z_fhfV+tWdEQMvJ4wDPdTs z6g38e2@R^?R8duo2mtCpQBXku5h}My_4gwN098Oh$UCeQP{>G*%j5H@n!pO+*sg%b>Lvro;`ayMqCnKcIl;uQ>fed^v;gMhYvTS0RXv_inhgzdf)rr z_jJAR!t?Fl{m%E>0u=*6nx+m-6(yw{KpMdMtFPRD-uV~25f%iamb0+qIHSp=%Q}k} zsMAR`4bJehX?dRKd2=o+!|_LOc%FBLI8(b=UvQj8!G>eaJF2KE0HT5diBpON0}ce} z+TY#U^V-q&`Hjv0%if*GM^&DC0RO%3dFRZTH7i+62oNL&1la;2OIfV4D2fXxqJYbF zp%zneLiS81GiT0u&wFmjgeZvI zdiD02%ln$iKI!D1$00 zV}2h9IF27LK|w(QxMkq@vExt}MI>B{q1O+rX9XooarMEvZXvhyfOihW47$JbEz>(r&=k_i6z3Kyj6qm~# zaxjL7Y0#qGMXt>ox7OZ#^G(a|nLP2}@#Ce=`5$~ZI6b3%{SBkX9Mwab)wE6g{Et5# z(UgG57&Cgz*2I`Nz4%CRY~Jd%IpJ_)Qd!xlxM`0(vKaz4H-Llt55=!qp4ZRgb=UOm z-M^~z#0mep)f@VrI8lHW4;V(?mwcj6*|*{Gc>{^Y+U(Zrt35DT*r;3=*f) z2@4jO!(oT@FoA6$J~<)K<%;Yo0TluQj9ywFA&M`w#glr0|B;I}CAJ_ysXStpBuSFK zii$6KJP{iZwoRyL!)FeXBwZ3{8$8aJ365`zQc%#=o)ShVgham^ALo8N+_pHfx?Qm? z9EO03b5KU%^?N}n#lFuzO9SPuXw9O44WPWT3iCh8#flZHP<(Jd8tbajvv)Vlm@yq4 zJ30XiaJdNJ1W+GB?fUIFQd9`VqoN{YWBH~M96nSG-E!k($%)j;iYm7!Rtt!h{u7)F zoKb$dLff)wbB?BIff+M?JvS$(Z>``QJ9q9*oc+R!cP(GJa>T&FgAYCNo;cHF=1>mX8;ADI2cr?COT&(9)0=cmp`eksfClNG;iIS^p8IJ@Wz!(mk$_y-Ss6f zI6O|5?F!QuZGvF!rQ@zU(9#_ z-Fv3P!2lQlR0f0$)a@%o)%Kl;7r^n5iNCDKM_$osG!h>iE)}L(=R0|_B&L0rlm^p; z?R9GaqYwZ>dV~c+4Qi}EF5I;u3WZk$*{$L`?SxPk)sd$Vwf!e zFseXxFc3n7&*O@CTrQ{#xbE5!rMq|TDn7LTKvsQCjazkShD&wYh8{svQX@8ZLGGYK z`wwScd+mrVkN#-dHkYPZpK7rVS@wA3m67q3J!OI&xlQqGq}zHmm1Px35Vh^QW6uxDec=ga>3#C zGlW8b$|#tsL2yWyINP!bp+rtmkt9iyE+{a ztootmQu%#T@69#2FqsAjoQp#s7z{=eBf9PfY)WkbVxuW2h#<{PMJ+ReV4w;Q{o4eL zy1qYLDgX|E0I&g+RpRj00x*k0VSW@Is=@Yy6BSI{^ncvW_7y!a7|Tp$HHB^lPRJE1gH&! zgW=W@t-+uH2oS-A${Y@1a?4g#)_hgGzP>L0z4zW5abVwp%uyppZhh#X2lJhp#sNT8 z0f52goW#c@)C?Oubc=&h^4Hu2Ju53}-4qOlZa^UflmLWMfDnWl8{NBh?@8L8Uy!nS z)8^Ej`TLSSFE4kg8UrZ60WdcMb2^A&nlNCIuw}yQj_$9fP6usiaLQ$JT- zk|ase*P~~G5)jKKkR(ZxE=VRgz7zD~LD@OcdZQE?W1s>!u=lfeAJ6~zHpQWc+b7)q zantgY3a^*KFwla5f;Hb8ItQf;6cnLGoq3&J5(!$+>o`Q1K$rv&7JM-Z9+`F*emZS3 zVl^9z6#`TM5d#R>C|$V;F%btE;K911Re0y``6vrG!5kha#D+x$3?hggF_{noDq{d| z=@}sa&7p~3|MJ(%`}OX(S#Q)6mMvL6cIH#hJTU2wNe|DO`Rve>C#pQUZh&(ERZ~G3 zg=Lx`HsGKXjG`$RR1FA+b-H(NVW-B1dhay@`WGc9wKMwl?NefN%dz+$pI#XX3Ftb& z2m=KHv4yi}cVY7GJq5|zw{1^*=bd-^965S8D?UD9Pdsw$Xl9q} ztYZ`I9KSO*-fIa62zoZbz@fkaW)rJ_->XYTUO#%vXZ!YbTeRSB*$M&mI9+x$anw?7 zWdlc!9P7Af;lgneSP}mF*R3NBFlPa33 zf%9nP4#gS#ocP8l03z@OaZY^K1pQ~?>pvyuqu;YQpE&OZac&6k3rFkrK=jANR|5iP z*bsyga>4z}vJOd-B#8=!GZe^VxFku^MacxmzaC>~rfJcW{7oA-ro8^z8&egBL%nJ2 zO`i-LG^kkBRD=vb)9@8uulmJEQ=6K>`k>u8qa%h4>W9>1H`=Fa7OH`J1;6d*UZQyR)*Q$_3Cbt;Zrz zKtTjr86lvdv7T*MzxFD(+g0DYcb}8b%zS$Af<=EFs_S9pXz`&=B_$<3ad!7Y*tM0_ z89#aKv4@}h`I8SnJ8RYh%a;6OxZf93+Ek&jmJn)kBbo&Acs%t$M4}oh7UQMnwDC%anr^gO_d|b=T^FIRj2;>e<%my+3%FFbh>vsQ_1Audty}+$EnD8jTW>s$3Agry zR{<2K1~iy}K>!0Vckjp1T?G)7!}MzSbjN<|C<{P%y`WA&5Dvu_P&tKaIrKz-f=(#2 zg%D6FAVf6EPFAbySLdfR1R`2;QeybdJ8n7hlj+mfz46McbNlx0lYi>-vh?+N>(X$B z_@dB&+7y7&T30KD%hO?k(SFf_ur{V-` zVF9oZ9rx<>`s3;x0@mq;y7P0#9NXi45_K<<%B3^)A9~1So9Ix8bx9| z4L-jEFacs(fC0em1sWm{2TM>|Z~!#oK#0X+@zz4D*ti|SCU6h~nqoj9BDy5QW}rd| zcs#y3g-{y;&A1WW|BfBoQfB||#d~MXdUgoT;DFz+Li4zdw6wHxg;3Z6j*DJppg^D@ zsN}6(lWkgDZ3qR@t7~f0`sDQ8^1|%d^CsUnWtk9Qd8<};3kD3R4hC)sD1TTdArJvTXUXYfhDwyD0^1TYyqZydIC;f8fCChaP@#b>`)r_Z~TNq}!Z1 zbB9(|)jL4}m&*lJbHe3u!4xKf1~BTDv4^kdmUWQZmMa);^x3ckzQphMHvb-?HmJv?n*PXB9;3jt`F21+Rm1I@u0`^xXh zC<7M)pcErVjw)j=XIM7`-g@&Ry!WTS4ZcUgcA|iwgtlkva_!$>)p3!7~r4)xIk;)fU5^wUFB3A zHCwi99r)a==Y}s`wK{Ffw!(HzV_>^3U%qSzajk-~+UoRo=gsM7S|Ey31vf1cY-}Wvh)(+S?NL8@@{~>O)6x&` z*s-JA+i$*+Q*}B(L*XF8dLwEAwS-dv!{A6xiHVH5arFL__Nm7dhXU2566ydfSkSqS zrX))2s?}?fijyUqP`?v;xc{39dHh7RG=sEFEqZhgfMA-nPkO!@jBuP>$D(Hm|wux*qDoK*`wJwDO$9F|g zd~*WOGy!g`Fm^t%REc$Q*inbp_$?jt8`E(tMmTyMMv1+L9RFvxsZ!cPfPq%!A zQqx4rW$iI~#0X3rcQby_KL@ZZI5jV*TeF5-Kdg`tSZEI0 zaBM?f-jLtUdT#2kX8gzf3l}UH4@$`0lkWaBvrCsc0f2Lkxy7lWj5rqoP=`@H# zF+&Cr3;`~$Cvwxx16HF=#ao7)_m$0Wp>%t4#?84T$dFt~3;&egq&(lb)a1t6HiVK?nps7|MO zx~d{&?b@~1&Y3&!*7xSlxpiLC{lY~HuRnU^Xw2DVMTP-5Rku(b8W*;(ER)+RW6cRH zNjevWZCeDgahxPcl5`%5ws|o?lB7$Qpnz!O83Km?=P14)K)-S|8ua2n9G!XsFh=pw z{M_!F)^EJU>2L?9KQ?_{c6N3(Wv$~vTPG_}PynKJpBF?aOaXh;&13eIo;sPygL=&A zKmhN|%SBP)KJ@C=1=;P>(9Yq21`Vex8nEx^No?AC0LM>P!sYS8&*D)R76=PBToHoP zr^5(y7xajQEBjuxf8g+I$}9pKU=WN0f}u74LV=vC`&Rxj=T9Hx=H_&**Z#1$L&r{yng-|qn5qGc**$vnsBC)Qx&FBLAk#EhgxeV%(kiC^^s!G;Qj)8# z?ApCv)zCcp)vKya_gqZ5cS>Q;UOmfW+9d=N6B6|M?whmvxj|3>4B!C9-*Ly`E3&#)Q_4hIT3R?MIn_`c>bi=`itUzZfe;GjaDbZz zarxaw&z?PNHB|){92CHS0RzgNPIYN~YJ6ko&Yi#ASX$ZB%ODV zd0rI5`w^)>CD znfc7`E^D9E2=?EXu^5Jc-~zb|b9=2`vGS%Ee@xwj5B}S{?pJlKYwow9GJpcy0CZi4 z+pV2D6N9zf1Fgvq+WI)^rP;q9v~uanA#Un$YLp;YQw0yBNc6bjqkzpRf+jm<_Pug8I%JpOJf*iUrNeE zdxiu9I=o&D6j77`fuI2cqWO6y0EX!Mq$;5Ev)|hSOr56f(e66<#-B1OUU( zK{XAG0nnrS3+M*iUKP<*9~>-N1=HHZRkVJpqK^#`eQipk&odg`Mx}smaBvzO^U9mI zYVG8iI8p_}%W-A+Uzf!JDgJG*F7~ z3=<5@0H#iP=;?Rozx5k~atO*>N6JwVeUsm$5=mV2%F(yY$e#atZ9l{N?U(B?tX#S* zD}O_N-~m+4ncs~vtPW$ z6YH^j|Ha<@yvR{R0UZC<>zdlx&14cI7{sG`lHfr^JqbC8!9z5X+`UBbVn9UEe?SmK z2uR3DlpG{p14-~8cnhLuB?^)#!LaHkW7AXp`juce-5D}jC41RT>T~Jpg8DTxP}8rf zyT`ks)`c>ok*BVeB-HP{|IU|_Ae08*T=@D$t!lUL;XUQqGhZA!dqzl20>FC@2&#%p zP&fgEx-g!8{;5j`UpV-amw;J&!Ho^$ik0%l@z*b1yL#=xUoQWAV14}$ziV}hIpHrY z*w7j?N5aua!Z~4OWd%#d-;JUU)}vC+Zo+7c7E--(A3gStL1YkRPX*A2SdtQu@5CR}@ znH^`_2RLMllR#NP_x)frAW+V$N8@_U1{>5jOI)JYG>Z2lcI}?bO(9Gns^CTiX%1I^ z`}L7Nwq*&yD2ld$MiqdfNDAoLlA3_MkDk36ai(}h6^+fgci4$*LJbmhP`u^MR z4%D$3`O%n4Ar%El9E%KdfE0)yaigwS-TMHpkn+_dFQ0qu_|YHh1~Z1>h7BJihC)XW zOboHx!$}4UX^|mq!X1hDJI10^SZu{WSY%s!wo2bu!w~eY_E=e7RmuJ@XU<`H+i{j< zS+?B5f2f4zwTmpvwz0`%LRCc&;IYTqX|{cUBc&99mAf5M2*ZW&$0tAhq@Q36FqZP6 zEmv0X`>eeU<)c$4KL|mH@z$+})+Qx%b;kC*4j?v9XtBfONS3#X=)N4 zqzg7E3drrzA_K#at}h^L##lz#lq|2sU}$%f+a82}*t^>h$*wXF;Q!~jr>ko^{gNyi zVcaCUWYRN}khs~f%kGASWOr89s2GeI-%tcKf~ZI^%HW6o5X6Weh+lm9;0HxvL`214 zFwBQBng~WQaVD9J86uLH4}rlx&e4dyqD(*x)tQ7GI1WN?%?l7ond259>aU|dCoh{jtz&tWiBLd8G% zo9{M}nDI|=sMG+=VKc0(i&3dm(JlsRXcZ0Z)L)2Zod&I`6f1Rw0nn-<20()%2Y{+} zYJphnnL1&yFH3KR7$ZVOkw-&N1r#up)XKJ%s=`cB&F7k*_|(TAUR*qQ_7@L4c+(Rn zPc23%=0!}<$JF5Ne%Wg;d+w$iZ+z^IJKy>Hf4+Kuy}K?+Za~z$o!l6p=aU?O?m{`4 zPLg9AR>2vTJeiQYU*e+ zeRV|-D>K#dO@acg;+2LnV1OY4+MSeWClER*kN$ZSefQ;-16|)oSbJNvq5u@_^;N8I z8x_bSN&(30Io|rVBhSD2tw(-#@`*FQeE7t#uRL?+PuD#4^y$~VQmf5gvTx1+ynOiD z#XsMC^UbFZ9zOj1!osEXOJ6gKXeenJrm?jVhGBHzb*;}7+rqYSA!CKM-xnM5g3YYA z8$}Og3WPS`Zcr#sT8W7EG{c1uK+vMLw~KWX(RivxcG3abe;BgC)mYRveIV2RuT5dvS+T?rpeUL4jbJdKQmr62KovN2?SWSgEFO3~ z#`w4b&=6n-#8}qz2$cX;Afk+c?NnP|JYyNIeACsh*>(Fh`f0uE)NQ6d^^R+c&N z;#nkU{1Y5`{si{T+=>ep%XWR0EQiyAzd+SB(H-jODhf0%}ZU5bZEkg}DnSR1*==Z~+ED1P%bo#0C-VBDMZe z`i8DC?d_F6Yx%h+kf5>uh&}QjuY0~wc@Ztz7f{>UkU?ALdE5U0m=5kN)2=`}dRr<= zI=XAMc37FVfL6+7TW9C1Krn==0s&a5FC$bG%k?@|R+eFi&;TYkXb28{-4UKaAf8Ch zn23mWjP@Of1t?rBi8F8_nnY>=KpBI{j#dDeQZyca>Cv-DP!eb3jVU}-ZQ?CzU8`hh zY-O7iriMNvhW}}AVnc`Rk~q8qgX)I6R1s0KkqH+w^e`yQfM~I`YgW^IuEjf!l7orh!Byb58#M*DaiZu0Cimn4%S$(n}zs z31a|6SYwokh}NS30@^gV7d&JT(e5w>3=yU|OzS{TIRk?tLcQ_G8?T%FJrb5wcHm9d z&Hr+$nmxK=5f&q6t0^smy2pl&(1lR|VrbdBLyZz;1~lpoR4dcYs`x}idzqE70fz`u zI(;Rg2@-qP$j~wr3Rr|nazSfa2AQWo%mHQjjA>wCvHPG$Tr#4;Pd6 zw@}kEP%@1$MJwX2*UL5Sj=eakCJycpufRQc_erenx!-FdBI;!*ML^M_fU5MK2q<(d zFd|rwl!z{dPBGEx0;`$F<1d~%`PC!W&rVEoBiRug=N)_3yNYALBLIH$vxook`hD}S zIaEY>y&L94F=rO05n|s_!L~Rlz%UZ0DO`jEhE4eXi%SA|fK1R5x7vK_)m7c4+ZqAGz-E zC%y?HBBBuvU4Pd{ue$mJ-vAL24Y!x4s1QwpsRER+DFj)mz04#P5fP2lTweBIfrY7w zh=^!%z2VSDcyXMtL;v)tyWX&PH-{V(5z$D84}A2)Hyr#lr!*1~jkHHsQ6ZWXZp?3_ zEZ0nnjCI|Ji0A@12XGJ(jlwA^M2S<$LFp<&E)5lCsfdVZB+JYVb!Iq-h=$?_4x;3l zL{P%ALIed997IGkTH$WOAsj?R!!W@?Gzl~VrAxgK7)Njr5zz)DxEK>0L_|X{!9hf{ z+gza#*5Du_qKzm|y@`lMVhs)=qFtpf;_e*5K}19&1&AA~j1mzI#}OPvM7zxe!liJC zh-d>Mt^gApL`3Uif`f=?_o)hyF~LDZL?ap8!2|~p(J)MK5E1P*aj38c2N4kw5z*!` z!9hec2Gj*$4GtnA+JK2WM{p1kjld$KM9IrMg3?vNIhis}Q6VCt(JFY!#gz#TA|fK1 zT>oln++rA4TBHA94Qs~H+mbCVkcmCJh zrE|A8n~j^?Wxv4pLu3{M45KN!u|3;wzWrzgX0T$f#e3iX9vu757jemS6KEEIE1Fta zyHyy(0Tsa-F?2KYb^CY08f)D;N&-VSb@UM5+UwtX|Kr^r=-h7z$eV(n{P^csUC!}= z_rDvNEJKk)JfLJf&nM#O=I$5w_fJ>~gotQIxDNfycK7zJLEFcR6AwLt$Num*KKI$X z(ac|fAcvyuB5#-B0(2fL#{Stq`=9Xs#Q{Z&`!bL{YvRv_*-L&~tG)Q6xnswEB}+@m zpG+oQgX8S+JahrJriGx(vJN8F}XoR zwBu~u5b?E8)wRe}F*TJz6;REvy0VJxWmqFNGD?OH_Rs#=|D^YC?T}d$TLkQJKp`=%IP!r{QVjm2}?G?Q9E_&j;r?n zEe11#n`7U;8RX46GUQN1h-+s`idg6QM9{;T!cZCanaPG{RFU%Y`@Oc4}su!5l2o49N zc;=b!O}iX50dhBpOhg$Gq7GMH@QyKYKz(qUNQbq8(?*Dh2mp92Afnx8{n7V_JZ(jF zW(L#K)6iydwEpzd-%D+I>!cDKwNp>to7c|W8O>l*id-EZtFpz`=+6)D9)|k`NCs=ycY>cCc&|C>hv9RVfv^wi%xZF;}r&_%*t4g z7+e5LDql)OL`1ByL_{fDU0nqLR4NrzG+;hVAARZ6sbp$$B$41ad;DxwRlkxq8qJg`ji)(K!zG;NcTVm;W+`+q=z0t7-WK3cp--PHh2mF+K8-fbez z_G$n}6<*iI_H>n1u5X{r&lQV7%gawvhN?L)62OPe* z$oYKsZna!#a&{&FXhlTq+?F<2Q3e3mD7L8pXhMEpTMq4!+pQ|A)k5>x?42(zn$HiK zAK<@l-n^R4rq7=I@90>E#j}52zj>v` zH6L)y=Vz~N>+=eZoCr8AB}MJeQloTVa$QH0lJW%ZpZcC{MVf6Y0DzmeGxqf%9Kbk5 zeKl{*X0y-N;x&}ce>!`u#x*~;rt;-543b1sCX7V$Z%gbPr8U@6hHL^30D$&vS1f%i zSo8;=Wl`EEB44U;&0k3^hv7Nl27p%N&NdZi$RS0THn0GI!=e5;o6*QB%o1Y-k<;goC4d52u|DrfWyWVaFBKbXj?=l(V_TP(mpVT`SI`w70000dtB-5%egX~vXpCJdTaiqq z0002Mj~h+E!AcDPZKCf60001RA4U^!0ORE7Wg*zO*`=gm8~^|Sa2I0>IO^N#W*-o6 z7saa|0002Myd2LRx9tNp6@ryYQvwLgauZ~y=R01qr9WV6~2Kqs7=>MJtnYqS6W z06=H9D>&HB2ml8VZ~(wjMFdSo0RT6O2<0RsaQbY^Wl2(` zq$nxq#Q^{S0Q^s53OF{LlC#@0c>$ajSLjMaJo@xnU)95@y>)ygsTv+%>*}hac8kZ4 z*Wa~H?eXLJ0)SiTX0{|D0DwDn!!JbyN5ujFt`!k97zKcX2si+s1;-0FqSp1pD>`cD zeyKZi-ah4LeAkSx7~f-z&nY?E9UqV1b>qA5m1x@)Ob^9nUCAU62Y`n%RpTlo5q4vQ z98z(TO7phI#70RjJv!%3R$ZHMq#V*9NuI8!dgqr=L@Sk+n#ATlp2|uMno3HQQfVn9 zMOe}&Nu{-vJm1`Eqjr9_q*$pml{J?<-F$B)sT671gVqj@PqEU(THp6-T%O92+uu1< zim-f(@!5kSy)(Ylf9#suj+-zPMVBuzB!Olc_5c4cQPfcqF!-D*#6oFl8MT^@A`M&O z#SfdM#d*M%mGWQtMt@dEzR}+!pCj`b$$bxeFy%u4CVct5f5o?A&L8>vCR8VUx$}>F zPwr0;JX3!oUtY_7gc*PDG=EdR#oq_`8~YylOaug@jB6hiyWHSdvSi7U*?fuvjwMSz zdt|wS_2jXDFp1iC|8bUC250uh00m1+Oe-^gKFkeI}m#pQFG*cJ+P~4Qoq8PuR~vq ziS@c5$%Uk6oVE{q;Z44}-XVQ~)jMD8I@TLA_>k05szByT#v`&B{3&7ZT57_$h;ZU^ zJy6#-zJN2iFW&kJQfdZ1LpyHPR7*PDBU_ z9tC|3`z#g&y?Ihp6nuale1~3q0zs2anqw^Mj9FmgVD{k6jjq*`d`D zyc0&wjg0g*M@ zNlGFej*q|My~m5Aw1yz9xxbmw*L@NNPQWj0ELmtvkg;fO*)96ayr-%vdc73qJpjfU zj4@cV&-V5sthKDKuX7%)HH9f^X?FWLGiD4%1G+c5;oPYvA9~NS^>7=#uW5JM5O6__ z-(029!LOf}VT{A7B2Ck94xDBS(z+zu%)+>pQp@ENhqgB4D|E?&tt{NH5&}+K=n$YZ zO}5~@dz#PH{rxhZAB1=bIO}{ukfzTTC2^ds_1T{`00r0bPD2vpOOim zKfJ`D5H$yghazKLPL;o$*YzeD&pK9LlBpI$u=KH!``0A_z5M?NRx zl2BL5zGaY;*`La9zL%KE1wQ0AUqYnk_`?x+Cit-UXC7ugTm`q9kFPKC4P6a?^#|dP zlMDWW&jozqyZ4Ll$FyH8`jpY%yCX~#5x*sW&@|21cbD+TK=6r#v*Y(Kz*mSAkjY=y zjeKkNy9Q5=Tl=5>^rF8@`F6n<{;-KJp|be97Joy{;d<^Tc$ytLh{MFmwJL9i(h@U`7^H6J}f(;X2 zwT8^q{(iD|_BxUzRTTd2jjWn(^{kd3lU+O(UIH)>7SF*eFj(*&80&y=z(N8WB!n=K z5YA#@;34gbW%h4osxr<+dlkBx>h99eGhH*&Y<$w`tE{TbIC(l+s?3gvd}jaaRR6o; zFY_yZU;wCV=6AyU!r@{$$J&C~hE%*)xub+ZVesy|@ABZm1HSdnJE-q5+Y)=>CRl+m&bH?ePIL$l zEC3TNRsb9l1rX3pz``og#_(!$5p?!~wuN9%?;QY(ag>N*%Sq(p{RJ~4L{>EX38Y}V z+)IDjfw6!IfEEITqw?2>clS;DTGgS0SOe{*3&bqr}YbH2E#%=jkI@Ts_)$yTyIO-{1QOzy8&4Ar{6t z+?jdilgVTlcW9}vDnwju+W)BSV7 z>T4=|1rzn3<5*~YOIy!U#1^r|!*L)?gh8++;tYmd<8h5RVV?_9c(yAe)qSPZc68s3 zZRlS9kO}#k3S;2ukA9Z&p8kfMBAj}?JZ^`-rThty9r2ecf2?-gpJ3ovEa}VF^oOhb zrHWW8H}At^EC+rfMkm~(n>ezb}T>D$d4=eX=H;#G4j*rs{DWju@D^mervn? zt>;($503nPRp(Itgr_2P_*zdNB2_+B`8{|4yXvpJmA`l@KN$Hj^Shn=hE`I(tMzOM z$F(h)wlo$z;M1J?vhe-y{eVCH@h=c{bL7tc*K#tMOeXUN$7C{@ya;2;hGl)(SderK z89dp2oR3)zf5dW6U@IifRaEa!Q$c~BB zVSXu+xZKw9cI&g$`_$(%yCFcvsq!mdSMlo=soIw1Ho?&FDLiYb&f}*2?|=2TK%~l- zQZv8X%&-0qT(u2FwHFaESXx6e-g@ineDJ})=hx!NWHR|bVXnb3nY`xAuUoG-FLMNk zUm9M%+}pBS_o(kVKR+Yv43EyfKfxQA7CgK@ZwRoVMnJt6=0pR+=q4;+6M_g<4-7*D zAg~>nLy*TWXQqSN00=y-t4M|KX0AfWaQM<$@iZ7n`p>Ig6w4QhWgBaI`P!O|VV zAUbQ>ZO8yy2@_3A`ExT!T6wX0O@I>-3DK zw*?Sh`Gp72VPM$sH}XC151B!=ydWHR0Yd4O^wuzlfN;zWjFDwvifWlUAyHUB@#6V) za}-eLJn{npU_Q)601#P8uarkWG7FdKXXxW==@F zY#u)R53Oz3@0`E=^*vf_=p7^-taV|4QS<4uMplq<_#aVMO_4|fJixMgRuWOwhOR{^ z3jjwvJd% zmA9cQcxY>U3Yt4F6%#;?+Su)a*1pP* zfAm9s_nV(%vB#DgU4bFOS3oE$gb5uCV_&j5!ond1GT~ezmbzKth-=7ppT3`408O;1%L4M{2822yU$eSF?`G7Ri zj2fx2x)C_k`<+wMi5itdc-{191Rg?joY>?G%6>1r!IS+%dRILL^UN#Ytk2>sY=h36j(#IhJK)#|DbaQsy+35n= zS9t$nDR1h&|h_^YEh&Y0Cw>eFNK|h-?o9bc6r0cRwLg)^Qxi-{0@^ zn`dVBU#mq2=@NAE7*=b zL~s=>6QTsH+RH?tIDtiVFusfoT+uwIDH&AmqETdsWZ)4uM=T=dbK|j<4sj7O8{^;qUaV>F0Jc0b@>)=JvHBNs?q`S{c8+SIz=Q zk|fC;#?9MZR8)lJ*45Qbv=R+XLLP7GN@6I6I5W>7x=@sgg+BHl{E8>HJjbRj+u5}F z88&Qun%Cdh!`Sr(SyrRjG|v8Vk=?uZar*Q*kP1aK6hqxmKrxiX=uE&Q@bmdU82s#O zzC7_A6VnbTOG9x2jaX&x$47Yk-B0-Sw=0+gW{I=p#I==K6O#p(N2l1k?=Xjtp1=q! z8CSGYLqnCxLKyz(LTesQ4W9?eC}NrZBuG{*5usYGAd=x$r7>=EItMKk6~W!{w8)Vp zNpfqeV}T>>)JT%#&SmbXD$B~Xm1eUfuVysk2=_nG57K}+1uRRzW}>)ub70^&yLNrV zr7KXxE-JM(INf~l`M2zREhdW3 zYd1MM*5pP58m1HxOmu{X}tQczVarWzbck|h5s)!;~y|0fr))Jf%z=I+cARlrzIA*(PoJwdge@zTy0K}v7~ z3=_r05C9ZBkY#oDA2>p&-o@H`?q%E7jr7z5$B!N7`;$X#-TD-s0M?#HA1QY

6KHkpeKxbD}6tXpdJg)SHMK04_=)dAkj*ijsMa%nfA>!3mWpy3+eTD~0$7e(PT7EKqoYjO7>{pwgvTCz zkcS_-kLPzh!OO31XZ`whSSD=S@dBR?{l(tB$5eUWaU6f2=W?zf#dV=}G2Pm!>9#b@ zTo#vIUE8IaC2Hc@WgSK*vm3QqhIbq)C?E;~MaC*#BC`dt6^FGNb>b{oTkp!j0v^E1 z9Xy-^oXc~bOVg94^^acC@JCC0UdbmpImweemp`6gzE7UdU8{<1C1PE2EN;wq|+ze`ARMYlzAvUGJJe_fhS_2J7LtbT`-lw5p%2Z14h zP*BI}up&F{gtc)Ll)k}&B^hMq??lxknmyetT%5sQ{*g<4V=pUn%9uTW4asYYx$(g; z7VCZJnm|Z_2G1}rtS(~CpO%xDw2sXDa=HgWvsk(AZsKpr%NY(x2-XP{ZrjJIWw{WJ z11$#08iOHfM2HX&og6%Qg{0I1e*fHB)@HrN$vO|=aCCnOYA&wa@RGW2C%>JQ!ZQmu zk-4>!{yPG??uzF1LvQnZ>Q*)sR#ETn<%P6uOn+u6*`==&*6mjw zcSuK&U4%jgBiK3L)WgzsWz3wH&is@DN-IyHkBeu>5O{I%25L`S=gy$Ux$}*@l#)YR z>o6GBFY2@!b?22~7+)BR{`JN%#&*o}H=1Z*F%SU(9f!^S*?m5IUcNdDpEAcACX;DQ z7^A(HV`#u(GMP-@EQVo>V!$!_n~oq@&@~-V6c`sb9`641>&N{M!bbr_UBDqr#K(@q zVY5kR&&TTYbWWZ* z!;SVfydy#G1T|jXQO=>aP9w@LG)<((tI^sy#N}%qUfHpiOV=9+DPasl$8L8L7zq;$ zS$M1VJq{l~M`w?hS+nM#s2W~>h?^aL8d`d(c%z2;vlr<1XOc*dw|q`X7lcaYuH@zboUKWTX%^SYqGFd z#}ib9=zpGDJ}zEsWpn<^G~eoCP?0!ZcbOx{&Ja-~y1NG$^!fpitTr0l%?u7j@COXs z&0XAV_fvP)%_}?iQCD|9dL0f_SF>wxIgRf(5eTXD3=DJVSUsEaO3@4v$>E@(rGwP8 zY~1el=#yyo`z`F-zn|iNm!PRCUAKGCLprg}SiJpS+B_ZjeIauRV7jMy`}z58#x8{C&~0{OqR>v!gVFvOT#>crb=gP@%r=BItG$ zRVENp@QwI*@BIIn{KE&C{fFr|<1_-{0c6pF(|R9GH+#t2z8kD|RxDY>l!@OaE;a_6 zGX`un3_<6S3Gr0yE@sY*Cm<5x+Eq6J6-HDmuT>wV*BfN&)T!($+s5|7Y$RJe&8>Z$ z_+KrL{b({dx$BW_3c3(vO?nCi+cqMKK?FIBZbT5U5f~PDwelz~TO4zrn#RFh*(CjO zIujElIy&3&20~Q)_ZX@qGWp^ADa~8O=FDZd93mHQc&K{wBo6be9I1YF+xdU4wJr{fK$?V`pI8YTAa(HlO`gdVlv&UTuv8J76mNfPdbafY`8J{ zl2LO_`yqSx@)Bhf#&P_6-uKMgJLAkdsnf-4CXJUaS}9qs3KFYLDHIkNQ5n(3f)=%C zkpx{X3?%qL>ZnB{B~z?mWSs&Jda@* z#xE_O0*7H3#?qs;LMhF^lJV0x0T(|5ZzrZeOVAcj2wH#=K!GA)Yx+(e_0|+NvPdUHJRWCy`V;dDY3euB6AXqK z9T`CjC@Jv>I2vJPaf246tHSu%IV?NJ{PzSxOD5lcCY2UQ8RSTJ2Qg1^yk|edLwD%v z?#9mxUcMPG+^ci%E~?5xY-*??-cU>N+Db+zCdt`0!nV+PMSOh?bv5Nwu8z>w+RSV+ z!N}_|>_CuMX_#=4#0fY6G}cxV^Fn0vkn*$S(6qEQbLG-G`c51oT;$++9s@T9Xxv2JTR6q3tI-z4nigpg>h5yIy0QwRYC+U4Sf%RGPf1W;HCl%>eY9F~TFvJi`Lq)jIMjZ?jyoIiV* z@v$-9P5xl-?t|>A>pPCWf4}oP=iGDmKJ0F?8v-N}9wa=Zw3a%JDNG2`7EB@t7-(sN zf@25)JJz;56{BR(f^ElfpxVs%SD&!LAJoE7A4r6>7@=y_D6%G+2Tb<)?mhROr{9A+ zH<%fM%s3-aR?chYGrRYXz30sCxo2j-=lA=5Cwb`MoxS41)6eW?W8!1{3@r*YIY~N0 zU*uDy8MWGCcJ0{3e{X+;XTQ0dEOi(Z?Of2Vr%2zSi-fq_MFl=f&pMqvn?d+ptP8;u zcu4l`-A`@~kOozrerhM1uU$pQW`tpg=LaN7j+CIg9hw9EG%JuLIm)Zh?HVRp38P~z zWMzQIAAg+fUwW9Vo8j^rxP<8`g|;B1W2QZc@@s?@59@OJssYv|GzOcb9YbrnL!fHJ z?G8df5IT&Ms34@sHI=ZzPhOnF_f_vb92tXygZRGB!x7D?XiQ1LwEY@BlxNsJPPBv0@HkEGq<^fML{cwKxFe1CwE{S$ol^IzbF zJqOwQ{P$6^f#;f#IaE+Z;5-had{T9*67yXpw^+CvoLxt5hn@1#WKMtLElemrAA5 z>x8ooAq393U(<+d2`&U19kYVtCBk9>CnQO#5q?CR78DqkoO%+gE?&->E7$h=Z3r)9 zd}4}$T7&rm{bWT>RIibyDV-$Yo4bF=-S>QgukL(~w=G}EhyL<*-unB0fb#2T9Ux=~ zQc-U<=q4QmIS37abkJ_ipd{!bX8H2-s7HeF@iG48KOQ+UfdmP{_99-<@XsQ!m?ERz z7lAY6X~KmUUdU~?-_1w1+{4zbALhP~Z)M#z>(EwU0b>kON@}$u6I7Cqn9n8k__`>zpw3(H5*>HWq6w z&KQifXlF6AQBwB$oJi&Mj@L~x0zV{*B80O@G>H7ASbRU?qg(Fd$?ebLsTvzMe}F%^ zZarZb;s+IKwRuF<0RTMDBw0bV)=xJ}Ns@TZH4Q73 zUTe-75IM*c(17jbmwrm==EgqtQmIt>O;p}}OQli?Udst8zrv2wmL3~`3trxX!%9LU z3ADs>U{Tmgoxk7qIo56ZD4+Y{ZeE-YIWShRW7o4x#giD@;p7EP=)??!HH05Ao#Z&> z(Hx%7$e{zsMwO1~a?4*_&)Y6sO1%lzz~I0lJXIqI>tv}xc^(LjWHt_jlSE-ip0`wZ?lZCW>?hsT5y%Za353 zJa+#7K5n@AHoms&+e9*8(ZCSCQ9QZx|0u!%x+dbg-yNYI_3?Y>Eklumu;3(GD9mgu zs`pwtK3P{#`Rdo1uyeMfda3kkPbQDvZ={}$J+4c!g^&OUDJYdnrP3>v1&&gwRC;~+ zwG8od~4S(LYec<)fW+} zoO*x2va?U2&o_K^`xm+S=35vY9p|*umQa{3wLYKw@B0}4^qEhxXXIOC$tZhAzQcnL zewrl7G5HJ>Gk8wpA(0|L3DtXD3mhje?5E;oT)k!$L(PCVj``FB|A-YJ(S$a|cPRi) z03yeuOXz7D6@@Sve{}H$NSpBN|L)+%_1ALGhwozJ#tm%S_8@ykeu&8p&AtlD&ODWD zdX!Jze=qm{?Z=4YF20KJq@rH0Gk>tjinpGF(lHNw>H$9Z!P~j(?yc0` z{@s_dpdQQ~YZo_Mzlob}+)Qh9f}y%%%_YkTD9~w}z)NS7ql7|OM<_JD%u!NfYyrTs zvz8+Bn9lS;uHUepFMavT*sM#@nLv@^yByC8a3a93L@YdEA)zol`NX3<`pCcY(7%3` zD9rHvoO|#6IBA;lr&q5f?~L)p6OVD@O&fXd``^dz@4dkPd~FxbiP<<-u3SzOXr9{s zUu@pAvG?}`d34oJFGtBax#zZ2`o&3{1Bb%8Dw-;|;5e+jkjE_ZmRMVUmP(~k=~cZk z3LNt1WzLMLDV2UH<<5volm*~gm8S8(Y?%jlO0qX!QYPj)zE zXpqYWRC`ZHh08B3q*;B}|KX!1M*W{|WXn1_{2U&c0a?Tk37VNYp>#tTi4T6G2N+ADhhu0 z+{N7afg2dENu~~tV6zF%J?l+ux${nhvj~&2YQ;HR^N#bFr^Y#a;0Ls(Ti_H{C_n-7 zm_mo-mBl*yvy=so(%gr{*ocA!T=A}3aJB|6z#_5YH5`ZNBmmBem$oyOt2aueQt5bl z-QQ(ro`1nrtSgtpmVVtmEu6--Hqw(pkhY#SbSq4lH?*68d%Ww1TffkTD326%wF#E(m+HSBMoLJ&83I zCF}fXPnSl0n0Z4DjEyN=8)O$Nb3lTr;mHa~lA@G{=lcL;Sw@m)NTmn@e>MT8&~)1| z^XJdUIfu>*oYn|OkFX9Y#F6)qg2EQ$u0RTfb(Pr^_$sF_3h8!^G;Y;JJe!Pxc|&AL zO6UgwbmA^v;G=?oRy$^La+1DAli}fEiaf>H9N~U86hVV^AZ+h^^E{_ktD=o&CT>x! z*GM~AZ|lh9_zcriZB9L7DK>AT^&t=%&#(5*De~tt)5^hCXf&%>IfWAm2!W6SYd~vF zRIO6vImTLqCo#?;>};F_W5~2V(ooftSnGPgDy z!a3Lb{Z}d#oRnCt0SG)r+Kq|h4oZpMgqt{tQNF?xU<-{W1RjoVmiB&LNe{3{EC52d zV+wV4?mr_bm0pD{G*&do5z~B0Xj)0nVG)$QiZTYHV4Gw2uM(WlGSe6U9Ij#+5Rn8-QnE`l#d^OO4zWd=9zWVwb?(V*&*C#wPD=RB2ua*z|ps;w@eewCL))3Y#Dl021D<2ViL(Tr9 z^VHG;Ri2MC;sQTMQd*DVuG3C+>D5^ z-$zW1Tt>RSCj`SRv%4NBrI7Ln!0qjp7z^Y1jQ4;CF&e=MP6VwJ#S|Zf0mwBYX1D+) zok(S&T4jIzj)z~*Twiaf`G9Jolt9Uqe(1=WFk9H|gw5uLIc0*MIj2XgDp%Vpl!C({ z=4gV6DZ8tIN2!IPO7I=sg(sym z+hI%h$)1$|u)Cm|>3v6)LMavRJ1)1Lz8}!4IG4B_BDGX72+`xz+IQbv?5I^SGn^@Z zkN%mUv1VOadE*G6ILROh6-7`S%0I-*SmE5OUK^~etgO6g-pFi3-fWthm6etME7FRo zL!4k{|GJ-=r-VqL?<1-OOn~s0yYHn`v?{05u`TZJAHOH|GY^L!K}OK@@?3D9AWEK| znU4?Dbi%ug<}CpDNGC43N{kC> zd_?O)%?n*Lo(?~8v+tXYyd2pKLf1p+D)aQjcJR%{MendWvgwWae2=FPypr+>N5L$k zO&pn9{rUL-PTB4ToK#9p)VeUu2aJ(vdCxT86S_jm3;kw;6QkCVYGeCfu^%yc0+$%) zW3%7&0ZH2D^W^yyLrf?{k-y4#ue41;dha|k1Z5t2PW z__55~?%cd7mYcV{+cRohusNc|59gHa3qJm6!q|~Dv$2YAUp6has9unnnKW~8e#ZHW z|4_Z;C{@h2948@4^W=1cCC5ypJWp5c za}A?(W$<7bB`Ob_$}yMm3Ew?_!nfai&F7ze%A|r(?x;isrqdI4=QCb1IZae|kb`zW z!RV8+r74m)q|*8c0XXggj0guDV?9cl zHxUUJNQn>-MnnMM5k!CmNQMOqt~cX#0D{`$0;i23rz5Oerygszb+SxDeie@+1ppyO zCh*{GglqX8_llIk#2!Pe>|@jtdpoj{^M>s_14fInv0p34g6=v=hb1cS=QESRAPij0 zF3RyKUw-ukfBx}1nH>rTz`_7~rzI+X|MM?D{P+`3pZ?6I{y$1o27|%~@ zD4=q)(!R(Ln@)M|BGA=&=BtV(=Dlk6eMB!cT`AhJOl#W(b-FS&_hS;xrLAaobL&29 z8iFSB-iEEQ`-XL%2JB^NU$b88Ie70%KVIY;c>TJjHMU+~wXh}_io>Lk16`71Bs~Tn zG_Tpao83sxDvaa*=TvpK$1|hRkSGhpA|Q5%n}HQbzy%-y3l?k;n?yok#RULs#Ld7u ztk?od0vV6pU3Cu9tGIhQ>9&WNc2C#%`B{%jwk5mTYFE8=-mgbbpOQ7w^#kv|_Xsoq z>CwSvW)tTEhuMiL`H^D^_AWB2yMJgLhLK@4GV332F#OC&9f?Yu`u zO4+jc*#)5%scX6Z2wr^s%k}I3@`#J57eb;O*-oLkEkjnG3ysJ6)mq;KHIM%Zwz|%tSLc5JH9mK&fH3S zONKi}RP6j+J4eLq5-qRSxTv@#;)_i7c5ikx5n{IJfq*>c`R7pM3<#+HfJM8lqK3OB z%xvPO(V=nrXJ}@2@)DFla7@e9l77}PjL&)hTi@6&5|AxBOtKnpugxPa%%I5{8CF;1 z2z|W6kACe)W@bB8aDM(6 zl&JqN^q+z*K?4@YL4J?_UYDxODfW+!J|*pS2esZwFhu7UOGkaP0r@&!mW?vOFTCNw!+gkl!9?4;5wo6q}6`(m$iE;o92kKZ$ zAU#mp%L&yhsd1>gDZH$em85pQN@H@72! zsu2hx&-niLehk$EK@>y<&~o?@$V!h)HnWME#*;8-N_ z=+P5a!;;xd1ch>hN&pX!HZ!}45`d@$k#ndX6i@*I2o9+#xu%fo&}L@4cm#*p+pFCE znS_x-6313m%x1H8R1}NFjA8^leb3D7X2~YevZaE%5Ryl5n3>(=eib-p$O8ObRkbVBqrN8IWwLAlaW=DYuU#Quq#TX45gz zbuZllHZyw-U*0A*3d9j8dG?=Ana$>`mK}fl>&H+%O$AhV2Ng53JuWYw6AXkd`SV}? z2pWh=#Gz~#H#Tc4Z=vQ;JybuP z%e$G`Q6!tdlP6ze%z>DF&b#l;K}*p3`v>2(ud28v2{SX>)5na$p1lNKTckc4?lCuYAtd>hMPydEvW_Ajyisf<%z&MU977Jda;sA2{ zsGQ8hftlHqr#w&VY|YG0MFo`tAPOWMeV*dO^G8&TD6W{z2hiYUXwA%SA&L2-r>O-O z&kCvsVx8CI;)a>oD{z6s%`P0Sz=t&@j1ez3w9wBs3`+Rm+LUt-QRq<@fKWYH1Rhba7)c&K@j)fI8#( zGobp(>=0mPW|J;(#IE=zWcP;O{im(6h!7|_CP`31RiRkX&&$346QY8s%|m;srRg(U zmdhox|FL)fx={l`9LK*iYdg7v6hKLXXd;@t01rZipr+wXkZ5@ZL_?RBhCda82Bm-~ z4Ty*+5kz;kcYdH#$cZRX3XO9apQ}v3F;%OyI~8UGC{4)2kyNJYhiqa>MMb zLeuagVJF67=06N0rG&!hx=dX+REkMJAP;052wYJL9W&0BmT*rfjH>!u?C|+n9v4MX z6m#4~MP9x{7MG5xEV1T+B+MK|0OF!ZqN)<@cubuV%PZFy@9Y2pQ0B~eBxlNLhF91d z1#O#1sU~p+0x{v@{~Wz9Kmc*Vrq7Rg{{_h}#}3B}M1}~=4OwQ~2aVN8 z9Z@=d&ZWKWZLSV)FdB7#V!zCrMNt$BVm=BSMNt$p$lZ~IC%^(^U;#Mi&CKX?hkH%# zo&DVrNfju7zML7KVJ0TRoCyo2op&7E$uzVK`7vsF@%$z4-hO0j^E;?PQIQS06l4!1 z9U1$4E=D}Ppy0qF7U2&C2{-6h(2IOH|-+P^qjJMKODFWB{Z9GcJlG+OA`Hu)@!A zX6wr)tG92K;>J9YBcE>O&1!lQy;o$0ynesIlc&%4_H~!GGnSj{C@+B;vP4UevjE5v zXU0xwZ>dxNpjeFjKnkbM6)wPAuo0g=@9<$`o%L65c>L%gch`QicPDU`on@WJf6w#2 z=iIHT_v{NHWQ8n5lL#ZYp`d~=iIK!WFrX;7vZ%OZ& z#2tt%ffz9%Bmt5@=uU5SZ{2&(J@4}jpZlrqvWhCYJ6+vXxBLBmKL1a3b=5iVsj5@w zzUQg;yzdi;00K(Q9xfo3N1m>AA(U83AQf+U+na%!L&?nnFwf5}Wm%Rj@2DwoEZKR< z!wIu2TV;xyAR@4sD~FUAF$$x)rYxrUnVKq!v(wu#m?DoYC1PlWKP#}T>L{#86-~3kI zeB z08kNDhcV_QSQ9+vb#^9*345u7h)@ki-16Q(WBaZlPDE`k{_p<{vNyK!p+=Z{>xOte z&QhNya=#fX?Fh5~bM{ZM4S4FILy+d(%0(D``I;mq=E zVZ=~pj*b%$rl!~P_y6#5r06U-pT-fz1Po|h4{QjY6pC#HK+wb;W7Y5mP z_AnV|(f5Du-$YDXeCY3QrykXKssUw8>O6X5LKqSEHi;&lyTnJ5fLd!HEi3un_;CmiVMpI2}?(1QTzZSa|tXTK_o1SeBGe? zo3La=_K_vpaakC2KN5VYEId9bs8h+-M|KfHF<+DxKnEZLkeX}_GXZZhvSWGPS>b|l#JmI|>Hr3=xByr#ZcGY~m^U$+cwV|S%d+h2 znV3hQ^CY8LmSvCmW;PR>BEp7F2djpZ8c-F$F?04)p3VOt zi3ltv2F{qeVkpeb+fa-0lRtMoFL>d#oO9OcOcfEeA;}eyg5VK+e!^IhJ^K?tApf}5 zCNadp6con9^N(w-a|4%zE|`Pk&=C=2@(Yt>S(dGJxxkTSS+)|R%*0R!JD>^boX5(6 zq9_>jhZIFX%7S_@0Aau7Td;#9vhNY_fQyo(r1FBhKlcc)c+Kni#wTCE%U*mHXPtfu ziG(_+3+|44!d>zZoE0JtF043r!`Gq z=d5+s?3|tC%9Wj*9a7}Kt3zUh`E?Y`Ck(PU)^$!JxWRgiBlt4bI8sC6Yj3(@cZWv% zBQ5G#YY&u8tFQ4zuWWdrFnm_2U*8$Jo9b>Hjr;Mq+? z)9_zr>>xm+51S)YcdXO|0(C4SpCc5MH!P875GIF%%h=XZ|Xov=@IIi*67M>s2qLWv1D9JZ6tE%TPvl{zwzLp4JneLvP~Cg{%|2+m$_ zPDQSLa$-JaPm-$P+r|=i*+W?M-L>GH>!K z7EP2}!2^`kg25VcIr>k$eJA3;mY?2q#p@4`iu$NO9Uc+)@Ffh$a}Kx&&9lug<*Wkl)5?MMnbwaIu0N3L*7 zjB*BOKl@U^@a1LSaj%KsYW&0Zq+vkPTp^1%MPO|TGZnnXN0zbV4Sdmnyjnh@33wlP z2?LnE-Ye@^URkZ&D#no?k_KBt5JE}P?}g*^|7;l<|J8kl0<3dvBsA2JojOCC^q78d z(&Bl>H0G}(SxNxDj!GIldXw%;q}E9IyUPQMBAlpS4OSS;>DAzXfIP$_i%zP=J+8eB5j;I(hxw7*~f%^v@t|F)L-7=n}bRi@%_mQPXZCj?&N z!&{mz=Uw=N1_DPO3$>OO=g|TWF^1HqRa-=@oX@tXbJ*N)neHt^#vH*-n#szRmhO2+ zsVJO0Haw`ZZWO)oxtn$7lH&$g+7c+lC7Pj#lDO$(bZho0`3xn;#N1zWzBvH_OT7vhRucS3p#!dW!_UE)>4yY5gc=mnmrGuA=JczLsG-c4Eo9P z=8LVq3hOyqeFk+^#o>DuUH4w>iH=;`G*}C+kL8T5AP!3T6emKphXBfYW)gf$1Ekp& z+;nSM>Jyt8r05zV?GSw6VN$`yiDrkjH`hcDQiBeH+n}3*+e}+9qY<-Nh`*7%vp_ihWZy> zS4i~cAXy+Zr9HKn^uh(?Wn z%HTQDOioxzGr*;S9TupftN;}(X{d-idcIxEFK|}ms!15{kHZ*wnUnlozawb9Z}_lf zh+R-?zb5p9ws}pAgpc2If9yRgCIe1#Yv=ui*6-?HwFM8)yxk|mD{A)b^px*N$co$# zlSbbI7Yse%ESM?tCS2Hkh{Z28+395S<^l)|Z;w~6(~#6LqK{xK)L}6h%B9fti4uv; z0j4bNQ$IxMWG-QQR zYGGPAvYMVdBt{d48gYr0e4(7ug&+)%i(~#5mK4Jm&*e(7IY;`QG9(QsmIy%@J$oSn z!(Wf?ee`cI_NN%~L=j@}DQoO~6S*hE(zM&3X!Y-z#g)scX-K9svbsdoV=N!X&%K2P zvau#j!FCacw+LD8Rxk33)%=^I+!GS;V99)L6@Yp_3hW0FM+#%~a-vbI$2*l- zo@YYG?T7)jWP~+)50S6ter6U#l|4~$7Q z9O_w{kP@>!9c&E^7Dgyghp)I6_t+GR#BO0}AS}EOfAM^+ZqNGrmh<7FbKlaMe@l0w zHAIoUDFDPU_W9S+e0Bdr9>F`HG>qNfhM9_qKD#kAElrHO1v_i6cGY{t=sL&$knCmI zc4JuleWqg?%fy{t|Ngq8@Az%z{349xEnd9sGNm_Q(`Ph#~}dF7Nu@b($5j3o4KQ+IO_ zElxp%Sg2utV+Rt^7XtGF+(?8@Xqy^q=^(Y?d83#(MF?YutRb=_D3P+#y-qHpq#j+Y z#%uv~UwapuTu7|4e1*y`22-p&Cn_m+=fAv#{e2m4@p`R()%LDOQTIIZf1oqPjVHDm z{LsEB_-zs1{vvjxBTa`U67kzoU4%-pa<%s5mj4Sb#lwvMwyOOz)^Ty1nI&TTg+xln zRnCwNz~ah5v0e^rDCdkuNQQ zz#s??ECjVINS;uRwx&7S@{8bWv>8m}an%Indj67*oEApo``d)N7M{K1(NM8^F>oBR zWsM~MQlLF~)_LCcs=D~}(_nU<9@lqxFJApf16N9Gu6Hp{UFG^=z(ErJ?0J=d5EI89 zp>kfxd+l=ns^Z*Bh&~5a*rVIW;ko?sg+j}M)aRtOk)+ep-&TeNRJn&J_IMfY)yKRc z!5bYAG>aUj0~UexI$YG+5>hFjgDIst>2^gr0Q5R1P(wA|tt|1sY$6gE-KK;t9Po(K z>++e~J3avpSyAM#IO$zP%%JfnmwT&oneJ>Ch#=bXmxnjv*K8FHSIKV?0mdcFY#&kW z&K^byJpZw`MJ&7wzi%3yEy?yFeoaHP3+7Y90ITN*36u{C{F^ni_MoI~yw64|Wh!PE zt}c@7*q|@@F`9OGmcOwPGqc|`;X_BlFP*hHFYYJ4LUD@o%e;AQ`}d5hgex*3r|i*G zJdUb}pZ%dWbbDKDl1Wmt$V^bAaMM}IR9S=wyN%u+!Q#0`s#;163^3H{;MHja!TD=#~~w5{S!!Y(Rohr+BqtP zHUt?Z0mi}S_?<2lh%TYN0N3Qlu9$_;YqA=<59|705*Awp8_ufY=QKzc%SqA2uts#- zJljJYLz@>e$q|Vi32T}c0>a+mLfHaPBc;{+NPF1Po(mp=`J;7^4^PDhdX%k@L`t3NGQWJIYxh;X{r=5Fo_97Zn$TZ_HuVq#rE+YxIZ*Xw z1=H_lj{j;}du@HOc|p2OHyWww_f;ffju*a)tuSJfEPig47wV_s@K52I&6#k zsRV<-?d*(A1L|;CjoJR^$Z3W4MD5liz0u8J|3?$@wdRb|FFrb7IVv_6clg!#Fp6dI zq|~o5QZhr~7`t9`UO{s#Nz0Nb=;h=SEhj#UH7Mz&m2N%!HU#U;mVp_ZO1Ksbjyyj<#dTClk>>4ahNk zwckv^`ni~R1p)!_$Pe9vAz`o4EIES$QFkrfE7TBfOD&nQuR=1xiE)ClAenrAh6>4C z2^1Hn{se?2E8##1th5a}e4c_I-Yt_`EL|=Xd?R(d_EP(8nei5;^(TX$_>$a?izXL) z!G{>kSOyp0{x-tqVn#KQAkhK(VNF?vZXIW(36Sn4aSr)EKeLOBStGz^3I}TV3 zT^~JM`qK#1e8y1dGr=D2VOreeT~4q=ofzcaj?A?T)_maER!O5!nvFICWk!(z!FH*AJZD4=bs z37K124|&ZWzj{uoUh5bdw*L^h6JUzTwuv1WQa~uB0iZT6fiq3535eV2ygDtBL6`Un z2s5bJ4bjn@Yl-MHU*mvM2j$@>BOHy*L3Y@s1j)3N-V0e%wb}2__3Q;pncdi<+!E?W z?e&Le%x*3MR5C#d;%{&bFJmFI)(MMEJ`%-F*m(j8R=($o5??PMjckM;#}; z)kDL{gDSs3Ki4?bjNf|V$S`Rl){nIx03Z{#JYA|AFYYcoA}GYt!$DEiN55~>k;V__zfW&koA6r_SJI@z9ZIH~jmwptSVYfp9fOsDpAb#cvJ-1O;He;N*56)@GSN%?dOcg=|jsL zZf`QH4^*(O&@7e(i_SSjML|6l)+DEr9L8$tvHQ0K`GZ$s&CBxj@QqP{FsYvW=I*4te$i9nBLK0My3Wt z0C})dGF$rr>O1&W&8`C!*Lvdf&c@vQD#Dr1;1)^4*m&~HzVrIG9p@Jv3T4x+)0GAXYMu4=mry=jIL z19XbF0pZdoyC7Lv6xm?98M1>9#v{qBu096CjhF+vk!ax|&A|Rr2H#{wc9E>8aerQl z=bN^dONv)sk5xa4%6wC4dNm)=6LP?^;*TK3w#^ryRY$1rcf0NK`nJ<@HIU-Dk?$dp za6B`3bzMiEEI+_A!n^H$zvL5xG2sz4E*zzRKkwo8MhWP7c?^LYUi=TgYVQz`jGlJrIt9XPLQUb*wuV$i5}?43q1t{iG|LzD z^jS!mY7@d}3e=ZO>QM$;^AMvW!i|d^OCi>)B_W*ExX_~`IZmv7aNN(z*@7lKnc?Io z^)@?#ttS@MU_5d!WU-543dvtG<#VzOgcup0UNLX6_#Du`Ex9s%IX1XyZt?0qw3=bb zBkqo68xbvZb(%>hp@Z@vf(+V}~?C6eeO`S|Kcee$TNB?B@>IqcRmA${7Z zj}rvcr3oBZaK?UOm}W{@(ERYk_8&BaD068Oa$~_kudkF@<5*hY_%8l?Vv@C80oN>) ztZ%^IaaB^u<~K3ARX8QDX^?!32_+(OC(!$?BJ?h_dSG@@nqxNXWrE*eqRN1qM~a}9 zEgL%-l?mq~qm%k)MK#*Okg_YE_w%fmyZ5IK>k1%Q;4HkkpM65JLj7uY)oH!{?MuqE zHR_z&WpnV?-qBK7Jo`W+-_wi|S%XiCER0OFS>uT7&}*MBzVN^CWzEwal?BR!wH_yp z-dRVw45D+vQ5!MSw4aqf#J+%M@G zp>B@I;M_Zk{S%rJC z6c2)kb(n>+sqc*+b!s+t{nT83ve04cbYh#CM$xHiNvNY@!Ig5TZUQ~hn3Dop0F*+o z=#xzx?+iZ)8-wIn7^!dtP)bm?DZ_wWKXWlwF*xFhuS3u_fs-Y1i+e~GNEK4)Wddl8_+rNaRJHtsRRua-2FAE~6 z_PaM+z#0~~_77_Q8TCz3I06Uyl}+|TNAY)URGs7Io1G5l41pW?l4H1Kw=wbdOZEUb ztUc*Y!3CVlmz0Z#;GqT_0WxW>3v&=gO()C_=SVsgXRwY0DcAQgB6HCOb-~s4rjD6= z^igMI-MHspJ;vAdi!Y=csy}K8xgOil+Y}-4Pdrc7@|N-3onE`shoccxFumqM)+3#| zn1Pfr%CLmz4!x8NgXknSz4(MybYkUjuY5IpuhkfjTU zlKlA?TF*|g;xr#tHM8tw_%_(TG!TOZtKQ4yekC9{A#%+Ew5@0#aXGi`Os1E?d?mpK zGU`ydI1210^7H& zq9qI-9lQ4yl>tY7nqP7dik_Op1A3KN&?&EBO(iCD4t}o=mlOLr`i+>PeVg8?XSKA3 z%05F4!{{#&Cko##YR}iA{vGH)2%-cNZf6?@dKr?|BmG+L4a+p)9J0_=akj{w*$&H4 zPuto#7T#U$*uNSuIC*s4Q4q#T%Y`FfktoFleXX@kZ~{@m@2FMHsfCH zrXCH2ab1@swPOwRsYH0vHBM}?+)fly+cV$Z+zFlc&MzuEd2HTN?>ER&`&~SYwX532 zG5=_P`b5fB#eFt{b>-~8arZ7wA664_9*H^)s*7Xk%x{F=lJhp|;V?iQ1rd=2N^T%2 zYr1$k#`JAtd4vak&SDCs*MWu4ofC*Og~4ZHz&|=Ye__|sn(`1G*`Wo2>NGif?(g1_ zWx%`W+y%#H@)n5<@LtE1Z-VL4%2tXT#;o?y5; zy<|aF`JXcr?xLH*=)zT5V4}HQH|=)`wVxMMbL1SOUWsuB4Qsz##Q8-(-*0T~DYAEU z22MJLOVNnxv?xGf{?c$4gTfn!&BLAheXUz`WZxksjgqt}rzjQP)_p)Dy(@64 z33p}re$9_$$!e)M8td3G!0xw~sGmby{tx&GkBCo~jlUwgc38E1l+p=A;L0*<83_@g znoW;_;4)JBSaKJC{rvr5?mqYr;gO|5bfr_J!Gfml)d|Z(EroX|d&gV(_XFv0k!O9? zUOO(mx?ufXW>oh7bTXg6SE&;4b$~MQ+Fi?_}3kfcg);A z$%+B}Jm-ro!Mx3M!rCEfh^mFut|<5X(^vi=hhbxzMLVz-(KBK$HX*9M-oV ztYx?rEn}p=^iX!fVlUZ_CnX|cc~*E8q1vwrY^L}<(WkcEX}WI3^GZ8%VY9F?aKIOA zitP1+vsoQ=oU6X4!Xk~^U&c?Ue#6t>-a@5441v*a=;W+JuK^qn>YHVQ?>BgUYFZ${ zd=r%=hFf78m*6PmY>Z2R3w$JQrDbt!gARM^WB%1i1p=)&ug%P2_;Jv;z>}5);xlG= zO;6T~`DHW-PmymKn(P^49{!@;1bk{La5NU(uXQ!vU0K=EXUHqg`4-;x7Xfp^$){{% zwO#Am&{r4z@qbYyfiv8L0U?j3DtBad6=@UIQ{?x?vAPHnmR!!1f);rwX7_5A0e_4Y zDUGp+hgd-xHO{D{M_ddbE|Vw((rN)Qp`z0CAY#|0IaQcUB?x>u6KtpLDC|KvdN+WA z3y%Y`cAjVXr7tEM2Vdp0Xp0V=Nf!#-^rB;Kht!9$${hvyC$xK)Aajw}&OiWZ0ewss z3)Nr$jbDwhb}g`-ZKiGCP)O0s4&!rXM42mt>N}>Lst>3;Q%Ko2V2=T}-*JE@pLQKb zUd5$=K*5Ep@s&?*eco%={Uq=3@RK%PQ}m$-PL^&7gk}WF*uxJ$jpegr;$VvYngrGh zFQ%QI4){1WQVL>x5K89Wh}#MrfZnb?gYvnn)*RWyoF*HcD^bapi7kS*;*5PrsV3Rs z<<=49zPx& zD_dsFMo+k?SpYW6Y;ljDD!+j5KDiB`u^WgpI+iTdKm)Mr9WzLyr0Q7b!?hzRhb<J5TigiP4zHU&h!V{hGmb8d!cj}NB{be|+lHUZ|{`!J5vj}Aq_sTtqXEp&vH=Q3b z;+-RrzklY*aWtu;GVqB8rND-G{y4UvfEoj8LajPtZgP%0G^M>_jpObCUXayUw6TM2`h3j66A!vk9mIB<_R- zoRuID$(hPudx6Z3Q3A1dylBDTia|Tk8g%8jf z=a<>`mfwU2_;4`&2?&H^76@m=rNTm7W)=lGiBB^ZT121d+;(+V$K!)O z_jx|eLFgAj3tcs2u!SzGD0{~eOn%u$@d`*y4#xuurt}d~)+3R|A>_RD7E{@FUc#%6 z-O_=&OG>t@_3WX0xYp$I!Q)^XBL2|B9_V)TnH6+JiEr)>ru&ad%*Hc)g>nOx%0`HM z;Ar&mfpzxWHY8XTrIwk0sZAbG?r6Z0?a#>3u1myigY zH1tXJ(Z2fs!@iNA;9$YyhJwre$I6Wtu3q$MD%(Ll8K~80b`dsuT?;-PT%LI!6lWWnIb*?Tf5UEmL&ox{lee2xK3K;qzrexAZte)v>Cg&0BvhxVrc z`WkF_ zrWlhs{&Ct-2P1)j2_qLX=5)umkq3!kU%u~Yb_8*TyAo=i%qapBikH^^F6JFpK;2wR zoBMOQ*&dQ@`_&(IPJI4ms<@S#V963!5Xi^Oi35q$x$DxG()M;8N<%2p%|AikV~XB) z!;~nsI*^#9Q%D}^YiAP=8X$;S9?1pJAEXGt)Rp%3!t(%nnJ#{hW%qHmo4x&>nY#q* zh-W4PMlHOC+Pjq2pP5_Hv+*%22QK-JD-qIcGs50NZuyQ)4`FGZZ38fQqOe1|!i<1# zhh>up?Bt6K2=uQYo}ARX2MAokpVDkfG#FbGX2$=l8i|%-(bR%!FEV*kTOSNR`Zu|z za$toOAdex3n;>^^u?cP6=KU{0dMtv-KTgVULsw@_k$a)=@gO%}(p~p>c@{Yr+_zs7 zEhmiO>(m33!v6?mMPa9M56UVF;R;)XrGlVwfY{(-C0Mwu%@QO6&bmI%f(drA^~PATrKjiw5rNKax~<(3~q z5_83w#Fj!fxf@gIqH>qmX6VK0j^p5rY?~&2I6P}kHyLz2Bn>d zQ5aVDNp+dAY;s8mmXs$=!494df?>dKxmA-EVL&#w;trxR+>u4k*c6Yc(B0YFB!eLR zlgk%R>wC80X`5x(qiCAJb;<+uKPOZn1NePIkh-E-j?XAgBHxgyMstZ61XwInq>;Cb zdjV?YYRA>tD$c)HNEC1^`?E!H3?C`hLy}0;fTL|Kk;vgHLqyIiT!dO8heO2|bty)p zt5SWrOczcV<5V?iBtqy^BI%6wh=f0gFVGp{DDi3Kpev+8SCB%c68SMD(_GOaPMnVG zVP#`8%HMtq*w6H!E6#fI#5L1bg^?ypYHjztfM=isATn4?(Ob#LJnR;~5l}oI7{Rc1 zyhRekkBpY6bz;^bg-@w>iK3oib&F#b0N6PtY!ZlwIxwk1E>al;zU}=5qELmHl`_Cz z<14dTWj})BiLDpD@uBvApsYxd_%Yp(CiM5_iI&}Os^i}(^cs_FwyV?U^M5GxIlVQX zTFG}x^BA!05((L@p4tRS5h^)R!(Mk5+pN-JGQveJ)>@iY++Cho|2o}jpKq0w8%}f= zp(YUPGk$`h-bYlIi-N6J>gSw-OWw6^eG12ljYW~q>2J6gneZW}cujl{8RiOtIgT3= zOD!>!Mvn6`olL8w^{Ky348xMrv4YM@r*T@PYrVB|Kty+w0dQbye{8l#iHr#RO+!bs zG=L=jVA%e=Rz1nK5xz{$WKfiK)}0|ED=K3bxybc{Uf!_C?oQ)ZSYeybqjtxI65Dg- z#%?5kYl4;j1vd+;$`JBi&=!wiy_FM1rC^xG0>%;o4#Gm3w;2Z2C^9?8x!H|V#6l{T z)I*mm-BB=6+9o8S3o4c(I5lHs5)VeJI@|}A`2gZ3I3M#|ZuI&!tS!>7thG5at1h+%q%H$ z87i~=;|;6GvC*4|C1Nrol1tJ**!%B?eqt^wWJ*QP01g-=x+V*K)fTB=WlZ=41WV0s zXg>FB8o06CGV|YS4sH=o{2bZ8@Y(HG)Q|6-6laD_2N5>H*nLMvp(6dF7pw#bj_u2J zftv2cCiE)^st}F>8d?n|Xouy5nZ>7&M4MvG;j)Q# zr;*Bc52W|Yd-2{oXp6<2;*ZZK8S_eWoF+dZ@jP3C1qzPUKnG~?95L7{z4qePM{LX{ zt|QBK{e>yp^UCQrU!gdI6B5nGSgdY!XBjYutpr_k@rS_Q0eySKP&tC1?R&}p6X-g+ zux|}l2K2W-mMjMe{ntO}Fl)X3I`w4Qo~?M>sGC6 z=N^o66F+-2qqhB(*0Vp_&hNfHrICVVU*Q=()H4W4A zSF=JzEYIJBDv)UIT$@K(@uzI-Nya?}3IF8rZK_J~T3C@o(;e%{suzFH z6taiaD$CR&p*Fo%x3zR!Oa{{T#}VPCt!CRL5!VLH47M+_7y}q9bKl5)*=q`;>TTHS zIR;5Pyd;dcCw%WZwr*x}x_K82Cq(bR!`afV*GVA{j9T~5IrIIthFSnjP1^q;0_#7! z650DLIKz`xN2qr4fecRjBBN(@mnT!$ZklIr{+v~bRx)ZQGR`e=XiuG^l@5+N5Ia5otIo6G(l&G< z%X#kB9>g_gbc{?}8WM)ucmdO7!`iXV%)C<32qDpbYL-fMnl?~vGmkzby9RHc1VvlS>LmU2B|BMOr3LC6$NmK~c zUMxfnUsT91dc=rxR4?EsEt7C*S)^~&vvme~)vTTL3=af3e|-PEIT$)-n;&pgE*JpA zD&Mweiwhudl9u%YAtA`83V z5key@@kBP%jC!``ghQ|_KN&0}S>%tKk-wYKPXUFC=wl%A1ObXhPK?EwSDtiV{wOXzF#P)d z)EiIFK111n8s2wVWGYe(o8z>GG*exLx(EXCcYYuRrD1?a#K108PwL!P!i%8~k5uh)d-$cDv!FWoJ^MTkFT7Kj#ql4J7+AP z_tDhXgo6+hOKV(UN1^qmkllin-%1pry7S3ZJE`!WFV890#8Y3+zf$ox^M;(?F*vHL z^_!Ix=YJ$dgId)cskUtI zyz5u#DUPSMY+I4q?eU82Z+PBI@`(9C{a{(-Eso+qq+s9~>wzKIJy1oBzcUxd;y+51 z{~seVk%fA@46iwtR{PaIhaiH~0JH#SmPQ`}fVzp3Q^MIza#5ijx1iPXs)0>@+vp4%^O550agZ000CLJI6OyY~8BQ5sIY4?U1gTD^fq;nkcmhj5+ zt!Cl<$0!BN*(B5hf6H_3!BI4qw#a=e>aUT8;-CgpZ6QRzqQhL2lJhn_4Lu$mF7_!} zh*}Lipyk2u;$d~kO$CT&^DZaNt)n|ONmy%sPF2rOe$ z_|jMR(`(fVx;5~URcoI(C&qX+SN38KOPPJ@BtVBqV#7|Pl;d1CTb3bskCA6#A zgwWy!p;Scm8=oPGSr9c8gfeZSY%r#$fx`I>YipdJtIkReno(k-*xOTaR7BF6t6D6W zb~1Gp!3m$q_C@vuZ}#_1Ojn(c2_EX>{3H8Hrz}U z+SEUk#}I-+?+utE%@7qB)jpT&p=vXXJ9LfwnqL6R0LYj6NNZ6YZc#86Ynxwz$`eTQ znVDYJVt;sa2Rro@rbtF^?tFP!#*u~s1 zdoNi`{V$N~?tbJuxK*sM7r6b6BdIqVBYQ}*Uy@29qx&Or7LS;J<2!f9Wu*T^lT}t^ zvkAyJ@}s0ZcV%Gw!->`TuIl@9j^oi!Z4Pnbs~fb5-PY>~SY^QCeHsVwryNU^0*J-| z$X^$%7q}<(6%U&N3}qF)juVs!o;mws_u3DOa`uSm=I-R%(#U~k4s`cxkpHQJV&)K6 zj%Wen+(nxGSE&bqgcY^TmC62qcr>X#NK>C;*bu(#rII zdlWhRO|SmR7rjrfXRY*yDQpm_Yf5`VDG_?OQa=t)peckTC@=tak5Y`pRszb>4bQ?_ z0iXyl_&8A(S5zU?dtU(zqO(jFuxePH|7V@rfvi^Pbqy<+me*B8*kB7Qjha9_NTchoz#qiEEUEd zCPk@&md1j?%*u&^r@v%vNJ1TF@+-xqM^ctZeChdcf)iW<(bQ z7;wa{wmz6b(+7D)sE;i1QsavFS+wU&pEjeN-bUoXWGztIk~542x& zqY0ih?l|VC;UnnLU?VWnYD^)xoVV|Fqxqv!sjG&zbUa~*UH{E7TewPMnf!$xz@=Tn zj6^-F)0Selg8#5DevRHh_7@Pkb!6=j^m)e90g9qj7JfUHcdROtZ`c`s@n&za!zAhX z2%%w6m-qkjC^%ka1=k4Np;Fa{qJr5+s-b2|bEplY3%3;)YP5*2%roY!G(>c;}f>qE= zUG*1~qkh}1SX?`049!?{N}#&|5ZJNGJ9kc*LmYSi*=gbJR&3(!SjcI@oLwsZff70= z?u!s>N+%WQK}>}+LT=R;L~0YGYf4oSH|jxn4rsE3tcbZI!FIv_cePvfbr)eYr-sOu zYblh^s#yc{mq!_`^YwmXB1`x!*8layipx$<%zr`j<&?~$-l~==%2Z0OZKUj5S{+LZ zhCKUAMDf*ZaVCTVQ8AS;w~;|5Fk+kg;!6ltcR`#_ksV15OoVdl<|F%Vhu_0}Kzgj) z5OjCynX)mZp-iRl6K9snAx0*Y@$$-JOvBFqD}iwGldAm+D$+{6Bg$EGBB(@hW48Vy zp^I5EOeIss5Jheo2D#Xj{@}bHD_qlHAwXK^U=#6vo%Us^>ALE5X=sgk$xEW$^Pb>w z)k=Ke^zX*_Li-ypfRw}J&ngE@)CY2^kb+r?B-dsXOgQ%W90@$d|MC&Ku}*j-W)`7z zEGYmMoVJEWk)7g-lFe0!B=ICr_*a1`o*C-^5FRMmSKB&z)!ugEXH9+U+Ud}CgbE#&r-%vfS|*!1W&`-y@c_GIEJ7f-cCmB#AxEuQbEHbWq)KEldo0De*v=Q^G5`}tbB{1A`G}I z&+nf|xXYQKTfoInN+tHM`LEH~UJMD$pk04Rtf~IZNJlUG%XU3uB&>40i!$H8dSUmA zDe+edeV2d7Y7T+K0LcS^caHEASO(LN9(|lJPHHTl*~7467uS)26BX*kN03_W z^>9m|6a`rbrw4&s!?8C*2?_>-6_T3yW5esByaiG?(#U5RG)PyVK{NN~JbEyW-Ql88(oWJ6+{+BKjG(-#^aJD!Yf?z*x(dMQS zsYr62=3~nVL1h?q6aa97NirGb(R99X5krH4y(}s;lSM`nrfWEw;57XDu)NSd)TAni z*Q=%-O>K6T1VWedWqX=4g4NPsg5ls^g$HzD+3FguE6>E*q%)qWBxq<43%Cq5mDQYO?sCK~F6Q|NlWuR4)T=g_~^fSnJjw?aLI3XX>QnlStH)|v{cI2Z4=&f{w5P4X$_Q-;PiSAZ;pCCGN*aapF(7Wb9SZe*@VZdQ%>7@2Fz*Fp z2!mR+iC|31Dw^Bo;W4kbSQEM|r$j%VZD3~qed2tEAdi6ntMXw)bydX{(Q$DGzlybp z_b9#skb81#{cD21LwL*9zXM|P_`cMVL!fZR6}xl3|M*$!-rOB0s7soyE(j@D@SuZo z{RY(Jd7%oC;|%W%@?3oH%AiO1AT=2rgmlT2VI93GLyMHs*SnULby!6)LCw>$@?~i} zntP>w<2jUn9(*6>}N)h6@e7oc%AQ;C+ev!h!te|g0$PIy0 z;s5>Vx_s5a>ifTu>K!8UuguWG7&|>kzFeUihT}>78pzGMbp6M9yE$jCgjP<=~s;;D1d*!wUXkVoq!lpGIKoSOFh5qBM=R zhw+mnCM%vOHO;UpaD4oLfmte3T+KBFh)5vHbxnztx2&|RWk)J1g__g2&B0L=ety&Cb3!(yTOXmajY5TiQNnyUTiwj>K~p>MCSB<{ z8XcvEabPf;IoFES`5RFrWKdSlL#!|KXJLp-zgM6c{9-ox*PZA(3|!gsV{m7zQDKvN>J&spl=S#IXj^O zeY84TMq13y&iBum{CvazueYy?ilb}V9bh0>aMwYC1{f?19^Bnsl0bmq!C`QBhhQN< zu;3cp-Q5}7EkJNM^M3N5bNAn!TD|&euin+QYfE=kJ&!XnBm=2bR|r)_diq97boT5{ zma%JpiO7${)R=m6kj~87DJ;wsfhf`7(rGUz%E!LY_+j7qsm{hx3s;XHB1BKi)LVS$ zS^HP|^b#p5Y=C(s%2OKwi*s)qLPIV)e@@}uBV zeW8{0l51z3jfpzGrsVcpB1x>P)dZ67)jD_2H*0-=07W3yRjSA^#k6u*GYh4*cjhl1 zHYrK%l9Eb8_ViI}yOl;URa^*;-?toE+Kl{Hvz-XA9`M#S#82i%C(%QJnf4E+qMZ+| zQL9@rGTlMx%w;JF_drAxqF(VLO?B+l#T`w$+=V}@jxjAtk-U28Qs*@X6e|G%1}}F>qCV#| zzR&yiEiW4~k6T*?m^}IXRygm%O-jSQbb3GIDXmVpGOo1wWUN2^y&3sdIx~wy~bdS`%dh>2E^YZbRNhm~c%kxX4Mb3qfImHoQ_WJGX^Pj!n zkzga2HQs5a6jYy%nGY?+(%|~H?q6@I*>-(T*YUoNwlQpfmgw@DtHt_fr6qJ-5ww4S zc_yRKlj~LM0p#YdH4Ac8_nWhG$(gjG(?eyT|n(wlWP|3=&S2r@ksO#-)V;XL_)Ko&HF@{sBmg&%`t!U}hbg#ePRI z)+PuB>Qo^kpAmBdMI%YX0(m(b&dN%h$JT7*-nle4zN6#`bF~{o!Z_6IY&Kqd-76Bg zRQN90ib>PiJPZ}3`tm*NhNz6}YJdR$EP9@xFZ7b5?*tiz|mdE1jQhpdKt^m|kLrrONNTi_mtnsbJW03yC#q0+57;h86{&&`1|} z_SS8hHxjHcNP^giFpmgX#1;K#9fE*1fr&T-{Y9t0LSMszNMt$H%V3+$T+4@Sq;oa_ zpN|B;e0%qaEUW}(iq&lq2+1!BBI!gAqtgW1+|!EBKicA`sjJVOdA?4z(#J)7-`iTf z_zOVSCmV%;C>tlZvkMcq^F-3)=DbnNc+E_Is42&p3j~^x$Y=&HNSVV?Bi_HB5o0|? z2H*E4HM@_|Hha+d@}TE+bdR(|ir?b9_&ruH2J(`X`jX za+pJ&cE@hae(Ve>J_p62I7uL(spq7-J0-mcM9UO|bc)Cx#ss=4@$lm1=61dpJ8ddQ z=PdvI{|p3QW(wbc$PkcaI5jf;4EluqEr)<) z+;;f0iQjHD{PCxGk1doLndcKY*Rw|`@M{pX6GE8(>D3Peon9lb#-Ss0 zO^rb|w|`WY+3pEV8xA)$u-)?g4kOn}4rk%Mbj~arjL0x*GCbabr_RtvCBw`+`6n?u zDHZdRI4urk{ayN`XLCP)JAeC&2NVY!sve|H5I^HdI>w{iC|JuXw%r3gx7#h79T^!3 z4Z+^^+iDY)@^QFSS<7%%>2c=>F;h~;;Cai50f68y;Lb`*B8qh@D+ed`>vMg-t&a^y zMB%ExF&~POkm58)b?3#ASOGYwtzn}?CnXo7&f-_JxhCsCpB38f>nhHBIfTd8*X~(G zpC?t^H>YIo`sUk5jMaZg_QVR4O;|t2!;xQ^yG9XKiP9#D0?+TGGYs4Q;Bk202pYO? zB1EBaAiT|+qq~BoGet;uKf;48+Srb6mDxpmI4PiTGm`zAq%JsrP!z8P-7LOHmW}?v zLdmjopXZEms(?AWX=IskXaqQ>;UM+HQ7OU-kOQ|NXukZQ_>)7y8D7Df^p&6W%V7mw zSi{*ZG&jvQ4h+LgvoA_vh9VT&LwN}3YsZ)BwEFkYm#$RLaD&Z+^6$1N%}F>bbhW;< zGY8%jo!Ajw5bh%+(~;H7Fj{gRsUmhaGH}#h&q6jaM{TaLsKjBZ#n zcHFwo@P7QDa(Oo{EE5+l!yz&P4>_UPtv2;uAKAmE>Ymv{G;lBO#Pqni3yGFziO_6B zo*uak+q~2JUk2BHA4$KKG`qbyF0TZ@BK%F4>bso8qN6LGT7 zpVu9 zWAzKiwLE$snnO3penF|bbZuxRVEaA)qP(AH_W;80+HmGha%-?r0@>(W$+kNA7bK@%IH zvcy8%v)Ei-Mvy+)lr&)7a^b1#;=GgFd;LY)#*o8AD3o|S$5dTq0w4n~L(s#?p|n0s z;QG$bFV-79p5uD4@g#$Z!socL>A`aaD8{*pWwBpx$-_t>&p3j(xuW}vG6akw6h(&>hTU+ri@=){DX?C-_8# zfBW<)xQEeapgIwhBF(SmGt)4o6Qkuw3zlSgH8d@rx`h6-G2Z&BE$$G~0SaPrDTXGu zO%c2NI^_K9B%5Pd;EU*Z5Sl_LqT|ins;$@;&a5kC;(=8x60B`aZ!G_;RhP`4UvWr% zQ2O*RxJKG6t1fBwcw>BX?8y`wALd2N!1BxM#|C<#`R0q6`On|}#AuAxrXUn^Q+kq& z-%RlI*3|C)AGC3 zr@Q!S?hca531$|5IDd?ul_CF7?PT*aJ_Xy6A8Tvz2!^GFCC7lIdCHS%wcZN&-?O{<)oU-u3hwtY>ubjv|F`Ru~XUIk~Udgiv8EQbkr zuMt-Hp@I-0vZ1nmK_qcW;Hdy+j{CvL?_p!@*-|^U5-XsM2~!yNcg9(rhK=9HR7X46 z0Af{4!7*x|MF~&(JSWuJd@3b*UsIluU1wI@hR)5h5y6vJ^w;JvQ;0j@Cy25!z`{h{ z)AraJ`dwzrRgbkUx?jx(W1Ra|0&~ksiaGj#LQL$s5JW-(q=0?pTCFwpF4>CYJrgjPh*0Pv>RV z5}>Pj2(rw|Z4Ev_2wE|jo_4ag+=o2lyrq%f{IL2+ktnI2E&9;1^*BT^eWN;BvD*-F zN6K&wlP*v%{)MOD;J5YizB6&DNXh|0|GmLIcq36obZfO?eeZd?&||Oc@{4Fy@5Tu^ zPZozWjIkH~H=uC+*6ECvL*xa~vYrZXgmVT^4IPbUFb=cd zJ6?3hdPrtn=Q^U)DsZE_X=ku^DX1Q6#EXZr3;s2&DzuHl4S6V7(dLV*dLnhic@K_5 z-c1x|d=MxvXDwhPzp?x#L^Liomx=33$4_8ReUh|8_ zI6hT%T6d=X8rtBBQ;f;3?OZ#iIfZg3Hkr2Z`1k>Gwg}W;QYwa8Fd~|W87&DNd9zob z&N_HWd^Wb-aUTZi4tz-WzRX@s_xMtET=>a(3^v2F&b|CON-tm|MFv#qjT%x-Oz$#r zI^z+IZY=Y|{G8VKyeT9h?ORT-4Ovr2er<_vYSHLU{{8h+qi8-&nMh|w?Wj$TRjP1! zLW*+2$!O_##z|_(!MiyH?(QVEZ~XPviW#tPb)V)flO@;frwpf6IwsiLN1m@EE(6pC z2FEi5^b|Ga{@M?4Y&U$nv|-NYWgp{?YR5$dK4W`c1vp?E!E|YV-UVVnazE6LmFjSi zkduG->>gKRsZwpmHp9xD6#XNTx3;{8bLNN>&FCukfD7Zz58Yc{V$N%iZ;aSETwGjT z9dm4cTqebr7sHqpjG`B2*5CAbe;OXs#eBe`7U|kmLVB)XsVhO!3#9dcvn8K)lc55? z2Lq7psiw5AU1K~i=S#zD3HMLSizk2Go&3pJI4Wv;yq4>Cjs41Gw4J(2O}QPK&>8$F z4y9>-55htHxSwu6mTZzMqsM-z*5jYsYS`lNjk{2}(j%{P|1I*xbh=rYRF8R?`*f@; zI{!!MXE(fDlo`?_kv3?l!^4=c>+#x{|AtseByZceraO;F=V&uF#CJzvk0aLUt$VFz&->IYja1*@ds4l5 zXFzm;Zr#gWWZBd=*{iaAb~&pZahgJ`uV&Z3L=VI(+`s0FpP)5-;GaH^91 z+PW)1H$+0P2K&tTOrJrJJ3UHCZBo|l!8?KROmI+n4qgy$@$$DOJK14%3YllVpm7tD zK9QJ$vF$`E3H$)W)%g8l*>dCjlClV_a8j;WMyWNMiFy0dnNq=#y z7g{^gRWC?VmuH6GMv5Y+dn)`sn7>wT^uvFCBkl)`>Co$8=t*$y-#lvTEC6~q5Pa5*f*Csl3 zp_+yW2>rg$h%k4FearD!K16MRBZOllh=idq zX=yJSD1%bf=kU0(UVXeobzct+ATKu(-wvKGG+|`YV@lPlElOR>R@PqiMhZm<_4sto zWZ%X)IJv>y;{G|#j0F9WcK0=ckU%RwPW&^bJTl@b!NUJew!* zA^n9p&=JKD6;7`m%oFLj8<026?vy1F1%~hhxnLa$NpMhi7xEIIgPk7fKUpsR_F{}y z;=Q`6uQ?gc*-^+@9Vufa#$S?aVT1kZT|Ov~2>m#8_4f4R(+QvR4e{ybJ)uI?+Elx} zXyP7z2zHM77akS$D2T`(lsh>HpBcXp52DBfDaF5r8-6RvMxl7AWh+!4Sqp_pbbwQv zVV;~f>%OAhp`o~lZ7)v`=|VcN?Lm#lZ5eDomtSoMKDBN<)2bPrgy{4d9tq;{Jj`2$ z5pIY)XC#hTeCK!&j_| zUpMg3Luzp`B4DjqJ{ zYcHq4`GYhR6f}_7l^PFx&I(#>MVfQg#{;oN`i2OH8?RFcYwPCB=<{LfT}(2A0WL94 zhoscP<5lr=6hb^bznwkiDhwpfW`)0gt)E!XRlz|w7oyCv1)>B@Oz>A^LGZaGBrn3o-dct+?24w6Do0~Jt6Uq5T%hw{ICNMxdLuhd0(ohfG9~-cLs+Z@?%HVI-7HCI6YT zCDvLp9gfU@P=c(8(_1$kd!V z;B#6I%;Q2HYa{SolRyH=}hMkJ3exc}-9{<;;WRigtD35QR3%ryY9UbKo z;)ZAOz5!Z7RR>;d0}L~fklq-W52vU&Z4cQSR?gVG9GOudrKsp8W%( zVq&=NcS%Fw@J78uT3^R~u?t$Z?u@(^L@V350`n^D>5Ozn>DY*i2K(~o5(FZhv2ba0 zQgh?n!rcEKPns>Eho$Ylt|_UQ?(k9}kfJZZL-gw|j9F^JjNuyd=<(7wAX}_<;VvA@ zENE>_#;5D&e;mT0)_p*D_vIGn>B)=K_lV62p5eb*pAvG8z%^RkqI17)G?JIt zODRl*fE(4nDXQNKinGU8u9=~?-PBc=zlFanJ^C8XHv1K3FO8j1-M?-Xj%<859iOZ- zr3&Q0zDV`=xiaLCee4^g^32--osG8TWSv%ILLu^G8;kZj3BWV;+-(5~FV?LSAoI>wVb}vc0}W z<>KoOj zlHcyQBj`blnIW_)D&1MRUH|+A7iZX};whO<#-u=3NS=j;I|{8hDKyoX1mqG!3V(xy zK@DX*>mwUdO3J*dVj>~GK=kevRubSA!dqm)&Tj_Vj$dyHR7CH1vM~6x=Y~IW5kyKw z1P4(Hx`Hp}n2zRs;$p@aGFjtzX>uVHaX;Wy7610bVz(j9-k?YYsBhQyL}hF%;MAO^ zPYR#$%pw3WkPwLhlpH7j8-TzSjw9fp3+S3KwH41qyI}Ay8qmyrU;mRdBP3s>1A}mr z24rqQdEwklg^5M?$pKA`VzagP?&BE2Qu_Ruo!5nPK$a$EaV*63Sm~erM6dZ&dza&Q zT`8d&Vwb^ep;~idT92)2y!lrs=W5Y?;`E$YxD${=q?AhRsL?Z8> z3qAM&|6198v)*|T;}J*_D&{bT7m9G#wY|RB97xO@!xXc%e$({RO`0>KaT|mi7`F|h z$rk?sr%}U8czFk-hN)e^#IQHTIDRm4u#A*XUqj8SzD$OBsm6)4U_Ta-{%k5Hy`PHZ zGm0wZ4fH2y{0_qGe*hP4X7X^h>4VefOYW?N!m|4f<-y&P2 zqX|tGfVSjk8A*VDx){D60xST$w6OlFxvAHC`+;@+{K$U(x7Q67pYQrB!b8p9&U;kE z?Q47E-Q-{9Vz@W3(BJDr(IWpdALNG{9-~=^d>=Kxr~5keU1gQCI+IZUW7U&@w+Jg=h2 zf~%ddu%w?KZaB(~n#E_>GKBL$hB2Y|eNmC=O^*to|5$n|mELlUp9VN24(b)~W)&RiNz#beHnLUQJx(Y8* zrqHUZ5$(4YDAZv1L1(iQ84LTxw8Vf)sAW8{F!s0OC2_fN>qsLR>58L2eLiI;dqbeo zKgU|QYhEqVw_0ovnZUq{&iH8%Lh0efAH7!m{C&mRX)WMI*-!aRH+C2u+qwjb!5!%% z{On+U&Ad_KVAI$74ZqoQdVwfxJ}1g~hy zaw=X1cD*~rqq=|QOfyu%F;|Iew`-)~=hA_$sDVP}i0=q6_jYy2oH;qs3H?y!w0QmBR)%svSWCyHu|a zt|4lZnm1yq-PId!}Nxyhfr( zaRxcr+^1BZT+>L6fEo!ryFd5_VVeC)5pl|~E}Bo_VPM(7%8ufP3jy2!-2T6fs7PVY zZH`gmvB;4hmC;J^SzG_4q^I>)-FX#02$zc=M5E0F!fTuV5hB@Frn>0q;d;5`ud}f^ zjJy@QzqLmWHB@+=y&L-_iny@8ZfWa78KqGLMEx#LQH0p><0c~kpzQM#%BbSuABF7O zcM${tozs0dH?GlA>7Z}|NIq!jhW$%qBe9xe_61f#CBtuc%J1|;qTTF8!4xM{RIYH+ zSp=-BVToTGYj{>QBS0Lg5%Uqm$>D>demKy}Kk{f4*cs+Xd|Px}-sW-X-^c5V9BOOV zcQuzq%vxGH{u5VnCggiQ$LN#$@;}fN|B@m$@`US4%k-YBUI*uzyXmFf3K(EviJ4>C zTkuDU+05HPkn-S&1@q;C+-38vcuUUM^(*C)md66;XG1~TARI*wkutr}^FPA`nfW{-t%Fe58?ydHy zTRMLf?;J6_$wfOgc6h&J5pk{_)(;jrv?It`yU_BD8~=;tG84S!*A|Fn8P k@iM;#{$Jbwe{DbkY-{&(woHIM{L`(Rl(J;GxM{%u0a}9kZU6uP diff --git a/cairo/kakarot-ssj/scripts/compare_snapshot.py b/cairo/kakarot-ssj/scripts/compare_snapshot.py index e8c4c83eb..fa725cb71 100644 --- a/cairo/kakarot-ssj/scripts/compare_snapshot.py +++ b/cairo/kakarot-ssj/scripts/compare_snapshot.py @@ -2,8 +2,6 @@ import logging import os import re - -# trunk-ignore(bandit/B404) import subprocess import tempfile import zipfile @@ -42,7 +40,6 @@ def get_previous_snapshot(): # Fetch the list of workflow runs cmd = f"curl -s -H 'Authorization: token {GITHUB_TOKEN}' -H 'Accept: application/vnd.github.v3+json' 'https://api.github.com/repos/{REPO}/actions/runs?branch=main&per_page=100'" - # trunk-ignore(bandit/B602) result = subprocess.check_output(cmd, shell=True) runs = json.loads(result) @@ -63,7 +60,6 @@ def get_previous_snapshot(): # Fetch the artifacts for that run run_id = latest_successful_run["id"] cmd = f"curl -s -H 'Authorization: token {GITHUB_TOKEN}' -H 'Accept: application/vnd.github.v3+json' 'https://api.github.com/repos/{REPO}/actions/runs/{run_id}/artifacts'" - # trunk-ignore(bandit/B602) result = subprocess.check_output(cmd, shell=True) artifacts = json.loads(result) @@ -85,7 +81,6 @@ def get_previous_snapshot(): archive_name = temp_dir / "gas_snapshot.zip" cmd = f"curl -s -L -o {archive_name} -H 'Authorization: token {GITHUB_TOKEN}' -H 'Accept: application/vnd.github.v3+json' '{snapshot_artifact['archive_download_url']}'" - # trunk-ignore(bandit/B602) subprocess.check_call(cmd, shell=True) with zipfile.ZipFile(archive_name, "r") as archive: archive.extractall(temp_dir) @@ -95,8 +90,6 @@ def get_previous_snapshot(): def get_current_gas_snapshot(): """Execute command and return current gas snapshots.""" - # trunk-ignore(bandit/B602) - # trunk-ignore(bandit/B607) output = subprocess.check_output("scarb test", shell=True).decode("utf-8") pattern = r"test ([\w\:]+).*gas usage est\.\: (\d+)" matches = re.findall(pattern, output) diff --git a/cairo/kakarot-ssj/scripts/filter_tests.py b/cairo/kakarot-ssj/scripts/filter_tests.py index 0463df14c..6247e703a 100644 --- a/cairo/kakarot-ssj/scripts/filter_tests.py +++ b/cairo/kakarot-ssj/scripts/filter_tests.py @@ -27,9 +27,6 @@ def replace_func(match): full_match = match.group(0) func_name = match.group(1) - - - if filter_string.lower() in func_name.lower(): return full_match else: diff --git a/cairo/kakarot-ssj/scripts/gen_snapshot.py b/cairo/kakarot-ssj/scripts/gen_snapshot.py index 1e36f133c..b7b545e6b 100644 --- a/cairo/kakarot-ssj/scripts/gen_snapshot.py +++ b/cairo/kakarot-ssj/scripts/gen_snapshot.py @@ -1,12 +1,8 @@ import json import re - -# trunk-ignore(bandit/B404) import subprocess # Execute the command and capture the output -# trunk-ignore(bandit/B602) -# trunk-ignore(bandit/B607) output = subprocess.check_output("scarb cairo-test", shell=True).decode("utf-8") # Use regex to capture test names and their associated gas usage From f412117beffb8745036881ed3f6ba6081c1f9fa9 Mon Sep 17 00:00:00 2001 From: Oba Date: Thu, 3 Oct 2024 11:40:29 +0200 Subject: [PATCH 43/56] fix: npm audit fix --- cairo/kakarot-ssj/bun.lockb | Bin 48666 -> 50891 bytes cairo/kakarot-ssj/package-lock.json | 850 +++++++++++++++++++++++++++- cairo/kakarot-ssj/package.json | 6 +- 3 files changed, 837 insertions(+), 19 deletions(-) diff --git a/cairo/kakarot-ssj/bun.lockb b/cairo/kakarot-ssj/bun.lockb index 3a0d4b4921e98b571370bcbc8b21c638de9aa551..ad0e905376435dee0e72792ba66365f4e506394e 100755 GIT binary patch delta 11205 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 diff --git a/cairo/kakarot-ssj/package-lock.json b/cairo/kakarot-ssj/package-lock.json index d17076994..a5570a15c 100644 --- a/cairo/kakarot-ssj/package-lock.json +++ b/cairo/kakarot-ssj/package-lock.json @@ -7,10 +7,13 @@ "name": "kakarot-ssj", "dependencies": { "@ethereumjs/tx": "^5.0.0", + "@types/inquirer": "^9.0.7", "dotenv": "^16.3.1", "ethers": "^6.8.1", + "inquirer": "^9.2.12", "rlp": "^3.0.0", - "starknet": "^5.19.5" + "starknet": "^5.19.5", + "viem": "^2.21.17" }, "devDependencies": { "bun-types": "latest" @@ -20,9 +23,10 @@ } }, "node_modules/@adraffy/ens-normalize": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz", - "integrity": "sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==" + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz", + "integrity": "sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==", + "license": "MIT" }, "node_modules/@ethereumjs/common": { "version": "4.1.0", @@ -86,6 +90,15 @@ } } }, + "node_modules/@inquirer/figures": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.6.tgz", + "integrity": "sha512-yfZzps3Cso2UbM7WlxKwZQh2Hs6plrbjs1QnzQDZhK2DgyCo6D8AaHps9olkNcUFlcYERMqU3uJSp1gmy3s/qQ==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/@noble/curves": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz", @@ -109,9 +122,10 @@ } }, "node_modules/@scure/base": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.3.tgz", - "integrity": "sha512-/+SgoRjLq7Xlf0CWuLHq2LUZeL/w65kfzAPG5NH9pcmBhs+nunQTn4gvdwgMTIXnt9b2C/1SeL2XiysZEyIC9Q==", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", + "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", + "license": "MIT", "funding": { "url": "https://paulmillr.com/funding/" } @@ -178,22 +192,264 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/@types/inquirer": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/@types/inquirer/-/inquirer-9.0.7.tgz", + "integrity": "sha512-Q0zyBupO6NxGRZut/JdmqYKOnN95Eg5V8Csg3PGKkP+FnvsUZx1jAyK7fztIszxxMuoBA6E3KXWvdZVXIpx60g==", + "license": "MIT", + "dependencies": { + "@types/through": "*", + "rxjs": "^7.2.0" + } + }, "node_modules/@types/node": { "version": "18.15.13", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.13.tgz", "integrity": "sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==" }, + "node_modules/@types/through": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/through/-/through-0.0.33.tgz", + "integrity": "sha512-HsJ+z3QuETzP3cswwtzt2vEIiHBk/dCcHGhbmG5X3ecnwFD/lPrMpliGXxSCg03L9AhrdwA4Oz/qfspkDW+xGQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/abitype": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.0.5.tgz", + "integrity": "sha512-YzDhti7cjlfaBhHutMaboYB21Ha3rXR9QTkNJFzYC4kC8YclaiwPBBBJY8ejFdu2wnJeZCVZSMlQJ7fi8S6hsw==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/wevm" + }, + "peerDependencies": { + "typescript": ">=5.0.4", + "zod": "^3 >=3.22.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + }, + "zod": { + "optional": true + } + } + }, "node_modules/aes-js": { "version": "4.0.0-beta.5", "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz", "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==" }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, "node_modules/bun-types": { "version": "1.0.14", "resolved": "https://registry.npmjs.org/bun-types/-/bun-types-1.0.14.tgz", "integrity": "sha512-hLVfM2fk8xSJeobfuPGilfvxM5gLtEy1bn7RJhrtw3u4OaC0kieXKYFFTVHU8jZ3hj8YyPLIFClIUodkFSrMBQ==", "dev": true }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "license": "MIT" + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "license": "ISC", + "engines": { + "node": ">= 12" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, "node_modules/crc": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/crc/-/crc-4.3.2.tgz", @@ -210,6 +466,18 @@ } } }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/dotenv": { "version": "16.3.1", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", @@ -221,6 +489,12 @@ "url": "https://github.com/motdotla/dotenv?sponsor=1" } }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, "node_modules/ethereum-cryptography": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.1.2.tgz", @@ -233,9 +507,9 @@ } }, "node_modules/ethers": { - "version": "6.8.1", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.8.1.tgz", - "integrity": "sha512-iEKm6zox5h1lDn6scuRWdIdFJUCGg3+/aQWu0F4K0GVyEZiktFkqrJbRjTn1FlYEPz7RKA707D6g5Kdk6j7Ljg==", + "version": "6.13.3", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.13.3.tgz", + "integrity": "sha512-/DzbZOLVtoO4fKvvQwpEucHAQgIwBGWuRvBdwE/lMXgXvvHHTSkn7XqAQ2b+gjJzZDJjWA9OD05bVceVOsBHbg==", "funding": [ { "type": "individual", @@ -246,14 +520,15 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "dependencies": { - "@adraffy/ens-normalize": "1.10.0", + "@adraffy/ens-normalize": "1.10.1", "@noble/curves": "1.2.0", "@noble/hashes": "1.3.2", "@types/node": "18.15.13", "aes-js": "4.0.0-beta.5", "tslib": "2.4.0", - "ws": "8.5.0" + "ws": "8.17.1" }, "engines": { "node": ">=14.0.0" @@ -281,6 +556,120 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "license": "MIT", + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/inquirer": { + "version": "9.3.7", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.3.7.tgz", + "integrity": "sha512-LJKFHCSeIRq9hanN14IlOtPSTe3lNES7TYDTE2xxdAy1LS5rYphajK1qtwvj3YmQXvvk0U2Vbmcni8P9EIQW9w==", + "license": "MIT", + "dependencies": { + "@inquirer/figures": "^1.0.3", + "ansi-escapes": "^4.3.2", + "cli-width": "^4.1.0", + "external-editor": "^3.1.0", + "mute-stream": "1.0.0", + "ora": "^5.4.1", + "run-async": "^3.0.0", + "rxjs": "^7.8.1", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/isomorphic-fetch": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", @@ -290,11 +679,60 @@ "whatwg-fetch": "^3.4.1" } }, + "node_modules/isows": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/isows/-/isows-1.0.4.tgz", + "integrity": "sha512-hEzjY+x9u9hPmBom9IIAqdJCwNLax+xrPb51vEPpERoFlIxgmZcHzsT5jKG06nvInKOBGvReAVz80Umed5CczQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wagmi-dev" + } + ], + "license": "MIT", + "peerDependencies": { + "ws": "*" + } + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/lossless-json": { "version": "2.0.11", "resolved": "https://registry.npmjs.org/lossless-json/-/lossless-json-2.0.11.tgz", "integrity": "sha512-BP0vn+NGYvzDielvBZaFain/wgeJ1hTvURCqtKvhr1SCPePdaaTanmmcplrHfEJSJOUql7hk4FHwToNJjWRY3g==" }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/mute-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", + "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", @@ -314,11 +752,85 @@ } } }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/pako": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==" }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/rlp": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/rlp/-/rlp-3.0.0.tgz", @@ -327,6 +839,56 @@ "rlp": "bin/rlp" } }, + "node_modules/run-async": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", + "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC" + }, "node_modules/starknet": { "version": "5.24.3", "resolved": "https://registry.npmjs.org/starknet/-/starknet-5.24.3.tgz", @@ -363,6 +925,65 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "license": "MIT", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", @@ -373,6 +994,18 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/typescript": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.2.tgz", @@ -391,6 +1024,164 @@ "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/viem": { + "version": "2.21.17", + "resolved": "https://registry.npmjs.org/viem/-/viem-2.21.17.tgz", + "integrity": "sha512-YtqH0JZxmxQ4KBzXFwIe2EMFydlb8oOcwYnXgnNNOTy5nryEVkEO3Dbf7/VzFOIVsatr778i+QbUtSO60bKGkw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], + "license": "MIT", + "dependencies": { + "@adraffy/ens-normalize": "1.10.0", + "@noble/curves": "1.4.0", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.4.0", + "abitype": "1.0.5", + "isows": "1.0.4", + "webauthn-p256": "0.0.5", + "ws": "8.17.1" + }, + "peerDependencies": { + "typescript": ">=5.0.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/viem/node_modules/@adraffy/ens-normalize": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz", + "integrity": "sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==", + "license": "MIT" + }, + "node_modules/viem/node_modules/@noble/curves": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.0.tgz", + "integrity": "sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/viem/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/viem/node_modules/@scure/bip32": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", + "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", + "license": "MIT", + "dependencies": { + "@noble/curves": "~1.4.0", + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/viem/node_modules/@scure/bip39": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.4.0.tgz", + "integrity": "sha512-BEEm6p8IueV/ZTfQLp/0vhw4NPnT9oWf5+28nvmeUICjP99f4vr2d+qc7AVGDDtwRep6ifR43Yed9ERVmiITzw==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "~1.5.0", + "@scure/base": "~1.1.8" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/viem/node_modules/@scure/bip39/node_modules/@noble/hashes": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.5.0.tgz", + "integrity": "sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/webauthn-p256": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/webauthn-p256/-/webauthn-p256-0.0.5.tgz", + "integrity": "sha512-drMGNWKdaixZNobeORVIqq7k5DsRC9FnG201K2QjeOoQLmtSDaSsVZdkg6n5jUALJKcAG++zBPJXmv6hy0nWFg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], + "license": "MIT", + "dependencies": { + "@noble/curves": "^1.4.0", + "@noble/hashes": "^1.4.0" + } + }, + "node_modules/webauthn-p256/node_modules/@noble/curves": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.6.0.tgz", + "integrity": "sha512-TlaHRXDehJuRNR9TfZDNQ45mMEd5dwUwmicsafcIX4SsNiqnCHKjE/1alYPd/lDRVhxdhUAlv8uEhMCI5zjIJQ==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.5.0" + }, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/webauthn-p256/node_modules/@noble/hashes": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.5.0.tgz", + "integrity": "sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", @@ -410,16 +1201,31 @@ "webidl-conversions": "^3.0.0" } }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/ws": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", - "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "license": "MIT", "engines": { "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { @@ -429,6 +1235,18 @@ "optional": true } } + }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz", + "integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/cairo/kakarot-ssj/package.json b/cairo/kakarot-ssj/package.json index 6b1f6bed4..25687aee3 100644 --- a/cairo/kakarot-ssj/package.json +++ b/cairo/kakarot-ssj/package.json @@ -9,13 +9,13 @@ }, "dependencies": { "@ethereumjs/tx": "^5.0.0", + "@types/inquirer": "^9.0.7", "dotenv": "^16.3.1", "ethers": "^6.8.1", - "rlp": "^3.0.0", - "@types/inquirer": "^9.0.7", "inquirer": "^9.2.12", + "rlp": "^3.0.0", "starknet": "^5.19.5", - "viem": "^1.19.8" + "viem": "^2.21.17" }, "scripts": { "compute_starknet_address": "bun run scripts/compute_starknet_address.ts", From a71b7900ffdad90fc40e592618453aeb312e06ac Mon Sep 17 00:00:00 2001 From: Oba Date: Thu, 3 Oct 2024 11:51:53 +0200 Subject: [PATCH 44/56] ci: merge trunk workflows --- .github/workflows/ssj-trunk-check.yaml | 31 ------------------- ...zero-trunk-check.yaml => trunk-check.yaml} | 4 +-- 2 files changed, 2 insertions(+), 33 deletions(-) delete mode 100644 .github/workflows/ssj-trunk-check.yaml rename .github/workflows/{cairo-zero-trunk-check.yaml => trunk-check.yaml} (89%) diff --git a/.github/workflows/ssj-trunk-check.yaml b/.github/workflows/ssj-trunk-check.yaml deleted file mode 100644 index ec0864d84..000000000 --- a/.github/workflows/ssj-trunk-check.yaml +++ /dev/null @@ -1,31 +0,0 @@ -name: SSJ-Trunk - -on: [pull_request] - -concurrency: - group: ssj-${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -permissions: read-all - -jobs: - trunk_check: - name: Trunk Check Runner - runs-on: ubuntu-latest - permissions: - checks: write # For trunk to post annotations - contents: read # For repo checkout - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Set up Python 3.10.14 - uses: actions/setup-python@v5 - with: - python-version: 3.10.14 - cache: pip - - run: pip install cairo-lang==0.13.1 sympy==1.11.1 - - - name: Trunk Check - uses: trunk-io/trunk-action@v1 diff --git a/.github/workflows/cairo-zero-trunk-check.yaml b/.github/workflows/trunk-check.yaml similarity index 89% rename from .github/workflows/cairo-zero-trunk-check.yaml rename to .github/workflows/trunk-check.yaml index 872ee6d27..0adad3aa0 100644 --- a/.github/workflows/cairo-zero-trunk-check.yaml +++ b/.github/workflows/trunk-check.yaml @@ -1,9 +1,9 @@ -name: cairo-zero-Trunk +name: Trunk on: [pull_request] concurrency: - group: cairo-zero-${{ github.workflow }}-${{ github.ref }} + group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true permissions: read-all From b371b7e814f8b2a1cd3f3abf50b7d74a5cdfc7bc Mon Sep 17 00:00:00 2001 From: Oba Date: Thu, 3 Oct 2024 17:39:26 +0200 Subject: [PATCH 45/56] refactor: move cairo_zero unit tests --- .github/workflows/cairo-zero-ci.yml | 2 +- .../workflows/cairo-zero-nightly-fuzzing.yml | 2 +- Makefile | 23 +++++++++++++++---- cairo/kakarot-ssj/Makefile | 19 --------------- cairo_zero/tests/conftest.py | 12 ++++++++++ .../tests}/src/backend/test_starknet.cairo | 0 .../tests}/src/backend/test_starknet.py | 0 {tests => cairo_zero/tests}/src/conftest.py | 0 .../tests}/src/kakarot/__init__.py | 0 .../accounts/test_account_contract.cairo | 0 .../kakarot/accounts/test_account_contract.py | 0 .../instructions/test_block_information.cairo | 0 .../instructions/test_block_information.py | 0 .../test_duplication_operations.cairo | 0 .../test_duplication_operations.py | 0 .../test_environmental_information.cairo | 0 .../test_environmental_information.py | 0 .../test_exchange_operations.cairo | 0 .../instructions/test_exchange_operations.py | 0 .../instructions/test_memory_operations.cairo | 0 .../instructions/test_memory_operations.py | 0 .../instructions/test_push_operations.cairo | 0 .../instructions/test_push_operations.py | 0 .../test_stop_and_math_operations.cairo | 0 .../test_stop_and_math_operations.py | 0 .../kakarot/precompiles/test_blake2f.cairo | 0 .../src/kakarot/precompiles/test_blake2f.py | 0 .../kakarot/precompiles/test_datacopy.cairo | 0 .../src/kakarot/precompiles/test_datacopy.py | 0 .../kakarot/precompiles/test_ec_recover.cairo | 0 .../kakarot/precompiles/test_ec_recover.py | 0 .../precompiles/test_precompiles.cairo | 0 .../kakarot/precompiles/test_precompiles.py | 0 .../kakarot/precompiles/test_ripemd160.cairo | 0 .../src/kakarot/precompiles/test_ripemd160.py | 0 .../src/kakarot/precompiles/test_sha256.cairo | 0 .../src/kakarot/precompiles/test_sha256.py | 0 .../tests}/src/kakarot/test_account.cairo | 0 .../tests}/src/kakarot/test_account.py | 0 .../tests}/src/kakarot/test_evm.cairo | 0 .../tests}/src/kakarot/test_evm.py | 0 .../tests}/src/kakarot/test_gas.cairo | 0 .../tests}/src/kakarot/test_gas.py | 0 .../tests}/src/kakarot/test_kakarot.cairo | 0 .../tests}/src/kakarot/test_kakarot.py | 0 .../tests}/src/kakarot/test_memory.cairo | 0 .../tests}/src/kakarot/test_memory.py | 0 .../tests}/src/kakarot/test_stack.cairo | 0 .../tests}/src/kakarot/test_stack.py | 0 .../tests}/src/kakarot/test_state.cairo | 0 .../tests}/src/kakarot/test_state.py | 0 .../tests}/src/utils/test_array.cairo | 0 .../tests}/src/utils/test_array.py | 0 .../tests}/src/utils/test_bytes.cairo | 0 .../tests}/src/utils/test_bytes.py | 0 .../tests}/src/utils/test_dict.cairo | 0 .../tests}/src/utils/test_dict.py | 0 .../src/utils/test_eth_transaction.cairo | 0 .../tests}/src/utils/test_eth_transaction.py | 0 .../tests}/src/utils/test_rlp.cairo | 0 .../tests}/src/utils/test_rlp.py | 0 .../tests}/src/utils/test_uint256.cairo | 0 .../tests}/src/utils/test_uint256.py | 0 .../tests}/src/utils/test_utils.cairo | 0 .../tests}/src/utils/test_utils.py | 0 kakarot_scripts/constants.py | 6 +++-- kakarot_scripts/utils/starknet.py | 8 ++++--- pyproject.toml | 6 ++++- tests/fixtures/__init__.py | 0 tests/utils/__init__.py | 0 70 files changed, 47 insertions(+), 31 deletions(-) delete mode 100644 cairo/kakarot-ssj/Makefile create mode 100644 cairo_zero/tests/conftest.py rename {tests => cairo_zero/tests}/src/backend/test_starknet.cairo (100%) rename {tests => cairo_zero/tests}/src/backend/test_starknet.py (100%) rename {tests => cairo_zero/tests}/src/conftest.py (100%) rename {tests => cairo_zero/tests}/src/kakarot/__init__.py (100%) rename {tests => cairo_zero/tests}/src/kakarot/accounts/test_account_contract.cairo (100%) rename {tests => cairo_zero/tests}/src/kakarot/accounts/test_account_contract.py (100%) rename {tests => cairo_zero/tests}/src/kakarot/instructions/test_block_information.cairo (100%) rename {tests => cairo_zero/tests}/src/kakarot/instructions/test_block_information.py (100%) rename {tests => cairo_zero/tests}/src/kakarot/instructions/test_duplication_operations.cairo (100%) rename {tests => cairo_zero/tests}/src/kakarot/instructions/test_duplication_operations.py (100%) rename {tests => cairo_zero/tests}/src/kakarot/instructions/test_environmental_information.cairo (100%) rename {tests => cairo_zero/tests}/src/kakarot/instructions/test_environmental_information.py (100%) rename {tests => cairo_zero/tests}/src/kakarot/instructions/test_exchange_operations.cairo (100%) rename {tests => cairo_zero/tests}/src/kakarot/instructions/test_exchange_operations.py (100%) rename {tests => cairo_zero/tests}/src/kakarot/instructions/test_memory_operations.cairo (100%) rename {tests => cairo_zero/tests}/src/kakarot/instructions/test_memory_operations.py (100%) rename {tests => cairo_zero/tests}/src/kakarot/instructions/test_push_operations.cairo (100%) rename {tests => cairo_zero/tests}/src/kakarot/instructions/test_push_operations.py (100%) rename {tests => cairo_zero/tests}/src/kakarot/instructions/test_stop_and_math_operations.cairo (100%) rename {tests => cairo_zero/tests}/src/kakarot/instructions/test_stop_and_math_operations.py (100%) rename {tests => cairo_zero/tests}/src/kakarot/precompiles/test_blake2f.cairo (100%) rename {tests => cairo_zero/tests}/src/kakarot/precompiles/test_blake2f.py (100%) rename {tests => cairo_zero/tests}/src/kakarot/precompiles/test_datacopy.cairo (100%) rename {tests => cairo_zero/tests}/src/kakarot/precompiles/test_datacopy.py (100%) rename {tests => cairo_zero/tests}/src/kakarot/precompiles/test_ec_recover.cairo (100%) rename {tests => cairo_zero/tests}/src/kakarot/precompiles/test_ec_recover.py (100%) rename {tests => cairo_zero/tests}/src/kakarot/precompiles/test_precompiles.cairo (100%) rename {tests => cairo_zero/tests}/src/kakarot/precompiles/test_precompiles.py (100%) rename {tests => cairo_zero/tests}/src/kakarot/precompiles/test_ripemd160.cairo (100%) rename {tests => cairo_zero/tests}/src/kakarot/precompiles/test_ripemd160.py (100%) rename {tests => cairo_zero/tests}/src/kakarot/precompiles/test_sha256.cairo (100%) rename {tests => cairo_zero/tests}/src/kakarot/precompiles/test_sha256.py (100%) rename {tests => cairo_zero/tests}/src/kakarot/test_account.cairo (100%) rename {tests => cairo_zero/tests}/src/kakarot/test_account.py (100%) rename {tests => cairo_zero/tests}/src/kakarot/test_evm.cairo (100%) rename {tests => cairo_zero/tests}/src/kakarot/test_evm.py (100%) rename {tests => cairo_zero/tests}/src/kakarot/test_gas.cairo (100%) rename {tests => cairo_zero/tests}/src/kakarot/test_gas.py (100%) rename {tests => cairo_zero/tests}/src/kakarot/test_kakarot.cairo (100%) rename {tests => cairo_zero/tests}/src/kakarot/test_kakarot.py (100%) rename {tests => cairo_zero/tests}/src/kakarot/test_memory.cairo (100%) rename {tests => cairo_zero/tests}/src/kakarot/test_memory.py (100%) rename {tests => cairo_zero/tests}/src/kakarot/test_stack.cairo (100%) rename {tests => cairo_zero/tests}/src/kakarot/test_stack.py (100%) rename {tests => cairo_zero/tests}/src/kakarot/test_state.cairo (100%) rename {tests => cairo_zero/tests}/src/kakarot/test_state.py (100%) rename {tests => cairo_zero/tests}/src/utils/test_array.cairo (100%) rename {tests => cairo_zero/tests}/src/utils/test_array.py (100%) rename {tests => cairo_zero/tests}/src/utils/test_bytes.cairo (100%) rename {tests => cairo_zero/tests}/src/utils/test_bytes.py (100%) rename {tests => cairo_zero/tests}/src/utils/test_dict.cairo (100%) rename {tests => cairo_zero/tests}/src/utils/test_dict.py (100%) rename {tests => cairo_zero/tests}/src/utils/test_eth_transaction.cairo (100%) rename {tests => cairo_zero/tests}/src/utils/test_eth_transaction.py (100%) rename {tests => cairo_zero/tests}/src/utils/test_rlp.cairo (100%) rename {tests => cairo_zero/tests}/src/utils/test_rlp.py (100%) rename {tests => cairo_zero/tests}/src/utils/test_uint256.cairo (100%) rename {tests => cairo_zero/tests}/src/utils/test_uint256.py (100%) rename {tests => cairo_zero/tests}/src/utils/test_utils.cairo (100%) rename {tests => cairo_zero/tests}/src/utils/test_utils.py (100%) create mode 100644 tests/fixtures/__init__.py create mode 100644 tests/utils/__init__.py diff --git a/.github/workflows/cairo-zero-ci.yml b/.github/workflows/cairo-zero-ci.yml index 98413d8b1..bf3a4b43e 100644 --- a/.github/workflows/cairo-zero-ci.yml +++ b/.github/workflows/cairo-zero-ci.yml @@ -98,7 +98,7 @@ jobs: - name: Run tests env: HYPOTHESIS_PROFILE: ci - run: make test-unit + run: make test-unit-cairo-zero - name: Upload coverage report to codecov uses: codecov/codecov-action@v3 with: diff --git a/.github/workflows/cairo-zero-nightly-fuzzing.yml b/.github/workflows/cairo-zero-nightly-fuzzing.yml index c1cbcac83..506b9acf6 100644 --- a/.github/workflows/cairo-zero-nightly-fuzzing.yml +++ b/.github/workflows/cairo-zero-nightly-fuzzing.yml @@ -30,7 +30,7 @@ jobs: - name: Run tests env: HYPOTHESIS_PROFILE: nightly - run: make test-unit + run: make test-unit-cairo-zero - name: Upload coverage report to codecov uses: codecov/codecov-action@v3 with: diff --git a/Makefile b/Makefile index a73d5946a..72eef65dc 100644 --- a/Makefile +++ b/Makefile @@ -28,12 +28,27 @@ fetch-ef-tests: setup: uv sync --all-extras --dev -test: deploy - uv run pytest tests/src -m "not NoCI" --log-cli-level=INFO -n logical --seed 42 +test-cairo-zero: deploy + uv run pytest cairo_zero/tests/src -m "not NoCI" --log-cli-level=INFO -n logical --seed 42 uv run pytest tests/end_to_end --seed 42 -test-unit: build-sol - uv run pytest tests/src -m "not NoCI" -n logical --seed 42 +test-unit-cairo-zero: build-sol + uv run pytest cairo_zero/tests/src -m "not NoCI" -n logical --seed 42 + +test-unit-cairo: + @PACKAGE="$(word 2,$(MAKECMDGOALS))" && \ + FILTER="$(word 3,$(MAKECMDGOALS))" && cd cairo/kakarot-ssj && \ + if [ -z "$$PACKAGE" ] && [ -z "$$FILTER" ]; then \ + scarb test; \ + elif [ -n "$$PACKAGE" ] && [ -z "$$FILTER" ]; then \ + scarb test -p $$PACKAGE; \ + elif [ -n "$$PACKAGE" ] && [ -n "$$FILTER" ]; then \ + uv run scripts/run_filtered_tests.py $$PACKAGE $$FILTER; \ + else \ + echo "Usage: make test-unit-cairo [PACKAGE] [FILTER]"; \ + exit 1; \ + fi + test-end-to-end: deploy uv run pytest tests/end_to_end --seed 42 diff --git a/cairo/kakarot-ssj/Makefile b/cairo/kakarot-ssj/Makefile deleted file mode 100644 index c69fc0ec1..000000000 --- a/cairo/kakarot-ssj/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -install: - bash scripts/install_hook.sh - -test-unit: - @PACKAGE="$(word 2,$(MAKECMDGOALS))" && \ - FILTER="$(word 3,$(MAKECMDGOALS))" && \ - if [ -z "$$PACKAGE" ] && [ -z "$$FILTER" ]; then \ - scarb test; \ - elif [ -n "$$PACKAGE" ] && [ -z "$$FILTER" ]; then \ - scarb test -p $$PACKAGE; \ - elif [ -n "$$PACKAGE" ] && [ -n "$$FILTER" ]; then \ - uv run scripts/run_filtered_tests.py $$PACKAGE $$FILTER; \ - else \ - echo "Usage: make test-unit [PACKAGE] [FILTER]"; \ - exit 1; \ - fi - -%: - @: diff --git a/cairo_zero/tests/conftest.py b/cairo_zero/tests/conftest.py new file mode 100644 index 000000000..302f817e7 --- /dev/null +++ b/cairo_zero/tests/conftest.py @@ -0,0 +1,12 @@ +import sys +import os +from pathlib import Path + +# Add the project root to the Python path +project_root = Path(__file__).resolve().parent.parent.parent +sys.path.insert(0, str(project_root)) + +# Import everything from the root conftest.py +from tests.conftest import * +from tests.fixtures import * +from tests.utils import * diff --git a/tests/src/backend/test_starknet.cairo b/cairo_zero/tests/src/backend/test_starknet.cairo similarity index 100% rename from tests/src/backend/test_starknet.cairo rename to cairo_zero/tests/src/backend/test_starknet.cairo diff --git a/tests/src/backend/test_starknet.py b/cairo_zero/tests/src/backend/test_starknet.py similarity index 100% rename from tests/src/backend/test_starknet.py rename to cairo_zero/tests/src/backend/test_starknet.py diff --git a/tests/src/conftest.py b/cairo_zero/tests/src/conftest.py similarity index 100% rename from tests/src/conftest.py rename to cairo_zero/tests/src/conftest.py diff --git a/tests/src/kakarot/__init__.py b/cairo_zero/tests/src/kakarot/__init__.py similarity index 100% rename from tests/src/kakarot/__init__.py rename to cairo_zero/tests/src/kakarot/__init__.py diff --git a/tests/src/kakarot/accounts/test_account_contract.cairo b/cairo_zero/tests/src/kakarot/accounts/test_account_contract.cairo similarity index 100% rename from tests/src/kakarot/accounts/test_account_contract.cairo rename to cairo_zero/tests/src/kakarot/accounts/test_account_contract.cairo diff --git a/tests/src/kakarot/accounts/test_account_contract.py b/cairo_zero/tests/src/kakarot/accounts/test_account_contract.py similarity index 100% rename from tests/src/kakarot/accounts/test_account_contract.py rename to cairo_zero/tests/src/kakarot/accounts/test_account_contract.py diff --git a/tests/src/kakarot/instructions/test_block_information.cairo b/cairo_zero/tests/src/kakarot/instructions/test_block_information.cairo similarity index 100% rename from tests/src/kakarot/instructions/test_block_information.cairo rename to cairo_zero/tests/src/kakarot/instructions/test_block_information.cairo diff --git a/tests/src/kakarot/instructions/test_block_information.py b/cairo_zero/tests/src/kakarot/instructions/test_block_information.py similarity index 100% rename from tests/src/kakarot/instructions/test_block_information.py rename to cairo_zero/tests/src/kakarot/instructions/test_block_information.py diff --git a/tests/src/kakarot/instructions/test_duplication_operations.cairo b/cairo_zero/tests/src/kakarot/instructions/test_duplication_operations.cairo similarity index 100% rename from tests/src/kakarot/instructions/test_duplication_operations.cairo rename to cairo_zero/tests/src/kakarot/instructions/test_duplication_operations.cairo diff --git a/tests/src/kakarot/instructions/test_duplication_operations.py b/cairo_zero/tests/src/kakarot/instructions/test_duplication_operations.py similarity index 100% rename from tests/src/kakarot/instructions/test_duplication_operations.py rename to cairo_zero/tests/src/kakarot/instructions/test_duplication_operations.py diff --git a/tests/src/kakarot/instructions/test_environmental_information.cairo b/cairo_zero/tests/src/kakarot/instructions/test_environmental_information.cairo similarity index 100% rename from tests/src/kakarot/instructions/test_environmental_information.cairo rename to cairo_zero/tests/src/kakarot/instructions/test_environmental_information.cairo diff --git a/tests/src/kakarot/instructions/test_environmental_information.py b/cairo_zero/tests/src/kakarot/instructions/test_environmental_information.py similarity index 100% rename from tests/src/kakarot/instructions/test_environmental_information.py rename to cairo_zero/tests/src/kakarot/instructions/test_environmental_information.py diff --git a/tests/src/kakarot/instructions/test_exchange_operations.cairo b/cairo_zero/tests/src/kakarot/instructions/test_exchange_operations.cairo similarity index 100% rename from tests/src/kakarot/instructions/test_exchange_operations.cairo rename to cairo_zero/tests/src/kakarot/instructions/test_exchange_operations.cairo diff --git a/tests/src/kakarot/instructions/test_exchange_operations.py b/cairo_zero/tests/src/kakarot/instructions/test_exchange_operations.py similarity index 100% rename from tests/src/kakarot/instructions/test_exchange_operations.py rename to cairo_zero/tests/src/kakarot/instructions/test_exchange_operations.py diff --git a/tests/src/kakarot/instructions/test_memory_operations.cairo b/cairo_zero/tests/src/kakarot/instructions/test_memory_operations.cairo similarity index 100% rename from tests/src/kakarot/instructions/test_memory_operations.cairo rename to cairo_zero/tests/src/kakarot/instructions/test_memory_operations.cairo diff --git a/tests/src/kakarot/instructions/test_memory_operations.py b/cairo_zero/tests/src/kakarot/instructions/test_memory_operations.py similarity index 100% rename from tests/src/kakarot/instructions/test_memory_operations.py rename to cairo_zero/tests/src/kakarot/instructions/test_memory_operations.py diff --git a/tests/src/kakarot/instructions/test_push_operations.cairo b/cairo_zero/tests/src/kakarot/instructions/test_push_operations.cairo similarity index 100% rename from tests/src/kakarot/instructions/test_push_operations.cairo rename to cairo_zero/tests/src/kakarot/instructions/test_push_operations.cairo diff --git a/tests/src/kakarot/instructions/test_push_operations.py b/cairo_zero/tests/src/kakarot/instructions/test_push_operations.py similarity index 100% rename from tests/src/kakarot/instructions/test_push_operations.py rename to cairo_zero/tests/src/kakarot/instructions/test_push_operations.py diff --git a/tests/src/kakarot/instructions/test_stop_and_math_operations.cairo b/cairo_zero/tests/src/kakarot/instructions/test_stop_and_math_operations.cairo similarity index 100% rename from tests/src/kakarot/instructions/test_stop_and_math_operations.cairo rename to cairo_zero/tests/src/kakarot/instructions/test_stop_and_math_operations.cairo diff --git a/tests/src/kakarot/instructions/test_stop_and_math_operations.py b/cairo_zero/tests/src/kakarot/instructions/test_stop_and_math_operations.py similarity index 100% rename from tests/src/kakarot/instructions/test_stop_and_math_operations.py rename to cairo_zero/tests/src/kakarot/instructions/test_stop_and_math_operations.py diff --git a/tests/src/kakarot/precompiles/test_blake2f.cairo b/cairo_zero/tests/src/kakarot/precompiles/test_blake2f.cairo similarity index 100% rename from tests/src/kakarot/precompiles/test_blake2f.cairo rename to cairo_zero/tests/src/kakarot/precompiles/test_blake2f.cairo diff --git a/tests/src/kakarot/precompiles/test_blake2f.py b/cairo_zero/tests/src/kakarot/precompiles/test_blake2f.py similarity index 100% rename from tests/src/kakarot/precompiles/test_blake2f.py rename to cairo_zero/tests/src/kakarot/precompiles/test_blake2f.py diff --git a/tests/src/kakarot/precompiles/test_datacopy.cairo b/cairo_zero/tests/src/kakarot/precompiles/test_datacopy.cairo similarity index 100% rename from tests/src/kakarot/precompiles/test_datacopy.cairo rename to cairo_zero/tests/src/kakarot/precompiles/test_datacopy.cairo diff --git a/tests/src/kakarot/precompiles/test_datacopy.py b/cairo_zero/tests/src/kakarot/precompiles/test_datacopy.py similarity index 100% rename from tests/src/kakarot/precompiles/test_datacopy.py rename to cairo_zero/tests/src/kakarot/precompiles/test_datacopy.py diff --git a/tests/src/kakarot/precompiles/test_ec_recover.cairo b/cairo_zero/tests/src/kakarot/precompiles/test_ec_recover.cairo similarity index 100% rename from tests/src/kakarot/precompiles/test_ec_recover.cairo rename to cairo_zero/tests/src/kakarot/precompiles/test_ec_recover.cairo diff --git a/tests/src/kakarot/precompiles/test_ec_recover.py b/cairo_zero/tests/src/kakarot/precompiles/test_ec_recover.py similarity index 100% rename from tests/src/kakarot/precompiles/test_ec_recover.py rename to cairo_zero/tests/src/kakarot/precompiles/test_ec_recover.py diff --git a/tests/src/kakarot/precompiles/test_precompiles.cairo b/cairo_zero/tests/src/kakarot/precompiles/test_precompiles.cairo similarity index 100% rename from tests/src/kakarot/precompiles/test_precompiles.cairo rename to cairo_zero/tests/src/kakarot/precompiles/test_precompiles.cairo diff --git a/tests/src/kakarot/precompiles/test_precompiles.py b/cairo_zero/tests/src/kakarot/precompiles/test_precompiles.py similarity index 100% rename from tests/src/kakarot/precompiles/test_precompiles.py rename to cairo_zero/tests/src/kakarot/precompiles/test_precompiles.py diff --git a/tests/src/kakarot/precompiles/test_ripemd160.cairo b/cairo_zero/tests/src/kakarot/precompiles/test_ripemd160.cairo similarity index 100% rename from tests/src/kakarot/precompiles/test_ripemd160.cairo rename to cairo_zero/tests/src/kakarot/precompiles/test_ripemd160.cairo diff --git a/tests/src/kakarot/precompiles/test_ripemd160.py b/cairo_zero/tests/src/kakarot/precompiles/test_ripemd160.py similarity index 100% rename from tests/src/kakarot/precompiles/test_ripemd160.py rename to cairo_zero/tests/src/kakarot/precompiles/test_ripemd160.py diff --git a/tests/src/kakarot/precompiles/test_sha256.cairo b/cairo_zero/tests/src/kakarot/precompiles/test_sha256.cairo similarity index 100% rename from tests/src/kakarot/precompiles/test_sha256.cairo rename to cairo_zero/tests/src/kakarot/precompiles/test_sha256.cairo diff --git a/tests/src/kakarot/precompiles/test_sha256.py b/cairo_zero/tests/src/kakarot/precompiles/test_sha256.py similarity index 100% rename from tests/src/kakarot/precompiles/test_sha256.py rename to cairo_zero/tests/src/kakarot/precompiles/test_sha256.py diff --git a/tests/src/kakarot/test_account.cairo b/cairo_zero/tests/src/kakarot/test_account.cairo similarity index 100% rename from tests/src/kakarot/test_account.cairo rename to cairo_zero/tests/src/kakarot/test_account.cairo diff --git a/tests/src/kakarot/test_account.py b/cairo_zero/tests/src/kakarot/test_account.py similarity index 100% rename from tests/src/kakarot/test_account.py rename to cairo_zero/tests/src/kakarot/test_account.py diff --git a/tests/src/kakarot/test_evm.cairo b/cairo_zero/tests/src/kakarot/test_evm.cairo similarity index 100% rename from tests/src/kakarot/test_evm.cairo rename to cairo_zero/tests/src/kakarot/test_evm.cairo diff --git a/tests/src/kakarot/test_evm.py b/cairo_zero/tests/src/kakarot/test_evm.py similarity index 100% rename from tests/src/kakarot/test_evm.py rename to cairo_zero/tests/src/kakarot/test_evm.py diff --git a/tests/src/kakarot/test_gas.cairo b/cairo_zero/tests/src/kakarot/test_gas.cairo similarity index 100% rename from tests/src/kakarot/test_gas.cairo rename to cairo_zero/tests/src/kakarot/test_gas.cairo diff --git a/tests/src/kakarot/test_gas.py b/cairo_zero/tests/src/kakarot/test_gas.py similarity index 100% rename from tests/src/kakarot/test_gas.py rename to cairo_zero/tests/src/kakarot/test_gas.py diff --git a/tests/src/kakarot/test_kakarot.cairo b/cairo_zero/tests/src/kakarot/test_kakarot.cairo similarity index 100% rename from tests/src/kakarot/test_kakarot.cairo rename to cairo_zero/tests/src/kakarot/test_kakarot.cairo diff --git a/tests/src/kakarot/test_kakarot.py b/cairo_zero/tests/src/kakarot/test_kakarot.py similarity index 100% rename from tests/src/kakarot/test_kakarot.py rename to cairo_zero/tests/src/kakarot/test_kakarot.py diff --git a/tests/src/kakarot/test_memory.cairo b/cairo_zero/tests/src/kakarot/test_memory.cairo similarity index 100% rename from tests/src/kakarot/test_memory.cairo rename to cairo_zero/tests/src/kakarot/test_memory.cairo diff --git a/tests/src/kakarot/test_memory.py b/cairo_zero/tests/src/kakarot/test_memory.py similarity index 100% rename from tests/src/kakarot/test_memory.py rename to cairo_zero/tests/src/kakarot/test_memory.py diff --git a/tests/src/kakarot/test_stack.cairo b/cairo_zero/tests/src/kakarot/test_stack.cairo similarity index 100% rename from tests/src/kakarot/test_stack.cairo rename to cairo_zero/tests/src/kakarot/test_stack.cairo diff --git a/tests/src/kakarot/test_stack.py b/cairo_zero/tests/src/kakarot/test_stack.py similarity index 100% rename from tests/src/kakarot/test_stack.py rename to cairo_zero/tests/src/kakarot/test_stack.py diff --git a/tests/src/kakarot/test_state.cairo b/cairo_zero/tests/src/kakarot/test_state.cairo similarity index 100% rename from tests/src/kakarot/test_state.cairo rename to cairo_zero/tests/src/kakarot/test_state.cairo diff --git a/tests/src/kakarot/test_state.py b/cairo_zero/tests/src/kakarot/test_state.py similarity index 100% rename from tests/src/kakarot/test_state.py rename to cairo_zero/tests/src/kakarot/test_state.py diff --git a/tests/src/utils/test_array.cairo b/cairo_zero/tests/src/utils/test_array.cairo similarity index 100% rename from tests/src/utils/test_array.cairo rename to cairo_zero/tests/src/utils/test_array.cairo diff --git a/tests/src/utils/test_array.py b/cairo_zero/tests/src/utils/test_array.py similarity index 100% rename from tests/src/utils/test_array.py rename to cairo_zero/tests/src/utils/test_array.py diff --git a/tests/src/utils/test_bytes.cairo b/cairo_zero/tests/src/utils/test_bytes.cairo similarity index 100% rename from tests/src/utils/test_bytes.cairo rename to cairo_zero/tests/src/utils/test_bytes.cairo diff --git a/tests/src/utils/test_bytes.py b/cairo_zero/tests/src/utils/test_bytes.py similarity index 100% rename from tests/src/utils/test_bytes.py rename to cairo_zero/tests/src/utils/test_bytes.py diff --git a/tests/src/utils/test_dict.cairo b/cairo_zero/tests/src/utils/test_dict.cairo similarity index 100% rename from tests/src/utils/test_dict.cairo rename to cairo_zero/tests/src/utils/test_dict.cairo diff --git a/tests/src/utils/test_dict.py b/cairo_zero/tests/src/utils/test_dict.py similarity index 100% rename from tests/src/utils/test_dict.py rename to cairo_zero/tests/src/utils/test_dict.py diff --git a/tests/src/utils/test_eth_transaction.cairo b/cairo_zero/tests/src/utils/test_eth_transaction.cairo similarity index 100% rename from tests/src/utils/test_eth_transaction.cairo rename to cairo_zero/tests/src/utils/test_eth_transaction.cairo diff --git a/tests/src/utils/test_eth_transaction.py b/cairo_zero/tests/src/utils/test_eth_transaction.py similarity index 100% rename from tests/src/utils/test_eth_transaction.py rename to cairo_zero/tests/src/utils/test_eth_transaction.py diff --git a/tests/src/utils/test_rlp.cairo b/cairo_zero/tests/src/utils/test_rlp.cairo similarity index 100% rename from tests/src/utils/test_rlp.cairo rename to cairo_zero/tests/src/utils/test_rlp.cairo diff --git a/tests/src/utils/test_rlp.py b/cairo_zero/tests/src/utils/test_rlp.py similarity index 100% rename from tests/src/utils/test_rlp.py rename to cairo_zero/tests/src/utils/test_rlp.py diff --git a/tests/src/utils/test_uint256.cairo b/cairo_zero/tests/src/utils/test_uint256.cairo similarity index 100% rename from tests/src/utils/test_uint256.cairo rename to cairo_zero/tests/src/utils/test_uint256.cairo diff --git a/tests/src/utils/test_uint256.py b/cairo_zero/tests/src/utils/test_uint256.py similarity index 100% rename from tests/src/utils/test_uint256.py rename to cairo_zero/tests/src/utils/test_uint256.py diff --git a/tests/src/utils/test_utils.cairo b/cairo_zero/tests/src/utils/test_utils.cairo similarity index 100% rename from tests/src/utils/test_utils.cairo rename to cairo_zero/tests/src/utils/test_utils.cairo diff --git a/tests/src/utils/test_utils.py b/cairo_zero/tests/src/utils/test_utils.py similarity index 100% rename from tests/src/utils/test_utils.py rename to cairo_zero/tests/src/utils/test_utils.py diff --git a/kakarot_scripts/constants.py b/kakarot_scripts/constants.py index 038a61423..676cc59ef 100644 --- a/kakarot_scripts/constants.py +++ b/kakarot_scripts/constants.py @@ -220,13 +220,15 @@ class ChainId(IntEnum): ) CAIRO_ZERO_DIR = Path("cairo_zero") CAIRO_DIR = Path("cairo") -TESTS_DIR = Path("tests") +TESTS_DIR_CAIRO_ZERO = Path("cairo_zero/tests") +TESTS_DIR_END_TO_END = Path("tests") CONTRACTS = { p.stem: p for p in ( list(CAIRO_ZERO_DIR.glob("**/*.cairo")) - + list(TESTS_DIR.glob("**/*.cairo")) + + list(TESTS_DIR_CAIRO_ZERO.glob("**/*.cairo")) + + list(TESTS_DIR_END_TO_END.glob("**/*.cairo")) + [x for x in list(CAIRO_DIR.glob("**/*.cairo")) if "kakarot-ssj" not in str(x)] ) } diff --git a/kakarot_scripts/utils/starknet.py b/kakarot_scripts/utils/starknet.py index aef217e78..a52e55965 100644 --- a/kakarot_scripts/utils/starknet.py +++ b/kakarot_scripts/utils/starknet.py @@ -249,9 +249,11 @@ def get_artifact(contract_name): return Artifact(sierra=None, casm=artifacts[0]) # Cairo 1 artifacts - artifacts = list(CAIRO_DIR.glob(f"**/*{contract_name}.*.json")) or list( - BUILD_DIR_SSJ.glob(f"**/*{contract_name}.*.json") - ) + artifacts = [ + artifact + for artifact in list(CAIRO_DIR.glob(f"**/*{contract_name}.*.json")) + if "test" not in str(artifact) + ] or list(BUILD_DIR_SSJ.glob(f"**/*{contract_name}.*.json")) if artifacts: sierra, casm = ( artifacts diff --git a/pyproject.toml b/pyproject.toml index f5adb40b8..7926d72fa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -67,6 +67,10 @@ filterwarnings = [ "ignore:abi:DeprecationWarning", # from web3 "ignore::marshmallow.warnings.RemovedInMarshmallow4Warning", # from marshmallow ] +pythonpath = [ + ".", + "tests" +] asyncio_mode = "auto" markers = [ "ArithmeticOperations", @@ -191,7 +195,7 @@ check-filenames = '' check-hidden = '' [tool.bandit] -exclude_dirs = ["tests"] +exclude_dirs = ["tests", "cairo_zero/tests"] [build-system] requires = ["hatchling"] diff --git a/tests/fixtures/__init__.py b/tests/fixtures/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/utils/__init__.py b/tests/utils/__init__.py new file mode 100644 index 000000000..e69de29bb From b36e8caa95af5b29e81a9ddbe2804e5ec3f6815f Mon Sep 17 00:00:00 2001 From: Oba Date: Fri, 4 Oct 2024 11:22:39 +0200 Subject: [PATCH 46/56] update SSJ --- .gitignore | 2 + Makefile | 2 +- .../contracts/tests/test_kakarot_core.cairo | 45 ++- .../evm/src/backend/starknet_backend.cairo | 68 +++- .../crates/snforge_utils/src/lib.cairo | 24 +- .../utils/src/eth_transaction/legacy.cairo | 57 +++ .../src/eth_transaction/transaction.cairo | 49 +-- .../crates/utils/src/traits/bytes.cairo | 238 +++++------- .../crates/utils/src/traits/integer.cairo | 351 +++++++++++++++++- .../scripts/compute_rlp_encoding.ts | 6 +- cairo/kakarot-ssj/scripts/filter_tests.py | 1 - .../kakarot-ssj/scripts/run_filtered_tests.py | 41 +- .../kakarot-ssj/scripts/setup_cairo_native.sh | 1 + 13 files changed, 663 insertions(+), 222 deletions(-) diff --git a/.gitignore b/.gitignore index 9669a74f8..1a0132793 100644 --- a/.gitignore +++ b/.gitignore @@ -53,3 +53,5 @@ cairo/kakarot-ssj/target cairo/kakarot-ssj/cache/ cairo/kakarot-ssj/scripts/libcairo_native_runtime.a cairo/kakarot-ssj/scripts/__pycache__ +cairo/kakarot-ssj/*__pycache__ +cairo/kakarot-ssj/*.snfoundry diff --git a/Makefile b/Makefile index 72eef65dc..eda68b149 100644 --- a/Makefile +++ b/Makefile @@ -43,7 +43,7 @@ test-unit-cairo: elif [ -n "$$PACKAGE" ] && [ -z "$$FILTER" ]; then \ scarb test -p $$PACKAGE; \ elif [ -n "$$PACKAGE" ] && [ -n "$$FILTER" ]; then \ - uv run scripts/run_filtered_tests.py $$PACKAGE $$FILTER; \ + uv run scripts/run_filtered_tests.py scarb test -p $$PACKAGE $$FILTER; \ else \ echo "Usage: make test-unit-cairo [PACKAGE] [FILTER]"; \ exit 1; \ diff --git a/cairo/kakarot-ssj/crates/contracts/tests/test_kakarot_core.cairo b/cairo/kakarot-ssj/crates/contracts/tests/test_kakarot_core.cairo index 89bcde981..45fde481f 100644 --- a/cairo/kakarot-ssj/crates/contracts/tests/test_kakarot_core.cairo +++ b/cairo/kakarot-ssj/crates/contracts/tests/test_kakarot_core.cairo @@ -18,7 +18,7 @@ use evm::test_utils::chain_id; use evm::test_utils; use snforge_std::{ declare, DeclareResultTrait, start_cheat_caller_address, spy_events, EventSpyTrait, - cheat_caller_address, CheatSpan, store + cheat_caller_address, CheatSpan, store, load }; use snforge_utils::snforge_utils::{EventsFilterBuilderTrait, ContractEventsTrait}; use starknet::storage::StorageTrait; @@ -159,6 +159,49 @@ fn test_kakarot_core_upgrade_contract() { assert(version == 1, 'version is not 1'); } +#[test] +fn test_kakarot_core_get_starknet_address() { + let (_, kakarot_core) = contract_utils::setup_contracts_for_testing(); + let mut kakarot_state = KakarotCore::unsafe_new_contract_state(); + + let registered_evm_address = test_utils::evm_address(); + let registered_starknet_address = test_utils::starknet_address(); + let registered_map_entry_address = kakarot_state + .snapshot_deref() + .storage() + .Kakarot_evm_to_starknet_address + .entry(registered_evm_address) + .deref() + .__storage_pointer_address__; + // store the registered address in the mapping + store( + kakarot_core.contract_address, + registered_map_entry_address.into(), + [registered_starknet_address.into()].span() + ); + // when the address is registered in the mapping, it's returned + assert_eq!( + kakarot_core.get_starknet_address(registered_evm_address), registered_starknet_address + ); + + let unregistered_evm_address = test_utils::other_evm_address(); + let unregistered_map_entry_address = kakarot_state + .snapshot_deref() + .storage() + .Kakarot_evm_to_starknet_address + .entry(unregistered_evm_address) + .deref() + .__storage_pointer_address__; + let map_data = load(kakarot_core.contract_address, unregistered_map_entry_address.into(), 1); + // when the map entry is empty + assert_eq!(*map_data[0], 0); + // then an unregistered address should return the same as compute_starknet_address + assert_eq!( + kakarot_core.get_starknet_address(unregistered_evm_address), + kakarot_core.compute_starknet_address(unregistered_evm_address) + ); +} + #[test] fn test_eth_send_transaction_non_deploy_tx() { // Given diff --git a/cairo/kakarot-ssj/crates/evm/src/backend/starknet_backend.cairo b/cairo/kakarot-ssj/crates/evm/src/backend/starknet_backend.cairo index 52a0de60c..c5db6215f 100644 --- a/cairo/kakarot-ssj/crates/evm/src/backend/starknet_backend.cairo +++ b/cairo/kakarot-ssj/crates/evm/src/backend/starknet_backend.cairo @@ -244,18 +244,23 @@ fn commit_storage(ref self: State) -> Result<(), EVMError> { #[cfg(test)] mod tests { - use core::starknet::ClassHash; + use core::starknet::{ClassHash}; use crate::backend::starknet_backend; - use crate::model::Address; use crate::model::account::Account; + use crate::model::{Address, Event}; use crate::state::{State, StateTrait}; use crate::test_utils::{ setup_test_environment, uninitialized_account, account_contract, register_account }; use crate::test_utils::{evm_address}; - use snforge_std::{test_address, start_mock_call, get_class_hash}; - use snforge_utils::snforge_utils::{assert_not_called, assert_called}; - use super::commit_storage; + use snforge_std::{ + test_address, start_mock_call, get_class_hash, spy_events, EventSpyTrait, + Event as StarknetEvent + }; + use snforge_utils::snforge_utils::{ + assert_not_called, assert_called, EventsFilterBuilderTrait, ContractEventsTrait + }; + use super::{commit_storage, emit_events}; use utils::helpers::compute_starknet_address; use utils::traits::bytes::U8SpanExTrait; @@ -274,6 +279,18 @@ mod tests { } } + // Implementation to convert an `Event` into a serialized `StarknetEvent` + impl EventIntoStarknetEvent of Into { + fn into(self: Event) -> StarknetEvent { + let mut serialized_keys = array![]; + let mut serialized_data = array![]; + Serde::>::serialize(@self.keys, ref serialized_keys); + Serde::>::serialize(@self.data, ref serialized_data); + StarknetEvent { keys: serialized_keys, data: serialized_data } + } + } + + mod test_commit_storage { use snforge_std::start_mock_call; use snforge_utils::snforge_utils::{assert_called_with, assert_not_called}; @@ -479,6 +496,47 @@ mod tests { assert_called(starknet_address, selector!("set_code_hash")); assert_called(starknet_address, selector!("set_nonce")); } + + #[test] + fn test_emit_events() { + // Initialize the state + let mut state: State = Default::default(); + + // Prepare a list of events with different combinations of keys and data + let evm_events = array![ + Event { keys: array![], data: array![] }, // Empty event + Event { keys: array![1.into()], data: array![2, 3] }, // Single key, multiple data + Event { + keys: array![4.into(), 5.into()], data: array![6] + }, // Multiple keys, single data + Event { + keys: array![7.into(), 8.into(), 9.into()], data: array![10, 11, 12, 13] + } // Multiple keys and data + ]; + + // Add each event to the state + for event in evm_events.clone() { + state.add_event(event); + }; + + // Emit the events and assert that no events are left in the state + let mut spy = spy_events(); + emit_events(ref state).expect('emit events failed'); + assert!(state.events.is_empty()); + + // Capture emitted events + let contract_events = EventsFilterBuilderTrait::from_events(@spy.get_events()) + .with_contract_address(test_address()) + .build(); + + // Assert that each original event was emitted as expected + for event in evm_events { + let starknet_event = EventIntoStarknetEvent::into( + event + ); // Convert to StarkNet event format + contract_events.assert_emitted(@starknet_event); + }; + } } // #[test] // #[ignore] diff --git a/cairo/kakarot-ssj/crates/snforge_utils/src/lib.cairo b/cairo/kakarot-ssj/crates/snforge_utils/src/lib.cairo index 0588fe66c..eba213ef3 100644 --- a/cairo/kakarot-ssj/crates/snforge_utils/src/lib.cairo +++ b/cairo/kakarot-ssj/crates/snforge_utils/src/lib.cairo @@ -150,7 +150,7 @@ pub mod snforge_utils { /// A wrapper structure on an array of events emitted by a given contract. #[derive(Drop, Clone)] pub struct ContractEvents { - pub events: Array + pub events: Span } pub trait EventsFilterTrait { @@ -246,33 +246,33 @@ pub mod snforge_utils { } }; - ContractEvents { events: filtered_events } + ContractEvents { events: filtered_events.span() } } } pub trait ContractEventsTrait { fn assert_emitted, impl TDrop: Drop>( - self: ContractEvents, event: @T + self: @ContractEvents, event: @T ); fn assert_not_emitted, impl TDrop: Drop>( - self: ContractEvents, event: @T + self: @ContractEvents, event: @T ); } impl ContractEventsTraitImpl of ContractEventsTrait { fn assert_emitted, impl TDrop: Drop>( - self: ContractEvents, event: @T + self: @ContractEvents, event: @T ) { let mut expected_keys = array![]; let mut expected_data = array![]; event.append_keys_and_data(ref expected_keys, ref expected_data); + let contract_events = (*self.events); let mut found = false; for i in 0 - ..self - .events + ..contract_events .len() { - let event = self.events.at(i); + let event = contract_events.at(i); if event.keys == @expected_keys && event.data == @expected_data { found = true; break; @@ -283,17 +283,17 @@ pub mod snforge_utils { } fn assert_not_emitted, impl TDrop: Drop>( - self: ContractEvents, event: @T + self: @ContractEvents, event: @T ) { let mut expected_keys = array![]; let mut expected_data = array![]; event.append_keys_and_data(ref expected_keys, ref expected_data); + let contract_events = (*self.events); for i in 0 - ..self - .events + ..contract_events .len() { - let event = self.events.at(i); + let event = contract_events.at(i); assert( event.keys != @expected_keys || event.data != @expected_data, 'Unexpected event was emitted' diff --git a/cairo/kakarot-ssj/crates/utils/src/eth_transaction/legacy.cairo b/cairo/kakarot-ssj/crates/utils/src/eth_transaction/legacy.cairo index 3119ef4bc..541a1821b 100644 --- a/cairo/kakarot-ssj/crates/utils/src/eth_transaction/legacy.cairo +++ b/cairo/kakarot-ssj/crates/utils/src/eth_transaction/legacy.cairo @@ -1,5 +1,8 @@ +use crate::errors::{RLPError, EthTransactionError, RLPErrorTrait}; use crate::eth_transaction::common::TxKind; +use crate::rlp::{RLPItem, RLPHelpersTrait}; use crate::traits::SpanDefault; +use crate::traits::{DefaultSignature}; #[derive(Copy, Drop, Debug, Default, PartialEq, Serde)] @@ -37,3 +40,57 @@ pub struct TxLegacy { /// input data of the message call. pub input: Span, } + +#[generate_trait] +pub impl _impl of TxLegacyTrait { + /// Decodes the RLP-encoded fields into a TxLegacy struct. + /// + /// # Arguments + /// + /// * `data` - A span of RLPItems containing the encoded transaction fields + /// + /// # Returns + /// + /// A Result containing either the decoded TxLegacy struct or an EthTransactionError + fn decode_fields(ref data: Span) -> Result { + let boxed_fields = data + .multi_pop_front::<7>() + .ok_or(EthTransactionError::RLPError(RLPError::InputTooShort))?; + let [ + nonce_encoded, + gas_price_encoded, + gas_limit_encoded, + to_encoded, + value_encoded, + input_encoded, + chain_id_encoded + ] = + (*boxed_fields) + .unbox(); + + let nonce = nonce_encoded.parse_u64_from_string().map_err()?; + let gas_price = gas_price_encoded.parse_u128_from_string().map_err()?; + let gas_limit = gas_limit_encoded.parse_u64_from_string().map_err()?; + let to = to_encoded.try_parse_address_from_string().map_err()?; + let value = value_encoded.parse_u256_from_string().map_err()?; + let input = input_encoded.parse_bytes_from_string().map_err()?; + let chain_id = chain_id_encoded.parse_u64_from_string().map_err()?; + + let transact_to = match to { + Option::Some(to) => { TxKind::Call(to) }, + Option::None => { TxKind::Create } + }; + + Result::Ok( + TxLegacy { + nonce, + gas_price, + gas_limit, + to: transact_to, + value, + input, + chain_id: Option::Some(chain_id), + } + ) + } +} diff --git a/cairo/kakarot-ssj/crates/utils/src/eth_transaction/transaction.cairo b/cairo/kakarot-ssj/crates/utils/src/eth_transaction/transaction.cairo index f301c8b4e..9e1d57f90 100644 --- a/cairo/kakarot-ssj/crates/utils/src/eth_transaction/transaction.cairo +++ b/cairo/kakarot-ssj/crates/utils/src/eth_transaction/transaction.cairo @@ -3,9 +3,9 @@ use crate::errors::{RLPError, EthTransactionError, RLPErrorTrait}; use crate::eth_transaction::common::{TxKind, TxKindTrait}; use crate::eth_transaction::eip1559::{TxEip1559, TxEip1559Trait}; use crate::eth_transaction::eip2930::{AccessListItem, TxEip2930, TxEip2930Trait}; -use crate::eth_transaction::legacy::TxLegacy; +use crate::eth_transaction::legacy::{TxLegacy, TxLegacyTrait}; use crate::eth_transaction::tx_type::{TxType}; -use crate::rlp::{RLPItem, RLPTrait, RLPHelpersTrait}; +use crate::rlp::{RLPItem, RLPTrait}; use crate::traits::bytes::U8SpanExTrait; use crate::traits::{DefaultSignature}; @@ -237,7 +237,7 @@ pub impl _TransactionUnsigned of TransactionUnsignedTrait { ref encoded_tx_data: Span ) -> Result { let rlp_decoded_data = RLPTrait::decode(encoded_tx_data); - let rlp_decoded_data = rlp_decoded_data.map_err()?; + let mut rlp_decoded_data = rlp_decoded_data.map_err()?; if (rlp_decoded_data.len() != 1) { return Result::Err( @@ -245,51 +245,14 @@ pub impl _TransactionUnsigned of TransactionUnsignedTrait { ); } - let rlp_decoded_data = *rlp_decoded_data.at(0); - let legacy_tx: TxLegacy = match rlp_decoded_data { + let rpl_item = *rlp_decoded_data.at(0); + let legacy_tx: TxLegacy = match rpl_item { RLPItem::String => { Result::Err(EthTransactionError::ExpectedRLPItemToBeList)? }, RLPItem::List(mut val) => { if (val.len() != 9) { return Result::Err(EthTransactionError::LegacyTxWrongPayloadLength(val.len())); } - - let boxed_fields = val - .multi_pop_front::<7>() - .ok_or(EthTransactionError::RLPError(RLPError::InputTooShort))?; - let [ - nonce_encoded, - gas_price_encoded, - gas_limit_encoded, - to_encoded, - value_encoded, - input_encoded, - chain_id_encoded - ] = - (*boxed_fields) - .unbox(); - - let nonce = nonce_encoded.parse_u64_from_string().map_err()?; - let gas_price = gas_price_encoded.parse_u128_from_string().map_err()?; - let gas_limit = gas_limit_encoded.parse_u64_from_string().map_err()?; - let to = to_encoded.try_parse_address_from_string().map_err()?; - let value = value_encoded.parse_u256_from_string().map_err()?; - let input = input_encoded.parse_bytes_from_string().map_err()?; - let chain_id = chain_id_encoded.parse_u64_from_string().map_err()?; - - let transact_to = match to { - Option::Some(to) => { TxKind::Call(to) }, - Option::None => { TxKind::Create } - }; - - TxLegacy { - nonce, - gas_price, - gas_limit, - to: transact_to, - value, - input, - chain_id: Option::Some(chain_id), - } + TxLegacyTrait::decode_fields(ref val)? } }; diff --git a/cairo/kakarot-ssj/crates/utils/src/traits/bytes.cairo b/cairo/kakarot-ssj/crates/utils/src/traits/bytes.cairo index 1499597d5..177b60a79 100644 --- a/cairo/kakarot-ssj/crates/utils/src/traits/bytes.cairo +++ b/cairo/kakarot-ssj/crates/utils/src/traits/bytes.cairo @@ -32,21 +32,22 @@ pub impl U8SpanExImpl of U8SpanExTrait { /// - A usize representing the number of bytes in the last word fn to_u64_words(self: Span) -> (Array, u64, usize) { let nonzero_8: NonZero = 8_u32.try_into().unwrap(); - let (full_u64_word_count, last_input_num_bytes) = DivRem::div_rem(self.len(), nonzero_8); + let (_, last_input_num_bytes) = DivRem::div_rem(self.len(), nonzero_8); - let mut u64_words: Array = Default::default(); + let mut u64_words: Array = array![]; + let mut word_index = 0; let mut byte_counter: u8 = 0; let mut pending_word: u64 = 0; - let mut u64_word_counter: usize = 0; - while u64_word_counter != full_u64_word_count { + // Iterate until we have iterated over all the full words and the last word + while true { if byte_counter == 8 { u64_words.append(pending_word); + word_index += 8; byte_counter = 0; pending_word = 0; - u64_word_counter += 1; } - pending_word += match self.get(u64_word_counter * 8 + byte_counter.into()) { + pending_word += match self.get(word_index + byte_counter.into()) { Option::Some(byte) => { let byte: u64 = (*byte.unbox()).into(); // Accumulate pending_word in a little endian manner @@ -56,25 +57,7 @@ pub impl U8SpanExImpl of U8SpanExTrait { }; byte_counter += 1; }; - - // Fill the last input word - let mut last_input_word: u64 = 0; - - // We enter a second loop for clarity. - // O(2n) should be okay - // We might want to regroup every computation into a single loop with appropriate `if` - // branching For optimisation - for byte_counter in 0 - ..last_input_num_bytes { - last_input_word += match self.get(full_u64_word_count * 8 + byte_counter.into()) { - Option::Some(byte) => { - let byte: u64 = (*byte.unbox()).into(); - byte.shl(8_u32 * byte_counter.into()) - }, - Option::None => { break; }, - }; - }; - + let last_input_word: u64 = pending_word; (u64_words, last_input_word, last_input_num_bytes) } @@ -225,6 +208,24 @@ pub trait ToBytes { fn to_le_bytes_padded(self: T) -> Span; } +pub impl U8ToBytes of ToBytes { + fn to_be_bytes(self: u8) -> Span { + [self].span() + } + + fn to_be_bytes_padded(self: u8) -> Span { + self.to_be_bytes() + } + + fn to_le_bytes(self: u8) -> Span { + [self].span() + } + + fn to_le_bytes_padded(self: u8) -> Span { + self.to_le_bytes() + } +} + pub impl ToBytesImpl< T, +Zero, @@ -232,11 +233,12 @@ pub impl ToBytesImpl< +Add, +Sub, +Mul, + +Div, +BitAnd, +Bitshift, +BitSize, +BytesUsedTrait, - +Into, + +Into, +TryInto, +Copy, +Drop, @@ -244,19 +246,9 @@ pub impl ToBytesImpl< +PartialEq > of ToBytes { fn to_be_bytes(self: T) -> Span { - let bytes_used = self.bytes_used(); - - // 0xFF - let mask = Bounded::::MAX.into(); - - let mut bytes: Array = Default::default(); - for i in 0 - ..bytes_used { - let val = Bitshift::::shr(self, 8_u32 * (bytes_used.into() - i.into() - 1)); - bytes.append((val & mask).try_into().unwrap()); - }; - - bytes.span() + // U8 type is handled in another impl. + let be_bytes = to_be_bytes_recursive(self); + be_bytes.span() } fn to_be_bytes_padded(mut self: T) -> Span { @@ -265,17 +257,21 @@ pub impl ToBytesImpl< } fn to_le_bytes(mut self: T) -> Span { + // U8 type is handled in another impl. + let bytes_used = self.bytes_used(); // 0xFF - let mask = Bounded::::MAX.into(); + let mask: u16 = Bounded::::MAX.into(); + let mask: T = mask.into(); let mut bytes: Array = Default::default(); + let mut value = self; - for i in 0 + for _ in 0 ..bytes_used { - let val = self.shr(8_u32 * i.into()); - bytes.append((val & mask).try_into().unwrap()); + bytes.append((value & mask).try_into().unwrap()); + value = value / 256_u16.into(); }; bytes.span() @@ -287,6 +283,46 @@ pub impl ToBytesImpl< } } +// Helper function to recursively build the bytes +fn to_be_bytes_recursive< + T, + +Zero, + +One, + +Add, + +Sub, + +Mul, + +Div, + +BitAnd, + +Bitshift, + +BitSize, + +BytesUsedTrait, + +Into, + +TryInto, + +Copy, + +Drop, + +core::ops::AddAssign, + +PartialEq +>( + value: T +) -> Array { + // Base case: if value is 0, unpile the call stack + if value == 0_u16.into() { + return array![]; + } + + // 0xFF + let mask: u16 = Bounded::::MAX.into(); + let mask: T = mask.into(); + + // Get the least significant byte + let byte: u8 = (value & mask).try_into().unwrap(); + + // Recurse with the value shifted right by 8 bits + let mut be_bytes = to_be_bytes_recursive(value / (256_u16.into())); + be_bytes.append(byte); + return be_bytes; +} + pub trait FromBytes { /// Parses a span of big endian bytes into a type T /// @@ -380,7 +416,7 @@ pub impl FromBytesImpl< Option::Some(result) } - fn from_le_bytes(self: Span) -> Option { + fn from_le_bytes(mut self: Span) -> Option { let byte_size = ByteSize::::byte_size(); if self.len() != byte_size { @@ -388,16 +424,19 @@ pub impl FromBytesImpl< } let mut result: T = Zero::zero(); - let mut i = self.len(); - while i != 0 { - i -= 1; - let tmp = result * 256_u16.into(); - result = tmp + (*self[i]).into(); + loop { + match self.pop_back() { + Option::None => { break; }, + Option::Some(byte) => { + let tmp = result * 256_u16.into(); + result = tmp + (*byte).into(); + } + }; }; Option::Some(result) } - fn from_le_bytes_partial(self: Span) -> Option { + fn from_le_bytes_partial(mut self: Span) -> Option { let byte_size = ByteSize::::byte_size(); if self.len() > byte_size { @@ -405,11 +444,14 @@ pub impl FromBytesImpl< } let mut result: T = Zero::zero(); - let mut i = self.len(); - while i != 0 { - i -= 1; - let tmp = result * 256_u16.into(); - result = tmp + (*self[i]).into(); + loop { + match self.pop_back() { + Option::None => { break; }, + Option::Some(byte) => { + let tmp = result * 256_u16.into(); + result = tmp + (*byte).into(); + } + }; }; Option::Some(result) } @@ -484,69 +526,6 @@ pub impl ByteArrayExt of ByteArrayExTrait { }; output.span() } - - - /// Transforms a ByteArray into an Array of u64 full words, a pending u64 word and its length in - /// bytes - /// # Arguments - /// * `self` - The ByteArray to transform - /// # Returns - /// * A tuple containing: - /// - An Array of full words - /// - A u64 representing the last (potentially partial) word - /// - A usize representing the number of bytes in the last word - fn to_u64_words(self: ByteArray) -> (Array, u64, usize) { - // We pass it by value because we want to take ownership, but we snap it - // because `at` takes a snap and if this snap is automatically done by - // the compiler in the loop, it won't compile - let self = @self; - let nonzero_8: NonZero = 8_u32.try_into().unwrap(); - let (full_u64_word_count, last_input_num_bytes) = DivRem::div_rem(self.len(), nonzero_8); - - let mut u64_words: Array = Default::default(); - let mut byte_counter: u8 = 0; - let mut pending_word: u64 = 0; - let mut u64_word_counter: usize = 0; - - while u64_word_counter != full_u64_word_count { - if byte_counter == 8 { - u64_words.append(pending_word); - byte_counter = 0; - pending_word = 0; - u64_word_counter += 1; - } - pending_word += match self.at(u64_word_counter * 8 + byte_counter.into()) { - Option::Some(byte) => { - let byte: u64 = byte.into(); - // Accumulate pending_word in a little endian manner - byte.shl(8_u32 * byte_counter.into()) - }, - Option::None => { break; }, - }; - byte_counter += 1; - }; - - // Fill the last input word - let mut last_input_word: u64 = 0; - - // We enter a second loop for clarity. - // O(2n) should be okay - // We might want to regroup every computation into a single loop with appropriate `if` - // branching For optimisation - - for byte_counter in 0 - ..last_input_num_bytes { - last_input_word += match self.at(full_u64_word_count * 8 + byte_counter.into()) { - Option::Some(byte) => { - let byte: u64 = byte.into(); - byte.shl(8_u32 * byte_counter.into()) - }, - Option::None => { break; }, - }; - }; - - (u64_words, last_input_word, last_input_num_bytes) - } } @@ -670,29 +649,6 @@ mod tests { assert(*arr[i] == res[i], 'byte mismatch'); }; } - - - #[test] - fn test_bytearray_to_64_words_partial() { - let input = ByteArrayExTrait::from_bytes([0x01, 0x02, 0x03, 0x04, 0x05, 0x06].span()); - let (u64_words, pending_word, pending_word_len) = input.to_u64_words(); - assert(pending_word == 6618611909121, 'wrong pending word'); - assert(pending_word_len == 6, 'wrong pending word length'); - assert(u64_words.len() == 0, 'wrong u64 words length'); - } - - #[test] - fn test_bytearray_to_64_words_full() { - let input = ByteArrayExTrait::from_bytes( - [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08].span() - ); - let (u64_words, pending_word, pending_word_len) = input.to_u64_words(); - - assert(pending_word == 0, 'wrong pending word'); - assert(pending_word_len == 0, 'wrong pending word length'); - assert(u64_words.len() == 1, 'wrong u64 words length'); - assert(*u64_words[0] == 578437695752307201, 'wrong u64 words length'); - } } diff --git a/cairo/kakarot-ssj/crates/utils/src/traits/integer.cairo b/cairo/kakarot-ssj/crates/utils/src/traits/integer.cairo index d038336b8..6fd837630 100644 --- a/cairo/kakarot-ssj/crates/utils/src/traits/integer.cairo +++ b/cairo/kakarot-ssj/crates/utils/src/traits/integer.cairo @@ -245,6 +245,7 @@ pub(crate) mod bits_used_internal { mod tests { mod u8_test { use crate::math::Bitshift; + use crate::traits::bytes::{ToBytes, FromBytes}; use super::super::BitsUsed; #[test] @@ -262,6 +263,22 @@ mod tests { i -= 1; }; } + + #[test] + fn test_u8_to_le_bytes() { + let input: u8 = 0xf4; + let res: Span = input.to_le_bytes(); + + assert_eq!(res, [0xf4].span()); + } + + #[test] + fn test_u8_to_le_bytes_padded() { + let input: u8 = 0xf4; + let res: Span = input.to_le_bytes_padded(); + + assert_eq!(res, [0xf4].span()); + } } mod u32_test { @@ -295,7 +312,7 @@ mod tests { } #[test] - fn test_u32_from_be_bytes_partial_full() { + fn test_u32_from_be_bytes_partial() { let input: Array = array![0xf4, 0x32, 0x15, 0x62]; let res: Option = input.span().from_be_bytes_partial(); @@ -430,11 +447,7 @@ mod tests { let input: u32 = 0xf4321562; let res: Span = input.to_be_bytes(); - assert_eq!(res.len(), 4); - assert_eq!(*res[0], 0xf4); - assert_eq!(*res[1], 0x32); - assert_eq!(*res[2], 0x15); - assert_eq!(*res[3], 0x62); + assert_eq!(res, [0xf4, 0x32, 0x15, 0x62].span()); } #[test] @@ -451,12 +464,12 @@ mod tests { #[test] fn test_u32_to_bytes_leading_zeros() { - let input: u32 = 0x00f432; + let input: u32 = 0x001234; let res: Span = input.to_be_bytes(); assert_eq!(res.len(), 2); - assert_eq!(*res[0], 0xf4); - assert_eq!(*res[1], 0x32); + assert_eq!(*res[0], 0x12); + assert_eq!(*res[1], 0x34); } #[test] @@ -468,6 +481,43 @@ mod tests { assert_eq!(result, expected); } + #[test] + fn test_u32_to_le_bytes_full() { + let input: u32 = 0xf4321562; + let res: Span = input.to_le_bytes(); + + assert_eq!(res, [0x62, 0x15, 0x32, 0xf4].span()); + } + + #[test] + fn test_u32_to_le_bytes_partial() { + let input: u32 = 0xf43215; + let res: Span = input.to_le_bytes(); + + assert_eq!(res.len(), 3); + assert_eq!(*res[0], 0x15); + assert_eq!(*res[1], 0x32); + assert_eq!(*res[2], 0xf4); + } + + #[test] + fn test_u32_to_le_bytes_leading_zeros() { + let input: u32 = 0x00f432; + let res: Span = input.to_le_bytes(); + + assert_eq!(res.len(), 2); + assert_eq!(*res[0], 0x32); + assert_eq!(*res[1], 0xf4); + } + + #[test] + fn test_u32_to_le_bytes_padded() { + let input: u32 = 7; + let result = input.to_le_bytes_padded(); + let expected = [7, 0x0, 0x0, 0x0].span(); + + assert_eq!(result, expected); + } #[test] fn test_u32_bytes_used() { @@ -552,6 +602,30 @@ mod tests { assert_eq!(result, expected); } + + #[test] + fn test_u64_to_le_bytes_full() { + let input: u64 = 0xf432156278901234; + let res: Span = input.to_le_bytes(); + + assert_eq!(res, [0x34, 0x12, 0x90, 0x78, 0x62, 0x15, 0x32, 0xf4].span()); + } + + #[test] + fn test_u64_to_le_bytes_partial() { + let input: u64 = 0xf43215; + let res: Span = input.to_le_bytes(); + + assert_eq!(res, [0x15, 0x32, 0xf4].span()); + } + + #[test] + fn test_u64_to_le_bytes_padded() { + let input: u64 = 0xf43215; + let res: Span = input.to_le_bytes_padded(); + + assert_eq!(res, [0x15, 0x32, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x00].span()); + } } mod u128_test { @@ -605,10 +679,75 @@ mod tests { assert_eq!(result, expected); } + + #[test] + fn test_u128_to_le_bytes_full() { + let input: u128 = 0xf432156278901234deadbeefcafebabe; + let res: Span = input.to_le_bytes(); + + assert_eq!( + res, + [ + 0xbe, + 0xba, + 0xfe, + 0xca, + 0xef, + 0xbe, + 0xad, + 0xde, + 0x34, + 0x12, + 0x90, + 0x78, + 0x62, + 0x15, + 0x32, + 0xf4 + ].span() + ); + } + + #[test] + fn test_u128_to_le_bytes_partial() { + let input: u128 = 0xf43215; + let res: Span = input.to_le_bytes(); + + assert_eq!(res, [0x15, 0x32, 0xf4].span()); + } + + #[test] + fn test_u128_to_le_bytes_padded() { + let input: u128 = 0xf43215; + let res: Span = input.to_le_bytes_padded(); + + assert_eq!( + res, + [ + 0x15, + 0x32, + 0xf4, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00 + ].span() + ); + } } mod u256_test { use crate::math::Bitshift; + use crate::traits::bytes::{ToBytes}; use crate::traits::integer::{U256Trait}; use super::super::{BitsUsed, BytesUsedTrait}; @@ -658,12 +797,204 @@ mod tests { } #[test] - fn test_u64_bits_used() { + fn test_u256_bits_used() { let input: u256 = 7; let result = input.bits_used(); let expected = 3; assert_eq!(result, expected); } + + #[test] + fn test_u256_to_be_bytes_full() { + let input: u256 = 0xf432156278901234deadbeefcafebabe0123456789abcdef0fedcba987654321; + let res: Span = input.to_be_bytes(); + + assert_eq!( + res, + [ + 0xf4, + 0x32, + 0x15, + 0x62, + 0x78, + 0x90, + 0x12, + 0x34, + 0xde, + 0xad, + 0xbe, + 0xef, + 0xca, + 0xfe, + 0xba, + 0xbe, + 0x01, + 0x23, + 0x45, + 0x67, + 0x89, + 0xab, + 0xcd, + 0xef, + 0x0f, + 0xed, + 0xcb, + 0xa9, + 0x87, + 0x65, + 0x43, + 0x21 + ].span() + ); + } + + #[test] + fn test_u256_to_be_bytes_partial() { + let input: u256 = 0xf43215; + let res: Span = input.to_be_bytes(); + + assert_eq!(res, [0xf4, 0x32, 0x15].span()); + } + + #[test] + fn test_u256_to_be_bytes_padded() { + let input: u256 = 0xf43215; + let res: Span = input.to_be_bytes_padded(); + + assert_eq!( + res, + [ + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xf4, + 0x32, + 0x15 + ].span() + ); + } + + #[test] + fn test_u256_to_le_bytes_full() { + let input: u256 = 0xf432156278901234deadbeefcafebabe0123456789abcdef0fedcba987654321; + let res: Span = input.to_le_bytes(); + + assert_eq!( + res, + [ + 0x21, + 0x43, + 0x65, + 0x87, + 0xa9, + 0xcb, + 0xed, + 0x0f, + 0xef, + 0xcd, + 0xab, + 0x89, + 0x67, + 0x45, + 0x23, + 0x01, + 0xbe, + 0xba, + 0xfe, + 0xca, + 0xef, + 0xbe, + 0xad, + 0xde, + 0x34, + 0x12, + 0x90, + 0x78, + 0x62, + 0x15, + 0x32, + 0xf4 + ].span() + ); + } + + #[test] + fn test_u256_to_le_bytes_partial() { + let input: u256 = 0xf43215; + let res: Span = input.to_le_bytes(); + + assert_eq!(res, [0x15, 0x32, 0xf4].span()); + } + + #[test] + fn test_u256_to_le_bytes_padded() { + let input: u256 = 0xf43215; + let res: Span = input.to_le_bytes_padded(); + + assert_eq!( + res, + [ + 0x15, + 0x32, + 0xf4, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00 + ].span() + ); + } } } diff --git a/cairo/kakarot-ssj/scripts/compute_rlp_encoding.ts b/cairo/kakarot-ssj/scripts/compute_rlp_encoding.ts index a556f0b33..692922397 100644 --- a/cairo/kakarot-ssj/scripts/compute_rlp_encoding.ts +++ b/cairo/kakarot-ssj/scripts/compute_rlp_encoding.ts @@ -24,14 +24,14 @@ const main = async () => { const { Transaction, Wallet } = ethers; const { decodeRlp, getBytes } = ethers; - if (!process.env.PRIVATE_KEY_RLP_SCRIPT) { + if (!process.env.PRIVATE_KEY) { console.log( - "missing private key in environment, please provide PRIVATE_KEY_RLP_SCRIPT environment variable", + "missing private key in environment, please provide PRIVATE_KEY environment variable", ); process.exit(1); } - const wallet = new Wallet(process.env.PRIVATE_KEY_RLP_SCRIPT); + const wallet = new Wallet(process.env.PRIVATE_KEY); console.log("address of the wallet is", wallet.address); let tx_type = parseInt( diff --git a/cairo/kakarot-ssj/scripts/filter_tests.py b/cairo/kakarot-ssj/scripts/filter_tests.py index 6247e703a..7d514b79a 100644 --- a/cairo/kakarot-ssj/scripts/filter_tests.py +++ b/cairo/kakarot-ssj/scripts/filter_tests.py @@ -26,7 +26,6 @@ def filter_file(file_path, filter_string): def replace_func(match): full_match = match.group(0) func_name = match.group(1) - if filter_string.lower() in func_name.lower(): return full_match else: diff --git a/cairo/kakarot-ssj/scripts/run_filtered_tests.py b/cairo/kakarot-ssj/scripts/run_filtered_tests.py index 9c755c572..4e9c6447e 100644 --- a/cairo/kakarot-ssj/scripts/run_filtered_tests.py +++ b/cairo/kakarot-ssj/scripts/run_filtered_tests.py @@ -18,6 +18,7 @@ def temporary_project_copy(src_dir): with tempfile.TemporaryDirectory() as temp_dir: temp_path = Path(temp_dir) src_path = Path(src_dir) + temp_dir_creation_time = temp_path.stat().st_ctime for file in PROJECT_FILES: if (src_file := src_path / file).exists(): @@ -28,6 +29,24 @@ def temporary_project_copy(src_dir): yield temp_path + # Copy back only newly created or modified files, excluding build/ directories and .cairo files + for root, dirs, files in os.walk(temp_path): + dirs[:] = [ + d for d in dirs if d != "target" + ] # Don't traverse into build directories + for file in files: + temp_file = Path(root) / file + rel_path = temp_file.relative_to(temp_path) + src_file = src_path / rel_path + + if ( + not src_file.exists() + or temp_file.stat().st_mtime > temp_dir_creation_time + ) and temp_file.suffix != ".cairo": + src_file.parent.mkdir(parents=True, exist_ok=True) + shutil.copy2(temp_file, src_file) + print(f"Copied new or modified file: {rel_path}") + def stream_output(fd): while True: @@ -45,6 +64,7 @@ def stream_output(fd): def run_scarb_command(command, cwd): master, slave = pty.openpty() + print(f"Running command: {command}") with subprocess.Popen( command, shell=True, stdout=slave, stderr=slave, close_fds=True, cwd=cwd ) as process: @@ -57,17 +77,28 @@ def run_scarb_command(command, cwd): sys.exit(return_code) -def run_filtered_tests(package, filter_name): +def run_filtered_tests(command): project_root = Path(__file__).parent.parent with temporary_project_copy(project_root) as temp_project_dir: + # Extract the package and filter name from the command + cmd_parts = command.split() + package_index = cmd_parts.index("-p") + 1 + cmd_parts[package_index] + filter_name = cmd_parts[package_index + 1] + filter_tests(temp_project_dir / "crates", filter_name) - run_scarb_command(f"scarb test -p {package} {filter_name}", temp_project_dir) + run_scarb_command(command, temp_project_dir) if __name__ == "__main__": - if len(sys.argv) != 3: - print("Usage: python run_filtered_tests.py ") + if len(sys.argv) < 2: + print("Usage: python run_filtered_tests.py ") + print("Example: python run_filtered_tests.py scarb test -p evm foo") + print( + "Example: python run_filtered_tests.py snforge test -p evm foo --build-profile" + ) sys.exit(1) - run_filtered_tests(sys.argv[1], sys.argv[2]) + full_command = " ".join(sys.argv[1:]) + run_filtered_tests(full_command) diff --git a/cairo/kakarot-ssj/scripts/setup_cairo_native.sh b/cairo/kakarot-ssj/scripts/setup_cairo_native.sh index 1cf59c891..4f3101749 100755 --- a/cairo/kakarot-ssj/scripts/setup_cairo_native.sh +++ b/cairo/kakarot-ssj/scripts/setup_cairo_native.sh @@ -120,6 +120,7 @@ install_cairo_native_runtime() { git clone https://github.com/lambdaclass/cairo_native.git pushd ./cairo_native || exit 1 git fetch + git checkout ae17dd370a7bbf6affeefb9fa6954965e8b52239 make deps make runtime cp libcairo_native_runtime.a ../libcairo_native_runtime.a From 8bfa1017157e3ad19ce1a2bfa33826a9194b5075 Mon Sep 17 00:00:00 2001 From: Oba Date: Fri, 4 Oct 2024 11:25:40 +0200 Subject: [PATCH 47/56] style: trunk fmt --- cairo_zero/tests/conftest.py | 2 +- pyproject.toml | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/cairo_zero/tests/conftest.py b/cairo_zero/tests/conftest.py index 302f817e7..774cac68a 100644 --- a/cairo_zero/tests/conftest.py +++ b/cairo_zero/tests/conftest.py @@ -1,5 +1,5 @@ -import sys import os +import sys from pathlib import Path # Add the project root to the Python path diff --git a/pyproject.toml b/pyproject.toml index 7926d72fa..b1dbb437e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -67,10 +67,7 @@ filterwarnings = [ "ignore:abi:DeprecationWarning", # from web3 "ignore::marshmallow.warnings.RemovedInMarshmallow4Warning", # from marshmallow ] -pythonpath = [ - ".", - "tests" -] +pythonpath = [".", "tests"] asyncio_mode = "auto" markers = [ "ArithmeticOperations", From a27c49dba9bf8d2966d986676a54a602cb57851c Mon Sep 17 00:00:00 2001 From: Oba Date: Fri, 4 Oct 2024 11:35:21 +0200 Subject: [PATCH 48/56] style: trunk check --- cairo_zero/tests/conftest.py | 10 +++++----- cairo_zero/tests/src/utils/test_rlp.py | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cairo_zero/tests/conftest.py b/cairo_zero/tests/conftest.py index 774cac68a..0b35aca5f 100644 --- a/cairo_zero/tests/conftest.py +++ b/cairo_zero/tests/conftest.py @@ -1,12 +1,12 @@ -import os +# ruff: noqa: F403 import sys from pathlib import Path -# Add the project root to the Python path -project_root = Path(__file__).resolve().parent.parent.parent -sys.path.insert(0, str(project_root)) - # Import everything from the root conftest.py from tests.conftest import * from tests.fixtures import * from tests.utils import * + +# Add the project root to the Python path +project_root = Path(__file__).resolve().parent.parent.parent +sys.path.insert(0, str(project_root)) diff --git a/cairo_zero/tests/src/utils/test_rlp.py b/cairo_zero/tests/src/utils/test_rlp.py index 10a029369..7180b1730 100644 --- a/cairo_zero/tests/src/utils/test_rlp.py +++ b/cairo_zero/tests/src/utils/test_rlp.py @@ -21,7 +21,7 @@ def test_should_match_prefix_reference_implementation(self, cairo_run, data): expected_len, expected_offset, ] = codec.consume_length_prefix(encoded_data, 0) - expected_type = 0 if rlp_type == bytes else 1 + expected_type = 0 if rlp_type is bytes else 1 output = cairo_run("test__decode_type", data=list(encoded_data)) From 2840b793566e219cb988cce1806603f324088d97 Mon Sep 17 00:00:00 2001 From: Oba Date: Fri, 4 Oct 2024 11:51:08 +0200 Subject: [PATCH 49/56] ci: fix ssj release --- .github/workflows/ssj-release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ssj-release.yml b/.github/workflows/ssj-release.yml index c007b0bee..3e4da5724 100644 --- a/.github/workflows/ssj-release.yml +++ b/.github/workflows/ssj-release.yml @@ -17,7 +17,7 @@ jobs: tool-versions: ./cairo/kakarot-ssj/.tool-versions - name: Build contracts run: | - scarb build -p contracts + cd cairo/kakarot-ssj && scarb build -p contracts - name: Zip dev artifacts run: zip -rj kakarot-ssj-build.zip cairo/kakarot-ssj/target/dev - name: Upload artifacts to release From 6d46f7fbe2d69d3b6f66a3a75061b4bf20e919f8 Mon Sep 17 00:00:00 2001 From: Oba Date: Fri, 4 Oct 2024 15:16:20 +0200 Subject: [PATCH 50/56] update ef test skipfile ssj --- cairo/kakarot-ssj/blockchain-tests-skip.yml | 879 ++++++-------------- 1 file changed, 255 insertions(+), 624 deletions(-) diff --git a/cairo/kakarot-ssj/blockchain-tests-skip.yml b/cairo/kakarot-ssj/blockchain-tests-skip.yml index 4b69f227c..f6c175d4b 100644 --- a/cairo/kakarot-ssj/blockchain-tests-skip.yml +++ b/cairo/kakarot-ssj/blockchain-tests-skip.yml @@ -21,644 +21,275 @@ regex: testname: stEIP1153-transientStorage: - - transStorageOK_d3g0v0_Cancun + - 15_tstoreCannotBeDosd_d0g0v0_Cancun + - 21_tstoreCannotBeDosdOOO_d0g0v0_Cancun eip198_modexp_precompile: - - modexp__fork_Cancun_minus_blockchain_test_minus_EIP_minus_198_minus_case3_minus_raw_minus_input_minus_out_minus_of_minus_gas - initcode: - - contract_creating_tx__fork_Cancun_minus_blockchain_test_minus_over_limit_ones - - contract_creating_tx__fork_Cancun_minus_blockchain_test_minus_over_limit_zeros - stEIP3651-warmcoinbase: - - coinbaseWarmAccountCallGasFail_d0g0v0_Cancun - vmIOandFlowOperations: - - jump_d5g0v0_Cancun - - jumpi_d19g0v0_Cancun - - jumpi_d21g0v0_Cancun - - jumpi_d9g0v0_Cancun - vmLogTest: - - log0_d0g0v0_Cancun - - log1_d0g0v0_Cancun - - log2_d0g0v0_Cancun - - log3_d0g0v0_Cancun - - log4_d0g0v0_Cancun + - modexp__fork_Cancun_minus_blockchain_test_minus_EIP_minus_198_minus_case1 + - modexp__fork_Cancun_minus_blockchain_test_minus_EIP_minus_198_minus_case2 + - modexp__fork_Cancun_minus_blockchain_test_minus_EIP_minus_198_minus_case4_minus_extra_minus_data_07 + - modexp__fork_Cancun_minus_blockchain_test_minus_EIP_minus_198_minus_case5_minus_raw_minus_input + - modexp__fork_Cancun_minus_blockchain_test_minus_ModExpInput_base_00_minus_exponent_00_minus_modulus_02_minus_ExpectedOutput_call_return_code_0x01_minus_returned_data_0x01 + - modexp__fork_Cancun_minus_blockchain_test_minus_ModExpInput_base_01_minus_exponent_01_minus_modulus_02_minus_ExpectedOutput_call_return_code_0x01_minus_returned_data_0x01 + - modexp__fork_Cancun_minus_blockchain_test_minus_ModExpInput_base_02_minus_exponent_01_minus_modulus_03_minus_ExpectedOutput_call_return_code_0x01_minus_returned_data_0x02 + - modexp__fork_Cancun_minus_blockchain_test_minus_ModExpInput_base_02_minus_exponent_02_minus_modulus_05_minus_ExpectedOutput_call_return_code_0x01_minus_returned_data_0x04 + - modexp__fork_Cancun_minus_blockchain_test_minus_ModExpInput_base__minus_exponent_01_minus_modulus_02_minus_ExpectedOutput_call_return_code_0x01_minus_returned_data_0x00 + - modexp__fork_Cancun_minus_blockchain_test_minus_ModExpInput_base__minus_exponent__minus_modulus_0001_minus_ExpectedOutput_call_return_code_0x01_minus_returned_data_0x0000 + - modexp__fork_Cancun_minus_blockchain_test_minus_ModExpInput_base__minus_exponent__minus_modulus_0002_minus_ExpectedOutput_call_return_code_0x01_minus_returned_data_0x0001 + - modexp__fork_Cancun_minus_blockchain_test_minus_ModExpInput_base__minus_exponent__minus_modulus_00_minus_ExpectedOutput_call_return_code_0x01_minus_returned_data_0x00 + - modexp__fork_Cancun_minus_blockchain_test_minus_ModExpInput_base__minus_exponent__minus_modulus_01_minus_ExpectedOutput_call_return_code_0x01_minus_returned_data_0x00 + - modexp__fork_Cancun_minus_blockchain_test_minus_ModExpInput_base__minus_exponent__minus_modulus_02_minus_ExpectedOutput_call_return_code_0x01_minus_returned_data_0x01 + - modexp__fork_Cancun_minus_blockchain_test_minus_ModExpInput_base__minus_exponent__minus_modulus__minus_ExpectedOutput_call_return_code_0x01_minus_returned_data_0x + tstorage: + - run_until_out_of_gas__fork_Cancun_minus_blockchain_test_minus_tstore + - run_until_out_of_gas__fork_Cancun_minus_blockchain_test_minus_tstore_tload + - run_until_out_of_gas__fork_Cancun_minus_blockchain_test_minus_tstore_wide_address_space vmPerformance: - - loopExp_d2g0v0_Cancun - - performanceTester_d0g0v0_Cancun - - performanceTester_d2g0v0_Cancun - - performanceTester_d3g0v0_Cancun - vmTests: - - blockInfo_d2g0v0_Cancun - stBadOpcode: - - invalidDiffPlaces_d34g0v0_Cancun - - opc0CDiffPlaces_d34g0v0_Cancun - - opc0DDiffPlaces_d34g0v0_Cancun - - opc0EDiffPlaces_d34g0v0_Cancun - - opc0FDiffPlaces_d34g0v0_Cancun - - opc1EDiffPlaces_d34g0v0_Cancun - - opc1FDiffPlaces_d34g0v0_Cancun - - opc21DiffPlaces_d34g0v0_Cancun - - opc22DiffPlaces_d34g0v0_Cancun - - opc23DiffPlaces_d34g0v0_Cancun - - opc24DiffPlaces_d34g0v0_Cancun - - opc25DiffPlaces_d34g0v0_Cancun - - opc26DiffPlaces_d34g0v0_Cancun - - opc27DiffPlaces_d34g0v0_Cancun - - opc28DiffPlaces_d34g0v0_Cancun - - opc29DiffPlaces_d34g0v0_Cancun - - opc2ADiffPlaces_d34g0v0_Cancun - - opc2BDiffPlaces_d34g0v0_Cancun - - opc2CDiffPlaces_d34g0v0_Cancun - - opc2DDiffPlaces_d34g0v0_Cancun - - opc2EDiffPlaces_d34g0v0_Cancun - - opc2FDiffPlaces_d34g0v0_Cancun - - opc49DiffPlaces_d34g0v0_Cancun - - opc4ADiffPlaces_d34g0v0_Cancun - - opc4BDiffPlaces_d34g0v0_Cancun - - opc4CDiffPlaces_d34g0v0_Cancun - - opc4DDiffPlaces_d34g0v0_Cancun - - opc4EDiffPlaces_d34g0v0_Cancun - - opc4FDiffPlaces_d34g0v0_Cancun - - opc5CDiffPlaces_d34g0v0_Cancun - - opc5DDiffPlaces_d34g0v0_Cancun - - opc5EDiffPlaces_d34g0v0_Cancun - - opc5FDiffPlaces_d34g0v0_Cancun - - opcA5DiffPlaces_d34g0v0_Cancun - - opcA6DiffPlaces_d34g0v0_Cancun - - opcA7DiffPlaces_d34g0v0_Cancun - - opcA8DiffPlaces_d34g0v0_Cancun - - opcA9DiffPlaces_d34g0v0_Cancun - - opcAADiffPlaces_d34g0v0_Cancun - - opcABDiffPlaces_d34g0v0_Cancun - - opcACDiffPlaces_d34g0v0_Cancun - - opcADDiffPlaces_d34g0v0_Cancun - - opcAEDiffPlaces_d34g0v0_Cancun - - opcAFDiffPlaces_d34g0v0_Cancun - - opcB0DiffPlaces_d34g0v0_Cancun - - opcB1DiffPlaces_d34g0v0_Cancun - - opcB2DiffPlaces_d34g0v0_Cancun - - opcB3DiffPlaces_d34g0v0_Cancun - - opcB4DiffPlaces_d34g0v0_Cancun - - opcB5DiffPlaces_d34g0v0_Cancun - - opcB6DiffPlaces_d34g0v0_Cancun - - opcB7DiffPlaces_d34g0v0_Cancun - - opcB8DiffPlaces_d34g0v0_Cancun - - opcB9DiffPlaces_d34g0v0_Cancun - - opcBADiffPlaces_d34g0v0_Cancun - - opcBBDiffPlaces_d34g0v0_Cancun - - opcBCDiffPlaces_d34g0v0_Cancun - - opcBDDiffPlaces_d34g0v0_Cancun - - opcBEDiffPlaces_d34g0v0_Cancun - - opcBFDiffPlaces_d34g0v0_Cancun - - opcC0DiffPlaces_d34g0v0_Cancun - - opcC1DiffPlaces_d34g0v0_Cancun - - opcC2DiffPlaces_d34g0v0_Cancun - - opcC3DiffPlaces_d34g0v0_Cancun - - opcC4DiffPlaces_d34g0v0_Cancun - - opcC5DiffPlaces_d34g0v0_Cancun - - opcC6DiffPlaces_d34g0v0_Cancun - - opcC7DiffPlaces_d34g0v0_Cancun - - opcC8DiffPlaces_d34g0v0_Cancun - - opcC9DiffPlaces_d34g0v0_Cancun - - opcCADiffPlaces_d34g0v0_Cancun - - opcCBDiffPlaces_d34g0v0_Cancun - - opcCCDiffPlaces_d34g0v0_Cancun - - opcCDDiffPlaces_d34g0v0_Cancun - - opcCEDiffPlaces_d34g0v0_Cancun - - opcCFDiffPlaces_d34g0v0_Cancun - - opcD0DiffPlaces_d34g0v0_Cancun - - opcD1DiffPlaces_d34g0v0_Cancun - - opcD2DiffPlaces_d34g0v0_Cancun - - opcD3DiffPlaces_d34g0v0_Cancun - - opcD4DiffPlaces_d34g0v0_Cancun - - opcD5DiffPlaces_d34g0v0_Cancun - - opcD6DiffPlaces_d34g0v0_Cancun - - opcD7DiffPlaces_d34g0v0_Cancun - - opcD8DiffPlaces_d34g0v0_Cancun - - opcD9DiffPlaces_d34g0v0_Cancun - - opcDADiffPlaces_d34g0v0_Cancun - - opcDBDiffPlaces_d34g0v0_Cancun - - opcDCDiffPlaces_d34g0v0_Cancun - - opcDDDiffPlaces_d34g0v0_Cancun - - opcDEDiffPlaces_d34g0v0_Cancun - - opcDFDiffPlaces_d34g0v0_Cancun - - opcE0DiffPlaces_d34g0v0_Cancun - - opcE1DiffPlaces_d34g0v0_Cancun - - opcE2DiffPlaces_d34g0v0_Cancun - - opcE3DiffPlaces_d34g0v0_Cancun - - opcE4DiffPlaces_d34g0v0_Cancun - - opcE5DiffPlaces_d34g0v0_Cancun - - opcE6DiffPlaces_d34g0v0_Cancun - - opcE7DiffPlaces_d34g0v0_Cancun - - opcE8DiffPlaces_d34g0v0_Cancun - - opcE9DiffPlaces_d34g0v0_Cancun - - opcEADiffPlaces_d34g0v0_Cancun - - opcEBDiffPlaces_d34g0v0_Cancun - - opcECDiffPlaces_d34g0v0_Cancun - - opcEDDiffPlaces_d34g0v0_Cancun - - opcEEDiffPlaces_d34g0v0_Cancun - - opcEFDiffPlaces_d34g0v0_Cancun - - opcF6DiffPlaces_d34g0v0_Cancun - - opcF7DiffPlaces_d34g0v0_Cancun - - opcF8DiffPlaces_d34g0v0_Cancun - - opcF9DiffPlaces_d34g0v0_Cancun - - opcFBDiffPlaces_d34g0v0_Cancun - - opcFCDiffPlaces_d34g0v0_Cancun - - opcFEDiffPlaces_d34g0v0_Cancun - - operationDiffGas_d0g0v0_Cancun - - operationDiffGas_d1g0v0_Cancun - stEIP3860-limitmeterinitcode: - - creationTxInitCodeSizeLimit_d1g0v0_Cancun + - loopExp_d10g0v0_Cancun + - loopExp_d11g0v0_Cancun + - loopExp_d12g0v0_Cancun + - loopExp_d13g0v0_Cancun + - loopExp_d14g0v0_Cancun + - loopExp_d8g0v0_Cancun + - loopExp_d9g0v0_Cancun + - loopMul_d0g0v0_Cancun + - loopMul_d1g0v0_Cancun + - loopMul_d2g0v0_Cancun + - performanceTester_d1g0v0_Cancun + - performanceTester_d4g0v0_Cancun + stAttackTest: + - ContractCreationSpam_d0g0v0_Cancun stCallCreateCallCodeTest: - - Call1024BalanceTooLow_d0g0v0_Cancun - - CallRecursiveBombPreCall_d0g0v0_Cancun - - Callcode1024BalanceTooLow_d0g0v0_Cancun - - createInitFailStackSizeLargerThan1024_d0g0v0_Cancun + - Call1024PreCalls_d0g0v0_Cancun + - Call1024PreCalls_d0g1v0_Cancun stCreate2: - - Create2OnDepth1023_d0g0v0_Cancun - - Create2OnDepth1024_d0g0v0_Cancun - - create2callPrecompiles_d2g0v0_Cancun + - RevertInCreateInInitCreate2Paris_d0g0v0_Cancun + - create2collisionStorageParis_d0g0v0_Cancun + - create2collisionStorageParis_d1g0v0_Cancun + - create2collisionStorageParis_d2g0v0_Cancun stCreateTest: - - CreateOOGafterMaxCodesize_d2g0v0_Cancun - stEIP150Specific: - - Transaction64Rule_integerBoundaries_d0g0v0_Cancun - - Transaction64Rule_integerBoundaries_d10g0v0_Cancun - - Transaction64Rule_integerBoundaries_d11g0v0_Cancun - - Transaction64Rule_integerBoundaries_d1g0v0_Cancun - - Transaction64Rule_integerBoundaries_d2g0v0_Cancun - - Transaction64Rule_integerBoundaries_d3g0v0_Cancun - - Transaction64Rule_integerBoundaries_d4g0v0_Cancun - - Transaction64Rule_integerBoundaries_d5g0v0_Cancun - - Transaction64Rule_integerBoundaries_d6g0v0_Cancun - - Transaction64Rule_integerBoundaries_d7g0v0_Cancun - - Transaction64Rule_integerBoundaries_d8g0v0_Cancun - - Transaction64Rule_integerBoundaries_d9g0v0_Cancun + - CreateOOGafterMaxCodesize_d3g0v0_Cancun + - CreateOOGafterMaxCodesize_d5g0v0_Cancun stDelegatecallTestHomestead: - - Call1024BalanceTooLow_d0g0v0_Cancun - - CallRecursiveBombPreCall_d0g0v0_Cancun - - Delegatecall1024_d0g0v0_Cancun - stEIP150singleCodeGasPrices: - - gasCostJump_d0g0v0_Cancun - - gasCostJump_d1g0v0_Cancun - - gasCostJump_d2g0v0_Cancun - - gasCostReturn_d0g0v0_Cancun - stEIP1559: - - baseFeeDiffPlaces_d34g0v0_Cancun - - gasPriceDiffPlaces_d34g0v0_Cancun + - Call1024PreCalls_d0g0v0_Cancun + - Call1024PreCalls_d0g1v0_Cancun + - Call1024PreCalls_d0g2v0_Cancun stExtCodeHash: - - extCodeHashDynamicArgument_d1g0v0_Cancun - stMemoryTest: - - stackLimitGas_1023_d0g0v0_Cancun - - stackLimitGas_1024_d0g0v0_Cancun - - stackLimitGas_1025_d0g0v0_Cancun - - stackLimitPush31_1023_d0g0v0_Cancun - - stackLimitPush31_1024_d0g0v0_Cancun - - stackLimitPush31_1025_d0g0v0_Cancun - - stackLimitPush32_1023_d0g0v0_Cancun - - stackLimitPush32_1024_d0g0v0_Cancun - - stackLimitPush32_1025_d0g0v0_Cancun + - dynamicAccountOverwriteEmpty_Paris_d0g0v0_Cancun stPreCompiledContracts2: - - CALLCODERipemd160_0_d0g0v0_Cancun - - CALLCODERipemd160_1_d0g0v0_Cancun - - CALLCODERipemd160_2_d0g0v0_Cancun - - CALLCODERipemd160_3_d0g0v0_Cancun - - CALLCODERipemd160_3_postfixed0_d0g0v0_Cancun - - CALLCODERipemd160_3_prefixed0_d0g0v0_Cancun - - CALLCODERipemd160_4_d0g0v0_Cancun - - CALLCODERipemd160_4_gas719_d0g0v0_Cancun - - CallRipemd160_0_d0g0v0_Cancun - - CallRipemd160_1_d0g0v0_Cancun - - CallRipemd160_2_d0g0v0_Cancun - - CallRipemd160_3_d0g0v0_Cancun - - CallRipemd160_3_postfixed0_d0g0v0_Cancun - - CallRipemd160_3_prefixed0_d0g0v0_Cancun - - CallRipemd160_4_d0g0v0_Cancun - - CallRipemd160_4_gas719_d0g0v0_Cancun - - ecrecoverShortBuff_d0g0v0_Cancun - - modexpRandomInput_d2g0v0_Cancun - - modexpRandomInput_d2g1v0_Cancun + - CALLBlake2f_d9g0v0_Cancun + - CALLBlake2f_d9g1v0_Cancun + - CALLBlake2f_d9g2v0_Cancun + - CALLBlake2f_d9g3v0_Cancun + - CALLCODEBlake2f_d9g0v0_Cancun + - CALLCODEBlake2f_d9g1v0_Cancun + - CALLCODEBlake2f_d9g2v0_Cancun + - CALLCODEBlake2f_d9g3v0_Cancun + - CALLCODERipemd160_5_d0g0v0_Cancun + - CallEcrecover_Overflow_d0g0v0_Cancun + - CallEcrecover_Overflow_d4g0v0_Cancun + - CallEcrecover_Overflow_d5g0v0_Cancun + - CallRipemd160_5_d0g0v0_Cancun stPreCompiledContracts: - - idPrecomps_d2g0v0_Cancun - - idPrecomps_d7g0v0_Cancun - - idPrecomps_d9g0v0_Cancun - - precompsEIP2929Cancun_d110g0v0_Cancun - - precompsEIP2929Cancun_d117g0v0_Cancun - - precompsEIP2929Cancun_d128g0v0_Cancun - - precompsEIP2929Cancun_d12g0v0_Cancun - - precompsEIP2929Cancun_d135g0v0_Cancun - - precompsEIP2929Cancun_d146g0v0_Cancun - - precompsEIP2929Cancun_d151g0v0_Cancun - - precompsEIP2929Cancun_d153g0v0_Cancun - - precompsEIP2929Cancun_d164g0v0_Cancun - - precompsEIP2929Cancun_d169g0v0_Cancun - - precompsEIP2929Cancun_d171g0v0_Cancun - - precompsEIP2929Cancun_d182g0v0_Cancun - - precompsEIP2929Cancun_d189g0v0_Cancun - - precompsEIP2929Cancun_d200g0v0_Cancun - - precompsEIP2929Cancun_d207g0v0_Cancun - - precompsEIP2929Cancun_d20g0v0_Cancun - - precompsEIP2929Cancun_d218g0v0_Cancun - - precompsEIP2929Cancun_d225g0v0_Cancun - - precompsEIP2929Cancun_d236g0v0_Cancun - - precompsEIP2929Cancun_d241g0v0_Cancun - - precompsEIP2929Cancun_d243g0v0_Cancun - - precompsEIP2929Cancun_d254g0v0_Cancun - - precompsEIP2929Cancun_d261g0v0_Cancun - - precompsEIP2929Cancun_d272g0v0_Cancun - - precompsEIP2929Cancun_d279g0v0_Cancun - - precompsEIP2929Cancun_d27g0v0_Cancun - - precompsEIP2929Cancun_d290g0v0_Cancun - - precompsEIP2929Cancun_d295g0v0_Cancun - - precompsEIP2929Cancun_d297g0v0_Cancun - - precompsEIP2929Cancun_d308g0v0_Cancun - - precompsEIP2929Cancun_d315g0v0_Cancun - - precompsEIP2929Cancun_d38g0v0_Cancun - - precompsEIP2929Cancun_d43g0v0_Cancun - - precompsEIP2929Cancun_d45g0v0_Cancun - - precompsEIP2929Cancun_d56g0v0_Cancun - - precompsEIP2929Cancun_d5g0v0_Cancun - - precompsEIP2929Cancun_d61g0v0_Cancun - - precompsEIP2929Cancun_d63g0v0_Cancun - - precompsEIP2929Cancun_d74g0v0_Cancun - - precompsEIP2929Cancun_d81g0v0_Cancun - - precompsEIP2929Cancun_d92g0v0_Cancun - - precompsEIP2929Cancun_d99g0v0_Cancun + - modexp_d11g0v0_Cancun + - modexp_d11g1v0_Cancun + - modexp_d11g2v0_Cancun + - modexp_d11g3v0_Cancun + - modexp_d14g0v0_Cancun + - modexp_d14g1v0_Cancun + - modexp_d14g2v0_Cancun + - modexp_d14g3v0_Cancun + - modexp_d16g0v0_Cancun + - modexp_d16g1v0_Cancun + - modexp_d16g2v0_Cancun + - modexp_d16g3v0_Cancun + - modexp_d17g0v0_Cancun + - modexp_d17g1v0_Cancun + - modexp_d17g2v0_Cancun + - modexp_d17g3v0_Cancun + - modexp_d25g0v0_Cancun + - modexp_d25g1v0_Cancun + - modexp_d25g2v0_Cancun + - modexp_d25g3v0_Cancun + - modexp_d26g0v0_Cancun + - modexp_d26g1v0_Cancun + - modexp_d26g2v0_Cancun + - modexp_d26g3v0_Cancun + - modexp_d27g0v0_Cancun + - modexp_d27g1v0_Cancun + - modexp_d27g2v0_Cancun + - modexp_d27g3v0_Cancun + - modexp_d29g0v0_Cancun + - modexp_d29g1v0_Cancun + - modexp_d29g2v0_Cancun + - modexp_d29g3v0_Cancun + - modexp_d30g0v0_Cancun + - modexp_d30g1v0_Cancun + - modexp_d30g2v0_Cancun + - modexp_d30g3v0_Cancun + - modexp_d33g0v0_Cancun + - modexp_d33g1v0_Cancun + - modexp_d33g2v0_Cancun + - modexp_d33g3v0_Cancun + - precompsEIP2929Cancun_d10g0v0_Cancun + - precompsEIP2929Cancun_d115g0v0_Cancun + - precompsEIP2929Cancun_d133g0v0_Cancun + - precompsEIP2929Cancun_d187g0v0_Cancun + - precompsEIP2929Cancun_d205g0v0_Cancun + - precompsEIP2929Cancun_d223g0v0_Cancun + - precompsEIP2929Cancun_d259g0v0_Cancun + - precompsEIP2929Cancun_d25g0v0_Cancun + - precompsEIP2929Cancun_d277g0v0_Cancun + - precompsEIP2929Cancun_d313g0v0_Cancun + - precompsEIP2929Cancun_d79g0v0_Cancun + - precompsEIP2929Cancun_d97g0v0_Cancun stQuadraticComplexityTest: - - Call20KbytesContract50_1_d0g0v0_Cancun - - Call20KbytesContract50_2_d0g0v0_Cancun - - Call20KbytesContract50_3_d0g0v0_Cancun - - Call20KbytesContract50_3_d0g1v0_Cancun + - Call1MB1024Calldepth_d0g1v0_Cancun + - Call20KbytesContract50_1_d0g1v0_Cancun + - Call20KbytesContract50_2_d0g1v0_Cancun + - Call50000_d0g1v0_Cancun + - Call50000_ecrec_d0g1v0_Cancun + - Call50000_identity2_d0g1v0_Cancun + - Call50000_identity_d0g1v0_Cancun + - Call50000_rip160_d0g0v0_Cancun + - Call50000_rip160_d0g1v0_Cancun + - Call50000_sha256_d0g1v0_Cancun + - Callcode50000_d0g1v0_Cancun + - QuadraticComplexitySolidity_CallDataCopy_d0g1v0_Cancun + - Return50000_2_d0g0v0_Cancun + - Return50000_2_d0g1v0_Cancun + - Return50000_d0g0v0_Cancun + - Return50000_d0g1v0_Cancun stRandom2: - - randomStatetest415_d0g0v0_Cancun - - randomStatetest418_d0g0v0_Cancun - - randomStatetest433_d0g0v0_Cancun - - randomStatetest450_d0g0v0_Cancun - - randomStatetest458_d0g0v0_Cancun - - randomStatetest467_d0g0v0_Cancun - - randomStatetest469_d0g0v0_Cancun - - randomStatetest541_d0g0v0_Cancun - - randomStatetest547_d0g0v0_Cancun - - randomStatetest554_d0g0v0_Cancun - - randomStatetest560_d0g0v0_Cancun - - randomStatetest583_d0g0v0_Cancun - - randomStatetest636_d0g0v0_Cancun - - randomStatetest639_d0g0v0_Cancun - - randomStatetest645_d0g0v0_Cancun - - randomStatetest645_d0g0v1_Cancun + - randomStatetest476_d0g0v0_Cancun stRandom: - - randomStatetest111_d0g0v0_Cancun - - randomStatetest124_d0g0v0_Cancun - - randomStatetest14_d0g0v0_Cancun - - randomStatetest150_d0g0v0_Cancun - - randomStatetest154_d0g0v0_Cancun - - randomStatetest178_d0g0v0_Cancun - - randomStatetest211_d0g0v0_Cancun - - randomStatetest260_d0g0v0_Cancun - - randomStatetest306_d0g0v0_Cancun - - randomStatetest308_d0g0v0_Cancun - - randomStatetest343_d0g0v0_Cancun - stReturnDataTest: - - modexp_modsize0_returndatasize_d4g0v0_Cancun - - revertRetDataSize_d0g0v0_Cancun - - revertRetDataSize_d10g0v0_Cancun - - revertRetDataSize_d11g0v0_Cancun - - revertRetDataSize_d12g0v0_Cancun - - revertRetDataSize_d13g0v0_Cancun - - revertRetDataSize_d14g0v0_Cancun - - revertRetDataSize_d15g0v0_Cancun - - revertRetDataSize_d16g0v0_Cancun - - revertRetDataSize_d17g0v0_Cancun - - revertRetDataSize_d18g0v0_Cancun - - revertRetDataSize_d19g0v0_Cancun - - revertRetDataSize_d1g0v0_Cancun - - revertRetDataSize_d20g0v0_Cancun - - revertRetDataSize_d21g0v0_Cancun - - revertRetDataSize_d22g0v0_Cancun - - revertRetDataSize_d23g0v0_Cancun - - revertRetDataSize_d24g0v0_Cancun - - revertRetDataSize_d25g0v0_Cancun - - revertRetDataSize_d26g0v0_Cancun - - revertRetDataSize_d27g0v0_Cancun - - revertRetDataSize_d28g0v0_Cancun - - revertRetDataSize_d29g0v0_Cancun - - revertRetDataSize_d2g0v0_Cancun - - revertRetDataSize_d30g0v0_Cancun - - revertRetDataSize_d31g0v0_Cancun - - revertRetDataSize_d32g0v0_Cancun - - revertRetDataSize_d33g0v0_Cancun - - revertRetDataSize_d34g0v0_Cancun - - revertRetDataSize_d35g0v0_Cancun - - revertRetDataSize_d3g0v0_Cancun - - revertRetDataSize_d4g0v0_Cancun - - revertRetDataSize_d5g0v0_Cancun - - revertRetDataSize_d6g0v0_Cancun - - revertRetDataSize_d7g0v0_Cancun - - revertRetDataSize_d8g0v0_Cancun - - revertRetDataSize_d9g0v0_Cancun + - randomStatetest159_d0g0v0_Cancun + - randomStatetest163_d0g0v0_Cancun + - randomStatetest177_d0g0v0_Cancun + - randomStatetest185_d0g0v0_Cancun + - randomStatetest326_d0g0v0_Cancun + - randomStatetest36_d0g0v0_Cancun + - randomStatetest384_d0g0v0_Cancun + - randomStatetest48_d0g0v0_Cancun stRevertTest: - - LoopCallsDepthThenRevert2_d0g0v0_Cancun - - LoopCallsDepthThenRevert3_d0g0v0_Cancun - - LoopCallsThenRevert_d0g0v0_Cancun - - RevertPrecompiledTouchExactOOG_Paris_d10g1v0_Cancun - - RevertPrecompiledTouchExactOOG_Paris_d10g2v0_Cancun - - RevertPrecompiledTouchExactOOG_Paris_d15g2v0_Cancun - - RevertPrecompiledTouchExactOOG_Paris_d18g1v0_Cancun - - RevertPrecompiledTouchExactOOG_Paris_d18g2v0_Cancun - - RevertPrecompiledTouchExactOOG_Paris_d23g2v0_Cancun - - RevertPrecompiledTouchExactOOG_Paris_d26g1v0_Cancun - - RevertPrecompiledTouchExactOOG_Paris_d26g2v0_Cancun - - RevertPrecompiledTouchExactOOG_Paris_d2g1v0_Cancun - - RevertPrecompiledTouchExactOOG_Paris_d2g2v0_Cancun - - RevertPrecompiledTouchExactOOG_Paris_d31g2v0_Cancun - - RevertPrecompiledTouchExactOOG_Paris_d7g2v0_Cancun - - RevertPrecompiledTouch_Paris_d0g0v0_Cancun - - RevertPrecompiledTouch_Paris_d1g0v0_Cancun - - RevertPrecompiledTouch_Paris_d2g0v0_Cancun - - RevertPrecompiledTouch_Paris_d3g0v0_Cancun - - RevertPrecompiledTouch_nonce_d0g0v0_Cancun - - RevertPrecompiledTouch_nonce_d1g0v0_Cancun - - RevertPrecompiledTouch_nonce_d2g0v0_Cancun - - RevertPrecompiledTouch_nonce_d3g0v0_Cancun - - RevertPrecompiledTouch_noncestorage_d0g0v0_Cancun - - RevertPrecompiledTouch_noncestorage_d1g0v0_Cancun - - RevertPrecompiledTouch_noncestorage_d2g0v0_Cancun - - RevertPrecompiledTouch_noncestorage_d3g0v0_Cancun - - RevertPrecompiledTouch_storage_Paris_d0g0v0_Cancun - - RevertPrecompiledTouch_storage_Paris_d1g0v0_Cancun - - RevertPrecompiledTouch_storage_Paris_d2g0v0_Cancun - - RevertPrecompiledTouch_storage_Paris_d3g0v0_Cancun - - costRevert_d0g0v0_Cancun - - costRevert_d14g0v0_Cancun - - costRevert_d21g0v0_Cancun - - costRevert_d7g0v0_Cancun - - stateRevert_d0g0v0_Cancun + - RevertInCreateInInit_Paris_d0g0v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d15g1v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d23g1v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d31g1v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d7g1v0_Cancun stSStoreTest: - - SstoreCallToSelfSubRefundBelowZero_d0g0v0_Cancun - stSelfBalance: - - diffPlaces_d34g0v0_Cancun - stSolidityTest: - - CallInfiniteLoop_d0g0v0_Cancun - - TestCryptographicFunctions_d0g0v0_Cancun + - InitCollisionParis_d0g0v0_Cancun + - InitCollisionParis_d1g0v0_Cancun + - InitCollisionParis_d2g0v0_Cancun + - InitCollisionParis_d3g0v0_Cancun stSpecialTest: - - JUMPDEST_Attack_d0g0v0_Cancun - - JUMPDEST_AttackwithJump_d0g0v0_Cancun - - block504980_d0g0v0_Cancun - - selfdestructEIP2929_d0g0v0_Cancun - - sha3_deja_d0g0v0_Cancun - stShift: - - shiftCombinations_d0g0v0_Cancun - - shiftSignedCombinations_d0g0v0_Cancun + - failed_tx_xcf416c53_Paris_d0g0v0_Cancun stStaticCall: - - static_Call1024BalanceTooLow2_d1g0v0_Cancun - - static_Call1024BalanceTooLow_d1g0v0_Cancun - - static_Call1024PreCalls2_d0g0v0_Cancun - - static_Call1024PreCalls2_d1g0v0_Cancun - - static_Call1024PreCalls3_d1g0v0_Cancun - - static_Call1024PreCalls_d1g0v0_Cancun - - static_Call50000bytesContract50_3_d0g0v0_Cancun - - static_Call50000bytesContract50_3_d1g0v0_Cancun - - static_CallEcrecover0_0input_d3g0v0_Cancun - - static_CallEcrecover0_0input_d8g0v0_Cancun - - static_CallGoesOOGOnSecondLevel2_d1g0v0_Cancun - - static_CallRecursiveBomb0_OOG_atMaxCallDepth_d0g0v0_Cancun - - static_CallRecursiveBombPreCall2_d0g0v0_Cancun - - static_CallRecursiveBombPreCall_d0g0v0_Cancun - - static_CallRipemd160_1_d0g0v0_Cancun - - static_CallRipemd160_2_d0g0v0_Cancun - - static_CallRipemd160_3_d0g0v0_Cancun - - static_CallRipemd160_3_postfixed0_d0g0v0_Cancun - - static_CallRipemd160_3_prefixed0_d0g0v0_Cancun - - static_CallRipemd160_4_d0g0v0_Cancun - - static_CallRipemd160_4_gas719_d0g0v0_Cancun - - static_LoopCallsDepthThenRevert2_d0g0v0_Cancun - - static_LoopCallsDepthThenRevert3_d0g0v0_Cancun - - static_callChangeRevert_d1g0v0_Cancun - - static_callCreate2_d2g0v0_Cancun - - static_callcallcall_000_OOGMAfter2_d0g0v0_Cancun - - static_callcallcall_000_OOGMBefore_d0g0v0_Cancun - - static_callcallcallcode_001_OOGE_2_d1g0v0_Cancun - - static_callcallcallcode_001_OOGE_d0g0v0_Cancun - - static_callcallcallcode_001_OOGMAfter2_d1g0v0_Cancun - - static_callcallcallcode_001_OOGMAfter_3_d1g0v0_Cancun - - static_callcallcallcode_001_OOGMAfter_d1g0v0_Cancun - - static_callcallcallcode_001_OOGMBefore2_d1g0v0_Cancun - - static_callcallcallcode_001_OOGMBefore_d0g0v0_Cancun - - static_callcallcodecall_010_OOGE_2_d1g0v0_Cancun - - static_callcallcodecall_010_OOGE_d0g0v0_Cancun - - static_callcallcodecall_010_OOGMAfter_2_d1g0v0_Cancun - - static_callcallcodecall_010_OOGMAfter_3_d1g0v0_Cancun - - static_callcallcodecall_010_OOGMAfter_d1g0v0_Cancun - - static_callcallcodecall_010_OOGMBefore2_d0g0v0_Cancun - - static_callcallcodecall_010_OOGMBefore_d1g0v0_Cancun - - static_callcodecallcall_100_OOGMAfter2_d0g0v0_Cancun - - static_callcodecallcall_100_OOGMAfter2_d0g0v1_Cancun - - static_callcodecallcall_100_OOGMAfter_2_d0g0v0_Cancun - - static_callcodecallcallcode_101_OOGE_d0g0v0_Cancun - - static_callcodecallcallcode_101_OOGMAfter_1_d0g0v0_Cancun - stSystemOperationsTest: - - CallRecursiveBomb0_OOG_atMaxCallDepth_d0g0v0_Cancun + - StaticcallToPrecompileFromCalledContract_d0g0v0_Cancun + - StaticcallToPrecompileFromContractInitialization_d0g0v0_Cancun + - StaticcallToPrecompileFromTransaction_d0g0v0_Cancun + - static_Call1MB1024Calldepth_d1g0v0_Cancun + - static_Call50000_d0g0v0_Cancun + - static_Call50000_d1g0v0_Cancun + - static_Call50000_ecrec_d0g0v0_Cancun + - static_Call50000_ecrec_d1g0v0_Cancun + - static_Call50000_identity2_d0g0v0_Cancun + - static_Call50000_identity2_d1g0v0_Cancun + - static_Call50000_identity_d0g0v0_Cancun + - static_Call50000_identity_d1g0v0_Cancun + - static_Call50000_rip160_d0g0v0_Cancun + - static_Call50000_rip160_d1g0v0_Cancun + - static_Call50000bytesContract50_1_d0g0v0_Cancun + - static_Call50000bytesContract50_1_d1g0v0_Cancun + - static_Call50000bytesContract50_2_d0g0v0_Cancun + - static_Call50000bytesContract50_2_d1g0v0_Cancun + - static_CallRipemd160_5_d0g0v0_Cancun + - static_LoopCallsThenRevert_d0g0v0_Cancun + - static_LoopCallsThenRevert_d0g1v0_Cancun + - static_Return50000_2_d0g0v0_Cancun + stStaticFlagEnabled: + - CallWithZeroValueToPrecompileFromCalledContract_d0g0v0_Cancun + - CallWithZeroValueToPrecompileFromContractInitialization_d0g0v0_Cancun + - CallWithZeroValueToPrecompileFromTransaction_d0g0v0_Cancun + - CallcodeToPrecompileFromCalledContract_d0g0v0_Cancun + - CallcodeToPrecompileFromContractInitialization_d0g0v0_Cancun + - CallcodeToPrecompileFromTransaction_d0g0v0_Cancun + - DelegatecallToPrecompileFromCalledContract_d0g0v0_Cancun + - DelegatecallToPrecompileFromContractInitialization_d0g0v0_Cancun + - DelegatecallToPrecompileFromTransaction_d0g0v0_Cancun + stTimeConsuming: + - CALLBlake2f_MaxRounds_d0g0v0_Cancun + - static_Call50000_sha256_d0g0v0_Cancun + - static_Call50000_sha256_d1g0v0_Cancun + stTransactionTest: + - HighGasPriceParis_d0g0v0_Cancun + - ValueOverflowParis_d0g0v0_Cancun stZeroKnowledge: - - ecpairing_bad_length_191_d0g0v0_Cancun - - ecpairing_bad_length_191_d0g1v0_Cancun - - ecpairing_bad_length_191_d0g2v0_Cancun - - ecpairing_bad_length_191_d0g3v0_Cancun - - ecpairing_bad_length_193_d0g0v0_Cancun - - ecpairing_bad_length_193_d0g1v0_Cancun - - ecpairing_bad_length_193_d0g2v0_Cancun - - ecpairing_bad_length_193_d0g3v0_Cancun - - ecpairing_empty_data_d0g1v0_Cancun - - ecpairing_empty_data_d0g2v0_Cancun - - ecpairing_empty_data_insufficient_gas_d0g0v0_Cancun - - ecpairing_empty_data_insufficient_gas_d0g1v0_Cancun - - ecpairing_inputs_d100g0v0_Cancun - - ecpairing_inputs_d101g0v0_Cancun - - ecpairing_inputs_d102g0v0_Cancun - - ecpairing_inputs_d103g0v0_Cancun - - ecpairing_inputs_d104g0v0_Cancun - - ecpairing_inputs_d105g0v0_Cancun - - ecpairing_inputs_d106g0v0_Cancun - - ecpairing_inputs_d107g0v0_Cancun - - ecpairing_inputs_d108g0v0_Cancun - - ecpairing_inputs_d109g0v0_Cancun - - ecpairing_inputs_d110g0v0_Cancun - - ecpairing_inputs_d111g0v0_Cancun - - ecpairing_inputs_d112g0v0_Cancun - - ecpairing_inputs_d113g0v0_Cancun - - ecpairing_inputs_d114g0v0_Cancun - - ecpairing_inputs_d115g0v0_Cancun - - ecpairing_inputs_d116g0v0_Cancun - - ecpairing_inputs_d117g0v0_Cancun - - ecpairing_inputs_d118g0v0_Cancun - - ecpairing_inputs_d119g0v0_Cancun - - ecpairing_inputs_d120g0v0_Cancun - - ecpairing_inputs_d121g0v0_Cancun - - ecpairing_inputs_d122g0v0_Cancun - - ecpairing_inputs_d123g0v0_Cancun - - ecpairing_inputs_d124g0v0_Cancun - - ecpairing_inputs_d125g0v0_Cancun - - ecpairing_inputs_d126g0v0_Cancun - - ecpairing_inputs_d127g0v0_Cancun - - ecpairing_inputs_d128g0v0_Cancun - - ecpairing_inputs_d129g0v0_Cancun - - ecpairing_inputs_d130g0v0_Cancun - - ecpairing_inputs_d131g0v0_Cancun - - ecpairing_inputs_d132g0v0_Cancun - - ecpairing_inputs_d133g0v0_Cancun - - ecpairing_inputs_d134g0v0_Cancun - - ecpairing_inputs_d135g0v0_Cancun - - ecpairing_inputs_d136g0v0_Cancun - - ecpairing_inputs_d137g0v0_Cancun - - ecpairing_inputs_d138g0v0_Cancun - - ecpairing_inputs_d139g0v0_Cancun - - ecpairing_inputs_d140g0v0_Cancun - - ecpairing_inputs_d141g0v0_Cancun - - ecpairing_inputs_d142g0v0_Cancun - - ecpairing_inputs_d143g0v0_Cancun - - ecpairing_inputs_d38g0v0_Cancun - - ecpairing_inputs_d39g0v0_Cancun - - ecpairing_inputs_d40g0v0_Cancun - - ecpairing_inputs_d41g0v0_Cancun - - ecpairing_inputs_d42g0v0_Cancun - - ecpairing_inputs_d43g0v0_Cancun - - ecpairing_inputs_d44g0v0_Cancun - - ecpairing_inputs_d45g0v0_Cancun - - ecpairing_inputs_d46g0v0_Cancun - - ecpairing_inputs_d47g0v0_Cancun - - ecpairing_inputs_d48g0v0_Cancun - - ecpairing_inputs_d49g0v0_Cancun - - ecpairing_inputs_d50g0v0_Cancun - - ecpairing_inputs_d51g0v0_Cancun - - ecpairing_inputs_d52g0v0_Cancun - - ecpairing_inputs_d53g0v0_Cancun - - ecpairing_inputs_d54g0v0_Cancun - - ecpairing_inputs_d55g0v0_Cancun - - ecpairing_inputs_d56g0v0_Cancun - - ecpairing_inputs_d57g0v0_Cancun - - ecpairing_inputs_d58g0v0_Cancun - - ecpairing_inputs_d59g0v0_Cancun - - ecpairing_inputs_d60g0v0_Cancun - - ecpairing_inputs_d61g0v0_Cancun - - ecpairing_inputs_d62g0v0_Cancun - - ecpairing_inputs_d63g0v0_Cancun - - ecpairing_inputs_d64g0v0_Cancun - - ecpairing_inputs_d65g0v0_Cancun - - ecpairing_inputs_d66g0v0_Cancun - - ecpairing_inputs_d67g0v0_Cancun - - ecpairing_inputs_d68g0v0_Cancun - - ecpairing_inputs_d69g0v0_Cancun - - ecpairing_inputs_d70g0v0_Cancun - - ecpairing_inputs_d71g0v0_Cancun - - ecpairing_inputs_d72g0v0_Cancun - - ecpairing_inputs_d73g0v0_Cancun - - ecpairing_inputs_d74g0v0_Cancun - - ecpairing_inputs_d75g0v0_Cancun - - ecpairing_inputs_d76g0v0_Cancun - - ecpairing_inputs_d77g0v0_Cancun - - ecpairing_inputs_d78g0v0_Cancun - - ecpairing_inputs_d79g0v0_Cancun - - ecpairing_inputs_d80g0v0_Cancun - - ecpairing_inputs_d81g0v0_Cancun - - ecpairing_inputs_d82g0v0_Cancun - - ecpairing_inputs_d83g0v0_Cancun - - ecpairing_inputs_d84g0v0_Cancun - - ecpairing_inputs_d85g0v0_Cancun - - ecpairing_inputs_d86g0v0_Cancun - - ecpairing_inputs_d87g0v0_Cancun - - ecpairing_inputs_d88g0v0_Cancun - - ecpairing_inputs_d89g0v0_Cancun - - ecpairing_inputs_d90g0v0_Cancun - - ecpairing_inputs_d91g0v0_Cancun - - ecpairing_inputs_d92g0v0_Cancun - - ecpairing_inputs_d93g0v0_Cancun - - ecpairing_inputs_d94g0v0_Cancun - - ecpairing_inputs_d95g0v0_Cancun - - ecpairing_inputs_d96g0v0_Cancun - - ecpairing_inputs_d97g0v0_Cancun - - ecpairing_inputs_d98g0v0_Cancun - - ecpairing_inputs_d99g0v0_Cancun - - ecpairing_one_point_fail_d0g1v0_Cancun - - ecpairing_one_point_fail_d0g2v0_Cancun - - ecpairing_one_point_insufficient_gas_d0g0v0_Cancun - - ecpairing_one_point_insufficient_gas_d0g1v0_Cancun - - ecpairing_one_point_insufficient_gas_d0g2v0_Cancun - - ecpairing_one_point_not_in_subgroup_d0g0v0_Cancun - - ecpairing_one_point_not_in_subgroup_d0g1v0_Cancun - - ecpairing_one_point_not_in_subgroup_d0g2v0_Cancun - - ecpairing_one_point_not_in_subgroup_d0g3v0_Cancun - - ecpairing_one_point_with_g1_zero_d0g1v0_Cancun - - ecpairing_one_point_with_g1_zero_d0g2v0_Cancun - - ecpairing_one_point_with_g2_zero_and_g1_invalid_d0g0v0_Cancun - - ecpairing_one_point_with_g2_zero_and_g1_invalid_d0g1v0_Cancun - - ecpairing_one_point_with_g2_zero_and_g1_invalid_d0g2v0_Cancun - - ecpairing_one_point_with_g2_zero_and_g1_invalid_d0g3v0_Cancun - - ecpairing_one_point_with_g2_zero_d0g1v0_Cancun - - ecpairing_perturb_g2_by_curve_order_d0g0v0_Cancun - - ecpairing_perturb_g2_by_curve_order_d0g1v0_Cancun - - ecpairing_perturb_g2_by_curve_order_d0g2v0_Cancun - - ecpairing_perturb_g2_by_curve_order_d0g3v0_Cancun - - ecpairing_perturb_g2_by_field_modulus_again_d0g0v0_Cancun - - ecpairing_perturb_g2_by_field_modulus_again_d0g1v0_Cancun - - ecpairing_perturb_g2_by_field_modulus_again_d0g2v0_Cancun - - ecpairing_perturb_g2_by_field_modulus_again_d0g3v0_Cancun - - ecpairing_perturb_g2_by_field_modulus_d0g0v0_Cancun - - ecpairing_perturb_g2_by_field_modulus_d0g1v0_Cancun - - ecpairing_perturb_g2_by_field_modulus_d0g2v0_Cancun - - ecpairing_perturb_g2_by_field_modulus_d0g3v0_Cancun - - ecpairing_perturb_g2_by_one_d0g0v0_Cancun - - ecpairing_perturb_g2_by_one_d0g1v0_Cancun - - ecpairing_perturb_g2_by_one_d0g2v0_Cancun - - ecpairing_perturb_g2_by_one_d0g3v0_Cancun - - ecpairing_perturb_zeropoint_by_curve_order_d0g0v0_Cancun - - ecpairing_perturb_zeropoint_by_curve_order_d0g1v0_Cancun - - ecpairing_perturb_zeropoint_by_curve_order_d0g2v0_Cancun - - ecpairing_perturb_zeropoint_by_curve_order_d0g3v0_Cancun - - ecpairing_perturb_zeropoint_by_field_modulus_d0g0v0_Cancun - - ecpairing_perturb_zeropoint_by_field_modulus_d0g1v0_Cancun - - ecpairing_perturb_zeropoint_by_field_modulus_d0g2v0_Cancun - - ecpairing_perturb_zeropoint_by_field_modulus_d0g3v0_Cancun - - ecpairing_perturb_zeropoint_by_one_d0g0v0_Cancun - - ecpairing_perturb_zeropoint_by_one_d0g1v0_Cancun - - ecpairing_perturb_zeropoint_by_one_d0g2v0_Cancun - - ecpairing_perturb_zeropoint_by_one_d0g3v0_Cancun - - ecpairing_three_point_fail_1_d0g1v0_Cancun - - ecpairing_three_point_fail_1_d0g2v0_Cancun - - ecpairing_three_point_fail_1_d0g3v0_Cancun - - ecpairing_three_point_match_1_d0g1v0_Cancun - - ecpairing_three_point_match_1_d0g2v0_Cancun - - ecpairing_two_point_fail_1_d0g1v0_Cancun - - ecpairing_two_point_fail_1_d0g2v0_Cancun - - ecpairing_two_point_fail_2_d0g1v0_Cancun - - ecpairing_two_point_fail_2_d0g2v0_Cancun - - ecpairing_two_point_fail_2_d0g3v0_Cancun - - ecpairing_two_point_match_1_d0g1v0_Cancun - - ecpairing_two_point_match_1_d0g2v0_Cancun - - ecpairing_two_point_match_1_d0g3v0_Cancun - - ecpairing_two_point_match_2_d0g1v0_Cancun - - ecpairing_two_point_match_2_d0g2v0_Cancun - - ecpairing_two_point_match_3_d0g1v0_Cancun - - ecpairing_two_point_match_3_d0g2v0_Cancun - - ecpairing_two_point_match_4_d0g1v0_Cancun - - ecpairing_two_point_match_4_d0g2v0_Cancun - - ecpairing_two_point_match_5_d0g1v0_Cancun - - ecpairing_two_point_match_5_d0g2v0_Cancun - - ecpairing_two_point_match_5_d0g3v0_Cancun - - ecpairing_two_point_oog_d0g1v0_Cancun - - ecpairing_two_point_oog_d0g2v0_Cancun - - ecpairing_two_points_with_one_g2_zero_d0g1v0_Cancun - - ecpairing_two_points_with_one_g2_zero_d0g2v0_Cancun - - pairingTest_d0g1v0_Cancun - - pairingTest_d0g2v0_Cancun - - pairingTest_d0g3v0_Cancun - - pairingTest_d1g1v0_Cancun - - pairingTest_d1g2v0_Cancun - - pairingTest_d1g3v0_Cancun - - pairingTest_d2g1v0_Cancun - - pairingTest_d2g2v0_Cancun - - pairingTest_d2g3v0_Cancun - - pairingTest_d3g1v0_Cancun - - pairingTest_d3g2v0_Cancun - - pairingTest_d3g3v0_Cancun - - pairingTest_d4g1v0_Cancun - - pairingTest_d4g2v0_Cancun - - pairingTest_d4g3v0_Cancun - - pairingTest_d5g1v0_Cancun - - pairingTest_d5g2v0_Cancun - - pairingTest_d5g3v0_Cancun + - ecpairing_empty_data_d0g0v0_Cancun + - ecpairing_empty_data_d0g3v0_Cancun + - ecpairing_empty_data_insufficient_gas_d0g2v0_Cancun + - ecpairing_inputs_d0g0v0_Cancun + - ecpairing_inputs_d10g0v0_Cancun + - ecpairing_inputs_d11g0v0_Cancun + - ecpairing_inputs_d12g0v0_Cancun + - ecpairing_inputs_d13g0v0_Cancun + - ecpairing_inputs_d14g0v0_Cancun + - ecpairing_inputs_d15g0v0_Cancun + - ecpairing_inputs_d16g0v0_Cancun + - ecpairing_inputs_d17g0v0_Cancun + - ecpairing_inputs_d18g0v0_Cancun + - ecpairing_inputs_d19g0v0_Cancun + - ecpairing_inputs_d1g0v0_Cancun + - ecpairing_inputs_d20g0v0_Cancun + - ecpairing_inputs_d21g0v0_Cancun + - ecpairing_inputs_d22g0v0_Cancun + - ecpairing_inputs_d23g0v0_Cancun + - ecpairing_inputs_d24g0v0_Cancun + - ecpairing_inputs_d25g0v0_Cancun + - ecpairing_inputs_d26g0v0_Cancun + - ecpairing_inputs_d27g0v0_Cancun + - ecpairing_inputs_d28g0v0_Cancun + - ecpairing_inputs_d29g0v0_Cancun + - ecpairing_inputs_d2g0v0_Cancun + - ecpairing_inputs_d30g0v0_Cancun + - ecpairing_inputs_d31g0v0_Cancun + - ecpairing_inputs_d32g0v0_Cancun + - ecpairing_inputs_d33g0v0_Cancun + - ecpairing_inputs_d34g0v0_Cancun + - ecpairing_inputs_d35g0v0_Cancun + - ecpairing_inputs_d36g0v0_Cancun + - ecpairing_inputs_d37g0v0_Cancun + - ecpairing_inputs_d3g0v0_Cancun + - ecpairing_inputs_d4g0v0_Cancun + - ecpairing_inputs_d5g0v0_Cancun + - ecpairing_inputs_d6g0v0_Cancun + - ecpairing_inputs_d7g0v0_Cancun + - ecpairing_inputs_d8g0v0_Cancun + - ecpairing_inputs_d9g0v0_Cancun + - ecpairing_one_point_fail_d0g0v0_Cancun + - ecpairing_one_point_with_g1_zero_d0g0v0_Cancun + - ecpairing_one_point_with_g2_zero_d0g0v0_Cancun + - ecpairing_one_point_with_g2_zero_d0g2v0_Cancun + - ecpairing_one_point_with_g2_zero_d0g3v0_Cancun + - ecpairing_three_point_fail_1_d0g0v0_Cancun + - ecpairing_three_point_match_1_d0g0v0_Cancun + - ecpairing_three_point_match_1_d0g3v0_Cancun + - ecpairing_two_point_fail_1_d0g0v0_Cancun + - ecpairing_two_point_fail_2_d0g0v0_Cancun + - ecpairing_two_point_match_1_d0g0v0_Cancun + - ecpairing_two_point_match_2_d0g0v0_Cancun + - ecpairing_two_point_match_2_d0g3v0_Cancun + - ecpairing_two_point_match_3_d0g0v0_Cancun + - ecpairing_two_point_match_3_d0g3v0_Cancun + - ecpairing_two_point_match_4_d0g0v0_Cancun + - ecpairing_two_point_match_4_d0g3v0_Cancun + - ecpairing_two_point_match_5_d0g0v0_Cancun + - ecpairing_two_point_oog_d0g0v0_Cancun + - ecpairing_two_point_oog_d0g3v0_Cancun + - ecpairing_two_points_with_one_g2_zero_d0g0v0_Cancun + - ecpairing_two_points_with_one_g2_zero_d0g3v0_Cancun + - pairingTest_d0g0v0_Cancun + - pairingTest_d1g0v0_Cancun + - pairingTest_d2g0v0_Cancun + - pairingTest_d3g0v0_Cancun + - pairingTest_d4g0v0_Cancun + - pairingTest_d5g0v0_Cancun From 74bb7a71b2276cf4d639014c8ab37c065b23544c Mon Sep 17 00:00:00 2001 From: Oba Date: Fri, 4 Oct 2024 15:16:49 +0200 Subject: [PATCH 51/56] apply review --- .codespellignore | 4 ---- .gitignore | 13 ++++++------- .markdownlint.json | 8 -------- .prettierrc.json | 3 --- .trunk/configs/.codespellrc | 5 +++++ .trunk/trunk.yaml | 10 ++++++---- Makefile | 2 +- .../crates/utils/src/crypto/modexp/arith.cairo | 4 ++-- .../crates/utils/src/crypto/modexp/mpnat.cairo | 4 ++-- cairo_zero/tests/conftest.py | 6 ------ pyproject.toml | 6 ------ 11 files changed, 22 insertions(+), 43 deletions(-) delete mode 100644 .codespellignore delete mode 100644 .markdownlint.json delete mode 100644 .prettierrc.json create mode 100644 .trunk/configs/.codespellrc diff --git a/.codespellignore b/.codespellignore deleted file mode 100644 index b044176f4..000000000 --- a/.codespellignore +++ /dev/null @@ -1,4 +0,0 @@ -keypair -astroid -uvloop -crate diff --git a/.gitignore b/.gitignore index 1a0132793..b7d3baf47 100644 --- a/.gitignore +++ b/.gitignore @@ -45,13 +45,12 @@ profile*.png *.air_private_input.json *.air_public_input.json -cairo/kakarot-ssj/.DS_Store -cairo/kakarot-ssj/.idea/ -cairo/kakarot-ssj/node_modules/ -cairo/kakarot-ssj/*.snfoundry_cache +.DS_Store +.idea +node_modules +*.snfoundry_cache cairo/kakarot-ssj/target cairo/kakarot-ssj/cache/ cairo/kakarot-ssj/scripts/libcairo_native_runtime.a -cairo/kakarot-ssj/scripts/__pycache__ -cairo/kakarot-ssj/*__pycache__ -cairo/kakarot-ssj/*.snfoundry +__pycache__ +*.snfoundry diff --git a/.markdownlint.json b/.markdownlint.json deleted file mode 100644 index 73c09417e..000000000 --- a/.markdownlint.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "MD033": false, - "MD041": false, - "MD045": false, - "MD013": { - "code_blocks": false - } -} diff --git a/.prettierrc.json b/.prettierrc.json deleted file mode 100644 index 5b5bd9933..000000000 --- a/.prettierrc.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "proseWrap": "always" -} diff --git a/.trunk/configs/.codespellrc b/.trunk/configs/.codespellrc new file mode 100644 index 000000000..e4a1d2d22 --- /dev/null +++ b/.trunk/configs/.codespellrc @@ -0,0 +1,5 @@ +[codespell] +ignore-words-list = keypair,astroid,uvloop,crate +skip = '.git' +check-filenames = +check-hidden = diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index d9c32a905..3a5423cb0 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -67,6 +67,12 @@ lint: paths: [tests, docker] - linters: [codespell] paths: [uv.lock] + - linters: [cairo] + paths: + - cairo/mock_pragma + - cairo/token + - cairo/utils + - cairo/kakarot-ssj/crates - linters: [ALL] paths: - logs* @@ -75,10 +81,6 @@ lint: - tests/ef_tests/test_data - .katana/messaging_config.json - deployments - - cairo/mock_pragma - - cairo/token - - cairo/utils - - cairo/kakarot-ssj/crates - linters: [solidity] paths: - solidity_contracts/src/UniswapV2/**/*.sol diff --git a/Makefile b/Makefile index eda68b149..49593abcf 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ deploy: build build-sol uv run deploy fetch-ef-tests: - uv run python ./kakarot_scripts/ef_tests/fetch.py + uv run ef_tests setup: uv sync --all-extras --dev diff --git a/cairo/kakarot-ssj/crates/utils/src/crypto/modexp/arith.cairo b/cairo/kakarot-ssj/crates/utils/src/crypto/modexp/arith.cairo index d302048a8..95a53bd37 100644 --- a/cairo/kakarot-ssj/crates/utils/src/crypto/modexp/arith.cairo +++ b/cairo/kakarot-ssj/crates/utils/src/crypto/modexp/arith.cairo @@ -240,12 +240,12 @@ pub fn big_wrapping_pow( big_wrapping_mul(ref result, ref tmp, ref scratch_space); result.digits.copy_from_vec_le(ref scratch_space).unwrap(); - scratch_space.reset(); // zero-out the scatch space + scratch_space.reset(); // zero-out the scratch space if (b & mask) != 0 { big_wrapping_mul(ref result, ref base, ref scratch_space); result.digits.copy_from_vec_le(ref scratch_space).unwrap(); - scratch_space.reset(); // zero-out the scatch space + scratch_space.reset(); // zero-out the scratch space } mask = mask.shr(1); diff --git a/cairo/kakarot-ssj/crates/utils/src/crypto/modexp/mpnat.cairo b/cairo/kakarot-ssj/crates/utils/src/crypto/modexp/mpnat.cairo index 6cd2d7fff..2fdefeca3 100644 --- a/cairo/kakarot-ssj/crates/utils/src/crypto/modexp/mpnat.cairo +++ b/cairo/kakarot-ssj/crates/utils/src/crypto/modexp/mpnat.cairo @@ -497,7 +497,7 @@ pub impl MPNatTraitImpl of MPNatTrait { MPNat { digits: out } }; - // Re-use allocation for efficiency + // Reuse allocation for efficiency let mut digits = diff.digits; let s = modulus.digits.len(); digits.reset(); @@ -532,7 +532,7 @@ pub impl MPNatTraitImpl of MPNatTrait { let s = modulus.digits.len; let mut digits = Felt252VecImpl::new(); - // safe unwrap, since intiail length is 0; + // safe unwrap, since initial length is 0; digits.expand(s).unwrap(); let mut x_bar = MPNat { digits }; // Initialize result as `r mod modulus` (Montgomery form of 1) diff --git a/cairo_zero/tests/conftest.py b/cairo_zero/tests/conftest.py index 0b35aca5f..8b116a7c9 100644 --- a/cairo_zero/tests/conftest.py +++ b/cairo_zero/tests/conftest.py @@ -1,12 +1,6 @@ # ruff: noqa: F403 -import sys -from pathlib import Path # Import everything from the root conftest.py from tests.conftest import * from tests.fixtures import * from tests.utils import * - -# Add the project root to the Python path -project_root = Path(__file__).resolve().parent.parent.parent -sys.path.insert(0, str(project_root)) diff --git a/pyproject.toml b/pyproject.toml index b1dbb437e..365ec16ab 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -185,12 +185,6 @@ in_place = true remove_unused_variables = true remove_all_unused_imports = true -[tool.codespell] -ignore-words = '.codespellignore' -skip = '.git' -check-filenames = '' -check-hidden = '' - [tool.bandit] exclude_dirs = ["tests", "cairo_zero/tests"] From d845a168780369182e8d26b68faa0ef3fbc07e23 Mon Sep 17 00:00:00 2001 From: Oba Date: Fri, 4 Oct 2024 16:08:23 +0200 Subject: [PATCH 52/56] fix: ssj script --- cairo/kakarot-ssj/scripts/compute_rlp_encoding.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cairo/kakarot-ssj/scripts/compute_rlp_encoding.ts b/cairo/kakarot-ssj/scripts/compute_rlp_encoding.ts index 692922397..a556f0b33 100644 --- a/cairo/kakarot-ssj/scripts/compute_rlp_encoding.ts +++ b/cairo/kakarot-ssj/scripts/compute_rlp_encoding.ts @@ -24,14 +24,14 @@ const main = async () => { const { Transaction, Wallet } = ethers; const { decodeRlp, getBytes } = ethers; - if (!process.env.PRIVATE_KEY) { + if (!process.env.PRIVATE_KEY_RLP_SCRIPT) { console.log( - "missing private key in environment, please provide PRIVATE_KEY environment variable", + "missing private key in environment, please provide PRIVATE_KEY_RLP_SCRIPT environment variable", ); process.exit(1); } - const wallet = new Wallet(process.env.PRIVATE_KEY); + const wallet = new Wallet(process.env.PRIVATE_KEY_RLP_SCRIPT); console.log("address of the wallet is", wallet.address); let tx_type = parseInt( From 2c8fb607b847837fc449e81b5fc46db67af131d0 Mon Sep 17 00:00:00 2001 From: Oba Date: Fri, 4 Oct 2024 16:48:31 +0200 Subject: [PATCH 53/56] update ssj skip file --- cairo/kakarot-ssj/blockchain-tests-skip.yml | 661 +++++++++++++++++++- 1 file changed, 638 insertions(+), 23 deletions(-) diff --git a/cairo/kakarot-ssj/blockchain-tests-skip.yml b/cairo/kakarot-ssj/blockchain-tests-skip.yml index f6c175d4b..748b39ade 100644 --- a/cairo/kakarot-ssj/blockchain-tests-skip.yml +++ b/cairo/kakarot-ssj/blockchain-tests-skip.yml @@ -21,9 +21,11 @@ regex: testname: stEIP1153-transientStorage: + - transStorageOK_d3g0v0_Cancun - 15_tstoreCannotBeDosd_d0g0v0_Cancun - 21_tstoreCannotBeDosdOOO_d0g0v0_Cancun eip198_modexp_precompile: + - modexp__fork_Cancun_minus_blockchain_test_minus_EIP_minus_198_minus_case3_minus_raw_minus_input_minus_out_minus_of_minus_gas - modexp__fork_Cancun_minus_blockchain_test_minus_EIP_minus_198_minus_case1 - modexp__fork_Cancun_minus_blockchain_test_minus_EIP_minus_198_minus_case2 - modexp__fork_Cancun_minus_blockchain_test_minus_EIP_minus_198_minus_case4_minus_extra_minus_data_07 @@ -39,11 +41,24 @@ testname: - modexp__fork_Cancun_minus_blockchain_test_minus_ModExpInput_base__minus_exponent__minus_modulus_01_minus_ExpectedOutput_call_return_code_0x01_minus_returned_data_0x00 - modexp__fork_Cancun_minus_blockchain_test_minus_ModExpInput_base__minus_exponent__minus_modulus_02_minus_ExpectedOutput_call_return_code_0x01_minus_returned_data_0x01 - modexp__fork_Cancun_minus_blockchain_test_minus_ModExpInput_base__minus_exponent__minus_modulus__minus_ExpectedOutput_call_return_code_0x01_minus_returned_data_0x - tstorage: - - run_until_out_of_gas__fork_Cancun_minus_blockchain_test_minus_tstore - - run_until_out_of_gas__fork_Cancun_minus_blockchain_test_minus_tstore_tload - - run_until_out_of_gas__fork_Cancun_minus_blockchain_test_minus_tstore_wide_address_space + initcode: + - contract_creating_tx__fork_Cancun_minus_blockchain_test_minus_over_limit_ones + - contract_creating_tx__fork_Cancun_minus_blockchain_test_minus_over_limit_zeros + stEIP3651-warmcoinbase: + - coinbaseWarmAccountCallGasFail_d0g0v0_Cancun + vmIOandFlowOperations: + - jump_d5g0v0_Cancun + - jumpi_d9g0v0_Cancun + vmLogTest: + - log0_d0g0v0_Cancun + - log1_d0g0v0_Cancun + - log2_d0g0v0_Cancun + - log3_d0g0v0_Cancun + - log4_d0g0v0_Cancun vmPerformance: + - loopExp_d2g0v0_Cancun + - performanceTester_d0g0v0_Cancun + - performanceTester_d3g0v0_Cancun - loopExp_d10g0v0_Cancun - loopExp_d11g0v0_Cancun - loopExp_d12g0v0_Cancun @@ -56,26 +71,208 @@ testname: - loopMul_d2g0v0_Cancun - performanceTester_d1g0v0_Cancun - performanceTester_d4g0v0_Cancun - stAttackTest: - - ContractCreationSpam_d0g0v0_Cancun + vmTests: + - blockInfo_d2g0v0_Cancun + stBadOpcode: + - invalidDiffPlaces_d34g0v0_Cancun + - opc0CDiffPlaces_d34g0v0_Cancun + - opc0DDiffPlaces_d34g0v0_Cancun + - opc0EDiffPlaces_d34g0v0_Cancun + - opc0FDiffPlaces_d34g0v0_Cancun + - opc1EDiffPlaces_d34g0v0_Cancun + - opc1FDiffPlaces_d34g0v0_Cancun + - opc21DiffPlaces_d34g0v0_Cancun + - opc22DiffPlaces_d34g0v0_Cancun + - opc23DiffPlaces_d34g0v0_Cancun + - opc24DiffPlaces_d34g0v0_Cancun + - opc25DiffPlaces_d34g0v0_Cancun + - opc26DiffPlaces_d34g0v0_Cancun + - opc27DiffPlaces_d34g0v0_Cancun + - opc28DiffPlaces_d34g0v0_Cancun + - opc29DiffPlaces_d34g0v0_Cancun + - opc2ADiffPlaces_d34g0v0_Cancun + - opc2BDiffPlaces_d34g0v0_Cancun + - opc2CDiffPlaces_d34g0v0_Cancun + - opc2DDiffPlaces_d34g0v0_Cancun + - opc2EDiffPlaces_d34g0v0_Cancun + - opc2FDiffPlaces_d34g0v0_Cancun + - opc49DiffPlaces_d34g0v0_Cancun + - opc4ADiffPlaces_d34g0v0_Cancun + - opc4BDiffPlaces_d34g0v0_Cancun + - opc4CDiffPlaces_d34g0v0_Cancun + - opc4DDiffPlaces_d34g0v0_Cancun + - opc4EDiffPlaces_d34g0v0_Cancun + - opc4FDiffPlaces_d34g0v0_Cancun + - opc5CDiffPlaces_d34g0v0_Cancun + - opc5DDiffPlaces_d34g0v0_Cancun + - opc5EDiffPlaces_d34g0v0_Cancun + - opc5FDiffPlaces_d34g0v0_Cancun + - opcA5DiffPlaces_d34g0v0_Cancun + - opcA6DiffPlaces_d34g0v0_Cancun + - opcA7DiffPlaces_d34g0v0_Cancun + - opcA8DiffPlaces_d34g0v0_Cancun + - opcA9DiffPlaces_d34g0v0_Cancun + - opcAADiffPlaces_d34g0v0_Cancun + - opcABDiffPlaces_d34g0v0_Cancun + - opcACDiffPlaces_d34g0v0_Cancun + - opcADDiffPlaces_d34g0v0_Cancun + - opcAEDiffPlaces_d34g0v0_Cancun + - opcAFDiffPlaces_d34g0v0_Cancun + - opcB0DiffPlaces_d34g0v0_Cancun + - opcB1DiffPlaces_d34g0v0_Cancun + - opcB2DiffPlaces_d34g0v0_Cancun + - opcB3DiffPlaces_d34g0v0_Cancun + - opcB4DiffPlaces_d34g0v0_Cancun + - opcB5DiffPlaces_d34g0v0_Cancun + - opcB6DiffPlaces_d34g0v0_Cancun + - opcB7DiffPlaces_d34g0v0_Cancun + - opcB8DiffPlaces_d34g0v0_Cancun + - opcB9DiffPlaces_d34g0v0_Cancun + - opcBADiffPlaces_d34g0v0_Cancun + - opcBBDiffPlaces_d34g0v0_Cancun + - opcBCDiffPlaces_d34g0v0_Cancun + - opcBDDiffPlaces_d34g0v0_Cancun + - opcBEDiffPlaces_d34g0v0_Cancun + - opcBFDiffPlaces_d34g0v0_Cancun + - opcC0DiffPlaces_d34g0v0_Cancun + - opcC1DiffPlaces_d34g0v0_Cancun + - opcC2DiffPlaces_d34g0v0_Cancun + - opcC3DiffPlaces_d34g0v0_Cancun + - opcC4DiffPlaces_d34g0v0_Cancun + - opcC5DiffPlaces_d34g0v0_Cancun + - opcC6DiffPlaces_d34g0v0_Cancun + - opcC7DiffPlaces_d34g0v0_Cancun + - opcC8DiffPlaces_d34g0v0_Cancun + - opcC9DiffPlaces_d34g0v0_Cancun + - opcCADiffPlaces_d34g0v0_Cancun + - opcCBDiffPlaces_d34g0v0_Cancun + - opcCCDiffPlaces_d34g0v0_Cancun + - opcCDDiffPlaces_d34g0v0_Cancun + - opcCEDiffPlaces_d34g0v0_Cancun + - opcCFDiffPlaces_d34g0v0_Cancun + - opcD0DiffPlaces_d34g0v0_Cancun + - opcD1DiffPlaces_d34g0v0_Cancun + - opcD2DiffPlaces_d34g0v0_Cancun + - opcD3DiffPlaces_d34g0v0_Cancun + - opcD4DiffPlaces_d34g0v0_Cancun + - opcD5DiffPlaces_d34g0v0_Cancun + - opcD6DiffPlaces_d34g0v0_Cancun + - opcD7DiffPlaces_d34g0v0_Cancun + - opcD8DiffPlaces_d34g0v0_Cancun + - opcD9DiffPlaces_d34g0v0_Cancun + - opcDADiffPlaces_d34g0v0_Cancun + - opcDBDiffPlaces_d34g0v0_Cancun + - opcDCDiffPlaces_d34g0v0_Cancun + - opcDDDiffPlaces_d34g0v0_Cancun + - opcDEDiffPlaces_d34g0v0_Cancun + - opcDFDiffPlaces_d34g0v0_Cancun + - opcE0DiffPlaces_d34g0v0_Cancun + - opcE1DiffPlaces_d34g0v0_Cancun + - opcE2DiffPlaces_d34g0v0_Cancun + - opcE3DiffPlaces_d34g0v0_Cancun + - opcE4DiffPlaces_d34g0v0_Cancun + - opcE5DiffPlaces_d34g0v0_Cancun + - opcE6DiffPlaces_d34g0v0_Cancun + - opcE7DiffPlaces_d34g0v0_Cancun + - opcE8DiffPlaces_d34g0v0_Cancun + - opcE9DiffPlaces_d34g0v0_Cancun + - opcEADiffPlaces_d34g0v0_Cancun + - opcEBDiffPlaces_d34g0v0_Cancun + - opcECDiffPlaces_d34g0v0_Cancun + - opcEDDiffPlaces_d34g0v0_Cancun + - opcEEDiffPlaces_d34g0v0_Cancun + - opcEFDiffPlaces_d34g0v0_Cancun + - opcF6DiffPlaces_d34g0v0_Cancun + - opcF7DiffPlaces_d34g0v0_Cancun + - opcF8DiffPlaces_d34g0v0_Cancun + - opcF9DiffPlaces_d34g0v0_Cancun + - opcFBDiffPlaces_d34g0v0_Cancun + - opcFCDiffPlaces_d34g0v0_Cancun + - opcFEDiffPlaces_d34g0v0_Cancun + - operationDiffGas_d0g0v0_Cancun + - operationDiffGas_d1g0v0_Cancun + stEIP3860-limitmeterinitcode: + - creationTxInitCodeSizeLimit_d1g0v0_Cancun stCallCreateCallCodeTest: + - Call1024BalanceTooLow_d0g0v0_Cancun + - CallRecursiveBombPreCall_d0g0v0_Cancun + - Callcode1024BalanceTooLow_d0g0v0_Cancun + - createInitFailStackSizeLargerThan1024_d0g0v0_Cancun - Call1024PreCalls_d0g0v0_Cancun - Call1024PreCalls_d0g1v0_Cancun stCreate2: + - Create2OnDepth1023_d0g0v0_Cancun + - Create2OnDepth1024_d0g0v0_Cancun + - create2callPrecompiles_d2g0v0_Cancun - RevertInCreateInInitCreate2Paris_d0g0v0_Cancun - create2collisionStorageParis_d0g0v0_Cancun - create2collisionStorageParis_d1g0v0_Cancun - create2collisionStorageParis_d2g0v0_Cancun stCreateTest: + - CreateOOGafterMaxCodesize_d2g0v0_Cancun - CreateOOGafterMaxCodesize_d3g0v0_Cancun - CreateOOGafterMaxCodesize_d5g0v0_Cancun + stEIP150Specific: + - Transaction64Rule_integerBoundaries_d0g0v0_Cancun + - Transaction64Rule_integerBoundaries_d10g0v0_Cancun + - Transaction64Rule_integerBoundaries_d11g0v0_Cancun + - Transaction64Rule_integerBoundaries_d1g0v0_Cancun + - Transaction64Rule_integerBoundaries_d2g0v0_Cancun + - Transaction64Rule_integerBoundaries_d3g0v0_Cancun + - Transaction64Rule_integerBoundaries_d4g0v0_Cancun + - Transaction64Rule_integerBoundaries_d5g0v0_Cancun + - Transaction64Rule_integerBoundaries_d6g0v0_Cancun + - Transaction64Rule_integerBoundaries_d7g0v0_Cancun + - Transaction64Rule_integerBoundaries_d8g0v0_Cancun + - Transaction64Rule_integerBoundaries_d9g0v0_Cancun stDelegatecallTestHomestead: + - Call1024BalanceTooLow_d0g0v0_Cancun + - CallRecursiveBombPreCall_d0g0v0_Cancun + - Delegatecall1024_d0g0v0_Cancun - Call1024PreCalls_d0g0v0_Cancun - Call1024PreCalls_d0g1v0_Cancun - Call1024PreCalls_d0g2v0_Cancun + stEIP150singleCodeGasPrices: + - gasCostJump_d0g0v0_Cancun + - gasCostJump_d1g0v0_Cancun + - gasCostJump_d2g0v0_Cancun + - gasCostReturn_d0g0v0_Cancun + stEIP1559: + - baseFeeDiffPlaces_d34g0v0_Cancun + - gasPriceDiffPlaces_d34g0v0_Cancun stExtCodeHash: + - extCodeHashDynamicArgument_d1g0v0_Cancun - dynamicAccountOverwriteEmpty_Paris_d0g0v0_Cancun + stMemoryTest: + - stackLimitGas_1023_d0g0v0_Cancun + - stackLimitGas_1024_d0g0v0_Cancun + - stackLimitGas_1025_d0g0v0_Cancun + - stackLimitPush31_1023_d0g0v0_Cancun + - stackLimitPush31_1024_d0g0v0_Cancun + - stackLimitPush31_1025_d0g0v0_Cancun + - stackLimitPush32_1023_d0g0v0_Cancun + - stackLimitPush32_1024_d0g0v0_Cancun + - stackLimitPush32_1025_d0g0v0_Cancun stPreCompiledContracts2: + - CALLCODERipemd160_0_d0g0v0_Cancun + - CALLCODERipemd160_1_d0g0v0_Cancun + - CALLCODERipemd160_2_d0g0v0_Cancun + - CALLCODERipemd160_3_d0g0v0_Cancun + - CALLCODERipemd160_3_postfixed0_d0g0v0_Cancun + - CALLCODERipemd160_3_prefixed0_d0g0v0_Cancun + - CALLCODERipemd160_4_d0g0v0_Cancun + - CALLCODERipemd160_4_gas719_d0g0v0_Cancun + - CallRipemd160_0_d0g0v0_Cancun + - CallRipemd160_1_d0g0v0_Cancun + - CallRipemd160_2_d0g0v0_Cancun + - CallRipemd160_3_d0g0v0_Cancun + - CallRipemd160_3_postfixed0_d0g0v0_Cancun + - CallRipemd160_3_prefixed0_d0g0v0_Cancun + - CallRipemd160_4_d0g0v0_Cancun + - CallRipemd160_4_gas719_d0g0v0_Cancun + - ecrecoverShortBuff_d0g0v0_Cancun + - modexpRandomInput_d2g0v0_Cancun + - modexpRandomInput_d2g1v0_Cancun - CALLBlake2f_d9g0v0_Cancun - CALLBlake2f_d9g1v0_Cancun - CALLBlake2f_d9g2v0_Cancun @@ -90,6 +287,51 @@ testname: - CallEcrecover_Overflow_d5g0v0_Cancun - CallRipemd160_5_d0g0v0_Cancun stPreCompiledContracts: + - idPrecomps_d2g0v0_Cancun + - idPrecomps_d7g0v0_Cancun + - idPrecomps_d9g0v0_Cancun + - precompsEIP2929Cancun_d110g0v0_Cancun + - precompsEIP2929Cancun_d117g0v0_Cancun + - precompsEIP2929Cancun_d128g0v0_Cancun + - precompsEIP2929Cancun_d12g0v0_Cancun + - precompsEIP2929Cancun_d135g0v0_Cancun + - precompsEIP2929Cancun_d146g0v0_Cancun + - precompsEIP2929Cancun_d151g0v0_Cancun + - precompsEIP2929Cancun_d153g0v0_Cancun + - precompsEIP2929Cancun_d164g0v0_Cancun + - precompsEIP2929Cancun_d169g0v0_Cancun + - precompsEIP2929Cancun_d171g0v0_Cancun + - precompsEIP2929Cancun_d182g0v0_Cancun + - precompsEIP2929Cancun_d189g0v0_Cancun + - precompsEIP2929Cancun_d200g0v0_Cancun + - precompsEIP2929Cancun_d207g0v0_Cancun + - precompsEIP2929Cancun_d20g0v0_Cancun + - precompsEIP2929Cancun_d218g0v0_Cancun + - precompsEIP2929Cancun_d225g0v0_Cancun + - precompsEIP2929Cancun_d236g0v0_Cancun + - precompsEIP2929Cancun_d241g0v0_Cancun + - precompsEIP2929Cancun_d243g0v0_Cancun + - precompsEIP2929Cancun_d254g0v0_Cancun + - precompsEIP2929Cancun_d261g0v0_Cancun + - precompsEIP2929Cancun_d272g0v0_Cancun + - precompsEIP2929Cancun_d279g0v0_Cancun + - precompsEIP2929Cancun_d27g0v0_Cancun + - precompsEIP2929Cancun_d290g0v0_Cancun + - precompsEIP2929Cancun_d295g0v0_Cancun + - precompsEIP2929Cancun_d297g0v0_Cancun + - precompsEIP2929Cancun_d308g0v0_Cancun + - precompsEIP2929Cancun_d315g0v0_Cancun + - precompsEIP2929Cancun_d38g0v0_Cancun + - precompsEIP2929Cancun_d43g0v0_Cancun + - precompsEIP2929Cancun_d45g0v0_Cancun + - precompsEIP2929Cancun_d56g0v0_Cancun + - precompsEIP2929Cancun_d5g0v0_Cancun + - precompsEIP2929Cancun_d61g0v0_Cancun + - precompsEIP2929Cancun_d63g0v0_Cancun + - precompsEIP2929Cancun_d74g0v0_Cancun + - precompsEIP2929Cancun_d81g0v0_Cancun + - precompsEIP2929Cancun_d92g0v0_Cancun + - precompsEIP2929Cancun_d99g0v0_Cancun - modexp_d11g0v0_Cancun - modexp_d11g1v0_Cancun - modexp_d11g2v0_Cancun @@ -143,6 +385,10 @@ testname: - precompsEIP2929Cancun_d79g0v0_Cancun - precompsEIP2929Cancun_d97g0v0_Cancun stQuadraticComplexityTest: + - Call20KbytesContract50_1_d0g0v0_Cancun + - Call20KbytesContract50_2_d0g0v0_Cancun + - Call20KbytesContract50_3_d0g0v0_Cancun + - Call20KbytesContract50_3_d0g1v0_Cancun - Call1MB1024Calldepth_d0g1v0_Cancun - Call20KbytesContract50_1_d0g1v0_Cancun - Call20KbytesContract50_2_d0g1v0_Cancun @@ -160,8 +406,30 @@ testname: - Return50000_d0g0v0_Cancun - Return50000_d0g1v0_Cancun stRandom2: + - randomStatetest415_d0g0v0_Cancun + - randomStatetest418_d0g0v0_Cancun + - randomStatetest433_d0g0v0_Cancun + - randomStatetest458_d0g0v0_Cancun + - randomStatetest467_d0g0v0_Cancun + - randomStatetest469_d0g0v0_Cancun + - randomStatetest547_d0g0v0_Cancun + - randomStatetest554_d0g0v0_Cancun + - randomStatetest560_d0g0v0_Cancun + - randomStatetest583_d0g0v0_Cancun + - randomStatetest636_d0g0v0_Cancun + - randomStatetest639_d0g0v0_Cancun + - randomStatetest645_d0g0v0_Cancun + - randomStatetest645_d0g0v1_Cancun - randomStatetest476_d0g0v0_Cancun stRandom: + - randomStatetest111_d0g0v0_Cancun + - randomStatetest14_d0g0v0_Cancun + - randomStatetest150_d0g0v0_Cancun + - randomStatetest154_d0g0v0_Cancun + - randomStatetest178_d0g0v0_Cancun + - randomStatetest211_d0g0v0_Cancun + - randomStatetest260_d0g0v0_Cancun + - randomStatetest306_d0g0v0_Cancun - randomStatetest159_d0g0v0_Cancun - randomStatetest163_d0g0v0_Cancun - randomStatetest177_d0g0v0_Cancun @@ -170,20 +438,153 @@ testname: - randomStatetest36_d0g0v0_Cancun - randomStatetest384_d0g0v0_Cancun - randomStatetest48_d0g0v0_Cancun + stReturnDataTest: + - revertRetDataSize_d0g0v0_Cancun + - revertRetDataSize_d10g0v0_Cancun + - revertRetDataSize_d11g0v0_Cancun + - revertRetDataSize_d12g0v0_Cancun + - revertRetDataSize_d13g0v0_Cancun + - revertRetDataSize_d14g0v0_Cancun + - revertRetDataSize_d15g0v0_Cancun + - revertRetDataSize_d16g0v0_Cancun + - revertRetDataSize_d17g0v0_Cancun + - revertRetDataSize_d18g0v0_Cancun + - revertRetDataSize_d19g0v0_Cancun + - revertRetDataSize_d1g0v0_Cancun + - revertRetDataSize_d20g0v0_Cancun + - revertRetDataSize_d21g0v0_Cancun + - revertRetDataSize_d22g0v0_Cancun + - revertRetDataSize_d23g0v0_Cancun + - revertRetDataSize_d24g0v0_Cancun + - revertRetDataSize_d25g0v0_Cancun + - revertRetDataSize_d26g0v0_Cancun + - revertRetDataSize_d27g0v0_Cancun + - revertRetDataSize_d28g0v0_Cancun + - revertRetDataSize_d29g0v0_Cancun + - revertRetDataSize_d2g0v0_Cancun + - revertRetDataSize_d30g0v0_Cancun + - revertRetDataSize_d31g0v0_Cancun + - revertRetDataSize_d32g0v0_Cancun + - revertRetDataSize_d33g0v0_Cancun + - revertRetDataSize_d34g0v0_Cancun + - revertRetDataSize_d35g0v0_Cancun + - revertRetDataSize_d3g0v0_Cancun + - revertRetDataSize_d4g0v0_Cancun + - revertRetDataSize_d5g0v0_Cancun + - revertRetDataSize_d6g0v0_Cancun + - revertRetDataSize_d7g0v0_Cancun + - revertRetDataSize_d8g0v0_Cancun + - revertRetDataSize_d9g0v0_Cancun stRevertTest: + - LoopCallsDepthThenRevert2_d0g0v0_Cancun + - LoopCallsDepthThenRevert3_d0g0v0_Cancun + - LoopCallsThenRevert_d0g0v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d10g1v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d10g2v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d15g2v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d18g1v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d18g2v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d23g2v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d26g1v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d26g2v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d2g1v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d2g2v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d31g2v0_Cancun + - RevertPrecompiledTouchExactOOG_Paris_d7g2v0_Cancun + - RevertPrecompiledTouch_Paris_d0g0v0_Cancun + - RevertPrecompiledTouch_Paris_d1g0v0_Cancun + - RevertPrecompiledTouch_Paris_d2g0v0_Cancun + - RevertPrecompiledTouch_Paris_d3g0v0_Cancun + - RevertPrecompiledTouch_nonce_d0g0v0_Cancun + - RevertPrecompiledTouch_nonce_d1g0v0_Cancun + - RevertPrecompiledTouch_nonce_d2g0v0_Cancun + - RevertPrecompiledTouch_nonce_d3g0v0_Cancun + - RevertPrecompiledTouch_noncestorage_d0g0v0_Cancun + - RevertPrecompiledTouch_noncestorage_d1g0v0_Cancun + - RevertPrecompiledTouch_noncestorage_d2g0v0_Cancun + - RevertPrecompiledTouch_noncestorage_d3g0v0_Cancun + - RevertPrecompiledTouch_storage_Paris_d0g0v0_Cancun + - RevertPrecompiledTouch_storage_Paris_d1g0v0_Cancun + - RevertPrecompiledTouch_storage_Paris_d2g0v0_Cancun + - RevertPrecompiledTouch_storage_Paris_d3g0v0_Cancun + - costRevert_d0g0v0_Cancun + - costRevert_d14g0v0_Cancun + - costRevert_d21g0v0_Cancun + - costRevert_d7g0v0_Cancun + - stateRevert_d0g0v0_Cancun - RevertInCreateInInit_Paris_d0g0v0_Cancun - RevertPrecompiledTouchExactOOG_Paris_d15g1v0_Cancun - RevertPrecompiledTouchExactOOG_Paris_d23g1v0_Cancun - RevertPrecompiledTouchExactOOG_Paris_d31g1v0_Cancun - RevertPrecompiledTouchExactOOG_Paris_d7g1v0_Cancun stSStoreTest: + - SstoreCallToSelfSubRefundBelowZero_d0g0v0_Cancun - InitCollisionParis_d0g0v0_Cancun - InitCollisionParis_d1g0v0_Cancun - InitCollisionParis_d2g0v0_Cancun - InitCollisionParis_d3g0v0_Cancun + stSelfBalance: + - diffPlaces_d34g0v0_Cancun + stSolidityTest: + - CallInfiniteLoop_d0g0v0_Cancun + - TestCryptographicFunctions_d0g0v0_Cancun stSpecialTest: + - JUMPDEST_Attack_d0g0v0_Cancun + - JUMPDEST_AttackwithJump_d0g0v0_Cancun + - block504980_d0g0v0_Cancun + - selfdestructEIP2929_d0g0v0_Cancun + - sha3_deja_d0g0v0_Cancun - failed_tx_xcf416c53_Paris_d0g0v0_Cancun + stShift: + - shiftCombinations_d0g0v0_Cancun + - shiftSignedCombinations_d0g0v0_Cancun stStaticCall: + - static_Call1024BalanceTooLow2_d1g0v0_Cancun + - static_Call1024BalanceTooLow_d1g0v0_Cancun + - static_Call1024PreCalls2_d0g0v0_Cancun + - static_Call1024PreCalls2_d1g0v0_Cancun + - static_Call1024PreCalls3_d1g0v0_Cancun + - static_Call1024PreCalls_d1g0v0_Cancun + - static_Call50000bytesContract50_3_d0g0v0_Cancun + - static_Call50000bytesContract50_3_d1g0v0_Cancun + - static_CallEcrecover0_0input_d3g0v0_Cancun + - static_CallEcrecover0_0input_d8g0v0_Cancun + - static_CallGoesOOGOnSecondLevel2_d1g0v0_Cancun + - static_CallRecursiveBomb0_OOG_atMaxCallDepth_d0g0v0_Cancun + - static_CallRecursiveBombPreCall2_d0g0v0_Cancun + - static_CallRecursiveBombPreCall_d0g0v0_Cancun + - static_CallRipemd160_1_d0g0v0_Cancun + - static_CallRipemd160_2_d0g0v0_Cancun + - static_CallRipemd160_3_d0g0v0_Cancun + - static_CallRipemd160_3_postfixed0_d0g0v0_Cancun + - static_CallRipemd160_3_prefixed0_d0g0v0_Cancun + - static_CallRipemd160_4_d0g0v0_Cancun + - static_CallRipemd160_4_gas719_d0g0v0_Cancun + - static_LoopCallsDepthThenRevert2_d0g0v0_Cancun + - static_LoopCallsDepthThenRevert3_d0g0v0_Cancun + - static_callChangeRevert_d1g0v0_Cancun + - static_callCreate2_d2g0v0_Cancun + - static_callcallcall_000_OOGMAfter2_d0g0v0_Cancun + - static_callcallcall_000_OOGMBefore_d0g0v0_Cancun + - static_callcallcallcode_001_OOGE_2_d1g0v0_Cancun + - static_callcallcallcode_001_OOGE_d0g0v0_Cancun + - static_callcallcallcode_001_OOGMAfter2_d1g0v0_Cancun + - static_callcallcallcode_001_OOGMAfter_3_d1g0v0_Cancun + - static_callcallcallcode_001_OOGMAfter_d1g0v0_Cancun + - static_callcallcallcode_001_OOGMBefore2_d1g0v0_Cancun + - static_callcallcallcode_001_OOGMBefore_d0g0v0_Cancun + - static_callcallcodecall_010_OOGE_2_d1g0v0_Cancun + - static_callcallcodecall_010_OOGE_d0g0v0_Cancun + - static_callcallcodecall_010_OOGMAfter_2_d1g0v0_Cancun + - static_callcallcodecall_010_OOGMAfter_3_d1g0v0_Cancun + - static_callcallcodecall_010_OOGMAfter_d1g0v0_Cancun + - static_callcallcodecall_010_OOGMBefore2_d0g0v0_Cancun + - static_callcallcodecall_010_OOGMBefore_d1g0v0_Cancun + - static_callcodecallcall_100_OOGMAfter2_d0g0v0_Cancun + - static_callcodecallcall_100_OOGMAfter2_d0g0v1_Cancun + - static_callcodecallcall_100_OOGMAfter_2_d0g0v0_Cancun + - static_callcodecallcallcode_101_OOGE_d0g0v0_Cancun + - static_callcodecallcallcode_101_OOGMAfter_1_d0g0v0_Cancun - StaticcallToPrecompileFromCalledContract_d0g0v0_Cancun - StaticcallToPrecompileFromContractInitialization_d0g0v0_Cancun - StaticcallToPrecompileFromTransaction_d0g0v0_Cancun @@ -206,24 +607,215 @@ testname: - static_LoopCallsThenRevert_d0g0v0_Cancun - static_LoopCallsThenRevert_d0g1v0_Cancun - static_Return50000_2_d0g0v0_Cancun - stStaticFlagEnabled: - - CallWithZeroValueToPrecompileFromCalledContract_d0g0v0_Cancun - - CallWithZeroValueToPrecompileFromContractInitialization_d0g0v0_Cancun - - CallWithZeroValueToPrecompileFromTransaction_d0g0v0_Cancun - - CallcodeToPrecompileFromCalledContract_d0g0v0_Cancun - - CallcodeToPrecompileFromContractInitialization_d0g0v0_Cancun - - CallcodeToPrecompileFromTransaction_d0g0v0_Cancun - - DelegatecallToPrecompileFromCalledContract_d0g0v0_Cancun - - DelegatecallToPrecompileFromContractInitialization_d0g0v0_Cancun - - DelegatecallToPrecompileFromTransaction_d0g0v0_Cancun - stTimeConsuming: - - CALLBlake2f_MaxRounds_d0g0v0_Cancun - - static_Call50000_sha256_d0g0v0_Cancun - - static_Call50000_sha256_d1g0v0_Cancun - stTransactionTest: - - HighGasPriceParis_d0g0v0_Cancun - - ValueOverflowParis_d0g0v0_Cancun + stSystemOperationsTest: + - CallRecursiveBomb0_OOG_atMaxCallDepth_d0g0v0_Cancun stZeroKnowledge: + - ecpairing_bad_length_191_d0g0v0_Cancun + - ecpairing_bad_length_191_d0g1v0_Cancun + - ecpairing_bad_length_191_d0g2v0_Cancun + - ecpairing_bad_length_191_d0g3v0_Cancun + - ecpairing_bad_length_193_d0g0v0_Cancun + - ecpairing_bad_length_193_d0g1v0_Cancun + - ecpairing_bad_length_193_d0g2v0_Cancun + - ecpairing_bad_length_193_d0g3v0_Cancun + - ecpairing_empty_data_d0g1v0_Cancun + - ecpairing_empty_data_d0g2v0_Cancun + - ecpairing_empty_data_insufficient_gas_d0g0v0_Cancun + - ecpairing_empty_data_insufficient_gas_d0g1v0_Cancun + - ecpairing_inputs_d100g0v0_Cancun + - ecpairing_inputs_d101g0v0_Cancun + - ecpairing_inputs_d102g0v0_Cancun + - ecpairing_inputs_d103g0v0_Cancun + - ecpairing_inputs_d104g0v0_Cancun + - ecpairing_inputs_d105g0v0_Cancun + - ecpairing_inputs_d106g0v0_Cancun + - ecpairing_inputs_d107g0v0_Cancun + - ecpairing_inputs_d108g0v0_Cancun + - ecpairing_inputs_d109g0v0_Cancun + - ecpairing_inputs_d110g0v0_Cancun + - ecpairing_inputs_d111g0v0_Cancun + - ecpairing_inputs_d112g0v0_Cancun + - ecpairing_inputs_d113g0v0_Cancun + - ecpairing_inputs_d114g0v0_Cancun + - ecpairing_inputs_d115g0v0_Cancun + - ecpairing_inputs_d116g0v0_Cancun + - ecpairing_inputs_d117g0v0_Cancun + - ecpairing_inputs_d118g0v0_Cancun + - ecpairing_inputs_d119g0v0_Cancun + - ecpairing_inputs_d120g0v0_Cancun + - ecpairing_inputs_d121g0v0_Cancun + - ecpairing_inputs_d122g0v0_Cancun + - ecpairing_inputs_d123g0v0_Cancun + - ecpairing_inputs_d124g0v0_Cancun + - ecpairing_inputs_d125g0v0_Cancun + - ecpairing_inputs_d126g0v0_Cancun + - ecpairing_inputs_d127g0v0_Cancun + - ecpairing_inputs_d128g0v0_Cancun + - ecpairing_inputs_d129g0v0_Cancun + - ecpairing_inputs_d130g0v0_Cancun + - ecpairing_inputs_d131g0v0_Cancun + - ecpairing_inputs_d132g0v0_Cancun + - ecpairing_inputs_d133g0v0_Cancun + - ecpairing_inputs_d134g0v0_Cancun + - ecpairing_inputs_d135g0v0_Cancun + - ecpairing_inputs_d136g0v0_Cancun + - ecpairing_inputs_d137g0v0_Cancun + - ecpairing_inputs_d138g0v0_Cancun + - ecpairing_inputs_d139g0v0_Cancun + - ecpairing_inputs_d140g0v0_Cancun + - ecpairing_inputs_d141g0v0_Cancun + - ecpairing_inputs_d142g0v0_Cancun + - ecpairing_inputs_d143g0v0_Cancun + - ecpairing_inputs_d38g0v0_Cancun + - ecpairing_inputs_d39g0v0_Cancun + - ecpairing_inputs_d40g0v0_Cancun + - ecpairing_inputs_d41g0v0_Cancun + - ecpairing_inputs_d42g0v0_Cancun + - ecpairing_inputs_d43g0v0_Cancun + - ecpairing_inputs_d44g0v0_Cancun + - ecpairing_inputs_d45g0v0_Cancun + - ecpairing_inputs_d46g0v0_Cancun + - ecpairing_inputs_d47g0v0_Cancun + - ecpairing_inputs_d48g0v0_Cancun + - ecpairing_inputs_d49g0v0_Cancun + - ecpairing_inputs_d50g0v0_Cancun + - ecpairing_inputs_d51g0v0_Cancun + - ecpairing_inputs_d52g0v0_Cancun + - ecpairing_inputs_d53g0v0_Cancun + - ecpairing_inputs_d54g0v0_Cancun + - ecpairing_inputs_d55g0v0_Cancun + - ecpairing_inputs_d56g0v0_Cancun + - ecpairing_inputs_d57g0v0_Cancun + - ecpairing_inputs_d58g0v0_Cancun + - ecpairing_inputs_d59g0v0_Cancun + - ecpairing_inputs_d60g0v0_Cancun + - ecpairing_inputs_d61g0v0_Cancun + - ecpairing_inputs_d62g0v0_Cancun + - ecpairing_inputs_d63g0v0_Cancun + - ecpairing_inputs_d64g0v0_Cancun + - ecpairing_inputs_d65g0v0_Cancun + - ecpairing_inputs_d66g0v0_Cancun + - ecpairing_inputs_d67g0v0_Cancun + - ecpairing_inputs_d68g0v0_Cancun + - ecpairing_inputs_d69g0v0_Cancun + - ecpairing_inputs_d70g0v0_Cancun + - ecpairing_inputs_d71g0v0_Cancun + - ecpairing_inputs_d72g0v0_Cancun + - ecpairing_inputs_d73g0v0_Cancun + - ecpairing_inputs_d74g0v0_Cancun + - ecpairing_inputs_d75g0v0_Cancun + - ecpairing_inputs_d76g0v0_Cancun + - ecpairing_inputs_d77g0v0_Cancun + - ecpairing_inputs_d78g0v0_Cancun + - ecpairing_inputs_d79g0v0_Cancun + - ecpairing_inputs_d80g0v0_Cancun + - ecpairing_inputs_d81g0v0_Cancun + - ecpairing_inputs_d82g0v0_Cancun + - ecpairing_inputs_d83g0v0_Cancun + - ecpairing_inputs_d84g0v0_Cancun + - ecpairing_inputs_d85g0v0_Cancun + - ecpairing_inputs_d86g0v0_Cancun + - ecpairing_inputs_d87g0v0_Cancun + - ecpairing_inputs_d88g0v0_Cancun + - ecpairing_inputs_d89g0v0_Cancun + - ecpairing_inputs_d90g0v0_Cancun + - ecpairing_inputs_d91g0v0_Cancun + - ecpairing_inputs_d92g0v0_Cancun + - ecpairing_inputs_d93g0v0_Cancun + - ecpairing_inputs_d94g0v0_Cancun + - ecpairing_inputs_d95g0v0_Cancun + - ecpairing_inputs_d96g0v0_Cancun + - ecpairing_inputs_d97g0v0_Cancun + - ecpairing_inputs_d98g0v0_Cancun + - ecpairing_inputs_d99g0v0_Cancun + - ecpairing_one_point_fail_d0g1v0_Cancun + - ecpairing_one_point_fail_d0g2v0_Cancun + - ecpairing_one_point_insufficient_gas_d0g0v0_Cancun + - ecpairing_one_point_insufficient_gas_d0g1v0_Cancun + - ecpairing_one_point_insufficient_gas_d0g2v0_Cancun + - ecpairing_one_point_not_in_subgroup_d0g0v0_Cancun + - ecpairing_one_point_not_in_subgroup_d0g1v0_Cancun + - ecpairing_one_point_not_in_subgroup_d0g2v0_Cancun + - ecpairing_one_point_not_in_subgroup_d0g3v0_Cancun + - ecpairing_one_point_with_g1_zero_d0g1v0_Cancun + - ecpairing_one_point_with_g1_zero_d0g2v0_Cancun + - ecpairing_one_point_with_g2_zero_and_g1_invalid_d0g0v0_Cancun + - ecpairing_one_point_with_g2_zero_and_g1_invalid_d0g1v0_Cancun + - ecpairing_one_point_with_g2_zero_and_g1_invalid_d0g2v0_Cancun + - ecpairing_one_point_with_g2_zero_and_g1_invalid_d0g3v0_Cancun + - ecpairing_one_point_with_g2_zero_d0g1v0_Cancun + - ecpairing_perturb_g2_by_curve_order_d0g0v0_Cancun + - ecpairing_perturb_g2_by_curve_order_d0g1v0_Cancun + - ecpairing_perturb_g2_by_curve_order_d0g2v0_Cancun + - ecpairing_perturb_g2_by_curve_order_d0g3v0_Cancun + - ecpairing_perturb_g2_by_field_modulus_again_d0g0v0_Cancun + - ecpairing_perturb_g2_by_field_modulus_again_d0g1v0_Cancun + - ecpairing_perturb_g2_by_field_modulus_again_d0g2v0_Cancun + - ecpairing_perturb_g2_by_field_modulus_again_d0g3v0_Cancun + - ecpairing_perturb_g2_by_field_modulus_d0g0v0_Cancun + - ecpairing_perturb_g2_by_field_modulus_d0g1v0_Cancun + - ecpairing_perturb_g2_by_field_modulus_d0g2v0_Cancun + - ecpairing_perturb_g2_by_field_modulus_d0g3v0_Cancun + - ecpairing_perturb_g2_by_one_d0g0v0_Cancun + - ecpairing_perturb_g2_by_one_d0g1v0_Cancun + - ecpairing_perturb_g2_by_one_d0g2v0_Cancun + - ecpairing_perturb_g2_by_one_d0g3v0_Cancun + - ecpairing_perturb_zeropoint_by_curve_order_d0g0v0_Cancun + - ecpairing_perturb_zeropoint_by_curve_order_d0g1v0_Cancun + - ecpairing_perturb_zeropoint_by_curve_order_d0g2v0_Cancun + - ecpairing_perturb_zeropoint_by_curve_order_d0g3v0_Cancun + - ecpairing_perturb_zeropoint_by_field_modulus_d0g0v0_Cancun + - ecpairing_perturb_zeropoint_by_field_modulus_d0g1v0_Cancun + - ecpairing_perturb_zeropoint_by_field_modulus_d0g2v0_Cancun + - ecpairing_perturb_zeropoint_by_field_modulus_d0g3v0_Cancun + - ecpairing_perturb_zeropoint_by_one_d0g0v0_Cancun + - ecpairing_perturb_zeropoint_by_one_d0g1v0_Cancun + - ecpairing_perturb_zeropoint_by_one_d0g2v0_Cancun + - ecpairing_perturb_zeropoint_by_one_d0g3v0_Cancun + - ecpairing_three_point_fail_1_d0g1v0_Cancun + - ecpairing_three_point_fail_1_d0g2v0_Cancun + - ecpairing_three_point_fail_1_d0g3v0_Cancun + - ecpairing_three_point_match_1_d0g1v0_Cancun + - ecpairing_three_point_match_1_d0g2v0_Cancun + - ecpairing_two_point_fail_1_d0g1v0_Cancun + - ecpairing_two_point_fail_1_d0g2v0_Cancun + - ecpairing_two_point_fail_2_d0g1v0_Cancun + - ecpairing_two_point_fail_2_d0g2v0_Cancun + - ecpairing_two_point_fail_2_d0g3v0_Cancun + - ecpairing_two_point_match_1_d0g1v0_Cancun + - ecpairing_two_point_match_1_d0g2v0_Cancun + - ecpairing_two_point_match_1_d0g3v0_Cancun + - ecpairing_two_point_match_2_d0g1v0_Cancun + - ecpairing_two_point_match_2_d0g2v0_Cancun + - ecpairing_two_point_match_3_d0g1v0_Cancun + - ecpairing_two_point_match_3_d0g2v0_Cancun + - ecpairing_two_point_match_4_d0g1v0_Cancun + - ecpairing_two_point_match_4_d0g2v0_Cancun + - ecpairing_two_point_match_5_d0g1v0_Cancun + - ecpairing_two_point_match_5_d0g2v0_Cancun + - ecpairing_two_point_match_5_d0g3v0_Cancun + - ecpairing_two_point_oog_d0g1v0_Cancun + - ecpairing_two_point_oog_d0g2v0_Cancun + - ecpairing_two_points_with_one_g2_zero_d0g1v0_Cancun + - ecpairing_two_points_with_one_g2_zero_d0g2v0_Cancun + - pairingTest_d0g1v0_Cancun + - pairingTest_d0g2v0_Cancun + - pairingTest_d0g3v0_Cancun + - pairingTest_d1g1v0_Cancun + - pairingTest_d1g2v0_Cancun + - pairingTest_d1g3v0_Cancun + - pairingTest_d2g1v0_Cancun + - pairingTest_d2g2v0_Cancun + - pairingTest_d2g3v0_Cancun + - pairingTest_d3g1v0_Cancun + - pairingTest_d3g2v0_Cancun + - pairingTest_d3g3v0_Cancun + - pairingTest_d4g1v0_Cancun + - pairingTest_d4g2v0_Cancun + - pairingTest_d4g3v0_Cancun + - pairingTest_d5g1v0_Cancun + - pairingTest_d5g2v0_Cancun + - pairingTest_d5g3v0_Cancun - ecpairing_empty_data_d0g0v0_Cancun - ecpairing_empty_data_d0g3v0_Cancun - ecpairing_empty_data_insufficient_gas_d0g2v0_Cancun @@ -293,3 +885,26 @@ testname: - pairingTest_d3g0v0_Cancun - pairingTest_d4g0v0_Cancun - pairingTest_d5g0v0_Cancun + tstorage: + - run_until_out_of_gas__fork_Cancun_minus_blockchain_test_minus_tstore + - run_until_out_of_gas__fork_Cancun_minus_blockchain_test_minus_tstore_tload + - run_until_out_of_gas__fork_Cancun_minus_blockchain_test_minus_tstore_wide_address_space + stAttackTest: + - ContractCreationSpam_d0g0v0_Cancun + stStaticFlagEnabled: + - CallWithZeroValueToPrecompileFromCalledContract_d0g0v0_Cancun + - CallWithZeroValueToPrecompileFromContractInitialization_d0g0v0_Cancun + - CallWithZeroValueToPrecompileFromTransaction_d0g0v0_Cancun + - CallcodeToPrecompileFromCalledContract_d0g0v0_Cancun + - CallcodeToPrecompileFromContractInitialization_d0g0v0_Cancun + - CallcodeToPrecompileFromTransaction_d0g0v0_Cancun + - DelegatecallToPrecompileFromCalledContract_d0g0v0_Cancun + - DelegatecallToPrecompileFromContractInitialization_d0g0v0_Cancun + - DelegatecallToPrecompileFromTransaction_d0g0v0_Cancun + stTimeConsuming: + - CALLBlake2f_MaxRounds_d0g0v0_Cancun + - static_Call50000_sha256_d0g0v0_Cancun + - static_Call50000_sha256_d1g0v0_Cancun + stTransactionTest: + - HighGasPriceParis_d0g0v0_Cancun + - ValueOverflowParis_d0g0v0_Cancun From c68f5934989e2a54942e034f5a70a8eedfc6dcef Mon Sep 17 00:00:00 2001 From: Oba Date: Mon, 7 Oct 2024 10:25:13 +0200 Subject: [PATCH 54/56] fix ef-tests resources --- .github/workflows/ssj-ef-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ssj-ef-tests.yml b/.github/workflows/ssj-ef-tests.yml index 2814f2c7d..6af3f2914 100644 --- a/.github/workflows/ssj-ef-tests.yml +++ b/.github/workflows/ssj-ef-tests.yml @@ -101,7 +101,7 @@ jobs: working-directory: ef-tests run: | set -o pipefail - RUST_MIN_STACK=1342177280 make ef-test-v1-native | tee data.txt + RUST_MIN_STACK=1342177280 make ef-test-v1-native | tee test_v1.out set +o pipefail - name: Retrieve ef-tests execution resources From 8bdf75b3b353b711ae71edac938d297fb37e820e Mon Sep 17 00:00:00 2001 From: Oba Date: Mon, 7 Oct 2024 11:55:13 +0200 Subject: [PATCH 55/56] update ssj --- .../contracts/src/account_contract.cairo | 13 +- .../contracts/src/kakarot_core/eth_rpc.cairo | 158 ++++++++++++------ .../src/kakarot_core/interface.cairo | 27 +-- .../contracts/src/kakarot_core/kakarot.cairo | 36 ++-- .../crates/contracts/src/test_utils.cairo | 1 - .../tests/test_execution_from_outside.cairo | 33 +--- .../contracts/tests/test_kakarot_core.cairo | 39 +++-- .../evm/src/backend/starknet_backend.cairo | 2 +- .../crates/evm/src/call_helpers.cairo | 6 +- .../crates/evm/src/interpreter.cairo | 4 +- .../crates/evm/src/model/account.cairo | 25 ++- .../src/eth_transaction/transaction.cairo | 114 +++++-------- 12 files changed, 236 insertions(+), 222 deletions(-) diff --git a/cairo/kakarot-ssj/crates/contracts/src/account_contract.cairo b/cairo/kakarot-ssj/crates/contracts/src/account_contract.cairo index 9391ac4db..5de99dd12 100644 --- a/cairo/kakarot-ssj/crates/contracts/src/account_contract.cairo +++ b/cairo/kakarot-ssj/crates/contracts/src/account_contract.cairo @@ -68,7 +68,7 @@ pub mod AccountContract { use crate::storage::StorageBytecode; use openzeppelin::token::erc20::interface::{IERC20CamelDispatcher, IERC20CamelDispatcherTrait}; use super::OutsideExecution; - use utils::eth_transaction::transaction::TransactionUnsignedTrait; + use utils::eth_transaction::transaction::TransactionTrait; use utils::serialization::{deserialize_signature, deserialize_bytes, serialize_bytes}; use utils::traits::DefaultSignature; @@ -249,18 +249,13 @@ pub mod AccountContract { let mut encoded_tx_data = deserialize_bytes((*outside_execution.calls[0]).calldata) .expect('conversion to Span failed') .span(); - let unsigned_transaction = TransactionUnsignedTrait::decode_enveloped( - ref encoded_tx_data - ) - .expect('EOA: could not decode tx'); + let unsigned_transaction_hash = TransactionTrait::compute_hash(encoded_tx_data); let address = self.Account_evm_address.read(); - verify_eth_signature(unsigned_transaction.hash, signature, address); + verify_eth_signature(unsigned_transaction_hash, signature, address); - //TODO: refactor this to call eth_send_raw_unsigned_tx. Only the transactions bytes are - //passed. let (success, return_data, gas_used) = kakarot - .eth_send_transaction(unsigned_transaction.transaction); + .eth_send_raw_unsigned_tx(encoded_tx_data); let return_data = serialize_bytes(return_data).span(); // See Argent account diff --git a/cairo/kakarot-ssj/crates/contracts/src/kakarot_core/eth_rpc.cairo b/cairo/kakarot-ssj/crates/contracts/src/kakarot_core/eth_rpc.cairo index 8e98b20e4..b5259b65d 100644 --- a/cairo/kakarot-ssj/crates/contracts/src/kakarot_core/eth_rpc.cairo +++ b/cairo/kakarot-ssj/crates/contracts/src/kakarot_core/eth_rpc.cairo @@ -1,16 +1,17 @@ use core::num::traits::Zero; use core::starknet::get_tx_info; -use core::starknet::{EthAddress, get_caller_address}; +use core::starknet::{EthAddress, get_caller_address, ContractAddress}; use crate::account_contract::{IAccountDispatcher, IAccountDispatcherTrait}; use crate::kakarot_core::interface::IKakarotCore; use crate::kakarot_core::kakarot::{KakarotCore, KakarotCore::{KakarotCoreState}}; use evm::backend::starknet_backend; use evm::backend::validation::validate_eth_tx; +use evm::model::account::AccountTrait; use evm::model::{TransactionResult, Address}; use evm::{EVMTrait}; use openzeppelin::token::erc20::interface::{IERC20CamelDispatcher, IERC20CamelDispatcherTrait}; use utils::constants::POW_2_53; -use utils::eth_transaction::transaction::Transaction; +use utils::eth_transaction::transaction::{Transaction, TransactionTrait}; #[starknet::interface] pub trait IEthRPC { @@ -84,21 +85,6 @@ pub trait IEthRPC { /// * The estimated gas as a u64 fn eth_estimate_gas(self: @T, origin: EthAddress, tx: Transaction) -> (bool, Span, u64); - //TODO: make this an internal function. The account contract should call - //eth_send_raw_transaction. - /// Executes a transaction and possibly modifies the state. - /// - /// # Arguments - /// - /// * `tx` - The transaction object - /// - /// # Returns - /// - /// A tuple containing: - /// * A boolean indicating success - /// * The return data as a Span - /// * The amount of gas used as a u64 - fn eth_send_transaction(ref self: T, tx: Transaction) -> (bool, Span, u64); /// Executes an unsigned transaction. /// @@ -153,9 +139,7 @@ pub impl EthRPC< core::panic_with_felt252('fn must be called, not invoked'); }; - let origin = Address { - evm: origin, starknet: kakarot_state.compute_starknet_address(origin) - }; + let origin = Address { evm: origin, starknet: kakarot_state.get_starknet_address(origin) }; let TransactionResult { success, return_data, gas_used, state: _state } = EVMTrait::process_transaction( @@ -171,16 +155,49 @@ pub impl EthRPC< panic!("unimplemented") } - //TODO: make this one internal, and the eth_send_raw_unsigned_tx one public - fn eth_send_transaction( - ref self: TContractState, mut tx: Transaction + //TODO: we can't really unit-test this with foundry because we can't generate the RLP-encoding + //in Cairo Find another way - perhaps test-data gen with python? + fn eth_send_raw_unsigned_tx( + ref self: TContractState, mut tx_data: Span ) -> (bool, Span, u64) { + let tx = TransactionTrait::decode_enveloped(ref tx_data).expect('EOA: could not decode tx'); + EthRPCInternal::eth_send_transaction(ref self, tx) + } +} + +trait EthRPCInternal { + /// Executes a transaction and possibly modifies the state. + /// + /// This function implements the `eth_sendTransaction` method as described in the Ethereum + /// JSON-RPC specification. + /// The nonce is taken from the corresponding account contract. + /// + /// # Arguments + /// + /// * `tx` - A `Transaction` struct + /// + /// # Returns + /// + /// A tuple containing: + /// * A boolean indicating success (TRUE if the transaction succeeded, FALSE otherwise) + /// * The return data as a `Span` + /// * The amount of gas used by the transaction as a `u64` + fn eth_send_transaction(ref self: T, tx: Transaction) -> (bool, Span, u64); +} + +impl EthRPCInternalImpl< + TContractState, impl KakarotState: KakarotCoreState, +Drop +> of EthRPCInternal { + fn eth_send_transaction(ref self: TContractState, tx: Transaction) -> (bool, Span, u64) { let mut kakarot_state = KakarotState::get_state(); let intrinsic_gas = validate_eth_tx(@kakarot_state, tx); let starknet_caller_address = get_caller_address(); - let account = IAccountDispatcher { contract_address: starknet_caller_address }; - let origin = Address { evm: account.get_evm_address(), starknet: starknet_caller_address }; + // panics if the caller is a spoofer of an EVM address. + //TODO: e2e test this! :) Send a transaction from an account that is not Kakarot's account + //(e.g. deploy an account but not from Kakarot) + let origin_evm_address = safe_get_evm_address(@self, starknet_caller_address); + let origin = Address { evm: origin_evm_address, starknet: starknet_caller_address }; let TransactionResult { success, return_data, gas_used, mut state } = EVMTrait::process_transaction( @@ -189,26 +206,40 @@ pub impl EthRPC< starknet_backend::commit(ref state).expect('Committing state failed'); (success, return_data, gas_used) } - - fn eth_send_raw_unsigned_tx( - ref self: TContractState, tx_data: Span - ) -> (bool, Span, u64) { - panic!("unimplemented") - } } -trait IEthRPCInternal { - fn eth_send_transaction( - ref self: T, origin: EthAddress, tx: Transaction - ) -> (bool, Span, u64); -} -impl EthRPCInternalImpl> of IEthRPCInternal { - fn eth_send_transaction( - ref self: TContractState, origin: EthAddress, tx: Transaction - ) -> (bool, Span, u64) { - panic!("unimplemented") - } +/// Returns the EVM address associated with a Starknet account deployed by Kakarot. +/// +/// This function prevents cases where a Starknet account has an entrypoint `get_evm_address()` +/// but isn't part of the Kakarot system. It also mitigates re-entrancy risk with the Cairo Interop +/// module. +/// +/// # Arguments +/// +/// * `starknet_address` - The Starknet address of the account +/// +/// # Returns +/// +/// * `EthAddress` - The associated EVM address +/// +/// # Panics +/// +/// Panics if the declared corresponding EVM address (retrieved with `get_evm_address`) +/// does not recompute into the actual caller address. +fn safe_get_evm_address< + TContractState, impl KakarotState: KakarotCoreState, +Drop +>( + self: @TContractState, starknet_address: ContractAddress +) -> EthAddress { + let account = IAccountDispatcher { contract_address: starknet_address }; + let evm_address = account.get_evm_address(); + let safe_starknet_address = AccountTrait::get_starknet_address(evm_address); + assert!( + safe_starknet_address == starknet_address, + "Kakarot: caller contract is not a Kakarot Account" + ); + evm_address } fn is_view(self: @KakarotCore::ContractState) -> bool { @@ -225,16 +256,19 @@ fn is_view(self: @KakarotCore::ContractState) -> bool { #[cfg(test)] mod tests { + use core::ops::DerefMut; + use core::starknet::EthAddress; + use core::starknet::storage::{StoragePathEntry, StoragePointerWriteAccess}; use crate::kakarot_core::KakarotCore; use crate::kakarot_core::eth_rpc::IEthRPC; - use crate::kakarot_core::interface::IExtendedKakarotCoreDispatcherTrait; + use crate::kakarot_core::interface::{IKakarotCore, IExtendedKakarotCoreDispatcherTrait}; use crate::test_utils::{setup_contracts_for_testing, fund_account_with_native_token}; use evm::test_utils::{sequencer_evm_address, evm_address, uninitialized_account}; use snforge_std::{ start_mock_call, start_cheat_chain_id_global, stop_cheat_chain_id_global, test_address }; + use super::safe_get_evm_address; use utils::constants::POW_2_53; - use utils::helpers::compute_starknet_address; fn set_up() -> KakarotCore::ContractState { // Define the kakarot state to access contract functions @@ -250,12 +284,7 @@ mod tests { #[test] fn test_eth_get_transaction_count() { let kakarot_state = set_up(); - // Deployed eoa should return a zero nonce - let starknet_address = compute_starknet_address( - test_address(), - evm_address(), - 0.try_into().unwrap() // Using 0 as the kakarot storage is empty - ); + let starknet_address = kakarot_state.get_starknet_address(evm_address()); start_mock_call::(starknet_address, selector!("get_nonce"), 1); assert_eq!(kakarot_state.eth_get_transaction_count(evm_address()), 1); } @@ -301,4 +330,33 @@ mod tests { ); tear_down(); } + + #[test] + fn test_safe_get_evm_address_succeeds() { + let kakarot_state = set_up(); + // no registry - returns the computed address + let starknet_address = kakarot_state.get_starknet_address(evm_address()); + start_mock_call::< + EthAddress + >(starknet_address, selector!("get_evm_address"), evm_address()); + let safe_evm_address = safe_get_evm_address(@kakarot_state, starknet_address); + assert_eq!(safe_evm_address, evm_address()); + } + + #[test] + #[should_panic(expected: "Kakarot: caller contract is not a Kakarot Account")] + fn test_safe_get_evm_address_panics_when_caller_is_not_kakarot_account() { + let mut kakarot_state = set_up(); + let mut kakarot_storage = kakarot_state.deref_mut(); + + // Calling get_evm_address() on a fake starknet account that will return `evm_address()`. + // Then, when computing the deterministic starknet_address with get_starknet_address(), it + // will return a different address. + // This should fail. + let fake_starknet_account = 'fake_account'.try_into().unwrap(); + start_mock_call::< + EthAddress + >(fake_starknet_account, selector!("get_evm_address"), evm_address()); + safe_get_evm_address(@kakarot_state, fake_starknet_account); + } } diff --git a/cairo/kakarot-ssj/crates/contracts/src/kakarot_core/interface.cairo b/cairo/kakarot-ssj/crates/contracts/src/kakarot_core/interface.cairo index 4bce029d5..e0fcdb1a8 100644 --- a/cairo/kakarot-ssj/crates/contracts/src/kakarot_core/interface.cairo +++ b/cairo/kakarot-ssj/crates/contracts/src/kakarot_core/interface.cairo @@ -9,11 +9,6 @@ pub trait IKakarotCore { /// Gets the native token used by the Kakarot smart contract fn get_native_token(self: @TContractState) -> ContractAddress; - /// Deterministically computes a Starknet address for a given EVM address - /// The address is computed as the Starknet address corresponding to the deployment of an EOA, - /// Using its EVM address as salt, and KakarotCore as deployer. - fn compute_starknet_address(self: @TContractState, evm_address: EthAddress) -> ContractAddress; - /// Checks into KakarotCore storage if an EOA or a CA has been deployed for /// a particular EVM address and. If so returns its corresponding address, /// otherwise returns 0 @@ -47,7 +42,18 @@ pub trait IKakarotCore { /// Setter for the base fee fn set_base_fee(ref self: TContractState, base_fee: u64); - // Getter for the Starknet Address + /// Returns the corresponding Starknet address for a given EVM address. + /// + /// Returns the registered address if there is one, otherwise returns the deterministic + /// address got when Kakarot deploys an account. + /// + /// # Arguments + /// + /// * `evm_address` - The EVM address to transform to a starknet address + /// + /// # Returns + /// + /// * `ContractAddress` - The Starknet Account Contract address fn get_starknet_address(self: @TContractState, evm_address: EthAddress) -> ContractAddress; } @@ -59,11 +65,6 @@ pub trait IExtendedKakarotCore { /// Gets the native token used by the Kakarot smart contract fn get_native_token(self: @TContractState) -> ContractAddress; - /// Deterministically computes a Starknet address for a given EVM address - /// The address is computed as the Starknet address corresponding to the deployment of an EOA, - /// Using its EVM address as salt, and KakarotCore as deployer. - fn compute_starknet_address(self: @TContractState, evm_address: EthAddress) -> ContractAddress; - /// Checks into KakarotCore storage if an EOA or a CA has been deployed for /// a particular EVM address and. If so returns its corresponding address, /// otherwise returns 0 @@ -88,6 +89,10 @@ pub trait IExtendedKakarotCore { /// Executes an EVM transaction and possibly modifies the state fn eth_send_transaction(ref self: TContractState, tx: Transaction) -> (bool, Span, u64); + fn eth_send_raw_unsigned_tx( + ref self: TContractState, encoded_tx_data: Span + ) -> (bool, Span, u64); + // Returns the transaction count (nonce) of the specified address fn eth_get_transaction_count(self: @TContractState, address: EthAddress) -> u64; diff --git a/cairo/kakarot-ssj/crates/contracts/src/kakarot_core/kakarot.cairo b/cairo/kakarot-ssj/crates/contracts/src/kakarot_core/kakarot.cairo index fec55b8a0..2b5f14355 100644 --- a/cairo/kakarot-ssj/crates/contracts/src/kakarot_core/kakarot.cairo +++ b/cairo/kakarot-ssj/crates/contracts/src/kakarot_core/kakarot.cairo @@ -5,6 +5,7 @@ const INVOKE_ETH_CALL_FORBIDDEN: felt252 = 'KKT: Cannot invoke eth_call'; pub mod KakarotCore { use core::num::traits::Zero; use core::starknet::event::EventEmitter; + use core::starknet::get_caller_address; use core::starknet::storage::{ Map, StorageMapReadAccess, StorageMapWriteAccess, StoragePointerReadAccess, StoragePointerWriteAccess @@ -15,6 +16,7 @@ pub mod KakarotCore { use crate::kakarot_core::eth_rpc; use crate::kakarot_core::interface::IKakarotCore; use evm::backend::starknet_backend; + use evm::model::account::AccountTrait; use utils::helpers::compute_starknet_address; component!(path: ownable_component, storage: ownable, event: OwnableEvent); @@ -133,15 +135,6 @@ pub mod KakarotCore { self.Kakarot_native_token_address.read() } - fn compute_starknet_address( - self: @ContractState, evm_address: EthAddress - ) -> ContractAddress { - let kakarot_address = get_contract_address(); - compute_starknet_address( - kakarot_address, evm_address, self.Kakarot_uninitialized_account_class_hash.read() - ) - } - fn address_registry(self: @ContractState, evm_address: EthAddress) -> ContractAddress { self.Kakarot_evm_to_starknet_address.read(evm_address) } @@ -183,9 +176,14 @@ pub mod KakarotCore { let existing_address = self.Kakarot_evm_to_starknet_address.read(evm_address); assert(existing_address.is_zero(), 'Account already exists'); - let starknet_address = self.compute_starknet_address(evm_address); - //TODO: enable this assertion. Will require changing test runner to snfoundry - // assert!(starknet_address == caller, "Account must be registered by the caller"); + let starknet_address = compute_starknet_address( + get_contract_address(), + evm_address, + self.Kakarot_uninitialized_account_class_hash.read() + ); + assert!( + starknet_address == get_caller_address(), "Account must be registered by the caller" + ); self.Kakarot_evm_to_starknet_address.write(evm_address, starknet_address); self.emit(AccountDeployed { evm_address, starknet_address }); @@ -204,19 +202,9 @@ pub mod KakarotCore { self.Kakarot_base_fee.read() } - // @notice Returns the corresponding Starknet address for a given EVM address. - // @dev Returns the registered address if there is one, otherwise returns the deterministic - // address got when Kakarot deploys an account. - // @param evm_address The EVM address to transform to a starknet address - // @return starknet_address The Starknet Account Contract address - fn get_starknet_address(self: @ContractState, evm_address: EthAddress) -> ContractAddress { - let registered_starknet_address = self.address_registry(evm_address); - if (!registered_starknet_address.is_zero()) { - return registered_starknet_address; - } - let computed_starknet_address = self.compute_starknet_address(evm_address); - return computed_starknet_address; + fn get_starknet_address(self: @ContractState, evm_address: EthAddress) -> ContractAddress { + AccountTrait::get_starknet_address(evm_address) } } diff --git a/cairo/kakarot-ssj/crates/contracts/src/test_utils.cairo b/cairo/kakarot-ssj/crates/contracts/src/test_utils.cairo index d412068a2..e56908366 100644 --- a/cairo/kakarot-ssj/crates/contracts/src/test_utils.cairo +++ b/cairo/kakarot-ssj/crates/contracts/src/test_utils.cairo @@ -142,7 +142,6 @@ pub fn setup_contracts_for_testing() -> (IERC20CamelDispatcher, IExtendedKakarot let sequencer_sn_address = kakarot_core.address_registry(sequencer); start_cheat_sequencer_address_global(sequencer_sn_address); - start_cheat_caller_address_global(kakarot_core.contract_address); start_cheat_chain_id_global(chain_id().into()); return (native_token, kakarot_core); } diff --git a/cairo/kakarot-ssj/crates/contracts/tests/test_execution_from_outside.cairo b/cairo/kakarot-ssj/crates/contracts/tests/test_execution_from_outside.cairo index 9daff0fe4..568565968 100644 --- a/cairo/kakarot-ssj/crates/contracts/tests/test_execution_from_outside.cairo +++ b/cairo/kakarot-ssj/crates/contracts/tests/test_execution_from_outside.cairo @@ -20,7 +20,7 @@ use snforge_std::{ start_cheat_caller_address, stop_cheat_caller_address, start_cheat_transaction_hash, spy_events, EventSpyTrait, CheatSpan, cheat_caller_address, stop_cheat_block_timestamp, start_cheat_block_timestamp, start_cheat_chain_id_global, stop_cheat_chain_id_global, - start_cheat_caller_address_global, stop_cheat_caller_address_global + stop_cheat_caller_address_global }; use snforge_utils::snforge_utils::EventsFilterBuilderTrait; @@ -142,8 +142,6 @@ fn set_up() -> (IExtendedKakarotCoreDispatcher, IAccountDispatcher, IERC20CamelD let eoa = IAccountDispatcher { contract_address: kakarot_core.deploy_externally_owned_account(transaction_signer()) }; - start_cheat_caller_address_global(kakarot_core.contract_address); - start_cheat_block_timestamp(eoa.contract_address, 999); start_cheat_chain_id_global(chain_id().into()); @@ -251,35 +249,6 @@ fn test_execute_from_outside_invalid_signature() { tear_down(contract_account); } -#[test] -#[should_panic(expected: 'EOA: could not decode tx')] -fn test_execute_from_outside_invalid_tx() { - let (kakarot_core, contract_account, _) = set_up(); - - let mut faulty_eip_2930_tx = eip_2930_encoded_tx(); - let signature = Signature { - r: 0x5c4ae1ed01c8df4277f02aa3443f8183ed44627217fd7f27badaed8795906e78, - s: 0x4d2af576441428d47c174ffddc6e70b980527a57795b3c87a71878f97ecef274, - y_parity: true - }; - let _ = faulty_eip_2930_tx.pop_front(); - - let outside_execution = OutsideExecutionBuilderTrait::new(kakarot_core.contract_address) - .with_calls( - [ - CallBuilderTrait::new(kakarot_core.contract_address) - .with_calldata(faulty_eip_2930_tx) - .build() - ].span() - ) - .build(); - - let signature = serialize_transaction_signature(signature, TxType::Eip2930, chain_id()).span(); - - let _ = contract_account.execute_from_outside(outside_execution, signature); - - tear_down(contract_account); -} #[test] #[should_panic(expected: 'KKRT: Multicall not supported')] diff --git a/cairo/kakarot-ssj/crates/contracts/tests/test_kakarot_core.cairo b/cairo/kakarot-ssj/crates/contracts/tests/test_kakarot_core.cairo index 45fde481f..29b2a32bf 100644 --- a/cairo/kakarot-ssj/crates/contracts/tests/test_kakarot_core.cairo +++ b/cairo/kakarot-ssj/crates/contracts/tests/test_kakarot_core.cairo @@ -130,16 +130,6 @@ fn test_kakarot_core_eoa_mapping() { assert_eq!(address, another_sn_address) } -#[test] -fn test_kakarot_core_compute_starknet_address() { - let evm_address = test_utils::evm_address(); - let (_, kakarot_core) = contract_utils::setup_contracts_for_testing(); - let expected_starknet_address = kakarot_core.deploy_externally_owned_account(evm_address); - - let actual_starknet_address = kakarot_core.compute_starknet_address(evm_address); - assert_eq!(actual_starknet_address, expected_starknet_address); -} - #[test] fn test_kakarot_core_upgrade_contract() { let (_, kakarot_core) = contract_utils::setup_contracts_for_testing(); @@ -160,7 +150,7 @@ fn test_kakarot_core_upgrade_contract() { } #[test] -fn test_kakarot_core_get_starknet_address() { +fn test_kakarot_core_get_starknet_address_registered() { let (_, kakarot_core) = contract_utils::setup_contracts_for_testing(); let mut kakarot_state = KakarotCore::unsafe_new_contract_state(); @@ -183,6 +173,12 @@ fn test_kakarot_core_get_starknet_address() { assert_eq!( kakarot_core.get_starknet_address(registered_evm_address), registered_starknet_address ); +} + +#[test] +fn test_kakarot_core_get_starknet_address_unregistered() { + let (_, kakarot_core) = contract_utils::setup_contracts_for_testing(); + let mut kakarot_state = KakarotCore::unsafe_new_contract_state(); let unregistered_evm_address = test_utils::other_evm_address(); let unregistered_map_entry_address = kakarot_state @@ -196,13 +192,18 @@ fn test_kakarot_core_get_starknet_address() { // when the map entry is empty assert_eq!(*map_data[0], 0); // then an unregistered address should return the same as compute_starknet_address - assert_eq!( - kakarot_core.get_starknet_address(unregistered_evm_address), - kakarot_core.compute_starknet_address(unregistered_evm_address) + let computed_address = utils::helpers::compute_starknet_address( + kakarot_core.contract_address, + unregistered_evm_address, + kakarot_core.uninitialized_account_class_hash() ); + assert_eq!(kakarot_core.get_starknet_address(unregistered_evm_address), computed_address); } +//TODO Needs to be restored by giving the RLP encoding of the transaction to the test +// More generally, this should _probably_ be an e2e test anyway #[test] +#[ignore] fn test_eth_send_transaction_non_deploy_tx() { // Given let (native_token, kakarot_core) = contract_utils::setup_contracts_for_testing(); @@ -274,7 +275,6 @@ fn test_eth_call() { let evm_address = test_utils::evm_address(); kakarot_core.deploy_externally_owned_account(evm_address); - let account = contract_utils::deploy_contract_account( kakarot_core, test_utils::other_evm_address(), counter_evm_bytecode() ); @@ -299,7 +299,9 @@ fn test_eth_call() { } +//TODO Needs to be restored by giving the RLP encoding of the transaction to the test #[test] +#[ignore] fn test_eth_send_transaction_deploy_tx() { // Given let (native_token, kakarot_core) = contract_utils::setup_contracts_for_testing(); @@ -315,7 +317,8 @@ fn test_eth_send_transaction_deploy_tx() { let value = 0; // When - // Set the contract address to the EOA address, so that the caller of the `eth_send_transaction` + // Set the contract address to the EOA address, so that the caller of the + // `eth_send_transaction` // is an eoa let tx = TxLegacy { chain_id: Option::Some(chain_id()), @@ -326,7 +329,7 @@ fn test_eth_send_transaction_deploy_tx() { gas_limit, input: deploy_counter_calldata() }; - start_cheat_caller_address(kakarot_core.contract_address, eoa); + cheat_caller_address(kakarot_core.contract_address, eoa, CheatSpan::TargetCalls(1)); let (_, deploy_result, _) = kakarot_core.eth_send_transaction(Transaction::Legacy(tx)); // Then @@ -337,7 +340,7 @@ fn test_eth_send_transaction_deploy_tx() { // Set back the contract address to Kakarot for the calculation of the deployed SN contract // address, where we use a kakarot internal functions and thus must "mock" its address. - let computed_sn_addr = kakarot_core.compute_starknet_address(expected_address); + let computed_sn_addr = kakarot_core.get_starknet_address(expected_address); let CA = IAccountDispatcher { contract_address: computed_sn_addr }; let bytecode = CA.bytecode(); assert_eq!(bytecode, counter_evm_bytecode()); diff --git a/cairo/kakarot-ssj/crates/evm/src/backend/starknet_backend.cairo b/cairo/kakarot-ssj/crates/evm/src/backend/starknet_backend.cairo index c5db6215f..26237c045 100644 --- a/cairo/kakarot-ssj/crates/evm/src/backend/starknet_backend.cairo +++ b/cairo/kakarot-ssj/crates/evm/src/backend/starknet_backend.cairo @@ -168,7 +168,7 @@ fn commit_account(self: @Account, ref state: State) { if (self.is_selfdestruct() && self.is_created()) { let kakarot_state = KakarotCore::unsafe_new_contract_state(); let burn_starknet_address = kakarot_state - .compute_starknet_address(BURN_ADDRESS.try_into().unwrap()); + .get_starknet_address(BURN_ADDRESS.try_into().unwrap()); let burn_address = Address { starknet: burn_starknet_address, evm: BURN_ADDRESS.try_into().unwrap() }; diff --git a/cairo/kakarot-ssj/crates/evm/src/call_helpers.cairo b/cairo/kakarot-ssj/crates/evm/src/call_helpers.cairo index 26088d43c..2c38fbbf0 100644 --- a/cairo/kakarot-ssj/crates/evm/src/call_helpers.cairo +++ b/cairo/kakarot-ssj/crates/evm/src/call_helpers.cairo @@ -74,10 +74,8 @@ pub impl CallHelpersImpl of CallHelpers { let read_only = is_staticcall || self.message.read_only; let kakarot_core = KakarotCore::unsafe_new_contract_state(); - let to = Address { evm: to, starknet: kakarot_core.compute_starknet_address(to) }; - let caller = Address { - evm: caller, starknet: kakarot_core.compute_starknet_address(caller) - }; + let to = Address { evm: to, starknet: kakarot_core.get_starknet_address(to) }; + let caller = Address { evm: caller, starknet: kakarot_core.get_starknet_address(caller) }; let message = Message { caller, diff --git a/cairo/kakarot-ssj/crates/evm/src/interpreter.cairo b/cairo/kakarot-ssj/crates/evm/src/interpreter.cairo index 793f0eef9..54fb0a52c 100644 --- a/cairo/kakarot-ssj/crates/evm/src/interpreter.cairo +++ b/cairo/kakarot-ssj/crates/evm/src/interpreter.cairo @@ -47,12 +47,12 @@ pub impl EVMImpl of EVMTrait { let to_evm_address = compute_contract_address( sender_account.address().evm, origin_nonce ); - let to_starknet_address = self.compute_starknet_address(to_evm_address); + let to_starknet_address = self.get_starknet_address(to_evm_address); let to = Address { evm: to_evm_address, starknet: to_starknet_address }; (to, true, tx.input(), Zero::zero(), [].span()) }, TxKind::Call(to) => { - let target_starknet_address = self.compute_starknet_address(to); + let target_starknet_address = self.get_starknet_address(to); let to = Address { evm: to, starknet: target_starknet_address }; let code = env.state.get_account(to.evm).code; (to, false, code, to, tx.input()) diff --git a/cairo/kakarot-ssj/crates/evm/src/model/account.cairo b/cairo/kakarot-ssj/crates/evm/src/model/account.cairo index f61590923..849afc84e 100644 --- a/cairo/kakarot-ssj/crates/evm/src/model/account.cairo +++ b/cairo/kakarot-ssj/crates/evm/src/model/account.cairo @@ -2,10 +2,13 @@ use contracts::account_contract::{IAccountDispatcher, IAccountDispatcherTrait}; use contracts::kakarot_core::{KakarotCore, IKakarotCore}; use core::dict::{Felt252Dict, Felt252DictTrait}; use core::num::traits::Zero; -use core::starknet::{ContractAddress, EthAddress}; +use core::ops::SnapshotDeref; +use core::starknet::storage::{StoragePointerReadAccess, StoragePathEntry}; +use core::starknet::{ContractAddress, EthAddress, get_contract_address}; use crate::backend::starknet_backend::fetch_balance; use crate::model::Address; use utils::constants::EMPTY_KECCAK; +use utils::helpers::compute_starknet_address; use utils::traits::bytes::U8SpanExTrait; #[derive(Drop)] @@ -82,6 +85,24 @@ pub struct Account { #[generate_trait] pub impl AccountImpl of AccountTrait { + fn get_starknet_address(evm_address: EthAddress) -> ContractAddress { + let kakarot_state = KakarotCore::unsafe_new_contract_state(); + let kakarot_storage = kakarot_state.snapshot_deref(); + let existing_address = kakarot_storage + .Kakarot_evm_to_starknet_address + .entry(evm_address) + .read(); + if existing_address.is_zero() { + return compute_starknet_address( + get_contract_address(), + evm_address, + kakarot_state.uninitialized_account_class_hash() + ); + } + existing_address + } + + /// Fetches an account from Starknet /// An non-deployed account is just an empty account. /// # Arguments @@ -96,7 +117,7 @@ pub impl AccountImpl of AccountTrait { Option::Some(account) => account, Option::None => { let kakarot_state = KakarotCore::unsafe_new_contract_state(); - let starknet_address = kakarot_state.compute_starknet_address(evm_address); + let starknet_address = kakarot_state.get_starknet_address(evm_address); // If no account exists at `address`, then we are trying to // access an undeployed account. We create an // empty account with the correct address, fetch the balance, and return it. diff --git a/cairo/kakarot-ssj/crates/utils/src/eth_transaction/transaction.cairo b/cairo/kakarot-ssj/crates/utils/src/eth_transaction/transaction.cairo index 9e1d57f90..959ab463b 100644 --- a/cairo/kakarot-ssj/crates/utils/src/eth_transaction/transaction.cairo +++ b/cairo/kakarot-ssj/crates/utils/src/eth_transaction/transaction.cairo @@ -173,19 +173,8 @@ pub impl _Transasction of TransactionTrait { Transaction::Eip1559(tx) => tx.input, } } -} - -#[derive(Copy, Drop, Debug, PartialEq)] -pub struct TransactionUnsigned { - /// Transaction hash - pub hash: u256, - /// Raw transaction info - pub transaction: Transaction, -} -#[generate_trait] -pub impl _TransactionUnsigned of TransactionUnsignedTrait { /// Decodes the "raw" format of transaction (similar to `eth_sendRawTransaction`). /// /// This should be used for any method that accepts a raw transaction. @@ -201,9 +190,7 @@ pub impl _TransactionUnsigned of TransactionUnsignedTrait { /// /// Both for legacy and EIP-2718 transactions, an error will be returned if there is an excess /// of bytes in input data. - fn decode_enveloped( - ref tx_data: Span, - ) -> Result { + fn decode_enveloped(ref tx_data: Span,) -> Result { if tx_data.is_empty() { return Result::Err(EthTransactionError::RLPError(RLPError::InputTooShort)); } @@ -233,9 +220,7 @@ pub impl _TransactionUnsigned of TransactionUnsignedTrait { /// chainId, 0, 0] /// Note: this function assumes that tx_type has been checked to make sure it is a legacy /// transaction - fn decode_legacy_tx( - ref encoded_tx_data: Span - ) -> Result { + fn decode_legacy_tx(ref encoded_tx_data: Span) -> Result { let rlp_decoded_data = RLPTrait::decode(encoded_tx_data); let mut rlp_decoded_data = rlp_decoded_data.map_err()?; @@ -256,11 +241,7 @@ pub impl _TransactionUnsigned of TransactionUnsignedTrait { } }; - let tx_hash = Self::compute_hash(encoded_tx_data); - - Result::Ok( - TransactionUnsigned { transaction: Transaction::Legacy(legacy_tx), hash: tx_hash, } - ) + Result::Ok(Transaction::Legacy(legacy_tx)) } /// Decodes an enveloped EIP-2718 typed transaction. @@ -275,7 +256,7 @@ pub impl _TransactionUnsigned of TransactionUnsignedTrait { /// CAUTION: this expects that `data` is `tx-type || rlp(tx-data)` fn decode_enveloped_typed_transaction( ref encoded_tx_data: Span - ) -> Result { + ) -> Result { // keep this around so we can use it to calculate the hash let original_data = encoded_tx_data; @@ -316,8 +297,7 @@ pub impl _TransactionUnsigned of TransactionUnsignedTrait { } }; - let tx_hash = Self::compute_hash(original_data); - Result::Ok(TransactionUnsigned { transaction, hash: tx_hash }) + Result::Ok(transaction) } /// Returns the hash of the unsigned transaction @@ -355,7 +335,7 @@ mod tests { legacy_rlp_encoded_tx, legacy_rlp_encoded_deploy_tx, eip_2930_encoded_tx, eip_1559_encoded_tx }; - use super::{TransactionTrait, TransactionUnsignedTrait}; + use super::{TransactionTrait}; #[test] @@ -368,18 +348,18 @@ mod tests { // message_hash: 0xcf71743e6e25fef715398915997f782b95554c8bbfb7b3f7701e007332ed31b4 // chain id used: 'KKRT' let mut encoded_tx_data = legacy_rlp_encoded_tx(); - let decoded = TransactionUnsignedTrait::decode_enveloped(ref encoded_tx_data).unwrap(); - assert_eq!(decoded.transaction.nonce(), 0); - assert_eq!(decoded.transaction.max_fee_per_gas(), 0x3b9aca00); - assert_eq!(decoded.transaction.gas_limit(), 0x1e8480); + let transaction = TransactionTrait::decode_enveloped(ref encoded_tx_data).unwrap(); + assert_eq!(transaction.nonce(), 0); + assert_eq!(transaction.max_fee_per_gas(), 0x3b9aca00); + assert_eq!(transaction.gas_limit(), 0x1e8480); assert_eq!( - decoded.transaction.kind(), + transaction.kind(), TxKind::Call(0x1f9840a85d5af5bf1d1762f925bdaddc4201f984.try_into().unwrap()) ); - assert_eq!(decoded.transaction.value(), 0x016345785d8a0000); - assert_eq!(decoded.transaction.input(), [0xab, 0xcd, 0xef].span()); - assert_eq!(decoded.transaction.chain_id(), Option::Some(0x4b4b5254)); - assert_eq!(decoded.transaction.transaction_type(), TxType::Legacy); + assert_eq!(transaction.value(), 0x016345785d8a0000); + assert_eq!(transaction.input(), [0xab, 0xcd, 0xef].span()); + assert_eq!(transaction.chain_id(), Option::Some(0x4b4b5254)); + assert_eq!(transaction.transaction_type(), TxType::Legacy); } #[test] @@ -389,18 +369,18 @@ mod tests { // expected rlp decoding: // ["0x","0x0a","0x061a80","0x","0x0186a0","0x600160010a5060006000f3","0x4b4b5254","0x","0x"] let mut encoded_tx_data = legacy_rlp_encoded_deploy_tx(); - let decoded = TransactionUnsignedTrait::decode_enveloped(ref encoded_tx_data).unwrap(); - assert_eq!(decoded.transaction.nonce(), 0); - assert_eq!(decoded.transaction.max_fee_per_gas(), 0x0a); - assert_eq!(decoded.transaction.gas_limit(), 0x061a80); - assert_eq!(decoded.transaction.kind(), TxKind::Create); - assert_eq!(decoded.transaction.value(), 0x0186a0); + let transaction = TransactionTrait::decode_enveloped(ref encoded_tx_data).unwrap(); + assert_eq!(transaction.nonce(), 0); + assert_eq!(transaction.max_fee_per_gas(), 0x0a); + assert_eq!(transaction.gas_limit(), 0x061a80); + assert_eq!(transaction.kind(), TxKind::Create); + assert_eq!(transaction.value(), 0x0186a0); assert_eq!( - decoded.transaction.input(), + transaction.input(), [0x60, 0x01, 0x60, 0x01, 0x0a, 0x50, 0x60, 0x00, 0x60, 0x00, 0xf3].span() ); - assert_eq!(decoded.transaction.chain_id(), Option::Some(0x4b4b5254)); - assert_eq!(decoded.transaction.transaction_type(), TxType::Legacy); + assert_eq!(transaction.chain_id(), Option::Some(0x4b4b5254)); + assert_eq!(transaction.transaction_type(), TxType::Legacy); } #[test] @@ -416,18 +396,18 @@ mod tests { // chain id used: 'KKRT' let mut encoded_tx_data = eip_2930_encoded_tx(); - let decoded = TransactionUnsignedTrait::decode_enveloped(ref encoded_tx_data).unwrap(); - assert_eq!(decoded.transaction.chain_id(), Option::Some(0x4b4b5254)); - assert_eq!(decoded.transaction.nonce(), 0); - assert_eq!(decoded.transaction.max_fee_per_gas(), 0x3b9aca00); - assert_eq!(decoded.transaction.gas_limit(), 0x1e8480); + let transaction = TransactionTrait::decode_enveloped(ref encoded_tx_data).unwrap(); + assert_eq!(transaction.chain_id(), Option::Some(0x4b4b5254)); + assert_eq!(transaction.nonce(), 0); + assert_eq!(transaction.max_fee_per_gas(), 0x3b9aca00); + assert_eq!(transaction.gas_limit(), 0x1e8480); assert_eq!( - decoded.transaction.kind(), + transaction.kind(), TxKind::Call(0x1f9840a85d5af5bf1d1762f925bdaddc4201f984.try_into().unwrap()) ); - assert_eq!(decoded.transaction.value(), 0x016345785d8a0000); - assert_eq!(decoded.transaction.input(), [0xab, 0xcd, 0xef].span()); - assert_eq!(decoded.transaction.transaction_type(), TxType::Eip2930); + assert_eq!(transaction.value(), 0x016345785d8a0000); + assert_eq!(transaction.input(), [0xab, 0xcd, 0xef].span()); + assert_eq!(transaction.transaction_type(), TxType::Eip2930); } #[test] @@ -443,17 +423,17 @@ mod tests { // chain id used: 'KKRT' let mut encoded_tx_data = eip_1559_encoded_tx(); - let decoded = TransactionUnsignedTrait::decode_enveloped(ref encoded_tx_data).unwrap(); - assert_eq!(decoded.transaction.chain_id(), Option::Some(0x4b4b5254)); - assert_eq!(decoded.transaction.nonce(), 0); - assert_eq!(decoded.transaction.max_fee_per_gas(), 0x3b9aca00); - assert_eq!(decoded.transaction.gas_limit(), 0x1e8480); + let transaction = TransactionTrait::decode_enveloped(ref encoded_tx_data).unwrap(); + assert_eq!(transaction.chain_id(), Option::Some(0x4b4b5254)); + assert_eq!(transaction.nonce(), 0); + assert_eq!(transaction.max_fee_per_gas(), 0x3b9aca00); + assert_eq!(transaction.gas_limit(), 0x1e8480); assert_eq!( - decoded.transaction.kind(), + transaction.kind(), TxKind::Call(0x1f9840a85d5af5bf1d1762f925bdaddc4201f984.try_into().unwrap()) ); - assert_eq!(decoded.transaction.value(), 0x016345785d8a0000); - assert_eq!(decoded.transaction.input(), [0xab, 0xcd, 0xef].span()); + assert_eq!(transaction.value(), 0x016345785d8a0000); + assert_eq!(transaction.input(), [0xab, 0xcd, 0xef].span()); let expected_access_list = [ AccessListItem { ethereum_address: 0x1f9840a85d5af5bf1d1762f925bdaddc4201f984.try_into().unwrap(), @@ -463,16 +443,14 @@ mod tests { ].span() } ].span(); - assert_eq!( - decoded.transaction.access_list().expect('access_list is none'), expected_access_list - ); - assert_eq!(decoded.transaction.transaction_type(), TxType::Eip1559); + assert_eq!(transaction.access_list().expect('access_list is none'), expected_access_list); + assert_eq!(transaction.transaction_type(), TxType::Eip1559); } #[test] fn test_is_legacy_tx_eip_155_tx() { let encoded_tx_data = legacy_rlp_encoded_tx(); - let result = TransactionUnsignedTrait::is_legacy_tx(encoded_tx_data); + let result = TransactionTrait::is_legacy_tx(encoded_tx_data); assert(result, 'is_legacy_tx expected true'); } @@ -480,7 +458,7 @@ mod tests { #[test] fn test_is_legacy_tx_eip_1559_tx() { let encoded_tx_data = eip_1559_encoded_tx(); - let result = TransactionUnsignedTrait::is_legacy_tx(encoded_tx_data); + let result = TransactionTrait::is_legacy_tx(encoded_tx_data); assert(!result, 'is_legacy_tx expected false'); } @@ -488,7 +466,7 @@ mod tests { #[test] fn test_is_legacy_tx_eip_2930_tx() { let encoded_tx_data = eip_2930_encoded_tx(); - let result = TransactionUnsignedTrait::is_legacy_tx(encoded_tx_data); + let result = TransactionTrait::is_legacy_tx(encoded_tx_data); assert(!result, 'is_legacy_tx expected false'); } From 630eaa8d3971f1bf28a6e89352c96df6fe30f8ba Mon Sep 17 00:00:00 2001 From: Oba Date: Mon, 7 Oct 2024 14:15:43 +0200 Subject: [PATCH 56/56] update skipfile ssj --- cairo/kakarot-ssj/blockchain-tests-skip.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cairo/kakarot-ssj/blockchain-tests-skip.yml b/cairo/kakarot-ssj/blockchain-tests-skip.yml index 748b39ade..6d06e0129 100644 --- a/cairo/kakarot-ssj/blockchain-tests-skip.yml +++ b/cairo/kakarot-ssj/blockchain-tests-skip.yml @@ -58,6 +58,7 @@ testname: vmPerformance: - loopExp_d2g0v0_Cancun - performanceTester_d0g0v0_Cancun + - performanceTester_d2g0v0_Cancun - performanceTester_d3g0v0_Cancun - loopExp_d10g0v0_Cancun - loopExp_d11g0v0_Cancun @@ -564,6 +565,8 @@ testname: - static_LoopCallsDepthThenRevert3_d0g0v0_Cancun - static_callChangeRevert_d1g0v0_Cancun - static_callCreate2_d2g0v0_Cancun + - static_callcall_00_OOGE_1_d1g0v0_Cancun + - static_callcall_00_OOGE_2_d1g0v0_Cancun - static_callcallcall_000_OOGMAfter2_d0g0v0_Cancun - static_callcallcall_000_OOGMBefore_d0g0v0_Cancun - static_callcallcallcode_001_OOGE_2_d1g0v0_Cancun

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 literal 192120 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 literal 0 HcmV?d00001 diff --git a/kakarot-ssj/docs/img/kakarot_github_banner.png b/kakarot-ssj/docs/img/kakarot_github_banner.png new file mode 100644 index 0000000000000000000000000000000000000000..0a0ba283e57e1781c1fd89d734d2296b8b6024bf GIT binary patch literal 68625 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