People often ask me "How did you learn how to hack?" The answer: by reading. This page is a collection of the blog posts and other articles that I have accumulated over the years of my journey. Enjoy!
uint256 _fromBalance = _balances[_id][_from]; uint256 _toBalance = _balances[_id][_to]; _balances[_id][_from] = _fromBalance - _amount; _balances[_id][_to] = _toBalance + _amount;
to being the same as from. Walking through the values if they are the same with the starting balance being 10 and the amount being 10:
mint() to provide liquidity and get an LP token in return. Additionally, it can call burn() to return the LP token to get their underlying assets as well as call collectFees to get the fees they are owed._beforeTokenTransfer is called to update the user debts. The hook only updates the cache fees via _cachefees() if the address is not 0 and the address does not equal the address of the pool. This was done since the contract is never expected to own the LP tokens._cacheFees is never triggered! This means that the time we got in (debt) does NOT get added to the calculations. When calling mint, the recipient of the token can be chosen. Because of further bad bookkeeping, the funds can be taken out as well. mint with the recipient being the contract itself. collectFees() with pair address as the account. It will send itself the fees. Now, the token believes that the user sent it money, even though the contract paid itself! This is because of it keeps an internal balance and comparing that to the actual balance of it. This difference convinces the protocol that we indeed set money to it!swap to collect all of the fees.unchecked block that allows for the fees calculation to go rouge. This allows the attacker to steal the entire reserves, instead of the total fees accrued only. I absolutely love this bug! Super crazy attack which starts by sending your money away.