mirror of
https://github.com/orionprotocol/sdk.git
synced 2026-03-14 14:12:35 +03:00
Merge branch 'refs/heads/main' into feat/OP-4308-cross-chain-swap
# Conflicts: # package-lock.json # package.json
This commit is contained in:
69
package-lock.json
generated
69
package-lock.json
generated
@@ -1,16 +1,17 @@
|
||||
{
|
||||
"name": "@orionprotocol/sdk",
|
||||
"version": "0.21.0-rc19",
|
||||
"version": "0.20.76-rc110",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@orionprotocol/sdk",
|
||||
"version": "0.21.0-rc19",
|
||||
"version": "0.20.76-rc110",
|
||||
"hasInstallScript": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.21.0",
|
||||
"@ethersproject/abstract-signer": "^5.7.0",
|
||||
"@ethersproject/providers": "^5.7.2",
|
||||
"@orionprotocol/contracts": "1.23.3",
|
||||
"@types/lodash.clonedeep": "^4.5.9",
|
||||
@@ -26,7 +27,7 @@
|
||||
"merge-anything": "^5.1.7",
|
||||
"neverthrow": "^6.0.0",
|
||||
"patch-package": "^8.0.0",
|
||||
"simple-typed-fetch": "0.2.5",
|
||||
"simple-typed-fetch": "0.2.3",
|
||||
"stream-browserify": "^3.0.0",
|
||||
"tiny-invariant": "^1.3.1",
|
||||
"ts-is-present": "^1.2.2",
|
||||
@@ -1084,6 +1085,28 @@
|
||||
"@ethersproject/web": "^5.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ethersproject/abstract-signer": {
|
||||
"version": "5.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz",
|
||||
"integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==",
|
||||
"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/bignumber": "^5.7.0",
|
||||
"@ethersproject/bytes": "^5.7.0",
|
||||
"@ethersproject/logger": "^5.7.0",
|
||||
"@ethersproject/properties": "^5.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ethersproject/address": {
|
||||
"version": "5.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz",
|
||||
@@ -1214,6 +1237,7 @@
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"@ethersproject/abstract-signer": "^5.7.0",
|
||||
"@ethersproject/address": "^5.7.0",
|
||||
"@ethersproject/base64": "^5.7.0",
|
||||
"@ethersproject/bignumber": "^5.7.0",
|
||||
@@ -1310,6 +1334,7 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"@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",
|
||||
@@ -2614,9 +2639,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@types/jest": {
|
||||
"version": "29.5.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.4.tgz",
|
||||
"integrity": "sha512-PhglGmhWeD46FYOVLt3X7TiWjzwuVGW9wG/4qocPevXMjCmrIc5b6db9WjeGE4QYVpUAWMDv3v0IiBwObY289A==",
|
||||
"version": "29.5.12",
|
||||
"resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz",
|
||||
"integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"expect": "^29.0.0",
|
||||
@@ -10374,9 +10399,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/simple-typed-fetch": {
|
||||
"version": "0.2.5",
|
||||
"resolved": "https://registry.npmjs.org/simple-typed-fetch/-/simple-typed-fetch-0.2.5.tgz",
|
||||
"integrity": "sha512-T/KKUHKOZgaYVp3dbjE1wEK5cAGmG5N7FNAzP6ZGqLDhzBsRm3Gpt8bO/kowV6bt8duXDWiapYFQibW/8iHp6Q==",
|
||||
"version": "0.2.3",
|
||||
"resolved": "https://registry.npmjs.org/simple-typed-fetch/-/simple-typed-fetch-0.2.3.tgz",
|
||||
"integrity": "sha512-EXP2mVVsVf4A3+5QGevs8789ztnT6FozsYyMrIrUYhfqtX2V+X9xETHeGXffmgv7YQ0p+GrW7N+5x+b+pBW59Q==",
|
||||
"dependencies": {
|
||||
"isomorphic-unfetch": "^4.0.2",
|
||||
"neverthrow": "^6.0.0",
|
||||
@@ -12554,6 +12579,18 @@
|
||||
"@ethersproject/web": "^5.7.0"
|
||||
}
|
||||
},
|
||||
"@ethersproject/abstract-signer": {
|
||||
"version": "5.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz",
|
||||
"integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==",
|
||||
"requires": {
|
||||
"@ethersproject/abstract-provider": "^5.7.0",
|
||||
"@ethersproject/bignumber": "^5.7.0",
|
||||
"@ethersproject/bytes": "^5.7.0",
|
||||
"@ethersproject/logger": "^5.7.0",
|
||||
"@ethersproject/properties": "^5.7.0"
|
||||
}
|
||||
},
|
||||
"@ethersproject/address": {
|
||||
"version": "5.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz",
|
||||
@@ -12614,6 +12651,7 @@
|
||||
"resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz",
|
||||
"integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==",
|
||||
"requires": {
|
||||
"@ethersproject/abstract-signer": "^5.7.0",
|
||||
"@ethersproject/address": "^5.7.0",
|
||||
"@ethersproject/base64": "^5.7.0",
|
||||
"@ethersproject/bignumber": "^5.7.0",
|
||||
@@ -12660,6 +12698,7 @@
|
||||
"integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==",
|
||||
"requires": {
|
||||
"@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",
|
||||
@@ -13667,9 +13706,9 @@
|
||||
}
|
||||
},
|
||||
"@types/jest": {
|
||||
"version": "29.5.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.4.tgz",
|
||||
"integrity": "sha512-PhglGmhWeD46FYOVLt3X7TiWjzwuVGW9wG/4qocPevXMjCmrIc5b6db9WjeGE4QYVpUAWMDv3v0IiBwObY289A==",
|
||||
"version": "29.5.12",
|
||||
"resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz",
|
||||
"integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"expect": "^29.0.0",
|
||||
@@ -19297,9 +19336,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"simple-typed-fetch": {
|
||||
"version": "0.2.5",
|
||||
"resolved": "https://registry.npmjs.org/simple-typed-fetch/-/simple-typed-fetch-0.2.5.tgz",
|
||||
"integrity": "sha512-T/KKUHKOZgaYVp3dbjE1wEK5cAGmG5N7FNAzP6ZGqLDhzBsRm3Gpt8bO/kowV6bt8duXDWiapYFQibW/8iHp6Q==",
|
||||
"version": "0.2.3",
|
||||
"resolved": "https://registry.npmjs.org/simple-typed-fetch/-/simple-typed-fetch-0.2.3.tgz",
|
||||
"integrity": "sha512-EXP2mVVsVf4A3+5QGevs8789ztnT6FozsYyMrIrUYhfqtX2V+X9xETHeGXffmgv7YQ0p+GrW7N+5x+b+pBW59Q==",
|
||||
"requires": {
|
||||
"isomorphic-unfetch": "^4.0.2",
|
||||
"neverthrow": "^6.0.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@orionprotocol/sdk",
|
||||
"version": "0.21.0-rc19",
|
||||
"version": "0.21.0-rc20",
|
||||
"description": "Orion Protocol SDK",
|
||||
"main": "./lib/index.cjs",
|
||||
"module": "./lib/index.js",
|
||||
|
||||
@@ -3,6 +3,15 @@ import { SafeArray } from "../../../utils/safeGetters.js"
|
||||
import { type BytesLike, type BigNumberish, concat, ethers, toBeHex } from "ethers"
|
||||
import { addCallParams } from "./utils.js"
|
||||
import type { SingleSwap } from "../../../types.js"
|
||||
import { BigNumber } from 'bignumber.js';
|
||||
|
||||
const BILLION = 1000000000;
|
||||
const TEN_THOUSANDS = 10000;
|
||||
|
||||
function countScaledFee(fee: string) {
|
||||
// The count is needed for the swapUniV2Scaled function, where the denominator is one billion
|
||||
return new BigNumber(fee).multipliedBy(BILLION).div(TEN_THOUSANDS).toNumber();
|
||||
}
|
||||
|
||||
export async function generateUni2Calls(
|
||||
path: SafeArray<SingleSwap>,
|
||||
@@ -19,17 +28,21 @@ export async function generateUni2Calls(
|
||||
currentSwap.pool,
|
||||
currentSwap.assetIn,
|
||||
currentSwap.assetOut,
|
||||
nextSwap.pool
|
||||
nextSwap.pool,
|
||||
currentSwap.fee
|
||||
)
|
||||
calls.push(call)
|
||||
}
|
||||
}
|
||||
|
||||
const lastSwap = path.last();
|
||||
const calldata = executorInterface.encodeFunctionData('swapUniV2', [
|
||||
const fee = lastSwap.fee ?? 3;
|
||||
const scaledFee = countScaledFee(fee.toString());
|
||||
const calldata = executorInterface.encodeFunctionData('swapUniV2Scaled', [
|
||||
lastSwap.pool,
|
||||
lastSwap.assetIn,
|
||||
lastSwap.assetOut,
|
||||
ethers.AbiCoder.defaultAbiCoder().encode(['uint256'], [concat(['0x03', recipient])]),
|
||||
ethers.AbiCoder.defaultAbiCoder().encode(['uint256'], [concat([toBeHex(scaledFee), recipient])]),
|
||||
])
|
||||
calls.push(addCallParams(calldata))
|
||||
|
||||
@@ -44,11 +57,12 @@ export function generateUni2Call(
|
||||
fee: BigNumberish = 3,
|
||||
) {
|
||||
const executorInterface = SwapExecutor__factory.createInterface()
|
||||
const calldata = executorInterface.encodeFunctionData('swapUniV2', [
|
||||
const scaledFee = countScaledFee(fee.toString());
|
||||
const calldata = executorInterface.encodeFunctionData('swapUniV2Scaled', [
|
||||
pool,
|
||||
assetIn,
|
||||
assetOut,
|
||||
ethers.AbiCoder.defaultAbiCoder().encode(['uint256'], [concat([toBeHex(fee), recipient])]),
|
||||
ethers.AbiCoder.defaultAbiCoder().encode(['uint256'], [concat([toBeHex(scaledFee), recipient])]),
|
||||
])
|
||||
return addCallParams(calldata)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,49 +1,50 @@
|
||||
import type { LibValidator } from "@orionprotocol/contracts/lib/ethers-v6/Exchange.js";
|
||||
import { ethers, ZeroAddress } from "ethers";
|
||||
import type { AddressLike, JsonRpcProvider, BigNumberish, BytesLike } from "ethers";
|
||||
import cloneDeep from "lodash.clonedeep";
|
||||
import { safeGet, SafeArray } from "../../utils/safeGetters.js";
|
||||
import { simpleFetch } from "simple-typed-fetch";
|
||||
import type Unit from "../index.js";
|
||||
import { generateUni2Calls, generateUni2Call } from "./callGenerators/uniswapV2.js";
|
||||
import type { LibValidator } from '@orionprotocol/contracts/lib/ethers-v6/Exchange.js';
|
||||
import { ethers, ZeroAddress } from 'ethers';
|
||||
import type { AddressLike, JsonRpcProvider, BigNumberish, BytesLike } from 'ethers';
|
||||
import cloneDeep from 'lodash.clonedeep';
|
||||
import { safeGet, SafeArray } from '../../utils/safeGetters.js';
|
||||
import { simpleFetch } from 'simple-typed-fetch';
|
||||
import type Unit from '../index.js';
|
||||
import { generateUni2Calls, generateUni2Call } from './callGenerators/uniswapV2.js';
|
||||
import {
|
||||
generateUni3Calls,
|
||||
generateOrion3Calls,
|
||||
generateUni3Call,
|
||||
generateOrion3Call,
|
||||
} from "./callGenerators/uniswapV3.js";
|
||||
import { exchangeToNativeDecimals, generateCalls, pathCallWithBalance } from "./callGenerators/utils.js";
|
||||
import { generateTransferCall } from "./callGenerators/erc20.js";
|
||||
import { generateCurveStableSwapCall } from "./callGenerators/curve.js";
|
||||
import type { SingleSwap } from "../../types.js";
|
||||
import { addressLikeToString } from "../../utils/addressLikeToString.js";
|
||||
import { generateUnwrapAndTransferCall, generateWrapAndTransferCall } from "./callGenerators/weth.js";
|
||||
import { getExchangeAllowance, getTotalBalance } from "../../utils/getBalance.js";
|
||||
import { generateFeePaymentCall } from "./callGenerators/feePayment.js";
|
||||
} from './callGenerators/uniswapV3.js';
|
||||
import { exchangeToNativeDecimals, generateCalls, pathCallWithBalance } from './callGenerators/utils.js';
|
||||
import { generateTransferCall } from './callGenerators/erc20.js';
|
||||
import { generateCurveStableSwapCall } from './callGenerators/curve.js';
|
||||
import type { SingleSwap } from '../../types.js';
|
||||
import { addressLikeToString } from '../../utils/addressLikeToString.js';
|
||||
import { generateUnwrapAndTransferCall, generateWrapAndTransferCall } from './callGenerators/weth.js';
|
||||
import { getExchangeAllowance, getTotalBalance } from '../../utils/getBalance.js';
|
||||
import { generateFeePaymentCall } from './callGenerators/feePayment.js';
|
||||
|
||||
export type Factory = "UniswapV2" | "UniswapV3" | "Curve" | "OrionV2" | "OrionV3";
|
||||
export type Factory = 'UniswapV2' | 'UniswapV3' | 'Curve' | 'OrionV2' | 'OrionV3';
|
||||
|
||||
type BaseGenerateSwapCalldataParams = {
|
||||
amount: BigNumberish;
|
||||
minReturnAmount: BigNumberish;
|
||||
initiatorAddress: string;
|
||||
receiverAddress: string;
|
||||
path: ArrayLike<SingleSwap>;
|
||||
matcher?: AddressLike,
|
||||
feeToken?: AddressLike,
|
||||
fee?: BigNumberish;
|
||||
amount: BigNumberish
|
||||
minReturnAmount: BigNumberish
|
||||
initiatorAddress: string
|
||||
receiverAddress: string
|
||||
path: ArrayLike<SingleSwap>
|
||||
matcher?: AddressLike
|
||||
feeToken?: AddressLike
|
||||
fee?: BigNumberish
|
||||
}
|
||||
|
||||
export type GenerateSwapCalldataWithUnitParams = BaseGenerateSwapCalldataParams & {
|
||||
unit: Unit;
|
||||
unit: Unit
|
||||
};
|
||||
|
||||
export type GenerateSwapCalldataParams = BaseGenerateSwapCalldataParams & {
|
||||
exchangeContractAddress: AddressLike;
|
||||
wethAddress: AddressLike;
|
||||
curveRegistryAddress: AddressLike;
|
||||
swapExecutorContractAddress: AddressLike;
|
||||
provider: JsonRpcProvider;
|
||||
exchangeContractAddress: AddressLike
|
||||
wethAddress: AddressLike
|
||||
curveRegistryAddress: AddressLike
|
||||
swapExecutorContractAddress: AddressLike
|
||||
provider: JsonRpcProvider
|
||||
logger?: ((message: string) => void) | undefined
|
||||
};
|
||||
|
||||
export async function generateSwapCalldataWithUnit({
|
||||
@@ -57,29 +58,27 @@ export async function generateSwapCalldataWithUnit({
|
||||
fee = 0,
|
||||
unit,
|
||||
}: GenerateSwapCalldataWithUnitParams): Promise<{
|
||||
calldata: string;
|
||||
swapDescription: LibValidator.SwapDescriptionStruct;
|
||||
value: bigint;
|
||||
calldata: string
|
||||
swapDescription: LibValidator.SwapDescriptionStruct
|
||||
value: bigint
|
||||
}> {
|
||||
if (arrayLikePath == undefined || arrayLikePath.length == 0) {
|
||||
throw new Error("Empty path");
|
||||
throw new Error('Empty path');
|
||||
}
|
||||
const wethAddress = safeGet(unit.contracts, "WETH");
|
||||
const curveRegistryAddress = safeGet(unit.contracts, "curveRegistry");
|
||||
const { assetToAddress, swapExecutorContractAddress, exchangeContractAddress } = await simpleFetch(
|
||||
const wethAddress = safeGet(unit.contracts, 'WETH');
|
||||
const curveRegistryAddress = safeGet(unit.contracts, 'curveRegistry');
|
||||
const { swapExecutorContractAddress, exchangeContractAddress } = await simpleFetch(
|
||||
unit.blockchainService.getInfo
|
||||
)();
|
||||
|
||||
const arrayLikePathCopy = cloneDeep(arrayLikePath);
|
||||
let path = SafeArray.from(arrayLikePathCopy);
|
||||
|
||||
path = SafeArray.from(arrayLikePathCopy).map((swapInfo) => {
|
||||
swapInfo.assetIn = assetToAddress[swapInfo.assetIn] ?? swapInfo.assetIn
|
||||
swapInfo.assetOut = assetToAddress[swapInfo.assetOut] ?? swapInfo.assetOut
|
||||
swapInfo.assetIn = swapInfo.assetIn.toLowerCase()
|
||||
swapInfo.assetOut = swapInfo.assetOut.toLowerCase()
|
||||
return swapInfo;
|
||||
});
|
||||
path = SafeArray.from(arrayLikePathCopy).map((swapInfo) => ({
|
||||
...swapInfo,
|
||||
assetIn: swapInfo.assetAddressIn.toLowerCase(),
|
||||
assetOut: swapInfo.assetAddressOut.toLowerCase(),
|
||||
}));
|
||||
|
||||
return await generateSwapCalldata({
|
||||
amount,
|
||||
@@ -95,6 +94,7 @@ export async function generateSwapCalldataWithUnit({
|
||||
curveRegistryAddress,
|
||||
swapExecutorContractAddress,
|
||||
provider: unit.provider,
|
||||
logger: unit.logger,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -112,21 +112,30 @@ export async function generateSwapCalldata({
|
||||
curveRegistryAddress: curveRegistryAddressLike,
|
||||
swapExecutorContractAddress: swapExecutorContractAddressLike,
|
||||
provider,
|
||||
logger,
|
||||
}: GenerateSwapCalldataParams): Promise<{
|
||||
calldata: string;
|
||||
swapDescription: LibValidator.SwapDescriptionStruct;
|
||||
value: bigint;
|
||||
calldata: string
|
||||
swapDescription: LibValidator.SwapDescriptionStruct
|
||||
value: bigint
|
||||
}> {
|
||||
const wethAddress = await addressLikeToString(wethAddressLike);
|
||||
logger?.(`wethAddress: ${wethAddress}`);
|
||||
const curveRegistryAddress = await addressLikeToString(curveRegistryAddressLike);
|
||||
logger?.(`curveRegistryAddress: ${curveRegistryAddress}`);
|
||||
const swapExecutorContractAddress = await addressLikeToString(swapExecutorContractAddressLike);
|
||||
logger?.(`swapExecutorContractAddress, ${swapExecutorContractAddress}`);
|
||||
const feeToken = await addressLikeToString(feeTokenAddressLike);
|
||||
logger?.(`feeToken, ${feeToken}`);
|
||||
const matcher = await addressLikeToString(matcherAddressLike);
|
||||
logger?.(`matcher: ${matcher}`);
|
||||
logger?.(`arrayLikePath: ${arrayLikePath}`);
|
||||
let path = SafeArray.from(arrayLikePath).map((swapInfo) => {
|
||||
logger?.(`swapInfo: ${swapInfo}`);
|
||||
swapInfo.assetIn = swapInfo.assetIn.toLowerCase()
|
||||
swapInfo.assetOut = swapInfo.assetOut.toLowerCase()
|
||||
return swapInfo;
|
||||
});
|
||||
logger?.(`path: ${path}`);
|
||||
|
||||
const { assetIn: srcToken } = path.first();
|
||||
const { assetOut: dstToken } = path.last();
|
||||
@@ -140,14 +149,18 @@ export async function generateSwapCalldata({
|
||||
minReturnAmount,
|
||||
flags: 0,
|
||||
};
|
||||
logger?.(`swapDescription: ${swapDescription}`);
|
||||
const amountNativeDecimals = await exchangeToNativeDecimals(srcToken, amount, provider);
|
||||
logger?.(`amountNativeDecimals: ${amountNativeDecimals}`);
|
||||
const feeNativeDecimals = await exchangeToNativeDecimals(feeToken, fee, provider)
|
||||
logger?.(`feeNativeDecimals: ${feeNativeDecimals}`);
|
||||
|
||||
path = SafeArray.from(arrayLikePath).map((singleSwap) => {
|
||||
if (singleSwap.assetIn == ethers.ZeroAddress) singleSwap.assetIn = wethAddress;
|
||||
if (singleSwap.assetOut == ethers.ZeroAddress) singleSwap.assetOut = wethAddress;
|
||||
return singleSwap;
|
||||
});
|
||||
logger?.(`path2: ${path}`);
|
||||
|
||||
let calls: BytesLike[];
|
||||
({ swapDescription, calls } = await processSwaps(
|
||||
@@ -162,19 +175,26 @@ export async function generateSwapCalldata({
|
||||
curveRegistryAddress,
|
||||
provider
|
||||
));
|
||||
logger?.(`swapDescription: ${swapDescription}`);
|
||||
logger?.(`calls: ${calls}`);
|
||||
const calldata = generateCalls(calls);
|
||||
logger?.(`calldata: ${calldata}`);
|
||||
|
||||
const { useExchangeBalance, additionalTransferAmount } = await shouldUseExchangeBalance(
|
||||
srcToken,
|
||||
initiatorAddress,
|
||||
exchangeContractAddress,
|
||||
amountNativeDecimals,
|
||||
provider
|
||||
provider,
|
||||
logger
|
||||
);
|
||||
logger?.(`useExchangeBalance: ${useExchangeBalance}`);
|
||||
logger?.(`additionalTransferAmount: ${additionalTransferAmount}`);
|
||||
if (useExchangeBalance) {
|
||||
swapDescription.flags = 1n << 255n;
|
||||
}
|
||||
const value = srcToken == ZeroAddress ? additionalTransferAmount : 0n;
|
||||
logger?.(`value: ${value}`);
|
||||
return { swapDescription, calldata, value };
|
||||
}
|
||||
|
||||
@@ -214,7 +234,7 @@ async function processSwaps(
|
||||
));
|
||||
}
|
||||
|
||||
({swapDescription, calls} = await payFeeToMatcher(matcher, feeToken, fee, calls, swapDescription));
|
||||
({ swapDescription, calls } = await payFeeToMatcher(matcher, feeToken, fee, calls, swapDescription));
|
||||
|
||||
({ swapDescription, calls } = wrapOrUnwrapIfNeeded(
|
||||
amount,
|
||||
@@ -238,27 +258,27 @@ async function processSingleFactorySwaps(
|
||||
) {
|
||||
let calls: BytesLike[] = [];
|
||||
switch (factory) {
|
||||
case "OrionV2": {
|
||||
case 'OrionV2': {
|
||||
swapDescription.srcReceiver = path.first().pool;
|
||||
calls = await generateUni2Calls(path, swapExecutorContractAddress);
|
||||
break;
|
||||
}
|
||||
case "UniswapV2": {
|
||||
case 'UniswapV2': {
|
||||
swapDescription.srcReceiver = path.first().pool;
|
||||
calls = await generateUni2Calls(path, swapExecutorContractAddress);
|
||||
break;
|
||||
}
|
||||
case "UniswapV3": {
|
||||
case 'UniswapV3': {
|
||||
calls = await generateUni3Calls(path, amount, swapExecutorContractAddress, provider);
|
||||
break;
|
||||
}
|
||||
case "OrionV3": {
|
||||
case 'OrionV3': {
|
||||
calls = await generateOrion3Calls(path, amount, swapExecutorContractAddress, provider);
|
||||
break;
|
||||
}
|
||||
case "Curve": {
|
||||
case 'Curve': {
|
||||
if (path.length > 1) {
|
||||
throw new Error("Supporting only single stable swap on curve");
|
||||
throw new Error('Supporting only single stable swap on curve');
|
||||
}
|
||||
calls = await generateCurveStableSwapCall(
|
||||
amount,
|
||||
@@ -285,37 +305,37 @@ async function processMultiFactorySwaps(
|
||||
curveRegistryAddress: string,
|
||||
provider: JsonRpcProvider
|
||||
) {
|
||||
let calls: BytesLike[] = [];
|
||||
const calls: BytesLike[] = [];
|
||||
for (const swap of path) {
|
||||
switch (swap.factory) {
|
||||
case "OrionV2": {
|
||||
case 'OrionV2': {
|
||||
let transferCall = generateTransferCall(swap.assetIn, swap.pool, 0);
|
||||
transferCall = pathCallWithBalance(transferCall, swap.assetIn);
|
||||
const uni2Call = generateUni2Call(swap.pool, swap.assetIn, swap.assetOut, swapExecutorContractAddress);
|
||||
const uni2Call = generateUni2Call(swap.pool, swap.assetIn, swap.assetOut, swapExecutorContractAddress, swap.fee);
|
||||
calls.push(transferCall, uni2Call);
|
||||
break;
|
||||
}
|
||||
case "UniswapV2": {
|
||||
case 'UniswapV2': {
|
||||
let transferCall = generateTransferCall(swap.assetIn, swap.pool, 0);
|
||||
transferCall = pathCallWithBalance(transferCall, swap.assetIn);
|
||||
const uni2Call = generateUni2Call(swap.pool, swap.assetIn, swap.assetOut, swapExecutorContractAddress);
|
||||
const uni2Call = generateUni2Call(swap.pool, swap.assetIn, swap.assetOut, swapExecutorContractAddress, swap.fee);
|
||||
calls.push(transferCall, uni2Call);
|
||||
break;
|
||||
}
|
||||
case "UniswapV3": {
|
||||
case 'UniswapV3': {
|
||||
let uni3Call = await generateUni3Call(swap, 0, swapExecutorContractAddress, provider);
|
||||
uni3Call = pathCallWithBalance(uni3Call, swap.assetIn);
|
||||
calls.push(uni3Call);
|
||||
break;
|
||||
}
|
||||
case "OrionV3": {
|
||||
case 'OrionV3': {
|
||||
let orion3Call = await generateOrion3Call(swap, 0, swapExecutorContractAddress, provider);
|
||||
orion3Call = pathCallWithBalance(orion3Call, swap.assetIn);
|
||||
calls.push(orion3Call);
|
||||
break;
|
||||
}
|
||||
case "Curve": {
|
||||
let curveCalls = await generateCurveStableSwapCall(
|
||||
case 'Curve': {
|
||||
const curveCalls = await generateCurveStableSwapCall(
|
||||
amount,
|
||||
swapExecutorContractAddress,
|
||||
swap,
|
||||
@@ -346,7 +366,7 @@ async function payFeeToMatcher(
|
||||
const feePaymentCall = generateFeePaymentCall(matcher, feeToken, feeAmount)
|
||||
calls.push(feePaymentCall)
|
||||
}
|
||||
return {swapDescription, calls}
|
||||
return { swapDescription, calls }
|
||||
}
|
||||
|
||||
function wrapOrUnwrapIfNeeded(
|
||||
@@ -356,7 +376,7 @@ function wrapOrUnwrapIfNeeded(
|
||||
swapExecutorContractAddress: string,
|
||||
wethAddress: string
|
||||
) {
|
||||
const {dstReceiver, srcReceiver, srcToken, dstToken} = swapDescription;
|
||||
const { dstReceiver, srcReceiver, srcToken, dstToken } = swapDescription;
|
||||
if (srcToken === ZeroAddress) {
|
||||
const wrapCall = generateWrapAndTransferCall(srcReceiver, { value: amount });
|
||||
swapDescription.srcReceiver = swapExecutorContractAddress;
|
||||
@@ -379,7 +399,8 @@ async function shouldUseExchangeBalance(
|
||||
initiatorAddress: AddressLike,
|
||||
exchangeContractAddress: AddressLike,
|
||||
amount: bigint,
|
||||
provider: JsonRpcProvider
|
||||
provider: JsonRpcProvider,
|
||||
logger?: ((message: string) => void) | undefined
|
||||
) {
|
||||
const { walletBalance, exchangeBalance } = await getTotalBalance(
|
||||
srcToken,
|
||||
@@ -387,11 +408,13 @@ async function shouldUseExchangeBalance(
|
||||
exchangeContractAddress,
|
||||
provider
|
||||
);
|
||||
|
||||
const exchangeAllowance = await getExchangeAllowance(srcToken, initiatorAddress, exchangeContractAddress, provider);
|
||||
logger?.('test_123');
|
||||
|
||||
if (walletBalance + exchangeBalance < amount) {
|
||||
throw new Error(
|
||||
`Not enough balance to make swap, totalBalance - ${walletBalance + exchangeBalance} swapAmount - ${amount}`
|
||||
`Not enough balance to make swap, walletBalance: ${walletBalance} exchangeBalance: ${exchangeBalance} totalBalance - ${walletBalance + exchangeBalance} swapAmount - ${amount}`
|
||||
);
|
||||
}
|
||||
let useExchangeBalance = true;
|
||||
|
||||
@@ -47,7 +47,7 @@ export default class Exchange {
|
||||
public generateSwapCalldata(params: PureGenerateSwapCalldataParams) {
|
||||
return generateSwapCalldataWithUnit({
|
||||
...params,
|
||||
unit: this.unit
|
||||
unit: this.unit,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@ const exchangeContractStep = z.object({
|
||||
assetIn: z.string(),
|
||||
assetOut: z.string(),
|
||||
factory: z.string(),
|
||||
assetAddressIn: z.string(),
|
||||
assetAddressOut: z.string(),
|
||||
});
|
||||
|
||||
const swapInfoBase = z.object({
|
||||
|
||||
@@ -518,6 +518,9 @@ class AggregatorWS {
|
||||
assetIn: path.ai,
|
||||
assetOut: path.ao,
|
||||
factory: path.f,
|
||||
assetAddressIn: path.aai,
|
||||
assetAddressOut: path.aao,
|
||||
fee: path.fee,
|
||||
})),
|
||||
poolOptimal: json.po,
|
||||
...(json.oi) && {
|
||||
|
||||
@@ -40,6 +40,9 @@ const swapInfoSchemaBase = baseMessageSchema.extend({
|
||||
ai: z.string().toUpperCase(), // asset in
|
||||
ao: z.string().toUpperCase(), // asset out
|
||||
f: factorySchema, // factory
|
||||
aai: z.string(), // asset address in
|
||||
aao: z.string(), // asset address out
|
||||
fee: z.number().optional(), // fee
|
||||
})),
|
||||
usd: z.object({ // USD info of this swap, nullable
|
||||
aa: z.number().optional(), // available amount in, USD
|
||||
|
||||
@@ -201,6 +201,9 @@ export type SingleSwap = {
|
||||
assetIn: string
|
||||
assetOut: string
|
||||
factory: Factory
|
||||
assetAddressIn: string
|
||||
assetAddressOut: string
|
||||
fee?: number | undefined
|
||||
}
|
||||
|
||||
export type SwapInfoBase = {
|
||||
|
||||
Reference in New Issue
Block a user