Skip to content

Commit

Permalink
Merge branch 'main' of github.com:connext/nxtp
Browse files Browse the repository at this point in the history
  • Loading branch information
rhlsthrm committed Oct 26, 2021
2 parents a695bb1 + 855fde5 commit 32d229b
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 4 deletions.
42 changes: 42 additions & 0 deletions packages/router/src/lib/helpers/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export const getNtpTimeSeconds = async () => {
/**
* Helper to calculate router gas fee in token
*
* @param sendingAssetId The asset address on source chain
* @param sendingChainId The source chain Id
* @param receivingAssetId The asset address on destination chain
* @param receivingChainId The destination chain Id
Expand Down Expand Up @@ -71,6 +72,47 @@ export const calculateGasFeeInReceivingToken = async (

return totalCost;
};

/**
* Helper to calculate router gas fee in token for meta transaction
*
* @param receivingAssetId The asset address on destination chain
* @param receivingChainId The destination chain Id
* @param outputDecimals Decimal number of receiving asset
* @param requestContext Request context instance
*/
export const calculateGasFeeInReceivingTokenForFulfill = async (
receivingAssetId: string,
receivingChainId: number,
outputDecimals: number,
requestContext: RequestContext,
): Promise<BigNumber> => {
const chaindIdsForGasFee = getChainIdForGasFee();

if (!chaindIdsForGasFee.includes(receivingChainId)) return constants.Zero;
let totalCost = constants.Zero;

if (chaindIdsForGasFee.includes(receivingChainId)) {
const gasLimitForFulfill = BigNumber.from(GAS_ESTIMATES.fulfill);
const ethPriceInReceivingChain = await getTokenPrice(receivingChainId, constants.AddressZero, requestContext);
const receivingTokenPrice = await getTokenPrice(receivingChainId, receivingAssetId, requestContext);
const gasPriceInReceivingChain = await getGasPrice(receivingChainId, requestContext);

const gasAmountInUsd = gasPriceInReceivingChain.mul(gasLimitForFulfill).mul(ethPriceInReceivingChain);
const tokenAmountForGasFee = receivingTokenPrice.isZero()
? constants.Zero
: gasAmountInUsd.div(receivingTokenPrice).div(BigNumber.from(10).pow(18 - outputDecimals));

console.log("gasLimitForFulfill = ", gasLimitForFulfill.toString());
console.log("gasPriceInReceivingChain = ", gasPriceInReceivingChain.toString());
console.log("ethPriceInReceivingChain = ", ethPriceInReceivingChain.toString());
console.log("receivingTokenPrice = ", receivingTokenPrice.toString());
totalCost = totalCost.add(tokenAmountForGasFee);
}

return totalCost;
};

/**
* Gets token price in usd from price oracle
*
Expand Down
26 changes: 22 additions & 4 deletions packages/router/src/lib/operations/fulfill.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { getContext } from "../../router";
import { FulfillInput, FulfillInputSchema } from "../entities";
import { NoChainConfig, ParamsInvalid, NotEnoughRelayerFee } from "../errors";
import { NotAllowedFulfillRelay } from "../errors/fulfill";
import { calculateGasFeeInReceivingTokenForFulfill } from "../helpers/shared";

export const fulfill = async (
invariantData: InvariantTransactionData,
Expand All @@ -19,7 +20,7 @@ export const fulfill = async (
): Promise<providers.TransactionReceipt | undefined> => {
const { requestContext, methodContext } = createLoggingContext(fulfill.name, _requestContext);

const { logger, contractWriter, config } = getContext();
const { logger, contractWriter, config, chainData, txService } = getContext();
logger.info("Method start", requestContext, methodContext, { invariantData, input });

// Validate InvariantData schema
Expand Down Expand Up @@ -73,9 +74,26 @@ export const fulfill = async (
});
}

const recvAmountLowerBound = BigNumber.from(amount)
.mul(100 - relayerFeeLowerBound)
.div(100);
let outputDecimals = chainData.get(invariantData.receivingChainId.toString())?.assetId[
invariantData.receivingAssetId
]?.decimals;
if (!outputDecimals) {
outputDecimals = await txService.getDecimalsForAsset(
invariantData.receivingChainId,
invariantData.receivingAssetId,
);
}
logger.info("Got output decimals", requestContext, methodContext, { outputDecimals });
const expectedFulfillFee = await calculateGasFeeInReceivingTokenForFulfill(
invariantData.receivingAssetId,
invariantData.receivingChainId,
outputDecimals,
requestContext,
);
logger.info("Expected Fulfill fee in router side", requestContext, methodContext, {
expectedFulfillFee: expectedFulfillFee.toString(),
});
const recvAmountLowerBound = expectedFulfillFee.mul(100 - relayerFeeLowerBound).div(100);

if (BigNumber.from(amount).sub(input.relayerFee).lt(recvAmountLowerBound)) {
throw new NotEnoughRelayerFee(fulfillChain, {
Expand Down

0 comments on commit 32d229b

Please sign in to comment.