--- tags: ADR --- # Lido Insurance Fund ADR - Status: Done - Deciders: Lido dev team, Lido DAO - Date: 1 Sep 2022 ## Context and Problem Statement Initially, Lido hedged against slashing penalties via a third party insurance provider. In a [July 2021 vote](https://snapshot.org/#/lido-snapshot.eth/proposal/QmWeMuwkLJ3strPAM58kzLaKzbEPrWTLb1VC93ergrYrbv), the DAO decided to take on a self-insurance approach by marking the funds accrued in the form of protocol fees as usable for insurance purposes. The enactment of [vote #134](https://vote.lido.fi/vote/134) redirected the flow of protocol fees into the Treasury and fixed the precise amount allocated for insurance at 4546.38 wstETH or its equivalent in stETH. However, there is still no apparent distinction between Insurance and Treasury funds as both are stored under the same contract. In this document, we propose to introduce a dedicated vault contract for insurance funds. The vault does not make any assumptions in regards to policies, restrictions and regulations that may be applied and only serves as a transparent store for funds which can only be retrieved by the DAO Agent. ## Technical Overview The proposed design for the insurance fund is quite simple. At its core, an insurance fund is a contract that stores stETH and allows the DAO Agent to take control of the funds whenever the DAO decides to apply insurance. Additionally, it features recovery methods to allow the Agent to return any ether or tokens sent to the contract by mistake. ## Considered Options There are two approaches to insurance fund design that mainly differ in how the Agent takes control over the funds, via direct transfers or the allowance model. ### Approach 1. Direct transfers The fully permissioned insurance fund gives us the flexibility to specify a number of parameters for recovery (e.g. recipient, token, and amount of tokens). At the same it adds overhead as all operations will have to be carried out by the DAO. This approach implies setting the DAO Agent as the owner of the insurance fund with the help of OpenZeppelin's `Ownable` contract and using the `onlyOwner` modifier for all external functions. To activate insurance, the Agent simply withdraws the required amount of stETH using the token transfer method. One big benefit for this approach is that we can reuse the [asset recoverer](https://github.com/lidofinance/jumpgates/blob/main/contracts/AssetRecoverer.sol) code and the [tests that go along with it](https://github.com/lidofinance/jumpgates/blob/main/tests/test_jumpgate_unit.py#L54) from Jumpgates, which will reduce the time to delivery. A rough outline of the vault is given below, ```solidity contract LidoInsuranceFund is Ownable { constructor(address _owner) { transferOwnership(_owner); } modifier burnDisallowed(address _recipient) { require(_recipient != address(0), "Recipient cannot be zero address!"); _; } function renounceOwnership() public override onlyOwner { revert("Renouncing ownership disabled!"); } function changeOwner(address _newOwner) external onlyOwner burnDisallowed(_newOwner) { transferOwnership(_newOwner); } function transferEther(address _recipient, uint256 _amount) external onlyOwner burnDisallowed(_recipient) { // transfer logic } function transferERC20( address _token, address _recipient, uint256 _amount ) external onlyOwner burnDisallowed(_recipient) { // transfer logic } function transferERC721( address _token, uint256 _tokenId, address _recipient ) external onlyOwner burnDisallowed(_recipient) { // transfer logic } function transferERC1155( address _token, uint256 _tokenId, address _recipient ) external onlyOwner burnDisallowed(_recipient) { // transfer logic } } ``` ### Approach 2. Allowance The allowance-based design builds upon the approach 1 but instead of directly transferring funds to the Agent, it utilizes the allowance model. Giving allowance to the Agent will be performed via a public non-parametrized method that will `approve` 2<sup>256</sup>-1 stETH tokens in favor of the Agent, while recovery methods for stray funds are still permissioned operations. One distinct difference between Approach 1 is that transfer method will only be used to recover stray funds because the Agent will always have an allowance of stETH to work with in case an insurance cover is required. An outstanding allowance presents a slight concern because it will have to be accounted for for contract upgrades. Furthermore, this model introduces redundancy in that the Agent may bypass allowance and directly transfer stETH using the token recovery methods. A rought outline of the contract is presented below, ```solidity contract LidoInsuranceFund is Ownable { // same constructor and methods as Approach 1 function approveStETH() public { // approve logic } ``` ## Decision Outcome We view Approach 1 as the optimal solution mainly because of its simple design and short delivery time due to code reuse. ## Useful links - [Redirecting incoming revenue stream from insurance fund to DAO treasury](https://research.lido.fi/t/redirecting-incoming-revenue-stream-from-insurance-fund-to-dao-treasury/2528) - [Offline & Slashing Risks: Are Self-Cover Options Enough?](https://blog.lido.fi/offline-slashing-risks-are-self-cover-options-enough/) - [Jumpgates Asset Recoverer](https://github.com/lidofinance/jumpgates/blob/main/contracts/AssetRecoverer.sol)