Full Report
Fuel Network is an Ethereum L2 with a custom language, bridge and VM. The contest had a reward pool of $1M. Some big-time vulnerabilities were found in it, which are explained in the article. In Fuel, messages can be sent from the L2 to the L1. The function update_execution_data adds all message ids to the MessageOut receipts of the current tx execution data even if the tx itself has reverted. Because the tx failed, it un-burns the tokens on the Fuel side. Even though the receipt has already been used with a revert, it can be used again on a successful call. This means it's possible to relay the same receipt multiple times (as long as it corresponds with another user transfer) to steal the user's funds. The next two issues are compiler-related. Supertraits allow defining a function that is inherited by the contract implementing a given trait. Because these are sensitive functions, they should be locked down by the user-programmed behavior. In reality, all of the supertraits are available externally. The example they show is renounce_ownership being called by an arbitrary user, even though it shouldn't be callable. The second compiler bug is an optimization issue. The compiler needs to decide which instructions are considered dead or in use. Alongside this, the DCE optimization pass will eliminate dead code that has no bearing on the output of the program. The Sway optimization step labeled instructions which actually had results in it as having dead code. This leads to incorrect values in a register and unexpected behavior by the program. One of the standard libraries was missing overflow protections for smaller data types of the pow function such as u8, u16 and u32. If developers were expecting these overflows to be caught (which is a fair assumption), then incorrect math would occur, leading to potential security risks. The Code Copy (CCP) instruction copies code from a specified contract into memory. When it does this, it charges gas based on the contract's total size rather than the number of bytes copied. If an offset into the contracts bytecode is given that exceeds the length then unwrap_or_default will return an empty slice. Later on, the write occurs to the contract but it contains a way to backfill it if the lengths don't line up with zeros. Neat! Since the cost is associated with the size of the contract and nothing is copied, this ends up being super cheap! In blockchain-land, having expensive operations (like clearing memory) can lead to a denial of service (DoS) by resource exhaustion. I took some time to look at the code when this contest happened but didn't find anything. It was interesting to see bugs in the compiler and bridge handling when I spent my time looking at the VM for memory safety issues. I enjoyed the write-up and learned a bunch more about proper target selection!
Analysis Summary
This summary is based solely on the contextual information provided, which details vulnerabilities found during a Fuel Network contest. Since CVE identifiers and official CVSS scores are not present in the source text, placeholders are used. All listed vulnerabilities state they are fixed as of the article's publication.
# Vulnerability: L2-L1 Message Replay via Reverted Transactions
## CVE Details
- CVE ID: N/A (Pending Assignment)
- CVSS Score: N/A (Severity noted as Critical)
- CWE: CWE-824: Use of a Deleted or Invalidated Pointer (Conceptual)
## Affected Systems
- Products: Fuel Network (L2 execution/bridge components)
- Versions: Mentioned asset points to `fuel-core/tree/v0.31.0` (Vulnerable state)
- Configurations: Transactions involving L2 to L1 message passing, specifically during execution revert flows.
## Vulnerability Description
The function `executor/src/executor.rs::update_execution_data` incorrectly adds all `message_ids` from `MessageOut` receipts to the execution data, even if the transaction itself subsequently reverts. This allows an attacker to successfully relay an L1 message corresponding to a burnt L2 token withdrawal, even after the L2 transaction that initiated the withdrawal (and 'un-burn' of tokens) failed. An attacker can replay the same L1 receipt relay multiple times (once after a successful L2 transfer/burn, and potentially again after a reverted L2 transfer/burn), leading to double-spending or theft from the bridge by exploiting the state mismatch between the L2 revert and the L1 receipt relay.
## Exploitation
- Status: PoC available (Steps described, implies successful simulation/demonstration)
- Complexity: Medium (Requires coordinating L2 transaction states and L1 relay)
- Attack Vector: Network (Interacting with the L2 and L1 bridge mechanisms)
## Impact
- Confidentiality: None
- Integrity: High (Allows unauthorized modification of asset balances via replay)
- Availability: Low (Potential for asset exhaustion on the bridge)
## Remediation
### Patches
- Patches are implied as the vulnerabilities are stated to be FIXED as of publication. Specific patch versions are not listed.
### Workarounds
- No specific workarounds are listed, as patching is assumed complete. Developers should ensure L1 relay logic correctly validates the originating L2 transaction state.
## Detection
- Monitoring for sequential L1 relays corresponding to a single L2 withdrawal event, especially if the initial L2 transaction eventually results in a state change inconsistent with the L1 operation.
## References
- Report 32965
***
# Vulnerability: Exposed ABI SuperTrait Methods
## CVE Details
- CVE ID: N/A (Pending Assignment)
- CVSS Score: N/A (Severity noted as Critical)
- CWE: CWE-284: Improper Access Control
## Affected Systems
- Products: Sway compiler, Fuel Network Smart Contracts
- Versions: Mentioned asset points to `sway/tree/v0.61.2` (Vulnerable state)
- Configurations: Contracts implementing traits that define sensitive methods (like `renounce_ownership`) via ABI supertraits.
## Vulnerability Description
ABI supertraits are intended to provide compositional methods inherited by implementing contracts. However, the implementation allows methods defined in supertraits (such as `renounce_ownership` from an `Ownable` trait) to be externally callable on the resulting contract, despite them being sensitive functions that should be guarded by user-programmed logic. This violates the expected encapsulation of trait methods inherited through ABI composition.
## Exploitation
- Status: PoC available (Example shows external calling of `renounce_ownership`)
- Complexity: Low (Simple external call)
- Attack Vector: Network (Calling the exposed contract function)
## Impact
- Confidentiality: None
- Integrity: High (Allows unauthorized changes to critical contract states, e.g., ownership transfer)
- Availability: Low
## Remediation
### Patches
- Patches are implied as the vulnerabilities are stated to be FIXED as of publication. Specific patch versions are not listed.
### Workarounds
- Developers must ensure sensitive functions inherited from traits are explicitly guarded within the implementing contract or use mechanisms that genuinely restrict external visibility of trait methods.
## Detection
- Static analysis tools checking trait implementations for unintended public exposure of sensitive functions.
## References
- Report 33351
***
# Vulnerability: Incorrect Register Usage Leading to Dead Code Elimination (DCE) Errors
## CVE Details
- CVE ID: N/A (Pending Assignment)
- CVSS Score: N/A (Severity noted as High)
- CWE: CWE-839: Improper Initialization (Conceptual: Incorrect optimization state leading to bad code)
## Affected Systems
- Products: Sway Compiler
- Versions: Mentioned asset points to commit hash beginning `7b56ec734d4a4fda550313d448f7f20dba818b59` (Vulnerable state)
- Configurations: Code generation involving WQAM instructions where the DCE optimization pass is active.
## Vulnerability Description
The DCE optimization pass in the Sway compiler incorrectly models register usage for instructions like WQAM. Functions tracking register definitions/uses (`def_registers`, `use_registers`) failed to correctly identify instructions that actually wrote to registers. This caused the DCE pass to wrongly eliminate instructions that had legitimate side effects on program output, leading to dead code elimination when code was still in use. This results in incorrect values residing in registers and unpredictable program behavior in the resulting bytecode.
## Exploitation
- Status: PoC available (Described flaw in compiler logic)
- Complexity: Medium (Requires deep understanding of Sway assembly and optimization passes)
- Attack Vector: Indirect (Affects the compiler output, exploitation relies on deploying the resulting faulty bytecode)
## Impact
- Confidentiality: None
- Integrity: Medium (Potential for incorrect execution flow/results)
- Availability: Low (Potential for runtime errors/crashes)
## Remediation
### Patches
- Patches are implied as the vulnerabilities are stated to be FIXED as of publication.
### Workarounds
- Disabling the DCE optimization pass during compilation of sensitive contracts, if possible, while awaiting a permanent fix.
## Detection
- Auditing compiled bytecode for missing instructions, especially around WQAM usage, compared to the expected assembly output before optimization.
## References
- Report 32269
***
# Vulnerability: Missing Overflow Protection for Smaller Data Type `pow` Function
## CVE Details
- CVE ID: N/A (Pending Assignment)
- CVSS Score: N/A (Severity not explicitly rated, implied moderate/high due to math error)
- CWE: CWE-190: Integer Overflow or Wraparound
## Affected Systems
- Products: Fuel Standard Libraries (Sway/Fuel Runtime)
- Versions: Unspecified, affecting the standard library implementation of `pow`.
- Configurations: Usage of the `pow` function specifically with smaller integer types (u8, u16, u32) where overflow is possible.
## Vulnerability Description
The standard library implementation of the power function (`pow`) lacked explicit overflow checks for smaller primitive data types, specifically `u8`, `u16`, and `u32`. If a calculation resulted in an overflow, the expectation that Rust/Sway would trap or handle this error was unmet, leading to mathematical results that wrap around or produce incorrect values, which developers may not have anticipated, opening risks for incorrect system arithmetic.
## Exploitation
- Status: Not exploited (Assumed, based on security focus)
- Complexity: Low (Simple mathematical error if input constraints are violated)
- Attack Vector: Application Logic
## Impact
- Confidentiality: None
- Integrity: Medium (Incorrect mathematical results affecting contract logic)
- Availability: Low
## Remediation
### Patches
- Patches are implied as the vulnerabilities are stated to be FIXED as of publication.
### Workarounds
- Developers must manually check for potential overflows before calling `pow` with smaller integer types or use larger data types (e.g., u64) for intermediate calculations if possible.
## Detection
- Static analysis focusing on standard library function call usage, checking for integer inputs susceptible to overflow.
## References
- Not explicitly referenced with a report number in the context provided for this specific bug description.
***
# Vulnerability: Gas Cost Bypass in Code Copy (CCP) Instruction
## CVE Details
- CVE ID: N/A (Pending Assignment)
- CVSS Score: N/A (Severity not explicitly rated, implies high DoS potential)
- CWE: CWE-778: Insufficient Resource Quota Management
## Affected Systems
- Products: Fuel VM / Execution Engine
- Versions: Unspecified
- Configurations: When using the Code Copy (`CCP`) instruction with specific offsets that point past the end of the target contract's bytecode.
## Vulerability Description
The `CCP` instruction charges gas based on the **total size** of the source contract, regardless of how many bytes are actually copied. If the specified offset into the contract bytecode exceeds the length, `unwrap_or_default` returns an empty slice. Because the instruction might execute logic that conditionally fills length discrepancies with zeros (backfilling), the operation effectively performs minimal real work (or perhaps none if the slice is empty), but still incurs a high, fixed gas cost associated with the entire source contract size. This structure allows an attacker to execute an operation that looks expensive gas-wise but results in very little computation or memory write, potentially leading to a low-cost Denial of Service (DoS) via resource exhaustion by simulating high-cost activity cheaply.
## Exploitation
- Status: Not exploited (Assumed)
- Complexity: High (Requires deep knowledge of gas metering and instruction execution flow)
- Attack Vector: Network (Transaction submission)
## Impact
- Confidentiality: None
- Integrity: None
- Availability: High (Potential for DoS by exhausting block gas limits cheaply, though the description confusingly says "expensive operations... can lead to a denial of service [DoS] by resource exhaustion," implying the bug *lowers* the cost of an operation that should be expensive, which itself can lead to DoS if abused to spam the network cheaply). *Interpreted as a low-cost DoS vector.*
## Remediation
### Patches
- Patches are implied as the vulnerabilities are stated to be FIXED as of publication.
### Workarounds
- Disabling or imposing strict limits on transactions utilizing the `CCP` instruction until the gas metering logic is corrected to charge based on the actual number of bytes copied, not the contract size.
## Detection
- Transaction monitoring for high gas usage patterns related to `CCP` instructions relative to the actual data manipulated.
## References
- Not explicitly referenced with a report number in the context provided for this specific bug description.