Skip to content

Instantly share code, notes, and snippets.

@BlockmanCodes
Created November 22, 2022 01:29
Show Gist options
  • Save BlockmanCodes/d0068cfc56ab67925dfd4b854ffea8fc to your computer and use it in GitHub Desktop.
Save BlockmanCodes/d0068cfc56ab67925dfd4b854ffea8fc to your computer and use it in GitHub Desktop.
Uniswap V3 Flashloans and Arbitrage
const { Contract, ContractFactory, utils, BigNumber } = require("ethers")
const WETH9 = require("../WETH9.json")
const artifacts = {
UniswapV3Factory: require("@uniswap/v3-core/artifacts/contracts/UniswapV3Factory.sol/UniswapV3Factory.json"),
SwapRouter: require("@uniswap/v3-periphery/artifacts/contracts/SwapRouter.sol/SwapRouter.json"),
NFTDescriptor: require("@uniswap/v3-periphery/artifacts/contracts/libraries/NFTDescriptor.sol/NFTDescriptor.json"),
NonfungibleTokenPositionDescriptor: require("@uniswap/v3-periphery/artifacts/contracts/NonfungibleTokenPositionDescriptor.sol/NonfungibleTokenPositionDescriptor.json"),
NonfungiblePositionManager: require("@uniswap/v3-periphery/artifacts/contracts/NonfungiblePositionManager.sol/NonfungiblePositionManager.json"),
WETH9,
};
const linkLibraries = ({ bytecode, linkReferences }, libraries) => {
Object.keys(linkReferences).forEach((fileName) => {
Object.keys(linkReferences[fileName]).forEach((contractName) => {
if (!libraries.hasOwnProperty(contractName)) {
throw new Error(`Missing link library name ${contractName}`)
}
const address = utils
.getAddress(libraries[contractName])
.toLowerCase()
.slice(2)
linkReferences[fileName][contractName].forEach(
({ start, length }) => {
const start2 = 2 + start * 2
const length2 = length * 2
bytecode = bytecode
.slice(0, start2)
.concat(address)
.concat(bytecode.slice(start2 + length2, bytecode.length))
}
)
})
})
return bytecode
}
async function main() {
const [owner] = await ethers.getSigners();
Weth = new ContractFactory(artifacts.WETH9.abi, artifacts.WETH9.bytecode, owner);
weth = await Weth.deploy();
Factory = new ContractFactory(artifacts.UniswapV3Factory.abi, artifacts.UniswapV3Factory.bytecode, owner);
factory = await Factory.deploy();
SwapRouter = new ContractFactory(artifacts.SwapRouter.abi, artifacts.SwapRouter.bytecode, owner);
swapRouter = await SwapRouter.deploy(factory.address, weth.address);
NFTDescriptor = new ContractFactory(artifacts.NFTDescriptor.abi, artifacts.NFTDescriptor.bytecode, owner);
nftDescriptor = await NFTDescriptor.deploy();
const linkedBytecode = linkLibraries(
{
bytecode: artifacts.NonfungibleTokenPositionDescriptor.bytecode,
linkReferences: {
"NFTDescriptor.sol": {
NFTDescriptor: [
{
length: 20,
start: 1261,
},
],
},
},
},
{
NFTDescriptor: nftDescriptor.address,
}
);
NonfungibleTokenPositionDescriptor = new ContractFactory(artifacts.NonfungibleTokenPositionDescriptor.abi, linkedBytecode, owner);
nonfungibleTokenPositionDescriptor = await NonfungibleTokenPositionDescriptor.deploy(weth.address);
NonfungiblePositionManager = new ContractFactory(artifacts.NonfungiblePositionManager.abi, artifacts.NonfungiblePositionManager.bytecode, owner);
nonfungiblePositionManager = await NonfungiblePositionManager.deploy(factory.address, weth.address, nonfungibleTokenPositionDescriptor.address);
console.log('WETH_ADDRESS=', `'${weth.address}'`)
console.log('FACTORY_ADDRESS=', `'${factory.address}'`)
console.log('SWAP_ROUTER_ADDRESS=', `'${swapRouter.address}'`)
console.log('NFT_DESCRIPTOR_ADDRESS=', `'${nftDescriptor.address}'`)
console.log('POSITION_DESCRIPTOR_ADDRESS=', `'${nonfungibleTokenPositionDescriptor.address}'`)
console.log('POSITION_MANAGER_ADDRESS=', `'${nonfungiblePositionManager.address}'`)
}
/*
npx hardhat run --network localhost scripts/01_deployContracts.js
*/
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
async function main() {
const [owner, signer2] = await ethers.getSigners();
Tether = await ethers.getContractFactory('Tether', owner);
tether = await Tether.deploy();
Usdc = await ethers.getContractFactory('UsdCoin', owner);
usdc = await Usdc.deploy();
await tether.connect(owner).mint(
owner.address,
ethers.utils.parseEther('100000')
)
await usdc.connect(owner).mint(
owner.address,
ethers.utils.parseEther('100000')
)
console.log('TETHER_ADDRESS=', `'${tether.address}'`)
console.log('USDC_ADDRESS=', `'${usdc.address}'`)
}
/*
npx hardhat run --network localhost scripts/02_deployTokens.js
*/
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
// Token addresses
TETHER_ADDRESS= '0x0165878A594ca255338adfa4d48449f69242Eb8F'
USDC_ADDRESS= '0xa513E6E4b8f2a923D98304ec87F64353C4D5C853'
// Uniswap contract address
WETH_ADDRESS= '0x5FbDB2315678afecb367f032d93F642f64180aa3'
FACTORY_ADDRESS= '0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512'
SWAP_ROUTER_ADDRESS= '0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0'
NFT_DESCRIPTOR_ADDRESS= '0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9'
POSITION_DESCRIPTOR_ADDRESS= '0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9'
POSITION_MANAGER_ADDRESS= '0x5FC8d32690cc91D4c39d9d3abcBD16989F875707'
const artifacts = {
UniswapV3Factory: require("@uniswap/v3-core/artifacts/contracts/UniswapV3Factory.sol/UniswapV3Factory.json"),
NonfungiblePositionManager: require("@uniswap/v3-periphery/artifacts/contracts/NonfungiblePositionManager.sol/NonfungiblePositionManager.json"),
};
const { Contract, BigNumber } = require("ethers")
const bn = require('bignumber.js')
bn.config({ EXPONENTIAL_AT: 999999, DECIMAL_PLACES: 40 })
const provider = waffle.provider;
function encodePriceSqrt(reserve1, reserve0) {
return BigNumber.from(
new bn(reserve1.toString())
.div(reserve0.toString())
.sqrt()
.multipliedBy(new bn(2).pow(96))
.integerValue(3)
.toString()
)
}
const nonfungiblePositionManager = new Contract(
POSITION_MANAGER_ADDRESS,
artifacts.NonfungiblePositionManager.abi,
provider
)
const factory = new Contract(
FACTORY_ADDRESS,
artifacts.UniswapV3Factory.abi,
provider
)
async function deployPool(token0, token1, fee, price) {
const [owner] = await ethers.getSigners();
await nonfungiblePositionManager.connect(owner).createAndInitializePoolIfNecessary(
token0,
token1,
fee,
price,
{ gasLimit: 5000000 }
)
const poolAddress = await factory.connect(owner).getPool(
token0,
token1,
fee,
)
return poolAddress
}
async function main() {
const usdtUsdc500 = await deployPool(TETHER_ADDRESS, USDC_ADDRESS, 500, encodePriceSqrt(1, 1))
const usdtUsdc3000 = await deployPool(TETHER_ADDRESS, USDC_ADDRESS, 3000, encodePriceSqrt(1, 2))
const usdtUsdc10000 = await deployPool(TETHER_ADDRESS, USDC_ADDRESS, 10000, encodePriceSqrt(2, 1))
console.log('USDT_USDC_500=', `'${usdtUsdc500}'`)
console.log('USDT_USDC_3000=', `'${usdtUsdc3000}'`)
console.log('USDT_USDC_10000=', `'${usdtUsdc10000}'`)
}
/*
npx hardhat run --network localhost scripts/03_deployPools.js
*/
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
// Uniswap contract addresses
WETH_ADDRESS= '0x5FbDB2315678afecb367f032d93F642f64180aa3'
FACTORY_ADDRESS= '0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512'
SWAP_ROUTER_ADDRESS= '0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0'
NFT_DESCRIPTOR_ADDRESS= '0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9'
POSITION_DESCRIPTOR_ADDRESS= '0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9'
POSITION_MANAGER_ADDRESS= '0x5FC8d32690cc91D4c39d9d3abcBD16989F875707'
// Pool addresses
USDT_USDC_500= '0x1FA8DDa81477A5b6FA1b2e149e93ed9C7928992F'
USDT_USDC_3000= '0x3B00F82071576B8489A6e3df223dcC0e937841d1'
USDT_USDC_10000= '0xb09EB46A30889ae3cE4AFa5d8ebD136B4f389B85'
// Token addresses
TETHER_ADDRESS= '0x0165878A594ca255338adfa4d48449f69242Eb8F'
USDC_ADDRESS= '0xa513E6E4b8f2a923D98304ec87F64353C4D5C853'
const artifacts = {
NonfungiblePositionManager: require("@uniswap/v3-periphery/artifacts/contracts/NonfungiblePositionManager.sol/NonfungiblePositionManager.json"),
Usdt: require("../artifacts/contracts/Tether.sol/Tether.json"),
Usdc: require("../artifacts/contracts/UsdCoin.sol/UsdCoin.json"),
UniswapV3Pool: require("@uniswap/v3-core/artifacts/contracts/UniswapV3Pool.sol/UniswapV3Pool.json"),
};
const { Contract } = require("ethers")
const { Token } = require('@uniswap/sdk-core')
const { Pool, Position, nearestUsableTick } = require('@uniswap/v3-sdk')
async function getPoolData(poolContract) {
const [tickSpacing, fee, liquidity, slot0] = await Promise.all([
poolContract.tickSpacing(),
poolContract.fee(),
poolContract.liquidity(),
poolContract.slot0(),
])
return {
tickSpacing: tickSpacing,
fee: fee,
liquidity: liquidity,
sqrtPriceX96: slot0[0],
tick: slot0[1],
}
}
LIQUIDITY = ethers.utils.parseEther('100')
DEADLINE = Math.floor(Date.now() / 1000) + (60 * 10)
POOL_ADDRESSES = [USDT_USDC_500, USDT_USDC_3000, USDT_USDC_10000] // ,
async function main() {
const [owner, signer2] = await ethers.getSigners();
const provider = waffle.provider;
const nonfungiblePositionManager = new Contract(
POSITION_MANAGER_ADDRESS,
artifacts.NonfungiblePositionManager.abi,
provider
)
const usdtContract = new Contract(TETHER_ADDRESS,artifacts.Usdt.abi,provider)
const usdcContract = new Contract(USDC_ADDRESS,artifacts.Usdc.abi,provider)
await usdtContract.connect(owner).approve(POSITION_MANAGER_ADDRESS, ethers.utils.parseEther('9999999'))
await usdcContract.connect(owner).approve(POSITION_MANAGER_ADDRESS, ethers.utils.parseEther('9999999'))
const UsdtToken = new Token(31337, TETHER_ADDRESS, 18, 'USDT', 'Tether')
const UsdcToken = new Token(31337, USDC_ADDRESS, 18, 'USDC', 'UsdCoin')
const poolContract1 = new Contract(USDT_USDC_500, artifacts.UniswapV3Pool.abi, provider)
const poolContract2 = new Contract(USDT_USDC_3000, artifacts.UniswapV3Pool.abi, provider)
const poolContract3 = new Contract(USDT_USDC_10000, artifacts.UniswapV3Pool.abi, provider)
const poolData = {}
poolData[USDT_USDC_500] = await getPoolData(poolContract1)
poolData[USDT_USDC_3000] = await getPoolData(poolContract2)
poolData[USDT_USDC_10000] = await getPoolData(poolContract3)
// appears I cannot interact with contracts in the async map
const mintParams = {}
POOL_ADDRESSES.map(async poolAddress => {
pd = poolData[poolAddress]
const poolObj = new Pool(
UsdtToken,
UsdcToken,
pd.fee,
pd.sqrtPriceX96.toString(),
pd.liquidity.toString(),
pd.tick
)
const tickLower = nearestUsableTick(pd.tick, pd.tickSpacing) - pd.tickSpacing * 100
const tickUpper = nearestUsableTick(pd.tick, pd.tickSpacing) + pd.tickSpacing * 100
const positionObj = new Position({
pool: poolObj,
liquidity: LIQUIDITY,
tickLower: tickLower,
tickUpper: tickUpper,
})
const { amount0: amount0Desired, amount1: amount1Desired} = positionObj.mintAmounts
const params = {
token0: TETHER_ADDRESS,
token1: USDC_ADDRESS,
fee: pd.fee,
tickLower: tickLower,
tickUpper: tickUpper,
amount0Desired: amount0Desired.toString(),
amount1Desired: amount1Desired.toString(),
amount0Min: 0,
amount1Min: 0,
recipient: signer2.address,
deadline: DEADLINE
}
mintParams[poolAddress] = params
})
const tx1 = await nonfungiblePositionManager.connect(owner).mint(mintParams[USDT_USDC_500], { gasLimit: '1000000' })
await tx1.wait()
const tx2 = await nonfungiblePositionManager.connect(owner).mint(mintParams[USDT_USDC_3000], { gasLimit: '1000000' })
await tx2.wait()
const tx3 = await nonfungiblePositionManager.connect(owner).mint(mintParams[USDT_USDC_10000], { gasLimit: '1000000' })
await tx3.wait()
console.log('done')
}
/*
npx hardhat run --network localhost scripts/04_addLiquidity.js
*/
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
// pool
USDT_USDC_500= '0x1FA8DDa81477A5b6FA1b2e149e93ed9C7928992F'
USDT_USDC_3000= '0x3B00F82071576B8489A6e3df223dcC0e937841d1'
USDT_USDC_10000= '0xb09EB46A30889ae3cE4AFa5d8ebD136B4f389B85'
const UniswapV3Pool = require("@uniswap/v3-core/artifacts/contracts/UniswapV3Pool.sol/UniswapV3Pool.json")
const { Contract, BigNumber } = require("ethers")
async function getPoolData(poolContract) {
const [tickSpacing, fee, liquidity, slot0] = await Promise.all([
poolContract.tickSpacing(),
poolContract.fee(),
poolContract.liquidity(),
poolContract.slot0(),
])
const sqrtPriceX96 = slot0[0]
const numerator = BigNumber.from(sqrtPriceX96).pow(2)
const denominator = BigNumber.from(2).pow(192)
const priceRatio = numerator/denominator
return {
tickSpacing: tickSpacing,
fee: fee,
liquidity: liquidity.toString(),
sqrtPriceX96: sqrtPriceX96.toString(),
priceRatio: priceRatio.toString(),
tick: slot0[1],
}
}
async function main() {
const provider = waffle.provider;
const poolContract500 = new Contract(USDT_USDC_500, UniswapV3Pool.abi, provider)
const poolData500 = await getPoolData(poolContract500)
console.log('poolData500', poolData500)
const poolContract3000 = new Contract(USDT_USDC_3000, UniswapV3Pool.abi, provider)
const poolData3000 = await getPoolData(poolContract3000)
console.log('poolData3000', poolData3000)
const poolContract10000 = new Contract(USDT_USDC_10000, UniswapV3Pool.abi, provider)
const poolData10000 = await getPoolData(poolContract10000)
console.log('poolData10000', poolData10000)
}
/*
npx hardhat run --network localhost scripts/05_checkLiquidity.js
*/
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
const { Contract } = require("ethers")
// Uniswap contract address
WETH_ADDRESS= '0x5FbDB2315678afecb367f032d93F642f64180aa3'
FACTORY_ADDRESS= '0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512'
SWAP_ROUTER_ADDRESS= '0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0'
NFT_DESCRIPTOR_ADDRESS= '0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9'
POSITION_DESCRIPTOR_ADDRESS= '0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9'
POSITION_MANAGER_ADDRESS= '0x5FC8d32690cc91D4c39d9d3abcBD16989F875707'
// Token addresses
TETHER_ADDRESS= '0x0165878A594ca255338adfa4d48449f69242Eb8F'
USDC_ADDRESS= '0xa513E6E4b8f2a923D98304ec87F64353C4D5C853'
const WETH9 = require("../WETH9.json")
const artifacts = {
UniswapV3Factory: require("@uniswap/v3-core/artifacts/contracts/UniswapV3Factory.sol/UniswapV3Factory.json"),
SwapRouter: require("@uniswap/v3-periphery/artifacts/contracts/SwapRouter.sol/SwapRouter.json"),
NFTDescriptor: require("@uniswap/v3-periphery/artifacts/contracts/libraries/NFTDescriptor.sol/NFTDescriptor.json"),
NonfungibleTokenPositionDescriptor: require("@uniswap/v3-periphery/artifacts/contracts/NonfungibleTokenPositionDescriptor.sol/NonfungibleTokenPositionDescriptor.json"),
NonfungiblePositionManager: require("@uniswap/v3-periphery/artifacts/contracts/NonfungiblePositionManager.sol/NonfungiblePositionManager.json"),
Usdt: require("../artifacts/contracts/Tether.sol/Tether.json"),
Usdc: require("../artifacts/contracts/UsdCoin.sol/UsdCoin.json"),
WETH9,
};
const toEth = (wei) => ethers.utils.formatEther(wei)
async function main() {
const provider = waffle.provider;
const [owner, signer2] = await ethers.getSigners();
Flash = await ethers.getContractFactory('PairFlash', signer2);
flash = await Flash.deploy(SWAP_ROUTER_ADDRESS, FACTORY_ADDRESS, WETH_ADDRESS);
console.log('flash', flash.address)
const usdtContract = new Contract(TETHER_ADDRESS,artifacts.Usdt.abi,provider)
const usdcContract = new Contract(USDC_ADDRESS,artifacts.Usdc.abi,provider)
let usdtBalance = await usdtContract.connect(provider).balanceOf(signer2.address)
let usdcBalance = await usdcContract.connect(provider).balanceOf(signer2.address)
console.log('-------------------- BEFORE')
console.log('usdtBalance', toEth(usdtBalance.toString()))
console.log('usdcBalance', toEth(usdcBalance.toString()))
console.log('--------------------')
const tx = await flash.connect(signer2).initFlash(
[
TETHER_ADDRESS,
USDC_ADDRESS,
500,
ethers.utils.parseEther('1'),
ethers.utils.parseEther('1'),
3000,
10000
],
{ gasLimit: ethers.utils.hexlify(1000000) }
);
await tx.wait()
usdtBalance = await usdtContract.connect(provider).balanceOf(signer2.address)
usdcBalance = await usdcContract.connect(provider).balanceOf(signer2.address)
console.log('-------------------- AFTER')
console.log('usdtBalance', toEth(usdtBalance.toString()))
console.log('usdcBalance', toEth(usdcBalance.toString()))
console.log('--------------------')
}
/*
npx hardhat run --network localhost scripts/06_flashSwap.js
*/
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
require("@nomiclabs/hardhat-waffle");
module.exports = {
solidity: {
compilers: [
{ version: "0.7.6" },
],
settings: {
optimizer: {
enabled: true,
runs: 5000,
details: { yul: false },
},
}
},
};
{
"name": "solidity-flashswap-1",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@nomiclabs/hardhat-ethers": "^2.2.1",
"@nomiclabs/hardhat-waffle": "^2.0.3",
"@openzeppelin/contracts": "^3.4.0",
"@uniswap/v3-periphery": "^1.0.1",
"@uniswap/v3-sdk": "^3.9.0",
"bignumber.js": "^9.1.0",
"ethereum-waffle": "^3.4.4",
"ethers": "^5.7.2",
"hardhat": "^2.12.2"
}
}
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity =0.7.6;
pragma abicoder v2;
import '@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3FlashCallback.sol';
import '@uniswap/v3-core/contracts/libraries/LowGasSafeMath.sol';
import '@uniswap/v3-periphery/contracts/base/PeripheryPayments.sol';
import '@uniswap/v3-periphery/contracts/base/PeripheryImmutableState.sol';
import '@uniswap/v3-periphery/contracts/libraries/PoolAddress.sol';
import '@uniswap/v3-periphery/contracts/libraries/CallbackValidation.sol';
import '@uniswap/v3-periphery/contracts/libraries/TransferHelper.sol';
import '@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol';
contract PairFlash is IUniswapV3FlashCallback, PeripheryImmutableState, PeripheryPayments {
using LowGasSafeMath for uint256;
using LowGasSafeMath for int256;
ISwapRouter public immutable swapRouter;
constructor(
ISwapRouter _swapRouter,
address _factory,
address _WETH9
) PeripheryImmutableState(_factory, _WETH9) {
swapRouter = _swapRouter;
}
function uniswapV3FlashCallback(
uint256 fee0,
uint256 fee1,
bytes calldata data
) external override {
FlashCallbackData memory decoded = abi.decode(data, (FlashCallbackData));
CallbackValidation.verifyCallback(factory, decoded.poolKey);
address token0 = decoded.poolKey.token0;
address token1 = decoded.poolKey.token1;
TransferHelper.safeApprove(token0, address(swapRouter), decoded.amount0);
TransferHelper.safeApprove(token1, address(swapRouter), decoded.amount1);
uint256 amount1Min = LowGasSafeMath.add(decoded.amount1, fee1);
uint256 amount0Min = LowGasSafeMath.add(decoded.amount0, fee0);
uint256 amountOut0 =
swapRouter.exactInputSingle(
ISwapRouter.ExactInputSingleParams({
tokenIn: token1,
tokenOut: token0,
fee: decoded.poolFee2,
recipient: address(this),
deadline: block.timestamp,
amountIn: decoded.amount1,
amountOutMinimum: amount0Min,
sqrtPriceLimitX96: 0
})
);
uint256 amountOut1 =
swapRouter.exactInputSingle(
ISwapRouter.ExactInputSingleParams({
tokenIn: token0,
tokenOut: token1,
fee: decoded.poolFee3,
recipient: address(this),
deadline: block.timestamp,
amountIn: decoded.amount0,
amountOutMinimum: amount1Min,
sqrtPriceLimitX96: 0
})
);
uint256 amount0Owed = LowGasSafeMath.add(decoded.amount0, fee0);
uint256 amount1Owed = LowGasSafeMath.add(decoded.amount1, fee1);
TransferHelper.safeApprove(token0, address(this), amount0Owed);
TransferHelper.safeApprove(token1, address(this), amount1Owed);
if (amount0Owed > 0) pay(token0, address(this), msg.sender, amount0Owed);
if (amount1Owed > 0) pay(token1, address(this), msg.sender, amount1Owed);
if (amountOut0 > amount0Owed) {
uint256 profit0 = LowGasSafeMath.sub(amountOut0, amount0Owed);
TransferHelper.safeApprove(token0, address(this), profit0);
pay(token0, address(this), decoded.payer, profit0);
}
if (amountOut1 > amount1Owed) {
uint256 profit1 = LowGasSafeMath.sub(amountOut1, amount1Owed);
TransferHelper.safeApprove(token0, address(this), profit1);
pay(token1, address(this), decoded.payer, profit1);
}
}
struct FlashParams {
address token0;
address token1;
uint24 fee1;
uint256 amount0;
uint256 amount1;
uint24 fee2;
uint24 fee3;
}
struct FlashCallbackData {
uint256 amount0;
uint256 amount1;
address payer;
PoolAddress.PoolKey poolKey;
uint24 poolFee2;
uint24 poolFee3;
}
function initFlash(FlashParams memory params) external {
// {token0: token0, token1: token1, fee: fee}
PoolAddress.PoolKey memory poolKey = PoolAddress.PoolKey({token0: params.token0, token1: params.token1, fee: params.fee1});
IUniswapV3Pool pool = IUniswapV3Pool(PoolAddress.computeAddress(factory, poolKey));
pool.flash(
address(this),
params.amount0,
params.amount1,
abi.encode(
FlashCallbackData({
amount0: params.amount0,
amount1: params.amount1,
payer: msg.sender,
poolKey: poolKey,
poolFee2: params.fee2,
poolFee3: params.fee3
})
)
);
}
}
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity =0.7.6;
import '@openzeppelin/contracts/token/ERC20/ERC20.sol';
import "@openzeppelin/contracts/access/Ownable.sol";
contract Tether is ERC20, Ownable {
constructor() ERC20('Tether', 'USDT') {}
function mint(address to, uint256 amount) public onlyOwner {
_mint(to, amount);
}
}
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity =0.7.6;
import '@openzeppelin/contracts/token/ERC20/ERC20.sol';
import "@openzeppelin/contracts/access/Ownable.sol";
contract UsdCoin is ERC20, Ownable {
constructor() ERC20('UsdCoin', 'USDC') {}
function mint(address to, uint256 amount) public onlyOwner {
_mint(to, amount);
}
}
{
"bytecode": "60606040526040805190810160405280600d81526020017f57726170706564204574686572000000000000000000000000000000000000008152506000908051906020019061004f9291906100c8565b506040805190810160405280600481526020017f57455448000000000000000000000000000000000000000000000000000000008152506001908051906020019061009b9291906100c8565b506012600260006101000a81548160ff021916908360ff16021790555034156100c357600080fd5b61016d565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061010957805160ff1916838001178555610137565b82800160010185558215610137579182015b8281111561013657825182559160200191906001019061011b565b5b5090506101449190610148565b5090565b61016a91905b8082111561016657600081600090555060010161014e565b5090565b90565b610c348061017c6000396000f3006060604052600436106100af576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100b9578063095ea7b31461014757806318160ddd146101a157806323b872dd146101ca5780632e1a7d4d14610243578063313ce5671461026657806370a082311461029557806395d89b41146102e2578063a9059cbb14610370578063d0e30db0146103ca578063dd62ed3e146103d4575b6100b7610440565b005b34156100c457600080fd5b6100cc6104dd565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561010c5780820151818401526020810190506100f1565b50505050905090810190601f1680156101395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015257600080fd5b610187600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061057b565b604051808215151515815260200191505060405180910390f35b34156101ac57600080fd5b6101b461066d565b6040518082815260200191505060405180910390f35b34156101d557600080fd5b610229600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061068c565b604051808215151515815260200191505060405180910390f35b341561024e57600080fd5b61026460048080359060200190919050506109d9565b005b341561027157600080fd5b610279610b05565b604051808260ff1660ff16815260200191505060405180910390f35b34156102a057600080fd5b6102cc600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610b18565b6040518082815260200191505060405180910390f35b34156102ed57600080fd5b6102f5610b30565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561033557808201518184015260208101905061031a565b50505050905090810190601f1680156103625780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561037b57600080fd5b6103b0600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610bce565b604051808215151515815260200191505060405180910390f35b6103d2610440565b005b34156103df57600080fd5b61042a600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610be3565b6040518082815260200191505060405180910390f35b34600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055503373ffffffffffffffffffffffffffffffffffffffff167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040518082815260200191505060405180910390a2565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156105735780601f1061054857610100808354040283529160200191610573565b820191906000526020600020905b81548152906001019060200180831161055657829003601f168201915b505050505081565b600081600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60003073ffffffffffffffffffffffffffffffffffffffff1631905090565b600081600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101515156106dc57600080fd5b3373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141580156107b457507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414155b156108cf5781600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561084457600080fd5b81600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b81600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610a2757600080fd5b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501515610ab457600080fd5b3373ffffffffffffffffffffffffffffffffffffffff167f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65826040518082815260200191505060405180910390a250565b600260009054906101000a900460ff1681565b60036020528060005260406000206000915090505481565b60018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610bc65780601f10610b9b57610100808354040283529160200191610bc6565b820191906000526020600020905b815481529060010190602001808311610ba957829003601f168201915b505050505081565b6000610bdb33848461068c565b905092915050565b60046020528160005260406000206020528060005260406000206000915091505054815600a165627a7a72305820deb4c2ccab3c2fdca32ab3f46728389c2fe2c165d5fafa07661e4e004f6c344a0029",
"abi": [
{
"constant": true,
"inputs": [],
"name": "name",
"outputs": [{ "name": "", "type": "string" }],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{ "name": "guy", "type": "address" },
{ "name": "wad", "type": "uint256" }
],
"name": "approve",
"outputs": [{ "name": "", "type": "bool" }],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "totalSupply",
"outputs": [{ "name": "", "type": "uint256" }],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{ "name": "src", "type": "address" },
{ "name": "dst", "type": "address" },
{ "name": "wad", "type": "uint256" }
],
"name": "transferFrom",
"outputs": [{ "name": "", "type": "bool" }],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [{ "name": "wad", "type": "uint256" }],
"name": "withdraw",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "decimals",
"outputs": [{ "name": "", "type": "uint8" }],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [{ "name": "", "type": "address" }],
"name": "balanceOf",
"outputs": [{ "name": "", "type": "uint256" }],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "symbol",
"outputs": [{ "name": "", "type": "string" }],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{ "name": "dst", "type": "address" },
{ "name": "wad", "type": "uint256" }
],
"name": "transfer",
"outputs": [{ "name": "", "type": "bool" }],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [],
"name": "deposit",
"outputs": [],
"payable": true,
"stateMutability": "payable",
"type": "function"
},
{
"constant": true,
"inputs": [
{ "name": "", "type": "address" },
{ "name": "", "type": "address" }
],
"name": "allowance",
"outputs": [{ "name": "", "type": "uint256" }],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{ "payable": true, "stateMutability": "payable", "type": "fallback" },
{
"anonymous": false,
"inputs": [
{ "indexed": true, "name": "src", "type": "address" },
{ "indexed": true, "name": "guy", "type": "address" },
{ "indexed": false, "name": "wad", "type": "uint256" }
],
"name": "Approval",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{ "indexed": true, "name": "src", "type": "address" },
{ "indexed": true, "name": "dst", "type": "address" },
{ "indexed": false, "name": "wad", "type": "uint256" }
],
"name": "Transfer",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{ "indexed": true, "name": "dst", "type": "address" },
{ "indexed": false, "name": "wad", "type": "uint256" }
],
"name": "Deposit",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{ "indexed": true, "name": "src", "type": "address" },
{ "indexed": false, "name": "wad", "type": "uint256" }
],
"name": "Withdrawal",
"type": "event"
}
]
}
@andreyddk
Copy link

