-
-
Save stonegao/745db351b8e01768c2f505ebf860d250 to your computer and use it in GitHub Desktop.
flash-lendable ETH wrapper with elastic shares
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: GPL-3.0-or-later | |
pragma solidity >=0.8.4; | |
import "https://github.com/Rari-Capital/solmate/blob/audit-fixes/src/tokens/WETH.sol"; | |
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/interfaces/IERC3156FlashBorrower.sol"; | |
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/interfaces/IERC3156FlashLender.sol"; | |
contract FlashPot is WETH, IERC3156FlashLender { | |
using SafeTransferLib for address; | |
/*/////////////////////////////////////////////////////////////// | |
FLASH STORAGE | |
//////////////////////////////////////////////////////////////*/ | |
bytes32 public constant CALLBACK_SUCCESS = keccak256("ERC3156FlashBorrower.onFlashLoan"); | |
uint256 public constant fee = 1000; // 1 == 0.0001 %. | |
/*/////////////////////////////////////////////////////////////// | |
FLASH OPERATIONS | |
//////////////////////////////////////////////////////////////*/ | |
function flashLoan( | |
IERC3156FlashBorrower receiver, | |
address, | |
uint256 amount, | |
bytes calldata data | |
) public override returns (bool success) { | |
uint256 flee = flashFee(address(0), amount); | |
uint256 startingBalance = address(this).balance; | |
address(receiver).safeTransferETH(amount); | |
require( | |
receiver.onFlashLoan(msg.sender, address(0), amount, flee, data) == CALLBACK_SUCCESS, | |
"FlashLender: Callback failed" | |
); | |
require(address(this).balance == startingBalance + flee, "FlashLender: Repay failed"); | |
success = true; | |
} | |
function flashFee( | |
address, | |
uint256 amount | |
) public pure override returns (uint256 flee) { | |
flee = amount * fee / 10000; | |
} | |
function maxFlashLoan(address) public view override returns (uint256 max) { | |
max = address(this).balance; | |
} | |
/*/////////////////////////////////////////////////////////////// | |
WRAP OPERATIONS | |
//////////////////////////////////////////////////////////////*/ | |
function deposit() public payable override { | |
uint256 totalShares = totalSupply; | |
uint256 totalETH = address(this).balance; | |
if (totalShares == 0 || totalETH == 0) { | |
_mint(msg.sender, msg.value); | |
} else { | |
uint256 what = (msg.value * totalShares) / totalETH; | |
_mint(msg.sender, what); | |
} | |
emit Deposit(msg.sender, msg.value); | |
} | |
function withdraw(uint256 share) public override { | |
uint256 totalShares = totalSupply; | |
uint256 what = (share * address(this).balance) / totalShares; | |
_burn(msg.sender, share); | |
msg.sender.safeTransferETH(what); | |
emit Withdrawal(msg.sender, share); | |
} | |
receive() external payable override { | |
deposit(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment