SNARKeling Treasure Hunt

First Flight #59
Beginner FriendlyGameFiFoundry
100 EXP
View results
Submission Details
Severity: high
Valid

Deploy script comments disclose plaintext treasure secrets

Root + Impact

Description

  • Normal behavior: Physical treasure secrets stay confidential until discovery; only public hashes and proofs appear on chain.

  • Problem: Deploy.s.sol states secrets are not revealed to the public, then lists the secrets as 1 through 10 in comments. Anyone with repository access can generate witnesses and proofs without field discovery.

// @> claims secrets are not public, then lists them on the next lines
// Secret Treasures for the snorkeling hunt (not revealed to the public):
// 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

Risk

Likelihood:

  • The script ships in the contest repository and is copied into deployments and forks.

  • Reviewers, auditors, and competitors read deploy scripts during setup.

Impact:

  • The physical hunt fairness property fails because proof generation does not require discovering a secret in the field.

  • Rewards can be claimed by anyone who runs the documented proving pipeline with the leaked values.

Proof of Concept

The deploy script comments contradict the stated confidentiality of treasure secrets: plaintext values appear next to the phrase not revealed to the public. This is a documentary PoC (no chain interaction): open the file and compare with fixture inputs.

Steps

  1. Open contracts/scripts/Deploy.s.sol and locate the comment block that lists secrets 110 and the public hash lines (see excerpt below).

  2. Open circuits/Prover.toml.example and confirm the treasure array uses the same small domain ("1""10"), so anyone with the repo can derive witnesses without field discovery.

Expected result: Reviewer can read plaintext secrets and matching hashes directly from the repository; no guessing required.

// contracts/scripts/Deploy.s.sol (excerpt — line numbers vary by version)
// Secret Treasures for the snorkeling hunt (not revealed to the public):
// 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
// Treasures' hashes (revealed to the public, used as public inputs for the proof generation):
// 1505662313093145631275418581390771847921541863527840230091007112166041775502,
// ...

Recommended Mitigation

Explanation: Physical treasure values must not appear in version control. Operators should load secrets from secure storage (KMS, sealed CI, or offline ceremony) at deploy or proving time. Comments that list plaintext secrets defeat the hunt and should be deleted; publish only public hashes or commitments on chain or in docs.

-// Secret Treasures for the snorkeling hunt (not revealed to the public):
-// 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
+// Load treasure secrets from a private operator process or KMS; never commit plaintext.
Updates

Lead Judging Commences

s3mvl4d Lead Judge 18 days ago
Submission Judgement Published
Validated
Assigned finding tags:

secrets stored in plain text

In `Deploy.s.sol`, the comments explicitly list the “Secret Treasures for the snorkeling hunt” as 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, and `circuits/Prover.toml.example` likewise stores the full treasure array in plaintext alongside the corresponding `treasure_hash` values. Since the Noir circuit proves knowledge of one of these treasure secrets by checking that `pedersen_hash([treasure]) == treasure_hash`, publishing the raw treasure inputs defeats the intended secrecy assumption behind the treasure-hunt design: anyone with repository access can recover valid witnesses and generate proofs without actually discovering the treasure in the real world.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!