sherlock-audit / 2024-02-tapioca-judging

3 stars 2 forks source link

GiuseppeDeLaZara - `TOFTMarketReceiverModule::marketBorrowReceiver` flow is broken #137

Open sherlock-admin2 opened 4 months ago

sherlock-admin2 commented 4 months ago

GiuseppeDeLaZara

high

TOFTMarketReceiverModule::marketBorrowReceiver flow is broken

Summary

The TOFTMarketReceiverModule::marketBorrowReceiver flow is broken and will revert when the Magnetar contract tries to transfer the ERC1155 tokens to the Market contract.

Vulnerability Detail

TOFTMarketReceiverModule::marketBorrowReceiver flow is broken.

Let's examine it more closely:

    function _extractTokens(address _from, address _token, uint256 _amount) internal returns (uint256) {
        uint256 balanceBefore = IERC20(_token).balanceOf(address(this));
        // IERC20(_token).safeTransferFrom(_from, address(this), _amount);
        pearlmit.transferFromERC20(_from, address(this), address(_token), _amount);
        uint256 balanceAfter = IERC20(_token).balanceOf(address(this));
        if (balanceAfter <= balanceBefore) revert Magnetar_ExtractTokenFail();
        return balanceAfter - balanceBefore;
    }

Other occurrences

  1. TOFT::mintLendXChainSGLXChainLockAndParticipateReceiver has a similar issue as:

    • Extract the bbCollateral from the user, sets approval for the BigBang contract through YieldBox.
    • But then inside the BBCollateral::addCollateral the _addTokens again expects an allowance through the Pearlmit contract.
  2. TOFT::lockAndParticipateReceiver calls the Magnetar:lockAndParticipate where:


## MagnetarMintCommonModule.sol

function _lockOnTOB(
        IOptionsLockData memory lockData,
        IYieldBox yieldBox_,
        uint256 fraction,
        bool participate,
        address user,
        address singularityAddress
    ) internal returns (uint256 tOLPTokenId) {
    ....
        _setApprovalForYieldBox(lockData.target, yieldBox_);
        tOLPTokenId = ITapiocaOptionLiquidityProvision(lockData.target).lock(
             participate ? address(this) : user, singularityAddress, lockData.lockDuration, lockData.amount
        );
}

## TapiocaOptionLiquidityProvision.sol

function lock(address _to, IERC20 _singularity, uint128 _lockDuration, uint128 _ybShares)
    external
    nonReentrant
    returns (uint256 tokenId)
{
    // Transfer the Singularity position to this contract
    // yieldBox.transfer(msg.sender, address(this), sglAssetID, _ybShares);
    {
        bool isErr =
            pearlmit.transferFromERC1155(msg.sender, address(this), address(yieldBox), sglAssetID, _ybShares);
        if (isErr) {
            revert TransferFailed();
        }
    }

Impact

The TOFTMarketReceiverModule::marketBorrowReceiver flow is broken and will revert when the Magnetar contract tries to transfer the ERC1155 tokens to the Market contract. There are also other instances of similar issues.

Code Snippet

Tool used

Manual Review

Recommendation

Review all the allowance mechanisms and ensure that they are correct.

sherlock-admin3 commented 4 months ago

1 comment(s) were left on this issue during the judging contest.

takarez commented:

the cause of the revert wasn't mentioned

sherlock-admin4 commented 3 months ago

The protocol team fixed this issue in PR/commit https://github.com/Tapioca-DAO/tapioca-periph/commit/0a03bbbd04b30bcac183f1bae24d7f9fe9fd4103#diff-4a6decd451580f83dfe716ed16851529590c8349b1ba9bff97b42248c75e5430.