Blockchain security isn't optional.

$12 million vanished in seconds and the contracts worked exactly as written. Undefined behavior is still a bug. Get your free smart contract audit quote today.

Get a Quote Today

Polter Finance: Brief Introduction

Polter Finance is a decentralized, non-custodial protocol designed for lending and borrowing digital assets. It uses liquidity pools where users can deposit assets to earn interest or borrow against their collateral. The protocol is based on the same smart contracts as the GEIST platform, which previously operated on the Fantom blockchain, but with modifications such as disabling flash loans to address known vulnerabilities.

The platform operates using a tokenized incentive model centered around $POLTER tokens, which are distributed to participants for providing liquidity, borrowing, or staking. Its mechanics include dynamic interest rate adjustments, vesting of earned rewards, and a liquidation system to maintain solvency and ensure borrower accountability. What caused the vulnerability in Polter Finance’s system, this question is at the core of understanding the exploit that drained $12 million from the platform.

How Polter Finance Lending and Borrowing Operates

Lending Pools

Assets deposited into Polter Finance are pooled into a single reserve for each token type. Borrowers access liquidity from these reserves, and the interest paid by borrowers is distributed among depositors and stakers.

Collateralization and Borrowing

Borrowers must collateralize assets to access liquidity. The borrowing limit is determined by the Loan-to-Value (LTV) ratio specific to each asset. For instance, an asset with a 30% LTV allows borrowing up to 30% of the collateral's value. Borrowers' positions are monitored via a "Health Factor," which indicates the solvency of their loans.

Interest Rate Mechanism

Polter employs a dynamic interest rate model tied to the utilization rate of each asset pool:

  • Utilization Rate (U):
  • Interest Rate Curve: Each pool has a two-segment linear curve. Below the optimal utilization point, interest rates grow slowly, encouraging borrowing. Beyond this point, rates increase steeply to incentivize deposits and reduce borrowing.

Liquidation Process

Borrowers with a Health Factor below 1 become eligible for liquidation:

  • Health Factor Calculation:
  • Liquidation Mechanism: Liquidators repay a portion of the borrower's debt and claim a corresponding value of collateral, along with a penalty fee.

Tokenomics

$POLTER tokens are central to the protocol's incentive structure. Tokens are distributed based on participation metrics such as deposit size, borrowing utilization, and staking contributions. Rewards are vested for a 3-month period to encourage long-term engagement.

Polter Finance's Security Risks: Audit Oversights and Vulnerabilities

Before delving into the details of the exploit, it's important to highlight a significant security oversight by the Polter Finance team. The project neglected to conduct an independent security audit of their platform, instead relying on the audit report of another project, Geist Finance, from which they had forked their codebase.

Reliance on Forked Code Audits

On their audit page, Polter Finance stated:

Polter Finance audit disclaimer stating reliance on Geist Finance’s audit

While forking code from a reputable project can be a starting point, relying solely on the original project's audit is insufficient for several reasons:

  • Code Modifications: Even minor changes, such as the removal of the flash-loan function, can introduce unforeseen vulnerabilities.
  • Different Deployment Contexts: The operational environment, integrations, and dependencies may differ, affecting security.
  • Updates and Patches: The forked code may not include the latest security patches or updates implemented in the original project.
  • Responsibility for Security: Relying on another project's audit does not transfer the responsibility of ensuring security to your own project.

Polter Finance Exploit: Price Oracle Manipulation and Security Flaws

On November 16, 2024, Polter Finance, a decentralized lending protocol operating on the Fantom network, suffered a significant exploit resulting in the loss of approximately $12 million. The attacker leveraged a common vulnerability in decentralized finance: price oracle manipulation. Specifically, the exploit targeted Polter Finance's reliance on price data from SpookySwap's V2 and V3 liquidity pools for the BOO token.

By executing a flash loan to manipulate these liquidity pools, the attacker artificially inflated the BOO token's price. This allowed them to deposit a minimal amount of BOO as collateral and borrow assets worth far more than the actual value of the collateral, effectively draining multiple lending pools.

To protect your project against vulnerabilities, you can explore our blockchain security services.

Overview of the Exploit

