code-423n4 / 2023-07-tapioca-findings

12 stars 9 forks source link

The internal function _debitFrom can be called #1082

Closed code423n4 closed 1 year ago

code423n4 commented 1 year ago

Lines of code

https://github.com/Tapioca-DAO/tapioca-bar-audit/blob/2286f80f928f41c8bc189d0657d74ba83286c668/contracts/usd0/modules/USDOMarketModule.sol#L60

Vulnerability details

Impact

The attacker can use the USDOMarketModule.sendAndLendOrRepay function to call _debitFrom, which can be used to cheat victims.

Proof of Concept

_debitFrom is an internal function, but can be by USDOMarketModule.sendAndLendOrRepay or other functions to call, sendAndLendOrRepay first calls _debitFrom and then _lzSend. _lzSend can pass any lzDstChainId and address parameters, regardless of the result of _lzSend. It only needs to make sure that the transaction is not rolling back, this is equivalent to calling the internal function _debitFromdirectly.

function sendAndLendOrRepay(
        address _from,
        address _to,
        uint16 lzDstChainId,
        address zroPaymentAddress,
        IUSDOBase.ILendOrRepayParams calldata lendParams,
        ICommonData.IApproval[] calldata approvals,
        ICommonData.IWithdrawParams calldata withdrawParams,
        bytes calldata adapterParams
    ) external payable {
        bytes32 toAddress = LzLib.addressToBytes32(_to);
        _debitFrom(
            _from,
            lzEndpoint.getChainId(),
            toAddress,
            lendParams.depositAmount
        );

        bytes memory lzPayload = abi.encode(
            PT_YB_SEND_SGL_LEND_OR_REPAY,
            _from,
            _to,
            lendParams,
            approvals,
            withdrawParams
        );

        _lzSend(
            lzDstChainId,
            lzPayload,
            payable(_from),
            zroPaymentAddress,
            adapterParams,
            msg.value
        );

        emit SendToChain(
            lzDstChainId,
            _from,
            toAddress,
            lendParams.depositAmount
        );
    }
    function _debitFrom(address _from, uint16, bytes32, uint _amount) internal virtual override returns (uint) {
        address spender = _msgSender();
        if (_from != spender) _spendAllowance(_from, spender, _amount);
        _burn(_from, _amount);
        return _amount;
    }

Tools Used

vscode

Recommended Mitigation Steps

hash checks incoming and outgoing parameters during cross-chain calls to add a feedback mechanism for _lzSend.

Assessed type

Other

c4-pre-sort commented 1 year ago

minhquanym marked the issue as low quality report

minhquanym commented 1 year ago

Insufficient proof

c4-judge commented 1 year ago

dmvt marked the issue as unsatisfactory: Insufficient proof