Within the TokenManager contract, there is "no" implementation of the receive()
or fallback()
function to receive the native ETH-sent.
This lead the TokenManager contract to failing to receive the native ETH-sent from the WETH contract - when the IWrappedNativeToken(wrappedNativeToken)#withdraw()
is called via the TokenManager#withdraw()
.
This result in that a deposited-collateral of the caller (msg.sender
) of the TokenManager#withdraw()
is stuck forever inside the TokenManager contract.
When a user would like to withdraw their deposited-collateral (native ETH) from the CapitalPool contract, the user would call the TokenManager#withdraw()
.
Within the TokenManager#withdraw()
, the following three steps would be proceeded:
1/ WETH (wrappedNativeToken
) would be transferred from the CapitalPool contract (capitalPoolAddr
) to the TokenManager contract (address(this)
).
2/ Then, the claimAbleAmount
of the native ETH would be withdrawn from the WETH contract (IWrappedNativeToken(wrappedNativeToken)
) to the TokenManager contract (address(this)
).
3/ Finally, the claimAbleAmount
of the native ETH-withdrawn would be transferred from the TokenManager contract (address(this)
) to the user (msg.sender
).
https://github.com/Cyfrin/2024-08-tadle/blob/main/src/core/TokenManager.sol#L160-L166
https://github.com/Cyfrin/2024-08-tadle/blob/main/src/core/TokenManager.sol#L168
https://github.com/Cyfrin/2024-08-tadle/blob/main/src/core/TokenManager.sol#L169
When the step 2/ above, the claimAbleAmount
of the native ETH would be transferred from the WETH contract to the TokenManager contract via the IWrappedNativeToken(wrappedNativeToken).withdraw(claimAbleAmount)
like this:
https://github.com/Cyfrin/2024-08-tadle/blob/main/src/core/TokenManager.sol#L168
According to the Solidity's documentation, the receive()
or fallback()
function must be implemented for a smart contract to receive the native ETH-sent.
However, within the TokenManager contract, there is "no" implementation of the receive()
or fallback()
function to receive the native ETH-sent.
This lead the TokenManager contract to failing to receive (the claimAbleAmount
of) the native ETH-sent from the WETH contract - when the IWrappedNativeToken(wrappedNativeToken)#withdraw()
is called via the TokenManager#withdraw()
.
(NOTE:At this point, the TX of the TokenManager#withdraw()
will be reverted)
This lead a deposited-collateral of the caller (msg.sender
) of the TokenManager#withdraw()
to being stuck forever inside the TokenManager contract.
Foundry
Within the TokenManager contract, consider implementing the receive()
or fallback()
- so that the TokenManager contract can receive the native ETH-sent from the WETH contract when the IWrappedNativeToken(wrappedNativeToken)#withdraw()
is called via the TokenManager#withdraw()
.
Invalid, TokenManager is the implementation contract of 9the transparent upgradeable proxy, as can seen by the comments [here](https://github.com/Cyfrin/2024-08-tadle/blob/04fd8634701697184a3f3a5558b41c109866e5f8/src/proxy/UpgradeableProxy.sol#L15). The receive payable is implemented as seen [here](https://github.com/Cyfrin/2024-08-tadle/blob/04fd8634701697184a3f3a5558b41c109866e5f8/src/proxy/UpgradeableProxy.sol#L37)
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.