MIP25: Flash Mint Module

MIP25: Flash Mint Module


MIP#: 25
Title: Flash Mint Module
Author(s): Sam MacPherson (@hexonaut)
Contributors: Chris Mooney (@godsflaw), Brian McMichael (@brianmcmichael), Gonzalo Balabasquer (@gbalabasquer)
Type: Technical
Status: Formal Submission
Date Proposed: 2020-09-25
Date Ratified: <yyyy-mm-dd>
Dependencies: n/a
Replaces: n/a
License: AGPL3+


Sentence Summary

This proposal provides a smart contract implementation of Flash, a module which enables any user to execute a flash mint of Dai.

Paragraph Summary

Flash mints allow anyone to mint as much Dai as they need with the one condition that they pay it all back in the same transaction with a fee. This allows anyone to exploit arbitrage opportunities in the DeFi space without having to commit upfront capital. This implementation conforms to the description laid out in the MIP13c3-SP2.

Component Summary

MIP25c1: Definitions: defines Debt Ceiling (line) and Minting Fees (toll).

MIP25c2: Proposed code: contains snippet of proposed implementation.

MIP25c3: Test cases: lists existing test cases, including integration test

MIP25c4: Security considerations: comments on the limited nature of the security implications of adding the Flash.

MIP25c5: Formal verification/audit information: comments on the amenability of the proposed code to formal verification, even though formal specification, audit, or code review have yet to be conducted.

MIP25c6: Licensing: states the license under which the proposal and code are distributed.


Flash can provide many benefits to the Dai ecosystem including, but not limited to:

  • Improved market efficiencies for Dai.
  • Democratization of arbitrage - anyone can participate.
  • Exploits requiring a large amount of capital will be found quicker which makes the DeFi space safer overall.
  • Fees provide an income source for the protocol.


MIP25c1: Definitions

  • Debt Ceiling: The maximum amount of Dai any single transaction can borrow. Encoded as line in rad units.
  • Minting Fees: How much additional Dai must be returned to the Flash module at the end of the transaction. This fee is transferred into the vow at the end of a successful mint. Encoded as toll in wad units.

MIP25c2: Proposed code

see flash.sol. The core minting functionality is simple:

function mint(
    address _receiver,      // address of conformant IFlashMintReceiver
    uint256 _amount,        // amount to flash mint [wad]
    bytes calldata _data    // arbitrary data to pass to the _receiver
) external lock {
    uint256 arad = rad(_amount);

    require(arad > 0, "DssFlash/amount-zero");
    require(arad <= line, "DssFlash/ceiling-exceeded");

    vat.suck(address(this), _receiver, arad);

    uint256 fee = mul(_amount, toll) / WAD;
    uint256 bal = vat.dai(address(this));

    IFlashMintReceiver(_receiver).execute(_amount, fee, _data);

    uint256 frad = rad(fee);
    require(vat.dai(address(this)) == add(bal, add(arad, frad)), "DssFlash/invalid-payback");

    vat.move(address(this), vow, frad);
    emit Mint(_receiver, _amount, fee);

The IFlashMintReceiver interface:

interface IFlashMintReceiver {

    * Must transfer _amount + _fee back to the flash mint contract when complete.
    function execute(uint256 _amount, uint256 _fee, bytes calldata _params) external;


MIP25c3: Test cases

see flash.t.sol

  • test_dex_trade
  • test_mint_with_fee
  • testFail_mint_zero_amount
  • testFail_mint_amount_over_line
  • testFail_mint_insufficient_dai
  • testFail_mint_too_much_dai
  • testFail_mint_line_zero
  • testFail_mint_unauthorized_suck
  • testFail_mint_reentrancy
  • test_mint_data
  • test_mint_no_fee_payback
  • test_preexisting_dai_in_flash

MIP25c4: Security considerations

The proposed solution is simple and non-invasive, interacting with only one other component of the system (the Vat) through an existing method for suck. A lock modifier has been added to mint to prevent any possible re-entrancy bugs.

MIP25c5: Formal verification/audit information

The proposed contract is written in a way which is amenable to formal specification and verification, in accordance with the style and practices of the core multi-collateral DAI contracts, though it has not been formally specified. No audit or code review has taken place yet.

MIP25c6: Licensing


Hey @hexonaut, this looks great! A couple comments:

Once these are completed, I can happily move this proposal to the Request for Comments (RFC) status.


Updated the MIP number and PR submitted: https://github.com/makerdao/mips/pull/107


Do we have an idea on what the fee for Dai flash mints should be/is?

1 Like

Awesome in long term, scary in short term.
I expect many exploits to happen now and many projects rekt.
Flash loans are the nuclear fusion of DeFi.


Iā€™m curious to understand how payback of the newly minted DAI is enforced. If full payback is not achieved then does the entire transaction just fail atomically?

This is achieved by this line:

require(vat.dai(address(this)) == add(bal, add(arad, frad)), "DssFlash/invalid-payback");


Hi, could I suggest a different name for the callback function?

IFlashMintReceiver(_receiver).onFlashMint(_amount, fee, _data);

execute is very generic, and could clash with other functionality in the receiver or in some other interface the receiver also implements.

I would suggest using onFlashMint, which is both descriptive, and follows the naming set up by other callbacks such as onTokenTransfer from EIP667.

Even more, Iā€™m developing flash minting for WETH10, and would be happy to use the same interface and work towards a flash minting ERC standard, if we agree on something that can be used by everyone.


This is a great point. Could you open an issue in the repository?

Edit: Nevermind, I opened a PR here. Thanks for the recommendation @albertocuestacanada.


It looks like EIP-3156 just got merged yesterday. Congrats @albertocuestacanada and @hexonaut!

Weā€™ll definitely want to make a pass back through this and ensure itā€™s standards-conformant. This has MIP been pushed back until sometime after the new year, so weā€™ve got a little breathing room to review and update.