codehawks-2023-08-sparkn-l03

[L-03] Lack of checking the existence of the Proxy contract

보고서

Summary

로우레벨 call은 해당 주소에 컨트랙트가 배포되지 않았다면 revert 되지 않고, true를 리턴한다. 따라서 로우레벨 call을 하기 전 해당 주소에 컨트랙트가 배포되었는지 확인해야 한다.

Keyword

low level call

Vulnerability

리워드를 분배하거나 실수로 넣은 토큰을 꺼내는 데 사용되는 _distribute 함수에서 proxy.call(data)로 로우레벨 call을 한다. 로우레벨 call은 해당 주소에 컨트랙트가 배포되지 않은 경우 true를 리턴한다. 따라서 실제로는 실패했더라도 성공한 것처럼 이벤트를 생성하고, revert 되지 않는다.

    function _distribute(address proxy, bytes calldata data) internal {
@>      (bool success,) = proxy.call(data);
        if (!success) revert ProxyFactory__DelegateCallFailed();
@>      emit Distributed(proxy, data);
    }

Impact

로우레벨 call이 실패했음에도 revert 되지 않는다.

Mitigation

로우레벨 call을 하기 전에 해당 주소에 컨트랙트가 배포되었는지 확인한다.

+   import {Address} from "openzeppelin/utils/Address.sol";
 
    ...
 
    function _distribute(address proxy, bytes calldata data) internal {
+       if (!Address.isContract(proxy)) revert ProxyFactory__NoProxyContract();
        (bool success,) = proxy.call(data);
        if (!success) revert ProxyFactory__DelegateCallFailed();
        emit Distributed(proxy, data);
    }

tags: bughunting, sparkn, smart contract, solidity, solidity low-level call, severity low