Tadle

Tadle
DeFiFoundry
27,750 USDC
View results
Submission Details
Severity: low
Valid

`CapitalPool::approve` Vulnerable to Non-Whitelisted Token Approvals

Summary

The CapitalPool::approve function lacks a check to ensure that only whitelisted tokens can be approved, potentially allowing approvals for non-ERC20 or malicious tokens.

Vulnerability Details

The approve function does not verify if the token being approved is whitelisted in the TokenManager. This oversight could lead to approvals of unauthorized or potentially malicious tokens.

function approve(address tokenAddr) external {
// Missing whitelist check
(bool success, ) = tokenAddr.call(
abi.encodeWithSelector(
APPROVE_SELECTOR,
tokenManager,
type(uint256).max
)
);
// ... rest of the function
}

Impact

  1. Potential approval of non-whitelisted or malicious tokens.

  2. Risk of interacting with non-standard token contracts.

  3. Inconsistency with the protocol's token whitelist policy.

Tools Used

Foundry

Recommendations

  1. Add a getter function to view whitelisted tokens in TokenManager and implement it in ITokenManager:

// inside `TokenManager`
+ function isWhitelisted(address token) external view returns (bool) {
+ return tokenWhiteListed[token];
+ }
// Inside `ITokenManager`
+ function isWhitelisted(address token) external view returns (bool);
  1. Import ITokenManager & Implement a whitelist check in the CapitalPool::approve function:

+ import {ITokenManager} from "../interfaces/ITokenManager.sol";
+ error NotWhitelisted();
function approve(address tokenAddr) external {
address tokenManager = tadleFactory.relatedContracts(
RelatedContractLibraries.TOKEN_MANAGER
);
+ if(!ITokenManager(tokenManager).isWhitelisted(tokenAddr)) {
+ revert NotWhitelisted();
+ }
// ... rest of the function
}
  1. Consider using the IERC20 interface for the approve call instead of a low-level call:

+ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
- (bool success, ) = tokenAddr.call(
- abi.encodeWithSelector(
- APPROVE_SELECTOR,
- tokenManager,
- type(uint256).max
- )
- );
+ bool success = IERC20(tokenAddr).approve(tokenManager, type(uint256).max);
if (!success) {
revert ApproveFailed();
}
Updates

Lead Judging Commences

0xnevi Lead Judge over 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

finding-CapitalPool-approve-missing-access-control

This is at most low severity, even though giving max approvals shouldn't be permisionless, the respective tokenManager address is retrieved from the TadleFactory contract whereby the trusted guardian role is responsible for deploying such contracts as seen [here](https://github.com/Cyfrin/2024-08-tadle/blob/04fd8634701697184a3f3a5558b41c109866e5f8/src/factory/TadleFactory.sol#L68). Since the user still has to go through the PreMarkets/DeliveryPlace contracts to perform market actions, this max approval cannot be exploited.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!