Skip to content

Commit

Permalink
Merge pull request #46 from bleu/jean/create-vesting-external-review
Browse files Browse the repository at this point in the history
Create vesting external review pt1
  • Loading branch information
JeanNeiverth authored Oct 25, 2024
2 parents 84022d5 + 001e169 commit 5585f8f
Show file tree
Hide file tree
Showing 19 changed files with 137 additions and 95 deletions.
Binary file modified apps/claim-vesting/public/llama-pay-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 0 additions & 4 deletions apps/create-vesting/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@
"@bleu/utils": "workspace:*",
"@cowprotocol/cow-sdk": "^5.5.1",
"@cowprotocol/hook-dapp-lib": "1.1.0-RC0",
"@fortawesome/fontawesome-svg-core": "^6.6.0",
"@fortawesome/free-regular-svg-icons": "^6.6.0",
"@fortawesome/free-solid-svg-icons": "^6.6.0",
"@fortawesome/react-fontawesome": "^0.2.2",
"@hookform/resolvers": "3.9.0",
"@radix-ui/react-icons": "1.3.0",
"@uniswap/sdk-core": "5.4.0",
Expand Down
Binary file modified apps/create-vesting/public/llama-pay-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 0 additions & 3 deletions apps/create-vesting/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ import Head from "next/head";
import type * as React from "react";
import { FormContextProvider } from "#/context/form";
import { TokenContextProvider } from "#/context/token";
import "@fortawesome/fontawesome-svg-core/styles.css";
import { config } from "@fortawesome/fontawesome-svg-core";
config.autoAddCss = false;

