punkkit-sdk 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env +47 -0
- package/.gitmodules +3 -0
- package/README.md +158 -0
- package/config/auction.config.ts +40 -0
- package/config/env.config.ts +204 -0
- package/config/uniswap.config.ts +107 -0
- package/config/voucher.config.ts +10 -0
- package/contracts/MutiVoucher.sol +78 -0
- package/contracts/auction/ChainXAuction.sol +177 -0
- package/contracts/auction/ChainXAuctionV2.sol +672 -0
- package/contracts/auction/ChainXWrappedETH.sol +80 -0
- package/contracts/auction/ChainYLiquidityManager.sol +57 -0
- package/contracts/auction/ChainYShadowETH.sol +148 -0
- package/contracts/auction/ChainYVault.sol +195 -0
- package/contracts/auction/ChainYVaultCoinbase.sol +276 -0
- package/contracts/auction/ChainYVaultV2.sol +318 -0
- package/contracts/auction/coinbase-and-stake/README.md +55 -0
- package/contracts/auction/coinbase-and-stake/coinbase.sol +142 -0
- package/contracts/auction/coinbase-and-stake/invokeCoinbase.sol +159 -0
- package/contracts/auction/coinbase-and-stake/invokeStake.sol +82 -0
- package/contracts/auction/coinbase-and-stake/stake.sol +92 -0
- package/contracts/auction/interfaces/IUniswapV2Factory.sol +15 -0
- package/contracts/auction/interfaces/IUniswapV2Pair.sol +53 -0
- package/contracts/auction/interfaces/IUniswapV2Router02.sol +25 -0
- package/contracts/auction/interfaces/IUnlockStrategy.sol +18 -0
- package/contracts/auction/libraries/EventParser.sol +32 -0
- package/contracts/auction/libraries/TransactionParser.sol +70 -0
- package/contracts/auction/strategies/MatchResultWithdrawnStrategy.sol +33 -0
- package/contracts/auction/utils/BytesLib.sol +180 -0
- package/contracts/auction/utils/RLPReader.sol +355 -0
- package/contracts/uniswap/Create2.sol +80 -0
- package/contracts/uniswap/DynamicFee.sol +100 -0
- package/contracts/uniswap/Example.sol +35 -0
- package/contracts/uniswap/HookMiner.sol +52 -0
- package/contracts/uniswap/LimitOrder.sol +486 -0
- package/contracts/uniswap/LiquidPool.sol +179 -0
- package/contracts/uniswap/MockERC20.sol +20 -0
- package/hardhat.config.ts +35 -0
- package/ignition/modules/LimitOrder.ts +33 -0
- package/package.json +32 -0
- package/scripts/auction/deploy.ts +23 -0
- package/scripts/auction/deployCoinbase.ts +21 -0
- package/scripts/auction/deployXAuction.ts +23 -0
- package/scripts/auction/deployYVault.ts +22 -0
- package/scripts/deploy_voucher.ts +20 -0
- package/scripts/uniswap/deploy/deploy.ts +65 -0
- package/scripts/uniswap/deploy/deploy_create2.ts +11 -0
- package/scripts/uniswap/deploy/deploy_example.ts +35 -0
- package/scripts/uniswap/deploy/deploy_hooks.ts +74 -0
- package/scripts/uniswap/deploy/deploy_mockERC20.ts +42 -0
- package/scripts/uniswap/deploy/help.ts +96 -0
- package/scripts/uniswap/deploy/init.ts +70 -0
- package/src/auction/chainXAuction.ts +209 -0
- package/src/auction/chainYVault.ts +153 -0
- package/src/auction/event.ts +19 -0
- package/src/auction/serialize.ts +162 -0
- package/src/auction/type.ts +71 -0
- package/src/lib/signer.ts +20 -0
- package/src/lib/unlock.ts +14 -0
- package/src/uniswap/1-marketprice/addLiquidity.ts +80 -0
- package/src/uniswap/1-marketprice/removeLiquidity.ts +63 -0
- package/src/uniswap/1-marketprice/swap.ts +100 -0
- package/src/uniswap/2-limitorder/kill.ts +70 -0
- package/src/uniswap/2-limitorder/place.ts +93 -0
- package/src/uniswap/2-limitorder/withdraw.ts +78 -0
- package/src/uniswap/3-dynamicfee/dynamicfee.ts +321 -0
- package/src/uniswap/lib/ERC20.ts +49 -0
- package/src/uniswap/lib/contract.ts +18 -0
- package/src/uniswap/lib/limitOrder.ts +40 -0
- package/src/uniswap/lib/liqCalculation.ts +152 -0
- package/src/uniswap/lib/listen.ts +57 -0
- package/src/uniswap/lib/pool.ts +62 -0
- package/src/uniswap/lib/swap.ts +8 -0
- package/src/uniswap/lib/types.ts +21 -0
- package/src/uniswap/lib/utils.ts +26 -0
- package/src/uniswap/playgroud/abiencode.ts +21 -0
- package/src/uniswap/playgroud/amount0.ts +47 -0
- package/src/uniswap/playgroud/errordecode.ts +54 -0
- package/src/uniswap/playgroud/errorsigs.ts +86 -0
- package/src/voucher.ts +122 -0
- package/test/auction/ChainXAuctionV2.test.ts +265 -0
- package/test/auction/ChainYVaultV2.test.js +163 -0
- package/test/auction/ChainYVaultV2.test.ts +183 -0
- package/test/auction/auction.test.ts +106 -0
- package/test/connect_punk.test.ts +26 -0
- package/test/create2.test.ts +44 -0
- package/test/normal.ts +43 -0
- package/test/test-config.ts +18 -0
- package/test/uniswap/example.test.ts +62 -0
- package/test/uniswap/limitOrder.test.ts +184 -0
- package/test/uniswap/mockERC20.test.ts +142 -0
- package/test/voucher_hardhat.test.ts +120 -0
- package/test/voucher_punk.test.ts +83 -0
- package/tsconfig.json +11 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { ethers } from "hardhat";
|
|
2
|
+
import type { Contract } from "ethers";
|
|
3
|
+
import { PoolKey, ModifyPositionParams } from "./types";
|
|
4
|
+
|
|
5
|
+
export async function modifyPosition(contract: Contract, modifyPositionParams: ModifyPositionParams, hookData: string) {
|
|
6
|
+
// Add liquidity
|
|
7
|
+
const tx = await contract.addLiquidity(modifyPositionParams, hookData);
|
|
8
|
+
await tx.wait();
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// Function to get Pool ID
|
|
12
|
+
export function getPoolId(poolKey: PoolKey): string {
|
|
13
|
+
;
|
|
14
|
+
return ethers.utils.keccak256(ethers.utils.solidityPack(
|
|
15
|
+
["bytes"],
|
|
16
|
+
[ethers.utils.defaultAbiCoder.encode(
|
|
17
|
+
["address", "address", "uint24", "int24", "address"],
|
|
18
|
+
[poolKey.currency0, poolKey.currency1, poolKey.fee, poolKey.tickSpacing, poolKey.hooks]
|
|
19
|
+
)]
|
|
20
|
+
));
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Function to get Slot0 of the Pool
|
|
24
|
+
async function getSlot0(contract: Contract) {
|
|
25
|
+
const slot0 = await contract.getSlot0();
|
|
26
|
+
// console.log(`Returned slot0: ${JSON.stringify(slot0)}`);
|
|
27
|
+
return slot0;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Function to get Liquidity of the Pool
|
|
31
|
+
export async function getLiquidity(contract: Contract, poolKey: PoolKey) {
|
|
32
|
+
const poolId = getPoolId(poolKey);
|
|
33
|
+
console.log(`PoolId: ${poolId}`);
|
|
34
|
+
|
|
35
|
+
const liquidity = await contract.getLiquidity(poolId);
|
|
36
|
+
console.log(`Returned liquidity: ${liquidity}`);
|
|
37
|
+
return liquidity;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export async function getPoolSqrtPrice(liqPool: Contract): Promise<bigint> {
|
|
41
|
+
const slot0 = await getSlot0(liqPool);
|
|
42
|
+
return slot0[0].toBigInt();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Function to get Pool Price
|
|
46
|
+
export async function getPoolPrice(liqPool: Contract): Promise<number> {
|
|
47
|
+
const slot0 = await getSlot0(liqPool);
|
|
48
|
+
const q96 = 2n ** 96n;
|
|
49
|
+
// slot0 type is @BigNumber
|
|
50
|
+
const sqrtPriceX96:bigint = slot0[0].toBigInt();
|
|
51
|
+
|
|
52
|
+
const priceX1e18 = (sqrtPriceX96 * sqrtPriceX96 * (10n ** 18n)) / (q96 * q96);
|
|
53
|
+
const result = Number(priceX1e18) / 10**18;
|
|
54
|
+
// console.log("price:", result.toString());
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export async function getCurrentTick(liqPool: Contract): Promise<number> {
|
|
59
|
+
const slot0 = await getSlot0(liqPool);
|
|
60
|
+
const tick: number = slot0[1];
|
|
61
|
+
return tick;
|
|
62
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Contract } from "ethers";
|
|
2
|
+
import { SwapParams } from "./types";
|
|
3
|
+
|
|
4
|
+
export async function executeSwap(contract: Contract, swapParams: SwapParams, hookData: string) {
|
|
5
|
+
let tx = await contract.executeSwap(swapParams, hookData);
|
|
6
|
+
await tx.wait();
|
|
7
|
+
console.log("Swap executed successfully");
|
|
8
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
|
|
2
|
+
export interface PoolKey {
|
|
3
|
+
currency0: string;
|
|
4
|
+
currency1: string;
|
|
5
|
+
fee: number;
|
|
6
|
+
tickSpacing: number;
|
|
7
|
+
hooks: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface SwapParams {
|
|
11
|
+
zeroForOne: boolean;
|
|
12
|
+
amountSpecified: bigint;
|
|
13
|
+
sqrtPriceLimitX96: bigint;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface ModifyPositionParams {
|
|
17
|
+
tickLower: number; // 流动性生效最低价格
|
|
18
|
+
tickUpper: number; // 流动性生效最高价格
|
|
19
|
+
liquidityDelta: bigint;
|
|
20
|
+
salt?:string;
|
|
21
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// JsonRpcProvider is runtime object
|
|
2
|
+
import { JsonRpcProvider } from "@ethersproject/providers";
|
|
3
|
+
import { ethers } from "hardhat"
|
|
4
|
+
|
|
5
|
+
export async function isDeployed(provider: JsonRpcProvider, address: string) {
|
|
6
|
+
let code = await provider.getCode(address);
|
|
7
|
+
// console.log("code =", code);
|
|
8
|
+
return code !== "0x";
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function bigintToBytes32(value : bigint): string {
|
|
12
|
+
return ethers.utils.id(value.toString());
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Function to encode the parameters
|
|
16
|
+
export function abiEncode(types: string[], values: any[]): string {
|
|
17
|
+
const abiCoder = ethers.utils.defaultAbiCoder;
|
|
18
|
+
const encodedParams = abiCoder.encode(types, values);
|
|
19
|
+
return encodedParams;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function bytecodeWithArgs(bytecode: string, types: string[], params: any[]): string {
|
|
23
|
+
const encodedParams = abiEncode(types, params);
|
|
24
|
+
const initCode = ethers.utils.hexConcat([bytecode, encodedParams]);
|
|
25
|
+
return initCode;
|
|
26
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ethers } from "hardhat";
|
|
2
|
+
import { ModifyPositionParams } from "../lib/types";
|
|
3
|
+
|
|
4
|
+
// Example ModifyLiquidityParams
|
|
5
|
+
const positionParams: ModifyPositionParams = {
|
|
6
|
+
tickLower: 84222,
|
|
7
|
+
tickUpper: 86129,
|
|
8
|
+
liquidityDelta: BigInt("1517882343751509868544"),
|
|
9
|
+
salt: ethers.utils.keccak256("0x00")
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
// Example hookData as a hex string
|
|
13
|
+
const hookData = "0x10";
|
|
14
|
+
|
|
15
|
+
// Get ABI encoding
|
|
16
|
+
const encodedData = ethers.utils.defaultAbiCoder.encode(
|
|
17
|
+
["tuple(int24,int24,int256,bytes32)", "bytes"],
|
|
18
|
+
[positionParams, hookData]
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
console.log("Encoded Data:", encodedData);
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { BigNumber } from 'ethers';
|
|
2
|
+
import { amount0 } from '../lib/liqCalculation';
|
|
3
|
+
|
|
4
|
+
// FullMath.mulDivRoundingUp: Multiplies two numbers and divides the result by a denominator, rounding up
|
|
5
|
+
function mulDivRoundingUp(a: BigNumber, b: BigNumber, denominator: BigNumber): BigNumber {
|
|
6
|
+
const product = a.mul(b);
|
|
7
|
+
const remainder = product.mod(denominator);
|
|
8
|
+
const quotient = product.div(denominator);
|
|
9
|
+
return remainder.isZero() ? quotient : quotient.add(1);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// UnsafeMath.divRoundingUp: Divides two numbers, rounding up
|
|
13
|
+
function divRoundingUp(a: BigNumber, b: BigNumber): BigNumber {
|
|
14
|
+
const remainder = a.mod(b);
|
|
15
|
+
const quotient = a.div(b);
|
|
16
|
+
return remainder.isZero() ? quotient : quotient.add(1);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Example usage
|
|
20
|
+
function calculateAmount0Delta(
|
|
21
|
+
numerator1: BigNumber,
|
|
22
|
+
numerator2: BigNumber,
|
|
23
|
+
sqrtPriceBX96: BigNumber,
|
|
24
|
+
sqrtPriceAX96: BigNumber
|
|
25
|
+
): BigNumber {
|
|
26
|
+
// Equivalent to the Solidity code snippet
|
|
27
|
+
return divRoundingUp(mulDivRoundingUp(numerator1, numerator2, sqrtPriceBX96), sqrtPriceAX96);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Define the FixedPoint96 resolution (2^96)
|
|
31
|
+
const FixedPoint96_RESOLUTION = BigNumber.from(2).pow(96);
|
|
32
|
+
|
|
33
|
+
// Example values for liquidity, sqrtPriceAX96, and sqrtPriceBX96
|
|
34
|
+
// ref: test/libraries/SqrtPriceMath.t.sol, test_swapComputation_sqrtPTimessqrtQOverflows, line 337
|
|
35
|
+
const liquidity = BigNumber.from("50015962439936049619261659728067971248"); // Example value
|
|
36
|
+
const sqrtPriceAX96 = BigNumber.from("1025574284609383582644711336373707553698163132913"); // Example value
|
|
37
|
+
const sqrtPriceBX96 = BigNumber.from("1025574284609383690408304870162715216695788925244"); // Example value
|
|
38
|
+
|
|
39
|
+
// Calculate numerator1 and numerator2
|
|
40
|
+
const numerator1 = liquidity.mul(FixedPoint96_RESOLUTION); // This is equivalent to shifting left by the FixedPoint96 resolution
|
|
41
|
+
const numerator2 = sqrtPriceBX96.sub(sqrtPriceAX96);
|
|
42
|
+
|
|
43
|
+
const result = calculateAmount0Delta(numerator1, numerator2, sqrtPriceBX96, sqrtPriceAX96);
|
|
44
|
+
console.log(result.toString());
|
|
45
|
+
|
|
46
|
+
const result2 = amount0(liquidity.toBigInt(), sqrtPriceBX96.toBigInt(), sqrtPriceAX96.toBigInt());
|
|
47
|
+
console.log(result2.toString());
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { ethers } from "ethers";
|
|
2
|
+
|
|
3
|
+
interface DecodedData {
|
|
4
|
+
functionSelector: string;
|
|
5
|
+
address: string;
|
|
6
|
+
fixedInteger: number;
|
|
7
|
+
offset: number;
|
|
8
|
+
errorFunctionSelector: string;
|
|
9
|
+
stringLength: number;
|
|
10
|
+
stringData: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function hexToString(hex: string): string {
|
|
14
|
+
// Remove the '0x' prefix if present
|
|
15
|
+
hex = hex.replace(/^0x/, '');
|
|
16
|
+
|
|
17
|
+
// Convert hex to bytes
|
|
18
|
+
const bytes = Buffer.from(hex, 'hex');
|
|
19
|
+
|
|
20
|
+
// Convert bytes to string using UTF-8 encoding
|
|
21
|
+
return bytes.toString('utf8');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function decodeData(encodedData: string): DecodedData {
|
|
25
|
+
const functionSelector = encodedData.slice(0, 10);
|
|
26
|
+
const address = `0x${encodedData.slice(34, 74)}`;
|
|
27
|
+
const fixedInteger = parseInt(encodedData.slice(74, 138), 16);
|
|
28
|
+
const offset = parseInt(encodedData.slice(138, 202), 16);
|
|
29
|
+
let errorFunctionSelector, stringLength, stringData;
|
|
30
|
+
if (offset != 0 ) {
|
|
31
|
+
errorFunctionSelector = `0x${encodedData.slice(202, 210)}`;
|
|
32
|
+
const offset = parseInt(encodedData.slice(210, 274), 16);
|
|
33
|
+
stringLength = parseInt(encodedData.slice(274, 338), 16);
|
|
34
|
+
stringData = hexToString(`0x${encodedData.slice(338, 338 + stringLength * 2)}`);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
functionSelector,
|
|
39
|
+
address,
|
|
40
|
+
fixedInteger,
|
|
41
|
+
offset,
|
|
42
|
+
errorFunctionSelector,
|
|
43
|
+
stringLength,
|
|
44
|
+
stringData
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Test the function with the provided data
|
|
49
|
+
const data1 = "0x319d54c3000000000000000000000000a1353ea8013d59ce815bf2fe7211e61e5519d0400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006408c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000c636f72726563742073616c74000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
|
|
50
|
+
const data2 = "0x319d54c3000000000000000000000000a1353ea8013d59ce815bf2fe7211e61e5519d0400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006408c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000a77726f6e672073616c740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
|
|
51
|
+
const data3 = "0x319d54c3000000000000000000000000867cd373c2567a10bc512f05771e55e73e67d0400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000429c3b7ee00000000000000000000000000000000000000000000000000000000";
|
|
52
|
+
const data4 = "0xb12c5f9c000000000000000000000000d9b3d09f662b3b5479a785ac6aba5dd17a132dc300000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000064e450d38c0000000000000000000000004132f0bebb312245fd4c33d1177a617a98691040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006db11235f6ec6a4c0100000000000000000000000000000000000000000000000000000000"
|
|
53
|
+
|
|
54
|
+
console.log(decodeData(data4));
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { ethers } from "hardhat";
|
|
2
|
+
|
|
3
|
+
// Define an array of error signatures
|
|
4
|
+
// Error NotSelf(): 0x29c3b7ee
|
|
5
|
+
// Error HookAddressNotValid(address): 0xe65af6a0
|
|
6
|
+
// Error InvalidHookResponse(): 0x1e048e1d
|
|
7
|
+
// Error Wrap__FailedHookCall(address,bytes): 0x319d54c3
|
|
8
|
+
// Error ProtocolFeeCannotBeFetched(): 0x1ee49702
|
|
9
|
+
// Error AlreadyUnlocked(): 0x5090d6c6
|
|
10
|
+
// Error NotPoolManager(): 0xae18210a
|
|
11
|
+
// Error CurrencyNotSettled: 0x5212cba1
|
|
12
|
+
// Error PoolAlreadyInitialized(): 0x7983c051
|
|
13
|
+
// Error PoolNotInitialized(): 0x486aa307
|
|
14
|
+
// Error PriceLimitAlreadyExceeded(uint160,uint160): 0x7c9c6e8f
|
|
15
|
+
// Error NonZeroNativeValue(): 0x19d245cf
|
|
16
|
+
// Error ERC20InsufficientBalance(address,uint256,uint256): 0xe450d38c
|
|
17
|
+
// Error ERC20InsufficientAllowance(address,uint256,uint256): 0xfb8f41b2
|
|
18
|
+
// Error Wrap__NativeTransferFailed(address,bytes): 0x8549db59
|
|
19
|
+
// Error Wrap__ERC20TransferFailed(address,bytes): 0xb12c5f9c
|
|
20
|
+
// Error NotPoolManager(): 0xae18210a
|
|
21
|
+
// Error NotFilled(): 0x6cb6fbf0
|
|
22
|
+
// Error InvalidFunc(bytes4): 0x1f8f8d4b
|
|
23
|
+
// Error ZeroLiquidity(): 0x10074548
|
|
24
|
+
// Error InRange(): 0x23ac68e7
|
|
25
|
+
// Error CrossedRange(): 0xb319920d
|
|
26
|
+
const errorSignatures = [
|
|
27
|
+
// Hooks.sol
|
|
28
|
+
'NotSelf()',
|
|
29
|
+
'HookAddressNotValid(address)',
|
|
30
|
+
'InvalidHookResponse()',
|
|
31
|
+
'Wrap__FailedHookCall(address,bytes)',
|
|
32
|
+
|
|
33
|
+
'ProtocolFeeCannotBeFetched()',
|
|
34
|
+
|
|
35
|
+
// PoolManager.sol
|
|
36
|
+
'AlreadyUnlocked()',
|
|
37
|
+
'NotPoolManager()',
|
|
38
|
+
'CurrencyNotSettled()',
|
|
39
|
+
'PoolAlreadyInitialized()',
|
|
40
|
+
'PoolNotInitialized()',
|
|
41
|
+
'PriceLimitAlreadyExceeded(uint160,uint160)',
|
|
42
|
+
'NonZeroNativeValue()',
|
|
43
|
+
|
|
44
|
+
// ERC20.sol
|
|
45
|
+
'ERC20InsufficientBalance(address,uint256,uint256)',
|
|
46
|
+
'ERC20InsufficientAllowance(address,uint256,uint256)',
|
|
47
|
+
|
|
48
|
+
'Wrap__NativeTransferFailed(address,bytes)',
|
|
49
|
+
'Wrap__ERC20TransferFailed(address,bytes)',
|
|
50
|
+
|
|
51
|
+
// SafeCallBack.sol
|
|
52
|
+
'NotPoolManager()',
|
|
53
|
+
|
|
54
|
+
// LimitOrder.sol
|
|
55
|
+
'NotFilled()',
|
|
56
|
+
'InvalidFunc(bytes4)',
|
|
57
|
+
'ZeroLiquidity()',
|
|
58
|
+
'InRange()',
|
|
59
|
+
'CrossedRange()',
|
|
60
|
+
];
|
|
61
|
+
|
|
62
|
+
// FuncSig afterInitialize(address,PoolKey,uint160,int24,bytes): 0x105397c6
|
|
63
|
+
// FuncSig lockAcquiredPlace((address,address,uint24,int24,address),int24,bool,int256,address,bytes32): 0x3f3e517d
|
|
64
|
+
const funcSignatures = [
|
|
65
|
+
'afterInitialize(address,PoolKey,uint160,int24,bytes)',
|
|
66
|
+
|
|
67
|
+
// LimitOrder.sol
|
|
68
|
+
'lockAcquiredPlace((address,address,uint24,int24,address),int24,bool,int256,address,bytes32)'
|
|
69
|
+
]
|
|
70
|
+
|
|
71
|
+
// Function to compute the function selector for an error signature
|
|
72
|
+
const computeFunctionSelector = (signature: string): string => {
|
|
73
|
+
const hash = ethers.keccak256(ethers.toUtf8Bytes(signature));
|
|
74
|
+
return hash.slice(0, 10); // "0x" + 8 hex characters
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
// Iterate over the error signatures and compute their function selectors
|
|
78
|
+
errorSignatures.forEach((signature) => {
|
|
79
|
+
const functionSelector = computeFunctionSelector(signature);
|
|
80
|
+
console.log(`Error ${signature}: ${functionSelector}`);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
funcSignatures.forEach((signature) => {
|
|
84
|
+
const functionSelector = computeFunctionSelector(signature);
|
|
85
|
+
console.log(`FuncSig ${signature}: ${functionSelector}`);
|
|
86
|
+
});
|
package/src/voucher.ts
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BigNumber,
|
|
3
|
+
BigNumberish,
|
|
4
|
+
Contract,
|
|
5
|
+
ContractTransaction,
|
|
6
|
+
Signer,
|
|
7
|
+
providers,
|
|
8
|
+
utils,
|
|
9
|
+
} from "ethers";
|
|
10
|
+
|
|
11
|
+
import { MUTI_VOUCHER_ABI,MUTI_VOUCHER_ADDR } from "../config/voucher.config";
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
export const mutiVoucherABI = MUTI_VOUCHER_ABI.abi;
|
|
15
|
+
|
|
16
|
+
export type SignerOrProvider = Signer | providers.Provider;
|
|
17
|
+
|
|
18
|
+
export function getVoucherContract(
|
|
19
|
+
contractAddress: string,
|
|
20
|
+
signerOrProvider: SignerOrProvider
|
|
21
|
+
): Contract {
|
|
22
|
+
return new Contract(contractAddress, mutiVoucherABI, signerOrProvider);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export async function createVoucher(
|
|
26
|
+
contractAddress: string,
|
|
27
|
+
signer: Signer,
|
|
28
|
+
name: string,
|
|
29
|
+
conversionRate: BigNumberish
|
|
30
|
+
): Promise<ContractTransaction> {
|
|
31
|
+
const contract = getVoucherContract(contractAddress, signer);
|
|
32
|
+
return contract.createVoucher(name, conversionRate);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export async function getVoucherInfo(
|
|
36
|
+
contractAddress: string,
|
|
37
|
+
provider: SignerOrProvider,
|
|
38
|
+
name: string
|
|
39
|
+
): Promise<BigNumber> {
|
|
40
|
+
const contract = getVoucherContract(contractAddress, provider);
|
|
41
|
+
return contract.getVoucherInfo(name);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export async function buyVoucher(
|
|
45
|
+
contractAddress: string,
|
|
46
|
+
signer: Signer,
|
|
47
|
+
name: string,
|
|
48
|
+
valueWei: BigNumberish
|
|
49
|
+
): Promise<ContractTransaction> {
|
|
50
|
+
const contract = getVoucherContract(contractAddress, signer);
|
|
51
|
+
return contract.buy(name, { value: valueWei });
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export async function buyVoucherWithEth(
|
|
55
|
+
contractAddress: string,
|
|
56
|
+
signer: Signer,
|
|
57
|
+
name: string,
|
|
58
|
+
valueEth: string
|
|
59
|
+
): Promise<ContractTransaction> {
|
|
60
|
+
const valueWei = utils.parseEther(valueEth);
|
|
61
|
+
return buyVoucher(contractAddress, signer, name, valueWei);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// UseVoucher不是直接调用的
|
|
65
|
+
export async function useVoucher(
|
|
66
|
+
contractAddress: string,
|
|
67
|
+
signer: Signer,
|
|
68
|
+
name: string,
|
|
69
|
+
amount: BigNumberish
|
|
70
|
+
): Promise<ContractTransaction> {
|
|
71
|
+
const contract = getVoucherContract(contractAddress, signer);
|
|
72
|
+
return contract.use(name, amount);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export async function balanceOf(
|
|
76
|
+
contractAddress: string,
|
|
77
|
+
provider: SignerOrProvider,
|
|
78
|
+
name: string,
|
|
79
|
+
user: string
|
|
80
|
+
): Promise<BigNumber> {
|
|
81
|
+
const contract = getVoucherContract(contractAddress, provider);
|
|
82
|
+
return contract.balanceOf(name, user);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export async function getAllVouchers(
|
|
86
|
+
contractAddress: string,
|
|
87
|
+
provider: SignerOrProvider
|
|
88
|
+
): Promise<string[]> {
|
|
89
|
+
const contract = getVoucherContract(contractAddress, provider);
|
|
90
|
+
return contract.getAllVouchers();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// 仅仅能够在punk链上使用
|
|
94
|
+
function buildUseVoucherPrefix(voucherNameBytes32: string): string {
|
|
95
|
+
const nameHex = utils.hexlify(voucherNameBytes32).replace(
|
|
96
|
+
/^0x/,
|
|
97
|
+
""
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
if (nameHex.length > 64) {
|
|
101
|
+
throw new Error("Voucher name too long for 32 bytes");
|
|
102
|
+
}
|
|
103
|
+
const paddedName = nameHex.padEnd(64, "0");
|
|
104
|
+
console.log(paddedName)
|
|
105
|
+
return `0x0A0D03${paddedName}`;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// 仅仅能够在punk链上使用
|
|
109
|
+
export function BuildUseVoucherTx(
|
|
110
|
+
tx: providers.TransactionRequest,
|
|
111
|
+
voucherName: string
|
|
112
|
+
): providers.TransactionRequest {
|
|
113
|
+
const prefix = buildUseVoucherPrefix(voucherName);
|
|
114
|
+
const rawData = tx.data ?? "0x";
|
|
115
|
+
const dataHex = utils.hexlify(rawData);
|
|
116
|
+
const mergedData = utils.hexConcat([prefix, dataHex]);
|
|
117
|
+
|
|
118
|
+
return {
|
|
119
|
+
...tx,
|
|
120
|
+
data: mergedData,
|
|
121
|
+
};
|
|
122
|
+
}
|