diff --git a/apps/dashboard/src/@/components/blocks/distribution-chart.tsx b/apps/dashboard/src/@/components/blocks/distribution-chart.tsx index 186f8671cf4..2c9b8ea1c5c 100644 --- a/apps/dashboard/src/@/components/blocks/distribution-chart.tsx +++ b/apps/dashboard/src/@/components/blocks/distribution-chart.tsx @@ -10,6 +10,7 @@ type DistributionBarChartProps = { segments: Segment[]; title: string; }; + export function DistributionBarChart(props: DistributionBarChartProps) { const totalPercentage = props.segments.reduce( (sum, segment) => sum + segment.percent, @@ -59,7 +60,13 @@ export function DistributionBarChart(props: DistributionBarChartProps) { backgroundColor: segment.color, }} /> -

+

100 || segment.percent < 0) && + "text-destructive-text", + )} + > {segment.label}: {segment.percent}%

diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/create-token-card.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/create-token-card.tsx index fbcf382cda3..f46166dce68 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/create-token-card.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/create-token-card.tsx @@ -15,6 +15,7 @@ export function StepCard(props: { | undefined | { type: "submit"; + disabled?: boolean; } | { type: "custom"; @@ -56,6 +57,7 @@ export function StepCard(props: { variant="default" className="gap-2" type="submit" + disabled={props.nextButton.disabled} onClick={() => { trackEvent( getStepCardTrackingData({ diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/distribution/token-distribution.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/distribution/token-distribution.tsx index eb1fcc0e63d..b35585c9e89 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/distribution/token-distribution.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/distribution/token-distribution.tsx @@ -26,6 +26,7 @@ export function TokenDistributionFieldset(props: { tokenSymbol: string | undefined; }) { const { form } = props; + const distributionError = getDistributionError(form); return (
@@ -38,6 +39,7 @@ export function TokenDistributionFieldset(props: { }} nextButton={{ type: "submit", + disabled: !!distributionError, }} >
@@ -56,9 +58,17 @@ export function TokenDistributionFieldset(props: {
- +
+ + + {distributionError && ( +
+ {distributionError} +
+ )} +
@@ -74,6 +84,36 @@ export function TokenDistributionFieldset(props: { ); } +function getDistributionError(form: TokenDistributionForm) { + const supply = Number(form.watch("supply")); + const totalAirdrop = form.watch("airdropAddresses").reduce((sum, addr) => { + return sum + SafeNumber(addr.quantity); + }, 0); + + if (totalAirdrop > supply) { + return "Total airdrop quantity exceeds total supply"; + } + + const saleSupplyPercentage = SafeNumber( + form.watch("saleAllocationPercentage"), + ); + + const saleSupply = (saleSupplyPercentage / 100) * supply; + const ownerSupply = Math.max(supply - totalAirdrop - saleSupply, 0); + const totalSumOfSupply = totalAirdrop + saleSupply + ownerSupply; + + if (totalSumOfSupply > supply) { + return "Token distribution exceeds total supply"; + } + + return undefined; +} + +function SafeNumber(value: string) { + const num = Number(value); + return Number.isNaN(num) ? 0 : num; +} + export function TokenDistributionBarChart(props: { distributionFormValues: TokenDistributionFormValues; }) { @@ -87,7 +127,8 @@ export function TokenDistributionBarChart(props: { const salePercentage = Number( props.distributionFormValues.saleAllocationPercentage, ); - const ownerPercentage = 100 - airdropPercentage - salePercentage; + + const ownerPercentage = Math.max(100 - airdropPercentage - salePercentage, 0); const tokenAllocations: Segment[] = [ {