Full Report
Silo Finance creates isolated lending markets. This is done by having every token asset in its own lending market. Additionally, it is paired against the bridge assets ETH and XAI (Silo's over-collateralized stablecoin). By doing this, lenders are only exposed to the risk of ETH and XAI at any point as a result. The Base Silo contract handles the core logic of the protocol. Users call deposit() to add collateral to the protocol so that they can borrow. In return, the contract mints a pro-rata share that is stored in _assetStorage[_asset]. Users who have deposited collateral can call borrow() to temporary gain access to the new asset. On this call, the accrued interest rate is updated and the loan-to-value (LTV) ratio is checked. In loan based protocols, the interest rate is calculated based upon the utilization of the asset. By making the contract believe it has borrowed more than 100%, the math goes crazy. How is this possible though? Donations! By adding more value to the contract than what is being tracked, the utilization trade goes through the roof. Using this, the value of the loan is much higher than it should be, allowing for us to take almost all of the funds. Practically, these are the steps to exploit this assuming that the market has 0 total deposits for one of the assets in a market: Become the main shareholder by depositing a little amount of the asset, such as 10^5 wei of WETH. Donate additional WETH to the market. To get even higher utilization, the bulk of the funds should be here. Use another account to deposit a seperate asset into the protocol. When accrueInterest() is called, the utilization rate of the deposit is over 100%, creating an insane interest rate. Our initial deposit (collateral) is now valued more than is should be. As a result, all of the funds can be borrowed from the protocol to steal it. To fix this problem, there is now a cap on the utilization rate. However, I find it odd that the donation attack was possible at all. To me, it makes more sense to have the liquidity and borrowed funds amount match what's actually available. Weird report!
Analysis Summary
# Vulnerability: Silo Finance Interest Rate Manipulation via Donation
## CVE Details
- **CVE ID:** Not Assigned (DeFi Protocol Vulnerability)
- **CVSS Score:** 9.6 (Critical) - *Estimated based on potential for total fund loss.*
- **CWE:** CWE-682: Incorrect Calculation; CWE-20: Improper Input Validation
## Affected Systems
- **Products:** Silo Finance (Lending Protocol)
- **Versions:** Deployments prior to the utilization cap implementation.
- **Configurations:** This vulnerability specifically targets isolated lending markets with low or zero initial liquidity for a specific asset.
## Vulnerability Description
The flaw resides in the interest rate calculation logic within the `Base Silo` contract. Silo Finance determines interest rates based on the **utilization ratio** of a specific asset market.
The vulnerability is triggered by a "Donation Attack." Because the protocol's interest rate math relied on the actual balance of assets held in the contract versus accounted debt, an attacker could manually send assets (e.g., WETH) directly to the contract address without calling the `deposit()` function. This "donation" increases the asset balance without increasing the protocol's internal accounting of shares. When `accrueInterest()` is triggered, the misaligned ratio between tracked debt and total assets causes the utilization rate to exceed 100%. This results in an exponential spike in the interest rate, artificially inflating the value of the attacker's original collateral shares and allowing them to borrow nearly all liquidity from the protocol.
## Exploitation
- **Status:** PoC Available / Disclosed via Security Report.
- **Complexity:** Medium (Requires two accounts and specific market conditions).
- **Attack Vector:** Network (Smart Contract Interaction).
### Step-by-Step Exploitation (PoC):
1. **Initial Deposit:** Use Account A to deposit a tiny amount (e.g., $10^5$ wei) of an asset into a market with 0 current deposits.
2. **Donation:** Direct transfer a large amount of the same asset to the Silo contract address (bypassing `deposit()`).
3. **Collateralize:** Use Account B to deposit a separate asset as collateral.
4. **Trigger Accrual:** Call `accrueInterest()`. The utilization math "breaks" due to the donation, causing the interest rate to skyrocket.
5. **Drain:** The value of Account A's shares increases instantly due to the manipulated interest; borrow all available funds in the protocol against the inflated shares.
## Impact
- **Confidentiality:** None
- **Integrity:** High (Internal accounting and interest rate logic are compromised).
- **Availability:** High (Total loss of protocol liquidity and funds).
## Remediation
### Patches
- **Utilization Cap:** A protocol-level update has been implemented to enforce a hard cap on the utilization rate, preventing the math from "breaking" even if a donation occurs.
- **Contract Logic:** Updates to the `Base Silo` contract to ensure interest rate calculations cannot exceed sane physical limits.
### Workarounds
- **Minimum Liquidity:** Seeding new markets with a small amount of "burned" liquidity to prevent the zero-share exploitation state.
- **Balance Verification:** Implementing checks that compare `internalBalances` (tracked via state variables) against `externalBalances` (held by the contract address).
## Detection
- **Indicators of Compromise:** Large direct asset transfers to the Silo contract addresses that do not originate from the `Silo:deposit` function.
- **Detection Methods:** Monitor for transactions where the `utilizationRate` for any market exceeds 100% or where interest rates show a non-linear, vertical spike within a single block.
## References
- Silo Finance Official Documentation: hxxps[://]docs[.]silo[.]finance/
- Smart Contract Security Reports: hxxps[://]github[.]com/silo-finance/silo-core-v1/
- Vulnerability Lead: "Silo Finance Isolated Lending Market Logic Flaw"