TokenManager
calls approve
function on CapitalPool
with wrong arguments, leading to a freeze of funds/broken logic.
In CapitalPool
, there is a function approve
that should only be callable by TokenManager
, according to the @notice
comment. Currently, it is callable by anyone. There are two possible outcomes: first, if this gets fixed and only TokenManager
can call approve
, and second, if it is not fixed and anyone can call approve
on CapitalPool
.
TokenManager
calls this function in the _transfer
function, specifically when _from
is CapitalPool
and the allowance of _token
has not yet been set.
As we can see, the argument for approve is set to address(this), which means that CapitalPool
will attempt to call TokenManager
instead of _token. Since TokenManager
does not have a function with a selector matching APPROVE_SELECTOR
, this will result in a failure, preventing the use of _transfer until the allowance is set.
As mentioned earlier, the current code allows anyone to call the approve function in CapitalPool
with any input. This means it is possible to set the allowance for TokenManager
, temporarily freezing the funds. However, if the code is fixed, it will no longer be possible to fix _transfer from outside, rendering both TokenManager
and CapitalPool
unusable.
There are two possible scenarios:
The approve
function of CapitalPool
is fixed (accordingly to how it's documented to behave) so that only the TokenManager
can call it. In this case, the _transfer
functionality becomes broken and unusable, without fix from outside. Since the TokenManager
relies heavily on _transfer
, this affects the integrity of the entire system.
The approve
function of CapitalPool
is not fixed, allowing anyone to call it externally. This would allow the _transfer
functionality to be fixed, so it results in a temporary freeze of funds.
Manual Review.
Fix call to CapitalPool
in TokenManager
.
This is the expected behavior of the _transfer
function, and the fix applies to both cases: whether approve
is fixed or left unchanged.
If we consider the correct permissioned implementation for the `approve()` function within `CapitalPool.sol`, this would be a critical severity issue, because the withdrawal of funds will be permanently blocked and must be rescued by the admin via the `Rescuable.sol` contract, given it will always revert [here](https://github.com/Cyfrin/2024-08-tadle/blob/04fd8634701697184a3f3a5558b41c109866e5f8/src/core/CapitalPool.sol#L36-L38) when attempting to call a non-existent function selector `approve` within the TokenManager contract. The argument up in the air is since the approval function `approve` was made permisionless, the `if` block within the internal `_transfer()` function will never be invoked if somebody beforehand calls approval for the TokenManager for the required token, so the transfer will infact not revert when a withdrawal is invoked. I will leave open for escalation discussions, but based on my first point, I believe high severity is appropriate.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.