Medium Risk
https://github.com/Cyfrin/2023-12-the-standard/blob/main/contracts/LiquidationPool.sol#L35
The smart contract code lacks interface validation in the constructor, specifically during the assignment of the tokenManager
variable. This oversight may result in the assignment of an address of a contract that doesn't have the required functionality(the function signatures declared in the ITokenManager
interface) as the tokenManager
, potentially compromising the execution and behavior of the entire contract.
In the provided code, the constructor assigns an address to the tokenManager
without verifying whether it adheres to the specified interface (ITokenManager
). The problem is that when deploying the LiquidationPool
contract, the deployer can provide a contract address for the tokenManager
that doesn't have the implemented functionality that is required in the interface ITokenManager
. If this happens, the code will result in a compilation error.
The impact of this vulnerability is significant, as it opens the possibility of interacting with a tokenManager
that does not conform to the expected interface. This can lead to unexpected behaviour.
Mannual Review
Interface Validation: Implement a check in the constructor to ensure that the assigned tokenManager
contract adheres to the specified ITokenManager interface. This can be achieved by calling the supportsInterface
function or using a similar method to verify compatibility.
Here is how you can implement interface validation in the constructor:
constructor(address _TST, address _EUROs, address _eurUsd, address _tokenManager) {
TST = _TST;
EUROs = _EUROs;
eurUsd = _eurUsd;
+ require(
+ supportsInterface(_tokenManager, type(ITokenManager).interfaceId),
+ "Token manager does not support ITokenManager interface"
+ );
tokenManager = _tokenManager;
manager = payable(msg.sender);
}
+ // Check if a contract supports a specific interface
+ function supportsInterface(address _contract, bytes4 _interfaceId) internal view returns (bool) {
+ (bool success, bytes memory result) = _contract.staticcall(abi.encodeWithSelector(0x01ffc9a7, _interfaceId));
+ return success && (result.length > 0);
+ }