Created
August 29, 2021 20:37
-
-
Save livingrock7/eefcc8ba8fca76899453c8d58fe97b2d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if (shouldForwardWithERC20Forwarder) { | |
oracleAggregatorContract = blockchain.getContract( | |
blockchain.getOracleAggregatorAbi(), | |
blockchain.getOracleAggregatorContractAddress() | |
); | |
erc20ForwarderPreFlightCheck = await preFlightChecksService.getPreFlightChecks( | |
networkId, | |
oracleAggregatorContract, | |
request | |
); | |
log.info( | |
`ERC20Forwarder pre flight check result: ${JSON.stringify( | |
erc20ForwarderPreFlightCheck | |
)}` | |
); | |
} | |
if ( | |
shouldForwardWithERC20Forwarder && | |
!erc20ForwarderPreFlightCheck.readyToPayGasInTokens | |
) { | |
log.error(`Error while pre flight checks for token gas price`); | |
let result = createResponseBodyV2( | |
STATUSES.TOKEN_PRICE_UNACCEPTABLE, | |
`Error while pre flight check : ${erc20ForwarderPreFlightCheck.errorMessage}`, | |
STATUSES.CONFLICT | |
); | |
return result; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const appRoot = require("app-root-path"); | |
var log = require(`${appRoot}/config/winston`).logger(module); | |
const config = require(`${appRoot}/config`); | |
const cache = require(`${appRoot}/src/services/caching`); | |
const ethers = require("ethers"); | |
const { | |
getGasPriceKey, | |
} = require(`${appRoot}/src/controllers/utils/cache-utils`); | |
const TOKEN_GAS_PRICE_THRESHOLD_PERCENTAGE = | |
config.TOKEN_GAS_PRICE_THRESHOLD_PERCENTAGE; | |
const getPreFlightChecks = async ( | |
networkId, | |
oracleAggregatorContract, | |
forwardRequest | |
) => { | |
let result = {}; | |
result.readyToPayGasInTokens = false; | |
try { | |
let gasPriceFromCache = await cache.get( | |
getGasPriceKey(networkId, config.networksGasPriceType[networkId]) | |
); | |
let tokenAddress = forwardRequest.token; | |
const tokenGasPriceFromRequest = ethers.BigNumber.from( | |
forwardRequest.tokenGasPrice | |
); | |
const tokenPriceCurrent = await oracleAggregatorContract.getTokenPrice( | |
tokenAddress | |
); | |
const tokenOracleDecimals = await oracleAggregatorContract.getTokenOracleDecimals( | |
tokenAddress | |
); | |
/* should probably assume use of high gas price and calculate from different sources on the go (upvest,gasstation,etherscan) and avergae out | |
same for the oracle vs token price fetch apis - coingecko etc | |
add robustness for calcs | |
//todo | |
*/ | |
const gasPrice = ethers.BigNumber.from( | |
ethers.utils.parseUnits(gasPriceFromCache.toString(), "wei").toString() | |
); | |
const tokenGasPriceCurrent = ethers.BigNumber.from(gasPrice) | |
.mul(ethers.BigNumber.from(10).pow(tokenOracleDecimals)) | |
.div(tokenPriceCurrent); | |
if (tokenGasPriceCurrent && tokenPriceCurrent && tokenOracleDecimals) { | |
log.info(`token price ${tokenPriceCurrent.toString()}`); | |
log.info(`token oracle decimals ${tokenOracleDecimals.toString()}`); | |
log.info(`token gas price ${tokenGasPriceCurrent.toString()}`); | |
var minimumTokenGasPriceAccepted = ethers.BigNumber.from( | |
TOKEN_GAS_PRICE_THRESHOLD_PERCENTAGE | |
) | |
.mul(ethers.BigNumber.from(tokenGasPriceCurrent)) | |
.div(ethers.BigNumber.from(100)); | |
if (tokenGasPriceFromRequest.lte(minimumTokenGasPriceAccepted)) { | |
log.info("Not favorable to process this transaction"); | |
result.errorMessage = | |
"$token/ETH pair price has dropped beyond threshold"; | |
} else { | |
result.readyToPayGasInTokens = true; | |
} | |
} | |
} catch (error) { | |
log.info("Error while getting data points for pre flight checks"); | |
result.errorMessage = error.toString(); | |
log.error(error); | |
} | |
log.info(`ready to pay in ERC20 tokens? ${result.readyToPayGasInTokens}`); | |
return result; | |
}; | |
module.exports = { getPreFlightChecks }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const appRoot = require("app-root-path"); | |
var log = require(`${appRoot}/config/winston`).logger(module); | |
const { STATUSES, createResponseBodyV2 } = require(`${appRoot}/src/middleware`); | |
const { providerMap } = require(`${appRoot}/src/controllers/provider`); | |
const preFlightChecksService = require(`${appRoot}/src/services/erc20forwarder`); | |
const config = require(`${appRoot}/config`); | |
const network = require(`${appRoot}/src/controllers/blockchain/network`); | |
const ZERO_ADDRESS = config.ETHEREUM_ZERO_ADDRESS; | |
const validateForwardRequest = async ( | |
request, | |
metaTransactionType, | |
networkId | |
) => { | |
let validationResponse = {}; | |
validationResponse.success = true; | |
validationResponse.code = STATUSES.SUCCESS; | |
var blockchain = providerMap[networkId]; | |
if (!blockchain) { | |
validationResponse.success = false; | |
validationResponse.message = `Network with id ${networkId} is not supported`; | |
validationResponse.code = STATUSES.UNSUPPORTED_NETWORK; | |
validationResponse.responseCode = STATUSES.CONFLICT; | |
return validationResponse; | |
} | |
let { | |
from, | |
to, | |
token, | |
txGas, | |
tokenGasPrice, | |
batchId, | |
batchNonce, | |
deadline, | |
data, | |
} = request; | |
/** | |
* cases to check here | |
* i) typeof tokeGasPrice must be string - Check | |
* ii) typeof txGas must be number - Check | |
* iii) unsupported tokens are not allowed (ERC20 Forwarder) - Config aid for supported stable coins | |
* iv) to address should be registered recipient - | |
* | |
* v) deadLine is passed - Check | |
*/ | |
if (typeof txGas != "number" || typeof tokenGasPrice != "string") { | |
validationResponse.success = false; | |
validationResponse.message = `"txGas" should be numeric and "tokenGasPrice" should be a string only in the forward request.`; | |
validationResponse.code = STATUSES.CONFLICT; | |
return validationResponse; | |
} | |
if (deadline < Math.floor(Date.now() / 1000)) { | |
validationResponse.success = false; | |
validationResponse.message = `Deadline is exceeded to forward this transaction through trusted forwarder`; | |
validationResponse.code = STATUSES.CONFLICT; | |
return validationResponse; | |
} | |
if (metaTransactionType == config.metaTransactionType.ERC20_FORWARDER) { | |
const oracleAggregatorAddress = blockchain.getOracleAggregatorContractAddress(); | |
const oracleAggregatorABI = blockchain.getOracleAggregatorAbi(); | |
if(!oracleAggregatorAddress || !oracleAggregatorABI) { | |
return createResponseBodyV2(STATUSES.INTERNAL_SERVER_ERROR, "oracleAggreagator address or ABI is not defined"); | |
} | |
let oracleAggregatorContract = blockchain.getContract( | |
oracleAggregatorABI, | |
oracleAggregatorAddress | |
); | |
let erc20ForwarderPreFlightCheck = await preFlightChecksService.getPreFlightChecks( | |
networkId, | |
oracleAggregatorContract, | |
request | |
); | |
if (!erc20ForwarderPreFlightCheck.readyToPayGasInTokens) { | |
validationResponse.success = false; | |
validationResponse.message = `Error while pre flight checks for token gas price`; | |
validationResponse.code = STATUSES.CONFLICT; | |
return validationResponse; | |
} | |
} else if ( | |
metaTransactionType == config.metaTransactionType.TRUSTED_FORWARDER | |
) { | |
if (token != ZERO_ADDRESS || tokenGasPrice != "0") { | |
validationResponse.success = false; | |
validationResponse.message = `token should be zero address and tokenGasPrice should be 0 for meta transaction type 'TRUSTED_FORWARDER'`; | |
validationResponse.code = STATUSES.CONFLICT; | |
return validationResponse; | |
} | |
} | |
return validationResponse; | |
}; | |
module.exports = { validateForwardRequest }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment