# Rarible/Daohaus Boost Phase 1 deliverables link to initial proposal https://gov.rarible.com/t/collector-daos-with-rarible-boost-on-daohaus/13023 contributors to this doc Dekan, Isaac, Penguin, Ven ## Table of contents [User Research](#User-Research) * Hypothesis * User interviews and feedback * Conculsion [DAO mechanics Research](#DAO-mechanics---Tribute-Rage-Quitting-amp-Buyouts) * NFT Tribute * Rage Quitting * Buyouts * Buyout penalty * Fractionalization [Rarible Boost Integration Research](#Rarible-Boost-Integration-Research) * Rarible Boost Integration Research * Future Research Needed * Daohaus Integration and UI * Figma [Rarible Protocol Overview](#Rarible-Protocol-Overview) [Contracts](#Contracts) [Order Structure](#Order-Structure) * Sell Orders * Buy Orders * Bid Orders [Fees](#Fees) [Indexing](#Indexing) [Exchange Alternatives](#Exchange-Alternatives) [Minion Integration](#Minion-Integration) [Multi Chain](#Multi-Chain) ## User Research ### Hypothesis Most DAOs that engage with NFTs do not have a good solution and are looking for ways to empower community with NFT buying, selling and minting. ### User interviews and feedback, dao community outreach and engagement * Created Survery to Colelct DAO use of NFTs with particular focus of * DaoHaus Rarible Survey: https://hrf435j03ci.typeform.com/to/XGaHb0Gl * Results: https://docs.google.com/spreadsheets/d/1xg2bPFkF0glDKo2poG4iZQ0SqlmvlX9SdHnKQNsOUbk/edit?usp=sharing * Engage initial communities that want to use and test initial project * Established testing group of UX based on Survey. * Response was very positive and most people either were not actively engaging with NFTs as a dao or that was their main focus. Nearly everyone saw the value in being able to buy sell and trade NFTs but had questions about NFT tribute and upon exit from the dao. Several of the larger NFT focused DAOs would be willing to pay for aditional brokerage services and appraisal. * People want to be able to see the daos collection. * Most people were excited to hear that Moloch and Rarible were working on the problem and several were already looking for a solution to do this in the market. ### Conculsion We have very good market timing and are catching DAOs at a time where they are intersecting with NFTs more frequently. Being able to put DaoHaus and Rarible as the initial seed should help gain adoption. Several larger organizations took the time to response and were interested which speak highly to current market users and also familiar enough to make people that had not considered it interested. ## DAO mechanics Tribute, Rage Quitting & Buyouts ### NFT Tribute Prospective members can tribute an NFT in exchange for new DAO shares. A simple implementation for this system would use a conditional minion escrow attached to a share funding proposal. First the prospective member must deposit an NFT into an escrow minion. The NFT is allowed to be withdrawn under 2 scenarios: * Membership proposal passes, NFT withdrawable by DAO by executing Minion action * Membership proposal fails, NFT withdrawable by proposer https://static.swimlanes.io/931d1ad1a41ecfa6dc227b1e5c6337ec.png ![](https://i.imgur.com/xm7aHUy.png) ### Rage Quitting NFTs are not 'rage-quittable' through the existing DAO framework. NFTs are not held in the main DAO treasury, and they are not divisible. Members of a DAO that holds NFTs *can* still rage quit and get their share of the treasury, but the value they receive is not proportional to the total value held by the DAO. For some quitting scenarios, this may be an acceptable situation, but often a member may wish to leave with their fair share of the NFT value as well. ### Buyouts A member can propose that they receive a buyout for their position in the DAO. The buyout would be paid upon rage quitting, and demonstrating that the individual now has 0 shares in the DAO. The formula for calculating a fair buyout prices is: ``` Buyout Price: P Value of NFTs held by DAO: V Number of shares held by other members: N_m P = V / N_m ``` *Example* ``` V: $150 of NFTs held by DAO T: $100 of ERC20s in DAO treasury N_total: 100 shares total N_rq: 25 shares owned by leaving member N_m: 75 shares owned by everyone else Leaving member's shares are worth 25/100 * $250 = $62.50 P = V / N_m P = $150 / 75 P = $2 ------------------------------------ Step 1 - Buyout proposal is funded V: $150 of NFTs held by DAO T: $50 of ERC20s in DAO treasury N_total: 100 shares total N_rq: 25 shares owned by leaving member N_m: 75 shares owned by everyone else E: $50 is held in buyout escrow ------------------------------------ Step 2 - Member rage quits V: $150 of NFTs held by DAO T: $37.50 of ERC20s left in treasury N_total: 75 shares total N_rq: 0 shares owned by leaving member N_m: 75 shares owned by everyone else Member has received $12.50 They are now allowed to withdraw the remaining $50 from buyout escrow ------------------------------------ Step 3 - Member receives buyout funds V: $150 of NFTs held by DAO T: $37.50 of ERC20s left in treasury N_total: 75 shares total N_rq: 0 shares owned by leaving member N_m: 75 shares owned by everyone else Member has now received a total of $62.50 DAO shares are worth the same as they were when this started ``` #### Buyout penalty We can also calculate a buyout price that leaves the member with slightly less than their share value. This leaves the other DAO members with slightly higher value of their shares. ``` Buyout Price: P Value of NFTs held by DAO: V Number of shares held by other members: N_m Number of shares held by leaving member: N_rq Number of shares total: N_total Premium/ penalty left behind to DAO: R P = (V * N_rq - R * N_rq - R * N_m) / (N_m * N_rq) ``` *Example* ``` V: $150 of NFTs held by DAO T: $100 of ERC20s in DAO treasury N_total: 100 shares total N_rq: 25 shares owned by leaving member N_m: 75 shares owned by everyone else R: $1 penalty Leaving member's shares are worth 25/100 * $250 = $62.50 P = (V * N_rq - R * N_rq - R * N_m) / (N_m * N_rq) P = (150 * 25 - 1 * 25 - 1 * 75) / (75 * 25) P = $1.95 ------------------------------------ Step 1 - Buyout proposal is funded V: $150 of NFTs held by DAO T: $51.25 of ERC20s in DAO treasury N_total: 100 shares total N_rq: 25 shares owned by leaving member N_m: 75 shares owned by everyone else E: $48.75 is held in buyout escrow ------------------------------------ Step 2 - Member rage quits V: $150 of NFTs held by DAO T: $38.44 of ERC20s left in treasury N_total: 75 shares total N_rq: 0 shares owned by leaving member N_m: 75 shares owned by everyone else Member has received $12.81 They are now allowed to withdraw the remaining $48.75 from buyout escrow ------------------------------------ Step 3 - Member receives buyout funds V: $150 of NFTs held by DAO T: $38.44 of ERC20s left in treasury N_total: 75 shares total N_rq: 0 shares owned by leaving member N_m: 75 shares owned by everyone else Member has now received a total of $61.56 DAO shares are worth more than they were when this started ``` A model for buyout price & buyout fees can be found here: https://docs.google.com/spreadsheets/d/1EscQrD4ePCH_xS0KDpCAYiMyNjy5-Ppd0mE9BsP0yR4/edit?usp=sharing A proof of concept conditional minion that release funds upon a member rage quitting can be found here: https://github.com/ipatka/MinionSummoner/tree/ipatka-conditional-minion https://static.swimlanes.io/05dbe742fb405206d893744c697a5540.png ![](https://i.imgur.com/1ZPJwh7.png) ### Fractionalization Once NFTs are purchased by the DAO, the members could choose to send the NFT to a fractionalization platform like Fractional, Unicly, or add them to a token denominated index like Niftex or NFTX. The resulting tokens would go into the DAO treasury and would become 'rage-quittable' by members. While this is possible, we anticipate that DAOs will often prefer to keep NFTs whole. Both scenarios are feasible with minimal additional development effort. https://static.swimlanes.io/78f972cb6061e3d44f262601351092b2.png ![](https://i.imgur.com/RFFaqld.png) ## Rarible Boost Integration Research This section summarizes the Rarible protocol interactions relevant to boost development and includes information on the feasibility of integration with the Minion framework, as well as potential alternatives if needed. The example code in this section is generated from this repo which demonstrates the functionality of signatures, contract signatures, order creation, and order matching on Rarible. https://github.com/ipatka/scaffold-eth/tree/raribleBoost ### Future Research Needed This overview excludes the information on Minting, including royalty and origination fee standards ### Daohaus integration An initial user test of managing NFTs on a side chain has been created. Several things came out of these tests and a start to a special minion contract that can handle specific things, like early execution for quick acton by DAOs and main treasury funds withdraws to NFT vaults for buying NFTS #### UI elements * New boost launcher * On the daohaus 'apps' page we will need to add a new rarible boost type. This will launch a custom minion from a minion factory that can be indexed by the subgraph. * NFT cards * new component to list nft collections, tokens, and metadata * Proposal details * THe propsal detail page will display metadata associated around a NFT buy/sell/bid proposals * actions will include - sponser, vote, process, execute and early execute. * early execute: a special execution type that cecks some configured quorum. If the quorum has been met and their is no NO votes a proposal could be executed early. THis allows the dao to act quick with time sesitive orders * Buy NFT Proposal type * A new proposal type of 'Buy NFT' * proposal form to take in a rarible nft detail page url and from that pull out the token id information to hydrate metadata from the rarible api * display NFT metadata * display saleprice/last sale price if availible * price/bid field * New Member NFT tribute proposal * This will add a way for new members to tribute NFTs directly into a NFT valut * Buyout Ragequit proposal * members can exit the dao buy making a proposal for the dao to buy them out. This is important when assets like nfts are held in an external vault. * Discord notifications * current discord notifications should include a visual element if possible * Nft dao prototype notes and tests https://hackmd.io/5HIXIRHeQl-m_QPKmgW5Sw?both ### Spec initial design with Figma prototype. ![](https://i.imgur.com/H8trdNT.jpg) ![](https://i.imgur.com/xrxUAx9.jpg) ![](https://i.imgur.com/pQrxuPh.png) ### figma https://www.figma.com/file/DyuLU9SbCf8BWNrUMnSXsi/DAOHaus-v2-UX?node-id=2435%3A3343 ## Rarible Protocol Overview Rarible's protocol includes contracts, standards, and APIs for: **Minting** (mostly out of scope of this doc) * Minting (Both ERC721 & ERC1155) * Lazy Minting - Token metadata & minting signatures are stored on Rarible back-end until a buyer fills the order. Then a `mintAndTransfer` call is made on chain when the order is filled **Exchange** (Buy, Sell, Bid) * Signature based order matching using an off chain order book * Asset discovery is off chain, then buyers or sellers can submit both sides of an order, including relevant signatures to execute a transfer. * Asset owners must `approve` the Rarible exchange to transfer on their behalf * Multiple asset types are supported to fill orders (ERC721, ERC1155, ERC20) * Bidding is supported using unmatched buy orders **Indexer** * Rarible API exposes ways to query NFTs indexed on Ethereum * Rarible API exposes ways to create orders ## Contracts | Contract | Rinkeby Address | | -------- | -------- | | Asset Contract ERC721 | 0x6ede7f3c26975aad32a475e1021d8f6f39c89d82| | Asset Contract ERC1155 | 0x1AF7A7555263F275433c6Bb0b8FdCD231F89B1D7| |Exchange Contract | 0x1e1B6E13F0eB4C570628589e3c088BC92aD4dB45| |NFT Transfer Proxy (for NFT approvals) | 0x7d47126a2600E22eab9eD6CF0e515678727779A6 | | ERC20 Transfer Proxy (for ERC20 approvals) | 0x2FCE8435F0455eDc702199741411dbcD1B7606cA | ## Order Structure Each order (both buy & sell) consist of a `makeAsset` and a `takeAsset` **Make Asset** is what you are sending. * In a buy order this is what you are *paying* for the seller's NFT. This can be ETH, ERC20, ERC721, ERC1155, or any custom asset using their Asset Matcher interface * In a sell order this is the NFT you are selling **Take Asset** is what you are accepting in return * In a buy order this is the NFT you are buying * In a sell order this is what you are willing to accept. ### Order | Field | Description | Required | | -------- | -------- | -------- | | **Maker** | Address of entity giving up `makeAsset` | Yes | | **makeAsset** | Asset the entity is giving up | Yes | | **taker** | Address of counterparty | no, if 0 then anyone can fill the order | | **takeAsset** | Asset the entity is receving | Yes | | **salt** | nonce for signatures submitted with the order | Generally signatures are only needed if msg.sender != maker | | **start** | uint - order can't be filled before this time | no | | **end** | uint - order can't be filled after this time | no | | **dataType** | bytes4, usually hash of a string like v1 or v2 | ? | | **data** | generic `bytes`. Can be used for protocol extensions | no | ### Asset | Field | Description | Required | | -------- | -------- | -------- | | assetType | Specifies ETH, specific ERC20, ERC721, ERC1155 | Yes | | value | uint | Yes | ### AssetType | Field | Description | Required | | -------- | -------- | -------- | | assetClass | bytes4 specifies ETH, ERC20, ERC721 | Yes | | data | bytes - generic data depending on tp. Ex. address for ERC20, token + tokenID for ERC721 | yes | ### Asset Types Asset Class data field is calculated as follows ``` bytes4 constant public ETH_ASSET_CLASS = bytes4(keccak256("ETH")); bytes4 constant public ERC20_ASSET_CLASS = bytes4(keccak256("ERC20")); bytes4 constant public ERC721_ASSET_CLASS = bytes4(keccak256("ERC721")); bytes4 constant public ERC1155_ASSET_CLASS = bytes4(keccak256("ERC1155")); ``` All asset types get encoded using these helper functions https://github.com/rariblecom/protocol-contracts/blob/master/exchange-v2/test/assets.js #### ERC721 `assetClass`: Truncated hash of string "ERC721" `data`: ABI encoded parameters of `address` and `tokenId` `value`: 1 ERC721 Input (Pre encoding) ``` { assetType: { assetClass: "ERC721", token: "0x25646b08d9796ceda5fb8ce0105a51820740c049", tokenId: "0xc66d094ed928f7840a6b0d373c1cd825c97e3c7c00000000000000000000000a" }, value: "1", } ``` #### ERC1155 `assetClass`: Truncated hash of string "ERC1155" `data`: ABI encoded parameters of `address` and `tokenId` `value`: 1->totalSupply ERC1155 Input (Pre encoding) ``` { assetType: { assetClass: "ERC1155", token: "0x25646b08d9796ceda5fb8ce0105a51820740c049", tokenId: "0xc66d094ed928f7840a6b0d373c1cd825c97e3c7c00000000000000000000000a" }, value: "100", } ``` #### ERC20 `assetClass`: Truncated hash of string "ERC20" `data`: ABI encoded parameters of `address` `value`: 1->totalSupply ERC20 Input (Pre encoding) ``` { assetType: { assetClass: "ERC20", token: "0x25646b08d9796ceda5fb8ce0105a51820740c049", }, value: "10000000000000000", } ``` #### ETH `assetClass`: Truncated hash of string "ETH" `data`: 0x `value`: 1->1e18 Input (pre encoding) ``` { assetType: { assetClass: "ETH" }, value: "10000000000000000", }, ``` #### Custom Asset Matcher Any asset can be added `assetClass`: Truncated hash of any string `data`: Whatever is relevant `value`: some uint ### Sell Orders #### Sell ERC721 for ERC20 #### Sell ERC721 for ETH **You can only fill an ETH order if your side of the order is providing the ETH**. Otherwise you would have to use WETH which has the transferFrom capability. **First** Encode the order for signing POST to `https://api-staging.rarible.com/protocol/v0.1/ethereum/order/encoder/order` ``` { "type": "RARIBLE_V2", "maker": "0x744222844bFeCC77156297a6427B5876A6769e19", "make": { "assetType": { "assetClass": "ERC721", "contract": "0xcfa14f6DC737b8f9e0fC39f05Bf3d903aC5D4575", "tokenId": 1 }, "value": "1" }, "take": { "assetType": { "assetClass": "ETH" }, "value": "1000000000000000000" }, "data": { "dataType": "RARIBLE_V2_DATA_V1", "payouts": [], "originFees": [] }, "salt": "3621" } ``` Response: ``` { "maker": "0x744222844bfecc77156297a6427b5876a6769e19", "makeAsset": { "assetType": { "assetClass": "0x73ad2146", "data": "0x000000000000000000000000cfa14f6dc737b8f9e0fc39f05bf3d903ac5d45750000000000000000000000000000000000000000000000000000000000000001" }, "value": "1" }, "taker": "0x0000000000000000000000000000000000000000", "takeAsset": { "assetType": { "assetClass": "0xaaaebeba", "data": "0x" }, "value": "1000000000000000000" }, "salt": "3621", "start": "0", "end": "0", "dataType": "0x4c234266", "data": "0x0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" } ``` **Then** Sign the order ``` async function sign(provider, order, account, verifyingContract) { const chainId = Number(provider._network.chainId); const data = EIP712.createTypeData({ name: "Exchange", version: "2", chainId, verifyingContract }, 'Order', order, Types); console.log({data}) return (await EIP712.signTypedData(provider, account, data)).sig; } ``` **Then** Post the order to Rarible indexer POST to `https://api-staging.rarible.com/protocol/v0.1/ethereum/order/orders` Payload ``` { "type": "RARIBLE_V2", "maker": "0x744222844bFeCC77156297a6427B5876A6769e19", "make": { "assetType": { "assetClass": "ERC721", "contract": "0xcfa14f6DC737b8f9e0fC39f05Bf3d903aC5D4575", "tokenId": 1 }, "value": "1" }, "take": { "assetType": { "assetClass": "ETH" }, "value": "1000000000000000000" }, "data": { "dataType": "RARIBLE_V2_DATA_V1", "payouts": [], "originFees": [] }, "salt": "5422", "signature": "0x45461654b86e856686e7a2e9a9213b29f8dc32a731046e0c2f1aa01e4eaa991e41ebc67535fac14c333ad5b0d0d821ef518edc9ed08ad7efc0af572620c045ce1c" } ``` Response ``` { "maker": "0x744222844bfecc77156297a6427b5876a6769e19", "make": { "assetType": { "assetClass": "ERC721", "contract": "0xcfa14f6dc737b8f9e0fc39f05bf3d903ac5d4575", "tokenId": "1" }, "value": "1" }, "take": { "assetType": { "assetClass": "ETH" }, "value": "1000000000000000000" }, "type": "RARIBLE_V2", "fill": "0", "makeStock": "1", "cancelled": false, "salt": "0x000000000000000000000000000000000000000000000000000000000000152e", "data": { "dataType": "RARIBLE_V2_DATA_V1", "payouts": [], "originFees": [] }, "signature": "0x45461654b86e856686e7a2e9a9213b29f8dc32a731046e0c2f1aa01e4eaa991e41ebc67535fac14c333ad5b0d0d821ef518edc9ed08ad7efc0af572620c045ce1c", "createdAt": "2021-05-25T02:04:28.836+00:00", "lastUpdateAt": "2021-05-25T02:04:28.983+00:00", "pending": [], "hash": "0xc9cb92588fc1434a417f4cacb9e1267750e6f1cbe650988a6fdc1d0be8a310a9", "makeBalance": "1", "takePriceUsd": 2735.1365826056253000000000000000000 } ``` #### Sell ERC721 for another ERC721 #### Sell ERC721 for ERC1155 ### Buy Orders #### Pay ERC20 for ERC721 #### Pay ETH for ERC721 **You can only fill an ETH order if your side of the order is providing the ETH**. Otherwise you would have to use WETH which has the transferFrom capability. Encoded order ``` { "maker": "0x744222844bfecc77156297a6427b5876a6769e19", "makeAsset": { "assetType": { "assetClass": "0xaaaebeba", "data": "0x" }, "value": "100000000000000000" }, "taker": "0x0000000000000000000000000000000000000000", "takeAsset": { "assetType": { "assetClass": "0x73ad2146", "data": "0x000000000000000000000000cfa14f6dc737b8f9e0fc39f05bf3d903ac5d45750000000000000000000000000000000000000000000000000000000000000005" }, "value": "1" }, "salt": "0", "start": "0", "end": "0", "dataType": "0x4c234266", "data": "0x0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" } ``` Example transaction that has both a signed sell order and an unsigned buy order, submitted by the buyer. https://rinkeby.etherscan.io/tx/0x2d01b1869b556629acf7304b53d2f77fd927a2c3c9daea02aa093ba8ba41b4c6 #### Swap ERC721 for ERC721 #### Pay ERC1155 for ERC721 ### Bid Orders A bid is just an unmatched buy order. The seller accepts it by creating a matched order. ## Signatures Signatures are required to validate the orders. They are only required when the order maker is not the message sender. This means a buyer can submit an order to the contract without their signature, only the seller's signature. And in return, a seller can submit an order to the contract without their signature, only the buyer's signature. ### EIP712 #### Example Sell ERC721 for ETH ``` { "types": { "EIP712Domain": [ { "type": "string", "name": "name" }, { "type": "string", "name": "version" }, { "type": "uint256", "name": "chainId" }, { "type": "address", "name": "verifyingContract" } ], "AssetType": [ { "name": "assetClass", "type": "bytes4" }, { "name": "data", "type": "bytes" } ], "Asset": [ { "name": "assetType", "type": "AssetType" }, { "name": "value", "type": "uint256" } ], "Order": [ { "name": "maker", "type": "address" }, { "name": "makeAsset", "type": "Asset" }, { "name": "taker", "type": "address" }, { "name": "takeAsset", "type": "Asset" }, { "name": "salt", "type": "uint256" }, { "name": "start", "type": "uint256" }, { "name": "end", "type": "uint256" }, { "name": "dataType", "type": "bytes4" }, { "name": "data", "type": "bytes" } ] }, "domain": { "name": "Exchange", "version": "2", "chainId": 4, "verifyingContract": "0x1e1B6E13F0eB4C570628589e3c088BC92aD4dB45" }, "primaryType": "Order", "message": { "maker": "0x744222844bfecc77156297a6427b5876a6769e19", "makeAsset": { "assetType": { "assetClass": "0x73ad2146", "data": "0x000000000000000000000000cfa14f6dc737b8f9e0fc39f05bf3d903ac5d45750000000000000000000000000000000000000000000000000000000000000001" }, "value": "1" }, "taker": "0x0000000000000000000000000000000000000000", "takeAsset": { "assetType": { "assetClass": "0xaaaebeba", "data": "0x" }, "value": "1000000000000000000" }, "salt": "6274", "start": "0", "end": "0", "dataType": "0x4c234266", "data": "0x0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" } } ``` ![](https://i.imgur.com/Ry921oC.png) ### EIP1271 Example implementation: https://rinkeby.etherscan.io/address/0x998Cf6fDd7FF1EB258c288762284142D28D0ee39#code EIP1271 allows a contract to delegate authorized signers. Usually EIP1271 expects an authorized delegate to submit a signature via the contract, and uses typical ECrecover to see if the signature is valid. EIP1271 returns `valid signature: true**` if the signature is valid & the signer is authorized by the contract ** not actually `true`, but instead a magic value to guard against mistaken 'true' bit However you can also implement EIP1271 to return `valid signature: true` for any bytes value. This is useful for a DAO which has no single authorized signer. Instead the bytes value would return as a valid signature if a proposal passes. The Rarible contract checks if the signature is valid with the following code ``` require( ERC1271(order.maker).isValidSignature(_hashTypedDataV4(hash), signature) == MAGICVALUE, "contract order signature verification error" ); ``` The minion should therefore implement the `isValidSignature` method as follows (pseudocode) ``` function isValidSignature(msgHash, signature): if messageHash corresponds to passed proposal && signature corresponds to same proposal: return MAGICVALUE ``` In solidity this would probably be implemented like ``` Struct DAOSig { uint256 proposalId bytes signature bytes4 magicValue } mapping (msgHash => DAOSig) sigs; function isValidSignature (msgHash, signature) { require(proposalPassed(proposalId)); require(sigs[msgHash].signature == signature); return sigs[msgHash].magicValue } ``` #### Example Contract approves NFT to be transfered by Rarible proxy https://rinkeby.etherscan.io/tx/0xf125555eb7ae1f5067cd3b0a7c119c789854cdc56245f060979fad1f6b772ec8 Create the proposal with EIP1271 signature https://rinkeby.etherscan.io/tx/0x670321b9a4467b578a5c625608705dbc679317fcda0559574e8e625bb3f906e2 ![](https://i.imgur.com/RCqXJrq.png) Set the proposal to passed https://rinkeby.etherscan.io/tx/0x78cf14365e9b414572275c785c8dbb467bf82c2fe8ab5033502bedd9e343434a Magic value returns successfully ![](https://i.imgur.com/0yZWdP6.png) ## Fees Rarible calculates 3 types of fees during a transfer: **origin**, **royalties**, and **protocol** Origin fees are specified for each order Royalties are defined by the NFT Protocol fees are defined by the contract. ## Indexing Example of how to query orders for all NFTs in a collection ``` curl --location --request GET 'https://api-staging.rarible.com/protocol/v0.1/ethereum/order/orders/sell/byCollection?collection=0xcfa14f6DC737b8f9e0fC39f05Bf3d903aC5D4575&sort=LAST_UPDATE' ``` Response ``` { "orders": [ { "maker": "0x744222844bfecc77156297a6427b5876a6769e19", "make": { "assetType": { "assetClass": "ERC721", "contract": "0xcfa14f6dc737b8f9e0fc39f05bf3d903ac5d4575", "tokenId": "1" }, "value": "1" }, "take": { "assetType": { "assetClass": "ETH" }, "value": "1000000000000000000" }, "type": "RARIBLE_V2", "fill": "0", "makeStock": "1", "cancelled": false, "salt": "0x00000000000000000000000000000000000000000000000000000000000002b3", "data": { "dataType": "RARIBLE_V2_DATA_V1", "payouts": [], "originFees": [] }, "signature": "0xf45a9adfb58fdd9da808b5f80302ebdb7d75f032d6aaee9700ee93f567fff3b148116a93ad2bd908a2d8e9576295650460a653d442f7c3472cb8f1275739075e1c", "createdAt": "2021-05-25T01:33:43.358+00:00", "lastUpdateAt": "2021-05-25T01:33:43.532+00:00", "pending": [], "hash": "0x0b3007a2a4cd8701f98b8fd02f2a9bc09320d11d5e4fa8134f884904d8bfdf3b", "makeBalance": "1", "takePriceUsd": 2735.136582605625300000000000000000 } ], "continuation": "1621906423532_0b3007a2a4cd8701f98b8fd02f2a9bc09320d11d5e4fa8134f884904d8bfdf3b" } ``` ## Exchange Alternatives ### Delegate There may be scenarios where direct execution of marketplace transactions is not feasible for a DAO. These include: * Off chain auctions * Timed auctions with live bidding In these scenarios the DAO may wish to elect a delegate to take some DAO funds, complete the transaction, and return the assets. If the acquisition only requires a single, well-timed transaction, an escrow contract could be set up that releases the funds once a desired contract state is achieved. In our case, the escrow contract would hold funds (say $100), and the desired future state would be that Address X is the owner of NFT Y. Any delegate could create a transaction that withdraws funds from escrow, provided the desired state is achieved in the same transaction. If this is too complex, we could also just use a smart invoice system where there is 3rd party arbitration functionality. However the risk of a simple invoce system is that the delegate might need to float their own capital to make the transaction. Maybe in the future someone will make a system to borrow a line of credit against a smart invoice. ### Other NFT Marketplaces OpenSea uses the Wyvern protocol, which has a similar order book structure to Rarible. There is an order indexer, signature based maker and taker orders, and an asset matching contract on chain. https://docs.opensea.io/reference#terminology The structures are not exactly the same, but the same overall proposal flow we have defined here should work with any Wyvern system too. Wyvern specifies a calldata matching system > Matching calldata can be constructed in any fashion off-chain. The protocol does not care how the final calldata is obtained, only that it fulfills the orders' predicate functions. In practice, orderbook maintainers (relayers) will likely store additional metadata along with orders which can be used to construct possible matching calldatas. https://wyvernprotocol.com/docs This should mean it is possible to use the same EIP1271 system for call data matching. ## Minion Integration ### Lifecycle of a proposal ![](https://i.imgur.com/uUaKk8j.png) https://swimlanes.io/u/30aSd055Y?rev=2 ### Minion contract exploration * special early execute minion factory exploration https://github.com/HausDAO/NiftyMInionSummoner * buyout minion https://github.com/ipatka/MinionSummoner/tree/ipatka-conditional-minion ## Multi Chain The same system will work for any chain where Rarible protocol is implemented. We would just need to change the indexer API calls and contract addresses to the relevant chain where the DAO & NFTs operate. This proposal does not currently include considerations for cross chain execution of proposals. This means DAOs and NFTs and Rarible need to be on the same chain for now. * Research application of AMB to govern & hold NFTs on different chains/ layer 2 @Dekan Although this may not be the first usecase we have started doing exploration into cross chain interactions using a DAO on a side chain and a gnosis safe on mainnet. A layer 2 sidechain minion (xdai currently) can be used to control a gnosis safe. This flow would work by a signer on the safe staging up transactions and the DAO voting through a proposal that allows the minion to execute the transaction. there is a seperate initiative with Gnosis to build out this usecase. current work can be viewed here. https://hackmd.io/c9up0zF5QDSiD87ACiw6HA