codehawks-2023-08-sparkn-m02

[M-02] Blacklisted STADIUM_ADDRESS address cause fund stuck in the contract forever

보고서

Summary

immutable로 설정되는 수수료 전달 주소가 토큰의 블락리스트에 오르면 리워드 정산이 불가하다. 토큰이 컨트랙트에 묶인다.

Keyword

blocklisting token, erc20, asset lock, dos

Vulnerability

USDC와 같이 토큰 자체에 블락리스트가 존재하는 토큰이라면 토큰 전송에 주의해야 한다.

Distributor._distribute 함수는 리워드 정산을 담당한다. 유저들에게 정산을 마친 후 상금의 5%는 수수료로 지불한다. 수수료를 받는 주소는 STADIUM_ADDRESS라는 immutable 변수에 저장된다.

// Findings are labeled with '<= FOUND'
// File: src/Distributor.sol
116:    function _distribute(address token, address[] memory winners, uint256[] memory percentages, bytes memory data)
117:        ...
154:        _commissionTransfer(erc20);// <= FOUND
155:        ...
156:    }
				...
163:    function _commissionTransfer(IERC20 token) internal {
164:        token.safeTransfer(STADIUM_ADDRESS, token.balanceOf(address(this)));// <= FOUND: Blacklisted STADIUM_ADDRESS address cause fund stuck in the contract forever
165:    }

만약 STADIUM_ADDRESS가 USDC 블락리스트에 오른다면 수수료를 전송할 때 트랜잭션이 revert 된다. 컨트랙트 내의 토큰을 이동하는 함수는 _distribute 뿐이고, STADIUM_ADDRESS는 변경할 수 없으므로 토큰이 컨트랙트에 영원히 묶여있게 된다.

Impact

리워드로 예치된 토큰을 컨트랙트에서 꺼낼 수 없다.

Mitigation

어드민이 STADIUM_ADDRESS를 변경할 수 있도록 수정한다.


tags: bughunting, sparkn, smart contract, solidity, blocklisting token, erc20, dos, asset lock, severity medium