code4rena-2023-09-ondo-m02

[M-02] All bridged funds will be lost for the users using the account abstraction wallet

보고서

Summary

계정 추상화 지갑을 사용하는 유저는 여러 체인에 걸쳐 다른 주소의 지갑을 가진다. 따라서 계정 추상화 지갑을 사용하는 유저가 잘못된 주소로 자산을 브릿징할 수 있으며, 이로 인해 영구적인 손실을 입을 수 있다.

Keyword

account abstraction, erc4337, business logic vul, asset lock, bridge

Vulnerability

출발지 체인에서 브릿징을 요청할 때 burnAndCallAxelar 함수를 호출한다. 이 때, 목적지 체인에서 토큰을 수령할 주소는 bytes memory payload = abi.encode(VERSION, msg.sender, amount, nonce++); 에서 msg.sender로 설정된다.

  function burnAndCallAxelar(
    uint256 amount,
    string calldata destinationChain
  ) external payable whenNotPaused {
    ...
 
@>  bytes memory payload = abi.encode(VERSION, msg.sender, amount, nonce++);
 
    _payGasAndCallContract(destinationChain, destContract, payload);
  }

목적지 체인 측에서는 이 주소로 브릿징된 토큰을 민팅해준다.

  function _execute(
    string calldata srcChain,
    string calldata srcAddr,
    bytes calldata payload
  ) internal override whenNotPaused {
  
@>  (bytes32 version, address srcSender, uint256 amt, uint256 nonce) = abi
      .decode(payload, (bytes32, address, uint256, uint256));
 
    ...
 
    // same payload would have the same txhash
    bytes32 txnHash = keccak256(payload);
@>  txnHashToTransaction[txnHash] = Transaction(srcSender, amt);
    _attachThreshold(amt, txnHash, srcChain);
    _approve(txnHash);
@>  _mintIfThresholdMet(txnHash);
    emit MessageReceived(srcChain, srcSender, amt, nonce);
  }
 
  function _mintIfThresholdMet(bytes32 txnHash) internal {
    bool thresholdMet = _checkThresholdMet(txnHash);
@>  Transaction memory txn = txnHashToTransaction[txnHash];
    if (thresholdMet) {
      _checkAndUpdateInstantMintLimit(txn.amount);
      if (!ALLOWLIST.isAllowed(txn.sender)) {
        ALLOWLIST.setAccountStatus(
          txn.sender,
          ALLOWLIST.getValidTermIndexes()[0],
          true
        );
      }
@>    TOKEN.mint(txn.sender, txn.amount);
      delete txnHashToTransaction[txnHash];
      emit BridgeCompleted(txn.sender, txn.amount);
    }
  }

계정 추상화 지갑을 사용하는 유저는 여러 체인에 걸쳐 다른 주소의 지갑을 가진다. 즉, 출발지 체인에서의 계정 추상화 지갑의 주소가 목적지 체인에서 동일인의 계정이 아닐 수 있다. 따라서 msg.sender 를 이용하여 브릿징한다면 잘못된 주소로 자산을 브릿징할 수 있으며, 이로 인해 유저가 영구적인 손실을 입을 수 있다.

일부 지갑은 동일한 주소를 할당하기 위해 결정론적으로 배포하기도 하지만, 각 체인마다 상태와 연산 코드가 다르기 때문에 결정론적으로 생성하더라도 다른 주소가 생성될 수 있으므로 여전히 문제가 존재한다.

Impact

계정 추상화 지갑을 사용하는 유저가 잘못된 주소로 자산을 브릿징하여 토큰을 잃는다.

Mitigation

유저가 목적지 체인에서 토큰을 수령할 주소를 전달할 수 있는 방법을 제공한다. 계정 추상화 지갑 소유자가 동일한 주소를 이용하지 않도록 경고를 한다.


tags: bughunting, ondo finance, smart contract, solidity, account abstraction, erc4337, bridge, asset lock, business-logic-vul, wallet, severity medium