All incidents

ParaSpace cAPE Donation Repricing

Share
Mar 17, 2023 05:48 UTCAttackLoss: 7,200,000 USDC, 1,200 WETHPending manual check1 exploit txWindow: Atomic
Estimated Impact
7,200,000 USDC, 1,200 WETH
Label
Attack
Exploit Tx
1
Addresses
2
Attack Window
Atomic
Mar 17, 2023 05:48 UTC → Mar 17, 2023 05:48 UTC

Exploit Transactions

TX 1Ethereum
0xe3f0d14cfb6076cabdc9057001c3fafe28767a192e88005bc37bd7d385a1116a
Mar 17, 2023 05:48 UTCExplorer

Victim Addresses

0x638a98bbb92a7582d07c52ff407d49664dc8b3eeEthereum
0xc5c9fb6223a989208df27dcee33fc59ff5c26fffEthereum

Loss Breakdown

7,200,000USDC
1,200WETH

Similar Incidents

Root Cause Analysis

ParaSpace cAPE Donation Repricing

1. Incident Overview TL;DR

In Ethereum mainnet transaction 0xe3f0d14cfb6076cabdc9057001c3fafe28767a192e88005bc37bd7d385a1116a at block 16845559, an unprivileged attacker used a single public transaction to flash-borrow wstETH, open multiple attacker-controlled cAPE debt positions on ParaSpace, and build a large PTokenCApe collateral position on the main attacker-controlled account. The attacker then deposited APE into Yoga Labs' ApeCoinStaking contract on behalf of the cAPE contract address 0xC5c9fB6223A989208Df27dCEE33fC59ff5c26fFF, which immediately increased the cAPE exchange rate used by ParaSpace. With that inflated collateral valuation, the attacker borrowed wstETH, USDC, and WETH from ParaSpace and exited with a net ETH profit.

The root cause is that ParaSpace trusted a cAPE rebasing index that could be increased permissionlessly by third-party ApeCoinStaking deposits credited to the AutoCompoundApe contract, without minting offsetting cAPE shares. That let the attacker reprice already-held PTokenCApe collateral upward inside the same transaction and borrow against the inflated value.

2. Key Background

cAPE is a rebasing ERC-20 wrapper around an ApeCoinStaking position. User balances are share-based rather than fixed-unit based, so account balances are derived from getPooledApeByShares(shares) and therefore depend on the protocol's total pooled APE per share.

ParaSpace integrates cAPE through two rebasing token adapters:

  • PTokenCApe for collateral accounting.
  • CApeDebtToken for debt accounting.

Both adapters read the same cAPE rebasing index:

function lastRebasingIndex() internal view override returns (uint256) {
    return ICApe(_underlyingAsset).getPooledApeByShares(WadRayMath.RAY);
}

Origin: ParaSpace PTokenCApe and CApeDebtToken sources.

The cAPE exchange rate itself is derived from total pooled APE divided by total shares:

function getPooledApeByShares(uint256 sharesAmount) public view returns (uint256) {
    uint256 totalShares = _getTotalShares();
    if (totalShares == 0) return 0;
    return sharesAmount.mul(_getTotalPooledApeBalance()).div(totalShares);
}

Origin: cAPE base token source.

AutoCompoundApe computes total pooled APE from its staking position, pending rewards, and buffer balance:

function _getTotalPooledApeBalance() internal view override returns (uint256) {
    uint256 rewardAmount = apeStaking.pendingRewards(APE_COIN_POOL_ID, address(this), 0);
    return stakingBalance + rewardAmount + bufferBalance;
}

Origin: AutoCompoundApe source.

Yoga Labs' ApeCoinStaking contract exposes a public recipient-directed deposit path:

function depositApeCoin(uint256 _amount, address _recipient) public {
    Position storage position = addressPosition[_recipient];
    _deposit(APECOIN_POOL_ID, position, _amount);
    apeCoin.transferFrom(msg.sender, address(this), _amount);
}

Origin: ApeCoinStaking source.

That interface matters because any caller can increase the staking position of the cAPE contract without going through cAPE's share-minting logic.

3. Vulnerability Analysis & Root Cause Summary

The vulnerability is an integration flaw in how ParaSpace priced cAPE collateral and debt. ParaSpace treated ICApe.getPooledApeByShares(WadRayMath.RAY) as a trustworthy rebasing index for both PTokenCApe and CApeDebtToken, but the underlying cAPE implementation allowed its pooled APE per share to rise when third parties deposited principal directly into ApeCoinStaking for the cAPE recipient. Because that external deposit did not mint new cAPE shares, existing shares became more valuable immediately. The attacker first accumulated a large cAPE-backed collateral position through public flash liquidity and public ParaSpace supply and borrow entrypoints. The attacker then triggered a public depositApeCoin(amount, recipient = cAPE) call that repriced the same collateral upward inside the same transaction. Once the rebasing index jumped, ParaSpace reported materially higher borrow capacity and allowed the attacker to drain external reserves. The violated invariant is that external principal injections must not increase the borrowable value of pre-existing cAPE collateral unless matching new shares are minted.

4. Detailed Root Cause Analysis

The critical breakpoint is the combination of a permissionless recipient-directed ApeCoinStaking deposit and ParaSpace's immediate reuse of the resulting cAPE exchange rate. The seed trace shows the donation into cAPE and the downstream borrowing sequence in the same transaction:

ApeCoinStaking::depositApeCoin(
  2332214464588784613678467,
  InitializableAdminUpgradeabilityProxy: [0xC5c9fB6223A989208Df27dCEE33fC59ff5c26fFF]
)
...
PoolCore::borrow(WstETH, 44952823905004708422332, 0, 0xc0064DEA80567e7ABd0294e55DB32426535001Cc)
PoolCore::borrow(FiatTokenProxy, 7200000000000, 0, 0xc0064DEA80567e7ABd0294e55DB32426535001Cc)
PoolCore::borrow(WETH9, 1200000000000000000000, 0, 0xc0064DEA80567e7ABd0294e55DB32426535001Cc)

