Skip to content

Commit

Permalink
feat: build cross swap tx
Browse files Browse the repository at this point in the history
  • Loading branch information
dohaki committed Nov 14, 2024
1 parent 1e36933 commit 57b5d6d
Show file tree
Hide file tree
Showing 7 changed files with 450 additions and 202 deletions.
99 changes: 98 additions & 1 deletion api/_dexes/cross-swap.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
import { SpokePool } from "@across-protocol/contracts/dist/typechain";

import {
isRouteEnabled,
isInputTokenBridgeable,
isOutputTokenBridgeable,
getBridgeQuoteForMinOutput,
getSpokePool,
latestGasPriceCache,
} from "../_utils";
import {
getUniswapCrossSwapQuotesForMinOutputB2A,
getUniswapCrossSwapQuotesForMinOutputA2B,
getBestUniswapCrossSwapQuotesForMinOutputA2A,
} from "./uniswap";
import { CrossSwap, CrossSwapQuotes } from "./types";
import { getSwapAndBridge } from "./utils";
import { tagIntegratorId } from "../_integrator-id";
import { PopulatedTransaction } from "ethers";
import { getMultiCallHandlerAddress } from "../_multicall-handler";

export type CrossSwapType =
(typeof CROSS_SWAP_TYPE)[keyof typeof CROSS_SWAP_TYPE];
Expand Down Expand Up @@ -139,4 +147,93 @@ export function getCrossSwapType(params: {
return CROSS_SWAP_TYPE.ANY_TO_ANY;
}

export function calcFees() {}
export async function buildCrossSwapTx(
crossSwapQuotes: CrossSwapQuotes,
integratorId?: string
) {
const originChainId = crossSwapQuotes.crossSwap.inputToken.chainId;
const destinationChainId = crossSwapQuotes.crossSwap.outputToken.chainId;
const spokePool = getSpokePool(originChainId);
const deposit = {
depositor: crossSwapQuotes.crossSwap.recipient,
recipient: crossSwapQuotes.destinationSwapQuote
? getMultiCallHandlerAddress(destinationChainId)
: crossSwapQuotes.crossSwap.recipient,
inputToken: crossSwapQuotes.bridgeQuote.inputToken.address,
outputToken: crossSwapQuotes.bridgeQuote.outputToken.address,
inputAmount: crossSwapQuotes.bridgeQuote.inputAmount,
outputAmount: crossSwapQuotes.bridgeQuote.outputAmount,
destinationChainid: crossSwapQuotes.bridgeQuote.outputToken.chainId,
exclusiveRelayer:
crossSwapQuotes.bridgeQuote.suggestedFees.exclusiveRelayer,
quoteTimestamp: crossSwapQuotes.bridgeQuote.suggestedFees.timestamp,
fillDeadline: await getFillDeadline(spokePool),
exclusivityDeadline:
crossSwapQuotes.bridgeQuote.suggestedFees.exclusivityDeadline,
message: crossSwapQuotes.bridgeQuote?.message || "0x",
};

let tx: PopulatedTransaction;
let toAddress: string;

if (crossSwapQuotes.originSwapQuote) {
const swapAndBridge = getSwapAndBridge("uniswap", originChainId);
tx = await swapAndBridge.populateTransaction.swapAndBridge(
crossSwapQuotes.originSwapQuote.tokenIn.address,
crossSwapQuotes.originSwapQuote.tokenOut.address,
crossSwapQuotes.originSwapQuote.swapTx.data,
crossSwapQuotes.originSwapQuote.maximumAmountIn,
crossSwapQuotes.originSwapQuote.minAmountOut,
deposit
);
toAddress = swapAndBridge.address;
console.log(tx, toAddress);
} else {
const spokePool = getSpokePool(
crossSwapQuotes.crossSwap.inputToken.chainId
);
tx = await spokePool.populateTransaction.depositV3(
deposit.depositor,
deposit.recipient,
deposit.inputToken,
deposit.outputToken,
deposit.inputAmount,
deposit.outputAmount,
deposit.destinationChainid,
deposit.exclusiveRelayer,
deposit.quoteTimestamp,
deposit.fillDeadline,
deposit.exclusivityDeadline,
deposit.message
);
toAddress = spokePool.address;
}

const [gas, gasPrice] = await Promise.all([
spokePool.provider.estimateGas({
from: crossSwapQuotes.crossSwap.depositor,
...tx,
}),
latestGasPriceCache(originChainId).get(),
]);

return {
from: crossSwapQuotes.crossSwap.depositor,
to: toAddress,
data: integratorId ? tagIntegratorId(integratorId, tx.data!) : tx.data,
gas,
gasPrice,
value: tx.value,
};
}

async function getFillDeadline(spokePool: SpokePool): Promise<number> {
const calls = [
spokePool.interface.encodeFunctionData("getCurrentTime"),
spokePool.interface.encodeFunctionData("fillDeadlineBuffer"),
];

const [currentTime, fillDeadlineBuffer] =
await spokePool.callStatic.multicall(calls);
return Number(currentTime) + Number(fillDeadlineBuffer);
}
1 change: 1 addition & 0 deletions api/_dexes/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export type CrossSwap = {
amount: BigNumber;
inputToken: Token;
outputToken: Token;
depositor: string;
recipient: string;
slippageTolerance: number;
type: AmountType;
Expand Down
Loading

0 comments on commit 57b5d6d

Please sign in to comment.