code-423n4 / 2024-02-spectra-findings

4 stars 2 forks source link

Reentrancy allows double minting, inflating token supply, extracting value. #191

Closed c4-bot-3 closed 8 months ago

c4-bot-3 commented 8 months ago

Lines of code

https://github.com/code-423n4/2024-02-spectra/blob/383202d0b84985122fe1ba53cfbbb68f18ba3986/src/tokens/PrincipalToken.sol#L750-L769

Vulnerability details

Impact

_depositIBT function handles depositing IBT into the Principal Token vault, minting corresponding PT and YT. In PrincipalToken.sol::_depositIBT

function _depositIBT(
    uint256 _ibts,
    address _ptReceiver,
    address _ytReceiver
) internal notExpired nonReentrant whenNotPaused returns (uint256 shares) {

    // Update user yield  <@
    updateYield(_ytReceiver);

    // Compute tokenization fee <@
    uint256 tokenizationFee = PrincipalTokenUtil._computeTokenizationFee(
        _ibts,
        address(this),
        registry
    );

    // Update total fees  <@
    _updateFees(tokenizationFee);

    // Mint new shares    <@
    shares = _convertIBTsToShares(_ibts - tokenizationFee, false);
    if (shares == 0) {
        revert RateError();
    }

    // Mint tokens        <@
    _mint(_ptReceiver, shares);
    emit Mint(msg.sender, _ptReceiver, shares);
    IYieldToken(yt).mint(_ytReceiver, shares);
}

There is a risk of reentrancy here between updating yields and minting new shares.

A malicious contract could implement IYieldToken and reenter _depositIBT before shares are minted. This could enable inflating the _ibts balance used to mint shares by calling _convertIBTsToShares again before shares are minted.

By reentering, duplicate PT and YT minting would occur while fees only paid once. This breaks share supply invariants.

Root cause - Shares minting occurs after potential reentrancy trigger in updateYield.

User extracts extra protocol value by inflating share supply via reentrancy. Breaks key PT/YT supply equality invariant.

Proof of Concept

This reentrancy vulnerability enables attackers to artificially inflate the Principal Token and Yield Token supply. By reentering before shares are minted, an attacker can double mint tokens for only a single deposit amount. This breaks the key token supply ratio invariants in the protocol.

Attackers can exploit this to extract additional value from the protocol by minting free shares that they can later redeem or withdraw against.

  1. Attacker deploys a malicious contract implementing IYieldToken

  2. Attacker calls _depositIBT with 100 IBT deposit

  3. On updateYield call, malicious contract reenters _depositIBT

  4. In reentered call, _ibts balance still reflects original 100 deposit

  5. Tokenization fee only deducted once across two calls

  6. _convertIBTsToShares uses inflated _ibts balance to double mint shares

  7. Attacker burns 100 extra PT + YT they shouldn't have been able to mint

Performing the token share conversion and minting after updateYield. This enables reentering at updateYield and inflating the _ibts balance used in conversion before shares are minted in the first call.

By reentering, duplicated PT and YT minting occurs based on the original, pre-fee _ibts amount. This mints additional token supply the depositor shouldn't have access to.

Tools Used

Vs

Fix

  1. Move _convertIBTsToShares and token minting before the updateYield call. This prevents inflating the _ibts amount via reentrancy.

  2. Use a reentrancy guard on updateYield. This prevents reentering back into _depositIBT at all.

Recommended Mitigation Steps

Assessed type

Reentrancy

c4-pre-sort commented 8 months ago

gzeon-c4 marked the issue as insufficient quality report

gzeon-c4 commented 8 months ago

yt is trusted

c4-judge commented 8 months ago

JustDravee marked the issue as unsatisfactory: Invalid