Skip to content

Instantly share code, notes, and snippets.

@spalladino
Created March 20, 2021 16:57
Show Gist options
  • Star 23 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save spalladino/e0b867402b6c22447c54f32a399c885f to your computer and use it in GitHub Desktop.
Save spalladino/e0b867402b6c22447c54f32a399c885f to your computer and use it in GitHub Desktop.
Strawman for flashloans for flashbots
pragma solidity ^0.7.0;
// Each mining pool that intends to provide flash loans deploys a Loaner contract and transfers ETH to it
// When testing each bundle, the diff in balance in this contract is taking into account for calculating effective gas price
// The contract loans funds only on blocks mined by the miner and on zero-gasprice txs
contract Loaner {
address immutable owner;
constructor(address _owner) {
owner = _owner;
}
function loan(address payable to, uint256 amount) public returns (uint256) {
require(tx.gasprice == 0 && block.coinbase == owner);
to.transfer(amount);
return amount;
}
function withdraw(address payable to) public {
require(msg.sender == owner);
to.transfer(address(this).balance);
}
}
// Users interact with the router, which redirects to the corresponding loaner based on the miner that picked up the bundle
contract Router {
mapping(address => Loaner) registry;
function getBalance() public view returns(uint256) {
Loaner loaner = registry[block.coinbase];
if (address(loaner) == address(0)) return 0;
return address(loaner).balance;
}
function loan(address payable to, uint256 amount) public returns(uint256) {
Loaner loaner = registry[block.coinbase];
if (address(loaner) == address(0)) return 0;
return loaner.loan(to, amount);
}
function register(Loaner loaner) public {
registry[msg.sender] = loaner;
}
}
@spalladino
Copy link
Author

Broken by onewayfunction here

@dmarzzz
Copy link

dmarzzz commented Nov 20, 2022

hey @spalladino that link is broken, any way u could recap it or point to another resource on this? I've recently started thinking about this problem and would be massively appreciative 😄

@spalladino
Copy link
Author

The coinbase account (ie block.coinbase) can be set to any value by the miner, they don't need to own it. So if the amount of ETH stored in a loaner is greater than the block reward, any miner has an incentive to steal it.

@dmarzzz
Copy link

dmarzzz commented Nov 21, 2022

but in the case of PoS + mev-boost, the builder has full control of the coinbase so shouldn't be an issue. I guess theres large uncle risk there though..

@spalladino
Copy link
Author

the builder has full control of the coinbase

I'm not sure that's the case, but even if it were, there's still risk: the validator that's proposing the current block could set the block.coinbase of the block they're producing to be the address of a loaner, and include a zero-gas-price tx that siphons out all those funds, since it passes the tx.gasprice == 0 && block.coinbase == owner check.

@spalladino
Copy link
Author

a zero-gas-price tx

This bit probably needs to be adjusted to post-1559

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment