# Hypercert dev spec
::: warning
WIP document with most focus on hypercerts and we can keep refining as we see features arising on the horizon
:::
[TOC]
## Features
### Checklist
:::warning
:warning: Please link to git merge that establishes the feature
:::
__Hypercert Contract - Phase 0__
Creators claim impact by minting a hypercert
- [ ] Basic contract
- [ ] Creator mints hypercert
- [ ] Creator specifies metadata (IPFS CID)
- [ ] Creator sets supply of tokens
- [ ] Creators confirm that all creators in the hypercert have agreed to minting the hypercert
- [ ] Creator sets a royalty rate, royalties can be split between multiple addresses
- [ ] Creator can edit hypercert metadata
- [ ] Creator can freeze hypercert metadata
__Evaluation (Contract?) - TBD__
Evaluators create impact evaluation of a hypercert
- [ ] Evaluators create evaluation
- [ ] Evaluators link evaluation to certificate via address
- [ ] Evaluators confirm the scope of work and can comment
- [ ] Evaluators can comment by adding confirmation/update for each impact variable
- [ ] Evaluators can add additional impact variables
- [ ] Evaluators can add fields to the evaluation
- [ ] Evaluators add the CID of evaluation to mint
## Hypercert Contract - Phase 0
### Basic contract
- [ ] [ERC1155 multi-token](https://eips.ethereum.org/EIPS/eip-1155)
:::spoiler Mint
On mint, creator(s) supply IPFS CID containing metadata and in case of multiple creators provide a data object with all creators, their signatures and -optional- the royalties division.
:::
:::spoiler Burn
On burn, token is sent to zero-address
:::
:::spoiler Donate
On donate, token state is updated as 'donated' and token is sent to zero-address
:::
- [ ] [EIP-2981 royalty standard](https://eips.ethereum.org/EIPS/eip-2981)
- [ ] Upgradeable
- [ ] Hypercert will be minted as an NFT
:::info
:arrow_down: See NFT split topic below
:::
### Creator mints hypercert
> As a hypercert creator, I want to be able to mint a new hypercert to claim an impact space
- [ ] Creator provides metadata as IPFS CID
:::info
:arrow_down: See Metadata topic below
:::
- [ ] Creator sets supply of tokens (1 for NFT, [can mix NFT and FT](https://eips.ethereum.org/EIPS/eip-1155#non-fungible-tokens))
- [ ] Creators confirm that all creators in the hypercert have agreed to minting the hypercert by collecting signatures
:::spoiler See/follow Rarible ERC1155 implementation for multiple creators and signatures
[Rarible protocol contracts](https://github.com/rarible/protocol-contracts) allow for supplying data that contains signers, signatures and royalty split
:::
:::warning
:eyes: Using Gnosis multisigs might be easiest way to start as it enables 1) defining a group of creators 2) get the approval of said group on minting/transacting/mutating/freesing 3) control royalty flow
:::
- [ ] Contract checks creators[]-signatures[] to validate approvals
- [ ] Contract checks creator-cid[] for all creator[] entries to quick-check on overlap
### Creator sets a royalty rate
> As a hypercert creator, I want to enable a royalty flow so that I can benefit from future trades of my impact claim.
- [ ] Set and get royalty rate
- [ ] Royalties can be split between multiple addresses
:::spoiler See/follow Rarible ERC1155 implementation for multiple creators and signatures
[Rarible protocol contracts](https://github.com/rarible/protocol-contracts) allow for supplying data that contains signers, signatures and royalty split
:::
:::warning
:eyes: The specification for royalties defines a [single value transfer](https://eips.ethereum.org/EIPS/eip-2981#simple-royalty-payments-to-a-single-address) where the receiver is responsible for dividing the fee. Again, a Gnosis safe sounds like a good place to start
:::
### Creator can update hypercert metadata
> As a hypercert creator, I want to be able to update the metadata so that changes in the claim are represented in the token
- [ ] Change CID in token (update URI)
- [ ] If multiple creators, require signature of multiple creators before change
### Creator can freeze hypercert metadata
> As a hypercert creator, I want to be able to freeze future changes to metadata to represented the work as completed (for example)
- [ ] Freeze URI in token and [emit event](https://docs.opensea.io/docs/metadata-standards#freezing-metadata)
- [ ] If multiple creators, require signature of multiple creators before change
## Evaluations
### Evaluators create evaluation
> As an impact evaluator, I want to be able to create and store an impact evaluation so that the value of an impact claim can be asessed
### Evaluators link evaluation to certificate via address
> As an impact evaluator, I want to be able to define the linked hypercert so that hypercert-evaluation can quickly be indexed
### Evaluators confirm the scope of work and can comment
### Evaluators can comment by adding confirmation/update/null
### Evaluators can add additional impact
### Evaluators can add fields to the evaluation
### Evaluators add the CID of evaluation to mint
> As an impact evaluator, I want to be able to link to evaluation data in a evaluation stored on-chain, so that both impact claim and evaluation are referenced on-chain.
## Metadata
### Hypercert v0.1
```jsonld
{
name: "demo impact",
image: "https://gateway.ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR",
external_link: "http://example.com",
format_version: 0.1,
description: "built code v0.0.1",
prev_hypercert: "2mbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR",
properties: {
creators: [ethAddress1, ethAddress2, ...],
work_scope: "implemented MVP spec",
work_time: [12312352354,43256345677],
impact_scope: "all",
impact_time: [32312352354,63256345677],
rights: "..."
}
}
```
### Evaluation - WIP dirty copy
```jsonld
{
name: "demo evaluation",
impact_certificate: "http://example.com",
type: prospective | intermediate | retroactive,
version: 1,
description: "built code v0.0.1",
claimHash: "canudincv34356t4njkn",
properties: {
creators: [ethAddress1, ethAddress2, ...],
work_scope: "implemented MVP spec",
work_time: [12312352354,43256345677],
impact_scope: "all",
impact_time: [32312352354,63256345677],
rights: "..."
}
}
```
## Flows
### Minting
- single creator
- user supplies [hypercert metadata](https://hackmd.io/e3WhpdP8R1eOWgPDspfXVQ?both=#Hypercert-v01) in app
```mermaid
sequenceDiagram
participant Creator
participant App
participant IPFS
participant Contract
Creator->>App: Submit impact claim information
note over App: Validate input
App-->>Creator: Data valid (mint button active)
Creator->>App: Mint impact claim
App->>IPFS: Store impact claim data
IPFS-->>App: Return CID
App->>Contract: Mint hypercert token
note over Contract: Check mapping(creator => hypercerts[]) for overlap creator-hypercert
note over Contract: set royalties for creator(s) according to royalties[]
Contract-->>App: Hypercert token minted
App->>Creator: Display NFT
```
- multiple creators
- user supplies hypercert metadata in app
```mermaid
sequenceDiagram
participant Creator
participant App
participant IPFS
participant Contract
Creator->>App: Submit impact claim information
note over App: Validate input
App->>IPFS: Store impact claim data
IPFS-->>App: Return CID
App-->>Creator: Impact claim uploaded
Creator->>App: Mint impact claim
App->>Contract: Mint hypercert token
note over Contract: Check creators[] against signatures[]
note over Contract: Check mapping(creator => hypercerts[]) for overlap creator-hypercert
note over Contract: set royalties for creator(s) according to royalties[]
Contract-->>Creator: Hypercert token minted
```
### Linking hypercert-evaluation
- Creators mint hypercert describing impact claim
- Evaluators evaluate impact claim described in hypercert
- Evaluators and creators have no overlap for a claim
- A hypercert contains an URI that in practice will be a CID on IPFS (for impact metadata)
- An evaluation contains an URI that in practice will be a CID on IPFS (for evaluation metadata)
- An evaluation is linked to a hypercert by storing the address of the hypercert it refers to
- An evaluation refers to a specific state of the claim by storing the CID the hypercert refers to in the metadata
```mermaid
erDiagram
CREATOR }|--|| HYPERCERT : mints
CREATOR {
address address
}
HYPERCERT {
uint hypercertID
address creator
string claimURI
}
EVALUATOR }|--|{ HYPERCERT : reviews
EVALUATOR }|--|{ EVALUATION : creates
EVALUATION }|--|| HYPERCERT : covers
EVALUATOR {
address address
}
EVALUATION {
uint evaluationID
string evaluationUri
address hypercertAddress
}
```
### NFT split
::: info
Small brainstorm on splitting the NFTs with current ERC1155 spec
:::
ERC1155 => mint token with ID int128 (rootNFT), range of ID + <int128> are fractional NFTs (subNFT)
__RootNFT:__
- Merkleroot proof of array state
- Count of total/active subNFT
- Index of latest subNFT (when 0 no subNFTs)
- URI to IPFS metadata
__SubNFT:__
- Merkleroot proof of array state (root hash + proofs)
- URI to subtoken metadata
- Burnable (burn token with ID)
- Donatable (burn with blocking future claims)
__SubToken metadata:__
- time work
- scope work
- Time impact
- Scope impact
__Claim:__
- create token with ID int128
- lastestToken = 0
- rootHash = dadwe2qe3394wti4gksdncvdsvnds
- owner
- creator
__Split:__
- check if caller is owner
- check if splitting token is not burned
- check if sum time and scope potential children matches parents values