Organization
- @panoptic-labs
Engagement Type
Cantina Reviews
Period
-
Repositories
Researchers
Findings
Medium Risk
1 findings
1 fixed
0 acknowledged
Low Risk
1 findings
1 fixed
0 acknowledged
Informational
3 findings
2 fixed
1 acknowledged
Medium Risk1 finding
Anyone can call claim for any account
Severity
- Severity: Medium
Submitted by
m4rio
Description
The function allows third parties to execute a claim for a given leaf, and tokens are always sent to the
account
encoded in the leaf. The trade‑off: if a leaf contains a wrongaccount
, a third party can proactively claim to that wrong address, preventing later recovery via the admin’swithdrawUnclaimed
.Recommendation
Consider using
msg.sender
to claim instead of account or a signature from the account.
Low Risk1 finding
Admin key is a single EOA set to msg.sender and immutable
Severity
- Severity: Low
Submitted by
m4rio
Description
admin
is set to the deployer EOA and cannot be changed. If the key is lost or compromised, unclaimed funds afterwithdrawableAt
can be withdrawn by an attacker, and there is no recovery path.Recommendation
Pass the admin address in the constructor and use a multisig. Consider adding a one‑time admin transfer mechanism or making admin upgradable behind a multisig/DAO if governance changes are expected.
Informational3 findings
Token registry uses mapping + array instead of an enumerable set
State
- Acknowledged
Severity
- Severity: Informational
Submitted by
m4rio
Description
supportedTokens
is amapping(address => bool)
plus a separatetokenList
array. This pattern works but can drift out of sync (e.g., accidental duplicates intokenList
, or forgetting to push/remove). Managing two data structures also increases maintenance.Furthermore they are not enforced anymore on claim so right now it seems they are only for offchain reading?
Recommendation
Use
EnumerableSet.AddressSet
from OZ for a single source of truth (add/remove/check/iterate safely).Consider enforcing them on claim or removing them at all.
Lack of end‑to‑end Merkle tests before release
Severity
- Severity: Informational
Submitted by
m4rio
Description
Without fork/integration tests that attempt to claim every leaf, discrepancies in leaf encoding, amounts, or unsupported tokens can surface only after deployment, potentially DoS’ing some claims.
Recommendation
Add a pre‑release script/test that: (1) rebuilds the Merkle root from the JSON snapshot, (2) attempts a fork dry‑run claim for every leaf, and (3) checks contract balances cover all amounts for all tokens.
Using MerkleProof.verify (memory) instead of verifyCalldata
Severity
- Severity: Informational
Submitted by
m4rio
Description
verify
copies the proof to memory. Since the proof is alreadycalldata
, usingverifyCalldata
avoids an unnecessary copy.Recommendation
Replace with
MerkleProof.verifyCalldata(merkleProof, merkleRoot, node)
.