{"id":19709934,"url":"https://github.com/laugharne/rust_smart_contract_vulnerabilities","last_synced_at":"2026-05-14T15:35:15.677Z","repository":{"id":262273814,"uuid":"886739252","full_name":"Laugharne/rust_smart_contract_vulnerabilities","owner":"Laugharne","description":"This article will explore some of the **top vulnerabilities** in Rust smart contracts and provide examples to illustrate these issues, along with best practices for mitigation.","archived":false,"fork":false,"pushed_at":"2024-11-11T14:20:37.000Z","size":3,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-10T13:53:06.239Z","etag":null,"topics":["blockchain","code","rust","rust-lang","solana","vulnerabilities"],"latest_commit_sha":null,"homepage":"https://medium.com/@dehvcurtis/top-rust-smart-contract-vulnerabilities-a-deep-dive-with-examples-eb36a84c800b","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Laugharne.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-11-11T14:14:35.000Z","updated_at":"2024-11-11T14:20:40.000Z","dependencies_parsed_at":"2024-11-11T15:27:54.445Z","dependency_job_id":"8bba44d6-238b-4be8-9305-5c4f87abebf4","html_url":"https://github.com/Laugharne/rust_smart_contract_vulnerabilities","commit_stats":null,"previous_names":["laugharne/rust_smart_contract_vulnerabilities"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Laugharne%2Frust_smart_contract_vulnerabilities","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Laugharne%2Frust_smart_contract_vulnerabilities/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Laugharne%2Frust_smart_contract_vulnerabilities/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Laugharne%2Frust_smart_contract_vulnerabilities/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Laugharne","download_url":"https://codeload.github.com/Laugharne/rust_smart_contract_vulnerabilities/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241026878,"owners_count":19896716,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blockchain","code","rust","rust-lang","solana","vulnerabilities"],"created_at":"2024-11-11T22:05:20.340Z","updated_at":"2026-05-14T15:35:15.612Z","avatar_url":"https://github.com/Laugharne.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Top Rust Smart Contract Vulnerabilities: A Deep Dive with Examples\n\n\u003e **Source:** [Top Rust Smart Contract Vulnerabilities: A Deep Dive with Examples](https://medium.com/@dehvcurtis/top-rust-smart-contract-vulnerabilities-a-deep-dive-with-examples-eb36a84c800b)\n\nRust has quickly become a favored language for smart contract development on blockchain platforms such as **NEAR Protocol** , **Polkadot** and **Solana** due to its strong safety guarantees and memory management features. However, smart contracts written in Rust are still prone to a range of vulnerabilities, just like in other blockchain development languages.\n\nThis article will explore some of the **top vulnerabilities** in Rust smart contracts and provide examples to illustrate these issues, along with best practices for mitigation.\n\n## Unchecked Integer Overflow/Underflow\n\nInteger overflow occurs when a value exceeds the maximum for a type, while underflow occurs when it falls below the minimum (e.g., a subtraction leading to a negative value in an unsigned integer).\n\nBy default, Rust's integer arithmetic is safe in debug mode, but in release mode, it behaves similarly to languages like C, where overflows wrap around, which can lead to unexpected behavior.\n\n**Vulnerable Example:**\n\n```rust\nfn main() {\n    let mut balance: u64 = 10;\n    balance -= 20; // Underflow\n    println!(\"Balance: {}\", balance); // This will panic in debug mode\n}\n```\n\n**Mitigation**: Use Rust's `checked_*` or `saturating_*` methods to safely handle overflows and underflows:\n\n```rust\nfn main() {\n    let balance: u64 = 10;\n    let new_balance = balance.checked_sub(20).expect(\"Subtraction overflowed!\");\n    println!(\"New Balance: {}\", new_balance);\n}\n```\n\n## Reentrancy Attacks\n\nReentrancy attacks occur when an external contract calls back into the vulnerable contract before the original function call is completed, potentially allowing the external contract to alter the state unexpectedly (such as withdrawing funds multiple times).\n\n**Example**:\n\n```rust\npub fn withdraw(\u0026mut self, amount: u128) {\n    assert!(self.balances[self.caller()] \u003e= amount, \"Insufficient funds\");\n    self.transfer(self.caller(), amount);\n    self.balances[self.caller()] -= amount;  // Reentrancy vulnerability\n}\n```\n\nIn this case, if `self.transfer()` calls into another contract that can recursively call `withdraw()`, it could repeatedly drain funds.\n\n**Mitigation**: Use the **checks-effects-interactions** pattern, updating the state before making external calls:\n\n```rust\npub fn withdraw(\u0026mut self, amount: u128) {\n    assert!(self.balances[self.caller()] \u003e= amount, \"Insufficient funds\");\n    self.balances[self.caller()] -= amount;  // Update state first\n    self.transfer(self.caller(), amount);    // Then make the external call\n}\n```\n\n## Unrestricted Access to Critical Functions\n\n**Description**: Critical functions that are not properly restricted by access control can be executed by anyone, leading to unauthorized fund transfers or administrative actions.\n\n**Example**:\n\n```rust\npub fn set_admin(\u0026mut self, new_admin: AccountId) {\n    self.admin = new_admin; // Anyone can call this and set themselves as admin\n}\n```\n\n**Mitigation**: Ensure proper access control by restricting function execution to only authorized users:\n\n```rust\npub fn set_admin(\u0026mut self, new_admin: AccountId) {\n    assert_eq!(self.admin, self.caller(), \"Unauthorized\");\n    self.admin = new_admin;\n}\n```\n\n## Unchecked External Calls\n\n**Description**: External calls can fail for many reasons, such as the called contract being non-existent or out of gas. If the result of these calls is not checked, it can lead to silent failures that are not handled, leaving the contract in an inconsistent state.\n\n**Example**:\n\n```rust\npub fn perform_external_call(\u0026self, contract_id: AccountId) {\n    let result = env::promise_create(\n        contract_id,\n        \"some_function\",\n        \u0026json!({}).to_string().into_bytes(),\n        0,\n        env::prepaid_gas(),\n    );\n    // If `result` fails, the contract doesn't handle it\n}\n```\n\n**Mitigation**: Always check the outcome of external contract calls:\n\n```rust\npub fn perform_external_call(\u0026self, contract_id: AccountId) {\n    let result = env::promise_create(\n        contract_id,\n        \"some_function\",\n        \u0026json!({}).to_string().into_bytes(),\n        0,\n        env::prepaid_gas(),\n    );\n    assert!(result.is_ok(), \"External call failed\"); }\n```\n\n## Unbounded Loops and High Gas Consumption\n\n**Description**: Smart contracts operate within gas limits. If a contract has loops that can iterate indefinitely or over large datasets, it may exceed the gas limit, causing the transaction to fail or the contract to be unusable.\n\n**Example**:\n\n```rust\npub fn sum_values(\u0026self, values: Vec\u003cu128\u003e) -\u003e u128 {\n    let mut sum = 0;\n    for value in values {\n        sum += value;  // This loop can be too expensive if `values` is large\n    }\n    sum\n}\n```\n\n**Mitigation**: Avoid unbounded loops or large iterations. Consider using batching techniques:\n\n```rust\npub fn sum_values_in_batches(\u0026self, values: Vec\u003cu128\u003e, batch_size: usize) -\u003e u128 {\n    let mut sum = 0;\n    for value in values.iter().take(batch_size) {\n        sum += value;\n    }\n    sum\n}\n```\n\n## Storage Attacks (Denial of Service)\n\n**Description**: In a storage-based denial of service (DoS) attack, an attacker can exploit an inefficient storage mechanism to inflate the contract's storage, incurring large storage fees or even causing the contract to run out of storage.\n\n**Example**:\n\n```rust\npub fn add_to_list(\u0026mut self, item: u128) {\n    self.list.push(item);  // Unbounded storage growth\n}\n```\n\n**Mitigation**: Use efficient storage structures like `BTreeMap` for more scalable storage and apply limits:\n\n```rust\npub fn add_to_list(\u0026mut self, item: u128) {\n    assert!(self.list.len() \u003c 100, \"List is full\");\n    self.list.push(item);\n}\n```\n\n## Floating-Point Precision Errors\n\n**Description**: Floating-point arithmetic can introduce rounding errors, which is dangerous when handling financial transactions in smart contracts. Rust's floating-point types, `f32` and `f64`, are not suitable for precise financial calculations.\n\n**Example**:\n\n```rust\nlet amount: f64 = 1.1 + 2.2;  // May not exactly equal 3.3 due to precision errors\n```\n\n**Mitigation**: Avoid using floating-point numbers for financial calculations. Instead, use integers to represent the smallest units (e.g., `wei` in Ethereum or `lamports` in Solana):\n\n```rust\nlet amount: u64 = 110 + 220;  // Use integers to maintain precision\n```\n\n## State Manipulation in Asynchronous Operations\n\n**Description**: Contracts may perform asynchronous operations like cross-contract calls. If the state is not validated after these operations, malicious actors can manipulate the contract state during execution.\n\n**Example**:\n\n```rust\npub fn async_operation(\u0026mut self) {\n    let initial_state = self.state;\n    env::promise_create(\"another_contract\", \"external_call\", \u0026[], 0, env::prepaid_gas());\n    assert_eq!(self.state, initial_state);  // State could have changed unexpectedly\n}\n```\n\n**Mitigation**: Re-validate the contract's state after asynchronous calls and ensure changes are expected.\n\n## Improper Initialization of Contract State\n\n**Description**: Smart contracts that don't properly initialize their state can leave critical variables in an uninitialized or default state, leading to security issues.\n\n**Example**:\n\n```rust\npub fn new() -\u003e Self {\n    Self {\n        admin: Default::default(), // Could lead to undefined behavior\n    }\n}\n```\n\n**Mitigation**: Ensure that all state variables are initialized correctly during the contract's deployment:\n\n```rust\npub fn new(admin: AccountId) -\u003e Self {\n    Self {\n        admin: admin, // Explicitly initialize the admin\n    }\n}\n```\n\n## Conclusion:\n\nRust's safety features, such as its ownership and type system, can prevent many common issues in smart contract development. However, even in Rust, developers must remain vigilant about smart contract-specific vulnerabilities such as reentrancy attacks, integer overflow, and gas consumption limits.\n\nBy following best practices and carefully structuring your contract's code, you can write robust, secure Rust smart contracts that stand the test of time in decentralized systems.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flaugharne%2Frust_smart_contract_vulnerabilities","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flaugharne%2Frust_smart_contract_vulnerabilities","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flaugharne%2Frust_smart_contract_vulnerabilities/lists"}