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!
convertFacet() is used. When passing in token addresses for the stablecoin pool, there was no validation that the well address is valid.convert() takes in three parameters: convertData structure, an array of ints called stems and an array of int called amounts. When providing a list of stems and amounts, there is no validation that these are NOT zero length. I imagine that a loop contained some validations but didn't consider this case.convertData has a type of WELL_LP_TO_BEANS, it contains a well address. When using this, the well address not was verified to be an allowlisted value. This allows for an expected and trusted contract to be spoofed with arbitrary values._wellRemoveLiquidityTowardsPeg is made. This has a call to removeLiquidityOneToken on the well, which can return extremely small values. So, the convert function is made with a BEAN deposit without withdrawing any real tokens. Eventually, these can be claimed by an attacker through a different function call.