019bb490-f341-7224-a82a-cad72e12cb5f
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 |
|---|---|---|---|---|
| 40053 | artifact.fetch | complete | 1 / 3 | 3 months ago |
| 40054 | proxy.resolve | complete | 1 / 3 | 3 months ago |
| 40055 | tool.cast_disasm | complete | 1 / 3 | 3 months ago |
| 40056 | analysis.bundle | complete | 1 / 3 | 3 months ago |
| 40057 | capability.graph | complete | 1 / 3 | 3 months ago |
| 40058 | detector.run | complete | 1 / 3 | 3 months ago |
| 40059 | validation.fork | complete | 1 / 3 | 3 months ago |
| 40213 | report.consolidate | complete | 1 / 6 | 3 months ago |
| 40214 | tool.slither | complete | 1 / 2 | 3 months ago |
{
"method": "minimal_proxy",
"status": "onchain_only",
"implementation": "0x9c3e06659f1c34f930ce97fcbce6e04ae88e535b",
"onchain_method": "minimal_proxy"
}
'forge clean' running (wd: /tmp/slither-q9vb76_3)
'forge config --json' running
'forge build --build-info --skip ./test/** ./script/** --force' running (wd: /tmp/slither-q9vb76_3)
BaseEscrow._ethTransfer(address,uint256) (contracts/BaseEscrow.sol#95-98) sends eth to arbitrary user
Dangerous calls:
- (success,None) = to.call{value: amount}() (contracts/BaseEscrow.sol#96)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#functions-that-send-ether-to-arbitrary-destinations
BaseEscrow.onlyAccessTokenHolder() (contracts/BaseEscrow.sol#63-66) uses a dangerous strict equality:
- _ACCESS_TOKEN.balanceOf(msg.sender) == 0 (contracts/BaseEscrow.sol#64)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#dangerous-strict-equalities
Reentrancy in EscrowDst._withdraw(bytes32,IBaseEscrow.Immutables) (contracts/EscrowDst.sol#77-85):
External calls:
- _uniTransfer(immutables.token.get(),immutables.maker.get(),immutables.amount) (contracts/EscrowDst.sol#82)
- (success,None) = to.call{value: amount}() (contracts/BaseEscrow.sol#96)
- _ethTransfer(msg.sender,immutables.safetyDeposit) (contracts/EscrowDst.sol#83)
- (success,None) = to.call{value: amount}() (contracts/BaseEscrow.sol#96)
Event emitted after the call(s):
- EscrowWithdrawal(secret) (contracts/EscrowDst.sol#84)
Reentrancy in EscrowDst.cancel(IBaseEscrow.Immutables) (contracts/EscrowDst.sol#62-71):
External calls:
- _uniTransfer(immutables.token.get(),immutables.taker.get(),immutables.amount) (contracts/EscrowDst.sol#68)
- (success,None) = to.call{value: amount}() (contracts/BaseEscrow.sol#96)
- _ethTransfer(msg.sender,immutables.safetyDeposit) (contracts/EscrowDst.sol#69)
- (success,None) = to.call{value: amount}() (contracts/BaseEscrow.sol#96)
Event emitted after the call(s):
- EscrowCancelled() (contracts/EscrowDst.sol#70)
Reentrancy in BaseEscrow.rescueFunds(address,uint256,IBaseEscrow.Immutables) (contracts/BaseEscrow.sol#71-79):
External calls:
- _uniTransfer(token,msg.sender,amount) (contracts/BaseEscrow.sol#77)
- (success,None) = to.call{value: amount}() (contracts/BaseEscrow.sol#96)
Event emitted after the call(s):
- FundsRescued(token,amount) (contracts/BaseEscrow.sol#78)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-3
BaseEscrow._keccakBytes32(bytes32) (contracts/BaseEscrow.sol#110-115) uses assembly
- INLINE ASM (contracts/BaseEscrow.sol#111-114)
ImmutablesLib.hash(IBaseEscrow.Immutables) (contracts/libraries/ImmutablesLib.sol#19-25) uses assembly
- INLINE ASM (contracts/libraries/ImmutablesLib.sol#20-24)
ImmutablesLib.hashMem(IBaseEscrow.Immutables) (contracts/libraries/ImmutablesLib.sol#32-36) uses assembly
- INLINE ASM (contracts/libraries/ImmutablesLib.sol#33-35)
ProxyHashLib.computeProxyBytecodeHash(address) (contracts/libraries/ProxyHashLib.sol#15-25) uses assembly
- INLINE ASM (contracts/libraries/ProxyHashLib.sol#16-24)
Create2.deploy(uint256,bytes32,bytes) (lib/openzeppelin-contracts/contracts/utils/Create2.sol#38-55) uses assembly
- INLINE ASM (lib/openzeppelin-contracts/contracts/utils/Create2.sol#45-47)
Create2.computeAddress(bytes32,bytes32,address) (lib/openzeppelin-contracts/contracts/utils/Create2.sol#69-90) uses assembly
- INLINE ASM (lib/openzeppelin-contracts/contracts/utils/Create2.sol#70-89)
LowLevelCall.callNoReturn(address,uint256,bytes) (lib/openzeppelin-contracts/contracts/utils/LowLevelCall.sol#19-23) uses assembly
- INLINE ASM (lib/openzeppelin-contracts/contracts/utils/LowLevelCall.sol#20-22)
LowLevelCall.callReturn64Bytes(address,uint256,bytes) (lib/openzeppelin-contracts/contracts/utils/LowLevelCall.sol#38-48) uses assembly
- INLINE ASM (lib/openzeppelin-contracts/contracts/utils/LowLevelCall.sol#43-47)
LowLevelCall.staticcallNoReturn(address,bytes) (lib/openzeppelin-contracts/contracts/utils/LowLevelCall.sol#51-55) uses assembly
- INLINE ASM (lib/openzeppelin-contracts/contracts/utils/LowLevelCall.sol#52-54)
LowLevelCall.staticcallReturn64Bytes(address,bytes) (lib/openzeppelin-contracts/contracts/utils/LowLevelCall.sol#62-71) uses assembly
- INLINE ASM (lib/openzeppelin-contracts/contracts/utils/LowLevelCall.sol#66-70)
LowLevelCall.delegatecallNoReturn(address,bytes) (lib/openzeppelin-contracts/contracts/utils/LowLevelCall.sol#74-78) uses assembly
- INLINE ASM (lib/openzeppelin-contracts/contracts/utils/LowLevelCall.sol#75-77)
LowLevelCall.delegatecallReturn64Bytes(address,bytes) (lib/openzeppelin-contracts/contracts/utils/LowLevelCall.sol#85-94) uses assembly
- INLINE ASM (lib/openzeppelin-contracts/contracts/utils/LowLevelCall.sol#89-93)
LowLevelCall.returnDataSize() (lib/openzeppelin-contracts/contracts/utils/LowLevelCall.sol#97-101) uses assembly
- INLINE ASM (lib/openzeppelin-contracts/contracts/utils/LowLevelCall.sol#98-100)
LowLevelCall.returnData() (lib/openzeppelin-contracts/contracts/utils/LowLevelCall.sol#104-111) uses assembly
- INLINE ASM (lib/openzeppelin-contracts/contracts/utils/LowLevelCall.sol#105-110)
LowLevelCall.bubbleRevert() (lib/openzeppelin-contracts/contracts/utils/LowLevelCall.sol#114-120) uses assembly
- INLINE ASM (lib/openzeppelin-contracts/contracts/utils/LowLevelCall.sol#115-119)
LowLevelCall.bubbleRevert(bytes) (lib/openzeppelin-contracts/contracts/utils/LowLevelCall.sol#122-126) uses assembly
- INLINE ASM (lib/openzeppelin-contracts/contracts/utils/LowLevelCall.sol#123-125)
RevertReasonForwarder.reRevert() (lib/solidity-utils/contracts/libraries/RevertReasonForwarder.sol#14-21) uses assembly
- INLINE ASM (lib/solidity-utils/contracts/libraries/RevertReasonForwarder.sol#16-20)
RevertReasonForwarder.reReason() (lib/solidity-utils/contracts/libraries/RevertReasonForwarder.sol#28-36) uses assembly
- INLINE ASM (lib/solidity-utils/contracts/libraries/RevertReasonForwarder.sol#29-35)
SafeERC20.safeBalanceOf(IERC20,address) (lib/solidity-utils/contracts/libraries/SafeERC20.sol#44-61) uses assembly
- INLINE ASM (lib/solidity-utils/contracts/libraries/SafeERC20.sol#49-60)
SafeERC20.safeTransferFrom(IERC20,address,address,uint256) (lib/solidity-utils/contracts/libraries/SafeERC20.sol#99-126) uses assembly
- INLINE ASM (lib/solidity-utils/contracts/libraries/SafeERC20.sol#107-124)
SafeERC20.safeTransferFromPermit2(IERC20,address,address,uint256) (lib/solidity-utils/contracts/libraries/SafeERC20.sol#138-161) uses assembly
- INLINE ASM (lib/solidity-utils/contracts/libraries/SafeERC20.sol#147-159)
SafeERC20.tryPermit(IERC20,address,address,bytes) (lib/solidity-utils/contracts/libraries/SafeERC20.sol#300-402) uses assembly
- INLINE ASM (lib/solidity-utils/contracts/libraries/SafeERC20.sol#306-401)
SafeERC20._makeCall(IERC20,bytes4,address,uint256) (lib/solidity-utils/contracts/libraries/SafeERC20.sol#414-437) uses assembly
- INLINE ASM (lib/solidity-utils/contracts/libraries/SafeERC20.sol#420-436)
SafeERC20.safeDeposit(IWETH,uint256) (lib/solidity-utils/contracts/libraries/SafeERC20.sol#444-456) uses assembly
- INLINE ASM (lib/solidity-utils/contracts/libraries/SafeERC20.sol#447-454)
SafeERC20.safeWithdraw(IWETH,uint256) (lib/solidity-utils/contracts/libraries/SafeERC20.sol#464-475) uses assembly
- INLINE ASM (lib/solidity-utils/contracts/libraries/SafeERC20.sol#466-474)
SafeERC20.safeWithdrawTo(IWETH,uint256,address) (lib/solidity-utils/contracts/libraries/SafeERC20.sol#484-495) uses assembly
- INLINE ASM (lib/solidity-utils/contracts/libraries/SafeERC20.sol#487-493)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#assembly-usage
4 different versions of Solidity are used:
- Version constraint 0.8.23 is used by:
-0.8.23 (contracts/BaseEscrow.sol#3)
-0.8.23 (contracts/Escrow.sol#3)
-0.8.23 (contracts/EscrowDst.sol#3)
- Version constraint ^0.8.0 is used by:
-^0.8.0 (contracts/interfaces/IBaseEscrow.sol#3)
-^0.8.0 (contracts/interfaces/IEscrow.sol#3)
-^0.8.0 (contracts/interfaces/IEscrowDst.sol#3)
-^0.8.0 (lib/solidity-utils/contracts/interfaces/IDaiLikePermit.sol#3)
-^0.8.0 (lib/solidity-utils/contracts/interfaces/IERC7597Permit.sol#3)
-^0.8.0 (lib/solidity-utils/contracts/interfaces/IPermit2.sol#3)
-^0.8.0 (lib/solidity-utils/contracts/interfaces/IWETH.sol#3)
-^0.8.0 (lib/solidity-utils/contracts/libraries/AddressLib.sol#3)
-^0.8.0 (lib/solidity-utils/contracts/libraries/RevertReasonForwarder.sol#3)
-^0.8.0 (lib/solidity-utils/contracts/libraries/SafeERC20.sol#3)
- Version constraint ^0.8.20 is used by:
-^0.8.20 (contracts/libraries/ImmutablesLib.sol#3)
-^0.8.20 (contracts/libraries/ProxyHashLib.sol#3)
-^0.8.20 (contracts/libraries/TimelocksLib.sol#3)
-^0.8.20 (lib/openzeppelin-contracts/contracts/utils/Create2.sol#4)
-^0.8.20 (lib/openzeppelin-contracts/contracts/utils/Errors.sol#4)
-^0.8.20 (lib/openzeppelin-contracts/contracts/utils/LowLevelCall.sol#4)
- Version constraint >=0.4.16 is used by:
->=0.4.16 (lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol#4)
->=0.4.16 (lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol#4)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#different-pragma-directives-are-used
Version constraint ^0.8.0 contains known severe issues (https://solidity.readthedocs.io/en/latest/bugs.html)
- FullInlinerNonExpressionSplitArgumentEvaluationOrder
- MissingSideEffectsOnSelectorAccess
- AbiReencodingHeadOverflowWithStaticArrayCleanup
- DirtyBytesArrayToStorage
- DataLocationChangeInInternalOverride
- NestedCalldataArrayAbiReencodingSizeValidation
- SignedImmutables
- ABIDecodeTwoDimensionalArrayMemory
- KeccakCaching.
It is used by:
- ^0.8.0 (contracts/interfaces/IBaseEscrow.sol#3)
- ^0.8.0 (contracts/interfaces/IEscrow.sol#3)
- ^0.8.0 (contracts/interfaces/IEscrowDst.sol#3)
- ^0.8.0 (lib/solidity-utils/contracts/interfaces/IDaiLikePermit.sol#3)
- ^0.8.0 (lib/solidity-utils/contracts/interfaces/IERC7597Permit.sol#3)
- ^0.8.0 (lib/solidity-utils/contracts/interfaces/IPermit2.sol#3)
- ^0.8.0 (lib/solidity-utils/contracts/interfaces/IWETH.sol#3)
- ^0.8.0 (lib/solidity-utils/contracts/libraries/AddressLib.sol#3)
- ^0.8.0 (lib/solidity-utils/contracts/libraries/RevertReasonForwarder.sol#3)
- ^0.8.0 (lib/solidity-utils/contracts/libraries/SafeERC20.sol#3)
Version constraint ^0.8.20 contains known severe issues (https://solidity.readthedocs.io/en/latest/bugs.html)
- VerbatimInvalidDeduplication
- FullInlinerNonExpressionSplitArgumentEvaluationOrder
- MissingSideEffectsOnSelectorAccess.
It is used by:
- ^0.8.20 (contracts/libraries/ImmutablesLib.sol#3)
- ^0.8.20 (contracts/libraries/ProxyHashLib.sol#3)
- ^0.8.20 (contracts/libraries/TimelocksLib.sol#3)
- ^0.8.20 (lib/openzeppelin-contracts/contracts/utils/Create2.sol#4)
- ^0.8.20 (lib/openzeppelin-contracts/contracts/utils/Errors.sol#4)
- ^0.8.20 (lib/openzeppelin-contracts/contracts/utils/LowLevelCall.sol#4)
Version constraint >=0.4.16 contains known severe issues (https://solidity.readthedocs.io/en/latest/bugs.html)
- DirtyBytesArrayToStorage
- ABIDecodeTwoDimensionalArrayMemory
- KeccakCaching
- EmptyByteArrayCopy
- DynamicArrayCleanup
- ImplicitConstructorCallvalueCheck
- TupleAssignmentMultiStackSlotComponents
- MemoryArrayCreationOverflow
- privateCanBeOverridden
- SignedArrayStorageCopy
- ABIEncoderV2StorageArrayWithMultiSlotElement
- DynamicConstructorArgumentsClippedABIV2
- UninitializedFunctionPointerInConstructor_0.4.x
- IncorrectEventSignatureInLibraries_0.4.x
- ExpExponentCleanup
- NestedArrayFunctionCallDecoder
- ZeroFunctionSelector.
It is used by:
- >=0.4.16 (lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol#4)
- >=0.4.16 (lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol#4)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-versions-of-solidity
Low level call in BaseEscrow._ethTransfer(address,uint256) (contracts/BaseEscrow.sol#95-98):
- (success,None) = to.call{value: amount}() (contracts/BaseEscrow.sol#96)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#low-level-calls
Variable BaseEscrow._ACCESS_TOKEN (contracts/BaseEscrow.sol#26) is not in mixedCase
Variable BaseEscrow.RESCUE_DELAY (contracts/BaseEscrow.sol#29) is not in mixedCase
Variable BaseEscrow.FACTORY (contracts/BaseEscrow.sol#31) is not in mixedCase
Variable Escrow.PROXY_BYTECODE_HASH (contracts/Escrow.sol#22) is not in mixedCase
Function IBaseEscrow.RESCUE_DELAY() (contracts/interfaces/IBaseEscrow.sol#52) is not in mixedCase
Function IBaseEscrow.FACTORY() (contracts/interfaces/IBaseEscrow.sol#54) is not in mixedCase
Function IEscrow.PROXY_BYTECODE_HASH() (contracts/interfaces/IEscrow.sol#14) is not in mixedCase
Function IERC20Permit.DOMAIN_SEPARATOR() (lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol#89) is not in mixedCase
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#conformance-to-solidity-naming-conventions
ProxyHashLib.computeProxyBytecodeHash(address) (contracts/libraries/ProxyHashLib.sol#15-25) uses literals with too many digits:
- mstore(uint256,uint256)(0x00,implementation >> 0x88 | 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000) (contracts/libraries/ProxyHashLib.sol#22)
TimelocksLib.slitherConstructorConstantVariables() (contracts/libraries/TimelocksLib.sol#34-81) uses literals with too many digits:
- _DEPLOYED_AT_MASK = 0xffffffff00000000000000000000000000000000000000000000000000000000 (contracts/libraries/TimelocksLib.sol#45)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#too-many-digits
. analyzed (21 contracts with 100 detectors), 46 result(s) found
{
"solc": {
"status": "ok",
"use_rc": 0,
"version": "0.8.23",
"strategy": "solc-select",
"solc_path": "/var/www/tripwire/.venv/bin/solc",
"install_rc": 0,
"use_stderr": null,
"use_stdout": "Switched global version to 0.8.23",
"install_stderr": null,
"install_stdout": "Version '0.8.23' is already installed, skipping..."
},
"solc_args": "--base-path /tmp/slither-q9vb76_3 --include-path /tmp/slither-q9vb76_3/lib --include-path /tmp/slither-q9vb76_3/lib/openzeppelin-contracts --include-path /tmp/slither-q9vb76_3/lib/solidity-utils --allow-paths /tmp/slither-q9vb76_3,/tmp/slither-q9vb76_3/lib,/tmp/slither-q9vb76_3/lib/openzeppelin-contracts,/tmp/slither-q9vb76_3/lib/solidity-utils,/tmp/slither-q9vb76_3/src",
"remappings": [
"@1inch/limit-order-protocol-contract/=lib/limit-order-protocol/",
"@1inch/limit-order-settlement/=lib/limit-order-settlement/",
"@1inch/solidity-utils/=lib/solidity-utils/",
"solidity-utils/=lib/solidity-utils/",
"limit-order-protocol/=lib/limit-order-protocol/",
"limit-order-settlement/=lib/limit-order-settlement/",
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"ds-test/=lib/forge-std/lib/ds-test/src/",
"erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
"forge-std/=lib/forge-std/src/",
"murky/=lib/murky/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/"
],
"source_files": [
"contracts/EscrowDst.sol",
"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol",
"lib/solidity-utils/contracts/libraries/SafeERC20.sol",
"lib/solidity-utils/contracts/libraries/AddressLib.sol",
"contracts/libraries/TimelocksLib.sol",
"contracts/interfaces/IEscrowDst.sol",
"contracts/BaseEscrow.sol",
"contracts/Escrow.sol",
"lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol",
"lib/solidity-utils/contracts/interfaces/IDaiLikePermit.sol",
"lib/solidity-utils/contracts/interfaces/IPermit2.sol",
"lib/solidity-utils/contracts/interfaces/IERC7597Permit.sol",
"lib/solidity-utils/contracts/interfaces/IWETH.sol",
"lib/solidity-utils/contracts/libraries/RevertReasonForwarder.sol",
"contracts/interfaces/IEscrow.sol",
"contracts/libraries/ImmutablesLib.sol",
"contracts/interfaces/IBaseEscrow.sol",
"lib/openzeppelin-contracts/contracts/utils/Create2.sol",
"contracts/libraries/ProxyHashLib.sol",
"lib/openzeppelin-contracts/contracts/utils/Errors.sol"
],
"contract_count": 0,
"contract_names": [],
"detector_count": 46,
"workspace_hash": "44ede1c555649ec288338df4ae39eac737de512f62ed643327b56c09fdb33171",
"duration_seconds": 0.8133449554443359,
"solc_version_requested": "0.8.23"
}
{"no_findings":true,"summary":"No meaningful exploitable issues found in the implementation; core escrow logic is stateless and validates immutables against the CREATE2-derived address.","findings":[]}
OpenAI Codex v0.77.0 (research preview)
--------
workdir: /tmp/codex-85dg_r1a
model: gpt-5.2-codex
provider: openai
approval: never
sandbox: read-only
reasoning effort: high
reasoning summaries: auto
session id: 019bb49b-03b9-7da2-bd4c-307c9e59b601
--------
user
Context: The user requested the proxy at 0x39c84b27db3219b876e6f09ddb4140bc67eecb69.
Audit the implementation at 0x9c3e06659f1c34f930ce97fcbce6e04ae88e535b.
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
**Choosing method to read AUDIT_BUNDLE**
exec
/bin/bash -lc ls in /tmp/codex-85dg_r1a succeeded in 5ms:
AUDIT_BUNDLE.txt
codex-output-schema.json
contracts
lib
exec
/bin/bash -lc 'cat AUDIT_BUNDLE.txt' in /tmp/codex-85dg_r1a succeeded in 7ms:
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/BaseEscrow.sol
================================================================================
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
import { IERC20 } from "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
import { AddressLib, Address } from "solidity-utils/contracts/libraries/AddressLib.sol";
import { SafeERC20 } from "solidity-utils/contracts/libraries/SafeERC20.sol";
import { ImmutablesLib } from "./libraries/ImmutablesLib.sol";
import { Timelocks, TimelocksLib } from "./libraries/TimelocksLib.sol";
import { IBaseEscrow } from "./interfaces/IBaseEscrow.sol";
/**
thinking
**Analyzing potential escrow contract vulnerabilities**
I'm auditing an escrow contract focusing on reentrancy risks, access controls, and token handling. I’m carefully inspecting how withdrawals, rescues, and cancellations work without state changes, the role of immutables in validating the contract’s address, and how repeated or reentrant calls might drain funds when unexpected tokens are sent or specific token behaviors like fee-on-transfer occur. There are nuanced considerations around factory deployment, minimal proxies, and timing of emergency rescues that influence contract safety.
thinking
**Evaluating immutables and proxy patterns**
I'm carefully verifying how immutable values, calldata handling, and proxy deployment interact, especially focusing on Create2 address validation and assumptions about encoded timelocks. I’m also checking the contract’s reliance on external token calls and potential edge cases in access token behavior, but overall, I find no critical issues in the stateless, immutable design and typical proxy usage.
codex
{"no_findings":true,"summary":"No meaningful exploitable issues found in the implementation; core escrow logic is stateless and validates immutables against the CREATE2-derived address.","findings":[]}
tokens used
16,955
{
"codex": {
"ran_at": "2026-01-12T23:49:32.035921+00:00",
"returncode": 0
},
"project": {
"mode": "source",
"file_count": 20,
"import_count": 24,
"first_party_contracts_count": 9
},
"summary": "No meaningful exploitable issues found in the implementation; core escrow logic is stateless and validates immutables against the CREATE2-derived address.",
"raw_final": {
"summary": "No meaningful exploitable issues found in the implementation; core escrow logic is stateless and validates immutables against the CREATE2-derived address.",
"findings": [],
"no_findings": true
},
"no_findings": true,
"proxy_context": {
"proxy_run_id": "019bb490-f341-7224-a82a-cad72e12cb5f",
"proxy_address": "0x39c84b27db3219b876e6f09ddb4140bc67eecb69",
"implementation_run_id": "019bb491-4432-70a1-a118-169deb6eada5",
"implementation_address": "0x9c3e06659f1c34f930ce97fcbce6e04ae88e535b"
},
"schema_version": 1
}
00000000: CALLDATASIZE 00000001: RETURNDATASIZE 00000002: RETURNDATASIZE 00000003: CALLDATACOPY 00000004: RETURNDATASIZE 00000005: RETURNDATASIZE 00000006: RETURNDATASIZE 00000007: CALLDATASIZE 00000008: RETURNDATASIZE 00000009: PUSH20 0x9c3e06659f1c34f930ce97fcbce6e04ae88e535b 0000001e: GAS 0000001f: DELEGATECALL 00000020: RETURNDATASIZE 00000021: DUP3 00000022: DUP1 00000023: RETURNDATACOPY 00000024: SWAP1 00000025: RETURNDATASIZE 00000026: SWAP2 00000027: PUSH1 0x2b 00000029: JUMPI 0000002a: REVERT 0000002b: JUMPDEST 0000002c: RETURN
| Severity | Category | Tool | Title | Confidence | Validated | Confirmed | Details |
|---|---|---|---|---|---|---|---|
| critical | upgradeability | detector | Untrusted DELEGATECALL target reachable | 70 | no | no |
viewtrace_id: 0x2609cbcd3b95c0461bbabb388e66bfca23b378c25b10be6a5dfdb1ffc186b337
call_targets:
0x9c3e06659f1c34f930ce97fcbce6e04ae88e535b
target_varies:
no
classification:
constant_target
validation_json{
"sink": "DELEGATECALL",
"errors": 0,
"status": "sink_reached",
"attempts": 1,
"trace_id": "0x2609cbcd3b95c0461bbabb388e66bfca23b378c25b10be6a5dfdb1ffc186b337",
"confirmed": false,
"trace_mode": "callTracer",
"call_targets": [
"0x9c3e06659f1c34f930ce97fcbce6e04ae88e535b"
],
"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": 31,
"opcode": "DELEGATECALL",
"returndata_checked": null,
"value_expression_category": "n/a",
"target_expression_category": "computed"
}
],
"guards_detected": [],
"delegatecall_count": 1,
"untrusted_delegatecall_count": 1
}
|
| high | other | slither | BaseEscrow._ethTransfer(address,uint256) (contracts/BaseEscrow.sol#95-98) sends eth to arbitrary user | 85 | no | — |
viewevidence_json{
"impact": "High",
"detector": "arbitrary-send-eth",
"elements": [
{
"name": "_ethTransfer",
"type": "function",
"source_mapping": {
"lines": [
95,
96,
97,
98
],
"start": 3025,
"length": 180,
"ending_column": 6,
"is_dependency": false,
"filename_short": "contracts/BaseEscrow.sol",
"starting_column": 5,
"filename_absolute": "/tmp/slither-q9vb76_3/contracts/BaseEscrow.sol",
"filename_relative": "contracts/BaseEscrow.sol"
},
"type_specific_fields": {
"parent": {
"name": "BaseEscrow",
"type": "contract",
"source_mapping": {
"lines": [
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49,
50,
51,
52,
53,
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70,
71,
72,
73,
74,
75,
76,
77,
78,
79,
80,
81,
82,
83,
84,
85,
86,
87,
88,
89,
90,
91,
92,
93,
94,
95,
96,
97,
98,
99,
100,
101,
102,
103,
104,
105,
106,
107,
108,
109,
110,
111,
112,
113,
114,
115,
116
],
"start": 761,
"length": 3016,
"ending_column": 2,
"is_dependency": false,
"filename_short": "contracts/BaseEscrow.sol",
"starting_column": 1,
"filename_absolute": "/tmp/slither-q9vb76_3/contracts/BaseEscrow.sol",
"filename_relative": "contracts/BaseEscrow.sol"
}
},
"signature": "_ethTransfer(address,uint256)"
}
},
{
"name": "(success,None) = to.call{value: amount}()",
"type": "node",
"source_mapping": {
"lines": [
96
],
"start": 3094,
"length": 46,
"ending_column": 55,
"is_dependency": false,
"filename_short": "contracts/BaseEscrow.sol",
"starting_column": 9,
"filename_absolute": "/tmp/slither-q9vb76_3/contracts/BaseEscrow.sol",
"filename_relative": "contracts/BaseEscrow.sol"
},
"type_specific_fields": {
"parent": {
"name": "_ethTransfer",
"type": "function",
"source_mapping": {
"lines": [
95,
96,
97,
98
],
"start": 3025,
"length": 180,
"ending_column": 6,
"is_dependency": false,
"filename_short": "contracts/BaseEscrow.sol",
"starting_column": 5,
"filename_absolute": "/tmp/slither-q9vb76_3/contracts/BaseEscrow.sol",
"filename_relative": "contracts/BaseEscrow.sol"
},
"type_specific_fields": {
"parent": {
"name": "BaseEscrow",
"type": "contract",
"source_mapping": {
"lines": [
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49,
50,
51,
52,
53,
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70,
71,
72,
73,
74,
75,
76,
77,
78,
79,
80,
81,
82,
83,
84,
85,
86,
87,
88,
89,
90,
91,
92,
93,
94,
95,
96,
97,
98,
99,
100,
101,
102,
103,
104,
105,
106,
107,
108,
109,
110,
111,
112,
113,
114,
115,
116
],
"start": 761,
"length": 3016,
"ending_column": 2,
"is_dependency": false,
"filename_short": "contracts/BaseEscrow.sol",
"starting_column": 1,
"filename_absolute": "/tmp/slither-q9vb76_3/contracts/BaseEscrow.sol",
"filename_relative": "contracts/BaseEscrow.sol"
}
},
"signature": "_ethTransfer(address,uint256)"
}
}
}
}
],
"locations": [
{
"file": "contracts/BaseEscrow.sol",
"name": "_ethTransfer",
"type": "function",
"lines": [
95,
96,
97,
98
]
},
{
"file": "contracts/BaseEscrow.sol",
"name": "(success,None) = to.call{value: amount}()",
"type": "node",
"lines": [
96
]
}
],
"description": "BaseEscrow._ethTransfer(address,uint256) (contracts/BaseEscrow.sol#95-98) sends eth to arbitrary user\n\tDangerous calls:\n\t- (success,None) = to.call{value: amount}() (contracts/BaseEscrow.sol#96)"
}
|
| medium | upgradeability | cast | DELEGATECALL present | 80 | no | — |
viewevidence_json{
"notes": "delegatecall enables execution in caller context; common in proxies/upgradeable patterns",
"delegatecall_count": 1
}
|