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

Analysis Run

019bb004-7af0-71cd-ab6e-35bf05fc077a

failed
Chain ID
1
Address
Block Number
Created
Mon, Jan 12, 2026 2:24 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
Untrusted DELEGATECALL target reachable
crit 0 high 0 proxy context implementation known
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
39339 artifact.fetch complete 1 / 3 3 months ago
39340 proxy.resolve complete 1 / 3 3 months ago
39341 tool.cast_disasm complete 1 / 3 3 months ago
39342 analysis.bundle complete 1 / 3 3 months ago
39343 capability.graph complete 1 / 3 3 months ago
39344 detector.run complete 1 / 3 3 months ago
39345 validation.fork complete 1 / 3 3 months ago
39477 report.consolidate complete 1 / 6 3 months ago
39478 tool.slither failed 2 / 2 3 months ago

Artifact

Runtime bytecode: available
Creation TX:
Deployer:
Proxy: yes confirmed
Verified Source: yes
Proxy evidence
{
    "method": "etherscan+onchain",
    "status": "confirmed",
    "etherscan_hint": {
        "source": "etherscan",
        "etherscan": {
            "proxy_flag": true,
            "implementation": "0x90b6047da43a370a402fb1f88f4313faa34a923b"
        }
    },
    "implementation": "0x90b6047da43a370a402fb1f88f4313faa34a923b",
    "onchain_method": "beacon"
}

Slither

