| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- //SPDX-License-Identifier: Unlicense
- pragma solidity ^0.7.6;
- pragma abicoder v2;
- import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
- import '@uniswap/v3-core/contracts/interfaces/pool/IUniswapV3PoolActions.sol';
- import '@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol';
- import '@uniswap/v3-core/contracts/libraries/TickMath.sol';
- import './base/TransferHelper.sol';
- import './base/Address.sol';
- contract Flash is IUniswapV3SwapCallback {
- mapping(address => bool) private adminMap;
- mapping(address => bool) private poolMap;
- mapping(address => mapping(address => uint256)) private approveMap;
- address private owner;
- constructor() {
- owner = msg.sender;
- adminMap[owner] = true;
- adminMap[address(this)] = true;
- }
- modifier onlyOwner() {
- require(msg.sender == owner || msg.sender == address(this), 'Not is owner.');
- _;
- }
- modifier onlyMaster() {
- require(msg.sender == owner || msg.sender == address(this) || adminMap[msg.sender], 'Not is master.');
- _;
- }
- modifier onlyPool() {
- require(msg.sender == owner || msg.sender == address(this) || poolMap[msg.sender], 'Not is pool.');
- _;
- }
- function addAdmin(address _addr) public onlyOwner {
- adminMap[_addr] = true;
- }
- function approve(uint256 _volume, address _token, address _to) public onlyOwner {
- TransferHelper.safeApprove(_token, _to, _volume);
- approveMap[_to][_token] = _volume;
- }
- function withdraw(address _token) public onlyOwner {
- uint256 token_balance = IERC20(_token).balanceOf(address(this));
- TransferHelper.safeTransfer(_token, owner, token_balance);
- }
- struct FlashLoanParams {
- address pool;
- bool inToken0;
- int256 inAmount;
- uint160 sqrtPriceLimitX96;
- address inToken;
- }
- function flashLoan(FlashLoanParams memory params) public onlyOwner returns (int256 amount0, int256 amount1) {
- IUniswapV3PoolActions pool = IUniswapV3PoolActions(params.pool);
- bytes memory callBackData = abi.encodeWithSelector(
- bytes4(keccak256(bytes("transfer(address,address,uint256)"))),
- params.inToken, params.pool, params.inAmount
- );
- poolMap[params.pool] = true;
- return pool.swap(
- address(this),
- params.inToken0,
- params.inAmount,
- params.sqrtPriceLimitX96 == 0
- ? (params.inToken0 ? TickMath.MIN_SQRT_RATIO + 1 : TickMath.MAX_SQRT_RATIO - 1)
- : params.sqrtPriceLimitX96,
- callBackData
- );
- }
- function uniswapV3SwapCallback(
- int256 amount0Delta,
- int256 amount1Delta,
- bytes calldata data
- ) override public onlyPool {
- Address.functionCall(address(this), data);
- }
- function transfer(address token, address to, uint256 amount) public onlyOwner {
- TransferHelper.safeTransfer(token, to, amount);
- }
- }
|