Skip to content

Use of depreciated OZ Function isContract(), can be bypassed #96

@c4-bot-10

Description

@c4-bot-10

Lines of code

https://github.com/code-423n4/2024-03-taiko/blob/f58384f44dbf4c6535264a472322322705133b11/packages/protocol/contracts/bridge/Bridge.sol#L493

Vulnerability details

Impact

Bypass Logic to Verify if Caller is a Contract (Deprecated by OZ)

Proof of Concept

The processMessage() calls the _invokeMessageCall() function to invoke the message call which in turn checks if the to value is a contract or not and if it is, then it assigns false value to success_ parameter (L495).

However, OZ's official docs state that isContract function can return false for an address where a contract lived but, but was destroyed and also, the function has been deprecated. In which case the following condition:

     if (
            _message.data.length >= 4 // msg can be empty
                && bytes4(_message.data) != IMessageInvocable.onMessageInvocation.selector
                && _message.to.isContract()
        ) {
            success_ = false;
        } else {
            --snip--
        }

will resolve as false and the funds will get transferred regardless.

Tools Used

Manual audit (VS Code)

Recommended Mitigation Steps

Make a function that verifies their EOA status with 2 calls that must be on 2 different blocks.

Assessed type

call/delegatecall

Metadata

Metadata

Assignees

No one assigned

    Labels

    2 (Med Risk)Assets not at direct risk, but function/availability of the protocol could be impacted or leak valuebugSomething isn't workingedited-by-wardeninsufficient quality reportThis report is not of sufficient qualityunsatisfactorydoes not satisfy C4 submission criteria; not eligible for awards

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions