Nashpoint engaged Guardian to review the security of their Nashpoint Contract Review. From the 11th of February 2026 to the 19th of February 2026, a team of 2 auditors reviewed the source code in scope.
- Published
- Review window
- February 11 to 19, 2026
- Rounds
- Main Review, Remediation Review
- Language
- Solidity
- Chains
- Arbitrum
- Sector
- Real-world assets, Yield and vaults
- 0 Critical
- 1 High
- 2 Medium
- 4 Low
- 14 Informational
Scope
Overview
Nashpoint engaged Guardian to review the security of their Nashpoint Contract Review. From the 11th of February 2026 to the 19th of February 2026, a team of 2 auditors reviewed the source code in scope.
Findings 21
Main Review
16 findings-
H-01 High Event Verification DoS Due To readList Cap DoS Resolved
Description
Proof of concept: PoC
The
RLPReaderlibrary imposes a hard limit of 32 elements when reading RLP lists and does not support lists exceeding this size. ReferenceConsequently, any transaction that emits more than 32 logs cannot be verified by the current event verification logic, despite being valid.
Note that although
DigiFT’s event verification has the same limitation, it is unlikely to result in a DoS, as theSubRedManagementcontract can emit only oneSettleSubscriberand oneSettleRedemptionevent per settlement batch, since investor addresses and quantities included as arrays within the event.However, this assumption does not hold for
WisdomTree. Since each transfer or mint emits an individual event, a single dividend batch mint can realistically result in more than 32 event logs, which cannot be verified.Recommendation
Do not rely on Optimism’s
RLPReaderlibrary for verifyingWisdomTreetransfers and dividend events, especially when batch operations are expected. Consider usingOpenZeppelin’s RLP library, which does not impose a fixed limit on RLP list lengthHowever, it is important to review and account for the limitations and assumptions of the
OpenZeppelinimplementation, as documented in its source code.Resolution
Nashpoint Team: The issue was resolved in commit 56cc082.
-
M-01 Medium claimableRedeemRequest Dilutes Dividends Logical Error Resolved
Description
When Nodes invest in
WisdomTree, all WT fund tokens are held by theWTAdaptercontract, and Nodes receive correspondingWTAdaptershares as receipts. WhenWisdomTreemints dividends, it mints all dividends to the adapter contract, which are later distributed to participating Nodes on a pro-rata basis.Dividend distribution is determined based on a Node's
WTAdapterreceipt token balance,pendingRedeemRequest,claimableRedeemRequest, andmaxMint. However, includingclaimableRedeemRequestin this calculation results in an incorrect distribution, as the adapter contract never receives dividends corresponding to that amount.The reason is that the
WTAdaptercontract does not hold the fund tokens corresponding to theclaimableRedeemRequestportion in custody at the time of theWisdomTreedividend minting.Assuming that WT dividends are minted after deposit and redeem settlements (as in the test cases), the token custody state for the weight calculation parameters is as follows:
balanceOf(node):WTAdapterreceipt tokens are held by the Node, the corresponding WT fund tokens are held by the adapter contract.pendingRedeemRequest:WTAdapterreceipt tokens are held by the adapter contract, and the corresponding WT fund tokens are also held by
the adapter contract.
maxMint:WTAdapterreceipt tokens have not yet been minted; however, the corresponding WT fund tokens are transferred to the adapter
contract prior to
settleDepositand are held by the adapter contract.claimableRedeemRequest:WTAdapterreceipt tokens have not yet been burned and remain in the adapter contract. However, the
corresponding WT fund tokens are already transferred to the WT receiver wallet during
forwardRequests, well before settlement, and are therefore held by the WT receiver wallet. Not the adapter contract.As a result, when the
WisdomTreeprotocol mints dividends based on the amount of WT fund tokens custodied by the adapter, dividends corresponding to theclaimableRedeemRequestportion are never minted as the corresponding WT fund tokens are not in the adapter at the dividend minting time.Additionally, the
pendingRedeemRequestandmaxMintvalues can also introduce inconsistencies depending on the timing of the dividend mint. The highest-risk period is between theforwardRequestscall and thesettleDeposit / settleRedeemcalls. If dividends are minted during this window, larger miscalculations can occur, as the WT fund tokens corresponding topendingRedeemRequestare are custodied in the WT receiver wallet, and the adapter would not receive dividends for that portion either.Risks related to
pendingRedeemRequestandmaxMintcan be mitigated by managers through correct timing of request forwarding. However, includingclaimableRedeemRequestresults in incorrect distribution regardless of when dividends are minted.Another issue with including
claimableRedeemRequestis that the asset-to-share ratio is locked at settlement time. A Node can submit a redemption request before dividend distribution, lock in the pre-dividend asset price, and then withdraw after dividends are distributed. As a result, the Node avoids the post-dividend price decrease and also receive a portion of the dividend, leading to an unfair advantage.Recommendation
Do not include
claimableRedeemRequestin the dividend weight calculation. ForpendingRedeemRequestandmaxMint, ensure that managers carefully time the request forwarding process and document the associated risks.Resolution
Nashpoint Team: The issue was resolved in commit ab25b7d.
-
M-02 Medium No Ex-Dividend Enforcement At Node Level MEV Partially resolved
Description
After the
ex-dividend date, the fund's oracle price drops to reflect the upcomingdividend distribution. In traditional finance, investors who purchase shares after the ex-dividend date are not entitled to the dividend. However, the Node has no mechanism to enforce this cutoff.A user can deposit into the Node after the ex-dividend date but before the actual dividend distribution. When
settleDividendexecutes and mints additional adapter shares to the Node, theNode's underlying valueincreases (moreadapter shares x post ex-div price).After
cacheTotalAssetsrefreshes viastartRebalance()orupdateTotalAssets(), thedepositor'ssharesreflect this increased value, allowing them to capture dividends they were not entitled to.The team has indicated they plan to time operations at the Node level to prevent this, and one possible approach is letting
isCacheValid()expire between the ex-dividend date and distribution, which blocks deposits viamaxDeposit()returning 0.However, this is only feasible for short windows and relies on deliberately skipping rebalances, which also blocks redemption processing, fee payments, and all rebalance-dependent operations.
Recommendation
Document the requirement to block Node deposits between the ex-dividend date and dividend distribution. Consider extending
rebalanceCooldownaround the ex-dividend date, or introducing a deposit pause mechanism (at the Node level).Resolution
Nashpoint Team: The issue was resolved in commit f0ac6d8.
-
L-01 Low Unsafe Cast When Setting lastFundPrice Validation Resolved
Description
AdapterBase.initializeandforceUpdateLastPricefunctions reads thelatestRoundDataand blindly casts theint256answer touint256when setting thelastFundPrice.Previously, these actions used the
getPrice, which was already returninguint256. If the oracle ever emits a negative value (e.g., stale feed or sentinel), the cast wraps to a huge positive number, corruptinglastFundPrice.Recommendation
Ensure the returned answer > 0 before casting and revert with
BadPriceOracleerror otherwise.Resolution
Nashpoint Team: The issue was resolved in commit 3f96145.
-
L-02 Low Fund Token Clawback Breaks Adapter Redemptions Compatibility Acknowledged
Description
The
WisdomTreefund token implements a clawback function allowing itsregistrarto forcibly transfer tokens from any holder, including theWTAdapter, for "regulatory compliance, legal orders, emergency asset recovery, correcting erroneous transactions".If fund shares are clawed back from the adapter,
_fundRedeemwill revert when attempting tosafeTransferfund tokens it no longer holds, bricking all pending and future redemptions.The adapter has no mechanism to handle this case. Nodes would hold adapter shares they cannot redeem, and
forwardRequestswould continue attempting to transfer fund tokens that don't exist.Recommendation
Consider implementing a function that allows the manager to re-sync adapter state with its actual fund token balance after a clawback event.
Resolution
Nashpoint Team: Acknowledged.
-
L-03 Low Strict Equality And BalanceOf Could Cause DoS Validation Acknowledged
Description
For the
settleDividendcall to be successful,totalWeightmust be strictly equal tototalSupply +totalMaxMint.totalWeightis calculated using the balances of each participating node.This means that the manager must include all nodes that have the
WTAdapteras a component when calling the function, even if a node holds only a small amount ofWTAdaptershares, in order to satisfy thetotalSupplycheck.While all nodes must be whitelisted to participate and this does not pose an immediate threat, it may introduce multiple issues in future development: 1.
totalSupplycheck: As the number of whitelisted nodes grows, the manager may be unable to supply all nodes to the function due to gas limitations. 2.balanceOf(node)usage: Current routers do not transferWTAdaptershares out of the node.However, if future development introduces new router types that allow investing component shares (e.g., via looping mechanisms) or allow transfers, dividend settlement would become impossible, as relying on
balanceOf(node)would cause the check to fail.Recommendation
Be aware of these risks when adding nodes to whitelist and during future development processes.
Resolution
Nashpoint Team: Acknowledged.
-
I-01 Informational Event Verifier Assumes Standard ERC20 Compliance Warning Acknowledged
Description
The
TransferEventVerifierassumes the fund token complies with theERC20standard and emits a Transfer event where the from and to parameters are indexed and the amount parameter is non-indexed.If the underlying fund does not emit standard-compliant events with indexed parameters, event verification will fail.
Although the expected fund contracts are not currently available, it is important to ensure that they emit events with two indexed address parameters and one non-indexed
uint256amount parameter.Recommendation
Ensure that all events emitted by the
WisdomTreefunds areERC20-standard compliant.Resolution
Nashpoint Team: Acknowledged.
-
I-02 Informational DuplicateComponent Error Is Dead Code Superfluous Code Resolved
Description
ErrorsLib.DuplicateComponentis declared but never referenced anywhere in the codebase. It was previously used by_validateNoDuplicateComponents, which has since been removed. The error definition should have been cleaned up alongside that removal.Recommendation
Remove the unused
DuplicateComponenterror fromErrorsLib.Resolution
Nashpoint Team: The issue was resolved in commit 9028b37.
-
I-03 Informational _getBlockHash Can Migrate To OZ Blockhash Lib Trust Assumptions Resolved
Description
The
_getBlockHashfunction inEventVerifierBaserelies on thesetBlockHashadmin function to handle blocks older than 256, which may introduce risks as it allows the registry owner to set arbitrary block hashes.EIP-2935provides trustless access to the last 8,191 block hashes (rather than 256 limit).The TODO in
_getBlockHashstates that migration toBlockhash.solwill be done whenOpenZeppelinv5.6.0 is stable. However,EIP-2935was a part of the Pectra upgrade in 2025, whereOpenZeppelinv5.4.0 shipped a Blockhash library that already allows this functionality.Recommendation
Upgrade to
OpenZeppelinContracts v5.4.0+ and replace_getBlockHashwith the Blockhash library.https://github.com/OpenZeppelin/openzeppelin-contracts/releases/tag/v5.4.0
Resolution
Nashpoint Team: The issue was resolved in commit 8634234.
-
I-04 Informational Failed settleRedeem Temporarily Blocks Dividends Unexpected Behavior Acknowledged
Description
settleDividendrequires bothpendingDepositRequest == 0andpendingRedeemRequest == 0. IfsettleRedeemreverts due to thesettlementDeviationcheck,pendingRedeemRequestremains non-zero, blocking dividend distribution until the redemption is successfully settled.This means any
settlement price deviationcan delay dividend distribution to all nodes, even though dividends are unrelated to the redemption flow.Recommendation
Document this case. Alternatively, consider whether
settleDividendneeds thependingRedeemRequest == 0check, or if dividends could safely be distributed while a redemption is pending.Resolution
Nashpoint Team: Acknowledged.
-
I-05 Informational Small Dividends Can Round To Zero Rounding Acknowledged
Description
In
settleDividend, each node's share is calculated asdividends * weights[i] / totalWeight, which rounds down.When dividends is small relative to
totalWeight(more likely when the fund token has low decimals), all nodes except the last may receive zero. The dust correction assigns the entire remainder to the last node in the array (determined by the manager).Recommendation
Consider refactoring the dividend distribution to handle cases where any node's calculated share rounds to zero. Additionally, document that fund tokens with low decimals increase the likelihood of rounding issues in dividend distribution.
Resolution
Nashpoint Team: Acknowledged.
-
I-06 Informational De-Whitelisted Nodes Still Receive Dividends Access Control Acknowledged
Description
settleDividenddoes not checknodeWhitelisted[nodes[i]]before distributing. The invarianttotalWeight == totalSupply() + totalMaxMintforces inclusion of every address holding shares, so a de-whitelisted node that still has a share balance continues receiving minted dividend shares with no way to opt it out (asrequestRedeemenforces whitelisted nodes only).Recommendation
No changes needed if this is intentional or expected behavior. Otherwise, consider validating whitelist status within the
settleDividendloop, or providing a mechanism to exclude de-whitelisted nodes from dividend distribution.Resolution
Nashpoint Team: Acknowledged.
-
I-07 Informational New Deposits Can Capture Unearned Dividends Warning Acknowledged
Description
settleDividenddistributes shares based off the share weight of each node at the time of distribution. A node that deposits and settles shortly before a dividend distribution receives the same per-share dividend as nodes that have held shares for the full accrual period.The
totalWeight == totalSupply() + totalMaxMintinvariant prevents the manager from excluding a node from dividend distribution, so there is no mechanism to differentiate between long held and recently acquired shares.The team has acknowledged this and plans to handle it by timing
deposit/redeem requestsaround dividend payouts (processing new deposits only after dividends are distributed). However, this relies entirely on off-chain coordination.Recommendation
Document the requirement to time deposits around dividend distributions. Consider if a deposit cooldown period before dividend eligibility would help reduce the need for manual timing.
Resolution
Nashpoint Team: Acknowledged.
-
I-08 Informational Settlement Type Relies On OffChain Parsing Trust Assumptions Acknowledged
Description
For both the deposit settlement flow and the dividend settlement flow, the verified events are identical Transfer events emitted with the from address set to
address(0), and verification is performed usingTransferEventVerifier.OnchainArgs(fund, address(0)).Consequently,
WTAdapterrelies on off-chain event parsing to distinguish whether a Transfer log represents a deposit mint or a dividend mint. A misclassified log (e.g., a dividend mint as a deposit, or vice versa) causes the adapter to run the wrong settlement branch, which would revert.Recommendation
Ensure that the off-chain indexer can reliably distinguish whether a Transfer log represents a dividend settlement or a deposit settlement.
Resolution
Nashpoint Team: Acknowledged.
-
I-09 Informational settleDividend Should Use mulDiv For Consistency Best Practices Resolved
Description
settleDividenduses rawdividends * weights[i] / totalWeightfor pro-rata calculation, whilesettleDepositandsettleRedeeminAdapterBaseuseOpenZeppelin'sMath.mulDivfor equivalent calculations.Although overflow is practically unreachable with realistic token supplies, the inconsistency could become a concern if the
WTAdaptersupport tokens with unusual denominations.Recommendation
Use
Math.mulDiv(dividends, weights[i], totalWeight)for consistency with the rest of the codebase.Resolution
Nashpoint Team: The issue was resolved in commit e52ee94.
-
I-10 Informational Implementations Can Be Initialized Best Practices Resolved
Description
Adapters use the Beacon proxy pattern and deployed through factory contracts. All of these proxies are atomically initialized at the time of deployment. However, the implementation contract stay uninitialized and can be initialized by anyone.
Adapters use the Beacon proxy pattern and are deployed through factory contracts. All of these proxies are atomically initialized at the time of deployment. However, the implementation contract remains uninitialized and can be initialized by anyone.
While this does not affect the state of the Beacon proxies or directly affect proxy behavior, it alters the implementation’s storage. Initializing the implementation contract should be disabled as a best practice.
Recommendation
Consider adding
_disableInitializersin implementation contract constructors.Resolution
Nashpoint Team: The issue was resolved in commit 616e6f0.
Remediation Review
5 findings-
L-01 Low Stale Price Arbitrage During Price Freeze MEV Acknowledged
Description
During the price freeze window,
convertToSharesandconvertToAssetsboth use the cachedlastFundPrice. If the underlying NAV moves for non-dividend reasons (i.e., market movements), a discrepancy between the frozen price and real NAV creates arbitrage opportunities.Redeemers can exit at the stale high price when real value is lower, extracting value from remaining holders. Conversely, depositors benefit if real value rises above the frozen price.
Recommendation
Be aware of this behavior. If this is an accepted trade-off, ensure that the freeze window is as short as possible and monitor for sudden NAV changes during the freeze.
If an unexpected NAV change occurs during the freeze, consider using forced price updates to reflect the real value at the node level.
If this is not acceptable, reconsider the price freeze approach or explore alternatives that do not expose the protocol to stale price arbitrage during the freeze window.
Resolution
Nashpoint Team: Acknowledged.
-
I-01 Informational Operational Limitations Related To Price Freeze Warning Acknowledged
Description
A temporary price-freezing feature is added to protect against post–ex-dividend price drops. For the price to be frozen, there must be no pending forwarded requests, meaning all deposits and redemptions must be settled before the freeze.
Assuming there are 2 days between the ex-dividend date and the dividend distribution on the
WisdomTreeprotocol, and dividends are distributed on day 30:- Dividend distribution date: Day 30
- Ex-dividend date: Day 28
- Price freeze must occur just before the ex-dividend date (assumed earlier that day): Day 28
- All settlements must be completed on or before: Day 28
- Given that settlements also take time (assumed 2–3 days), the latest
forwardRequestscall should
occur around: ~Day 25
While the price freeze period itself lasts only 2 days, the actual window between the latest request forwarding before the freeze and the first request forwarding after unfreeze could be up to 5 days, or potentially even a week (Note that these figures are illustrative only, and the actual values depend on
WisdomTree’s configuration).Managers should be aware of these limitations and stop forwarding requests even before the expected freeze day. Forwarding requests a few days before the expected freeze date may prevent the price from being frozen if
WisdomTreecannot complete settlements within that period.Recommendation
Consider documenting these behaviors for both managers and users.
Resolution
Nashpoint Team: Acknowledged.
-
I-02 Informational Price Update May Fail Due To Freeze Warning Acknowledged
Description
The fixes introduce a price-freezing mechanism with a maximum freeze period of 7 days. Once the freeze ends, the first required action is to refresh the price.
However, depending on the length of the freeze period, the price change over this window is more likely to exceed the deviation threshold compared to regular daily price updates.
As a result, regular
updateLastPricemay revert withPriceNotInRangeerror, forcing the registry owner to useforceUpdateLastPrice.Recommendation
Be aware of this behavior when using the price freeze mechanism.
Resolution
Nashpoint Team: Acknowledged.
-
I-03 Informational forceUpdateLastPrice Bypasses Freeze Informational Acknowledged
Description
The
forceUpdateLastPricefunction bypassespriceFreezeActive, similar to how it bypasses deviation checks. No change is needed if this behavior is intentional. This issue is intended only to flag the bypass and confirm that it is expected.The
forceUpdateLastPricecan be used in its current form when required if a situation mentioned in L-01 occurs.Recommendation
No change is needed if this is the desired behavior.
Resolution
Nashpoint Team: Acknowledged.
-
I-04 Informational Temporary totalAssets Inflation Risk Warning Acknowledged
Description
The price freeze mechanism implemented in
WTAdapterprevents price recovery arbitrage during the ex-dividend window.After distribution, the oracle price drops to reflect the dividend payout, and the newly minted shares compensate so
totalAssetsremains roughly unchanged once the price updates.However, if
endPriceFreezeandupdateLastPriceare not executed alongsidesettleDividendbefore a Node-level cache refresh, the Node will temporarily reflect an inflatedtotalAssets(increased shares × stale high price).If a Node cache refresh occurs during this window, depositors could capture value they were not entitled to.
Recommendation
Ensure
endPriceFreezeandupdateLastPriceare executed alongsidesettleDividend, before any Node-level cache refresh occurs.Resolution
Nashpoint Team: Acknowledged.
No findings match.
More from Nashpoint
Put your code through the same review.
This review started with a conversation about scope. Tell us what you are building and we will plan yours with you.