Skip to content

Instantly share code, notes, and snippets.

@stonegao
Forked from z0r0z/FlashPot.sol
Created December 27, 2021 04:33
Show Gist options
  • Save stonegao/745db351b8e01768c2f505ebf860d250 to your computer and use it in GitHub Desktop.
Save stonegao/745db351b8e01768c2f505ebf860d250 to your computer and use it in GitHub Desktop.
flash-lendable ETH wrapper with elastic shares
// 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