sherlock-audit / 2024-02-tapioca-judging

3 stars 2 forks source link

GiuseppeDeLaZara - TOFT can be forcefully unwrapped resulting in long-term DoS #133

Closed sherlock-admin4 closed 4 months ago

sherlock-admin4 commented 4 months ago

GiuseppeDeLaZara

high

TOFT can be forcefully unwrapped resulting in long-term DoS

Summary

TOFTGenericModule::receiveWithParamsReceiver function can be abused to wipe out anyone's allowance of the TOFT token. At the same time, it unwraps the TOFT. As a result, the allowance mechanism is broken and there is no point in wrapping your tokens in an OFT as a griever can immediately unwrap them.

Vulnerability Detail

TOFTGenericModule::receiveWithParamsReceiver function can be used to wipe out the allowance of the TOFT token by anyone and unwrap TOFT tokens.

Let's imagine the following scenario:

## TOFTGenericReceiverModule.sol

TOFTGenericReceiverModule.receiveWithParamsReceiver(
    srcChainSender = Bob,
    data = abi.encode(SendParamsMsg(
        receiver = Alice,
        unwrap =  true,
        amount = 100
    ))
)

A griever has forcefully wiped out the allowance of Bob and unwrapped Alice's OFT.

This makes a critical vulnerability as it means there is no point in wrapping your tokens in an OFT as a griever can immediately unwrap them. Also, the allowance mechanism is broken as it can be wiped out by anyone.

Any system that accepts OFTs as collateral or otherwise won't work as no one can wrap their tokens in an OFT as they can be unwrapped immediately by anyone.

As giving allowances to external systems to use your TOFT tokens is a typical flow the likelihood of this occurring all the time is high.

Impact

The impact of this vulnerability is critical. It allows anyone to wipe out the allowance of any user and unwrap their OFT tokens. This makes the allowance mechanism broken and as the TOFT token is a wrapper token, it makes it useless as a griever can immediately unwrap them.

Code Snippet

Tool used

Manual Review

Recommendation

The whole receiveWithParamsReceiver function should be reviewed and refactored. It is not clear what the expected behavior is.

There should be a different flow if used as part of the cross-chain flow as opposed to being callable on the same chain.

If used on the same chain, the msg.sender should only be able to transfer the OFT tokens if the owner has given him sufficient allowance. Check the typical transferFrom implementation:

    function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {
        address spender = msg.sender;
        _spendAllowance(from, spender, amount);
        _transfer(from, to, amount);
        return true;
    }

If used in the cross-chain context, you can rely on the srcChainSender as the owner of the TOFT tokens, and he can unwrap them to an arbitrary receiver address.

Duplicate of #134

sherlock-admin3 commented 4 months ago

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

takarez commented:

seem valid; high(4)