### Generate Example Project Source: https://github.com/ackee-blockchain/wake/blob/main/docs/testing-framework/getting-started.md Use this command to create an example project in your current directory. Code snippets in this guide are based on such a project. ```shell wake up --example counter ``` -------------------------------- ### Setup Git Hooks Source: https://github.com/ackee-blockchain/wake/blob/main/docs/contributing.md Makes the git hooks script executable and then runs it to install the necessary hooks for development. This script should be run after cloning the repository. ```bash chmod +x ./setup-githooks.sh ./setup-githooks.sh ``` -------------------------------- ### Install Dependencies Source: https://github.com/ackee-blockchain/wake/blob/main/examples/counter/README.md Installs project dependencies using npm. This is a prerequisite for using Wake commands. ```bash npm install ``` -------------------------------- ### Install Project with Poetry Source: https://github.com/ackee-blockchain/wake/blob/main/docs/contributing.md Installs the project dependencies, including optional features for tests and development, using Poetry. ```bash poetry install -E tests -E dev ``` -------------------------------- ### Run Printer with Contract Paths Source: https://github.com/ackee-blockchain/wake/blob/main/docs/static-analysis/using-printers.md Example of running the 'inheritance-graph' printer on contracts located in the 'contracts/utils' directory. ```bash wake print inheritance-graph contracts/utils ``` -------------------------------- ### Running Wake Detector with Paths Source: https://github.com/ackee-blockchain/wake/blob/main/docs/static-analysis/getting-started.md Command-line example showing how to run a Wake detector on specific contract files or directories. ```bash wake detect my-detector contracts/utils ``` -------------------------------- ### Install Wake using pip Source: https://github.com/ackee-blockchain/wake/blob/main/docs/installation.md Use this command to install the eth-wake package via pip. Ensure you have Python 3.8 or higher installed. ```shell pip3 install eth-wake ``` -------------------------------- ### Install Project with pip Source: https://github.com/ackee-blockchain/wake/blob/main/docs/contributing.md Installs the project in editable mode with pip, including development and test dependencies. Ensure you are in the project root. ```bash pip install -e ".[tests,dev]" ``` -------------------------------- ### Wake-integrated console.sol Example Source: https://github.com/ackee-blockchain/wake/blob/main/docs/testing-framework/debugging.md Demonstrates how to use Wake's integrated `console.sol` library within a Solidity contract to emit log messages. ```solidity import "wake/console.sol"; contract MyContract { function myFunction() public view { console.log("Hello world!"); } } ``` -------------------------------- ### List Detector Sources Source: https://github.com/ackee-blockchain/wake/blob/main/docs/static-analysis/using-detectors.md Run this command to see the list of available sources for each detector, including local directories and installed packages. ```bash wake detect list ``` -------------------------------- ### Create Virtual Environment with Poetry Source: https://github.com/ackee-blockchain/wake/blob/main/docs/contributing.md Activates a virtual environment using Poetry. Ensure Poetry is installed and the project is initialized. ```bash poetry shell ``` -------------------------------- ### Printer CLI with Arguments and Options Source: https://github.com/ackee-blockchain/wake/blob/main/docs/static-analysis/getting-started.md Example of a Click command for a printer that accepts a required argument and an optional flag. ```python @printer.command(name="my-printer") @click.argument( "modifier", type=str, required=True, help="Name of the modifier to analyze.", ) @click.option( "--follow-function-calls/--no-follow-function-calls", is_flag=True, default=False, help="Follow function calls in the modifier.", ) ``` -------------------------------- ### Setup Config and Generate Pytypes Source: https://github.com/ackee-blockchain/wake/blob/main/docs/testing-framework/getting-started.md Use these commands to specifically set up the configuration file and generate pytypes. The `-w` flag enables watching for contract changes and auto-regeneration. ```shell wake up config ``` ```shell wake up pytypes -w ``` -------------------------------- ### Install Latest Anvil Source: https://github.com/ackee-blockchain/wake/blob/main/docs/testing-framework/getting-started.md Ensure you have the latest version of Anvil installed, which is crucial for active development. Run this command to update. ```shell foundryup ``` -------------------------------- ### List Available Printer Sources Source: https://github.com/ackee-blockchain/wake/blob/main/docs/static-analysis/using-printers.md Run this command to see all available sources for each printer, including local directories and installed packages. ```bash wake print list ``` -------------------------------- ### Example Deployment Script Source: https://github.com/ackee-blockchain/wake/blob/main/docs/testing-framework/deployment.md A Python script demonstrating contract deployment to a live chain using `wake.deployment`. It connects to Alchemy, sets default accounts, deploys a `Counter` contract, and asserts its state after an increment. ```python from wake.deployment import * from pytypes.contracts.Counter import Counter ALCHEMY_API_KEY = "YOUR_ALCHEMY_API_KEY" @chain.connect(f"wss://eth-mainnet.g.alchemy.com/v2/{ALCHEMY_API_KEY}") def main(): acc = Account.from_alias("deployment") chain.set_default_accounts(acc) counter = Counter.deploy() print(counter) counter.increment() assert counter.count() == 1 ``` -------------------------------- ### Install Pyright via npm Source: https://github.com/ackee-blockchain/wake/blob/main/docs/contributing.md Installs Pyright, the static type checker, globally using npm. This is required for type checking Python code. ```bash npm i -g pyright ``` -------------------------------- ### Running the Wake LSP Server Source: https://github.com/ackee-blockchain/wake/blob/main/README.md Command to start the Wake Language Server Protocol (LSP) server. ```shell wake lsp ``` -------------------------------- ### Plugin Loading Priorities Example Source: https://github.com/ackee-blockchain/wake/blob/main/docs/configuration.md This TOML snippet demonstrates how to set loading priorities for detectors and printers in the plugins.toml file. It allows specifying preferred modules for specific detectors or printers, or a default for all. ```toml [detector_loading_priorities] reentrancy = "my_detectors" # prefer my_detectors module if present unused-import = ["my_detectors", "wake_detectors"] # prefer my_detectors, then wake_detectors "*" = "wake_detectors" # prefer wake_detectors for all other detectors [printer_loading_priorities] # follows the same structure ``` -------------------------------- ### Configure Printer in wake.toml Source: https://github.com/ackee-blockchain/wake/blob/main/docs/static-analysis/using-printers.md Printer configuration can be set in the project's TOML file. This example shows how to set a 'custom_option' for a specific printer. ```toml [printer."printer-name"] custom_option = "value" ``` -------------------------------- ### Get Printer-Specific Help Source: https://github.com/ackee-blockchain/wake/blob/main/docs/static-analysis/using-printers.md To view arguments and options for a specific printer, append '--help' to the printer's command. ```bash wake print printer-name --help ``` -------------------------------- ### Subconfig Loading Example Source: https://github.com/ackee-blockchain/wake/blob/main/docs/configuration.md This TOML snippet shows how to specify additional TOML configuration files (subconfigs) to be loaded. These subconfigs override values from the parent configuration file. ```toml subconfigs = ["loaded_next.toml", "../relative.toml", "/tmp/absolute.toml", "loaded_last.toml"] ``` -------------------------------- ### Configure LSP References Printer Source: https://github.com/ackee-blockchain/wake/blob/main/docs/configuration.md Example of how to configure the LSP references printer. Set `local_variables` to false to exclude them from results. ```toml [printer."lsp-references"] local_variables = false ``` -------------------------------- ### Using Request Types with Contract Deployment Source: https://github.com/ackee-blockchain/wake/blob/main/docs/testing-framework/interacting-with-contracts.md Demonstrates various request types for contract deployment, including 'call' to get runtime code, 'tx' for deployment, 'tx' with return_tx=True, 'estimate' for gas, and 'access_list' for access list and gas estimation. ```python # does not deploy the contract runtime_code = Counter.deploy(request_type="call") # deploys the contract and returns the contract instance, the default behavior counter = Counter.deploy(request_type="tx") # deploys the contract and returns the transaction object tx = Counter.deploy(request_type="tx", return_tx=True) # amount of gas needed to deploy the contract gas_estimate = Counter.deploy(request_type="estimate") # access list and amount of gas needed to deploy the contract access_list, gas_estimate = Counter.deploy(request_type="access_list") ``` -------------------------------- ### Using generate_link in Visitor Source: https://github.com/ackee-blockchain/wake/blob/main/docs/static-analysis/getting-started.md Example demonstrating how to use the generate_link method within a visit function to create a link to a function's canonical name. ```python def visit_function_definition(self, node: ir.FunctionDefinition) -> None: link = f"[link={self.generate_link(node)}]{node.canonical_name}[/link]" ``` -------------------------------- ### Filtering Nodes When Visit Mode is 'all' Source: https://github.com/ackee-blockchain/wake/blob/main/docs/static-analysis/getting-started.md Example for a printer that overrides visit_mode to 'all' but includes logic to filter nodes based on the provided paths, ensuring relevance. ```python class MyPrinterPrinter(Printer): ... @property def visit_mode(self): return "all" def visit_contract_definition(self, node: ir.ContractDefinition) -> None: from wake.utils import is_relative_to if not any(is_relative_to(node.source_unit.file, p) for p in self.paths): return ... ``` -------------------------------- ### Registering and Using a Transaction Callback Source: https://github.com/ackee-blockchain/wake/blob/main/docs/testing-framework/transaction-objects.md Demonstrates how to register a `tx_callback` on a `Chain` instance to process transaction objects. The callback receives the transaction object and can access its properties like `console_logs`. This example deploys a `Counter` contract and calls its `increment` function. ```python from wake.testing import * from pytypes.contracts.Counter import Counter def tx_callback(tx: TransactionAbc): print(tx.console_logs) @chain.connect() def test_callback(): chain.tx_callback = tx_callback counter = Counter.deploy() counter.increment() ``` -------------------------------- ### Fuzz Testing Solidity Contracts with Wake Source: https://github.com/ackee-blockchain/wake/blob/main/README.md Demonstrates how to use Wake's fuzzing framework to test a Solidity 'Counter' contract. Includes pre-sequence setup, flow definitions for increment/decrement operations with error handling, and an invariant to check the contract's state. ```python from wake.testing import * from wake.testing.fuzzing import * from pytypes.contracts.Counter import Counter class CounterTest(FuzzTest): def pre_sequence(self) -> None: self.counter = Counter.deploy() self.count = 0 @flow() def increment(self) -> None: self.counter.increment() self.count += 1 @flow() def decrement(self) -> None: with may_revert(PanicCodeEnum.UNDERFLOW_OVERFLOW) as e: self.counter.decrement() if e.value is not None: assert self.count == 0 else: self.count -= 1 @invariant(period=10) def count(self) -> None: assert self.counter.count() == self.count @chain.connect() def test_counter(): CounterTest().run(sequences_count=30, flows_count=100) ``` -------------------------------- ### Debug Wake LSP Server Source: https://github.com/ackee-blockchain/wake/blob/main/docs/language-server.md Use this command to start the Wake LSP server in debug mode. This is useful for troubleshooting and understanding the server's behavior. ```shell wake --debug lsp ``` -------------------------------- ### Example of Unused Contracts, Interfaces, and Libraries Source: https://github.com/ackee-blockchain/wake/blob/main/docs/static-analysis/detectors/unused-contract.md This Solidity code demonstrates an abstract contract 'A', an interface 'I', a library 'L', and a regular contract 'C'. The detector will report 'A', 'I', and 'L' as unused if they are not referenced elsewhere in the project. ```solidity abstract contract A { // (1)! function foo() external virtual; } interface I { // (2)! function bar() external; } library L { // (3)! function baz() external {} } contract C { function qux() external {} } ``` -------------------------------- ### Flow with Typed Arguments Source: https://github.com/ackee-blockchain/wake/blob/main/docs/testing-framework/fuzzing.md Demonstrates how to define a flow function that accepts typed arguments, which Wake's fuzzing engine will automatically generate. Uses 'uint' as an example argument type. ```python @flow() def flow_set_count(self, count: uint) -> None: self.counter.set_count(count, from_=self.counter.owner()) self.count = count ``` -------------------------------- ### Setting up Multiple Chains and Deploying Contracts Source: https://github.com/ackee-blockchain/wake/blob/main/docs/testing-framework/cross-chain-testing.md Demonstrates how to create separate Chain instances for different chains and deploy contracts to them. It also shows how to use accounts from one chain when deploying to another, highlighting a common ValueError and its solution. ```python from wake.testing import * from wake.testing.fuzzing import random_account from pytypes.contracts.Counter import Counter chain1 = Chain() chain2 = Chain() @chain1.connect() @chain2.connect() def test_cross_chain(): owner = random_account(chain=chain2) counter1 = Counter.deploy(from_=owner, chain=chain1) ``` ```python counter1 = Counter.deploy(from_=owner.address, chain=chain1) ``` -------------------------------- ### Creating a New Account with a Random Private Key Source: https://github.com/ackee-blockchain/wake/blob/main/docs/testing-framework/accounts-and-addresses.md Illustrates how to generate a new Account instance with a randomly generated private key. This is useful for creating fresh accounts for testing. ```python from wake.testing import Account Account.new() ``` -------------------------------- ### Install pytest-cov for Python Coverage Source: https://github.com/ackee-blockchain/wake/blob/main/docs/testing-framework/coverage-analysis.md Install the pytest-cov plugin to measure coverage of Python scripts executed with `wake test`. This is a prerequisite for Python coverage analysis. ```bash pip3 install pytest-cov ``` -------------------------------- ### Python Coverage Report Example Source: https://github.com/ackee-blockchain/wake/blob/main/docs/testing-framework/coverage-analysis.md Example output of a Python coverage report generated by pytest-cov. It shows statements, missed lines, and coverage percentage for test files. ```text ---------- coverage: platform linux, python 3.7.12-final-0 ---------- Name Stmts Miss Cover -------------------------------------------------------- tests/__init__.py 0 0 100% tests/test_counter.py 36 4 89% tests/test_counter_fuzz.py 34 0 100% tests/test_counter_fuzz_failing.py 23 4 83% tests/test_crosschain.py 63 0 100% -------------------------------------------------------- TOTAL 156 8 95% ``` -------------------------------- ### Interacting with Contracts via Proxies Source: https://github.com/ackee-blockchain/wake/blob/main/docs/testing-framework/accounts-and-addresses.md Demonstrates how to deploy an implementation contract and a proxy, then interact with the implementation through the proxy address. This pattern is common for upgradeable contracts. ```python from wake.testing import * from pytypes.contracts.Counter import Counter from pytypes.openzeppelin.contracts.proxy.ERC1967.ERC1967Proxy import ERC1967Proxy @chain.connect() def test_proxy(): impl = Counter.deploy() proxy = ERC1967Proxy.deploy(impl, b"") # behave as if Counter was deployed at proxy.address counter = Counter(proxy.address) counter.increment() assert counter.count() == 1 ``` -------------------------------- ### Counter Fuzz Test Example Source: https://github.com/ackee-blockchain/wake/blob/main/docs/testing-framework/fuzzing.md An example of a FuzzTest class that tests a Counter contract, including pre_sequence hook, increment/decrement flows, and an invariant check. Demonstrates basic fuzz test structure and execution. ```python from wake.testing import * from wake.testing.fuzzing import * from pytypes.contracts.Counter import Counter class CounterTest(FuzzTest): counter: Counter count: int def pre_sequence(self) -> None: self.counter = Counter.deploy() self.count = 0 @flow() def flow_increment(self) -> None: self.counter.increment() self.count += 1 @flow() def flow_decrement(self) -> None: with may_revert(PanicCodeEnum.UNDERFLOW_OVERFLOW) as e: self.counter.decrement() if e.value is None: self.count -= 1 else: assert self.count == 0 @invariant(period=10) def invariant_count(self) -> None: assert self.counter.count() == self.count @chain.connect() def test_counter(): CounterTest().run(sequences_count=30, flows_count=100) ``` -------------------------------- ### Solidity Call Options Not Called Example Source: https://github.com/ackee-blockchain/wake/blob/main/docs/static-analysis/detectors/call-options-not-called.md This example demonstrates the usage of call options (`value`) with the low-level `call` function in Solidity. It highlights scenarios where the `value` option is specified but the `call` function itself is not invoked, which is what the detector flags. ```solidity pragma solidity ^0.6.0; contract Example { function withdraw() external { msg.sender.call{value: address(this).balance}; // (1)! } function withdraw2() external { msg.sender.call.value(address(this).balance); // (2)! } } ``` -------------------------------- ### Solidity Example of Calldata Tuple Reencoding Head Overflow Bug Source: https://github.com/ackee-blockchain/wake/blob/main/docs/static-analysis/detectors/calldata-tuple-reencoding-head-overflow-bug.md This example demonstrates a Solidity contract with a struct and functions that can trigger the calldata tuple reencoding head overflow bug. It highlights the conditions required for the bug, such as a dynamic component and a calldata array as the last component. ```solidity pragma solidity 0.8.0; struct T { bytes x; // (1)! uint[3] y; } contract C { function f(bool a, T memory b, bytes32[2] memory c) public {} function vulnerable(bytes32[2] calldata data) external { this.f(true, T("abcd", [uint(11), 12, 13]), data); } } ``` -------------------------------- ### List All Detectors Source: https://github.com/ackee-blockchain/wake/blob/main/docs/static-analysis/using-detectors.md Run this command to see a list of all available detectors and their help information. ```bash wake detect --help ``` -------------------------------- ### Solidity Contract Using address.balance in Comparison Source: https://github.com/ackee-blockchain/wake/blob/main/docs/static-analysis/detectors/balance-relied-on.md This Solidity code demonstrates a contract where the `bid` function relies on `address(this).balance != 0` to determine if the auction has started. This pattern is flagged by the detector. An attacker could exploit this by sending Ether to the contract address via `selfdestruct` from another contract, thereby bypassing the intended auction start condition. ```solidity pragma solidity ^0.8; contract Auction { address owner; constructor() { owner = msg.sender; } receive() external payable { // only the owner can start the auction with initial bid require(msg.sender == owner); } function bid() external payable { require( address(this).balance != 0, // (1)! "Cannot bid on an auction that has not started" ); // ... } } ``` -------------------------------- ### Python Deployment Script for Proxy Source: https://github.com/ackee-blockchain/wake/blob/main/docs/cookbook/specialized-use-cases/deploy-with-proxy.md Deploys an implementation contract and then deploys a proxy contract pointing to the implementation, initializing the contract through the proxy. ```python impl = MyContract.deploy() proxy = Proxy.deploy(impl, abi.encode(self.owner, 1)) self.my_contract = MyContract(proxy) ``` -------------------------------- ### Solidity Event Definition Source: https://github.com/ackee-blockchain/wake/blob/main/docs/testing-framework/events-and-errors.md Example of a Solidity event definition for a `Transfer` event with indexed and non-indexed parameters. ```solidity event Transfer( address indexed from, address indexed to, uint256 value ); ``` -------------------------------- ### Generate Pytypes Source: https://github.com/ackee-blockchain/wake/blob/main/docs/testing-framework/getting-started.md This command initializes Wake by preparing configuration files, updating gitignore, setting up directories, and generating pytypes for all Solidity source files. ```shell wake up ``` -------------------------------- ### Array Delete Nullification Example Source: https://github.com/ackee-blockchain/wake/blob/main/docs/static-analysis/detectors/array-delete-nullification.md Demonstrates how `delete` on an array element sets it to 0 but does not shorten the array. ```solidity pragma solidity ^0.8.0; contract Example { uint[] public numbers = [1, 2, 3, 4, 5]; function deleteNumber(uint index) public { delete numbers[index]; // (1)! // If index was 2, array would be [1, 2, 0, 4, 5] } } ``` -------------------------------- ### Solidity User-Defined Error Definition Source: https://github.com/ackee-blockchain/wake/blob/main/docs/testing-framework/events-and-errors.md Example of a Solidity user-defined error definition `NotEnoughFunds` with two `uint256` parameters. ```solidity error NotEnoughFunds( uint256 requested, uint256 available ); ``` -------------------------------- ### Run Wake Compiler Source: https://github.com/ackee-blockchain/wake/blob/main/docs/compilation.md Use this command to initiate the compilation process with Wake. The `--help` flag provides access to additional command-line options. ```sh wake compile ``` -------------------------------- ### Deploying a Contract from Creation Code Source: https://github.com/ackee-blockchain/wake/blob/main/docs/testing-framework/accounts-and-addresses.md Shows how to deploy a contract using its creation code with the `chain.deploy` method. This is useful for deploying contracts that do not have a direct constructor interface available. ```python chain.deploy(Counter.get_creation_code()) ``` -------------------------------- ### Configure Detector Arguments Source: https://github.com/ackee-blockchain/wake/blob/main/docs/static-analysis/using-detectors.md View detailed help for a specific detector, including its arguments, options, and configurable environment variables. ```bash wake detect detector-name --help ``` -------------------------------- ### Importing wake modules for testing and deployment Source: https://github.com/ackee-blockchain/wake/blob/main/docs/testing-framework/deployment.md Use `wake.deployment` for live chains (testnet/mainnet) and `wake.testing` for local development chains. This choice affects various chain behaviors. ```python # use wake.deployment when interacting with a live chain from wake.deployment import * # use wake.testing when interacting with a local development chain from wake.testing import * ``` -------------------------------- ### Running the Wake LSP Server on a Specific Port Source: https://github.com/ackee-blockchain/wake/blob/main/README.md Command to start the Wake LSP server on a custom network port. ```shell wake lsp --port 1234 ``` -------------------------------- ### Solidity Contract with Incorrect State Mutability Source: https://github.com/ackee-blockchain/wake/blob/main/docs/static-analysis/detectors/incorrect-interface.md This example highlights a `totalSupply` function that should be `view` or `pure` but is not marked as such, violating the ERC-20 standard. ```solidity pragma solidity ^0.8; contract MyToken { mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256)) public allowance; event Transfer(address indexed from, address indexed to, uint256 value); event Approval( address indexed owner, address indexed spender, uint256 value ); function totalSupply() external returns (uint256) { // (1)! // ... } function approve(address spender, uint256 value) external returns (bool) { // ... } function transfer(address to, uint256 value) external returns (bool) { // ... } function transferFrom( address from, address to, uint256 value ) external returns (bool) { // ... } } ``` -------------------------------- ### Configuring Chain Connection with Keyword Arguments Source: https://github.com/ackee-blockchain/wake/blob/main/docs/testing-framework/chains-and-blocks.md Shows how to use keyword arguments with the `chain.connect()` decorator to customize chain parameters like the number of accounts and the chain ID. Assertions verify the applied configurations. ```python from wake.testing import chain @chain.connect( accounts=15, chain_id=1020, ) def test_chain(): assert len(chain.accounts) == 15 assert chain.chain_id == 1020 ``` -------------------------------- ### Unused Modifier Example Source: https://github.com/ackee-blockchain/wake/blob/main/docs/static-analysis/detectors/unused-modifier.md This Solidity code demonstrates a contract with an unused 'onlyOwner' modifier. The detector would flag this modifier as unused. ```solidity pragma solidity ^0.8; contract C { address public owner; modifier onlyOwner() { require(msg.sender == owner, "Not owner."); _; } constructor() { owner = msg.sender; } function withdraw() external /*onlyOwner*/ { (bool success, ) = msg.sender.call{value: address(this).balance}(""); require(success, "Transfer failed."); } } ``` -------------------------------- ### Import Contract from node_modules in Wake Source: https://github.com/ackee-blockchain/wake/blob/main/docs/testing-framework/migrating-from-ape-and-brownie.md Import a contract type from `node_modules` into your Wake project. This example shows importing `ERC1967Proxy` from OpenZeppelin contracts. ```python from pytypes.node_modules.openzeppelin.contracts.proxy.ERC1967.ERC1967Proxy import ERC1967Proxy ``` -------------------------------- ### Wake Accounts CLI Help Source: https://github.com/ackee-blockchain/wake/blob/main/docs/testing-framework/deployment.md Displays help information for the `wake accounts` CLI command, outlining available subcommands for managing accounts. ```console $ wake accounts --help Usage: wake accounts [OPTIONS] COMMAND [ARGS]... Run Wake accounts manager. ╭─ Options ───────────────────────────────────────────────────────────────╮ │ --help Show this message and exit. │ ╰─────────────────────────────────────────────────────────────────────────╯ ╭─ Commands ────────────────────────────────────────────────────────────── │ export Export an account's private key. │ │ import Import an account from a private key or mnemonic. │ │ list List all accounts. │ │ new Create a new account. │ │ remove Remove an account. │ ╰─────────────────────────────────────────────────────────────────────────╯ ``` -------------------------------- ### Default Include Paths Configuration Source: https://github.com/ackee-blockchain/wake/blob/main/docs/compilation.md Specifies the default directories where the compiler searches for Solidity files imported via direct import strings. This configuration is typically found in the `wake.toml` file. ```toml [compiler.solc] include_paths = ["node_modules"] ``` -------------------------------- ### Create a Printer Template Source: https://github.com/ackee-blockchain/wake/blob/main/docs/static-analysis/getting-started.md Use this command to generate a template for a new printer. The template will be created in the `./printers` directory. ```bash wake up printer printer-name ``` -------------------------------- ### Solidity Contract Missing ERC-20 Functions/Events Source: https://github.com/ackee-blockchain/wake/blob/main/docs/static-analysis/detectors/incorrect-interface.md This example shows a contract missing the `transferFrom` function and `Approval` event required by the ERC-20 standard. ```solidity pragma solidity ^0.8; contract MyToken { // (1)! uint256 public totalSupply; mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256)) public allowance; event Transfer(address indexed from, address indexed to, uint256 value); function approve(address spender, uint256 value) external returns (bool) { // ... } function transfer(address to, uint256 value) external returns (bool) { // ... } } ``` -------------------------------- ### Importing Accounts and Addresses from a Private Key Source: https://github.com/ackee-blockchain/wake/blob/main/docs/testing-framework/accounts-and-addresses.md Demonstrates how to import Account and Address objects using a private key. The private key must be a 64-character hex string prefixed with '0x'. ```python from wake.testing import Account, Address Account.from_key("0x" + "a" * 64) Address.from_key("0x" + "a" * 64) ``` -------------------------------- ### Configure Development Chain in wake.toml Source: https://github.com/ackee-blockchain/wake/blob/main/docs/testing-framework/migrating-from-ape-and-brownie.md Configure the development chain executable and its arguments in the `wake.toml` file. Supports `anvil`, `hardhat`, and `ganache`. ```toml [testing] cmd = "anvil" # other options: "hardhat", "ganache" [testing.anvil] cmd_args = "--prune-history 100 --transaction-block-keeper 10 --steps-tracing --silent" ``` -------------------------------- ### Detect Unused Event in Solidity Source: https://github.com/ackee-blockchain/wake/blob/main/docs/static-analysis/detectors/unused-event.md This example demonstrates a Solidity contract with an unused event. The detector will flag `WithdrawalCompleted` as it is declared but never emitted. ```solidity contract C { event WithdrawalCompleted(address indexed user, uint256 amount); // (1)! function withdraw() public { (bool success, ) = msg.sender.call{value: address(this).balance}(""); require(success, "Transfer failed."); } } ``` -------------------------------- ### Signing Message Hashes with an Account Source: https://github.com/ackee-blockchain/wake/blob/main/docs/testing-framework/accounts-and-addresses.md Shows how to sign a pre-computed message hash using an Account instance. This method is generally not recommended unless the original message is known. ```python from wake.testing import * account = Account.from_mnemonic(" ".join(["test"] * 11 + ["junk"])) signature = account.sign_hash(keccak256(b"Hello, world!")) ``` -------------------------------- ### Detecting Unused Custom Error Source: https://github.com/ackee-blockchain/wake/blob/main/docs/static-analysis/detectors/unused-error.md This example demonstrates a contract with a custom error `TransferFailed` that is defined but never used. The detector will flag this error. ```solidity contract C { error TransferFailed(); // (1)! function withdraw() public { (bool success, ) = msg.sender.call{value: address(this).balance}(""); require(success, "Transfer failed."); } } ``` -------------------------------- ### Create a Global Printer Template Source: https://github.com/ackee-blockchain/wake/blob/main/docs/static-analysis/getting-started.md Use this command to generate a template for a global printer. The template will be created in the `$XDG_DATA_HOME/wake/global-printers` directory. ```bash wake up printer printer-name --global ``` -------------------------------- ### Get Logic Contract from Proxy Source: https://github.com/ackee-blockchain/wake/blob/main/docs/testing-framework/helper-functions.md Retrieves the logic contract Account from a given proxy Account. If the input is not a proxy, it returns the input account itself. ```python from wake.testing import Account, get_logic_contract usdc_proxy = Account("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48") usdc_logic = get_logic_contract(usdc_proxy) ``` -------------------------------- ### Expect Reverts with Wake Context Managers Source: https://github.com/ackee-blockchain/wake/blob/main/docs/testing-framework/migrating-from-ape-and-brownie.md Use `must_revert` with specific error types or enums to assert that a transaction will revert. This example uses `PanicCodeEnum.UNDERFLOW_OVERFLOW`. ```python with must_revert(PanicCodeEnum.UNDERFLOW_OVERFLOW): counter.decrement() ``` -------------------------------- ### Initialize Pytypes Source: https://github.com/ackee-blockchain/wake/blob/main/examples/counter/README.md Generates Python types for the project. Use the -w flag to enable watch mode for automatic regeneration. ```bash wake init pytypes ``` ```bash wake init pytypes -w ``` -------------------------------- ### Catching TransactionRevertedError in Python Tests Source: https://github.com/ackee-blockchain/wake/blob/main/docs/testing-framework/events-and-errors.md Demonstrates how to catch a `TransactionRevertedError` when a contract function reverts. This example specifically checks for a `Panic` error related to underflow/overflow. ```python from wake.testing import * from pytypes.contracts.Counter import Counter @chain.connect() def test_errors(): counter = Counter.deploy() try: counter.decrement() assert False, "Should have reverted" except TransactionRevertedError as e: assert e == Panic(PanicCodeEnum.UNDERFLOW_OVERFLOW) tx = e.tx ``` -------------------------------- ### Importing an account by alias in Python Source: https://github.com/ackee-blockchain/wake/blob/main/docs/testing-framework/deployment.md Demonstrates how to import an account using its user-defined alias within a Python script. ```python a = Account.from_alias("my-account") ``` -------------------------------- ### Visit Function for Function Definitions Source: https://github.com/ackee-blockchain/wake/blob/main/docs/static-analysis/getting-started.md Example of a visit function that accepts an IR node for a function definition. This method is automatically called by the execution engine. ```python def visit_function_definition(self, node: ir.FunctionDefinition) -> None: pass ``` -------------------------------- ### Non-deterministic Code Example with `set` Source: https://github.com/ackee-blockchain/wake/blob/main/docs/testing-framework/fuzzing.md Illustrates non-deterministic behavior in fuzz tests due to Python's built-in `set`. It is recommended to use `OrderedSet` instead. ```python items = {1, 2, 3} item = random.choice(list(items)) ``` -------------------------------- ### Accessing Contract Creation Code and Method Selectors Source: https://github.com/ackee-blockchain/wake/blob/main/docs/testing-framework/accounts-and-addresses.md Illustrates how to retrieve the creation code of a contract and the selector for a specific method using `get_creation_code` and `.selector` properties. This is useful for low-level contract interactions. ```python from pytypes.contracts.Counter import Counter assert len(Counter.get_creation_code()) > 0 print(Counter.setCount.selector.hex()) ``` -------------------------------- ### Flow Weight Example Source: https://github.com/ackee-blockchain/wake/blob/main/docs/testing-framework/fuzzing.md Illustrates how flow weights determine execution probability. A flow with a higher weight is more likely to be chosen for execution within a test sequence. ```python @flow(weight=100) def flow_1(self) -> None: ... @flow(weight=50) def flow_2(self) -> None: ... ``` -------------------------------- ### Override Visit Mode to 'all' Source: https://github.com/ackee-blockchain/wake/blob/main/docs/static-analysis/getting-started.md Example of overriding the default 'paths' visit mode to 'all' in a custom detector. This ensures all IR nodes in the project are visited. ```python class MyDetectorDetector(Detector): ... @property def visit_mode(self) -> str: return "all" ``` -------------------------------- ### Create a Global Detector Template Source: https://github.com/ackee-blockchain/wake/blob/main/docs/static-analysis/getting-started.md Use this command to generate a template for a global detector. The template will be created in the `$XDG_DATA_HOME/wake/global-detectors` directory. ```bash wake up detector detector-name --global ``` -------------------------------- ### Solidity Contract with Incorrect Indexed Event Parameters Source: https://github.com/ackee-blockchain/wake/blob/main/docs/static-analysis/detectors/incorrect-interface.md This example shows incorrect usage of indexed parameters in `Transfer` and `Approval` events, deviating from the ERC-20 standard. ```solidity pragma solidity ^0.8; contract MyToken { uint256 public totalSupply; mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256)) public allowance; event Transfer(address indexed from, address to, uint256 value); // (1)! event Approval( address indexed owner, address indexed spender, uint256 indexed value // (2)! ); function approve(address spender, uint256 value) external returns (bool) { // ... } function transfer(address to, uint256 value) external returns (bool) { // ... } function transferFrom( address from, address to, uint256 value ) external returns (bool) { // ... } } ``` -------------------------------- ### Python Test for Multi-Token Swaps Source: https://github.com/ackee-blockchain/wake/blob/main/docs/cookbook/common-testing-patterns/multi-token-interaction.md Demonstrates a Python test case using the wake framework to simulate a user swapping between two different tokens via a liquidity pool. It includes random amount generation and token approval. ```python class MultiTokenTest(FuzzTest): token_a: Token token_b: Token pool: Pool def random_amount(self) -> int: return random_int(1, 10) * 10**18 # Handle decimals @flow() def flow_swap(self): amount = self.random_amount() user = random_account() # Approve and swap self.token_a.approve(self.pool, amount, from_=user) self.pool.swap(self.token_a, self.token_b, amount, from_=user) ``` -------------------------------- ### Importing Accounts and Addresses from an Alias Source: https://github.com/ackee-blockchain/wake/blob/main/docs/testing-framework/accounts-and-addresses.md Demonstrates importing Account and Address objects using a predefined alias. Aliases are typically managed via private key files. ```python from wake.testing import Account, Address Account.from_alias("alice") Address.from_alias("alice") ``` -------------------------------- ### Solidity Contract with Incorrect Return Types Source: https://github.com/ackee-blockchain/wake/blob/main/docs/static-analysis/detectors/incorrect-interface.md This example demonstrates functions (`approve`, `transfer`, `transferFrom`) that are missing the required `bool` return type as specified by the ERC-20 standard. ```solidity pragma solidity ^0.8; contract MyToken { uint256 public totalSupply; mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256)) public allowance; event Transfer(address indexed from, address indexed to, uint256 value); event Approval( address indexed owner, address indexed spender, uint256 value ); function approve(address spender, uint256 value) external { // (1)! // ... } function transfer(address to, uint256 value) external { // (2)! // ... } function transferFrom( address from, address to, uint256 value ) external { // (3)! // ... } } ``` -------------------------------- ### Create a Detector Template Source: https://github.com/ackee-blockchain/wake/blob/main/docs/static-analysis/getting-started.md Use this command to generate a template for a new detector. The template will be created in the `./detectors` directory. ```bash wake up detector detector-name ```