Browse Source

对接完成,数量不对

skyfffire 3 năm trước cách đây
mục cha
commit
0105e31347
8 tập tin đã thay đổi với 161 bổ sung106 xóa
  1. 0 0
      abi/IERC20_ABI.json
  2. 1 1
      config/contracts.ts
  3. 45 4
      contracts/Flash.sol
  4. 19 0
      scripts/deploy.ts
  5. 0 18
      scripts/deployCalc.ts
  6. 0 2
      test/BaseOperationTest.ts
  7. 33 0
      test/FlashTest.ts
  8. 63 81
      test/Univ3Test.ts

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
abi/IERC20_ABI.json


+ 1 - 1
config/contracts.ts

@@ -7,5 +7,5 @@ export default {
   QUOTER: '0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6',
   ZERO: '0x0000000000000000000000000000000000000000',
   CALC: '0x30c34b111121aCDb423eF2C0e39235Dc68a793A4',
-  FLASH: ''
+  FLASH: '0x1f05Ac6791e10E6667FED65B903d2b1DA7c30281'
 }

+ 45 - 4
contracts/Flash.sol

@@ -4,11 +4,14 @@ 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 {
+contract Flash is IUniswapV3SwapCallback {
     mapping(address => bool) private adminMap;
+    mapping(address => bool) private poolMap;
     mapping(address => mapping(address => uint256)) private approveMap;
     address private owner;
 
@@ -25,7 +28,12 @@ contract Flash {
     }
 
     modifier onlyMaster() {
-        require(adminMap[msg.sender], 'Not is master.');
+        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.');
         _;
     }
 
@@ -45,9 +53,42 @@ contract Flash {
 
     struct FlashLoanParams {
         address pool;
+        bool inToken0;
+        int256 outAmount;
+        uint256 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.outAmount,
+            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 flashLoan(FlashLoanParams memory params) external pure returns (uint256 num){
-        return 0;
+    function transfer(address token, address to, uint256 amount) public onlyOwner {
+        TransferHelper.safeTransfer(token, to, amount);
     }
 }

+ 19 - 0
scripts/deploy.ts

@@ -0,0 +1,19 @@
+import { ethers } from "hardhat";
+
+async function main() {
+  const contractName = 'Flash'
+
+  const Contract = await ethers.getContractFactory(contractName);
+  console.log('deploying...')
+  const contract = await Contract.deploy();
+  console.log(`${ contractName } deployed, confirm...`)
+  await contract.deployed();
+  console.log(`${ contractName } deployed to ${contract.address}`);
+}
+
+// We recommend this pattern to be able to use async/await everywhere
+// and properly handle errors.
+main().catch((error) => {
+  console.error(error);
+  process.exitCode = 1;
+});

+ 0 - 18
scripts/deployCalc.ts

@@ -1,18 +0,0 @@
-import { ethers } from "hardhat";
-
-async function main() {
-  const Calc = await ethers.getContractFactory("Calc");
-  const calc = await Calc.deploy();
-
-  console.log('deploying...')
-  await calc.deployed();
-
-  console.log(`Calc deployed to ${calc.address}`);
-}
-
-// We recommend this pattern to be able to use async/await everywhere
-// and properly handle errors.
-main().catch((error) => {
-  console.error(error);
-  process.exitCode = 1;
-});

+ 0 - 2
test/BaseOperationTest.ts

@@ -1,8 +1,6 @@
 import { web3 } from "hardhat"
-import { ethers } from "hardhat"
 import deployer from '../.secret'
 import contracts from '../config/contracts'
-import fee from '../config/fee'
 
 describe('Base operation test', () => {
   it('Parse ether test', async () => {

+ 33 - 0
test/FlashTest.ts

@@ -0,0 +1,33 @@
+import {ethers, web3} from "hardhat";
+import contracts from "../config/contracts";
+import deployer from "../.secret";
+import fee from "../config/fee";
+
+describe('Flash test', () => {
+  let inAmount = 1e15.toString()
+
+  it('Flash swap test', async () => {
+    const FLASH_ABI = require('../artifacts/contracts/Flash.sol/Flash.json').abi
+
+    let flash = new web3.eth.Contract(FLASH_ABI, contracts.FLASH)
+
+    let rawTx = {
+      from: deployer.address,
+      nonce: await web3.eth.getTransactionCount(deployer.address),
+      gasPrice: web3.utils.toWei('2', 'gwei'),
+      gasLimit: 1e6
+    }
+
+    const WETH_USDT_POOL_CONTRACT = '0x4e68Ccd3E89f51C3074ca5072bbAC773960dFa36'
+    await flash.methods
+      .flashLoan({
+        pool: WETH_USDT_POOL_CONTRACT,
+        inToken0: true,
+        outAmount: 1,
+        inAmount: 1e10,
+        sqrtPriceLimitX96: 0,
+        inToken: contracts.WETH
+      })
+      .send(rawTx).then(console.log)
+  })
+})

+ 63 - 81
test/Univ3Test.ts

@@ -4,85 +4,67 @@ import deployer from "../.secret";
 import fee from "../config/fee";
 
 describe('Uniswap v3 test', () => {
-    let inAmount = 1e15.toString()
-
-    it('Univ3 swap test', async () => {
-        const UNIV3_ABI = require('../abi/UNIV3_ROUTER_ABI.json')
-
-        let univ3_contract = new web3.eth.Contract(UNIV3_ABI, contracts.UNIV3)
-
-        let rawTx = {
-            from: deployer.address,
-            nonce: await web3.eth.getTransactionCount(deployer.address),
-            gasPrice: web3.utils.toWei('2', 'gwei'),
-            gasLimit: 1_000_000
-        }
-
-        let amountIn = inAmount
-        let amountOutMin = 1
-        let path = [contracts.WETH, contracts.HEX]
-        let to = deployer.address
-
-        await univ3_contract.methods
-            .swapExactTokensForTokens(amountIn, amountOutMin, path, to)
-            .send(rawTx).then(console.log)
-    })
-
-    it('Univ3 `exactInput` test', async () => {
-        const UNIV3_ABI = require('../abi/UNIV3_ROUTER_ABI.json')
-
-        let univ3_contract = new web3.eth.Contract(UNIV3_ABI, contracts.UNIV3)
-
-        let rawTx = {
-            from: deployer.address,
-            nonce: await web3.eth.getTransactionCount(deployer.address),
-            gasPrice: web3.utils.toWei('2', 'gwei'),
-            gasLimit: 1e6
-        }
-
-        let amountOutMin = 1
-        let deadline = parseInt(String(new Date().getTime() / 1e3)) + 60
-        let path = [contracts.WETH, fee._30_per_10000, contracts.USDT]
-        let to = deployer.address
-
-        let params = {
-            path: ethers.utils.solidityPack(['address', 'uint24', 'address'], path),
-            recipient: to,
-            deadline: deadline,
-            amountIn: inAmount,
-            amountOutMinimum: amountOutMin
-        }
-
-        await univ3_contract.methods
-            .exactInput(params)
-            .send(rawTx).then(console.log)
-    })
-
-    it('Quoter calc test', async () => {
-        const QUOTER_ABI = require('../abi/QUOTER_ABI.json')
-
-        let quoter = new web3.eth.Contract(QUOTER_ABI, contracts.QUOTER)
-
-        await quoter.methods
-            .quoteExactInputSingle(contracts.WETH, contracts.USDT, fee._30_per_10000, inAmount, 0)
-            .call().then(console.log)
-    })
-
-    it('Univ3 swap test', async () => {
-        const FLASH_ABI = require('../artifacts/contracts/Flash.sol').abi
-
-        let flash = new web3.eth.Contract(FLASH_ABI, contracts.FLASH)
-
-        let rawTx = {
-            from: deployer.address,
-            nonce: await web3.eth.getTransactionCount(deployer.address),
-            gasPrice: web3.utils.toWei('2', 'gwei'),
-            gasLimit: 1e6
-        }
-
-        const WETH_USDT_POOL_CONTRACT = '0x4e68Ccd3E89f51C3074ca5072bbAC773960dFa36'
-        await flash.methods
-            .swap()
-            .send(rawTx).then(console.log)
-    })
+  let inAmount = 1e15.toString()
+
+  it('Univ3 swap test', async () => {
+    const UNIV3_ABI = require('../abi/UNIV3_ROUTER_ABI.json')
+
+    let univ3_contract = new web3.eth.Contract(UNIV3_ABI, contracts.UNIV3)
+
+    let rawTx = {
+      from: deployer.address,
+      nonce: await web3.eth.getTransactionCount(deployer.address),
+      gasPrice: web3.utils.toWei('2', 'gwei'),
+      gasLimit: 1_000_000
+    }
+
+    let amountIn = inAmount
+    let amountOutMin = 1
+    let path = [contracts.WETH, contracts.HEX]
+    let to = deployer.address
+
+    await univ3_contract.methods
+      .swapExactTokensForTokens(amountIn, amountOutMin, path, to)
+      .send(rawTx).then(console.log)
+  })
+
+  it('Univ3 `exactInput` test', async () => {
+    const UNIV3_ABI = require('../abi/UNIV3_ROUTER_ABI.json')
+
+    let univ3_contract = new web3.eth.Contract(UNIV3_ABI, contracts.UNIV3)
+
+    let rawTx = {
+      from: deployer.address,
+      nonce: await web3.eth.getTransactionCount(deployer.address),
+      gasPrice: web3.utils.toWei('2', 'gwei'),
+      gasLimit: 1e6
+    }
+
+    let amountOutMin = 1
+    let deadline = parseInt(String(new Date().getTime() / 1e3)) + 60
+    let path = [contracts.WETH, fee._30_per_10000, contracts.USDT]
+    let to = deployer.address
+
+    let params = {
+      path: ethers.utils.solidityPack(['address', 'uint24', 'address'], path),
+      recipient: to,
+      deadline: deadline,
+      amountIn: inAmount,
+      amountOutMinimum: amountOutMin
+    }
+
+    await univ3_contract.methods
+      .exactInput(params)
+      .send(rawTx).then(console.log)
+  })
+
+  it('Quoter calc test', async () => {
+    const QUOTER_ABI = require('../abi/QUOTER_ABI.json')
+
+    let quoter = new web3.eth.Contract(QUOTER_ABI, contracts.QUOTER)
+
+    await quoter.methods
+      .quoteExactInputSingle(contracts.WETH, contracts.USDT, fee._30_per_10000, inAmount, 0)
+      .call().then(console.log)
+  })
 })

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác