Skip to content

Commit c10996b

Browse files
author
Emiliano Bonassi
committed
feat: rentable v2
0 parents  commit c10996b

File tree

1,031 files changed

+182743
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,031 files changed

+182743
-0
lines changed

.env.example

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
ETHERSCAN_TOKEN=<your-token-here>
2+
WEB3_INFURA_PROJECT_ID=<your-token-here>
3+

.github/workflows/lint.yaml

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
on: [push]
2+
3+
name: Lint
4+
5+
jobs:
6+
solidity:
7+
runs-on: ubuntu-latest
8+
9+
steps:
10+
- uses: actions/checkout@v2
11+
with:
12+
submodules: recursive
13+
14+
- name: Setup node.js
15+
uses: actions/setup-node@v1
16+
with:
17+
node-version: "12.x"
18+
19+
- name: Set yarn cache directory path
20+
id: yarn-cache-dir-path
21+
run: echo "::set-output name=dir::$(yarn cache dir)"
22+
23+
- name: Restore yarn cache
24+
uses: actions/cache@v2
25+
id: yarn-cache
26+
with:
27+
path: |
28+
${{ steps.yarn-cache-dir-path.outputs.dir }}
29+
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
30+
restore-keys: |
31+
${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
32+
${{ runner.os }}-yarn-
33+
- name: Install node.js dependencies
34+
run: yarn --frozen-lockfile
35+
36+
- name: Run formater check on *.sol and *.json
37+
run: yarn format:check:sol
38+
39+
- name: run linter check on *.sol file
40+
run: yarn hint
41+
42+
brownie:
43+
runs-on: ubuntu-latest
44+
45+
steps:
46+
- uses: actions/checkout@v2
47+
with:
48+
submodules: recursive
49+
50+
- name: Set up python 3.8
51+
uses: actions/setup-python@v2
52+
with:
53+
python-version: 3.8
54+
55+
- name: Set pip cache directory path
56+
id: pip-cache-dir-path
57+
run: |
58+
echo "::set-output name=dir::$(pip cache dir)"
59+
- name: Restore pip cache
60+
uses: actions/cache@v2
61+
id: pip-cache
62+
with:
63+
path: |
64+
${{ steps.pip-cache-dir-path.outputs.dir }}
65+
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements-dev.txt') }}
66+
restore-keys: |
67+
${{ runner.os }}-pip-${{ hashFiles('**/requirements-dev.txt') }}
68+
${{ runner.os }}-pip-
69+
- name: Install python dependencies
70+
run: pip install -r requirements-dev.txt
71+
72+
- name: Run black
73+
run: black --check --include "(tests|scripts)" .

.github/workflows/slither.yaml

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: Slither Analysis
2+
3+
on:
4+
push:
5+
branches: [main, dev]
6+
pull_request:
7+
branches: [main, dev]
8+
9+
jobs:
10+
analyze:
11+
name: Slither Analysis
12+
# run only on main/dev branch and pull requests
13+
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev' || github.event_name == 'pull_request'
14+
runs-on: ubuntu-latest
15+
permissions:
16+
contents: read
17+
security-events: write
18+
19+
steps:
20+
- name: Checkout repository
21+
uses: actions/checkout@v2
22+
23+
- name: Run Slither
24+
uses: crytic/[email protected]
25+
continue-on-error: true
26+
id: slither
27+
with:
28+
node-version: 16
29+
sarif: results.sarif
30+
31+
- name: Upload SARIF file
32+
uses: github/codeql-action/upload-sarif@v1
33+
with:
34+
sarif_file: ${{ steps.slither.outputs.sarif }}
35+
continue-on-error: true

.github/workflows/test.yaml

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
on: [push]
2+
3+
name: Test
4+
5+
env:
6+
ETHERSCAN_TOKEN: ${{ secrets.ETHERSCAN_TOKEN }}
7+
WEB3_INFURA_PROJECT_ID: ${{ secrets.WEB3_INFURA_PROJECT_ID }}
8+
9+
jobs:
10+
tests:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- uses: actions/checkout@v2
15+
with:
16+
submodules: recursive
17+
18+
- name: Install Foundry
19+
uses: onbjerg/foundry-toolchain@v1
20+
with:
21+
version: nightly
22+
23+
- name: Run tests
24+
run: forge test --gas-report -vvv

.gitignore

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
cache/
2+
out/
3+
__pycache__
4+
.history
5+
.hypothesis/
6+
build/
7+
reports/
8+
.env
9+
node_modules/
10+
.DS_Store
11+
artifacts/
12+
.venv

.gitmodules

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
2+
[submodule "lib/openzeppelin-contracts-upgradeable"]
3+
path = lib/openzeppelin-contracts-upgradeable
4+
url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable
5+
[submodule "lib/solmate"]
6+
path = lib/solmate
7+
url = https://github.com/Rari-Capital/solmate
8+
[submodule "lib/ds-test"]
9+
path = lib/ds-test
10+
url = https://github.com/dapphub/ds-test
11+
[submodule "lib/openzeppelin-contracts"]
12+
path = lib/openzeppelin-contracts
13+
url = https://github.com/OpenZeppelin/openzeppelin-contracts
14+
[submodule "lib/forge-std"]
15+
path = lib/forge-std
16+
url = https://github.com/brockelmore/forge-std

.husky/commit-msg

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/bin/sh
2+
. "$(dirname "$0")/_/husky.sh"
3+
4+
yarn format:check
5+
yarn commitlint --edit $1

.prettierignore

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
out
2+
lib
3+
cache
4+
build
5+
artifacts
6+
reports
7+
out

.solhint.json

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"extends": "solhint:default",
3+
"rules": {
4+
"max-line-length": ["error", 145]
5+
}
6+
}

.vscode/settings.json

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"solidity.remappings": [
3+
"@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
4+
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
5+
"solmate/=lib/solmate/src/",
6+
"ds-test/=lib/ds-test/src/"
7+
],
8+
"editor.formatOnSave": true,
9+
"solidity.formatter": "prettier",
10+
"[solidity]": {
11+
"editor.defaultFormatter": "JuanBlanco.solidity"
12+
},
13+
"python.formatting.provider": "black"
14+
}
Binary file not shown.

README.md

+186
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
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+
![Diagram](Rentable.png)
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).

Rentable.png

141 KB
Loading

0 commit comments

Comments
 (0)