@net-protocol/score 0.1.0 → 0.1.1
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/README.md +229 -0
- package/dist/index.d.mts +39 -4
- package/dist/index.d.ts +39 -4
- package/dist/index.js +667 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +660 -1
- package/dist/index.mjs.map +1 -1
- package/dist/react.d.mts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js.map +1 -1
- package/dist/react.mjs.map +1 -1
- package/dist/{scoreKeyUtils-DIjbizO-.d.mts → scoreKeyUtils-Dn43l8hQ.d.mts} +14 -1
- package/dist/{scoreKeyUtils-DIjbizO-.d.ts → scoreKeyUtils-Dn43l8hQ.d.ts} +14 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1657,6 +1657,283 @@ var dynamic_split_strategy_default = [
|
|
|
1657
1657
|
}
|
|
1658
1658
|
];
|
|
1659
1659
|
|
|
1660
|
+
// src/abis/multi-version-uniswap-bulk-pool-finder.json
|
|
1661
|
+
var multi_version_uniswap_bulk_pool_finder_default = [
|
|
1662
|
+
{
|
|
1663
|
+
type: "function",
|
|
1664
|
+
name: "V2_FACTORY",
|
|
1665
|
+
inputs: [],
|
|
1666
|
+
outputs: [{ name: "", type: "address", internalType: "address" }],
|
|
1667
|
+
stateMutability: "view"
|
|
1668
|
+
},
|
|
1669
|
+
{
|
|
1670
|
+
type: "function",
|
|
1671
|
+
name: "V3_FACTORY",
|
|
1672
|
+
inputs: [],
|
|
1673
|
+
outputs: [{ name: "", type: "address", internalType: "address" }],
|
|
1674
|
+
stateMutability: "view"
|
|
1675
|
+
},
|
|
1676
|
+
{
|
|
1677
|
+
type: "function",
|
|
1678
|
+
name: "V4_POOL_MANAGER",
|
|
1679
|
+
inputs: [],
|
|
1680
|
+
outputs: [{ name: "", type: "address", internalType: "address" }],
|
|
1681
|
+
stateMutability: "view"
|
|
1682
|
+
},
|
|
1683
|
+
{
|
|
1684
|
+
type: "function",
|
|
1685
|
+
name: "_checkV4PoolExternal",
|
|
1686
|
+
inputs: [
|
|
1687
|
+
{
|
|
1688
|
+
name: "poolKey",
|
|
1689
|
+
type: "tuple",
|
|
1690
|
+
internalType: "struct PoolKey",
|
|
1691
|
+
components: [
|
|
1692
|
+
{
|
|
1693
|
+
name: "currency0",
|
|
1694
|
+
type: "address",
|
|
1695
|
+
internalType: "Currency"
|
|
1696
|
+
},
|
|
1697
|
+
{
|
|
1698
|
+
name: "currency1",
|
|
1699
|
+
type: "address",
|
|
1700
|
+
internalType: "Currency"
|
|
1701
|
+
},
|
|
1702
|
+
{ name: "fee", type: "uint24", internalType: "uint24" },
|
|
1703
|
+
{ name: "tickSpacing", type: "int24", internalType: "int24" },
|
|
1704
|
+
{
|
|
1705
|
+
name: "hooks",
|
|
1706
|
+
type: "address",
|
|
1707
|
+
internalType: "contract IHooks"
|
|
1708
|
+
}
|
|
1709
|
+
]
|
|
1710
|
+
}
|
|
1711
|
+
],
|
|
1712
|
+
outputs: [{ name: "exists", type: "bool", internalType: "bool" }],
|
|
1713
|
+
stateMutability: "view"
|
|
1714
|
+
},
|
|
1715
|
+
{
|
|
1716
|
+
type: "function",
|
|
1717
|
+
name: "getPoolsMultiVersion",
|
|
1718
|
+
inputs: [
|
|
1719
|
+
{
|
|
1720
|
+
name: "params",
|
|
1721
|
+
type: "tuple",
|
|
1722
|
+
internalType: "struct MultiVersionUniswapBulkPoolFinder.PoolFinderParams",
|
|
1723
|
+
components: [
|
|
1724
|
+
{
|
|
1725
|
+
name: "tokenAs",
|
|
1726
|
+
type: "address[]",
|
|
1727
|
+
internalType: "address[]"
|
|
1728
|
+
},
|
|
1729
|
+
{
|
|
1730
|
+
name: "tokenBs",
|
|
1731
|
+
type: "address[]",
|
|
1732
|
+
internalType: "address[]"
|
|
1733
|
+
},
|
|
1734
|
+
{ name: "fees", type: "uint24[]", internalType: "uint24[]" },
|
|
1735
|
+
{
|
|
1736
|
+
name: "v4TickSpacings",
|
|
1737
|
+
type: "int24[]",
|
|
1738
|
+
internalType: "int24[]"
|
|
1739
|
+
},
|
|
1740
|
+
{
|
|
1741
|
+
name: "v4Hooks",
|
|
1742
|
+
type: "address[]",
|
|
1743
|
+
internalType: "address[]"
|
|
1744
|
+
}
|
|
1745
|
+
]
|
|
1746
|
+
}
|
|
1747
|
+
],
|
|
1748
|
+
outputs: [
|
|
1749
|
+
{
|
|
1750
|
+
name: "pools",
|
|
1751
|
+
type: "tuple[]",
|
|
1752
|
+
internalType: "struct MultiVersionUniswapBulkPoolFinder.PoolDiscovery[]",
|
|
1753
|
+
components: [
|
|
1754
|
+
{
|
|
1755
|
+
name: "pairIndex",
|
|
1756
|
+
type: "uint256",
|
|
1757
|
+
internalType: "uint256"
|
|
1758
|
+
},
|
|
1759
|
+
{ name: "version", type: "uint8", internalType: "uint8" },
|
|
1760
|
+
{
|
|
1761
|
+
name: "poolAddress",
|
|
1762
|
+
type: "address",
|
|
1763
|
+
internalType: "address"
|
|
1764
|
+
},
|
|
1765
|
+
{
|
|
1766
|
+
name: "poolKey",
|
|
1767
|
+
type: "tuple",
|
|
1768
|
+
internalType: "struct PoolKey",
|
|
1769
|
+
components: [
|
|
1770
|
+
{
|
|
1771
|
+
name: "currency0",
|
|
1772
|
+
type: "address",
|
|
1773
|
+
internalType: "Currency"
|
|
1774
|
+
},
|
|
1775
|
+
{
|
|
1776
|
+
name: "currency1",
|
|
1777
|
+
type: "address",
|
|
1778
|
+
internalType: "Currency"
|
|
1779
|
+
},
|
|
1780
|
+
{ name: "fee", type: "uint24", internalType: "uint24" },
|
|
1781
|
+
{
|
|
1782
|
+
name: "tickSpacing",
|
|
1783
|
+
type: "int24",
|
|
1784
|
+
internalType: "int24"
|
|
1785
|
+
},
|
|
1786
|
+
{
|
|
1787
|
+
name: "hooks",
|
|
1788
|
+
type: "address",
|
|
1789
|
+
internalType: "contract IHooks"
|
|
1790
|
+
}
|
|
1791
|
+
]
|
|
1792
|
+
},
|
|
1793
|
+
{ name: "fee", type: "uint24", internalType: "uint24" },
|
|
1794
|
+
{ name: "tickSpacing", type: "int24", internalType: "int24" },
|
|
1795
|
+
{ name: "hooks", type: "address", internalType: "address" }
|
|
1796
|
+
]
|
|
1797
|
+
},
|
|
1798
|
+
{ name: "count", type: "uint256", internalType: "uint256" }
|
|
1799
|
+
],
|
|
1800
|
+
stateMutability: "view"
|
|
1801
|
+
}
|
|
1802
|
+
];
|
|
1803
|
+
|
|
1804
|
+
// src/abis/multi-version-uniswap-pool-info-retriever.json
|
|
1805
|
+
var multi_version_uniswap_pool_info_retriever_default = [
|
|
1806
|
+
{
|
|
1807
|
+
type: "function",
|
|
1808
|
+
name: "V4_POOL_MANAGER",
|
|
1809
|
+
inputs: [],
|
|
1810
|
+
outputs: [{ name: "", type: "address", internalType: "address" }],
|
|
1811
|
+
stateMutability: "view"
|
|
1812
|
+
},
|
|
1813
|
+
{
|
|
1814
|
+
type: "function",
|
|
1815
|
+
name: "_getV4Slot0",
|
|
1816
|
+
inputs: [
|
|
1817
|
+
{
|
|
1818
|
+
name: "poolKey",
|
|
1819
|
+
type: "tuple",
|
|
1820
|
+
internalType: "struct PoolKey",
|
|
1821
|
+
components: [
|
|
1822
|
+
{
|
|
1823
|
+
name: "currency0",
|
|
1824
|
+
type: "address",
|
|
1825
|
+
internalType: "Currency"
|
|
1826
|
+
},
|
|
1827
|
+
{
|
|
1828
|
+
name: "currency1",
|
|
1829
|
+
type: "address",
|
|
1830
|
+
internalType: "Currency"
|
|
1831
|
+
},
|
|
1832
|
+
{ name: "fee", type: "uint24", internalType: "uint24" },
|
|
1833
|
+
{ name: "tickSpacing", type: "int24", internalType: "int24" },
|
|
1834
|
+
{
|
|
1835
|
+
name: "hooks",
|
|
1836
|
+
type: "address",
|
|
1837
|
+
internalType: "contract IHooks"
|
|
1838
|
+
}
|
|
1839
|
+
]
|
|
1840
|
+
}
|
|
1841
|
+
],
|
|
1842
|
+
outputs: [
|
|
1843
|
+
{ name: "sqrtPriceX96", type: "uint160", internalType: "uint160" }
|
|
1844
|
+
],
|
|
1845
|
+
stateMutability: "view"
|
|
1846
|
+
},
|
|
1847
|
+
{
|
|
1848
|
+
type: "function",
|
|
1849
|
+
name: "getPoolsFullInfoMultiVersion",
|
|
1850
|
+
inputs: [
|
|
1851
|
+
{
|
|
1852
|
+
name: "v2PoolAddresses",
|
|
1853
|
+
type: "address[]",
|
|
1854
|
+
internalType: "address[]"
|
|
1855
|
+
},
|
|
1856
|
+
{
|
|
1857
|
+
name: "v3PoolAddresses",
|
|
1858
|
+
type: "address[]",
|
|
1859
|
+
internalType: "address[]"
|
|
1860
|
+
},
|
|
1861
|
+
{
|
|
1862
|
+
name: "v4PoolKeys",
|
|
1863
|
+
type: "tuple[]",
|
|
1864
|
+
internalType: "struct PoolKey[]",
|
|
1865
|
+
components: [
|
|
1866
|
+
{
|
|
1867
|
+
name: "currency0",
|
|
1868
|
+
type: "address",
|
|
1869
|
+
internalType: "Currency"
|
|
1870
|
+
},
|
|
1871
|
+
{
|
|
1872
|
+
name: "currency1",
|
|
1873
|
+
type: "address",
|
|
1874
|
+
internalType: "Currency"
|
|
1875
|
+
},
|
|
1876
|
+
{ name: "fee", type: "uint24", internalType: "uint24" },
|
|
1877
|
+
{ name: "tickSpacing", type: "int24", internalType: "int24" },
|
|
1878
|
+
{
|
|
1879
|
+
name: "hooks",
|
|
1880
|
+
type: "address",
|
|
1881
|
+
internalType: "contract IHooks"
|
|
1882
|
+
}
|
|
1883
|
+
]
|
|
1884
|
+
},
|
|
1885
|
+
{ name: "baseToken", type: "address", internalType: "address" }
|
|
1886
|
+
],
|
|
1887
|
+
outputs: [
|
|
1888
|
+
{
|
|
1889
|
+
name: "",
|
|
1890
|
+
type: "tuple[]",
|
|
1891
|
+
internalType: "struct MultiVersionPoolInfoRetriever.PoolFullInfo[]",
|
|
1892
|
+
components: [
|
|
1893
|
+
{
|
|
1894
|
+
name: "poolAddress",
|
|
1895
|
+
type: "address",
|
|
1896
|
+
internalType: "address"
|
|
1897
|
+
},
|
|
1898
|
+
{ name: "token0", type: "address", internalType: "address" },
|
|
1899
|
+
{ name: "token1", type: "address", internalType: "address" },
|
|
1900
|
+
{
|
|
1901
|
+
name: "token0Decimals",
|
|
1902
|
+
type: "uint8",
|
|
1903
|
+
internalType: "uint8"
|
|
1904
|
+
},
|
|
1905
|
+
{
|
|
1906
|
+
name: "token1Decimals",
|
|
1907
|
+
type: "uint8",
|
|
1908
|
+
internalType: "uint8"
|
|
1909
|
+
},
|
|
1910
|
+
{
|
|
1911
|
+
name: "sqrtPriceX96",
|
|
1912
|
+
type: "uint256",
|
|
1913
|
+
internalType: "uint256"
|
|
1914
|
+
},
|
|
1915
|
+
{
|
|
1916
|
+
name: "baseTokenBalance",
|
|
1917
|
+
type: "uint256",
|
|
1918
|
+
internalType: "uint256"
|
|
1919
|
+
},
|
|
1920
|
+
{
|
|
1921
|
+
name: "token0Balance",
|
|
1922
|
+
type: "uint256",
|
|
1923
|
+
internalType: "uint256"
|
|
1924
|
+
},
|
|
1925
|
+
{
|
|
1926
|
+
name: "token1Balance",
|
|
1927
|
+
type: "uint256",
|
|
1928
|
+
internalType: "uint256"
|
|
1929
|
+
}
|
|
1930
|
+
]
|
|
1931
|
+
}
|
|
1932
|
+
],
|
|
1933
|
+
stateMutability: "view"
|
|
1934
|
+
}
|
|
1935
|
+
];
|
|
1936
|
+
|
|
1660
1937
|
// src/constants.ts
|
|
1661
1938
|
var SCORE_CONTRACT = {
|
|
1662
1939
|
address: "0x0000000fa09b022e5616e5a173b4b67fa2fbcf28",
|
|
@@ -1690,6 +1967,17 @@ var ALL_STRATEGY_ADDRESSES = [
|
|
|
1690
1967
|
var LEGACY_UPVOTE_V1_ADDRESS = "0x0ada882dbbdc12388a1f9ca85d2d847088f747df";
|
|
1691
1968
|
var LEGACY_UPVOTE_V2_ADDRESS = "0x9027dcad0a3dca5835895e14fbc022a1e5ea909b";
|
|
1692
1969
|
var SUPPORTED_SCORE_CHAINS = [8453];
|
|
1970
|
+
var MULTI_VERSION_UNISWAP_BULK_POOL_FINDER = {
|
|
1971
|
+
address: "0xbc237dac4c74c170780fc12f353a258bdd31a8cf",
|
|
1972
|
+
abi: multi_version_uniswap_bulk_pool_finder_default
|
|
1973
|
+
};
|
|
1974
|
+
var MULTI_VERSION_UNISWAP_POOL_INFO_RETRIEVER = {
|
|
1975
|
+
address: "0x7A9EF0AC6F6a254cd570B05D62D094D3aa5067f1",
|
|
1976
|
+
abi: multi_version_uniswap_pool_info_retriever_default
|
|
1977
|
+
};
|
|
1978
|
+
var WETH_ADDRESS = "0x4200000000000000000000000000000000000006";
|
|
1979
|
+
var NULL_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
1980
|
+
var UPVOTE_PRICE_ETH = 25e-6;
|
|
1693
1981
|
var encodeUpvoteKey = (tokenAddress) => {
|
|
1694
1982
|
return `0x${BigInt(`0x${tokenAddress.slice(2)}`).toString(16).padStart(64, "0")}`;
|
|
1695
1983
|
};
|
|
@@ -2116,21 +2404,400 @@ var encodePoolKey = (poolKey) => {
|
|
|
2116
2404
|
function isValidPoolKey2(poolKey) {
|
|
2117
2405
|
return poolKey.fee !== void 0 || poolKey.tickSpacing !== void 0 || poolKey.currency0 !== void 0;
|
|
2118
2406
|
}
|
|
2407
|
+
var V3_V4_FEE_TIERS = [500, 3e3, 1e4, 12e3, 8388608];
|
|
2408
|
+
var V4_TICK_SPACINGS = [200];
|
|
2409
|
+
var V4_HOOKS = [
|
|
2410
|
+
NULL_ADDRESS,
|
|
2411
|
+
"0xDd5EeaFf7BD481AD55Db083062b13a3cdf0A68CC",
|
|
2412
|
+
"0x34a45c6B61876d739400Bd71228CbcbD4F53E8cC",
|
|
2413
|
+
"0xb429d62f8f3bFFb98CdB9569533eA23bF0Ba28CC",
|
|
2414
|
+
"0xd60D6B218116cFd801E28F78d011a203D2b068Cc",
|
|
2415
|
+
"0x3e342a06f9592459D75721d6956B570F02eF2Dc0",
|
|
2416
|
+
"0xbB7784A4d481184283Ed89619A3e3ed143e1Adc0"
|
|
2417
|
+
];
|
|
2418
|
+
var LIQUIDITY_THRESHOLD_TO_PREFER_V2_V3_POOLS = 0.1 * 1e18;
|
|
2419
|
+
var LIQUIDITY_THRESHOLD_TO_CONSIDER_V2_V3_POOLS = 0.01 * 1e18;
|
|
2420
|
+
function normalizeTokenPairs(pairs) {
|
|
2421
|
+
return pairs.map((pair) => {
|
|
2422
|
+
const tokenA = pair.tokenAddress;
|
|
2423
|
+
const tokenB = pair.baseTokenAddress || WETH_ADDRESS;
|
|
2424
|
+
return {
|
|
2425
|
+
originalPair: pair,
|
|
2426
|
+
tokenA: tokenA.toLowerCase() < tokenB.toLowerCase() ? tokenA : tokenB,
|
|
2427
|
+
tokenB: tokenA.toLowerCase() < tokenB.toLowerCase() ? tokenB : tokenA
|
|
2428
|
+
};
|
|
2429
|
+
});
|
|
2430
|
+
}
|
|
2431
|
+
function buildDiscoveryArgs(normalizedPairs) {
|
|
2432
|
+
return {
|
|
2433
|
+
tokenAs: normalizedPairs.map((p) => p.tokenA),
|
|
2434
|
+
tokenBs: normalizedPairs.map((p) => p.tokenB),
|
|
2435
|
+
fees: V3_V4_FEE_TIERS,
|
|
2436
|
+
v4TickSpacings: V4_TICK_SPACINGS,
|
|
2437
|
+
v4Hooks: V4_HOOKS
|
|
2438
|
+
};
|
|
2439
|
+
}
|
|
2440
|
+
function parsePoolDiscoveries(poolResults, pairs) {
|
|
2441
|
+
if (!poolResults) {
|
|
2442
|
+
return {
|
|
2443
|
+
v2PoolAddresses: [],
|
|
2444
|
+
v3PoolAddresses: [],
|
|
2445
|
+
v4PoolKeys: [],
|
|
2446
|
+
v2PoolAddressToPair: {},
|
|
2447
|
+
v3PoolAddressToPair: {},
|
|
2448
|
+
v4PoolKeyToPair: {}
|
|
2449
|
+
};
|
|
2450
|
+
}
|
|
2451
|
+
const [discoveries, countRaw] = poolResults;
|
|
2452
|
+
const countNum = typeof countRaw === "bigint" ? Number(countRaw) : Number(countRaw || 0);
|
|
2453
|
+
const v2PoolAddresses = [];
|
|
2454
|
+
const v3PoolAddresses = [];
|
|
2455
|
+
const v4PoolKeys = [];
|
|
2456
|
+
const seenV2V3Addresses = /* @__PURE__ */ new Set();
|
|
2457
|
+
const seenV4Keys = /* @__PURE__ */ new Set();
|
|
2458
|
+
const v2PoolAddressToPair = {};
|
|
2459
|
+
const v3PoolAddressToPair = {};
|
|
2460
|
+
const v4PoolKeyToPair = {};
|
|
2461
|
+
for (let i = 0; i < Math.min(countNum, discoveries.length); i++) {
|
|
2462
|
+
const discovery = discoveries[i];
|
|
2463
|
+
const version = Number(discovery?.version ?? 0);
|
|
2464
|
+
const poolAddressValue = discovery?.poolAddress;
|
|
2465
|
+
const pairIndex = Number(discovery?.pairIndex ?? 0);
|
|
2466
|
+
const feeNum = Number(discovery?.fee ?? 0);
|
|
2467
|
+
const poolKey = discovery?.poolKey;
|
|
2468
|
+
const pair = pairs[pairIndex];
|
|
2469
|
+
if (!pair) continue;
|
|
2470
|
+
if (version === 2 && poolAddressValue && poolAddressValue !== NULL_ADDRESS) {
|
|
2471
|
+
const poolAddress = poolAddressValue.toLowerCase();
|
|
2472
|
+
if (!seenV2V3Addresses.has(poolAddress)) {
|
|
2473
|
+
seenV2V3Addresses.add(poolAddress);
|
|
2474
|
+
v2PoolAddresses.push(poolAddressValue);
|
|
2475
|
+
v2PoolAddressToPair[poolAddress] = {
|
|
2476
|
+
tokenAddress: pair.tokenAddress,
|
|
2477
|
+
baseTokenAddress: pair.baseTokenAddress || WETH_ADDRESS,
|
|
2478
|
+
fee: feeNum
|
|
2479
|
+
};
|
|
2480
|
+
}
|
|
2481
|
+
} else if (version === 3 && poolAddressValue && poolAddressValue !== NULL_ADDRESS) {
|
|
2482
|
+
const poolAddress = poolAddressValue.toLowerCase();
|
|
2483
|
+
if (!seenV2V3Addresses.has(poolAddress)) {
|
|
2484
|
+
seenV2V3Addresses.add(poolAddress);
|
|
2485
|
+
v3PoolAddresses.push(poolAddressValue);
|
|
2486
|
+
v3PoolAddressToPair[poolAddress] = {
|
|
2487
|
+
tokenAddress: pair.tokenAddress,
|
|
2488
|
+
baseTokenAddress: pair.baseTokenAddress || WETH_ADDRESS,
|
|
2489
|
+
fee: feeNum
|
|
2490
|
+
};
|
|
2491
|
+
}
|
|
2492
|
+
} else if (version === 4 && poolKey) {
|
|
2493
|
+
const poolKeyString = JSON.stringify(poolKey);
|
|
2494
|
+
if (!seenV4Keys.has(poolKeyString)) {
|
|
2495
|
+
seenV4Keys.add(poolKeyString);
|
|
2496
|
+
v4PoolKeys.push(poolKey);
|
|
2497
|
+
v4PoolKeyToPair[poolKeyString] = {
|
|
2498
|
+
tokenAddress: pair.tokenAddress,
|
|
2499
|
+
baseTokenAddress: pair.baseTokenAddress || WETH_ADDRESS,
|
|
2500
|
+
fee: feeNum
|
|
2501
|
+
};
|
|
2502
|
+
}
|
|
2503
|
+
}
|
|
2504
|
+
}
|
|
2505
|
+
return {
|
|
2506
|
+
v2PoolAddresses,
|
|
2507
|
+
v3PoolAddresses,
|
|
2508
|
+
v4PoolKeys,
|
|
2509
|
+
v2PoolAddressToPair,
|
|
2510
|
+
v3PoolAddressToPair,
|
|
2511
|
+
v4PoolKeyToPair
|
|
2512
|
+
};
|
|
2513
|
+
}
|
|
2514
|
+
function determinePoolVersion(discoveries, index) {
|
|
2515
|
+
const {
|
|
2516
|
+
v2PoolAddresses,
|
|
2517
|
+
v3PoolAddresses,
|
|
2518
|
+
v4PoolKeys,
|
|
2519
|
+
v2PoolAddressToPair,
|
|
2520
|
+
v3PoolAddressToPair,
|
|
2521
|
+
v4PoolKeyToPair
|
|
2522
|
+
} = discoveries;
|
|
2523
|
+
if (index < v2PoolAddresses.length) {
|
|
2524
|
+
const poolAddress = v2PoolAddresses[index].toLowerCase();
|
|
2525
|
+
return {
|
|
2526
|
+
version: 2,
|
|
2527
|
+
pair: v2PoolAddressToPair[poolAddress],
|
|
2528
|
+
fee: 0,
|
|
2529
|
+
v4PoolKey: void 0
|
|
2530
|
+
};
|
|
2531
|
+
} else if (index < v2PoolAddresses.length + v3PoolAddresses.length) {
|
|
2532
|
+
const v3Index = index - v2PoolAddresses.length;
|
|
2533
|
+
const poolAddress = v3PoolAddresses[v3Index].toLowerCase();
|
|
2534
|
+
return {
|
|
2535
|
+
version: 3,
|
|
2536
|
+
pair: v3PoolAddressToPair[poolAddress],
|
|
2537
|
+
fee: v3PoolAddressToPair[poolAddress]?.fee || 0,
|
|
2538
|
+
v4PoolKey: void 0
|
|
2539
|
+
};
|
|
2540
|
+
} else {
|
|
2541
|
+
const v4Index = index - v2PoolAddresses.length - v3PoolAddresses.length;
|
|
2542
|
+
const poolKey = v4PoolKeys[v4Index];
|
|
2543
|
+
const poolKeyString = JSON.stringify(poolKey);
|
|
2544
|
+
return {
|
|
2545
|
+
version: 4,
|
|
2546
|
+
pair: v4PoolKeyToPair[poolKeyString],
|
|
2547
|
+
fee: v4PoolKeyToPair[poolKeyString]?.fee || 0,
|
|
2548
|
+
v4PoolKey: poolKey
|
|
2549
|
+
};
|
|
2550
|
+
}
|
|
2551
|
+
}
|
|
2552
|
+
function calculatePriceFromSqrtPriceX96(sqrtPriceX96, token0Decimals, token1Decimals, isToken0) {
|
|
2553
|
+
const sqrtPrice = Number(sqrtPriceX96);
|
|
2554
|
+
if (sqrtPrice === 0) return 0;
|
|
2555
|
+
const priceX96 = (sqrtPrice / 2 ** 96) ** 2;
|
|
2556
|
+
if (isToken0) {
|
|
2557
|
+
return priceX96 * 10 ** (token0Decimals - token1Decimals);
|
|
2558
|
+
} else {
|
|
2559
|
+
return 1 / priceX96 * 10 ** (token1Decimals - token0Decimals);
|
|
2560
|
+
}
|
|
2561
|
+
}
|
|
2562
|
+
function calculatePoolPrice(info, pair, version) {
|
|
2563
|
+
try {
|
|
2564
|
+
const sqrtPriceX96 = Number(info.sqrtPriceX96);
|
|
2565
|
+
const token0Decimals = Number(info.token0Decimals);
|
|
2566
|
+
const token1Decimals = Number(info.token1Decimals);
|
|
2567
|
+
const isToken0 = info.token0.toLowerCase() === pair.tokenAddress.toLowerCase();
|
|
2568
|
+
if (version === 2) {
|
|
2569
|
+
const token0Balance = Number(info.token0Balance) / 10 ** token0Decimals;
|
|
2570
|
+
const token1Balance = Number(info.token1Balance) / 10 ** token1Decimals;
|
|
2571
|
+
if (token0Balance === 0 || token1Balance === 0) return null;
|
|
2572
|
+
if (isToken0) {
|
|
2573
|
+
return token1Balance / token0Balance;
|
|
2574
|
+
} else {
|
|
2575
|
+
return token0Balance / token1Balance;
|
|
2576
|
+
}
|
|
2577
|
+
} else {
|
|
2578
|
+
if (sqrtPriceX96 === 0) return null;
|
|
2579
|
+
if (isToken0) {
|
|
2580
|
+
return (sqrtPriceX96 / 2 ** 96) ** 2 * 10 ** (token0Decimals - token1Decimals);
|
|
2581
|
+
} else {
|
|
2582
|
+
const priceX96 = (sqrtPriceX96 / 2 ** 96) ** 2;
|
|
2583
|
+
return 1 / priceX96 * 10 ** (token1Decimals - token0Decimals);
|
|
2584
|
+
}
|
|
2585
|
+
}
|
|
2586
|
+
} catch {
|
|
2587
|
+
return null;
|
|
2588
|
+
}
|
|
2589
|
+
}
|
|
2590
|
+
function constructPoolKey(info, pair, version, v4PoolKey) {
|
|
2591
|
+
try {
|
|
2592
|
+
if (!info.token0 || !info.token1 || typeof pair.fee !== "number") {
|
|
2593
|
+
return void 0;
|
|
2594
|
+
}
|
|
2595
|
+
if (!info.token0.startsWith("0x") || !info.token1.startsWith("0x")) {
|
|
2596
|
+
return void 0;
|
|
2597
|
+
}
|
|
2598
|
+
const currency0 = info.token0.toLowerCase() < info.token1.toLowerCase() ? info.token0 : info.token1;
|
|
2599
|
+
const currency1 = info.token0.toLowerCase() < info.token1.toLowerCase() ? info.token1 : info.token0;
|
|
2600
|
+
if (version === 2) {
|
|
2601
|
+
return {
|
|
2602
|
+
currency0,
|
|
2603
|
+
currency1,
|
|
2604
|
+
fee: 0,
|
|
2605
|
+
tickSpacing: 0,
|
|
2606
|
+
hooks: NULL_ADDRESS
|
|
2607
|
+
};
|
|
2608
|
+
} else if (version === 3) {
|
|
2609
|
+
return {
|
|
2610
|
+
currency0,
|
|
2611
|
+
currency1,
|
|
2612
|
+
fee: pair.fee,
|
|
2613
|
+
tickSpacing: 0,
|
|
2614
|
+
hooks: NULL_ADDRESS
|
|
2615
|
+
};
|
|
2616
|
+
} else {
|
|
2617
|
+
if (!v4PoolKey || !v4PoolKey.currency0 || !v4PoolKey.currency1) {
|
|
2618
|
+
return void 0;
|
|
2619
|
+
}
|
|
2620
|
+
return v4PoolKey;
|
|
2621
|
+
}
|
|
2622
|
+
} catch {
|
|
2623
|
+
return void 0;
|
|
2624
|
+
}
|
|
2625
|
+
}
|
|
2626
|
+
function getWethBalanceWei(pool) {
|
|
2627
|
+
if (pool.token0?.toLowerCase() === WETH_ADDRESS.toLowerCase()) {
|
|
2628
|
+
return Number(pool.token0Balance);
|
|
2629
|
+
} else if (pool.token1?.toLowerCase() === WETH_ADDRESS.toLowerCase()) {
|
|
2630
|
+
return Number(pool.token1Balance);
|
|
2631
|
+
} else {
|
|
2632
|
+
return Number(pool.baseTokenBalance);
|
|
2633
|
+
}
|
|
2634
|
+
}
|
|
2635
|
+
function filterV2V3PoolsByLiquidity(pools, threshold) {
|
|
2636
|
+
return pools.filter((pool) => {
|
|
2637
|
+
if (!pool.poolAddress) return false;
|
|
2638
|
+
const wethBalanceWei = getWethBalanceWei(pool);
|
|
2639
|
+
return wethBalanceWei >= threshold;
|
|
2640
|
+
});
|
|
2641
|
+
}
|
|
2642
|
+
function selectBestV2V3Pool(pools) {
|
|
2643
|
+
return pools.reduce((a, b) => {
|
|
2644
|
+
const aIsV3 = a.fee > 0;
|
|
2645
|
+
const bIsV3 = b.fee > 0;
|
|
2646
|
+
if (aIsV3 && !bIsV3) return a;
|
|
2647
|
+
if (!aIsV3 && bIsV3) return b;
|
|
2648
|
+
return Number(a.baseTokenBalance) > Number(b.baseTokenBalance) ? a : b;
|
|
2649
|
+
});
|
|
2650
|
+
}
|
|
2651
|
+
function selectBestV4Pool(pools) {
|
|
2652
|
+
return pools.reduce((a, b) => {
|
|
2653
|
+
return a.fee < b.fee ? a : b;
|
|
2654
|
+
});
|
|
2655
|
+
}
|
|
2656
|
+
function selectBestV2V3PoolByFee(pools) {
|
|
2657
|
+
return pools.reduce((a, b) => {
|
|
2658
|
+
return a.fee < b.fee ? a : b;
|
|
2659
|
+
});
|
|
2660
|
+
}
|
|
2661
|
+
function selectBestPoolPerPair(allPools) {
|
|
2662
|
+
const poolsByPair = {};
|
|
2663
|
+
for (const pool of allPools) {
|
|
2664
|
+
const key = pool.tokenAddress.toLowerCase() + "_" + pool.baseTokenAddress.toLowerCase();
|
|
2665
|
+
if (!poolsByPair[key]) poolsByPair[key] = [];
|
|
2666
|
+
poolsByPair[key].push(pool);
|
|
2667
|
+
}
|
|
2668
|
+
const bestPools = [];
|
|
2669
|
+
for (const [, group] of Object.entries(poolsByPair)) {
|
|
2670
|
+
let best;
|
|
2671
|
+
if (group.length === 1) {
|
|
2672
|
+
best = group[0];
|
|
2673
|
+
} else {
|
|
2674
|
+
const v2v3PoolsWithPreferredLiquidity = filterV2V3PoolsByLiquidity(
|
|
2675
|
+
group,
|
|
2676
|
+
LIQUIDITY_THRESHOLD_TO_PREFER_V2_V3_POOLS
|
|
2677
|
+
);
|
|
2678
|
+
if (v2v3PoolsWithPreferredLiquidity.length > 0) {
|
|
2679
|
+
best = selectBestV2V3Pool(v2v3PoolsWithPreferredLiquidity);
|
|
2680
|
+
} else {
|
|
2681
|
+
const v4Pools = group.filter((pool) => !pool.poolAddress);
|
|
2682
|
+
if (v4Pools.length > 0) {
|
|
2683
|
+
best = selectBestV4Pool(v4Pools);
|
|
2684
|
+
} else {
|
|
2685
|
+
const v2v3PoolsWithAcceptableLiquidity = filterV2V3PoolsByLiquidity(
|
|
2686
|
+
group,
|
|
2687
|
+
LIQUIDITY_THRESHOLD_TO_CONSIDER_V2_V3_POOLS
|
|
2688
|
+
);
|
|
2689
|
+
if (v2v3PoolsWithAcceptableLiquidity.length > 0) {
|
|
2690
|
+
best = selectBestV2V3PoolByFee(v2v3PoolsWithAcceptableLiquidity);
|
|
2691
|
+
}
|
|
2692
|
+
}
|
|
2693
|
+
}
|
|
2694
|
+
}
|
|
2695
|
+
if (best) {
|
|
2696
|
+
bestPools.push(best);
|
|
2697
|
+
}
|
|
2698
|
+
}
|
|
2699
|
+
return bestPools;
|
|
2700
|
+
}
|
|
2701
|
+
async function discoverPools({
|
|
2702
|
+
publicClient,
|
|
2703
|
+
pairs
|
|
2704
|
+
}) {
|
|
2705
|
+
if (pairs.length === 0) return [];
|
|
2706
|
+
const normalizedPairs = normalizeTokenPairs(pairs);
|
|
2707
|
+
const discoveryArgs = buildDiscoveryArgs(normalizedPairs);
|
|
2708
|
+
const poolResults = await actions.readContract(publicClient, {
|
|
2709
|
+
address: MULTI_VERSION_UNISWAP_BULK_POOL_FINDER.address,
|
|
2710
|
+
abi: MULTI_VERSION_UNISWAP_BULK_POOL_FINDER.abi,
|
|
2711
|
+
functionName: "getPoolsMultiVersion",
|
|
2712
|
+
args: [discoveryArgs]
|
|
2713
|
+
});
|
|
2714
|
+
const discoveries = parsePoolDiscoveries(poolResults, pairs);
|
|
2715
|
+
const totalPools = discoveries.v2PoolAddresses.length + discoveries.v3PoolAddresses.length + discoveries.v4PoolKeys.length;
|
|
2716
|
+
if (totalPools === 0) return [];
|
|
2717
|
+
const poolInfos = await actions.readContract(publicClient, {
|
|
2718
|
+
address: MULTI_VERSION_UNISWAP_POOL_INFO_RETRIEVER.address,
|
|
2719
|
+
abi: MULTI_VERSION_UNISWAP_POOL_INFO_RETRIEVER.abi,
|
|
2720
|
+
functionName: "getPoolsFullInfoMultiVersion",
|
|
2721
|
+
args: [
|
|
2722
|
+
discoveries.v2PoolAddresses,
|
|
2723
|
+
discoveries.v3PoolAddresses,
|
|
2724
|
+
discoveries.v4PoolKeys,
|
|
2725
|
+
WETH_ADDRESS
|
|
2726
|
+
]
|
|
2727
|
+
});
|
|
2728
|
+
if (!Array.isArray(poolInfos) || poolInfos.length === 0) return [];
|
|
2729
|
+
const allPools = poolInfos.map((info, index) => {
|
|
2730
|
+
const poolData = determinePoolVersion(discoveries, index);
|
|
2731
|
+
if (!poolData || !poolData.pair) return null;
|
|
2732
|
+
return {
|
|
2733
|
+
tokenAddress: poolData.pair.tokenAddress,
|
|
2734
|
+
baseTokenAddress: poolData.pair.baseTokenAddress || WETH_ADDRESS,
|
|
2735
|
+
poolAddress: poolData.version === 4 ? null : info.poolAddress,
|
|
2736
|
+
price: calculatePoolPrice(info, poolData.pair, poolData.version),
|
|
2737
|
+
baseTokenBalance: String(info.baseTokenBalance || 0),
|
|
2738
|
+
token0: info.token0,
|
|
2739
|
+
token1: info.token1,
|
|
2740
|
+
token0Balance: String(info.token0Balance || 0),
|
|
2741
|
+
token1Balance: String(info.token1Balance || 0),
|
|
2742
|
+
fee: poolData.fee,
|
|
2743
|
+
poolKey: constructPoolKey(
|
|
2744
|
+
info,
|
|
2745
|
+
poolData.pair,
|
|
2746
|
+
poolData.version,
|
|
2747
|
+
poolData.v4PoolKey
|
|
2748
|
+
)
|
|
2749
|
+
};
|
|
2750
|
+
}).filter((p) => p !== null);
|
|
2751
|
+
const bestPools = selectBestPoolPerPair(allPools);
|
|
2752
|
+
return bestPools.map(
|
|
2753
|
+
(pool) => ({
|
|
2754
|
+
tokenAddress: pool.tokenAddress,
|
|
2755
|
+
baseTokenAddress: pool.baseTokenAddress,
|
|
2756
|
+
poolAddress: pool.poolAddress,
|
|
2757
|
+
price: pool.price,
|
|
2758
|
+
fee: pool.fee,
|
|
2759
|
+
poolKey: pool.poolKey,
|
|
2760
|
+
balances: {
|
|
2761
|
+
baseTokenBalance: pool.baseTokenBalance,
|
|
2762
|
+
token0Balance: pool.token0Balance,
|
|
2763
|
+
token1Balance: pool.token1Balance
|
|
2764
|
+
}
|
|
2765
|
+
})
|
|
2766
|
+
);
|
|
2767
|
+
}
|
|
2768
|
+
async function discoverTokenPool({
|
|
2769
|
+
publicClient,
|
|
2770
|
+
tokenAddress
|
|
2771
|
+
}) {
|
|
2772
|
+
const results = await discoverPools({
|
|
2773
|
+
publicClient,
|
|
2774
|
+
pairs: [{ tokenAddress }]
|
|
2775
|
+
});
|
|
2776
|
+
return results[0] ?? null;
|
|
2777
|
+
}
|
|
2119
2778
|
|
|
2120
2779
|
exports.ALL_STRATEGY_ADDRESSES = ALL_STRATEGY_ADDRESSES;
|
|
2121
2780
|
exports.DYNAMIC_SPLIT_STRATEGY = DYNAMIC_SPLIT_STRATEGY;
|
|
2122
2781
|
exports.LEGACY_UPVOTE_V1_ADDRESS = LEGACY_UPVOTE_V1_ADDRESS;
|
|
2123
2782
|
exports.LEGACY_UPVOTE_V2_ADDRESS = LEGACY_UPVOTE_V2_ADDRESS;
|
|
2783
|
+
exports.MULTI_VERSION_UNISWAP_BULK_POOL_FINDER = MULTI_VERSION_UNISWAP_BULK_POOL_FINDER;
|
|
2784
|
+
exports.MULTI_VERSION_UNISWAP_POOL_INFO_RETRIEVER = MULTI_VERSION_UNISWAP_POOL_INFO_RETRIEVER;
|
|
2785
|
+
exports.NULL_ADDRESS = NULL_ADDRESS;
|
|
2124
2786
|
exports.PURE_ALPHA_STRATEGY = PURE_ALPHA_STRATEGY;
|
|
2125
2787
|
exports.SCORE_CONTRACT = SCORE_CONTRACT;
|
|
2126
2788
|
exports.SUPPORTED_SCORE_CHAINS = SUPPORTED_SCORE_CHAINS;
|
|
2127
2789
|
exports.ScoreClient = ScoreClient;
|
|
2128
2790
|
exports.UNIV234_POOLS_STRATEGY = UNIV234_POOLS_STRATEGY;
|
|
2129
2791
|
exports.UPVOTE_APP = UPVOTE_APP;
|
|
2792
|
+
exports.UPVOTE_PRICE_ETH = UPVOTE_PRICE_ETH;
|
|
2130
2793
|
exports.UPVOTE_STORAGE_APP = UPVOTE_STORAGE_APP;
|
|
2794
|
+
exports.WETH_ADDRESS = WETH_ADDRESS;
|
|
2795
|
+
exports.calculatePriceFromSqrtPriceX96 = calculatePriceFromSqrtPriceX96;
|
|
2131
2796
|
exports.decodeStrategyMetadata = decodeStrategyMetadata;
|
|
2132
2797
|
exports.decodeUpvoteMessage = decodeUpvoteMessage;
|
|
2133
2798
|
exports.decodeUpvoteStorageBlob = decodeUpvoteStorageBlob;
|
|
2799
|
+
exports.discoverPools = discoverPools;
|
|
2800
|
+
exports.discoverTokenPool = discoverTokenPool;
|
|
2134
2801
|
exports.encodePoolKey = encodePoolKey;
|
|
2135
2802
|
exports.encodeUpvoteKey = encodeUpvoteKey;
|
|
2136
2803
|
exports.extractStrategyAddress = extractStrategyAddress;
|