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

1 stars 1 forks source link

Missing an option to wrap Singularity tokens in `mintBBLendSGLLockTOLP` function to be able to lock into OLP #182

Closed c4-bot-5 closed 6 months ago

c4-bot-5 commented 6 months ago

Lines of code

https://github.com/Tapioca-DAO/tapioca-periph/blob/032396f701be935b04a7e5cf3cb40a0136259dbc/contracts/Magnetar/modules/MagnetarMintModule.sol#L69-L84

Vulnerability details

Description

The mintBBLendSGLLockTOLP function of the MagnetarAssetModule attempts to lend to Singularity and then lock the received Singularity liquidity tokens into the TapiocaOptionLiquidityProvision contract.

uint256 fraction = _depositYBLendSGL(
    data.depositData, data.externalContracts.singularity, yieldBox_, data.user, data.lendAmount
);

// if `lockData.lock`:
//      - transfer `fraction` from data.user to `address(this)
//      - deposits `fraction` to YB for `address(this)`
//      - performs tOLP.lock
uint256 tOLPTokenId = _lockOnTOB(
    data.lockData,
    yieldBox_,
    fraction,
    data.participateData.participate,
    data.user,
    data.externalContracts.singularity
);

The TapiocaOptionLiquidityProvision.lock() function attempts to acquire YieldBox's shares of the original Singularity tokens. _lockOnTOB will retrieve the received Singularity tokens from the user to deposit into YieldBox before locking into TapiocaOptionLiquidityProvision.

function _lockOnTOB(
    IOptionsLockData memory lockData,
    IYieldBox yieldBox_,
    uint256 fraction,
    bool participate,
    address user,
    address singularityAddress
) internal returns (uint256 tOLPTokenId) {
    tOLPTokenId = 0;
    if (lockData.lock) {
        if (!cluster.isWhitelisted(0, lockData.target)) {
            revert Magnetar_TargetNotWhitelisted(lockData.target);
        }
        if (lockData.fraction > 0) fraction = lockData.fraction;

        // retrieve and deposit SGLAssetId registered in tOLP
        (uint256 tOLPSglAssetId,,) =
            ITapiocaOptionLiquidityProvision(lockData.target).activeSingularities(singularityAddress);
        if (fraction == 0) revert Magnetar_ActionParamsMismatch();

        //deposit to YieldBox
        _extractTokens(user, singularityAddress, fraction);
        yieldBox_.depositAsset(tOLPSglAssetId, address(this), address(this), fraction, 0);

        _setApprovalForYieldBox(lockData.target, yieldBox_);
        tOLPTokenId = ITapiocaOptionLiquidityProvision(lockData.target).lock(
            participate ? address(this) : user, singularityAddress, lockData.lockDuration, lockData.amount
        );
        _revertYieldBoxApproval(lockData.target, yieldBox_);
    }
}

However, on some specific chains, YieldBox uses the tOFT-wrapped version of Singularity liquidity tokens for SingularityAssetId. This means that after lending into SGL, the user needs to wrap the received Singularity tokens into the tOFT version of Singularity, then deposit them into YieldBox to obtain shares of SingularityAssetId. This information was provided by the sponsor, indicating that YieldBox uses the tOFT version of SGL tokens on chains except Arbitrum.

Therefore, in that case, the mintBBLendSGLLockTOLP() function needs to have an option to wrap Singularity tokens before executing _lockOnTOB.

Impact

The mintBBLendSGLLockTOLP() function of Magnetar will be broken on some chains due to the difference in handling Singularity tokens.

Tools Used

Manual review

Recommended Mitigation Steps

mintBBLendSGLLockTOLP() function should have an option to wrap Singularity tokens before executing _lockOnTOB

Assessed type

Context

c4-sponsor commented 6 months ago

cryptotechmaker marked the issue as disagree with severity

cryptotechmaker commented 6 months ago

There might be no case for that

c4-judge commented 6 months ago

dmvt marked the issue as duplicate of #140

c4-judge commented 6 months ago

dmvt marked the issue as satisfactory