Guardian's review of LayerZero Composer for Sapience, published November 2025. The report records 7 findings, including 5 low and 2 informational.
- Published
- Review window
- November 10 to 11, 2025
- Language
- Solidity
- Chains
- Base, Arbitrum, Polygon
- Sector
- Derivatives
- 0 Critical
- 0 High
- 0 Medium
- 5 Low
- 2 Informational
Scope
2 files in scope · 356 nSLOC
| File | nSLOC | Lines |
|---|---|---|
packages/protocol/src/predictionMarket/resolvers/PredictionMarketLZResolver.sol | 158 | 215 |
packages/protocol/src/predictionMarket/resolvers/PredictionMarketLZResolverUmaSide.sol | 198 | 279 |
Findings 7
-
L-01 Low Misleading getPredictionResolution Results Validation Resolved
Description
When the getPredictionResolution function is called with an empty encodedPredictedOutcomes array, the function skips the loop and returns (true, NO_ERROR, true). This contradicts validatePredictionMarkets, which reverts on zero markets. If any on-chain consumer relies solely on getPredictionResolution, an empty parlay incorrectly appears as a resolved success.
Furthermore, there is no maximum length validation as exists in the validatePredictionMarkets function.
Recommendation
Consider mirroring the validation in getPredictionResolution: require the array to be non-empty and within configured bounds, or call validatePredictionMarkets internally and propagate its result.
-
L-02 Low Lacking Receiver Settlement Check Validation Resolved
Description
The prediction market side resolver does not enforce immutability of a market resolution once marked settled. A later cross-chain message with assertedTruthfully=true can set resolvedToYes to a different value, flipping an already-settled market outcome. While the configured UMA-side contract should only send one truthful resolution per market, any misconfiguration, replay from a different authorized remote bridge, or future code changes could toggle outcomes and corrupt payouts.
Recommendation
Consider adding validation to assert that
market.settledis not already true in themarketResolvedCallbackfunction. -
L-03 Low Duplicate MarketIds Allowed Validation Acknowledged
Description
Neither the validation nor resolution functions reject duplicate marketIds in the encoded PredictedOutcome[]. This can yield ambiguous parlay semantics, allow overcounting a single market multiple times.
Recommendation
Track seen marketIds within the loop and reject duplicated entries. Alternatively, deduplicate before processing and enforce a strict normalized format.
-
L-04 Low Markets Allowed To Re-Resolve Unexpected Behavior Acknowledged
Description
In the PredictionMarketLZResolverUmaSide resolver, the
assertionResolvedCallbackfunction always clears all mappings related to the marketId, which allows for subsequent submissions to the same market.This is important to allow untruthful assertions to be re-submitted, however also allows assertions to be submitted for markets after they have already truthfully resolved.
Recommendation
To avoid any unexpected behavior, consider only clearing the mappings when the assertion was resolved non-truthfully so that the already truthfully resolved market cannot be re-submitted.
-
L-05 Low Missing Configuration Updates Configuration Acknowledged
Description
In the
PredictionMarketUmaResolvercontract there is no path to update theconfigvalues after it has been set on construction.In case the configurations ought to be changed after deployment a new
PredictionMarketUmaResolverinstance will have to be deployed.Recommendation
Be aware of this limitation for the PredictionMarketUmaResolver address and consider if a configuration setter should be added.
-
I-01 Informational Incorrect MarketId Warning Warning Acknowledged
Description
The UMA resolvers cannot validate the
marketIdcorrectness since they require resolution through the UMA oracle and themarketIdis based upon thekeccak256(abi.encodePacked(claim, ":", endTime))result.As a result, matched predictions can pass the
_createPredictionfunction even though they might use an incorrectmarketId. Currently there is no pathway for users to be able to escape their matched prediction of an incorrect marketId was used, meaning that if no other market in the parlay resolves to false, and the invalid marketId remains unresolved the collateral for these users would be trapped.Recommendation
Ensure that the marketId used to create orders from the offchain system is always correct and be aware of this risk.
-
I-02 Informational Unnecessary marketAsserter Superfluous Code Resolved
Description
In the UMA side LZ Resolver the marketAsserter mapping is used to store the assertor of the marketId assertion, however this value is never used nor exposed to be read.
Recommendation
Consider removing the
marketAssertermapping.
No findings match.
More from Sapience
All 6 reports-
Foil Vault and Prediction Market
61 findings2 critical · 3 high 61 findings: 2 critical, 3 high, 7 medium, 26 low, 23 informational -
Sapience
87 findings8 high 87 findings: 8 high, 18 medium, 30 low, 31 informational -
Foil Updates
36 findings2 critical · 4 high 36 findings: 2 critical, 4 high, 7 medium, 23 low -
Foil Vault
35 findings2 critical · 2 high 35 findings: 2 critical, 2 high, 14 medium, 17 low
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.
