Does require always reverts all state and balances? Plus Flash Loan contract

Hi guys, I wanted to ask you if this code looks safe to you?
Any possibilities to be penetrated?

pragma solidity ^0.5.0;

interface IExec {
  function run(uint) external;
}

contract Proxy {

    function run(address payable addr,uint amount) public {
      uint prevBalance=address(this).balance;

      (bool success, ) = addr.call.value(amount)("");
      require(success);
    
      IExec(addr).run(amount+amount/1000);
    
      require(address(this).balance==prevBalance.add(amount/1000));
    }
    
    function() external payable {}
}
1 Like

Hi @4ntrek0t,

Welcome to the community :wave:

Is it your code?

I'm a community manager and not an auditor so don't have the skills and training to give a lot of feedback on issues with this code. Any solution should be appropriately tested and audited.

Assuming it is your code, if you haven't already, you should document what this contract is meant to do and create extensive tests. (see: Follow this quality checklist before an audit). If it isn't your code, then I wouldn't use it without reading the documentation, seeing appropriate testing and reading the audit reports.

I would check if the contract has issues with reentrancy: Reentrancy After Istanbul

The contract fails for amounts smaller than 1kwei.

I didn't immediately pickup what the code was trying to do. It took me a bit of time to realize that this is meant to be a form of Flash Loan with a fee.

I suggest looking at the slides/video on the Flash Loan pattern (if you haven't already) and the implementation by @Austin-Williams. :warning: Don't use these contracts in production. They have not yet been audited.


As for your first question:

Does require always reverts all state and balances

Please see the Solidity documentation for details on this:
https://solidity.readthedocs.io/en/v0.5.15/control-structures.html#assert-and-require

Solidity uses state-reverting exceptions to handle errors. Such an exception undoes all changes made to the state in the current call (and all its sub-calls) and flags an error to the caller.

When exceptions happen in a sub-call, they “bubble up” (i.e., exceptions are rethrown) automatically. Exceptions to this rule are send and the low-level functions call , delegatecall and staticcall , they return false as their first return value in case of an exception instead of “bubbling up”.