Skip to content

Commit

Permalink
Merge pull request #1490 from multiversx/SERVICES-2610-update-transac…
Browse files Browse the repository at this point in the history
…tion-generation-for-wrap-sc

[SERVICES-2610] Update transaction generation for Wrap SC
  • Loading branch information
mad2sm0key authored Sep 27, 2024
2 parents 4899b8c + bdbf8fc commit 8f698ce
Show file tree
Hide file tree
Showing 17 changed files with 1,404 additions and 906 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
AddressValue,
BigUIntValue,
BytesValue,
Token,
TokenTransfer,
TypedValue,
} from '@multiversx/sdk-core';
Expand All @@ -19,6 +20,7 @@ import { ComposableTasksTransactionService } from 'src/modules/composable-tasks/
import { EsdtTokenPayment } from '@multiversx/sdk-exchange';
import { EgldOrEsdtTokenPayment } from 'src/models/esdtTokenPayment.model';
import { decimalToHex } from 'src/utils/token.converters';
import { TransactionOptions } from 'src/modules/common/transaction.options';

@Injectable()
export class AutoRouterTransactionService {
Expand All @@ -33,7 +35,6 @@ export class AutoRouterTransactionService {
args: MultiSwapTokensArgs,
): Promise<TransactionModel[]> {
const transactions = [];
const contract = await this.mxProxy.getRouterSmartContract();

const amountIn = new BigNumber(args.intermediaryAmounts[0]).plus(
new BigNumber(args.intermediaryAmounts[0]).multipliedBy(
Expand All @@ -44,6 +45,7 @@ export class AutoRouterTransactionService {
if (args.tokenInID === mxConfig.EGLDIdentifier) {
return [
await this.wrapEgldAndMultiSwapTransaction(
sender,
amountIn.integerValue().toFixed(),
args,
),
Expand All @@ -53,6 +55,7 @@ export class AutoRouterTransactionService {
if (args.tokenOutID === mxConfig.EGLDIdentifier) {
return [
await this.multiSwapAndUnwrapEgldTransaction(
sender,
amountIn.integerValue().toFixed(),
args,
),
Expand All @@ -62,25 +65,31 @@ export class AutoRouterTransactionService {
const gasLimit =
args.addressRoute.length * gasConfig.router.multiPairSwapMultiplier;

const transactionArgs =
args.swapType == SWAP_TYPE.fixedInput
? this.multiPairFixedInputSwaps(args)
: this.multiPairFixedOutputSwaps(args);
const transactionOptions = new TransactionOptions({
sender: sender,
chainID: mxConfig.chainID,
gasLimit: gasLimit,
function: 'multiPairSwap',
arguments:
args.swapType == SWAP_TYPE.fixedInput
? this.multiPairFixedInputSwaps(args)
: this.multiPairFixedOutputSwaps(args),
tokenTransfers: [
new TokenTransfer({
token: new Token({
identifier: args.tokenRoute[0],
}),
amount: BigInt(amountIn.integerValue().toFixed()),
}),
],
});

const transaction =
await this.mxProxy.getRouterSmartContractTransaction(
transactionOptions,
);
transactions.push(transaction);

transactions.push(
contract.methodsExplicit
.multiPairSwap(transactionArgs)
.withSingleESDTTransfer(
TokenTransfer.fungibleFromBigInteger(
args.tokenRoute[0],
amountIn.integerValue(),
),
)
.withGasLimit(gasLimit)
.withChainID(mxConfig.chainID)
.buildTransaction()
.toPlainObject(),
);
if (args.tokenOutID === mxConfig.EGLDIdentifier) {
transactions.push(
await this.transactionsWrapService.unwrapEgld(
Expand Down Expand Up @@ -209,6 +218,7 @@ export class AutoRouterTransactionService {
}

async wrapEgldAndMultiSwapTransaction(
sender: string,
value: string,
args: MultiSwapTokensArgs,
): Promise<TransactionModel> {
Expand All @@ -219,6 +229,7 @@ export class AutoRouterTransactionService {
const swaps = this.convertMultiPairSwapsToBytesValues(typedArgs);

return this.composeTasksTransactionService.getComposeTasksTransaction(
sender,
new EsdtTokenPayment({
tokenIdentifier: 'EGLD',
tokenNonce: 0,
Expand All @@ -245,6 +256,7 @@ export class AutoRouterTransactionService {
}

async multiSwapAndUnwrapEgldTransaction(
sender: string,
value: string,
args: MultiSwapTokensArgs,
): Promise<TransactionModel> {
Expand All @@ -255,6 +267,7 @@ export class AutoRouterTransactionService {
const swaps = this.convertMultiPairSwapsToBytesValues(typedArgs);

return this.composeTasksTransactionService.getComposeTasksTransaction(
sender,
new EsdtTokenPayment({
tokenIdentifier: args.tokenRoute[0],
tokenNonce: 0,
Expand Down
43 changes: 23 additions & 20 deletions src/modules/auto-router/specs/auto-router.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ import { PairFilteringService } from 'src/modules/pair/services/pair.filtering.s

describe('AutoRouterService', () => {
let service: AutoRouterService;
const senderAddress = Address.newFromHex(
'0000000000000000000000000000000000000000000000000000000000000001',
).toBech32();

const ContextGetterServiceProvider = {
provide: ContextGetterService,
Expand Down Expand Up @@ -117,9 +120,9 @@ describe('AutoRouterService', () => {
tokenRoute: ['USDC-123456', 'WEGLD-123456'],
pairs: [
new PairModel({
address: Address.fromHex(
address: Address.newFromHex(
'0000000000000000000000000000000000000000000000000000000000000013',
).bech32(),
).toBech32(),
firstToken: Tokens('WEGLD-123456'),
secondToken: Tokens('USDC-123456'),
info: new PairInfoModel({
Expand Down Expand Up @@ -161,9 +164,9 @@ describe('AutoRouterService', () => {
tokenRoute: ['USDC-123456', 'WEGLD-123456'],
pairs: [
new PairModel({
address: Address.fromHex(
address: Address.newFromHex(
'0000000000000000000000000000000000000000000000000000000000000013',
).bech32(),
).toBech32(),
firstToken: Tokens('WEGLD-123456'),
secondToken: Tokens('USDC-123456'),
info: new PairInfoModel({
Expand Down Expand Up @@ -210,9 +213,9 @@ describe('AutoRouterService', () => {
tokenRoute: ['USDC-123456', 'WEGLD-123456', 'MEX-123456'],
pairs: [
new PairModel({
address: Address.fromHex(
address: Address.newFromHex(
'0000000000000000000000000000000000000000000000000000000000000013',
).bech32(),
).toBech32(),
firstToken: Tokens('WEGLD-123456'),
secondToken: Tokens('USDC-123456'),
info: new PairInfoModel({
Expand All @@ -223,9 +226,9 @@ describe('AutoRouterService', () => {
totalFeePercent: 0.003,
}),
new PairModel({
address: Address.fromHex(
address: Address.newFromHex(
'0000000000000000000000000000000000000000000000000000000000000012',
).bech32(),
).toBech32(),
firstToken: Tokens('WEGLD-123456'),
secondToken: Tokens('MEX-123456'),
info: new PairInfoModel({
Expand All @@ -245,7 +248,7 @@ describe('AutoRouterService', () => {

it('should get a wrap tx + a fixed input simple swap tx', async () => {
const transactions = await service.getTransactions(
Address.Zero().bech32(),
senderAddress,
new AutoRouteModel({
swapType: 0,
tokenInID: 'EGLD',
Expand All @@ -263,9 +266,9 @@ describe('AutoRouterService', () => {
tokenRoute: ['USDC-123456', 'WEGLD-123456'],
pairs: [
new PairModel({
address: Address.fromHex(
address: Address.newFromHex(
'0000000000000000000000000000000000000000000000000000000000000013',
).bech32(),
).toBech32(),
}),
],
tolerance: 0.01,
Expand All @@ -275,8 +278,8 @@ describe('AutoRouterService', () => {
{
nonce: 0,
value: '1000000000000000000',
receiver: Address.Zero().bech32(),
sender: '',
receiver: Address.Zero().toBech32(),
sender: senderAddress,
receiverUsername: undefined,
senderUsername: undefined,
gasPrice: 1000000000,
Expand All @@ -294,7 +297,7 @@ describe('AutoRouterService', () => {

it('should get a fixed output multi swap tx + unwrap tx', async () => {
const transactions = await service.getTransactions(
Address.Zero().bech32(),
senderAddress,
new AutoRouteModel({
swapType: 1,
tokenInID: 'USDC-123456',
Expand All @@ -313,14 +316,14 @@ describe('AutoRouterService', () => {
tokenRoute: ['USDC-123456', 'WEGLD-123456', 'MEX-123456'],
pairs: [
new PairModel({
address: Address.fromHex(
address: Address.newFromHex(
'0000000000000000000000000000000000000000000000000000000000000013',
).bech32(),
).toBech32(),
}),
new PairModel({
address: Address.fromHex(
address: Address.newFromHex(
'0000000000000000000000000000000000000000000000000000000000000012',
).bech32(),
).toBech32(),
}),
],
tolerance: 0.01,
Expand All @@ -330,8 +333,8 @@ describe('AutoRouterService', () => {
{
nonce: 0,
value: '0',
receiver: Address.Zero().bech32(),
sender: '',
receiver: Address.Zero().toBech32(),
sender: senderAddress,
receiverUsername: undefined,
senderUsername: undefined,
gasPrice: 1000000000,
Expand Down
15 changes: 15 additions & 0 deletions src/modules/common/transaction.options.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { TokenTransfer } from '@multiversx/sdk-core';

export class TransactionOptions {
chainID: string;
function: string;
gasLimit: number;
sender: string;
arguments?: any[];
tokenTransfers?: TokenTransfer[];
nativeTransferAmount?: string;

constructor(init?: Partial<TransactionOptions>) {
Object.assign(this, init);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,19 @@ import {
List,
ListType,
Struct,
Token,
TokenIdentifierValue,
TokenTransfer,
TypedValue,
U64Value,
} from '@multiversx/sdk-core/out';
VariadicValue,
} from '@multiversx/sdk-core';
import BigNumber from 'bignumber.js';
import { gasConfig, mxConfig } from 'src/config';
import { EgldOrEsdtTokenPayment } from 'src/models/esdtTokenPayment.model';
import { decimalToHex } from 'src/utils/token.converters';
import { WrapAbiService } from 'src/modules/wrapping/services/wrap.abi.service';
import { TransactionOptions } from 'src/modules/common/transaction.options';

export type ComposableTask = {
type: ComposableTaskType;
Expand All @@ -40,6 +43,7 @@ export class ComposableTasksTransactionService {
) {}

async getComposeTasksTransaction(
sender: string,
payment: EsdtTokenPayment,
tokenOut: EgldOrEsdtTokenPayment,
tasks: ComposableTask[],
Expand All @@ -66,10 +70,12 @@ export class ComposableTasksTransactionService {
}
}

const contract = await this.mxProxy.getComposableTasksSmartContract();

let interaction = contract.methodsExplicit
.composeTasks([
const transactionOptions = new TransactionOptions({
sender: sender,
chainID: mxConfig.chainID,
gasLimit: gasLimit,
function: 'composeTasks',
arguments: [
new Struct(EgldOrEsdtTokenPayment.getStructure(), [
new Field(
new TokenIdentifierValue(tokenOut.tokenIdentifier),
Expand All @@ -81,31 +87,30 @@ export class ComposableTasksTransactionService {
'amount',
),
]),
...this.getRawTasks(tasks),
])
.withGasLimit(gasLimit)
.withChainID(mxConfig.chainID);

switch (payment.tokenIdentifier) {
case 'EGLD':
interaction = interaction.withValue(
new BigUIntValue(new BigNumber(payment.amount)),
);
break;
default:
interaction = interaction.withSingleESDTTransfer(
TokenTransfer.fungibleFromBigInteger(
payment.tokenIdentifier,
new BigNumber(payment.amount),
),
);
break;
VariadicValue.fromItems(...this.getRawTasks(tasks)),
],
});

if (payment.tokenIdentifier === mxConfig.EGLDIdentifier) {
transactionOptions.nativeTransferAmount = payment.amount;
} else {
transactionOptions.tokenTransfers = [
new TokenTransfer({
token: new Token({
identifier: payment.tokenIdentifier,
}),
amount: BigInt(payment.amount),
}),
];
}

return interaction.buildTransaction().toPlainObject();
return await this.mxProxy.getComposableTasksContractTransaction(
transactionOptions,
);
}

async wrapEgldAndSwapTransaction(
sender: string,
value: string,
tokenOutID: string,
tokenOutAmountMin: string,
Expand All @@ -131,6 +136,7 @@ export class ComposableTasksTransactionService {
};

return this.getComposeTasksTransaction(
sender,
new EsdtTokenPayment({
tokenIdentifier: 'EGLD',
tokenNonce: 0,
Expand All @@ -145,6 +151,7 @@ export class ComposableTasksTransactionService {
}

async swapAndUnwrapEgldTransaction(
sender: string,
payment: EsdtTokenPayment,
minimumValue: string,
swapEndpoint: string,
Expand All @@ -170,6 +177,7 @@ export class ComposableTasksTransactionService {
};

return this.getComposeTasksTransaction(
sender,
payment,
new EgldOrEsdtTokenPayment({
tokenIdentifier: 'EGLD',
Expand Down
Loading

0 comments on commit 8f698ce

Please sign in to comment.