This document provides technical details for PV01 perpetual vault smart contracts, in particular the on-chain software components. The associated off-chain software, including in-house APIs, 3rd party APIs and the Pivio platform are not in scope. For details on the PV01 bond smart contracts see the PV01 bond whitepaper.
All contract source code is available in Etherscan at the deployed contract addresses listed in the last section. All bespoke source code developed by PV01 is licensed under Business Source License 1.1 and is not an open source license.
The Perpetual Vault is an ERC-4626 compliant contract that contains a single PV01 bond contract as its asset token. When this bond matures, the Vault uses the old bond token to buy new bond tokens. The Vault is said to “roll over” its asset and switches to using the new asset, all without requiring any action from investors. This rollover process enables the perpetual nature of the vault, and has a non-technical explanation here.
The ERC-4626 standard refers to vault share tokens and vault asset tokens. In this whitepaper the vault share tokens are referred to simply as vault tokens.
The diagram below shows the logical implementation for PV01 Vault contracts on EVM chains.
The diagram shows a Vault Factory producing a Vault of a given type (e.g. “BondPerpetualVault”) and version (e.g. “1”). Each vault is deployed as a separate ERC-4626 compliant contract. A vault has an Address Screen contract that enforces transfer restrictions. The Address Screen contract can be shared by many vaults (and also bonds) and makes use of internal PV01 allow and deny lists as well as the Chainalysis Sanctions oracle contract.
PV01 Perpetual Vault Contract Architecture on EVM Chains
For clarity, the above diagram makes some simplifications. The standard OpenZeppelin contracts relating to Ownable, ERC-20, ERC-165 and ERC-4626 are not shown. The vault proxy/implementation relationship is not shown and is explained in the Physical Architecture section below.
All on-chain state changes emit appropriate contract events to allow off-chain monitoring. These are not shown in the diagram.
The physical architecture is very close to the logical architecture above. The main difference is that the Vault Factory deploys a PV01VaultProxy.sol
contract that itself holds all storage and points to an implementation contract for its logic. This proxy uses the OpenZeppelin Transparent Upgradeable Proxy design pattern. This is done to reduce vault contract deployment costs, and also to allow vault business logic upgrades.
In practice, Vault implementation contracts are deployed once per Vault type and Vault version pair. These contracts are then registered with the Vault Factory contract. At Vault deployment time an appropriate implementation is then selected. The term “Vault contract” refers to the PV01VaultProxy
address, but functionally it behaves as if the contract were deployed using the complete implementation contract.
The vault contract is upgradeable. It is a long-lived contract and upgradeability allows for new vault features.