Error: missing argument: in Contract constructor (count=1, expectedCount=2, code=MISSING_ARGUMENT, version=contracts/5.7.0) at Logger.makeError (C:\Users\Rajat\Desktop\hardhat\node_modules@ethersproject\logger\src.ts\index.ts:269:28) at Logger.throwError (C:\Users\Rajat\Desktop\hardhat\node_modules@ethersproject\logger\src.ts\index.ts:281:20) at Logger.checkArgumentCount (C:\Users\Rajat\Desktop\hardhat\node_modules@ethersproject\logger\src.ts\index.ts:340:18) at ContractFactory. (C:\Users\Rajat\Desktop\hardhat\node_modules@ethersproject\contracts\src.ts\index.ts:1237:16) at step (C:\Users\Rajat\Desktop\hardhat\node_modules@ethersproject\contracts\lib\index.js:48:23) at Object.next (C:\Users\Rajat\Desktop\hardhat\node_modules@ethersproject\contracts\lib\index.js:29:53) at C:\Users\Rajat\Desktop\hardhat\node_modules@ethersproject\contracts\lib\index.js:23:71 at new Promise () at __awaiter (C:\Users\Rajat\Desktop\hardhat\node_modules@ethersproject\contracts\lib\index.js:19:12) at ContractFactory.deploy (C:\Users\Rajat\Desktop\hardhat\node_modules@ethersproject\contracts\lib\index.js:1138:16) { reason: 'missing argument: in Contract constructor', code: 'MISSING_ARGUMENT', count: 1, expectedCount: 2 } this error occur when i call deploycontracts scripts

