codehawks-2023-08-sparkn-l11
[L-11] Insufficient validation leads to locking up prize tokens forever
Summary
implementation에 실제로 컨트랙트가 배포되었는지 확인하지 않는다. 잘못된 implementation으로 로직 컨트랙트를 설정하면 예치된 토큰을 꺼낼 수 없을 것이다.
Keyword
lack of input validation, asset lock
Vulnerability
setContest로 컨테스트를 등록할 때, implementation 파라미터를 검증하지 않는다. 단지 address(0)가 아닌지만 확인하며, 실제로 컨트랙트의 로직이 배포되어 있는지는 확인하지 않는다.
function setContest(address organizer, bytes32 contestId, uint256 closeTime, address implementation)
public
onlyOwner
{
if (organizer == address(0) || implementation == address(0)) revert ProxyFactory__NoZeroAddress();
if (closeTime > block.timestamp + MAX_CONTEST_PERIOD || closeTime < block.timestamp) {
revert ProxyFactory__CloseTimeNotInRange();
}
bytes32 salt = _calculateSalt(organizer, contestId, implementation);
if (saltToCloseTime[salt] != 0) revert ProxyFactory__ContestIsAlreadyRegistered();
saltToCloseTime[salt] = closeTime;
emit SetContest(organizer, contestId, closeTime, implementation);
}구현 컨트랙트가 address(1) 등 실수로 잘못된 주소로 설정하면 추후 토큰을 꺼낼 수 없을 것이다.
Impact
잘못된 implementation으로 로직 컨트랙트를 설정하여 예치된 토큰을 꺼낼 수 없게 된다.
Mitigation
setContest에서 설정 시 implementation 주소에 컨트랙트가 배포되었는지 확인한다.
+ import {Address} from "openzeppelin/utils/Address.sol";
...
function setContest(address organizer, bytes32 contestId, uint256 closeTime, address implementation)
public
onlyOwner
{
if (organizer == address(0) || implementation == address(0)) revert ProxyFactory__NoZeroAddress();
+ if (!Address.isContract(implementation)) revert ProxyFactory__NoImplementationContract();
if (closeTime > block.timestamp + MAX_CONTEST_PERIOD || closeTime < block.timestamp) {
revert ProxyFactory__CloseTimeNotInRange();
}
bytes32 salt = _calculateSalt(organizer, contestId, implementation);
if (saltToCloseTime[salt] != 0) revert ProxyFactory__ContestIsAlreadyRegistered();
saltToCloseTime[salt] = closeTime;
emit SetContest(organizer, contestId, closeTime, implementation);
}tags: bughunting, sparkn, smart contract, solidity, lack-of-input-validation-vul, asset lock, severity low