Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/moleculeprotocol/IPNFT

IP-NFTs are building blocks for the DeSci economy.
https://github.com/moleculeprotocol/IPNFT

desci nft web3

Last synced: about 2 months ago
JSON representation

IP-NFTs are building blocks for the DeSci economy.

Awesome Lists containing this project

README

        

# IPNFT

IP-NFTs allow their users to tokenize intellectual property. This repo contains code for IP-NFT smart contracts and compatible subgraphs. Details on how IP-NFTs are minted, their purpose and applications [can be found here](https://docs.molecule.to)

## Deployments

### Mainnet

| Contract | Address | Actions |
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| IP-NFT | [0xcaD88677CA87a7815728C72D74B4ff4982d54Fc1](https://etherscan.io/address/0xcaD88677CA87a7815728C72D74B4ff4982d54Fc1#code) | View contract |
| SignedMintAuthorizer | [0xBc5FbB45A2bbB64d9B2EeBFa327284a35d5C5865](https://etherscan.io/address/0xBc5FbB45A2bbB64d9B2EeBFa327284a35d5C5865#code) | View contract |
| SchmackoSwap | [0xc09b8577c762b5e97a7d640f242e1d9bfaa7eb9d](https://etherscan.io/address/0xc09b8577c762b5e97a7d640f242e1d9bfaa7eb9d#code) | View contract |
| Tokenizer | [0x58EB89C69CB389DBef0c130C6296ee271b82f436](https://etherscan.io/address/0x58EB89C69CB389DBef0c130C6296ee271b82f436#code) | View contract |
| Permissioner | [0xC837E02982992B701A1B5e4E21fA01cEB0a628fA](https://etherscan.io/address/0xC837E02982992B701A1B5e4E21fA01cEB0a628fA#code) | View contract |
| Crowdsale | [0xf0a8d23f38e9cbbe01c4ed37f23bd519b65bc6c2](https://etherscan.io/address/0xf0a8d23f38e9cbbe01c4ed37f23bd519b65bc6c2#code) | View contract |
| StakedLockingCrowdSale | [0x35Bce29F52f51f547998717CD598068Afa2B29B7](https://etherscan.io/address/0x35Bce29F52f51f547998717CD598068Afa2B29B7#code) | View contract |

#### Subgraph

API: https://subgraph.satsuma-prod.com/742d8952ab24/molecule--4039244/ip-nft-mainnet/api
Playground: https://subgraph.satsuma-prod.com/molecule--4039244/ip-nft-mainnet/playground

tokenizer implementation 1.3: 0x6517DD48908F4C1FF4eD74FfD780908241a3654C
tokenizer implementation 1.2: 0xE8701330F196FeFe415b28dAA767AB076F42557A
tokenizer implementation 1.1: 0x9C70FA8c87D7e94Fd63eeCCcA657D5c4224a36f3

iptoken implementation 1.3: 0x89a14Be8f7824d4775053Edad0f2fA2d6767b72B
iptoken implementation: 0x9E4fc6E6d1A64e3429aB852d3CB31AD7aa06997A

ipnft implementation 2.4: 0x6B179Dffac5E190c670176606f552cB792847f80

#### Defender Relayer

Deprecated after migrating to Defender 2 (was 0x3D30452c48F2448764d5819a9A2b684Ae2CC5AcF). We're using a key signoff with 0x8626c6293B5101E5E534B5B60F411a37294D8cBE.

---

### Sepolia

| Contract | Address | Explorer |
| ------------------ | ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| IPNFT | 0x152B444e60C526fe4434C721561a077269FcF61a | View contract |
| Swap | 0x9e4c638e703d0Af3a3B9eb488dE79A16d402698f | View contract |
| Authorizer | 0x7a9F3773352e4ee0Da6307Cd32C45fE89602129A | View contract |
| Terms Permissioner | 0xC05D649368d8A5e2E98CAa205d47795de5fCB599 | View contract |
| Tokenizer | 0xca63411FF5187431028d003eD74B57531408d2F9 | View contract |
| Crowdsale | 0x8cA737E2cdaE1Ceb332bEf7ba9eA711a3a2f8037 | View contract |
| Staked Crowdsale | 0xd1cE2EA7d3b0C9cAB025A4aD762FC00315141ad7 | View contract |

#### Subgraphs

on Satsuma, Techprod Account

API: https://subgraph.satsuma-prod.com/742d8952ab24/molecule--4039244/ip-nft-sepolia/api
Playground: https://subgraph.satsuma-prod.com/molecule--4039244/ip-nft-sepolia/playground

#### Defender Relayer

Deprecated after migrating to Defender 2 (was 0xd7B298c9fB0377124d01D4E826d9D5beFB7CD6FE). We're using a key signoff with 0x8626c6293B5101E5E534B5B60F411a37294D8cBE.

#### Tokens

| Contract | Address | |
| ----------------- | ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| USDC (6 decimals) | 0xC7B1b8BEA20d559040928FA1e6a23a3c221286B1 | View contract |
| MOL Dao | 0xe0D404C22228b03D5b8a715Cb569C4944BC5A27A | View contract |
| vested MOL Dao | 0x8f80d1183CD983B01B0C9AC6777cC732Ec9800de | View contract |

old
Plain Crowdsale 0xc272b3e980ee3c1e52a9814b1a1d6c48295e8d91 https://sepolia.etherscan.io/address/0xc272b3e980ee3c1e52a9814b1a1d6c48295e8d91

```
IPNFT_ADDRESS=0x152B444e60C526fe4434C721561a077269FcF61a
ipnft impl 0x67881bbE2d58f5eeb2f2cad3a1FB7Bb6CB834A5A
SOS_ADDRESS=0x9e4c638e703d0Af3a3B9eb488dE79A16d402698f
AUTHORIZER_ADDRESS=0x7a9F3773352e4ee0Da6307Cd32C45fE89602129A

TERMS_ACCEPTED_PERMISSIONER_ADDRESS=0xC05D649368d8A5e2E98CAa205d47795de5fCB599
TOKENIZER_ADDRESS=0xca63411FF5187431028d003eD74B57531408d2F9
CROWDSALE_ADDRESS=0x8cA737E2cdaE1Ceb332bEf7ba9eA711a3a2f8037
STAKED_LOCKING_CROWDSALE_ADDRESS=0xd1cE2EA7d3b0C9cAB025A4aD762FC00315141ad7

initial IP Token implementation=0xB16e92029De283800df9030De2F255DcB99F19e9
tokenizer imple 0x672d3389b5c5a050ad93100d548817d87edc8597

USDC_ADDRESS=0x309EFD49752803D0B3Ddba2B66A7A900F99B4E70
DAO_TOKEN_ADDRESS=0x62f3cBab2C84fbA31DEc50CD21dbb5577333C69a
VDAO_TOKEN_ADDRESS=0x19A3036b828bffB5E14da2659E950E76f8e6BAA2
```

---

### upgrading to Tokenizer 1.3

forge script --private-key=$PRIVATE_KEY --rpc-url=$RPC_URL script/prod/RolloutTokenizerV13.s.sol --broadcast

// 0xTokenizer 0xNewImpl 0xNewTokenImpl
cast send --rpc-url=$RPC_URL --private-key=$PRIVATE_KEY 0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e "upgradeToAndCall(address,bytes)" 0x70e0bA845a1A0F2DA3359C97E0285013525FFC49 0x84646c1f000000000000000000000000998abeb3e57409262ae5b751f60747921b33613e

## Prerequisites

To work with this repository you have to install Foundry (). Run the following command in your terminal, then follow the onscreen instructions (macOS and Linux):

`curl -L https://foundry.paradigm.xyz | bash`

The above command will install `foundryup`. Then install Foundry by running `foundryup` in your terminal.

(Check out the Foundry book for a Windows installation guide: )

## Usage

### install dependencies and build

Run `forge install`. This will clone dependency repos as submodules into the `lib` folder.

Run `forge build`

### Testing

Run `forge test`

Run `forge test --gas-report` for gas usage reports

Run `forge test --match-contract IPNFTV2 -vvv -w` to watch only relevant tests an include meaningful output

### Hardhat tests

We also added a basic hardhat environment to this project. While foundry stays our primary tool for contract development, hardhat allows us to test e.g. JSON / metadata related features of the contracts. After installing all js dependencies (`yarn`), you can execute the hardhat tests like:

`yarn hardhat test --network hardhat`

## Deployment

### General config

- The deploy scripts are located in `script`
- Copy `.env.example` to `.env`
- Set the `ETHERSCAN_KEY` if you want to verify deployed contracts on Etherscan.
- Set a moderator address that's going to be enabled to issue and revoke mintpasses (only needed for "real" deployments)

You can place required env vars in your `.env` file and run `source .env` to get them into your current terminal session or provide them when invoking the command.

### Deployment scripts

- a fresh, proxied IPNFT deployment can be created by `forge script script/IPNFT.sol`
- to rollout a new upgrade on a live network without calling the proxy's upgrade function, you can use `forge script script/UpgradeImplementation.s.sol:DeployImplementation` and invoke the upgrade function manually (e.g. from your multisig)
- for the "real" thing you'll need to add `-f` and `--private-key` and finally `--broadcast` params .

### Deploying everything locally

You need Docker.

#### Automatically

- `yarn localenv` sets up *everything*
- use `./setupLocal.sh` to deploy all contracts. Add the optional `-f` or `--fixture` flag to also run the fixture scripts to tokenize one IPNFT or `-fx` to create two crowdsale instances.

#### Manual

- the dev scripts are supposed to run on your _local_ environment and depend on contract addresses on your local environment. Use `source .env` to pull deterministic local contract addresses to your local session.

- Anvil is a local testnet node shipped with Foundry. You can use it for testing your contracts from frontends or for interacting over RPC. You can also use the anvil node from docker, see the [accompanying README in the `subgraph` folder](./subgraph/README.md).
- Run `anvil -h 0.0.0.0` in a terminal window and keep it running

To just deploy all contracts using the default mnemonic's first account, run `forge script script/dev/Ipnft.s.sol:DeployIpnft -f $RPC_URL --broadcast`

To issue a mintpass, reserve and mint a test IPNFT for the 1st user, run `forge script script/dev/Ipnft.s.sol:FixtureIpnft -f $RPC_URL --broadcast`. This requires you to have executed Dev.s.sol before. This also creates a listing on Schmackoswap but doesn't accept it.

To deploy the Synthesizer, run `forge script script/dev/Synthesizer.s.sol:DeploySynthesizer -f $RPC_URL --broadcast`
To synthesize the test IPNFT, run `forge script script/dev/Synthesizer.s.sol:FixtureSynthesizer -f $RPC_URL --broadcast`

To deploy the StakedLockingCrowdSale contract, run `forge script script/dev/CrowdSale.s.sol:DeployCrowdSale -f $RPC_URL --broadcast`
To test a simple StakedLockingCrowdSale with Molecules, run `forge script script/dev/CrowdSale.s.sol:FixtureCrowdSale -f $RPC_URL --broadcast`

To approve and finalize the sales listing, run `forge script script/dev/ApproveAndBuy.s.sol -f $RPC_URL --broadcast`. See the inline comment on why this is a separate script.

### Deploy to a live network

> The easiest way to deploy contracts without exposing a local private key is the thirdweb. Here's how you initialize the process from the root folder: `npx thirdweb@latest deploy`

To manually broadcast a bundle of deploy transactions, you can use `Deploy.s.sol`. It deploys all three relevant contracts (IPNFT, Schmackoswap and Mintpass) and sets up a first moderator (defined by the `MODERATOR_ADDRESS` env var). Make sure that you're using the correct moderator address for the network you're deploying to.

1. Make sure you have the private key for your deployer account at hand and that it has ETH on the target network on it.
2. Run `forge script script/Deploy.s.sol:DeployScript -f $RPC_URL --interactives 1 --sender --broadcast -vvvv`
3. Paste the private key for the deployer account
4. to verify the contract during deployment, get an Etherscan API key and add `--verify --etherscan-api-key $ETHERSCAN_API_KEY` to the command.

### Deploying the Synthesizer suite

You can deploy the Synthesizer individually, but we created a deployment script that deploys all relevant contracts in the recommended order. These are

- BioPriceFeed
- TermsAcceptedPermissioner
- Synthesizer
- StakedLockingCrowdSale

You can deploy them all in one go (requires the current network's IPNFT address):

`IPNFT_ADDRESS=... forge script script/DeploySynthesizer.s.sol:DeploySynthesizerInfrastructure --private-key $PRIVATE_KEY --rpc-url $RPC_URL --broadcast`

The crowdsale computation model can be tried out here:

Deploying and verifying a single contract without the help of any script
`forge create --rpc-url $RPC_URL --private-key $PRIVATE_KEY --chain 5 --etherscan-api-key $ETHERSCAN_API_KEY --verify src/crowdsale/StakedLockingCrowdSale.sol:StakedLockingCrowdSale`

### Deploying (vested) test tokens

To test staked / vested token interactions, you need some test tokens. Here are 2 convenient script to get them running:

`NAME=Vita SYMBOL=VITA SUPPLY_ETH=10000000 forge script script/Tokens.s.sol:DeployTestTokensManually --private-key $PRIVATE_KEY --rpc-url $RPC_URL --broadcast`

and to create the vested tokens counterpart:

`TOKEN=0xaddress forge script script/Tokens.s.sol:DeployTokenVesting --private-key $PRIVATE_KEY --rpc-url $RPC_URL --broadcast`

### Testing a manual upgrade

deploy the old version

```
forge script script/IPNFT.s.sol -f $RPC_URL -vvvv --broadcast --private-key ...
```

switch your branch or get the new contract impl at hand

```
PROXY_ADDRESS= forge script script/UpgradeImplementation.s.sol -f $RPC_URL --sender
```

(or use your pk and --broadcast to submit it)

### Manually verify contracts on Etherscan

full docs:

`forge verify-contract --chain-id 5

IPNFT`

or, if you need to verify with constructor arguments:

`forge verify-contract --chain-id 5

Mintpass --constructor-args $(cast abi-encode "constructor(address)" "0xabcdef")`

ERC1967 Proxies are verified using their implementation contstructor call

`forge verify-contract --chain-id 5 ERC1967Proxy --constructor-args $(cast abi-encode "constructor(address,bytes)" "" "")`

## checking with mythril on docker

`docker run -m 6G --cpus=8 -w /tmp -v $(pwd):/tmp mythril/myth analyze /tmp/src/IPNFT.sol --solc-json /tmp/mythril.config.json`

## Creating coverage reports

requires the lcov suite installed on your machine

```
forge coverage --report lcov && genhtml lcov.info -o report --branch-coverage
```

## Interacting with cast

`cast` is another CLI command installed by Foundry and allows you to query/manipulate your deployed contracts easily. Find out more here:

When having an RPC_URL in your local env, you e.g. can simply call view functions like this:
`cast call $IPNFT_ADDRESS "tokenURI(uint256)" 1 | cast --to-ascii`

### manual interaction playbook

Here are some helpful interaction examples with the contracts that you can execute from your command line. Ensure your local environment contains all contract addresses and is sourced to your terminal. We're using your local PRIVATE_KEY here

Manually issue 2 mintpasses to anvil address #0

`cast send -i $MINTPASS_ADDRESS --private-key $PRIVATE_KEY "batchMint(address,uint256)" 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 2`

Create a reservation

`cast send -i $IPNFT_ADDRESS --private-key $PRIVATE_KEY "reserve()(uint256)"`

mint an IP-NFT to the first account

`cast send --private-key $PRIVATE_KEY -i $IPNFT_ADDRESS --value 0.001ether --broadcast "mintReservation(address,uint256,uint256,string)(uint256)" 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 1 1 "ipfs://test"`

approve SchmackoSwap to spend token 0

`cast send -i $IPNFT_ADDRESS --private-key $PRIVATE_KEY "approve(address, uint256)()" $SOS_ADDRESS 0`

Create a Listing for 10 sample tokens

`cast send -i $SOS_ADDRESS --private-key $PRIVATE_KEY "list(address, uint256, address, uint256)(uint256)" $IPNFT_ADDRESS 0 $ERC20_ADDRESS 10`

take note of the resulting listing id

Cancel a listing

`cast send -i $SOS_ADDRESS --private-key $PRIVATE_KEY "cancel(uint256)()" `

Create a new Listing (take down id)

`cast send -i $SOS_ADDRESS --private-key $PRIVATE_KEY "list(address, uint256, address, uint256)(uint256)" $IPNFT_ADDRESS 0 $ERC20_ADDRESS 10`

allow Account(1)

`cast send -i $SOS_ADDRESS "changeBuyerAllowance(uint256, address, bool)()" 0x70997970c51812dc3a010c7d01b50e0d17dc79c8 true`

supply Account(1) with ERC20

`cast send -i $ERC20_ADDRESS --private-key $PRIVATE_KEY "mint(address, uint256)()" 0x70997970c51812dc3a010c7d01b50e0d17dc79c8 10`

allow SOS to spend ERC20

`cast send --i $ERC20_ADDRESS --private-key "increaseAllowance(address, uint256)()" $SOS_ADDRESS 10`

let account(1) fulfill the listing

`cast send -i \$SOS_ADDRESS --private-key "fulfill(uint256)()" `

grant read access to another party

`cast send --private-key $PRIVATE_KEY -i $IPNFT_ADDRESS "grantReadAccess(address,uint256,uint256)" 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 1 1680265071`

## Actions

We are using Tenderly Web3Actions to trigger actions based on emitted Events from our deployed Contracts.

These are setup under the moleculeprotocol organization on Tenderly.
The QueryIds and API-KEY are stored in the Tenderly context and can be accessed via the Tenderly Frontend.
To update these actions you need the Tenderly login credentials.

- StakedLockingCrowdSale (Mainnet & Goerli): BidEvent => Triggers a POST request that executes Dune Queries to update the Dune Visualizations.

You can find out more about Web3Actions on Tenderly here:
How to init & deploy new Web3Actions: