From 2aa60505c18432200fdb7d2407f702838d91e36c Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Sat, 19 Nov 2022 15:26:14 +0400 Subject: [PATCH 001/103] v0.0.1 --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 8583e93..e21948a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { - "name": "@dfyn/sdk", + "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.8", + "version": "0.0.1", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", @@ -56,4 +56,4 @@ "semi": false, "singleQuote": true } -} \ No newline at end of file +} From 0b9eb565c83e2573c27e2776795abf11d8c1f3e2 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Sat, 19 Nov 2022 15:31:59 +0400 Subject: [PATCH 002/103] v0.0.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e21948a..15d657a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.1", + "version": "0.0.2", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From b394538a1df7d01997ab0d124a48e266cf07f393 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Sun, 20 Nov 2022 17:08:22 +0400 Subject: [PATCH 003/103] v0.0.3 --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 15d657a..d21aae0 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.2", + "version": "0.0.3", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", @@ -22,6 +22,7 @@ "prepublishOnly": "tsdx build" }, "dependencies": { + "@ethersproject/abi": "^5.0.12", "@uniswap/v2-core": "^1.0.0", "big.js": "^5.2.2", "decimal.js-light": "^2.5.0", From 8f0fec14edfa2aeeff7271d58cc43f48901a8992 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Sun, 20 Nov 2022 17:13:32 +0400 Subject: [PATCH 004/103] v0.0.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d21aae0..ad5dce9 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.3", + "version": "0.0.4", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 188fc06392fb454e696577d9e222696a2a2c6d6c Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Sun, 20 Nov 2022 17:36:32 +0400 Subject: [PATCH 005/103] v0.0.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ad5dce9..fb5f833 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.4", + "version": "0.0.5", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From efdd3fb38afd2752d0fc83b017eaad7dedca7461 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Sun, 20 Nov 2022 17:43:18 +0400 Subject: [PATCH 006/103] v0.0.6 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fb5f833..d335360 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.5", + "version": "0.0.6", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From cf25c3c3c252a6aabfd614ba9b3689c9ab207f3a Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Mon, 21 Nov 2022 03:57:33 +0400 Subject: [PATCH 007/103] v0.0.7 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d335360..af5abe9 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.6", + "version": "0.0.7", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 8d68169f7ed0ed5eb9a4de0d2f82c482969215c0 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Mon, 21 Nov 2022 20:53:28 +0400 Subject: [PATCH 008/103] v0.0.8 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index af5abe9..588ff51 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.7", + "version": "0.0.8", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 74531b3dfa10959bd7de07d99ea9f3826f546854 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Tue, 22 Nov 2022 02:39:30 +0400 Subject: [PATCH 009/103] v0.0.9 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 588ff51..5536e10 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.8", + "version": "0.0.9", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 55572e4461c806a2a2c5acd6758cac760d861ddf Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Tue, 22 Nov 2022 04:38:48 +0400 Subject: [PATCH 010/103] v0.0.10 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5536e10..a116040 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.9", + "version": "0.0.10", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 60bdeeff6214d6c7b9966a29548a378f6ff3d2b3 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Tue, 22 Nov 2022 13:05:50 +0400 Subject: [PATCH 011/103] v0.0.11 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a116040..c8ef04b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.10", + "version": "0.0.11", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 09d74ad7a4865e928186867510f6015957d96d50 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Tue, 22 Nov 2022 14:12:50 +0400 Subject: [PATCH 012/103] v0.0.12 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c8ef04b..d9c3eb9 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.11", + "version": "0.0.12", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 75909d8c119d09d7ec5ad0c99c3edd5ccebf2dc4 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Tue, 22 Nov 2022 14:17:36 +0400 Subject: [PATCH 013/103] v0.0.13 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d9c3eb9..52342db 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.12", + "version": "0.0.13", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From ad0a117d9c3d466cb228ac09df85b0d87d45eac0 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Tue, 22 Nov 2022 14:26:07 +0400 Subject: [PATCH 014/103] v0.0.14 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 52342db..d8ff2cb 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.13", + "version": "0.0.14", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 05348d84e6b3fac1aef8fe45951b21ecadec1e12 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Tue, 22 Nov 2022 14:38:12 +0400 Subject: [PATCH 015/103] v0.0.15 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d8ff2cb..839fe61 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.14", + "version": "0.0.15", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 9166214ce270987c1312218b27eb32371535f198 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Tue, 22 Nov 2022 15:00:49 +0400 Subject: [PATCH 016/103] v0.0.16 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 839fe61..d5e8c90 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.15", + "version": "0.0.16", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 9fb181898102d07411e2c12ebc460fe40fa7f9d5 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Tue, 22 Nov 2022 15:16:14 +0400 Subject: [PATCH 017/103] v0.0.17 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d5e8c90..56d471f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.16", + "version": "0.0.17", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 6d042a0bb2b3b0366daf3223ad98444b4dd692de Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Tue, 22 Nov 2022 16:18:41 +0400 Subject: [PATCH 018/103] v0.0.18 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 56d471f..2a61d65 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.17", + "version": "0.0.18", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 0f3c08964b38f988e223bca869ec9cf6fb94cef1 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Tue, 22 Nov 2022 20:02:21 +0400 Subject: [PATCH 019/103] v0.0.19 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2a61d65..9292290 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.18", + "version": "0.0.19", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 94d874cf27aff146a8f51062f268a49d95c34c93 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Tue, 22 Nov 2022 20:41:25 +0400 Subject: [PATCH 020/103] v0.0.20 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9292290..596b003 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.19", + "version": "0.0.20", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 4a03f3acf874ec8f356d504830bfe6d89a7271a9 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Tue, 22 Nov 2022 20:46:07 +0400 Subject: [PATCH 021/103] v0.0.21 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 596b003..f777b67 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.20", + "version": "0.0.21", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From f41021ac164ee672a5b129763d27a1bf09c9374f Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Tue, 22 Nov 2022 22:35:54 +0400 Subject: [PATCH 022/103] v0.0.22 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f777b67..72a899b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.21", + "version": "0.0.22", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 7afa49d87158fbdb463ad670e9144fbf0bd47b99 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Wed, 23 Nov 2022 12:03:03 +0400 Subject: [PATCH 023/103] v0.0.23 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 72a899b..a95ba53 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.22", + "version": "0.0.23", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From e0f83c2d2ced529d66b33ce8033f30284ceb4d7e Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Thu, 24 Nov 2022 17:37:12 +0400 Subject: [PATCH 024/103] v0.0.24 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a95ba53..abcb520 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.23", + "version": "0.0.24", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From d5caa6b3d3e90c05ef555c380fd68a40b68ddceb Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Fri, 25 Nov 2022 14:12:02 +0400 Subject: [PATCH 025/103] v0.0.25 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index abcb520..2948405 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.24", + "version": "0.0.25", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From ecc65c74231ea7e0fc545360c265b1ca7222f51a Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Fri, 25 Nov 2022 15:03:35 +0400 Subject: [PATCH 026/103] v0.0.26 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2948405..cb53ce0 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.25", + "version": "0.0.26", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 33178a2b2be5caa40026171ce876bc464208ccc6 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Fri, 25 Nov 2022 15:38:05 +0400 Subject: [PATCH 027/103] v0.0.27 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cb53ce0..fe2cbcd 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.26", + "version": "0.0.27", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 0b9f7eee1a1f54576c22d5b8b8c9cef744c9236e Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Sat, 26 Nov 2022 03:16:30 +0400 Subject: [PATCH 028/103] v0.0.28 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fe2cbcd..a63f7ea 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.27", + "version": "0.0.28", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 5b3374bfde113b667de6a84011e6d4be64a58a23 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Sat, 26 Nov 2022 03:34:21 +0400 Subject: [PATCH 029/103] v0.0.29 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a63f7ea..31d3898 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.28", + "version": "0.0.29", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From f4458b05896f9c1743ccbb32a6bbdf2c9705e473 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Sat, 26 Nov 2022 03:38:21 +0400 Subject: [PATCH 030/103] v0.0.30 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 31d3898..059c65b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.29", + "version": "0.0.30", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 4353c123872786dd7a5af1129a076edad1908b7e Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Sat, 26 Nov 2022 05:12:55 +0400 Subject: [PATCH 031/103] v0.0.31 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 059c65b..fc115c9 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.30", + "version": "0.0.31", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 347dc20d4cd1fd4544fafbfe556bbb7f39a99d84 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Sun, 27 Nov 2022 01:36:31 +0400 Subject: [PATCH 032/103] v0.0.32 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fc115c9..d5e64f9 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.31", + "version": "0.0.32", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 8c63cef01dcd98febc2eda683ba85beb1f54b86f Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Sun, 27 Nov 2022 02:17:20 +0400 Subject: [PATCH 033/103] v0.0.33 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d5e64f9..a9ea126 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.32", + "version": "0.0.33", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 6765f9e6ebd727ecf4e0d473c49b36427fdbcbc4 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Sun, 27 Nov 2022 15:33:07 +0400 Subject: [PATCH 034/103] v0.0.34 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a9ea126..353c98a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.33", + "version": "0.0.34", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From f0123145d6957715564fea7dadebc7e633dac7c0 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Sun, 27 Nov 2022 16:49:02 +0400 Subject: [PATCH 035/103] v0.0.35 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 353c98a..41053ac 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.34", + "version": "0.0.35", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 4d257846ac8615115eda6fbedcba3329082f55a6 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Sun, 27 Nov 2022 18:04:01 +0400 Subject: [PATCH 036/103] v0.0.36 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 41053ac..17597c7 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.35", + "version": "0.0.36", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From c8a7494736c63adabc2a195ba07ad75f5a6512f5 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Sun, 27 Nov 2022 19:12:21 +0400 Subject: [PATCH 037/103] v0.0.37 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 17597c7..8a65ea3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.36", + "version": "0.0.37", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From e22a271329ce1a74760b8c3bdd7fa2ecdac306a2 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Sun, 27 Nov 2022 22:24:41 +0400 Subject: [PATCH 038/103] v0.0.38 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8a65ea3..5c0e2bd 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.37", + "version": "0.0.38", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From bb28992d33158df700a3223dc43ab037bc17d847 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Mon, 28 Nov 2022 03:28:05 +0400 Subject: [PATCH 039/103] v0.0.39 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5c0e2bd..9eca439 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.38", + "version": "0.0.39", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 8fad36bf6974a3cff36fe2df385aa58165c94cfc Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Mon, 28 Nov 2022 23:54:15 +0400 Subject: [PATCH 040/103] v0.0.40 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9eca439..6a6605a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.39", + "version": "0.0.40", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From ec5dd942ca30b23f32619c4ca9e804a2bb9276e1 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Tue, 29 Nov 2022 00:26:19 +0400 Subject: [PATCH 041/103] v0.0.41 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6a6605a..fee4af4 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.40", + "version": "0.0.41", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 2fd47fa882d2e756eeaadd4968fa26420d70e066 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Tue, 29 Nov 2022 03:52:34 +0400 Subject: [PATCH 042/103] v0.0.42 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fee4af4..e94e676 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.41", + "version": "0.0.42", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 1688b4dadd3cf0dfc2e36b4e6bfb3df5f116244a Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Tue, 29 Nov 2022 03:53:53 +0400 Subject: [PATCH 043/103] v0.0.45 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e94e676..e7cf5e9 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.42", + "version": "0.0.45", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 92092d3566d7768154f17d8f8c458aadbfee0016 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Tue, 29 Nov 2022 03:55:48 +0400 Subject: [PATCH 044/103] v0.0.46 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e7cf5e9..24d8509 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.45", + "version": "0.0.46", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 3c1c6c2b2da23e0073203287f4608e05e09548f9 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Tue, 29 Nov 2022 03:56:28 +0400 Subject: [PATCH 045/103] v0.0.47 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 24d8509..0b0ba78 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.46", + "version": "0.0.47", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 02b58bc67e51b5257dceddd49e387c9482fec09d Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Tue, 29 Nov 2022 04:05:10 +0400 Subject: [PATCH 046/103] v0.0.48 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0b0ba78..9e3280e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.47", + "version": "0.0.48", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 71f33183b670b24f3f7b9fb965af8d335f77ff82 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Tue, 29 Nov 2022 04:09:44 +0400 Subject: [PATCH 047/103] v0.0.49 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9e3280e..e00d261 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.48", + "version": "0.0.49", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 6953f2b4e890b0ca5220fa5afabbece19e52e744 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Tue, 29 Nov 2022 23:09:37 +0400 Subject: [PATCH 048/103] v0.0.50 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e00d261..ef0ae55 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.49", + "version": "0.0.50", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 53ad1a81a97dc35bf89179077613da0289c3d367 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Tue, 29 Nov 2022 23:18:20 +0400 Subject: [PATCH 049/103] v0.0.51 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ef0ae55..5156bf0 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.50", + "version": "0.0.51", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From fd4b5df1ca46e3f9ab1b24274ee80e338c787fa4 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Wed, 30 Nov 2022 01:53:37 +0400 Subject: [PATCH 050/103] v0.0.52 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5156bf0..5821336 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.51", + "version": "0.0.52", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 9acdbb6dc7d8ec9f3be3f33b72be94e8612c9a4e Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Wed, 30 Nov 2022 04:42:53 +0400 Subject: [PATCH 051/103] v0.0.53 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5821336..de96112 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.52", + "version": "0.0.53", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From a40e0c241c58283372f8ed5b4d9e418945a419a7 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Wed, 30 Nov 2022 04:50:44 +0400 Subject: [PATCH 052/103] v0.0.54 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index de96112..3951a23 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.53", + "version": "0.0.54", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 1f23c0ccc8dfc83f17b8d39d651aa5f7a1571bc6 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Wed, 30 Nov 2022 04:55:33 +0400 Subject: [PATCH 053/103] v0.0.55 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3951a23..eb62f2c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.54", + "version": "0.0.55", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 574497ca54c91955d3fcd7cb1ab2250e0e9f13ff Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Wed, 30 Nov 2022 22:17:36 +0400 Subject: [PATCH 054/103] v0.0.57 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index eb62f2c..52eb023 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.55", + "version": "0.0.57", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From c1fdc3b631a745908d5049be962440596a6c9934 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Thu, 1 Dec 2022 02:34:42 +0400 Subject: [PATCH 055/103] v0.0.58 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 52eb023..ed1de28 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.57", + "version": "0.0.58", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From fbec95fcc962886f9ad911e0b97b27e5f96bb116 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Thu, 1 Dec 2022 02:52:55 +0400 Subject: [PATCH 056/103] v0.0.59 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ed1de28..c950c07 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.58", + "version": "0.0.59", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 8830ec3955e28e38e022b650db72ff6d9a787992 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Thu, 1 Dec 2022 03:22:00 +0400 Subject: [PATCH 057/103] v0.0.60 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c950c07..4839fc9 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.59", + "version": "0.0.60", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 7f0de70625dce68f684c8270d4f520b3c41885ac Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Thu, 1 Dec 2022 20:13:09 +0400 Subject: [PATCH 058/103] v0.0.61 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4839fc9..d90951f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.60", + "version": "0.0.61", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 4249dc840affeb4f9365f478a5a0ee8aef9d57d0 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Thu, 1 Dec 2022 20:26:13 +0400 Subject: [PATCH 059/103] v0.0.62 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d90951f..e150aec 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.61", + "version": "0.0.62", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 2a632046a37ff2838b6b2f63ef2839dd9e00eecf Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Fri, 2 Dec 2022 12:18:41 +0400 Subject: [PATCH 060/103] v0.0.63 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e150aec..fba5d9a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.62", + "version": "0.0.63", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From a70c7d22e133ef7988a34f6552fae1510e4522c9 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Sat, 3 Dec 2022 20:08:19 +0400 Subject: [PATCH 061/103] v0.0.64 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fba5d9a..7d3e80e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.63", + "version": "0.0.64", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 5d9039377ad2d028065b7d7f9bbb7588649500bd Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Fri, 9 Dec 2022 16:41:00 +0400 Subject: [PATCH 062/103] feat: v2 updates --- src/MasterDeployer.ts | 37 + src/abis/ConcentratedPoolManager.json | 902 ++++++++++++++++ src/abis/LimitOrderManager.json | 360 +++++++ src/abis/MasterDeployer.json | 348 +++++++ src/abis/SwapRouter.json | 1377 +++++++++++++++++++++++++ src/concentratedPoolManager.ts | 370 +++++++ src/constants.ts | 91 +- src/entities/RouteWrappers.ts | 72 ++ src/entities/TradeWrappers.ts | 404 ++++++++ src/entities/index.ts | 12 + src/entities/mixedRoute/route.ts | 90 ++ src/entities/mixedRoute/trade.ts | 496 +++++++++ src/entities/order.ts | 126 +++ src/entities/pool.ts | 331 ++++++ src/entities/positions.ts | 395 +++++++ src/entities/protocol.ts | 6 + src/entities/tick.ts | 23 + src/entities/tickDataProvider.ts | 39 + src/entities/tickListDataProvider.ts | 25 + src/entities/trade.ts | 4 +- src/entities/v2route.ts | 84 ++ src/entities/v2trade.ts | 613 +++++++++++ src/index.ts | 12 +- src/internalConstants.ts | 10 + src/limitOrderManager.ts | 164 +++ src/utils/calldata.ts | 30 + src/utils/computePoolAddress.ts | 36 + src/utils/encodeSqrtRatioX96.ts | 17 + src/utils/fullMath.ts | 16 + src/{utils.ts => utils/index.ts} | 17 +- src/utils/isSorted.ts | 15 + src/utils/maxLiquidityForAmounts.ts | 91 ++ src/utils/mostSignificantBit.ts | 24 + src/utils/nearestUsableTick.ts | 29 + src/utils/priceTickConversions.ts | 51 + src/utils/sqrtPriceMath.ts | 119 +++ src/utils/tickList.ts | 133 +++ src/utils/tickMath.ts | 130 +++ test/pool.test.ts | 28 + yarn.lock | 187 ++++ 40 files changed, 7308 insertions(+), 6 deletions(-) create mode 100644 src/MasterDeployer.ts create mode 100644 src/abis/ConcentratedPoolManager.json create mode 100644 src/abis/LimitOrderManager.json create mode 100644 src/abis/MasterDeployer.json create mode 100644 src/abis/SwapRouter.json create mode 100644 src/concentratedPoolManager.ts create mode 100644 src/entities/RouteWrappers.ts create mode 100644 src/entities/TradeWrappers.ts create mode 100644 src/entities/mixedRoute/route.ts create mode 100644 src/entities/mixedRoute/trade.ts create mode 100644 src/entities/order.ts create mode 100644 src/entities/pool.ts create mode 100644 src/entities/positions.ts create mode 100644 src/entities/protocol.ts create mode 100644 src/entities/tick.ts create mode 100644 src/entities/tickDataProvider.ts create mode 100644 src/entities/tickListDataProvider.ts create mode 100644 src/entities/v2route.ts create mode 100644 src/entities/v2trade.ts create mode 100644 src/internalConstants.ts create mode 100644 src/limitOrderManager.ts create mode 100644 src/utils/calldata.ts create mode 100644 src/utils/computePoolAddress.ts create mode 100644 src/utils/encodeSqrtRatioX96.ts create mode 100644 src/utils/fullMath.ts rename src/{utils.ts => utils/index.ts} (84%) create mode 100644 src/utils/isSorted.ts create mode 100644 src/utils/maxLiquidityForAmounts.ts create mode 100644 src/utils/mostSignificantBit.ts create mode 100644 src/utils/nearestUsableTick.ts create mode 100644 src/utils/priceTickConversions.ts create mode 100644 src/utils/sqrtPriceMath.ts create mode 100644 src/utils/tickList.ts create mode 100644 src/utils/tickMath.ts create mode 100644 test/pool.test.ts diff --git a/src/MasterDeployer.ts b/src/MasterDeployer.ts new file mode 100644 index 0000000..1c7d3d7 --- /dev/null +++ b/src/MasterDeployer.ts @@ -0,0 +1,37 @@ +import { defaultAbiCoder, Interface } from "@ethersproject/abi"; +import MasterDeployerAbi from "./abis/MasterDeployer.json" +import { TICK_SPACINGS, V2_FACTORY_ADDRESS } from "./constants"; +import { Pool } from "./entities"; +import { MethodParameters, toHex } from "./utils"; + +export abstract class MasterDeployer { + public static INTERFACE: Interface = new Interface(MasterDeployerAbi) + + /** + * Cannot be constructed. + */ + private constructor() {} + + private static encodeCreate(pool: Pool): string { + console.log([pool.token0.address, pool.token1.address, pool.sqrtRatioX96, TICK_SPACINGS[pool.fee]]) + const deployData = defaultAbiCoder.encode( + ["address", "address", "uint160", "uint24"], + [pool.token0.address, pool.token1.address, pool.sqrtRatioX96.toString(), TICK_SPACINGS[pool.fee]] + ); + console.log(deployData) + const x= this.INTERFACE.encodeFunctionData('deployPool', [ + V2_FACTORY_ADDRESS[pool.token0.chainId], + deployData + ]) + console.log(x) + return x + } + + public static createCallParameters(pool: Pool): MethodParameters { + return { + calldata: this.encodeCreate(pool), + value: toHex(0) + } + } + +} \ No newline at end of file diff --git a/src/abis/ConcentratedPoolManager.json b/src/abis/ConcentratedPoolManager.json new file mode 100644 index 0000000..dd0c091 --- /dev/null +++ b/src/abis/ConcentratedPoolManager.json @@ -0,0 +1,902 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_masterDeployer", + "type": "address" + }, + { + "internalType": "address", + "name": "_wETH", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "approved", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "positionId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + } + ], + "name": "DecreaseLiquidity", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "positionId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + } + ], + "name": "IncreaseLiquidity", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "domainSeperator", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PERMIT_ALL_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PERMIT_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "bool", + "name": "unwrapVault", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "minimumOut0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minimumOut1", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "uint256", + "name": "token0Amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "token1Amount", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "bool", + "name": "unwrapVault", + "type": "bool" + } + ], + "name": "collect", + "outputs": [ + { + "internalType": "uint256", + "name": "token0amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "token1amount", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getApproved", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "masterDeployer", + "outputs": [ + { + "internalType": "contract IMasterDeployer", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IConcentratedLiquidityPool", + "name": "pool", + "type": "address" + }, + { + "internalType": "int24", + "name": "lowerOld", + "type": "int24" + }, + { + "internalType": "int24", + "name": "lower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "upperOld", + "type": "int24" + }, + { + "internalType": "int24", + "name": "upper", + "type": "int24" + }, + { + "internalType": "uint128", + "name": "amount0Desired", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1Desired", + "type": "uint128" + }, + { + "internalType": "bool", + "name": "native", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "minLiquidity", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "positionId", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "_positionId", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "native", + "type": "bool" + } + ], + "name": "mintCallback", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes[]", + "name": "data", + "type": "bytes[]" + } + ], + "name": "multicall", + "outputs": [ + { + "internalType": "bytes[]", + "name": "results", + "type": "bytes[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nftCount", + "outputs": [ + { + "internalType": "uint128", + "name": "minted", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "burned", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "noncesForAll", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "ownerOf", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenOwner", + "type": "address" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permitAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "positionFees", + "outputs": [ + { + "internalType": "uint256", + "name": "token0amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "token1amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside1", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "positions", + "outputs": [ + { + "internalType": "contract IConcentratedLiquidityPool", + "name": "pool", + "type": "address" + }, + { + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "internalType": "int24", + "name": "lower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "upper", + "type": "int24" + }, + { + "internalType": "uint32", + "name": "latestAddition", + "type": "uint32" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside1", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "tokenURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "vault", + "outputs": [ + { + "internalType": "contract IVaultMinimal", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/abis/LimitOrderManager.json b/src/abis/LimitOrderManager.json new file mode 100644 index 0000000..2b4fb89 --- /dev/null +++ b/src/abis/LimitOrderManager.json @@ -0,0 +1,360 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_masterDeployer", + "type": "address" + }, + { + "internalType": "address", + "name": "_weth", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "TickOutOfBounds", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "CancelLimitOrder", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ClaimLimitOrder", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tick", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "CreateLImitOrder", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "unwrapVault", + "type": "bool" + } + ], + "name": "cancelLimitOrder", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "unwrapVault", + "type": "bool" + } + ], + "name": "claimLimitOrder", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IConcentratedLiquidityPool", + "name": "pool", + "type": "address" + }, + { + "internalType": "int24", + "name": "tick", + "type": "int24" + }, + { + "internalType": "int24", + "name": "lowerOld", + "type": "int24" + }, + { + "internalType": "int24", + "name": "upperOld", + "type": "int24" + }, + { + "internalType": "bool", + "name": "native", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "zeroForOne", + "type": "bool" + } + ], + "name": "createLimitOrder", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getClaimableAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "owner", + "type": "uint256" + } + ], + "name": "getLimitOrderTokenBalance", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "native", + "type": "bool" + } + ], + "name": "limitOrderCallback", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "limitOrderId", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "limitOrderToken", + "outputs": [ + { + "internalType": "contract LimitOrderToken", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "limitOrders", + "outputs": [ + { + "internalType": "contract IConcentratedLiquidityPool", + "name": "pool", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "int24", + "name": "tick", + "type": "int24" + }, + { + "internalType": "uint256", + "name": "sqrtpriceX96", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "zeroForOne", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimedAmount", + "type": "uint256" + }, + { + "internalType": "enum ILimitOrderStruct.LimitOrderStatus", + "name": "status", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "masterDeployer", + "outputs": [ + { + "internalType": "contract IMasterDeployer", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vault", + "outputs": [ + { + "internalType": "contract IVaultMinimal", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/abis/MasterDeployer.json b/src/abis/MasterDeployer.json new file mode 100644 index 0000000..b8f6126 --- /dev/null +++ b/src/abis/MasterDeployer.json @@ -0,0 +1,348 @@ +[ + { + "inputs": [ + { + "internalType": "uint256", + "name": "_dfynFee", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_dfynFeeTo", + "type": "address" + }, + { + "internalType": "address", + "name": "_vault", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_limitOrderFee", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "InvalidDfynFee", + "type": "error" + }, + { + "inputs": [], + "name": "NotWhitelisted", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "factory", + "type": "address" + } + ], + "name": "AddToWhitelist", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "factory", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "deployData", + "type": "bytes" + } + ], + "name": "DeployPool", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "dfynFee", + "type": "uint256" + } + ], + "name": "DfynFeeUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "limitOrderFee", + "type": "uint256" + } + ], + "name": "LimitOrderFeeUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "factory", + "type": "address" + } + ], + "name": "RemoveFromWhitelist", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_factory", + "type": "address" + } + ], + "name": "addToWhitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_factory", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_deployData", + "type": "bytes" + } + ], + "name": "deployPool", + "outputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "dfynFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "dfynFeeTo", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "limitOrderFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "pools", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_factory", + "type": "address" + } + ], + "name": "removeFromWhitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_dfynFee", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_isLimit", + "type": "bool" + } + ], + "name": "setDfynFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "vault", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "whitelistedFactories", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/src/abis/SwapRouter.json b/src/abis/SwapRouter.json new file mode 100644 index 0000000..fc3f834 --- /dev/null +++ b/src/abis/SwapRouter.json @@ -0,0 +1,1377 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_factoryV2", + "type": "address" + }, + { + "internalType": "address", + "name": "factoryV3", + "type": "address" + }, + { + "internalType": "address", + "name": "_positionManager", + "type": "address" + }, + { + "internalType": "address", + "name": "_WETH9", + "type": "address" + }, + { + "internalType": "address", + "name": "_WETH9V1", + "type": "address" + }, + { + "internalType": "address", + "name": "_vault", + "type": "address" + }, + { + "internalType": "address", + "name": "_masterDeployer", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "WETH9", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WETH9V1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "approveMax", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "approveMaxMinusOne", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "approveZeroThenMax", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "approveZeroThenMaxMinusOne", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "callPositionManager", + "outputs": [ + { + "internalType": "bytes", + "name": "result", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes", + "name": "path", + "type": "bytes" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMinimum", + "type": "uint256" + } + ], + "internalType": "struct IV3SwapRouter.ExactInputParams", + "name": "params", + "type": "tuple" + } + ], + "name": "exactInput", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMinimum", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "bool", + "name": "unwrapVault", + "type": "bool" + }, + { + "components": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + } + ], + "internalType": "struct IDfynRouter.Path[]", + "name": "path", + "type": "tuple[]" + } + ], + "internalType": "struct IDfynRouter.ExactInputParamsDfyn", + "name": "params", + "type": "tuple" + } + ], + "name": "exactInputDfyn", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenOut", + "type": "address" + }, + { + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMinimum", + "type": "uint256" + }, + { + "internalType": "uint160", + "name": "sqrtPriceLimitX96", + "type": "uint160" + } + ], + "internalType": "struct IV3SwapRouter.ExactInputSingleParams", + "name": "params", + "type": "tuple" + } + ], + "name": "exactInputSingle", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMinimum", + "type": "uint256" + }, + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "internalType": "struct IDfynRouter.ExactInputSingleParamsDfyn", + "name": "params", + "type": "tuple" + } + ], + "name": "exactInputSingleDfyn", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMinimum", + "type": "uint256" + }, + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "internalType": "struct IDfynRouter.ExactInputSingleParamsDfyn", + "name": "params", + "type": "tuple" + } + ], + "name": "exactInputSingleWithNativeToken", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMinimum", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "bool", + "name": "unwrapVault", + "type": "bool" + }, + { + "components": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + } + ], + "internalType": "struct IDfynRouter.Path[]", + "name": "path", + "type": "tuple[]" + } + ], + "internalType": "struct IDfynRouter.ExactInputParamsDfyn", + "name": "params", + "type": "tuple" + } + ], + "name": "exactInputWithNativeToken", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes", + "name": "path", + "type": "bytes" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountInMaximum", + "type": "uint256" + } + ], + "internalType": "struct IV3SwapRouter.ExactOutputParams", + "name": "params", + "type": "tuple" + } + ], + "name": "exactOutput", + "outputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenOut", + "type": "address" + }, + { + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountInMaximum", + "type": "uint256" + }, + { + "internalType": "uint160", + "name": "sqrtPriceLimitX96", + "type": "uint160" + } + ], + "internalType": "struct IV3SwapRouter.ExactOutputSingleParams", + "name": "params", + "type": "tuple" + } + ], + "name": "exactOutputSingle", + "outputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "factoryV2", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "getApprovalType", + "outputs": [ + { + "internalType": "enum IApproveAndCall.ApprovalType", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount0Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Min", + "type": "uint256" + } + ], + "internalType": "struct IApproveAndCall.IncreaseLiquidityParams", + "name": "params", + "type": "tuple" + } + ], + "name": "increaseLiquidity", + "outputs": [ + { + "internalType": "bytes", + "name": "result", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "masterDeployer", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint256", + "name": "amount0Min", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1Min", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "internalType": "struct IApproveAndCall.MintParams", + "name": "params", + "type": "tuple" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "bytes", + "name": "result", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "previousBlockhash", + "type": "bytes32" + }, + { + "internalType": "bytes[]", + "name": "data", + "type": "bytes[]" + } + ], + "name": "multicall", + "outputs": [ + { + "internalType": "bytes[]", + "name": "", + "type": "bytes[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "bytes[]", + "name": "data", + "type": "bytes[]" + } + ], + "name": "multicall", + "outputs": [ + { + "internalType": "bytes[]", + "name": "", + "type": "bytes[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes[]", + "name": "data", + "type": "bytes[]" + } + ], + "name": "multicall", + "outputs": [ + { + "internalType": "bytes[]", + "name": "results", + "type": "bytes[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "positionManager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "pull", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "refundETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "selfPermit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expiry", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "selfPermitAllowed", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expiry", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "selfPermitAllowedIfNecessary", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "selfPermitIfNecessary", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "swapCallBack", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOutMin", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "swapExactTokensForTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountInMax", + "type": "uint256" + }, + { + "internalType": "address[]", + "name": "path", + "type": "address[]" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "swapTokensForExactTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "bool", + "name": "onVault", + "type": "bool" + } + ], + "name": "sweep", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountMinimum", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "name": "sweepToken", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountMinimum", + "type": "uint256" + } + ], + "name": "sweepToken", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountMinimum", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeBips", + "type": "uint256" + }, + { + "internalType": "address", + "name": "feeRecipient", + "type": "address" + } + ], + "name": "sweepTokenWithFee", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountMinimum", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "feeBips", + "type": "uint256" + }, + { + "internalType": "address", + "name": "feeRecipient", + "type": "address" + } + ], + "name": "sweepTokenWithFee", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int256", + "name": "amount0Delta", + "type": "int256" + }, + { + "internalType": "int256", + "name": "amount1Delta", + "type": "int256" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "uniswapV3SwapCallback", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountMinimum", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "name": "unwrapWETH9", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountMinimum", + "type": "uint256" + } + ], + "name": "unwrapWETH9", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountMinimum", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "bool", + "name": "v1", + "type": "bool" + } + ], + "name": "unwrapWETH9Legacy", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountMinimum", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "feeBips", + "type": "uint256" + }, + { + "internalType": "address", + "name": "feeRecipient", + "type": "address" + } + ], + "name": "unwrapWETH9WithFee", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountMinimum", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeBips", + "type": "uint256" + }, + { + "internalType": "address", + "name": "feeRecipient", + "type": "address" + } + ], + "name": "unwrapWETH9WithFee", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "vault", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "wrapETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "v1", + "type": "bool" + } + ], + "name": "wrapETHLegacy", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ] \ No newline at end of file diff --git a/src/concentratedPoolManager.ts b/src/concentratedPoolManager.ts new file mode 100644 index 0000000..549dfaf --- /dev/null +++ b/src/concentratedPoolManager.ts @@ -0,0 +1,370 @@ +import { Interface } from "@ethersproject/abi"; +import invariant from "tiny-invariant"; +import ConcentratedPoolManagerAbi from "./abis/ConcentratedPoolManager.json" +import { Currency, CurrencyAmount, Percent, Pool, Position, wrappedCurrency } from "./entities"; +import { ZERO } from "./internalConstants"; +import { MethodParameters, toHex, validateAndParseAddress } from "./utils"; +import JSBI from 'jsbi' +import { ADDRESS_ZERO, BigintIsh } from "./constants"; + +export interface MintSpecificOptions { + /** + * The account that should receive the minted NFT. + */ + recipient: string + + /** + * Creates pool if not initialized before mint. + */ + createPool?: boolean + } + export interface CollectOptions { + /** + * Indicates the ID of the position to collect for. + */ + tokenId: BigintIsh + + /** + * Expected value of tokensOwed0, including as-of-yet-unaccounted-for fees/liquidity value to be burned + */ + expectedCurrencyOwed0: CurrencyAmount + + /** + * Expected value of tokensOwed1, including as-of-yet-unaccounted-for fees/liquidity value to be burned + */ + expectedCurrencyOwed1: CurrencyAmount + + /** + * The account that should receive the tokens. + */ + recipient: string + + /** + * To unwrap or not + */ + unwrapVault: boolean + } +/** + * Options for producing the calldata to exit a position. + */ + export interface RemoveLiquidityOptions { + /** + * The ID of the token to exit + */ + tokenId: BigintIsh + + /** + * The percentage of position liquidity to exit. + */ + liquidityPercentage: Percent + + /** + * How much the pool price is allowed to move. + */ + slippageTolerance: Percent + + + /** + * The account that should receive the tokens. + */ + recipient: string + + /** + * To unwrap or not + */ + unwrapVault: boolean +} + + export interface IncreaseSpecificOptions { + /** + * Indicates the ID of the position to increase liquidity for. + */ + tokenId: BigintIsh + } + + /** + * Options for producing the calldata to add liquidity. + */ + export interface CommonAddLiquidityOptions { + /** + * How much the pool price is allowed to move. + */ + slippageTolerance: Percent + + /** + * When the transaction expires, in epoch seconds. + */ + deadline: BigintIsh + + /** + * Whether to spend ether. If true, one of the pool tokens must be WETH, by default false + */ + useNative?: Currency + + // /** + // * The optional permit parameters for spending token0 + // */ + // token0Permit?: PermitOptions + + // /** + // * The optional permit parameters for spending token1 + // */ + // token1Permit?: PermitOptions + + /** + * The lower and upper old + */ + lowerOldTick: number + + /** + * The lower and upper old + */ + upperOldTick: number + + } + + export type MintOptions = CommonAddLiquidityOptions & MintSpecificOptions + export type IncreaseOptions = CommonAddLiquidityOptions & IncreaseSpecificOptions + + export type AddLiquidityOptions = MintOptions | IncreaseOptions + + export interface SafeTransferOptions { + /** + * The account sending the NFT. + */ + sender: string + + /** + * The account that should receive the NFT. + */ + recipient: string + + /** + * The id of the token being sent. + */ + tokenId: BigintIsh + /** + * The optional parameter that passes data to the `onERC721Received` call for the staker + */ + data?: string + } + + // type guard +export function isMint(options: AddLiquidityOptions): options is MintOptions { + return Object.keys(options).some(k => k === 'recipient') + } + + +export abstract class ConcentratedPoolManager { + public static INTERFACE: Interface = new Interface(ConcentratedPoolManagerAbi) + + /** + * Cannot be constructed. + */ + private constructor() {} + + public static addCallParameters(position: Position, options: AddLiquidityOptions): MethodParameters { + invariant(JSBI.greaterThan(position.liquidity, ZERO), 'ZERO_LIQUIDITY') + + let calldata: string + + // get amounts + const { amount0: amount0Desired, amount1: amount1Desired } = position.mintAmounts + + // adjust for slippage + // const minimumAmounts = position.mintAmountsWithSlippage(options.slippageTolerance) + // const amount0Min = toHex(minimumAmounts.amount0) + // const amount1Min = toHex(minimumAmounts.amount1) + + // const deadline = toHex(options.deadline) + + // revert if pool not present + // invariant(options?.createPool,'POOL_DOES_NOT_EXISTS'); + + // permits if necessary + // if (options.token0Permit) { + // calldatas.push(SelfPermit.encodePermit(position.pool.token0, options.token0Permit)) + // } + // if (options.token1Permit) { + // calldatas.push(SelfPermit.encodePermit(position.pool.token1, options.token1Permit)) + // } + + // mint + if (isMint(options)) { + calldata= + this.INTERFACE.encodeFunctionData('mint', [ + Pool.getAddress(position.pool.token0,position.pool.token1), + options.lowerOldTick, + position.tickLower, + options.upperOldTick, + position.tickUpper, + toHex(amount0Desired), + toHex(amount1Desired), + true, + position.liquidity.toString(), + "0" + // token0: position.pool.token0.address, + // token1: position.pool.token1.address, + // fee: position.pool.fee, + // tickLower: position.tickLower, + // tickUpper: position.tickUpper, + // amount0Desired: toHex(amount0Desired), + // amount1Desired: toHex(amount1Desired), + // amount0Min, + // amount1Min, + // recipient, + // deadline + ]) + + } else { + // increase + calldata= + this.INTERFACE.encodeFunctionData('mint', [ + Pool.getAddress(position.pool.token0,position.pool.token1), + options.lowerOldTick, + position.tickLower, + options.upperOldTick, + position.tickUpper, + toHex(amount0Desired), + toHex(amount1Desired), + true, + position.liquidity.toString(), + options.tokenId + // token0: position.pool.token0.address, + // token1: position.pool.token1.address, + // fee: position.pool.fee, + // tickLower: position.tickLower, + // tickUpper: position.tickUpper, + // amount0Desired: toHex(amount0Desired), + // amount1Desired: toHex(amount1Desired), + // amount0Min, + // amount1Min, + // recipient, + // deadline + ]) + } + + let value: string = toHex(0) + if (options.useNative) { + const wrapped = wrappedCurrency(options.useNative,position.pool.token0.chainId) + invariant(position.pool.token0.equals(wrapped) || position.pool.token1.equals(wrapped), 'NO_WETH') + + const wrappedValue = position.pool.token0.equals(wrapped) ? amount0Desired : amount1Desired + + value = toHex(wrappedValue) + } + + return { + calldata, + value + } + } + + private static encodeCollect(options: CollectOptions): string { + let calldata + + const tokenId = toHex(options.tokenId) + + // // // // // // // // // // // // // // // // // // // // // + // // // // // // // NATIVE SUPPORT TO BE ADDED // // // // // + // // // // // // // // // // // // // // // // // // // // // + // const involvesETH = + // options.expectedCurrencyOwed0.currency.isNative || options.expectedCurrencyOwed1.currency.isNative + const involvesETH = + false + + const recipient = validateAndParseAddress(options.recipient) + + // collect + calldata= + this.INTERFACE.encodeFunctionData('collect', [ + tokenId, + involvesETH ? ADDRESS_ZERO : recipient, + options.unwrapVault + ]) + + // if (involvesETH) { + // const ethAmount = options.expectedCurrencyOwed0.currency.isNative + // ? options.expectedCurrencyOwed0.quotient + // : options.expectedCurrencyOwed1.quotient + // const token = options.expectedCurrencyOwed0.currency.isNative + // ? (options.expectedCurrencyOwed1.currency as Token) + // : (options.expectedCurrencyOwed0.currency as Token) + // const tokenAmount = options.expectedCurrencyOwed0.currency.isNative + // ? options.expectedCurrencyOwed1.quotient + // : options.expectedCurrencyOwed0.quotient + + // calldatas.push(Payments.encodeUnwrapWETH9(ethAmount, recipient)) + // calldatas.push(Payments.encodeSweepToken(token, tokenAmount, recipient)) + // } + + return calldata + } + + public static collectCallParameters(options: CollectOptions): MethodParameters { + const calldata = this.encodeCollect(options) + + return { + calldata, + value: toHex(0) + } + } + + /** + * Produces the calldata for completely or partially exiting a position + * @param position The position to exit + * @param options Additional information necessary for generating the calldata + * @returns The call parameters + */ + public static removeCallParameters(position: Position, options: RemoveLiquidityOptions): MethodParameters { + let calldata; + + const tokenId = toHex(options.tokenId) + const recipient=options.recipient + + // construct a partial position with a percentage of liquidity + const partialPosition = new Position({ + pool: position.pool, + liquidity: options.liquidityPercentage.multiply(position.liquidity).quotient, + tickLower: position.tickLower, + tickUpper: position.tickUpper + }) + invariant(JSBI.greaterThan(partialPosition.liquidity, ZERO), 'ZERO_LIQUIDITY') + + // slippage-adjusted underlying amounts + const { amount0: amount0Min, amount1: amount1Min } = partialPosition.burnAmountsWithSlippage( + options.slippageTolerance + ) + + // if (options.permit) { + // calldatas.push( + // NonfungiblePositionManager.INTERFACE.encodeFunctionData('permit', [ + // validateAndParseAddress(options.permit.spender), + // tokenId, + // toHex(options.permit.deadline), + // options.permit.v, + // options.permit.r, + // options.permit.s + // ]) + // ) + // } + + // remove liquidity + + calldata=this.INTERFACE.encodeFunctionData('burn', [ + tokenId, + partialPosition.liquidity.toString(), + recipient, + options.unwrapVault, + amount0Min.toString(), + amount1Min.toString() + ]) + + + return { + calldata, + value: toHex(0) + } + } + +} \ No newline at end of file diff --git a/src/constants.ts b/src/constants.ts index 3034de2..9a157e9 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,7 +1,7 @@ import JSBI from 'jsbi' // exports for external consumption -export type BigintIsh = JSBI | bigint | string +export type BigintIsh = JSBI | number | string export enum ChainId { MAINNET = 1, @@ -104,3 +104,92 @@ export const SOLIDITY_TYPE_MAXIMA = { [SolidityType.uint8]: JSBI.BigInt('0xff'), [SolidityType.uint256]: JSBI.BigInt('0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff') } + +export const V2_FACTORY_ADDRESS: { [chainId in ChainId]: string } = { + [ChainId.MAINNET]: '', + [ChainId.ROPSTEN]: '', + [ChainId.RINKEBY]: '', + [ChainId.GΓ–RLI]: '', + [ChainId.KOVAN]: '', + [ChainId.MATIC]: '0x76e8Ce7D482F29Efd66E4aC1994A13B2Aa398812', + [ChainId.OKEX]: '', + [ChainId.ARBITRUM]: '', + [ChainId.XDAI]: '', + [ChainId.FANTOM]: '', + [ChainId.HARMONY]: '', + [ChainId.BSC]: '', + [ChainId.AVALANCHE]: '', +} + + +export const V2_DEPLOYER_ADDRESS: { [chainId in ChainId]: string } = { + [ChainId.MAINNET]: '', + [ChainId.ROPSTEN]: '', + [ChainId.RINKEBY]: '', + [ChainId.GΓ–RLI]: '', + [ChainId.KOVAN]: '', + [ChainId.MATIC]: '0xd3fD03f36F1e490290DEd8f93A098c7C9921AFC7', + [ChainId.OKEX]: '', + [ChainId.ARBITRUM]: '', + [ChainId.XDAI]: '', + [ChainId.FANTOM]: '', + [ChainId.HARMONY]: '', + [ChainId.BSC]: '', + [ChainId.AVALANCHE]: '', +} +export const V2_MASTER_DEPLOYER_ADDRESS: { [chainId in ChainId]: string } = { + [ChainId.MAINNET]: '', + [ChainId.ROPSTEN]: '', + [ChainId.RINKEBY]: '', + [ChainId.GΓ–RLI]: '', + [ChainId.KOVAN]: '', + [ChainId.MATIC]: '0x8b4e43a9922ca57b06Ab3A1Ee222163Cdd504cc1', + [ChainId.OKEX]: '', + [ChainId.ARBITRUM]: '', + [ChainId.XDAI]: '', + [ChainId.FANTOM]: '', + [ChainId.HARMONY]: '', + [ChainId.BSC]: '', + [ChainId.AVALANCHE]: '', +} + +export const ADDRESS_ZERO = '0x0000000000000000000000000000000000000000' + +export const V2_POOL_INIT_CODE_HASH: { [chainId in ChainId]: string } = { + [ChainId.MAINNET]: '', + [ChainId.ROPSTEN]: '', + [ChainId.RINKEBY]: '', + [ChainId.GΓ–RLI]: '', + [ChainId.KOVAN]: '', + [ChainId.MATIC]: '0xb1467d61353f1381ce595794734cf69d5ab5cb73d48acc00e8d720d62280c232', + [ChainId.OKEX]: '', + [ChainId.ARBITRUM]: '', + [ChainId.XDAI]: '', + [ChainId.FANTOM]: '', + [ChainId.HARMONY]: '', + [ChainId.BSC]: '', + [ChainId.AVALANCHE]: '', +} + + +/** + * The default factory enabled fee amounts, denominated in hundredths of bips. + */ +export enum FeeAmount { + // LOWEST = 100, + LOW = 500, + // MEDIUM = 3000, + // HIGH = 10000 +} + +/** + * The default factory tick spacings by fee amount. + */ +export const TICK_SPACINGS: { [amount in FeeAmount]: number } = { + // [FeeAmount.LOWEST]: 1, + [FeeAmount.LOW]: 10, + // [FeeAmount.MEDIUM]: 60, + // [FeeAmount.HIGH]: 200 +} + +export const MaxUint256 = JSBI.BigInt('0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff') diff --git a/src/entities/RouteWrappers.ts b/src/entities/RouteWrappers.ts new file mode 100644 index 0000000..b9c5aeb --- /dev/null +++ b/src/entities/RouteWrappers.ts @@ -0,0 +1,72 @@ +// entities/route.ts + +import { Route as V1RouteSDK, Pair } from '../index' +import { V2Route as V2RouteSDK, Pool } from '../index' +import { Protocol } from './protocol' +import { Currency, Price, Token } from '../index' +import { MixedRouteSDK } from './mixedRoute/route' +type TPool = Pair | Pool + +export interface IRoute { + protocol: Protocol + // array of pools if v3 or pairs if v2 + pools: TPool[] + path: Token[] + midPrice: Price + input: Currency + output: Currency +} + +// V1 route wrapper +export class RouteV1 + extends V1RouteSDK + implements IRoute +{ + public readonly protocol: Protocol = Protocol.V1 + public readonly pools: Pair[] + + constructor(v1Route: V1RouteSDK) { + super(v1Route.pairs, v1Route.input, v1Route.output) + this.pools = this.pairs + } +} + +// V2 route wrapper +export class RouteV2 + extends V2RouteSDK + implements IRoute +{ + public readonly protocol: Protocol = Protocol.V2 + public readonly path: Token[] + + constructor(v2Route: V2RouteSDK) { + super(v2Route.pools, v2Route.input, v2Route.output) + this.path = v2Route.tokenPath + } +} + +// UniV3 route wrapper +export class RouteUniV2 + extends V2RouteSDK + implements IRoute +{ + public readonly protocol: Protocol = Protocol.UNIV3 + public readonly path: Token[] + + constructor(v2Route: V2RouteSDK) { + super(v2Route.pools, v2Route.input, v2Route.output) + this.path = v2Route.tokenPath + } +} + +// Mixed route wrapper +export class MixedRoute + extends MixedRouteSDK + implements IRoute +{ + public readonly protocol: Protocol = Protocol.MIXED + + constructor(mixedRoute: MixedRouteSDK) { + super(mixedRoute.pools, mixedRoute.input, mixedRoute.output) + } +} \ No newline at end of file diff --git a/src/entities/TradeWrappers.ts b/src/entities/TradeWrappers.ts new file mode 100644 index 0000000..9477a76 --- /dev/null +++ b/src/entities/TradeWrappers.ts @@ -0,0 +1,404 @@ +import { CurrencyAmount, Fraction, Percent, Price, TradeType, wrappedCurrency } from '../index' +import { Pair, Route as V1RouteSDK, Trade as V1TradeSDK } from '../index' +import { Pool, V2Route as V2RouteSDK, V2Trade as V2TradeSDK } from '../index' +import invariant from 'tiny-invariant' +import { ONE, ZERO } from '../constants' +import { MixedRouteSDK } from './mixedRoute/route' +import { MixedRouteTrade as MixedRouteTradeSDK } from './mixedRoute/trade' +import { IRoute, MixedRoute, RouteV1, RouteV2, RouteUniV2 } from './RouteWrappers' + +export class MixedTrade { + public readonly routes: IRoute[] + public readonly tradeType: TradeType + private _outputAmount: CurrencyAmount | undefined + private _inputAmount: CurrencyAmount | undefined + + /** + * The swaps of the trade, i.e. which routes and how much is swapped in each that + * make up the trade. May consist of swaps in v1 or v2. + */ + public readonly swaps: { + route: IRoute + inputAmount: CurrencyAmount + outputAmount: CurrencyAmount + }[] + + // construct a trade across v1 and v2 routes from pre-computed amounts + public constructor({ + v1Routes, + v2Routes, + uniV3Routes, + tradeType, + mixedRoutes, + }: { + v1Routes: { + routev1: V1RouteSDK + inputAmount: CurrencyAmount + outputAmount: CurrencyAmount + }[] + v2Routes: { + routev2: V2RouteSDK + inputAmount: CurrencyAmount + outputAmount: CurrencyAmount + }[] + uniV3Routes: { + routeUniV3: V2RouteSDK + inputAmount: CurrencyAmount + outputAmount: CurrencyAmount + }[] + tradeType: TradeType + mixedRoutes?: { + mixedRoute: MixedRouteSDK + inputAmount: CurrencyAmount + outputAmount: CurrencyAmount + }[] + }) { + this.swaps = [] + this.routes = [] + // wrap v1 routes + for (const { routev1, inputAmount, outputAmount } of v1Routes) { + const route = new RouteV1(routev1) + this.routes.push(route) + this.swaps.push({ + route, + inputAmount, + outputAmount, + }) + } + // wrap v2 routes + for (const { routev2, inputAmount, outputAmount } of v2Routes) { + const route = new RouteV2(routev2) + this.routes.push(route) + this.swaps.push({ + route, + inputAmount, + outputAmount, + }) + } + // wrap univ3 routes + for (const { routeUniV3, inputAmount, outputAmount } of uniV3Routes) { + const route = new RouteUniV2(routeUniV3) + this.routes.push(route) + this.swaps.push({ + route, + inputAmount, + outputAmount, + }) + } + // wrap mixedRoutes + if (mixedRoutes) { + for (const { mixedRoute, inputAmount, outputAmount } of mixedRoutes) { + const route = new MixedRoute(mixedRoute) + this.routes.push(route) + this.swaps.push({ + route, + inputAmount, + outputAmount, + }) + } + } + this.tradeType = tradeType + + // each route must have the same input and output currency + const inputCurrency = this.swaps[0].inputAmount.currency + const outputCurrency = this.swaps[0].outputAmount.currency + invariant( + this.swaps.every(({ route }) => { + const chainId=route.pools[0].chainId + return wrappedCurrency(inputCurrency,chainId).equals(wrappedCurrency(route.input,chainId))}), + 'INPUT_CURRENCY_MATCH' + ) + invariant( + this.swaps.every(({ route }) => { + const chainId=route.pools[0].chainId + return wrappedCurrency(outputCurrency,chainId).equals(wrappedCurrency(route.output,chainId))}), + 'OUTPUT_CURRENCY_MATCH' + ) + + // pools must be unique inter protocols + const numPools = this.swaps.map(({ route }) => route.pools.length).reduce((total, cur) => total + cur, 0) + const poolAddressSet = new Set() + for (const { route } of this.swaps) { + for (const pool of route.pools) { + if (pool instanceof Pool) { + poolAddressSet.add(Pool.getAddress(pool.token0, pool.token1)) + } else if (pool instanceof Pair) { + const pair = pool + poolAddressSet.add(Pair.getAddress(pair.token0, pair.token1)) + } else { + throw new Error('Unexpected pool type in route when constructing trade object') + } + } + } + invariant(numPools == poolAddressSet.size, 'POOLS_DUPLICATED') + } + + public get inputAmount(): CurrencyAmount { + if (this._inputAmount) { + return this._inputAmount + } + + const inputCurrency = this.swaps[0].inputAmount.currency + const totalInputFromRoutes = this.swaps + .map(({ inputAmount }) => inputAmount) + .reduce((total, cur) => total.add(cur), new CurrencyAmount(inputCurrency, 0)) + + this._inputAmount = totalInputFromRoutes + return this._inputAmount + } + + public get outputAmount(): CurrencyAmount { + if (this._outputAmount) { + return this._outputAmount + } + + const outputCurrency = this.swaps[0].outputAmount.currency + const totalOutputFromRoutes = this.swaps + .map(({ outputAmount }) => outputAmount) + .reduce((total, cur) => total.add(cur), new CurrencyAmount(outputCurrency, 0)) + + this._outputAmount = totalOutputFromRoutes + return this._outputAmount + } + + private _executionPrice: Price | undefined + + /** + * The price expressed in terms of output amount/input amount. + */ + public get executionPrice(): Price { + return ( + this._executionPrice ?? + (this._executionPrice = new Price( + this.inputAmount.currency, + this.outputAmount.currency, + this.inputAmount.quotient, + this.outputAmount.quotient + )) + ) + } + + /** + * The cached result of the price impact computation + * @private + */ + private _priceImpact: Percent | undefined + /** + * Returns the percent difference between the route's mid price and the price impact + */ + public get priceImpact(): Percent { + if (this._priceImpact) { + return this._priceImpact + } + + let spotOutputAmount = new CurrencyAmount(this.outputAmount.currency, 0) + for (const { route, inputAmount } of this.swaps) { + const midPrice = route.midPrice + spotOutputAmount = spotOutputAmount.add(midPrice.quote(inputAmount)) + } + + const priceImpact = spotOutputAmount.subtract(this.outputAmount).divide(spotOutputAmount) + this._priceImpact = new Percent(priceImpact.numerator, priceImpact.denominator) + + return this._priceImpact + } + + /** + * Get the minimum amount that must be received from this trade for the given slippage tolerance + * @param slippageTolerance The tolerance of unfavorable slippage from the execution price of this trade + * @returns The amount out + */ + public minimumAmountOut(slippageTolerance: Percent, amountOut = this.outputAmount): CurrencyAmount { + invariant(!slippageTolerance.lessThan(ZERO), 'SLIPPAGE_TOLERANCE') + if (this.tradeType === TradeType.EXACT_OUTPUT) { + return amountOut + } else { + const slippageAdjustedAmountOut = new Fraction(ONE) + .add(slippageTolerance) + .invert() + .multiply(amountOut.quotient).quotient + return new CurrencyAmount(amountOut.currency, slippageAdjustedAmountOut) + } + } + + /** + * Get the maximum amount in that can be spent via this trade for the given slippage tolerance + * @param slippageTolerance The tolerance of unfavorable slippage from the execution price of this trade + * @returns The amount in + */ + public maximumAmountIn(slippageTolerance: Percent, amountIn = this.inputAmount): CurrencyAmount { + invariant(!slippageTolerance.lessThan(ZERO), 'SLIPPAGE_TOLERANCE') + if (this.tradeType === TradeType.EXACT_INPUT) { + return amountIn + } else { + const slippageAdjustedAmountIn = new Fraction(ONE).add(slippageTolerance).multiply(amountIn.quotient).quotient + return new CurrencyAmount(amountIn.currency, slippageAdjustedAmountIn) + } + } + + /** + * Return the execution price after accounting for slippage tolerance + * @param slippageTolerance the allowed tolerated slippage + * @returns The execution price + */ + public worstExecutionPrice(slippageTolerance: Percent): Price { + return new Price( + this.inputAmount.currency, + this.outputAmount.currency, + this.maximumAmountIn(slippageTolerance).quotient, + this.minimumAmountOut(slippageTolerance).quotient + ) + } + + public static async fromRoutes( + v1Routes: { + routev1: V1RouteSDK + amount: TradeType extends TradeType.EXACT_INPUT ? CurrencyAmount : CurrencyAmount + }[], + v2Routes: { + routev2: V2RouteSDK + amount: TradeType extends TradeType.EXACT_INPUT ? CurrencyAmount : CurrencyAmount + }[], + uniV3Routes: { + routeUniV3: V2RouteSDK + amount: TradeType extends TradeType.EXACT_INPUT ? CurrencyAmount : CurrencyAmount + }[], + tradeType: TradeType, + mixedRoutes?: { + mixedRoute: MixedRouteSDK + amount: TradeType extends TradeType.EXACT_INPUT ? CurrencyAmount : CurrencyAmount + }[] + ): Promise { + const populatedV1Routes: { + routev1: V1RouteSDK + inputAmount: CurrencyAmount + outputAmount: CurrencyAmount + }[] = [] + + const populatedV2Routes: { + routev2: V2RouteSDK + inputAmount: CurrencyAmount + outputAmount: CurrencyAmount + }[] = [] + + const populatedUniV3Routes: { + routeUniV3: V2RouteSDK + inputAmount: CurrencyAmount + outputAmount: CurrencyAmount + }[] = [] + + const populatedMixedRoutes: { + mixedRoute: MixedRouteSDK + inputAmount: CurrencyAmount + outputAmount: CurrencyAmount + }[] = [] + + for (const { routev1, amount } of v1Routes) { + const v1Trade = new V1TradeSDK(routev1, amount, tradeType) + const { inputAmount, outputAmount } = v1Trade + + populatedV1Routes.push({ + routev1, + inputAmount, + outputAmount, + }) + } + + for (const { routev2, amount } of v2Routes) { + const v2Trade = await V2TradeSDK.fromRoute(routev2, amount, tradeType) + const { inputAmount, outputAmount } = v2Trade + + populatedV2Routes.push({ + routev2, + inputAmount, + outputAmount, + }) + } + + for (const { routeUniV3, amount } of uniV3Routes) { + const v2Trade = await V2TradeSDK.fromRoute(routeUniV3, amount, tradeType) + const { inputAmount, outputAmount } = v2Trade + + populatedUniV3Routes.push({ + routeUniV3, + inputAmount, + outputAmount, + }) + } + + if (mixedRoutes) { + for (const { mixedRoute, amount } of mixedRoutes) { + const mixedRouteTrade = await MixedRouteTradeSDK.fromRoute(mixedRoute, amount, tradeType) + const { inputAmount, outputAmount } = mixedRouteTrade + + populatedMixedRoutes.push({ + mixedRoute, + inputAmount, + outputAmount, + }) + } + } + + return new MixedTrade({ + v1Routes: populatedV1Routes, + v2Routes: populatedV2Routes, + uniV3Routes: populatedUniV3Routes, + mixedRoutes: populatedMixedRoutes, + tradeType, + }) + } + + public static async fromRoute( + route: V1RouteSDK | V2RouteSDK | MixedRouteSDK, + amount: TradeType extends TradeType.EXACT_INPUT ? CurrencyAmount : CurrencyAmount, + tradeType: TradeType + ): Promise { + let v1Routes: { + routev1: V1RouteSDK + inputAmount: CurrencyAmount + outputAmount: CurrencyAmount + }[] = [] + + let v2Routes: { + routev2: V2RouteSDK + inputAmount: CurrencyAmount + outputAmount: CurrencyAmount + }[] = [] + + let uniV3Routes: { + routeUniV3: V2RouteSDK + inputAmount: CurrencyAmount + outputAmount: CurrencyAmount + }[] = [] + + let mixedRoutes: { + mixedRoute: MixedRouteSDK + inputAmount: CurrencyAmount + outputAmount: CurrencyAmount + }[] = [] + + if (route instanceof V1RouteSDK) { + const v1Trade = new V1TradeSDK(route, amount, tradeType) + const { inputAmount, outputAmount } = v1Trade + v1Routes = [{ routev1: route, inputAmount, outputAmount }] + } else if (route instanceof V2RouteSDK) { + const v2Trade = await V2TradeSDK.fromRoute(route, amount, tradeType) + const { inputAmount, outputAmount } = v2Trade + v2Routes = [{ routev2: route, inputAmount, outputAmount }] + } else if (route instanceof MixedRouteSDK) { + const mixedRouteTrade = await MixedRouteTradeSDK.fromRoute(route, amount, tradeType) + const { inputAmount, outputAmount } = mixedRouteTrade + mixedRoutes = [{ mixedRoute: route, inputAmount, outputAmount }] + } else { + throw new Error('Invalid route type') + } + + return new MixedTrade({ + v1Routes, + v2Routes, + uniV3Routes, + mixedRoutes, + tradeType, + }) + } +} \ No newline at end of file diff --git a/src/entities/index.ts b/src/entities/index.ts index c217ba5..7f17458 100644 --- a/src/entities/index.ts +++ b/src/entities/index.ts @@ -3,5 +3,17 @@ export * from './pair' export * from './route' export * from './trade' export * from './currency' +export * from './pool' +export * from './positions' +export * from './order' +export * from './tick' +export * from './tickDataProvider' +export * from './v2route' +export * from './v2trade' +export * from './protocol' +export * from './RouteWrappers' +export * from './TradeWrappers' +export * from './mixedRoute/route' +export * from './mixedRoute/trade' export * from './fractions' diff --git a/src/entities/mixedRoute/route.ts b/src/entities/mixedRoute/route.ts new file mode 100644 index 0000000..b90de4f --- /dev/null +++ b/src/entities/mixedRoute/route.ts @@ -0,0 +1,90 @@ +import invariant from 'tiny-invariant' + +import { Currency,Pair, Pool,Price, Token,wrappedCurrency } from '../index' + +type TPool = Pair | Pool + +/** + * Represents a list of pools or pairs through which a swap can occur + * @template TInput The input token + * @template TOutput The output token + */ +export class MixedRouteSDK { + public readonly pools: TPool[] + public readonly path: Token[] + public readonly input: Currency + public readonly output: Currency + + private _midPrice: Price | null = null + + /** + * Creates an instance of route. + * @param pools An array of `TPool` objects (pools or pairs), ordered by the route the swap will take + * @param input The input token + * @param output The output token + */ + public constructor(pools: TPool[], input: Currency, output: Currency) { + invariant(pools.length > 0, 'POOLS') + + const chainId = pools[0].chainId + const allOnSameChain = pools.every((pool) => pool.chainId === chainId) + invariant(allOnSameChain, 'CHAIN_IDS') + + const wrappedInput = wrappedCurrency(input,chainId) + invariant(pools[0].involvesToken(wrappedInput), 'INPUT') + + invariant(pools[pools.length - 1].involvesToken(wrappedCurrency(output,chainId)), 'OUTPUT') + + /** + * Normalizes token0-token1 order and selects the next token/fee step to add to the path + * */ + const tokenPath: Token[] = [wrappedInput] + for (const [i, pool] of pools.entries()) { + const currentInputToken = tokenPath[i] + invariant(currentInputToken.equals(pool.token0) || currentInputToken.equals(pool.token1), 'PATH') + const nextToken = currentInputToken.equals(pool.token0) ? pool.token1 : pool.token0 + tokenPath.push(nextToken) + } + + this.pools = pools + this.path = tokenPath + this.input = input + this.output = output ?? tokenPath[tokenPath.length - 1] + } + + public get chainId(): number { + return this.pools[0].chainId + } + + /** + * Returns the mid price of the route + */ + public get midPrice(): Price { + if (this._midPrice !== null) return this._midPrice + + const price = this.pools.slice(1).reduce( + ({ nextInput, price }, pool) => { + return nextInput.equals(pool.token0) + ? { + nextInput: pool.token1, + price: price.multiply(pool.token0Price), + } + : { + nextInput: pool.token0, + price: price.multiply(pool.token1Price), + } + }, + this.pools[0].token0.equals(wrappedCurrency(this.input,this.pools[0].chainId)) + ? { + nextInput: this.pools[0].token1, + price: this.pools[0].token0Price, + } + : { + nextInput: this.pools[0].token0, + price: this.pools[0].token1Price, + } + ).price + + return (this._midPrice = new Price(this.input, this.output, price.denominator, price.numerator)) + } +} \ No newline at end of file diff --git a/src/entities/mixedRoute/trade.ts b/src/entities/mixedRoute/trade.ts new file mode 100644 index 0000000..0d84419 --- /dev/null +++ b/src/entities/mixedRoute/trade.ts @@ -0,0 +1,496 @@ +import { Currency, Fraction, Percent, Price, CurrencyAmount, wrappedCurrency,wrappedAmount,TokenAmount,Pair,Pool,BestTradeOptions } from '../index' +import invariant from 'tiny-invariant' +import { ONE, ZERO,TradeType } from '../../constants' +import { MixedRouteSDK } from './route' +import { sortedInsert } from '../../index'; + +/** + * Trades comparator, an extension of the input output comparator that also considers other dimensions of the trade in ranking them + * @template TInput The input token, either Ether or an ERC-20 + * @template TOutput The output token, either Ether or an ERC-20 + * @template TradeType The trade type, either exact input or exact output + * @param a The first trade to compare + * @param b The second trade to compare + * @returns A sorted ordering for two neighboring elements in a trade array + */ +export function mixedTradeComparator( + a: MixedRouteTrade, + b: MixedRouteTrade +) { + // must have same input and output token for comparison + const chainId= a.route.chainId; + invariant(wrappedCurrency(a.inputAmount.currency,chainId).equals(wrappedCurrency(b.inputAmount.currency,chainId)), 'INPUT_CURRENCY') + invariant(wrappedCurrency(a.outputAmount.currency,chainId).equals(wrappedCurrency(b.outputAmount.currency,chainId)), 'OUTPUT_CURRENCY') + if (a.outputAmount.equalTo(b.outputAmount)) { + if (a.inputAmount.equalTo(b.inputAmount)) { + // consider the number of hops since each hop costs gas + const aHops = a.swaps.reduce((total, cur) => total + cur.route.path.length, 0) + const bHops = b.swaps.reduce((total, cur) => total + cur.route.path.length, 0) + return aHops - bHops + } + // trade A requires less input than trade B, so A should come first + if (a.inputAmount.lessThan(b.inputAmount)) { + return -1 + } else { + return 1 + } + } else { + // tradeA has less output than trade B, so should come second + if (a.outputAmount.lessThan(b.outputAmount)) { + return 1 + } else { + return -1 + } + } +} + +/** + * Represents a trade executed against a set of routes where some percentage of the input is + * split across each route. + * + * Each route has its own set of pools. Pools can not be re-used across routes. + * + * Does not account for slippage, i.e., changes in price environment that can occur between + * the time the trade is submitted and when it is executed. + * @notice This class is functionally the same as the `Trade` class in the `@uniswap/v3-sdk` package, aside from typing and some input validation. + * @template TInput The input token, either Ether or an ERC-20 + * @template TOutput The output token, either Ether or an ERC-20 + * @template TradeType The trade type, either exact input or exact output + */ +export class MixedRouteTrade { + /** + * @deprecated Deprecated in favor of 'swaps' property. If the trade consists of multiple routes + * this will return an error. + * + * When the trade consists of just a single route, this returns the route of the trade, + * i.e. which pools the trade goes through. + */ + public get route(): MixedRouteSDK { + invariant(this.swaps.length == 1, 'MULTIPLE_ROUTES') + return this.swaps[0].route + } + + /** + * The swaps of the trade, i.e. which routes and how much is swapped in each that + * make up the trade. + */ + public readonly swaps: { + route: MixedRouteSDK + inputAmount: CurrencyAmount + outputAmount: CurrencyAmount + }[] + + /** + * The type of the trade, either exact in or exact out. + */ + public readonly tradeType: TradeType + + /** + * The cached result of the input amount computation + * @private + */ + private _inputAmount: CurrencyAmount | undefined + + /** + * The input amount for the trade assuming no slippage. + */ + public get inputAmount(): CurrencyAmount { + if (this._inputAmount) { + return this._inputAmount + } + + const inputCurrency = this.swaps[0].inputAmount.currency + const totalInputFromRoutes = this.swaps + .map(({ inputAmount }) => inputAmount) + .reduce((total, cur) => total.add(cur), new CurrencyAmount(inputCurrency, 0)) + + this._inputAmount = totalInputFromRoutes + return this._inputAmount + } + + /** + * The cached result of the output amount computation + * @private + */ + private _outputAmount: CurrencyAmount | undefined + + /** + * The output amount for the trade assuming no slippage. + */ + public get outputAmount(): CurrencyAmount { + if (this._outputAmount) { + return this._outputAmount + } + + const outputCurrency = this.swaps[0].outputAmount.currency + const totalOutputFromRoutes = this.swaps + .map(({ outputAmount }) => outputAmount) + .reduce((total, cur) => total.add(cur), new CurrencyAmount(outputCurrency, 0)) + + this._outputAmount = totalOutputFromRoutes + return this._outputAmount + } + + /** + * The cached result of the computed execution price + * @private + */ + private _executionPrice: Price | undefined + + /** + * The price expressed in terms of output amount/input amount. + */ + public get executionPrice(): Price { + return ( + this._executionPrice ?? + (this._executionPrice = new Price( + this.inputAmount.currency, + this.outputAmount.currency, + this.inputAmount.quotient, + this.outputAmount.quotient + )) + ) + } + + /** + * The cached result of the price impact computation + * @private + */ + private _priceImpact: Percent | undefined + + /** + * Returns the percent difference between the route's mid price and the price impact + */ + public get priceImpact(): Percent { + if (this._priceImpact) { + return this._priceImpact + } + + let spotOutputAmount = new CurrencyAmount(this.outputAmount.currency, 0) + for (const { route, inputAmount } of this.swaps) { + const midPrice = route.midPrice + spotOutputAmount = spotOutputAmount.add(midPrice.quote(inputAmount)) + } + + const priceImpact = spotOutputAmount.subtract(this.outputAmount).divide(spotOutputAmount) + this._priceImpact = new Percent(priceImpact.numerator, priceImpact.denominator) + + return this._priceImpact + } + + /** + * Constructs a trade by simulating swaps through the given route + * @template TInput The input token, either Ether or an ERC-20. + * @template TOutput The output token, either Ether or an ERC-20. + * @template TradeType The type of the trade, either exact in or exact out. + * @param route route to swap through + * @param amount the amount specified, either input or output, depending on tradeType + * @param tradeType whether the trade is an exact input or exact output swap + * @returns The route + */ + public static async fromRoute( + route: MixedRouteSDK, + amount: TradeType extends TradeType.EXACT_INPUT ? CurrencyAmount : CurrencyAmount, + tradeType: TradeType + ): Promise { + const amounts: TokenAmount[] = new Array(route.path.length) + let inputAmount: CurrencyAmount + let outputAmount: CurrencyAmount + const chainId=route.chainId + + invariant(tradeType === TradeType.EXACT_INPUT, 'TRADE_TYPE') + + invariant(wrappedCurrency(amount.currency,chainId).equals(wrappedCurrency(route.input,chainId)), 'INPUT') + amounts[0] = wrappedAmount(amount,chainId) + for (let i = 0; i < route.path.length - 1; i++) { + const pool = route.pools[i] + const [outputAmount] = await pool.getOutputAmount(amounts[i]) + amounts[i + 1] = outputAmount + } + inputAmount = new CurrencyAmount(route.input, amount.raw) + outputAmount =new CurrencyAmount( + route.output, + amounts[amounts.length - 1].raw + ) + + return new MixedRouteTrade({ + routes: [{ inputAmount, outputAmount, route }], + tradeType, + }) + } + + /** + * Constructs a trade from routes by simulating swaps + * + * @template TInput The input token, either Ether or an ERC-20. + * @template TOutput The output token, either Ether or an ERC-20. + * @template TradeType The type of the trade, either exact in or exact out. + * @param routes the routes to swap through and how much of the amount should be routed through each + * @param tradeType whether the trade is an exact input or exact output swap + * @returns The trade + */ + public static async fromRoutes( + routes: { + amount: TradeType extends TradeType.EXACT_INPUT ? CurrencyAmount : CurrencyAmount + route: MixedRouteSDK + }[], + tradeType: TradeType + ): Promise { + const populatedRoutes: { + route: MixedRouteSDK + inputAmount: CurrencyAmount + outputAmount: CurrencyAmount + }[] = [] + + invariant(tradeType === TradeType.EXACT_INPUT, 'TRADE_TYPE') + + for (const { route, amount } of routes) { + const amounts: TokenAmount[] = new Array(route.path.length) + let inputAmount: CurrencyAmount + let outputAmount: CurrencyAmount + const chainId=route.chainId + + invariant(wrappedCurrency(amount.currency,chainId).equals(wrappedCurrency(route.input,chainId)), 'INPUT') + inputAmount = new CurrencyAmount(route.input, amount.raw) + amounts[0] = new TokenAmount(wrappedCurrency(route.input,chainId), amount.raw) + + for (let i = 0; i < route.path.length - 1; i++) { + const pool = route.pools[i] + const [outputAmount] = await pool.getOutputAmount(amounts[i]) + amounts[i + 1] = outputAmount + } + + outputAmount = new CurrencyAmount( + route.output, + amounts[amounts.length - 1].raw + ) + + populatedRoutes.push({ route, inputAmount, outputAmount }) + } + + return new MixedRouteTrade({ + routes: populatedRoutes, + tradeType, + }) + } + + /** + * Creates a trade without computing the result of swapping through the route. Useful when you have simulated the trade + * elsewhere and do not have any tick data + * @template TInput The input token, either Ether or an ERC-20 + * @template TOutput The output token, either Ether or an ERC-20 + * @template TradeType The type of the trade, either exact in or exact out + * @param constructorArguments The arguments passed to the trade constructor + * @returns The unchecked trade + */ + public static createUncheckedTrade(constructorArguments: { + route: MixedRouteSDK + inputAmount: CurrencyAmount + outputAmount: CurrencyAmount + tradeType: TradeType + }): MixedRouteTrade { + return new MixedRouteTrade({ + ...constructorArguments, + routes: [ + { + inputAmount: constructorArguments.inputAmount, + outputAmount: constructorArguments.outputAmount, + route: constructorArguments.route, + }, + ], + }) + } + + /** + * Creates a trade without computing the result of swapping through the routes. Useful when you have simulated the trade + * elsewhere and do not have any tick data + * @template TInput The input token, either Ether or an ERC-20 + * @template TOutput The output token, either Ether or an ERC-20 + * @template TradeType The type of the trade, either exact in or exact out + * @param constructorArguments The arguments passed to the trade constructor + * @returns The unchecked trade + */ + public static createUncheckedTradeWithMultipleRoutes(constructorArguments: { + routes: { + route: MixedRouteSDK + inputAmount: CurrencyAmount + outputAmount: CurrencyAmount + }[] + tradeType: TradeType + }): MixedRouteTrade { + return new MixedRouteTrade(constructorArguments) + } + + /** + * Construct a trade by passing in the pre-computed property values + * @param routes The routes through which the trade occurs + * @param tradeType The type of trade, exact input or exact output + */ + private constructor({ + routes, + tradeType, + }: { + routes: { + route: MixedRouteSDK + inputAmount: CurrencyAmount + outputAmount: CurrencyAmount + }[] + tradeType: TradeType + }) { + const inputCurrency = routes[0].inputAmount.currency + const outputCurrency = routes[0].outputAmount.currency + invariant( + routes.every(({ route }) =>{ + const chainId=route.chainId + return wrappedCurrency(inputCurrency,chainId).equals(wrappedCurrency(route.input,chainId))}), + 'INPUT_CURRENCY_MATCH' + ) + invariant( + routes.every(({ route }) =>{ + const chainId=route.chainId + return wrappedCurrency(outputCurrency,chainId).equals(wrappedCurrency(route.output,chainId))}), + 'OUTPUT_CURRENCY_MATCH' + ) + + const numPools = routes.map(({ route }) => route.pools.length).reduce((total, cur) => total + cur, 0) + const poolAddressSet = new Set() + for (const { route } of routes) { + for (const pool of route.pools) { + pool instanceof Pool + ? poolAddressSet.add(Pool.getAddress(pool.token0, pool.token1)) + : poolAddressSet.add(Pair.getAddress(pool.token0, pool.token1)) + } + } + + invariant(numPools == poolAddressSet.size, 'POOLS_DUPLICATED') + + invariant(tradeType === TradeType.EXACT_INPUT, 'TRADE_TYPE') + + this.swaps = routes + this.tradeType = tradeType + } + + /** + * Get the minimum amount that must be received from this trade for the given slippage tolerance + * @param slippageTolerance The tolerance of unfavorable slippage from the execution price of this trade + * @returns The amount out + */ + public minimumAmountOut(slippageTolerance: Percent, amountOut = this.outputAmount): CurrencyAmount { + invariant(!slippageTolerance.lessThan(ZERO), 'SLIPPAGE_TOLERANCE') + /// does not support exactOutput, as enforced in the constructor + const slippageAdjustedAmountOut = new Fraction(ONE) + .add(slippageTolerance) + .invert() + .multiply(amountOut.quotient).quotient + return new CurrencyAmount(amountOut.currency, slippageAdjustedAmountOut) + } + + /** + * Get the maximum amount in that can be spent via this trade for the given slippage tolerance + * @param slippageTolerance The tolerance of unfavorable slippage from the execution price of this trade + * @returns The amount in + */ + public maximumAmountIn(slippageTolerance: Percent, amountIn = this.inputAmount): CurrencyAmount { + invariant(!slippageTolerance.lessThan(ZERO), 'SLIPPAGE_TOLERANCE') + return amountIn + /// does not support exactOutput + } + + /** + * Return the execution price after accounting for slippage tolerance + * @param slippageTolerance the allowed tolerated slippage + * @returns The execution price + */ + public worstExecutionPrice(slippageTolerance: Percent): Price { + return new Price( + this.inputAmount.currency, + this.outputAmount.currency, + this.maximumAmountIn(slippageTolerance).quotient, + this.minimumAmountOut(slippageTolerance).quotient + ) + } + + /** + * Given a list of pools, and a fixed amount in, returns the top `maxNumResults` trades that go from an input token + * amount to an output token, making at most `maxHops` hops. + * Note this does not consider aggregation, as routes are linear. It's possible a better route exists by splitting + * the amount in among multiple routes. + * @param pools the pools to consider in finding the best trade + * @param nextAmountIn exact amount of input currency to spend + * @param currencyOut the desired currency out + * @param maxNumResults maximum number of results to return + * @param maxHops maximum number of hops a returned trade can make, e.g. 1 hop goes through a single pool + * @param currentPools used in recursion; the current list of pools + * @param currencyAmountIn used in recursion; the original value of the currencyAmountIn parameter + * @param bestTrades used in recursion; the current list of best trades + * @returns The exact in trade + */ + public static async bestTradeExactIn( + pools: (Pool | Pair)[], + currencyAmountIn: CurrencyAmount, + currencyOut: Currency, + { maxNumResults = 3, maxHops = 3 }: BestTradeOptions = {}, + // used in recursion. + currentPools: (Pool | Pair)[] = [], + nextAmountIn: CurrencyAmount = currencyAmountIn, + bestTrades: MixedRouteTrade[] = [] + ): Promise { + invariant(pools.length > 0, 'POOLS') + invariant(maxHops > 0, 'MAX_HOPS') + invariant(currencyAmountIn === nextAmountIn || currentPools.length > 0, 'INVALID_RECURSION') + const chainId=pools[0].chainId + const amountIn = wrappedAmount(nextAmountIn,chainId) + const tokenOut = wrappedCurrency(currencyOut,chainId) + for (let i = 0; i < pools.length; i++) { + const pool = pools[i] + // pool irrelevant + if (!pool.token0.equals(amountIn.token) && !pool.token1.equals(amountIn.token)) continue + if (pool instanceof Pair) { + if ((pool as Pair).reserve0.equalTo(ZERO) || (pool as Pair).reserve1.equalTo(ZERO)) continue + } + + let amountOut: TokenAmount + try { + ;[amountOut] = await pool.getOutputAmount(amountIn) + } catch (error) { + // input too low + // @ts-ignore[2571] error is unknown + if (error.isInsufficientInputAmountError) { + continue + } + throw error + } + // we have arrived at the output token, so this is the final trade of one of the paths + if (amountOut.token && amountOut.token.equals(tokenOut)) { + sortedInsert( + bestTrades, + await MixedRouteTrade.fromRoute( + new MixedRouteSDK([...currentPools, pool], currencyAmountIn.currency, currencyOut), + currencyAmountIn, + TradeType.EXACT_INPUT + ), + maxNumResults, + mixedTradeComparator + ) + } else if (maxHops > 1 && pools.length > 1) { + const poolsExcludingThisPool = pools.slice(0, i).concat(pools.slice(i + 1, pools.length)) + + // otherwise, consider all the other paths that lead from this token as long as we have not exceeded maxHops + await MixedRouteTrade.bestTradeExactIn( + poolsExcludingThisPool, + currencyAmountIn, + currencyOut, + { + maxNumResults, + maxHops: maxHops - 1, + }, + [...currentPools, pool], + amountOut, + bestTrades + ) + } + } + + return bestTrades + } +} \ No newline at end of file diff --git a/src/entities/order.ts b/src/entities/order.ts new file mode 100644 index 0000000..dd3a6bb --- /dev/null +++ b/src/entities/order.ts @@ -0,0 +1,126 @@ +import JSBI from "jsbi" +import { Pool } from "./pool" +import invariant from "tiny-invariant" +import { BigintIsh, Price, TokenAmount,FullMath, TickMath, tickToPrice } from '../index' +import { Q96 } from "../internalConstants" + +interface OrderConstructorArgs { + pool: Pool + tick: number + amountIn: BigintIsh + zeroForOne: boolean +} + +enum ORDER_TYPE { + BUY_ORDER, + SELL_ORDER +} +/** + * Represents a limit order on a Dfyn V2 Pool + */ + export class Order { + public readonly pool: Pool + public readonly tick: number + public readonly amountIn: JSBI + public readonly zeroForOne: boolean + + // cached resuts for the getters + private _tokenAmountIn: TokenAmount | null = null + private _expectedTokenAmountOut: TokenAmount | null = null + + /** + * Constructs a position for a given pool with the given liquidity + * @param pool For which pool the liquidity is assigned + * @param tick The tick where limit order sits + * @param amountIn The amount of liquidity that is in the position + * @param tickUpper The upper tick of the position + */ + public constructor({ pool, tick, amountIn, zeroForOne }:OrderConstructorArgs){ + invariant(tick >= TickMath.MIN_TICK && tick % pool.tickSpacing === 0, 'INVALID_TICK') + invariant(tick <= TickMath.MAX_TICK && tick % pool.tickSpacing === 0, 'INVALID_TICK') + // const sqrtpriceX96=TickMath.getSqrtRatioAtTick(tick) + // if (zeroForOne) { + // invariant( + // JSBI.greaterThan(sqrtpriceX96,pool.sqrtRatioX96) + // , "INVALID_SELL_ORDER"); + // } else { + // invariant(JSBI.lessThan(sqrtpriceX96,pool.sqrtRatioX96), "INVALID_BUY_ORDER"); + // } + this.pool = pool + this.tick = tick + this.zeroForOne = zeroForOne + this.amountIn = JSBI.BigInt(amountIn) + } + + /** + * Returns the price of where limit order sits + */ + public get atPrice(): Price { + return tickToPrice(this.pool.token0, this.pool.token1, this.tick) + } + + /** + * Returns the type of limit order + */ + public get type(): ORDER_TYPE { + if (this.zeroForOne) { + return ORDER_TYPE.BUY_ORDER + } else { + return ORDER_TYPE.SELL_ORDER + } + } + + /** + * Returns the amountIn of limit order + */ + public get tokenAmountIn(): TokenAmount { + if (this._tokenAmountIn === null) { + if (this.zeroForOne) { + this._tokenAmountIn = new TokenAmount( + this.pool.token1, + this.amountIn.toString() + ) + } else { + this._tokenAmountIn = new TokenAmount( + this.pool.token0, + this.amountIn.toString() + ) + } + } + return this._tokenAmountIn + } + + /** + * Returns the expected amountOut of limit order + */ + public get expectedTokenAmountOut(): TokenAmount { + if (this._expectedTokenAmountOut === null) { + if (this.zeroForOne) { + let amountOut = FullMath.mulDivRoundingUp(this.amountIn, this.sqrtpriceX96, Q96); + amountOut = FullMath.mulDivRoundingUp(amountOut, this.sqrtpriceX96, Q96); + this._expectedTokenAmountOut = new TokenAmount( + this.pool.token0, + amountOut.toString() + ) + } else { + let amountOut = FullMath.mulDivRoundingUp(this.amountIn, Q96, + this.sqrtpriceX96); + amountOut = FullMath.mulDivRoundingUp(amountOut, Q96, + this.sqrtpriceX96); + this._expectedTokenAmountOut = new TokenAmount( + this.pool.token1, + amountOut.toString() + ) + } + } + return this._expectedTokenAmountOut + } + + /** + * Returns the sqrtpriceX96 + */ + public get sqrtpriceX96():JSBI{ + return TickMath.getSqrtRatioAtTick(this.tick) + } + +} \ No newline at end of file diff --git a/src/entities/pool.ts b/src/entities/pool.ts new file mode 100644 index 0000000..7df04c0 --- /dev/null +++ b/src/entities/pool.ts @@ -0,0 +1,331 @@ +import { TokenAmount, Price, Token } from './index' +import JSBI from 'jsbi' +import invariant from 'tiny-invariant' +import { V2_DEPLOYER_ADDRESS, FeeAmount, TICK_SPACINGS,BigintIsh } from '../constants' +import { NEGATIVE_ONE, ONE, Q192, ZERO } from '../internalConstants' +import { computePoolAddress } from '../utils/computePoolAddress' +// import { LiquidityMath } from '../utils/liquidityMath' +// import { SwapMath } from '../utils/swapMath' +import { TickMath } from '../utils/tickMath' +import { Tick, TickConstructorArgs } from './tick' +import { NoTickDataProvider, TickDataProvider } from './tickDataProvider' +import { TickListDataProvider } from './tickListDataProvider' + +// interface StepComputations { +// sqrtPriceStartX96: JSBI +// tickNext: number +// initialized: boolean +// sqrtPriceNextX96: JSBI +// amountIn: JSBI +// amountOut: JSBI +// feeAmount: JSBI +// } + +/** + * By default, pools will not allow operations that require ticks. + */ +const NO_TICK_DATA_PROVIDER_DEFAULT = new NoTickDataProvider() + +/** + * Represents a V3 pool + */ +export class Pool { + public readonly token0: Token + public readonly token1: Token + public readonly fee: FeeAmount + public readonly sqrtRatioX96: JSBI + public readonly liquidity: JSBI + public readonly tickCurrent: number + public readonly tickDataProvider: TickDataProvider + + private _token0Price?: Price + private _token1Price?: Price + + + // dfyn: we are computing pool address using to factory(deployer address), + public static getAddress( + tokenA: Token, + tokenB: Token, + initCodeHashManualOverride?: string, + deployerAddressOverride?: string + ): string { + return computePoolAddress({ + deployerAddress: deployerAddressOverride ?? V2_DEPLOYER_ADDRESS[tokenA.chainId], + tokenA, + tokenB, + initCodeHashManualOverride + }) + } + + /** + * Construct a pool + * @param tokenA One of the tokens in the pool + * @param tokenB The other token in the pool + * @param fee The fee in hundredths of a bips of the input amount of every swap that is collected by the pool + * @param sqrtRatioX96 The sqrt of the current ratio of amounts of token1 to token0 + * @param liquidity The current value of in range liquidity + * @param tickCurrent The current tick of the pool + * @param ticks The current state of the pool ticks or a data provider that can return tick data + */ + public constructor( + tokenA: Token, + tokenB: Token, + fee: FeeAmount, + sqrtRatioX96: BigintIsh, + liquidity: BigintIsh, + tickCurrent: number, + ticks: TickDataProvider | (Tick | TickConstructorArgs)[] = NO_TICK_DATA_PROVIDER_DEFAULT + ) { + invariant(Number.isInteger(fee) && fee < 1_000_000, 'FEE') + + const tickCurrentSqrtRatioX96 = TickMath.getSqrtRatioAtTick(tickCurrent) + const nextTickSqrtRatioX96 = TickMath.getSqrtRatioAtTick(tickCurrent + 1) + invariant( + JSBI.greaterThanOrEqual(JSBI.BigInt(sqrtRatioX96), tickCurrentSqrtRatioX96) && + JSBI.lessThanOrEqual(JSBI.BigInt(sqrtRatioX96), nextTickSqrtRatioX96), + 'PRICE_BOUNDS' + ) + // always create a copy of the list since we want the pool's tick list to be immutable + ;[this.token0, this.token1] = tokenA.sortsBefore(tokenB) ? [tokenA, tokenB] : [tokenB, tokenA] + this.fee = fee + this.sqrtRatioX96 = JSBI.BigInt(sqrtRatioX96) + this.liquidity = JSBI.BigInt(liquidity) + this.tickCurrent = tickCurrent + this.tickDataProvider = Array.isArray(ticks) ? new TickListDataProvider(ticks, TICK_SPACINGS[fee]) : ticks + } + + /** + * Returns true if the token is either token0 or token1 + * @param token The token to check + * @returns True if token is either token0 or token + */ + public involvesToken(token: Token): boolean { + return token.equals(this.token0) || token.equals(this.token1) + } + + /** + * Returns the current mid price of the pool in terms of token0, i.e. the ratio of token1 over token0 + */ + public get token0Price(): Price { + return ( + this._token0Price ?? + (this._token0Price = new Price( + this.token0, + this.token1, + Q192, + JSBI.multiply(this.sqrtRatioX96, this.sqrtRatioX96) + )) + ) + } + + /** + * Returns the current mid price of the pool in terms of token1, i.e. the ratio of token0 over token1 + */ + public get token1Price(): Price { + return ( + this._token1Price ?? + (this._token1Price = new Price( + this.token1, + this.token0, + JSBI.multiply(this.sqrtRatioX96, this.sqrtRatioX96), + Q192 + )) + ) + } + + /** + * Return the price of the given token in terms of the other token in the pool. + * @param token The token to return price of + * @returns The price of the given token, in terms of the other. + */ + public priceOf(token: Token): Price { + invariant(this.involvesToken(token), 'TOKEN') + return token.equals(this.token0) ? this.token0Price : this.token1Price + } + + /** + * Returns the chain ID of the tokens in the pool. + */ + public get chainId(): number { + return this.token0.chainId + } + // // // // // // // // // // // // // // // // // // // // // // // // // // // + // // // // // // // // // Depends on swap function // // // // // // // // // + // // // // // // // // // // // // // // // // // // // // // // // // // // // + + /** + * Given an input amount of a token, return the computed output amount, and a pool with state updated after the trade + * @param inputAmount The input amount for which to quote the output amount + * @param sqrtPriceLimitX96 The Q64.96 sqrt price limit + * @returns The output amount and the pool with updated state + */ + public async getOutputAmount( + inputAmount: TokenAmount, + sqrtPriceLimitX96?: JSBI + ): Promise<[TokenAmount, Pool]> { + invariant(this.involvesToken(inputAmount.token), 'TOKEN') + + const zeroForOne = inputAmount.token.equals(this.token0) + + const { amountCalculated: outputAmount, sqrtRatioX96, liquidity, tickCurrent } = await this.swap( + zeroForOne, + inputAmount.quotient, + sqrtPriceLimitX96 + ) + const outputToken = zeroForOne ? this.token1 : this.token0 + return [ + new TokenAmount(outputToken,JSBI.multiply(outputAmount, NEGATIVE_ONE)), + // TokenAmount.fromRawAmount(outputToken, JSBI.multiply(outputAmount, NEGATIVE_ONE)), + new Pool(this.token0, this.token1, this.fee, sqrtRatioX96, liquidity, tickCurrent, this.tickDataProvider) + ] + } + // // // // // // // // // // // // // // // // // // // // // // // // // // // + // // // // // // // // // Depends on swap function // // // // // // // // // + // // // // // // // // // // // // // // // // // // // // // // // // // // // + + /** + * Given a desired output amount of a token, return the computed input amount and a pool with state updated after the trade + * @param outputAmount the output amount for which to quote the input amount + * @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this value after the swap. If one for zero, the price cannot be greater than this value after the swap + * @returns The input amount and the pool with updated state + */ + public async getInputAmount( + outputAmount: TokenAmount, + sqrtPriceLimitX96?: JSBI + ): Promise<[TokenAmount, Pool]> { + invariant(this.involvesToken(outputAmount.token), 'TOKEN') + + const zeroForOne = outputAmount.token.equals(this.token1) + + const { amountCalculated: inputAmount, sqrtRatioX96, liquidity, tickCurrent } = await this.swap( + zeroForOne, + JSBI.multiply(outputAmount.quotient, NEGATIVE_ONE), + sqrtPriceLimitX96 + ) + const inputToken = zeroForOne ? this.token0 : this.token1 + return [ + new TokenAmount(inputToken,inputAmount), + new Pool(this.token0, this.token1, this.fee, sqrtRatioX96, liquidity, tickCurrent, this.tickDataProvider) + ] + } + + + // // // // // // // // // // // // // // // // // // // // // // // // // // // + // // // // // Swap Logic needs to be modified how we are doing it// // // // // + // // // // // // // // // // // // // // // // // // // // // // // // // // // + /** + * Executes a swap + * @param zeroForOne Whether the amount in is token0 or token1 + * @param amountSpecified The amount of the swap, which implicitly configures the swap as exact input (positive), or exact output (negative) + * @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this value after the swap. If one for zero, the price cannot be greater than this value after the swap + * @returns amountCalculated + * @returns sqrtRatioX96 + * @returns liquidity + * @returns tickCurrent + */ + private async swap( + zeroForOne: boolean, + amountSpecified: JSBI, + sqrtPriceLimitX96?: JSBI + ): Promise<{ amountCalculated: JSBI; sqrtRatioX96: JSBI; liquidity: JSBI; tickCurrent: number }> { + if (!sqrtPriceLimitX96) + sqrtPriceLimitX96 = zeroForOne + ? JSBI.add(TickMath.MIN_SQRT_RATIO, ONE) + : JSBI.subtract(TickMath.MAX_SQRT_RATIO, ONE) + + if (zeroForOne) { + invariant(JSBI.greaterThan(sqrtPriceLimitX96, TickMath.MIN_SQRT_RATIO), 'RATIO_MIN') + invariant(JSBI.lessThan(sqrtPriceLimitX96, this.sqrtRatioX96), 'RATIO_CURRENT') + } else { + invariant(JSBI.lessThan(sqrtPriceLimitX96, TickMath.MAX_SQRT_RATIO), 'RATIO_MAX') + invariant(JSBI.greaterThan(sqrtPriceLimitX96, this.sqrtRatioX96), 'RATIO_CURRENT') + } + + // const exactInput = JSBI.greaterThanOrEqual(amountSpecified, ZERO) + + // keep track of swap state + + const state = { + amountSpecifiedRemaining: amountSpecified, + amountCalculated: ZERO, + sqrtPriceX96: this.sqrtRatioX96, + tick: this.tickCurrent, + liquidity: this.liquidity + } + + // start swap while loop + // while (JSBI.notEqual(state.amountSpecifiedRemaining, ZERO) && state.sqrtPriceX96 != sqrtPriceLimitX96) { + // let step: Partial = {} + // step.sqrtPriceStartX96 = state.sqrtPriceX96 + + // // because each iteration of the while loop rounds, we can't optimize this code (relative to the smart contract) + // // by simply traversing to the next available tick, we instead need to exactly replicate + // // tickBitmap.nextInitializedTickWithinOneWord + // ;[step.tickNext, step.initialized] = await this.tickDataProvider.nextInitializedTickWithinOneWord( + // state.tick, + // zeroForOne, + // this.tickSpacing + // ) + + // if (step.tickNext < TickMath.MIN_TICK) { + // step.tickNext = TickMath.MIN_TICK + // } else if (step.tickNext > TickMath.MAX_TICK) { + // step.tickNext = TickMath.MAX_TICK + // } + + // step.sqrtPriceNextX96 = TickMath.getSqrtRatioAtTick(step.tickNext) + // ;[state.sqrtPriceX96, step.amountIn, step.amountOut, step.feeAmount] = SwapMath.computeSwapStep( + // state.sqrtPriceX96, + // (zeroForOne + // ? JSBI.lessThan(step.sqrtPriceNextX96, sqrtPriceLimitX96) + // : JSBI.greaterThan(step.sqrtPriceNextX96, sqrtPriceLimitX96)) + // ? sqrtPriceLimitX96 + // : step.sqrtPriceNextX96, + // state.liquidity, + // state.amountSpecifiedRemaining, + // this.fee + // ) + + // if (exactInput) { + // state.amountSpecifiedRemaining = JSBI.subtract( + // state.amountSpecifiedRemaining, + // JSBI.add(step.amountIn, step.feeAmount) + // ) + // state.amountCalculated = JSBI.subtract(state.amountCalculated, step.amountOut) + // } else { + // state.amountSpecifiedRemaining = JSBI.add(state.amountSpecifiedRemaining, step.amountOut) + // state.amountCalculated = JSBI.add(state.amountCalculated, JSBI.add(step.amountIn, step.feeAmount)) + // } + + // // TODO + // if (JSBI.equal(state.sqrtPriceX96, step.sqrtPriceNextX96)) { + // // if the tick is initialized, run the tick transition + // if (step.initialized) { + // let liquidityNet = JSBI.BigInt((await this.tickDataProvider.getTick(step.tickNext)).liquidityNet) + // // if we're moving leftward, we interpret liquidityNet as the opposite sign + // // safe because liquidityNet cannot be type(int128).min + // if (zeroForOne) liquidityNet = JSBI.multiply(liquidityNet, NEGATIVE_ONE) + + // state.liquidity = LiquidityMath.addDelta(state.liquidity, liquidityNet) + // } + + // state.tick = zeroForOne ? step.tickNext - 1 : step.tickNext + // } else if (JSBI.notEqual(state.sqrtPriceX96, step.sqrtPriceStartX96)) { + // // updated comparison function + // // recompute unless we're on a lower tick boundary (i.e. already transitioned ticks), and haven't moved + // state.tick = TickMath.getTickAtSqrtRatio(state.sqrtPriceX96) + // } + // } + + return { + amountCalculated: state.amountCalculated, + sqrtRatioX96: state.sqrtPriceX96, + liquidity: state.liquidity, + tickCurrent: state.tick + } + } + + public get tickSpacing(): number { + return TICK_SPACINGS[this.fee] + } +} diff --git a/src/entities/positions.ts b/src/entities/positions.ts new file mode 100644 index 0000000..248dea4 --- /dev/null +++ b/src/entities/positions.ts @@ -0,0 +1,395 @@ +import { BigintIsh, Percent, Price, CurrencyAmount } from '../index' +import JSBI from 'jsbi' +import invariant from 'tiny-invariant' +import { ZERO } from '../internalConstants' +import { maxLiquidityForAmounts } from '../utils/maxLiquidityForAmounts' +import { tickToPrice } from '../utils/priceTickConversions' +import { SqrtPriceMath } from '../utils/sqrtPriceMath' +import { TickMath } from '../utils/tickMath' +import { encodeSqrtRatioX96 } from '../utils/encodeSqrtRatioX96' +import { Pool } from './pool' +import { MaxUint256 } from '../constants' + +interface PositionConstructorArgs { + pool: Pool + tickLower: number + tickUpper: number + liquidity: BigintIsh +} + +/** + * Represents a position on a Dfyn V2 Pool + */ +export class Position { + public readonly pool: Pool + public readonly tickLower: number + public readonly tickUpper: number + public readonly liquidity: JSBI + + // cached resuts for the getters + private _token0Amount: CurrencyAmount | null = null + private _token1Amount: CurrencyAmount | null = null + private _mintAmounts: Readonly<{ amount0: JSBI; amount1: JSBI }> | null = null + + /** + * Constructs a position for a given pool with the given liquidity + * @param pool For which pool the liquidity is assigned + * @param liquidity The amount of liquidity that is in the position + * @param tickLower The lower tick of the position + * @param tickUpper The upper tick of the position + */ + public constructor({ pool, liquidity, tickLower, tickUpper }: PositionConstructorArgs) { + invariant(tickLower < tickUpper, 'TICK_ORDER') + invariant(tickLower >= TickMath.MIN_TICK && tickLower % pool.tickSpacing === 0, 'TICK_LOWER') + invariant(tickUpper <= TickMath.MAX_TICK && tickUpper % pool.tickSpacing === 0, 'TICK_UPPER') + invariant((tickLower % pool.tickSpacing )%2=== 0, 'TICK_LOWER_ODD') + invariant((tickUpper % pool.tickSpacing )%2=== 0, 'TICK_UPPER_EVEN') + + this.pool = pool + this.tickLower = tickLower + this.tickUpper = tickUpper + this.liquidity = JSBI.BigInt(liquidity) + } + + /** + * Returns the price of token0 at the lower tick + */ + public get token0PriceLower(): Price { + return tickToPrice(this.pool.token0, this.pool.token1, this.tickLower) + } + + /** + * Returns the price of token0 at the upper tick + */ + public get token0PriceUpper(): Price { + return tickToPrice(this.pool.token0, this.pool.token1, this.tickUpper) + } + + /** + * Returns the amount of token0 that this position's liquidity could be burned for at the current pool price + */ + public get amount0(): CurrencyAmount { + if (this._token0Amount === null) { + if (this.pool.tickCurrent < this.tickLower) { + this._token0Amount = new CurrencyAmount( + this.pool.token0, + SqrtPriceMath.getAmount0Delta( + TickMath.getSqrtRatioAtTick(this.tickLower), + TickMath.getSqrtRatioAtTick(this.tickUpper), + this.liquidity, + false + ) + ) + } else if (this.pool.tickCurrent < this.tickUpper) { + this._token0Amount = new CurrencyAmount( + this.pool.token0, + SqrtPriceMath.getAmount0Delta( + this.pool.sqrtRatioX96, + TickMath.getSqrtRatioAtTick(this.tickUpper), + this.liquidity, + false + ) + ) + } else { + this._token0Amount = new CurrencyAmount(this.pool.token0, ZERO) + } + } + return this._token0Amount + } + + /** + * Returns the amount of token1 that this position's liquidity could be burned for at the current pool price + */ + public get amount1(): CurrencyAmount { + if (this._token1Amount === null) { + if (this.pool.tickCurrent < this.tickLower) { + this._token1Amount = new CurrencyAmount(this.pool.token1, ZERO) + } else if (this.pool.tickCurrent < this.tickUpper) { + this._token1Amount = new CurrencyAmount( + this.pool.token1, + SqrtPriceMath.getAmount1Delta( + TickMath.getSqrtRatioAtTick(this.tickLower), + this.pool.sqrtRatioX96, + this.liquidity, + false + ) + ) + } else { + this._token1Amount = new CurrencyAmount( + this.pool.token1, + SqrtPriceMath.getAmount1Delta( + TickMath.getSqrtRatioAtTick(this.tickLower), + TickMath.getSqrtRatioAtTick(this.tickUpper), + this.liquidity, + false + ) + ) + } + } + return this._token1Amount + } + + /** + * Returns the lower and upper sqrt ratios if the price 'slips' up to slippage tolerance percentage + * @param slippageTolerance The amount by which the price can 'slip' before the transaction will revert + * @returns The sqrt ratios after slippage + */ + private ratiosAfterSlippage(slippageTolerance: Percent): { sqrtRatioX96Lower: JSBI; sqrtRatioX96Upper: JSBI } { + const priceLower = this.pool.token0Price.raw.multiply(new Percent(1).subtract(slippageTolerance)) + const priceUpper = this.pool.token0Price.raw.multiply(slippageTolerance.add(1)) + let sqrtRatioX96Lower = encodeSqrtRatioX96(priceLower.numerator, priceLower.denominator) + if (JSBI.lessThanOrEqual(sqrtRatioX96Lower, TickMath.MIN_SQRT_RATIO)) { + sqrtRatioX96Lower = JSBI.add(TickMath.MIN_SQRT_RATIO, JSBI.BigInt(1)) + } + let sqrtRatioX96Upper = encodeSqrtRatioX96(priceUpper.numerator, priceUpper.denominator) + if (JSBI.greaterThanOrEqual(sqrtRatioX96Upper, TickMath.MAX_SQRT_RATIO)) { + sqrtRatioX96Upper = JSBI.subtract(TickMath.MAX_SQRT_RATIO, JSBI.BigInt(1)) + } + return { + sqrtRatioX96Lower, + sqrtRatioX96Upper + } + } + + /** + * Returns the minimum amounts that must be sent in order to safely mint the amount of liquidity held by the position + * with the given slippage tolerance + * @param slippageTolerance Tolerance of unfavorable slippage from the current price + * @returns The amounts, with slippage + */ + public mintAmountsWithSlippage(slippageTolerance: Percent): Readonly<{ amount0: JSBI; amount1: JSBI }> { + // get lower/upper prices + const { sqrtRatioX96Upper, sqrtRatioX96Lower } = this.ratiosAfterSlippage(slippageTolerance) + + // construct counterfactual pools + const poolLower = new Pool( + this.pool.token0, + this.pool.token1, + this.pool.fee, + sqrtRatioX96Lower, + 0 /* liquidity doesn't matter */, + TickMath.getTickAtSqrtRatio(sqrtRatioX96Lower) + ) + const poolUpper = new Pool( + this.pool.token0, + this.pool.token1, + this.pool.fee, + sqrtRatioX96Upper, + 0 /* liquidity doesn't matter */, + TickMath.getTickAtSqrtRatio(sqrtRatioX96Upper) + ) + + // because the router is imprecise, we need to calculate the position that will be created (assuming no slippage) + const positionThatWillBeCreated = Position.fromAmounts({ + pool: this.pool, + tickLower: this.tickLower, + tickUpper: this.tickUpper, + ...this.mintAmounts, // the mint amounts are what will be passed as calldata + useFullPrecision: false + }) + + // we want the smaller amounts... + // ...which occurs at the upper price for amount0... + const { amount0 } = new Position({ + pool: poolUpper, + liquidity: positionThatWillBeCreated.liquidity, + tickLower: this.tickLower, + tickUpper: this.tickUpper + }).mintAmounts + // ...and the lower for amount1 + const { amount1 } = new Position({ + pool: poolLower, + liquidity: positionThatWillBeCreated.liquidity, + tickLower: this.tickLower, + tickUpper: this.tickUpper + }).mintAmounts + + return { amount0, amount1 } + } + + /** + * Returns the minimum amounts that should be requested in order to safely burn the amount of liquidity held by the + * position with the given slippage tolerance + * @param slippageTolerance tolerance of unfavorable slippage from the current price + * @returns The amounts, with slippage + */ + public burnAmountsWithSlippage(slippageTolerance: Percent): Readonly<{ amount0: JSBI; amount1: JSBI }> { + // get lower/upper prices + const { sqrtRatioX96Upper, sqrtRatioX96Lower } = this.ratiosAfterSlippage(slippageTolerance) + + // construct counterfactual pools + const poolLower = new Pool( + this.pool.token0, + this.pool.token1, + this.pool.fee, + sqrtRatioX96Lower, + 0 /* liquidity doesn't matter */, + TickMath.getTickAtSqrtRatio(sqrtRatioX96Lower) + ) + const poolUpper = new Pool( + this.pool.token0, + this.pool.token1, + this.pool.fee, + sqrtRatioX96Upper, + 0 /* liquidity doesn't matter */, + TickMath.getTickAtSqrtRatio(sqrtRatioX96Upper) + ) + + // we want the smaller amounts... + // ...which occurs at the upper price for amount0... + const amount0 = new Position({ + pool: poolUpper, + liquidity: this.liquidity, + tickLower: this.tickLower, + tickUpper: this.tickUpper + }).amount0 + // ...and the lower for amount1 + const amount1 = new Position({ + pool: poolLower, + liquidity: this.liquidity, + tickLower: this.tickLower, + tickUpper: this.tickUpper + }).amount1 + + return { amount0: amount0.quotient, amount1: amount1.quotient } + } + + /** + * Returns the minimum amounts that must be sent in order to mint the amount of liquidity held by the position at + * the current price for the pool + */ + public get mintAmounts(): Readonly<{ amount0: JSBI; amount1: JSBI }> { + if (this._mintAmounts === null) { + if (this.pool.tickCurrent < this.tickLower) { + return { + amount0: SqrtPriceMath.getAmount0Delta( + TickMath.getSqrtRatioAtTick(this.tickLower), + TickMath.getSqrtRatioAtTick(this.tickUpper), + this.liquidity, + true + ), + amount1: ZERO + } + } else if (this.pool.tickCurrent < this.tickUpper) { + return { + amount0: SqrtPriceMath.getAmount0Delta( + this.pool.sqrtRatioX96, + TickMath.getSqrtRatioAtTick(this.tickUpper), + this.liquidity, + true + ), + amount1: SqrtPriceMath.getAmount1Delta( + TickMath.getSqrtRatioAtTick(this.tickLower), + this.pool.sqrtRatioX96, + this.liquidity, + true + ) + } + } else { + return { + amount0: ZERO, + amount1: SqrtPriceMath.getAmount1Delta( + TickMath.getSqrtRatioAtTick(this.tickLower), + TickMath.getSqrtRatioAtTick(this.tickUpper), + this.liquidity, + true + ) + } + } + } + return this._mintAmounts + } + + /** + * Computes the maximum amount of liquidity received for a given amount of token0, token1, + * and the prices at the tick boundaries. + * @param pool The pool for which the position should be created + * @param tickLower The lower tick of the position + * @param tickUpper The upper tick of the position + * @param amount0 token0 amount + * @param amount1 token1 amount + * @param useFullPrecision If false, liquidity will be maximized according to what the router can calculate, + * not what core can theoretically support + * @returns The amount of liquidity for the position + */ + public static fromAmounts({ + pool, + tickLower, + tickUpper, + amount0, + amount1, + useFullPrecision + }: { + pool: Pool + tickLower: number + tickUpper: number + amount0: BigintIsh + amount1: BigintIsh + useFullPrecision: boolean + }) { + const sqrtRatioAX96 = TickMath.getSqrtRatioAtTick(tickLower) + const sqrtRatioBX96 = TickMath.getSqrtRatioAtTick(tickUpper) + return new Position({ + pool, + tickLower, + tickUpper, + liquidity: maxLiquidityForAmounts( + pool.sqrtRatioX96, + sqrtRatioAX96, + sqrtRatioBX96, + amount0, + amount1, + useFullPrecision + ) + }) + } + + /** + * Computes a position with the maximum amount of liquidity received for a given amount of token0, assuming an unlimited amount of token1 + * @param pool The pool for which the position is created + * @param tickLower The lower tick + * @param tickUpper The upper tick + * @param amount0 The desired amount of token0 + * @param useFullPrecision If true, liquidity will be maximized according to what the router can calculate, + * not what core can theoretically support + * @returns The position + */ + public static fromAmount0({ + pool, + tickLower, + tickUpper, + amount0, + useFullPrecision + }: { + pool: Pool + tickLower: number + tickUpper: number + amount0: BigintIsh + useFullPrecision: boolean + }) { + return Position.fromAmounts({ pool, tickLower, tickUpper, amount0, amount1: MaxUint256, useFullPrecision }) + } + + /** + * Computes a position with the maximum amount of liquidity received for a given amount of token1, assuming an unlimited amount of token0 + * @param pool The pool for which the position is created + * @param tickLower The lower tick + * @param tickUpper The upper tick + * @param amount1 The desired amount of token1 + * @returns The position + */ + public static fromAmount1({ + pool, + tickLower, + tickUpper, + amount1 + }: { + pool: Pool + tickLower: number + tickUpper: number + amount1: BigintIsh + }) { + // this function always uses full precision, + return Position.fromAmounts({ pool, tickLower, tickUpper, amount0: MaxUint256, amount1, useFullPrecision: true }) + } +} diff --git a/src/entities/protocol.ts b/src/entities/protocol.ts new file mode 100644 index 0000000..4a7063a --- /dev/null +++ b/src/entities/protocol.ts @@ -0,0 +1,6 @@ +export enum Protocol { + V1 = 'V1', + V2 = 'V2', + MIXED = 'MIXED', + UNIV3 = 'UNIV3', + } \ No newline at end of file diff --git a/src/entities/tick.ts b/src/entities/tick.ts new file mode 100644 index 0000000..860b6e0 --- /dev/null +++ b/src/entities/tick.ts @@ -0,0 +1,23 @@ +import JSBI from 'jsbi' +import invariant from 'tiny-invariant' +import { BigintIsh } from '../constants' +import { TickMath } from '../utils/tickMath' + +export interface TickConstructorArgs { + index: number + liquidityGross: BigintIsh + liquidityNet: BigintIsh +} + +export class Tick { + public readonly index: number + public readonly liquidityGross: JSBI + public readonly liquidityNet: JSBI + + constructor({ index, liquidityGross, liquidityNet }: TickConstructorArgs) { + invariant(index >= TickMath.MIN_TICK && index <= TickMath.MAX_TICK, 'TICK') + this.index = index + this.liquidityGross = JSBI.BigInt(liquidityGross) + this.liquidityNet = JSBI.BigInt(liquidityNet) + } +} diff --git a/src/entities/tickDataProvider.ts b/src/entities/tickDataProvider.ts new file mode 100644 index 0000000..5dd4c18 --- /dev/null +++ b/src/entities/tickDataProvider.ts @@ -0,0 +1,39 @@ +import { BigintIsh } from '../constants' + +/** + * Provides information about ticks + */ +export interface TickDataProvider { + /** + * Return information corresponding to a specific tick + * @param tick the tick to load + */ + getTick(tick: number): Promise<{ liquidityNet: BigintIsh }> + + /** + * Return the next tick that is initialized within a single word + * @param tick The current tick + * @param lte Whether the next tick should be lte the current tick + * @param tickSpacing The tick spacing of the pool + */ + nextInitializedTickWithinOneWord(tick: number, lte: boolean, tickSpacing: number): Promise<[number, boolean]> +} + +/** + * This tick data provider does not know how to fetch any tick data. It throws whenever it is required. Useful if you + * do not need to load tick data for your use case. + */ +export class NoTickDataProvider implements TickDataProvider { + private static ERROR_MESSAGE = 'No tick data provider was given' + async getTick(_tick: number): Promise<{ liquidityNet: BigintIsh }> { + throw new Error(NoTickDataProvider.ERROR_MESSAGE) + } + + async nextInitializedTickWithinOneWord( + _tick: number, + _lte: boolean, + _tickSpacing: number + ): Promise<[number, boolean]> { + throw new Error(NoTickDataProvider.ERROR_MESSAGE) + } +} diff --git a/src/entities/tickListDataProvider.ts b/src/entities/tickListDataProvider.ts new file mode 100644 index 0000000..f390f2b --- /dev/null +++ b/src/entities/tickListDataProvider.ts @@ -0,0 +1,25 @@ +import { BigintIsh } from '../constants' +import { TickList } from '../utils/tickList' +import { Tick, TickConstructorArgs } from './tick' +import { TickDataProvider } from './tickDataProvider' + +/** + * A data provider for ticks that is backed by an in-memory array of ticks. + */ +export class TickListDataProvider implements TickDataProvider { + private ticks: readonly Tick[] + + constructor(ticks: (Tick | TickConstructorArgs)[], tickSpacing: number) { + const ticksMapped: Tick[] = ticks.map(t => (t instanceof Tick ? t : new Tick(t))) + TickList.validateList(ticksMapped, tickSpacing) + this.ticks = ticksMapped + } + + async getTick(tick: number): Promise<{ liquidityNet: BigintIsh; liquidityGross: BigintIsh }> { + return TickList.getTick(this.ticks, tick) + } + + async nextInitializedTickWithinOneWord(tick: number, lte: boolean, tickSpacing: number): Promise<[number, boolean]> { + return TickList.nextInitializedTickWithinOneWord(this.ticks, tick, lte, tickSpacing) + } +} diff --git a/src/entities/trade.ts b/src/entities/trade.ts index a822407..2cfcbb9 100644 --- a/src/entities/trade.ts +++ b/src/entities/trade.ts @@ -87,13 +87,13 @@ export interface BestTradeOptions { * In other words, if the currency is NATIVE, returns the WETH token amount for the given chain. Otherwise, returns * the input currency amount. */ -function wrappedAmount(currencyAmount: CurrencyAmount, chainId: ChainId): TokenAmount { +export function wrappedAmount(currencyAmount: CurrencyAmount, chainId: ChainId): TokenAmount { if (currencyAmount instanceof TokenAmount) return currencyAmount if (!(currencyAmount.currency instanceof Token) && (currencyAmount.currency instanceof Currency)) return new TokenAmount(WETH[chainId], currencyAmount.raw) invariant(false, 'CURRENCY') } -function wrappedCurrency(currency: Currency, chainId: ChainId): Token { +export function wrappedCurrency(currency: Currency, chainId: ChainId): Token { if (currency instanceof Token) return currency if (!(currency instanceof Token) && (currency instanceof Currency)) return WETH[chainId] invariant(false, 'CURRENCY') diff --git a/src/entities/v2route.ts b/src/entities/v2route.ts new file mode 100644 index 0000000..69c8d5c --- /dev/null +++ b/src/entities/v2route.ts @@ -0,0 +1,84 @@ +import invariant from 'tiny-invariant' + +import { Currency, Price, Token, wrappedCurrency } from '../index' +import { Pool } from './pool' + +export class V2Route { + public readonly pools: Pool[] + public readonly tokenPath: Token[] + public readonly input: Currency + public readonly output: Currency + + private _midPrice: Price | null = null + + /** + * Creates an instance of route. + * @param pools An array of `Pool` objects, ordered by the route the swap will take + * @param input The input token + * @param output The output token + */ + public constructor(pools: Pool[], input: Currency, output: Currency) { + invariant(pools.length > 0, 'POOLS') + + const chainId = pools[0].chainId + const allOnSameChain = pools.every(pool => pool.chainId === chainId) + invariant(allOnSameChain, 'CHAIN_IDS') + + const wrappedInput = wrappedCurrency(input,chainId) + invariant(pools[0].involvesToken(wrappedInput), 'INPUT') + + invariant(pools[pools.length - 1].involvesToken(wrappedCurrency(output,chainId)), 'OUTPUT') + + /** + * Normalizes token0-token1 order and selects the next token/fee step to add to the path + * */ + const tokenPath: Token[] = [wrappedInput] + for (const [i, pool] of pools.entries()) { + const currentInputToken = tokenPath[i] + invariant(currentInputToken.equals(pool.token0) || currentInputToken.equals(pool.token1), 'PATH') + const nextToken = currentInputToken.equals(pool.token0) ? pool.token1 : pool.token0 + tokenPath.push(nextToken) + } + + this.pools = pools + this.tokenPath = tokenPath + this.input = input + this.output = output ?? tokenPath[tokenPath.length - 1] + } + + public get chainId(): number { + return this.pools[0].chainId + } + + /** + * Returns the mid price of the route + */ + public get midPrice(): Price { + if (this._midPrice !== null) return this._midPrice + + const price = this.pools.slice(1).reduce( + ({ nextInput, price }, pool) => { + return nextInput.equals(pool.token0) + ? { + nextInput: pool.token1, + price: price.multiply(pool.token0Price) + } + : { + nextInput: pool.token0, + price: price.multiply(pool.token1Price) + } + }, + this.pools[0].token0.equals(wrappedCurrency(this.input,this.pools[0].chainId)) + ? { + nextInput: this.pools[0].token1, + price: this.pools[0].token0Price + } + : { + nextInput: this.pools[0].token0, + price: this.pools[0].token1Price + } + ).price + + return (this._midPrice = new Price(this.input, this.output, price.denominator, price.numerator)) + } +} diff --git a/src/entities/v2trade.ts b/src/entities/v2trade.ts new file mode 100644 index 0000000..42101a9 --- /dev/null +++ b/src/entities/v2trade.ts @@ -0,0 +1,613 @@ +import { ChainId, Fraction, Percent, Price, CurrencyAmount, TokenAmount,TradeType, wrappedCurrency, wrappedAmount } from '../index' +import invariant from 'tiny-invariant' +import { ONE, ZERO } from '../internalConstants' +import { Pool } from './pool' +import { V2Route } from './v2route' + + +export function v2TradeComparator( + a: V2Trade, + b: V2Trade, + chainId: ChainId +) { + // must have same input and output token for comparison + invariant(wrappedCurrency(a.inputAmount.currency,chainId).equals(wrappedCurrency(b.inputAmount.currency,chainId)), 'INPUT_CURRENCY') + invariant(wrappedCurrency(a.outputAmount.currency,chainId).equals(wrappedCurrency(b.outputAmount.currency,chainId)), 'OUTPUT_CURRENCY') + if (a.outputAmount.equalTo(b.outputAmount)) { + if (a.inputAmount.equalTo(b.inputAmount)) { + // consider the number of hops since each hop costs gas + const aHops = a.swaps.reduce((total, cur) => total + cur.route.tokenPath.length, 0) + const bHops = b.swaps.reduce((total, cur) => total + cur.route.tokenPath.length, 0) + return aHops - bHops + } + // trade A requires less input than trade B, so A should come first + if (a.inputAmount.lessThan(b.inputAmount)) { + return -1 + } else { + return 1 + } + } else { + // tradeA has less output than trade B, so should come second + if (a.outputAmount.lessThan(b.outputAmount)) { + return 1 + } else { + return -1 + } + } +} + +export interface BestV2TradeOptions { + // how many results to return + maxNumResults?: number + // the maximum number of hops a trade should contain + maxHops?: number +} + + +export class V2Trade { + /** + * @deprecated Deprecated in favor of 'swaps' property. If the trade consists of multiple routes + * this will return an error. + * + * When the trade consists of just a single route, this returns the route of the trade, + * i.e. which pools the trade goes through. + */ + public get route(): V2Route { + invariant(this.swaps.length == 1, 'MULTIPLE_ROUTES') + return this.swaps[0].route + } + + /** + * The swaps of the trade, i.e. which routes and how much is swapped in each that + * make up the trade. + */ + public readonly swaps: { + route: V2Route + inputAmount: CurrencyAmount + outputAmount: CurrencyAmount + }[] + + /** + * The type of the trade, either exact in or exact out. + */ + public readonly tradeType: TradeType + + /** + * The cached result of the input amount computation + * @private + */ + private _inputAmount: CurrencyAmount | undefined + + /** + * The input amount for the trade assuming no slippage. + */ + public get inputAmount(): CurrencyAmount { + if (this._inputAmount) { + return this._inputAmount + } + + const inputCurrency = this.swaps[0].inputAmount.currency + const totalInputFromRoutes = this.swaps + .map(({ inputAmount }) => inputAmount) + .reduce((total, cur) => total.add(cur), new CurrencyAmount(inputCurrency, 0)) + + this._inputAmount = totalInputFromRoutes + return this._inputAmount + } + + /** + * The cached result of the output amount computation + * @private + */ + private _outputAmount: CurrencyAmount | undefined + + /** + * The output amount for the trade assuming no slippage. + */ + public get outputAmount(): CurrencyAmount { + if (this._outputAmount) { + return this._outputAmount + } + + const outputCurrency = this.swaps[0].outputAmount.currency + const totalOutputFromRoutes = this.swaps + .map(({ outputAmount }) => outputAmount) + .reduce((total, cur) => total.add(cur), new CurrencyAmount(outputCurrency, 0)) + + this._outputAmount = totalOutputFromRoutes + return this._outputAmount + } + + /** + * The cached result of the computed execution price + * @private + */ + private _executionPrice: Price | undefined + + /** + * The price expressed in terms of output amount/input amount. + */ + public get executionPrice(): Price { + return ( + this._executionPrice ?? + (this._executionPrice = new Price( + this.inputAmount.currency, + this.outputAmount.currency, + this.inputAmount.quotient, + this.outputAmount.quotient + )) + ) + } + + /** + * The cached result of the price impact computation + * @private + */ + private _priceImpact: Percent | undefined + + /** + * Returns the percent difference between the route's mid price and the price impact + */ + public get priceImpact(): Percent { + if (this._priceImpact) { + return this._priceImpact + } + + let spotOutputAmount = new CurrencyAmount(this.outputAmount.currency, 0) + for (const { route, inputAmount } of this.swaps) { + const midPrice = route.midPrice + spotOutputAmount = spotOutputAmount.add(midPrice.quote(inputAmount)) + } + + const priceImpact = spotOutputAmount.subtract(this.outputAmount).divide(spotOutputAmount) + this._priceImpact = new Percent(priceImpact.numerator, priceImpact.denominator) + + return this._priceImpact + } + + /** + * Constructs an exact in trade with the given amount in and route + * @template TInput The input token, either Ether or an ERC-20 + * @template TOutput The output token, either Ether or an ERC-20 + * @param route The route of the exact in trade + * @param amountIn The amount being passed in + * @returns The exact in trade + */ + public static async exactIn( + route: V2Route, + amountIn: CurrencyAmount + ): Promise { + return V2Trade.fromRoute(route, amountIn, TradeType.EXACT_INPUT) + } + + /** + * Constructs an exact out trade with the given amount out and route + * @template TInput The input token, either Ether or an ERC-20 + * @template TOutput The output token, either Ether or an ERC-20 + * @param route The route of the exact out trade + * @param amountOut The amount returned by the trade + * @returns The exact out trade + */ + public static async exactOut( + route: V2Route, + amountOut: CurrencyAmount + ): Promise { + return V2Trade.fromRoute(route, amountOut, TradeType.EXACT_OUTPUT) + } + + /** + * Constructs a trade by simulating swaps through the given route + * @template TInput The input token, either Ether or an ERC-20. + * @template TOutput The output token, either Ether or an ERC-20. + * @template TradeType The type of the trade, either exact in or exact out. + * @param route route to swap through + * @param amount the amount specified, either input or output, depending on tradeType + * @param tradeType whether the trade is an exact input or exact output swap + * @returns The route + */ + public static async fromRoute( + route: V2Route, + amount: TradeType extends TradeType.EXACT_INPUT ? CurrencyAmount: CurrencyAmount, + tradeType: TradeType + ): Promise { + const amounts: CurrencyAmount[] = new Array(route.tokenPath.length) + let inputAmount: CurrencyAmount + let outputAmount: CurrencyAmount + const chainId=route.chainId; + if (tradeType === TradeType.EXACT_INPUT) { + invariant(wrappedCurrency(amount.currency,chainId).equals(wrappedCurrency(route.input,chainId)), 'INPUT') + amounts[0] = wrappedAmount(amount,chainId) + for (let i = 0; i < route.tokenPath.length - 1; i++) { + const pool = route.pools[i] + const [outputAmount] = await pool.getOutputAmount(wrappedAmount(amounts[i],chainId)) + amounts[i + 1] = outputAmount + } + inputAmount = new CurrencyAmount(route.input, amount.raw) + outputAmount = new CurrencyAmount( + route.output, + amounts[amounts.length - 1].raw + ) + } else { + invariant(wrappedCurrency(amount.currency,chainId).equals(wrappedCurrency(route.output,chainId)), 'OUTPUT') + amounts[amounts.length - 1] = wrappedAmount(amount,chainId) + for (let i = route.tokenPath.length - 1; i > 0; i--) { + const pool = route.pools[i - 1] + const [inputAmount] = await pool.getInputAmount(wrappedAmount(amounts[i],chainId)) + amounts[i - 1] = inputAmount + } + inputAmount = new CurrencyAmount(route.input, amount.raw) + outputAmount = new CurrencyAmount(route.output, amount.raw) + } + + return new V2Trade({ + routes: [{ inputAmount, outputAmount, route }], + tradeType + }) + } + + /** + * Constructs a trade from routes by simulating swaps + * + * @template TInput The input token, either Ether or an ERC-20. + * @template TOutput The output token, either Ether or an ERC-20. + * @template TradeType The type of the trade, either exact in or exact out. + * @param routes the routes to swap through and how much of the amount should be routed through each + * @param tradeType whether the trade is an exact input or exact output swap + * @returns The trade + */ + public static async fromRoutes( + routes: { + amount: TradeType extends TradeType.EXACT_INPUT ? CurrencyAmount : CurrencyAmount + route: V2Route + }[], + tradeType: TradeType + ): Promise { + const populatedRoutes: { + route: V2Route + inputAmount: CurrencyAmount + outputAmount: CurrencyAmount + }[] = [] + + for (const { route, amount } of routes) { + const amounts: CurrencyAmount[] = new Array(route.tokenPath.length) + let inputAmount: CurrencyAmount + let outputAmount: CurrencyAmount + const chainId=route.chainId; + if (tradeType === TradeType.EXACT_INPUT) { + invariant(wrappedCurrency(amount.currency,chainId).equals(wrappedCurrency(route.input,chainId)), 'INPUT') + inputAmount = new CurrencyAmount(route.input, amount.raw) + amounts[0] = new TokenAmount(wrappedCurrency(route.input,chainId), amount.raw) + + for (let i = 0; i < route.tokenPath.length - 1; i++) { + const pool = route.pools[i] + const [outputAmount] = await pool.getOutputAmount(wrappedAmount(amounts[i],chainId)) + amounts[i + 1] = outputAmount + } + + outputAmount = new CurrencyAmount( + route.output, + amounts[amounts.length - 1].raw + ) + } else { + invariant(wrappedCurrency(amount.currency,chainId).equals(wrappedCurrency(route.output,chainId)), 'OUTPUT') + outputAmount = new CurrencyAmount(route.output, amount.raw) + amounts[amounts.length - 1] =new CurrencyAmount( + wrappedCurrency(route.output,chainId), + amount.raw + ) + + for (let i = route.tokenPath.length - 1; i > 0; i--) { + const pool = route.pools[i - 1] + const [inputAmount] = await pool.getInputAmount(wrappedAmount(amounts[i],chainId)) + amounts[i - 1] = inputAmount + } + + inputAmount =new CurrencyAmount(route.input, amounts[0].raw) + } + + populatedRoutes.push({ route, inputAmount, outputAmount }) + } + + return new V2Trade({ + routes: populatedRoutes, + tradeType + }) + } + + /** + * Creates a trade without computing the result of swapping through the route. Useful when you have simulated the trade + * elsewhere and do not have any tick data + * @template TInput The input token, either Ether or an ERC-20 + * @template TOutput The output token, either Ether or an ERC-20 + * @template TradeType The type of the trade, either exact in or exact out + * @param constructorArguments The arguments passed to the trade constructor + * @returns The unchecked trade + */ + public static createUncheckedTrade(constructorArguments: { + route: V2Route + inputAmount: CurrencyAmount + outputAmount: CurrencyAmount + tradeType: TradeType + }): V2Trade { + return new V2Trade({ + ...constructorArguments, + routes: [ + { + inputAmount: constructorArguments.inputAmount, + outputAmount: constructorArguments.outputAmount, + route: constructorArguments.route + } + ] + }) + } + + /** + * Creates a trade without computing the result of swapping through the routes. Useful when you have simulated the trade + * elsewhere and do not have any tick data + * @template TInput The input token, either Ether or an ERC-20 + * @template TOutput The output token, either Ether or an ERC-20 + * @template TradeType The type of the trade, either exact in or exact out + * @param constructorArguments The arguments passed to the trade constructor + * @returns The unchecked trade + */ + public static createUncheckedTradeWithMultipleRoutes(constructorArguments: { + routes: { + route: V2Route + inputAmount: CurrencyAmount + outputAmount: CurrencyAmount + }[] + tradeType: TradeType + }): V2Trade { + return new V2Trade(constructorArguments) + } + + /** + * Construct a trade by passing in the pre-computed property values + * @param routes The routes through which the trade occurs + * @param tradeType The type of trade, exact input or exact output + */ + private constructor({ + routes, + tradeType + }: { + routes: { + route: V2Route + inputAmount: CurrencyAmount + outputAmount: CurrencyAmount + }[] + tradeType: TradeType + }) { + const chainId=routes[0].route.chainId + const inputCurrency = routes[0].inputAmount.currency + const outputCurrency = routes[0].outputAmount.currency + invariant( + routes.every(({ route }) => wrappedCurrency(inputCurrency,chainId).equals(wrappedCurrency(route.input,chainId))), + 'INPUT_CURRENCY_MATCH' + ) + invariant( + routes.every(({ route }) => wrappedCurrency(outputCurrency,chainId).equals(wrappedCurrency(route.output,chainId))), + 'OUTPUT_CURRENCY_MATCH' + ) + + const numPools = routes.map(({ route }) => route.pools.length).reduce((total, cur) => total + cur, 0) + const poolAddressSet = new Set() + for (const { route } of routes) { + for (const pool of route.pools) { + poolAddressSet.add(Pool.getAddress(pool.token0, pool.token1)) + } + } + + invariant(numPools == poolAddressSet.size, 'POOLS_DUPLICATED') + + this.swaps = routes + this.tradeType = tradeType + } + + /** + * Get the minimum amount that must be received from this trade for the given slippage tolerance + * @param slippageTolerance The tolerance of unfavorable slippage from the execution price of this trade + * @returns The amount out + */ + public minimumAmountOut(slippageTolerance: Percent, amountOut = this.outputAmount): CurrencyAmount { + invariant(!slippageTolerance.lessThan(ZERO), 'SLIPPAGE_TOLERANCE') + if (this.tradeType === TradeType.EXACT_OUTPUT) { + return amountOut + } else { + const slippageAdjustedAmountOut = new Fraction(ONE) + .add(slippageTolerance) + .invert() + .multiply(amountOut.quotient).quotient + return new CurrencyAmount(amountOut.currency, slippageAdjustedAmountOut) + } + } + + /** + * Get the maximum amount in that can be spent via this trade for the given slippage tolerance + * @param slippageTolerance The tolerance of unfavorable slippage from the execution price of this trade + * @returns The amount in + */ + public maximumAmountIn(slippageTolerance: Percent, amountIn = this.inputAmount): CurrencyAmount { + invariant(!slippageTolerance.lessThan(ZERO), 'SLIPPAGE_TOLERANCE') + if (this.tradeType === TradeType.EXACT_INPUT) { + return amountIn + } else { + const slippageAdjustedAmountIn = new Fraction(ONE).add(slippageTolerance).multiply(amountIn.quotient).quotient + return new CurrencyAmount(amountIn.currency, slippageAdjustedAmountIn) + } + } + + /** + * Return the execution price after accounting for slippage tolerance + * @param slippageTolerance the allowed tolerated slippage + * @returns The execution price + */ + public worstExecutionPrice(slippageTolerance: Percent): Price { + return new Price( + this.inputAmount.currency, + this.outputAmount.currency, + this.maximumAmountIn(slippageTolerance).quotient, + this.minimumAmountOut(slippageTolerance).quotient + ) + } + + /** + * Given a list of pools, and a fixed amount in, returns the top `maxNumResults` trades that go from an input token + * amount to an output token, making at most `maxHops` hops. + * Note this does not consider aggregation, as routes are linear. It's possible a better route exists by splitting + * the amount in among multiple routes. + * @param pools the pools to consider in finding the best trade + * @param nextAmountIn exact amount of input currency to spend + * @param currencyOut the desired currency out + * @param maxNumResults maximum number of results to return + * @param maxHops maximum number of hops a returned trade can make, e.g. 1 hop goes through a single pool + * @param currentPools used in recursion; the current list of pools + * @param currencyAmountIn used in recursion; the original value of the currencyAmountIn parameter + * @param bestTrades used in recursion; the current list of best trades + * @returns The exact in trade + */ +// public static async bestTradeExactIn( +// pools: Pool[], +// currencyAmountIn: CurrencyAmount, +// currencyOut: Currency, +// { maxNumResults = 3, maxHops = 3 }: BestTradeOptions = {}, +// // used in recursion. +// currentPools: Pool[] = [], +// nextAmountIn: CurrencyAmount = currencyAmountIn, +// bestTrades: Trade[] = [] +// ): Promise { +// invariant(pools.length > 0, 'POOLS') +// invariant(maxHops > 0, 'MAX_HOPS') +// invariant(currencyAmountIn === nextAmountIn || currentPools.length > 0, 'INVALID_RECURSION') + +// const amountIn = nextAmountIn.wrapped +// const tokenOut = currencyOut.wrapped +// for (let i = 0; i < pools.length; i++) { +// const pool = pools[i] +// // pool irrelevant +// if (!pool.token0.equals(amountIn.currency) && !pool.token1.equals(amountIn.currency)) continue + +// let amountOut: CurrencyAmount +// try { +// ;[amountOut] = await pool.getOutputAmount(amountIn) +// } catch (error) { +// // input too low +// if (error.isInsufficientInputAmountError) { +// continue +// } +// throw error +// } +// // we have arrived at the output token, so this is the final trade of one of the paths +// if (amountOut.currency.isToken && amountOut.currency.equals(tokenOut)) { +// sortedInsert( +// bestTrades, +// await Trade.fromRoute( +// new Route([...currentPools, pool], currencyAmountIn.currency, currencyOut), +// currencyAmountIn, +// TradeType.EXACT_INPUT +// ), +// maxNumResults, +// tradeComparator +// ) +// } else if (maxHops > 1 && pools.length > 1) { +// const poolsExcludingThisPool = pools.slice(0, i).concat(pools.slice(i + 1, pools.length)) + +// // otherwise, consider all the other paths that lead from this token as long as we have not exceeded maxHops +// await Trade.bestTradeExactIn( +// poolsExcludingThisPool, +// currencyAmountIn, +// currencyOut, +// { +// maxNumResults, +// maxHops: maxHops - 1 +// }, +// [...currentPools, pool], +// amountOut, +// bestTrades +// ) +// } +// } + +// return bestTrades +// } + + /** + * similar to the above method but instead targets a fixed output amount + * given a list of pools, and a fixed amount out, returns the top `maxNumResults` trades that go from an input token + * to an output token amount, making at most `maxHops` hops + * note this does not consider aggregation, as routes are linear. it's possible a better route exists by splitting + * the amount in among multiple routes. + * @param pools the pools to consider in finding the best trade + * @param currencyIn the currency to spend + * @param currencyAmountOut the desired currency amount out + * @param nextAmountOut the exact amount of currency out + * @param maxNumResults maximum number of results to return + * @param maxHops maximum number of hops a returned trade can make, e.g. 1 hop goes through a single pool + * @param currentPools used in recursion; the current list of pools + * @param bestTrades used in recursion; the current list of best trades + * @returns The exact out trade + */ +// public static async bestTradeExactOut( +// pools: Pool[], +// currencyIn: TInput, +// currencyAmountOut: CurrencyAmount, +// { maxNumResults = 3, maxHops = 3 }: BestTradeOptions = {}, +// // used in recursion. +// currentPools: Pool[] = [], +// nextAmountOut: CurrencyAmount = currencyAmountOut, +// bestTrades: Trade[] = [] +// ): Promise[]> { +// invariant(pools.length > 0, 'POOLS') +// invariant(maxHops > 0, 'MAX_HOPS') +// invariant(currencyAmountOut === nextAmountOut || currentPools.length > 0, 'INVALID_RECURSION') + +// const amountOut = nextAmountOut.wrapped +// const tokenIn = currencyIn.wrapped +// for (let i = 0; i < pools.length; i++) { +// const pool = pools[i] +// // pool irrelevant +// if (!pool.token0.equals(amountOut.currency) && !pool.token1.equals(amountOut.currency)) continue + +// let amountIn: CurrencyAmount +// try { +// ;[amountIn] = await pool.getInputAmount(amountOut) +// } catch (error) { +// // not enough liquidity in this pool +// if (error.isInsufficientReservesError) { +// continue +// } +// throw error +// } +// // we have arrived at the input token, so this is the first trade of one of the paths +// if (amountIn.currency.equals(tokenIn)) { +// sortedInsert( +// bestTrades, +// await Trade.fromRoute( +// new Route([pool, ...currentPools], currencyIn, currencyAmountOut.currency), +// currencyAmountOut, +// TradeType.EXACT_OUTPUT +// ), +// maxNumResults, +// tradeComparator +// ) +// } else if (maxHops > 1 && pools.length > 1) { +// const poolsExcludingThisPool = pools.slice(0, i).concat(pools.slice(i + 1, pools.length)) + +// // otherwise, consider all the other paths that arrive at this token as long as we have not exceeded maxHops +// await Trade.bestTradeExactOut( +// poolsExcludingThisPool, +// currencyIn, +// currencyAmountOut, +// { +// maxNumResults, +// maxHops: maxHops - 1 +// }, +// [pool, ...currentPools], +// amountIn, +// bestTrades +// ) +// } +// } + +// return bestTrades +// } +} diff --git a/src/index.ts b/src/index.ts index f1d1d5a..dd6cae1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,10 +9,20 @@ export { FACTORY_ADDRESS, ROUTER_ADDRESS, INIT_CODE_HASH, - MINIMUM_LIQUIDITY + MINIMUM_LIQUIDITY, + V2_DEPLOYER_ADDRESS, + V2_MASTER_DEPLOYER_ADDRESS, + V2_FACTORY_ADDRESS, + V2_POOL_INIT_CODE_HASH, + FeeAmount, + TICK_SPACINGS } from './constants' export * from './errors' export * from './entities' export * from './router' export * from './fetcher' +export * from './utils' +export * from './MasterDeployer' +export * from './concentratedPoolManager' +export * from './limitOrderManager' diff --git a/src/internalConstants.ts b/src/internalConstants.ts new file mode 100644 index 0000000..97e6650 --- /dev/null +++ b/src/internalConstants.ts @@ -0,0 +1,10 @@ +import JSBI from 'jsbi' + +// constants used internally but not expected to be used externally +export const NEGATIVE_ONE = JSBI.BigInt(-1) +export const ZERO = JSBI.BigInt(0) +export const ONE = JSBI.BigInt(1) + +// used in liquidity amount math +export const Q96 = JSBI.exponentiate(JSBI.BigInt(2), JSBI.BigInt(96)) +export const Q192 = JSBI.exponentiate(Q96, JSBI.BigInt(2)) diff --git a/src/limitOrderManager.ts b/src/limitOrderManager.ts new file mode 100644 index 0000000..b73f35a --- /dev/null +++ b/src/limitOrderManager.ts @@ -0,0 +1,164 @@ +import { Interface } from "@ethersproject/abi"; +import { Order } from "entities/order"; +import { MethodParameters, Percent,Currency, Pool, toHex, wrappedCurrency } from "./index"; +import invariant from "tiny-invariant"; +import LimitOrderManagerAbi from "./abis/LimitOrderManager.json" +import JSBI from 'jsbi' +import { BigintIsh, ZERO } from "./constants"; + + /** + * Options for producing the calldata to create limit order. + */ +export interface CreateOrderOptions{ + /** + * How much the pool price is allowed to move. + */ + slippageTolerance: Percent + + /** + * When the transaction expires, in epoch seconds. + */ + deadline: BigintIsh + + /** + * Whether to spend ether. If true, one of the pool tokens must be WETH, by default false + */ + useNative?: Currency + + /** + * The lower and upper old + */ + lowerOldTick: number + + /** + * The lower and upper old + */ + upperOldTick: number + +} + +export interface ClaimOrderOptions{ + /** + * Indicates the ID of the position to collect for. + */ + tokenId: BigintIsh + + /** + * When the transaction expires, in epoch seconds. + */ + deadline: BigintIsh + + + amountToClaim: BigintIsh + + unwrapVault: Boolean + +} +export interface CancelOrderOptions{ + /** + * Indicates the ID of the position to collect for. + */ + tokenId: BigintIsh + + /** + * When the transaction expires, in epoch seconds. + */ + deadline: BigintIsh + + unwrapVault: Boolean + +} + + + +export abstract class LimitOrderManager { + public static INTERFACE: Interface = new Interface(LimitOrderManagerAbi); + + /** + * Cannot be constructed. + */ + private constructor() {} + + public static createCallParameters(order:Order, options:CreateOrderOptions):MethodParameters { + invariant(JSBI.greaterThan(order.amountIn, ZERO), 'ZERO_AMOUNT_IN') + + let calldata: string + + // get amounts + const {zeroForOne,amountIn,tick}=order; + const {lowerOldTick,upperOldTick}=options + + calldata=this.INTERFACE.encodeFunctionData('createLimitOrder',[ + Pool.getAddress(order.pool.token0,order.pool.token1), + tick, + lowerOldTick, + upperOldTick, + true, + amountIn.toString(), + zeroForOne + ]) + + let value: string = toHex(0) + if (options.useNative) { + const wrapped = wrappedCurrency(options.useNative,order.tokenAmountIn.token.chainId) + invariant(order.tokenAmountIn.token.equals(wrapped), 'NO_WETH') + + const wrappedValue = order.amountIn + + value = toHex(wrappedValue) + } + + return { + calldata, + value + } + + } + + public static claimCallParameters(options:ClaimOrderOptions):MethodParameters { + let calldata + + const tokenId = toHex(options.tokenId) + const amountToClaim=toHex(options.amountToClaim) + const unwrapVault=options.unwrapVault + // const involvesETH = + // false + + calldata=this.INTERFACE.encodeFunctionData('claimLimitOrder',[ + tokenId, + amountToClaim, + unwrapVault + ]) + + const value = toHex(0) + + return { + calldata, + value + } + + + } + public static cancelallParameters(options:CancelOrderOptions):MethodParameters { + let calldata + + const tokenId = toHex(options.tokenId) + const unwrapVault=options.unwrapVault + // const involvesETH = + // false + + calldata=this.INTERFACE.encodeFunctionData('cancelLimitOrder',[ + tokenId, + unwrapVault + ]) + + const value = toHex(0) + + return { + calldata, + value + } + + } + +} \ No newline at end of file diff --git a/src/utils/calldata.ts b/src/utils/calldata.ts new file mode 100644 index 0000000..d4c0302 --- /dev/null +++ b/src/utils/calldata.ts @@ -0,0 +1,30 @@ +import { BigintIsh } from '../constants' +import JSBI from 'jsbi' + +/** + * Generated method parameters for executing a call. + */ +export interface MethodParameters { + /** + * The hex encoded calldata to perform the given operation + */ + calldata: string + /** + * The amount of ether (wei) to send in hex. + */ + value: string +} + +/** + * Converts a big int to a hex string + * @param bigintIsh + * @returns The hex encoded calldata + */ +export function toHex(bigintIsh: BigintIsh) { + const bigInt = JSBI.BigInt(bigintIsh) + let hex = bigInt.toString(16) + if (hex.length % 2 !== 0) { + hex = `0${hex}` + } + return `0x${hex}` +} diff --git a/src/utils/computePoolAddress.ts b/src/utils/computePoolAddress.ts new file mode 100644 index 0000000..b0a0452 --- /dev/null +++ b/src/utils/computePoolAddress.ts @@ -0,0 +1,36 @@ +import { defaultAbiCoder } from '@ethersproject/abi' +import { getCreate2Address } from '@ethersproject/address' +import { keccak256 } from '@ethersproject/solidity' +import { Token } from '../index' +import { V2_POOL_INIT_CODE_HASH } from '../constants' + +/** + * Computes a pool address + * @param deployerAddress The Uniswap V3 factory address + * @param tokenA The first token of the pair, irrespective of sort order + * @param tokenB The second token of the pair, irrespective of sort order + * @param initCodeHashManualOverride Override the init code hash used to compute the pool address if necessary + * @returns The pool address + */ +export function computePoolAddress({ + deployerAddress, + tokenA, + tokenB, + initCodeHashManualOverride +}: { + deployerAddress: string + tokenA: Token + tokenB: Token + initCodeHashManualOverride?: string +}): string { + const [token0, token1] = tokenA.sortsBefore(tokenB) ? [tokenA, tokenB] : [tokenB, tokenA] // does safety checks + const salt=keccak256( + ['bytes'], + [defaultAbiCoder.encode(['address', 'address'], [token0.address, token1.address])] + ) + return getCreate2Address( + deployerAddress, + salt, + initCodeHashManualOverride ?? V2_POOL_INIT_CODE_HASH[token0.chainId] + ) +} diff --git a/src/utils/encodeSqrtRatioX96.ts b/src/utils/encodeSqrtRatioX96.ts new file mode 100644 index 0000000..c32d086 --- /dev/null +++ b/src/utils/encodeSqrtRatioX96.ts @@ -0,0 +1,17 @@ +import { BigintIsh } from '../constants' +import JSBI from 'jsbi' +import {sqrt} from "./index" + +/** + * Returns the sqrt ratio as a Q64.96 corresponding to a given ratio of amount1 and amount0 + * @param amount1 The numerator amount i.e., the amount of token1 + * @param amount0 The denominator amount i.e., the amount of token0 + * @returns The sqrt ratio + */ + +export function encodeSqrtRatioX96(amount1: BigintIsh, amount0: BigintIsh): JSBI { + const numerator = JSBI.leftShift(JSBI.BigInt(amount1), JSBI.BigInt(192)) + const denominator = JSBI.BigInt(amount0) + const ratioX192 = JSBI.divide(numerator, denominator) + return sqrt(ratioX192) +} diff --git a/src/utils/fullMath.ts b/src/utils/fullMath.ts new file mode 100644 index 0000000..97f1a36 --- /dev/null +++ b/src/utils/fullMath.ts @@ -0,0 +1,16 @@ +import JSBI from 'jsbi' +import { ONE, ZERO } from '../internalConstants' + +export abstract class FullMath { + /** + * Cannot be constructed. + */ + private constructor() {} + + public static mulDivRoundingUp(a: JSBI, b: JSBI, denominator: JSBI): JSBI { + const product = JSBI.multiply(a, b) + let result = JSBI.divide(product, denominator) + if (JSBI.notEqual(JSBI.remainder(product, denominator), ZERO)) result = JSBI.add(result, ONE) + return result + } +} diff --git a/src/utils.ts b/src/utils/index.ts similarity index 84% rename from src/utils.ts rename to src/utils/index.ts index 867684d..4e6f4e8 100644 --- a/src/utils.ts +++ b/src/utils/index.ts @@ -3,7 +3,7 @@ import warning from 'tiny-warning' import JSBI from 'jsbi' import { getAddress } from '@ethersproject/address' -import { BigintIsh, ZERO, ONE, TWO, THREE, SolidityType, SOLIDITY_TYPE_MAXIMA } from './constants' +import { BigintIsh, ZERO, ONE, TWO, THREE, SolidityType, SOLIDITY_TYPE_MAXIMA } from '../constants' export function validateSolidityTypeInstance(value: JSBI, solidityType: SolidityType): void { invariant(JSBI.greaterThanOrEqual(value, ZERO), `${value} is not a ${solidityType}.`) @@ -25,7 +25,7 @@ export function parseBigintIsh(bigintIsh: BigintIsh): JSBI { return bigintIsh instanceof JSBI ? bigintIsh : typeof bigintIsh === 'bigint' - ? JSBI.BigInt(bigintIsh.toString()) + ? JSBI.BigInt(bigintIsh) : JSBI.BigInt(bigintIsh) } @@ -80,3 +80,16 @@ export function sortedInsert(items: T[], add: T, maxSize: number, comparator: return isFull ? items.pop()! : null } } + +export * from './computePoolAddress' +export * from './calldata' +export * from './isSorted' +export * from './mostSignificantBit' +export * from './tickList' +export * from './tickMath' +export * from './fullMath' +export * from './priceTickConversions' +export * from './encodeSqrtRatioX96' +export * from './maxLiquidityForAmounts' +export * from './sqrtPriceMath' +export * from './nearestUsableTick' diff --git a/src/utils/isSorted.ts b/src/utils/isSorted.ts new file mode 100644 index 0000000..763291c --- /dev/null +++ b/src/utils/isSorted.ts @@ -0,0 +1,15 @@ +/** + * Determines if a tick list is sorted + * @param list The tick list + * @param comparator The comparator + * @returns true if sorted + */ + export function isSorted(list: Array, comparator: (a: T, b: T) => number): boolean { + for (let i = 0; i < list.length - 1; i++) { + if (comparator(list[i], list[i + 1]) > 0) { + return false + } + } + return true + } + \ No newline at end of file diff --git a/src/utils/maxLiquidityForAmounts.ts b/src/utils/maxLiquidityForAmounts.ts new file mode 100644 index 0000000..9bef16d --- /dev/null +++ b/src/utils/maxLiquidityForAmounts.ts @@ -0,0 +1,91 @@ +import { BigintIsh } from '../constants' +import JSBI from 'jsbi' +import { Q96 } from '../internalConstants' + +/** + * Returns an imprecise maximum amount of liquidity received for a given amount of token 0. + * This function is available to accommodate LiquidityAmounts#getLiquidityForAmount0 in the v3 periphery, + * which could be more precise by at least 32 bits by dividing by Q64 instead of Q96 in the intermediate step, + * and shifting the subtracted ratio left by 32 bits. This imprecise calculation will likely be replaced in a future + * v3 router contract. + * @param sqrtRatioAX96 The price at the lower boundary + * @param sqrtRatioBX96 The price at the upper boundary + * @param amount0 The token0 amount + * @returns liquidity for amount0, imprecise + */ +function maxLiquidityForAmount0Imprecise(sqrtRatioAX96: JSBI, sqrtRatioBX96: JSBI, amount0: BigintIsh): JSBI { + if (JSBI.greaterThan(sqrtRatioAX96, sqrtRatioBX96)) { + ;[sqrtRatioAX96, sqrtRatioBX96] = [sqrtRatioBX96, sqrtRatioAX96] + } + const intermediate = JSBI.divide(JSBI.multiply(sqrtRatioAX96, sqrtRatioBX96), Q96) + return JSBI.divide(JSBI.multiply(JSBI.BigInt(amount0), intermediate), JSBI.subtract(sqrtRatioBX96, sqrtRatioAX96)) +} + +/** + * Returns a precise maximum amount of liquidity received for a given amount of token 0 by dividing by Q64 instead of Q96 in the intermediate step, + * and shifting the subtracted ratio left by 32 bits. + * @param sqrtRatioAX96 The price at the lower boundary + * @param sqrtRatioBX96 The price at the upper boundary + * @param amount0 The token0 amount + * @returns liquidity for amount0, precise + */ +function maxLiquidityForAmount0Precise(sqrtRatioAX96: JSBI, sqrtRatioBX96: JSBI, amount0: BigintIsh): JSBI { + if (JSBI.greaterThan(sqrtRatioAX96, sqrtRatioBX96)) { + ;[sqrtRatioAX96, sqrtRatioBX96] = [sqrtRatioBX96, sqrtRatioAX96] + } + + const numerator = JSBI.multiply(JSBI.multiply(JSBI.BigInt(amount0), sqrtRatioAX96), sqrtRatioBX96) + const denominator = JSBI.multiply(Q96, JSBI.subtract(sqrtRatioBX96, sqrtRatioAX96)) + + return JSBI.divide(numerator, denominator) +} + +/** + * Computes the maximum amount of liquidity received for a given amount of token1 + * @param sqrtRatioAX96 The price at the lower tick boundary + * @param sqrtRatioBX96 The price at the upper tick boundary + * @param amount1 The token1 amount + * @returns liquidity for amount1 + */ +function maxLiquidityForAmount1(sqrtRatioAX96: JSBI, sqrtRatioBX96: JSBI, amount1: BigintIsh): JSBI { + if (JSBI.greaterThan(sqrtRatioAX96, sqrtRatioBX96)) { + ;[sqrtRatioAX96, sqrtRatioBX96] = [sqrtRatioBX96, sqrtRatioAX96] + } + return JSBI.divide(JSBI.multiply(JSBI.BigInt(amount1), Q96), JSBI.subtract(sqrtRatioBX96, sqrtRatioAX96)) +} + +/** + * Computes the maximum amount of liquidity received for a given amount of token0, token1, + * and the prices at the tick boundaries. + * @param sqrtRatioCurrentX96 the current price + * @param sqrtRatioAX96 price at lower boundary + * @param sqrtRatioBX96 price at upper boundary + * @param amount0 token0 amount + * @param amount1 token1 amount + * @param useFullPrecision if false, liquidity will be maximized according to what the router can calculate, + * not what core can theoretically support + */ +export function maxLiquidityForAmounts( + sqrtRatioCurrentX96: JSBI, + sqrtRatioAX96: JSBI, + sqrtRatioBX96: JSBI, + amount0: BigintIsh, + amount1: BigintIsh, + useFullPrecision: boolean +): JSBI { + if (JSBI.greaterThan(sqrtRatioAX96, sqrtRatioBX96)) { + ;[sqrtRatioAX96, sqrtRatioBX96] = [sqrtRatioBX96, sqrtRatioAX96] + } + + const maxLiquidityForAmount0 = useFullPrecision ? maxLiquidityForAmount0Precise : maxLiquidityForAmount0Imprecise + + if (JSBI.lessThanOrEqual(sqrtRatioCurrentX96, sqrtRatioAX96)) { + return maxLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, amount0) + } else if (JSBI.lessThan(sqrtRatioCurrentX96, sqrtRatioBX96)) { + const liquidity0 = maxLiquidityForAmount0(sqrtRatioCurrentX96, sqrtRatioBX96, amount0) + const liquidity1 = maxLiquidityForAmount1(sqrtRatioAX96, sqrtRatioCurrentX96, amount1) + return JSBI.lessThan(liquidity0, liquidity1) ? liquidity0 : liquidity1 + } else { + return maxLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amount1) + } +} diff --git a/src/utils/mostSignificantBit.ts b/src/utils/mostSignificantBit.ts new file mode 100644 index 0000000..0aebe1c --- /dev/null +++ b/src/utils/mostSignificantBit.ts @@ -0,0 +1,24 @@ +import { MaxUint256 } from '../constants' +import JSBI from 'jsbi' +import invariant from 'tiny-invariant' +import { ZERO } from '../internalConstants' + +const TWO = JSBI.BigInt(2) +const POWERS_OF_2 = [128, 64, 32, 16, 8, 4, 2, 1].map((pow: number): [number, JSBI] => [ + pow, + JSBI.exponentiate(TWO, JSBI.BigInt(pow)) +]) + +export function mostSignificantBit(x: JSBI): number { + invariant(JSBI.greaterThan(x, ZERO), 'ZERO') + invariant(JSBI.lessThanOrEqual(x, MaxUint256), 'MAX') + + let msb: number = 0 + for (const [power, min] of POWERS_OF_2) { + if (JSBI.greaterThanOrEqual(x, min)) { + x = JSBI.signedRightShift(x, JSBI.BigInt(power)) + msb += power + } + } + return msb +} diff --git a/src/utils/nearestUsableTick.ts b/src/utils/nearestUsableTick.ts new file mode 100644 index 0000000..6dc630a --- /dev/null +++ b/src/utils/nearestUsableTick.ts @@ -0,0 +1,29 @@ +import invariant from 'tiny-invariant' +import { TickMath } from './tickMath' + +/** + * Returns the closest tick that is nearest a given tick and usable for the given tick spacing + * @param tick the target tick + * @param tickSpacing the spacing of the pool + */ +export function nearestUsableTick(tick: number, tickSpacing: number,even?:boolean) { + invariant(Number.isInteger(tick) && Number.isInteger(tickSpacing), 'INTEGERS') + invariant(tickSpacing > 0, 'TICK_SPACING') + invariant(tick >= TickMath.MIN_TICK && tick <= TickMath.MAX_TICK, 'TICK_BOUND') + const rounded = Math.round(tick / tickSpacing) * tickSpacing + const evenMultiple=Math.round(Math.round(tick / tickSpacing)/2)*2 + const roundedEven = (evenMultiple) * tickSpacing + const roundedOdd = (evenMultiple+1) * tickSpacing + if(even===undefined) + if (rounded < TickMath.MIN_TICK) return rounded + tickSpacing + else if (rounded > TickMath.MAX_TICK) return rounded - tickSpacing + else return rounded + if(even) + if (roundedEven < TickMath.MIN_TICK) return roundedEven + (tickSpacing*2) + else if (roundedEven > TickMath.MAX_TICK) return roundedEven - (tickSpacing*2) + else return roundedEven + else + if (roundedOdd < TickMath.MIN_TICK) return roundedOdd + (tickSpacing*2) + else if (roundedOdd > TickMath.MAX_TICK) return roundedOdd - (tickSpacing*2) + else return roundedOdd +} diff --git a/src/utils/priceTickConversions.ts b/src/utils/priceTickConversions.ts new file mode 100644 index 0000000..86ea32d --- /dev/null +++ b/src/utils/priceTickConversions.ts @@ -0,0 +1,51 @@ +import { Price, Token,ChainId,wrappedCurrency } from '../index' +import JSBI from 'jsbi' +import { Q192 } from '../internalConstants' +// import { encodeSqrtRatioX96 } from './encodeSqrtRatioX96' +import { TickMath } from './tickMath' +import { encodeSqrtRatioX96 } from './encodeSqrtRatioX96' + +/** + * Returns a price object corresponding to the input tick and the base/quote token + * Inputs must be tokens because the address order is used to interpret the price represented by the tick + * @param baseToken the base token of the price + * @param quoteToken the quote token of the price + * @param tick the tick for which to return the price + */ +export function tickToPrice(baseToken: Token, quoteToken: Token, tick: number): Price { + const sqrtRatioX96 = TickMath.getSqrtRatioAtTick(tick) + + const ratioX192 = JSBI.multiply(sqrtRatioX96, sqrtRatioX96) + + return baseToken.sortsBefore(quoteToken) + ? new Price(baseToken, quoteToken, Q192, ratioX192) + : new Price(baseToken, quoteToken, ratioX192, Q192) +} + +/** + * Returns the first tick for which the given price is greater than or equal to the tick price + * @param price for which to return the closest tick that represents a price less than or equal to the input price, + * i.e. the price of the returned tick is less than or equal to the input price + */ +export function priceToClosestTick(price: Price,chainId:ChainId): number { + const baseCurrency=wrappedCurrency(price.baseCurrency,chainId); +const quoteCurrency=wrappedCurrency(price.quoteCurrency,chainId); + const sorted = baseCurrency.sortsBefore(quoteCurrency) + + const sqrtRatioX96 = sorted + ? encodeSqrtRatioX96(price.numerator, price.denominator) + : encodeSqrtRatioX96(price.denominator, price.numerator) + + let tick = TickMath.getTickAtSqrtRatio(sqrtRatioX96) + const nextTickPrice = tickToPrice(baseCurrency, quoteCurrency, tick + 1) + if (sorted) { + if (!price.lessThan(nextTickPrice)) { + tick++ + } + } else { + if (!price.greaterThan(nextTickPrice)) { + tick++ + } + } + return tick +} diff --git a/src/utils/sqrtPriceMath.ts b/src/utils/sqrtPriceMath.ts new file mode 100644 index 0000000..74776aa --- /dev/null +++ b/src/utils/sqrtPriceMath.ts @@ -0,0 +1,119 @@ +import { MaxUint256 } from '../constants' +import JSBI from 'jsbi' +import invariant from 'tiny-invariant' +import { ONE, ZERO, Q96 } from '../internalConstants' +import { FullMath } from './fullMath' + +const MaxUint160 = JSBI.subtract(JSBI.exponentiate(JSBI.BigInt(2), JSBI.BigInt(160)), ONE) + +function multiplyIn256(x: JSBI, y: JSBI): JSBI { + const product = JSBI.multiply(x, y) + return JSBI.bitwiseAnd(product, MaxUint256) +} + +function addIn256(x: JSBI, y: JSBI): JSBI { + const sum = JSBI.add(x, y) + return JSBI.bitwiseAnd(sum, MaxUint256) +} + +export abstract class SqrtPriceMath { + /** + * Cannot be constructed. + */ + private constructor() {} + + public static getAmount0Delta(sqrtRatioAX96: JSBI, sqrtRatioBX96: JSBI, liquidity: JSBI, roundUp: boolean): JSBI { + if (JSBI.greaterThan(sqrtRatioAX96, sqrtRatioBX96)) { + ;[sqrtRatioAX96, sqrtRatioBX96] = [sqrtRatioBX96, sqrtRatioAX96] + } + + const numerator1 = JSBI.leftShift(liquidity, JSBI.BigInt(96)) + const numerator2 = JSBI.subtract(sqrtRatioBX96, sqrtRatioAX96) + + return roundUp + ? FullMath.mulDivRoundingUp(FullMath.mulDivRoundingUp(numerator1, numerator2, sqrtRatioBX96), ONE, sqrtRatioAX96) + : JSBI.divide(JSBI.divide(JSBI.multiply(numerator1, numerator2), sqrtRatioBX96), sqrtRatioAX96) + } + + public static getAmount1Delta(sqrtRatioAX96: JSBI, sqrtRatioBX96: JSBI, liquidity: JSBI, roundUp: boolean): JSBI { + if (JSBI.greaterThan(sqrtRatioAX96, sqrtRatioBX96)) { + ;[sqrtRatioAX96, sqrtRatioBX96] = [sqrtRatioBX96, sqrtRatioAX96] + } + + return roundUp + ? FullMath.mulDivRoundingUp(liquidity, JSBI.subtract(sqrtRatioBX96, sqrtRatioAX96), Q96) + : JSBI.divide(JSBI.multiply(liquidity, JSBI.subtract(sqrtRatioBX96, sqrtRatioAX96)), Q96) + } + + public static getNextSqrtPriceFromInput(sqrtPX96: JSBI, liquidity: JSBI, amountIn: JSBI, zeroForOne: boolean): JSBI { + invariant(JSBI.greaterThan(sqrtPX96, ZERO)) + invariant(JSBI.greaterThan(liquidity, ZERO)) + + return zeroForOne + ? this.getNextSqrtPriceFromAmount0RoundingUp(sqrtPX96, liquidity, amountIn, true) + : this.getNextSqrtPriceFromAmount1RoundingDown(sqrtPX96, liquidity, amountIn, true) + } + + public static getNextSqrtPriceFromOutput( + sqrtPX96: JSBI, + liquidity: JSBI, + amountOut: JSBI, + zeroForOne: boolean + ): JSBI { + invariant(JSBI.greaterThan(sqrtPX96, ZERO)) + invariant(JSBI.greaterThan(liquidity, ZERO)) + + return zeroForOne + ? this.getNextSqrtPriceFromAmount1RoundingDown(sqrtPX96, liquidity, amountOut, false) + : this.getNextSqrtPriceFromAmount0RoundingUp(sqrtPX96, liquidity, amountOut, false) + } + + private static getNextSqrtPriceFromAmount0RoundingUp( + sqrtPX96: JSBI, + liquidity: JSBI, + amount: JSBI, + add: boolean + ): JSBI { + if (JSBI.equal(amount, ZERO)) return sqrtPX96 + const numerator1 = JSBI.leftShift(liquidity, JSBI.BigInt(96)) + + if (add) { + let product = multiplyIn256(amount, sqrtPX96) + if (JSBI.equal(JSBI.divide(product, amount), sqrtPX96)) { + const denominator = addIn256(numerator1, product) + if (JSBI.greaterThanOrEqual(denominator, numerator1)) { + return FullMath.mulDivRoundingUp(numerator1, sqrtPX96, denominator) + } + } + + return FullMath.mulDivRoundingUp(numerator1, ONE, JSBI.add(JSBI.divide(numerator1, sqrtPX96), amount)) + } else { + let product = multiplyIn256(amount, sqrtPX96) + + invariant(JSBI.equal(JSBI.divide(product, amount), sqrtPX96)) + invariant(JSBI.greaterThan(numerator1, product)) + const denominator = JSBI.subtract(numerator1, product) + return FullMath.mulDivRoundingUp(numerator1, sqrtPX96, denominator) + } + } + + private static getNextSqrtPriceFromAmount1RoundingDown( + sqrtPX96: JSBI, + liquidity: JSBI, + amount: JSBI, + add: boolean + ): JSBI { + if (add) { + const quotient = JSBI.lessThanOrEqual(amount, MaxUint160) + ? JSBI.divide(JSBI.leftShift(amount, JSBI.BigInt(96)), liquidity) + : JSBI.divide(JSBI.multiply(amount, Q96), liquidity) + + return JSBI.add(sqrtPX96, quotient) + } else { + const quotient = FullMath.mulDivRoundingUp(amount, Q96, liquidity) + + invariant(JSBI.greaterThan(sqrtPX96, quotient)) + return JSBI.subtract(sqrtPX96, quotient) + } + } +} diff --git a/src/utils/tickList.ts b/src/utils/tickList.ts new file mode 100644 index 0000000..d6988ac --- /dev/null +++ b/src/utils/tickList.ts @@ -0,0 +1,133 @@ +import JSBI from 'jsbi' +import invariant from 'tiny-invariant' +import { Tick } from '../entities/tick' +import { ZERO } from '../internalConstants' +import { isSorted } from './isSorted' + +function tickComparator(a: Tick, b: Tick) { + return a.index - b.index +} + +/** + * Utility methods for interacting with sorted lists of ticks + */ +export abstract class TickList { + /** + * Cannot be constructed + */ + private constructor() {} + + public static validateList(ticks: Tick[], tickSpacing: number) { + invariant(tickSpacing > 0, 'TICK_SPACING_NONZERO') + // ensure ticks are spaced appropriately + invariant( + ticks.every(({ index }) => index % tickSpacing === 0), + 'TICK_SPACING' + ) + + // ensure tick liquidity deltas sum to 0 + invariant( + JSBI.equal( + ticks.reduce((accumulator, { liquidityNet }) => JSBI.add(accumulator, liquidityNet), ZERO), + ZERO + ), + 'ZERO_NET' + ) + + invariant(isSorted(ticks, tickComparator), 'SORTED') + } + + public static isBelowSmallest(ticks: readonly Tick[], tick: number): boolean { + invariant(ticks.length > 0, 'LENGTH') + return tick < ticks[0].index + } + + public static isAtOrAboveLargest(ticks: readonly Tick[], tick: number): boolean { + invariant(ticks.length > 0, 'LENGTH') + return tick >= ticks[ticks.length - 1].index + } + + public static getTick(ticks: readonly Tick[], index: number): Tick { + const tick = ticks[this.binarySearch(ticks, index)] + invariant(tick.index === index, 'NOT_CONTAINED') + return tick + } + + /** + * Finds the largest tick in the list of ticks that is less than or equal to tick + * @param ticks list of ticks + * @param tick tick to find the largest tick that is less than or equal to tick + * @private + */ + private static binarySearch(ticks: readonly Tick[], tick: number): number { + invariant(!this.isBelowSmallest(ticks, tick), 'BELOW_SMALLEST') + + let l = 0 + let r = ticks.length - 1 + let i + while (true) { + i = Math.floor((l + r) / 2) + + if (ticks[i].index <= tick && (i === ticks.length - 1 || ticks[i + 1].index > tick)) { + return i + } + + if (ticks[i].index < tick) { + l = i + 1 + } else { + r = i - 1 + } + } + } + + public static nextInitializedTick(ticks: readonly Tick[], tick: number, lte: boolean): Tick { + if (lte) { + invariant(!TickList.isBelowSmallest(ticks, tick), 'BELOW_SMALLEST') + if (TickList.isAtOrAboveLargest(ticks, tick)) { + return ticks[ticks.length - 1] + } + const index = this.binarySearch(ticks, tick) + return ticks[index] + } else { + invariant(!this.isAtOrAboveLargest(ticks, tick), 'AT_OR_ABOVE_LARGEST') + if (this.isBelowSmallest(ticks, tick)) { + return ticks[0] + } + const index = this.binarySearch(ticks, tick) + return ticks[index + 1] + } + } + + public static nextInitializedTickWithinOneWord( + ticks: readonly Tick[], + tick: number, + lte: boolean, + tickSpacing: number + ): [number, boolean] { + const compressed = Math.floor(tick / tickSpacing) // matches rounding in the code + + if (lte) { + const wordPos = compressed >> 8 + const minimum = (wordPos << 8) * tickSpacing + + if (TickList.isBelowSmallest(ticks, tick)) { + return [minimum, false] + } + + const index = TickList.nextInitializedTick(ticks, tick, lte).index + const nextInitializedTick = Math.max(minimum, index) + return [nextInitializedTick, nextInitializedTick === index] + } else { + const wordPos = (compressed + 1) >> 8 + const maximum = (((wordPos + 1) << 8) - 1) * tickSpacing + + if (this.isAtOrAboveLargest(ticks, tick)) { + return [maximum, false] + } + + const index = this.nextInitializedTick(ticks, tick, lte).index + const nextInitializedTick = Math.min(maximum, index) + return [nextInitializedTick, nextInitializedTick === index] + } + } +} diff --git a/src/utils/tickMath.ts b/src/utils/tickMath.ts new file mode 100644 index 0000000..0706d7e --- /dev/null +++ b/src/utils/tickMath.ts @@ -0,0 +1,130 @@ +import { MaxUint256 } from '../constants' +import JSBI from 'jsbi' +import invariant from 'tiny-invariant' +import { ONE, ZERO } from '../internalConstants' +import { mostSignificantBit } from './mostSignificantBit' + +function mulShift(val: JSBI, mulBy: string): JSBI { + return JSBI.signedRightShift(JSBI.multiply(val, JSBI.BigInt(mulBy)), JSBI.BigInt(128)) +} + +const Q32 = JSBI.exponentiate(JSBI.BigInt(2), JSBI.BigInt(32)) + +export abstract class TickMath { + /** + * Cannot be constructed. + */ + private constructor() {} + + /** + * The minimum tick that can be used on any pool. + */ + public static MIN_TICK: number = -887272 + /** + * The maximum tick that can be used on any pool. + */ + public static MAX_TICK: number = -TickMath.MIN_TICK + + /** + * The sqrt ratio corresponding to the minimum tick that could be used on any pool. + */ + public static MIN_SQRT_RATIO: JSBI = JSBI.BigInt('4295128739') + /** + * The sqrt ratio corresponding to the maximum tick that could be used on any pool. + */ + public static MAX_SQRT_RATIO: JSBI = JSBI.BigInt('1461446703485210103287273052203988822378723970342') + + /** + * Returns the sqrt ratio as a Q64.96 for the given tick. The sqrt ratio is computed as sqrt(1.0001)^tick + * @param tick the tick for which to compute the sqrt ratio + */ + public static getSqrtRatioAtTick(tick: number): JSBI { + invariant(tick >= TickMath.MIN_TICK && tick <= TickMath.MAX_TICK && Number.isInteger(tick), 'TICK') + const absTick: number = tick < 0 ? tick * -1 : tick + + let ratio: JSBI = + (absTick & 0x1) != 0 + ? JSBI.BigInt('0xfffcb933bd6fad37aa2d162d1a594001') + : JSBI.BigInt('0x100000000000000000000000000000000') + if ((absTick & 0x2) != 0) ratio = mulShift(ratio, '0xfff97272373d413259a46990580e213a') + if ((absTick & 0x4) != 0) ratio = mulShift(ratio, '0xfff2e50f5f656932ef12357cf3c7fdcc') + if ((absTick & 0x8) != 0) ratio = mulShift(ratio, '0xffe5caca7e10e4e61c3624eaa0941cd0') + if ((absTick & 0x10) != 0) ratio = mulShift(ratio, '0xffcb9843d60f6159c9db58835c926644') + if ((absTick & 0x20) != 0) ratio = mulShift(ratio, '0xff973b41fa98c081472e6896dfb254c0') + if ((absTick & 0x40) != 0) ratio = mulShift(ratio, '0xff2ea16466c96a3843ec78b326b52861') + if ((absTick & 0x80) != 0) ratio = mulShift(ratio, '0xfe5dee046a99a2a811c461f1969c3053') + if ((absTick & 0x100) != 0) ratio = mulShift(ratio, '0xfcbe86c7900a88aedcffc83b479aa3a4') + if ((absTick & 0x200) != 0) ratio = mulShift(ratio, '0xf987a7253ac413176f2b074cf7815e54') + if ((absTick & 0x400) != 0) ratio = mulShift(ratio, '0xf3392b0822b70005940c7a398e4b70f3') + if ((absTick & 0x800) != 0) ratio = mulShift(ratio, '0xe7159475a2c29b7443b29c7fa6e889d9') + if ((absTick & 0x1000) != 0) ratio = mulShift(ratio, '0xd097f3bdfd2022b8845ad8f792aa5825') + if ((absTick & 0x2000) != 0) ratio = mulShift(ratio, '0xa9f746462d870fdf8a65dc1f90e061e5') + if ((absTick & 0x4000) != 0) ratio = mulShift(ratio, '0x70d869a156d2a1b890bb3df62baf32f7') + if ((absTick & 0x8000) != 0) ratio = mulShift(ratio, '0x31be135f97d08fd981231505542fcfa6') + if ((absTick & 0x10000) != 0) ratio = mulShift(ratio, '0x9aa508b5b7a84e1c677de54f3e99bc9') + if ((absTick & 0x20000) != 0) ratio = mulShift(ratio, '0x5d6af8dedb81196699c329225ee604') + if ((absTick & 0x40000) != 0) ratio = mulShift(ratio, '0x2216e584f5fa1ea926041bedfe98') + if ((absTick & 0x80000) != 0) ratio = mulShift(ratio, '0x48a170391f7dc42444e8fa2') + + if (tick > 0) ratio = JSBI.divide(MaxUint256, ratio) + + // back to Q96 + return JSBI.greaterThan(JSBI.remainder(ratio, Q32), ZERO) + ? JSBI.add(JSBI.divide(ratio, Q32), ONE) + : JSBI.divide(ratio, Q32) + } + + /** + * Returns the tick corresponding to a given sqrt ratio, s.t. #getSqrtRatioAtTick(tick) <= sqrtRatioX96 + * and #getSqrtRatioAtTick(tick + 1) > sqrtRatioX96 + * @param sqrtRatioX96 the sqrt ratio as a Q64.96 for which to compute the tick + */ + public static getTickAtSqrtRatio(sqrtRatioX96: JSBI): number { + invariant( + JSBI.greaterThanOrEqual(sqrtRatioX96, TickMath.MIN_SQRT_RATIO) && + JSBI.lessThan(sqrtRatioX96, TickMath.MAX_SQRT_RATIO), + 'SQRT_RATIO' + ) + + const sqrtRatioX128 = JSBI.leftShift(sqrtRatioX96, JSBI.BigInt(32)) + + const msb = mostSignificantBit(sqrtRatioX128) + + let r: JSBI + if (JSBI.greaterThanOrEqual(JSBI.BigInt(msb), JSBI.BigInt(128))) { + r = JSBI.signedRightShift(sqrtRatioX128, JSBI.BigInt(msb - 127)) + } else { + r = JSBI.leftShift(sqrtRatioX128, JSBI.BigInt(127 - msb)) + } + + let log_2: JSBI = JSBI.leftShift(JSBI.subtract(JSBI.BigInt(msb), JSBI.BigInt(128)), JSBI.BigInt(64)) + + for (let i = 0; i < 14; i++) { + r = JSBI.signedRightShift(JSBI.multiply(r, r), JSBI.BigInt(127)) + const f = JSBI.signedRightShift(r, JSBI.BigInt(128)) + log_2 = JSBI.bitwiseOr(log_2, JSBI.leftShift(f, JSBI.BigInt(63 - i))) + r = JSBI.signedRightShift(r, f) + } + + const log_sqrt10001 = JSBI.multiply(log_2, JSBI.BigInt('255738958999603826347141')) + + const tickLow = JSBI.toNumber( + JSBI.signedRightShift( + JSBI.subtract(log_sqrt10001, JSBI.BigInt('3402992956809132418596140100660247210')), + JSBI.BigInt(128) + ) + ) + const tickHigh = JSBI.toNumber( + JSBI.signedRightShift( + JSBI.add(log_sqrt10001, JSBI.BigInt('291339464771989622907027621153398088495')), + JSBI.BigInt(128) + ) + ) + + return tickLow === tickHigh + ? tickLow + : JSBI.lessThanOrEqual(TickMath.getSqrtRatioAtTick(tickHigh), sqrtRatioX96) + ? tickHigh + : tickLow + } +} diff --git a/test/pool.test.ts b/test/pool.test.ts new file mode 100644 index 0000000..4b19016 --- /dev/null +++ b/test/pool.test.ts @@ -0,0 +1,28 @@ +import { getCreate2Address } from "@ethersproject/address" +import { keccak256 } from "@ethersproject/solidity" +import { V2_POOL_INIT_CODE_HASH } from "../src/constants" +import { defaultAbiCoder } from '@ethersproject/abi' + +// TODO: replace the provider in these tests +describe('data', () => { + it('Token', async () => { + const salt0=keccak256( + ['bytes'], + [defaultAbiCoder.encode(['address', 'address'], ["0xC168E40227E4ebD8C1caE80F7a55a4F0e6D66C97".toLowerCase(), "0x16ECCfDbb4eE1A85A33f3A9B21175Cd7Ae753dB4".toLowerCase()])] + ) + console.log(getCreate2Address( + "0x68E776B2369696e589254cfc6d2ce4B29385952D", + salt0, + V2_POOL_INIT_CODE_HASH[137].toLowerCase() + )) + const salt1=keccak256( + ['bytes'], + [defaultAbiCoder.encode(['address', 'address'], ["0x16ECCfDbb4eE1A85A33f3A9B21175Cd7Ae753dB4".toLowerCase(), "0xC168E40227E4ebD8C1caE80F7a55a4F0e6D66C97".toLowerCase()])] + ) + console.log(getCreate2Address( + "0x68E776B2369696e589254cfc6d2ce4B29385952D", + salt1, + V2_POOL_INIT_CODE_HASH[137].toLowerCase() + )) + }) +}) \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index e6e713d..5bffa30 100644 --- a/yarn.lock +++ b/yarn.lock @@ -904,6 +904,21 @@ exec-sh "^0.3.2" minimist "^1.2.0" +"@ethersproject/abi@^5.0.12": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.7.0.tgz#b3f3e045bbbeed1af3947335c247ad625a44e449" + integrity sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA== + dependencies: + "@ethersproject/address" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/hash" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + "@ethersproject/abi@^5.4.0": version "5.4.1" resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.4.1.tgz#6ac28fafc9ef6f5a7a37e30356a2eb31fa05d39b" @@ -932,6 +947,19 @@ "@ethersproject/transactions" "^5.4.0" "@ethersproject/web" "^5.4.0" +"@ethersproject/abstract-provider@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz#b0a8550f88b6bf9d51f90e4795d48294630cb9ef" + integrity sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw== + dependencies: + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/networks" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + "@ethersproject/web" "^5.7.0" + "@ethersproject/abstract-signer@^5.4.0": version "5.4.1" resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.4.1.tgz#e4e9abcf4dd4f1ba0db7dff9746a5f78f355ea81" @@ -943,6 +971,17 @@ "@ethersproject/logger" "^5.4.0" "@ethersproject/properties" "^5.4.0" +"@ethersproject/abstract-signer@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz#13f4f32117868452191a4649723cb086d2b596b2" + integrity sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ== + dependencies: + "@ethersproject/abstract-provider" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/address@^5.0.2", "@ethersproject/address@^5.4.0": version "5.4.0" resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.4.0.tgz#ba2d00a0f8c4c0854933b963b9a3a9f6eb4a37a3" @@ -954,6 +993,17 @@ "@ethersproject/logger" "^5.4.0" "@ethersproject/rlp" "^5.4.0" +"@ethersproject/address@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.7.0.tgz#19b56c4d74a3b0a46bfdbb6cfcc0a153fc697f37" + integrity sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA== + dependencies: + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/rlp" "^5.7.0" + "@ethersproject/base64@^5.4.0": version "5.4.0" resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.4.0.tgz#7252bf65295954c9048c7ca5f43e5c86441b2a9a" @@ -961,6 +1011,13 @@ dependencies: "@ethersproject/bytes" "^5.4.0" +"@ethersproject/base64@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.7.0.tgz#ac4ee92aa36c1628173e221d0d01f53692059e1c" + integrity sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/basex@^5.4.0": version "5.4.0" resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.4.0.tgz#0a2da0f4e76c504a94f2b21d3161ed9438c7f8a6" @@ -978,6 +1035,15 @@ "@ethersproject/logger" "^5.4.0" bn.js "^4.11.9" +"@ethersproject/bignumber@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.7.0.tgz#e2f03837f268ba655ffba03a57853e18a18dc9c2" + integrity sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + bn.js "^5.2.1" + "@ethersproject/bytes@^5.4.0": version "5.4.0" resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.4.0.tgz#56fa32ce3bf67153756dbaefda921d1d4774404e" @@ -985,6 +1051,13 @@ dependencies: "@ethersproject/logger" "^5.4.0" +"@ethersproject/bytes@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.7.0.tgz#a00f6ea8d7e7534d6d87f47188af1148d71f155d" + integrity sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A== + dependencies: + "@ethersproject/logger" "^5.7.0" + "@ethersproject/constants@^5.4.0": version "5.4.0" resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.4.0.tgz#ee0bdcb30bf1b532d2353c977bf2ef1ee117958a" @@ -992,6 +1065,13 @@ dependencies: "@ethersproject/bignumber" "^5.4.0" +"@ethersproject/constants@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.7.0.tgz#df80a9705a7e08984161f09014ea012d1c75295e" + integrity sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA== + dependencies: + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/contracts@^5.0.2": version "5.4.1" resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.4.1.tgz#3eb4f35b7fe60a962a75804ada2746494df3e470" @@ -1022,6 +1102,21 @@ "@ethersproject/properties" "^5.4.0" "@ethersproject/strings" "^5.4.0" +"@ethersproject/hash@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.7.0.tgz#eb7aca84a588508369562e16e514b539ba5240a7" + integrity sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g== + dependencies: + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/address" "^5.7.0" + "@ethersproject/base64" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + "@ethersproject/keccak256@^5.4.0": version "5.4.0" resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.4.0.tgz#7143b8eea4976080241d2bd92e3b1f1bf7025318" @@ -1030,11 +1125,24 @@ "@ethersproject/bytes" "^5.4.0" js-sha3 "0.5.7" +"@ethersproject/keccak256@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.7.0.tgz#3186350c6e1cd6aba7940384ec7d6d9db01f335a" + integrity sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg== + dependencies: + "@ethersproject/bytes" "^5.7.0" + js-sha3 "0.8.0" + "@ethersproject/logger@^5.4.0": version "5.4.1" resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.4.1.tgz#503bd33683538b923c578c07d1c2c0dd18672054" integrity sha512-DZ+bRinnYLPw1yAC64oRl0QyVZj43QeHIhVKfD/+YwSz4wsv1pfwb5SOFjz+r710YEWzU6LrhuSjpSO+6PeE4A== +"@ethersproject/logger@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.7.0.tgz#6ce9ae168e74fecf287be17062b590852c311892" + integrity sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig== + "@ethersproject/networks@^5.0.2", "@ethersproject/networks@^5.4.0": version "5.4.2" resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.4.2.tgz#2247d977626e97e2c3b8ee73cd2457babde0ce35" @@ -1042,6 +1150,13 @@ dependencies: "@ethersproject/logger" "^5.4.0" +"@ethersproject/networks@^5.7.0": + version "5.7.1" + resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.7.1.tgz#118e1a981d757d45ccea6bb58d9fd3d9db14ead6" + integrity sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ== + dependencies: + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties@^5.4.0": version "5.4.1" resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.4.1.tgz#9f051f976ce790142c6261ccb7b826eaae1f2f36" @@ -1049,6 +1164,13 @@ dependencies: "@ethersproject/logger" "^5.4.0" +"@ethersproject/properties@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.7.0.tgz#a6e12cb0439b878aaf470f1902a176033067ed30" + integrity sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw== + dependencies: + "@ethersproject/logger" "^5.7.0" + "@ethersproject/providers@^5.0.5": version "5.4.5" resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.4.5.tgz#eb2ea2a743a8115f79604a8157233a3a2c832928" @@ -1090,6 +1212,14 @@ "@ethersproject/bytes" "^5.4.0" "@ethersproject/logger" "^5.4.0" +"@ethersproject/rlp@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.7.0.tgz#de39e4d5918b9d74d46de93af80b7685a9c21304" + integrity sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/sha2@^5.4.0": version "5.4.0" resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.4.0.tgz#c9a8db1037014cbc4e9482bd662f86c090440371" @@ -1111,6 +1241,18 @@ elliptic "6.5.4" hash.js "1.1.7" +"@ethersproject/signing-key@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.7.0.tgz#06b2df39411b00bc57c7c09b01d1e41cf1b16ab3" + integrity sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + bn.js "^5.2.1" + elliptic "6.5.4" + hash.js "1.1.7" + "@ethersproject/solidity@^5.0.2": version "5.4.0" resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.4.0.tgz#1305e058ea02dc4891df18b33232b11a14ece9ec" @@ -1131,6 +1273,15 @@ "@ethersproject/constants" "^5.4.0" "@ethersproject/logger" "^5.4.0" +"@ethersproject/strings@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.7.0.tgz#54c9d2a7c57ae8f1205c88a9d3a56471e14d5ed2" + integrity sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/transactions@^5.4.0": version "5.4.0" resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.4.0.tgz#a159d035179334bd92f340ce0f77e83e9e1522e0" @@ -1146,6 +1297,21 @@ "@ethersproject/rlp" "^5.4.0" "@ethersproject/signing-key" "^5.4.0" +"@ethersproject/transactions@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.7.0.tgz#91318fc24063e057885a6af13fdb703e1f993d3b" + integrity sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ== + dependencies: + "@ethersproject/address" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/rlp" "^5.7.0" + "@ethersproject/signing-key" "^5.7.0" + "@ethersproject/web@^5.4.0": version "5.4.0" resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.4.0.tgz#49fac173b96992334ed36a175538ba07a7413d1f" @@ -1157,6 +1323,17 @@ "@ethersproject/properties" "^5.4.0" "@ethersproject/strings" "^5.4.0" +"@ethersproject/web@^5.7.0": + version "5.7.1" + resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.7.1.tgz#de1f285b373149bee5928f4eb7bcb87ee5fbb4ae" + integrity sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w== + dependencies: + "@ethersproject/base64" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + "@jest/console@^24.7.1", "@jest/console@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.9.0.tgz#79b1bc06fb74a8cfb01cbdedf945584b1b9707f0" @@ -2034,6 +2211,11 @@ bn.js@^4.11.9: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== +bn.js@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" + integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -4251,6 +4433,11 @@ js-sha3@0.5.7: resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7" integrity sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc= +js-sha3@0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" + integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" From 0608b6aa5f61bb8e0851b64ba6e71452cfb29b6c Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Fri, 9 Dec 2022 16:49:05 +0400 Subject: [PATCH 063/103] v0.0.65 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7d3e80e..46e2e2a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.64", + "version": "0.0.65", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 848007c4419d9177ee6acb0c798b82e77c319951 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Fri, 9 Dec 2022 17:32:51 +0400 Subject: [PATCH 064/103] v0.0.66 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 46e2e2a..d608dc7 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.65", + "version": "0.0.66", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 8ca506f56f42a5f4687dfd9b73bde15ac8399445 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Fri, 9 Dec 2022 17:47:54 +0400 Subject: [PATCH 065/103] v0.0.67 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d608dc7..4e00384 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.66", + "version": "0.0.67", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 2ec8cb9264c0af10c309a5e2c3eeddeac64c8050 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Fri, 9 Dec 2022 17:56:55 +0400 Subject: [PATCH 066/103] v0.0.68 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4e00384..15b3d56 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.67", + "version": "0.0.68", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From d2686169d78c3ff2e8dc6af4c1bc6e316a658b48 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Sat, 10 Dec 2022 15:58:04 +0400 Subject: [PATCH 067/103] v0.0.69 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 15b3d56..59aefe9 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.68", + "version": "0.0.69", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 22d3b26cb73c985a07a7805f415deb00e82a96c0 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Tue, 13 Dec 2022 01:40:52 +0400 Subject: [PATCH 068/103] v0.0.70 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 59aefe9..53eae1b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.69", + "version": "0.0.70", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 8219fd58251bb23b2d932b0443a6bf76d1a7bee6 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Tue, 13 Dec 2022 02:40:15 +0400 Subject: [PATCH 069/103] v0.0.71 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 53eae1b..28148ee 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.70", + "version": "0.0.71", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 2a30c64b1bbec9e6fa0d3eea935e3a6baad88527 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Tue, 13 Dec 2022 14:50:36 +0400 Subject: [PATCH 070/103] v0.0.72 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 28148ee..77cdd75 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.71", + "version": "0.0.72", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From f391a83dce2f79777ce38633a74163d25a7a591a Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Tue, 13 Dec 2022 14:54:52 +0400 Subject: [PATCH 071/103] v0.0.73 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 77cdd75..5ce9a0f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.72", + "version": "0.0.73", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From b174b15cfcd9a3f7dce4a2f94cb7633e9efb2a18 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Fri, 16 Dec 2022 00:38:28 +0400 Subject: [PATCH 072/103] v0.0.74 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5ce9a0f..63b478e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.73", + "version": "0.0.74", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 48cba9fd2944da06012b33608f32dc722e5b04c1 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Sun, 18 Dec 2022 16:00:19 +0400 Subject: [PATCH 073/103] v0.0.75 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 63b478e..673ef49 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.74", + "version": "0.0.75", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From cd423fac968e491f4b4e0f515cffdc39e2739ca1 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Sun, 18 Dec 2022 16:32:53 +0400 Subject: [PATCH 074/103] v0.0.76 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 673ef49..cf84d77 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.75", + "version": "0.0.76", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From e330646c29e873dc278173fb6b403e5b4a7d6516 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Sun, 18 Dec 2022 17:34:04 +0400 Subject: [PATCH 075/103] v0.0.77 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cf84d77..648e085 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.76", + "version": "0.0.77", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From f85b47730a856388c0fb54ea54c382478d341f30 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Sun, 18 Dec 2022 17:39:27 +0400 Subject: [PATCH 076/103] v0.0.78 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 648e085..cd217e0 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.77", + "version": "0.0.78", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 59f5fcb545d040914a6479a483b4baa97b6c8bf3 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Tue, 20 Dec 2022 14:27:18 +0400 Subject: [PATCH 077/103] v0.0.79 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cd217e0..a99e3e4 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.78", + "version": "0.0.79", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From ea692531262bffbc99aad72ab298dbc4d6aaefb1 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Tue, 20 Dec 2022 14:59:42 +0400 Subject: [PATCH 078/103] v0.0.80 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a99e3e4..31968f5 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.79", + "version": "0.0.80", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From ae2e02f56ae5c3a70b3ec4e9db092c7f066ce7be Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Thu, 22 Dec 2022 15:42:24 +0400 Subject: [PATCH 079/103] fix: decimal order bug --- src/abis/LimitOrderManager.json | 27 ++++++++++++++++----------- src/concentratedPoolManager.ts | 4 ++-- src/constants.ts | 8 ++++---- src/entities/TradeWrappers.ts | 12 ++++++------ src/entities/mixedRoute/trade.ts | 10 +++++----- src/entities/order.ts | 8 ++++---- src/entities/pool.ts | 4 ++-- src/entities/positions.ts | 2 +- src/entities/token.ts | 2 +- src/entities/v2trade.ts | 12 ++++++------ src/limitOrderManager.ts | 5 ----- src/utils/nearestUsableTick.ts | 8 +++++++- 12 files changed, 54 insertions(+), 48 deletions(-) diff --git a/src/abis/LimitOrderManager.json b/src/abis/LimitOrderManager.json index 2b4fb89..b1a39c2 100644 --- a/src/abis/LimitOrderManager.json +++ b/src/abis/LimitOrderManager.json @@ -120,11 +120,6 @@ "name": "tokenId", "type": "uint256" }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, { "internalType": "bool", "name": "unwrapVault", @@ -164,9 +159,9 @@ "type": "bool" }, { - "internalType": "uint256", + "internalType": "uint128", "name": "amountIn", - "type": "uint256" + "type": "uint128" }, { "internalType": "bool", @@ -308,14 +303,14 @@ "type": "bool" }, { - "internalType": "uint256", + "internalType": "uint128", "name": "amountIn", - "type": "uint256" + "type": "uint128" }, { - "internalType": "uint256", + "internalType": "uint128", "name": "amountOut", - "type": "uint256" + "type": "uint128" }, { "internalType": "uint256", @@ -326,6 +321,16 @@ "internalType": "enum ILimitOrderStruct.LimitOrderStatus", "name": "status", "type": "uint8" + }, + { + "internalType": "uint256", + "name": "claimableGrowth0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimableGrowth1", + "type": "uint256" } ], "stateMutability": "view", diff --git a/src/concentratedPoolManager.ts b/src/concentratedPoolManager.ts index 549dfaf..cc38cac 100644 --- a/src/concentratedPoolManager.ts +++ b/src/concentratedPoolManager.ts @@ -201,7 +201,7 @@ export abstract class ConcentratedPoolManager { toHex(amount0Desired), toHex(amount1Desired), true, - position.liquidity.toString(), + "0", "0" // token0: position.pool.token0.address, // token1: position.pool.token1.address, @@ -228,7 +228,7 @@ export abstract class ConcentratedPoolManager { toHex(amount0Desired), toHex(amount1Desired), true, - position.liquidity.toString(), + "0", options.tokenId // token0: position.pool.token0.address, // token1: position.pool.token1.address, diff --git a/src/constants.ts b/src/constants.ts index 9a157e9..4ba81d0 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -111,7 +111,7 @@ export const V2_FACTORY_ADDRESS: { [chainId in ChainId]: string } = { [ChainId.RINKEBY]: '', [ChainId.GΓ–RLI]: '', [ChainId.KOVAN]: '', - [ChainId.MATIC]: '0x76e8Ce7D482F29Efd66E4aC1994A13B2Aa398812', + [ChainId.MATIC]: '0x7ED245AADAcD826dfF9478de019e76FfF7c202fC', [ChainId.OKEX]: '', [ChainId.ARBITRUM]: '', [ChainId.XDAI]: '', @@ -128,7 +128,7 @@ export const V2_DEPLOYER_ADDRESS: { [chainId in ChainId]: string } = { [ChainId.RINKEBY]: '', [ChainId.GΓ–RLI]: '', [ChainId.KOVAN]: '', - [ChainId.MATIC]: '0xd3fD03f36F1e490290DEd8f93A098c7C9921AFC7', + [ChainId.MATIC]: '0x20F200c65bDD173Df64a528e28F77F06ebDE61D9', [ChainId.OKEX]: '', [ChainId.ARBITRUM]: '', [ChainId.XDAI]: '', @@ -143,7 +143,7 @@ export const V2_MASTER_DEPLOYER_ADDRESS: { [chainId in ChainId]: string } = { [ChainId.RINKEBY]: '', [ChainId.GΓ–RLI]: '', [ChainId.KOVAN]: '', - [ChainId.MATIC]: '0x8b4e43a9922ca57b06Ab3A1Ee222163Cdd504cc1', + [ChainId.MATIC]: '0xaba5e148b0CB58e545d1E4D645EBBD6c250288b4', [ChainId.OKEX]: '', [ChainId.ARBITRUM]: '', [ChainId.XDAI]: '', @@ -161,7 +161,7 @@ export const V2_POOL_INIT_CODE_HASH: { [chainId in ChainId]: string } = { [ChainId.RINKEBY]: '', [ChainId.GΓ–RLI]: '', [ChainId.KOVAN]: '', - [ChainId.MATIC]: '0xb1467d61353f1381ce595794734cf69d5ab5cb73d48acc00e8d720d62280c232', + [ChainId.MATIC]: '0x927b92e6ba1767fdf9098da147c98f2e3f30c9507dd81ece2a3a4951c0614b43', [ChainId.OKEX]: '', [ChainId.ARBITRUM]: '', [ChainId.XDAI]: '', diff --git a/src/entities/TradeWrappers.ts b/src/entities/TradeWrappers.ts index 9477a76..61f5569 100644 --- a/src/entities/TradeWrappers.ts +++ b/src/entities/TradeWrappers.ts @@ -172,8 +172,8 @@ export class MixedTrade { (this._executionPrice = new Price( this.inputAmount.currency, this.outputAmount.currency, - this.inputAmount.quotient, - this.outputAmount.quotient + this.inputAmount.raw, + this.outputAmount.raw )) ) } @@ -216,7 +216,7 @@ export class MixedTrade { const slippageAdjustedAmountOut = new Fraction(ONE) .add(slippageTolerance) .invert() - .multiply(amountOut.quotient).quotient + .multiply(amountOut.raw).quotient return new CurrencyAmount(amountOut.currency, slippageAdjustedAmountOut) } } @@ -231,7 +231,7 @@ export class MixedTrade { if (this.tradeType === TradeType.EXACT_INPUT) { return amountIn } else { - const slippageAdjustedAmountIn = new Fraction(ONE).add(slippageTolerance).multiply(amountIn.quotient).quotient + const slippageAdjustedAmountIn = new Fraction(ONE).add(slippageTolerance).multiply(amountIn.raw).quotient return new CurrencyAmount(amountIn.currency, slippageAdjustedAmountIn) } } @@ -245,8 +245,8 @@ export class MixedTrade { return new Price( this.inputAmount.currency, this.outputAmount.currency, - this.maximumAmountIn(slippageTolerance).quotient, - this.minimumAmountOut(slippageTolerance).quotient + this.maximumAmountIn(slippageTolerance).raw, + this.minimumAmountOut(slippageTolerance).raw ) } diff --git a/src/entities/mixedRoute/trade.ts b/src/entities/mixedRoute/trade.ts index 0d84419..4124a06 100644 --- a/src/entities/mixedRoute/trade.ts +++ b/src/entities/mixedRoute/trade.ts @@ -146,8 +146,8 @@ export class MixedRouteTrade { (this._executionPrice = new Price( this.inputAmount.currency, this.outputAmount.currency, - this.inputAmount.quotient, - this.outputAmount.quotient + this.inputAmount.raw, + this.outputAmount.raw )) ) } @@ -381,7 +381,7 @@ export class MixedRouteTrade { const slippageAdjustedAmountOut = new Fraction(ONE) .add(slippageTolerance) .invert() - .multiply(amountOut.quotient).quotient + .multiply(amountOut.raw).quotient return new CurrencyAmount(amountOut.currency, slippageAdjustedAmountOut) } @@ -405,8 +405,8 @@ export class MixedRouteTrade { return new Price( this.inputAmount.currency, this.outputAmount.currency, - this.maximumAmountIn(slippageTolerance).quotient, - this.minimumAmountOut(slippageTolerance).quotient + this.maximumAmountIn(slippageTolerance).raw, + this.minimumAmountOut(slippageTolerance).raw ) } diff --git a/src/entities/order.ts b/src/entities/order.ts index dd3a6bb..78cb3ae 100644 --- a/src/entities/order.ts +++ b/src/entities/order.ts @@ -77,12 +77,12 @@ enum ORDER_TYPE { if (this._tokenAmountIn === null) { if (this.zeroForOne) { this._tokenAmountIn = new TokenAmount( - this.pool.token1, + this.pool.token0, this.amountIn.toString() ) } else { this._tokenAmountIn = new TokenAmount( - this.pool.token0, + this.pool.token1, this.amountIn.toString() ) } @@ -99,7 +99,7 @@ enum ORDER_TYPE { let amountOut = FullMath.mulDivRoundingUp(this.amountIn, this.sqrtpriceX96, Q96); amountOut = FullMath.mulDivRoundingUp(amountOut, this.sqrtpriceX96, Q96); this._expectedTokenAmountOut = new TokenAmount( - this.pool.token0, + this.pool.token1, amountOut.toString() ) } else { @@ -108,7 +108,7 @@ enum ORDER_TYPE { amountOut = FullMath.mulDivRoundingUp(amountOut, Q96, this.sqrtpriceX96); this._expectedTokenAmountOut = new TokenAmount( - this.pool.token1, + this.pool.token0, amountOut.toString() ) } diff --git a/src/entities/pool.ts b/src/entities/pool.ts index 7df04c0..e12732b 100644 --- a/src/entities/pool.ts +++ b/src/entities/pool.ts @@ -169,7 +169,7 @@ export class Pool { const { amountCalculated: outputAmount, sqrtRatioX96, liquidity, tickCurrent } = await this.swap( zeroForOne, - inputAmount.quotient, + inputAmount.raw, sqrtPriceLimitX96 ) const outputToken = zeroForOne ? this.token1 : this.token0 @@ -199,7 +199,7 @@ export class Pool { const { amountCalculated: inputAmount, sqrtRatioX96, liquidity, tickCurrent } = await this.swap( zeroForOne, - JSBI.multiply(outputAmount.quotient, NEGATIVE_ONE), + JSBI.multiply(outputAmount.raw, NEGATIVE_ONE), sqrtPriceLimitX96 ) const inputToken = zeroForOne ? this.token0 : this.token1 diff --git a/src/entities/positions.ts b/src/entities/positions.ts index 248dea4..7a1ebfa 100644 --- a/src/entities/positions.ts +++ b/src/entities/positions.ts @@ -251,7 +251,7 @@ export class Position { tickUpper: this.tickUpper }).amount1 - return { amount0: amount0.quotient, amount1: amount1.quotient } + return { amount0: amount0.raw, amount1: amount1.raw } } /** diff --git a/src/entities/token.ts b/src/entities/token.ts index 2398da9..592d000 100644 --- a/src/entities/token.ts +++ b/src/entities/token.ts @@ -82,7 +82,7 @@ export const WETH = { [ChainId.KOVAN]: new Token(ChainId.KOVAN, '0xd0A1E359811322d97991E03f863a0C30C2cF029C', 18, 'WETH', 'Wrapped Ether'), [ChainId.MATIC]: new Token( ChainId.MATIC, - '0x4c28f48448720e9000907bc2611f73022fdce1fa', + '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270', 18, 'WMATIC', 'Wrapped Matic' diff --git a/src/entities/v2trade.ts b/src/entities/v2trade.ts index 42101a9..8157cba 100644 --- a/src/entities/v2trade.ts +++ b/src/entities/v2trade.ts @@ -133,8 +133,8 @@ export class V2Trade { (this._executionPrice = new Price( this.inputAmount.currency, this.outputAmount.currency, - this.inputAmount.quotient, - this.outputAmount.quotient + this.inputAmount.raw, + this.outputAmount.raw )) ) } @@ -416,7 +416,7 @@ export class V2Trade { const slippageAdjustedAmountOut = new Fraction(ONE) .add(slippageTolerance) .invert() - .multiply(amountOut.quotient).quotient + .multiply(amountOut.raw).quotient return new CurrencyAmount(amountOut.currency, slippageAdjustedAmountOut) } } @@ -431,7 +431,7 @@ export class V2Trade { if (this.tradeType === TradeType.EXACT_INPUT) { return amountIn } else { - const slippageAdjustedAmountIn = new Fraction(ONE).add(slippageTolerance).multiply(amountIn.quotient).quotient + const slippageAdjustedAmountIn = new Fraction(ONE).add(slippageTolerance).multiply(amountIn.raw).quotient return new CurrencyAmount(amountIn.currency, slippageAdjustedAmountIn) } } @@ -445,8 +445,8 @@ export class V2Trade { return new Price( this.inputAmount.currency, this.outputAmount.currency, - this.maximumAmountIn(slippageTolerance).quotient, - this.minimumAmountOut(slippageTolerance).quotient + this.maximumAmountIn(slippageTolerance).raw, + this.minimumAmountOut(slippageTolerance).raw ) } diff --git a/src/limitOrderManager.ts b/src/limitOrderManager.ts index b73f35a..e6e7a45 100644 --- a/src/limitOrderManager.ts +++ b/src/limitOrderManager.ts @@ -48,9 +48,6 @@ export interface ClaimOrderOptions{ */ deadline: BigintIsh - - amountToClaim: BigintIsh - unwrapVault: Boolean } @@ -119,14 +116,12 @@ export abstract class LimitOrderManager { let calldata const tokenId = toHex(options.tokenId) - const amountToClaim=toHex(options.amountToClaim) const unwrapVault=options.unwrapVault // const involvesETH = // false calldata=this.INTERFACE.encodeFunctionData('claimLimitOrder',[ tokenId, - amountToClaim, unwrapVault ]) diff --git a/src/utils/nearestUsableTick.ts b/src/utils/nearestUsableTick.ts index 6dc630a..6c4642f 100644 --- a/src/utils/nearestUsableTick.ts +++ b/src/utils/nearestUsableTick.ts @@ -13,7 +13,7 @@ export function nearestUsableTick(tick: number, tickSpacing: number,even?:boolea const rounded = Math.round(tick / tickSpacing) * tickSpacing const evenMultiple=Math.round(Math.round(tick / tickSpacing)/2)*2 const roundedEven = (evenMultiple) * tickSpacing - const roundedOdd = (evenMultiple+1) * tickSpacing + const roundedOdd = (evenMultiple-1) * tickSpacing if(even===undefined) if (rounded < TickMath.MIN_TICK) return rounded + tickSpacing else if (rounded > TickMath.MAX_TICK) return rounded - tickSpacing @@ -27,3 +27,9 @@ export function nearestUsableTick(tick: number, tickSpacing: number,even?:boolea else if (roundedOdd > TickMath.MAX_TICK) return roundedOdd - (tickSpacing*2) else return roundedOdd } +// if(even===undefined) +// return rounded +// if(even) +// return roundedEven +// else +// return roundedOdd From dc2c3ce5378069cf9f1e015fe110d9ff11c36dff Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Thu, 22 Dec 2022 16:13:13 +0400 Subject: [PATCH 080/103] v0.0.81 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 31968f5..9be2ebb 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.80", + "version": "0.0.81", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 0acd7d7b94d88d7ce459edc1e02b1d6a754f2240 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Fri, 23 Dec 2022 18:30:43 +0400 Subject: [PATCH 081/103] v0.0.82 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9be2ebb..cb44fba 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.81", + "version": "0.0.82", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From f3900f6526fa06fe41ed1cc776389e908ff3208e Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Fri, 23 Dec 2022 19:00:14 +0400 Subject: [PATCH 082/103] v0.0.83 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cb44fba..1d63ab9 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.82", + "version": "0.0.83", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From af1006b7032a9853279ad0b3b68b09f66f0efb12 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Sat, 18 Mar 2023 10:14:46 +0530 Subject: [PATCH 083/103] feat: limit order claiming changes --- src/entities/fractions/price.ts | 6 +- src/entities/order.ts | 126 ++++++++++++++++++++++++-------- src/limitOrderManager.ts | 9 ++- 3 files changed, 104 insertions(+), 37 deletions(-) diff --git a/src/entities/fractions/price.ts b/src/entities/fractions/price.ts index 58b3288..b7b00f7 100644 --- a/src/entities/fractions/price.ts +++ b/src/entities/fractions/price.ts @@ -1,7 +1,5 @@ import { Token } from '../token' import { TokenAmount } from './tokenAmount' -import { currencyEquals } from '../token' -import invariant from 'tiny-invariant' import JSBI from 'jsbi' import { BigintIsh, Rounding, TEN } from '../../constants' @@ -52,14 +50,14 @@ export class Price extends Fraction { } public multiply(other: Price): Price { - invariant(currencyEquals(this.quoteCurrency, other.baseCurrency), 'TOKEN') + // invariant(currencyEquals(this.quoteCurrency, other.baseCurrency), 'TOKEN')// to be fixed const fraction = super.multiply(other) return new Price(this.baseCurrency, other.quoteCurrency, fraction.denominator, fraction.numerator) } // performs floor division on overflow public quote(currencyAmount: CurrencyAmount): CurrencyAmount { - invariant(currencyEquals(currencyAmount.currency, this.baseCurrency), 'TOKEN') + // invariant(currencyEquals(currencyAmount.currency, this.baseCurrency), 'TOKEN')// to be fixed if (this.quoteCurrency instanceof Token) { return new TokenAmount(this.quoteCurrency, super.multiply(currencyAmount.raw).quotient) } diff --git a/src/entities/order.ts b/src/entities/order.ts index 78cb3ae..bc236b3 100644 --- a/src/entities/order.ts +++ b/src/entities/order.ts @@ -1,14 +1,15 @@ import JSBI from "jsbi" import { Pool } from "./pool" import invariant from "tiny-invariant" -import { BigintIsh, Price, TokenAmount,FullMath, TickMath, tickToPrice } from '../index' +import { BigintIsh, Price, TokenAmount,FullMath, TickMath,TradeType, tickToPrice } from '../index' import { Q96 } from "../internalConstants" interface OrderConstructorArgs { pool: Pool tick: number - amountIn: BigintIsh + amount: BigintIsh zeroForOne: boolean + tradeType: TradeType } enum ORDER_TYPE { @@ -21,12 +22,16 @@ enum ORDER_TYPE { export class Order { public readonly pool: Pool public readonly tick: number - public readonly amountIn: JSBI + public readonly amount: JSBI public readonly zeroForOne: boolean + /** + * The type of the trade, either exact in or exact out. + */ + public readonly tradeType: TradeType // cached resuts for the getters private _tokenAmountIn: TokenAmount | null = null - private _expectedTokenAmountOut: TokenAmount | null = null + private _tokenAmountOut: TokenAmount | null = null /** * Constructs a position for a given pool with the given liquidity @@ -35,7 +40,7 @@ enum ORDER_TYPE { * @param amountIn The amount of liquidity that is in the position * @param tickUpper The upper tick of the position */ - public constructor({ pool, tick, amountIn, zeroForOne }:OrderConstructorArgs){ + public constructor({ pool, tick, amount, zeroForOne,tradeType }:OrderConstructorArgs){ invariant(tick >= TickMath.MIN_TICK && tick % pool.tickSpacing === 0, 'INVALID_TICK') invariant(tick <= TickMath.MAX_TICK && tick % pool.tickSpacing === 0, 'INVALID_TICK') // const sqrtpriceX96=TickMath.getSqrtRatioAtTick(tick) @@ -49,7 +54,8 @@ enum ORDER_TYPE { this.pool = pool this.tick = tick this.zeroForOne = zeroForOne - this.amountIn = JSBI.BigInt(amountIn) + this.amount = JSBI.BigInt(amount) + this.tradeType = tradeType } /** @@ -70,51 +76,113 @@ enum ORDER_TYPE { } } + // if exactIn return new TokenAmount( this.pool.token0, this.amountIn.toString() ) + // else + // if + // zeroForOne = false + // let amountOut = FullMath.mulDivRoundingUp(this.amountIn, this.sqrtpriceX96, Q96); + // amountOut = FullMath.mulDivRoundingUp(amountOut, this.sqrtpriceX96, Q96); + // this._expectedTokenAmountOut = new TokenAmount( + // this.pool.token1, + // amountOut.toString() + // ) + // else + // let amountOut = FullMath.mulDivRoundingUp(this.amountIn, Q96, + // this.sqrtpriceX96); + // amountOut = FullMath.mulDivRoundingUp(amountOut, Q96, + // this.sqrtpriceX96); + // this._expectedTokenAmountOut = new TokenAmount( + // this.pool.token0, + // amountOut.toString() + // ) + // + + + /** * Returns the amountIn of limit order */ - public get tokenAmountIn(): TokenAmount { - if (this._tokenAmountIn === null) { - if (this.zeroForOne) { - this._tokenAmountIn = new TokenAmount( - this.pool.token0, - this.amountIn.toString() - ) - } else { - this._tokenAmountIn = new TokenAmount( - this.pool.token1, - this.amountIn.toString() - ) + public get tokenAmountIn(): TokenAmount { + if (this._tokenAmountIn === null) { + if(this.tradeType===TradeType.EXACT_INPUT) + { + if (!this.zeroForOne) { + this._tokenAmountIn = new TokenAmount( + this.pool.token1, + this.amount.toString() + ) + } else { + this._tokenAmountIn = new TokenAmount( + this.pool.token0, + this.amount.toString() + ) + } + } else { + if (!this.zeroForOne) {// 1 -> 0 + let amountIn = FullMath.mulDivRoundingUp(this.amount, this.sqrtpriceX96, Q96); + amountIn = FullMath.mulDivRoundingUp(amountIn, this.sqrtpriceX96, Q96); + this._tokenAmountIn = new TokenAmount( + this.pool.token1, + amountIn.toString() + ) + } else {// 0 -> 1 + let amountIn = FullMath.mulDivRoundingUp(this.amount, Q96, + this.sqrtpriceX96); + amountIn = FullMath.mulDivRoundingUp(amountIn, Q96, + this.sqrtpriceX96); + this._tokenAmountIn = new TokenAmount( + this.pool.token0, + amountIn.toString() + ) + } + } } + return this._tokenAmountIn } - return this._tokenAmountIn - } /** * Returns the expected amountOut of limit order */ - public get expectedTokenAmountOut(): TokenAmount { - if (this._expectedTokenAmountOut === null) { - if (this.zeroForOne) { - let amountOut = FullMath.mulDivRoundingUp(this.amountIn, this.sqrtpriceX96, Q96); + public get tokenAmountOut(): TokenAmount { + if (this._tokenAmountOut === null) { + if(this.tradeType===TradeType.EXACT_OUTPUT) + { + if (this.zeroForOne) { + this._tokenAmountOut = new TokenAmount( + this.pool.token1, + this.amount.toString() + ) + } else { + this._tokenAmountOut = new TokenAmount( + this.pool.token0, + this.amount.toString() + ) + } + } else { + if (this.zeroForOne) {// 0->1 + let amountOut = FullMath.mulDivRoundingUp(this.amount, this.sqrtpriceX96, Q96); amountOut = FullMath.mulDivRoundingUp(amountOut, this.sqrtpriceX96, Q96); - this._expectedTokenAmountOut = new TokenAmount( + this._tokenAmountOut = new TokenAmount( this.pool.token1, amountOut.toString() ) - } else { - let amountOut = FullMath.mulDivRoundingUp(this.amountIn, Q96, + } else {// 1->0 + let amountOut = FullMath.mulDivRoundingUp(this.amount, Q96, this.sqrtpriceX96); amountOut = FullMath.mulDivRoundingUp(amountOut, Q96, this.sqrtpriceX96); - this._expectedTokenAmountOut = new TokenAmount( + this._tokenAmountOut = new TokenAmount( this.pool.token0, amountOut.toString() ) } } - return this._expectedTokenAmountOut + } + return this._tokenAmountOut } + /** + * Returns the expected amountIn of limit order + */ /** * Returns the sqrtpriceX96 diff --git a/src/limitOrderManager.ts b/src/limitOrderManager.ts index e6e7a45..f7d3611 100644 --- a/src/limitOrderManager.ts +++ b/src/limitOrderManager.ts @@ -77,13 +77,14 @@ export abstract class LimitOrderManager { private constructor() {} public static createCallParameters(order:Order, options:CreateOrderOptions):MethodParameters { - invariant(JSBI.greaterThan(order.amountIn, ZERO), 'ZERO_AMOUNT_IN') + invariant(JSBI.greaterThan(order.tokenAmountIn.raw, ZERO), 'ZERO_AMOUNT_IN') let calldata: string // get amounts - const {zeroForOne,amountIn,tick}=order; - const {lowerOldTick,upperOldTick}=options + const {zeroForOne,tokenAmountIn,tick}=order; + const {lowerOldTick,upperOldTick}=options; + const amountIn=tokenAmountIn.raw; calldata=this.INTERFACE.encodeFunctionData('createLimitOrder',[ Pool.getAddress(order.pool.token0,order.pool.token1), @@ -100,7 +101,7 @@ export abstract class LimitOrderManager { const wrapped = wrappedCurrency(options.useNative,order.tokenAmountIn.token.chainId) invariant(order.tokenAmountIn.token.equals(wrapped), 'NO_WETH') - const wrappedValue = order.amountIn + const wrappedValue = amountIn.toString() value = toHex(wrappedValue) } From ccc61297371d6a8ab6ca3253b34987c522f15449 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Sat, 18 Mar 2023 12:20:14 +0530 Subject: [PATCH 084/103] v0.1.83 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1d63ab9..45ba218 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.0.83", + "version": "0.1.83", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 0a063a44382bf8a2dcffba88bfa7e542b6eb5de0 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Mon, 20 Mar 2023 20:43:00 +0530 Subject: [PATCH 085/103] v0.2.83 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 45ba218..b9dcd4b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.1.83", + "version": "0.2.83", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From c9397a04f3956ab8e11de22f343cbae72a4c6cb9 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Sat, 25 Mar 2023 20:01:38 +0530 Subject: [PATCH 086/103] v0.2.84 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b9dcd4b..75bc82b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.2.83", + "version": "0.2.84", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From cbb7033ab49e72514cd8beb914705a56d1000bc5 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Sun, 26 Mar 2023 19:17:32 +0530 Subject: [PATCH 087/103] v0.2.85 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 75bc82b..8342197 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.2.84", + "version": "0.2.85", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 2ddc8bff85d09d8477c458d20acb8604f01ba443 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Mon, 27 Mar 2023 11:32:36 +0530 Subject: [PATCH 088/103] feat: swap --- src/abis/LimitOrderManager.json | 169 ++++++++++-- src/abis/MasterDeployer.json | 20 +- src/abis/Multicall.json | 110 ++++++++ src/concentratedPoolManager.ts | 449 +++++++++++++++----------------- src/constants.ts | 8 +- src/limitOrderManager.ts | 9 +- src/multicall.ts | 19 ++ 7 files changed, 520 insertions(+), 264 deletions(-) create mode 100644 src/abis/Multicall.json create mode 100644 src/multicall.ts diff --git a/src/abis/LimitOrderManager.json b/src/abis/LimitOrderManager.json index b1a39c2..011f3ad 100644 --- a/src/abis/LimitOrderManager.json +++ b/src/abis/LimitOrderManager.json @@ -15,6 +15,16 @@ "stateMutability": "nonpayable", "type": "constructor" }, + { + "inputs": [], + "name": "ExcessRebate", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyOwner", + "type": "error" + }, { "inputs": [], "name": "TickOutOfBounds", @@ -95,6 +105,54 @@ "name": "CreateLImitOrder", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "isRebate", + "type": "bool" + }, + { + "indexed": false, + "internalType": "uint24", + "name": "amount", + "type": "uint24" + } + ], + "name": "LimitOrderChargeUpdated", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_forwarder", + "type": "address" + }, + { + "internalType": "uint24", + "name": "_fee", + "type": "uint24" + }, + { + "internalType": "bool", + "name": "_authorize", + "type": "bool" + } + ], + "name": "authorizeForwarder", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -167,6 +225,11 @@ "internalType": "bool", "name": "zeroForOne", "type": "bool" + }, + { + "internalType": "address", + "name": "recepient", + "type": "address" } ], "name": "createLimitOrder", @@ -183,17 +246,22 @@ { "inputs": [ { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" + "internalType": "address", + "name": "", + "type": "address" } ], - "name": "getClaimableAmount", + "name": "forwarder", "outputs": [ { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" + "internalType": "bool", + "name": "isWhitelisted", + "type": "bool" + }, + { + "internalType": "uint24", + "name": "fee", + "type": "uint24" } ], "stateMutability": "view", @@ -203,15 +271,20 @@ "inputs": [ { "internalType": "uint256", - "name": "owner", + "name": "", "type": "uint256" } ], - "name": "getLimitOrderTokenBalance", + "name": "forwarderMeta", "outputs": [ + { + "internalType": "uint128", + "name": "forwarderRebateAmount", + "type": "uint128" + }, { "internalType": "address", - "name": "", + "name": "forwarder", "type": "address" } ], @@ -282,20 +355,15 @@ "name": "pool", "type": "address" }, - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - }, { "internalType": "int24", "name": "tick", "type": "int24" }, { - "internalType": "uint256", - "name": "sqrtpriceX96", - "type": "uint256" + "internalType": "enum ILimitOrderStruct.LimitOrderStatus", + "name": "status", + "type": "uint8" }, { "internalType": "bool", @@ -312,15 +380,30 @@ "name": "amountOut", "type": "uint128" }, + { + "internalType": "uint128", + "name": "chargeAmount", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "rebateAmount", + "type": "uint128" + }, { "internalType": "uint256", - "name": "claimedAmount", + "name": "id", "type": "uint256" }, { - "internalType": "enum ILimitOrderStruct.LimitOrderStatus", - "name": "status", - "type": "uint8" + "internalType": "uint256", + "name": "sqrtpriceX96", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimedAmount", + "type": "uint256" }, { "internalType": "uint256", @@ -349,6 +432,48 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "bytes[]", + "name": "data", + "type": "bytes[]" + } + ], + "name": "multicall", + "outputs": [ + { + "internalType": "bytes[]", + "name": "results", + "type": "bytes[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint24", + "name": "_rate", + "type": "uint24" + }, + { + "internalType": "address", + "name": "_pool", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isRebate", + "type": "bool" + } + ], + "name": "setLimitOrderCharge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [], "name": "vault", diff --git a/src/abis/MasterDeployer.json b/src/abis/MasterDeployer.json index b8f6126..f9e87fe 100644 --- a/src/abis/MasterDeployer.json +++ b/src/abis/MasterDeployer.json @@ -30,6 +30,11 @@ "name": "InvalidDfynFee", "type": "error" }, + { + "inputs": [], + "name": "InvalidLimitOrderFee", + "type": "error" + }, { "inputs": [], "name": "NotWhitelisted", @@ -286,7 +291,7 @@ "inputs": [ { "internalType": "uint256", - "name": "_dfynFee", + "name": "_fee", "type": "uint256" }, { @@ -300,6 +305,19 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "_dfynFeeTo", + "type": "address" + } + ], + "name": "setDfynFeeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { diff --git a/src/abis/Multicall.json b/src/abis/Multicall.json new file mode 100644 index 0000000..64bf70d --- /dev/null +++ b/src/abis/Multicall.json @@ -0,0 +1,110 @@ +[ + { + "inputs": [ + { + "internalType": "uint256", + "name": "a", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "b", + "type": "uint256" + } + ], + "name": "functionThatReturnsTuple", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "a", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "b", + "type": "uint256" + } + ], + "internalType": "struct MulticallMock.Tuple", + "name": "tuple", + "type": "tuple" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "error", + "type": "string" + } + ], + "name": "functionThatRevertsWithError", + "outputs": [], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "functionThatRevertsWithoutError", + "outputs": [], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes[]", + "name": "data", + "type": "bytes[]" + } + ], + "name": "multicall", + "outputs": [ + { + "internalType": "bytes[]", + "name": "results", + "type": "bytes[]" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "paid", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pays", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "returnSender", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ] \ No newline at end of file diff --git a/src/concentratedPoolManager.ts b/src/concentratedPoolManager.ts index cc38cac..6003566 100644 --- a/src/concentratedPoolManager.ts +++ b/src/concentratedPoolManager.ts @@ -6,48 +6,49 @@ import { ZERO } from "./internalConstants"; import { MethodParameters, toHex, validateAndParseAddress } from "./utils"; import JSBI from 'jsbi' import { ADDRESS_ZERO, BigintIsh } from "./constants"; +import { Multicall } from "./multicall"; export interface MintSpecificOptions { - /** - * The account that should receive the minted NFT. - */ - recipient: string - - /** - * Creates pool if not initialized before mint. - */ - createPool?: boolean - } - export interface CollectOptions { - /** - * Indicates the ID of the position to collect for. - */ - tokenId: BigintIsh - - /** - * Expected value of tokensOwed0, including as-of-yet-unaccounted-for fees/liquidity value to be burned - */ - expectedCurrencyOwed0: CurrencyAmount - - /** - * Expected value of tokensOwed1, including as-of-yet-unaccounted-for fees/liquidity value to be burned - */ - expectedCurrencyOwed1: CurrencyAmount - - /** - * The account that should receive the tokens. - */ - recipient: string + /** + * The account that should receive the minted NFT. + */ + recipient: string - /** - * To unwrap or not - */ - unwrapVault: boolean - } + /** + * Creates pool if not initialized before mint. + */ + createPool?: boolean +} +export interface CollectOptions { + /** + * Indicates the ID of the position to collect for. + */ + tokenId: BigintIsh + + /** + * Expected value of tokensOwed0, including as-of-yet-unaccounted-for fees/liquidity value to be burned + */ + expectedCurrencyOwed0: CurrencyAmount + + /** + * Expected value of tokensOwed1, including as-of-yet-unaccounted-for fees/liquidity value to be burned + */ + expectedCurrencyOwed1: CurrencyAmount + + /** + * The account that should receive the tokens. + */ + recipient: string + + /** + * To unwrap or not + */ + unwrapVault: boolean +} /** * Options for producing the calldata to exit a position. */ - export interface RemoveLiquidityOptions { +export interface RemoveLiquidityOptions { /** * The ID of the token to exit */ @@ -67,101 +68,103 @@ export interface MintSpecificOptions { /** * The account that should receive the tokens. */ - recipient: string + recipient: string - /** - * To unwrap or not - */ - unwrapVault: boolean + /** + * To unwrap or not + */ + unwrapVault: boolean } - - export interface IncreaseSpecificOptions { - /** - * Indicates the ID of the position to increase liquidity for. - */ - tokenId: BigintIsh - } - + +export interface IncreaseSpecificOptions { /** - * Options for producing the calldata to add liquidity. + * Indicates the ID of the position to increase liquidity for. */ - export interface CommonAddLiquidityOptions { - /** - * How much the pool price is allowed to move. - */ - slippageTolerance: Percent - - /** - * When the transaction expires, in epoch seconds. - */ - deadline: BigintIsh - - /** - * Whether to spend ether. If true, one of the pool tokens must be WETH, by default false - */ - useNative?: Currency - - // /** - // * The optional permit parameters for spending token0 - // */ - // token0Permit?: PermitOptions - - // /** - // * The optional permit parameters for spending token1 - // */ - // token1Permit?: PermitOptions - - /** - * The lower and upper old - */ - lowerOldTick: number - - /** - * The lower and upper old - */ - upperOldTick: number - - } - - export type MintOptions = CommonAddLiquidityOptions & MintSpecificOptions - export type IncreaseOptions = CommonAddLiquidityOptions & IncreaseSpecificOptions - - export type AddLiquidityOptions = MintOptions | IncreaseOptions - - export interface SafeTransferOptions { - /** - * The account sending the NFT. - */ - sender: string - - /** - * The account that should receive the NFT. - */ - recipient: string - - /** - * The id of the token being sent. - */ - tokenId: BigintIsh - /** - * The optional parameter that passes data to the `onERC721Received` call for the staker - */ - data?: string - } + tokenId: BigintIsh +} + +/** + * Options for producing the calldata to add liquidity. + */ +export interface CommonAddLiquidityOptions { + /** + * How much the pool price is allowed to move. + */ + slippageTolerance: Percent + + /** + * When the transaction expires, in epoch seconds. + */ + deadline: BigintIsh + + /** + * Whether to spend ether. If true, one of the pool tokens must be WETH, by default false + */ + useNative?: Currency + + // /** + // * The optional permit parameters for spending token0 + // */ + // token0Permit?: PermitOptions + + // /** + // * The optional permit parameters for spending token1 + // */ + // token1Permit?: PermitOptions + + /** + * The lower and upper old + */ + lowerOldTick: number + + /** + * The lower and upper old + */ + upperOldTick: number + +} + +export type MintOptions = CommonAddLiquidityOptions & MintSpecificOptions +export type IncreaseOptions = CommonAddLiquidityOptions & IncreaseSpecificOptions + +export type AddLiquidityOptions = MintOptions | IncreaseOptions + +export type RemoveAndAddLiquidityOptions = AddLiquidityOptions & RemoveLiquidityOptions + +export interface SafeTransferOptions { + /** + * The account sending the NFT. + */ + sender: string + + /** + * The account that should receive the NFT. + */ + recipient: string + + /** + * The id of the token being sent. + */ + tokenId: BigintIsh + /** + * The optional parameter that passes data to the `onERC721Received` call for the staker + */ + data?: string +} - // type guard +// type guard export function isMint(options: AddLiquidityOptions): options is MintOptions { - return Object.keys(options).some(k => k === 'recipient') - } + return Object.keys(options).some(k => k === 'recipient') +} export abstract class ConcentratedPoolManager { - public static INTERFACE: Interface = new Interface(ConcentratedPoolManagerAbi) + public static INTERFACE: Interface = new Interface(ConcentratedPoolManagerAbi) - /** - * Cannot be constructed. - */ - private constructor() {} + /** + * Cannot be constructed. + */ + private constructor() { } public static addCallParameters(position: Position, options: AddLiquidityOptions): MethodParameters { invariant(JSBI.greaterThan(position.liquidity, ZERO), 'ZERO_LIQUIDITY') @@ -171,93 +174,53 @@ export abstract class ConcentratedPoolManager { // get amounts const { amount0: amount0Desired, amount1: amount1Desired } = position.mintAmounts - // adjust for slippage - // const minimumAmounts = position.mintAmountsWithSlippage(options.slippageTolerance) - // const amount0Min = toHex(minimumAmounts.amount0) - // const amount1Min = toHex(minimumAmounts.amount1) - - // const deadline = toHex(options.deadline) - - // revert if pool not present - // invariant(options?.createPool,'POOL_DOES_NOT_EXISTS'); - - // permits if necessary - // if (options.token0Permit) { - // calldatas.push(SelfPermit.encodePermit(position.pool.token0, options.token0Permit)) - // } - // if (options.token1Permit) { - // calldatas.push(SelfPermit.encodePermit(position.pool.token1, options.token1Permit)) - // } - - // mint - if (isMint(options)) { - calldata= - this.INTERFACE.encodeFunctionData('mint', [ - Pool.getAddress(position.pool.token0,position.pool.token1), - options.lowerOldTick, - position.tickLower, - options.upperOldTick, - position.tickUpper, - toHex(amount0Desired), - toHex(amount1Desired), - true, - "0", - "0" - // token0: position.pool.token0.address, - // token1: position.pool.token1.address, - // fee: position.pool.fee, - // tickLower: position.tickLower, - // tickUpper: position.tickUpper, - // amount0Desired: toHex(amount0Desired), - // amount1Desired: toHex(amount1Desired), - // amount0Min, - // amount1Min, - // recipient, - // deadline - ]) - - } else { - // increase - calldata= - this.INTERFACE.encodeFunctionData('mint', [ - Pool.getAddress(position.pool.token0,position.pool.token1), - options.lowerOldTick, - position.tickLower, - options.upperOldTick, - position.tickUpper, - toHex(amount0Desired), - toHex(amount1Desired), - true, - "0", - options.tokenId - // token0: position.pool.token0.address, - // token1: position.pool.token1.address, - // fee: position.pool.fee, - // tickLower: position.tickLower, - // tickUpper: position.tickUpper, - // amount0Desired: toHex(amount0Desired), - // amount1Desired: toHex(amount1Desired), - // amount0Min, - // amount1Min, - // recipient, - // deadline - ]) - } - - let value: string = toHex(0) - if (options.useNative) { - const wrapped = wrappedCurrency(options.useNative,position.pool.token0.chainId) - invariant(position.pool.token0.equals(wrapped) || position.pool.token1.equals(wrapped), 'NO_WETH') - - const wrappedValue = position.pool.token0.equals(wrapped) ? amount0Desired : amount1Desired - - value = toHex(wrappedValue) - } - - return { - calldata, - value - } + // mint + if (isMint(options)) { + calldata = + this.INTERFACE.encodeFunctionData('mint', [ + Pool.getAddress(position.pool.token0, position.pool.token1), + options.lowerOldTick, + position.tickLower, + options.upperOldTick, + position.tickUpper, + toHex(amount0Desired), + toHex(amount1Desired), + true, + "0", + "0" + ]) + + } else { + // increase + calldata = + this.INTERFACE.encodeFunctionData('mint', [ + Pool.getAddress(position.pool.token0, position.pool.token1), + options.lowerOldTick, + position.tickLower, + options.upperOldTick, + position.tickUpper, + toHex(amount0Desired), + toHex(amount1Desired), + true, + "0", + options.tokenId + ]) + } + + let value: string = toHex(0) + if (options.useNative) { + const wrapped = wrappedCurrency(options.useNative, position.pool.token0.chainId) + invariant(position.pool.token0.equals(wrapped) || position.pool.token1.equals(wrapped), 'NO_WETH') + + const wrappedValue = position.pool.token0.equals(wrapped) ? amount0Desired : amount1Desired + + value = toHex(wrappedValue) + } + + return { + calldata, + value + } } private static encodeCollect(options: CollectOptions): string { @@ -276,28 +239,13 @@ export abstract class ConcentratedPoolManager { const recipient = validateAndParseAddress(options.recipient) // collect - calldata= + calldata = this.INTERFACE.encodeFunctionData('collect', [ - tokenId, - involvesETH ? ADDRESS_ZERO : recipient, - options.unwrapVault + tokenId, + involvesETH ? ADDRESS_ZERO : recipient, + options.unwrapVault ]) - // if (involvesETH) { - // const ethAmount = options.expectedCurrencyOwed0.currency.isNative - // ? options.expectedCurrencyOwed0.quotient - // : options.expectedCurrencyOwed1.quotient - // const token = options.expectedCurrencyOwed0.currency.isNative - // ? (options.expectedCurrencyOwed1.currency as Token) - // : (options.expectedCurrencyOwed0.currency as Token) - // const tokenAmount = options.expectedCurrencyOwed0.currency.isNative - // ? options.expectedCurrencyOwed1.quotient - // : options.expectedCurrencyOwed0.quotient - - // calldatas.push(Payments.encodeUnwrapWETH9(ethAmount, recipient)) - // calldatas.push(Payments.encodeSweepToken(token, tokenAmount, recipient)) - // } - return calldata } @@ -320,7 +268,7 @@ export abstract class ConcentratedPoolManager { let calldata; const tokenId = toHex(options.tokenId) - const recipient=options.recipient + const recipient = options.recipient // construct a partial position with a percentage of liquidity const partialPosition = new Position({ @@ -351,15 +299,15 @@ export abstract class ConcentratedPoolManager { // remove liquidity - calldata=this.INTERFACE.encodeFunctionData('burn', [ - tokenId, - partialPosition.liquidity.toString(), - recipient, - options.unwrapVault, - amount0Min.toString(), - amount1Min.toString() + calldata = this.INTERFACE.encodeFunctionData('burn', [ + tokenId, + partialPosition.liquidity.toString(), + recipient, + options.unwrapVault, + amount0Min.toString(), + amount1Min.toString() ]) - + return { calldata, @@ -367,4 +315,33 @@ export abstract class ConcentratedPoolManager { } } + /** + * Produces the calldata for removing a position and creating a new position + * @param position The position to exit + * @param options Additional information necessary for generating the calldata + * @returns The call parameters + */ + public static removeAndAddCallParameters(positionToBeRemoved: Position, positionToBeAdded: Position, options: RemoveAndAddLiquidityOptions): MethodParameters { + const removeCallParameters = this.removeCallParameters(positionToBeRemoved, { + liquidityPercentage: options.liquidityPercentage, + recipient: options.recipient, + slippageTolerance: options.slippageTolerance, + tokenId: options.tokenId, + unwrapVault: options.unwrapVault + }) + + const addCallParameters = this.addCallParameters(positionToBeAdded, { + deadline: options.deadline, + lowerOldTick: options.lowerOldTick, + recipient: options.recipient, + slippageTolerance: options.slippageTolerance, + tokenId: "0", + upperOldTick: options.upperOldTick, + useNative: options.useNative, + }) + return { + calldata: Multicall.encodeMulticall([removeCallParameters.calldata, addCallParameters.calldata]), + value: addCallParameters.value + } + } } \ No newline at end of file diff --git a/src/constants.ts b/src/constants.ts index 4ba81d0..20b8192 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -111,7 +111,7 @@ export const V2_FACTORY_ADDRESS: { [chainId in ChainId]: string } = { [ChainId.RINKEBY]: '', [ChainId.GΓ–RLI]: '', [ChainId.KOVAN]: '', - [ChainId.MATIC]: '0x7ED245AADAcD826dfF9478de019e76FfF7c202fC', + [ChainId.MATIC]: '0xE3c3c8286FbbbE6851E430D84Ffac35D83286F72', [ChainId.OKEX]: '', [ChainId.ARBITRUM]: '', [ChainId.XDAI]: '', @@ -128,7 +128,7 @@ export const V2_DEPLOYER_ADDRESS: { [chainId in ChainId]: string } = { [ChainId.RINKEBY]: '', [ChainId.GΓ–RLI]: '', [ChainId.KOVAN]: '', - [ChainId.MATIC]: '0x20F200c65bDD173Df64a528e28F77F06ebDE61D9', + [ChainId.MATIC]: '0xf79a83E3f8E853D9658e8b97a83942Af80d45b85', [ChainId.OKEX]: '', [ChainId.ARBITRUM]: '', [ChainId.XDAI]: '', @@ -143,7 +143,7 @@ export const V2_MASTER_DEPLOYER_ADDRESS: { [chainId in ChainId]: string } = { [ChainId.RINKEBY]: '', [ChainId.GΓ–RLI]: '', [ChainId.KOVAN]: '', - [ChainId.MATIC]: '0xaba5e148b0CB58e545d1E4D645EBBD6c250288b4', + [ChainId.MATIC]: '0xF9A626BB1eb10464F7E691d4070d283023910100', [ChainId.OKEX]: '', [ChainId.ARBITRUM]: '', [ChainId.XDAI]: '', @@ -161,7 +161,7 @@ export const V2_POOL_INIT_CODE_HASH: { [chainId in ChainId]: string } = { [ChainId.RINKEBY]: '', [ChainId.GΓ–RLI]: '', [ChainId.KOVAN]: '', - [ChainId.MATIC]: '0x927b92e6ba1767fdf9098da147c98f2e3f30c9507dd81ece2a3a4951c0614b43', + [ChainId.MATIC]: '0x1a7e5ef1e1989c411ffc5bd046a9f78d9f197278d7205be2531e46a142074f42', [ChainId.OKEX]: '', [ChainId.ARBITRUM]: '', [ChainId.XDAI]: '', diff --git a/src/limitOrderManager.ts b/src/limitOrderManager.ts index f7d3611..dec2ff2 100644 --- a/src/limitOrderManager.ts +++ b/src/limitOrderManager.ts @@ -34,6 +34,11 @@ export interface CreateOrderOptions{ * The lower and upper old */ upperOldTick: number + + /** + * The lower and upper old + */ + recipient: string } @@ -85,6 +90,7 @@ export abstract class LimitOrderManager { const {zeroForOne,tokenAmountIn,tick}=order; const {lowerOldTick,upperOldTick}=options; const amountIn=tokenAmountIn.raw; + const recipient=options.recipient; calldata=this.INTERFACE.encodeFunctionData('createLimitOrder',[ Pool.getAddress(order.pool.token0,order.pool.token1), @@ -93,7 +99,8 @@ export abstract class LimitOrderManager { upperOldTick, true, amountIn.toString(), - zeroForOne + zeroForOne, + recipient ]) let value: string = toHex(0) diff --git a/src/multicall.ts b/src/multicall.ts new file mode 100644 index 0000000..d70b54c --- /dev/null +++ b/src/multicall.ts @@ -0,0 +1,19 @@ +import { Interface } from '@ethersproject/abi' +import IMulticall from './abis/Multicall.json' + +export abstract class Multicall { + public static INTERFACE: Interface = new Interface(IMulticall) + + /** + * Cannot be constructed. + */ + private constructor() { } + + public static encodeMulticall(calldatas: string | string[]): string { + if (!Array.isArray(calldatas)) { + calldatas = [calldatas] + } + + return calldatas.length === 1 ? calldatas[0] : Multicall.INTERFACE.encodeFunctionData('multicall', [calldatas]) + } +} \ No newline at end of file From f76f2d91d42cfe56020bea13561816d306ba39db Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Mon, 27 Mar 2023 11:34:27 +0530 Subject: [PATCH 089/103] fix: typo fix --- src/limitOrderManager.ts | 191 ++++++++++++++++++++------------------- 1 file changed, 96 insertions(+), 95 deletions(-) diff --git a/src/limitOrderManager.ts b/src/limitOrderManager.ts index dec2ff2..5781fdc 100644 --- a/src/limitOrderManager.ts +++ b/src/limitOrderManager.ts @@ -1,111 +1,112 @@ import { Interface } from "@ethersproject/abi"; import { Order } from "entities/order"; -import { MethodParameters, Percent,Currency, Pool, toHex, wrappedCurrency } from "./index"; +import { MethodParameters, Percent, Currency, Pool, toHex, wrappedCurrency } from "./index"; import invariant from "tiny-invariant"; import LimitOrderManagerAbi from "./abis/LimitOrderManager.json" import JSBI from 'jsbi' import { BigintIsh, ZERO } from "./constants"; +import { Multicall } from "./multicall"; +/** + * Options for producing the calldata to create limit order. + */ +export interface CreateOrderOptions { /** - * Options for producing the calldata to create limit order. + * How much the pool price is allowed to move. */ -export interface CreateOrderOptions{ - /** - * How much the pool price is allowed to move. - */ - slippageTolerance: Percent - - /** - * When the transaction expires, in epoch seconds. - */ - deadline: BigintIsh - - /** - * Whether to spend ether. If true, one of the pool tokens must be WETH, by default false - */ - useNative?: Currency - - /** - * The lower and upper old - */ - lowerOldTick: number - - /** - * The lower and upper old - */ - upperOldTick: number - - /** - * The lower and upper old - */ - recipient: string - + slippageTolerance: Percent + + /** + * When the transaction expires, in epoch seconds. + */ + deadline: BigintIsh + + /** + * Whether to spend ether. If true, one of the pool tokens must be WETH, by default false + */ + useNative?: Currency + + /** + * The lower and upper old + */ + lowerOldTick: number + + /** + * The lower and upper old + */ + upperOldTick: number + + /** + * The lower and upper old + */ + recipient: string + } -export interface ClaimOrderOptions{ - /** - * Indicates the ID of the position to collect for. - */ - tokenId: BigintIsh +export interface ClaimOrderOptions { + /** + * Indicates the ID of the position to collect for. + */ + tokenId: BigintIsh - /** - * When the transaction expires, in epoch seconds. - */ - deadline: BigintIsh + /** + * When the transaction expires, in epoch seconds. + */ + deadline: BigintIsh - unwrapVault: Boolean + unwrapVault: Boolean } -export interface CancelOrderOptions{ - /** - * Indicates the ID of the position to collect for. - */ - tokenId: BigintIsh +export interface CancelOrderOptions { + /** + * Indicates the ID of the position to collect for. + */ + tokenId: BigintIsh - /** - * When the transaction expires, in epoch seconds. - */ - deadline: BigintIsh + /** + * When the transaction expires, in epoch seconds. + */ + deadline: BigintIsh - unwrapVault: Boolean + unwrapVault: Boolean } export abstract class LimitOrderManager { - public static INTERFACE: Interface = new Interface(LimitOrderManagerAbi); + public static INTERFACE: Interface = new Interface(LimitOrderManagerAbi); - /** - * Cannot be constructed. - */ - private constructor() {} + /** + * Cannot be constructed. + */ + private constructor() { } - public static createCallParameters(order:Order, options:CreateOrderOptions):MethodParameters { + public static createCallParameters(order: Order, options: CreateOrderOptions): MethodParameters { invariant(JSBI.greaterThan(order.tokenAmountIn.raw, ZERO), 'ZERO_AMOUNT_IN') let calldata: string // get amounts - const {zeroForOne,tokenAmountIn,tick}=order; - const {lowerOldTick,upperOldTick}=options; - const amountIn=tokenAmountIn.raw; - const recipient=options.recipient; - - calldata=this.INTERFACE.encodeFunctionData('createLimitOrder',[ - Pool.getAddress(order.pool.token0,order.pool.token1), - tick, - lowerOldTick, - upperOldTick, - true, - amountIn.toString(), - zeroForOne, - recipient + const { zeroForOne, tokenAmountIn, tick } = order; + const { lowerOldTick, upperOldTick } = options; + const amountIn = tokenAmountIn.raw; + const recipient = options.recipient; + + calldata = this.INTERFACE.encodeFunctionData('createLimitOrder', [ + Pool.getAddress(order.pool.token0, order.pool.token1), + tick, + lowerOldTick, + upperOldTick, + true, + amountIn.toString(), + zeroForOne, + recipient ]) let value: string = toHex(0) if (options.useNative) { - const wrapped = wrappedCurrency(options.useNative,order.tokenAmountIn.token.chainId) + const wrapped = wrappedCurrency(options.useNative, order.tokenAmountIn.token.chainId) invariant(order.tokenAmountIn.token.equals(wrapped), 'NO_WETH') const wrappedValue = amountIn.toString() @@ -114,53 +115,53 @@ export abstract class LimitOrderManager { } return { - calldata, - value - } + calldata, + value + } } - public static claimCallParameters(options:ClaimOrderOptions):MethodParameters { + public static claimCallParameters(options: ClaimOrderOptions): MethodParameters { let calldata const tokenId = toHex(options.tokenId) - const unwrapVault=options.unwrapVault + const unwrapVault = options.unwrapVault // const involvesETH = // false - calldata=this.INTERFACE.encodeFunctionData('claimLimitOrder',[ - tokenId, - unwrapVault + calldata = this.INTERFACE.encodeFunctionData('claimLimitOrder', [ + tokenId, + unwrapVault ]) - const value = toHex(0) + const value = toHex(0) return { - calldata, - value - } + calldata, + value + } } - public static cancelallParameters(options:CancelOrderOptions):MethodParameters { + public static cancelCallParameters(options: CancelOrderOptions): MethodParameters { let calldata const tokenId = toHex(options.tokenId) - const unwrapVault=options.unwrapVault + const unwrapVault = options.unwrapVault // const involvesETH = // false - calldata=this.INTERFACE.encodeFunctionData('cancelLimitOrder',[ - tokenId, - unwrapVault + calldata = this.INTERFACE.encodeFunctionData('cancelLimitOrder', [ + tokenId, + unwrapVault ]) - const value = toHex(0) + const value = toHex(0) return { - calldata, - value - } + calldata, + value + } } From e275e46b2fefb43cbc6d7c62605345819315a323 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Mon, 27 Mar 2023 11:57:09 +0530 Subject: [PATCH 090/103] feat: cancel and claim multiple by passing array of tokenIds instead of single tokenId --- src/limitOrderManager.ts | 70 +++++++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 23 deletions(-) diff --git a/src/limitOrderManager.ts b/src/limitOrderManager.ts index 5781fdc..e41e01f 100644 --- a/src/limitOrderManager.ts +++ b/src/limitOrderManager.ts @@ -47,7 +47,7 @@ export interface ClaimOrderOptions { /** * Indicates the ID of the position to collect for. */ - tokenId: BigintIsh + tokenId: BigintIsh | BigintIsh[] /** * When the transaction expires, in epoch seconds. @@ -61,7 +61,7 @@ export interface CancelOrderOptions { /** * Indicates the ID of the position to collect for. */ - tokenId: BigintIsh + tokenId: BigintIsh | BigintIsh[] /** * When the transaction expires, in epoch seconds. @@ -122,47 +122,71 @@ export abstract class LimitOrderManager { } public static claimCallParameters(options: ClaimOrderOptions): MethodParameters { - let calldata + const calldatas: string[] = [] - const tokenId = toHex(options.tokenId) const unwrapVault = options.unwrapVault - // const involvesETH = - // false + const tokenIdOrIds = options.tokenId + if (Array.isArray(tokenIdOrIds)) { + // If the tokenIdOrIds is an array of ids, iterate through each ids + tokenIdOrIds.forEach((tokenIdinBigInt) => { + // Handle each id here + const tokenId = toHex(tokenIdinBigInt) + calldatas.push(this.INTERFACE.encodeFunctionData('claimLimitOrder', [ + tokenId, + unwrapVault + ])) + }); + } else { + // If the tokenIdOrIds is a single tokenId, handle it directly + const tokenId = toHex(tokenIdOrIds) + calldatas.push(this.INTERFACE.encodeFunctionData('claimLimitOrder', [ + tokenId, + unwrapVault + ])) + } - calldata = this.INTERFACE.encodeFunctionData('claimLimitOrder', [ - tokenId, - unwrapVault - ]) const value = toHex(0) return { - calldata, + calldata: Multicall.encodeMulticall(calldatas), value } - } + public static cancelCallParameters(options: CancelOrderOptions): MethodParameters { - let calldata + let calldatas: string[] = [] - const tokenId = toHex(options.tokenId) const unwrapVault = options.unwrapVault - // const involvesETH = - // false - - calldata = this.INTERFACE.encodeFunctionData('cancelLimitOrder', [ - tokenId, - unwrapVault - ]) + const tokenIdOrIds = options.tokenId + + if (Array.isArray(tokenIdOrIds)) { + // If the tokenIdOrIds is an array of ids, iterate through each ids + tokenIdOrIds.forEach((tokenIdinBigInt) => { + // Handle each id here + const tokenId = toHex(tokenIdinBigInt) + calldatas.push(this.INTERFACE.encodeFunctionData('cancelLimitOrder', [ + tokenId, + unwrapVault + ])) + }); + } else { + // If the tokenIdOrIds is a single tokenId, handle it directly + const tokenId = toHex(tokenIdOrIds) + calldatas.push(this.INTERFACE.encodeFunctionData('cancelLimitOrder', [ + tokenId, + unwrapVault + ])) + } const value = toHex(0) return { - calldata, + calldata: Multicall.encodeMulticall(calldatas), value } - } + } \ No newline at end of file From cbc0fec1e0bb777b97a7e0d84ab6cdd3a64831ca Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Mon, 27 Mar 2023 11:58:32 +0530 Subject: [PATCH 091/103] v0.2.86 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8342197..aaf9560 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.2.85", + "version": "0.2.86", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 8c0e716b13cf9670deba4627095e8cfcd38d613e Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Wed, 17 May 2023 12:34:05 +0530 Subject: [PATCH 092/103] v0.2.87 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index aaf9560..a4f9d2f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.2.86", + "version": "0.2.87", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 97c697f398e3d4a68cd8a5c3df50be2004329949 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Fri, 16 Jun 2023 01:16:20 +0530 Subject: [PATCH 093/103] v0.2.89 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a4f9d2f..31dfbe9 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.2.87", + "version": "0.2.89", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 98bc40fb22409ad16da8606e8c3dc940580a8425 Mon Sep 17 00:00:00 2001 From: Joydeep Singha Date: Fri, 23 Jun 2023 12:42:12 +0400 Subject: [PATCH 094/103] feat: new contracts update --- src/constants.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index 20b8192..60f0c81 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -113,7 +113,7 @@ export const V2_FACTORY_ADDRESS: { [chainId in ChainId]: string } = { [ChainId.KOVAN]: '', [ChainId.MATIC]: '0xE3c3c8286FbbbE6851E430D84Ffac35D83286F72', [ChainId.OKEX]: '', - [ChainId.ARBITRUM]: '', + [ChainId.ARBITRUM]: '0xB765B066c088539256456ff4CA3C859597DE36B3', [ChainId.XDAI]: '', [ChainId.FANTOM]: '', [ChainId.HARMONY]: '', @@ -130,7 +130,7 @@ export const V2_DEPLOYER_ADDRESS: { [chainId in ChainId]: string } = { [ChainId.KOVAN]: '', [ChainId.MATIC]: '0xf79a83E3f8E853D9658e8b97a83942Af80d45b85', [ChainId.OKEX]: '', - [ChainId.ARBITRUM]: '', + [ChainId.ARBITRUM]: '0x201402538821Fb0cA7E0d04e37b116F11F189B2E', [ChainId.XDAI]: '', [ChainId.FANTOM]: '', [ChainId.HARMONY]: '', @@ -145,7 +145,7 @@ export const V2_MASTER_DEPLOYER_ADDRESS: { [chainId in ChainId]: string } = { [ChainId.KOVAN]: '', [ChainId.MATIC]: '0xF9A626BB1eb10464F7E691d4070d283023910100', [ChainId.OKEX]: '', - [ChainId.ARBITRUM]: '', + [ChainId.ARBITRUM]: '0x7d351b07F091b091F18e2656807Ab48276Ea07dC', [ChainId.XDAI]: '', [ChainId.FANTOM]: '', [ChainId.HARMONY]: '', @@ -163,7 +163,7 @@ export const V2_POOL_INIT_CODE_HASH: { [chainId in ChainId]: string } = { [ChainId.KOVAN]: '', [ChainId.MATIC]: '0x1a7e5ef1e1989c411ffc5bd046a9f78d9f197278d7205be2531e46a142074f42', [ChainId.OKEX]: '', - [ChainId.ARBITRUM]: '', + [ChainId.ARBITRUM]: '0x5de87646b5e50974033508c1107fd77c393026d0e7b0bf353788b202e6dd3f43', [ChainId.XDAI]: '', [ChainId.FANTOM]: '', [ChainId.HARMONY]: '', From 74dfe21d624a87f6278c4197270f244e5235571f Mon Sep 17 00:00:00 2001 From: Jayesh Bhole Date: Mon, 17 Jul 2023 12:48:47 +0400 Subject: [PATCH 095/103] fix: fee amount and entry module of SDK --- package.json | 4 ++-- src/constants.ts | 17 ++++++----------- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index 31dfbe9..03015a3 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "dfyn", "Multi-chain AMM" ], - "module": "dist/sdk.esm.js", + "module": "dist/dfyn-sdk-v2.esm.js", "scripts": { "lint": "tsdx lint src test", "build": "tsdx build", @@ -57,4 +57,4 @@ "semi": false, "singleQuote": true } -} +} \ No newline at end of file diff --git a/src/constants.ts b/src/constants.ts index 60f0c81..cf3720f 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -16,18 +16,18 @@ export enum ChainId { XDAI = 100, BSC = 56, HARMONY = 1666600000, - AVALANCHE = 43114 + AVALANCHE = 43114, } export enum TradeType { EXACT_INPUT, - EXACT_OUTPUT + EXACT_OUTPUT, } export enum Rounding { ROUND_DOWN, ROUND_HALF_UP, - ROUND_UP + ROUND_UP, } export const FACTORY_ADDRESS: { [chainId in ChainId]: string } = { @@ -79,9 +79,6 @@ export const INIT_CODE_HASH: { [chainId in ChainId]: string } = { [ChainId.AVALANCHE]: '0x512ce213a92fcce51fda9ba8738d5584ab111453ad8da5d2bd7d36bc97d14b5c', } - - - export const MINIMUM_LIQUIDITY = JSBI.BigInt(1000) // exports for internal consumption @@ -97,12 +94,12 @@ export const _1000 = JSBI.BigInt(1000) export enum SolidityType { uint8 = 'uint8', - uint256 = 'uint256' + uint256 = 'uint256', } export const SOLIDITY_TYPE_MAXIMA = { [SolidityType.uint8]: JSBI.BigInt('0xff'), - [SolidityType.uint256]: JSBI.BigInt('0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff') + [SolidityType.uint256]: JSBI.BigInt('0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'), } export const V2_FACTORY_ADDRESS: { [chainId in ChainId]: string } = { @@ -121,7 +118,6 @@ export const V2_FACTORY_ADDRESS: { [chainId in ChainId]: string } = { [ChainId.AVALANCHE]: '', } - export const V2_DEPLOYER_ADDRESS: { [chainId in ChainId]: string } = { [ChainId.MAINNET]: '', [ChainId.ROPSTEN]: '', @@ -171,13 +167,12 @@ export const V2_POOL_INIT_CODE_HASH: { [chainId in ChainId]: string } = { [ChainId.AVALANCHE]: '', } - /** * The default factory enabled fee amounts, denominated in hundredths of bips. */ export enum FeeAmount { // LOWEST = 100, - LOW = 500, + LOW = 1500, // MEDIUM = 3000, // HIGH = 10000 } From 2bbee4ec36115f4695abf84b122dcc122c34aa29 Mon Sep 17 00:00:00 2001 From: tusharXrouter Date: Sat, 18 May 2024 02:32:03 +0530 Subject: [PATCH 096/103] feat: base chain support added --- src/constants.ts | 8 ++++++++ src/entities/currency.ts | 4 ++-- src/entities/token.ts | 27 +++++---------------------- 3 files changed, 15 insertions(+), 24 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index cf3720f..c2f1159 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -17,6 +17,7 @@ export enum ChainId { BSC = 56, HARMONY = 1666600000, AVALANCHE = 43114, + BASE = 8453 } export enum TradeType { @@ -44,6 +45,7 @@ export const FACTORY_ADDRESS: { [chainId in ChainId]: string } = { [ChainId.HARMONY]: '0xd9820a17053d6314B20642E465a84Bf01a3D64f5', [ChainId.BSC]: '0xd9820a17053d6314B20642E465a84Bf01a3D64f5', [ChainId.AVALANCHE]: '0xd9820a17053d6314B20642E465a84Bf01a3D64f5', + [ChainId.BASE]: '0xa102072a4c07f06ec3b4900fdc4c7b80b6c57429', //TODO: change to base factory address } export const ROUTER_ADDRESS: { [chainId in ChainId]: string } = { @@ -60,6 +62,7 @@ export const ROUTER_ADDRESS: { [chainId in ChainId]: string } = { [ChainId.HARMONY]: '0x8973792d9E8EA794E546b62c0f2295e32a6d7E48', [ChainId.BSC]: '0x2724B9497b2cF3325C6BE3ea430b3cec34B5Ef2d', [ChainId.AVALANCHE]: '0x4c28f48448720e9000907BC2611F73022fdcE1fA', + [ChainId.BASE]: '0xaedE1EFe768bD8A1663A7608c63290C60B85e71c', //TODO: change to base router address } // export const INIT_CODE_HASH = '0xf187ed688403aa4f7acfada758d8d53698753b998a3071b06f1b777f4330eaf3' @@ -77,6 +80,7 @@ export const INIT_CODE_HASH: { [chainId in ChainId]: string } = { [ChainId.HARMONY]: '0xd3ab2c392f54feb4b3b2a677f449b133c188ad2f1015eff3e94ea9315282c5f5', [ChainId.BSC]: '0xd3ab2c392f54feb4b3b2a677f449b133c188ad2f1015eff3e94ea9315282c5f5', [ChainId.AVALANCHE]: '0x512ce213a92fcce51fda9ba8738d5584ab111453ad8da5d2bd7d36bc97d14b5c', + [ChainId.BASE]: '0xd49917af2b31d70ba7bea89230a93b55d3b6a99aacd03a72c288dfe524ec2f36', //TODO: change to base init code hash } export const MINIMUM_LIQUIDITY = JSBI.BigInt(1000) @@ -116,6 +120,7 @@ export const V2_FACTORY_ADDRESS: { [chainId in ChainId]: string } = { [ChainId.HARMONY]: '', [ChainId.BSC]: '', [ChainId.AVALANCHE]: '', + [ChainId.BASE]: '', } export const V2_DEPLOYER_ADDRESS: { [chainId in ChainId]: string } = { @@ -132,6 +137,7 @@ export const V2_DEPLOYER_ADDRESS: { [chainId in ChainId]: string } = { [ChainId.HARMONY]: '', [ChainId.BSC]: '', [ChainId.AVALANCHE]: '', + [ChainId.BASE]: '', } export const V2_MASTER_DEPLOYER_ADDRESS: { [chainId in ChainId]: string } = { [ChainId.MAINNET]: '', @@ -147,6 +153,7 @@ export const V2_MASTER_DEPLOYER_ADDRESS: { [chainId in ChainId]: string } = { [ChainId.HARMONY]: '', [ChainId.BSC]: '', [ChainId.AVALANCHE]: '', + [ChainId.BASE]: '', } export const ADDRESS_ZERO = '0x0000000000000000000000000000000000000000' @@ -165,6 +172,7 @@ export const V2_POOL_INIT_CODE_HASH: { [chainId in ChainId]: string } = { [ChainId.HARMONY]: '', [ChainId.BSC]: '', [ChainId.AVALANCHE]: '', + [ChainId.BASE]: '', } /** diff --git a/src/entities/currency.ts b/src/entities/currency.ts index c2b1cde..8547ebe 100644 --- a/src/entities/currency.ts +++ b/src/entities/currency.ts @@ -39,8 +39,8 @@ export class Currency { [ChainId.BSC]: Currency.BNB, [ChainId.FANTOM]: Currency.FTM, [ChainId.HARMONY]: Currency.ONE, - [ChainId.AVALANCHE]: Currency.AVAX - + [ChainId.AVALANCHE]: Currency.AVAX, + [ChainId.BASE]: Currency.ETHER, } /** diff --git a/src/entities/token.ts b/src/entities/token.ts index 592d000..b42219c 100644 --- a/src/entities/token.ts +++ b/src/entities/token.ts @@ -101,20 +101,10 @@ export const WETH = { 'WETH', 'Wrapped ETH' ), - [ChainId.BSC]: new Token( - ChainId.BSC, - '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c', - 18, - 'WBNB', - 'Wrapped BNB' - ), - [ChainId.FANTOM]: new Token( - ChainId.FANTOM, - '0x21be370D5312f44cB42ce377BC9b8a0cEF1A4C83', - 18, - 'WFTM', - 'Wrapped FTM' - ), + // TODO: Base Chain + [ChainId.BASE]: new Token(ChainId.BASE, '0x82af49447d8a07e3bd95bd0d56f35241523fbab1', 18, 'WETH', 'Wrapped ETH'), + [ChainId.BSC]: new Token(ChainId.BSC, '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c', 18, 'WBNB', 'Wrapped BNB'), + [ChainId.FANTOM]: new Token(ChainId.FANTOM, '0x21be370D5312f44cB42ce377BC9b8a0cEF1A4C83', 18, 'WFTM', 'Wrapped FTM'), [ChainId.HARMONY]: new Token( ChainId.HARMONY, '0xcF664087a5bB0237a0BAd6742852ec6c8d69A27a', @@ -122,14 +112,7 @@ export const WETH = { 'WONE', 'Wrapped ONE' ), - [ChainId.XDAI]: new Token( - ChainId.XDAI, - '0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d', - 18, - 'WXDAI', - 'Wrapped xDai' - ) - , + [ChainId.XDAI]: new Token(ChainId.XDAI, '0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d', 18, 'WXDAI', 'Wrapped xDai'), [ChainId.AVALANCHE]: new Token( ChainId.AVALANCHE, '0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7', From 7e1be66f1920955fa43313de3664439fd2395444 Mon Sep 17 00:00:00 2001 From: tushar Date: Tue, 21 May 2024 17:51:43 +0530 Subject: [PATCH 097/103] fix: removed placeholder addresses for base chain --- src/constants.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index c2f1159..6519522 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -45,7 +45,7 @@ export const FACTORY_ADDRESS: { [chainId in ChainId]: string } = { [ChainId.HARMONY]: '0xd9820a17053d6314B20642E465a84Bf01a3D64f5', [ChainId.BSC]: '0xd9820a17053d6314B20642E465a84Bf01a3D64f5', [ChainId.AVALANCHE]: '0xd9820a17053d6314B20642E465a84Bf01a3D64f5', - [ChainId.BASE]: '0xa102072a4c07f06ec3b4900fdc4c7b80b6c57429', //TODO: change to base factory address + [ChainId.BASE]: '', //TODO: change to base factory address } export const ROUTER_ADDRESS: { [chainId in ChainId]: string } = { @@ -62,7 +62,7 @@ export const ROUTER_ADDRESS: { [chainId in ChainId]: string } = { [ChainId.HARMONY]: '0x8973792d9E8EA794E546b62c0f2295e32a6d7E48', [ChainId.BSC]: '0x2724B9497b2cF3325C6BE3ea430b3cec34B5Ef2d', [ChainId.AVALANCHE]: '0x4c28f48448720e9000907BC2611F73022fdcE1fA', - [ChainId.BASE]: '0xaedE1EFe768bD8A1663A7608c63290C60B85e71c', //TODO: change to base router address + [ChainId.BASE]: '', //TODO: change to base router address } // export const INIT_CODE_HASH = '0xf187ed688403aa4f7acfada758d8d53698753b998a3071b06f1b777f4330eaf3' @@ -80,7 +80,7 @@ export const INIT_CODE_HASH: { [chainId in ChainId]: string } = { [ChainId.HARMONY]: '0xd3ab2c392f54feb4b3b2a677f449b133c188ad2f1015eff3e94ea9315282c5f5', [ChainId.BSC]: '0xd3ab2c392f54feb4b3b2a677f449b133c188ad2f1015eff3e94ea9315282c5f5', [ChainId.AVALANCHE]: '0x512ce213a92fcce51fda9ba8738d5584ab111453ad8da5d2bd7d36bc97d14b5c', - [ChainId.BASE]: '0xd49917af2b31d70ba7bea89230a93b55d3b6a99aacd03a72c288dfe524ec2f36', //TODO: change to base init code hash + [ChainId.BASE]: '', //TODO: change to base init code hash } export const MINIMUM_LIQUIDITY = JSBI.BigInt(1000) From 6706c5e21ed7436ddad184332dd6b0d4f662b50b Mon Sep 17 00:00:00 2001 From: Joydeep Date: Wed, 22 May 2024 13:56:59 +0400 Subject: [PATCH 098/103] feat: package update --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 03015a3..8931a7d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.2.89", + "version": "0.3.89", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 62b5f94f64e7562e67dbd3a50d8f0389f41c5db9 Mon Sep 17 00:00:00 2001 From: tushar Date: Mon, 24 Jun 2024 15:42:16 +0530 Subject: [PATCH 099/103] feat: Add support for Optimism and Mantle chains --- src/constants.ts | 30 +++++++++++++++++++++++------- src/entities/currency.ts | 2 ++ src/entities/token.ts | 11 ++++++++--- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index 6519522..4e5b806 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -17,18 +17,20 @@ export enum ChainId { BSC = 56, HARMONY = 1666600000, AVALANCHE = 43114, - BASE = 8453 + BASE = 8453, + OPTIMISM = 10, + MANTLE = 5000 } export enum TradeType { EXACT_INPUT, - EXACT_OUTPUT, + EXACT_OUTPUT } export enum Rounding { ROUND_DOWN, ROUND_HALF_UP, - ROUND_UP, + ROUND_UP } export const FACTORY_ADDRESS: { [chainId in ChainId]: string } = { @@ -46,6 +48,8 @@ export const FACTORY_ADDRESS: { [chainId in ChainId]: string } = { [ChainId.BSC]: '0xd9820a17053d6314B20642E465a84Bf01a3D64f5', [ChainId.AVALANCHE]: '0xd9820a17053d6314B20642E465a84Bf01a3D64f5', [ChainId.BASE]: '', //TODO: change to base factory address + [ChainId.OPTIMISM]: '', + [ChainId.MANTLE]: '' } export const ROUTER_ADDRESS: { [chainId in ChainId]: string } = { @@ -63,6 +67,8 @@ export const ROUTER_ADDRESS: { [chainId in ChainId]: string } = { [ChainId.BSC]: '0x2724B9497b2cF3325C6BE3ea430b3cec34B5Ef2d', [ChainId.AVALANCHE]: '0x4c28f48448720e9000907BC2611F73022fdcE1fA', [ChainId.BASE]: '', //TODO: change to base router address + [ChainId.OPTIMISM]: '', + [ChainId.MANTLE]: '' } // export const INIT_CODE_HASH = '0xf187ed688403aa4f7acfada758d8d53698753b998a3071b06f1b777f4330eaf3' @@ -81,6 +87,8 @@ export const INIT_CODE_HASH: { [chainId in ChainId]: string } = { [ChainId.BSC]: '0xd3ab2c392f54feb4b3b2a677f449b133c188ad2f1015eff3e94ea9315282c5f5', [ChainId.AVALANCHE]: '0x512ce213a92fcce51fda9ba8738d5584ab111453ad8da5d2bd7d36bc97d14b5c', [ChainId.BASE]: '', //TODO: change to base init code hash + [ChainId.OPTIMISM]: '', + [ChainId.MANTLE]: '' } export const MINIMUM_LIQUIDITY = JSBI.BigInt(1000) @@ -98,12 +106,12 @@ export const _1000 = JSBI.BigInt(1000) export enum SolidityType { uint8 = 'uint8', - uint256 = 'uint256', + uint256 = 'uint256' } export const SOLIDITY_TYPE_MAXIMA = { [SolidityType.uint8]: JSBI.BigInt('0xff'), - [SolidityType.uint256]: JSBI.BigInt('0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'), + [SolidityType.uint256]: JSBI.BigInt('0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff') } export const V2_FACTORY_ADDRESS: { [chainId in ChainId]: string } = { @@ -121,6 +129,8 @@ export const V2_FACTORY_ADDRESS: { [chainId in ChainId]: string } = { [ChainId.BSC]: '', [ChainId.AVALANCHE]: '', [ChainId.BASE]: '', + [ChainId.OPTIMISM]: '', + [ChainId.MANTLE]: '' } export const V2_DEPLOYER_ADDRESS: { [chainId in ChainId]: string } = { @@ -138,6 +148,8 @@ export const V2_DEPLOYER_ADDRESS: { [chainId in ChainId]: string } = { [ChainId.BSC]: '', [ChainId.AVALANCHE]: '', [ChainId.BASE]: '', + [ChainId.OPTIMISM]: '', + [ChainId.MANTLE]: '' } export const V2_MASTER_DEPLOYER_ADDRESS: { [chainId in ChainId]: string } = { [ChainId.MAINNET]: '', @@ -154,6 +166,8 @@ export const V2_MASTER_DEPLOYER_ADDRESS: { [chainId in ChainId]: string } = { [ChainId.BSC]: '', [ChainId.AVALANCHE]: '', [ChainId.BASE]: '', + [ChainId.OPTIMISM]: '', + [ChainId.MANTLE]: '' } export const ADDRESS_ZERO = '0x0000000000000000000000000000000000000000' @@ -173,6 +187,8 @@ export const V2_POOL_INIT_CODE_HASH: { [chainId in ChainId]: string } = { [ChainId.BSC]: '', [ChainId.AVALANCHE]: '', [ChainId.BASE]: '', + [ChainId.OPTIMISM]: '', + [ChainId.MANTLE]: '' } /** @@ -180,7 +196,7 @@ export const V2_POOL_INIT_CODE_HASH: { [chainId in ChainId]: string } = { */ export enum FeeAmount { // LOWEST = 100, - LOW = 1500, + LOW = 1500 // MEDIUM = 3000, // HIGH = 10000 } @@ -190,7 +206,7 @@ export enum FeeAmount { */ export const TICK_SPACINGS: { [amount in FeeAmount]: number } = { // [FeeAmount.LOWEST]: 1, - [FeeAmount.LOW]: 10, + [FeeAmount.LOW]: 10 // [FeeAmount.MEDIUM]: 60, // [FeeAmount.HIGH]: 200 } diff --git a/src/entities/currency.ts b/src/entities/currency.ts index 8547ebe..ae3917d 100644 --- a/src/entities/currency.ts +++ b/src/entities/currency.ts @@ -41,6 +41,8 @@ export class Currency { [ChainId.HARMONY]: Currency.ONE, [ChainId.AVALANCHE]: Currency.AVAX, [ChainId.BASE]: Currency.ETHER, + [ChainId.OPTIMISM]: Currency.ETHER, + [ChainId.MANTLE]: Currency.ETHER } /** diff --git a/src/entities/token.ts b/src/entities/token.ts index b42219c..2773053 100644 --- a/src/entities/token.ts +++ b/src/entities/token.ts @@ -101,8 +101,7 @@ export const WETH = { 'WETH', 'Wrapped ETH' ), - // TODO: Base Chain - [ChainId.BASE]: new Token(ChainId.BASE, '0x82af49447d8a07e3bd95bd0d56f35241523fbab1', 18, 'WETH', 'Wrapped ETH'), + [ChainId.BSC]: new Token(ChainId.BSC, '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c', 18, 'WBNB', 'Wrapped BNB'), [ChainId.FANTOM]: new Token(ChainId.FANTOM, '0x21be370D5312f44cB42ce377BC9b8a0cEF1A4C83', 18, 'WFTM', 'Wrapped FTM'), [ChainId.HARMONY]: new Token( @@ -119,5 +118,11 @@ export const WETH = { 18, 'XAVAX', 'Wrapped AVAX' - ) + ), + // TODO: Base Chain + [ChainId.BASE]: new Token(ChainId.BASE, '0x82af49447d8a07e3bd95bd0d56f35241523fbab1', 18, 'WETH', 'Wrapped ETH'), + // TODO: Optimism Chain + [ChainId.OPTIMISM]: new Token(ChainId.BASE, '0x82af49447d8a07e3bd95bd0d56f35241523fbab1', 18, 'WETH', 'Wrapped ETH'), + // TODO: Mantle Chain + [ChainId.MANTLE]: new Token(ChainId.BASE, '0x82af49447d8a07e3bd95bd0d56f35241523fbab1', 18, 'WETH', 'Wrapped ETH') } From 81ce3eeab4a9a61363d6e144c4ba78984d5bc9df Mon Sep 17 00:00:00 2001 From: tusharXrouter Date: Thu, 12 Sep 2024 17:28:29 +0530 Subject: [PATCH 100/103] feat: router chain added --- src/constants.ts | 24 ++++++++++++++++-------- src/entities/currency.ts | 4 +++- src/entities/token.ts | 4 +++- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index 4e5b806..579dec4 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -19,7 +19,8 @@ export enum ChainId { AVALANCHE = 43114, BASE = 8453, OPTIMISM = 10, - MANTLE = 5000 + MANTLE = 5000, + ROUTER = 9600 } export enum TradeType { @@ -49,7 +50,8 @@ export const FACTORY_ADDRESS: { [chainId in ChainId]: string } = { [ChainId.AVALANCHE]: '0xd9820a17053d6314B20642E465a84Bf01a3D64f5', [ChainId.BASE]: '', //TODO: change to base factory address [ChainId.OPTIMISM]: '', - [ChainId.MANTLE]: '' + [ChainId.MANTLE]: '', + [ChainId.ROUTER]: '' } export const ROUTER_ADDRESS: { [chainId in ChainId]: string } = { @@ -68,7 +70,8 @@ export const ROUTER_ADDRESS: { [chainId in ChainId]: string } = { [ChainId.AVALANCHE]: '0x4c28f48448720e9000907BC2611F73022fdcE1fA', [ChainId.BASE]: '', //TODO: change to base router address [ChainId.OPTIMISM]: '', - [ChainId.MANTLE]: '' + [ChainId.MANTLE]: '', + [ChainId.ROUTER]: '' } // export const INIT_CODE_HASH = '0xf187ed688403aa4f7acfada758d8d53698753b998a3071b06f1b777f4330eaf3' @@ -88,7 +91,8 @@ export const INIT_CODE_HASH: { [chainId in ChainId]: string } = { [ChainId.AVALANCHE]: '0x512ce213a92fcce51fda9ba8738d5584ab111453ad8da5d2bd7d36bc97d14b5c', [ChainId.BASE]: '', //TODO: change to base init code hash [ChainId.OPTIMISM]: '', - [ChainId.MANTLE]: '' + [ChainId.MANTLE]: '', + [ChainId.ROUTER]: '' } export const MINIMUM_LIQUIDITY = JSBI.BigInt(1000) @@ -130,7 +134,8 @@ export const V2_FACTORY_ADDRESS: { [chainId in ChainId]: string } = { [ChainId.AVALANCHE]: '', [ChainId.BASE]: '', [ChainId.OPTIMISM]: '', - [ChainId.MANTLE]: '' + [ChainId.MANTLE]: '', + [ChainId.ROUTER]: '' } export const V2_DEPLOYER_ADDRESS: { [chainId in ChainId]: string } = { @@ -149,7 +154,8 @@ export const V2_DEPLOYER_ADDRESS: { [chainId in ChainId]: string } = { [ChainId.AVALANCHE]: '', [ChainId.BASE]: '', [ChainId.OPTIMISM]: '', - [ChainId.MANTLE]: '' + [ChainId.MANTLE]: '', + [ChainId.ROUTER]: '' } export const V2_MASTER_DEPLOYER_ADDRESS: { [chainId in ChainId]: string } = { [ChainId.MAINNET]: '', @@ -167,7 +173,8 @@ export const V2_MASTER_DEPLOYER_ADDRESS: { [chainId in ChainId]: string } = { [ChainId.AVALANCHE]: '', [ChainId.BASE]: '', [ChainId.OPTIMISM]: '', - [ChainId.MANTLE]: '' + [ChainId.MANTLE]: '', + [ChainId.ROUTER]: '' } export const ADDRESS_ZERO = '0x0000000000000000000000000000000000000000' @@ -188,7 +195,8 @@ export const V2_POOL_INIT_CODE_HASH: { [chainId in ChainId]: string } = { [ChainId.AVALANCHE]: '', [ChainId.BASE]: '', [ChainId.OPTIMISM]: '', - [ChainId.MANTLE]: '' + [ChainId.MANTLE]: '', + [ChainId.ROUTER]: '' } /** diff --git a/src/entities/currency.ts b/src/entities/currency.ts index ae3917d..5accd45 100644 --- a/src/entities/currency.ts +++ b/src/entities/currency.ts @@ -25,6 +25,7 @@ export class Currency { public static readonly BNB: Currency = new Currency(18, 'BNB', 'Binance Coin') public static readonly FTM: Currency = new Currency(18, 'FTM', 'Fantom') public static readonly AVAX: Currency = new Currency(18, 'AVAX', 'Avalanche') + public static readonly ROUTE: Currency = new Currency(18, 'ROUTE', 'ROUTE') public static readonly NATIVE = { [ChainId.MAINNET]: Currency.ETHER, @@ -42,7 +43,8 @@ export class Currency { [ChainId.AVALANCHE]: Currency.AVAX, [ChainId.BASE]: Currency.ETHER, [ChainId.OPTIMISM]: Currency.ETHER, - [ChainId.MANTLE]: Currency.ETHER + [ChainId.MANTLE]: Currency.ETHER, + [ChainId.ROUTER]: Currency.ROUTE } /** diff --git a/src/entities/token.ts b/src/entities/token.ts index 2773053..3b1c429 100644 --- a/src/entities/token.ts +++ b/src/entities/token.ts @@ -124,5 +124,7 @@ export const WETH = { // TODO: Optimism Chain [ChainId.OPTIMISM]: new Token(ChainId.BASE, '0x82af49447d8a07e3bd95bd0d56f35241523fbab1', 18, 'WETH', 'Wrapped ETH'), // TODO: Mantle Chain - [ChainId.MANTLE]: new Token(ChainId.BASE, '0x82af49447d8a07e3bd95bd0d56f35241523fbab1', 18, 'WETH', 'Wrapped ETH') + [ChainId.MANTLE]: new Token(ChainId.BASE, '0x82af49447d8a07e3bd95bd0d56f35241523fbab1', 18, 'WETH', 'Wrapped ETH'), + // TODO: Router Chain + [ChainId.ROUTER]: new Token(ChainId.ROUTER, '0x82af49447d8a07e3bd95bd0d56f35241523fbab1', 18, 'WETH', 'Wrapped ETH') } From 25db834fd5852131f64db2811ddd536b05a2447d Mon Sep 17 00:00:00 2001 From: tusharXrouter Date: Thu, 12 Sep 2024 17:29:16 +0530 Subject: [PATCH 101/103] bumped: package version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8931a7d..8c1ffeb 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.3.89", + "version": "0.3.90", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts", From 59816627cbb6f0dfd9414ae05109b66cde0134d1 Mon Sep 17 00:00:00 2001 From: Joydeep Date: Tue, 25 Jun 2024 12:37:28 +0530 Subject: [PATCH 102/103] v0.3.90 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8c1ffeb..ca73f39 100644 --- a/package.json +++ b/package.json @@ -57,4 +57,4 @@ "semi": false, "singleQuote": true } -} \ No newline at end of file +} From 70bfe0b9c8d16aa958d9ae0aacb351325fb59c30 Mon Sep 17 00:00:00 2001 From: Joydeep Date: Thu, 12 Sep 2024 16:03:51 +0400 Subject: [PATCH 103/103] v0.3.91 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ca73f39..d93b250 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dfyn-sdk-v2", "license": "MIT", - "version": "0.3.90", + "version": "0.3.91", "description": "πŸ›  An SDK for building applications on top of Dfyn.", "main": "dist/index.js", "typings": "dist/index.d.ts",