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 yarnyarn installThis file defines environment variables read by Hardhat.
cp .env.template .envAdd 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 consoleIf you want to use a mainnet-fork run
FORK=mainnet yarn hardhat consoleYou 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()
> 95First 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 kovanReplace 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 testOn the other hand, if you want to run these tests against a mainnet fork.
yarn test:mainnetRuns the test suite and reports gas usage at then end.
yarn test:gasRun test coverage.
Coverage report is written to coverage/index.html.
yarn coverageRun solhint (Solidity linter).
yarn lintThese
yarnscripts 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-analyzerTo 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"
}
}