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