Typographical Error
Overview
Remediation Guide: Typographical Error Remediation
Some typos compile cleanly and change contract behavior. The classic case is SWC-129’s =+ transposition: balance =+ amount parses as “assign unary-plus amount to balance” instead of “add amount to balance”. The typographical error detector finds the bytecode fingerprints these mistakes leave behind. It reports three finding types:
- Unary-assignment typos (
=+,=-): a store that overwrites a variable with a unary-operated value where the surrounding context suggests accumulation was intended. - Identity assignments (
x = x): a variable assigned to itself, which is always a no-op and usually a mistyped variable name. - Canceling operations: consecutive operations that undo each other (double negation, double bitwise-not), leaving the value unchanged.
The distinction is visible at the bytecode level: x += y loads both operands and emits an ADD before storing, while x =+ y loads only y and stores it directly, discarding the original value of x.
Why This Is an Issue
These bugs are silent. A deposit function that assigns instead of accumulating wipes out every prior deposit each time it runs; a mistyped identity assignment means a validation or update simply never happens. Because the code compiles and the happy-path test (single deposit, fresh account) often passes, the error survives review and ships. Since Solidity 0.5.0 the compiler rejects the ambiguous =+/=- token sequence, but decompiled legacy contracts and semantically equivalent mistakes (a = b where a += b was intended) remain in the wild.
How to Resolve
// Before: assignment wipes prior balance (typo for +=)
function deposit() external payable {
balances[msg.sender] = msg.value;
}
// After: accumulate
function deposit() external payable {
balances[msg.sender] += msg.value;
}
For identity assignments, the fix is almost always a mistyped name — find the variable that was actually meant:
// Before: no-op — 'owner' assigned to itself, parameter ignored
function transferOwnership(address newOwner) external {
owner = owner;
}
// After
function transferOwnership(address newOwner) external {
owner = newOwner;
}
Examples
Sample Sigvex Output
{
"detector_id": "typographical-error",
"severity": "medium",
"confidence": 0.6,
"description": "Potential '=+' typo in deposit(): storage slot 2 is overwritten with an unmodified operand in a context suggesting accumulation.",
"location": { "function": "deposit()", "offset": 82 }
}
Detection Methodology
The detector runs data-flow analysis over the decompiled IR, tracking storage slot reads and writes per function. A store whose value derives from a single operand with a unary operation — and whose target slot is read elsewhere as a running total — is flagged as a probable transposition. Identity assignments are found by matching stores whose value is a load of the same slot with nothing in between. Canceling-operation findings match back-to-back unary operations of the same kind on the same value.
Limitations
- Deliberate overwrite semantics (a setter that intentionally replaces a value) can resemble a typo; the detector uses accumulation context to filter these, but naming and loop position are heuristics.
- Identity assignments introduced by compiler optimization artifacts, rather than source typos, may be flagged in unoptimized builds.
- The detector sees bytecode, not source, so it reports the effect (overwrite where accumulate was likely intended), not the literal typo.
Related Detectors
- Incorrect Exponent — XOR (
^) where exponentiation (**) was intended - Write After Write — storage written twice without an intervening read
- Tautological Compare — comparisons that are always true or false