Skip to content

Commit

Permalink
Merge branch 'main' into feature/WEB3-1195-set-config-claimant
Browse files Browse the repository at this point in the history
  • Loading branch information
conradocanasm0 committed Oct 21, 2024
2 parents 709655b + 207ddb5 commit 21cadba
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 85 deletions.
6 changes: 3 additions & 3 deletions components/layout/LayoutSidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -237,10 +237,10 @@ const mainMenuItems = computed(() => {
notification: amountLeftToAuction.value && isTransferEpoch.value,
},
{
title: "Protocol Fees",
path: "/fees/",
title: "Rewards",
path: "/rewards/",
isShow: isAuctionActive.value,
dataTest: "sidebar-link-fees",
dataTest: "sidebar-link-rewards",
},
{
title: "Wrap/Unwrap",
Expand Down
6 changes: 3 additions & 3 deletions components/proposal/InputDynamic.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
<div
v-if="props.modelValueErrors?.length"
class="text-red-500 text-xs my-2 h-4"
class="text-red-500 text-xs my-2 h-4 font-inter"
>
<p v-for="error of props.modelValueErrors" :key="error.$uid">
{{ error.$message }}
Expand Down Expand Up @@ -68,8 +68,8 @@ const value = useVModelWrapper<InputProps>(props, emit, "modelValue");
const hasErrors = computed(() => props.modelValueErrors?.length);
</script>
<style>
<style scoped>
.error {
@apply border border-red-500;
@apply bg-transparent border border-red-500;
}
</style>
10 changes: 4 additions & 6 deletions components/proposal/InputProtocolConfigOperation.vue
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ const inputs = {
penalty_rate: {
component: InputDynamic,
props: {
decorator: "%",
decorator: "BPS",
maska: masks.percentage,
},
},
Expand All @@ -77,7 +77,7 @@ const inputs = {
mint_ratio: {
component: InputDynamic,
props: {
decorator: "%",
decorator: "BPS",
maska: masks.percentage,
},
},
Expand All @@ -94,30 +94,28 @@ const inputs = {
component: InputDynamic,
props: {
decorator: "contract",
maska: masks.ethereumAddress,
},
},
earner_rate_model: {
component: InputDynamic,
props: {
decorator: "contract",
maska: masks.ethereumAddress,
},
},
base_minter_rate: {
component: InputDynamic,
props: {
decorator: "%",
decorator: "BPS",
maska: masks.percentage,
},
},
max_earner_rate: {
component: InputDynamic,
props: {
decorator: "%",
decorator: "BPS",
maska: masks.percentage,
},
},
Expand Down
2 changes: 1 addition & 1 deletion components/proposal/Preview.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
</h2>
<div
class="text-grey-400 my-1 font-inter text-xs truncate w-52 lg:w-full"
class="text-grey-500 my-1 font-inter text-xs truncate w-52 lg:w-full"
>
Proposed by
<u><MAddressAvatar :address="proposal?.proposer" /></u>
Expand Down
Original file line number Diff line number Diff line change
@@ -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 = "";
Expand Down
75 changes: 50 additions & 25 deletions pages/proposal/create.vue
Original file line number Diff line number Diff line change
Expand Up @@ -210,11 +210,10 @@ import {
encodeAbiParameters,
Hash,
erc20Abi,
bytesToHex,
toBytes,
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";
Expand Down Expand Up @@ -279,6 +278,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) },
Expand All @@ -294,8 +308,7 @@ const rules = computed(() => {
proposalValue: { required },
proposalValue2: {
required,
minLength: minLength(42),
maxLength: maxLength(42),
addressValidation: validations.address,
},
proposalValue3: {},
...constRules,
Expand All @@ -307,22 +320,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", "setKeyAddClaimant", "setKeyGuidance"].includes(type)) {
const selectedKey = formData.proposalValue || "";
return {
proposalValue: { required },
proposalValue2: { required },
proposalValue2: getKeyBasedValidation(selectedKey),
proposalValue3: {},
...constRules,
};
Expand All @@ -344,7 +356,7 @@ const rules = computed(() => {
].includes(type)
) {
return {
proposalValue: { required },
proposalValue: { required, range: validations.range(10, 100) },
proposalValue2: {},
proposalValue3: {},
...constRules,
Expand Down Expand Up @@ -877,20 +889,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)]);
};
Expand Down Expand Up @@ -954,6 +952,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;
Expand Down
82 changes: 36 additions & 46 deletions pages/fees.vue → pages/rewards.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<template>
<div>
<PageTitle class="px-6 lg:p-0 mb-8">
<template #default>Protocol Fees</template>
<template #default>Rewards</template>
<template #subtitle>
<p class="text-grey-500 font-inter">
In exchange for ZERO holders' guardianship over protocol governance,
In exchange for ZERO holders' participation in protocol governance,
they will receive the remainder of the protocol fees.
<a
href="https://docs.m0.org/m-0-documentation-portal/overview/whitepaper/iii.-governance/iii.ii-operation/iii.ii.viii-zero-claiming-of-residual-value"
Expand All @@ -17,37 +17,7 @@
</template>
</PageTitle>

<div class="px-6 lg:p-0 my-8">
<h3 class="text-sm font-inter text-grey-200 mb-3">
Total amount to be distributed among all holders
</h3>
<div class="flex flex-wrap gap-6 lg:gap-12">
<MIconLoading v-if="loadingData" />
<div v-for="(token, i) in cashTokens" v-else :key="token.address">
<span class="token-label">{{ token.name }}</span>
<MTokenAmount
:amount="formatUnits(token.distributable, token.decimals)"
:image="`/img/tokens/${token.symbol.toLowerCase()}.svg`"
:name="token.name"
size="20"
/>
<MButton
class="distribute-button"
:is-loading="token.isDistributing"
:disabled="token.isDistributing || token.distributable === 0n"
@click="distributeRewards(token, i)"
>
Distribute
</MButton>
</div>
</div>
</div>

<div class="px-6 lg:p-0 my-12">
<h3 class="text-sm font-inter text-grey-200 mb-3">
Claimable as ZERO holder
</h3>

<div class="grid grid-cols-1 lg:grid-cols-2 gap-4">
<MIconLoading v-if="loadingData" />
<div
Expand All @@ -58,28 +28,47 @@
>
<div class="flex justify-between items-end">
<div>
<h4 class="mb-3">{{ token.name }}</h4>
<span class="token-label">Claimable balance</span>
<h4 class="mb-3 text-2xl">{{ token.name }}</h4>
<span class="token-label">Available for distribution:</span>
<div>
<span class="text-sm">
{{ token.symbol }}
{{ formatUnits(token.distributable, token.decimals) }}
</span>
</div>
</div>

<MButton
class="min-w-32 flex justify-center"
:is-loading="token.isDistributing"
:disabled="token.isDistributing || token.distributable === 0n"
version="outline-light"
@click="distributeRewards(token, i)"
>
Distribute
</MButton>
</div>
<hr class="my-6 border-grey-700" />

<div class="flex justify-between items-end">
<div>
<span class="token-label">Available for claiming:</span>
<MTokenAmount
:amount="token.claimable"
:amount="formatUnits(token.claimable, token.decimals)"
:image="`/img/tokens/${token.symbol.toLowerCase()}.svg`"
:name="token.name"
size="30"
/>
</div>
<MButton
:disabled="token.claimable === 0n || token.isClaiming"
class="min-w-32 flex justify-center"
:is-loading="token.isClaiming"
@click="claimTokenRewards(token, i)"
>Claim</MButton
>
</div>
</div>
</div>

<p class="token-label my-3">
Residual balance will be claimed to the connected address.
</p>
</div>
</div>
</template>
Expand Down Expand Up @@ -111,9 +100,13 @@ const alerts = useAlertsStore();
const allowedCashTokens = computed(() => ttg.governors.zero.allowedCashTokens);
const claimEpochStart = computed(() =>
BigInt(epoch.value.current.asNumber - 50),
);
const claimEpochStart = computed(() => {
if (!epoch.value.current) return 0n;
return epoch.value.current.asNumber > 5000
? BigInt(epoch.value.current.asNumber - 5000)
: 1n;
});
const claimEpochEnd = computed(() => BigInt(epoch.value.current.asNumber - 1));
onMounted(async () => {
Expand Down Expand Up @@ -234,7 +227,4 @@ const claimTokenRewards = async (token, index) => {
.token-label {
@apply text-grey-500 text-xxs font-inter mb-1;
}
.distribute-button {
@apply mt-4 text-xs !important;
}
</style>

0 comments on commit 21cadba

Please sign in to comment.