Add EOS/EOP updates and magic-link spam guard#88
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughMigrate VoteToken/VOTE flows to EarthOptimizationPoint/EOP across DB, contracts, server, cron, APIs, ABI, frontend pages/components and demos; add EOS/game landing pages; refactor magic-link spam-guard logging, email BCC behavior, and tests; update CI/playwright timeouts. ChangesPoint mint & EOS landing migration
Sequence Diagram(s)sequenceDiagram
participant Client
participant NextAPI
participant PrismaDB
participant EOPContract
Client->>NextAPI: POST /api/cron/point-mint (cron)
NextAPI->>PrismaDB: find pending pointMint rows
NextAPI->>EOPContract: batchMintForVoters(tx)
EOPContract-->>NextAPI: txHash / success
NextAPI->>PrismaDB: update rows -> CONFIRMED with txHash
Estimated code review effort: 🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
This PR reduces noise in the email monitor by removing automatic monitor BCC on magic-link emails, and adds structured (sanitized) logging for /api/auth/signin/email to better understand where signup spam is coming from—while preserving the existing repeated-address suppression behavior with test coverage.
Changes:
- Make monitor-BCC behavior scope-aware so
"magic_link"emails don’t addEMAIL_MONITOR_BCC. - Add structured logging around magic-link send/suppress/fail outcomes (with request context like referer host/path, callback host, etc.).
- Extend tests to cover both “sent” and “suppressed” outcomes and the new magic-link BCC behavior.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/web/src/lib/email/resend.ts | Skip monitor BCC for scope: "magic_link"; minor refactor of email body composition call. |
| packages/web/src/lib/email/magic-link-email.ts | Return { existingUser, providerMessageId } metadata for downstream logging. |
| packages/web/src/lib/auth-spam-guard.server.ts | Add sanitized structured logging and refactor token counting used by magic-link suppression. |
| packages/web/src/lib/tests/resend.test.ts | Add regression test ensuring magic-link React emails do not include monitor BCC. |
| packages/web/src/lib/tests/auth-spam-guard.server.test.ts | Assert structured logs for “suppressed” and “sent” magic-link outcomes. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f58022d6af
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/web/src/lib/__tests__/auth-spam-guard.server.test.ts`:
- Around line 64-68: The helper lastAuthLog() currently assumes the final
console.log is the auth JSON and parses mock.calls.at(-1), which is flaky;
change lastAuthLog to scan consoleLogSpy.mock.calls backward, attempt JSON.parse
on each call[0], and return the first parsed object whose msg ===
"auth_magic_link_request"; if none found, throw or fail with a clear message.
Use the existing consoleLogSpy.mock.calls and JSON.parse, and reference the
lastAuthLog() function so the test locates and returns the correct auth log even
if unrelated logs were printed.
In `@packages/web/src/lib/auth-spam-guard.server.ts`:
- Around line 101-108: The auth log is currently writing uncontrolled
provider/runtime messages (error.message) into the sanitized auth log in
logMagicLinkRequest; change this to emit a stable, allowlisted failure reason
code (e.g., "provider_error", "rate_limited", "invalid_recipient", "unknown")
mapped from the thrown error or outcome, and send the raw error details only to
the separate error channel (e.g., processLogger.error or an error monitoring
call). Update logMagicLinkRequest and the nearby handling that writes
outcome/reason (the block handling outcome="failed") to perform the
mapping/whitelist and include recentTokenCount/providerMessageId as before, and
ensure raw exception is logged only to the error logger so the sanitized auth
log cannot contain uncontrolled messages.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 11f48190-7910-462e-8dfd-5fed4c70f9ac
📒 Files selected for processing (5)
packages/web/src/lib/__tests__/auth-spam-guard.server.test.tspackages/web/src/lib/__tests__/resend.test.tspackages/web/src/lib/auth-spam-guard.server.tspackages/web/src/lib/email/magic-link-email.tspackages/web/src/lib/email/resend.ts
Code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. |
PR review packetStart here
Review checklist
Changed files considered
Updated automatically when this PR's preview or visual review reruns. |
There was a problem hiding this comment.
Actionable comments posted: 10
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
packages/db/prisma/schema.prisma (1)
4874-4918:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift
PointMintstill cannot identify the vote it claims to represent.Line 4874 says this row links a referendum vote to a mint, but the schema only stores the referrer, referendum, and
nullifierHash. Without a directReferendumVoteFK (or another stable vote-level identifier), the database cannot enforce that a mint was issued for the correct vote or make that provenance queryable later.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/db/prisma/schema.prisma` around lines 4874 - 4918, PointMint currently lacks a direct FK to the vote it represents; add a voteId field on the PointMint model that references the ReferendumVote primary key and wire up the relation (e.g., fields: [voteId], references: [id], onDelete: Cascade) so provenance and referential integrity are enforced; update the model-level constraints (replace or extend @@unique([nullifierHash, referendumId]) to include voteId or add a separate unique constraint as appropriate) and add the inverse relation on ReferendumVote if present so queries can traverse from a vote to its PointMint(s).packages/web/src/app/api/cron/point-mint/route.ts (1)
40-60:⚠️ Potential issue | 🟠 MajorAdd recovery for orphaned
pointMintrows stuck inSUBMITTED
packages/web/src/app/api/cron/point-mint/route.tsmarkspointMintrecordsSUBMITTEDbefore the on-chain call, but the cron only queriesPENDINGon subsequent runs and no other code path updatesSUBMITTEDback toPENDING/FAILEDfor retry (referral sync rewrites onlyPENDING/FAILED). Add a periodic cleanup/retry that revertsSUBMITTEDrows older than a threshold (e.g., viasubmittedAt) back to a retryable state.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/web/src/app/api/cron/point-mint/route.ts` around lines 40 - 60, Add a recovery step in the cron handler in route.ts that flips orphaned pointMint rows from SUBMITTED back to a retryable status (e.g., PENDING) when their submittedAt timestamp is older than a configurable threshold; implement this by calling prisma.pointMint.updateMany before you fetch pendingMints (use the same BATCH_SIZE/ids context if needed) and target records where status === "SUBMITTED" && submittedAt < Date.now() - THRESHOLD_MS, updating status to "PENDING" (and optionally incrementing a retry counter or setting lastTriedAt) so those mints will be reprocessed by the existing logic that reads pendingMints.packages/treasury-prize/test/VoterPrizeTreasury.test.ts (1)
290-410:⚠️ Potential issue | 🔴 Critical | 🏗️ Heavy liftMissing critical test: post-redemption transfer scenario.
The test suite validates that:
- Same address cannot redeem twice (line 342-356) ✓
- Pre-snapshot transfers work correctly (line 659-696) ✓
But does NOT test the critical vulnerability: redeem → transfer → redeem by different address.The search results discuss ERC-4626 vault standards and token security, but don't directly address the specific double-redemption-via-transfer vulnerability. The standard practice is that shares are "burned to redeem the corresponding underlying assets", which this implementation does not do.
🧪 Suggested test to add after line 356
it("SECURITY: prevents redemption of transferred EOP post-redemption", async function () { const { treasury, usdc, aavePool, pointToken, contributor1, voter1, voter2 } = await loadFixture(deployFixture); // Setup: fund treasury await treasury.connect(contributor1).deposit(parseUSDC(30_000)); await aavePool.simulateYield( await treasury.getAddress(), parseUSDC(6_000) ); // Snapshot: voter1=1 EOP, voter2=1 EOP, voter3=1 EOP, total=3 EOP await treasury.updateMetrics(HEALTH_THRESHOLD, INCOME_THRESHOLD); await treasury.snapshotPointSupply(); await time.increase(Number(FIFTEEN_YEARS)); // voter1 redeems their 1 EOP share (1/3 of 36,000 = 12,000 USDC) const bal1Before = await usdc.balanceOf(voter1.address); await treasury.connect(voter1).redeemEarthOptimizationPoints(); const bal1After = await usdc.balanceOf(voter1.address); expect(bal1After - bal1Before).to.be.closeTo( parseUSDC(12_000), parseUSDC(1) ); // voter1 still holds 1 EOP (not burned on redemption) expect(await pointToken.balanceOf(voter1.address)).to.equal(ONE_POINT); // voter1 transfers their EOP to voter2 await pointToken .connect(voter1) .transfer(voter2.address, ONE_POINT); // voter2 now has 2 EOP (original 1 + transferred 1) expect(await pointToken.balanceOf(voter2.address)).to.equal( ONE_POINT * 2n ); // VULNERABILITY: voter2 can redeem 2 EOP (2/3 of pool = 24,000 USDC) // This drains 36,000 total from a pool that should only give 36,000 to all 3 voters // Expected behavior: This should either: // A) Revert because voter1's EOP was already redeemed, OR // B) Treasury should have burned voter1's EOP on redemption to prevent this const bal2Before = await usdc.balanceOf(voter2.address); await treasury.connect(voter2).redeemEarthOptimizationPoints(); const bal2After = await usdc.balanceOf(voter2.address); // Currently this succeeds and drains 24,000 USDC expect(bal2After - bal2Before).to.be.closeTo( parseUSDC(24_000), parseUSDC(1) ); // Total redeemed: 12,000 (voter1) + 24,000 (voter2) = 36,000 // voter3 will fail to redeem because pool is empty await expect( treasury.connect(voter3).redeemEarthOptimizationPoints() ).to.be.reverted; // Aave withdraw reverts when insufficient funds });🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/treasury-prize/test/VoterPrizeTreasury.test.ts` around lines 290 - 410, The test suite is missing a security test for the "redeem → transfer → redeem by different address" vulnerability; add a test that after calling redeemEarthOptimizationPoints by an address you assert the caller's EOP balance is reduced or the token burned/marked redeemed (inspect pointToken.balanceOf and treasury redemption state), then attempt to transfer those EOP to another address and assert that a subsequent redeemEarthOptimizationPoints by the recipient is reverted; if the contract currently allows this flow, fix the contract so redeemEarthOptimizationPoints either burns the caller's EOP via pointToken (or calls a burnOnRedeem(address) function) or marks those token IDs/amounts redeemed in the treasury (update the redemption tracking used in redeemEarthOptimizationPoints) to prevent double-redemption.packages/treasury-prize/src/abi.ts (1)
1-383:⚠️ Potential issue | 🟠 MajorFix ABI completeness: exported ABI fragments don’t match compiled contracts
packages/treasury-prize/src/abi.tsomits several function/event entries that exist in the compiled artifacts. Examples:EarthOptimizationPointis missingbatchMintForVoters,mintForVoter,claimed,owner,setPrizeTreasury,transferFrom, admin ownership-transfer events;VoterPrizeTreasuryis missing ERC20 function fragments liketransfer,transferFrom,allowance,approve, plus contract functions likeaToken,aavePool,updateMetrics,snapshotPointSupply,owner, etc. Add the missing fragments (or clearly document and enforce that this ABI is an intentional minimal subset that covers all current call sites).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/treasury-prize/src/abi.ts` around lines 1 - 383, The exported ABI arrays are incomplete vs the compiled contracts; update earthOptimizationPointAbi and voterPrizeTreasuryAbi to include the missing function and event fragments shown in the review (e.g., EarthOptimizationPoint: batchMintForVoters, mintForVoter, claimed, owner, setPrizeTreasury, transferFrom, OwnershipTransferred event and other ownership/admin events; VoterPrizeTreasury: transfer, transferFrom, allowance, approve, aToken, aavePool, updateMetrics, snapshotPointSupply, owner, and any corresponding events like PointSupplySnapshotted/OwnershipTransferred). Locate the two exports (earthOptimizationPointAbi and voterPrizeTreasuryAbi) and either append the full missing function/event descriptors matching the compiled artifact shapes or replace the arrays with the canonical ABI from the build output; alternatively add a clear comment and runtime assertion that the file is intentionally a minimal subset and enforce that all call sites only rely on included fragments. Ensure each added fragment uses the correct name, type, inputs/outputs and stateMutability to match the compiled JSON so consumers won’t fail at runtime.
🧹 Nitpick comments (2)
packages/db/src/zod/index.ts (1)
1913-1914: 💤 Low valueUpdate the section comment to reflect the new naming.
The section comment still references "VOTE TOKEN" but the model has been renamed to
PointMint. Update the comment to match the current terminology.📝 Suggested update
// ============================================================================ -// VOTE TOKEN & VOTER PRIZE TREASURY +// POINT MINT & VOTER PRIZE TREASURY // ============================================================================🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/db/src/zod/index.ts` around lines 1913 - 1914, The section comment currently reads "VOTE TOKEN & VOTER PRIZE TREASURY" but the model was renamed to PointMint; update that comment to use the new terminology (e.g., "POINT MINT & VOTER PRIZE TREASURY" or similar) so it matches the PointMint model; locate the comment near the PointMint-related zod schemas or the PointMint type declarations in this file and replace the old "VOTE TOKEN" wording with "POINT MINT" throughout.packages/web/src/components/demo/slides/sierra/slide-three-scenarios-all-win.tsx (1)
12-12: ⚡ Quick winRename
voteValuetopointValuefor consistency.The variable is sourcing from
EARTH_OPTIMIZATION_POINT_VALUEbut retains the oldvoteValuename. Renaming it topointValuemaintains consistency with the migration in other files (e.g.,slide-dominant-assurance-contract.tsxline 17,slide-point-value-asymmetry.tsxline 16) and prevents confusion.♻️ Proposed rename
-const voteValue = formatCurrency(EARTH_OPTIMIZATION_POINT_VALUE.value); +const pointValue = formatCurrency(EARTH_OPTIMIZATION_POINT_VALUE.value); const lifetimeGain = formatCurrency(TREATY_TRAJECTORY_LIFETIME_INCOME_GAIN_PER_CAPITA.value);Then update the usage on line 36:
- {voteValue}+ + {pointValue}+🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/web/src/components/demo/slides/sierra/slide-three-scenarios-all-win.tsx` at line 12, Rename the local variable voteValue to pointValue so it reflects its source EARTH_OPTIMIZATION_POINT_VALUE; change the declaration where formatCurrency(EARTH_OPTIMIZATION_POINT_VALUE.value) is assigned to use the identifier pointValue and update all subsequent uses of voteValue (e.g., the usage around the slide rendering at the later JSX) to pointValue; keep the call to formatCurrency and the EARTH_OPTIMIZATION_POINT_VALUE reference unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/data/src/parameters/parameters-calculations-citations.ts`:
- Around line 11207-11219: Update the MECHANISM_SHIRT_CASCADE_P_SUCCESS
Parameter to use the same dimensionless unit as the other probability
parameters: change its unit from "rate" to "ratio" in the
MECHANISM_SHIRT_CASCADE_P_SUCCESS object so it matches other mechanism
probability parameters (e.g., the ones near MECHANISM_*_P_* entries) and
reflects that probabilities are dimensionless ratios.
- Around line 6650-6663: The MECHANISM_LOVING_TAKEOVER_CAPITAL parameter
duplicates DEFENSE_TAKEOVER_COST_TOTAL; remove the duplicate definition and
either delete MECHANISM_LOVING_TAKEOVER_CAPITAL and update callers to use
DEFENSE_TAKEOVER_COST_TOTAL, or keep the symbol but change
MECHANISM_LOVING_TAKEOVER_CAPITAL to a reference form by setting its formula to
"DEFENSE_TAKEOVER_COST_TOTAL" (and drop the duplicated value/description) so all
logic points use the single canonical DEFENSE_TAKEOVER_COST_TOTAL parameter.
In
`@packages/db/prisma/migrations/20260607120000_rename_vote_token_mint_to_point_mint/migration.sql`:
- Around line 1-13: Add a rollback (down) migration that reverses the renames in
20260607120000_rename_vote_token_mint_to_point_mint/migration.sql by renaming
PointMint back to VoteTokenMint and PointMintStatus back to VoteTokenMintStatus
and reverting the constraint and index names (reverse each RENAME TO in the
file), or explicitly confirm the project intends up-only Prisma migrations and
document that decision; also update packages/db/prisma/anonymization-updates.sql
to replace references to public."VoteTokenMint" with public."PointMint" (or add
a safe existence check/guard around queries that reference
public."VoteTokenMint") so runtime SQL won’t fail after the rename.
In `@packages/treasury-prize/contracts/VoterPrizeTreasury.sol`:
- Around line 167-187: The redemption currently marks redemption per address
(hasRedeemedPoints) but does not burn or lock EOP tokens, allowing the same
token to be transferred and redeemed multiple times; modify
redeemEarthOptimizationPoints (or the EOP interaction around it) to require and
consume the tokens on redemption — e.g., call the EOP token's burnFrom or
transferFrom to move/burn the caller's pointBalance before or immediately after
computing assets and before setting hasRedeemedPoints, or require prior
approve+burnFrom so the contract actually reduces total supply/locks the tokens
when pointSupplySnapshotted is true; ensure you reference
earthOptimizationPoint, redeemEarthOptimizationPoints, hasRedeemedPoints,
pointSupplySnapshotted and pointTotalSupplySnapshot so the change prevents
double-redemption while preserving snapshot logic.
In `@packages/web/src/app/game/page.tsx`:
- Around line 14-15: The current expression building lateEmployeeTasks uses
treatyParentTask?.task.childTasks which will throw if treatyParentTask exists
but its task is nullish; change the access to guard task as well (use optional
chaining on task: treatyParentTask?.task?.childTasks ?? []) so null/undefined
task doesn't cause a TypeError, keeping the cast to TaskCardTask[] as needed and
updating the symbol lateEmployeeTasks accordingly.
- Around line 12-15: The unsafe double-casts on lateEmployeeProgramTask and
lateEmployeeTasks come from decorateTask/getTaskDetailData typing childTasks as
unknown[]; fix decorateTask so its decoratedChildTasks is typed as
TaskCardTask[] | undefined (and update decorateTask's return type accordingly)
so getTaskDetailData propagates childTasks with the proper TaskCardTask[] type;
once decorateTask/getTaskDetailData signatures are updated, remove the as
unknown/as TaskCardTask[] and the cast on lateEmployeeProgramTask in page.tsx
and let the correct types flow to lateEmployeeProgramTask and lateEmployeeTasks.
In `@packages/web/src/components/prize/VoterPrizeTreasuryDeposit.tsx`:
- Line 21: Replace the obvious test value in the PRESET_AMOUNTS constant inside
the VoterPrizeTreasuryDeposit component: remove or replace "9999999999999999"
with a sensible production cap (e.g., "10000" or "100000") or simply omit it
from PRESET_AMOUNTS so the preset list only contains realistic deposit options;
update any UI/validation expectations that assume the prior extreme value.
In `@packages/web/src/lib/impact-receipts.server.ts`:
- Line 94: The environment variable list used to determine the chain id omits
the legacy VOTE_TOKEN_CHAIN_ID, so current deployments without rotated envs will
default to "84532" and scan the wrong network; update the chain-id fallback
expression that assigns raw to include process.env.VOTE_TOKEN_CHAIN_ID (e.g.,
process.env.VOTE_TOKEN_CHAIN_ID ?? process.env.TREASURY_CHAIN_ID ??
process.env.EOP_CHAIN_ID ?? "84532") so VOTE_TOKEN_CHAIN_ID is honored during
migration, keeping the rest of the fallback order and variable name (raw)
intact.
In `@packages/web/src/lib/routes.ts`:
- Around line 976-988: Remove the TODO(copy) placeholders from the route
metadata for the "The Earth Optimization Game" route: finalize or replace the
provisional strings for label, description, tagline, cta (and any associated
fields like copyPreview, reviewName, screenshot) or delete the TODO comments
altogether so no TODO-gated copy ships; locate the route object containing
label: "The Earth Optimization Game" and update the description/tagline/cta to
final copy (or remove the TODO markers and set copyPreview/reviewName
appropriately) before merging.
In `@packages/web/src/lib/site.ts`:
- Around line 596-617: The production metadata in site.ts contains leftover
TODO(copy) markers and placeholder text for keys title, description,
openGraphTitle, openGraphDescription, openGraphImage.alt, twitterTitle, and
twitterDescription; update these keys with finalized copy (or remove the TODO
comments and replace the placeholder lines with the approved/production strings)
so no TODOs remain in root metadata before merging, ensuring openGraphImage
still includes valid url/width/height and alt text is updated accordingly.
---
Outside diff comments:
In `@packages/db/prisma/schema.prisma`:
- Around line 4874-4918: PointMint currently lacks a direct FK to the vote it
represents; add a voteId field on the PointMint model that references the
ReferendumVote primary key and wire up the relation (e.g., fields: [voteId],
references: [id], onDelete: Cascade) so provenance and referential integrity are
enforced; update the model-level constraints (replace or extend
@@unique([nullifierHash, referendumId]) to include voteId or add a separate
unique constraint as appropriate) and add the inverse relation on ReferendumVote
if present so queries can traverse from a vote to its PointMint(s).
In `@packages/treasury-prize/src/abi.ts`:
- Around line 1-383: The exported ABI arrays are incomplete vs the compiled
contracts; update earthOptimizationPointAbi and voterPrizeTreasuryAbi to include
the missing function and event fragments shown in the review (e.g.,
EarthOptimizationPoint: batchMintForVoters, mintForVoter, claimed, owner,
setPrizeTreasury, transferFrom, OwnershipTransferred event and other
ownership/admin events; VoterPrizeTreasury: transfer, transferFrom, allowance,
approve, aToken, aavePool, updateMetrics, snapshotPointSupply, owner, and any
corresponding events like PointSupplySnapshotted/OwnershipTransferred). Locate
the two exports (earthOptimizationPointAbi and voterPrizeTreasuryAbi) and either
append the full missing function/event descriptors matching the compiled
artifact shapes or replace the arrays with the canonical ABI from the build
output; alternatively add a clear comment and runtime assertion that the file is
intentionally a minimal subset and enforce that all call sites only rely on
included fragments. Ensure each added fragment uses the correct name, type,
inputs/outputs and stateMutability to match the compiled JSON so consumers won’t
fail at runtime.
In `@packages/treasury-prize/test/VoterPrizeTreasury.test.ts`:
- Around line 290-410: The test suite is missing a security test for the "redeem
→ transfer → redeem by different address" vulnerability; add a test that after
calling redeemEarthOptimizationPoints by an address you assert the caller's EOP
balance is reduced or the token burned/marked redeemed (inspect
pointToken.balanceOf and treasury redemption state), then attempt to transfer
those EOP to another address and assert that a subsequent
redeemEarthOptimizationPoints by the recipient is reverted; if the contract
currently allows this flow, fix the contract so redeemEarthOptimizationPoints
either burns the caller's EOP via pointToken (or calls a burnOnRedeem(address)
function) or marks those token IDs/amounts redeemed in the treasury (update the
redemption tracking used in redeemEarthOptimizationPoints) to prevent
double-redemption.
In `@packages/web/src/app/api/cron/point-mint/route.ts`:
- Around line 40-60: Add a recovery step in the cron handler in route.ts that
flips orphaned pointMint rows from SUBMITTED back to a retryable status (e.g.,
PENDING) when their submittedAt timestamp is older than a configurable
threshold; implement this by calling prisma.pointMint.updateMany before you
fetch pendingMints (use the same BATCH_SIZE/ids context if needed) and target
records where status === "SUBMITTED" && submittedAt < Date.now() - THRESHOLD_MS,
updating status to "PENDING" (and optionally incrementing a retry counter or
setting lastTriedAt) so those mints will be reprocessed by the existing logic
that reads pendingMints.
---
Nitpick comments:
In `@packages/db/src/zod/index.ts`:
- Around line 1913-1914: The section comment currently reads "VOTE TOKEN & VOTER
PRIZE TREASURY" but the model was renamed to PointMint; update that comment to
use the new terminology (e.g., "POINT MINT & VOTER PRIZE TREASURY" or similar)
so it matches the PointMint model; locate the comment near the PointMint-related
zod schemas or the PointMint type declarations in this file and replace the old
"VOTE TOKEN" wording with "POINT MINT" throughout.
In
`@packages/web/src/components/demo/slides/sierra/slide-three-scenarios-all-win.tsx`:
- Line 12: Rename the local variable voteValue to pointValue so it reflects its
source EARTH_OPTIMIZATION_POINT_VALUE; change the declaration where
formatCurrency(EARTH_OPTIMIZATION_POINT_VALUE.value) is assigned to use the
identifier pointValue and update all subsequent uses of voteValue (e.g., the
usage around the slide rendering at the later JSX) to pointValue; keep the call
to formatCurrency and the EARTH_OPTIMIZATION_POINT_VALUE reference unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 17a1661f-fd3e-4b86-a788-224fe1ca5cdc
📒 Files selected for processing (69)
TODO.mdpackages/data/src/parameters/parameters-calculations-citations.tspackages/db/prisma/migrations/20260607120000_rename_vote_token_mint_to_point_mint/migration.sqlpackages/db/prisma/schema.prismapackages/db/src/zod/index.tspackages/treasury-prize/contracts/EarthOptimizationPoint.solpackages/treasury-prize/contracts/VoterPrizeTreasury.solpackages/treasury-prize/package.jsonpackages/treasury-prize/scripts/deploy-voter-prize-treasury.tspackages/treasury-prize/src/abi.tspackages/treasury-prize/test/EarthOptimizationPoint.test.tspackages/treasury-prize/test/VoteToken.test.tspackages/treasury-prize/test/VoterPrizeTreasury.test.tspackages/treasury-shared/contracts/interfaces/IEarthOptimizationPoint.solpackages/treasury-shared/src/addresses.tspackages/web/src/app/api/cron/point-mint/route.test.tspackages/web/src/app/api/cron/point-mint/route.tspackages/web/src/app/api/game-stats/route.tspackages/web/src/app/api/personhood/world-id/verify/route.test.tspackages/web/src/app/api/personhood/world-id/verify/route.tspackages/web/src/app/api/points/balance/route.test.tspackages/web/src/app/api/points/balance/route.tspackages/web/src/app/api/prize-treasury/status/route.test.tspackages/web/src/app/api/prize-treasury/status/route.tspackages/web/src/app/api/referendums/[slug]/vote/route.test.tspackages/web/src/app/api/referendums/[slug]/vote/route.tspackages/web/src/app/contribute/page.tsxpackages/web/src/app/eos/page.logged-out.mdpackages/web/src/app/eos/page.tsxpackages/web/src/app/game/page.logged-out.mdpackages/web/src/app/game/page.tsxpackages/web/src/app/love/page.logged-out.mdpackages/web/src/app/page.tsxpackages/web/src/app/prize/page.tsxpackages/web/src/app/store/page.logged-out.mdpackages/web/src/components/demo/slides/index.tspackages/web/src/components/demo/slides/sierra/slide-dominant-assurance-contract.tsxpackages/web/src/components/demo/slides/sierra/slide-point-dollar-value.tsxpackages/web/src/components/demo/slides/sierra/slide-point-value-asymmetry.tsxpackages/web/src/components/demo/slides/sierra/slide-prize-pool-vs-index-fund.tsxpackages/web/src/components/demo/slides/sierra/slide-three-scenarios-all-win.tsxpackages/web/src/components/game/GameScoreBar.tsxpackages/web/src/components/landing/DecisionMatrixSection.tsxpackages/web/src/components/prize/EarthOptimizationPointsBalanceCard.tsxpackages/web/src/components/prize/PrizeCalculator.tsxpackages/web/src/components/prize/VoterPrizeTreasuryDeposit.tsxpackages/web/src/components/profile/ProfileHub.tsxpackages/web/src/components/site/EarthOptimizationGameLandingPage.tsxpackages/web/src/components/site/EarthOptimizationServicesLandingPage.tsxpackages/web/src/components/site/EosInvestmentCalculator.tsxpackages/web/src/lib/__tests__/auth-spam-guard.server.test.tspackages/web/src/lib/__tests__/impact-receipts.server.test.tspackages/web/src/lib/__tests__/referral-point-mint.server.test.tspackages/web/src/lib/__tests__/routes.test.tspackages/web/src/lib/__tests__/site.test.tspackages/web/src/lib/auth-spam-guard.server.tspackages/web/src/lib/contracts/server-client.tspackages/web/src/lib/daily-activity-digest.server.tspackages/web/src/lib/dashboard.server.tspackages/web/src/lib/demo-script.tspackages/web/src/lib/demo/parameters.tspackages/web/src/lib/env.tspackages/web/src/lib/impact-receipts.server.tspackages/web/src/lib/messaging.tspackages/web/src/lib/prize-deposit-hypercert.server.tspackages/web/src/lib/referral-point-mint.server.tspackages/web/src/lib/routes.tspackages/web/src/lib/site.tspackages/web/vercel.json
💤 Files with no reviewable changes (1)
- packages/treasury-prize/test/VoteToken.test.ts
✅ Files skipped from review due to trivial changes (6)
- packages/treasury-prize/package.json
- packages/web/src/app/store/page.logged-out.md
- packages/web/src/app/eos/page.tsx
- packages/web/src/app/love/page.logged-out.md
- TODO.md
- packages/web/src/app/prize/page.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/web/src/lib/auth-spam-guard.server.ts
…rminology for consistency and accuracy. Add new pages for "Dysfunction Tax" and "Efficiency Audit." Adjust descriptions and metadata for various sections, including the Prize and Optimization Tools. Correct numerical claims and enhance user engagement prompts. Update navigation links to reflect new terminology and improve user experience.
… logging - Implemented task applications server logic including fetching, updating, and permission checks. - Added unit tests for task application updates and review permissions. - Introduced new API routes for task applications. - Enhanced task ranking logic to consider user credentials, location, and payment preferences. - Updated TypeScript configurations for better test support and incremental builds. Edwardsville IL Edmonds. Sunrise Beach in the Ozarks.
Sentry preview audit failedThe preview smoke test ran, but the Sentry audit could not query issues. Error: Check that the GitHub secret used by this job has Sentry |
…cking to TaskExecutionAttempt - Add AgentTaskLease CREATE TABLE to migration before FK that references it (fixes P3018 CI failure) - Remove AgentRunCostId column from TaskExecutionAttempt in migration - Remove AgentComputeDeposit and AgentRunCost models from schema (consolidated into TaskExecutionAttempt) - Migrate logAgentRun MCP tool from AgentRunCost.create to TaskExecutionAttempt.create - Remove getFundingStats MCP tool and its docs reference (model no longer exists) - Fix sync-managed-tasks ownerOrganizationId handling via connect/disconnect instead of scalar - Add earth-special-education.ts script for generating misinformation corrections with math Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…prevent 200 response Next.js statically pre-renders Server Component redirect() calls as a meta-refresh + client hop (200 OK) rather than a real 307. Same pattern that fixed /people/manage. Move /about -> /eos to the REDIRECTS array so it is handled at the infrastructure level. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary
Local verification
pnpm --filter @optimitron/treasury-prize exec hardhat test test/EarthOptimizationPoint.test.ts test/VoterPrizeTreasury.test.tsNODE_OPTIONS=--max-old-space-size=8192 pnpm --filter @optimitron/web run typecheck:fastgit diff --check(clean; CRLF warnings only)Review links
Summary by CodeRabbit
New Features
Updates
Bug Fixes / Reliability