This is not a walkthrough of every contract or code of the challenge. I am sharing my notes and resources I have used to complete this challenge, as well as some lessons I think are useful to take away after completing the challenge. I highly recommend you finish the challenge yourself first and only use this as additional content.
Since we start with 10_000 USDC I tried to figure out a way to manipulate the calculation
uint256 r = (balance() * _shares) / (totalSupply())inwithdrawby transferring some USDC directly, but could not find a way.depositseems like it is susceptible to first deposit attack / inflation attack since it just mints shares whentotalSupply() == 0and does not mint them toaddress(0)like Uniswap doesWe can’t use this however since in the test file somebody already deposited 10_000 USDC in the vault
depositFortakes in an arbitrary token address as an input parameterAllowing a user to specify which token to use with
IERC20(token)is never a good idea, because there is always a possibility for an attacker to create their own token and use it in a malicious way.As soon as a user can specify which external function a contract will execute, it can be used in a malicious way
We can create a new contract where we call
depositForand inputtokenas that contract where we have created a customtransferFromfunctionIn
transferFromwe will transfer USDC toSafuVaultand calldepositForagain to reenter the contract
Checkout my comments on
depositForfunction inSafuVaultfor a better understanding of how funds increase with every reenter - hereAlso I highly suggest upping the verbosity when executing the test file to see all function calls
If there are more than one way to deposit / withdraw funds make sure all of them do it in the same way, and make sure that way is not exploitable
Compare opposite functions like deposit and withdraw - do they do the inverse of each other ?

