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;