Origin: seed trace for the incident transaction.

The same trace also shows the rebasing index before and after the donation. Before the donation, ParaSpace repeatedly read getPooledApeByShares(1e27) as 1232409456328880505544263667. After the donation, the same read returned 4607273441248019310320636539. No matching share mint to the attacker accompanied that jump. That is the direct accounting failure: the numerator in cAPE share pricing increased, while the denominator of existing shares did not.

The attack therefore depended on four deterministic exploit conditions:

  1. ParaSpace accepted cAPE as a reserve through PTokenCApe and CApeDebtToken.
  2. ApeCoinStaking allowed public deposits into an arbitrary recipient's staking position.
  3. cAPE priced balances from total pooled APE per share rather than from isolated share-minting events.
  4. ParaSpace had enough liquid wstETH, USDC, and WETH reserves to be borrowed after the repricing.

Before the donation step, the attacker used public Aave flash liquidity and attacker-controlled helper contracts to borrow cAPE against helper-owned wstETH collateral and to resupply most of that cAPE to the main attacker-controlled account. That setup mattered because the attacker needed a large pre-existing PTokenCApe share position before the rebasing index moved. After the donation, the pre-existing shares were worth far more APE in ParaSpace's accounting, so the attacker's available borrow headroom increased without any legitimate increase in the economic value of the original cAPE position.

This is an ACT-class issue because every required primitive was public: flash loans, ParaSpace supply and borrow entrypoints, cAPE transfers and withdrawals, ApeCoinStaking deposits, and public DEX liquidity for the unwind.

5. Adversary Flow Analysis

The adversary cluster identified in the evidence consists of:

  • EOA 0x0000003502aa61a5f1b1fdadff2cf947dfda526e, the sender that received the final ETH profit.
  • Main execution contract 0xc0064dea80567e7abd0294e55db32426535001cc, which received the flash loan, orchestrated helper funding, donated APE into cAPE's staking position, executed the final borrows, and unwound to ETH.
  • Helper contracts 0x0dab8bbc6b23234cb95c2063199daf9faafd0288, 0x335441a28b16ae8a89541307fe398a4bda35fb76, 0x5ef895a4320312127ba01678aa5aa87c3a404c16, 0xbc1f4b38ec14396b7482496ae5711774d44abc94, 0xfce3d3d46ddd52e6cbe353a5664263298bfd2bef, 0x19ec952365151a53a5b1b5be04df16df9b0bb15c, 0xd81ebcf3748c0eea59c141e6233cfcee4d3dcc06, and 0xb5ae840838f6f9497adfcc8747e6a232f62b76fd.

The end-to-end on-chain flow was:

  1. The attacker called the main execution contract from the profit-taking EOA.
  2. The main contract obtained 47352823905004708422332 wstETH from Aave via flashLoanSimple.
  3. The main contract distributed wstETH to helper contracts, which each supplied wstETH to ParaSpace and borrowed cAPE.
  4. The helpers transferred almost all borrowed cAPE back to the main contract, which resupplied most of it to ParaSpace to build a large PTokenCApe collateral position while the helpers retained the cAPE debt.
  5. The main contract redeemed the final unsupplied cAPE tranche into APE, swapped additional assets into APE, and called ApeCoinStaking.depositApeCoin with recipient = cAPE.
  6. ParaSpace immediately reread the higher cAPE rebasing index and allowed the main contract to borrow 44952823905004708422332 wstETH, 7200000000000 USDC, and 1200000000000000000000 WETH.
  7. The attacker unwound part of the proceeds, repaid the flash loan, withdrew WETH to ETH, and transferred the ETH profit to the sender EOA.

The victim candidates directly affected by this sequence were the ParaSpace pool at 0x638a98bbb92a7582d07c52ff407d49664dc8b3ee and the cAPE integration at 0xc5c9fb6223a989208df27dcee33fc59ff5c26fff.

6. Impact & Losses

The measurable reserve extraction recorded in the root-cause artifact is:

  • 7200000000000 raw USDC units, or 7,200,000 USDC.
  • 1200000000000000000000 raw WETH units, or 1,200 WETH.

The balance-diff artifact also shows the sender EOA's native balance increasing from 4396322826175822908 wei to 2909318257868361194941 wei, a net delta of 2904921935042185372033 wei after gas. The block builder address 0xdafea492d9c6733ae3d56b7ed1adb60692c98bc5 received 1246421426605621098 wei in priority fees. In other words, the attacker realized roughly 2904.921935042185372033 ETH of net value while draining ParaSpace reserves that had been made borrowable only by the donation-driven cAPE repricing.

The broader impact is that ParaSpace's cAPE collateral accounting allowed public third parties to convert an uncompensated principal donation into immediate same-transaction borrowing power against unrelated reserve assets.

7. References

  • Incident transaction: 0xe3f0d14cfb6076cabdc9057001c3fafe28767a192e88005bc37bd7d385a1116a
  • Block height: 16845559; public pre-state for ACT reproduction: block 16845558
  • ParaSpace pool: 0x638a98bbb92a7582d07c52ff407d49664dc8b3ee
  • cAPE proxy: 0xc5c9fb6223a989208df27dcee33fc59ff5c26fff
  • AutoCompoundApe implementation source
  • ParaSpace PTokenCApe and CApeDebtToken sources
  • Yoga Labs ApeCoinStaking.depositApeCoin(uint256,address) source
  • Seed transaction metadata, trace, and balance diff artifacts collected for the incident