diff --git a/docs/INTEGRATION.md b/docs/INTEGRATION.md index d1110f3..95798ec 100644 --- a/docs/INTEGRATION.md +++ b/docs/INTEGRATION.md @@ -28,7 +28,7 @@ import { BaseProvider } from "@metamask/providers"; import { ethers } from "ethers"; const startApp = async (provider: BaseProvider) => { - const web3Provider = new ethers.providers.Web3Provider(provider); + const web3Provider = new ethers.Web3Provider(provider); await web3Provider.ready; const signer = web3Provider.getSigner(); // ready to go }; diff --git a/package-lock.json b/package-lock.json index a0527fd..778239e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@orionprotocol/sdk", - "version": "0.19.95", + "version": "0.19.92-rc2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@orionprotocol/sdk", - "version": "0.19.95", + "version": "0.19.92-rc2", "hasInstallScript": true, "license": "ISC", "dependencies": { @@ -17,7 +17,7 @@ "bignumber.js": "^9.1.1", "bson-objectid": "^2.0.4", "buffer": "^6.0.3", - "ethers": "^5.6.2", + "ethers": "^6.7.1", "express": "^4.18.2", "isomorphic-ws": "^5.0.0", "just-clone": "^6.2.0", @@ -76,6 +76,11 @@ "node": ">=0.10.0" } }, + "node_modules/@adraffy/ens-normalize": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.9.2.tgz", + "integrity": "sha512-0h+FrQDqe2Wn+IIGFkTCd4aAwTJ+7834Ek1COohCyV26AXhwQ7WQaz+4F/nLOeVl/3BtWHOHLPsq46V8YB46Eg==" + }, "node_modules/@ampproject/remapping": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", @@ -1052,32 +1057,6 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/@ethersproject/abi": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", - "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "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" - } - }, "node_modules/@ethersproject/abstract-provider": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", @@ -1239,33 +1218,6 @@ "@ethersproject/bignumber": "^5.7.0" } }, - "node_modules/@ethersproject/contracts": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz", - "integrity": "sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abi": "^5.7.0", - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0" - } - }, "node_modules/@ethersproject/hash": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", @@ -1292,65 +1244,6 @@ "@ethersproject/strings": "^5.7.0" } }, - "node_modules/@ethersproject/hdnode": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", - "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "node_modules/@ethersproject/json-wallets": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", - "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" - } - }, "node_modules/@ethersproject/keccak256": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", @@ -1403,25 +1296,6 @@ "@ethersproject/logger": "^5.7.0" } }, - "node_modules/@ethersproject/pbkdf2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", - "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/sha2": "^5.7.0" - } - }, "node_modules/@ethersproject/properties": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", @@ -1578,29 +1452,6 @@ "hash.js": "1.1.7" } }, - "node_modules/@ethersproject/solidity": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", - "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, "node_modules/@ethersproject/strings": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", @@ -1647,58 +1498,6 @@ "@ethersproject/signing-key": "^5.7.0" } }, - "node_modules/@ethersproject/units": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", - "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/wallet": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", - "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/json-wallets": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, "node_modules/@ethersproject/web": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", @@ -1721,28 +1520,6 @@ "@ethersproject/strings": "^5.7.0" } }, - "node_modules/@ethersproject/wordlists": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", - "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, "node_modules/@fastify/deepmerge": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@fastify/deepmerge/-/deepmerge-1.3.0.tgz", @@ -2583,6 +2360,28 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@noble/hashes": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.1.2.tgz", + "integrity": "sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@noble/secp256k1": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.7.1.tgz", + "integrity": "sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -3459,9 +3258,9 @@ } }, "node_modules/aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==" + "version": "4.0.0-beta.5", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz", + "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==" }, "node_modules/ajv": { "version": "6.12.6", @@ -5526,13 +5325,13 @@ } }, "node_modules/ethers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", - "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.7.1.tgz", + "integrity": "sha512-qX5kxIFMfg1i+epfgb0xF4WM7IqapIIu50pOJ17aebkxxa4BacW5jFrQRmCJpDEg2ZK2oNtR5QjrQ1WDBF29dA==", "funding": [ { "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + "url": "https://github.com/sponsors/ethers-io/" }, { "type": "individual", @@ -5540,36 +5339,46 @@ } ], "dependencies": { - "@ethersproject/abi": "5.7.0", - "@ethersproject/abstract-provider": "5.7.0", - "@ethersproject/abstract-signer": "5.7.0", - "@ethersproject/address": "5.7.0", - "@ethersproject/base64": "5.7.0", - "@ethersproject/basex": "5.7.0", - "@ethersproject/bignumber": "5.7.0", - "@ethersproject/bytes": "5.7.0", - "@ethersproject/constants": "5.7.0", - "@ethersproject/contracts": "5.7.0", - "@ethersproject/hash": "5.7.0", - "@ethersproject/hdnode": "5.7.0", - "@ethersproject/json-wallets": "5.7.0", - "@ethersproject/keccak256": "5.7.0", - "@ethersproject/logger": "5.7.0", - "@ethersproject/networks": "5.7.1", - "@ethersproject/pbkdf2": "5.7.0", - "@ethersproject/properties": "5.7.0", - "@ethersproject/providers": "5.7.2", - "@ethersproject/random": "5.7.0", - "@ethersproject/rlp": "5.7.0", - "@ethersproject/sha2": "5.7.0", - "@ethersproject/signing-key": "5.7.0", - "@ethersproject/solidity": "5.7.0", - "@ethersproject/strings": "5.7.0", - "@ethersproject/transactions": "5.7.0", - "@ethersproject/units": "5.7.0", - "@ethersproject/wallet": "5.7.0", - "@ethersproject/web": "5.7.1", - "@ethersproject/wordlists": "5.7.0" + "@adraffy/ens-normalize": "1.9.2", + "@noble/hashes": "1.1.2", + "@noble/secp256k1": "1.7.1", + "@types/node": "18.15.13", + "aes-js": "4.0.0-beta.5", + "tslib": "2.4.0", + "ws": "8.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/ethers/node_modules/@types/node": { + "version": "18.15.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.13.tgz", + "integrity": "sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==" + }, + "node_modules/ethers/node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, + "node_modules/ethers/node_modules/ws": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", + "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, "node_modules/events": { @@ -10260,11 +10069,6 @@ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, - "node_modules/scrypt-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" - }, "node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", diff --git a/package.json b/package.json index c6206d8..ef29267 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@orionprotocol/sdk", - "version": "0.19.95", + "version": "0.19.92-rc2", "description": "Orion Protocol SDK", "main": "./lib/index.cjs", "module": "./lib/index.js", @@ -91,7 +91,7 @@ "bignumber.js": "^9.1.1", "bson-objectid": "^2.0.4", "buffer": "^6.0.3", - "ethers": "^5.6.2", + "ethers": "^6.7.1", "express": "^4.18.2", "isomorphic-ws": "^5.0.0", "just-clone": "^6.2.0", diff --git a/src/BalanceGuard.ts b/src/BalanceGuard.ts index 42bbb23..9434591 100644 --- a/src/BalanceGuard.ts +++ b/src/BalanceGuard.ts @@ -1,7 +1,7 @@ import { BigNumber } from 'bignumber.js'; import { ethers } from 'ethers'; import clone from 'just-clone'; -import { ERC20__factory } from '@orionprotocol/contracts/lib/ethers-v5/index.js'; +import { ERC20__factory } from '@orionprotocol/contracts/lib/ethers-v6'; import { APPROVE_ERC20_GAS_LIMIT, NATIVE_CURRENCY_PRECISION } from './constants/index.js'; import type { AggregatedBalanceRequirement, ApproveFix, Asset, BalanceIssue, BalanceRequirement, Source, @@ -24,7 +24,7 @@ export default class BalanceGuard { private readonly nativeCryptocurrency: Asset; - private readonly provider: ethers.providers.Provider; + private readonly provider: ethers.Provider; private readonly signer: ethers.Signer; @@ -33,7 +33,7 @@ export default class BalanceGuard { constructor( balances: Partial>>, nativeCryptocurrency: Asset, - provider: ethers.providers.Provider, + provider: ethers.Provider, signer: ethers.Signer, logger?: (message: string) => void, ) { @@ -62,10 +62,10 @@ export default class BalanceGuard { const walletAddress = await this.signer.getAddress(); const tokenContract = ERC20__factory .connect(assetAddress, this.provider); - const unsignedTx = await tokenContract.populateTransaction - .approve( + const unsignedTx = await tokenContract.approve + .populateTransaction( spenderAddress, - ethers.constants.MaxUint256, + ethers.MaxUint256, ); unsignedTx.from = walletAddress; let resetRequired = false; @@ -117,21 +117,23 @@ export default class BalanceGuard { const approve = async ({ spenderAddress, targetAmount }: ApproveFix) => { const bnTargetAmount = new BigNumber(targetAmount); const unsignedApproveTx = await tokenContract - .populateTransaction - .approve( + .approve.populateTransaction( spenderAddress, bnTargetAmount.isZero() ? '0' // Reset - : ethers.constants.MaxUint256, // Infinite approve + : ethers.MaxUint256, // Infinite approve ); const walletAddress = await this.signer.getAddress(); const nonce = await this.provider.getTransactionCount(walletAddress, 'pending'); - const gasPrice = await this.provider.getGasPrice(); + const { gasPrice, maxFeePerGas } = await this.provider.getFeeData(); const network = await this.provider.getNetwork(); + if (gasPrice !== null && maxFeePerGas !== null) { + unsignedApproveTx.gasPrice = gasPrice; + unsignedApproveTx.maxFeePerGas = maxFeePerGas; + } unsignedApproveTx.chainId = network.chainId; - unsignedApproveTx.gasPrice = gasPrice; unsignedApproveTx.nonce = nonce; unsignedApproveTx.from = walletAddress; const gasLimit = await this.provider.estimateGas(unsignedApproveTx); @@ -139,7 +141,7 @@ export default class BalanceGuard { this.logger?.('Approve transaction signing...'); const signedTx = await this.signer.signTransaction(unsignedApproveTx); - const txResponse = await this.provider.sendTransaction(signedTx); + const txResponse = await this.provider.broadcastTransaction(signedTx); this.logger?.(`${issue.asset.name} approve transaction sent ${txResponse.hash}. Waiting for confirmation...`); await txResponse.wait(); this.logger?.(`${issue.asset.name} approve transaction confirmed.`); @@ -230,7 +232,7 @@ export default class BalanceGuard { const lackAmount = remainingBalance.exchange.abs(); // e.g. -435.234234 to 434.234234 let denormalizedAllowance: BigNumber; - if (asset.address === ethers.constants.AddressZero) { + if (asset.address === ethers.ZeroAddress) { denormalizedAllowance = remainingBalance.wallet; } else { if (spenderAddress === undefined) throw new Error(`Spender address is required for ${asset.name}`); @@ -272,13 +274,11 @@ export default class BalanceGuard { asset.address, spenderAddress, ); - const gasPriceWei = await this.provider.getGasPrice(); - const approveTransactionCost = ethers.BigNumber - .from(APPROVE_ERC20_GAS_LIMIT) - .mul(gasPriceWei); + const { gasPrice: gasPriceWei } = await this.provider.getFeeData(); + const approveTransactionCost = BigInt(APPROVE_ERC20_GAS_LIMIT) * (gasPriceWei ?? 0n); const denormalizedApproveTransactionCost = denormalizeNumber( approveTransactionCost, - NATIVE_CURRENCY_PRECISION + BigInt(NATIVE_CURRENCY_PRECISION) ); requiredApproves.items = { @@ -329,7 +329,7 @@ export default class BalanceGuard { .reduce((p, c) => (c !== undefined ? p.plus(c) : p), new BigNumber(0)); let denormalizedAllowance: BigNumber; - if (asset.address === ethers.constants.AddressZero) { + if (asset.address === ethers.ZeroAddress) { denormalizedAllowance = remainingBalance.wallet; } else { if (spenderAddress === undefined) throw new Error(`Spender address is required for ${asset.name}`); @@ -365,13 +365,11 @@ export default class BalanceGuard { asset.address, spenderAddress, ); - const gasPriceWei = await this.provider.getGasPrice(); - const approveTransactionCost = ethers.BigNumber - .from(APPROVE_ERC20_GAS_LIMIT) - .mul(gasPriceWei); + const { gasPrice: gasPriceWei } = await this.provider.getFeeData(); + const approveTransactionCost = BigInt(APPROVE_ERC20_GAS_LIMIT) * (gasPriceWei ?? 0n); const denormalizedApproveTransactionCost = denormalizeNumber( approveTransactionCost, - NATIVE_CURRENCY_PRECISION + BigInt(NATIVE_CURRENCY_PRECISION) ); requiredApproves.items = { diff --git a/src/Orion/bridge/getHistory.ts b/src/Orion/bridge/getHistory.ts index 0cce384..13da84b 100644 --- a/src/Orion/bridge/getHistory.ts +++ b/src/Orion/bridge/getHistory.ts @@ -5,10 +5,10 @@ import { isValidChainId } from '../../utils/index.js'; import { simpleFetch } from 'simple-typed-fetch'; import bsonObjectId from 'bson-objectid'; -const ObjectID = bsonObjectId.default +const ObjectID = bsonObjectId; const getHistory = async (units: Unit[], address: string, limit = 1000) => { - if (!ethers.utils.isAddress(address)) throw new Error(`Invalid address: ${address}`); + if (!ethers.isAddress(address)) throw new Error(`Invalid address: ${address}`); const data = await Promise.all(units.map(async ({ blockchainService, aggregator, chainId }) => { const sourceNetworkHistory = await simpleFetch(blockchainService.getSourceAtomicSwapHistory)({ limit, diff --git a/src/Orion/bridge/index.ts b/src/Orion/bridge/index.ts index ccadd14..59da9c8 100644 --- a/src/Orion/bridge/index.ts +++ b/src/Orion/bridge/index.ts @@ -229,7 +229,7 @@ export default class Bridge { env?: string | undefined, ) { const secret = generateSecret(); - const secretHash = ethers.utils.keccak256(secret); + const secretHash = ethers.keccak256(secret); const lockExpiration = Date.now() + SECONDS_IN_DAY * EXPIRATION_DAYS * 1000; return { diff --git a/src/Orion/bridge/swap.ts b/src/Orion/bridge/swap.ts index 9fe41be..e9eae6b 100644 --- a/src/Orion/bridge/swap.ts +++ b/src/Orion/bridge/swap.ts @@ -1,6 +1,6 @@ import { BigNumber } from 'bignumber.js'; import { ethers } from 'ethers'; -import { Exchange__factory } from '@orionprotocol/contracts/lib/ethers-v5/index.js'; +import { Exchange__factory } from '@orionprotocol/contracts/lib/ethers-v6'; import getBalances from '../../utils/getBalances.js'; import BalanceGuard from '../../BalanceGuard.js'; import getAvailableSources from '../../utils/getAvailableFundsSources.js'; @@ -123,7 +123,7 @@ export default async function swap({ const sourceChainBalances = await getBalances( { [assetName]: sourceChainAssetAddress, - [sourceChainNativeCryptocurrency]: ethers.constants.AddressZero, + [sourceChainNativeCryptocurrency]: ethers.ZeroAddress, }, sourceAggregator, walletAddress, @@ -134,7 +134,7 @@ export default async function swap({ const targetChainBalances = await getBalances( { [assetName]: targetChainAssetAddress, - [targetChainNativeCryptocurrency]: ethers.constants.AddressZero, + [targetChainNativeCryptocurrency]: ethers.ZeroAddress, }, targetAggregator, walletAddress, @@ -146,7 +146,7 @@ export default async function swap({ sourceChainBalances, { name: sourceChainNativeCryptocurrency, - address: ethers.constants.AddressZero, + address: ethers.ZeroAddress, }, sourceProvider, signer, @@ -157,7 +157,7 @@ export default async function swap({ targetChainBalances, { name: targetChainNativeCryptocurrency, - address: ethers.constants.AddressZero, + address: ethers.ZeroAddress, }, targetProvider, signer, @@ -181,33 +181,33 @@ export default async function swap({ BigNumber.ROUND_FLOOR, ); const secret = generateSecret(); - const secretHash = ethers.utils.keccak256(secret); + const secretHash = ethers.keccak256(secret); options?.logger?.(`Secret is ${secret}`); options?.logger?.(`Secret hash is ${secretHash}`); const secondsInDay = 60 * 60 * 24; const expirationDays = 4; - const expirationEtherBN = ethers.BigNumber.from( + const expirationEtherBN = BigInt( Date.now() + (secondsInDay * expirationDays * 1000), ); - const unsignedLockAtomicTx = await sourceExchangeContract.populateTransaction.lockAtomic({ + const unsignedLockAtomicTx = await sourceExchangeContract.lockAtomic.populateTransaction({ amount: amountBlockchainParam, asset: sourceChainAssetAddress, expiration: expirationEtherBN, secretHash, sender: walletAddress, - targetChainId: ethers.BigNumber.from(targetChain), + targetChainId: BigInt(targetChain), }); - let sourceChainGasPrice: ethers.BigNumber; + let sourceChainGasPrice: bigint; const sourceChainFeeData = await sourceChainUnit.provider.getFeeData(); - if (ethers.BigNumber.isBigNumber(sourceChainFeeData.gasPrice)) { // + if (sourceChainFeeData.gasPrice !== null) { // unsignedLockAtomicTx.gasPrice = sourceChainFeeData.gasPrice; sourceChainGasPrice = sourceChainFeeData.gasPrice; } else if ( - ethers.BigNumber.isBigNumber(sourceChainFeeData.maxFeePerGas) && - ethers.BigNumber.isBigNumber(sourceChainFeeData.maxPriorityFeePerGas) + sourceChainFeeData.maxFeePerGas !== null && + sourceChainFeeData.maxPriorityFeePerGas !== null ) { // EIP-1559 unsignedLockAtomicTx.maxFeePerGas = sourceChainFeeData.maxFeePerGas; unsignedLockAtomicTx.maxPriorityFeePerGas = sourceChainFeeData.maxPriorityFeePerGas; @@ -216,7 +216,7 @@ export default async function swap({ throw new Error('Can\'t get gas price'); } - unsignedLockAtomicTx.chainId = parseInt(chainId, 10); + unsignedLockAtomicTx.chainId = BigInt(chainId); unsignedLockAtomicTx.from = walletAddress; let value = new BigNumber(0); @@ -230,16 +230,16 @@ export default async function swap({ NATIVE_CURRENCY_PRECISION, BigNumber.ROUND_CEIL, ); - unsignedLockAtomicTx.gasLimit = ethers.BigNumber.from(LOCKATOMIC_GAS_LIMIT); + unsignedLockAtomicTx.gasLimit = BigInt(LOCKATOMIC_GAS_LIMIT); - const transactionCost = ethers.BigNumber.from(LOCKATOMIC_GAS_LIMIT).mul(sourceChainGasPrice); - const denormalizedTransactionCost = denormalizeNumber(transactionCost, NATIVE_CURRENCY_PRECISION); + const transactionCost = BigInt(LOCKATOMIC_GAS_LIMIT) * sourceChainGasPrice; + const denormalizedTransactionCost = denormalizeNumber(transactionCost, BigInt(NATIVE_CURRENCY_PRECISION)); sourceChainBalanceGuard.registerRequirement({ reason: 'Network fee', asset: { name: sourceChainNativeCryptocurrency, - address: ethers.constants.AddressZero, + address: ethers.ZeroAddress, }, amount: denormalizedTransactionCost.toString(), sources: ['wallet'] @@ -252,7 +252,7 @@ export default async function swap({ options?.logger?.('Signing lock tx transaction...'); const signedTransaction = await signer.signTransaction(unsignedLockAtomicTx); - const lockAtomicTxResponse = await sourceChainUnit.provider.sendTransaction(signedTransaction); + const lockAtomicTxResponse = await sourceChainUnit.provider.broadcastTransaction(signedTransaction); options?.logger?.(`Lock tx sent. Tx hash: ${lockAtomicTxResponse.hash}. Waiting for tx to be mined...`); await lockAtomicTxResponse.wait(); options?.logger?.('Lock tx mined.'); @@ -280,7 +280,7 @@ export default async function swap({ options?.logger?.('Atomic swap placed.'); // const targetChainGasPriceWei = await simpleFetch(targetBlockchainService.getGasPriceWei)(); - const unsignedRedeemAtomicTx = await targetExchangeContract.populateTransaction.redeemAtomic( + const unsignedRedeemAtomicTx = await targetExchangeContract.redeemAtomic.populateTransaction( { amount: amountBlockchainParam, asset: targetChainAssetAddress, @@ -294,14 +294,14 @@ export default async function swap({ secret ) - let targetChainGasPrice: ethers.BigNumber; + let targetChainGasPrice: bigint; const targetChainFeeData = await targetChainUnit.provider.getFeeData(); - if (ethers.BigNumber.isBigNumber(targetChainFeeData.gasPrice)) { // + if (targetChainFeeData.gasPrice !== null) { // unsignedRedeemAtomicTx.gasPrice = targetChainFeeData.gasPrice; targetChainGasPrice = targetChainFeeData.gasPrice; } else if ( - ethers.BigNumber.isBigNumber(targetChainFeeData.maxFeePerGas) && - ethers.BigNumber.isBigNumber(targetChainFeeData.maxPriorityFeePerGas) + targetChainFeeData.maxFeePerGas !== null && + targetChainFeeData.maxPriorityFeePerGas !== null ) { // EIP-1559 unsignedRedeemAtomicTx.maxFeePerGas = targetChainFeeData.maxFeePerGas; unsignedRedeemAtomicTx.maxPriorityFeePerGas = targetChainFeeData.maxPriorityFeePerGas; @@ -310,18 +310,18 @@ export default async function swap({ throw new Error('Can\'t get gas price'); } - unsignedRedeemAtomicTx.chainId = parseInt(targetChain, 10); + unsignedRedeemAtomicTx.chainId = BigInt(parseInt(targetChain, 10)); unsignedRedeemAtomicTx.from = walletAddress; - unsignedRedeemAtomicTx.gasLimit = ethers.BigNumber.from(REDEEMATOMIC_GAS_LIMIT); + unsignedRedeemAtomicTx.gasLimit = BigInt(REDEEMATOMIC_GAS_LIMIT); - const redeemAtomicTransactionCost = ethers.BigNumber.from(REDEEMATOMIC_GAS_LIMIT).mul(targetChainGasPrice); - const targetDenormalizedTransactionCost = denormalizeNumber(redeemAtomicTransactionCost, NATIVE_CURRENCY_PRECISION); + const redeemAtomicTransactionCost = BigInt(REDEEMATOMIC_GAS_LIMIT) * targetChainGasPrice; + const targetDenormalizedTransactionCost = denormalizeNumber(redeemAtomicTransactionCost, BigInt(NATIVE_CURRENCY_PRECISION)); targetChainBalanceGuard.registerRequirement({ reason: 'Network fee', asset: { name: targetChainNativeCryptocurrency, - address: ethers.constants.AddressZero, + address: ethers.ZeroAddress, }, amount: targetDenormalizedTransactionCost.toString(), sources: ['wallet'] @@ -334,7 +334,7 @@ export default async function swap({ options?.logger?.('Signing redeem tx transaction...'); const targetSignedTransaction = await signer.signTransaction(unsignedRedeemAtomicTx); - const targetLockAtomicTxResponse = await targetChainUnit.provider.sendTransaction(targetSignedTransaction); + const targetLockAtomicTxResponse = await targetChainUnit.provider.broadcastTransaction(targetSignedTransaction); options?.logger?.(`Redeem tx sent. Tx hash: ${targetLockAtomicTxResponse.hash}. Waiting for tx to be mined...`); await targetLockAtomicTxResponse.wait(); @@ -343,16 +343,16 @@ export default async function swap({ if (options?.withdrawToWallet !== undefined && options.withdrawToWallet) { options.logger?.('Withdrawing to wallet...'); - const unsignedWithdrawTx = await targetExchangeContract.populateTransaction.withdraw( + const unsignedWithdrawTx = await targetExchangeContract.withdraw.populateTransaction( targetChainAssetAddress, amountBlockchainParam, ); - if (ethers.BigNumber.isBigNumber(targetChainFeeData.gasPrice)) { // + if (targetChainFeeData.gasPrice !== null) { // unsignedWithdrawTx.gasPrice = targetChainFeeData.gasPrice; targetChainGasPrice = targetChainFeeData.gasPrice; } else if ( - ethers.BigNumber.isBigNumber(targetChainFeeData.maxFeePerGas) && - ethers.BigNumber.isBigNumber(targetChainFeeData.maxPriorityFeePerGas) + targetChainFeeData.maxFeePerGas !== null && + targetChainFeeData.maxPriorityFeePerGas !== null ) { // EIP-1559 unsignedWithdrawTx.maxFeePerGas = targetChainFeeData.maxFeePerGas; unsignedWithdrawTx.maxPriorityFeePerGas = targetChainFeeData.maxPriorityFeePerGas; @@ -360,12 +360,12 @@ export default async function swap({ } else { throw new Error('Can\'t get gas price'); } - unsignedWithdrawTx.chainId = parseInt(targetChain, 10); - unsignedWithdrawTx.gasLimit = ethers.BigNumber.from(WITHDRAW_GAS_LIMIT); + unsignedWithdrawTx.chainId = BigInt(parseInt(targetChain, 10)); + unsignedWithdrawTx.gasLimit = BigInt(WITHDRAW_GAS_LIMIT); unsignedWithdrawTx.from = walletAddress; unsignedWithdrawTx.nonce = await targetProvider.getTransactionCount(walletAddress, 'pending'); const signedTx = await signer.signTransaction(unsignedWithdrawTx); - const withdrawTx = await targetProvider.sendTransaction(signedTx); + const withdrawTx = await targetProvider.broadcastTransaction(signedTx); options.logger?.(`Withdraw tx sent. Tx hash: ${withdrawTx.hash}. Waiting for tx to be mined...`); await withdrawTx.wait(); options.logger?.('Withdraw tx mined.'); diff --git a/src/Unit/Exchange/deposit.ts b/src/Unit/Exchange/deposit.ts index dd3ebf8..96bcbfe 100644 --- a/src/Unit/Exchange/deposit.ts +++ b/src/Unit/Exchange/deposit.ts @@ -1,6 +1,6 @@ import { BigNumber } from 'bignumber.js'; import { ethers } from 'ethers'; -import { Exchange__factory } from '@orionprotocol/contracts/lib/ethers-v5/index.js'; +import { Exchange__factory } from '@orionprotocol/contracts/lib/ethers-v6'; import getBalances from '../../utils/getBalances.js'; import BalanceGuard from '../../BalanceGuard.js'; import type Unit from '../index.js'; @@ -51,7 +51,7 @@ export default async function deposit({ const balances = await getBalances( { [asset]: assetAddress, - [nativeCryptocurrency]: ethers.constants.AddressZero, + [nativeCryptocurrency]: ethers.ZeroAddress, }, aggregator, walletAddress, @@ -63,7 +63,7 @@ export default async function deposit({ balances, { name: nativeCryptocurrency, - address: ethers.constants.AddressZero, + address: ethers.ZeroAddress, }, provider, signer, @@ -80,34 +80,34 @@ export default async function deposit({ sources: ['wallet'], }); - let unsignedTx: ethers.PopulatedTransaction; + let unsignedTx: ethers.TransactionLike; if (asset === nativeCryptocurrency) { - unsignedTx = await exchangeContract.populateTransaction.deposit(); + unsignedTx = await exchangeContract.deposit.populateTransaction(); unsignedTx.value = normalizeNumber(amount, NATIVE_CURRENCY_PRECISION, BigNumber.ROUND_CEIL); - unsignedTx.gasLimit = ethers.BigNumber.from(DEPOSIT_ETH_GAS_LIMIT); + unsignedTx.gasLimit = BigInt(DEPOSIT_ETH_GAS_LIMIT); } else { - unsignedTx = await exchangeContract.populateTransaction.depositAsset( + unsignedTx = await exchangeContract.depositAsset.populateTransaction( assetAddress, normalizeNumber(amount, INTERNAL_PROTOCOL_PRECISION, BigNumber.ROUND_CEIL), ); - unsignedTx.gasLimit = ethers.BigNumber.from(DEPOSIT_ERC20_GAS_LIMIT); + unsignedTx.gasLimit = BigInt(DEPOSIT_ERC20_GAS_LIMIT); } - const transactionCost = ethers.BigNumber.from(unsignedTx.gasLimit).mul(gasPriceWei); - const denormalizedTransactionCost = denormalizeNumber(transactionCost, NATIVE_CURRENCY_PRECISION); + const transactionCost = BigInt(unsignedTx.gasLimit) * BigInt(gasPriceWei); + const denormalizedTransactionCost = denormalizeNumber(transactionCost, BigInt(NATIVE_CURRENCY_PRECISION)); balanceGuard.registerRequirement({ reason: 'Network fee', asset: { name: nativeCryptocurrency, - address: ethers.constants.AddressZero, + address: ethers.ZeroAddress, }, amount: denormalizedTransactionCost.toString(), sources: ['wallet'], }); unsignedTx.chainId = parseInt(chainId, 10); - unsignedTx.gasPrice = ethers.BigNumber.from(gasPriceWei); + unsignedTx.gasPrice = BigInt(gasPriceWei); unsignedTx.from = walletAddress; await balanceGuard.check(true); @@ -117,10 +117,10 @@ export default async function deposit({ const signedTx = await signer.signTransaction(unsignedTx); try { - const txResponse = await provider.sendTransaction(signedTx); + const txResponse = await provider.broadcastTransaction(signedTx); console.log(`Deposit tx sent: ${txResponse.hash}. Waiting for confirmation...`); const txReceipt = await txResponse.wait(); - if (txReceipt.status !== undefined) { + if (txReceipt?.status !== undefined) { console.log('Deposit tx confirmed'); } else { console.log('Deposit tx failed'); diff --git a/src/Unit/Exchange/generateSwapCalldata.ts b/src/Unit/Exchange/generateSwapCalldata.ts index 11b56b0..76e9fe3 100644 --- a/src/Unit/Exchange/generateSwapCalldata.ts +++ b/src/Unit/Exchange/generateSwapCalldata.ts @@ -1,11 +1,10 @@ -import type { ExchangeWithGenericSwap } from '@orionprotocol/contracts/lib/ethers-v5/Exchange.js'; -import { UniswapV3Pool__factory, ERC20__factory, SwapExecutor__factory, CurveRegistry__factory } from '@orionprotocol/contracts/lib/ethers-v5/index.js'; -import { BigNumber, ethers, type BigNumberish } from 'ethers'; -import { concat, defaultAbiCoder, type BytesLike } from 'ethers/lib/utils.js'; +import type { ExchangeWithGenericSwap } from '@orionprotocol/contracts/lib/ethers-v6/Exchange.js'; +import { UniswapV3Pool__factory, ERC20__factory, SwapExecutor__factory, CurveRegistry__factory } from '@orionprotocol/contracts/lib/ethers-v6'; +import { ethers, type BigNumberish, type AddressLike, concat, type BytesLike } from 'ethers'; import { safeGet, SafeArray } from '../../utils/safeGetters.js'; import type Unit from '../index.js'; import { simpleFetch } from 'simple-typed-fetch'; -import type { PromiseOrValue } from '@orionprotocol/contracts/lib/ethers-v5/common.js'; +import { BigNumber } from 'bignumber.js'; const EXECUTOR_SWAP_FUNCTION = 'func_70LYiww' @@ -64,20 +63,24 @@ export default async function generateSwapCalldata({ flags: 0 } - const exchangeToNativeDecimals = async (token: PromiseOrValue) => { - token = await token - let decimals = 18 - if (token !== ethers.constants.AddressZero) { + const exchangeToNativeDecimals = async (token: AddressLike) => { + if (typeof token !== 'string' && 'getAddress' in token) { + token = await token.getAddress(); + } else { + token = await token + } + let decimals = 18n + if (token !== ethers.ZeroAddress) { const contract = ERC20__factory.connect(token, unit.provider) decimals = await contract.decimals() } - return BigNumber.from(amount).mul(BigNumber.from(10).pow(decimals)).div(BigNumber.from(10).pow(8)) + return BigNumber(amount.toString()).multipliedBy(BigNumber(10).pow(decimals.toString())).div(BigNumber(10).pow(8)) } const amountNativeDecimals = await exchangeToNativeDecimals(swapDescription.srcToken); path = SafeArray.from(path_).map((swapInfo) => { - if (swapInfo.assetIn == ethers.constants.AddressZero) swapInfo.assetIn = wethAddress - if (swapInfo.assetOut == ethers.constants.AddressZero) swapInfo.assetOut = wethAddress + if (swapInfo.assetIn == ethers.ZeroAddress) swapInfo.assetIn = wethAddress + if (swapInfo.assetOut == ethers.ZeroAddress) swapInfo.assetOut = wethAddress return swapInfo; }); @@ -94,16 +97,16 @@ export default async function generateSwapCalldata({ break; } case 'UniswapV3': { - calldata = await generateUni3Calls(amountNativeDecimals, exchangeContractAddress, path, unit.provider) + calldata = await generateUni3Calls(amountNativeDecimals.toString(), exchangeContractAddress, path, unit.provider) break; } case 'OrionV3': { - calldata = await generateOrion3Calls(amountNativeDecimals, exchangeContractAddress, path, unit.provider) + calldata = await generateOrion3Calls(amountNativeDecimals.toString(), exchangeContractAddress, path, unit.provider) break; } case 'Curve': { calldata = await generateCurveStableSwapCalls( - amountNativeDecimals, + amountNativeDecimals.toString(), exchangeContractAddress, swapExecutorContractAddress ?? '', path, @@ -134,7 +137,7 @@ export async function generateUni2Calls( currentSwap.pool, currentSwap.assetIn, currentSwap.assetOut, - defaultAbiCoder.encode(['uint256'], [concat(['0x03', nextSwap.pool])]), + ethers.AbiCoder.defaultAbiCoder().encode(['uint256'], [concat(['0x03', nextSwap.pool])]), ] ) calls.push(addCallParams(calldata)) @@ -145,7 +148,7 @@ export async function generateUni2Calls( lastSwap.pool, lastSwap.assetIn, lastSwap.assetOut, - defaultAbiCoder.encode(['uint256'], [concat(['0x03', exchangeAddress])]), + ethers.AbiCoder.defaultAbiCoder().encode(['uint256'], [concat(['0x03', exchangeAddress])]), ]) calls.push(addCallParams(calldata)) @@ -156,22 +159,22 @@ async function generateUni3Calls( amount: BigNumberish, exchangeContractAddress: string, path: SafeArray, - provider: ethers.providers.JsonRpcProvider + provider: ethers.JsonRpcApiProvider ) { - const encodedPools: BytesLike[] = [] + const encodedPools: string[] = [] for (const swap of path) { const pool = UniswapV3Pool__factory.connect(swap.pool, provider) const token0 = await pool.token0() const zeroForOne = token0.toLowerCase() === swap.assetIn.toLowerCase() - const unwrapWETH = swap.assetOut === ethers.constants.AddressZero + const unwrapWETH = swap.assetOut === ethers.ZeroAddress - let encodedPool = ethers.utils.solidityPack(['uint256'], [pool.address]) - encodedPool = ethers.utils.hexDataSlice(encodedPool, 1) + let encodedPool = ethers.solidityPacked(['uint256'], [await pool.getAddress()]) + encodedPool = ethers.dataSlice(encodedPool, 1) let firstByte = 0 if (unwrapWETH) firstByte += 32 if (!zeroForOne) firstByte += 128 - const encodedFirstByte = ethers.utils.solidityPack(['uint8'], [firstByte]) - encodedPool = ethers.utils.hexlify(ethers.utils.concat([encodedFirstByte, encodedPool])) + const encodedFirstByte = ethers.solidityPacked(['uint8'], [firstByte]) + encodedPool = ethers.hexlify(ethers.concat([encodedFirstByte, encodedPool])) encodedPools.push(encodedPool) } const executorInterface = SwapExecutor__factory.createInterface() @@ -185,22 +188,22 @@ async function generateOrion3Calls( amount: BigNumberish, exchangeContractAddress: string, path: SafeArray, - provider: ethers.providers.JsonRpcProvider + provider: ethers.JsonRpcApiProvider ) { - const encodedPools: BytesLike[] = [] + const encodedPools: string[] = [] for (const swap of path) { const pool = UniswapV3Pool__factory.connect(swap.pool, provider) const token0 = await pool.token0() const zeroForOne = token0.toLowerCase() === swap.assetIn.toLowerCase() - const unwrapWETH = swap.assetOut === ethers.constants.AddressZero + const unwrapWETH = swap.assetOut === ethers.ZeroAddress - let encodedPool = ethers.utils.solidityPack(['uint256'], [pool.address]) - encodedPool = ethers.utils.hexDataSlice(encodedPool, 1) + let encodedPool = ethers.solidityPacked(['uint256'], [await pool.getAddress()]) + encodedPool = ethers.dataSlice(encodedPool, 1) let firstByte = 0 if (unwrapWETH) firstByte += 32 if (!zeroForOne) firstByte += 128 - const encodedFirstByte = ethers.utils.solidityPack(['uint8'], [firstByte]) - encodedPool = ethers.utils.hexlify(ethers.utils.concat([encodedFirstByte, encodedPool])) + const encodedFirstByte = ethers.solidityPacked(['uint8'], [firstByte]) + encodedPool = ethers.hexlify(ethers.concat([encodedFirstByte, encodedPool])) encodedPools.push(encodedPool) } const executorInterface = SwapExecutor__factory.createInterface() @@ -215,7 +218,7 @@ async function generateCurveStableSwapCalls( exchangeContractAddress: string, executorAddress: string, path: SafeArray, - provider: ethers.providers.JsonRpcProvider, + provider: ethers.JsonRpcProvider, curveRegistry: string ) { if (path.length > 1) { @@ -231,12 +234,12 @@ async function generateCurveStableSwapCalls( const executorAllowance = await firstToken.allowance(executorAddress, swap.pool) const calls: BytesLike[] = [] - if (executorAllowance.lt(amount)) { + if (executorAllowance < BigInt(amount)) { const calldata = addCallParams( executorInterface.encodeFunctionData('safeApprove', [ swap.assetIn, swap.pool, - ethers.constants.MaxUint256 + ethers.MaxUint256 ]) ) calls.push(calldata) @@ -265,28 +268,28 @@ function addCallParams( if (callParams) { if (callParams.value !== undefined) { firstByte += 16 // 00010000 - const encodedValue = ethers.utils.solidityPack(['uint128'], [callParams.value]) - calldata = ethers.utils.hexlify(ethers.utils.concat([encodedValue, calldata])) + const encodedValue = ethers.solidityPacked(['uint128'], [callParams.value]) + calldata = ethers.hexlify(ethers.concat([encodedValue, calldata])) } if (callParams.target !== undefined) { firstByte += 32 // 00100000 - const encodedAddress = ethers.utils.solidityPack(['address'], [callParams.target]) - calldata = ethers.utils.hexlify(ethers.utils.concat([encodedAddress, calldata])) + const encodedAddress = ethers.solidityPacked(['address'], [callParams.target]) + calldata = ethers.hexlify(ethers.concat([encodedAddress, calldata])) } if (callParams.gaslimit !== undefined) { firstByte += 64 // 01000000 - const encodedGaslimit = ethers.utils.solidityPack(['uint32'], [callParams.gaslimit]) - calldata = ethers.utils.hexlify(ethers.utils.concat([encodedGaslimit, calldata])) + const encodedGaslimit = ethers.solidityPacked(['uint32'], [callParams.gaslimit]) + calldata = ethers.hexlify(ethers.concat([encodedGaslimit, calldata])) } if (callParams.isMandatory !== undefined) firstByte += 128 // 10000000 } - const encodedFirstByte = ethers.utils.solidityPack(['uint8'], [firstByte]) - calldata = ethers.utils.hexlify(ethers.utils.concat([encodedFirstByte, calldata])) + const encodedFirstByte = ethers.solidityPacked(['uint8'], [firstByte]) + calldata = ethers.hexlify(ethers.concat([encodedFirstByte, calldata])) return calldata } -async function generateCalls(calls: BytesLike[]) { +function generateCalls(calls: BytesLike[]) { const executorInterface = SwapExecutor__factory.createInterface() - return '0x' + executorInterface.encodeFunctionData(EXECUTOR_SWAP_FUNCTION, [ethers.constants.AddressZero, calls]).slice(74) + return '0x' + executorInterface.encodeFunctionData(EXECUTOR_SWAP_FUNCTION, [ethers.ZeroAddress, calls]).slice(74) } diff --git a/src/Unit/Exchange/getSwapInfo.ts b/src/Unit/Exchange/getSwapInfo.ts index aa3e315..02cd26d 100644 --- a/src/Unit/Exchange/getSwapInfo.ts +++ b/src/Unit/Exchange/getSwapInfo.ts @@ -51,7 +51,7 @@ export default async function getSwapInfo({ const allPrices = await simpleFetch(blockchainService.getPricesWithQuoteAsset)(); const gasPriceWei = await simpleFetch(blockchainService.getGasPriceWei)(); - const gasPriceGwei = ethers.utils.formatUnits(gasPriceWei, 'gwei').toString(); + const gasPriceGwei = ethers.formatUnits(gasPriceWei, 'gwei').toString(); const assetInAddress = assetToAddress[assetIn]; if (assetInAddress === undefined) throw new Error(`Asset '${assetIn}' not found`); @@ -101,15 +101,15 @@ export default async function getSwapInfo({ } if (route === 'pool') { - const transactionCost = ethers.BigNumber.from(SWAP_THROUGH_ORION_POOL_GAS_LIMIT).mul(gasPriceWei); - const denormalizedTransactionCost = denormalizeNumber(transactionCost, NATIVE_CURRENCY_PRECISION); + const transactionCost = BigInt(SWAP_THROUGH_ORION_POOL_GAS_LIMIT) * BigInt(gasPriceWei); + const denormalizedTransactionCost = denormalizeNumber(transactionCost, BigInt(NATIVE_CURRENCY_PRECISION)); return { route, swapInfo, fee: { assetName: nativeCryptocurrencyName, - assetAddress: ethers.constants.AddressZero, + assetAddress: ethers.ZeroAddress, networkFeeInFeeAsset: denormalizedTransactionCost.toString(), protocolFeeInFeeAsset: undefined, }, @@ -134,7 +134,7 @@ export default async function getSwapInfo({ gasPriceGwei, feePercent, baseAssetAddress, - ethers.constants.AddressZero, + ethers.ZeroAddress, feeAssetAddress, allPrices.prices ); diff --git a/src/Unit/Exchange/swapLimit.ts b/src/Unit/Exchange/swapLimit.ts index 11a9d06..e9d7492 100644 --- a/src/Unit/Exchange/swapLimit.ts +++ b/src/Unit/Exchange/swapLimit.ts @@ -1,6 +1,6 @@ import { BigNumber } from 'bignumber.js'; import { ethers } from 'ethers'; -import { Exchange__factory } from '@orionprotocol/contracts/lib/ethers-v5/index.js'; +import { Exchange__factory } from '@orionprotocol/contracts/lib/ethers-v6/index.js'; import getBalances from '../../utils/getBalances.js'; import BalanceGuard from '../../BalanceGuard.js'; import getAvailableSources from '../../utils/getAvailableFundsSources.js'; @@ -44,7 +44,7 @@ type PoolSwap = { amountOut: number through: 'pool' txHash: string - wait: (confirmations?: number | undefined) => Promise + wait: (confirmations?: number | undefined) => Promise } export type Swap = AggregatorOrder | PoolSwap; @@ -95,7 +95,7 @@ export default async function swapLimit({ const { factories } = await simpleFetch(blockchainService.getPoolsConfig)(); const poolExchangesList = factories !== undefined ? Object.keys(factories) : []; - const gasPriceGwei = ethers.utils.formatUnits(gasPriceWei, 'gwei').toString(); + const gasPriceGwei = ethers.formatUnits(gasPriceWei, 'gwei').toString(); const assetInAddress = assetToAddress[assetIn]; if (assetInAddress === undefined) throw new Error(`Asset '${assetIn}' not found`); @@ -108,7 +108,7 @@ export default async function swapLimit({ { [assetIn]: assetInAddress, [feeAsset]: feeAssetAddress, - [nativeCryptocurrency]: ethers.constants.AddressZero, + [nativeCryptocurrency]: ethers.ZeroAddress, }, aggregator, walletAddress, @@ -120,7 +120,7 @@ export default async function swapLimit({ balances, { name: nativeCryptocurrency, - address: ethers.constants.AddressZero, + address: ethers.ZeroAddress, }, provider, signer, @@ -271,7 +271,7 @@ export default async function swapLimit({ BigNumber.ROUND_FLOOR, ); - const unsignedSwapThroughOrionPoolTx = await exchangeContract.populateTransaction.swapThroughOrionPool( + const unsignedSwapThroughOrionPoolTx = await exchangeContract.swapThroughOrionPool.populateTransaction( amountSpendBlockchainParam, amountReceiveBlockchainParam, factoryAddress !== undefined @@ -280,8 +280,8 @@ export default async function swapLimit({ type === 'exactSpend', ); - unsignedSwapThroughOrionPoolTx.chainId = parseInt(chainId, 10); - unsignedSwapThroughOrionPoolTx.gasPrice = ethers.BigNumber.from(gasPriceWei); + unsignedSwapThroughOrionPoolTx.chainId = BigInt(parseInt(chainId, 10)); + unsignedSwapThroughOrionPoolTx.gasPrice = BigInt(gasPriceWei); unsignedSwapThroughOrionPoolTx.from = walletAddress; const amountSpendBN = new BigNumber(amountSpend); @@ -297,19 +297,19 @@ export default async function swapLimit({ NATIVE_CURRENCY_PRECISION, BigNumber.ROUND_CEIL, ); - unsignedSwapThroughOrionPoolTx.gasLimit = ethers.BigNumber.from(SWAP_THROUGH_ORION_POOL_GAS_LIMIT); + unsignedSwapThroughOrionPoolTx.gasLimit = BigInt(SWAP_THROUGH_ORION_POOL_GAS_LIMIT); - const transactionCost = ethers.BigNumber.from(SWAP_THROUGH_ORION_POOL_GAS_LIMIT).mul(gasPriceWei); - const denormalizedTransactionCost = denormalizeNumber(transactionCost, NATIVE_CURRENCY_PRECISION); + const transactionCost = BigInt(SWAP_THROUGH_ORION_POOL_GAS_LIMIT) * BigInt(gasPriceWei); + const denormalizedTransactionCost = denormalizeNumber(transactionCost, BigInt(NATIVE_CURRENCY_PRECISION)); balanceGuard.registerRequirement({ reason: 'Network fee', asset: { name: nativeCryptocurrency, - address: ethers.constants.AddressZero, + address: ethers.ZeroAddress, }, amount: denormalizedTransactionCost.toString(), - sources: getAvailableSources('network_fee', ethers.constants.AddressZero, 'pool'), + sources: getAvailableSources('network_fee', ethers.ZeroAddress, 'pool'), }); // if (value.gt(0)) { @@ -317,10 +317,10 @@ export default async function swapLimit({ // reason: 'Transaction value (extra amount)', // asset: { // name: nativeCryptocurrency, - // address: ethers.constants.AddressZero, + // address: ethers.ZeroAddress, // }, // amount: value.toString(), - // sources: getAvailableSources('amount', ethers.constants.AddressZero, 'pool'), + // sources: getAvailableSources('amount', ethers.ZeroAddress, 'pool'), // }); // } @@ -380,7 +380,7 @@ export default async function swapLimit({ gasPriceGwei, feePercent, baseAssetAddress, - ethers.constants.AddressZero, + ethers.ZeroAddress, feeAssetAddress, allPrices.prices, ); diff --git a/src/Unit/Exchange/swapMarket.ts b/src/Unit/Exchange/swapMarket.ts index 22ceaf1..90c6bd4 100644 --- a/src/Unit/Exchange/swapMarket.ts +++ b/src/Unit/Exchange/swapMarket.ts @@ -1,6 +1,6 @@ import { BigNumber } from 'bignumber.js'; import { ethers } from 'ethers'; -import { Exchange__factory } from '@orionprotocol/contracts/lib/ethers-v5/index.js'; +import { Exchange__factory } from '@orionprotocol/contracts/lib/ethers-v6/index.js'; import getBalances from '../../utils/getBalances.js'; import BalanceGuard from '../../BalanceGuard.js'; import getAvailableSources from '../../utils/getAvailableFundsSources.js'; @@ -28,7 +28,7 @@ type PoolSwap = { amountOut: number through: 'pool' txHash: string - wait: (confirmations?: number | undefined) => Promise + wait: (confirmations?: number | undefined) => Promise } export type Swap = AggregatorOrder | PoolSwap; @@ -80,7 +80,7 @@ export default async function swapMarket({ const { factories } = await simpleFetch(blockchainService.getPoolsConfig)(); const poolExchangesList = factories !== undefined ? Object.keys(factories) : []; - const gasPriceGwei = ethers.utils.formatUnits(gasPriceWei, 'gwei').toString(); + const gasPriceGwei = ethers.formatUnits(gasPriceWei, 'gwei').toString(); const assetInAddress = assetToAddress[assetIn]; if (assetInAddress === undefined) throw new Error(`Asset '${assetIn}' not found`); @@ -93,7 +93,7 @@ export default async function swapMarket({ { [assetIn]: assetInAddress, [feeAsset]: feeAssetAddress, - [nativeCryptocurrency]: ethers.constants.AddressZero, + [nativeCryptocurrency]: ethers.ZeroAddress, }, aggregator, walletAddress, @@ -105,7 +105,7 @@ export default async function swapMarket({ balances, { name: nativeCryptocurrency, - address: ethers.constants.AddressZero, + address: ethers.ZeroAddress, }, provider, signer, @@ -221,17 +221,17 @@ export default async function swapMarket({ INTERNAL_PROTOCOL_PRECISION, BigNumber.ROUND_FLOOR, ); - const unsignedSwapThroughOrionPoolTx = await exchangeContract.populateTransaction.swapThroughOrionPool( - amountSpendBlockchainParam, - amountReceiveBlockchainParam, + const unsignedSwapThroughOrionPoolTx = await exchangeContract.swapThroughOrionPool.populateTransaction( + amountSpendBlockchainParam.toString(), + amountReceiveBlockchainParam.toString(), factoryAddress !== undefined ? [factoryAddress, ...pathAddresses] : pathAddresses, type === 'exactSpend', ); - unsignedSwapThroughOrionPoolTx.chainId = parseInt(chainId, 10); - unsignedSwapThroughOrionPoolTx.gasPrice = ethers.BigNumber.from(gasPriceWei); + unsignedSwapThroughOrionPoolTx.chainId = BigInt(chainId); + unsignedSwapThroughOrionPoolTx.gasPrice = BigInt(gasPriceWei); unsignedSwapThroughOrionPoolTx.from = walletAddress; const amountSpendBN = new BigNumber(amountSpend); @@ -247,19 +247,19 @@ export default async function swapMarket({ NATIVE_CURRENCY_PRECISION, BigNumber.ROUND_CEIL, ); - unsignedSwapThroughOrionPoolTx.gasLimit = ethers.BigNumber.from(SWAP_THROUGH_ORION_POOL_GAS_LIMIT); + unsignedSwapThroughOrionPoolTx.gasLimit = BigInt(SWAP_THROUGH_ORION_POOL_GAS_LIMIT); - const transactionCost = ethers.BigNumber.from(SWAP_THROUGH_ORION_POOL_GAS_LIMIT).mul(gasPriceWei); - const denormalizedTransactionCost = denormalizeNumber(transactionCost, NATIVE_CURRENCY_PRECISION); + const transactionCost = BigInt(SWAP_THROUGH_ORION_POOL_GAS_LIMIT) * BigInt(gasPriceWei); + const denormalizedTransactionCost = denormalizeNumber(transactionCost, BigInt(NATIVE_CURRENCY_PRECISION)); balanceGuard.registerRequirement({ reason: 'Network fee', asset: { name: nativeCryptocurrency, - address: ethers.constants.AddressZero, + address: ethers.ZeroAddress, }, amount: denormalizedTransactionCost.toString(), - sources: getAvailableSources('network_fee', ethers.constants.AddressZero, 'pool'), + sources: getAvailableSources('network_fee', ethers.ZeroAddress, 'pool'), }); // if (value.gt(0)) { @@ -267,10 +267,10 @@ export default async function swapMarket({ // reason: 'Transaction value (extra amount)', // asset: { // name: nativeCryptocurrency, - // address: ethers.constants.AddressZero, + // address: ethers.ZeroAddress, // }, // amount: value.toString(), - // sources: getAvailableSources('amount', ethers.constants.AddressZero, 'pool'), + // sources: getAvailableSources('amount', ethers.ZeroAddress, 'pool'), // }); // } @@ -338,7 +338,7 @@ export default async function swapMarket({ gasPriceGwei, feePercent, baseAssetAddress, - ethers.constants.AddressZero, + ethers.ZeroAddress, feeAssetAddress, allPrices.prices, ); diff --git a/src/Unit/Exchange/withdraw.ts b/src/Unit/Exchange/withdraw.ts index 90ac0df..9b5d2d7 100644 --- a/src/Unit/Exchange/withdraw.ts +++ b/src/Unit/Exchange/withdraw.ts @@ -1,6 +1,6 @@ import { BigNumber } from 'bignumber.js'; import { ethers } from 'ethers'; -import { Exchange__factory } from '@orionprotocol/contracts/lib/ethers-v5/index.js'; +import { Exchange__factory } from '@orionprotocol/contracts/lib/ethers-v6/index.js'; import getBalances from '../../utils/getBalances.js'; import BalanceGuard from '../../BalanceGuard.js'; import type Unit from '../index.js'; @@ -50,7 +50,7 @@ export default async function withdraw({ const balances = await getBalances( { [asset]: assetAddress, - [nativeCryptocurrency]: ethers.constants.AddressZero, + [nativeCryptocurrency]: ethers.ZeroAddress, }, aggregator, walletAddress, @@ -62,7 +62,7 @@ export default async function withdraw({ balances, { name: nativeCryptocurrency, - address: ethers.constants.AddressZero, + address: ethers.ZeroAddress, }, provider, signer, @@ -78,27 +78,27 @@ export default async function withdraw({ sources: ['exchange'], }); - const unsignedTx = await exchangeContract.populateTransaction.withdraw( + const unsignedTx = await exchangeContract.withdraw.populateTransaction( assetAddress, - normalizeNumber(amount, INTERNAL_PROTOCOL_PRECISION, BigNumber.ROUND_FLOOR), + normalizeNumber(amount, INTERNAL_PROTOCOL_PRECISION, BigNumber.ROUND_FLOOR).toString(), ); - unsignedTx.gasLimit = ethers.BigNumber.from(WITHDRAW_GAS_LIMIT); + unsignedTx.gasLimit = BigInt(WITHDRAW_GAS_LIMIT); - const transactionCost = ethers.BigNumber.from(unsignedTx.gasLimit).mul(gasPriceWei); - const denormalizedTransactionCost = denormalizeNumber(transactionCost, NATIVE_CURRENCY_PRECISION); + const transactionCost = BigInt(unsignedTx.gasLimit) * BigInt(gasPriceWei); + const denormalizedTransactionCost = denormalizeNumber(transactionCost, BigInt(NATIVE_CURRENCY_PRECISION)); balanceGuard.registerRequirement({ reason: 'Network fee', asset: { name: nativeCryptocurrency, - address: ethers.constants.AddressZero, + address: ethers.ZeroAddress, }, amount: denormalizedTransactionCost.toString(), sources: ['wallet'], }); - unsignedTx.chainId = parseInt(chainId, 10); - unsignedTx.gasPrice = ethers.BigNumber.from(gasPriceWei); + unsignedTx.chainId = BigInt(chainId); + unsignedTx.gasPrice = BigInt(gasPriceWei); unsignedTx.from = walletAddress; await balanceGuard.check(true); @@ -107,11 +107,11 @@ export default async function withdraw({ unsignedTx.nonce = nonce; const signedTx = await signer.signTransaction(unsignedTx); - const txResponse = await provider.sendTransaction(signedTx); + const txResponse = await provider.broadcastTransaction(signedTx); console.log(`Withdraw tx sent: ${txResponse.hash}. Waiting for confirmation...`); try { const txReceipt = await txResponse.wait(); - if (txReceipt.status !== undefined) { + if (txReceipt?.status !== undefined) { console.log('Withdraw tx confirmed'); } else { console.log('Withdraw tx failed'); diff --git a/src/Unit/FarmingManager/index.ts b/src/Unit/FarmingManager/index.ts index a650d60..f4f7fbb 100644 --- a/src/Unit/FarmingManager/index.ts +++ b/src/Unit/FarmingManager/index.ts @@ -1,4 +1,4 @@ -import { Exchange__factory, IUniswapV2Pair__factory, IUniswapV2Router__factory } from '@orionprotocol/contracts/lib/ethers-v5/index.js'; +import { Exchange__factory, IUniswapV2Pair__factory, IUniswapV2Router__factory } from '@orionprotocol/contracts/lib/ethers-v6/index.js'; import { BigNumber } from 'bignumber.js'; import { ethers } from 'ethers'; import { simpleFetch } from 'simple-typed-fetch'; @@ -71,7 +71,7 @@ export default class FarmingManager { { [assetA]: assetAAddress, [assetB]: assetBAddress, - [nativeCryptocurrency]: ethers.constants.AddressZero, + [nativeCryptocurrency]: ethers.ZeroAddress, }, this.unit.aggregator, walletAddress, @@ -81,7 +81,7 @@ export default class FarmingManager { const balanceGuard = new BalanceGuard( balances, { - address: ethers.constants.AddressZero, + address: ethers.ZeroAddress, name: nativeCryptocurrency, }, this.unit.provider, @@ -109,13 +109,13 @@ export default class FarmingManager { const assetAReserve = pairTokensIsInversed ? _reserve1 : _reserve0; const assetBReserve = pairTokensIsInversed ? _reserve0 : _reserve1; - const denormalizedAssetAReserve = denormalizeNumber(assetAReserve, assetADecimals); - const denormalizedAssetBReserve = denormalizeNumber(assetBReserve, assetBDecimals); + const denormalizedAssetAReserve = denormalizeNumber(assetAReserve, BigInt(assetADecimals)); + const denormalizedAssetBReserve = denormalizeNumber(assetBReserve, BigInt(assetBDecimals)); const price = denormalizedAssetBReserve.div(denormalizedAssetAReserve); - const assetAIsNativeCurrency = assetAAddress === ethers.constants.AddressZero; - const assetBIsNativeCurrency = assetBAddress === ethers.constants.AddressZero; + const assetAIsNativeCurrency = assetAAddress === ethers.ZeroAddress; + const assetBIsNativeCurrency = assetBAddress === ethers.ZeroAddress; const assetAAmount = assetA === amountAsset ? amountBN : amountBN.div(price); const assetBAmount = assetA === amountAsset ? amountBN.multipliedBy(price) : amountBN; @@ -145,33 +145,33 @@ export default class FarmingManager { sources: ['exchange', 'wallet'], }); - const unsignedTx = await exchangeContract.populateTransaction.withdrawToPool( + const unsignedTx = await exchangeContract.withdrawToPool.populateTransaction( assetBIsNativeCurrency ? assetBAddress : assetAAddress, assetBIsNativeCurrency ? assetAAddress : assetBAddress, assetBIsNativeCurrency - ? normalizeNumber(assetBAmount, INTERNAL_PROTOCOL_PRECISION, BigNumber.ROUND_FLOOR) - : normalizeNumber(assetAAmount, INTERNAL_PROTOCOL_PRECISION, BigNumber.ROUND_FLOOR), + ? normalizeNumber(assetBAmount, INTERNAL_PROTOCOL_PRECISION, BigNumber.ROUND_FLOOR).toString() + : normalizeNumber(assetAAmount, INTERNAL_PROTOCOL_PRECISION, BigNumber.ROUND_FLOOR).toString(), assetBIsNativeCurrency - ? normalizeNumber(assetAAmount, INTERNAL_PROTOCOL_PRECISION, BigNumber.ROUND_FLOOR) - : normalizeNumber(assetBAmount, INTERNAL_PROTOCOL_PRECISION, BigNumber.ROUND_FLOOR), + ? normalizeNumber(assetAAmount, INTERNAL_PROTOCOL_PRECISION, BigNumber.ROUND_FLOOR).toString() + : normalizeNumber(assetBAmount, INTERNAL_PROTOCOL_PRECISION, BigNumber.ROUND_FLOOR).toString(), assetBIsNativeCurrency - ? normalizeNumber(assetBAmountWithSlippage, INTERNAL_PROTOCOL_PRECISION, BigNumber.ROUND_FLOOR) - : normalizeNumber(assetAAmountWithSlippage, INTERNAL_PROTOCOL_PRECISION, BigNumber.ROUND_FLOOR), + ? normalizeNumber(assetBAmountWithSlippage, INTERNAL_PROTOCOL_PRECISION, BigNumber.ROUND_FLOOR).toString() + : normalizeNumber(assetAAmountWithSlippage, INTERNAL_PROTOCOL_PRECISION, BigNumber.ROUND_FLOOR).toString(), assetBIsNativeCurrency - ? normalizeNumber(assetAAmountWithSlippage, INTERNAL_PROTOCOL_PRECISION, BigNumber.ROUND_FLOOR) - : normalizeNumber(assetBAmountWithSlippage, INTERNAL_PROTOCOL_PRECISION, BigNumber.ROUND_FLOOR), + ? normalizeNumber(assetAAmountWithSlippage, INTERNAL_PROTOCOL_PRECISION, BigNumber.ROUND_FLOOR).toString() + : normalizeNumber(assetBAmountWithSlippage, INTERNAL_PROTOCOL_PRECISION, BigNumber.ROUND_FLOOR).toString(), ); - const gasPrice = await this.unit.provider.getGasPrice(); + const { gasPrice, maxFeePerGas } = await this.unit.provider.getFeeData(); - const transactionCost = ethers.BigNumber.from(ADD_LIQUIDITY_GAS_LIMIT).mul(gasPrice); - const denormalizedTransactionCost = denormalizeNumber(transactionCost, NATIVE_CURRENCY_PRECISION); + const transactionCost = BigInt(ADD_LIQUIDITY_GAS_LIMIT) * (gasPrice ?? 0n); + const denormalizedTransactionCost = denormalizeNumber(transactionCost, BigInt(NATIVE_CURRENCY_PRECISION)); balanceGuard.registerRequirement({ reason: 'Network fee', asset: { name: nativeCryptocurrency, - address: ethers.constants.AddressZero, + address: ethers.ZeroAddress, }, amount: denormalizedTransactionCost.toString(), sources: ['wallet'], @@ -195,8 +195,11 @@ export default class FarmingManager { } } + if (gasPrice !== null && maxFeePerGas !== null) { + unsignedTx.gasPrice = gasPrice; + unsignedTx.maxFeePerGas = maxFeePerGas; + } unsignedTx.chainId = network.chainId; - unsignedTx.gasPrice = gasPrice; unsignedTx.nonce = nonce; unsignedTx.from = walletAddress; const gasLimit = await this.unit.provider.estimateGas(unsignedTx); @@ -205,13 +208,13 @@ export default class FarmingManager { await balanceGuard.check(true); const signedTx = await signer.signTransaction(unsignedTx); - const txResponse = await this.unit.provider.sendTransaction(signedTx); + const txResponse = await this.unit.provider.broadcastTransaction(signedTx); console.log(`Add liquidity tx sent: ${txResponse.hash}. Waiting for confirmation...`); const txReceipt = await txResponse.wait(); - if (txReceipt.status === 1) { - console.log(`Add liquidity tx confirmed: ${txReceipt.transactionHash}`); + if (txReceipt?.status === 1) { + console.log(`Add liquidity tx confirmed: ${txReceipt.hash}`); } else { - console.log(`Add liquidity tx failed: ${txReceipt.transactionHash}`); + console.log(`Add liquidity tx failed: ${txReceipt?.hash}`); } } @@ -254,7 +257,7 @@ export default class FarmingManager { [assetA]: assetAAddress, [assetB]: assetBAddress, [`${poolName} LP Token`]: pool.lpTokenAddress, - [nativeCryptocurrency]: ethers.constants.AddressZero, + [nativeCryptocurrency]: ethers.ZeroAddress, }, this.unit.aggregator, walletAddress, @@ -265,7 +268,7 @@ export default class FarmingManager { const balanceGuard = new BalanceGuard( balances, { - address: ethers.constants.AddressZero, + address: ethers.ZeroAddress, name: nativeCryptocurrency, }, this.unit.provider, @@ -298,8 +301,8 @@ export default class FarmingManager { const assetAReserve = pairTokensIsInversed ? _reserve1 : _reserve0; const assetBReserve = pairTokensIsInversed ? _reserve0 : _reserve1; - const denormalizedAssetAReserve = denormalizeNumber(assetAReserve, assetADecimals); - const denormalizedAssetBReserve = denormalizeNumber(assetBReserve, assetBDecimals); + const denormalizedAssetAReserve = denormalizeNumber(assetAReserve, BigInt(assetADecimals)); + const denormalizedAssetBReserve = denormalizeNumber(assetBReserve, BigInt(assetBDecimals)); const denormalizedUserPooledAssetA = denormalizedAssetAReserve.multipliedBy(userShare); const denormalizedUserPooledAssetB = denormalizedAssetBReserve.multipliedBy(userShare); @@ -307,8 +310,8 @@ export default class FarmingManager { const denormalizedUserPooledAssetAWithSlippage = denormalizedUserPooledAssetA.multipliedBy(1 - ADD_LIQUIDITY_SLIPPAGE); const denormalizedUserPooledAssetBWithSlippage = denormalizedUserPooledAssetB.multipliedBy(1 - ADD_LIQUIDITY_SLIPPAGE); - const assetAIsNativeCurrency = assetAAddress === ethers.constants.AddressZero; - const assetBIsNativeCurrency = assetBAddress === ethers.constants.AddressZero; + const assetAIsNativeCurrency = assetAAddress === ethers.ZeroAddress; + const assetBIsNativeCurrency = assetBAddress === ethers.ZeroAddress; balanceGuard.registerRequirement({ reason: `${poolName} liquidity`, @@ -321,9 +324,9 @@ export default class FarmingManager { sources: ['wallet'], }); - let unsignedTx: ethers.PopulatedTransaction; + let unsignedTx: ethers.TransactionLike; if (assetAIsNativeCurrency || assetBIsNativeCurrency) { - unsignedTx = await routerContract.populateTransaction.removeLiquidityETH( + unsignedTx = await routerContract.removeLiquidityETH.populateTransaction( assetBIsNativeCurrency ? assetAAddress : assetBAddress, // token lpTokenUserBalance, assetBIsNativeCurrency @@ -331,28 +334,28 @@ export default class FarmingManager { denormalizedUserPooledAssetAWithSlippage, assetADecimals, BigNumber.ROUND_FLOOR, - ) + ).toString() : normalizeNumber( denormalizedUserPooledAssetBWithSlippage, assetBDecimals, BigNumber.ROUND_FLOOR, - ), // token min + ).toString(), // token min assetBIsNativeCurrency ? normalizeNumber( denormalizedUserPooledAssetBWithSlippage, assetBDecimals, BigNumber.ROUND_FLOOR, - ) + ).toString() : normalizeNumber( denormalizedUserPooledAssetAWithSlippage, assetADecimals, BigNumber.ROUND_FLOOR, - ), // eth min + ).toString(), // eth min walletAddress, Math.floor(Date.now() / 1000) + 60 * 20, ); } else { - unsignedTx = await routerContract.populateTransaction.removeLiquidity( + unsignedTx = await routerContract.removeLiquidity.populateTransaction( assetAAddress, assetBAddress, lpTokenUserBalance, @@ -360,27 +363,27 @@ export default class FarmingManager { denormalizedUserPooledAssetAWithSlippage, assetADecimals, BigNumber.ROUND_FLOOR, - ), + ).toString(), normalizeNumber( denormalizedUserPooledAssetBWithSlippage, assetBDecimals, BigNumber.ROUND_FLOOR, - ), + ).toString(), walletAddress, Math.floor(Date.now() / 1000) + 60 * 20, ); } - const gasPrice = await this.unit.provider.getGasPrice(); + const { gasPrice } = await this.unit.provider.getFeeData() - const transactionCost = ethers.BigNumber.from(ADD_LIQUIDITY_GAS_LIMIT).mul(gasPrice); - const denormalizedTransactionCost = denormalizeNumber(transactionCost, NATIVE_CURRENCY_PRECISION); + const transactionCost = BigInt(ADD_LIQUIDITY_GAS_LIMIT) * (gasPrice ?? 0n); + const denormalizedTransactionCost = denormalizeNumber(transactionCost, BigInt(NATIVE_CURRENCY_PRECISION)); balanceGuard.registerRequirement({ reason: 'Network fee', asset: { name: nativeCryptocurrency, - address: ethers.constants.AddressZero, + address: ethers.ZeroAddress, }, amount: denormalizedTransactionCost.toString(), sources: ['wallet'], @@ -398,13 +401,13 @@ export default class FarmingManager { unsignedTx.gasLimit = gasLimit; const signedTx = await signer.signTransaction(unsignedTx); - const txResponse = await this.unit.provider.sendTransaction(signedTx); + const txResponse = await this.unit.provider.broadcastTransaction(signedTx); console.log(`Remove all liquidity tx sent: ${txResponse.hash}. Waiting for confirmation...`); const txReceipt = await txResponse.wait(); - if (txReceipt.status === 1) { - console.log(`Remove all liquidity tx confirmed: ${txReceipt.transactionHash}`); + if (txReceipt?.status === 1) { + console.log(`Remove all liquidity tx confirmed: ${txReceipt.hash}`); } else { - console.log(`Remove all liquidity tx failed: ${txReceipt.transactionHash}`); + console.log(`Remove all liquidity tx failed: ${txReceipt?.hash}`); } } } diff --git a/src/Unit/index.ts b/src/Unit/index.ts index c8b4462..e0ea40f 100644 --- a/src/Unit/index.ts +++ b/src/Unit/index.ts @@ -7,6 +7,7 @@ import Exchange from './Exchange/index.js'; import FarmingManager from './FarmingManager/index.js'; import { chains, envs } from '../config/index.js'; import type { networkCodes } from '../constants/index.js'; +import type { JsonRpcProvider } from 'ethers'; type KnownConfig = { env: KnownEnv @@ -18,7 +19,7 @@ export default class Unit { public readonly chainId: SupportedChainId; - public readonly provider: ethers.providers.StaticJsonRpcProvider; + public readonly provider: JsonRpcProvider; public readonly blockchainService: BlockchainService; @@ -65,13 +66,12 @@ export default class Unit { } const chainInfo = chains[config.chainId]; if (!chainInfo) throw new Error('Chain info is required'); - this.chainId = config.chainId; this.networkCode = chainInfo.code; this.contracts = chainInfo.contracts const intNetwork = parseInt(this.chainId, 10); if (Number.isNaN(intNetwork)) throw new Error('Invalid chainId (not a number)' + this.chainId); - this.provider = new ethers.providers.StaticJsonRpcProvider(this.config.nodeJsonRpc, intNetwork); + this.provider = new ethers.JsonRpcProvider(this.config.nodeJsonRpc, intNetwork); this.provider.pollingInterval = 1000; this.blockchainService = new BlockchainService(this.config.services.blockchainService.http, this.config.basicAuth); diff --git a/src/__tests__/basic.test.ts b/src/__tests__/basic.test.ts index 6f8241b..0643669 100644 --- a/src/__tests__/basic.test.ts +++ b/src/__tests__/basic.test.ts @@ -195,7 +195,7 @@ describe('Orion', () => { expect(unit.aggregator.ws.api).toBe(`ws://localhost:${server1.port}/v1`); expect(unit.blockchainService.api).toBe(blockchainServiceAPI); expect(unit.priceFeed.api).toBe(orionPriceFeedAPI + '/price-feed'); - expect(unit.provider.connection.url).toBe('https://cloudflare-eth.com/'); + expect(unit.provider._getConnection().url).toBe('https://cloudflare-eth.com/'); const info = await simpleFetch(unit.blockchainService.getInfo)(); expect(info).toBeDefined(); @@ -246,7 +246,7 @@ describe('Orion', () => { }); const bscUnit = orion.units[SupportedChainId.BSC_TESTNET] - expect(bscUnit?.provider.connection.url).toBe('https://data-seed-prebsc-1-s1.binance.org:8545/'); + expect(bscUnit?.provider._getConnection().url).toBe('https://data-seed-prebsc-1-s1.binance.org:8545/'); expect(orion.referralSystem.api).toBe('https://zxczxc.orionprotocol.io'); }); @@ -312,7 +312,7 @@ describe('Orion', () => { const network = await unitBSC.provider.getNetwork(); expect(network.chainId).toBe(97); - const zeroAddressWithout0x = ethers.constants.AddressZero.slice(2); + const zeroAddressWithout0x = ethers.ZeroAddress.slice(2); expect(simpleFetch(orion.referralSystem.getMiniStats)(zeroAddressWithout0x)) .rejects .toThrow('empty reward history'); diff --git a/src/__tests__/fee.test.ts b/src/__tests__/fee.test.ts index eec8eeb..1cf8b14 100644 --- a/src/__tests__/fee.test.ts +++ b/src/__tests__/fee.test.ts @@ -83,7 +83,7 @@ describe('Fee calculation', () => { const gasPriceGwei = 3; const feePercent = 0.2; const baseAssetAddress = '0xcb2951e90d8dcf16e1fa84ac0c83f48906d6a744'; - const baseCurrencyAddress = ethers.constants.AddressZero; + const baseCurrencyAddress = ethers.ZeroAddress; const feeAssetAddress = '0xf223eca06261145b3287a0fefd8cfad371c7eb34'; const { totalFeeInFeeAsset: ornTotalFee } = calculateFeeInFeeAsset( amount, diff --git a/src/addressSchema.ts b/src/addressSchema.ts index 982eda1..2eb9262 100644 --- a/src/addressSchema.ts +++ b/src/addressSchema.ts @@ -1,7 +1,7 @@ import { ethers } from 'ethers'; import { z } from 'zod'; -const addressSchema = z.string().refine(ethers.utils.isAddress, (value) => ({ +const addressSchema = z.string().refine(ethers.isAddress, (value) => ({ message: `Should be an address, got ${value}`, })); diff --git a/src/crypt/hashOrder.ts b/src/crypt/hashOrder.ts index 2106514..23bc474 100644 --- a/src/crypt/hashOrder.ts +++ b/src/crypt/hashOrder.ts @@ -1,7 +1,7 @@ import { ethers } from 'ethers'; import type { Order } from '../types.js'; -const hashOrder = (order: Order) => ethers.utils.solidityKeccak256( +const hashOrder = (order: Order) => ethers.solidityPackedKeccak256( [ 'uint8', 'address', diff --git a/src/crypt/signCancelOrder.ts b/src/crypt/signCancelOrder.ts index 1ed3cd1..ff49d22 100644 --- a/src/crypt/signCancelOrder.ts +++ b/src/crypt/signCancelOrder.ts @@ -1,6 +1,5 @@ import type { TypedDataSigner } from '@ethersproject/abstract-signer'; -import type { ethers } from 'ethers'; -import { joinSignature, splitSignature } from 'ethers/lib/utils.js'; +import { ethers } from 'ethers'; import CANCEL_ORDER_TYPES from '../constants/cancelOrderTypes.js'; import type { CancelOrderRequest, SignedCancelOrderRequest, SupportedChainId } from '../types.js'; import getDomainData from './getDomainData.js'; @@ -26,7 +25,7 @@ const signCancelOrder = async ( const signature = usePersonalSign ? await signCancelOrderPersonal(cancelOrderRequest, signer) // https://docs.ethers.io/v5/api/signer/#Signer-signTypedData - : await typedDataSigner._signTypedData( + : await typedDataSigner.signTypedData( getDomainData(chainId), CANCEL_ORDER_TYPES, cancelOrderRequest, @@ -34,7 +33,7 @@ const signCancelOrder = async ( // https://github.com/poap-xyz/poap-fun/pull/62#issue-928290265 // "Signature's v was always send as 27 or 28, but from Ledger was 0 or 1" - const fixedSignature = joinSignature(splitSignature(signature)); + const fixedSignature = ethers.Signature.from(signature).serialized; // if (!fixedSignature) throw new Error("Can't sign order cancel"); diff --git a/src/crypt/signCancelOrderPersonal.ts b/src/crypt/signCancelOrderPersonal.ts index c53975a..2837c3b 100644 --- a/src/crypt/signCancelOrderPersonal.ts +++ b/src/crypt/signCancelOrderPersonal.ts @@ -1,5 +1,4 @@ import { ethers } from 'ethers'; -import { arrayify, joinSignature, splitSignature } from 'ethers/lib/utils.js'; import type { CancelOrderRequest } from '../types.js'; const signCancelOrderPersonal = async ( @@ -7,14 +6,14 @@ const signCancelOrderPersonal = async ( signer: ethers.Signer, ) => { const types = ['string', 'string', 'address']; - const message = ethers.utils.solidityKeccak256( + const message = ethers.solidityPackedKeccak256( types, ['cancelOrder', cancelOrderRequest.id, cancelOrderRequest.senderAddress], ); - const signature = await signer.signMessage(arrayify(message)); + const signature = await signer.signMessage(ethers.getBytes(message)); // NOTE: metamask broke sig.v value and we fix it in next line - return joinSignature(splitSignature(signature)); + return ethers.Signature.from(signature).serialized; }; export default signCancelOrderPersonal; diff --git a/src/crypt/signOrder.ts b/src/crypt/signOrder.ts index 8df5414..90e59df 100644 --- a/src/crypt/signOrder.ts +++ b/src/crypt/signOrder.ts @@ -1,7 +1,6 @@ import type { TypedDataSigner } from '@ethersproject/abstract-signer'; import { BigNumber } from 'bignumber.js'; -import type { ethers } from 'ethers'; -import { joinSignature, splitSignature } from 'ethers/lib/utils.js'; +import { ethers } from 'ethers'; import { INTERNAL_PROTOCOL_PRECISION } from '../constants/index.js'; import ORDER_TYPES from '../constants/orderTypes.js'; import type { Order, SignedOrder, SupportedChainId } from '../types.js'; @@ -37,21 +36,21 @@ export const signOrder = async ( baseAsset: baseAssetAddr, quoteAsset: quoteAssetAddr, matcherFeeAsset: serviceFeeAssetAddr, - amount: normalizeNumber( + amount: Number(normalizeNumber( amount, INTERNAL_PROTOCOL_PRECISION, BigNumber.ROUND_FLOOR, - ).toNumber(), - price: normalizeNumber( + )), + price: Number(normalizeNumber( price, INTERNAL_PROTOCOL_PRECISION, BigNumber.ROUND_FLOOR, - ).toNumber(), - matcherFee: normalizeNumber( + )), + matcherFee: Number(normalizeNumber( matcherFee, INTERNAL_PROTOCOL_PRECISION, BigNumber.ROUND_CEIL, // ROUND_CEIL because we don't want get "not enough fee" error - ).toNumber(), + )), nonce, expiration, buySide: side === 'BUY' ? 1 : 0, @@ -63,7 +62,7 @@ export const signOrder = async ( const signature = usePersonalSign ? await signOrderPersonal(order, signer) - : await typedDataSigner._signTypedData( + : await typedDataSigner.signTypedData( getDomainData(chainId), ORDER_TYPES, order, @@ -71,7 +70,7 @@ export const signOrder = async ( // https://github.com/poap-xyz/poap-fun/pull/62#issue-928290265 // "Signature's v was always send as 27 or 28, but from Ledger was 0 or 1" - const fixedSignature = joinSignature(splitSignature(signature)); + const fixedSignature = ethers.Signature.from(signature).serialized; // if (!fixedSignature) throw new Error("Can't sign order"); diff --git a/src/crypt/signOrderPersonal.ts b/src/crypt/signOrderPersonal.ts index 82c163d..4573e96 100644 --- a/src/crypt/signOrderPersonal.ts +++ b/src/crypt/signOrderPersonal.ts @@ -1,10 +1,8 @@ import { ethers } from 'ethers'; import type { Order } from '../types.js'; -const { arrayify, joinSignature, splitSignature } = ethers.utils; - const signOrderPersonal = async (order: Order, signer: ethers.Signer) => { - const message = ethers.utils.solidityKeccak256( + const message = ethers.solidityPackedKeccak256( [ 'string', 'address', 'address', 'address', 'address', 'address', 'uint64', 'uint64', 'uint64', 'uint64', 'uint64', 'uint8', @@ -24,10 +22,10 @@ const signOrderPersonal = async (order: Order, signer: ethers.Signer) => { order.buySide, ], ); - const signature = await signer.signMessage(arrayify(message)); + const signature = await signer.signMessage(ethers.getBytes(message)); // NOTE: metamask broke sig.v value and we fix it in next line - return joinSignature(splitSignature(signature)); + return ethers.Signature.from(signature).serialized; }; export default signOrderPersonal; diff --git a/src/services/Aggregator/index.ts b/src/services/Aggregator/index.ts index 6da1b14..f30d7cf 100644 --- a/src/services/Aggregator/index.ts +++ b/src/services/Aggregator/index.ts @@ -74,13 +74,13 @@ class Aggregator { } getOrder = (orderId: string, owner?: string) => { - if (!ethers.utils.isHexString(orderId)) { + if (!ethers.isHexString(orderId)) { throw new Error(`Invalid order id: ${orderId}. Must be a hex string`); } const url = new URL(`${this.apiUrl}/api/v1/order`); url.searchParams.append('orderId', orderId); if (owner !== undefined) { - if (!ethers.utils.isAddress(owner)) { + if (!ethers.isAddress(owner)) { throw new Error(`Invalid owner address: ${owner}`); } url.searchParams.append('owner', owner); diff --git a/src/services/Aggregator/schemas/orderSchema.ts b/src/services/Aggregator/schemas/orderSchema.ts index 0f2accf..77d2347 100644 --- a/src/services/Aggregator/schemas/orderSchema.ts +++ b/src/services/Aggregator/schemas/orderSchema.ts @@ -3,22 +3,22 @@ import { z } from 'zod'; import { exchanges, orderStatuses, subOrderStatuses } from '../../../constants/index.js'; const blockchainOrderSchema = z.object({ - id: z.string().refine(ethers.utils.isHexString, (value) => ({ + id: z.string().refine(ethers.isHexString, (value) => ({ message: `blockchainOrder.id must be a hex string, got ${value}`, })), - senderAddress: z.string().refine(ethers.utils.isAddress, (value) => ({ + senderAddress: z.string().refine(ethers.isAddress, (value) => ({ message: `blockchainOrder.senderAddress must be an address, got ${value}`, })), - matcherAddress: z.string().refine(ethers.utils.isAddress, (value) => ({ + matcherAddress: z.string().refine(ethers.isAddress, (value) => ({ message: `blockchainOrder.matcherAddress must be an address, got ${value}`, })), - baseAsset: z.string().refine(ethers.utils.isAddress, (value) => ({ + baseAsset: z.string().refine(ethers.isAddress, (value) => ({ message: `blockchainOrder.baseAsset must be an address, got ${value}`, })), - quoteAsset: z.string().refine(ethers.utils.isAddress, (value) => ({ + quoteAsset: z.string().refine(ethers.isAddress, (value) => ({ message: `blockchainOrder.quoteAsset must be an address, got ${value}`, })), - matcherFeeAsset: z.string().refine(ethers.utils.isAddress, (value) => ({ + matcherFeeAsset: z.string().refine(ethers.isAddress, (value) => ({ message: `blockchainOrder.matcherFeeAsset must be an address, got ${value}`, })), amount: z.number().int().nonnegative(), @@ -27,7 +27,7 @@ const blockchainOrderSchema = z.object({ nonce: z.number(), expiration: z.number(), buySide: z.union([z.literal(1), z.literal(0)]), - signature: z.string().refine(ethers.utils.isHexString, (value) => ({ + signature: z.string().refine(ethers.isHexString, (value) => ({ message: `blockchainOrder.signature must be a hex string, got ${value}`, })).nullable(), isPersonalSign: z.boolean(), @@ -53,7 +53,7 @@ const baseOrderSchema = z.object({ amount: z.number().nonnegative(), remainingAmount: z.number().nonnegative(), price: z.number().nonnegative(), - sender: z.string().refine(ethers.utils.isAddress, (value) => ({ + sender: z.string().refine(ethers.isAddress, (value) => ({ message: `order.sender must be an address, got ${value}`, })), filledAmount: z.number().nonnegative(), @@ -77,13 +77,13 @@ const brokerAddressSchema = z.enum([ 'SELF_BROKER' ]) .or(selfBrokerSchema) - .or(z.string().refine(ethers.utils.isAddress, (value) => ({ + .or(z.string().refine(ethers.isAddress, (value) => ({ message: `subOrder.subOrders.[n].brokerAddress must be an address, got ${value}`, }))); const subOrderSchema = baseOrderSchema.extend({ price: z.number(), id: z.number(), - parentOrderId: z.string().refine(ethers.utils.isHexString, (value) => ({ + parentOrderId: z.string().refine(ethers.isHexString, (value) => ({ message: `subOrder.parentOrderId must be a hex string, got ${value}`, })), exchange: z.string(), @@ -98,11 +98,11 @@ const subOrderSchema = baseOrderSchema.extend({ }); const orderSchema = z.object({ - orderId: z.string().refine(ethers.utils.isHexString, (value) => ({ + orderId: z.string().refine(ethers.isHexString, (value) => ({ message: `orderId must be a hex string, got ${value}`, })), order: baseOrderSchema.extend({ - id: z.string().refine(ethers.utils.isHexString, (value) => ({ + id: z.string().refine(ethers.isHexString, (value) => ({ message: `order.id must be a hex string, got ${value}`, })), fee: z.number().nonnegative(), diff --git a/src/services/BlockchainService/schemas/atomicHistorySchema.ts b/src/services/BlockchainService/schemas/atomicHistorySchema.ts index 504145b..0123c1a 100644 --- a/src/services/BlockchainService/schemas/atomicHistorySchema.ts +++ b/src/services/BlockchainService/schemas/atomicHistorySchema.ts @@ -16,9 +16,9 @@ const baseAtomicHistoryItem = z.object({ _id: z.string(), __v: z.number(), asset: z.string(), - sender: z.string().refine(ethers.utils.isAddress), - secretHash: z.string().refine(ethers.utils.isHexString), - receiver: z.string().refine(ethers.utils.isAddress).optional(), + sender: z.string().refine(ethers.isAddress), + secretHash: z.string().refine(ethers.isHexString), + receiver: z.string().refine(ethers.isAddress).optional(), secret: z.string().optional(), }); diff --git a/src/services/ReferralSystem/schemas/contractsAddressesSchema.ts b/src/services/ReferralSystem/schemas/contractsAddressesSchema.ts index caa3a85..5004366 100644 --- a/src/services/ReferralSystem/schemas/contractsAddressesSchema.ts +++ b/src/services/ReferralSystem/schemas/contractsAddressesSchema.ts @@ -1,10 +1,10 @@ import { z } from 'zod'; import { SupportedChainId } from '../../../types.js'; -import { isAddress } from 'ethers/lib/utils.js'; +import { ethers } from 'ethers'; const contractsAddressesSchema = z.record( z.nativeEnum(SupportedChainId), - z.string().refine(isAddress) + z.string().refine(ethers.isAddress) ); export default contractsAddressesSchema; diff --git a/src/utils/calculateNetworkFee.ts b/src/utils/calculateNetworkFee.ts index 8f348e9..5a84809 100644 --- a/src/utils/calculateNetworkFee.ts +++ b/src/utils/calculateNetworkFee.ts @@ -8,6 +8,6 @@ export default function calculateNetworkFee( ) { const networkFeeGwei = new BigNumber(gasPriceGwei).multipliedBy(gasLimit); - const bn = new BigNumber(ethers.utils.parseUnits(networkFeeGwei.toString(), 'gwei').toString()); + const bn = new BigNumber(ethers.parseUnits(networkFeeGwei.toString(), 'gwei').toString()); return bn.div(new BigNumber(10).pow(NATIVE_CURRENCY_PRECISION)).toString(); } diff --git a/src/utils/checkIsToken.ts b/src/utils/checkIsToken.ts index 20d1f5d..5be176a 100644 --- a/src/utils/checkIsToken.ts +++ b/src/utils/checkIsToken.ts @@ -1,8 +1,8 @@ -import { ERC20__factory } from '@orionprotocol/contracts/lib/ethers-v5/index.js'; +import { ERC20__factory } from '@orionprotocol/contracts/lib/ethers-v6/index.js'; import { ethers } from 'ethers'; import invariant from 'tiny-invariant'; -const checkIsToken = async (address: string, provider?: ethers.providers.Provider) => { +const checkIsToken = async (address: string, provider?: ethers.Provider) => { invariant(provider, 'No provider for token checking'); const tokenContract = ERC20__factory.connect(address, provider); try { @@ -12,7 +12,7 @@ const checkIsToken = async (address: string, provider?: ethers.providers.Provide tokenContract.symbol(), tokenContract.decimals(), tokenContract.totalSupply(), - tokenContract.balanceOf(ethers.constants.AddressZero), + tokenContract.balanceOf(ethers.ZeroAddress), ], ); diff --git a/src/utils/denormalizeNumber.ts b/src/utils/denormalizeNumber.ts index 6ebffd9..86bce3c 100644 --- a/src/utils/denormalizeNumber.ts +++ b/src/utils/denormalizeNumber.ts @@ -1,5 +1,4 @@ import { BigNumber } from 'bignumber.js'; -import type { ethers } from 'ethers'; /** * Converts normalized blockchain ("machine-readable") number to denormalized ("human-readable") number. @@ -7,8 +6,8 @@ import type { ethers } from 'ethers'; * @param decimals Blockchain asset precision * @returns BigNumber */ -export default function denormalizeNumber(input: ethers.BigNumber, decimals: BigNumber.Value) { - const decimalsBN = new BigNumber(decimals); +export default function denormalizeNumber(input: bigint, decimals: bigint) { + const decimalsBN = new BigNumber(decimals.toString()); if (!decimalsBN.isInteger()) throw new Error(`Decimals '${decimalsBN.toString()}' is not an integer`); return new BigNumber(input.toString()).div(new BigNumber(10).pow(decimalsBN)); } diff --git a/src/utils/generateSecret.ts b/src/utils/generateSecret.ts index d1ff475..7caabca 100644 --- a/src/utils/generateSecret.ts +++ b/src/utils/generateSecret.ts @@ -45,7 +45,7 @@ function isomorphicCryptoRandomBytes(size: number): Uint8Array { const generateSecret = () => { const RANDOM_BITS = 256; const rand = isomorphicCryptoRandomBytes(RANDOM_BITS); - const secret = ethers.utils.keccak256(rand); + const secret = ethers.keccak256(rand); return secret; }; diff --git a/src/utils/getAvailableFundsSources.ts b/src/utils/getAvailableFundsSources.ts index e552576..4b490ec 100644 --- a/src/utils/getAvailableFundsSources.ts +++ b/src/utils/getAvailableFundsSources.ts @@ -8,7 +8,7 @@ export default function getAvailableFundsSources( ): Source[] { switch (route) { case 'aggregator': - if (assetAddress === ethers.constants.AddressZero) return ['exchange']; // We can't take native crypto from wallet + if (assetAddress === ethers.ZeroAddress) return ['exchange']; // We can't take native crypto from wallet return ['exchange', 'wallet']; // We can take any token amount from exchange + wallet. Order is important! case 'pool': if (expenseType === 'network_fee') return ['wallet']; // Network fee is always taken from wallet diff --git a/src/utils/getBalance.ts b/src/utils/getBalance.ts index f63b28c..861d0d8 100644 --- a/src/utils/getBalance.ts +++ b/src/utils/getBalance.ts @@ -1,5 +1,5 @@ -import type { Exchange } from '@orionprotocol/contracts/lib/ethers-v5/index.js'; -import { ERC20__factory } from '@orionprotocol/contracts/lib/ethers-v5/index.js'; +import type { Exchange } from '@orionprotocol/contracts/lib/ethers-v6'; +import { ERC20__factory } from '@orionprotocol/contracts/lib/ethers-v6'; import type { BigNumber } from 'bignumber.js'; import { ethers } from 'ethers'; import { INTERNAL_PROTOCOL_PRECISION, NATIVE_CURRENCY_PRECISION } from '../constants/index.js'; @@ -12,11 +12,11 @@ export default async function getBalance( assetAddress: string, walletAddress: string, exchangeContract: Exchange, - provider: ethers.providers.Provider, + provider: ethers.Provider, ) { - const assetIsNativeCryptocurrency = assetAddress === ethers.constants.AddressZero; + const assetIsNativeCryptocurrency = assetAddress === ethers.ZeroAddress; - let assetWalletBalance: ethers.BigNumber | undefined; + let assetWalletBalance: bigint | undefined; let denormalizedAssetInWalletBalance: BigNumber | undefined; @@ -28,10 +28,10 @@ export default async function getBalance( denormalizedAssetInWalletBalance = denormalizeNumber(assetWalletBalance, assetDecimals); } else { assetWalletBalance = await provider.getBalance(walletAddress); - denormalizedAssetInWalletBalance = denormalizeNumber(assetWalletBalance, NATIVE_CURRENCY_PRECISION); + denormalizedAssetInWalletBalance = denormalizeNumber(assetWalletBalance, BigInt(NATIVE_CURRENCY_PRECISION)); } const assetContractBalance = await exchangeContract.getBalance(assetAddress, walletAddress); - const denormalizedAssetInContractBalance = denormalizeNumber(assetContractBalance, INTERNAL_PROTOCOL_PRECISION); + const denormalizedAssetInContractBalance = denormalizeNumber(assetContractBalance, BigInt(INTERNAL_PROTOCOL_PRECISION)); const denormalizedAssetLockedBalanceResult = await aggregator.getLockedBalance(walletAddress, assetName); if (denormalizedAssetLockedBalanceResult.isErr()) { throw new Error(denormalizedAssetLockedBalanceResult.error.message); diff --git a/src/utils/getBalances.ts b/src/utils/getBalances.ts index 8475b1c..f9e5390 100644 --- a/src/utils/getBalances.ts +++ b/src/utils/getBalances.ts @@ -1,4 +1,4 @@ -import type { Exchange } from '@orionprotocol/contracts/lib/ethers-v5/index.js'; +import type { Exchange } from '@orionprotocol/contracts/lib/ethers-v6/index.js'; import type { BigNumber } from 'bignumber.js'; import type { ethers } from 'ethers'; import type { Aggregator } from '../services/Aggregator/index.js'; @@ -9,7 +9,7 @@ export default async ( aggregator: Aggregator, walletAddress: string, exchangeContract: Exchange, - provider: ethers.providers.Provider, + provider: ethers.Provider, ) => { const balances = await Promise.all( Object.entries(balancesRequired) diff --git a/src/utils/getNativeCryptocurrencyName.ts b/src/utils/getNativeCryptocurrencyName.ts index 67c3fec..fa12251 100644 --- a/src/utils/getNativeCryptocurrencyName.ts +++ b/src/utils/getNativeCryptocurrencyName.ts @@ -11,7 +11,7 @@ const getNativeCryptocurrencyName = (assetToAddress: Partial ({ @@ -21,34 +21,34 @@ const swapThroughOrionPoolSchema = z.object({ })); const buyOrderSchema = z.tuple([ // buy order - z.string().refine(ethers.utils.isAddress), // senderAddress - z.string().refine(ethers.utils.isAddress), // matcherAddress - z.string().refine(ethers.utils.isAddress), // baseAsset - z.string().refine(ethers.utils.isAddress), // quoteAsset - z.string().refine(ethers.utils.isAddress), // matcherFeeAsset - z.instanceof(ethers.BigNumber), // amount - z.instanceof(ethers.BigNumber), // price - z.instanceof(ethers.BigNumber), // matcherFee - z.instanceof(ethers.BigNumber), // nonce - z.instanceof(ethers.BigNumber), // expiration + z.string().refine(ethers.isAddress), // senderAddress + z.string().refine(ethers.isAddress), // matcherAddress + z.string().refine(ethers.isAddress), // baseAsset + z.string().refine(ethers.isAddress), // quoteAsset + z.string().refine(ethers.isAddress), // matcherFeeAsset + z.bigint(), // amount + z.bigint(), // price + z.bigint(), // matcherFee + z.bigint(), // nonce + z.bigint(), // expiration z.literal(1), // buySide z.boolean(), // isPersonalSign - z.string().refine(ethers.utils.isHexString), // signature + z.string().refine(ethers.isHexString), // signature ]); const sellOrderSchema = z.tuple([ // sell orer - z.string().refine(ethers.utils.isAddress), // senderAddress - z.string().refine(ethers.utils.isAddress), // matcherAddress - z.string().refine(ethers.utils.isAddress), // baseAsset - z.string().refine(ethers.utils.isAddress), // quoteAsset - z.string().refine(ethers.utils.isAddress), // matcherFeeAsset - z.instanceof(ethers.BigNumber), // amount - z.instanceof(ethers.BigNumber), // price - z.instanceof(ethers.BigNumber), // matcherFee - z.instanceof(ethers.BigNumber), // nonce - z.instanceof(ethers.BigNumber), // expiration + z.string().refine(ethers.isAddress), // senderAddress + z.string().refine(ethers.isAddress), // matcherAddress + z.string().refine(ethers.isAddress), // baseAsset + z.string().refine(ethers.isAddress), // quoteAsset + z.string().refine(ethers.isAddress), // matcherFeeAsset + z.bigint(), // amount + z.bigint(), // price + z.bigint(), // matcherFee + z.bigint(), // nonce + z.bigint(), // expiration z.literal(0), // buySide z.boolean(), // isPersonalSign - z.string().refine(ethers.utils.isHexString), // signature + z.string().refine(ethers.isHexString), // signature ]); const toOrder = | z.infer>(data: T) => ({ @@ -71,9 +71,9 @@ const fillThroughOrionPoolSchema = z.object({ name: z.literal('fillThroughOrionPool'), args: z.tuple([ sellOrderSchema, - z.instanceof(ethers.BigNumber), // filled amount - z.instanceof(ethers.BigNumber), // blockchainFee - z.string().refine(ethers.utils.isAddress).array().nonempty(), // path + z.bigint(), // filled amount + z.bigint(), // blockchainFee + z.string().refine(ethers.isAddress).array().nonempty(), // path ]), }).transform((data) => ({ name: data.name, @@ -90,8 +90,8 @@ const fillOrdersSchema = z.object({ args: z.tuple([ buyOrderSchema, sellOrderSchema, - z.instanceof(ethers.BigNumber), // filledPrice - z.instanceof(ethers.BigNumber), // filledAmount + z.bigint(), // filledPrice + z.bigint(), // filledAmount ]), }).transform((data) => ({ name: data.name, diff --git a/tsconfig.json b/tsconfig.json index 37764ec..2bbded1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,8 +12,7 @@ ], "compilerOptions": { "target": "esnext", - "module": "NodeNext", - "moduleResolution": "NodeNext", + "module": "ESNext", "esModuleInterop": true, "resolveJsonModule": true /* Enable importing .json files */, "declaration": true /* Generate .d.ts files from TypeScript and JavaScript files in your project. */,