Reproduced Exploit
Vultisig — whitelist index zero lets every unlisted buyer purchase
The whitelist map returns zero for an account that has never been added. The validation only rejects an index above the configured maximum. With a maximum of 10, index zero is not above the maximum, so an unlisted account passes exactly as though it had a valid entry.
Chain
Other
Category
logic
Date
Jun 2024
Source
AuditVault
EVM Playground
Source-level debugger — step opcodes and Solidity in sync
The attack is replayed in an in-browser EVM preloaded with the exact dumped fork state. The execution tree shows every call; step by Solidity line or by opcode across all depths — source, Stack, Memory, Storage, Balances (native / ERC-20 / NFT), Transient storage and Return value stay in sync. Click a tree node, opcode, or source line to jump. No backend, no live RPC.
Source & credit. Reproduction of a public audit finding curated by AuditVault — the original finding: 35754-h-02-vultisig-whitelisting-can-be-bypassed-by-anyone-code4re. Standalone Foundry PoC and full write-up: 35754-h-02-vultisig-whitelisting-can-be-bypassed-by-anyone-code4re_exp in the
evm-hack-registrymirror.
Vulnerability classes: vuln/logic/wrong-condition · vuln/access-control/missing-validation · vuln/logic/missing-check
Reproduction: self-contained Foundry PoC with no fork, RPC, or cheatcodes. Full trace: output.txt. Driver: test/35754-h-02-vultisig-whitelisting-can-be-bypassed-by-anyone-code4re_exp.sol.
AuditVault taxonomy: lang/solidity · sector/wallet · platform/code4rena · has/github · has/poc · severity/high · genome: wrong-condition · permanent · account-ownership
Key info#
| Impact | HIGH — any account with the default whitelist index zero passes a launch gate configured for an index limit above zero. |
| Protocol | Vultisig |
| Vulnerable code | whitelist purchase validation |
| Finding | Code4rena Vultisig, 2024-06 · #35754 (H-02) · reporter leegh |
| Status | Audit finding; local reduction shows an unlisted buyer receiving 100 VULT. |
| Compiler | ^0.8.24 (local reduction) |
TL;DR#
The whitelist map returns zero for an account that has never been added. The validation only rejects an index above the configured maximum. With a maximum of 10, index zero is not above the maximum, so an unlisted account passes exactly as though it had a valid entry.
The local PoC enables a limit of 10, does not grant the attacker a whitelist index, and completes a 100-token purchase. The asserted balance demonstrates the launch restriction has been bypassed.
The vulnerable code#
if (_allowedWhitelistIndex == 0 || _whitelistIndex[to] > _allowedWhitelistIndex) {
revert NotWhitelisted();
} // @> VULN: default index zero passes when allowed index is nonzero
The predicate bounds only the upper edge of the accepted range; it never proves that the caller has a membership index.
Root cause#
The sentinel value for missing membership overlaps the accepted range. The check needs both an existence test and a range test, but only the range test is present.
Preconditions#
- A whitelist-limited sale has
_allowedWhitelistIndex > 0. - Unlisted accounts retain the default mapping value zero.
- The attacker can invoke the normal purchase route.
Attack walkthrough#
- The sale operator configures an allowed whitelist index of 10.
- The attacker remains absent from the whitelist and therefore reads index zero.
0 > 10is false, so the check does not revert.- The sale mints 100 VULT to the unwhitelisted attacker.
Diagrams#
Remediation#
Reject the zero sentinel in addition to values above the permitted index:
uint256 index = _whitelistIndex[to];
if (_allowedWhitelistIndex == 0 || index == 0 || index > _allowedWhitelistIndex) {
revert NotWhitelisted();
}
Use a separate boolean membership map where possible, and test the default mapping value explicitly in whitelist tests.
How to reproduce#
cd /workspaces/RustroverProjects/audits/evm-hack-registry/35754-h-02-vultisig-whitelisting-can-be-bypassed-by-anyone-code4re_exp
forge test -vvv
Sources#
Reference: Code4rena Vultisig finding H-02, curated by AuditVault.
Sources & further analysis#
Reproductions & code
- Standalone PoC + full trace: 35754-h-02-vultisig-whitelisting-can-be-bypassed-by-anyone-code4re_exp (evm-hack-registry mirror).
- AuditVault finding: 35754-h-02-vultisig-whitelisting-can-be-bypassed-by-anyone-code4re.
Alerts & third-party analyses
These dashboards index community alerts tweets, post-mortems, and independent write-ups. Reach them through the protocol name above to cross-check this reproduction against other analyses.