Hi! The problem can be appear because of lost argument _nativeCurrencyLabelBytes look at the abi interface

{
          "internalType": "bytes32",
          "name": "_nativeCurrencyLabelBytes",
          "type": "bytes32"
        }

I was testing it in mumbai and for me the value will be 0x4d41544943000000000000000000000000000000000000000000000000000000

So for success deployment you should try to add like that

const nonfungibleTokenPositionDescriptor =
    await NonfungibleTokenPositionDescriptor.deploy(
      WMATIC_ADDRESS,
      "0x4d41544943000000000000000000000000000000000000000000000000000000"
    );

@Rajatdev12
Copy link

Rajatdev12 commented May 12, 2023 via email

@Rajatdev12
Copy link

TypeError: Cannot read properties of null (reading 'call')
at Contract. (C:\Users\Rajat\Desktop\hardhat\node_modules@ethersproject\contracts\src.ts\index.ts:397:47)
at step (C:\Users\Rajat\Desktop\hardhat\node_modules@ethersproject\contracts\lib\index.js:48:23)
at Object.next (C:\Users\Rajat\Desktop\hardhat\node_modules@ethersproject\contracts\lib\index.js:29:53)
at fulfilled (C:\Users\Rajat\Desktop\hardhat\node_modules@ethersproject\contracts\lib\index.js:20:58)
at processTicksAndRejections (node:internal/process/task_queues:96:5) i call addliquidity.js that error occur not in that file but in nodemodules why ,i properly pass value of both coins