The core issue stemmed from a flaw in Polter Finance's price oracle system, a vulnerability central to the Polter Finance hack, particularly within the ChainlinkUniV2Adapter contract used by the AaveOracle. The oracle failed to validate significant price fluctuations and lacked safeguards against manipulation via flash loans. The attacker exploited this by:

  1. Flash Loan Manipulation: Initiating flash loans to temporarily drain BOO tokens from SpookySwap V2 and V3 liquidity pools, causing a drastic imbalance in the token reserves.
  2. Collateral Deposit: Depositing a small amount of BOO into Polter Finance's lending pool as collateral.
  3. Exploiting Inflated Price: Leveraging the artificially inflated BOO price to borrow assets worth far more than the actual value of the collateral.
  4. Profiting and Exiting: Repaying the flash loans and retaining the borrowed assets, effectively draining Polter Finance's liquidity.

Detailed Breakdown of the Attack

Step 1 - Flash Loan Attack: Draining BOO Liquidity from SpookySwap

The attacker initiated the exploit by taking out substantial flash loans from SpookySwap's V2 and V3 liquidity pools:

  • SpookySwap V2 Flash Loan: 269,042 BOO tokens
  • SpookySwap V3 Flash Loan: 1,154,788 BOO tokens
Flash loans are uncollateralized loans that must be repaid within the same transaction. They are commonly used for arbitrage opportunities but can be exploited to manipulate on-chain data if not properly safeguarded.
Illustration of how flash loans were used to manipulate BOO token liquidity

By borrowing these large amounts of BOO tokens, the attacker temporarily removed significant liquidity from the pools. This action drastically reduced the BOO reserves in the pools, causing an imbalance in the token pairings.

Automated Market Maker (AMM) Model:

The price of tokens in AMM-based decentralized exchanges like SpookySwap is determined by the constant product formula:

  • x: Reserve of token A (e.g., BOO)
  • y: Reserve of token B (e.g., wFTM)
  • k: Constant product of the reserves

When the reserve xxx (BOO tokens) decreases significantly due to the flash loan, the price of BOO relative to token B increases sharply to maintain the constant kkk. This results in an artificially inflated price of BOO within the liquidity pools.

Step 2 - Using Fake Collateral: How the Attacker Borrowed Millions

Using the manipulated spot price, the attacker deposited just 1 BOO token into Polter Finance's lending pool as collateral.

Due to the logic flaw in the oracle, the AaveOracle used the flawed price feed that evaluated the 1 BOO token at an inflated value of approximately $1.37 trillion instead of its actual market value.

This allowed the attacker to have an excessively overvalued collateral, enabling them to borrow vast amounts of assets.

Visualization of attacker depositing BOO tokens with an inflated valuation
Visualization of attacker depositing BOO tokens with an inflated valuation

Step 3 - Polter Finance Oracle Exploit: Flawed Price Feeds and Manipulation

The ChainlinkUniV2Adapter contract was used to fetch the current price of the BOO token. However, it lacked safeguards to check for drastic price fluctuations resulting from the flash loan.

The _fetchPrice function within this adapter retrieved the current price of BOO directly from the liquidity pools without any mechanisms to detect or prevent sudden price manipulations.

Code snippet of fetchPrice function failing to validate price fluctuations

The getRoundData() function, used for retrieving historical price data, also failed to validate significant price changes.

Function code demonstrating incorrect round ID usage in price feeds

It relied on _getPriceAndTimestamp(), which simply returned the current manipulated price without assessing its legitimacy or comparing it to previous values. Moreover, getRoundData() used hardcoded values for answeredInRound, bypassing dynamic price verification mechanisms.

Code snippet showing the Polter Finance oracle vulnerability exploited by the attacker

As a result, the manipulated price was not validated before being returned. Additionally, the hardcoded answeredInRound = 2 value in the function did not account for whether the price data was accurate for the current round, further allowing the flawed price to pass unchecked.

Function code demonstrating incorrect round ID usage in price verification

The latestRoundData() function, intended to return the most recent price information, was instead providing falsely inflated prices due to liquidity shifts caused by the attacker's flash loan. It lacked mechanisms to verify that the retrieved price (answer) was accurate and unaffected by manipulation.

The getRoundData() and latestRoundData() functions were designed to maintain consistent and accurate pricing for BOO tokens but failed to account for the significant price deviations triggered by the flash loan. The attacker exploited this vulnerability by offering minimal collateral while benefiting from an artificially inflated price feed.

Code showing how the fetchPrice function failed to detect manipulated prices

The prevChainlink0Response mechanism was intended to flag price changes exceeding a defined threshold by comparing the current price with the previous one in the _chainlinkPriceChangeAboveMax function, which is called within _fetchPrice:

Step-by-step diagram of how the attacker leveraged the oracle vulnerability

