TW
Tripwire
Find contracts. Test them. Review real vulns.

Analysis Run

c28796c0-dadd-466a-a4b7-324e717eaa5f

complete
Chain ID
1
Address
Block Number
Created
Mon, Dec 29, 2025 4:20 AM
Review Summary

What survived the funnel

Open this run to answer one question: is this real attacker-relevant behavior with real impact, or just normal contract plumbing?

Confirmed
0
Validated
0
Source
Verified
Review Backing
Present
Best current signal
Authorization based on tx.origin
crit 0 high 0 direct contract
Review Checklist
1. Read the findings table first. Ignore raw jobs until the result looks real.
2. Confirm attacker control, not just the existence of a sink.
3. Confirm money or privilege impact.
4. Keep it if the behavior is real. Kill it if this is normal proxy, admin, or upgrade plumbing.

Processing Jobs

Status & attempts
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

Artifact

Runtime bytecode: available
Creation TX:
Deployer:
Proxy: no
Implementation:
Verified Source: yes

Slither

tool.slither

No slither job recorded yet.

Codex

report.consolidate
Job Status
complete
Attempts
1 / 1
Findings
3
No findings?
no
Summary
Identified 3 issues that can block claims or silently fail token transfers due to validation and accounting gaps.
View stderr
[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"]}]}
Metadata
{
    "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
}

Opcode Heuristics

tool.cast_disasm
Delegatecall
0
Selfdestruct
0
CREATE2
0
CALL-family (heavy)
7
EXT*/BALANCE
2
Total opcodes
921
Flags
No heuristic flags raised.
View cast disassembly output
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

Findings

validated = confirmed for call sinks; sink observed for others
Severity Category Tool Title Confidence Validated Confirmed Details
high auth detector Authorization based on tx.origin 70 no
view
validation_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
view
evidence_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
view
trace_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
view
trace_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
view
evidence_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
view
evidence_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."
}