2. Deploying vPool
To deploy a new vPool, you need to perform a transaction from the ADMIN
address of your vFactory.
The transaction should be made to the Nexus contract. This contract is the entry point of the system, it's mainly used to deploy new instances of contract, but once contracts are deployed, they do not rely on it anymore.
For this guide, the transactions are made with cast, a cli tool to make transactions and calls on Ethereum. Of course, any tool able to craft the transactions would do the job, we will provide the contract ABIs as we move forward in the guide.
Spawning a vPool instance
We need to call the spawnPool
method on the Nexus contract.
Several parameters are required to spawn a pool:
Let's go through all of them one by one:
epochsPerFrame
: an oracle quorum will need to run and report some important consensus layer data to the vPool contract. This parameter will control at which rate the reports will be made (reports are made at the beginning of every frame). On mainnet, we suggest setting this value to225
(24 hours), and on testnet we can use something lower like15
(1h30).operatorFeeBps
: Every time the oracle will report, possible rewards will be received by the pool. The operator can take a cut on these rewards in the form of shares of the vPool. These shares will be sent automatically to the vTreasury contract of the operator. This value is in basis points ( [0, 10000] )factory
: The address of the vFactory on which this vPool will be plugged.reportBounds
: To ensure the validity of the reported data, some reporting bounds are configured to prevent reports that would be reporting values out of bounds. The first value of the bound array if theupperBound
, this value is the maximumapy
authorized, in basis point. Setting it to1000
means that the oracle report will make sure that the accrued rewards are not exceeding10%
apy. The second value is thecoverageUpperBound
. The vPool has the ability to pull funds from a special recipient called thevCoverageRecipient
. This recipient will be used only in the case of loss of funds due to slashing. ThecoverageUpperBound
is a boost applied to theupperBound
only usable for coverage funds. This would ensure that coverage funds are pulled quickly into the system. The third value is thelowerBound
. This value is relative to the total underlying supply, setting it to100
means that the report balance shouldn't decrease by1%
of the total underlying supply or more. You can see these bounds as additional safety nets that would prevent invalid reports from going through as exceeding these bounds should not happen based on how the consensus layer works, the rewards rate, and how penalties could be applied.initialExtraData
: This argument is sent to the vFactory whenever a validator is purchased. This is an arbitrary metadata field that will be emitted with the event of funding on the vFactory. Feel free to use this value as you want as it has no impact on the behavior of the vPool. You can leave it empty if needed.exitQueueImageUrl
: This argument is used for the exit queue tickets. They are represented as NFTs, and this argument configures the image field in their metadata. You can use Kiln's endpoint (wip) or build your own and serve the image that you want.
We can now perform the transaction to spawn a new vPool instance
You have now deployed your vPool alongside all its required contracts. Let's recap what each contract does:
vPool
: the main pooling contract, receives deposits of any size and creates shares of the pool in exchange.vWithdrawalRecipient
: this contract's address is set as the withdrawal credential on the pool validators. It will be in charge of retrieving the consensus layer funds coming to the system, and will be called by the vPool contract to send the funds.vExecLayerRecipient
: this contract's address is set as the fee recipient on the pool validators. It will be in charge of retrieving all the block proposal related fees that happen directly on the execution layer, and will be called by the vPool contract to send the funds.vCoverageRecipient
: this contract holds funds provided by configured donors. In case of slashing losses, funds from this contract can be used to repay the loss. Pulled funds are not accounted in revenue, so no commission will be taken on these funds.vOracleAggregator
: this contract holds a list of quorum members that have to vote on a report. Once a quorum is met for a specific report value, the report is forwarded to the vPool contract. The contract cannot work if only one member is present in the quorum, this is why Kiln runs what is called the global oracle member, a member that is present by default in every vOracleAggregator contract, and makes sure bootstrapping happens as expected. This global oracle member can be ejected if and only if the contract has 5+ oracle members registered and the ejection flag is set totrue
vExitQueue
: this contract is in charge of processing the exit requests of the vPool share holders. In exchange of shares, a recipient will receive an NFT representing its future claim. Based on the demand in the exit queue contract, vPool will emit events that signal the possible need for an exit to the node operator
For both the oracle reporting and the exit queue events, Kiln provides the operatord
tool, that holds the daemons to perform the oracle reports automatically (start-oracle)
and to catch exit requests and forward them to a custom webhook endpoint (start-exit-daemon
). The configuration of both of these daemons is covered later in this guide.
Last updated