Resources

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!

Deposit Proxy Contract Post Mortem- 1148

DyDxPosted 2 Years Ago
  • DyDx is a trading platform perpetuals, leveraged trading and general trades that runs on Ethereum.
  • DyDx had a smart contract for currency conversion that worked by trading all assets to USDC then to the DyDx exchange in a single transaction. The goal was to make this doable in 0x API calls.
  • Initially, this was achieved by calling taking in user provided input for an exchange address and the call data. This is shown below:
    (bool success, bytes memory returndata) = exchange.call(data); 
    require(success, string(returndata)); 
    
  • Being able to contract the location of the call and the parameters from within the contract feels bad. However, the design of this was okay because of the design. There are three contracts: the currency converter proxy, the exchange wrapper and the exchange.
  • A user would call approve() for an asset on the currency converter proxy. Then, the funds would be exchanged to the wrapper and eventually the exchange. This call() with the arbitrary data was being made from within the wrapper after some input had already been provided. Since the wrapper didn't have the approvals, there were not funds at risk.
  • The problem comes up with a redesign of the system. Instead of having three contracts for the one call, they made only TWO. Now, the currency converter proxy was the contract with the arbitrary call() within the code. Since this contract had the approvals, this was bad.
  • A malicious user could provide an arbitrary ERC-20 token and arbitrary calldata. Since the contract was approved by users, a malicious user could steal anybody's funds! How did this get through? The code had 100% coverage. It seems the reason this slipped through the cracks was a lack of importance on a small contract and a last minute change for performance reasons.
  • Overall, interesting yet simple vulnerability. The finder of this bug received 500K and all of the funds were whitehat hacked by DyDx.