We take security extremely seriously at yAxis and also place a very high importance on transparency. Building off our previous security-focused article on the security of the Metavault, this post focuses on transparency on how the yAxis contracts are controlled.
TL;DR: We use a timelock for governance changes, and a multisig for time-critical changes like saving user funds. We should always consider risk when adding new strategies.
Before an official DAO contract is created, it’s important to understand that the yAxis Metavault and all related contracts are governed by either a multisig contract, which is a Gnosis Safe, requiring 3 out of 6 signers to execute, or a 24-hour timelock contract, which the multisig is an admin. The address of the multisig is 0xC1d40e197563dF727a4d3134E8BD1DeF4B498C6f. Anyone can plug that address into the Safe UI and see the current policy and transactions.
There are certain functions that do not, or rather should not, use a delay when applying a change to a contract. This is typically used for functions that do not directly affect user funds, and would need to be utilized in an emergency. Within our contracts, we typically refer to this role as a strategist. Long-term, once a DAO is created, all governance addresses across all contracts would be updated to the DAO’s address, and we would likely want to leave the multisig’s address as the strategist to be able to react quickly. During Pickle Finance’s incident mentioned in the previous blog post, we were able to react quickly and save over $17 million in user funds from a potentially vulnerable Pickle Jar.
Here we’ll take a look at each of our contracts and discuss what address has which role, and why it’s set that way. Across all contracts, governance is set to the timelock because changes to contracts should be determined by the community.
The yAxisMetavault contract is the only contract that users interact with to deposit and withdraw stablecoins. It is controlled by a governance address and a vaultManager address. The governance address is able to directly change variables on the contract, and the vaultManager is used to reference external variables.
The yAxisMetavaultManager contract acts as a shared storage contract. The Metavault and all strategies use it to determine fee amounts, addresses, and strategy statuses. The only address able to affect this contract is the address stored as its governance. This allows the community to vote on what each fee amount should be.
The StrategyControllerV1 contract is an important contract that can directly move user funds out of a strategy if needed. It has both a governance and strategist address to help with controlling the vault. For example, only governance can approve and revoke strategies, since this needs to be voted on and can be delayed, but the strategist would be able to pull funds out of a strategy and into the vault if needed, which should not be delayed. The strategist on this contract is set to the multisig.
The StableSwap3PoolConverter contract is used by the vault to convert stablecoins to 3CRV. Governance can control the address of the 3pool, the vaultManager, and can recover funds if stuck in this contract. There is no strategist associated with this contract so all changes would need to be voted on and go through the timelock contract.
StrategyCurve3Crv (and any future strategy)
The StrategyCurve3Crv contract and any other strategy for that matter allows governance to set the strategist, the controller, and Uniswap Router contracts. While the strategist is able to withdraw funds out of the strategy and into the vault (never receiving the funds themself) and can harvest. The strategist is currently set to the yAxisMetaVaultStrategists contract (discussed below). The same ownership pattern will be applied to any future strategy as well.
The yAxisMetaVaultStrategists contract allows for the harvest function to be called automatically by off-chain services. This limits the permission of any strategist added to the contract since all they can do is call harvest on strategies. Governance on this contract is set to the multisig instead of the timelock because of how limited this contract is, it cannot touch any user funds except by harvesting.
As seen with the Pickle Finance incident discussed in the previous blog post, yield aggregators (and aggregators of yield aggregators) are not without risks. With the coming release of the V2 Metavault, however, we can significantly reduce our risk by utilizing multiple strategies at once.
The current Metavault only supports a single strategy at a time. As such we have moved to a strategy that we feel has the lowest possible risk by providing liquidity to Curve directly. Doing so, we take on the same amount of risk as any Curve liquidity provider, which currently has over $800 million locked in the platform.
Usually when a user deposits funds into a vault, they're taking on what's referred to as stacked risk, where the risk is that of the vault they are depositing to as well as the risk of where the funds go in its strategy. Initially, one may think that a vault with multiple strategies would increase the stack of risks, but actually it reduces risk. Since multiple strategies spread funds to different platforms, if a single or even multiple platforms have a vulnerability that affects its users, depositors of the V2 Metavault won't suffer as high losses as if they had deposited directly to that vault. This also makes insuring a multi-strategy Metavault cheaper (discussed below) since it's not necessary to insure the entire vault's value.
Still, YAX voters should consider the risks associated with new strategies, rather than simply approving a strategy with a higher yield for the sake of yield. We in the DeFi space have seen a number of audited projects come under attack from malicious contracts. The Metavault V2 will allow us to assign a cap per strategy, so that higher-risk strategies can simply be given a lower cap so that in case there is a loss of funds, it is not as impactful.
We’re also exploring many different DeFi insurance projects, including simply using our own. If using our own insurance fund, it is likely that it would be covered by a deposit fee (voted on by the community) which would accrue over time. This fee could be reduced or even turned off when the community feels that it has grown large enough. A benefit here when combined with capped strategies is the insurance fund wouldn’t have to meet the total value locked (TVL) of the entire vault, only an amount that the community would feel covered if a number of strategies suffered losses. Please feel free to discuss this in our Discord if you have opinions on this subject!