MT
77 posts


We love a leaderboard. The @SizeCredit results are in! 🪐 Your top 3 ranked researchers are: 🥇 mt030d : $4,599.78 🥇 @0x_serial_coder : $4,599.78 🥈 @flack00n : $4,428.26 🥉 @0xEkkoo: $171.52 Thank you to everyone that participated! Full leaderboard below.




It’s the post everyone’s waiting for: the results of @eulerfinance’s competition on Cantina 🪐 Top 3: 🥇 @00xSEV: $28,026 🥈 Aussie Battlers ( @1_00_proof, highbit): $25,862 🥉 @mt030d: $22,669 To all that participated in this historic competition, thank you! Leaderboard below.

🏁 The results of the Vultisig competitive audit are in! Congratulations to everyone who submitted valid findings, especially to @juancito for their largest earnings yet! Big appreciation to @Vultisig for their commitment to the best security outcomes Full winner list 👇


Summary/lessons from @spearbitdao report on @eulerfinance EVK: - Hs - 5.1.1 Never assume decimals are 18 - 5.1.2 - You can increase attack impact by borrowing in a loop - When LTV borrow == LTV liquidation, it is dangerous. It can sandwich Oracle and self-liquidate, possibly leading to bad debt for the protocol - Socializing is a dangerous concept; it might be better to use government profits to repay bad debt - Sometimes liquidation can worsen health, leading to bad debt if a liquidator divides liquidations into several small parts. More in the "Counterproductive Incentives" issue described by OpenZeppelin in their 2019 Compound audit blog.openzeppelin.com/compound-audit - Fixes: - Add a spread between borrow LTV and liquidation LTV - Set limits on the discounts that a liquidator can get on collateral - Implement a cool-off period (e.g., a delay of X seconds before liquidation is allowed), increasing the attacker's risk by preventing same-block liquidations using flash loans - Ms - 5.2.1 It's possible to reset a virtual (not saved to storage) variable. For example, if accrued interest for 1 year is not saved and governance changes the interest rate to 0, all the interest for 1 year is lost. - Also, check what happens when interest starts to overflow. In this case, it was ignored (expected behavior due to unused vault/misconfiguration) - 5.2.2 The value is reset to 0 before the new value is received from an external source. If the external source fails to provide a value, we use the last value. But in this case, the last value is already updated to 0. - 5.2.3 Inconsistent behavior between different vault implementations. Not following a standard (ERC4626 in this case). - 5.2.4 Assumed decimals are 18 (as in 5.1.1) - 5.2.5 Forgot to subtract already minted shares from the max mintable - 5.2.6 Same as 5.2.3 - 5.2.7 Overflow still happens after Solidity 0.8, but now it causes unexpected reverts - Ls - 5.3.1 Unintuitive behavior: decimals are considered 18 when the IERC20.decimals function reverts - 5.3.2 The vault's governor must call 2 functions in a certain order; otherwise, it temporarily locks the vault - 5.3.3 Unintuitive behavior: limit not always enforced - 5.3.4 `from` and `to` in transfer are allowed to be 0, leading to inconsistencies in accounting - 5.3.5 Unintuitive behavior: limit not always enforced - 5.3.6 Unintuitive behavior: limit not always enforced - 5.3.7 Vault's governor's mistakes are not validated - 5.3.8 The vault's governor can change IERC20's `name` and `symbol` - 5.3.9 Flash loan borrower may return more than required - 5.3.10 Unintuitive behavior: the vault's governor can change a value that intuitively must be immutable - 5.3.11 Using virtual amounts change math: virtual shares earn interest that will be locked (dust) - 5.3.12 Missing validation: in rare cases, the vault's owner may use a newer implementation than expected (all implementations are considered trusted) - 5.3.13 Missing validation: the oracle can return 0, which should not be the case for IRMSynth - 5.3.14 Inconsistent speed of rewards; an attacker can slightly slow down rewards - 5.3.15 Vault's governor's mistakes are not validated - 5.3.16 Inconsistent behavior for 0 price (revert vs ok) in different implementations - 5.3.17 Unintuitive behavior: `from` == address(0) => special case - 5.3.18 Virtual amounts change math: fee receiver receives slightly less than expected in some cases - 5.3.19 Special case for 0 values: 0 mint does not check the minter but emits a `Mint` event - 5.3.20 Protocol's owner misconfiguration is possible only in theory: 2 instances of ~singleton - 5.3.21 Off-by-one in validation - 5.3.22, 5.3.23 Rounding in favor of the user, not the protocol - 5.3.24 Single-step ownership transfer github.com/euler-xyz/eule… I'm starting to summarize what I learned during the @eulerfinance contest on @cantinaxyz. There are going to be several posts like this in the following days. If you found this summary helpful, please consider following me on Twitter for more insights and updates. Thanks!


