@andreyddk
Copy link

TypeError: Cannot read properties of null (reading 'call') at Contract. (C:\Users\Rajat\Desktop\hardhat\node_modules@ethersproject\contracts\src.ts\index.ts:397:47) at step (C:\Users\Rajat\Desktop\hardhat\node_modules@ethersproject\contracts\lib\index.js:48:23) at Object.next (C:\Users\Rajat\Desktop\hardhat\node_modules@ethersproject\contracts\lib\index.js:29:53) at fulfilled (C:\Users\Rajat\Desktop\hardhat\node_modules@ethersproject\contracts\lib\index.js:20:58) at processTicksAndRejections (node:internal/process/task_queues:96:5) i call addliquidity.js that error occur not in that file but in nodemodules why ,i properly pass value of both coins

Please, share more details.

@Rajatdev12
Copy link

Rajatdev12 commented May 13, 2023 via email

@andreyddk
Copy link

I call add liquidityjs script to add liquidity of both tokens but when I call that error occur but error not show in liquidity is script

On Sat, 13 May, 2023, 11:45 am Andrey, @.> wrote: @.* commented on this gist. ------------------------------ TypeError: Cannot read properties of null (reading 'call') at Contract. @.\contracts\src.ts\index.ts:397:47) at step @.\contracts\lib\index.js:48:23) at Object.next @.\contracts\lib\index.js:29:53) at fulfilled @.\contracts\lib\index.js:20:58) at processTicksAndRejections (node:internal/process/task_queues:96:5) i call addliquidity.js that error occur not in that file but in nodemodules why ,i properly pass value of both coins Please, share more details. — Reply to this email directly, view it on GitHub https://gist.github.com/BlockmanCodes/d0068cfc56ab67925dfd4b854ffea8fc#gistcomment-4566749 or unsubscribe https://github.com/notifications/unsubscribe-auth/A7HLA7BIG32KGJA2Y3Y2IZLXF4RGLBFKMF2HI4TJMJ2XIZLTSKBKK5TBNR2WLJDHNFZXJJDOMFWWLK3UNBZGKYLEL52HS4DFQKSXMYLMOVS2I5DSOVS2I3TBNVS3W5DIOJSWCZC7OBQXE5DJMNUXAYLOORPWCY3UNF3GS5DZVRZXKYTKMVRXIX3UPFYGLK2HNFZXIQ3PNVWWK3TUUZ2G64DJMNZZDAVEOR4XAZNEM5UXG5FFOZQWY5LFVEYTCOJUGY3DMOJUU52HE2LHM5SXFJTDOJSWC5DF . You are receiving this email because you commented on the thread. Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub .

