RenVM is a permissionless and decentralized virtual machine protocol.
A secure network of virtual computers that power interoperability for decentralized applications, enabling cross-chain lending, exchanges, collateralization & more.
This document assumes a high-level understanding of the RenVM protocol. Check https://github.com/renproject/ren/wiki/ to learn more about the inner workings of RenVM. More information about Ren and the Ren project can be found in https://renproject.io/renvm. Visit https://github.com/renproject to explore their repos.
In other words, RenVM is a network of nodes, called darknodes, that perform Secure Multiparty Computation (SMPC) over Shamir Secret Shares, to control ECDSA Private Keys securely, and hence custody funds for cross-chain bridging.
These darknodes earn fees for every transaction they process.
In order to power a darknode, you need to stake a utility token provided by RenVM.
This is the REN token, an ERC20
Ethereum token.
The amount you have to stake, known as bond, is 100,000 REN
(currently about 88,000 USD
).
The RenPool project allows users to participate in REN staking pools, which are rewarded with a share of fees earned by the Darknode.
You can earn Darknode rewards without having 100K REN nor operaing a Darknode
RenPool allows any user to
- create a new pool by becoming the node operator of a new Darknode.
- deposit RENs into a pool and when it reaches 100K, the RenPool team will set up and manage a new Darknode.
- [TODO] request a withdraw of a running pool. When another staker wants to take your place, they transfer the staked RENs to you, and they become part of the pool. However, keep in mind that you will lose your rewards for that epoch. Instead the new staker will receive it.
- [TODO] automatically deregister a running node when more than 50% of the staked REN collectively requests to withdraw their share.
Moreover, the RenPool team will never be in possession of your REN tokens nor your rewards.
- We need to audit the smart contracts
- What about slashing?
- Ethereum gas?
- Explain fees for owner and node operator and staker
At its core, RenPool is powered by smart contracts that dictates how the pool rewards are distributed among its users.
There are three main actors when using a RenPool.
- Owner
- Node Operator
- Stakers
In turn, the RenPool uses Ren smart contracts https://renproject.github.io/ren-client-docs/contracts/ to interact with the RenVM in a decentralized and permissionless manner. Ren contract addresses are published
- for
mainnet
. https://renproject.github.io/contracts-ts/#/mainnet - for
testnet
. https://renproject.github.io/contracts-ts/#/testnet
The following picture shows different states the RenPool can be in.
When unlocked, stakers can either deposit
or withdraw
REN tokens as they see fit.
However, when the pool collects the Ren Bond, currently 100K REN tokens, it becomes locked.
Once the pool is locked, the node operator can register a new darknode
https://docs.renproject.io/darknodes/getting-started/digital-ocean-or-how-to-setup-a-darknode/mac-os-and-linux.
Please note that the REN tokens collected by the contract are never in possession of the node operator nor the owner.
After the darknode has been registered, it will start to earn fees. The stakers can then withdraw their respective percentage of these fees.
The RenPool project uses the Yarn package manager and the Hardhat https://hardhat.org/getting-started/ development environment for Ethereum. We use Alchemy JSON-RPC provider to fork Ethereum networks.
You can skip to the next section if you have a working Yarn installation. If not, here is how to install it.
npm install -g yarn
yarn install
This file defines environment variables read by Hardhat.
cp .env.template .env
Add your Alchemy Key to the newly created .env
file
ALCHEMY_KEY=<your Alchemy key here>
This will create a local Blockchain plus 10 local accounts
loaded with ETH.
yarn hardhat console
If you want to use a mainnet
-fork run
FORK=mainnet yarn hardhat console
You will get a fresh instance every time you init the Hardhat console.
> const { renPool, renToken, faucet } = await require('./scripts/deploy.js')()
RenPool
and RenToken
are contracts objects, while faucet
is a function used to mint the REN token.
To interact with the contract you can use any of the signers provided by Hardhat.
First, get some REN tokens from the faucet
> const [signer] = await ethers.getSigners()
> (await renToken.balanceOf(signer.address)).toString()
'0'
> await faucet(renToken, signer)
> (await renToken.balanceOf(signer.address)).toString()
'1000000000000000000000000'
Deposit REN tokens into the Ren Pool
> (await renPool.totalPooled()).toString()
'0'
> await renToken.connect(signer).approve(renPool.address, 100)
> await renPool.connect(signer).deposit(100)
Verify that the Ren Pool balance has been increased
> (await renPool.totalPooled()).toString()
'100'
Withdraw some REN tokens
> await renPool.connect(signer).withdraw(5)
> (await renPool.totalPooled()).toString()
> 95
First you need to fund a wallet for the target network, _e.g., kovan
or mainnet
.
Then add your private key and your Etherscan API key to the .env
file.
The Etherscan API key is used in the deployment process to verify the smart contract.
See https://etherscan.io/verifyContract for more information about smart contract verification on Etherscan.
We use the hardhat-etherscan
plugin to verify the smart contract.
PRIVATE_KEY=<your private key here>
ETHERSCAN_API_KEY=<your etherscan API key here>
To deploy the smart contract to kovan
use
yarn deploy --network kovan
Replace kovan
with the name of the network you wish you use, e.g., mainnet
.
The RenPool depends heavily on Ren smart contracts to interact with the RenVM.
Ren smart contracts have been deployed independently by the Ren team and their addresses can be found in
https://renproject.github.io/ren-client-docs/contracts/deployments/.
The test/ren
folder contains checks to verify that these contract addresses.
Our test suite is designed to run on local forks of networks where the Ren smart contracts have been already deployed. Currently these networks are mainnet and kovan. To run the test suite against a kovan fork.
yarn test
On the other hand, if you want to run these tests against a mainnet fork.
yarn test:mainnet
Runs the test suite and reports gas usage at then end.
yarn test:gas
Run test coverage.
Coverage report is written to coverage/index.html
.
yarn coverage
Run solhint
(Solidity linter).
yarn lint
These
yarn
scripts are declared inpackage.json
.
We use the Slither to run static analysis on the RenPool contract. Slither can run on a Hardhat application, so you only need to install Slither.
pip3 install slither-analyzer
To run it
slither .
See https://github.com/crytic/slither for more information.
The static analysis has been integrated into our pipeline with GitHub Actions. To see the result of the analysis, see https://github.com/Ethernautas/renpool/actions/workflows/analysis.yaml.
Useful for claiming rewards. Full docs here https://renproject.github.io/ren-client-docs/api/.
- https://explorer.renproject.io/
- https://lightnode-testnet.herokuapp.com
- https://lightnode-devnet.herokuapp.com
POST https://lightnode-testnet.herokuapp.com HTTP/1.1
Content-Type: application/json
Accept: application/json
{
"method": "ren_queryTxs",
"id": 1,
"jsonrpc": "2.0",
"params": {
"txStatus": "done",
"offset": "0",
"limit": "10"
}
}
POST https://lightnode-testnet.herokuapp.com/ HTTP/1.1
Content-Type: application/json
Accept: application/json
{
"method": "ren_queryTx",
"id": 1,
"jsonrpc": "2.0",
"params": {
"txHash": "s8BZA6dhMRTOL6nOEo3yAlgdtNQfEdEF4VkVVcXeCcI"
}
}