diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 47715f6ca..2571b4422 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,7 @@ jobs: - uses: actions/checkout@v4 # Python setup - name: Set up Python 3.10.14 - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: 3.10.14 - name: Load cached Poetry installation @@ -51,7 +51,8 @@ jobs: - name: Install dependencies if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true' run: make setup - + - uses: asdf-vm/actions/install@v3 + - run: asdf install # Build artifacts - name: Compile all the cairo files run: make build @@ -70,7 +71,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Set up Python 3.10.14 - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: 3.10.14 - name: Load cached Poetry installation @@ -123,7 +124,7 @@ jobs: KATANA_VERSION=$(grep -oP '^KATANA_VERSION = \K.*' Makefile) echo "katana_version=$KATANA_VERSION" >> "$GITHUB_OUTPUT" - name: Set up Python 3.10 - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: 3.10.14 - name: Load cached Poetry installation @@ -153,8 +154,7 @@ jobs: uses: foundry-rs/foundry-toolchain@v1 with: version: nightly - - name: Install asdf & tools # For multiple versions of scarb - reads from .tool-versions and installs them - uses: asdf-vm/actions/install@v3 + - uses: asdf-vm/actions/install@v3 - name: Load cached katana id: cached-katana uses: actions/cache@v4 @@ -204,7 +204,7 @@ jobs: - name: Move ERC20 run: mv build/v0/ERC20.json build/common - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: 3.10.14 - name: run tests @@ -228,7 +228,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Set up Python 3.10.14 - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: 3.10.14 - name: Load cached Poetry installation diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c5c88db80..92e33dab5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -41,7 +41,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Set up Python 3.10 - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: 3.10.14 - name: Load cached Poetry installation diff --git a/.github/workflows/trunk-check.yaml b/.github/workflows/trunk-check.yaml index 2e0ec335f..0adad3aa0 100644 --- a/.github/workflows/trunk-check.yaml +++ b/.github/workflows/trunk-check.yaml @@ -21,7 +21,7 @@ jobs: uses: actions/checkout@v3 - name: Set up Python 3.10.14 - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: 3.10.14 cache: pip diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index ac32e75b2..b5f0a28ca 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -75,6 +75,7 @@ lint: - resources* - tests/ef_tests/test_data - .katana/messaging_config.json + - deployments - linters: [solidity] paths: - solidity_contracts/src/UniswapV2/**/*.sol diff --git a/Makefile b/Makefile index 6f70432de..6e6ba2a7f 100644 --- a/Makefile +++ b/Makefile @@ -38,7 +38,7 @@ fetch-ssj-artifacts: setup: fetch-ssj-artifacts poetry install -test: build-sol build-cairo1 deploy +test: deploy poetry run pytest tests/src -m "not NoCI" --log-cli-level=INFO -n logical --seed 42 poetry run pytest tests/end_to_end --seed 42 @@ -46,7 +46,7 @@ test-unit: build-sol poetry run pytest tests/src -m "not NoCI" -n logical --seed 42 # run make run-nodes in other terminal -test-end-to-end: build-sol build-cairo1 deploy +test-end-to-end: deploy poetry run pytest tests/end_to_end --seed 42 deploy: build build-sol @@ -70,42 +70,6 @@ build-sol: git submodule update --init --recursive forge build --names --force -# Builds Cairo 1.0 contracts by iterating over subdirectories, -# compiling contracts, and copying the resulting .sierra.json (old versions) or .contract_class.json -# files to the ROOT_DIR/build/fixtures directory with appropriate file extensions. -build-cairo1: - @mkdir -p build/ssj - @for d in cairo1_contracts/*/ ; do \ - if [ "$$d" != "cairo1_contracts/build/" ]; then \ - echo "Building $$d"; \ - cd $$d; \ - scarb build; \ - for f in target/dev/*.sierra.json target/dev/*.contract_class.json target/dev/*.casm.json target/dev/*.compiled_contract_class.json; do \ - if [ -e "$$f" ]; then \ - case "$$f" in \ - *.sierra.json) \ - CONTRACT_NAME="$$(basename $$f | sed -E 's/^.*_([^_.]*)\.sierra\.json$$/\1/')"; \ - cp "$$f" "$(ROOT_DIR)/build/ssj/contracts_$$CONTRACT_NAME.contract_class.json"; \ - ;; \ - *.contract_class.json) \ - CONTRACT_NAME="$$(basename $$f | sed -E 's/^.*_([^_.]*)\.contract_class\.json$$/\1/')"; \ - cp "$$f" "$(ROOT_DIR)/build/ssj/contracts_$$CONTRACT_NAME.contract_class.json"; \ - ;; \ - *.casm.json) \ - CONTRACT_NAME="$$(basename $$f | sed -E 's/^.*_([^_.]*)\.casm\.json$$/\1/')"; \ - cp "$$f" "$(ROOT_DIR)/build/ssj/contracts_$$CONTRACT_NAME.compiled_contract_class.json"; \ - ;; \ - *.compiled_contract_class.json) \ - CONTRACT_NAME="$$(basename $$f | sed -E 's/^.*_([^_.]*)\.compiled_contract_class\.json$$/\1/')"; \ - cp "$$f" "$(ROOT_DIR)/build/ssj/contracts_$$CONTRACT_NAME.compiled_contract_class.json"; \ - ;; \ - esac; \ - fi; \ - done; \ - cd -; \ - fi; \ - done - install-katana: cargo install --git https://github.com/dojoengine/dojo --locked --tag "${KATANA_VERSION}" katana diff --git a/cairo1_contracts/token/src/lib.cairo b/cairo1_contracts/token/src/lib.cairo index 22a9f7028..9b8f06e6a 100644 --- a/cairo1_contracts/token/src/lib.cairo +++ b/cairo1_contracts/token/src/lib.cairo @@ -1,35 +1 @@ -#[starknet::contract] -mod StarknetToken { - use openzeppelin::token::erc20::ERC20Component; - use starknet::ContractAddress; - - component!(path: ERC20Component, storage: erc20, event: ERC20Event); - - #[abi(embed_v0)] - impl ERC20Impl = ERC20Component::ERC20Impl; - #[abi(embed_v0)] - impl ERC20MetadataImpl = ERC20Component::ERC20MetadataImpl; - impl ERC20InternalImpl = ERC20Component::InternalImpl; - - #[storage] - struct Storage { - #[substorage(v0)] - erc20: ERC20Component::Storage - } - - #[event] - #[derive(Drop, starknet::Event)] - enum Event { - #[flat] - ERC20Event: ERC20Component::Event - } - - #[constructor] - fn constructor(ref self: ContractState, initial_supply: u256, recipient: ContractAddress) { - let name = "MyToken"; - let symbol = "MTK"; - - self.erc20.initializer(name, symbol); - self.erc20._mint(recipient, initial_supply); - } -} +mod starknet_token; diff --git a/cairo1_contracts/token/src/starknet_token.cairo b/cairo1_contracts/token/src/starknet_token.cairo new file mode 100644 index 000000000..22a9f7028 --- /dev/null +++ b/cairo1_contracts/token/src/starknet_token.cairo @@ -0,0 +1,35 @@ +#[starknet::contract] +mod StarknetToken { + use openzeppelin::token::erc20::ERC20Component; + use starknet::ContractAddress; + + component!(path: ERC20Component, storage: erc20, event: ERC20Event); + + #[abi(embed_v0)] + impl ERC20Impl = ERC20Component::ERC20Impl; + #[abi(embed_v0)] + impl ERC20MetadataImpl = ERC20Component::ERC20MetadataImpl; + impl ERC20InternalImpl = ERC20Component::InternalImpl; + + #[storage] + struct Storage { + #[substorage(v0)] + erc20: ERC20Component::Storage + } + + #[event] + #[derive(Drop, starknet::Event)] + enum Event { + #[flat] + ERC20Event: ERC20Component::Event + } + + #[constructor] + fn constructor(ref self: ContractState, initial_supply: u256, recipient: ContractAddress) { + let name = "MyToken"; + let symbol = "MTK"; + + self.erc20.initializer(name, symbol); + self.erc20._mint(recipient, initial_supply); + } +} diff --git a/cairo1_contracts/utils/.gitignore b/cairo1_contracts/utils/.gitignore new file mode 100644 index 000000000..eb5a316cb --- /dev/null +++ b/cairo1_contracts/utils/.gitignore @@ -0,0 +1 @@ +target diff --git a/cairo1_contracts/utils/.tool-versions b/cairo1_contracts/utils/.tool-versions new file mode 100644 index 000000000..179f2a8c2 --- /dev/null +++ b/cairo1_contracts/utils/.tool-versions @@ -0,0 +1 @@ +scarb 2.6.5 diff --git a/cairo1_contracts/utils/Scarb.lock b/cairo1_contracts/utils/Scarb.lock new file mode 100644 index 000000000..abda56939 --- /dev/null +++ b/cairo1_contracts/utils/Scarb.lock @@ -0,0 +1,6 @@ +# Code generated by scarb DO NOT EDIT. +version = 1 + +[[package]] +name = "utils" +version = "0.1.0" diff --git a/cairo1_contracts/utils/Scarb.toml b/cairo1_contracts/utils/Scarb.toml new file mode 100644 index 000000000..084e2cea0 --- /dev/null +++ b/cairo1_contracts/utils/Scarb.toml @@ -0,0 +1,12 @@ +[package] +name = "utils" +version = "0.1.0" +edition = "2023_11" + +[dependencies] +starknet = "2.6.4" + +[[target.starknet-contract]] +casm = true +sierra = true +casm-add-pythonic-hints = true diff --git a/cairo1_contracts/utils/src/balance_sender.cairo b/cairo1_contracts/utils/src/balance_sender.cairo new file mode 100644 index 000000000..0afe76564 --- /dev/null +++ b/cairo1_contracts/utils/src/balance_sender.cairo @@ -0,0 +1,39 @@ +use core::starknet::{get_caller_address, 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::contract] +pub mod BalanceSender { + use core::starknet::{get_caller_address, ContractAddress, ClassHash, get_contract_address, SyscallResult}; + use super::{IERC20Dispatcher, IERC20DispatcherTrait}; + use core::starknet::syscalls::{replace_class_syscall}; + + #[storage] + struct Storage {} + + #[external(v0)] + fn send_balance(self: @ContractState, token_address: ContractAddress, recipient: ContractAddress) -> bool { + let erc20_dispatcher = IERC20Dispatcher { contract_address: token_address }; + let balance = erc20_dispatcher.balance_of(get_contract_address()); + erc20_dispatcher.transfer(recipient, balance) + } + + #[external(v0)] + fn replace_class(ref self: ContractState, new_class: ClassHash) -> SyscallResult<()>{ + replace_class_syscall(new_class) + } +} diff --git a/cairo1_contracts/utils/src/lib.cairo b/cairo1_contracts/utils/src/lib.cairo new file mode 100644 index 000000000..bdd1426d0 --- /dev/null +++ b/cairo1_contracts/utils/src/lib.cairo @@ -0,0 +1,3 @@ +mod universal_library_caller; + +mod balance_sender; diff --git a/cairo1_contracts/utils/src/universal_library_caller.cairo b/cairo1_contracts/utils/src/universal_library_caller.cairo new file mode 100644 index 000000000..b404a3e23 --- /dev/null +++ b/cairo1_contracts/utils/src/universal_library_caller.cairo @@ -0,0 +1,28 @@ +use starknet::{ + SyscallResult, storage_access::StorageAddress, class_hash::ClassHash, +}; + + +#[starknet::interface] +pub trait IUniversalLibraryCaller { + fn library_call(self: @TContractState, class_hash: ClassHash, function_selector: felt252, calldata: Span) -> SyscallResult>; +} + +#[starknet::contract] +pub mod UniversalLibraryCaller { + use starknet::syscalls::library_call_syscall; + use starknet::{ + SyscallResult, storage_access::StorageAddress, class_hash::ClassHash, + }; + + + #[storage] + struct Storage {} + + #[abi(embed_v0)] + impl UniversalLibraryCallerImpl of super::IUniversalLibraryCaller { + fn library_call(self: @ContractState, class_hash: ClassHash, function_selector: felt252, calldata: Span) -> SyscallResult> { + library_call_syscall(class_hash, function_selector, calldata) + } + } +} diff --git a/deployments/starknet-sepolia/declarations.json b/deployments/starknet-sepolia/declarations.json index 77d9b7a69..c4c401168 100644 --- a/deployments/starknet-sepolia/declarations.json +++ b/deployments/starknet-sepolia/declarations.json @@ -1,9 +1,17 @@ { - "kakarot": "0x6aa7b2a71ce0e28301a6547b8eb38c5f4130d0091b5aa8a12c8f380efcbc4c4", - "account_contract": "0x56d311021950bf65ee500426e007b9e3ced0db97f9c1e0d29a9e03d79a9bf6c", - "uninitialized_account": "0x1d8b8047e26b484d3f6262d1967217d980d0f2dfc69afa5661492bd5bfe2954", - "EVM": "0x78e943202d567c81ec9b523e5121c15914210f915dd7bce69f09ceb5ae91934", - "OpenzeppelinAccount": "0x452189b6cd1ef66a7daef29cbffb77ce809cac95449687aabb169117c04e2f9", - "Cairo1Helpers": "0xff0ec0846982c93e48ed5130dba8efe5905c099d0ffe45c1fd777a97a2b71a", - "replace_class": "0x5cd1a33bc766f50965fe2343e6aec12a12c562b3bb653085b88dc6751b71682" + "account_contract": "0x6cb1275516c11f6c1f9d2758bd212d2c40d8136ebd353c316779b754a216d83", + "uninitialized_account_fixture": "0x2957ff0877441dddcd140e6af50a3d45712f4f7205a36a846110a70297036be", + "uninitialized_account": "0x45f7d0803659c3f58b5b6ba46f349178253dadabbfc6ab47fa1ba4bab4699f8", + "EVM": "0x1ce258b332ad964d0d0a472b7795615a84f25196b733a319e101b948f3064a8", + "OpenzeppelinAccount": "0x6153ccf69fd20f832c794df36e19135f0070d0576144f0b47f75a226e4be530", + "Cairo1Helpers": "0x28ece3751ecf5bdf2d791eb64a65bfb6a8816432b698870dba2f38a36101d58", + "Cairo1HelpersFixture": "0x4e7811d9bbba41193bd3c77d05c16f7aaa55dd1d601686b50f6fa0e3766a712", + "replace_class": "0xa187318c5e79b010cf45975f589f0a8d441fadde5b1e7ccad46501568437b5", + "Counter": "0x4fc47610d8c9ce0bcfc2f9e03658f0fbcd3e0a9c351a1aa59d465a33533a7c8", + "MockPragmaOracle": "0x675f00328ff84f127d71b179b3f3a3a06ce8432054770cddd5729c8d62866da", + "StarknetToken": "0x27dd8ce628866f1544202ae06ec57b3c9b1f775d5f7c2797de7aa1586ecf693", + "ERC20": "0x3c5ee4bc12f4247cd8071150c3f5d9bee71f40b0ef7aeae59f468d898f60933", + "kakarot": "0x3f9e4ac97c943181453ce74f1fd1c163c154c40d9cbbbe5c2453512ee1a86e6", + "UniversalLibraryCaller": "0x5e84816dcbfd11581d8d5160af5754a4adc71ab35a0c0aaa053773f61838627", + "BalanceSender": "0x2cc118f56b9d3ad311900db5254f3dca75fbf24de3b68ee670a0fb3691ac5b3" } diff --git a/deployments/starknet-sepolia/deployments.json b/deployments/starknet-sepolia/deployments.json index 4f8a8d55a..9dcc82f1f 100644 --- a/deployments/starknet-sepolia/deployments.json +++ b/deployments/starknet-sepolia/deployments.json @@ -1,7 +1,27 @@ { "kakarot": { - "address": "0x464f7e37179d2f93ea208795bdb2d0912e8257f6fb5f67ae2559251523aee19", - "tx": "0x209a134f8c8f3a9b9e98c2e4789476d4432aceeb252ecfb3dba069cec5ec974", + "address": "0x6f625bb0bd82401b268c1ba9fa0973bb9cdf732c6a6f21fe14dfd4c82a28e89", + "tx": "0x36c51e168146d9c104a4323a2dddf873a9a54d52b02f5cbc83d8cb957426f60", "artifact": "build/kakarot.json" + }, + "EVM": { + "address": "0x41c4025537b9677034f3b58f6e722e19c40a7b77a82e3851fdc6b7adf5ad414", + "tx": "0xa0b92fd60470ac35b5a64236bacbe86d6b5aaea30997aced328123cba74024", + "artifact": "build/fixtures/EVM.json" + }, + "Counter": { + "address": "0x2d6741b182475b7cfc62ec1000fbcba553ea08f2e603fa2840d0288cd2d1e3c", + "tx": "0xd1781094a55ac09c3177e6799f9d484c5477baa6d120923c942da5c2fdbfea", + "artifact": "build/fixtures/Counter.json" + }, + "MockPragmaOracle": { + "address": "0x17e64c92b06da9a331da9fd333a683a33019ae2a393254caf332d4158edc74d", + "tx": "0x3d6b91602c1e290bc65c6f85751f5ea156cf982d01c6bf1ea694d7398a9d5a5", + "artifact": "build/ssj/contracts_MockPragmaOracle" + }, + "UniversalLibraryCaller": { + "address": "0x01e12ea32baf68b1e11c1ce32595d3a61a22ccdcbc67f94c77268b6ce99fa6d4", + "tx": "0x3d6b91602c1e290bc65c6f85751f5ea156cf982d01c6bf1ea694d7398a9d5a5", + "artifact": "cairo1_contracts/utils/target/dev/library_call_UniversalLibraryCaller" } } diff --git a/kakarot_scripts/constants.py b/kakarot_scripts/constants.py index 3547a6703..c6e47822b 100644 --- a/kakarot_scripts/constants.py +++ b/kakarot_scripts/constants.py @@ -41,9 +41,9 @@ class NetworkType(Enum): "sepolia": { "name": "starknet-sepolia", "explorer_url": "https://sepolia.starkscan.co/", - "rpc_url": "https://starknet-sepolia.public.blastapi.io/rpc/v0_6", + "rpc_url": os.getenv("STARKNET_SEPOLIA_RPC_URL"), "l1_rpc_url": f"https://sepolia.infura.io/v3/{os.getenv('INFURA_KEY')}", - "type": NetworkType.PROD, + "type": NetworkType.STAGING, "chain_id": StarknetChainId.SEPOLIA, "check_interval": 5, "max_wait": 30, @@ -155,7 +155,9 @@ class NetworkType(Enum): if WEB3.is_connected(): chain_id = WEB3.eth.chain_id else: - chain_id = starknet_chain_id + chain_id = starknet_chain_id % ( + 2**53 if NETWORK["name"] != "starknet-sepolia" else 2**32 + ) except ( requests.exceptions.ConnectionError, requests.exceptions.MissingSchema, @@ -164,8 +166,13 @@ class NetworkType(Enum): logger.info( f"⚠️ Could not get chain Id from {NETWORK['rpc_url']}: {e}, defaulting to KKRT" ) - chain_id = int.from_bytes(b"KKRT", "big") starknet_chain_id = int.from_bytes(b"KKRT", "big") + chain_id = starknet_chain_id % ( + # TODO: remove once Kakarot is redeployed on sepolia + 2**53 + if NETWORK["name"] != "starknet-sepolia" + else 2**32 + ) class ChainId(IntEnum): @@ -181,56 +188,59 @@ class ChainId(IntEnum): or "0x20eB005C0b9c906691F885eca5895338E15c36De", 16, ) -SOURCE_DIR = Path("src") -SOURCE_DIR_FIXTURES = Path("tests/fixtures") -CONTRACTS = {p.stem: p for p in list(SOURCE_DIR.glob("**/*.cairo"))} -CONTRACTS_FIXTURES = {p.stem: p for p in list(SOURCE_DIR_FIXTURES.glob("**/*.cairo"))} +CAIRO_ZERO_DIR = Path("src") +CAIRO_DIR = Path("cairo1_contracts") +TESTS_DIR = Path("tests") + +CONTRACTS = { + p.stem: p + for p in ( + list(CAIRO_ZERO_DIR.glob("**/*.cairo")) + + list(TESTS_DIR.glob("**/*.cairo")) + + list(CAIRO_DIR.glob("**/*.cairo")) + ) +} BUILD_DIR = Path("build") -BUILD_DIR_FIXTURES = BUILD_DIR / "fixtures" BUILD_DIR.mkdir(exist_ok=True, parents=True) -BUILD_DIR_FIXTURES.mkdir(exist_ok=True, parents=True) BUILD_DIR_SSJ = BUILD_DIR / "ssj" DATA_DIR = Path("kakarot_scripts") / "data" -class ArtifactType(Enum): - cairo0 = 0 - cairo1 = 1 - - DEPLOYMENTS_DIR = Path("deployments") / NETWORK["name"] DEPLOYMENTS_DIR.mkdir(exist_ok=True, parents=True) COMPILED_CONTRACTS = [ - {"contract_name": "kakarot", "is_account_contract": False}, {"contract_name": "account_contract", "is_account_contract": True}, - {"contract_name": "uninitialized_account_fixture", "is_account_contract": False}, - {"contract_name": "uninitialized_account", "is_account_contract": False}, + {"contract_name": "BalanceSender", "is_account_contract": False}, + {"contract_name": "Counter", "is_account_contract": False}, + {"contract_name": "ERC20", "is_account_contract": False}, {"contract_name": "EVM", "is_account_contract": False}, + {"contract_name": "kakarot", "is_account_contract": False}, + {"contract_name": "MockPragmaOracle", "is_account_contract": False}, {"contract_name": "OpenzeppelinAccount", "is_account_contract": True}, - {"contract_name": "ERC20", "is_account_contract": False}, {"contract_name": "replace_class", "is_account_contract": False}, - {"contract_name": "Counter", "is_account_contract": False}, + {"contract_name": "StarknetToken", "is_account_contract": False}, + {"contract_name": "uninitialized_account_fixture", "is_account_contract": False}, + {"contract_name": "uninitialized_account", "is_account_contract": False}, + {"contract_name": "UniversalLibraryCaller", "is_account_contract": False}, ] DECLARED_CONTRACTS = [ - {"contract_name": "kakarot", "cairo_version": ArtifactType.cairo0}, - {"contract_name": "account_contract", "cairo_version": ArtifactType.cairo0}, - { - "contract_name": "uninitialized_account_fixture", - "cairo_version": ArtifactType.cairo0, - }, - {"contract_name": "uninitialized_account", "cairo_version": ArtifactType.cairo0}, - {"contract_name": "EVM", "cairo_version": ArtifactType.cairo0}, - {"contract_name": "OpenzeppelinAccount", "cairo_version": ArtifactType.cairo0}, - {"contract_name": "Cairo1Helpers", "cairo_version": ArtifactType.cairo1}, - {"contract_name": "Cairo1HelpersFixture", "cairo_version": ArtifactType.cairo1}, - {"contract_name": "replace_class", "cairo_version": ArtifactType.cairo0}, - {"contract_name": "Counter", "cairo_version": ArtifactType.cairo0}, - {"contract_name": "MockPragmaOracle", "cairo_version": ArtifactType.cairo1}, - {"contract_name": "StarknetToken", "cairo_version": ArtifactType.cairo1}, - {"contract_name": "ERC20", "cairo_version": ArtifactType.cairo0}, + "account_contract", + "Cairo1Helpers", + "Cairo1HelpersFixture", + "Counter", + "ERC20", + "EVM", + "kakarot", + "MockPragmaOracle", + "OpenzeppelinAccount", + "replace_class", + "StarknetToken", + "uninitialized_account_fixture", + "uninitialized_account", + "UniversalLibraryCaller", ] # PRE-EIP155 TX diff --git a/kakarot_scripts/deploy_kakarot.py b/kakarot_scripts/deploy_kakarot.py index 3fddb4f41..fc6257e0e 100644 --- a/kakarot_scripts/deploy_kakarot.py +++ b/kakarot_scripts/deploy_kakarot.py @@ -44,10 +44,7 @@ async def main(): account = await get_starknet_account() logger.info(f"ℹ️ Using account 0x{account.address:064x} as deployer") - class_hash = { - contract["contract_name"]: await declare(contract) - for contract in DECLARED_CONTRACTS - } + class_hash = {contract: await declare(contract) for contract in DECLARED_CONTRACTS} dump_declarations(class_hash) # %% Deployments @@ -88,7 +85,7 @@ async def main(): ) freshly_deployed = True - if NETWORK["type"] is NetworkType.STAGING: + if NETWORK["type"] is NetworkType.STAGING or NETWORK["type"] is NetworkType.DEV: starknet_deployments["EVM"] = await upgrade( "EVM", account.address, # owner @@ -101,21 +98,8 @@ async def main(): ) starknet_deployments["Counter"] = await upgrade("Counter") starknet_deployments["MockPragmaOracle"] = await upgrade("MockPragmaOracle") - - if NETWORK["type"] is NetworkType.DEV: - starknet_deployments["EVM"] = await deploy_starknet( - "EVM", - account.address, # owner - ETH_TOKEN_ADDRESS, # native_token_address_ - class_hash["account_contract"], # account_contract_class_hash_ - class_hash["uninitialized_account"], # uninitialized_account_class_hash_ - class_hash["Cairo1Helpers"], - COINBASE, - BLOCK_GAS_LIMIT, - ) - starknet_deployments["Counter"] = await deploy_starknet("Counter") - starknet_deployments["MockPragmaOracle"] = await deploy_starknet( - "MockPragmaOracle" + starknet_deployments["UniversalLibraryCaller"] = await upgrade( + "UniversalLibraryCaller" ) dump_deployments(starknet_deployments) @@ -124,11 +108,7 @@ async def main(): logger.info(f"ℹ️ Found default EVM address {EVM_ADDRESS}") from kakarot_scripts.utils.kakarot import get_eoa - amount = ( - 0.02 - if NETWORK["type"] is not (NetworkType.DEV or NetworkType.STAGING) - else 100 - ) + amount = 100 if NETWORK["type"] is NetworkType.DEV else 0.01 await get_eoa(amount=amount) # Set the base fee if freshly deployed @@ -152,6 +132,22 @@ async def main(): evm_deployments["CreateX"] = await deploy_with_presigned_tx( CREATEX_DEPLOYER, CREATEX_SIGNED_TX, amount=0.3, name="CreateX" ) + + if NETWORK["type"] is NetworkType.STAGING or NETWORK["type"] is NetworkType.DEV: + bridge = await deploy_evm("CairoPrecompiles", "EthStarknetBridge") + evm_deployments["Bridge"] = { + "address": int(bridge.address, 16), + "starknet_address": bridge.starknet_address, + } + await invoke( + "kakarot", + "set_authorized_cairo_precompile_caller", + int(bridge.address, 16), + 1, + ) + await invoke("kakarot", "set_coinbase", int(bridge.address, 16)) + await invoke("kakarot", "set_base_fee", 1) + dump_evm_deployments(evm_deployments) diff --git a/kakarot_scripts/utils/kakarot.py b/kakarot_scripts/utils/kakarot.py index 17794733d..98e41d740 100644 --- a/kakarot_scripts/utils/kakarot.py +++ b/kakarot_scripts/utils/kakarot.py @@ -46,9 +46,9 @@ from kakarot_scripts.utils.starknet import get_starknet_account from kakarot_scripts.utils.starknet import invoke as _invoke_starknet from kakarot_scripts.utils.starknet import wait_for_transaction +from kakarot_scripts.utils.uint256 import int_to_uint256 from tests.utils.constants import TRANSACTION_GAS_LIMIT from tests.utils.helpers import pack_calldata, rlp_encode_signed_data -from tests.utils.uint256 import int_to_uint256 logging.basicConfig() logger = logging.getLogger(__name__) @@ -316,7 +316,16 @@ def dump_deployments(deployments): def get_deployments(): try: - return json.load(open(DEPLOYMENTS_DIR / "kakarot_deployments.json", "r")) + return { + name: { + **value, + "address": int(value["address"], 16), + "starknet_address": int(value["starknet_address"], 16), + } + for name, value in json.load( + open(DEPLOYMENTS_DIR / "kakarot_deployments.json", "r") + ).items() + } except FileNotFoundError: return {} @@ -432,6 +441,7 @@ async def _wrapper(self, *args, **kwargs): data=calldata, caller_eoa=caller_eoa_ if caller_eoa_ else None, max_fee=max_fee, + gas_price=gas_price, ) if success == 0: logger.error(f"❌ {self.address}.{fun} failed") @@ -450,13 +460,12 @@ async def _wrapper(self, *args, **kwargs): async def _contract_exists(address: int) -> bool: try: await RPC_CLIENT.get_class_hash_at(address) - logger.info(f"ℹ️ Contract at address {hex(address)} already exists") return True except ClientError: return False -async def get_eoa(private_key=None, amount=10) -> Account: +async def get_eoa(private_key=None, amount=0) -> Account: private_key = private_key or keys.PrivateKey(bytes.fromhex(EVM_PRIVATE_KEY[2:])) starknet_address = await deploy_and_fund_evm_address( private_key.public_key.to_checksum_address(), amount @@ -541,6 +550,7 @@ async def eth_send_transaction( value: Union[int, str] = 0, caller_eoa: Optional[Account] = None, max_fee: Optional[int] = None, + gas_price=DEFAULT_GAS_PRICE, ): """Execute the data at the EVM contract to on Kakarot.""" evm_account = caller_eoa or await get_eoa() @@ -558,12 +568,11 @@ async def eth_send_transaction( ).nonce payload = { - "type": 0x2, + "type": 0x1, "chainId": NETWORK["chain_id"], "nonce": nonce, "gas": gas, - "maxPriorityFeePerGas": 1, - "maxFeePerGas": DEFAULT_GAS_PRICE, + "gasPrice": gas_price, "to": to_checksum_address(to) if to else None, "value": value, "data": data, diff --git a/kakarot_scripts/utils/starknet.py b/kakarot_scripts/utils/starknet.py index 4de3adc14..4dcccfb9d 100644 --- a/kakarot_scripts/utils/starknet.py +++ b/kakarot_scripts/utils/starknet.py @@ -2,7 +2,9 @@ import json import logging import random +import re import subprocess +from collections import namedtuple from copy import deepcopy from datetime import datetime from functools import cache @@ -35,16 +37,14 @@ from kakarot_scripts.constants import ( BUILD_DIR, - BUILD_DIR_FIXTURES, BUILD_DIR_SSJ, + CAIRO_DIR, + CAIRO_ZERO_DIR, CONTRACTS, - CONTRACTS_FIXTURES, DEPLOYMENTS_DIR, ETH_TOKEN_ADDRESS, NETWORK, RPC_CLIENT, - SOURCE_DIR, - ArtifactType, ChainId, NetworkType, ) @@ -58,12 +58,7 @@ # to have at least 0.1 ETH _max_fee = int(1e17) - -def int_to_uint256(value): - value = int(value) - low = value & ((1 << 128) - 1) - high = value >> 128 - return {"low": low, "high": high} +Artifact = namedtuple("Artifact", ["sierra", "casm"]) @alru_cache @@ -85,7 +80,7 @@ async def get_starknet_account( key_pair = KeyPair.from_private_key(int(private_key, 16)) public_key = None - for selector in ["get_public_key", "getPublicKey", "getSigner"]: + for selector in ["get_public_key", "getPublicKey", "getSigner", "get_owner"]: try: call = Call( to_addr=address, @@ -105,6 +100,7 @@ async def get_starknet_account( or "Invalid message selector." in message or "StarknetErrorCode.ENTRY_POINT_NOT_FOUND_IN_CONTRACT" in message or ("code 40" in message and "not found in contract" in message) + or "{'error': 'Invalid message selector'}" in message ): continue else: @@ -133,21 +129,19 @@ async def get_starknet_account( async def get_eth_contract(provider=None) -> Contract: return Contract( ETH_TOKEN_ADDRESS, - get_abi("ERC20", cairo_version=ArtifactType.cairo0), + get_abi("ERC20"), provider or await get_starknet_account(), - cairo_version=ArtifactType.cairo0, + cairo_version=0, ) @cache -def get_contract( - contract_name, address=None, provider=None, cairo_version=None -) -> Contract: +def get_contract(contract_name, address=None, provider=None) -> Contract: return Contract( address or get_deployments()[contract_name]["address"], - get_abi(contract_name, cairo_version), + get_abi(contract_name), provider or RPC_CLIENT, - cairo_version=get_artifact_version(contract_name).value, + cairo_version=get_cairo_version(contract_name), ) @@ -158,7 +152,7 @@ async def fund_address( Fund a given starknet address with {amount} ETH. """ address = int(address, 16) if isinstance(address, str) else address - amount = amount * 1e18 + amount = int(amount * 1e18) if NETWORK["name"] == "starknet-devnet": response = requests.post( "http://127.0.0.1:5050/mint", @@ -176,9 +170,7 @@ async def fund_address( raise ValueError( f"Cannot send {amount / 1e18} ETH from default account with current balance {balance / 1e18} ETH" ) - prepared = eth_contract.functions["transfer"].prepare_invoke_v1( - address, int_to_uint256(amount) - ) + prepared = eth_contract.functions["transfer"].prepare_invoke_v1(address, amount) tx = await prepared.invoke(max_fee=_max_fee) status = await wait_for_transaction(tx.hash) @@ -249,86 +241,82 @@ def get_deployments(): @cache -def get_artifact(contract_name, cairo_version=None): - if cairo_version is None: - cairo_version = get_artifact_version(contract_name) - if cairo_version == ArtifactType.cairo1: - return (BUILD_DIR_SSJ / f"contracts_{contract_name}", ArtifactType.cairo1) - - return ( - ( - BUILD_DIR / f"{contract_name}.json" - if not is_fixture_contract(contract_name) - else BUILD_DIR_FIXTURES / f"{contract_name}.json" - ), - ArtifactType.cairo0, +def get_artifact(contract_name): + artifacts = list(CAIRO_DIR.glob(f"**/*{contract_name}.*.json")) or list( + BUILD_DIR_SSJ.glob(f"**/*{contract_name}.*.json") ) + if artifacts: + sierra, casm = ( + artifacts + if "sierra.json" in artifacts[0].name + or ".contract_class.json" in artifacts[0].name + else artifacts[::-1] + ) + return Artifact(sierra=sierra, casm=casm) + + artifacts = list(BUILD_DIR.glob(f"**/*{contract_name}*.json")) + if not artifacts: + raise FileNotFoundError(f"No artifact found for {contract_name}") + return Artifact(sierra=None, casm=artifacts[0]) @cache -def get_abi(contract_name, cairo_version=None): - artifact, cairo_version = get_artifact(contract_name, cairo_version) - if cairo_version == ArtifactType.cairo1: - artifact = artifact.with_suffix(".contract_class.json") +def get_abi(contract_name): + artifact = get_artifact(contract_name) + return json.loads( + (artifact.sierra if artifact.sierra else artifact.casm).read_text() + )["abi"] - return json.loads(artifact.read_text())["abi"] +@cache +def get_cairo_version(contract_name): + return get_artifact(contract_name).sierra is not None + +@cache def get_tx_url(tx_hash: int) -> str: return f"{NETWORK['explorer_url']}/tx/0x{tx_hash:064x}" -def is_fixture_contract(contract_name): - return CONTRACTS_FIXTURES.get(contract_name) is not None - - -def get_artifact_version(contract_name): - cairo_0 = contract_name in set(CONTRACTS_FIXTURES).union(set(CONTRACTS)) - cairo_1 = any( - contract_name in str(artifact) for artifact in BUILD_DIR_SSJ.glob("*.json") - ) - if cairo_0 and cairo_1: - raise ValueError(f"Contract {contract_name} is ambiguous") - if cairo_0: - return ArtifactType.cairo0 - if cairo_1: - return ArtifactType.cairo1 - raise ValueError(f"Cannot find artifact for contract {contract_name}") - - def compile_contract(contract): logger.info(f"⏳ Compiling {contract['contract_name']}") start = datetime.now() - is_fixture = is_fixture_contract(contract["contract_name"]) - artifact, cairo_version = get_artifact(contract["contract_name"]) - - if cairo_version == ArtifactType.cairo1: - raise NotImplementedError("SSJ compilation not implemented yet") - - output = subprocess.run( - [ - "starknet-compile-deprecated", - ( - CONTRACTS[contract["contract_name"]] - if not is_fixture - else CONTRACTS_FIXTURES[contract["contract_name"]] - ), - "--output", - artifact, - "--cairo_path", - str(SOURCE_DIR), - *(["--no_debug_info"] if NETWORK["type"] is not NetworkType.DEV else []), - *(["--account_contract"] if contract["is_account_contract"] else []), - *( - ["--disable_hint_validation"] - if NETWORK["type"] is NetworkType.DEV - else [] - ), - ], - capture_output=True, + contract_path = CONTRACTS.get(contract["contract_name"]) or CONTRACTS.get( + re.sub("(?!^)([A-Z]+)", r"_\1", contract["contract_name"]).lower() ) + + if contract_path.is_relative_to(CAIRO_DIR): + output = subprocess.run( + "scarb build", shell=True, cwd=contract_path.parent, capture_output=True + ) + else: + output = subprocess.run( + [ + "starknet-compile-deprecated", + contract_path, + "--output", + BUILD_DIR / f"{contract['contract_name']}.json", + "--cairo_path", + str(CAIRO_ZERO_DIR), + *( + ["--no_debug_info"] + if NETWORK["type"] is not NetworkType.DEV + else [] + ), + *(["--account_contract"] if contract["is_account_contract"] else []), + *( + ["--disable_hint_validation"] + if NETWORK["type"] is NetworkType.DEV + else [] + ), + ], + capture_output=True, + ) + if output.returncode != 0: - raise RuntimeError(output.stderr) + raise RuntimeError( + f"❌ {contract['contract_name']} raised:\n{output.stderr}.\nOutput:\n{output.stdout}" + ) elapsed = datetime.now() - start logger.info( @@ -374,18 +362,14 @@ async def deploy_starknet_account(class_hash=None, private_key=None, amount=1): } -async def declare(contract): - logger.info(f"ℹ️ Declaring {contract['contract_name']}") - artifact, cairo_version = get_artifact(**contract) +async def declare(contract_name): + logger.info(f"ℹ️ Declaring {contract_name}") + artifact = get_artifact(contract_name) account = await get_starknet_account() - if cairo_version == ArtifactType.cairo1: - casm_compiled_contract = artifact.with_suffix( - ".compiled_contract_class.json" - ).read_text() - sierra_compiled_contract = artifact.with_suffix( - ".contract_class.json" - ).read_text() + if artifact.sierra is not None: + casm_compiled_contract = artifact.casm.read_text() + sierra_compiled_contract = artifact.sierra.read_text() casm_class = create_casm_class(casm_compiled_contract) class_hash = compute_casm_class_hash(casm_class) @@ -408,7 +392,7 @@ async def declare(contract): resp = await account.client.declare(transaction=declare_v2_transaction) else: contract_class = create_compiled_contract( - compiled_contract=artifact.read_text() + compiled_contract=artifact.casm.read_text() ) class_hash = compute_class_hash(contract_class=deepcopy(contract_class)) try: @@ -453,24 +437,14 @@ async def declare(contract): status = await wait_for_transaction(resp.transaction_hash) - logger.info( - f"{status} {contract['contract_name']} class hash: {hex(resp.class_hash)}" - ) + logger.info(f"{status} {contract_name} class hash: {hex(resp.class_hash)}") return deployed_class_hash async def deploy(contract_name, *args): logger.info(f"ℹ️ Deploying {contract_name}") - artifact, cairo_version = get_artifact(contract_name) + abi = get_abi(contract_name) declarations = get_declarations() - if cairo_version == ArtifactType.cairo0: - compiled_contract = Path(artifact).read_text() - abi = json.loads(compiled_contract)["abi"] - else: - sierra_compiled_contract = artifact.with_suffix( - ".contract_class.json" - ).read_text() - abi = json.loads(sierra_compiled_contract)["abi"] account = await get_starknet_account() deploy_result = await Contract.deploy_contract_v1( @@ -479,7 +453,7 @@ async def deploy(contract_name, *args): abi=abi, constructor_args=list(args), max_fee=_max_fee, - cairo_version=cairo_version.value, + cairo_version=get_cairo_version(contract_name), ) status = await wait_for_transaction(deploy_result.hash) logger.info( diff --git a/tests/utils/uint256.py b/kakarot_scripts/utils/uint256.py similarity index 100% rename from tests/utils/uint256.py rename to kakarot_scripts/utils/uint256.py diff --git a/solidity_contracts/src/CairoPrecompiles/EthStarknetBridge.sol b/solidity_contracts/src/CairoPrecompiles/EthStarknetBridge.sol new file mode 100644 index 000000000..bead05a28 --- /dev/null +++ b/solidity_contracts/src/CairoPrecompiles/EthStarknetBridge.sol @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import {CairoLib} from "kakarot-lib/CairoLib.sol"; + +using CairoLib for uint256; + +contract EthStarknetBridge { + /// @dev The cairo contract to call + uint256 constant starknetEth = 0x49D36570D4E46F48E99674BD3FCC84644DDD6B96F7C741B1562B82F9E004DC7; + uint256 constant TRANSFER_SELECTOR = uint256(keccak256("transfer")) % 2 ** 250; + + // State variable to store the owner of the contract + address immutable owner; + + // Constructor sets the owner of the contract + constructor() { + owner = msg.sender; + } + + // Modifier to restrict access to owner only + modifier onlyOwner() { + require(msg.sender == owner, "Not the contract owner"); + _; + } + + /// @notice Withdraws ETH from the contract to a Starknet address + function withdraw(uint256 toStarknetAddress) external onlyOwner { + uint256 balance = address(this).balance; + transfer(toStarknetAddress, balance); + } + + /// @notice Calls the Eth Cairo contract + /// @param toStarknetAddress The Starknet address to send ETH to + /// @param amount The amount of ETH to send + function transfer(uint256 toStarknetAddress, uint256 amount) public { + // Split amount in [low, high] + uint128 amountLow = uint128(amount); + uint128 amountHigh = uint128(amount >> 128); + + uint256[] memory transferCallData = new uint256[](3); + transferCallData[0] = toStarknetAddress; + transferCallData[1] = uint256(amountLow); + transferCallData[2] = uint256(amountHigh); + + starknetEth.delegatecallCairo(TRANSFER_SELECTOR, transferCallData); + } +} diff --git a/tests/end_to_end/Solmate/conftest.py b/tests/end_to_end/Solmate/conftest.py index 0e27a2a27..10d70306a 100644 --- a/tests/end_to_end/Solmate/conftest.py +++ b/tests/end_to_end/Solmate/conftest.py @@ -3,9 +3,9 @@ @pytest_asyncio.fixture(scope="module") async def from_wallet(new_eoa): - return await new_eoa() + return await new_eoa(0.1) @pytest_asyncio.fixture(scope="module") async def to_wallet(new_eoa): - return await new_eoa() + return await new_eoa(0.1) diff --git a/tests/end_to_end/Solmate/test_erc20.py b/tests/end_to_end/Solmate/test_erc20.py index 540a0010c..fb9cd56a9 100644 --- a/tests/end_to_end/Solmate/test_erc20.py +++ b/tests/end_to_end/Solmate/test_erc20.py @@ -229,36 +229,9 @@ async def test_should_permit(self, erc_20, owner, other): } ] assert await erc_20.allowance(owner.address, other.address) == TEST_SUPPLY - assert await erc_20.nonces(owner.address) == 1 + assert await erc_20.nonces(owner.address) == nonce + 1 - async def test_permit_should_fail_with_bad_nonce(self, erc_20, owner, other): - bad_nonce = 1 - deadline = 2**256 - 1 - digest = get_approval_digest( - "Kakarot Token", - erc_20.address, - { - "owner": owner.address, - "spender": other.address, - "value": MAX_INT, - }, - bad_nonce, - deadline, - ) - v, r, s = ec_sign(digest, owner.private_key) - with evm_error("INVALID_SIGNER"): - await erc_20.permit( - owner.address, - other.address, - TEST_SUPPLY, - deadline, - v, - r, - s, - caller_eoa=owner.starknet_contract, - ) - - async def test_permit_should_fail_with_bad_deadline( + async def test_should_fail_with_bad_deadline( self, erc_20, block_timestamp, owner, other ): nonce = await erc_20.nonces(owner.address) @@ -289,7 +262,7 @@ async def test_permit_should_fail_with_bad_deadline( caller_eoa=owner.starknet_contract, ) - async def test_permit_should_fail_on_replay(self, erc_20, owner, other): + async def test_should_fail_on_replay(self, erc_20, owner, other): nonce = await erc_20.nonces(owner.address) deadline = 2**256 - 1 digest = get_approval_digest( diff --git a/tests/end_to_end/conftest.py b/tests/end_to_end/conftest.py index ecbb9e8b8..b9f3df2e7 100644 --- a/tests/end_to_end/conftest.py +++ b/tests/end_to_end/conftest.py @@ -9,8 +9,11 @@ from starknet_py.net.account.account import Account from kakarot_scripts.constants import RPC_CLIENT, NetworkType +from kakarot_scripts.utils.kakarot import eth_balance_of +from kakarot_scripts.utils.kakarot import get_contract as get_solidity_contract from kakarot_scripts.utils.kakarot import get_eoa from kakarot_scripts.utils.starknet import ( + call, get_contract, get_eth_contract, get_starknet_account, @@ -48,24 +51,46 @@ def max_fee(): return int(5e17) -@pytest.fixture(scope="session") -def new_eoa(max_fee) -> Wallet: +@pytest_asyncio.fixture(scope="session") +async def new_eoa(deployer) -> Wallet: """ Return a factory to create a new EOA with enough ETH to pass ~100 tx by default. """ - async def _factory(amount=None): + deployed = [] + + async def _factory(amount=0): private_key: PrivateKey = generate_random_private_key() - return Wallet( + wallet = Wallet( address=private_key.public_key.to_checksum_address(), private_key=private_key, - starknet_contract=await get_eoa( - private_key, amount=amount or (100 * max_fee / 1e18) - ), + starknet_contract=await get_eoa(private_key, amount=amount), + ) + deployed.append(wallet) + return wallet + + yield _factory + + bridge_address = (await call("kakarot", "get_coinbase")).coinbase + bridge = await get_solidity_contract( + "CairoPrecompiles", "EthStarknetBridge", address=bridge_address + ) + gas_price = (await call("kakarot", "get_base_fee")).base_fee + gas_limit = 40_000 + tx_cost = gas_limit * gas_price + for wallet in deployed: + balance = await eth_balance_of(wallet.address) + if balance < tx_cost: + continue + + await bridge.transfer( + deployer.address, + balance - tx_cost, + caller_eoa=wallet.starknet_contract, + gas_limit=gas_limit, + gas_price=gas_price, ) - - return _factory @pytest_asyncio.fixture(scope="session") @@ -73,7 +98,7 @@ async def owner(new_eoa): """ Return the main caller of all tests. """ - return await new_eoa() + return await new_eoa(0.1) @pytest_asyncio.fixture(scope="module") @@ -81,7 +106,7 @@ async def other(new_eoa): """ Just another EOA. """ - return await new_eoa() + return await new_eoa(0.1) @pytest_asyncio.fixture(scope="session") diff --git a/tests/end_to_end/test_kakarot.py b/tests/end_to_end/test_kakarot.py index c6c099e30..d592d69ba 100644 --- a/tests/end_to_end/test_kakarot.py +++ b/tests/end_to_end/test_kakarot.py @@ -394,11 +394,11 @@ async def test_should_raise_when_tx_view_entrypoint(self, kakarot, entrypoint): class TestEthRPCEntrypoints: async def test_should_return_native_balance_of(self, new_eoa): - eoa = await new_eoa() + eoa = await new_eoa(0x1234 / 1e18) balance = ( await call("kakarot", "eth_get_balance", int(eoa.address, 16)) ).balance - assert balance == 50000000000000000000 + assert balance == 0x1234 async def test_should_return_transaction_count(self, new_eoa): eoa = await new_eoa() diff --git a/tests/src/kakarot/accounts/test_account_contract.py b/tests/src/kakarot/accounts/test_account_contract.py index d6e776596..d487e1225 100644 --- a/tests/src/kakarot/accounts/test_account_contract.py +++ b/tests/src/kakarot/accounts/test_account_contract.py @@ -15,12 +15,12 @@ ) from kakarot_scripts.constants import ARACHNID_PROXY_DEPLOYER, ARACHNID_PROXY_SIGNED_TX +from kakarot_scripts.utils.uint256 import int_to_uint256 from tests.utils.constants import CHAIN_ID, TRANSACTIONS from tests.utils.errors import cairo_error from tests.utils.helpers import generate_random_private_key, rlp_encode_signed_data from tests.utils.hints import patch_hint from tests.utils.syscall_handler import SyscallHandler -from tests.utils.uint256 import int_to_uint256 CHAIN_ID_OFFSET = 35 V_OFFSET = 27 diff --git a/tests/src/kakarot/instructions/test_environmental_information.py b/tests/src/kakarot/instructions/test_environmental_information.py index f990ac5a1..d8014db5e 100644 --- a/tests/src/kakarot/instructions/test_environmental_information.py +++ b/tests/src/kakarot/instructions/test_environmental_information.py @@ -3,8 +3,8 @@ import pytest from Crypto.Hash import keccak +from kakarot_scripts.utils.uint256 import int_to_uint256 from tests.utils.syscall_handler import SyscallHandler -from tests.utils.uint256 import int_to_uint256 EXISTING_ACCOUNT = 0xABDE1 EXISTING_ACCOUNT_SN_ADDR = 0x1234 diff --git a/tests/src/kakarot/instructions/test_stop_and_math_operations.py b/tests/src/kakarot/instructions/test_stop_and_math_operations.py index a03871da9..c052b5bcd 100644 --- a/tests/src/kakarot/instructions/test_stop_and_math_operations.py +++ b/tests/src/kakarot/instructions/test_stop_and_math_operations.py @@ -1,7 +1,7 @@ import pytest +from kakarot_scripts.utils.uint256 import int_to_uint256 from tests.utils.constants import Opcodes -from tests.utils.uint256 import int_to_uint256 class TestStopMathOperations: diff --git a/tests/src/kakarot/test_account.cairo b/tests/src/kakarot/test_account.cairo index 98d83d5df..79e753100 100644 --- a/tests/src/kakarot/test_account.cairo +++ b/tests/src/kakarot/test_account.cairo @@ -24,7 +24,7 @@ func test__init__should_return_account_with_default_dict_as_storage{ local nonce: felt; local balance_low: felt; %{ - from tests.utils.uint256 import int_to_uint256 + from kakarot_scripts.utils.uint256 import int_to_uint256 ids.evm_address = program_input["evm_address"] ids.code_len = len(program_input["code"]) @@ -68,7 +68,7 @@ func test__copy__should_return_new_account_with_same_attributes{ local nonce: felt; local balance_low: felt; %{ - from tests.utils.uint256 import int_to_uint256 + from kakarot_scripts.utils.uint256 import int_to_uint256 ids.evm_address = program_input["evm_address"] ids.code_len = len(program_input["code"]) @@ -196,7 +196,7 @@ func test__has_code_or_nonce{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, ran let (code_hash_ptr) = alloc(); local nonce: felt; %{ - from tests.utils.uint256 import int_to_uint256 + from kakarot_scripts.utils.uint256 import int_to_uint256 ids.code_len = len(program_input["code"]) segments.write_arg(ids.code, program_input["code"]) diff --git a/tests/src/kakarot/test_account.py b/tests/src/kakarot/test_account.py index b9ebdcf67..046c39d0a 100644 --- a/tests/src/kakarot/test_account.py +++ b/tests/src/kakarot/test_account.py @@ -3,8 +3,8 @@ from hypothesis import given from hypothesis.strategies import binary +from kakarot_scripts.utils.uint256 import int_to_uint256 from tests.utils.syscall_handler import SyscallHandler -from tests.utils.uint256 import int_to_uint256 class TestAccount: diff --git a/tests/src/kakarot/test_gas.cairo b/tests/src/kakarot/test_gas.cairo index 6c57612ec..80b68d8fc 100644 --- a/tests/src/kakarot/test_gas.cairo +++ b/tests/src/kakarot/test_gas.cairo @@ -58,7 +58,7 @@ func test__memory_expansion_cost_saturated{range_check_ptr}() -> felt { let (offset) = alloc(); let (size) = alloc(); %{ - from tests.utils.uint256 import int_to_uint256 + from kakarot_scripts.utils.uint256 import int_to_uint256 ids.words_len = program_input["words_len"] segments.write_arg(ids.offset, int_to_uint256(program_input["offset"])) segments.write_arg(ids.size, int_to_uint256(program_input["size"])) diff --git a/tests/src/kakarot/test_kakarot.cairo b/tests/src/kakarot/test_kakarot.cairo index a97d08208..fef315d67 100644 --- a/tests/src/kakarot/test_kakarot.cairo +++ b/tests/src/kakarot/test_kakarot.cairo @@ -37,7 +37,7 @@ func eth_call{ let (access_list) = alloc(); %{ - from tests.utils.uint256 import int_to_uint256 + from kakarot_scripts.utils.uint256 import int_to_uint256 ids.origin = program_input.get("origin", 0) ids.to.is_some = int(bool(program_input.get("to") is not None)) diff --git a/tests/src/kakarot/test_state.cairo b/tests/src/kakarot/test_state.cairo index 9b0ee80b9..97848cb73 100644 --- a/tests/src/kakarot/test_state.cairo +++ b/tests/src/kakarot/test_state.cairo @@ -113,7 +113,7 @@ func test__is_account_alive__account_alive_in_state{ let (code) = alloc(); let (code_hash_ptr) = alloc(); %{ - from tests.utils.uint256 import int_to_uint256 + from kakarot_scripts.utils.uint256 import int_to_uint256 ids.nonce = program_input["nonce"] ids.balance_low = program_input["balance_low"] diff --git a/tests/src/utils/test_bytes.py b/tests/src/utils/test_bytes.py index 2ea3b5e0a..32b8f866b 100644 --- a/tests/src/utils/test_bytes.py +++ b/tests/src/utils/test_bytes.py @@ -4,9 +4,9 @@ from hypothesis import given from hypothesis.strategies import integers +from kakarot_scripts.utils.uint256 import int_to_uint256 from tests.utils.errors import cairo_error from tests.utils.hints import patch_hint -from tests.utils.uint256 import int_to_uint256 PRIME = 0x800000000000011000000000000000000000000000000000000000000000001 diff --git a/tests/src/utils/test_uint256.py b/tests/src/utils/test_uint256.py index 30313dac2..dbdfdfa37 100644 --- a/tests/src/utils/test_uint256.py +++ b/tests/src/utils/test_uint256.py @@ -2,7 +2,7 @@ from hypothesis import given, settings from hypothesis.strategies import integers -from tests.utils.uint256 import int_to_uint256, uint256_to_int +from kakarot_scripts.utils.uint256 import int_to_uint256, uint256_to_int class TestUint256: diff --git a/tests/utils/helpers.py b/tests/utils/helpers.py index 3df45f6d8..d0fea36a9 100644 --- a/tests/utils/helpers.py +++ b/tests/utils/helpers.py @@ -13,7 +13,7 @@ from starkware.starknet.public.abi import get_storage_var_address from kakarot_scripts.constants import NETWORK -from tests.utils.uint256 import int_to_uint256 +from kakarot_scripts.utils.uint256 import int_to_uint256 PERMIT_TYPEHASH = keccak( text="Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)" diff --git a/tests/utils/syscall_handler.py b/tests/utils/syscall_handler.py index 9cd505be7..fbc09f16f 100644 --- a/tests/utils/syscall_handler.py +++ b/tests/utils/syscall_handler.py @@ -16,12 +16,12 @@ get_storage_var_address, ) +from kakarot_scripts.utils.uint256 import int_to_uint256, uint256_to_int from tests.utils.constants import ( ACCOUNT_CLASS_IMPLEMENTATION, CAIRO1_HELPERS_CLASS_HASH, CHAIN_ID, ) -from tests.utils.uint256 import int_to_uint256, uint256_to_int def cairo_keccak(class_hash, calldata):