Skip to content

Instantly share code, notes, and snippets.

@BlockmanCodes
Created October 31, 2022 00:58
Show Gist options
  • Save BlockmanCodes/d0f1e31f711011b93b3a2fef96bf322c to your computer and use it in GitHub Desktop.
Save BlockmanCodes/d0f1e31f711011b93b3a2fef96bf322c to your computer and use it in GitHub Desktop.
Add Uniswap V3 pool liquidity locally
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();
WrappedBitcoin = await ethers.getContractFactory('WrappedBitcoin', owner);
wrappedBitcoin = await WrappedBitcoin.deploy();
await tether.connect(owner).mint(
signer2.address,
ethers.utils.parseEther('100000')
)
await usdc.connect(owner).mint(
signer2.address,
ethers.utils.parseEther('100000')
)
await wrappedBitcoin.connect(owner).mint(
signer2.address,
ethers.utils.parseEther('100000')
)
console.log('TETHER_ADDRESS=', `'${tether.address}'`)
console.log('USDC_ADDRESS=', `'${usdc.address}'`)
console.log('WRAPPED_BITCOIN_ADDRESS=', `'${wrappedBitcoin.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'
WRAPPED_BITCOIN_ADDRESS= '0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6'
// 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))
console.log('USDT_USDC_500=', `'${usdtUsdc500}'`)
}
/*
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'
// Token addresses
TETHER_ADDRESS= '0x0165878A594ca255338adfa4d48449f69242Eb8F'
USDC_ADDRESS= '0xa513E6E4b8f2a923D98304ec87F64353C4D5C853'
WRAPPED_BITCOIN_ADDRESS= '0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6'
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],
}
}
async function main() {
const [owner, signer2] = await ethers.getSigners();
const provider = waffle.provider;
const usdtContract = new Contract(TETHER_ADDRESS,artifacts.Usdt.abi,provider)
const usdcContract = new Contract(USDC_ADDRESS,artifacts.Usdc.abi,provider)
await usdtContract.connect(signer2).approve(POSITION_MANAGER_ADDRESS, ethers.utils.parseEther('1000'))
await usdcContract.connect(signer2).approve(POSITION_MANAGER_ADDRESS, ethers.utils.parseEther('1000'))
const poolContract = new Contract(USDT_USDC_500, artifacts.UniswapV3Pool.abi, provider)
const poolData = await getPoolData(poolContract)
const UsdtToken = new Token(31337, TETHER_ADDRESS, 18, 'USDT', 'Tether')
const UsdcToken = new Token(31337, USDC_ADDRESS, 18, 'USDC', 'UsdCoin')
const pool = new Pool(
UsdtToken,
UsdcToken,
poolData.fee,
poolData.sqrtPriceX96.toString(),
poolData.liquidity.toString(),
poolData.tick
)
const position = new Position({
pool: pool,
liquidity: ethers.utils.parseEther('1'),
tickLower: nearestUsableTick(poolData.tick, poolData.tickSpacing) - poolData.tickSpacing * 2,
tickUpper: nearestUsableTick(poolData.tick, poolData.tickSpacing) + poolData.tickSpacing * 2,
})
const { amount0: amount0Desired, amount1: amount1Desired} = position.mintAmounts
params = {
token0: TETHER_ADDRESS,
token1: USDC_ADDRESS,
fee: poolData.fee,
tickLower: nearestUsableTick(poolData.tick, poolData.tickSpacing) - poolData.tickSpacing * 2,
tickUpper: nearestUsableTick(poolData.tick, poolData.tickSpacing) + poolData.tickSpacing * 2,
amount0Desired: amount0Desired.toString(),
amount1Desired: amount1Desired.toString(),
amount0Min: 0,
amount1Min: 0,
recipient: signer2.address,
deadline: Math.floor(Date.now() / 1000) + (60 * 10)
}
const nonfungiblePositionManager = new Contract(
POSITION_MANAGER_ADDRESS,
artifacts.NonfungiblePositionManager.abi,
provider
)
const tx = await nonfungiblePositionManager.connect(signer2).mint(
params,
{ gasLimit: '1000000' }
)
const receipt = await tx.wait()
}
/*
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'
const UniswapV3Pool = require("@uniswap/v3-core/artifacts/contracts/UniswapV3Pool.sol/UniswapV3Pool.json")
const { Contract } = require("ethers")
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.toString(),
sqrtPriceX96: slot0[0],
tick: slot0[1],
}
}
async function main() {
const provider = waffle.provider;
const poolContract = new Contract(USDT_USDC_500, UniswapV3Pool.abi, provider)
const poolData = await getPoolData(poolContract)
console.log('poolData', poolData)
}
/*
npx hardhat run --network localhost scripts/05_checkLiquidity.js
*/
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
require("@nomiclabs/hardhat-waffle");
module.exports = {
solidity: {
version: "0.8.17",
settings: {
optimizer: {
enabled: true,
runs: 5000,
details: { yul: false },
},
}
},
};
{
"name": "hardhat-v3-deploy-local-2",
"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.1.1",
"@nomiclabs/hardhat-waffle": "^2.0.3",
"@openzeppelin/contracts": "^4.7.3",
"@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.1",
"hardhat": "^2.11.2"
}
}
pragma solidity ^0.8.0;
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);
}
}
pragma solidity ^0.8.0;
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"
}
]
}
pragma solidity ^0.8.0;
import '@openzeppelin/contracts/token/ERC20/ERC20.sol';
import "@openzeppelin/contracts/access/Ownable.sol";
contract WrappedBitcoin is ERC20, Ownable {
constructor() ERC20('WrappedBitcoin', 'WBTC') {}
function mint(address to, uint256 amount) public onlyOwner {
_mint(to, amount);
}
}
@lxiiiixi
Copy link

lxiiiixi commented Nov 9, 2024

I am very happy about that I successfully executed the entire deployment process, thank you very much!!! 🥰

@peter-mwau
Copy link

Hi @lxiiiixi,
I'm working on the local deployment and running into the same issue — a missing parameter error when deploying the NonfungibleTokenPositionDescriptor contract. Could you please clarify what your second parameter was that resolved the issue?

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