From 72a7de17c844ce05ddb499573b71faacbe72c7b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Conrado=20Ca=C3=B1as?= <146194347+conradocanasm0@users.noreply.github.com> Date: Thu, 10 Oct 2024 08:46:30 -0300 Subject: [PATCH] Feat/web3 1193 create values and ranges (#339) * WEB3 1193 replace percentage for BPS in create proposal flow * Update preview proposer text color * Create key-based validations for multiple items * Fix emergency setkey protocol test * Replace if for switch statement in getKeybasedValidation --- components/proposal/InputDynamic.vue | 6 +- .../proposal/InputProtocolConfigOperation.vue | 10 +-- components/proposal/Preview.vue | 2 +- ...als-emergency-setKey-protocol-config.cy.ts | 2 +- pages/proposal/create.vue | 80 +++++++++++++------ 5 files changed, 65 insertions(+), 35 deletions(-) diff --git a/components/proposal/InputDynamic.vue b/components/proposal/InputDynamic.vue index 6581944a..9c8196a9 100644 --- a/components/proposal/InputDynamic.vue +++ b/components/proposal/InputDynamic.vue @@ -34,7 +34,7 @@

{{ error.$message }} @@ -68,8 +68,8 @@ const value = useVModelWrapper(props, emit, "modelValue"); const hasErrors = computed(() => props.modelValueErrors?.length); - diff --git a/components/proposal/InputProtocolConfigOperation.vue b/components/proposal/InputProtocolConfigOperation.vue index 7c5761cd..fde5ce2e 100644 --- a/components/proposal/InputProtocolConfigOperation.vue +++ b/components/proposal/InputProtocolConfigOperation.vue @@ -53,7 +53,7 @@ const inputs = { penalty_rate: { component: InputDynamic, props: { - decorator: "%", + decorator: "BPS", maska: masks.percentage, }, }, @@ -77,7 +77,7 @@ const inputs = { mint_ratio: { component: InputDynamic, props: { - decorator: "%", + decorator: "BPS", maska: masks.percentage, }, }, @@ -94,7 +94,6 @@ const inputs = { component: InputDynamic, props: { decorator: "contract", - maska: masks.ethereumAddress, }, }, @@ -102,14 +101,13 @@ const inputs = { component: InputDynamic, props: { decorator: "contract", - maska: masks.ethereumAddress, }, }, base_minter_rate: { component: InputDynamic, props: { - decorator: "%", + decorator: "BPS", maska: masks.percentage, }, }, @@ -117,7 +115,7 @@ const inputs = { max_earner_rate: { component: InputDynamic, props: { - decorator: "%", + decorator: "BPS", maska: masks.percentage, }, }, diff --git a/components/proposal/Preview.vue b/components/proposal/Preview.vue index 84258e24..829c2df0 100644 --- a/components/proposal/Preview.vue +++ b/components/proposal/Preview.vue @@ -15,7 +15,7 @@

Proposed by diff --git a/cypress/e2e/basic-emergency/proposals-emergency-setKey-protocol-config.cy.ts b/cypress/e2e/basic-emergency/proposals-emergency-setKey-protocol-config.cy.ts index 7862ff8f..b079372c 100644 --- a/cypress/e2e/basic-emergency/proposals-emergency-setKey-protocol-config.cy.ts +++ b/cypress/e2e/basic-emergency/proposals-emergency-setKey-protocol-config.cy.ts @@ -1,6 +1,6 @@ describe("Proposals", () => { describe("type action: Emergency setKey", () => { - const value = "1"; + const value = "60"; const key = "mint_delay"; const description = `Add config ${key} = ${value}`; let proposalUrl = ""; diff --git a/pages/proposal/create.vue b/pages/proposal/create.vue index 0239cb7f..e51c3773 100644 --- a/pages/proposal/create.vue +++ b/pages/proposal/create.vue @@ -205,9 +205,15 @@ import { writeContract, readContract, } from "@wagmi/core"; -import { encodeFunctionData, encodeAbiParameters, Hash, erc20Abi } from "viem"; +import { + encodeFunctionData, + encodeAbiParameters, + Hash, + erc20Abi, + isAddress, +} from "viem"; import { useAccount } from "use-wagmi"; -import { required, minLength, maxLength, url } from "@vuelidate/validators"; +import { required, minLength, url, helpers } from "@vuelidate/validators"; import { useVuelidate } from "@vuelidate/core"; import { storeToRefs } from "pinia"; @@ -271,6 +277,21 @@ const formData = reactive({ discussionURL: null, }); +const validations = { + address: helpers.withMessage( + "Address is not valid", + (value: string) => isAddress(value) || !value, + ), + range: (min: number, max: number) => + helpers.withMessage( + `Invalid value, acceptable range is ${min}-${max}`, + (value: string) => { + const numberValue = Number(value); + return numberValue >= min && numberValue <= max; + }, + ), +}; + const rules = computed(() => { const constRules = { description: { required, minLength: minLength(6) }, @@ -286,8 +307,7 @@ const rules = computed(() => { proposalValue: { required }, proposalValue2: { required, - minLength: minLength(42), - maxLength: maxLength(42), + addressValidation: validations.address, }, proposalValue3: {}, ...constRules, @@ -299,22 +319,21 @@ const rules = computed(() => { proposalValue: { required }, proposalValue2: { required, - minLength: minLength(42), - maxLength: maxLength(42), + addressValidation: validations.address, }, proposalValue3: { required, - minLength: minLength(42), - maxLength: maxLength(42), + addressValidation: validations.address, }, ...constRules, }; } if (["setKey"].includes(type)) { + const selectedKey = formData.proposalValue || ""; return { proposalValue: { required }, - proposalValue2: { required }, + proposalValue2: getKeyBasedValidation(selectedKey), proposalValue3: {}, ...constRules, }; @@ -336,7 +355,7 @@ const rules = computed(() => { ].includes(type) ) { return { - proposalValue: { required }, + proposalValue: { required, range: validations.range(10, 100) }, proposalValue2: {}, proposalValue3: {}, ...constRules, @@ -854,20 +873,6 @@ function buildCalldatas(formData) { return addressToHexWith32Bytes(inp); } - if ( - [ - "penalty_rate", - "mint_ratio", - "base_minter_rate", - "max_earner_rate", - ].includes(key) - ) { - return encodeAbiParameters( - [{ type: "uint256" }], - [BigInt(percentageToBasispoints(inp))], - ); - } - return encodeAbiParameters([{ type: "uint256" }], [BigInt(inp)]); }; @@ -924,6 +929,33 @@ function buildCalldatasTtg(functionName: any, args: any) { }); } +function getKeyBasedValidation(key: string) { + switch (key) { + case "minter_rate_model": + case "earner_rate_model": + return { required, address: validations.address }; + case "base_minter_rate": + case "max_earner_rate": + return { required, range: validations.range(1, 5000) }; + case "penalty_rate": + return { required, range: validations.range(1, 1000) }; + case "update_collateral_interval": + return { required, range: validations.range(60, 31536000) }; // 1 minute to 1 year + case "update_collateral_threshold": + return { required, range: validations.range(1, 10) }; + case "mint_delay": + return { required, range: validations.range(60, 86400) }; // 1 minute to 1 day + case "mint_ttl": + return { required, range: validations.range(3600, 864000) }; // 1 hour to 10 days + case "mint_ratio": + return { required, range: validations.range(50, 100) }; // Percent range + case "minter_freeze_time": + return { required, range: validations.range(3600, 2592000) }; // 1 hour to 1 month + default: + return { required }; + } +} + function onBack() { isPreview.value = false; previewDescription.value = null;