Skip to content

Commit

Permalink
Merge pull request #90 from aragon/feat/lock-to-veto
Browse files Browse the repository at this point in the history
Adding the Lock To Vote plugin
  • Loading branch information
carlosgj94 authored Mar 15, 2024
2 parents 247e670 + 640d861 commit 2a7a144
Show file tree
Hide file tree
Showing 27 changed files with 3,913 additions and 0 deletions.
526 changes: 526 additions & 0 deletions artifacts/ERC20Permit.sol.ts

Large diffs are not rendered by default.

Binary file modified bun.lockb
Binary file not shown.
2 changes: 2 additions & 0 deletions constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ export const PUB_DAO_ADDRESS = (process.env.NEXT_PUBLIC_DAO_ADDRESS ??
export const PUB_TOKEN_ADDRESS = (process.env.NEXT_PUBLIC_TOKEN_ADDRESS ??
"") as Address;

export const PUB_LOCK_TO_VOTE_PLUGIN_ADDRESS = (process.env
.NEXT_PUBLIC_LOCK_TO_VOTE_PLUGIN_ADDRESS ?? "") as Address;
export const PUB_DUAL_GOVERNANCE_PLUGIN_ADDRESS = (process.env
.NEXT_PUBLIC_DUAL_GOVERNANCE_PLUGIN_ADDRESS ?? "") as Address;
export const PUB_TOKEN_VOTING_PLUGIN_ADDRESS = (process.env
Expand Down
109 changes: 109 additions & 0 deletions hooks/usePermit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { useEffect } from "react";
import {
useReadContracts,
useSignTypedData,
useAccount,
} from "wagmi";
import { hexToSignature, Address } from "viem";
import { ERC20PermitAbi } from "@/artifacts/ERC20Permit.sol";
import { useAlertContext, AlertContextProps } from "@/context/AlertContext";
import { PUB_CHAIN, PUB_TOKEN_ADDRESS } from "@/constants";

export function usePermit() {
const { addAlert } = useAlertContext() as AlertContextProps;

const account_address = useAccount().address!;
const erc20Contract = {
address: PUB_TOKEN_ADDRESS,
abi: ERC20PermitAbi,
};
const { data: erc20data, refetch: erc20refetch } = useReadContracts({
contracts: [{
...erc20Contract,
functionName: "nonces",
args: [account_address],
},{
...erc20Contract,
functionName: "name",
},{
...erc20Contract,
functionName: "version",
}]
});
const [nonceResult, nameResult, versionResult] = erc20data || [];

const { signTypedDataAsync: permitSign, status: permitSignStatus, error: permitSignError } = useSignTypedData();

useEffect(() => {
switch (permitSignStatus) {
case "idle":
case "pending":
return;
case "error":
if (permitSignError?.message?.startsWith("User rejected the request")) {
addAlert("Transaction rejected by the user", {
timeout: 4 * 1000,
});
} else {
addAlert("Could not sign the permit", { type: "error", timeout: 1500 });
}
return;
case "success":
addAlert("Permit signed", { type: "success", timeout: 1500 });
return;
}
}, [permitSignStatus]);

const signPermit = async (dest: Address, value: BigInt, deadline: BigInt = BigInt(Math.floor(Date.now() / 1000) + 60 * 60)) => {
if (!nonceResult || !nameResult || !versionResult) return;

const nonce = BigInt(Number(nonceResult?.result));
const erc20_name = String(nameResult?.result);
/* We assume 1 if permit version is not specified */
const versionFromContract = String(versionResult?.result ?? '1');

const domain = {
chainId: PUB_CHAIN.id,
name: erc20_name,
version: versionFromContract,
verifyingContract: PUB_TOKEN_ADDRESS,
};

const types = {
Permit: [
{ name: 'owner', type: 'address' },
{ name: 'spender', type: 'address' },
{ name: 'value', type: 'uint256' },
{ name: 'nonce', type: 'uint256' },
{ name: 'deadline', type: 'uint256' },
],
};

const message = {
owner: account_address,
spender: dest,
value,
nonce,
deadline,
};

try {
let sig = await permitSign({
account: account_address,
types,
domain,
primaryType: 'Permit',
message,
});

return hexToSignature(sig);
} catch (e) {
return;
}
};

return {
refetchPermitData: erc20refetch,
signPermit,
};
}
8 changes: 8 additions & 0 deletions plugins/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
PUB_DELEGATION_CONTRACT_ADDRESS,
PUB_DUAL_GOVERNANCE_PLUGIN_ADDRESS,
PUB_TOKEN_VOTING_PLUGIN_ADDRESS,
PUB_LOCK_TO_VOTE_PLUGIN_ADDRESS,
} from "@/constants";
import { IconType } from "@aragon/ods";

Expand Down Expand Up @@ -31,6 +32,13 @@ export const plugins: PluginItem[] = [
icon: IconType.BLOCKCHAIN_BLOCKCHAIN,
pluginAddress: PUB_TOKEN_VOTING_PLUGIN_ADDRESS,
},
{
id: "lock-to-vote",
folderName: "lockToVote",
title: "Morpho Vault Gov",
icon: IconType.BLOCKCHAIN_BLOCK,
pluginAddress: PUB_LOCK_TO_VOTE_PLUGIN_ADDRESS,
},
{
id: "delegate-wall",
folderName: "delegateAnnouncer",
Expand Down
Loading

0 comments on commit 2a7a144

Please sign in to comment.