Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
emduc
left a comment
There was a problem hiding this comment.
Thanks a lot for your submission Rick! It's a high-quality review, and I appreciate that you adapted to our new layout.
It looks like there are compilation issues, could you please look into it? Happy to help out if you have any issues.
My main comment is on the autonomy section, I left a few clarification questions that should help us clarify how to consider the chainlink dependency.
Most other comments are about style; we try to use codestyle for contract and token names, as well as Cursive Text for module names.
For completeness, could you please add the permissions for the BoldToken's setBranchAddresses and setCollateralRegistry functions? When it's not obvious in the name that a function is used to initialise the contract, we still document it and specify that in the description.
| If the market oracle or LST exchange rate fails on a given collateral branch, the system shuts that branch down: it freezes new debt issuance, and enables “urgent redemptions” in order to clear debt and collateral as fast as possible. Borrowers are free to repay BOLD, withdraw collateral and close their loans on the shut down branch. | ||
|
|
||
| Additionally, if a branch’s LST market oracle fails, the branch falls back to pricing collateral via a combination of the LST exchange rate and ETH-USD price. | ||
|
|
||
| Finally, each collateral branch uses the "last good price" as a last resort if all its price sources become untrusted. This ensures the protocol can continue pricing collateral without interruption, minimizing the impact of oracle failure on its operations. Despite its reliance on external oracles, Liquity v2’s branch shutdown mechanism and fallback pricing logic mitigate the risk of disruption due to price source failure. |
There was a problem hiding this comment.
Could you please clarify a few points, so that we can ensure this fits a Low centralization score for autonomy:
- How do you qualify an "Oracle failure", is it simply the Oracle returning 0, or do you also have other measures to prevent Oracle manipulation?
- As I understand it you use RETH's smart contract exchange rates first, is that also the case for WSTEH or do you use Chainlink's WSTETH-USD primarily?
- Is the "Last good price" stored in Liquity v2 contracts, or are you referring to Chainlink oracle's last pushed price?
- Can you define "Urgent redemption" ? Do all positions become redeemable?
There was a problem hiding this comment.
How do you qualify an "Oracle failure", is it simply the Oracle returning 0, or do you also have other measures to prevent Oracle manipulation?
V2 deems a Chainlink market oracle to have failed if 1) it returns a price of 0, 2) the call to the oracle reverts or 3) the oracle price has been stale for too long. The staleness thresholds are 24 hours for ETH-USD and STETH-USD (which have update heartbeats of 1 hour) and 48 hours for RETH-ETH (which has an update heartbeat of 24 hours).
Additionally, V2 deems an LST exchange rate to have failed if 1) it returns a value of 0 or 2) the call to the LST contract reverts.
There's no way for any protocol to rigorously detect and prevent all possible oracle manipulation. Whatever thresholds/logic a protocol implements, a malicious actor with technical or economic control over the oracle's price can "fly under the radar" of the protocol's logic/thresholds.
However, V2 still has measures to protect users against oracle manipulation. It uses the "worst" (highest) price for redemptions on WSTETH and RETH branches in order to mitigate adverse redemption arbs, and on the RETH branch, it uses the "worst" (lowest) price for borrowing and liquidations. This mitigates excessive BOLD minting if the RETH market oracle were to be manipulated upwards. This last protection was added since RETH historically has lower liquidity than STETH and market oracle may be more manipulable.
As I understand it you use RETH's smart contract exchange rates first, is that also the case for WSTEH or do you use Chainlink's WSTETH-USD primarily?
It's a bit more involved - the price calculation depends on both the branch and the operation (i.e. borrowing/liquidation vs redemption). The full logic is laid out here:
https://github.com/liquity/bold?tab=readme-ov-file#choice-of-oracles-and-price-calculations
Is the "Last good price" stored in Liquity v2 contracts, or are you referring to Chainlink oracle's last pushed price?
Yes, it's stored in v2 contracts. At a given price fetch, the price is calculated according to the logic above - i.e. based on the branch, the user operation and the state of the branch's price sources (i.e. if any have failed or not). That calculated price is then stored as the lastGoodPrice.
Can you define "Urgent redemption" ? Do all positions become redeemable?
Yes, urgent redemptions are a special operation that is enabled once a branch has been shut down (due to oracle failure or insufficient collateralization). With urgent redemptions:
- Any Trove can be directly redeemed from, regardless of interest rate ordering
- No redemption fee is charged
- The redeemer earns a 2% collateral bonus - i.e. for every 1 BOLD redeemed they receive $1.02 worth of collateral
The intent is to clear the debt of the shut down branch as quickly as possible. Borrowers can also close their Trove at any point after a shut down.
https://github.com/liquity/bold?tab=readme-ov-file#urgent-redemptions
Co-authored-by: Emilien Duc <56789637+emduc@users.noreply.github.com>
Co-authored-by: Emilien Duc <56789637+emduc@users.noreply.github.com>
Co-authored-by: Emilien Duc <56789637+emduc@users.noreply.github.com>
Co-authored-by: Emilien Duc <56789637+emduc@users.noreply.github.com>
Co-authored-by: Emilien Duc <56789637+emduc@users.noreply.github.com>
Co-authored-by: Emilien Duc <56789637+emduc@users.noreply.github.com>
|
Thanks! Addressed the questions and added the additional permissioned functions. Will look into the compilation issue shortly |
|
Btw, I'm unable to view the Vercel preview / deployment - think I don't have permission. Can you let me know what needs fixing and/or give permission? |
Yes the error is regarding the date, the publish date should be non-empty even though it's not published yet. You can also check locally by running npm run dev or npm run build |
Thanks! Fixed, I set all dates (submission, publish, update) to today. |
|
Thanks for incorporating the diagram and explanation. It would actually be in the section "Protocol Analysis", which you already have but is currently empty. Regarding "Autonomy", and "Dependencies", here is a suggestion. Unfortunately, that would bring the score to High for Autonomy, and Stage 0 as a result. AutonomyLiquity v2 relies on a combination of external Chainlink market oracles - ETH-USD, RETH-ETH and STETH-USD - as well as LST smart contract exchange rates in order to price collateral. Several mitigations are in place to handle oracle failure and minimise its impact. If the market oracle or LST exchange rate fails on a given collateral branch, the system shuts that branch down: it freezes new debt issuance, and enables “urgent redemptions” in order to clear debt and collateral as fast as possible. Borrowers are free to repay BOLD, withdraw collateral and close their loans on the shut down branch. Additionally, if a branch’s LST direct oracle fails, the branch falls back to pricing collateral via a combination of the LST exchange rate and ETH-USD price. Finally, each collateral branch uses the "last good price" as a last resort if all its price sources fail. This ensures the protocol can continue pricing collateral without interruption, minimizing the impact of oracle failure on its operations. Nonetheless, although different price sources might be used, each price calculation includes an oracle provided by Chainlink. Chainlink was reviewed to be of High centralization in a separate report. Since none of the mitigations account for oracle manipulation of both price feeds, this results in a High centralization risk score for the Autonomy section.
DepedenciesThe system has the following external dependencies:
Any problem or failure with the collateral contracts could have a significant impact on the Liquity v2 system. However, the system separates different collateral branches and shuts a collateral branch down if the branch collateralization ratio falls too low, or if the LST’s smart contract exchange rate fails. Thus, it does its best to mitigate economic or technical collateral failure and remain functional. Similarly, if a market oracle fails, the system shuts down the corresponding branch and falls back to a backup price calculation (see the Autonomy section for details). In either case of LST exchange rate or market oracle failure, the branch blocks new debt issuance and allows existing users to withdraw their assets. For LST collateral branches which have two price sources (direct rate and LST contract rate combined with ETH-USD), the protocol has different dynamics to mitigate the manipulation of one of the two price feeds. Nonetheless, both sources include a Chainlink price feed. Chainlink was reviewed to be of High centralization in a separate report. None of the mitigations account for oracle manipulation of both price feeds. Chainlink, therefore, has the power to trigger liquidations or branch shutdowns, with the additional power to sell off the debt (urgent redemption) at an arbitrary price. For those reasons, the Autonomy centralization risk score is High. ThoughtsI realise this is both surprising and annoying. Since the protocol is immutable, there are actually no ways for Bold to become Stage 2 now... Mitigations that would have been valid include: max price slippage tolerance / bounds, Using multiple price sources., etc. Happy to hear your thoughts and debate further |
|
Coming back to this, we would question the ranking relative to other DeFi systems with similar oracle dependencies. Of the systems currently ranked in DefiScan, it seems there are only two that a) use external oracles and b) have ratings better than Stage 0: Liquity v1 and Morpho. Your main concern with Liquity v2 seems to be the Chainlink oracle dependency. As you mention, if that oracle were controlled by a malicious actor, they could push very low ETH & LST prices and liquidate and/or urgent-redeem all branches. We’d add that very similar risks exist for both Liquity v1 and Morpho vaults:
Since oracle risk is the limiting factor, then it seems to us that Liquity v1, Morpho and Liquity v2 should all be rated at the same Stage for consistency. Happy to hear your thoughts. |
|
Thanks for following up! To complement the existing DeFiScan reviews, Sky would have a medium autonomy score in terms of oracle because they use Chronicle. In addition to that, they also have a 1-hour delay on price updates to allow emergency freezes. The reason their Autonomy score is High risk is because of Circle. Similarly, Spark would actually have Low risk in terms of oracle provider, as they use 3 oracle providers and take the median price (chainlink, redstone, chronicle), they used to only use chronicle which was already medium risk, the review is to be updated, the reason they have high autonmy risk is due to the dependency on Sky (Stage 0). I hear your point for Liquity V1 and Morpho. As you highlight, using oracles is not a black-and-white issue; we can find a better balance and criteria for the V2 of the framework, with more granular consideration. Nonetheless, in the current framework, our quite straightforward approach doesn't leave a lot of wiggle room for a better Autonomy score in Liquity V2.
On the other hand, I absolutely understood that you make many more efforts than a lot of other DeFi protocols, even with immutable contracts, cases like the oracles retiring or failures are all taken into account, with the protection of user funds at heart, the deal breaker for the current framework lies solely in the fact that Chainlink is trusted to not act maliciously. |
|
Btw, we've discussed this with one of the primary Liquity v2 auditors, ChainSecurity - and this was the feedback they gave:
We think this is an important point - while both V1 and V2 are equally exposed to the risk of the primary oracle going rogue, in case of a technical oracle failure, V2 immediately atttempts to limit the damage (branch shutdown + borrowing restrictions), and clear the branch debt as quickly as possible (urgent redemptions). |
No description provided.