Do you have stack trace? Show me the path of code where error was happened.

@zikkuratti
Copy link

ok guy's i read all your smartcringe are you ready? all you need is to change "@uniswap/v3-periphery": "^1.0.1", to "@uniswap/v3-periphery": "1.0.1", and npm install again all that shh

@SyxNyn3
Copy link

SyxNyn3 commented Jul 16, 2023

Make sure to replace 'https://example-ethereum-provider.com' with the actual Ethereum provider URL, ContractABI with the ABI of your contract, and ContractBytecode with the bytecode of your contract.

Additionally, replace 'your_wallet_address' with the address of your wallet and 'your_gas_limit' with the desired gas limit for the deployment transaction.

By providing the required arguments in the deployContracts script, you should be able to deploy the contract without encountering the MISSING_ARGUMENT error.
Your Welcome! ..Donation Accepted ;p @ 0xdD13BcD58E5B30a9C051A43E015467f2fFCebD92

@SyxNyn3
Copy link

SyxNyn3 commented Jul 16, 2023

I call add liquidityjs script to add liquidity of both tokens but when I call that error occur but error not show in liquidity is script

On Sat, 13 May, 2023, 11:45 am Andrey, @.> wrote: _@**._* commented on this gist. ------------------------------ TypeError: Cannot read properties of null (reading 'call') at Contract. _@.\contracts\src.ts\index.ts:397:47) at step @._\contracts\lib\index.js:48:23) at Object.next _@.\contracts\lib\index.js:29:53) at fulfilled @.**_\contracts\lib\index.js:20:58) at processTicksAndRejections (node:internal/process/task_queues:96:5) i call addliquidity.js that error occur not in that file but in nodemodules why ,i properly pass value of both coins Please, share more details. — Reply to this email directly, view it on GitHub https://gist.github.com/BlockmanCodes/d0068cfc56ab67925dfd4b854ffea8fc#gistcomment-4566749 or unsubscribe https://github.com/notifications/unsubscribe-auth/A7HLA7BIG32KGJA2Y3Y2IZLXF4RGLBFKMF2HI4TJMJ2XIZLTSKBKK5TBNR2WLJDHNFZXJJDOMFWWLK3UNBZGKYLEL52HS4DFQKSXMYLMOVS2I5DSOVS2I3TBNVS3W5DIOJSWCZC7OBQXE5DJMNUXAYLOORPWCY3UNF3GS5DZVRZXKYTKMVRXIX3UPFYGLK2HNFZXIQ3PNVWWK3TUUZ2G64DJMNZZDAVEOR4XAZNEM5UXG5FFOZQWY5LFVEYTCOJUGY3DMOJUU52HE2LHM5SXFJTDOJSWC5DF . You are receiving this email because you commented on the thread. Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub .

