From cc1a8fa65c61f016a4bdc13ead0beeff29fb35bc Mon Sep 17 00:00:00 2001 From: "Carina.Akaia.io" Date: Thu, 3 Oct 2024 23:16:47 +0000 Subject: [PATCH] Fix fee normalization --- .../interfaces/pot-factory.interfaces.ts | 2 +- src/common/contracts/potlock/pot-factory.ts | 20 ++++++-------- .../components/AccessControlList.tsx | 2 +- .../components/AccessControlListModal.tsx | 27 ++++++------------- src/modules/donation/models/schemas.ts | 23 ++++++++-------- src/modules/pot-editor/utils/normalization.ts | 4 +++ src/modules/pot/models/schemas.ts | 8 +++--- src/modules/pot/utils/validation.ts | 20 +++++++++----- 8 files changed, 52 insertions(+), 54 deletions(-) diff --git a/src/common/contracts/potlock/interfaces/pot-factory.interfaces.ts b/src/common/contracts/potlock/interfaces/pot-factory.interfaces.ts index 6cafb33f..b6799f6c 100644 --- a/src/common/contracts/potlock/interfaces/pot-factory.interfaces.ts +++ b/src/common/contracts/potlock/interfaces/pot-factory.interfaces.ts @@ -21,7 +21,7 @@ export type CustomSybilCheck = { weight: SybilProviderWeight; }; -export interface Config { +export interface PotFactoryConfig { owner: string; admins: string[]; protocol_fee_basis_points: number; diff --git a/src/common/contracts/potlock/pot-factory.ts b/src/common/contracts/potlock/pot-factory.ts index 3c67ba47..e87a5ddf 100644 --- a/src/common/contracts/potlock/pot-factory.ts +++ b/src/common/contracts/potlock/pot-factory.ts @@ -8,26 +8,18 @@ import { ByAccountId } from "@/common/types"; import { PotArgs, PotDeploymentResult, + PotFactoryConfig, } from "./interfaces/pot-factory.interfaces"; export type { PotDeploymentResult }; -/** - * Contract API - */ export const contractApi = naxiosInstance.contractApi({ contractId: POT_FACTORY_CONTRACT_ID, cache: new MemoryCache({ expirationTime: 5 }), // 10 seg }); -// READ METHODS - -type Config = { - require_whitelist: boolean; - whitelisted_deployers: string[]; -}; - -export const get_config = () => contractApi.view<{}, Config>("get_config"); +export const get_config = () => + contractApi.view<{}, PotFactoryConfig>("get_config"); export const calculate_min_deployment_deposit = (args: { args: PotArgs; @@ -36,7 +28,11 @@ export const calculate_min_deployment_deposit = (args: { .view("calculate_min_deployment_deposit", { args }) .then((amount) => Big(amount).plus(Big("20000000000000000000000")).toFixed(), - ); + ) + .catch((error) => { + console.error(error); + return undefined; + }); export const deploy_pot = async (args: { pot_args: PotArgs; diff --git a/src/modules/access-control/components/AccessControlList.tsx b/src/modules/access-control/components/AccessControlList.tsx index 826e441d..bf7fcaac 100644 --- a/src/modules/access-control/components/AccessControlList.tsx +++ b/src/modules/access-control/components/AccessControlList.tsx @@ -54,7 +54,7 @@ export const AccessControlList: React.FC = ({ <> {isEditingEnabled && } -
+
{accountList} {isEditingEnabled && ( diff --git a/src/modules/access-control/components/AccessControlListModal.tsx b/src/modules/access-control/components/AccessControlListModal.tsx index dc03a034..fd072465 100644 --- a/src/modules/access-control/components/AccessControlListModal.tsx +++ b/src/modules/access-control/components/AccessControlListModal.tsx @@ -110,12 +110,7 @@ export const AccessControlListModal = create(
- +
0 ? undefined : "none" }} > -
+
- {`${accountIds.length} Admins` + + {`${accountIds.length} Account(s)` + (selectedAccounts.length > 0 ? `, ${selectedAccounts.length} selected` : "")} @@ -176,7 +165,7 @@ export const AccessControlListModal = create( - Remove all selected + {"Remove all selected"}
@@ -202,7 +191,7 @@ export const AccessControlListModal = create( - Remove + {"Remove"} } diff --git a/src/modules/donation/models/schemas.ts b/src/modules/donation/models/schemas.ts index 4fc235ed..8dd96411 100644 --- a/src/modules/donation/models/schemas.ts +++ b/src/modules/donation/models/schemas.ts @@ -12,7 +12,6 @@ import { import { NEAR_TOKEN_DENOM } from "@/common/constants"; import { safePositiveNumber } from "@/common/lib"; -import { TOTAL_FEE_BASIS_POINTS } from "@/modules/core/constants"; import { TokenAvailableBalance } from "@/modules/token"; import { @@ -23,10 +22,6 @@ import { DonationAllocationStrategyEnum, DonationGroupAllocationStrategyEnum, } from "../types"; -import { - donationFeeBasisPointsToPercents, - donationFeePercentsToBasisPoints, -} from "../utils/converters"; import { isDonationAmountSufficient, isDonationMatchingPotSelected, @@ -39,15 +34,21 @@ export const donationTokenSchema = literal(NEAR_TOKEN_DENOM) export const donationAmount = safePositiveNumber; -export const donationFeeBasisPoints = preprocess( +/** + * # Heads up! + * + * The donation fee is stored in basis points, but the schema expects it to be a percentage. + * + * Thus make sure to convert it to percents before passing to the form + * and convert it back to basis points before passing to the contract. + */ +export const donationFee = preprocess( (value) => - typeof value === "string" - ? donationFeePercentsToBasisPoints(safePositiveNumber.parse(value)) - : value, + typeof value === "string" ? safePositiveNumber.parse(value) : value, safePositiveNumber, -).refine((basisPoints) => basisPoints <= TOTAL_FEE_BASIS_POINTS, { - message: `Fee cannot exceed ${donationFeeBasisPointsToPercents(TOTAL_FEE_BASIS_POINTS)}%.`, +).refine((percents) => percents < 100, { + message: `Fee must be less than 100%.`, }); export const donationSchema = object({ diff --git a/src/modules/pot-editor/utils/normalization.ts b/src/modules/pot-editor/utils/normalization.ts index 25e88062..7a260675 100644 --- a/src/modules/pot-editor/utils/normalization.ts +++ b/src/modules/pot-editor/utils/normalization.ts @@ -31,6 +31,7 @@ import { import { donationAmount, donationFeeBasisPointsToPercents, + donationFeePercentsToBasisPoints, } from "@/modules/donation"; import { PotInputs } from "@/modules/pot"; @@ -133,6 +134,9 @@ export const potInputsToPotArgs = ({ }, { + referral_fee_matching_pool_basis_points: donationFeePercentsToBasisPoints, + referral_fee_public_round_basis_points: donationFeePercentsToBasisPoints, + chef_fee_basis_points: donationFeePercentsToBasisPoints, application_start_ms: timestamp.parse, application_end_ms: timestamp.parse, public_round_start_ms: timestamp.parse, diff --git a/src/modules/pot/models/schemas.ts b/src/modules/pot/models/schemas.ts index 54f7823c..946076f6 100644 --- a/src/modules/pot/models/schemas.ts +++ b/src/modules/pot/models/schemas.ts @@ -4,7 +4,7 @@ import { futureTimestamp, safePositiveNumber } from "@/common/lib"; import { validAccountIdOrNothing } from "@/modules/core"; import { donationAmount, - donationFeeBasisPoints, + donationFee, donationFeeBasisPointsToPercents, } from "@/modules/donation"; @@ -149,7 +149,7 @@ export const potSchema = object({ .optional() .describe("Whether the projects must have Nadabot verification."), - referral_fee_matching_pool_basis_points: donationFeeBasisPoints + referral_fee_matching_pool_basis_points: donationFee .refine(isPotMatchingPoolReferralFeeValid, { message: `Cannot exceed ${donationFeeBasisPointsToPercents( POT_MAX_REFERRAL_FEE_MATCHING_POOL_BASIS_POINTS, @@ -157,7 +157,7 @@ export const potSchema = object({ }) .describe("Matching pool referral fee in basis points."), - referral_fee_public_round_basis_points: donationFeeBasisPoints + referral_fee_public_round_basis_points: donationFee .refine(isPotPublicRoundReferralFeeValid, { message: `Cannot exceed ${donationFeeBasisPointsToPercents( POT_MAX_REFERRAL_FEE_PUBLIC_ROUND_BASIS_POINTS, @@ -165,7 +165,7 @@ export const potSchema = object({ }) .describe("Public round referral fee in basis points."), - chef_fee_basis_points: donationFeeBasisPoints + chef_fee_basis_points: donationFee .refine(isPotChefFeeValid, { message: `Cannot exceed ${donationFeeBasisPointsToPercents( POT_MAX_CHEF_FEE_BASIS_POINTS, diff --git a/src/modules/pot/utils/validation.ts b/src/modules/pot/utils/validation.ts index 4ffc8734..7334d234 100644 --- a/src/modules/pot/utils/validation.ts +++ b/src/modules/pot/utils/validation.ts @@ -1,3 +1,5 @@ +import { donationFeeBasisPointsToPercents } from "@/modules/donation"; + import { POT_MAX_APPROVED_PROJECTS, POT_MAX_CHEF_FEE_BASIS_POINTS, @@ -36,11 +38,17 @@ export const isPotCooldownPeriodValid = (cooldown_period_ms: number) => export const isPotMaxProjectsValid = (max_projects: number) => max_projects <= POT_MAX_APPROVED_PROJECTS; -export const isPotMatchingPoolReferralFeeValid = (basisPoints: number) => - basisPoints <= POT_MAX_REFERRAL_FEE_MATCHING_POOL_BASIS_POINTS; +export const isPotMatchingPoolReferralFeeValid = (percents: number) => + percents <= + donationFeeBasisPointsToPercents( + POT_MAX_REFERRAL_FEE_MATCHING_POOL_BASIS_POINTS, + ); -export const isPotPublicRoundReferralFeeValid = (basisPoints: number) => - basisPoints <= POT_MAX_REFERRAL_FEE_PUBLIC_ROUND_BASIS_POINTS; +export const isPotPublicRoundReferralFeeValid = (percents: number) => + percents <= + donationFeeBasisPointsToPercents( + POT_MAX_REFERRAL_FEE_PUBLIC_ROUND_BASIS_POINTS, + ); -export const isPotChefFeeValid = (basisPoints: number) => - basisPoints <= POT_MAX_CHEF_FEE_BASIS_POINTS; +export const isPotChefFeeValid = (percents: number) => + percents <= donationFeeBasisPointsToPercents(POT_MAX_CHEF_FEE_BASIS_POINTS);