export default function Layout({ children }: { children: React.ReactNode }) {
return (
Expand Down
29 changes: 20 additions & 9 deletions apps/create-vesting/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export default function Page() {
const vestAllFromAccount = useWatch({ control, name: "vestAllFromAccount" });
const amount = useWatch({ control, name: "amount" });
const recipient = useWatch({ control, name: "recipient" });
const period = useWatch({ control, name: "period" });

const {
userBalanceFloat,
Expand Down Expand Up @@ -63,6 +64,7 @@ export default function Page() {
setValue("vestAllFromAccount", data.vestAllFromAccount);
setValue("recipient", data.recipient);
setValue("period", data.period);
setValue("periodScale", data.periodScale);
setValue("amount", data.amount);
setIsEditHookLoading(false);
}
Expand All @@ -76,16 +78,22 @@ export default function Page() {
isEditHookLoading,
]);

if (context?.hookToEdit && isEditHookLoading) {
loadHookInfo();
}

if (!context)
if (!context || (context?.hookToEdit && isEditHookLoading)) {
if (context?.hookToEdit && isEditHookLoading) loadHookInfo();
return (
<div className="flex items-center justify-center w-full h-full bg-transparent text-color-text-paper">
<Spinner size="lg" style={{ color: "gray" }} />
<Spinner
size="lg"
style={{
width: "25px",
height: "25px",
color: "gray",
animation: "spin 2s linear infinite",
}}
/>
</div>
);
}

if (!context.account)
return (
Expand All @@ -97,7 +105,7 @@ export default function Page() {
if (!context?.orderParams?.buyAmount || !context?.orderParams?.buyAmount)
return (
<span className="block w-full mt-10 text-center">
Provide a buy token and amount in swap
Please specify your swap order first
</span>
);

Expand All @@ -123,14 +131,15 @@ export default function Page() {
const buttonDisabled =
isOutOfFunds ||
!recipient ||
!period ||
(!amount && vestUserInput) ||
isSubmitting ||
isSubmitSuccessful;

const isBuildingHook = isSubmitting || isSubmitSuccessful;

return (
<div className="flex flex-col flex-wrap w-full flex-grow gap-4 mb-[-16px]">
<div className="flex flex-col flex-wrap w-full flex-grow gap-4">
<div className="w-full flex flex-col flex-grow gap-4 items-start justify-start text-center">
<RecipientInput />
<PeriodInput />
Expand All @@ -142,8 +151,9 @@ export default function Page() {
amountPreviewFullDecimals={amountPreviewFullDecimals}
formattedUserBalance={formattedUserBalance}
userBalanceFloat={userBalanceFloat}
shouldEnableMaxSelector={vestUserInput}
/>
<div className="flex flex-col gap-y-2">
<div className="w-full flex flex-col gap-y-2">
<VestAllFromSwapCheckbox />
<VestAllFromAccountCheckbox />
<VestUserInputCheckbox />
Expand All @@ -155,6 +165,7 @@ export default function Page() {
isOutOfFunds={isOutOfFunds}
isBuildingHook={isBuildingHook}
disabled={buttonDisabled}
tokenSymbol={token?.symbol}
/>
</div>
);
Expand Down
3 changes: 2 additions & 1 deletion apps/create-vesting/src/app/signing/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,12 @@ export default function Page() {
hookInfo?.permitData?.map((permit) => {
return {
label: `Approve ${permit.tokenSymbol}`,
description: `Approve proxy to manage your ${permit.tokenSymbol} (${permit.tokenAddress})`,
description: `Approve proxy to spend the ${permit.tokenSymbol} token`,
id: `approve-${permit.tokenAddress}`,
callback: async () => {
await permitCallback(permit);
},
tooltipText: permit.tokenAddress,
};
}) || [];
return [
Expand Down
4 changes: 4 additions & 0 deletions apps/create-vesting/src/components/AmountInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export const AmountInput = ({
amountPreviewFullDecimals,
formattedUserBalance,
userBalanceFloat,
shouldEnableMaxSelector,
}: {
token: Token | undefined;
vestAllFromSwap: boolean;
Expand All @@ -17,11 +18,13 @@ export const AmountInput = ({
amountPreviewFullDecimals: string | undefined;
formattedUserBalance: string | undefined;
userBalanceFloat: number | undefined;
shouldEnableMaxSelector: boolean;
}) => {
return (
<TokenAmountInput
name="amount"
type="number"
inputMode="decimal"
step={`0.${"0".repeat(token?.decimals ? token?.decimals - 1 : 8)}1`}
max="1000000000000"
token={token}
Expand All @@ -33,6 +36,7 @@ export const AmountInput = ({
disabledValueFullDecimals={amountPreviewFullDecimals}
userBalance={formattedUserBalance}
userBalanceFullDecimals={String(userBalanceFloat)}
shouldEnableMaxSelector={shouldEnableMaxSelector}
validation={{
setValueAs: (v) => (v === "" ? undefined : Number(v)),
required: !(vestAllFromAccount || vestAllFromSwap),
Expand Down
7 changes: 6 additions & 1 deletion apps/create-vesting/src/components/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,21 @@ export const Button = ({
isOutOfFunds,
isBuildingHook,
disabled,
tokenSymbol,
}: {
context: HookDappContextAdjusted;
isOutOfFunds: boolean;
isBuildingHook: boolean;
disabled: boolean;
tokenSymbol?: string | undefined;
}) => {
return (
<ButtonPrimary type="submit" disabled={disabled}>
<ButtonText
context={context}
isOutOfFunds={isOutOfFunds}
isBuildingHook={isBuildingHook}
tokenSymbol={tokenSymbol}
/>
</ButtonPrimary>
);
Expand All @@ -30,16 +33,18 @@ const ButtonText = ({
context,
isOutOfFunds,
isBuildingHook,
tokenSymbol,
}: {
context: HookDappContextAdjusted;
isOutOfFunds: boolean;
isBuildingHook: boolean;
tokenSymbol?: string | undefined;
}) => {
if (isOutOfFunds)
return (
<span className="flex items-center justify-center gap-2">
<ExclamationTriangleIcon className="w-6 h-6" />
You won't have enough funds
Insufficient {tokenSymbol ? `${tokenSymbol} ` : ""}balance
</span>
);

Expand Down
6 changes: 3 additions & 3 deletions apps/create-vesting/src/components/PeriodInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ export const PeriodInput = () => {
namePeriodValue="period"
namePeriodScale="periodScale"
type="number"
min="0.000000001"
step="0.000000001"
min="1"
step="1"
max="1000000000000"
label="Vesting Period"
validation={{ valueAsNumber: true, required: true }}
onKeyDown={(e) =>
["e", "E", "+", "-"].includes(e.key) && e.preventDefault()
["e", "E", "+", "-", ".", ","].includes(e.key) && e.preventDefault()
}
/>
);
Expand Down
4 changes: 2 additions & 2 deletions apps/create-vesting/src/hooks/useFormatVariables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,15 @@ export const useFormatVariables = ({
const formattedUserBalance = useMemo(
() =>
userBalanceFloat !== undefined
? formatNumber(userBalanceFloat, 6, "decimal", "standard", 0.000001)
? formatNumber(userBalanceFloat, 4, "decimal", "standard", 0.0001)
: "",
[userBalanceFloat],
);

const formattedSwapAmount = useMemo(
() =>
swapAmountFloat !== undefined
? formatNumber(swapAmountFloat, 6, "decimal", "standard", 0.000001)
? formatNumber(swapAmountFloat, 4, "decimal", "standard", 0.0001)
: "",
[swapAmountFloat],
);
Expand Down
47 changes: 39 additions & 8 deletions apps/create-vesting/src/utils/decodeCalldata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,24 @@ import {
} from "@bleu/utils/transactionFactory";
import { type DecodeFunctionDataReturnType, decodeFunctionData } from "viem";
import { scaleToSecondsMapping } from "./scaleToSecondsMapping";
import type { CreateVestingFormData } from "./schema";
import { type CreateVestingFormData, periodScaleOptions } from "./schema";

function recoverPeriodFieldFromSeconds(periodInSeconds: number) {
let largestScaleThatFitsValue: (typeof periodScaleOptions)[number] =
periodScaleOptions[0];
for (const scale of periodScaleOptions) {
if (periodInSeconds % scaleToSecondsMapping[scale] === 0) {
largestScaleThatFitsValue = scale;
} else {
break;
}
}

return {
period: periodInSeconds / scaleToSecondsMapping[largestScaleThatFitsValue],
periodScale: largestScaleThatFitsValue,
};
}

export const decodeCalldata = async (
string: `0x${string}`,
Expand Down Expand Up @@ -55,10 +72,15 @@ const decodeVestFromUserInput = (
const args = createVestingData.args;
if (!args) throw new Error("decode has no args");

const { period, periodScale } = recoverPeriodFieldFromSeconds(
//@ts-ignore
Number(args[3]),
);

result.recipient = args[1] as string;
result.amount = Number(args[2]) / 10 ** tokenDecimals;
result.period = Number(args[3]) / scaleToSecondsMapping.Day;
result.periodScale = "Day";
result.period = period;
result.periodScale = periodScale;
result.vestUserInput = true;
result.vestAllFromSwap = false;
result.vestAllFromAccount = false;
Expand Down Expand Up @@ -87,12 +109,16 @@ const decodeVestAllFromSwap = (
if (args[1].length !== 4)
throw new Error("type of vesting was vestAllFromAccount");

const { period, periodScale } = recoverPeriodFieldFromSeconds(
//@ts-ignore
Number.parseInt(args[1][3]),
);

//@ts-ignore
result.recipient = `0x${args[1][2].slice(-40)}` as string;
result.amount = undefined;
//@ts-ignore
result.period = Number.parseInt(args[1][3]) / scaleToSecondsMapping.Day;
result.periodScale = "Day";
result.period = period;
result.periodScale = periodScale;
result.vestUserInput = false;
result.vestAllFromSwap = true;
result.vestAllFromAccount = false;
Expand All @@ -116,12 +142,17 @@ const decodeVestAllFromAccount = (
//@ts-ignore
if (args[1].length !== 6) throw new Error("Unknown type of transaction");

const { period, periodScale } = recoverPeriodFieldFromSeconds(
//@ts-ignore
Number.parseInt(args[1][4]),
);

//@ts-ignore
result.recipient = `0x${args[1][3].slice(-40)}` as string;
result.amount = undefined;
//@ts-ignore
result.period = Number.parseInt(args[1][4]) / scaleToSecondsMapping.Day;
result.periodScale = "Day";
result.period = period;
result.periodScale = periodScale;
result.vestUserInput = false;
result.vestAllFromSwap = false;
result.vestAllFromAccount = true;
Expand Down
2 changes: 2 additions & 0 deletions apps/create-vesting/src/utils/scaleToSecondsMapping.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export const scaleToSecondsMapping = {
Minute: 60,
Hour: 60 * 60,
Day: 24 * 60 * 60,
Week: 7 * 24 * 60 * 60,
Month: 30 * 24 * 60 * 60,
Expand Down
10 changes: 8 additions & 2 deletions apps/create-vesting/src/utils/schema.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { isAddress } from "viem";
import { z } from "zod";

export const periodScaleOptions = ["Day", "Week", "Month"];
export const periodScaleOptions = [
"Minute",
"Hour",
"Day",
"Week",
"Month",
] as const;

const isValidRecipient = (recipient: string) => {
// better ENS validation is performed on form submit
Expand All @@ -17,7 +23,7 @@ export const createVestingSchema = z
period: z
.number({ message: "Invalid period" })
.gt(0, "Period must be greater than 0"),
periodScale: z.enum(["Day", "Week", "Month"]),
periodScale: z.enum(periodScaleOptions),
amount: z
.number({ message: "Invalid amount" })
.gt(0, "Amount must be greater than 0")
Expand Down
5 changes: 4 additions & 1 deletion packages/cow-hooks-ui/src/Wrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ export const ContentWrapper = ({
);

export const Wrapper = ({ children, ...props }: { children?: ReactNode }) => (
<div className="flex flex-col flex-wrap w-full flex-grow px-3" {...props}>
<div
className="flex flex-col flex-wrap w-full flex-grow px-3 pb-[16px]"
{...props}
>
{children}
</div>
);
4 changes: 2 additions & 2 deletions packages/cow-hooks-ui/src/ui/Checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const Checkbox = ({
const viewBoxSize = radius * 2;

return (
<div className="flex flex-col items-start justify-start">
<div className="w-full flex flex-col items-start justify-start">
<Label
htmlFor={name}
className="flex items-center hover:text-primary [&>div>svg>circle#circle1]:hover:fill-primary [&>div>svg>circle#circle3]:hover:fill-primary"
Expand Down Expand Up @@ -78,7 +78,7 @@ export const Checkbox = ({
<span className="cursor-pointer">{label}</span>
</Label>
{isSelected && isSelectedMessage && (
<span className="ml-4 pt-1 font-normal text-xs opacity-70">
<span className="w-full text-center mt-1 py-1 rounded-xl font-normal text-xs bg-color-warning/15 text-color-warning-text">
<ExclamationTriangleIcon className="w-4 h-4 mr-1 inline" />
{isSelectedMessage}
</span>
Expand Down
Loading

0 comments on commit 5585f8f

Please sign in to comment.