c28796c0-dadd-466a-a4b7-324e717eaa5f
Open this run to answer one question: is this real attacker-relevant behavior with real impact, or just normal contract plumbing?
| ID | Type | Status | Attempts | Heartbeat |
|---|---|---|---|---|
| 30407 | report.consolidate | complete | 1 / 1 | 3 months ago |
| 93841 | artifact.fetch | complete | 1 / 3 | 1 week ago |
| 93842 | tool.cast_disasm | complete | 1 / 3 | 1 week ago |
| 93843 | analysis.bundle | complete | 1 / 3 | 1 week ago |
| 93844 | capability.graph | complete | 1 / 3 | 1 week ago |
| 93845 | detector.run | complete | 1 / 3 | 1 week ago |
| 93846 | validation.fork | complete | 1 / 3 | 1 week ago |
No slither job recorded yet.
[codex:1313303] OpenAI Codex v0.77.0 (research preview)
[codex:1313303] --------
[codex:1313303] workdir: /tmp/codex-multi-yceoauod
[codex:1313303] model: gpt-5.2-codex
[codex:1313303] provider: openai
[codex:1313303] approval: never
[codex:1313303] sandbox: read-only
[codex:1313303] reasoning effort: xhigh
[codex:1313303] reasoning summaries: auto
[codex:1313303] session id: 019b6854-c167-7cb3-9b3a-bebee6651a65
[codex:1313303] --------
[codex:1313303] user
[codex:1313303] You are a security auditor. Audit this Solidity codebase for exploitable vulnerabilities.
[codex:1313303] Focus on: reentrancy, access control, upgradeability/proxy issues, signature validation, oracle manipulation,
[codex:1313303] accounting/invariant breaks, external call patterns, unchecked return values, and dangerous delegatecall.
[codex:1313303]
[codex:1313303] Scope rules:
[codex:1313303] - You MUST fully read `AUDIT_BUNDLE.txt` before concluding. It contains the complete contents of all first-party `contracts/**/*.sol` files.
[codex:1313303] - Treat `lib/` and `@openzeppelin/` as third-party dependencies; skip them unless there is a concrete misuse angle in first-party code.
[codex:1313303]
[codex:1313303] Output MUST be valid JSON matching the provided schema.
[codex:1313303] - If you find nothing meaningful: set no_findings=true and findings=[].
[codex:1313303] - Otherwise: set no_findings=false and include findings with severity/category/title and file/line locations when possible.
[codex:1313303]
[codex:1313303] Output constraints (IMPORTANT):
[codex:1313303] - severity MUST be exactly one of: info, low, medium, high, critical (lowercase).
[codex:1313303] - category MUST be exactly one of: access_control, reentrancy, math, oracle, upgradeability, auth, other.
[codex:1313303] mcp startup: no servers
[codex:1313303]
[codex:1313303] thinking
[codex:1313303] **Reading AUDIT_BUNDLE file**
[codex:1313303] exec
[codex:1313303] /bin/bash -lc ls in /tmp/codex-multi-yceoauod succeeded in 5ms:
[codex:1313303] AUDIT_BUNDLE.txt
[codex:1313303] codex-output-schema.json
[codex:1313303] contracts
[codex:1313303] exec
[codex:1313303] /bin/bash -lc 'cat AUDIT_BUNDLE.txt' in /tmp/codex-multi-yceoauod succeeded in 5ms:
[codex:1313303] This file concatenates the full contents of first-party Solidity sources for auditing.
[codex:1313303]
[codex:1313303] ================================================================================
[codex:1313303] FILE: contracts/Contract.sol
[codex:1313303] ================================================================================
[codex:1313303] # pragma version 0.4.1
[codex:1313303] """
[codex:1313303] @title vKP3R Snapshot Distribution
[codex:1313303] @license MIT
[codex:1313303] @author Creepy Old Dude
[codex:1313303] @notice Finally, distribute rKP3R rewards to vKP3R lockers.
[codex:1313303] """
[codex:1313303] from ethereum.ercs import IERC20
[codex:1313303]
[codex:1313303] SPRAY: public(constant(bytes32)) = 0x31ba7c9394ad2daed98dc335ae20f0bcbe6c778c1e72812f6e404405e950a761
[codex:1313303]
[codex:1313303] interface IVKP3R:
[codex:1313303] def balanceOfAt(locker: address, block: uint256) -> uint256: view
[codex:1313303] def totalSupplyAt(block: uint256) -> uint256: view
[codex:1313303]
[codex:1313303]
[codex:1313303] thinking
[codex:1313303] **Analyzing smart contract vulnerabilities and bugs**
[codex:1313303]
[codex:1313303] I'm reviewing potential issues like unvalidated transfer return values that could silently fail and lock claims, division by zero risks if total supply snapshot is zero, and incorrect snapshot validation comparing block numbers to timestamps allowing future blocks that cause reverts. I'll also consider line number references by correlating with the actual contract file for precise audit reporting.
[codex:1313303] exec
[codex:1313303] /bin/bash -lc 'nl -ba contracts/Contract.sol' in /tmp/codex-multi-yceoauod succeeded in 5ms:
[codex:1313303] 1 # pragma version 0.4.1
[codex:1313303] 2 """
[codex:1313303] 3 @title vKP3R Snapshot Distribution
[codex:1313303] 4 @license MIT
[codex:1313303] 5 @author Creepy Old Dude
[codex:1313303] 6 @notice Finally, distribute rKP3R rewards to vKP3R lockers.
[codex:1313303] 7 """
[codex:1313303] 8 from ethereum.ercs import IERC20
[codex:1313303] 9
[codex:1313303] 10 SPRAY: public(constant(bytes32)) = 0x31ba7c9394ad2daed98dc335ae20f0bcbe6c778c1e72812f6e404405e950a761
[codex:1313303] 11
[codex:1313303] 12 interface IVKP3R:
[codex:1313303] 13 def balanceOfAt(locker: address, block: uint256) -> uint256: view
[codex:1313303] 14 def totalSupplyAt(block: uint256) -> uint256: view
[codex:1313303] 15
[codex:1313303] 16
[codex:1313303] 17 TOKEN: public(immutable(IERC20))
[codex:1313303] 18 TOTAL_AMOUNT: public(immutable(uint256))
[codex:1313303] 19 SNAPSHOT: public(immutable(uint256)) # NOTE: block number
[codex:1313303] 20 DEPLOYMENT_TIMESTAMP: public(immutable(uint256))
[codex:1313303]
[codex:1313303] thinking
[codex:1313303] **Generating structured JSON findings**
[codex:1313303]
[codex:1313303] I'm gathering all vulnerability details including their severity, categories, scenarios, recommendations, and evidence locations to format a comprehensive JSON output with no extra text, ensuring clarity and adherence to the specified schema.
[codex:1313303] codex
[codex:1313303] {"no_findings":false,"summary":"Identified 3 issues that can block claims or silently fail token transfers due to validation and accounting gaps.","findings":[{"severity":"medium","category":"other","title":"Unchecked ERC20 transfer return value can permanently burn claims","exploit_scenario":"If `TOKEN` is non‑standard and returns `false` on failure (rather than reverting), `claim` marks `has_claimed[locker] = True` and ignores the `transfer` result. The locker cannot retry, leaving their allocation stuck in the contract and potentially clawed back later.","recommendation":"Require `transfer` success (check the boolean return value and revert on `false`), or use a safe transfer helper. Consider setting `has_claimed` only after a successful transfer.","evidence":"`claim` sets `has_claimed` before calling `extcall TOKEN.transfer(...)` and does not check the return value; `clawback` similarly ignores `transfer` success.","locations":["contracts/Contract.sol:60","contracts/Contract.sol:65","contracts/Contract.sol:79"]},{"severity":"low","category":"other","title":"Snapshot validation compares block number to timestamp","exploit_scenario":"The constructor check uses `block.timestamp` while `snapshot` is a block number. This allows future block numbers (still less than the current timestamp) to pass validation. If `balanceOfAt/totalSupplyAt` revert or return zero for future blocks, claims become impossible until clawback.","recommendation":"Validate `snapshot <= block.number` (and ideally enforce `snapshot < block.number` if the underlying implementation requires a strictly past block).","evidence":"`assert snapshot <= block.timestamp, \"No future snapshots\"` despite `snapshot` being documented as a block number.","locations":["contracts/Contract.sol:44"]},{"severity":"low","category":"math","title":"Division by zero if totalSupplyAt snapshot is zero","exploit_scenario":"If `VKP3R.totalSupplyAt(SNAPSHOT)` is zero, `_claimable` reverts on division by zero, preventing all claims.","recommendation":"Add a guard that `totalSupplyAt(SNAPSHOT) > 0` (e.g., in the constructor) or return `0` when the total supply is zero.","evidence":"`TOTAL_AMOUNT * balanceOfAt(...) // totalSupplyAt(SNAPSHOT)` performs division without checking for zero.","locations":["contracts/Contract.sol:107"]}]}
[codex:1313303] tokens used
[codex:1313303] 7,617
[codex:1313303] {"no_findings":false,"summary":"Identified 3 issues that can block claims or silently fail token transfers due to validation and accounting gaps.","findings":[{"severity":"medium","category":"other","title":"Unchecked ERC20 transfer return value can permanently burn claims","exploit_scenario":"If `TOKEN` is non‑standard and returns `false` on failure (rather than reverting), `claim` marks `has_claimed[locker] = True` and ignores the `transfer` result. The locker cannot retry, leaving their allocation stuck in the contract and potentially clawed back later.","recommendation":"Require `transfer` success (check the boolean return value and revert on `false`), or use a safe transfer helper. Consider setting `has_claimed` only after a successful transfer.","evidence":"`claim` sets `has_claimed` before calling `extcall TOKEN.transfer(...)` and does not check the return value; `clawback` similarly ignores `transfer` success.","locations":["contracts/Contract.sol:60","contracts/Contract.sol:65","contracts/Contract.sol:79"]},{"severity":"low","category":"other","title":"Snapshot validation compares block number to timestamp","exploit_scenario":"The constructor check uses `block.timestamp` while `snapshot` is a block number. This allows future block numbers (still less than the current timestamp) to pass validation. If `balanceOfAt/totalSupplyAt` revert or return zero for future blocks, claims become impossible until clawback.","recommendation":"Validate `snapshot <= block.number` (and ideally enforce `snapshot < block.number` if the underlying implementation requires a strictly past block).","evidence":"`assert snapshot <= block.timestamp, \"No future snapshots\"` despite `snapshot` being documented as a block number.","locations":["contracts/Contract.sol:44"]},{"severity":"low","category":"math","title":"Division by zero if totalSupplyAt snapshot is zero","exploit_scenario":"If `VKP3R.totalSupplyAt(SNAPSHOT)` is zero, `_claimable` reverts on division by zero, preventing all claims.","recommendation":"Add a guard that `totalSupplyAt(SNAPSHOT) > 0` (e.g., in the constructor) or return `0` when the total supply is zero.","evidence":"`TOTAL_AMOUNT * balanceOfAt(...) // totalSupplyAt(SNAPSHOT)` performs division without checking for zero.","locations":["contracts/Contract.sol:107"]}]}
{
"codex": {
"ran_at": "2025-12-29T04:20:15.192562+00:00",
"returncode": 0
},
"summary": "Identified 3 issues that can block claims or silently fail token transfers due to validation and accounting gaps.",
"raw_final": {
"summary": "Identified 3 issues that can block claims or silently fail token transfers due to validation and accounting gaps.",
"findings": [
{
"title": "Unchecked ERC20 transfer return value can permanently burn claims",
"category": "other",
"evidence": "`claim` sets `has_claimed` before calling `extcall TOKEN.transfer(...)` and does not check the return value; `clawback` similarly ignores `transfer` success.",
"severity": "medium",
"locations": [
"contracts/Contract.sol:60",
"contracts/Contract.sol:65",
"contracts/Contract.sol:79"
],
"recommendation": "Require `transfer` success (check the boolean return value and revert on `false`), or use a safe transfer helper. Consider setting `has_claimed` only after a successful transfer.",
"exploit_scenario": "If `TOKEN` is non\u2011standard and returns `false` on failure (rather than reverting), `claim` marks `has_claimed[locker] = True` and ignores the `transfer` result. The locker cannot retry, leaving their allocation stuck in the contract and potentially clawed back later."
},
{
"title": "Snapshot validation compares block number to timestamp",
"category": "other",
"evidence": "`assert snapshot <= block.timestamp, \"No future snapshots\"` despite `snapshot` being documented as a block number.",
"severity": "low",
"locations": [
"contracts/Contract.sol:44"
],
"recommendation": "Validate `snapshot <= block.number` (and ideally enforce `snapshot < block.number` if the underlying implementation requires a strictly past block).",
"exploit_scenario": "The constructor check uses `block.timestamp` while `snapshot` is a block number. This allows future block numbers (still less than the current timestamp) to pass validation. If `balanceOfAt/totalSupplyAt` revert or return zero for future blocks, claims become impossible until clawback."
},
{
"title": "Division by zero if totalSupplyAt snapshot is zero",
"category": "math",
"evidence": "`TOTAL_AMOUNT * balanceOfAt(...) // totalSupplyAt(SNAPSHOT)` performs division without checking for zero.",
"severity": "low",
"locations": [
"contracts/Contract.sol:107"
],
"recommendation": "Add a guard that `totalSupplyAt(SNAPSHOT) > 0` (e.g., in the constructor) or return `0` when the total supply is zero.",
"exploit_scenario": "If `VKP3R.totalSupplyAt(SNAPSHOT)` is zero, `_claimable` reverts on division by zero, preventing all claims."
}
],
"no_findings": false
},
"no_findings": false,
"schema_version": 1
}
00000000: PUSH0 00000001: CALLDATALOAD 00000002: PUSH1 0xe0 00000004: SHR 00000005: PUSH1 0x02 00000007: PUSH1 0x0b 00000009: DUP3 0000000a: MOD 0000000b: PUSH1 0x01 0000000d: SHL 0000000e: PUSH2 0x0603 00000011: ADD 00000012: PUSH1 0x1e 00000014: CODECOPY 00000015: PUSH0 00000016: MLOAD 00000017: JUMP 00000018: JUMPDEST 00000019: PUSH4 0x4e71d92d 0000001e: DUP2 0000001f: XOR 00000020: PUSH2 0x053a 00000023: JUMPI 00000024: CALLVALUE 00000025: PUSH2 0x05ff 00000028: JUMPI 00000029: CALLER 0000002a: PUSH2 0x0100 0000002d: MSTORE 0000002e: PUSH2 0x0057 00000031: JUMP 00000032: JUMPDEST 00000033: PUSH4 0x1e83409a 00000038: DUP2 00000039: XOR 0000003a: PUSH2 0x01c3 0000003d: JUMPI 0000003e: PUSH1 0x24 00000040: CALLDATASIZE 00000041: LT 00000042: CALLVALUE 00000043: OR 00000044: PUSH2 0x05ff 00000047: JUMPI 00000048: PUSH1 0x04 0000004a: CALLDATALOAD 0000004b: DUP1 0000004c: PUSH1 0xa0 0000004e: SHR 0000004f: PUSH2 0x05ff 00000052: JUMPI 00000053: PUSH2 0x0100 00000056: MSTORE 00000057: JUMPDEST 00000058: PUSH0 00000059: PUSH2 0x0100 0000005c: MLOAD 0000005d: PUSH1 0x20 0000005f: MSTORE 00000060: PUSH0 00000061: MSTORE 00000062: PUSH1 0x40 00000064: PUSH0 00000065: KECCAK256 00000066: SLOAD 00000067: ISZERO 00000068: PUSH2 0x00e8 0000006b: JUMPI 0000006c: PUSH1 0x20 0000006e: DUP1 0000006f: PUSH2 0x0180 00000072: MSTORE 00000073: PUSH1 0x0f 00000075: PUSH2 0x0120 00000078: MSTORE 00000079: PUSH32 0x416c726561647920636c61696d65640000000000000000000000000000000000 0000009a: PUSH2 0x0140 0000009d: MSTORE 0000009e: PUSH2 0x0120 000000a1: DUP2 000000a2: PUSH2 0x0180 000000a5: ADD 000000a6: PUSH1 0x20 000000a8: DUP3 000000a9: MLOAD 000000aa: ADD 000000ab: DUP1 000000ac: DUP4 000000ad: DUP4 000000ae: MCOPY 000000af: POP 000000b0: DUP1 000000b1: MLOAD 000000b2: DUP1 000000b3: PUSH1 0x20 000000b5: DUP4 000000b6: ADD 000000b7: ADD 000000b8: PUSH1 0x1f 000000ba: DUP3 000000bb: PUSH0 000000bc: SUB 000000bd: AND 000000be: CALLDATASIZE 000000bf: DUP3 000000c0: CALLDATACOPY 000000c1: POP 000000c2: POP 000000c3: PUSH1 0x1f 000000c5: NOT 000000c6: PUSH1 0x1f 000000c8: DUP3 000000c9: MLOAD 000000ca: PUSH1 0x20 000000cc: ADD 000000cd: ADD 000000ce: AND 000000cf: SWAP1 000000d0: POP 000000d1: SWAP1 000000d2: POP 000000d3: DUP2 000000d4: ADD 000000d5: SWAP1 000000d6: POP 000000d7: PUSH4 0x08c379a0 000000dc: PUSH2 0x0160 000000df: MSTORE 000000e0: DUP1 000000e1: PUSH1 0x04 000000e3: ADD 000000e4: PUSH2 0x017c 000000e7: REVERT 000000e8: JUMPDEST 000000e9: PUSH1 0x01 000000eb: PUSH0 000000ec: PUSH2 0x0100 000000ef: MLOAD 000000f0: PUSH1 0x20 000000f2: MSTORE 000000f3: PUSH0 000000f4: MSTORE 000000f5: PUSH1 0x40 000000f7: PUSH0 000000f8: KECCAK256 000000f9: SSTORE 000000fa: PUSH2 0x0100 000000fd: MLOAD 000000fe: PUSH1 0x40 00000100: MSTORE 00000101: PUSH2 0x010b 00000104: PUSH2 0x0140 00000107: PUSH2 0x053e 0000010a: JUMP 0000010b: JUMPDEST 0000010c: PUSH2 0x0140 0000010f: MLOAD 00000110: PUSH2 0x0120 00000113: MSTORE 00000114: PUSH1 0x20 00000116: PUSH2 0x0619 00000119: PUSH0 0000011a: CODECOPY 0000011b: PUSH0 0000011c: MLOAD 0000011d: PUSH4 0xa9059cbb 00000122: PUSH2 0x0140 00000125: MSTORE 00000126: PUSH1 0x40 00000128: PUSH2 0x0100 0000012b: PUSH2 0x0160 0000012e: MCOPY 0000012f: PUSH1 0x20 00000131: PUSH2 0x0140 00000134: PUSH1 0x44 00000136: PUSH2 0x015c 00000139: PUSH0 0000013a: DUP6 0000013b: GAS 0000013c: CALL 0000013d: PUSH2 0x0148 00000140: JUMPI 00000141: RETURNDATASIZE 00000142: PUSH0 00000143: PUSH0 00000144: RETURNDATACOPY 00000145: RETURNDATASIZE 00000146: PUSH0 00000147: REVERT 00000148: JUMPDEST 00000149: RETURNDATASIZE 0000014a: PUSH2 0x015f 0000014d: JUMPI 0000014e: DUP1 0000014f: EXTCODESIZE 00000150: ISZERO 00000151: PUSH2 0x05ff 00000154: JUMPI 00000155: PUSH1 0x01 00000157: PUSH2 0x01a0 0000015a: MSTORE 0000015b: PUSH2 0x0189 0000015e: JUMP 0000015f: JUMPDEST 00000160: RETURNDATASIZE 00000161: PUSH1 0x20 00000163: DUP2 00000164: XOR 00000165: RETURNDATASIZE 00000166: PUSH1 0x20 00000168: LT 00000169: MUL 0000016a: XOR 0000016b: DUP1 0000016c: PUSH2 0x0140 0000016f: ADD 00000170: PUSH2 0x0160 00000173: GT 00000174: PUSH2 0x05ff 00000177: JUMPI 00000178: PUSH2 0x0140 0000017b: MLOAD 0000017c: DUP1 0000017d: PUSH1 0x01 0000017f: SHR 00000180: PUSH2 0x05ff 00000183: JUMPI 00000184: PUSH2 0x01a0 00000187: MSTORE 00000188: POP 00000189: JUMPDEST 0000018a: PUSH2 0x01a0 0000018d: POP 0000018e: POP 0000018f: PUSH2 0x0100 00000192: MLOAD 00000193: PUSH32 0xd8138f8a3f377c5259ca548e70e4c2de94f129f5a11036a15b69513cba2b426a 000001b4: PUSH2 0x0120 000001b7: MLOAD 000001b8: PUSH2 0x0140 000001bb: MSTORE 000001bc: PUSH1 0x20 000001be: PUSH2 0x0140 000001c1: LOG2 000001c2: STOP 000001c3: JUMPDEST 000001c4: PUSH4 0xedf68558 000001c9: DUP2 000001ca: XOR 000001cb: PUSH2 0x053a 000001ce: JUMPI 000001cf: PUSH1 0x24 000001d1: CALLDATASIZE 000001d2: LT 000001d3: CALLVALUE 000001d4: OR 000001d5: PUSH2 0x05ff 000001d8: JUMPI 000001d9: PUSH1 0x04 000001db: CALLDATALOAD 000001dc: DUP1 000001dd: PUSH1 0xa0 000001df: SHR 000001e0: PUSH2 0x05ff 000001e3: JUMPI 000001e4: PUSH1 0x40 000001e6: MSTORE 000001e7: PUSH1 0x20 000001e9: PUSH2 0x0619 000001ec: PUSH0 000001ed: CODECOPY 000001ee: PUSH0 000001ef: MLOAD 000001f0: PUSH1 0x40 000001f2: MLOAD 000001f3: XOR 000001f4: PUSH2 0x028d 000001f7: JUMPI 000001f8: PUSH1 0x20 000001fa: PUSH2 0x0679 000001fd: PUSH0 000001fe: CODECOPY 000001ff: PUSH0 00000200: MLOAD 00000201: PUSH4 0x03c26700 00000206: DUP2 00000207: ADD 00000208: DUP2 00000209: DUP2 0000020a: LT 0000020b: PUSH2 0x05ff 0000020e: JUMPI 0000020f: SWAP1 00000210: POP 00000211: TIMESTAMP 00000212: LT 00000213: ISZERO 00000214: PUSH2 0x028d 00000217: JUMPI 00000218: PUSH1 0x20 0000021a: DUP1 0000021b: PUSH1 0xc0 0000021d: MSTORE 0000021e: PUSH1 0x08 00000220: PUSH1 0x60 00000222: MSTORE 00000223: PUSH32 0x546f6f20736f6f6e000000000000000000000000000000000000000000000000 00000244: PUSH1 0x80 00000246: MSTORE 00000247: PUSH1 0x60 00000249: DUP2 0000024a: PUSH1 0xc0 0000024c: ADD 0000024d: PUSH1 0x20 0000024f: DUP3 00000250: MLOAD 00000251: ADD 00000252: DUP1 00000253: DUP4 00000254: DUP4 00000255: MCOPY 00000256: POP 00000257: DUP1 00000258: MLOAD 00000259: DUP1 0000025a: PUSH1 0x20 0000025c: DUP4 0000025d: ADD 0000025e: ADD 0000025f: PUSH1 0x1f 00000261: DUP3 00000262: PUSH0 00000263: SUB 00000264: AND 00000265: CALLDATASIZE 00000266: DUP3 00000267: CALLDATACOPY 00000268: POP 00000269: POP 0000026a: PUSH1 0x1f 0000026c: NOT 0000026d: PUSH1 0x1f 0000026f: DUP3 00000270: MLOAD 00000271: PUSH1 0x20 00000273: ADD 00000274: ADD 00000275: AND 00000276: SWAP1 00000277: POP 00000278: SWAP1 00000279: POP 0000027a: DUP2 0000027b: ADD 0000027c: SWAP1 0000027d: POP 0000027e: PUSH4 0x08c379a0 00000283: PUSH1 0xa0 00000285: MSTORE 00000286: DUP1 00000287: PUSH1 0x04 00000289: ADD 0000028a: PUSH1 0xbc 0000028c: REVERT 0000028d: JUMPDEST 0000028e: PUSH1 0x40 00000290: MLOAD 00000291: PUSH4 0xa9059cbb 00000296: PUSH1 0xa0 00000298: MSTORE 00000299: PUSH20 0x0d5dc686d0a2abbfdafdfb4d0533e886517d4e83 000002ae: PUSH1 0xc0 000002b0: MSTORE 000002b1: PUSH1 0x40 000002b3: MLOAD 000002b4: PUSH4 0x70a08231 000002b9: PUSH1 0x60 000002bb: MSTORE 000002bc: ADDRESS 000002bd: PUSH1 0x80 000002bf: MSTORE 000002c0: PUSH1 0x20 000002c2: PUSH1 0x60 000002c4: PUSH1 0x24 000002c6: PUSH1 0x7c 000002c8: DUP5 000002c9: GAS 000002ca: STATICCALL 000002cb: PUSH2 0x02d6 000002ce: JUMPI 000002cf: RETURNDATASIZE 000002d0: PUSH0 000002d1: PUSH0 000002d2: RETURNDATACOPY 000002d3: RETURNDATASIZE 000002d4: PUSH0 000002d5: REVERT 000002d6: JUMPDEST 000002d7: PUSH1 0x20 000002d9: RETURNDATASIZE 000002da: LT 000002db: PUSH2 0x05ff 000002de: JUMPI 000002df: PUSH1 0x60 000002e1: SWAP1 000002e2: POP 000002e3: MLOAD 000002e4: PUSH1 0xe0 000002e6: MSTORE 000002e7: PUSH1 0x20 000002e9: PUSH1 0xa0 000002eb: PUSH1 0x44 000002ed: PUSH1 0xbc 000002ef: PUSH0 000002f0: DUP6 000002f1: GAS 000002f2: CALL 000002f3: PUSH2 0x02fe 000002f6: JUMPI 000002f7: RETURNDATASIZE 000002f8: PUSH0 000002f9: PUSH0 000002fa: RETURNDATACOPY 000002fb: RETURNDATASIZE 000002fc: PUSH0 000002fd: REVERT 000002fe: JUMPDEST 000002ff: RETURNDATASIZE 00000300: PUSH2 0x0315 00000303: JUMPI 00000304: DUP1 00000305: EXTCODESIZE 00000306: ISZERO 00000307: PUSH2 0x05ff 0000030a: JUMPI 0000030b: PUSH1 0x01 0000030d: PUSH2 0x0100 00000310: MSTORE 00000311: PUSH2 0x033c 00000314: JUMP 00000315: JUMPDEST 00000316: RETURNDATASIZE 00000317: PUSH1 0x20 00000319: DUP2 0000031a: XOR 0000031b: RETURNDATASIZE 0000031c: PUSH1 0x20 0000031e: LT 0000031f: MUL 00000320: XOR 00000321: DUP1 00000322: PUSH1 0xa0 00000324: ADD 00000325: PUSH1 0xc0 00000327: GT 00000328: PUSH2 0x05ff 0000032b: JUMPI 0000032c: PUSH1 0xa0 0000032e: MLOAD 0000032f: DUP1 00000330: PUSH1 0x01 00000332: SHR 00000333: PUSH2 0x05ff 00000336: JUMPI 00000337: PUSH2 0x0100 0000033a: MSTORE 0000033b: POP 0000033c: JUMPDEST 0000033d: PUSH2 0x0100 00000340: POP 00000341: POP 00000342: STOP 00000343: JUMPDEST 00000344: PUSH4 0xa7c8b710 00000349: DUP2 0000034a: XOR 0000034b: PUSH2 0x03b5 0000034e: JUMPI 0000034f: PUSH1 0x24 00000351: CALLDATASIZE 00000352: LT 00000353: CALLVALUE 00000354: OR 00000355: PUSH2 0x05ff 00000358: JUMPI 00000359: PUSH1 0x04 0000035b: CALLDATALOAD 0000035c: DUP1 0000035d: PUSH1 0xa0 0000035f: SHR 00000360: PUSH2 0x05ff 00000363: JUMPI 00000364: PUSH1 0x40 00000366: MSTORE 00000367: PUSH1 0x20 00000369: PUSH4 0x4ee2cd7e 0000036e: PUSH1 0x60 00000370: MSTORE 00000371: PUSH1 0x40 00000373: MLOAD 00000374: PUSH1 0x80 00000376: MSTORE 00000377: PUSH1 0x20 00000379: PUSH2 0x0659 0000037c: PUSH1 0xa0 0000037e: CODECOPY 0000037f: PUSH1 0x20 00000381: PUSH1 0x60 00000383: PUSH1 0x44 00000385: PUSH1 0x7c 00000387: PUSH20 0x2fc52c61fb0c03489649311989ce2689d93dc1a2 0000039c: GAS 0000039d: STATICCALL 0000039e: PUSH2 0x03a9 000003a1: JUMPI 000003a2: RETURNDATASIZE 000003a3: PUSH0 000003a4: PUSH0 000003a5: RETURNDATACOPY 000003a6: RETURNDATASIZE 000003a7: PUSH0 000003a8: REVERT 000003a9: JUMPDEST 000003aa: PUSH1 0x20 000003ac: RETURNDATASIZE 000003ad: LT 000003ae: PUSH2 0x05ff 000003b1: JUMPI 000003b2: PUSH1 0x60 000003b4: RETURN 000003b5: JUMPDEST 000003b6: PUSH4 0x1b581eaa 000003bb: DUP2 000003bc: XOR 000003bd: PUSH2 0x053a 000003c0: JUMPI 000003c1: CALLVALUE 000003c2: PUSH2 0x05ff 000003c5: JUMPI 000003c6: PUSH20 0x2fc52c61fb0c03489649311989ce2689d93dc1a2 000003db: PUSH1 0x40 000003dd: MSTORE 000003de: PUSH1 0x20 000003e0: PUSH1 0x40 000003e2: RETURN 000003e3: JUMPDEST 000003e4: PUSH4 0x402914f5 000003e9: DUP2 000003ea: XOR 000003eb: PUSH2 0x0420 000003ee: JUMPI 000003ef: PUSH1 0x24 000003f1: CALLDATASIZE 000003f2: LT 000003f3: CALLVALUE 000003f4: OR 000003f5: PUSH2 0x05ff 000003f8: JUMPI 000003f9: PUSH1 0x04 000003fb: CALLDATALOAD 000003fc: DUP1 000003fd: PUSH1 0xa0 000003ff: SHR 00000400: PUSH2 0x05ff 00000403: JUMPI 00000404: PUSH2 0x0100 00000407: MSTORE 00000408: PUSH1 0x20 0000040a: PUSH2 0x0100 0000040d: MLOAD 0000040e: PUSH1 0x40 00000410: MSTORE 00000411: PUSH2 0x041b 00000414: PUSH2 0x0120 00000417: PUSH2 0x053e 0000041a: JUMP 0000041b: JUMPDEST 0000041c: PUSH2 0x0120 0000041f: RETURN 00000420: JUMPDEST 00000421: PUSH4 0x311729e8 00000426: DUP2 00000427: XOR 00000428: PUSH2 0x053a 0000042b: JUMPI 0000042c: CALLVALUE 0000042d: PUSH2 0x05ff 00000430: JUMPI 00000431: PUSH1 0x20 00000433: PUSH2 0x0659 00000436: PUSH1 0x40 00000438: CODECOPY 00000439: PUSH1 0x20 0000043b: PUSH1 0x40 0000043d: RETURN 0000043e: JUMPDEST 0000043f: PUSH4 0x96029773 00000444: DUP2 00000445: XOR 00000446: PUSH2 0x053a 00000449: JUMPI 0000044a: CALLVALUE 0000044b: PUSH2 0x05ff 0000044e: JUMPI 0000044f: PUSH32 0x31ba7c9394ad2daed98dc335ae20f0bcbe6c778c1e72812f6e404405e950a761 00000470: PUSH1 0x40 00000472: MSTORE 00000473: PUSH1 0x20 00000475: PUSH1 0x40 00000477: RETURN 00000478: JUMPDEST 00000479: PUSH4 0x82bfefc8 0000047e: DUP2 0000047f: XOR 00000480: PUSH2 0x053a 00000483: JUMPI 00000484: CALLVALUE 00000485: PUSH2 0x05ff 00000488: JUMPI 00000489: PUSH1 0x20 0000048b: PUSH2 0x0619 0000048e: PUSH1 0x40 00000490: CODECOPY 00000491: PUSH1 0x20 00000493: PUSH1 0x40 00000495: RETURN 00000496: JUMPDEST 00000497: PUSH4 0xa2d7f5e3 0000049c: DUP2 0000049d: XOR 0000049e: PUSH2 0x04b4 000004a1: JUMPI 000004a2: CALLVALUE 000004a3: PUSH2 0x05ff 000004a6: JUMPI 000004a7: PUSH1 0x20 000004a9: PUSH2 0x0639 000004ac: PUSH1 0x40 000004ae: CODECOPY 000004af: PUSH1 0x20 000004b1: PUSH1 0x40 000004b3: RETURN 000004b4: JUMPDEST 000004b5: PUSH4 0xbec75575 000004ba: DUP2 000004bb: XOR 000004bc: PUSH2 0x053a 000004bf: JUMPI 000004c0: CALLVALUE 000004c1: PUSH2 0x05ff 000004c4: JUMPI 000004c5: PUSH20 0x0d5dc686d0a2abbfdafdfb4d0533e886517d4e83 000004da: PUSH1 0x40 000004dc: MSTORE 000004dd: PUSH1 0x20 000004df: PUSH1 0x40 000004e1: RETURN 000004e2: JUMPDEST 000004e3: PUSH4 0xfbc6def7 000004e8: DUP2 000004e9: XOR 000004ea: PUSH2 0x053a 000004ed: JUMPI 000004ee: CALLVALUE 000004ef: PUSH2 0x05ff 000004f2: JUMPI 000004f3: PUSH1 0x20 000004f5: PUSH2 0x0679 000004f8: PUSH1 0x40 000004fa: CODECOPY 000004fb: PUSH1 0x20 000004fd: PUSH1 0x40 000004ff: RETURN 00000500: JUMPDEST 00000501: PUSH4 0x71e87841 00000506: DUP2 00000507: XOR 00000508: PUSH2 0x053a 0000050b: JUMPI 0000050c: PUSH1 0x24 0000050e: CALLDATASIZE 0000050f: LT 00000510: CALLVALUE 00000511: OR 00000512: PUSH2 0x05ff 00000515: JUMPI 00000516: PUSH1 0x04 00000518: CALLDATALOAD 00000519: DUP1 0000051a: PUSH1 0xa0 0000051c: SHR 0000051d: PUSH2 0x05ff 00000520: JUMPI 00000521: PUSH1 0x40 00000523: MSTORE 00000524: PUSH0 00000525: PUSH1 0x40 00000527: MLOAD 00000528: PUSH1 0x20 0000052a: MSTORE 0000052b: PUSH0 0000052c: MSTORE 0000052d: PUSH1 0x40 0000052f: PUSH0 00000530: KECCAK256 00000531: SLOAD 00000532: PUSH1 0x60 00000534: MSTORE 00000535: PUSH1 0x20 00000537: PUSH1 0x60 00000539: RETURN 0000053a: JUMPDEST 0000053b: PUSH0 0000053c: PUSH0 0000053d: REVERT 0000053e: JUMPDEST 0000053f: PUSH1 0x20 00000541: PUSH2 0x0639 00000544: PUSH0 00000545: CODECOPY 00000546: PUSH0 00000547: MLOAD 00000548: PUSH4 0x4ee2cd7e 0000054d: PUSH1 0x60 0000054f: MSTORE 00000550: PUSH1 0x40 00000552: MLOAD 00000553: PUSH1 0x80 00000555: MSTORE 00000556: PUSH1 0x20 00000558: PUSH2 0x0659 0000055b: PUSH1 0xa0 0000055d: CODECOPY 0000055e: PUSH1 0x20 00000560: PUSH1 0x60 00000562: PUSH1 0x44 00000564: PUSH1 0x7c 00000566: PUSH20 0x2fc52c61fb0c03489649311989ce2689d93dc1a2 0000057b: GAS 0000057c: STATICCALL 0000057d: PUSH2 0x0588 00000580: JUMPI 00000581: RETURNDATASIZE 00000582: PUSH0 00000583: PUSH0 00000584: RETURNDATACOPY 00000585: RETURNDATASIZE 00000586: PUSH0 00000587: REVERT 00000588: JUMPDEST 00000589: PUSH1 0x20 0000058b: RETURNDATASIZE 0000058c: LT 0000058d: PUSH2 0x05ff 00000590: JUMPI 00000591: PUSH1 0x60 00000593: MLOAD 00000594: DUP1 00000595: DUP3 00000596: MUL 00000597: DUP2 00000598: ISZERO 00000599: DUP4 0000059a: DUP4 0000059b: DUP4 0000059c: DIV 0000059d: EQ 0000059e: OR 0000059f: ISZERO 000005a0: PUSH2 0x05ff 000005a3: JUMPI 000005a4: SWAP1 000005a5: POP 000005a6: SWAP1 000005a7: POP 000005a8: PUSH4 0x981b24d0 000005ad: PUSH1 0xc0 000005af: MSTORE 000005b0: PUSH1 0x20 000005b2: PUSH2 0x0659 000005b5: PUSH1 0xe0 000005b7: CODECOPY 000005b8: PUSH1 0x20 000005ba: PUSH1 0xc0 000005bc: PUSH1 0x24 000005be: PUSH1 0xdc 000005c0: PUSH20 0x2fc52c61fb0c03489649311989ce2689d93dc1a2 000005d5: GAS 000005d6: STATICCALL 000005d7: PUSH2 0x05e2 000005da: JUMPI 000005db: RETURNDATASIZE 000005dc: PUSH0 000005dd: PUSH0 000005de: RETURNDATACOPY 000005df: RETURNDATASIZE 000005e0: PUSH0 000005e1: REVERT 000005e2: JUMPDEST 000005e3: PUSH1 0x20 000005e5: RETURNDATASIZE 000005e6: LT 000005e7: PUSH2 0x05ff 000005ea: JUMPI 000005eb: PUSH1 0xc0 000005ed: MLOAD 000005ee: DUP1 000005ef: ISZERO 000005f0: PUSH2 0x05ff 000005f3: JUMPI 000005f4: DUP1 000005f5: DUP3 000005f6: DIV 000005f7: SWAP1 000005f8: POP 000005f9: SWAP1 000005fa: POP 000005fb: DUP2 000005fc: MSTORE 000005fd: POP 000005fe: JUMP 000005ff: JUMPDEST 00000600: PUSH0 00000601: DUP1 00000602: REVERT 00000603: DIV 00000604: SWAP7 00000605: DIV 00000606: UNKNOWN(0xE2) 00000607: STOP 00000608: XOR 00000609: STOP 0000060a: ORIGIN 0000060b: SUB 0000060c: UNKNOWN(0xE3) 0000060d: DIV 0000060e: RETURNDATACOPY 0000060f: SDIV 00000610: GASPRICE 00000611: SDIV 00000612: GASPRICE 00000613: DIV 00000614: PUSH25 0x05000343000000000000000000000000a0b86991c6218b36c1 0000062e: UNKNOWN(0xD1) 0000062f: SWAP14 00000630: BLOBBASEFEE 00000631: UNKNOWN(0x2E) 00000632: SWAP15 00000633: UNKNOWN(0xB0) 00000634: UNKNOWN(0xCE) 00000635: CALLDATASIZE 00000636: MOD 00000637: UNKNOWN(0xEB) 00000638: BASEFEE 00000639: STOP 0000063a: STOP 0000063b: STOP 0000063c: STOP 0000063d: STOP 0000063e: STOP 0000063f: STOP 00000640: STOP 00000641: STOP 00000642: STOP 00000643: STOP 00000644: STOP 00000645: STOP 00000646: STOP 00000647: STOP 00000648: STOP 00000649: STOP 0000064a: STOP 0000064b: STOP 0000064c: STOP 0000064d: STOP 0000064e: STOP 0000064f: STOP 00000650: STOP 00000651: STOP 00000652: STOP 00000653: ADD 00000654: UNKNOWN(0xE8) 00000655: CALL 00000656: UNKNOWN(0xC1) 00000657: ADDMOD 00000658: STOP 00000659: STOP 0000065a: STOP 0000065b: STOP 0000065c: STOP 0000065d: STOP 0000065e: STOP 0000065f: STOP 00000660: STOP 00000661: STOP 00000662: STOP 00000663: STOP 00000664: STOP 00000665: STOP 00000666: STOP 00000667: STOP 00000668: STOP 00000669: STOP 0000066a: STOP 0000066b: STOP 0000066c: STOP 0000066d: STOP 0000066e: STOP 0000066f: STOP 00000670: STOP 00000671: STOP 00000672: STOP 00000673: STOP 00000674: STOP 00000675: ADD 00000676: SELFBALANCE 00000677: PUSH26 0xdf00000000000000000000000000000000000000000000000000 00000692: STOP 00000693: STOP 00000694: STOP 00000695: PUSH9
| Severity | Category | Tool | Title | Confidence | Validated | Confirmed | Details |
|---|---|---|---|---|---|---|---|
| high | auth | detector | Authorization based on tx.origin | 70 | no | — |
viewvalidation_json{
"reason": "missing sink mapping",
"status": "no_sink"
}
witness_json{
"notes": "heuristic witness; entrypoints are best-effort selectors with zeroed calldata",
"constraints": [],
"entrypoints": [
{
"calldata": "0x",
"selector": "fallback",
"calldata_variants": [
"0x"
]
}
]
}
evidence_json{
"guards_detected": [
{
"pc": 1546,
"type": "tx_origin_used"
}
]
}
|
| medium | other | codex | Unchecked ERC20 transfer return value can permanently burn claims | 75 | no | — |
viewevidence_json{
"evidence": "`claim` sets `has_claimed` before calling `extcall TOKEN.transfer(...)` and does not check the return value; `clawback` similarly ignores `transfer` success.",
"locations": [
"contracts/Contract.sol:60",
"contracts/Contract.sol:65",
"contracts/Contract.sol:79"
],
"recommendation": "Require `transfer` success (check the boolean return value and revert on `false`), or use a safe transfer helper. Consider setting `has_claimed` only after a successful transfer.",
"exploit_scenario": "If `TOKEN` is non\u2011standard and returns `false` on failure (rather than reverting), `claim` marks `has_claimed[locker] = True` and ignores the `transfer` result. The locker cannot retry, leaving their allocation stuck in the contract and potentially clawed back later."
}
|
| medium | other | detector | Untrusted CALL target/value reachable | 45 | no | no |
viewtrace_id: 0x851076fe252595e8aa137afc443777f91aaa0ed777fdc43b562967d33ef4dfb7
call_targets:
0xea402139c2a2c77ac724f6ab7724bc2938d30967
target_varies:
no
classification:
constant_target
validation_json{
"sink": "CALL",
"errors": 0,
"status": "sink_reached",
"attempts": 1,
"trace_id": "0x851076fe252595e8aa137afc443777f91aaa0ed777fdc43b562967d33ef4dfb7",
"confirmed": false,
"trace_mode": "callTracer",
"call_targets": [
"0xea402139c2a2c77ac724f6ab7724bc2938d30967"
],
"matched_probe": null,
"target_varies": false,
"classification": "constant_target"
}
witness_json{
"notes": "heuristic witness; entrypoints are best-effort selectors with zeroed calldata",
"constraints": [],
"entrypoints": [
{
"calldata": "0x",
"selector": "fallback",
"calldata_variants": [
"0x"
]
}
]
}
evidence_json{
"examples": [
{
"pc": 754,
"opcode": "CALL",
"returndata_checked": null,
"value_expression_category": "constant",
"target_expression_category": "computed"
},
{
"pc": 1621,
"opcode": "CALL",
"returndata_checked": null,
"value_expression_category": "computed",
"target_expression_category": "computed"
}
],
"call_count": 3,
"guards_detected": [
{
"pc": 1546,
"type": "tx_origin_used"
}
],
"untrusted_call_count": 2
}
|
| medium | other | detector | ETH value transfer possible | 40 | no | no |
viewtrace_id: 0x851076fe252595e8aa137afc443777f91aaa0ed777fdc43b562967d33ef4dfb7
call_targets:
0xea402139c2a2c77ac724f6ab7724bc2938d30967
target_varies:
no
classification:
constant_target
validation_json{
"sink": "CALL",
"errors": 0,
"status": "sink_reached",
"attempts": 1,
"trace_id": "0x851076fe252595e8aa137afc443777f91aaa0ed777fdc43b562967d33ef4dfb7",
"confirmed": false,
"trace_mode": "callTracer",
"call_targets": [
"0xea402139c2a2c77ac724f6ab7724bc2938d30967"
],
"matched_probe": null,
"target_varies": false,
"classification": "constant_target"
}
witness_json{
"notes": "heuristic witness; entrypoints are best-effort selectors with zeroed calldata",
"constraints": [],
"entrypoints": [
{
"calldata": "0x",
"selector": "fallback",
"calldata_variants": [
"0x"
]
}
]
}
evidence_json{
"examples": [
{
"pc": 316,
"opcode": "CALL",
"returndata_checked": null,
"value_expression_category": "constant",
"target_expression_category": "constant"
},
{
"pc": 754,
"opcode": "CALL",
"returndata_checked": null,
"value_expression_category": "constant",
"target_expression_category": "computed"
},
{
"pc": 1621,
"opcode": "CALL",
"returndata_checked": null,
"value_expression_category": "computed",
"target_expression_category": "computed"
}
],
"eth_value_calls": 3,
"guards_detected": [
{
"pc": 1546,
"type": "tx_origin_used"
}
]
}
|
| low | other | codex | Snapshot validation compares block number to timestamp | 65 | no | — |
viewevidence_json{
"evidence": "`assert snapshot <= block.timestamp, \"No future snapshots\"` despite `snapshot` being documented as a block number.",
"locations": [
"contracts/Contract.sol:44"
],
"recommendation": "Validate `snapshot <= block.number` (and ideally enforce `snapshot < block.number` if the underlying implementation requires a strictly past block).",
"exploit_scenario": "The constructor check uses `block.timestamp` while `snapshot` is a block number. This allows future block numbers (still less than the current timestamp) to pass validation. If `balanceOfAt/totalSupplyAt` revert or return zero for future blocks, claims become impossible until clawback."
}
|
| low | math | codex | Division by zero if totalSupplyAt snapshot is zero | 65 | no | — |
viewevidence_json{
"evidence": "`TOTAL_AMOUNT * balanceOfAt(...) // totalSupplyAt(SNAPSHOT)` performs division without checking for zero.",
"locations": [
"contracts/Contract.sol:107"
],
"recommendation": "Add a guard that `totalSupplyAt(SNAPSHOT) > 0` (e.g., in the constructor) or return `0` when the total supply is zero.",
"exploit_scenario": "If `VKP3R.totalSupplyAt(SNAPSHOT)` is zero, `_claimable` reverts on division by zero, preventing all claims."
}
|