-
-
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