89322 w a medium call parsing in quantus sdk freezes mobile wallet
Submitted on Aug 18th 2026 at 15:24:16 UTC by @quasar for Audit Comp | Quantus
Report ID: #89322
Report Type: Websites & Apps
Report severity: Medium
Target: https://github.com/immunefi-team/audit-comp-quantus-apps/tree/audit-comp-ready/quantus_sdk
Impacts:
Taking down the application/website
Description
Brief/Intro
The shared call decoder in quantus_sdk describes the main sub-call of utility.if_else twice, so a chain of N nested if_else calls costs 2^N describe() invocations. A 230-byte payload freezes any consumer of the decoder, including the mobile wallet's multisig proposal sheet.
Vulnerability Details
case utility.IfElse(:final main, :final fallback): // (A)
return DecodedCall(
pallet: 'Utility',
call: 'if_else',
fields: [
NestedCallField('Primary call', describe(main)), // (B)
NestedCallField('Fallback call', describe(fallback)),
],
summary: describe(main).summary, // (C)
);(A)
quantus_sdk/lib/src/chain/call_decoder.dart:572: thedescribe()recursion has no depth counter, so nesting is unbounded.(B) First of the two traversals of the
mainsubtree.(C) The same subtree is traversed a second time just to read
summary, so each level doubles the work: T(N) = 2*T(N-1) + O(1).
(D)
call_decoder.dart:59: the multisig sheet feeds stored proposal bytes into this sink, where the linear codec decode hands off to the exponentialdescribe().
Attack path
Submit a nested call
A multisig co-signer submits Multisig.propose whose inner call is N=30 nested utility.if_else wrappers (pallet 9, call 6) around a system.remark leaf. The call encodes to 153 bytes: 30 levels at 5 bytes each (2 variant bytes plus the 3-byte fallback leaf), plus the 3-byte innermost leaf.
Impact Details
A multisig co-signer freezes the mobile wallet of every member who opens the malicious proposal, and the freeze repeats on every open for as long as the proposal exists on chain.
Proof of Concept
Get poc.txt, gist link - https://gist.github.com/lgprbs/3b5c53cb748c746972267db996498f45
Unpack it:
How to repro
Was this helpful?