DssBlow: Making Surplus Buffer Repayments Easy

Hello everyone! I’m happy to introduce DssBlow, a new helper smart contract that makes it easy for Core Units to repay excess Dai to the MakerDAO Surplus Buffer, aka the Vow. This is the opposite of suck-ing Dai from the Vow, hence the meme blow.


The motivation behind creating this contract was the recent need for GovAlpha to pay back excess Dai to the Maker Surplus Buffer. This is not trivial, as you cannot simply send ERC20 Dai to the Vow contract address. Rather, you need to use the Dai Join adapter, to deposit Dai into the Maker Protocol, and send “internal” Dai to the Vow.

This process is error prone for non technical users, which is why I have built DssBlow.


With DssBlow you can simply send ERC20 Dai directly to the DssBlow contract address. Once the Dai has been received by DssBlow, anyone can call blow() to send all deposited Dai in DssBlow as internal Dai to the Surplus Buffer. The blow() function handles the internal logic of depositing Dai into the Maker Protocol and sending internal Dai to the Vow, using the Dai Join adapter.


If a Core Unit has excess Dai they wish to repay to the surplus buffer, they simply send a standard ERC20 Dai transaction to the address of DssBlow:

This should make repayments easy, even when using a Multisig wallet.

Once the Dai has been transferred to DssBlow, anyone can call blow (on Etherscan it’s 1. blow), to finalize the transfer of internal Dai to the Vow.


  • Mainnet

    • 0x0048FC4357DB3c0f45AdEA433a07A20769dDB0CF
    • Etherscan
  • Goerli

    • 0x5Db4D1Be83EE0DaC45E0cc2e5565a19d9c428dAF
    • Etherscan



The code has not been audited, but the code is very simple, and has been tested and reviewed internally.


So in general I think this is super great, but I have some comments on verification with respect to the contract source.

I don’t love the parameterized constructor convention…


…because it means that you can’t verify that the daiJoin and vow addresses are correct purely by looking at the verified source. When PE write executives these are either defined as constant variables, or they are pulled from the chainlog contract (which requires governance permissions to edit, and is therefore more trustworthy.)

Basically, without digging through the deploy(?) transaction, I can’t verify that this is safe to use.

Second point is more minor, but I don’t love the overloading of blow to do two similar but distinct operations. Generally, the convention is that the same function name with and without a numeric parameter means that the unparameterized version makes some assumption about the numeric parameter (ie blow everything.)

Basically, my expectation would be:

  1. blow - Joins everything in the contract into the buffer.
  2. blow(int) - Joins int DAI from the contract into the buffer.


  1. blow(int) - Joins int from my wallet into the buffer.
  2. blow - Joins all the DAI in my wallet into the buffer.

I’m aware that 2 and 4 aren’t great pieces of functionality though, so maybe that’s fine in this case? I think I would prefer to see these with different function names, though, to make it more intuitively obviously that they are different functionality.

Caveat: Not a solidity dev :slight_smile:


All the contract addresses are immutable, and can be verified here: https://etherscan.io/address/0x0048fc4357db3c0f45adea433a07a20769ddb0cf#readContract

The pattern of assigning the addresses in the constructor is widely used in Maker already and is the same as e.g. dss-flash

I understand your second point, however I don’t see blow(wad) being used much, and I was thinking if I should even leave it in, as it is very similar to the old fashioned way of using DaiJoin where you need to specify the amount in wad, and grant approval first. That’s also why I didn’t mention it in the usage section - it’s more of a power function, but I decided to leave it in for flexibility :slight_smile:


Makerburn has been updated to register DAI transfers to DssBlow (0x0048fc4357db3c0f45adea433a07a20769ddb0cf) in addition to transfers to the pause proxy (0xbe8e3e3618f7474f8cb1d074a26affef007e98fb) as repayments.


This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.