How Was Paribus Exploited?

4 min read

Learn how Paribus was exploited due to a reentrancy issue, resulting in the loss of $67,800..

TL;DR#

On April 11, 2023, Paribus was exploited due to the re-entrancy issue with the old Compound V2 fork, which resulted in the loss of tokens including USDT, WBTC, and ETH totaling approximately $67,800.

Introduction to Paribus#

Paribus is a cross-chain borrowing and lending protocol for NFTs, liquidity positions, and synthetic assets built for the Cardano blockchain.

Vulnerability Assessment#

The root cause of the vulnerability is due to the well-known reentrancy issue from the forked old version of CompoundV2. 

Steps#

Step 1:

We attempted to analyze the attack transaction executed by the exploiter.

Step 2:

The exploiter initially took a flash loan of 200 WETH and 30,000 USDT in order to deposit them into their protocol and utilize them as collateral.

Step 3:

The attacker used the 30,000 USDT to borrow 13 ETH from the pETH pool and invoked a call to the redeem function on the pETH pool to withdraw the deposited collateral.

Step 4:

On the redeem function of the pToken, transfer occurred prior to the storage update, violating the check-effect-interaction pattern. However, it was safeguarded by the nonReentrant modifier.

/////////////////////////
// EFFECTS & INTERACTIONS
// (No safe failures beyond this point)

/*
* We invoke doTransferOut for the redeemer and the redeemAmount.
*  Note: The pToken must handle variations between ERC-20 and ETH underlying.
*  On success, the pToken has redeemAmount less of cash.
*  doTransferOut reverts if anything goes wrong, since we can't be sure if side effects occurred.
*/
doTransferOut(redeemer, vars.redeemAmount);

// We write previously calculated values into storage
totalSupply = vars.totalSupplyNew;
accountTokens[redeemer] = vars.accountTokensNew;

// We emit a Transfer event, and a Redeem event
emit Transfer(redeemer, address(0), vars.redeemTokens);
emit Redeem(redeemer, vars.redeemAmount, vars.redeemTokens);

Step 5:

According to the team, the violation was apparently reported as a `low-level` issue in their report, and later marked as mitigated during the later round of review. As the redeem function was executed on the pETH pool, the redeemed funds were in ETH and were subsequently utilized by the fallback function.

Step 6:

However, during the fallback execution, the pETH balance remained unaltered, which allowed the attacker to use the collateral to borrow from the pUSDT and pWBTC pools.

Step 7:

The nonReentrant modifier did not protect against this attack, as the pUSDT and pWBTC pools were separate contracts.

Step 8:

Upon the completion of the redeem function in the pETH pool, the initial borrowed amount was subsequently repaid, and the attacker took away funds worth approximately 20,000 USDT from the pUSDT pool, 0.755 WBTC from the pWBTC pool, and 13 ETH from the initial borrow.

Aftermath#

After the attack, the team paused the platform, made changes to their protocol, and will be deploying its newer version after the necessary audits and checks are completed.

The PBX token was unaffected, and the team also stated that they will be working with their audit partner to understand why the issue wasn't noticed in their audit reports before their Mainnet launch a couple of days earlier.

The team is also working on a solution to look for a way to reimburse the funds of all the affected users.

Solution#

In order to safeguard against exploits originating due to Reentrancy attack, a mutex can be used to make the function of a smart contract non-reentrant. Incomplete non-Reentrant mutex, on the other hand, can result in cross-contract or cross-function Reentrancy.

Another method for preventing reentrancy attacks is to use checks-effects-interactions design to ensure that all state changes take place internally before calling external smart contracts.

Additionally, many formal verification tools can also be used to ensure that the smart contract behaves as it is intended to. A team should also perform multiple security audits on their protocol to ensure that all potential vulnerabilities are identified and addressed in order to further secure the protocol.

We may not have prevented the occurrence of this hack, however the impact or aftermath of this attack could have been significantly reduced if the team associated with Paribus had set up a dedicated cover pool in the Neptune Mutual marketplace. We offer coverage to users who have suffered a loss of funds or digital assets occurring as a result of smart contract vulnerabilities owing to our parametric policies.

Users who purchase the available parametric cover policies do not need to provide loss evidence in order to receive payouts. Payouts can be claimed as soon as an incident is resolved through the incident resolution system. At the moment, our marketplace is available on two popular blockchain networks, Ethereum, and Arbitrum.

Neptune Mutual's security team would also have evaluated the platform for DNS and web-based security, frontend and backend security, intrusion detection and prevention, and other security considerations.

Reference Source Paribus

By

Tags