019bb004-7af0-71cd-ab6e-35bf05fc077a
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 |
|---|---|---|---|---|
| 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 |
{
"method": "etherscan+onchain",
"status": "confirmed",
"etherscan_hint": {
"source": "etherscan",
"etherscan": {
"proxy_flag": true,
"implementation": "0x90b6047da43a370a402fb1f88f4313faa34a923b"
}
},
"implementation": "0x90b6047da43a370a402fb1f88f4313faa34a923b",
"onchain_method": "beacon"
}
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.
{"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"]}]}
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
{
"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
}
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
| Severity | Category | Tool | Title | Confidence | Validated | Confirmed | Details |
|---|---|---|---|---|---|---|---|
| critical | upgradeability | detector | Untrusted DELEGATECALL target reachable | 70 | no | no |
viewtrace_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 | — |
viewevidence_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 | — |
viewevidence_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 |
viewtrace_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 | — |
viewevidence_json{
"notes": "runtime can deploy contracts dynamically via CREATE/CREATE2",
"create_count": 0,
"create2_count": 1
}
|