sherlock-2023-08-cooler-m01
[M-01] emergency_shutdown role is not enough for emergency shutdown
Summary
emergencyShutdown()의 내부에서 호출되는 함수에는 또다른 권한이 필요하므로 emergency_shutdown 권한만 가진 관리자로는 긴급 중지를 할 수 없다.
Keyword
access control, modifier
Vulnerability
프로토콜에서 관리자 역할로는 emergency_shutdown, cooler_overseer 두 가지가 있다. emergency_shutdown 에게는 Clearinghouse 를 중지할 수 있는 emergencyShutdown()를 호출할 권한이 있다.
하지만 이 권한만으로는 부족하다. emergencyShutdown() 에서는 defund()를 호출하는데, defund()를 호출하기 위해서는 cooler_overseer 권한이 필요하다.
@> function emergencyShutdown() external onlyRole("emergency_shutdown") {
active = false;
// If necessary, defund sDAI.
uint256 sdaiBalance = sdai.balanceOf(address(this));
@> if (sdaiBalance != 0) defund(sdai, sdaiBalance);
// If necessary, defund DAI.
uint256 daiBalance = dai.balanceOf(address(this));
@> if (daiBalance != 0) defund(dai, daiBalance);
emit Deactivated();
}
@> function defund(ERC20 token_, uint256 amount_) public onlyRole("cooler_overseer") {
...
}프로토콜 팀에게 질문하여 두 역할은 서로 다른 두 개의 멀티시그에 의해 유지될 것이며, emergency_shutdown 멀티시그는 임계값(threshold)이 낮고 보유자가 더 많다는 것을 확인했다. 따라서 거버넌스는 의도했던 것보다 긴급 상황에 신속하게 대처할 수 없을 것이다.
Impact
emergency_shutdown 역할만으로는 프로토콜을 긴급 중지할 수 없다.
Mitigation
긴급 종료 시 defund를 호출하지 않고 중단 후 별도로 호출하게 변경한다. 또는 defund 함수를 internal 함수로 분리하여 이용한다.
tags: bughunting, olympus dao, smart contract, solidity, lending protocol, access control vulnerability, severity medium