|
| 1 | +# Rentable Protocol |
| 2 | + |
| 3 | +NFT Renting Protocol |
| 4 | + |
| 5 | +## Architecture |
| 6 | + |
| 7 | +- [`Rentable.sol`](contracts/Rentable.sol): protocol core logic. It holds all the NFT deposited. |
| 8 | +- [`ORentable.sol`](contracts/tokenization/ORentable.sol): ERC721 token representing deposits (and asset ownership). Each NFT collection has a respective `ORentable` with the same token ids. It is minted on deposit and burnt on withdraw. `ORentable` can contain custom logic and use `Rentable.proxyCall` to operate on deposited assets. |
| 9 | +- [`WRentable.sol`](contracts/tokenization/WRentable.sol): ERC721 token, wrapper of the original NFT representing the rental. Each NFT collection has a respective `WRentable` with the same token ids. It is minted when rental starts and burnt on expiry. `WRentable.ownerOf` reflects rental duration (i.e., renter loses `WRentable` owerniship when rental period is over). `WRentable` can contain custom logic and use `Rentable.proxyCall` to operate on deposited assets. |
| 10 | +- [`ICollectionLibrary.sol`](contracts/collections/ICollectionLibrary.sol): interface to implement hooks on protocol events (e.g., `postDeposit`, `postRent`) for a given collection. Governance can set a Collection Library via `Rentable.setLibrary`. |
| 11 | +- [`SimpleWallet.sol`](contracts/wallet/simplewallet.sol): smart wallet used by the renter, cannot withdraw the rented assets but only interact with allowed protocols/methods. Implements EIP1217 for Standard Signature Validation enabling Wallet Connect logins. |
| 12 | +- [`WalletFactory.sol`](contracts/wallet/simplewallet.sol): factory for smart wallets, used by Rentable to generate upgradeable smart wallets for users. |
| 13 | + |
| 14 | +The following diagram shows the main components and their interactions. _ERC721 NFT Collection_ represents a generic NFT collection (e.g., Decentraland LAND) and it is not part of Rentable. |
| 15 | + |
| 16 | + |
| 17 | + |
| 18 | +## Main flows |
| 19 | + |
| 20 | +- **Rentee deposits an NFT (without listing)** |
| 21 | + - Call `safeTransferFrom(ownerAddress, rentableAddress, data)` on the NFT collection contract with empty data |
| 22 | +- **Rentee deposits and lists an NFT** |
| 23 | + - Call `safeTransferFrom(ownerAddress, rentableAddress, data)` on the NFT collection contract with [RentableTypes.RentalConditions](contracts/RentableTypes.sol) encoded in the `data` field |
| 24 | + - Rentee receives a `ORentable` token representing the deposit (and asset ownership) |
| 25 | +- **Rentee changes the rental conditions of a listed NFT** |
| 26 | + - Call `createOrUpdateRentalConditions` on Rentable |
| 27 | +- **Rentee delists an NFT** |
| 28 | + - Call `deleteRentalConditions` on Rentable |
| 29 | +- **Rentee withdraws an NFT** |
| 30 | + - Call `withdraw` on Rentable |
| 31 | +- **Renter rents an NFT** |
| 32 | + - Call `rent(address tokenAddress, uint256 tokenId, uint256 duration)` on Rentable |
| 33 | + - if payment token is Ether, renter must pay `pricePerSecond*duration` |
| 34 | + - if payment token is ERC20 or ERC1155, renter must have an amount equals to `pricePerSecond*duration` and approve Rentable to transfer it |
| 35 | + - Renter receives a `WRentable` |
| 36 | + - Renter receives the original NFT in its own `SimpleWallet` (cannot withdraw, only interact on owner approved protocols/methods) |
| 37 | + |
| 38 | +## Requirements |
| 39 | + |
| 40 | +To run the project you need: |
| 41 | + |
| 42 | +- Python 3.8 local development environment and Node.js 14.x development environment for Ganache. |
| 43 | +- Brownie local environment setup. Install |
| 44 | + [instructions](https://eth-brownie.readthedocs.io/en/stable/install.html). |
| 45 | +- Foundry. Install [instructions](https://github.com/gakonst/foundry#installation) |
| 46 | + |
| 47 | +## Test |
| 48 | + |
| 49 | +```bash |
| 50 | +yarn test |
| 51 | +``` |
| 52 | + |
| 53 | +## Installation |
| 54 | + |
| 55 | +To use the tools that this project provides, please pull the repository from GitHub |
| 56 | +and install its dependencies as follows. |
| 57 | +You will need [yarn](https://yarnpkg.com/lang/en/docs/install/) installed. |
| 58 | +It is recommended to use a Python virtual environment. |
| 59 | + |
| 60 | +```bash |
| 61 | +git clone https://github.com/rentable-world/rentable-protocol |
| 62 | +cd rentable-protocol |
| 63 | +yarn install --lock-file |
| 64 | +pip install -r requirements-dev.txt |
| 65 | +``` |
| 66 | + |
| 67 | +## Usage |
| 68 | + |
| 69 | +1. Choose network |
| 70 | +2. Deploy contracts (or use already deployed ones) |
| 71 | +3. Prepare your account |
| 72 | +4. Use network console |
| 73 | + |
| 74 | +Remember to [add](https://metamask.zendesk.com/hc/en-us/articles/360043227612-How-to-add-a-custom-network-RPC) the network to your Metamask |
| 75 | + |
| 76 | +### Network |
| 77 | + |
| 78 | +Run the following commands respectively and keep the session open. Network is ephemeral, when you close the command you reset it. |
| 79 | + |
| 80 | +#### Local Testnet |
| 81 | + |
| 82 | +```bash |
| 83 | +yarn network:testnet |
| 84 | +``` |
| 85 | + |
| 86 | +#### Mainnet Fork |
| 87 | + |
| 88 | +Useful to interact with other protocols in mainnet via a local fork. |
| 89 | + |
| 90 | +You need local env variables for [Etherscan API](https://etherscan.io/apis) and [Infura](https://infura.io/) (`ETHERSCAN_TOKEN` `WEB3_INFURA_PROJECT_ID`). |
| 91 | + |
| 92 | +Set them in `.env` file following `.env.example` |
| 93 | + |
| 94 | +```bash |
| 95 | +yarn network:mainnet-fork |
| 96 | +``` |
| 97 | + |
| 98 | +### Deploy contracts |
| 99 | + |
| 100 | +```bash |
| 101 | +yarn deploy:testnet |
| 102 | +``` |
| 103 | + |
| 104 | +### Use network console |
| 105 | + |
| 106 | +Run the console |
| 107 | + |
| 108 | +```bash |
| 109 | +yarn console |
| 110 | +``` |
| 111 | + |
| 112 | +and interact directly with contracts |
| 113 | + |
| 114 | +Example: Check owner of `tokenId = 4` for NFT with smart contract address `0x734f99154988a737ae7159594Ebf828eB6761645` |
| 115 | + |
| 116 | +```python |
| 117 | +>>> t = TestNFT.at('0x734f99154988a737ae7159594Ebf828eB6761645') |
| 118 | +>>> t.ownerOf(4) |
| 119 | +'0x5898D8D9a8895dBBd3d035724FA1Bc252876cC22' |
| 120 | +>>> |
| 121 | +``` |
| 122 | + |
| 123 | +### Run tests |
| 124 | + |
| 125 | +```bash |
| 126 | +yarn test |
| 127 | +``` |
| 128 | + |
| 129 | +## Prod Deployment (Ethereum Mainnet) |
| 130 | + |
| 131 | +- Deployer: 0xf6798a60B576658461eeFebf583C2AaECD732334 |
| 132 | +- Governance: 0xC08618375bb20ac1C4BB806Baa027a4362156fE6 |
| 133 | +- Operator: 0x49941c694693371894d6DCc1AbDbC91A7395b703 |
| 134 | +- FeeCollector: 0xa55D576DE85dA4295aBc1E2BEa5d5c77Fe189205 |
| 135 | +- ProxyAdmin: 0xdb246e57c401792Fd272314ce666f5dB07E89e67 |
| 136 | + |
| 137 | +- OLogic: 0xe1ac13c21e3F1EeBF71CC0F9e74D6059AbAc7970 |
| 138 | +- OBeacon: 0x31c82151B1fDD035C64EB8b4c896AFF799ca63b1 |
| 139 | +- WLogic: 0x160AC61AFb9323B372FEeB157471F23984544dFb |
| 140 | +- WBeacon: 0x3Ec6fd32bb71fc288f18DCc1F2EBd6Bb00BAB25f |
| 141 | + |
| 142 | +- SimpleWalletLogic: 0x0a988B2b8B53de1B21dbE0CfFB68eB6B6664868b |
| 143 | +- SimpleWalletBeacon: 0x268bC6FC0aB22847d9DE037DcEEb8F656826EF44 |
| 144 | +- WalletFactory: 0x4d0662FB57464EEf4Dc9431Bd49dF949B039836D |
| 145 | + |
| 146 | +- Rentable: 0xd766a11858c57252cC4F9978282B616C3e0bBAC4 |
| 147 | +- RentableLogic: 0xAcc7E1D41f62Eb75309a28D0a3D29F09DbbC56ca |
| 148 | + |
| 149 | +- Decentraland (LAND): 0xF87E31492Faf9A91B02Ee0dEAAd50d51d56D5d4d |
| 150 | +- OLandLogic: 0xc1E572797De159155174fEfa7BC0f023649153bf |
| 151 | +- OLandBeacon: 0x3b2Fb54b9f57ad9AEB9103aF55E10905dee0d8b1 |
| 152 | +- OLand: 0xcE6AC4D01d18B99BF7926a2cdFa87D03d271d3d8 |
| 153 | +- WLand: 0x21Fc48317b1772997EF4753a82f7CB4A26Eb2E07 |
| 154 | +- Library: 0x2B0672f10C2f6487394B5760e2E0A69ca6a4C710 |
| 155 | + |
| 156 | +- Meebits: 0x7Bd29408f11D2bFC23c34f18275bBf23bB716Bc7 |
| 157 | +- OMeebits: 0xBEc515aac1d601E8A1Ce7baaD493A80DaD667E33 |
| 158 | +- WMeebits: 0x9A87c43c15d7ba0e4eA9B7AB9A0a0821C8777e94 |
| 159 | + |
| 160 | +- LobsterDAO: 0x026224A2940bFE258D0dbE947919B62fE321F042 |
| 161 | +- OLOBS: 0x4fE71Dafdd15Ef1F9308F249Bc7eaE1fd48ba828 |
| 162 | +- WLOBS: 0xc0fdE9d7D28376CFEcAc37971397f01d2D9dfA59 |
| 163 | + |
| 164 | +## Experimental Deployment (Rinkeby) |
| 165 | + |
| 166 | +``` |
| 167 | + Deployer: 0xf6798a60B576658461eeFebf583C2AaECD732334 |
| 168 | + Governance: 0xf6798a60B576658461eeFebf583C2AaECD732334 |
| 169 | + Operator: 0xf6798a60B576658461eeFebf583C2AaECD732334 |
| 170 | + FeeCollector: 0xf6798a60B576658461eeFebf583C2AaECD732334 |
| 171 | + TestNFT: 0x8fA4d7B0C204B8f03C9f037E05Cece57decE2214 |
| 172 | + OBeacon: 0x6a54CAB15d7eDF3D97af0b73E2aC9e5e430359Ed |
| 173 | + ORentable: 0x029675B6bF1FE9bB55c8a46A18BEc30E70EdFC6e |
| 174 | + WBeacon: 0x94ddf9510c0BE76867ebc46dFDa4509dB492B30b |
| 175 | + WRentable: 0x9fa166996E2f1110332589f6E0f924a45fac4cAD |
| 176 | + SimpleWalletLogic: 0x23588c541018EE522e0C9BDea7172214e61b3a66 |
| 177 | + SimpleWalletBeacon: 0x09B76511d6f91081B6b5d316BC479b41803Cf888 |
| 178 | + WalletFactory: 0x8C0F6D5AfF5B5f6731cF976C0343ACA2F0d38ddC |
| 179 | + Rentable: 0xb8Cd02CbCc05Ac25D77F63FAbB2501Bb71f9e2BB |
| 180 | + RentableLogic: 0x7d9ba195f29C1a0102e8daAD16091f3d79486216 |
| 181 | + ProxyAdmin: 0xA9853c327d9F695FCCA73e592Cb624d1EcB60835 |
| 182 | +``` |
| 183 | + |
| 184 | +## Security |
| 185 | + |
| 186 | +For security concerns, please visit [Bug Bounty](https://github.com/rentable-world/rentable-protocol/security/policy). |
0 commit comments