code-423n4 / 2023-08-dopex-findings

3 stars 3 forks source link

the `perpetualVaultLP.sol` is vulnable by flashloan attack #2196

Closed code423n4 closed 12 months ago

code423n4 commented 1 year ago

Lines of code

https://github.com/code-423n4/2023-08-dopex/blob/eb4d4a201b3a75dd4bddc74a34e9c42c71d0d12f/contracts/perp-vault/PerpetualAtlanticVaultLP.sol#L118-L135 https://github.com/code-423n4/2023-08-dopex/blob/eb4d4a201b3a75dd4bddc74a34e9c42c71d0d12f/contracts/perp-vault/PerpetualAtlanticVaultLP.sol#L145-L175

Vulnerability details

impact

The perpVaultLp contract is susceptible to a flash loan attack. An attacker can exploit the vulnerability by executing flash loan transactions using both the deposit() and redeem() functions. This allows the attacker to acquire extra rdpx tokens and increase their share of assets within seconds, all without actually adding a balance to the perpVaultLP. The attacker only needs to obtain a flash loan of weth as the deposit asset, and then they can use the deposit function to mint shares and subsequently call the redeem function to receive the flash loan amount along with additional rdpx tokens.

proof of concepts

The deposit function allows users to deposit assets (weth or rdpx) into the perpVaultLp contract. Since this function is public and accessible to any users, it can be exploited by an attacker. Here's a portion of the deposit function:

function deposit(
        uint256 assets,
        address receiver
    ) public virtual returns (uint256 shares) {
        // Check for rounding error since we round down in previewDeposit.
        require((shares = previewDeposit(assets)) != 0, "ZERO_SHARES");

        perpetualAtlanticVault.updateFunding();

        // Need to transfer before minting or ERC777s could reenter.
        collateral.transferFrom(msg.sender, address(this), assets);

        _mint(receiver, shares);

        _totalCollateral += assets;

        emit Deposit(msg.sender, receiver, assets, shares);
    }

The redeem function allows users to redeem their assets by burning their shares and receiving extra rdpx tokens.

 function redeem(
        uint256 shares,
        address receiver,
        address owner
    ) public returns (uint256 assets, uint256 rdpxAmount) {
        perpetualAtlanticVault.updateFunding();

        if (msg.sender != owner) {
            uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals.

            if (allowed != type(uint256).max) {
                allowance[owner][msg.sender] = allowed - shares;
            }
        }
        (assets, rdpxAmount) = redeemPreview(shares);

        // Check for rounding error since we round down in previewRedeem.
        require(assets != 0, "ZERO_ASSETS");

        _rdpxCollateral -= rdpxAmount;

        beforeWithdraw(assets, shares);

        _burn(owner, shares);

        collateral.transfer(receiver, assets);

        IERC20WithBurn(rdpx).safeTransfer(receiver, rdpxAmount);

        emit Withdraw(msg.sender, receiver, owner, assets, shares);
    }

in this case an attacker can: Use a contract to obtain a substantial amount of weth through a flash loan.

Call the deposit function to update the _totalCollateral and mint shares corresponding to their weth balance.

In the same transaction, call the redeem function to redeem the weth, essentially paying back the flash loan. Simultaneously, the attacker receives an amount of rdpxAmount.

This attack can have a substantial impact as it effectively causes the protocol to grant the attacker a large quantity of rdpx tokens without any meaningful contribution.

Tools used

manual review

recommendation

I recommend implementing a delay mechanism for the deposited amount or restricting access to the deposit function to whitelist addresses only. These measures can help mitigate flash loan attacks and protect the protocol from such exploits

Assessed type

Other

c4-pre-sort commented 12 months ago

bytes032 marked the issue as duplicate of #867

c4-pre-sort commented 12 months ago

bytes032 marked the issue as sufficient quality report

c4-judge commented 10 months ago

GalloDaSballo marked the issue as satisfactory