From 6541e2b0fbad8748191c49c5fac6c83f5c1b282d Mon Sep 17 00:00:00 2001 From: Rafael Ventura Date: Thu, 14 Oct 2021 11:33:58 +0200 Subject: [PATCH] Feat/spell address hash (#200) --- lib/theme.js | 32 ++++ modules/executive/api/fetchExecutives.ts | 1 + modules/executive/api/mocks/proposals.json | 2 + modules/executive/api/parseExecutive.ts | 3 +- .../executive/components/SpellEffectsTab.tsx | 164 ++++++++++++++++-- modules/executive/types/proposal.d.ts | 1 + modules/executive/types/spellData.d.ts | 2 + package.json | 2 +- .../api/executive/analyze-spell/[address].ts | 26 ++- yarn.lock | 10 +- 10 files changed, 222 insertions(+), 21 deletions(-) diff --git a/lib/theme.js b/lib/theme.js index 7d03fbdf6..dc8d49634 100644 --- a/lib/theme.js +++ b/lib/theme.js @@ -338,6 +338,7 @@ export default { chevron_right: icons.chevron_right, chevron_left: icons.chevron_left, chevron_down: icons.chevron_down, + chevron_up: icons.chevron_up, checkmark: icons.checkmark, edit: icons.edit, verified: icons.verified, @@ -998,6 +999,37 @@ export default { fill="currentColor" /> ) + }, + hourglass: { + viewBox: '0 0 14 18', + path: ( + + + + + + + ) } } }; diff --git a/modules/executive/api/fetchExecutives.ts b/modules/executive/api/fetchExecutives.ts index 5ee77f0cd..f880daa59 100644 --- a/modules/executive/api/fetchExecutives.ts +++ b/modules/executive/api/fetchExecutives.ts @@ -41,6 +41,7 @@ export async function getExecutiveProposals(network?: SupportedNetworks): Promis return parseExecutive(proposalDoc, proposalIndex, proposalLink, currentNetwork); } catch (e) { + console.log(e); // Catch error and return null if failed fetching one proposal return null; } diff --git a/modules/executive/api/mocks/proposals.json b/modules/executive/api/mocks/proposals.json index 72310b834..dd3774046 100644 --- a/modules/executive/api/mocks/proposals.json +++ b/modules/executive/api/mocks/proposals.json @@ -15,6 +15,7 @@ }, "verified": false, "address": "0x261086981FC6c57EF4679Af6aC253C3755850362", + "proposalLink": "https://github.com", "about": "# [Executive Vote] Raise the ETH Debt Ceiling\r\n\r\nThe Maker Foundation Interim Governance Facilitator has placed an Executive Vote into the voting system, which will enable the community to approve the following alterations to the protocol:\r\n\r\n- [Raise the Dai ETH Debt Ceiling by 20 million to 140 million Dai](https://vote.makerdao.com/polling-proposal/qmsv7qsmqafardbhun2f9s65nge3xf5oe4we3dswzwbtfy)\r\n\r\nThe Executive Vote ([FAQ](https://community-development.makerdao.com/makerdao-mcd-faqs/faqs#governance)) will continue until the number of votes surpass the total in favor of the previous Executive Vote. This is a [continuous approval](https://community-development.makerdao.com/makerdao-mcd-faqs/faqs/governance#what-is-continuous-approval-voting) vote.\r\n\r\n## Review\r\n\r\nThese changes were discussed in the Governance call on Thursday, June 4. Please review the [Video](https://www.youtube.com/playlist?list=PLLzkWCj8ywWNq5-90-Id6VPSsrk4OWVan), [Audio](https://soundcloud.com/makerdao/sets/governance-calls), and the online [discussion](https://forum.makerdao.com/c/governance) to inform your position before voting.\r\n\r\nThe MakerDAO community is moving forward with an Executive Vote to determine whether it will enact the changes established by the previous [Governance Polls](https://vote.makerdao.com/polling).\r\n\r\n## Action\r\n\r\n**Voting for this proposal will place your MKR in support of implementing the changes outlined above.**\r\n\r\n---\r\n\r\n## Resources\r\n\r\nAdditional information about the Governance process can be found in the [Governance Risk Framework: Governing MakerDAO](https://community-development.makerdao.com/governance/governance-risk-framework)\r\n\r\nDemos, help and instructional material for the Governance Dashboard can be found at [Awesome MakerDAO](https://awesome.makerdao.com/#voting).\r\n\r\nTo participate in future Governance calls, please [join us](https://community-development.makerdao.com/governance/governance-and-risk-meetings) every Thursday at 16:00 UTC.\r\n\r\nTo add current and upcoming votes to your calendar, please see the [MakerDAO Public Events Calendar](https://calendar.google.com/calendar/embed?src=makerdao.com_3efhm2ghipksegl009ktniomdk%40group.calendar.google.com&ctz=America%2FLos_Angeles)." }, { @@ -33,6 +34,7 @@ }, "verified": false, "address": "0x261086981FC6c57EF4679Af6aC253C3755850362", + "proposalLink": "https://github.com", "about": "# [Executive Vote] Raise the ETH Debt Ceiling\r\n\r\nThe Maker Foundation Interim Governance Facilitator has placed an Executive Vote into the voting system, which will enable the community to approve the following alterations to the protocol:\r\n\r\n- [Raise the Dai ETH Debt Ceiling by 20 million to 140 million Dai](https://vote.makerdao.com/polling-proposal/qmsv7qsmqafardbhun2f9s65nge3xf5oe4we3dswzwbtfy)\r\n\r\nThe Executive Vote ([FAQ](https://community-development.makerdao.com/makerdao-mcd-faqs/faqs#governance)) will continue until the number of votes surpass the total in favor of the previous Executive Vote. This is a [continuous approval](https://community-development.makerdao.com/makerdao-mcd-faqs/faqs/governance#what-is-continuous-approval-voting) vote.\r\n\r\n## Review\r\n\r\nThese changes were discussed in the Governance call on Thursday, June 4. Please review the [Video](https://www.youtube.com/playlist?list=PLLzkWCj8ywWNq5-90-Id6VPSsrk4OWVan), [Audio](https://soundcloud.com/makerdao/sets/governance-calls), and the online [discussion](https://forum.makerdao.com/c/governance) to inform your position before voting.\r\n\r\nThe MakerDAO community is moving forward with an Executive Vote to determine whether it will enact the changes established by the previous [Governance Polls](https://vote.makerdao.com/polling).\r\n\r\n## Action\r\n\r\n**Voting for this proposal will place your MKR in support of implementing the changes outlined above.**\r\n\r\n---\r\n\r\n## Resources\r\n\r\nAdditional information about the Governance process can be found in the [Governance Risk Framework: Governing MakerDAO](https://community-development.makerdao.com/governance/governance-risk-framework)\r\n\r\nDemos, help and instructional material for the Governance Dashboard can be found at [Awesome MakerDAO](https://awesome.makerdao.com/#voting).\r\n\r\nTo participate in future Governance calls, please [join us](https://community-development.makerdao.com/governance/governance-and-risk-meetings) every Thursday at 16:00 UTC.\r\n\r\nTo add current and upcoming votes to your calendar, please see the [MakerDAO Public Events Calendar](https://calendar.google.com/calendar/embed?src=makerdao.com_3efhm2ghipksegl009ktniomdk%40group.calendar.google.com&ctz=America%2FLos_Angeles)." } ] diff --git a/modules/executive/api/parseExecutive.ts b/modules/executive/api/parseExecutive.ts index 9a6fda55d..cd78ec260 100644 --- a/modules/executive/api/parseExecutive.ts +++ b/modules/executive/api/parseExecutive.ts @@ -45,6 +45,7 @@ export function parseExecutive( key: slugify(title), address: address, date: String(date), - active: proposalIndex[network].includes(proposalLink) + active: proposalIndex[network].includes(proposalLink), + proposalLink }; } diff --git a/modules/executive/components/SpellEffectsTab.tsx b/modules/executive/components/SpellEffectsTab.tsx index fdcfe39ce..e9821f185 100644 --- a/modules/executive/components/SpellEffectsTab.tsx +++ b/modules/executive/components/SpellEffectsTab.tsx @@ -1,9 +1,29 @@ /** @jsx jsx */ -import { Box, Text, jsx, Link as ThemeUILink, Flex } from 'theme-ui'; -import { getNetwork } from 'lib/maker'; -import { getEtherscanLink } from 'lib/utils'; +import { Box, Flex, Text, jsx, Link as ThemeUILink } from 'theme-ui'; import { Proposal, SpellData } from '../types'; +import { useState } from 'react'; +import { Icon as DaiUIIcon } from '@makerdao/dai-ui-icons'; + +import SkeletonThemed from 'modules/app/components/SkeletonThemed'; +import { formatDateWithoutTime } from 'lib/datetime'; + +const CircleIcon = ({ name }) => ( + ({ + background: theme.colors?.background, + borderRadius: '100%', + width: '34px', + minWidth: '34px', + height: '34px', + alignItems: 'center', + justifyContent: 'center' + })} + > + + +); export function SpellEffectsTab({ proposal, @@ -39,17 +59,139 @@ export function SpellEffectsTab({ )} */ + const [expanded, setExpanded] = useState(false); return ( - - Spell at address - - - {proposal.address} - - - + + Spell Details + + + + Executive Hash + + + ({ + background: theme.colors?.background, + p: 3, + transition: 'all 300ms linear', + overflow: 'hidden', + borderRadius: '3px' + })} + > + + {spellData?.executiveHash ? ( + + {spellData?.executiveHash} + + ) : ( + + )} + + setExpanded(!expanded)}> + + What's this? + + + + + {expanded && ( + + + This hash allows for manually verifying that the spell belongs to the correct Executive + Proposal. It can be reproduced by hashing the raw markdown text of this Executive Proposal. + The hash, the URL to the raw markdown text, and the correct hashing algorithm are all + registered on the blockchain in the spell smart contract. + + + + + Learn more about auditing Executive Spells + + + + + + )} + + + + {'proposalLink' in proposal && ( + + + Proposal Markdown + + + + + View in GitHub + + + + + + )} + + + + + + Expiration + + + {formatDateWithoutTime(spellData?.eta)} + + + + {spellData?.officeHours && ( + + + + + Office Hours Only + + + Spell will only be executed Monday through Friday between 14:00 and 21:00 UTC + + + + )} + + ); } diff --git a/modules/executive/types/proposal.d.ts b/modules/executive/types/proposal.d.ts index 2d43bfc68..4cd716007 100644 --- a/modules/executive/types/proposal.d.ts +++ b/modules/executive/types/proposal.d.ts @@ -7,6 +7,7 @@ export type CMSProposal = { proposalBlurb: string; title: string; date: string; + proposalLink: string; }; export type RawAddressProposal = { diff --git a/modules/executive/types/spellData.d.ts b/modules/executive/types/spellData.d.ts index aa70659cd..eec8d24f5 100644 --- a/modules/executive/types/spellData.d.ts +++ b/modules/executive/types/spellData.d.ts @@ -6,4 +6,6 @@ export type SpellData = { datePassed?: Date; dateExecuted?: Date; mkrSupport: number; + executiveHash?: string; + officeHours?: boolean; }; diff --git a/package.json b/package.json index 2454e94a1..aef28f733 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ }, "dependencies": { "@makerdao/dai": "^0.32.15", - "@makerdao/dai-plugin-governance": "^0.14.3", + "@makerdao/dai-plugin-governance": "^0.14.5", "@makerdao/dai-plugin-ledger-web": "^0.9.10", "@makerdao/dai-plugin-mcd": "^1.6.36", "@makerdao/dai-plugin-trezor-web": "^0.9.7", diff --git a/pages/api/executive/analyze-spell/[address].ts b/pages/api/executive/analyze-spell/[address].ts index 0dcff04c6..34c1a9470 100644 --- a/pages/api/executive/analyze-spell/[address].ts +++ b/pages/api/executive/analyze-spell/[address].ts @@ -9,8 +9,18 @@ import { SpellData } from 'modules/executive/types/spellData'; // nextCastTime returns when the spell is available for execution, accounting for office hours (only works if the spell has not been executed yet) // eta returns when the spell is available for execution, not account for office hours +// executiveHash returns the hash of the executive proposal export const analyzeSpell = async (address: string, maker: any): Promise => { - const [done, nextCastTime, eta, datePassed, dateExecuted, mkrSupport] = await Promise.all([ + const [ + done, + nextCastTime, + eta, + datePassed, + dateExecuted, + mkrSupport, + executiveHash, + officeHours + ] = await Promise.all([ maker .service('spell') .getDone(address) @@ -33,7 +43,15 @@ export const analyzeSpell = async (address: string, maker: any): Promise null), // this fails if the spell has not been executed - maker.service('chief').getApprovalCount(address) + maker.service('chief').getApprovalCount(address), + maker + .service('spell') + .getExecutiveHash(address) + .catch(_ => null), + maker + .service('spell') + .getOfficeHours(address) + .catch(_ => null) ]); return { @@ -43,7 +61,9 @@ export const analyzeSpell = async (address: string, maker: any): Promise