Jan 16, 2025

PulsePot Flash Loan Attack 10 Jan 2025: $21.5K Lost

Decentralized On-Chain Casino PulsePot was Exploitd via a FlashLoan Attack and an Opportunity for Arbitrage

PulsePot Exploit
PulsePot Exploit
PulsePot Exploit

PulsePot is a decentralized on-chain casino on PulseChain and Binance Smart Chain. On Jan 10th their mechanisms were exploited via a flash loan attack.

Decentralized casinos operate through smart contracts that execute gambling mechanics in a transparent, verifiable way on the blockchain. PulsePot emerged as one of these platforms on the Binance Smart Chain, allowing users to participate in lottery-style games where outcomes were determined by smart contract code rather than a centralized operator.

Unlike traditional online casinos, these decentralized platforms let users verify the fairness of each bet through publicly viewable blockchain transactions, with automated payouts handled by smart contracts.

PulsePot Flash Loan Exploit

PulsePot's attacker used the swap logic of the swapProfitFees() function, which is a public function that handles tokens on the contract itself, to create an arbitrage opportunity and gain $21.5K.

Source: CertiK

How exactly was that done?

The attacker first identified that the swapProfitFees() function was public and could be called by anyone, not just the contract owner or authorized users 🚩

Since this function handled tokens within the contract itself, the attacker could manipulate the swap logic to create price discrepancies.

The attack pattern was likely:

  • Take out a flash loan to get a large amount of capital

  • Call swapProfitFees() to execute swaps that artificially create big price differences

  • Exploit these price differences through arbitrage trades

  • Repay the flash loan and keep the profit (approximately $21.5K)

The root causes are:

  • Poor access control

  • Lack of proper validation in the swap logic

  • No mechanisms to prevent price manipulation within a single transaction

Prevention and Best Practises

There are many ways this attack could have been prevented. If you're building similar swapping mechanisms, it is a MUST to add the following:

  • Implement proper access controls using modifiers like onlyOwner or onlyAuthorized

  • Include slippage protection and/or price manipulation checks

  • Consider implementing time delays or locks between significant token movements

  • Add reentrancy guards to prevent nested calls

  • Have thorough security audits focusing on swap functions and price calculations before you go live

Here's an example of a better implementation with a contract we'll call SecureContract:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract SecureContract {
    address private owner;
    mapping(address => bool) private authorizedUsers;

    // Events for tracking authorization changes
    event UserAuthorized(address indexed user);
    event UserDeauthorized(address indexed user);
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    constructor() {
        owner = msg.sender;
    }

    // Modifiers for access control
    modifier onlyOwner() {
        require(msg.sender == owner, "Caller is not the owner");
        _;
    }

    modifier onlyAuthorized() {
        require(authorizedUsers[msg.sender] || msg.sender == owner, "Caller is not authorized");
        _;
    }

    // Function to add authorized users
    function addAuthorizedUser(address user) external onlyOwner {
        require(user != address(0), "Invalid address");
        require(!authorizedUsers[user], "User already authorized");
        authorizedUsers[user] = true;
        emit UserAuthorized(user);
    }

    // Function to remove authorized users
    function removeAuthorizedUser(address user) external onlyOwner {
        require(authorizedUsers[user], "User not authorized");
        authorizedUsers[user] = false;
        emit UserDeauthorized(user);
    }

    // Example of a protected swap function
    function swapProfitFees() external onlyAuthorized {
        // Swap logic here
        require(/* your conditions */, "Invalid swap conditions");
        
        // Additional safety checks
        require(/* price impact check */, "Price impact too high");
        require(/* slippage check */, "Slippage too high");
    }

    // Function to check if a user is authorized
    function isAuthorized(address user) external view returns (bool) {
        return authorizedUsers[user] || user == owner;
    }

    // Function to transfer ownership
    function transferOwnership(address newOwner) external onlyOwner {
        require(newOwner != address(0), "Invalid new owner address");
        emit OwnershipTransferred(owner, newOwner);
        owner = newOwner;
    }
}

Here you have:

  • A clear ownership model

  • Role-based access control for authorized users

  • Proper events for tracking authorization changes

  • Input validation

  • Clear error messages

  • View functions for checking permissions

  • Ownership transfer capability

You might want to add:

  • Reentrancy guards using OpenZeppelin's ReentrancyGuard

  • Time locks for sensitive operations

  • Maximum swap limits

  • Price impact checks

  • Slippage protection

Request an Audit with Our Experts ⛊

Protect your protocol from preventable exploits that could've cost MUCH MORE in user funds.

The PulsePot incident demonstrates how even seemingly minor oversights in access controls can lead to significant losses. At Audita, our expert auditors specialize in identifying these critical vulnerabilities before malicious actors can exploit them.

Don't wait until after an incident – book a consultation with our security experts today. We'll work with your team to understand your protocol's unique architecture and ensure protection against common attack vectors.

Schedule your audit consultation now and launch with confidence, knowing your smart contracts have been thoroughly vetted by industry-leading security professionals.

STAY SAFU

Audita's Team

Tell us about your project

Tell us about your project

Tell us about your project

Blog

More from Audita

Our take on Web3 security

Our CLIENTS

Testimonials