-
-
Save spalladino/e0b867402b6c22447c54f32a399c885f to your computer and use it in GitHub Desktop.
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; | |
} | |
} |
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 😄
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.
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..
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.
a zero-gas-price tx
This bit probably needs to be adjusted to post-1559
Broken by onewayfunction here