Fei Bonding Curve Bug Post Mortem

Disclosing a vulnerability we found in the system

Brianna Montgomery
Fei Protocol
6 min readMay 13, 2021

--

On May 2, during an internal code review, we identified a critical vulnerability that could have removed ETH from the Protocol Controlled Value. The attack involved manipulating the spot price on the FEI-ETH Uniswap pair, before providing liquidity through the bonding curve. After validating a Proof of Concept (PoC) attack, we immediately paused the bonding curve, which prevented the exploit from being possible, and notified our community publicly on Discord. The following day, we received a report from Immunefi where Alexander Schlindwein had also independently discovered the exploit.

The vulnerability was not exploited and no funds were lost.

OpenZeppelin and Alexander further assisted with the review and validation of the fix. The fix removes the attack vector by sending ETH from the bonding curve to the reserve stabilizer rather than the ETH-FEI Uniswap pool. It also adds additional checks on the pool to ensure that if more funds are added to the pair in the future, it is protected from malicious arbitrage.

Vulnerability Analysis

Fei Protocol uses Protocol Controlled Value (PCV) to support FEI’s liquidity and stability. The primary deployment of ETH PCV is the ETH-FEI pair on Uniswap.

When the price of FEI is over $1.01, users can purchase newly minted FEI from the protocol’s bonding curve for ETH to arbitrage the secondary market price down towards $1. This ETH is escrowed in the bonding curve until a keeper allocates it, at which point it is deposited into the ETH-FEI pair at the spot price. Manipulation of the spot price with a flash loan is the primary vector of the attack.

During the OpenZeppelin pre-launch audit, we discovered this issue and reported it as a client reported vulnerability. In the audit report, they reviewed the fix that would send the liquidity to Uniswap at the oracle price ratio: https://github.com/fei-protocol/fei-protocol-core/pull/81.

However, the UniswapV2Router02 enforces liquidity provision at the spot price, even if the desired inputs are provided in another ratio. This invalidates the fix, and leads to the vulnerability being exploitable.

A malicious actor would have been able to:

  1. Flash borrow ETH
  2. Use some of that ETH to purchase FEI on the ETH-FEI Uniswap pair to drive up the spot price
  3. Use the remaining ETH to purchase FEI for $1.01 on the bonding curve
  4. Trigger the allocation for ETH from 3 to be added as liquidity to the pair at the elevated price.
  5. Sell back the FEI received from 2 and 3 at the elevated price
  6. Repay the flash loan with a profit

The source of profit is step 4, where the protocol is under-minting FEI due to it being more expensive. The FEI purchased is then sold at a premium using the deeper liquidity supplied by the protocol during that step.

Mitigation Steps

Immediately after confirming the vulnerability, we paused the EthBondingCurve contract using the Guardian. This disabled purchases and allocations.

Upon further verification that the purchase function is not exploitable, we

  1. paused the EthUniswapPCVDeposit contract effectively disabling the allocate() function from the bonding curve
  2. unpaused the bonding curve to allow purchasing of FEI from the protocol

The permanent fix to the exploit is two-fold:

  1. Decoupling the bonding curve from the Uniswap liquidity pool. ETH that enters from the bonding curve will now go to the dripper to the FEI stabilizer contract (used to add in the $0.95 price floor)
  2. Add slippage protection to the EthUniswapPCVDeposit contract that prevents it from minting any liquidity at a price significantly different from the oracle price of ETH.

To send ETH from the bonding curve to the stabilizer, we will update the allocation using setAllocation() via the DAO to the EthReserveStabilizer through the EthPCVDripper. New calls to allocate() would send any escrowed ETH to the dripper instead of the EthUniswapPCVDeposit. Decoupling the bonding curve from the EthUniswapPCVDeposit will prevent any well-funded attacks from exploiting any interaction of these protocol mechanisms. This fix is simple and removes the attack vector.

Without slippage protection, future liquidity deposits to the EthUniswapPCVDeposit would still be vulnerable to sandwich attacks. By using a 1% deviation from the ETH-USD oracle price as the boundary, sandwiching is only profitable with high volumes of ETH deposited. Because the amount of ETH deposited will be controlled by governance and no longer externally manipulable, we can verify an attack is not profitable. This will prevent similar exploits from affecting future deposits of PCV into liquidity pairs.

OpenZeppelin and Alexander Schlindwein have reviewed and approved this pull request with the relevant changes: https://github.com/fei-protocol/fei-protocol-core/pull/98.

Bug Bounty

On May 3, we received a vulnerability report from security researcher Alexander Schlindwein through our Immunefi bug bounty program, disclosing the same issue. By then, we had already paused the EthBondingCurve contract and publicly announced the vulnerability on Discord.

Immunefi notified us that they received his initial report without a PoC around the same time we discovered the issue. Once the PoC was delivered, the whitehat vulnerability report stated he could remove 40,000 ETH using parameter optimizations. Applying a larger flash loan, including ETH from several sources, such as Aave and Uniswap, could remove more ETH from the pair, up to the entire amount with infinite ETH.

To show our gratitude and commitment to security, we will award Alexander an $800,000 bounty, even though the report was disclosed to us after we discovered and mitigated the issue. This will be paid in TRIBE from Fei Labs through the portion of our grants allocated for bug bounties.

Alexander has provided ongoing assistance in both scoping and reviewing the proposed solution, and shown a high degree of skill and integrity given the severity of the issue. We greatly value the efforts of Alexander and the broader whitehat community in helping secure Fei Protocol and the broader Ethereum ecosystem.

Going Forward

Although we have thoroughly tested the code and received a comprehensive security audit, vulnerabilities are always a possibility in the complex and composable DeFi ecosystem. We will implement several strategies to reduce risks and improve system security.

We are going to continue to promote the reduction of complexity to protocol mechanisms, and propose further simplifications to maintaining FEI’s peg and managing PCV. This effort had already begun with the proposal to restore reweights with a regular frequency. The DAO vote for that proposal was delayed due to this vulnerability, and will be reintroduced after this fix is in place.

We are taking the additional steps to improve our security posture to enable us to support future proposals via the DAO.

Next Steps:

  • Continue to engage with auditors for all new protocol code, early and often
  • Our bug bounty program will continue to be well funded on Immunefi
  • Continue to run economic simulations and models
  • In collaboration with security consultants, we are implementing additional testing automation including fuzzing
  • We will expand our Bug bounty program to include Fei Improvement Proposals (FIPs) before they go to the DAO for voting
  • We will expand our efforts to hire smart contract developers and security engineers to join our team. If you are interested, contact us or apply here.

We are grateful to our security partners OpenZeppelin, ConsenSys Diligence and Immunefi for their continued support, as well as the broader Ethereum security community, including Alexander Schlindwein for promoting whitehat hacking and security research.

Security Reseachers

We welcome everyone to participate in our bug bounty program. If you are a hacker, we have a $1.1M payout reward for critical vulnerabilities.

If you have any questions or want to contribute to the project, we would love to hear from you! Reach out to us on our Discord and our forum.

--

--