@SyxNyn3
Copy link

SyxNyn3 commented Jul 16, 2023

The error message you shared indicates that there is an issue with the addLiquidity.js script in the nodemodules directory. It seems to be a problem related to reading properties of a null object.

To troubleshoot this issue, you can follow these steps:

Verify that you have properly installed the required dependencies for the addLiquidity.js script by running npm install or yarn install in your project directory. Make sure all dependencies are successfully installed.

Double-check the code in the addLiquidity.js script for any potential errors or missing configurations. Ensure that all required variables and parameters are properly defined and provided.

Check if there are any updates available for the dependencies used in the script. You can try updating the dependencies by running npm update or yarn update in your project directory.

If the issue persists, it might be helpful to review the specific code block in the addLiquidity.js script that is causing the error. Look for any null object references or potential logic errors.

You're Welcome! Donation accepted here>>> @ 0xdD13BcD58E5B30a9C051A43E015467f2fFCebD92

@PerunPrime
Copy link

PerunPrime commented Jul 25, 2023

ok guy's i read all your smartcringe are you ready? all you need is to change "@uniswap/v3-periphery": "^1.0.1", to "@uniswap/v3-periphery": "1.0.1", and npm install again all that shh

Thank you! It is working now (at least first 3 scripts)

@ghgr75
Copy link

ghgr75 commented Apr 26, 2024

in deployContracts.js you have to set the value to 1681 instead of 1261 so the bytecode is correct

buna ziua, cand aveti timp, putem vorbi un pic despre strategia asta,va rog? nu ma prea pricep si as avea nevoie de ajutor. multumesc anticipat.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment