Tadle

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

[H-2] Lack of access controls and input validation in `CapitalPool::approve` allows arbitrary calls on behalf of CapitalPool

Summary

The CapitalPool is the address that holds the funds of the protocol. Its CapitalPool::approve function lacks both access controls and input validation, allowing any user to make arbitrary low-level calls on behalf of the CapitalPool to any address. This critical vulnerability enables malicious actors to exploit the CapitalPool contract, including draining its funds.

Vulnerability Details

The CapitalPool contract includes an approve function intended to allow the TokenManager contract to approve token transfers on behalf of the CapitalPool. However, the function does not include access controls to restrict who can call it, nor does it validate the input to ensure that only legitimate token addresses are used.

Issues:

  1. Lack of Access Controls: The function can be called by anyone, not just the TokenManager. This opens the door for unauthorized users to make arbitrary calls.

  2. Lack of Input Validation: The function accepts any tokenAddress as input, allowing users to specify any address, including malicious contracts.

Exploit Scenario:

  1. An attacker could deploy a malicious contract with a function named approve that does something harmful, such as draining funds.

  2. The attacker calls the CapitalPool::approve function, passing the address of the malicious contract as the tokenAddress.

  3. The CapitalPool contract then calls the malicious contract’s approve function, enabling the attacker to execute arbitrary code on behalf of the CapitalPool, potentially draining its funds or causing other malicious actions.

Impact

This vulnerability allows any user to execute arbitrary low-level calls on behalf of the CapitalPool, giving them unrestricted access to the contract’s funds and capabilities. An attacker could drain the entire balance of the CapitalPool or perform other unauthorized actions, leading to a complete compromise of the contract’s security.

Tools Used

Manual code review.

Recommendations

To fix this vulnerability, implement access controls to restrict who can call the approve function and add input validation to ensure only legitimate token addresses are used:

  1. Create a onlyTokenManager modifier as there isn't one currently.

  2. Create a onlyExistingTokens modifier and an existingTokens mapping to support it, as the current tokenWhiteListed mapping does not work to fetch a list of all tokens that have been added.

  3. Add the modifiers to the approve function:

+ function approve(address tokenAddr) external onlyTokenManager, onlyExistingTokens(tokenAddr) {
- function approve(address tokenAddr) external {
address tokenManager = tadleFactory.relatedContracts(
RelatedContractLibraries.TOKEN_MANAGER
);
(bool success, ) = tokenAddr.call(
abi.encodeWithSelector(
APPROVE_SELECTOR,
tokenManager,
type(uint256).max
)
);
if (!success) {
revert ApproveFailed();
}
}
Updates

Lead Judging Commences

0xnevi Lead Judge about 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.