Skip to content

[#893] Add finalize script and MerkleClaim contract#911

Merged
realproject7 merged 5 commits intomainfrom
task/893-finalize-script
Apr 21, 2026
Merged

[#893] Add finalize script and MerkleClaim contract#911
realproject7 merged 5 commits intomainfrom
task/893-finalize-script

Conversation

@realproject7
Copy link
Copy Markdown
Owner

Fixes #893

Summary

  • scripts/airdrop-finalize.ts: campaign finalization script
    1. Computes 7-day TWAP from pl_daily_prices before campaign end
    2. Determines milestone tier (Gold/Silver/Bronze/None) based on TWAP mcap
    3. Aggregates points per address, calculates share and PLOT distribution amounts
    4. Generates Merkle tree via @openzeppelin/merkle-tree with per-user proofs
    5. Stores proofs in pl_airdrop_proofs DB table and scripts/airdrop-proofs.json
    6. Outputs deployment instructions (contract deploy, token transfer, burn)
  • contracts/MerkleClaim.sol: standard OZ MerkleProof-based claim contract
    • Double-hash leaf encoding (keccak256(bytes.concat(keccak256(abi.encode(...))))) matching StandardMerkleTree
    • Claimed mapping prevents double claims
    • Emits Claimed event
  • Added @openzeppelin/merkle-tree dependency

Test plan

  • Run script against test DB — verify TWAP calculation
  • Verify milestone thresholds match config
  • Verify distribution amounts sum to pool × milestone_pct
  • Verify Merkle proofs are valid against the root
  • Verify MerkleClaim.sol compiles with Solidity 0.8.20+
  • Verify proofs stored in DB match JSON output
  • Verify "None" milestone correctly outputs burn instructions

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 21, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
plotlink Ignored Ignored Apr 21, 2026 6:23am

Request Review

Copy link
Copy Markdown
Collaborator

@project7-interns project7-interns left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: REQUEST CHANGES

Summary

This PR is not merge-ready yet. CI is broken by an out-of-sync lockfile, and the finalize script does not guarantee the distributed amounts sum exactly to the intended pool slice.

Findings

  • [high] package.json adds utf-8-validate, but package-lock.json does not include a matching locked entry, so npm ci fails before any tests run.
    • File: package.json:36
    • Suggestion: Regenerate and commit package-lock.json so it is fully in sync with the dependency manifest.
  • [high] The distribution code rounds each recipient independently with parseUnits(plotAmount.toFixed(18), 18). That can leave leftover wei undistributed or over-distribute by cumulative rounding, which violates issue #893's requirement that distribution amounts sum exactly to pool_amount × milestone_pct.
    • File: scripts/airdrop-finalize.ts:114
    • Suggestion: Compute allocations in integer wei from a single total distributable amount, then assign the remainder deterministically (for example to the largest holder or via largest-remainder ordering) so the final sum is exact.

Decision

Requesting changes because the PR currently fails CI and the finalize script can produce a payout set that does not match the exact distributable amount.

…nc lockfile

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator

@project7-interns project7-interns left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: REQUEST CHANGES

Summary

The rounding approach changed, but the PR is still blocked by the same lockfile issue in CI.

Findings

  • [high] npm ci is still failing in GitHub Actions because package.json and package-lock.json are not actually in sync. The failed run still reports Missing: utf-8-validate@5.0.10 from lock file, so this PR cannot pass install/CI as submitted.
    • File: package-lock.json:1
    • Suggestion: Re-run npm install (or otherwise regenerate the lockfile cleanly), commit the resulting package-lock.json, and verify npm ci succeeds before re-requesting review.

Decision

Requesting changes because the PR remains red in CI on a dependency-lock mismatch.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator

@project7-interns project7-interns left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: REQUEST CHANGES

Summary

The bigint distribution update addresses the allocation-precision concern, but the PR is still blocked by the same dependency-lock mismatch in CI.

Findings

  • [high] GitHub Actions is still failing at npm ci with Missing: utf-8-validate@5.0.10 from lock file, so package.json and package-lock.json remain out of sync in the submitted branch.
    • File: package-lock.json:1
    • Suggestion: Regenerate the lockfile cleanly and confirm npm ci passes before re-requesting review.

Decision

Requesting changes because the PR remains red in CI on the install step.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator

@project7-interns project7-interns left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: REQUEST CHANGES

Summary

The package manifest change moved in the right direction, but the PR is still blocked by the same install failure in CI.

Findings

  • [high] GitHub Actions is still failing at npm ci with Missing: utf-8-validate@5.0.10 from lock file, so the submitted package-lock.json still does not satisfy the dependency graph npm expects for this branch.
    • File: package-lock.json:1
    • Suggestion: Regenerate the lockfile from a clean install state and verify npm ci passes before re-requesting review.

Decision

Requesting changes because the PR remains red on the install step.

…atch

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator

@project7-interns project7-interns left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: APPROVE

Summary

The latest update resolves the lockfile blocker from my prior reviews. The regenerated package-lock.json is consistent with the manifest changes, and the bigint allocation logic remains the correct approach for exact distribution totals.

Findings

  • No remaining code-level blockers in the changed files.

Decision

Approving because the finalize script and Merkle claim flow I reviewed now satisfy issue #893. The latest GitHub snapshot had CI pending rather than failing immediately on npm ci, so my prior merge blocker is resolved.

@realproject7 realproject7 merged commit 52d63fa into main Apr 21, 2026
2 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Airdrop P5] Finalize script (TWAP, Merkle tree, distribution)

2 participants