However, due to the hardcoded roundId in getRoundData(), the mechanism couldn't fetch valid previous prices, rendering the comparison ineffective and allowing the inflated price to bypass the oracle's checks.

  • Hardcoded roundId: The getRoundData() function always returns a roundId of 2, preventing access to historical price data by decrementing roundId.
  • Invalid Previous Round Data: Since roundId is always 2, attempting to fetch previous round data using _currentRoundId - 1 (which becomes 1) fails because the adapter does not support fetching data for roundId other than 2.
  • Undetected Price Spike: Consequently, the _chainlinkPriceChangeAboveMax function in the PriceFeedV2 contract could not detect the abnormal price spike caused by the flash loan manipulation.
Comparison chart of borrowed assets versus actual BOO collateral value

This failure allowed the artificially inflated price of 1 BOO token to bypass the oracle's checks, leading to erroneous collateral value calculations.

The attacker continued to borrow wFTM tokens against the inflated collateral. By maintaining the manipulated price, they could continue the borrowing cycle, draining the liquidity pools without restriction. The oracle contract was unable to detect these repeated borrowings due to its malfunctioning price validation logic.

Visualization of how the attacker repaid flash loans and retained stolen funds

The attacker borrowed 9,134,844 wFTM by using the inflated price of the BOO token as collateral, ultimately draining approximately $12 million from the Polter Finance lending pools.

Step 4 - Exiting the Attack: How the Attacker Laundered Funds

After successfully borrowing assets from Polter Finance, the attacker proceeded to repay the flash loans. By returning the borrowed BOO tokens to SpookySwap V2 and V3, they restored the liquidity pools' reserves, which normalized the BOO token's price back to its actual market value. With the flash loans settled, the attacker retained the borrowed wFTM tokens and any other assets obtained during the exploit.

Preventing Future Exploits: Lessons from the Polter Finance Hack

The exploit against Polter Finance stemmed from significant security oversights, primarily the absence of an independent security audit. Instead of thoroughly auditing their platform, Polter Finance relied on the audit report of Geist Finance, the project from which they forked their codebase. This reliance is insufficient because even minor modifications, like disabling the flash-loan function, can introduce new vulnerabilities. An independent audit could have identified the weaknesses in their oracle system that were exploited.

To prevent the attack, Polter Finance should have implemented robust validation mechanisms within their price oracle. The ChainlinkUniV2Adapter contract lacked safeguards against drastic price fluctuations caused by flash loans. Incorporating time-weighted average prices (TWAP) or using reliable price feeds from decentralized oracle networks like Chainlink would have mitigated the impact of temporary price manipulations. Additionally, functions responsible for fetching price data should have included checks to compare new prices against historical data and reject anomalous values.

By conducting an independent security audit and enhancing their oracle's validation processes, Polter Finance could have detected and addressed these vulnerabilities. Such measures would have significantly reduced the risk of price manipulation attacks, safeguarding the protocol and its users' assets.

Consequences of the Exploit

The immediate consequence of the Polter Finance exploit was the loss of approximately $12 million from its lending pools. This substantial financial loss affected both the platform and its users, who suffered significant asset depletion. As this severe breach exposed critical vulnerabilities in Polter Finance's security infrastructure, it could negatively impact user trust and tarnish the protocol's reputation. Such an incident may lead users to reassess the security and reliability of Polter Finance.

The Polter Finance Protocol Response

Following the exploit, Polter Finance took immediate action to mitigate the damage and communicate with their community. Their response included several key steps:

  1. Platform Suspension: The platform was promptly paused to prevent further exploitation and protect any remaining user funds.
Official statement from Polter Finance about pausing the platform after the attack

2. Reaching Out to the Exploiter: The team made an on-chain appeal to the individual responsible for the exploit, aiming to negotiate the return of the funds or reach an amicable solution.

Screenshot of Polter Finance reaching out to the hacker for fund recovery

3. Collaboration with Security Experts: Polter Finance actively engaged with cybersecurity organizations to investigate the exploit and seek a resolution.

Polter Finance working with cybersecurity firms to investigate the exploit

4. Legal Action: Polter Finance filed an official police report concerning the exploit and shared this development with their community.

Polter Finance legal report notifying authorities of the $12 million exploit
Polter Finance didn’t fall to an obvious exploit, it fell to misunderstood logic and silent assumptions. Our Smart Contract Audit service identifies unintended outcomes, economic edge cases, and off-chain dependencies before attackers do.

Read our Deltaprime DeFi Exploit and Ronin Network Exploit articles to stay updated in DeFi security.


Addresses

Addresses

Simeon Cholakov
Simeon Cholakov

Security Researcher