From 826b3b508caae83d18fb9adb0ba2afa2fdf7770e Mon Sep 17 00:00:00 2001 From: Steam Deck User <0xlomonoshka@gmail.com> Date: Fri, 15 Dec 2023 17:55:44 +0400 Subject: [PATCH] added fee payment to matcher if dst.Token === feeToken --- package-lock.json | 18 ++--- package.json | 4 +- src/Unit/Exchange/callGenerators/erc20.ts | 7 +- .../Exchange/callGenerators/feePayment.ts | 21 ++++++ src/Unit/Exchange/callGenerators/uniswapV2.ts | 2 +- src/Unit/Exchange/generateSwapCalldata.ts | 66 +++++++++++++++---- 6 files changed, 90 insertions(+), 28 deletions(-) create mode 100644 src/Unit/Exchange/callGenerators/feePayment.ts diff --git a/package-lock.json b/package-lock.json index e5dea1e..9d3274b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,19 +1,19 @@ { "name": "@orionprotocol/sdk", - "version": "0.20.28", + "version": "0.20.32", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@orionprotocol/sdk", - "version": "0.20.28", + "version": "0.20.32", "hasInstallScript": true, "license": "ISC", "dependencies": { "@babel/runtime": "^7.21.0", "@ethersproject/abstract-signer": "^5.7.0", "@ethersproject/providers": "^5.7.2", - "@orionprotocol/contracts": "1.22.3", + "@orionprotocol/contracts": "1.22.5", "@types/lodash.clonedeep": "^4.5.9", "bignumber.js": "^9.1.1", "bson-objectid": "^2.0.4", @@ -2421,9 +2421,9 @@ } }, "node_modules/@orionprotocol/contracts": { - "version": "1.22.3", - "resolved": "https://registry.npmjs.org/@orionprotocol/contracts/-/contracts-1.22.3.tgz", - "integrity": "sha512-TVZftFbrHA+ldZSvMAGTntSiTT20UWn6P/+N392A9dv6RtiIXaQpMic5hOhVdIed74DU/KixVxwjVL1Hr0RLGQ==" + "version": "1.22.5", + "resolved": "https://registry.npmjs.org/@orionprotocol/contracts/-/contracts-1.22.5.tgz", + "integrity": "sha512-kBgqMw0uqotl9UbSubw5cmEsck5aefS9l9/5DNvFfOfMLY1ewFLtn03X3/mO73ll1Y6tZBtqzYTGNZpcnk7tKA==" }, "node_modules/@sinclair/typebox": { "version": "0.27.8", @@ -13480,9 +13480,9 @@ } }, "@orionprotocol/contracts": { - "version": "1.22.3", - "resolved": "https://registry.npmjs.org/@orionprotocol/contracts/-/contracts-1.22.3.tgz", - "integrity": "sha512-TVZftFbrHA+ldZSvMAGTntSiTT20UWn6P/+N392A9dv6RtiIXaQpMic5hOhVdIed74DU/KixVxwjVL1Hr0RLGQ==" + "version": "1.22.5", + "resolved": "https://registry.npmjs.org/@orionprotocol/contracts/-/contracts-1.22.5.tgz", + "integrity": "sha512-kBgqMw0uqotl9UbSubw5cmEsck5aefS9l9/5DNvFfOfMLY1ewFLtn03X3/mO73ll1Y6tZBtqzYTGNZpcnk7tKA==" }, "@sinclair/typebox": { "version": "0.27.8", diff --git a/package.json b/package.json index 98378d0..513f328 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@orionprotocol/sdk", - "version": "0.20.34", + "version": "0.20.34-rc-0", "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.22.3", + "@orionprotocol/contracts": "1.22.5", "@types/lodash.clonedeep": "^4.5.9", "bignumber.js": "^9.1.1", "bson-objectid": "^2.0.4", diff --git a/src/Unit/Exchange/callGenerators/erc20.ts b/src/Unit/Exchange/callGenerators/erc20.ts index e88e24a..bd54dd2 100644 --- a/src/Unit/Exchange/callGenerators/erc20.ts +++ b/src/Unit/Exchange/callGenerators/erc20.ts @@ -1,9 +1,8 @@ import { SwapExecutor__factory } from "@orionprotocol/contracts/lib/ethers-v6/index.js" -import type { BigNumberish } from "ethers" +import type { BigNumberish, AddressLike } from "ethers" import { type CallParams, addCallParams } from "./utils.js" -import type { AddressLike } from "ethers" -export async function generateTransferCall( +export function generateTransferCall( token: AddressLike, target: AddressLike, amount: BigNumberish, @@ -20,7 +19,7 @@ export async function generateTransferCall( return addCallParams(calldata, callParams) } -export async function generateApproveCall( +export function generateApproveCall( token: AddressLike, target: AddressLike, amount: BigNumberish, diff --git a/src/Unit/Exchange/callGenerators/feePayment.ts b/src/Unit/Exchange/callGenerators/feePayment.ts new file mode 100644 index 0000000..ee1eb29 --- /dev/null +++ b/src/Unit/Exchange/callGenerators/feePayment.ts @@ -0,0 +1,21 @@ +import { SwapExecutor__factory } from "@orionprotocol/contracts/lib/ethers-v6/index.js" +import type { BigNumberish, AddressLike } from "ethers" +import { type CallParams, addCallParams } from "./utils.js" + + +export function generateFeePaymentCall( + matcher: AddressLike, + token: AddressLike, + amount: BigNumberish, + callParams?: CallParams +) { + + const executorInterface = SwapExecutor__factory.createInterface() + const calldata = executorInterface.encodeFunctionData('payFeeToMatcher', [ + matcher, + token, + amount + ]) + + return addCallParams(calldata, callParams) +} \ No newline at end of file diff --git a/src/Unit/Exchange/callGenerators/uniswapV2.ts b/src/Unit/Exchange/callGenerators/uniswapV2.ts index 19b86b0..4526fca 100644 --- a/src/Unit/Exchange/callGenerators/uniswapV2.ts +++ b/src/Unit/Exchange/callGenerators/uniswapV2.ts @@ -36,7 +36,7 @@ export async function generateUni2Calls( return calls } -export async function generateUni2Call( +export function generateUni2Call( pool: string, assetIn: string, assetOut: string, diff --git a/src/Unit/Exchange/generateSwapCalldata.ts b/src/Unit/Exchange/generateSwapCalldata.ts index cefce17..343723a 100644 --- a/src/Unit/Exchange/generateSwapCalldata.ts +++ b/src/Unit/Exchange/generateSwapCalldata.ts @@ -19,6 +19,7 @@ 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"; @@ -27,6 +28,9 @@ export type GenerateSwapCalldataWithUnitParams = { minReturnAmount: BigNumberish; initiatorAddress: string; receiverAddress: string; + matcher: AddressLike, + feeToken: AddressLike, + fee: BigNumberish; path: ArrayLike; unit: Unit; }; @@ -37,6 +41,9 @@ export type GenerateSwapCalldataParams = { initiatorAddress: string; receiverAddress: string; path: ArrayLike; + matcher: AddressLike, + feeToken: AddressLike, + fee: BigNumberish; exchangeContractAddress: AddressLike; wethAddress: AddressLike; curveRegistryAddress: AddressLike; @@ -50,6 +57,9 @@ export async function generateSwapCalldataWithUnit({ initiatorAddress, receiverAddress, path: arrayLikePath, + matcher = ZeroAddress, + feeToken = ZeroAddress, + fee = 0, unit, }: GenerateSwapCalldataWithUnitParams): Promise<{ calldata: string; @@ -80,6 +90,9 @@ export async function generateSwapCalldataWithUnit({ receiverAddress, initiatorAddress, path, + matcher, + feeToken, + fee, exchangeContractAddress, wethAddress, curveRegistryAddress, @@ -94,6 +107,9 @@ export async function generateSwapCalldata({ initiatorAddress, receiverAddress, path: arrayLikePath, + matcher = ZeroAddress, + feeToken = ZeroAddress, + fee = 0, exchangeContractAddress, wethAddress: wethAddressLike, curveRegistryAddress: curveRegistryAddressLike, @@ -134,6 +150,9 @@ export async function generateSwapCalldata({ swapDescription, path, amountNativeDecimals, + matcher, + feeToken, + fee, wethAddress, swapExecutorContractAddress, curveRegistryAddress, @@ -159,6 +178,9 @@ async function processSwaps( swapDescription: LibValidator.SwapDescriptionStruct, path: SafeArray, amount: BigNumberish, + matcher: AddressLike, + feeToken: AddressLike, + fee: BigNumberish, wethAddress: string, swapExecutorContractAddress: string, curveRegistryAddress: string, @@ -187,13 +209,17 @@ async function processSwaps( provider )); } - ({ swapDescription, calls } = await wrapOrUnwrapIfNeeded( + + ({swapDescription, calls} = payFeeToMatcher(matcher, feeToken, fee, calls, swapDescription)); + + ({ swapDescription, calls } = wrapOrUnwrapIfNeeded( amount, swapDescription, calls, swapExecutorContractAddress, wethAddress )); + return { swapDescription, calls }; } @@ -259,16 +285,16 @@ async function processMultiFactorySwaps( for (const swap of path) { switch (swap.factory) { case "OrionV2": { - let transferCall = await generateTransferCall(swap.assetIn, swap.pool, 0); + let transferCall = generateTransferCall(swap.assetIn, swap.pool, 0); transferCall = pathCallWithBalance(transferCall, swap.assetIn); - const uni2Call = await generateUni2Call(swap.pool, swap.assetIn, swap.assetOut, swapExecutorContractAddress); + const uni2Call = generateUni2Call(swap.pool, swap.assetIn, swap.assetOut, swapExecutorContractAddress); calls.push(transferCall, uni2Call); break; } case "UniswapV2": { - let transferCall = await generateTransferCall(swap.assetIn, swap.pool, 0); + let transferCall = generateTransferCall(swap.assetIn, swap.pool, 0); transferCall = pathCallWithBalance(transferCall, swap.assetIn); - const uni2Call = await generateUni2Call(swap.pool, swap.assetIn, swap.assetOut, swapExecutorContractAddress); + const uni2Call = generateUni2Call(swap.pool, swap.assetIn, swap.assetOut, swapExecutorContractAddress); calls.push(transferCall, uni2Call); break; } @@ -305,25 +331,41 @@ async function processMultiFactorySwaps( return { swapDescription, calls }; } -async function wrapOrUnwrapIfNeeded( +function payFeeToMatcher( + matcher: AddressLike, + feeToken: AddressLike, + feeAmount: BigNumberish, + calls: BytesLike[], + swapDescription: LibValidator.SwapDescriptionStruct, +) { + feeAmount = BigInt(feeAmount) + if (feeAmount !== 0n && feeToken === swapDescription.dstToken) { + const feePaymentCall = generateFeePaymentCall(matcher, feeToken, feeAmount) + calls.push(feePaymentCall) + } + return {swapDescription, calls} +} + +function wrapOrUnwrapIfNeeded( amount: BigNumberish, swapDescription: LibValidator.SwapDescriptionStruct, calls: BytesLike[], swapExecutorContractAddress: string, wethAddress: string ) { - if (swapDescription.srcToken === ZeroAddress) { - const wrapCall = generateWrapAndTransferCall(swapDescription.srcReceiver, { value: amount }); + const {dstReceiver, srcReceiver, srcToken, dstToken} = swapDescription; + if (srcToken === ZeroAddress) { + const wrapCall = generateWrapAndTransferCall(srcReceiver, { value: amount }); swapDescription.srcReceiver = swapExecutorContractAddress; calls = ([wrapCall] as BytesLike[]).concat(calls); } - if (swapDescription.dstToken === ZeroAddress) { - let unwrapCall = generateUnwrapAndTransferCall(swapDescription.dstReceiver, 0); + if (dstToken === ZeroAddress) { + let unwrapCall = generateUnwrapAndTransferCall(dstReceiver, 0); unwrapCall = pathCallWithBalance(unwrapCall, wethAddress); calls.push(unwrapCall); } else { - let transferCall = await generateTransferCall(swapDescription.dstToken, swapDescription.dstReceiver, 0); - transferCall = pathCallWithBalance(transferCall, swapDescription.dstToken); + let transferCall = generateTransferCall(dstToken, dstReceiver, 0); + transferCall = pathCallWithBalance(transferCall, dstToken); calls.push(transferCall); } return { swapDescription, calls };