mirror of
https://github.com/orionprotocol/sdk.git
synced 2026-03-15 14:42:38 +03:00
Change final transfer location. Add wrap/unwrap functionality
This commit is contained in:
18
package-lock.json
generated
18
package-lock.json
generated
@@ -1,19 +1,19 @@
|
||||
{
|
||||
"name": "@orionprotocol/sdk",
|
||||
"version": "0.20.10",
|
||||
"version": "0.20.10-rc101",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@orionprotocol/sdk",
|
||||
"version": "0.20.10",
|
||||
"version": "0.20.10-rc101",
|
||||
"hasInstallScript": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.21.0",
|
||||
"@ethersproject/abstract-signer": "^5.7.0",
|
||||
"@ethersproject/providers": "^5.7.2",
|
||||
"@orionprotocol/contracts": "1.19.5",
|
||||
"@orionprotocol/contracts": "1.22.1",
|
||||
"bignumber.js": "^9.1.1",
|
||||
"bson-objectid": "^2.0.4",
|
||||
"buffer": "^6.0.3",
|
||||
@@ -2419,9 +2419,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@orionprotocol/contracts": {
|
||||
"version": "1.19.5",
|
||||
"resolved": "https://registry.npmjs.org/@orionprotocol/contracts/-/contracts-1.19.5.tgz",
|
||||
"integrity": "sha512-z8oWz+BswG+kN2dZCgjmQJwNc52S3aAnchZX0JRMe8+l/4WHIYDJQ3W9pEClzvg/86LO41DAHmS73rHNrGAARw=="
|
||||
"version": "1.22.1",
|
||||
"resolved": "https://registry.npmjs.org/@orionprotocol/contracts/-/contracts-1.22.1.tgz",
|
||||
"integrity": "sha512-DrIyAmZ+LK3Eflv/gk6Uq3shpTLjeG4wV6PoKVxJKoqk05qL35cJs5V/2it16s5NolcQliFrtJ54G3xI78gTwA=="
|
||||
},
|
||||
"node_modules/@sinclair/typebox": {
|
||||
"version": "0.27.8",
|
||||
@@ -13460,9 +13460,9 @@
|
||||
}
|
||||
},
|
||||
"@orionprotocol/contracts": {
|
||||
"version": "1.19.5",
|
||||
"resolved": "https://registry.npmjs.org/@orionprotocol/contracts/-/contracts-1.19.5.tgz",
|
||||
"integrity": "sha512-z8oWz+BswG+kN2dZCgjmQJwNc52S3aAnchZX0JRMe8+l/4WHIYDJQ3W9pEClzvg/86LO41DAHmS73rHNrGAARw=="
|
||||
"version": "1.22.1",
|
||||
"resolved": "https://registry.npmjs.org/@orionprotocol/contracts/-/contracts-1.22.1.tgz",
|
||||
"integrity": "sha512-DrIyAmZ+LK3Eflv/gk6Uq3shpTLjeG4wV6PoKVxJKoqk05qL35cJs5V/2it16s5NolcQliFrtJ54G3xI78gTwA=="
|
||||
},
|
||||
"@sinclair/typebox": {
|
||||
"version": "0.27.8",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@orionprotocol/sdk",
|
||||
"version": "0.20.10-rc101",
|
||||
"version": "0.20.10-rc102",
|
||||
"description": "Orion Protocol SDK",
|
||||
"main": "./lib/index.cjs",
|
||||
"module": "./lib/index.js",
|
||||
@@ -88,7 +88,7 @@
|
||||
"@babel/runtime": "^7.21.0",
|
||||
"@ethersproject/abstract-signer": "^5.7.0",
|
||||
"@ethersproject/providers": "^5.7.2",
|
||||
"@orionprotocol/contracts": "1.19.5",
|
||||
"@orionprotocol/contracts": "1.22.1",
|
||||
"bignumber.js": "^9.1.1",
|
||||
"bson-objectid": "^2.0.4",
|
||||
"buffer": "^6.0.3",
|
||||
|
||||
@@ -1,28 +1,44 @@
|
||||
import { SwapExecutor__factory, CurveRegistry__factory } from "@orionprotocol/contracts/lib/ethers-v6/index.js"
|
||||
import type { BigNumberish, JsonRpcProvider } from "ethers"
|
||||
import { addCallParams } from "./utils.js"
|
||||
import type { SingleSwap } from "../../../types.js"
|
||||
import {
|
||||
SwapExecutor__factory,
|
||||
CurveRegistry__factory,
|
||||
ERC20__factory,
|
||||
} from "@orionprotocol/contracts/lib/ethers-v6/index.js";
|
||||
import { MaxUint256, type BigNumberish, type JsonRpcProvider } from "ethers";
|
||||
import { addCallParams } from "./utils.js";
|
||||
import type { SingleSwap } from "../../../types.js";
|
||||
import { generateApproveCall } from "./erc20.js";
|
||||
import type { BytesLike } from "ethers";
|
||||
|
||||
export async function generateCurveStableSwapCall(
|
||||
amount: BigNumberish,
|
||||
to: string,
|
||||
swap: SingleSwap,
|
||||
provider: JsonRpcProvider,
|
||||
swapExecutorContractAddress: string,
|
||||
curveRegistry: string
|
||||
) {
|
||||
const executorInterface = SwapExecutor__factory.createInterface()
|
||||
const registry = CurveRegistry__factory.connect(curveRegistry, provider)
|
||||
const { pool, assetIn, assetOut } = swap
|
||||
const [i, j,] = await registry.get_coin_indices(pool, assetIn, assetOut)
|
||||
const executorInterface = SwapExecutor__factory.createInterface();
|
||||
const registry = CurveRegistry__factory.connect(curveRegistry, provider);
|
||||
const { pool, assetIn, assetOut } = swap;
|
||||
const firstToken = ERC20__factory.connect(assetIn, provider)
|
||||
const executorAllowance = await firstToken.allowance(swapExecutorContractAddress, pool)
|
||||
|
||||
let calldata = executorInterface.encodeFunctionData('curveSwapStableAmountIn', [
|
||||
pool,
|
||||
assetOut,
|
||||
i,
|
||||
j,
|
||||
to,
|
||||
amount,
|
||||
])
|
||||
const calls: BytesLike[] = []
|
||||
if (executorAllowance <= BigInt(amount)) {
|
||||
const approveCall = await generateApproveCall(
|
||||
assetIn,
|
||||
pool,
|
||||
MaxUint256
|
||||
);
|
||||
calls.push(approveCall);
|
||||
}
|
||||
|
||||
return addCallParams(calldata)
|
||||
}
|
||||
const [i, j] = await registry.get_coin_indices(pool, assetIn, assetOut);
|
||||
let calldata = executorInterface.encodeFunctionData(
|
||||
"curveSwapStableAmountIn",
|
||||
[pool, assetOut, i, j, to, amount]
|
||||
);
|
||||
calls.push(addCallParams(calldata))
|
||||
|
||||
return calls
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { SwapExecutor__factory } from "@orionprotocol/contracts/lib/ethers-v6/index.js"
|
||||
import { SafeArray } from "../../../utils/safeGetters.js"
|
||||
import { type BytesLike, type BigNumberish, concat, ethers, toBeHex } from "ethers"
|
||||
import { addCallParams, generateCalls } from "./utils.js"
|
||||
import { addCallParams } from "./utils.js"
|
||||
import type { SingleSwap } from "../../../types.js"
|
||||
|
||||
export async function generateUni2Calls(
|
||||
@@ -33,7 +33,7 @@ export async function generateUni2Calls(
|
||||
])
|
||||
calls.push(addCallParams(calldata))
|
||||
|
||||
return generateCalls(calls)
|
||||
return calls
|
||||
}
|
||||
|
||||
export async function generateUni2Call(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { SwapExecutor__factory, UniswapV3Pool__factory } from "@orionprotocol/contracts/lib/ethers-v6/index.js"
|
||||
import { type BigNumberish , type BytesLike, ethers, JsonRpcProvider } from "ethers"
|
||||
import { type BigNumberish , ethers, JsonRpcProvider } from "ethers"
|
||||
import { SafeArray } from "../../../utils/safeGetters.js"
|
||||
import { addCallParams, generateCalls } from "./utils.js"
|
||||
import { addCallParams } from "./utils.js"
|
||||
import type { SingleSwap } from "../../../types.js"
|
||||
|
||||
export async function generateUni3Call(
|
||||
@@ -49,7 +49,7 @@ export async function generateUni3Calls(
|
||||
let calldata = executorInterface.encodeFunctionData('uniswapV3SwapTo', [encodedPools, recipient, amount])
|
||||
calldata = addCallParams(calldata)
|
||||
|
||||
return generateCalls([calldata])
|
||||
return [calldata]
|
||||
}
|
||||
|
||||
export async function generateOrion3Calls(
|
||||
@@ -67,7 +67,7 @@ export async function generateOrion3Calls(
|
||||
let calldata = executorInterface.encodeFunctionData('orionV3SwapTo', [encodedPools, recipient, amount])
|
||||
calldata = addCallParams(calldata)
|
||||
|
||||
return generateCalls([calldata])
|
||||
return [calldata]
|
||||
}
|
||||
|
||||
export async function encodePoolV3(
|
||||
|
||||
32
src/Unit/Exchange/callGenerators/weth.ts
Normal file
32
src/Unit/Exchange/callGenerators/weth.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { SwapExecutor__factory } from "@orionprotocol/contracts/lib/ethers-v6/index.js"
|
||||
import type { BigNumberish } from "ethers"
|
||||
import { type CallParams, addCallParams } from "./utils.js"
|
||||
import type { AddressLike } from "ethers"
|
||||
|
||||
export function generateWrapAndTransferCall(
|
||||
target: AddressLike,
|
||||
callParams?: CallParams
|
||||
) {
|
||||
|
||||
const executorInterface = SwapExecutor__factory.createInterface()
|
||||
const calldata = executorInterface.encodeFunctionData('wrapAndTransfer', [
|
||||
target,
|
||||
])
|
||||
|
||||
return addCallParams(calldata, callParams)
|
||||
}
|
||||
|
||||
export function generateUnwrapAndTransferCall(
|
||||
target: AddressLike,
|
||||
amount: BigNumberish,
|
||||
callParams?: CallParams
|
||||
) {
|
||||
|
||||
const executorInterface = SwapExecutor__factory.createInterface()
|
||||
const calldata = executorInterface.encodeFunctionData('unwrapAndTransfer', [
|
||||
target,
|
||||
amount
|
||||
])
|
||||
|
||||
return addCallParams(calldata, callParams)
|
||||
}
|
||||
@@ -1,61 +1,65 @@
|
||||
import type { LibValidator } from '@orionprotocol/contracts/lib/ethers-v6/Exchange.js';
|
||||
import type { LibValidator } from "@orionprotocol/contracts/lib/ethers-v6/Exchange.js";
|
||||
import { ethers, type BigNumberish, type BytesLike, JsonRpcProvider, ZeroAddress } from "ethers";
|
||||
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 {
|
||||
ERC20__factory
|
||||
} from '@orionprotocol/contracts/lib/ethers-v6/index.js';
|
||||
import { ethers, type BigNumberish, type BytesLike, JsonRpcProvider } from 'ethers';
|
||||
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 { generateApproveCall, generateTransferCall } from './callGenerators/erc20.js';
|
||||
import { generateCurveStableSwapCall } from './callGenerators/curve.js';
|
||||
import type { SingleSwap } from '../../types.js';
|
||||
import type { AddressLike } from 'ethers';
|
||||
import { addressLikeToString } from '../../utils/addressLikeToString.js';
|
||||
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 type { AddressLike } from "ethers";
|
||||
import { addressLikeToString } from "../../utils/addressLikeToString.js";
|
||||
import { generateUnwrapAndTransferCall, generateWrapAndTransferCall } from "./callGenerators/weth.js";
|
||||
|
||||
export type Factory = "UniswapV2" | "UniswapV3" | "Curve" | "OrionV2" | "OrionV3"
|
||||
export type Factory = "UniswapV2" | "UniswapV3" | "Curve" | "OrionV2" | "OrionV3";
|
||||
|
||||
export type GenerateSwapCalldataWithUnitParams = {
|
||||
amount: BigNumberish
|
||||
minReturnAmount: BigNumberish
|
||||
receiverAddress: string
|
||||
path: ArrayLike<SingleSwap>
|
||||
unit: Unit
|
||||
}
|
||||
amount: BigNumberish;
|
||||
minReturnAmount: BigNumberish;
|
||||
receiverAddress: string;
|
||||
path: ArrayLike<SingleSwap>;
|
||||
unit: Unit;
|
||||
};
|
||||
|
||||
export type GenerateSwapCalldataParams = {
|
||||
amount: BigNumberish
|
||||
minReturnAmount: BigNumberish
|
||||
receiverAddress: string
|
||||
path: ArrayLike<SingleSwap>
|
||||
wethAddress: AddressLike,
|
||||
curveRegistryAddress: AddressLike,
|
||||
swapExecutorContractAddress: AddressLike,
|
||||
exchangeContractAddress: AddressLike,
|
||||
provider: JsonRpcProvider
|
||||
}
|
||||
amount: BigNumberish;
|
||||
minReturnAmount: BigNumberish;
|
||||
receiverAddress: string;
|
||||
path: ArrayLike<SingleSwap>;
|
||||
wethAddress: AddressLike;
|
||||
curveRegistryAddress: AddressLike;
|
||||
swapExecutorContractAddress: AddressLike;
|
||||
provider: JsonRpcProvider;
|
||||
};
|
||||
|
||||
export async function generateSwapCalldataWithUnit({
|
||||
amount,
|
||||
minReturnAmount,
|
||||
receiverAddress,
|
||||
path: arrayLikePath,
|
||||
unit
|
||||
}: GenerateSwapCalldataWithUnitParams
|
||||
): Promise<{ calldata: string, swapDescription: LibValidator.SwapDescriptionStruct }> {
|
||||
unit,
|
||||
}: GenerateSwapCalldataWithUnitParams): Promise<{
|
||||
calldata: string;
|
||||
swapDescription: LibValidator.SwapDescriptionStruct;
|
||||
}> {
|
||||
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(unit.blockchainService.getInfo)();
|
||||
const wethAddress = safeGet(unit.contracts, "WETH");
|
||||
const curveRegistryAddress = safeGet(unit.contracts, "curveRegistry");
|
||||
const { assetToAddress, swapExecutorContractAddress } = await simpleFetch(unit.blockchainService.getInfo)();
|
||||
let path = SafeArray.from(arrayLikePath).map((swapInfo) => {
|
||||
swapInfo.assetIn = assetToAddress[swapInfo.assetIn] ?? swapInfo.assetIn.toLowerCase();
|
||||
swapInfo.assetOut = assetToAddress[swapInfo.assetOut] ?? swapInfo.assetOut.toLowerCase();
|
||||
return swapInfo;
|
||||
})
|
||||
});
|
||||
|
||||
return generateSwapCalldata({
|
||||
amount,
|
||||
@@ -65,9 +69,8 @@ export async function generateSwapCalldataWithUnit({
|
||||
wethAddress,
|
||||
curveRegistryAddress,
|
||||
swapExecutorContractAddress,
|
||||
exchangeContractAddress,
|
||||
provider: unit.provider
|
||||
})
|
||||
provider: unit.provider,
|
||||
});
|
||||
}
|
||||
|
||||
export async function generateSwapCalldata({
|
||||
@@ -78,198 +81,182 @@ export async function generateSwapCalldata({
|
||||
wethAddress: wethAddressLike,
|
||||
curveRegistryAddress: curveRegistryAddressLike,
|
||||
swapExecutorContractAddress: swapExecutorContractAddressLike,
|
||||
exchangeContractAddress: exchangeContractAddressLike,
|
||||
provider,
|
||||
}: GenerateSwapCalldataParams) {
|
||||
const wethAddress = await addressLikeToString(wethAddressLike)
|
||||
const curveRegistryAddress = await addressLikeToString(curveRegistryAddressLike)
|
||||
const swapExecutorContractAddress = await addressLikeToString(swapExecutorContractAddressLike)
|
||||
const exchangeContractAddress = await addressLikeToString(exchangeContractAddressLike)
|
||||
let path = SafeArray.from(arrayLikePath)
|
||||
const wethAddress = await addressLikeToString(wethAddressLike);
|
||||
const curveRegistryAddress = await addressLikeToString(curveRegistryAddressLike);
|
||||
const swapExecutorContractAddress = await addressLikeToString(swapExecutorContractAddressLike);
|
||||
let path = SafeArray.from(arrayLikePath);
|
||||
|
||||
const { factory, assetIn: srcToken } = path.first()
|
||||
const dstToken = path.last().assetOut
|
||||
const { factory, assetIn: srcToken } = path.first();
|
||||
const dstToken = path.last().assetOut;
|
||||
|
||||
const amountNativeDecimals = await exchangeToNativeDecimals(srcToken, amount, provider);
|
||||
const minReturnAmountNativeDecimals = await exchangeToNativeDecimals(dstToken, minReturnAmount, provider);
|
||||
let swapDescription: LibValidator.SwapDescriptionStruct = {
|
||||
srcToken: srcToken,
|
||||
dstToken: dstToken,
|
||||
srcReceiver: swapExecutorContractAddress,
|
||||
dstReceiver: receiverAddress,
|
||||
amount,
|
||||
minReturnAmount,
|
||||
flags: 0
|
||||
}
|
||||
const amountNativeDecimals = await exchangeToNativeDecimals(srcToken, amount, provider);
|
||||
amount: amountNativeDecimals,
|
||||
minReturnAmount: minReturnAmountNativeDecimals,
|
||||
flags: 0,
|
||||
};
|
||||
|
||||
path = SafeArray.from(arrayLikePath).map((singleSwap) => {
|
||||
if (singleSwap.assetIn == ethers.ZeroAddress) singleSwap.assetIn = wethAddress
|
||||
if (singleSwap.assetOut == ethers.ZeroAddress) singleSwap.assetOut = wethAddress
|
||||
if (singleSwap.assetIn == ethers.ZeroAddress) singleSwap.assetIn = wethAddress;
|
||||
if (singleSwap.assetOut == ethers.ZeroAddress) singleSwap.assetOut = wethAddress;
|
||||
return singleSwap;
|
||||
});
|
||||
|
||||
const isSingleFactorySwap = path.every(singleSwap => singleSwap.factory === factory)
|
||||
let calldata: BytesLike
|
||||
|
||||
const isSingleFactorySwap = path.every((singleSwap) => singleSwap.factory === factory);
|
||||
let calls: BytesLike[];
|
||||
if (isSingleFactorySwap) {
|
||||
({ swapDescription, calldata } = await processSingleFactorySwaps(
|
||||
({ swapDescription, calls } = await processSingleFactorySwaps(
|
||||
factory,
|
||||
swapDescription,
|
||||
path,
|
||||
exchangeContractAddress,
|
||||
amountNativeDecimals,
|
||||
swapExecutorContractAddress,
|
||||
curveRegistryAddress,
|
||||
provider
|
||||
))
|
||||
));
|
||||
} else {
|
||||
({ swapDescription, calldata } = await processMultiFactorySwaps(
|
||||
({ swapDescription, calls } = await processMultiFactorySwaps(
|
||||
swapDescription,
|
||||
path,
|
||||
exchangeContractAddress,
|
||||
amountNativeDecimals,
|
||||
swapExecutorContractAddress,
|
||||
curveRegistryAddress,
|
||||
provider
|
||||
))
|
||||
));
|
||||
}
|
||||
|
||||
return { swapDescription, calldata }
|
||||
calls = wrapOrUnwrapIfNeeded(swapDescription, calls);
|
||||
const calldata = generateCalls(calls);
|
||||
return { swapDescription, calldata };
|
||||
}
|
||||
|
||||
async function processSingleFactorySwaps(
|
||||
factory: Factory,
|
||||
swapDescription: LibValidator.SwapDescriptionStruct,
|
||||
path: SafeArray<SingleSwap>,
|
||||
recipient: string,
|
||||
amount: BigNumberish,
|
||||
swapExecutorContractAddress: string,
|
||||
curveRegistryAddress: string,
|
||||
provider: JsonRpcProvider
|
||||
) {
|
||||
let calldata: BytesLike
|
||||
let calls: BytesLike[] = [];
|
||||
switch (factory) {
|
||||
case 'OrionV2': {
|
||||
swapDescription.srcReceiver = path.first().pool
|
||||
calldata = await generateUni2Calls(path, recipient);
|
||||
case "OrionV2": {
|
||||
swapDescription.srcReceiver = path.first().pool;
|
||||
calls = await generateUni2Calls(path, swapExecutorContractAddress);
|
||||
break;
|
||||
}
|
||||
case 'UniswapV2': {
|
||||
swapDescription.srcReceiver = path.first().pool
|
||||
calldata = await generateUni2Calls(path, recipient);
|
||||
case "UniswapV2": {
|
||||
swapDescription.srcReceiver = path.first().pool;
|
||||
calls = await generateUni2Calls(path, swapExecutorContractAddress);
|
||||
break;
|
||||
}
|
||||
case 'UniswapV3': {
|
||||
calldata = await generateUni3Calls(path, amount, recipient, provider)
|
||||
case "UniswapV3": {
|
||||
calls = await generateUni3Calls(path, amount, swapExecutorContractAddress, provider);
|
||||
break;
|
||||
}
|
||||
case 'OrionV3': {
|
||||
calldata = await generateOrion3Calls(path, amount, recipient, provider)
|
||||
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");
|
||||
}
|
||||
const { pool, assetIn } = path.first()
|
||||
const firstToken = ERC20__factory.connect(assetIn, provider)
|
||||
const executorAllowance = await firstToken.allowance(swapExecutorContractAddress, pool)
|
||||
const calls: BytesLike[] = []
|
||||
if (executorAllowance <= BigInt(amount)) {
|
||||
const approveCall = await generateApproveCall(
|
||||
assetIn,
|
||||
pool,
|
||||
ethers.MaxUint256
|
||||
)
|
||||
calls.push(approveCall)
|
||||
}
|
||||
let curveCall = await generateCurveStableSwapCall(
|
||||
calls = await generateCurveStableSwapCall(
|
||||
amount,
|
||||
recipient,
|
||||
swapExecutorContractAddress,
|
||||
path.first(),
|
||||
provider,
|
||||
swapExecutorContractAddress,
|
||||
curveRegistryAddress
|
||||
);
|
||||
calls.push(curveCall)
|
||||
calldata = await generateCalls(calls)
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw new Error(`Factory ${factory} is not supported`)
|
||||
throw new Error(`Factory ${factory} is not supported`);
|
||||
}
|
||||
}
|
||||
return { swapDescription, calldata }
|
||||
return { swapDescription, calls };
|
||||
}
|
||||
|
||||
async function processMultiFactorySwaps(
|
||||
swapDescription: LibValidator.SwapDescriptionStruct,
|
||||
path: SafeArray<SingleSwap>,
|
||||
recipient: string,
|
||||
amount: BigNumberish,
|
||||
swapExecutorContractAddress: string,
|
||||
curveRegistryAddress: string,
|
||||
provider: JsonRpcProvider
|
||||
) {
|
||||
let calls: BytesLike[] = []
|
||||
let calls: BytesLike[] = [];
|
||||
if (swapDescription.srcToken === ZeroAddress) {
|
||||
const wrapCall = await generateWrapAndTransferCall(swapExecutorContractAddress, { value: amount });
|
||||
calls.push(wrapCall);
|
||||
}
|
||||
for (const swap of path) {
|
||||
switch (swap.factory) {
|
||||
case 'OrionV2': {
|
||||
let transferCall = await generateTransferCall(swap.assetIn, swap.pool, 0)
|
||||
transferCall = pathCallWithBalance(transferCall, swap.assetIn)
|
||||
const uni2Call = await generateUni2Call(swap.pool, swap.assetIn, swap.assetOut, swapExecutorContractAddress)
|
||||
calls = calls.concat([transferCall, uni2Call])
|
||||
case "OrionV2": {
|
||||
let transferCall = await generateTransferCall(swap.assetIn, swap.pool, 0);
|
||||
transferCall = pathCallWithBalance(transferCall, swap.assetIn);
|
||||
const uni2Call = await generateUni2Call(swap.pool, swap.assetIn, swap.assetOut, swapExecutorContractAddress);
|
||||
calls.push(transferCall, uni2Call);
|
||||
break;
|
||||
}
|
||||
case 'UniswapV2': {
|
||||
let transferCall = await generateTransferCall(swap.assetIn, swap.pool, 0)
|
||||
transferCall = pathCallWithBalance(transferCall, swap.assetIn)
|
||||
const uni2Call = await generateUni2Call(swap.pool, swap.assetIn, swap.assetOut, swapExecutorContractAddress)
|
||||
calls = calls.concat([transferCall, uni2Call])
|
||||
case "UniswapV2": {
|
||||
let transferCall = await generateTransferCall(swap.assetIn, swap.pool, 0);
|
||||
transferCall = pathCallWithBalance(transferCall, swap.assetIn);
|
||||
const uni2Call = await generateUni2Call(swap.pool, swap.assetIn, swap.assetOut, swapExecutorContractAddress);
|
||||
calls.push(transferCall, uni2Call);
|
||||
break;
|
||||
}
|
||||
case 'UniswapV3': {
|
||||
let uni3Call = await generateUni3Call(swap, 0, swapExecutorContractAddress, provider)
|
||||
uni3Call = pathCallWithBalance(uni3Call, swap.assetIn)
|
||||
calls.push(uni3Call)
|
||||
case "UniswapV3": {
|
||||
let uni3Call = await generateUni3Call(swap, 0, swapExecutorContractAddress, provider);
|
||||
uni3Call = pathCallWithBalance(uni3Call, swap.assetIn);
|
||||
calls.push(uni3Call);
|
||||
break;
|
||||
}
|
||||
case 'OrionV3': {
|
||||
let orion3Call = await generateOrion3Call(swap, 0, swapExecutorContractAddress, provider)
|
||||
orion3Call = pathCallWithBalance(orion3Call, swap.assetIn)
|
||||
calls.push(orion3Call)
|
||||
case "OrionV3": {
|
||||
let orion3Call = await generateOrion3Call(swap, 0, swapExecutorContractAddress, provider);
|
||||
orion3Call = pathCallWithBalance(orion3Call, swap.assetIn);
|
||||
calls.push(orion3Call);
|
||||
break;
|
||||
}
|
||||
case 'Curve': {
|
||||
const { pool, assetIn } = swap
|
||||
const firstToken = ERC20__factory.connect(assetIn, provider)
|
||||
const executorAllowance = await firstToken.allowance(swapExecutorContractAddress, pool)
|
||||
if (executorAllowance <= BigInt(amount)) {
|
||||
const approveCall = await generateApproveCall(
|
||||
assetIn,
|
||||
pool,
|
||||
ethers.MaxUint256
|
||||
)
|
||||
calls.push(approveCall)
|
||||
}
|
||||
let curveCall = await generateCurveStableSwapCall(
|
||||
case "Curve": {
|
||||
let curveCalls = await generateCurveStableSwapCall(
|
||||
amount,
|
||||
swapExecutorContractAddress,
|
||||
swap,
|
||||
provider,
|
||||
swapExecutorContractAddress,
|
||||
curveRegistryAddress
|
||||
);
|
||||
curveCall = pathCallWithBalance(curveCall, swap.assetIn)
|
||||
calls.push(curveCall)
|
||||
calls.push(...curveCalls);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw new Error(`Factory ${swap.factory} is not supported`)
|
||||
throw new Error(`Factory ${swap.factory} is not supported`);
|
||||
}
|
||||
}
|
||||
}
|
||||
const dstToken = swapDescription.dstToken
|
||||
let finalTransferCall = await generateTransferCall(dstToken, recipient, 0)
|
||||
finalTransferCall = pathCallWithBalance(finalTransferCall, dstToken)
|
||||
calls.push(finalTransferCall)
|
||||
const calldata = generateCalls(calls)
|
||||
|
||||
return { swapDescription, calldata }
|
||||
return { swapDescription, calls };
|
||||
}
|
||||
|
||||
function wrapOrUnwrapIfNeeded(swapDescription: LibValidator.SwapDescriptionStruct, calls: BytesLike[]): BytesLike[] {
|
||||
if (swapDescription.srcToken === ZeroAddress) {
|
||||
const wrapCall = generateWrapAndTransferCall(swapDescription.dstReceiver, { value: swapDescription.amount });
|
||||
calls = ([wrapCall] as BytesLike[]).concat(calls);
|
||||
}
|
||||
if (swapDescription.dstToken === ZeroAddress) {
|
||||
let unwrapCall = generateUnwrapAndTransferCall(swapDescription.dstReceiver, 0);
|
||||
unwrapCall = pathCallWithBalance(unwrapCall, swapDescription.dstToken);
|
||||
calls.push(unwrapCall);
|
||||
}
|
||||
return calls;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user