Findings
Informational6 findings
DeploySKNTQ: batched initialization calldata is not directly observable from script output
State
- New
Severity
- Severity: Informational
Submitted by
Optimum
Description
When
batchCallsexecution is skipped inforge script(e.g. due to precompile revert), the script logs each individual target, calldata, and value in a loop.This does not reflect the actual on-chain execution, which is a single call to
CallBatcher.batchCalls, and requires manual reconstruction of calldata, which is error-prone.As a result, the exact transaction that must be sent on-chain is not directly observable from the script output.
Recommendation
Log the fully encoded calldata for
CallBatcher.batchCalls(targets, data, values)so it can be submitted directly viacast send.Using CREATE2 in forge scripts can be front-run causing unexpected reverts
State
- New
Severity
- Severity: Informational
Submitted by
Optimum
Description
Foundry deployment scripts rely under the hood on the CREATE2 deployer at
0x4e59b44847b379578588920cA78FbF26c0B4956C, whose fallback function performs CREATE2 deployments.Because this is a public contract, a third party can front-run a deployment transaction and deploy a contract with the same salt and bytecode first. When the script’s transaction executes afterward, the CREATE2 call reverts, causing the deployment script to fail.
Foundry does not currently detect or gracefully handle this case, so the revert can be unexpected and hard to diagnose.
Impact
Deployment scripts using
new {salt: ...}may revert non-deterministically under adversarial or congested conditions, even when the script logic itself is correct.Note
While this can be worked around by avoiding
newand using a low-level call that tolerates pre-existing deployments, this is heavy-handed. At minimum, this behavior should be documented to raise awareness for users encountering unexplained deployment reverts.Avoid hardcoded CREATE2 deployer address magic constant
State
- New
Severity
- Severity: Informational
Submitted by
Optimum
Description
Some deployment scripts rely on the CREATE2 deployer at the fixed address
0x4e59b44847b379578588920cA78FbF26c0B4956C, embedding it directly as a literal in the code.Using this address as a magic constant is brittle and obscures where the value comes from, making scripts harder to reason about, audit, and maintain. It also tightly couples user code to Foundry internals without an explicit abstraction or reference.
Recommendation
Avoid hardcoding the CREATE2 deployer address as a literal in deployment scripts. Prefer a named constant, helper, or documented reference provided by Foundry.
See Foundry’s documentation on deterministic deployments for context:
https://getfoundry.sh/guides/deterministic-deployments-using-create2ERC4626AsynchronousUpgradeable: unused _transferIn function should be removed
State
- New
Severity
- Severity: Informational
Submitted by
Optimum
Description
The function
_transferIn(address from, uint256 assets)is defined inERC4626AsynchronousUpgradeablebut is never used by the contract.Deposits rely on the inherited ERC4626 implementation, and this override is not referenced anywhere in the codebase, making it dead code.
Recommendation
Remove
_transferInif it is not intended to be used, or explicitly document and integrate it into the deposit flow if customization is planned.ERC4626 inflation mitigation: isolate initial shares from vault-held assets
State
- New
Severity
- Severity: Informational
Submitted by
Optimum
Description
The initial shares minted for ERC4626 inflation-attack mitigation are currently sent to the
skntqcontract itself.
This is functionally correct because the vault already holds the corresponding token balance, and the accounting remains consistent.However, this design couples the “burned” shares with a contract that actively participates in vault accounting. While correct by construction, this reduces isolation between live vault state and permanently inaccessible shares.
Recommendation
Consider sending the initial shares to a burn address
0x000000000000000000000000000000000000dEaD
to fully isolate unspendable shares from the vault’s operational balance. This improves conceptual clarity and reduces the chance of confusion during audits or future changes.Note
This is a best-practice suggestion for clarity and isolation, not a correctness issue.
Storage layout inconsistency: SKNTQ uses linear storage while base contracts use ERC7201
State
- New
Severity
- Severity: Informational
Submitted by
Optimum
Description
The base contracts follow the ERC7201 namespaced storage pattern, while
SKNTQuses a traditional linear storage layout.While not incorrect, this inconsistency increases cognitive overhead and raises the risk of storage collisions or upgrade fragility in a system composed of multiple upgradeable components.
Recommendation
Consider migrating
SKNTQto the ERC7201 storage pattern to align with the base contracts and ensure consistent, collision-resistant storage layouts across the codebase.