Wednesday, March 27, 2024

186: DOS in Web3

 Denial of Service (DOS) attacks render web3 protocols unusable and unable to provide value to their users. Many of these attacks derive from the gas requirement users pay to interact with a blockchain. In certain scenarios an attacker can burden a protocol to the point where the code needs to do a tremendous account of calculations and the gas cost becomes prohibitive to honest users. Often these vulnerabilities come from unbounded loops in Solidity code, where there is no upper limit to the amount of times the loop must iterate and repeat. For example, the Bridges exchange dividend system was vulnerable to a Denial of Service attack because an attacker could create an arbitrary amount of users to extend a loop indefinitely long. The protocol had no minimum amount required to mint a pair token, so the attacker could mint a single wei of pair tokens and bog the users list down for a negligible price. The Bridges fixed this by changing their dividend logic: each unit of owned supply was entitled to a certain amount of dividend that the user could withdraw at one time based on the amount of pair tokens they held. This way, the withdrawal is computed at the time of the transaction and no loop is required. 

Another example of of a Denial of Service attack was found in an audit of the GMX code. In GMX, a leveraged position will be liquidated if the collateral value goes too low, and any excess collateral is sent back to the address. In this case, an attacker could create a contract without either a receive() or fallback() function that is unable to receive ether, and use the contract to create their leveraged position. In the event of liquidation, GMX would attempt to send the leftover ETH collateral the address, but the transfer will fail and cause an unintended revert. The attacker has now created a position that is unable to be liquidated, exploiting the system and threatening the solvency of the protocol. GMX fixed this by sending wrapped ERC20 ether as a backup in case the native transfer failed, solving the denial of service exploit on their liquidation function. 


When auditing code we can ask the following questions to identify DOS vulnerability:

1) Is a loop iterating a boundless number of iterations? Can a user add iterations to the loop? How much does it cost the user to add more iterations to the loop? 

2) Look for any external calls such as sending Ether to a contract. Is there a way for that call to fail? Is it possible for the external call to run out of gas? If it does, will it cause the top level transaction to fail? And how will that effect the overall system? 

No comments:

Post a Comment

190: Sablier

 The CodeHawks platform has an upcoming audit on the Sablier protocol, so I decided to read through the docs and familiarize myself with the...