Allow bypassing referrer fee in all donation scenarios#400
Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
WalkthroughThis update introduces explicit handling and bypass options for referral fees in donation and matching pool contribution flows, refines campaign form token selection logic, and improves fee calculation consistency. Several schema and hook types are extended for new fields, and UI components are updated to reflect these changes. Minor improvements to form structure and profile ownership logic are also included. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant DonationForm
participant FeeBreakdownHook
participant WalletSession
User->>DonationForm: Fill form (amount, bypass options)
DonationForm->>WalletSession: Get referrerAccountId
DonationForm->>FeeBreakdownHook: Pass amount, bypassProtocolFee, bypassReferralFee, referrerAccountId
FeeBreakdownHook-->>DonationForm: Return fee amounts (protocol, referral, etc.)
DonationForm-->>User: Show fee breakdown with bypass options
User->>DonationForm: Submit
DonationForm->>Backend: Submit donation with selected bypass options
sequenceDiagram
participant User
participant MatchingPoolForm
participant FeeCalculation
participant WalletSession
User->>MatchingPoolForm: Fill form (amount, bypass fee checkboxes)
MatchingPoolForm->>WalletSession: Get referrerAccountId
MatchingPoolForm->>FeeCalculation: Pass amount, bypassReferralFee, bypassProtocolFee, etc.
FeeCalculation-->>MatchingPoolForm: Return calculated fees
MatchingPoolForm-->>User: Show updated fee breakdown
User->>MatchingPoolForm: Submit
MatchingPoolForm->>Backend: Submit contribution with bypass flags
Possibly related PRs
Suggested reviewers
Poem
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
There was a problem hiding this comment.
Actionable comments posted: 2
🔭 Outside diff range comments (1)
src/features/donation/hooks/form.ts (1)
222-229: 🛠️ Refactor suggestion
⚠️ Potential issueFix missing dependency in useCallback.
The
onSubmitcallback usesinputs.bypassReferralFeebut the dependency array doesn't include this field, which could lead to stale closure issues.Apply this diff to fix the dependency array:
- [campaign?.recipient, isCampaignDonation, onSubmitError, params, viewer?.referrerAccountId], + [campaign?.recipient, isCampaignDonation, onSubmitError, params, viewer?.referrerAccountId],Note: Since
inputsis the parameter of the callback function, it doesn't need to be in the dependency array. However, ensure that all external variables used within the callback are properly included in the dependencies.
🧹 Nitpick comments (1)
src/entities/campaign/components/CampaignForm.tsx (1)
72-74: Address the performance TODO comment.The existing TODO comment highlights a significant performance issue where the effect runs on every render, which can substantially impact UX and performance. This should be prioritized for refactoring.
Would you like me to help implement the
useEnhancedFormapproach or create an issue to track this performance optimization task?
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (14)
.env.example(1 hunks)src/common/lib/format.ts(1 hunks)src/entities/campaign/components/CampaignForm.tsx(3 hunks)src/entities/campaign/hooks/forms.ts(4 hunks)src/features/donation/components/modal-confirmation-screen.tsx(6 hunks)src/features/donation/components/single-recipient-success.tsx(3 hunks)src/features/donation/components/summary.tsx(1 hunks)src/features/donation/hooks/breakdowns.ts(4 hunks)src/features/donation/hooks/form.ts(2 hunks)src/features/donation/models/schemas.ts(1 hunks)src/features/matching-pool-contribution/components/MatchingPoolContributionModal.tsx(9 hunks)src/features/matching-pool-contribution/hooks/forms.ts(3 hunks)src/features/matching-pool-contribution/model/schemas.ts(1 hunks)src/layout/profile/components/summary.tsx(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (5)
src/features/donation/components/single-recipient-success.tsx (1)
src/common/lib/format.ts (1)
indivisibleUnitsToFloat(16-20)
src/entities/campaign/components/CampaignForm.tsx (1)
src/common/constants.ts (1)
NATIVE_TOKEN_ID(114-114)
src/features/matching-pool-contribution/hooks/forms.ts (3)
src/features/matching-pool-contribution/model/schemas.ts (1)
MatchingPoolContributionInputs(14-14)src/common/constants.ts (1)
FIFTY_TGAS(135-135)src/common/lib/format.ts (1)
parseNearAmount(7-7)
src/entities/campaign/hooks/forms.ts (2)
src/common/types.ts (2)
ByCampaignId(118-120)TokenId(101-101)src/common/constants.ts (1)
NATIVE_TOKEN_ID(114-114)
src/features/donation/hooks/breakdowns.ts (6)
src/features/donation/types.ts (2)
WithTotalAmount(45-47)DonationBreakdown(49-62)src/features/donation/models/schemas.ts (1)
DonationSubmitParams(72-76)src/common/contracts/core/donation/index.ts (1)
donationContractHooks(7-7)src/common/contracts/core/utils.ts (2)
feePercentsToBasisPoints(8-9)feeBasisPointsToPercents(5-6)src/common/contracts/core/constants.ts (1)
TOTAL_FEE_BASIS_POINTS(1-1)src/common/constants.ts (1)
NATIVE_TOKEN_ID(114-114)
🔇 Additional comments (40)
.env.example (2)
1-1: Consistent comment marker update for Deployment environment
The##*prefix replaces the old##?marker, standardizing section headers without impacting any environment variables.
8-8: Consistent comment marker update for Debugging and testing section
Similarly, updating to##*maintains uniformity across the file. No functional/configuration changes introduced.src/layout/profile/components/summary.tsx (1)
124-124: Excellent security improvement!Adding the
viewer.isSignedIncheck to the ownership determination logic is a solid security enhancement. This ensures that profile ownership requires both proper authentication AND account ID matching, preventing potential scenarios where someone could manipulate account IDs without being properly signed in.src/entities/campaign/components/CampaignForm.tsx (3)
39-39: Good: Explicit ftId parameter passing.The explicit passing of
ftIdparameter touseCampaignFormimproves clarity and aligns with the hook's updated signature. The fallback logicexistingData?.ft_id ?? NATIVE_TOKEN_IDis appropriate.
76-78: Improved: More precise ft_id synchronization logic.The updated condition
isNonNullish(existingData.ft_id) && ftId !== existingData.ft_idis more precise than the previous implementation, preventing unnecessary form resets when the existing data doesn't have a specific token ID.
322-322: Good: Disable token selection during updates.Disabling the TokenSelector during campaign updates (
isUpdate) is a sensible UX decision that prevents token changes after campaign creation, which aligns with the backend logic that omitsft_idfrom update operations.src/entities/campaign/hooks/forms.ts (4)
11-11: Good: Updated import types for better type safety.The import changes from
CampaignIdtoByCampaignIdand addition ofTokenIdtype improve type safety and align with the updated parameter structure.
20-24: Well-designed: Flexible parameter type and function signature.The new
CampaignFormParamstype that extendsPartial<ByCampaignId>and adds optionalftIdcreates a clean, flexible interface. The updated function signature properly supports both campaign creation and updates.
35-35: Good: Parameterized default token ID.Using
ftId ?? NATIVE_TOKEN_IDas the default value allows the form to respect the passed token ID while maintaining a sensible fallback. This supports the use case where existing campaigns may have different token types.
194-194: Excellent: Conditional ft_id inclusion logic.The conditional inclusion of
ft_idonly for new campaigns (isNewCampaign) is well-designed. This prevents token type changes during campaign updates, which makes sense from both a business logic and data integrity perspective.src/features/donation/models/schemas.ts (1)
61-61: LGTM! Consistent schema enhancement for referral fee bypass.The addition of
bypassReferralFeefield follows the established pattern of other fee bypass flags and correctly defaults tofalsefor backward compatibility. This change aligns perfectly with the PR objective to allow bypassing referrer fees in donation scenarios.src/features/donation/components/summary.tsx (1)
46-51: Improved fee display ordering.Moving the "Referrer Fee" entry to appear after "Protocol Fee" creates a more logical flow in the fee breakdown display. This UI improvement enhances user experience without affecting any functionality.
src/common/lib/format.ts (1)
20-20:Details
❓ Verification inconclusive
Verify impact of increased precision on existing consumers.
Increasing the default fractional digits from 2 to 4 improves precision for fee calculations, which supports the referral fee bypass functionality. However, this is a global change that affects all consumers of
indivisibleUnitsToFloat.Please ensure that existing consumers can handle the increased precision or explicitly specify their required precision.
🏁 Script executed:
#!/bin/bash # Description: Find all usages of indivisibleUnitsToFloat to assess impact of precision change # Expected: Most usages should be compatible, but some might depend on 2-digit precision echo "Searching for all usages of indivisibleUnitsToFloat..." rg -A 3 -B 1 "indivisibleUnitsToFloat" --type ts --type tsx echo -e "\nSearching for usages that might specify custom fracDigits..." rg -A 2 "indivisibleUnitsToFloat.*,.*," --type ts --type tsxLength of output: 434
🏁 Script executed:
#!/bin/bash # Re-run usage search without relying on ripgrep’s built-in type filters echo "1) All usages of indivisibleUnitsToFloat in .ts/.tsx files:" rg -g '*.ts' -g '*.tsx' -n "indivisibleUnitsToFloat" echo -e "\n2) Usages passing a custom fracDigits argument:" # Match calls where a second numeric literal is supplied rg -g '*.ts' -g '*.tsx' -n -e 'indivisibleUnitsToFloat\([^,]*,\s*[0-9]'Length of output: 5523
Verify global default precision change
All 30+ existing calls to
indivisibleUnitsToFloat(amount, decimals)will now format with 4 decimal places by default. No consumers currently pass a customfracDigits, so this change affects every usage.• Representative call sites:
src/entities/voting-round/components/leaderboard.tsxsrc/features/donation/hooks/form.ts& related success componentssrc/entities/campaign/components/*src/entities/_shared/token/hooks/data.ts&value-summary.tsxPlease review any downstream UI layouts, exports, or integrations that may assume 2-digit precision and either confirm that 4 decimals is acceptable everywhere or explicitly pass a 2-digit
fracDigitswhere needed.src/features/donation/components/single-recipient-success.tsx (2)
22-22: Good cleanup of unused import.Removing the unused
rootPathnamesimport improves code cleanliness.
106-109: Consistent variable renaming improves clarity.The renaming from
referralFeeFinalAmountFloattoreferralFeeAmountFloatremoves redundant terminology and aligns with the referral fee bypass functionality. The corresponding parameter update maintains consistency throughout the component.Also applies to: 117-117
src/features/donation/hooks/form.ts (1)
86-88: LGTM: New bypass fields added correctly.The addition of
bypassProtocolFeeandbypassReferralFeeboolean fields with default values offalseis consistent with the PR objective to allow bypassing referrer fees.src/features/matching-pool-contribution/model/schemas.ts (3)
1-1: Good refactor: Using named imports for better readability.The change from importing the entire
znamespace to individual validators improves code readability and potentially reduces bundle size.
10-10: LGTM: New bypass referral fee field added.The addition of
bypassReferralFeeboolean field with defaultfalseis consistent with the PR objective and aligns with similar changes in the donation schema.
14-14:Details
✅ Verification successful
Verify the FromSchema type utility.
The change from
z.infertoFromSchemaappears to be part of a broader refactoring. Ensure thatFromSchemaprovides the same type inference capabilities and is properly implemented.
🏁 Script executed:
#!/bin/bash # Description: Verify the FromSchema utility type and its usage # Expected: Find the definition of FromSchema and check if it's properly typed # Search for FromSchema definition ast-grep --pattern 'type FromSchema$$$' # Search for other usages of FromSchema vs z.infer to check consistency rg -A 2 -B 2 "FromSchema|z\.infer"Length of output: 11407
FromSchema is a direct alias for z.infer; type inference remains correct.
Verified in
src/common/types.tsthat:
export type { infer as FromSchema } from "zod";This means
FromSchema<typeof matchingPoolFundingSchema>is identical toz.infer<typeof matchingPoolFundingSchema>. No further action required.src/features/matching-pool-contribution/components/MatchingPoolContributionModal.tsx (4)
62-76: Good separation of fee calculation logic.The separation of initial fee amounts from final amounts (considering bypass flags) improves code clarity and makes the fee calculation logic easier to understand and maintain.
149-171: Well-implemented conditional referral fee bypass UI.The conditional rendering of the referral fee bypass checkbox (only when
referrerFeePercentage > 0) is appropriate and prevents unnecessary UI clutter when there's no referral fee to bypass.
88-89: Good form structure improvement.The addition of a native
<form>element nested within the existingFormcomponent improves form semantics and accessibility.
199-213: Standardized fee label capitalization.The standardization of fee labels ("Protocol Fee," "Chef Fee," and "Referrer Fee") improves UI consistency.
src/features/matching-pool-contribution/hooks/forms.ts (3)
5-5: Import type change looks correct.The change from
FormSubmitHandlertoSubmitHandlerappears to be a standard React Hook Form type import update.
25-32: Conditional referrer logic implemented correctly.The logic to conditionally set
referrer_idtoundefinedwhenbypassReferralFeeis true, otherwise useviewer.referrerAccountId, correctly implements the bypass functionality.
28-32:Details
✅ Verification successful
Verify form data structure change.
The change from accessing nested
dataproperties (e.g.,formData.data.message) to direct properties (e.g.,formData.message) suggests a significant change in the form data structure. Ensure this aligns with the schema updates and doesn't break existing functionality.Also applies to: 39-39, 78-78
🏁 Script executed:
#!/bin/bash # Description: Verify the form data structure and its usage # Expected: Check how MatchingPoolContributionInputs type is structured # Search for the schema definition and type structure ast-grep --pattern 'const matchingPoolFundingSchema = $$$' # Search for other usages of form data in matching pool contribution files rg -A 3 -B 3 "formData\." src/features/matching-pool-contribution/Length of output: 3387
Form data schema verified
ThematchingPoolFundingSchemainsrc/features/matching-pool-contribution/model/schemas.tsdeclaresmessage,amountNEAR,bypassProtocolFee,bypassReferralFee, andbypassChefFeeas top-level properties, so usingformData.message,formData.amountNEAR, etc., is correct and aligns with the schema.src/features/donation/components/modal-confirmation-screen.tsx (7)
26-26: LGTM: Clean wallet session integration.The import of
useWalletUserSessionis appropriate for accessing wallet user data needed for referral fee handling.
49-49: LGTM: Proper wallet user session usage.The wallet user session hook is correctly instantiated for accessing referrer account information.
53-67: LGTM: Form watch array properly extended.The addition of
bypassReferralFeeto the watched form fields is consistent with the existing pattern and necessary for reactive UI updates.
93-99: LGTM: Allocation breakdown hook integration.The hook correctly receives the new
referrerAccountIdfrom wallet user session andbypassReferralFeeflag. The parameter ordering matches the hook's expected interface.
148-172: LGTM: Consistent fee bypass UI pattern.The protocol fee bypass checkbox follows the established pattern and is properly gated by
isFeeBypassAllowed.
198-215: LGTM: Chef fee bypass properly gated.The chef fee bypass checkbox correctly includes the
isFeeBypassAllowedcondition alongside existing pot donation checks.
217-239: LGTM: Campaign creator fee bypass properly gated.The campaign creator fee bypass checkbox correctly includes the
isFeeBypassAllowedcondition alongside existing campaign and fee percentage checks.src/features/donation/hooks/breakdowns.ts (7)
3-8: LGTM: Clean import additions.The new imports for
Pot,donationContractHooks, and fee conversion utilities are appropriate for the enhanced functionality.
17-26: LGTM: Type definition properly extended.The
DonationAllocationParamstype correctly includes the newbypassReferralFeeandreferrerAccountIdparameters, maintaining consistency with the existing pattern.
35-39: LGTM: Parameter defaults are appropriate.The
bypassReferralFeeparameter has a sensible default offalse, maintaining backward compatibility.
40-40: LGTM: Improved data fetching pattern.Using
donationContractHooks.useConfig()provides better integration with the donation contract system.
49-67: LGTM: Protocol fee calculation logic is sound.The refactored protocol fee calculation correctly handles both final amounts and percentage-based calculations. The logic properly falls back to basis points when final amounts aren't provided.
74-99: LGTM: Referral fee calculation with bypass support.The referral fee calculation logic correctly:
- Handles the bypass flag to set fee to 0
- Calculates initial basis points from campaign, pot, or donation config
- Supports final amount overrides with proper percentage calculations
- Maintains consistency with the protocol fee pattern
150-150: LGTM: Storage fee approximation logic.The storage fee approximation correctly differentiates between NEAR native tokens and other tokens with appropriate fee estimates.
* Implement campaign creator fee bypass mechanism * Fix project allocation calculation * Apply code review suggestion * Allow bypassing referrer fee in all donation scenarios (#400) * hotfix: Provide correct referrer account id * hotfix: Respect campaign's `allow_fee_avoidance` * hotfix: Pass campaign creator id to campaign FT donation flow * Stabilize fee calculation * Disable profile setup on staging * Use Pinata for campaign banner uploads (#408) * Reduce SWR revalidation rate for contracts * Reduce SWR revalidation rate for contracts * hotfix: Adjust campaign settings form hydration condition * hotfix: Don't display error for stale data & Remove console spam * Change campaigns overview heading * Change campaigns overview heading --------- Co-authored-by: Ebube111 <ebubeagwaze@gmail.com>
Summary by CodeRabbit
New Features
Improvements
Bug Fixes
Chores
Documentation