-
Notifications
You must be signed in to change notification settings - Fork 34
feat: uniswap v3 deployment and liquidity commands #295
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 41 commits
9b9d630
3d4725e
5c52248
2209951
ba4ae4b
dc308ae
9fd0071
442977d
50362ab
fe543e4
691b2fb
f6a7c28
2f6a239
f49f222
28cad95
3ea1b78
c6bfb85
d16debf
b15c2db
27a0062
0234c46
6f1553b
2985c00
e09172a
4904414
1aa83e7
6907609
4bc23f3
653ad1f
cfea79d
cfb9973
8b6e857
4dc7f2c
1fd27fd
583a152
dff4ad9
d26804c
1795013
228b66d
01acd19
a3d96c5
439a441
de14ad5
cf8946f
b8e2bd3
16bca71
01757b2
e01d06f
4cfa442
66e1330
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,159 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/******************************************************************** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* pools create — create a V3 pool and initialise it if required | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
*******************************************************************/ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import * as UniswapV3Factory from "@uniswap/v3-core/artifacts/contracts/UniswapV3Factory.sol/UniswapV3Factory.json"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import * as UniswapV3Pool from "@uniswap/v3-core/artifacts/contracts/UniswapV3Pool.sol/UniswapV3Pool.json"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { IERC20Metadata__factory } from "../../../../../typechain-types"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { Command } from "commander"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { Contract, ethers, JsonRpcProvider, Wallet } from "ethers"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
DEFAULT_FACTORY, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
DEFAULT_FEE, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
DEFAULT_RPC, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} from "../../../../../src/constants/pools"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
createPoolOptionsSchema, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
type CreatePoolOptions, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
PoolCreationError, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} from "../../../../../types/pools"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/* ─── helpers ---------------------------------------------------- */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const SCALE = 1_000_000_000_000_000_000n; // 1e18 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const TWO_192 = 1n << 192n; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
function sqrtBig(n: bigint): bigint { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Check warning on line 24 in packages/commands/src/zetachain/pools/create.ts
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// integer √ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (n < 2n) return n; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let x = n, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
y = (x + 1n) >> 1n; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
while (y < x) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
x = y; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
y = (x + n / x) >> 1n; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return x; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/** sqrtPriceX96 = √(price₁ / price₀) × 2⁹⁶ (token1/token0) */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
function buildSqrtPriceX96( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Check warning on line 36 in packages/commands/src/zetachain/pools/create.ts
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
usd0: number, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
usd1: number, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
dec0: number, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
dec1: number, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
cliToken0: boolean | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
): bigint { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// USD prices mapped to factory order | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const pTok0 = BigInt(Math.round((cliToken0 ? usd0 : usd1) * 1e18)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const pTok1 = BigInt(Math.round((cliToken0 ? usd1 : usd0) * 1e18)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// token1/token0 ratio in base-units, scaled by 2¹⁹² | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const num = pTok1 * 10n ** BigInt(dec0); // p₁ × 10^dec₀ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const den = pTok0 * 10n ** BigInt(dec1); // p₀ × 10^dec₁ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const ratioX192 = (num << 192n) / den; // shift before divide | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (ratioX192 === 0n) throw new Error("ratio underflow – raise precision"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/* integer √ → Q64.96 */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return sqrtBig(ratioX192); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/* ─── main ------------------------------------------------------- */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const main = async (raw: CreatePoolOptions) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const o = createPoolOptionsSchema.parse(raw); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const [usdA, usdB] = o.prices.map(Number); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const provider = new JsonRpcProvider(o.rpc ?? DEFAULT_RPC); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const signer = new Wallet(o.privateKey, provider); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/* factory --------------------------------------------------- */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const factory = new Contract( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
o.factory ?? DEFAULT_FACTORY, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
UniswapV3Factory.abi, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
signer | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let poolAddr = await factory.getPool( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
o.tokens[0], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
o.tokens[1], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
o.fee ?? DEFAULT_FEE | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (poolAddr === ethers.ZeroAddress) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
console.log("Creating pool …"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const tx = await factory.createPool( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
o.tokens[0], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
o.tokens[1], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
o.fee ?? DEFAULT_FEE | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await tx.wait(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Check failure on line 86 in packages/commands/src/zetachain/pools/create.ts
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
poolAddr = await factory.getPool( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
let poolAddr = await factory.getPool( | |
o.tokens[0], | |
o.tokens[1], | |
o.fee ?? DEFAULT_FEE | |
); | |
if (poolAddr === ethers.ZeroAddress) { | |
console.log("Creating pool …"); | |
const tx = await factory.createPool( | |
o.tokens[0], | |
o.tokens[1], | |
o.fee ?? DEFAULT_FEE | |
); | |
await tx.wait(); | |
poolAddr = await factory.getPool( | |
let poolAddr = await factory.getPool( | |
o.tokens[0], | |
o.tokens[1], | |
o.fee ?? DEFAULT_FEE | |
); | |
if (poolAddr === ethers.ZeroAddress) { | |
console.log("Creating pool …"); | |
const tx = await factory.createPool( | |
o.tokens[0], | |
o.tokens[1], | |
o.fee ?? DEFAULT_FEE | |
); | |
- await tx.wait(); | |
+ const receipt = await tx.wait(); | |
+ if (receipt?.status !== 1) { | |
+ throw new Error(`createPool failed (tx: ${tx.hash})`); | |
+ } | |
poolAddr = await factory.getPool( | |
o.tokens[0], | |
o.tokens[1], | |
o.fee ?? DEFAULT_FEE | |
); | |
} |
🧰 Tools
🪛 GitHub Check: build
[failure] 87-87:
Unsafe assignment of an any
value
[failure] 86-86:
Unsafe member access .wait on an any
value
[failure] 86-86:
Unsafe call of an any
typed value
[failure] 81-81:
Unsafe assignment of an any
value
[failure] 73-73:
Unsafe assignment of an any
value
🤖 Prompt for AI Agents
In packages/commands/src/zetachain/pools/create.ts around lines 73 to 87, the
calls to factory.createPool and tx.wait() are typed as any, which disables
static type checking and error detection. To fix this, import the generated
typings UniswapV3Factory__factory and use them to instantiate the factory so
getPool returns Promise<string> and createPool returns ContractTransaction.
After awaiting tx.wait(), check the receipt.status field and throw an error if
the transaction failed to ensure the code does not incorrectly assume success.
Uh oh!
There was an error while loading. Please reload this page.