tool.slither
Status
failed slither failed (exit 1): 'forge clean' running (wd: /tmp/slither-8mac_q8p) 'forge config --json' running 'forge build --build-info --skip ./test/** ./script/** --force' running (wd: /tmp/slither-8mac_q8p) Traceback (most recent call last): File "/var/www/tripwire/.venv/bin/slither", line 10, in <module> sys.exit(main()) ~~~~^^ File "/var/www/tripwire/.venv/lib/python3.13/site-packages/slither/__main__.py", line 776, in main main_impl(all_detector_classes=detectors, all_printer_classes=printers) ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/var/www/tripwire/.venv/lib/python3.13/site-packages/slither/__main__.py", line 882, in main_impl ) = process_all(filename, args, detector_classes, printer_classes) ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/var/www/tripwire/.venv/lib/python3.13/site-packages/slither/__main__.py", line 96, in process_all compilations = compile_all(target, **vars(args)) File "/var/www/tripwire/.venv/lib/python3.13/site-packages/crytic_compile/crytic_compile.py", line 722, in compile_all compilations.append(CryticCompile(target, **kwargs)) ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^ File "/var/www/tripwire/.venv/lib/python3.13/site-packages/crytic_compile/crytic_compile.py", line 211, in __init__ self._compile(**kwargs) ~~~~~~~~~~~~~^^^^^^^^^^ File "/var/www/tripwire/.venv/lib/python3.13/site-packages/crytic_compile/crytic_compile.py", line 633, in _compile self._platform.compile(self, **kwargs) ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^ File "/var/www/tripwire/.venv/lib/python3.13/site-packages/crytic_compile/platform/foundry.py", line 102, in compile hardhat_like_parsing( ~~~~~~~~~~~~~~~~~~~~^ crytic_compile, str(self._target), build_directory, str(self._project_root) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ) ^ File "/var/www/tripwire/.venv/lib/python3.13/site-packages/crytic_compile/platform/hardhat.py", line 52, in hardhat_like_parsing raise InvalidCompilation(txt) crytic_compile.platform.exceptions.InvalidCompilation: Compilation failed. Can you run build command? /tmp/slither-8mac_q8p/out/build-info is not a directory.
Attempts
2 / 2
Findings
0
Solc
View stderr
Traceback (most recent call last):
  File "/var/www/tripwire/worker/worker.py", line 198, in main
    payload = dispatch_job(job_type, job_id, job_meta, run_data, config, laravel_client)
  File "/var/www/tripwire/worker/worker.py", line 114, in dispatch_job
    return slither_run.run(job_id, job_meta, run_data, config, log, laravel_client)
           ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/var/www/tripwire/worker/jobs/slither_run.py", line 1084, in run
    stdout_text, stderr_text, result_json = _run_slither(
                                            ~~~~~~~~~~~~^
        workspace,
        ^^^^^^^^^^
    ...<4 lines>...
        target_path=target_path,
        ^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/var/www/tripwire/worker/jobs/slither_run.py", line 958, in _run_slither
    raise RuntimeError(f"slither failed (exit {result.returncode}): {stderr_text or stdout_text}")
RuntimeError: slither failed (exit 1): 'forge clean' running (wd: /tmp/slither-8mac_q8p)
'forge config --json' running
'forge build --build-info --skip ./test/** ./script/** --force' running (wd: /tmp/slither-8mac_q8p)
Traceback (most recent call last):
  File "/var/www/tripwire/.venv/bin/slither", line 10, in <module>
    sys.exit(main())
             ~~~~^^
  File "/var/www/tripwire/.venv/lib/python3.13/site-packages/slither/__main__.py", line 776, in main
    main_impl(all_detector_classes=detectors, all_printer_classes=printers)
    ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/var/www/tripwire/.venv/lib/python3.13/site-packages/slither/__main__.py", line 882, in main_impl
    ) = process_all(filename, args, detector_classes, printer_classes)
        ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/var/www/tripwire/.venv/lib/python3.13/site-packages/slither/__main__.py", line 96, in process_all
    compilations = compile_all(target, **vars(args))
  File "/var/www/tripwire/.venv/lib/python3.13/site-packages/crytic_compile/crytic_compile.py", line 722, in compile_all
    compilations.append(CryticCompile(target, **kwargs))
                        ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^
  File "/var/www/tripwire/.venv/lib/python3.13/site-packages/crytic_compile/crytic_compile.py", line 211, in __init__
    self._compile(**kwargs)
    ~~~~~~~~~~~~~^^^^^^^^^^
  File "/var/www/tripwire/.venv/lib/python3.13/site-packages/crytic_compile/crytic_compile.py", line 633, in _compile
    self._platform.compile(self, **kwargs)
    ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
  File "/var/www/tripwire/.venv/lib/python3.13/site-packages/crytic_compile/platform/foundry.py", line 102, in compile
    hardhat_like_parsing(
    ~~~~~~~~~~~~~~~~~~~~^
        crytic_compile, str(self._target), build_directory, str(self._project_root)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/var/www/tripwire/.venv/lib/python3.13/site-packages/crytic_compile/platform/hardhat.py", line 52, in hardhat_like_parsing
    raise InvalidCompilation(txt)
crytic_compile.platform.exceptions.InvalidCompilation: Compilation failed. Can you run build command?
/tmp/slither-8mac_q8p/out/build-info is not a directory.

Codex

report.consolidate
Job Status
complete
Attempts
1 / 6
Findings
1
No findings?
no
Summary
Found a high-severity logic flaw: after a successful buyout, listing tokens are never claimable by the offerer, leaving purchased tokens locked in the contract.
View stdout
{"no_findings":false,"summary":"Found a high-severity logic flaw: after a successful buyout, listing tokens are never claimable by the offerer, leaving purchased tokens locked in the contract.","findings":[{"severity":"high","category":"other","title":"Offerer can never claim listing tokens after successful buyout","exploit_scenario":"After the buyout succeeds, holders call `surrenderTokens` and receive funding tokens. The listing tokens they surrender (plus the offerer’s initial listing deposit) remain in the contract with no way for the offerer to claim them, so the offerer pays but never receives the purchased tokens.","recommendation":"Add a post-success claim mechanism for the offerer (e.g., `claimListingTokens`) or transfer surrendered listing tokens directly to the offerer during `surrenderTokens`. Ensure the claim is only available in `Status.SUCCESS` and after any required settlement conditions.","evidence":"`offer` and `surrenderTokens` transfer listing tokens into the contract, while the only listing token outflow is `withdrawTokens` (COUNTERED status). There is no function to transfer listing tokens to the offerer in SUCCESS.","locations":["contracts/Buyout.sol"]}]}
View stderr
OpenAI Codex v0.77.0 (research preview)
--------
workdir: /tmp/codex-s_a4zu2x
model: gpt-5.2-codex
provider: openai
approval: never
sandbox: read-only
reasoning effort: high
reasoning summaries: auto
session id: 019bb01f-7542-77f1-860f-9220079c0ba7
--------
user
Context: The user requested the proxy at 0xc6cc57767ac16c1ad20f507e11db1e5265034b09.
Audit the implementation at 0x90b6047da43a370a402fb1f88f4313faa34a923b.
Findings should refer to the implementation unless explicitly about proxy mechanics.

You are a security auditor. Audit this Solidity codebase for exploitable vulnerabilities.
Focus on: reentrancy, access control, upgradeability/proxy issues, signature validation, oracle manipulation,
accounting/invariant breaks, external call patterns, unchecked return values, and dangerous delegatecall.

Scope rules:
- You MUST fully read `AUDIT_BUNDLE.txt` before concluding. It contains the complete contents of all first-party Solidity sources in this workspace.
- Treat `lib/` and `@openzeppelin/` as third-party dependencies; skip them unless there is a concrete misuse angle in first-party code.
- If there are only dependency files and no first-party sources, set no_findings=true and explain in summary.

Output MUST be valid JSON matching the provided schema.
- If you find nothing meaningful: set no_findings=true and findings=[].
- Otherwise: set no_findings=false and include findings with severity/category/title and file/line locations when possible.

Output constraints (IMPORTANT):
- severity MUST be exactly one of: info, low, medium, high, critical (lowercase).
- category MUST be exactly one of: access_control, reentrancy, math, oracle, upgradeability, auth, other.
Keep summary short and concrete.
mcp startup: no servers

thinking
**Reading AUDIT_BUNDLE.txt**
exec
/bin/bash -lc 'cat AUDIT_BUNDLE.txt' in /tmp/codex-s_a4zu2x succeeded in 9ms:
This file concatenates the full contents of first-party Solidity sources for auditing.
Do not treat dependency code under lib/ or @openzeppelin/ as first-party.

================================================================================
FILE: contracts/Buyout.sol
================================================================================
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol";

import "./interfaces/IBuyout.sol";

/// Buyout is a shotgun clause / buy-sell agreement to allow holders to acquire
/// all other outstanding tokens.
///
/// @dev totalSupply() is currently frozen at start of offer
contract Buyout is IBuyout, Initializable {



thinking
**Analyzing Buyout contract for vulnerabilities**
thinking
**Identifying critical logic flaws and token accounting issues**

I’m noticing a major functional bug where the offerer cannot claim listing tokens after a successful buyout, leaving those tokens locked in the contract indefinitely. There are also subtle accounting risks if fee-on-transfer or rebasing tokens are used, which can cause payout imbalances or insolvency. Additionally, rounding in counterOfferTarget can lead to immediate COUNTERED status and permanent token locks for the offerer, though that’s mainly self-inflicted. Overall, these issues highlight gaps in token handling and buyout finalization rather than direct exploits.
thinking
**Detailing critical claim token omission and supply risks**

I found a major logic flaw where the offerer cannot claim listing tokens after the buyout succeeds, causing them to be locked inside the contract indefinitely. This breaks the buyout’s essential function since holders can surrender tokens and get funding, but the offerer never receives those tokens. There’s also a risk if the listing token supply changes post-offer, allowing extra tokens to be surrendered, potentially draining the contract’s funds. I’m preparing a detailed JSON report highlighting these issues with supporting function references.
codex
{"no_findings":false,"summary":"Found a high-severity logic flaw: after a successful buyout, listing tokens are never claimable by the offerer, leaving purchased tokens locked in the contract.","findings":[{"severity":"high","category":"other","title":"Offerer can never claim listing tokens after successful buyout","exploit_scenario":"After the buyout succeeds, holders call `surrenderTokens` and receive funding tokens. The listing tokens they surrender (plus the offerer’s initial listing deposit) remain in the contract with no way for the offerer to claim them, so the offerer pays but never receives the purchased tokens.","recommendation":"Add a post-success claim mechanism for the offerer (e.g., `claimListingTokens`) or transfer surrendered listing tokens directly to the offerer during `surrenderTokens`. Ensure the claim is only available in `Status.SUCCESS` and after any required settlement conditions.","evidence":"`offer` and `surrenderTokens` transfer listing tokens into the contract, while the only listing token outflow is `withdrawTokens` (COUNTERED status). There is no function to transfer listing tokens to the offerer in SUCCESS.","locations":["contracts/Buyout.sol"]}]}
tokens used
15,155
Metadata
{
    "codex": {
        "ran_at": "2026-01-12T02:56:14.457669+00:00",
        "returncode": 0
    },
    "project": {
        "mode": "source",
        "file_count": 6,
        "import_count": 6,
        "first_party_contracts_count": 2
    },
    "summary": "Found a high-severity logic flaw: after a successful buyout, listing tokens are never claimable by the offerer, leaving purchased tokens locked in the contract.",
    "raw_final": {
        "summary": "Found a high-severity logic flaw: after a successful buyout, listing tokens are never claimable by the offerer, leaving purchased tokens locked in the contract.",
        "findings": [
            {
                "title": "Offerer can never claim listing tokens after successful buyout",
                "category": "other",
                "evidence": "`offer` and `surrenderTokens` transfer listing tokens into the contract, while the only listing token outflow is `withdrawTokens` (COUNTERED status). There is no function to transfer listing tokens to the offerer in SUCCESS.",
                "severity": "high",
                "locations": [
                    "contracts/Buyout.sol"
                ],
                "recommendation": "Add a post-success claim mechanism for the offerer (e.g., `claimListingTokens`) or transfer surrendered listing tokens directly to the offerer during `surrenderTokens`. Ensure the claim is only available in `Status.SUCCESS` and after any required settlement conditions.",
                "exploit_scenario": "After the buyout succeeds, holders call `surrenderTokens` and receive funding tokens. The listing tokens they surrender (plus the offerer\u2019s initial listing deposit) remain in the contract with no way for the offerer to claim them, so the offerer pays but never receives the purchased tokens."
            }
        ],
        "no_findings": false
    },
    "no_findings": false,
    "proxy_context": {
        "proxy_run_id": "019bb004-7af0-71cd-ab6e-35bf05fc077a",
        "proxy_address": "0xc6cc57767ac16c1ad20f507e11db1e5265034b09",
        "implementation_run_id": "019bb004-d430-731f-a526-9f72bf0d193b",
        "implementation_address": "0x90b6047da43a370a402fb1f88f4313faa34a923b"
    },
    "schema_version": 1
}

Opcode Heuristics

tool.cast_disasm
Delegatecall
2
Selfdestruct
0
CREATE2
1
CALL-family (heavy)
1
EXT*/BALANCE
3
Total opcodes
520
Flags
delegatecall_present create_opcodes_present
View cast disassembly output
00000000: PUSH1 0x80
00000002: PUSH1 0x40
00000004: MSTORE
00000005: CALLDATASIZE
00000006: PUSH2 0x0013
00000009: JUMPI
0000000a: PUSH2 0x0011
0000000d: PUSH2 0x0017
00000010: JUMP
00000011: JUMPDEST
00000012: STOP
00000013: JUMPDEST
00000014: PUSH2 0x0011
00000017: JUMPDEST
00000018: PUSH2 0x0027
0000001b: PUSH2 0x0022
0000001e: PUSH2 0x005e
00000021: JUMP
00000022: JUMPDEST
00000023: PUSH2 0x0106
00000026: JUMP
00000027: JUMPDEST
00000028: JUMP
00000029: JUMPDEST
0000002a: PUSH1 0x60
0000002c: PUSH2 0x004e
0000002f: DUP4
00000030: DUP4
00000031: PUSH1 0x40
00000033: MLOAD
00000034: DUP1
00000035: PUSH1 0x60
00000037: ADD
00000038: PUSH1 0x40
0000003a: MSTORE
0000003b: DUP1
0000003c: PUSH1 0x27
0000003e: DUP2
0000003f: MSTORE
00000040: PUSH1 0x20
00000042: ADD
00000043: PUSH2 0x02e3
00000046: PUSH1 0x27
00000048: SWAP2
00000049: CODECOPY
0000004a: PUSH2 0x012a
0000004d: JUMP
0000004e: JUMPDEST
0000004f: SWAP4
00000050: SWAP3
00000051: POP
00000052: POP
00000053: POP
00000054: JUMP
00000055: JUMPDEST
00000056: EXTCODESIZE
00000057: ISZERO
00000058: ISZERO
00000059: SWAP1
0000005a: JUMP
0000005b: JUMPDEST
0000005c: SWAP1
0000005d: JUMP
0000005e: JUMPDEST
0000005f: PUSH1 0x00
00000061: PUSH2 0x0091
00000064: PUSH32 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50
00000085: SLOAD
00000086: PUSH1 0x01
00000088: PUSH1 0x01
0000008a: PUSH1 0xa0
0000008c: SHL
0000008d: SUB
0000008e: AND
0000008f: SWAP1
00000090: JUMP
00000091: JUMPDEST
00000092: PUSH1 0x01
00000094: PUSH1 0x01
00000096: PUSH1 0xa0
00000098: SHL
00000099: SUB
0000009a: AND
0000009b: PUSH4 0x5c60da1b
000000a0: PUSH1 0x40
000000a2: MLOAD
000000a3: DUP2
000000a4: PUSH4 0xffffffff
000000a9: AND
000000aa: PUSH1 0xe0
000000ac: SHL
000000ad: DUP2
000000ae: MSTORE
000000af: PUSH1 0x04
000000b1: ADD
000000b2: PUSH1 0x20
000000b4: PUSH1 0x40
000000b6: MLOAD
000000b7: DUP1
000000b8: DUP4
000000b9: SUB
000000ba: DUP2
000000bb: DUP7
000000bc: DUP1
000000bd: EXTCODESIZE
000000be: ISZERO
000000bf: DUP1
000000c0: ISZERO
000000c1: PUSH2 0x00c9
000000c4: JUMPI
000000c5: PUSH1 0x00
000000c7: DUP1
000000c8: REVERT
000000c9: JUMPDEST
000000ca: POP
000000cb: GAS
000000cc: STATICCALL
000000cd: ISZERO
000000ce: DUP1
000000cf: ISZERO
000000d0: PUSH2 0x00dd
000000d3: JUMPI
000000d4: RETURNDATASIZE
000000d5: PUSH1 0x00
000000d7: DUP1
000000d8: RETURNDATACOPY
000000d9: RETURNDATASIZE
000000da: PUSH1 0x00
000000dc: REVERT
000000dd: JUMPDEST
000000de: POP
000000df: POP
000000e0: POP
000000e1: POP
000000e2: PUSH1 0x40
000000e4: MLOAD
000000e5: RETURNDATASIZE
000000e6: PUSH1 0x1f
000000e8: NOT
000000e9: PUSH1 0x1f
000000eb: DUP3
000000ec: ADD
000000ed: AND
000000ee: DUP3
000000ef: ADD
000000f0: DUP1
000000f1: PUSH1 0x40
000000f3: MSTORE
000000f4: POP
000000f5: DUP2
000000f6: ADD
000000f7: SWAP1
000000f8: PUSH2 0x0101
000000fb: SWAP2
000000fc: SWAP1
000000fd: PUSH2 0x023c
00000100: JUMP
00000101: JUMPDEST
00000102: SWAP1
00000103: POP
00000104: SWAP1
00000105: JUMP
00000106: JUMPDEST
00000107: CALLDATASIZE
00000108: PUSH1 0x00
0000010a: DUP1
0000010b: CALLDATACOPY
0000010c: PUSH1 0x00
0000010e: DUP1
0000010f: CALLDATASIZE
00000110: PUSH1 0x00
00000112: DUP5
00000113: GAS
00000114: DELEGATECALL
00000115: RETURNDATASIZE
00000116: PUSH1 0x00
00000118: DUP1
00000119: RETURNDATACOPY
0000011a: DUP1
0000011b: DUP1
0000011c: ISZERO
0000011d: PUSH2 0x0125
00000120: JUMPI
00000121: RETURNDATASIZE
00000122: PUSH1 0x00
00000124: RETURN
00000125: JUMPDEST
00000126: RETURNDATASIZE
00000127: PUSH1 0x00
00000129: REVERT
0000012a: JUMPDEST
0000012b: PUSH1 0x60
0000012d: DUP4
0000012e: EXTCODESIZE
0000012f: PUSH2 0x018e
00000132: JUMPI
00000133: PUSH1 0x40
00000135: MLOAD
00000136: PUSH3 0x461bcd
0000013a: PUSH1 0xe5
0000013c: SHL
0000013d: DUP2
0000013e: MSTORE
0000013f: PUSH1 0x20
00000141: PUSH1 0x04
00000143: DUP3
00000144: ADD
00000145: MSTORE
00000146: PUSH1 0x26
00000148: PUSH1 0x24
0000014a: DUP3
0000014b: ADD
0000014c: MSTORE
0000014d: PUSH32 0x416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f
0000016e: PUSH1 0x44
00000170: DUP3
00000171: ADD
00000172: MSTORE
00000173: PUSH6 0x1b9d1c9858dd
0000017a: PUSH1 0xd2
0000017c: SHL
0000017d: PUSH1 0x64
0000017f: DUP3
00000180: ADD
00000181: MSTORE
00000182: PUSH1 0x84
00000184: ADD
00000185: JUMPDEST
00000186: PUSH1 0x40
00000188: MLOAD
00000189: DUP1
0000018a: SWAP2
0000018b: SUB
0000018c: SWAP1
0000018d: REVERT
0000018e: JUMPDEST
0000018f: PUSH1 0x00
00000191: DUP1
00000192: DUP6
00000193: PUSH1 0x01
00000195: PUSH1 0x01
00000197: PUSH1 0xa0
00000199: SHL
0000019a: SUB
0000019b: AND
0000019c: DUP6
0000019d: PUSH1 0x40
0000019f: MLOAD
000001a0: PUSH2 0x01a9
000001a3: SWAP2
000001a4: SWAP1
000001a5: PUSH2 0x0263
000001a8: JUMP
000001a9: JUMPDEST
000001aa: PUSH1 0x00
000001ac: PUSH1 0x40
000001ae: MLOAD
000001af: DUP1
000001b0: DUP4
000001b1: SUB
000001b2: DUP2
000001b3: DUP6
000001b4: GAS
000001b5: DELEGATECALL
000001b6: SWAP2
000001b7: POP
000001b8: POP
000001b9: RETURNDATASIZE
000001ba: DUP1
000001bb: PUSH1 0x00
000001bd: DUP2
000001be: EQ
000001bf: PUSH2 0x01e4
000001c2: JUMPI
000001c3: PUSH1 0x40
000001c5: MLOAD
000001c6: SWAP2
000001c7: POP
000001c8: PUSH1 0x1f
000001ca: NOT
000001cb: PUSH1 0x3f
000001cd: RETURNDATASIZE
000001ce: ADD
000001cf: AND
000001d0: DUP3
000001d1: ADD
000001d2: PUSH1 0x40
000001d4: MSTORE
000001d5: RETURNDATASIZE
000001d6: DUP3
000001d7: MSTORE
000001d8: RETURNDATASIZE
000001d9: PUSH1 0x00
000001db: PUSH1 0x20
000001dd: DUP5
000001de: ADD
000001df: RETURNDATACOPY
000001e0: PUSH2 0x01e9
000001e3: JUMP
000001e4: JUMPDEST
000001e5: PUSH1 0x60
000001e7: SWAP2
000001e8: POP
000001e9: JUMPDEST
000001ea: POP
000001eb: SWAP2
000001ec: POP
000001ed: SWAP2
000001ee: POP
000001ef: PUSH2 0x01f9
000001f2: DUP3
000001f3: DUP3
000001f4: DUP7
000001f5: PUSH2 0x0203
000001f8: JUMP
000001f9: JUMPDEST
000001fa: SWAP7
000001fb: SWAP6
000001fc: POP
000001fd: POP
000001fe: POP
000001ff: POP
00000200: POP
00000201: POP
00000202: JUMP
00000203: JUMPDEST
00000204: PUSH1 0x60
00000206: DUP4
00000207: ISZERO
00000208: PUSH2 0x0212
0000020b: JUMPI
0000020c: POP
0000020d: DUP2
0000020e: PUSH2 0x004e
00000211: JUMP
00000212: JUMPDEST
00000213: DUP3
00000214: MLOAD
00000215: ISZERO
00000216: PUSH2 0x0222
00000219: JUMPI
0000021a: DUP3
0000021b: MLOAD
0000021c: DUP1
0000021d: DUP5
0000021e: PUSH1 0x20
00000220: ADD
00000221: REVERT
00000222: JUMPDEST
00000223: DUP2
00000224: PUSH1 0x40
00000226: MLOAD
00000227: PUSH3 0x461bcd
0000022b: PUSH1 0xe5
0000022d: SHL
0000022e: DUP2
0000022f: MSTORE
00000230: PUSH1 0x04
00000232: ADD
00000233: PUSH2 0x0185
00000236: SWAP2
00000237: SWAP1
00000238: PUSH2 0x027f
0000023b: JUMP
0000023c: JUMPDEST
0000023d: PUSH1 0x00
0000023f: PUSH1 0x20
00000241: DUP3
00000242: DUP5
00000243: SUB
00000244: SLT
00000245: ISZERO
00000246: PUSH2 0x024d
00000249: JUMPI
0000024a: DUP1
0000024b: DUP2
0000024c: REVERT
0000024d: JUMPDEST
0000024e: DUP2
0000024f: MLOAD
00000250: PUSH1 0x01
00000252: PUSH1 0x01
00000254: PUSH1 0xa0
00000256: SHL
00000257: SUB
00000258: DUP2
00000259: AND
0000025a: DUP2
0000025b: EQ
0000025c: PUSH2 0x004e
0000025f: JUMPI
00000260: DUP2
00000261: DUP3
00000262: REVERT
00000263: JUMPDEST
00000264: PUSH1 0x00
00000266: DUP3
00000267: MLOAD
00000268: PUSH2 0x0275
0000026b: DUP2
0000026c: DUP5
0000026d: PUSH1 0x20
0000026f: DUP8
00000270: ADD
00000271: PUSH2 0x02b2
00000274: JUMP
00000275: JUMPDEST
00000276: SWAP2
00000277: SWAP1
00000278: SWAP2
00000279: ADD
0000027a: SWAP3
0000027b: SWAP2
0000027c: POP
0000027d: POP
0000027e: JUMP
0000027f: JUMPDEST
00000280: PUSH1 0x20
00000282: DUP2
00000283: MSTORE
00000284: PUSH1 0x00
00000286: DUP3
00000287: MLOAD
00000288: DUP1
00000289: PUSH1 0x20
0000028b: DUP5
0000028c: ADD
0000028d: MSTORE
0000028e: PUSH2 0x029e
00000291: DUP2
00000292: PUSH1 0x40
00000294: DUP6
00000295: ADD
00000296: PUSH1 0x20
00000298: DUP8
00000299: ADD
0000029a: PUSH2 0x02b2
0000029d: JUMP
0000029e: JUMPDEST
0000029f: PUSH1 0x1f
000002a1: ADD
000002a2: PUSH1 0x1f
000002a4: NOT
000002a5: AND
000002a6: SWAP2
000002a7: SWAP1
000002a8: SWAP2
000002a9: ADD
000002aa: PUSH1 0x40
000002ac: ADD
000002ad: SWAP3
000002ae: SWAP2
000002af: POP
000002b0: POP
000002b1: JUMP
000002b2: JUMPDEST
000002b3: PUSH1 0x00
000002b5: JUMPDEST
000002b6: DUP4
000002b7: DUP2
000002b8: LT
000002b9: ISZERO
000002ba: PUSH2 0x02cd
000002bd: JUMPI
000002be: DUP2
000002bf: DUP2
000002c0: ADD
000002c1: MLOAD
000002c2: DUP4
000002c3: DUP3
000002c4: ADD
000002c5: MSTORE
000002c6: PUSH1 0x20
000002c8: ADD
000002c9: PUSH2 0x02b5
000002cc: JUMP
000002cd: JUMPDEST
000002ce: DUP4
000002cf: DUP2
000002d0: GT
000002d1: ISZERO
000002d2: PUSH2 0x02dc
000002d5: JUMPI
000002d6: PUSH1 0x00
000002d8: DUP5
000002d9: DUP5
000002da: ADD
000002db: MSTORE
000002dc: JUMPDEST
000002dd: POP
000002de: POP
000002df: POP
000002e0: POP
000002e1: JUMP
000002e2: INVALID
000002e3: COINBASE
000002e4: PUSH5 0x6472657373
000002ea: GASPRICE
000002eb: KECCAK256
000002ec: PUSH13 0x6f772d6c6576656c2064656c65
000002fa: PUSH8 0x6174652063616c6c
00000303: KECCAK256
00000304: PUSH7 0x61696c6564a264
0000030c: PUSH10 0x706673582212207acb4b
00000317: CREATE2
00000318: DIFFICULTY
00000319: LOG1
0000031a: ISZERO
0000031b: UNKNOWN(0xE5)
0000031c: GT
0000031d: NUMBER
0000031e: RETURNDATASIZE
0000031f: PUSH2 0x6d31
00000322: SWAP9
00000323: PUSH3 0xbd74e5
00000327: UNKNOWN(0xEF)
00000328: UNKNOWN(0xEC)
00000329: ISZERO
0000032a: PUSH10 0x31a620d834fd45694664
00000335: PUSH20

Findings

validated = confirmed for call sinks; sink observed for others
Severity Category Tool Title Confidence Validated Confirmed Details
critical upgradeability detector Untrusted DELEGATECALL target reachable 70 no no
view
trace_id: 0xb5008d9857301259d83a6ea9a6c64d50a5c052573e094412e87246e547717f3f
call_targets: 0x90b6047da43a370a402fb1f88f4313faa34a923b
target_varies: no
classification: constant_target
validation_json
{
    "sink": "DELEGATECALL",
    "errors": 0,
    "status": "sink_reached",
    "attempts": 1,
    "trace_id": "0xb5008d9857301259d83a6ea9a6c64d50a5c052573e094412e87246e547717f3f",
    "confirmed": false,
    "trace_mode": "callTracer",
    "call_targets": [
        "0x90b6047da43a370a402fb1f88f4313faa34a923b"
    ],
    "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": 276,
            "opcode": "DELEGATECALL",
            "returndata_checked": null,
            "value_expression_category": "n/a",
            "target_expression_category": "computed"
        },
        {
            "pc": 437,
            "opcode": "DELEGATECALL",
            "returndata_checked": null,
            "value_expression_category": "n/a",
            "target_expression_category": "computed"
        }
    ],
    "guards_detected": [],
    "delegatecall_count": 2,
    "untrusted_delegatecall_count": 2
}
high other codex Offerer can never claim listing tokens after successful buyout 85 no
view
evidence_json
{
    "evidence": "`offer` and `surrenderTokens` transfer listing tokens into the contract, while the only listing token outflow is `withdrawTokens` (COUNTERED status). There is no function to transfer listing tokens to the offerer in SUCCESS.",
    "locations": [
        "contracts/Buyout.sol"
    ],
    "recommendation": "Add a post-success claim mechanism for the offerer (e.g., `claimListingTokens`) or transfer surrendered listing tokens directly to the offerer during `surrenderTokens`. Ensure the claim is only available in `Status.SUCCESS` and after any required settlement conditions.",
    "exploit_scenario": "After the buyout succeeds, holders call `surrenderTokens` and receive funding tokens. The listing tokens they surrender (plus the offerer\u2019s initial listing deposit) remain in the contract with no way for the offerer to claim them, so the offerer pays but never receives the purchased tokens."
}
medium upgradeability cast DELEGATECALL present 80 no
view
evidence_json
{
    "notes": "delegatecall enables execution in caller context; common in proxies/upgradeable patterns",
    "delegatecall_count": 2
}
medium other detector CREATE/CREATE2 reachable 45 no no
view
trace_id: 0x038ab95cf5729039f26127c53a1526021ded483f0a79694c88c853f661b43bf6
validation_json
{
    "sink": "CREATE",
    "errors": 0,
    "status": "unknown",
    "attempts": 1,
    "trace_id": "0x038ab95cf5729039f26127c53a1526021ded483f0a79694c88c853f661b43bf6",
    "confirmed": false,
    "trace_mode": "structLogs",
    "call_targets": null,
    "matched_probe": null,
    "target_varies": null,
    "classification": "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
{
    "create_count": 0,
    "create2_count": 1
}
low other cast Contract creation opcode present 60 no
view
evidence_json
{
    "notes": "runtime can deploy contracts dynamically via CREATE/CREATE2",
    "create_count": 0,
    "create2_count": 1
}