From a9c26f2d775db5bec050be2ec5a517ed8f0281a7 Mon Sep 17 00:00:00 2001 From: Yosif Hamed Date: Tue, 5 Nov 2024 15:36:24 +0200 Subject: [PATCH 1/4] Add one more socket humanizer method --- .../humanizer/modules/Socket/socketModules.ts | 66 ++++++++++++++++++- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/src/libs/humanizer/modules/Socket/socketModules.ts b/src/libs/humanizer/modules/Socket/socketModules.ts index b87468222..41bb65575 100644 --- a/src/libs/humanizer/modules/Socket/socketModules.ts +++ b/src/libs/humanizer/modules/Socket/socketModules.ts @@ -3,7 +3,7 @@ import { Interface, ZeroAddress } from 'ethers' import { AccountOp } from '../../../accountOp/accountOp' import { SocketViaAcross } from '../../const/abis' -import { HumanizerCallModule, IrCall } from '../../interfaces' +import { HumanizerCallModule, HumanizerVisualization, IrCall } from '../../interfaces' import { eToNative, getAction, @@ -43,7 +43,9 @@ export const SocketModule: HumanizerCallModule = (accountOp: AccountOp, irCalls: 'function bridgeERC20To(uint256,bytes32,address,address,uint256,uint32,uint256)', 'function bridgeERC20To(uint256 amount, (uint256 toChainId, uint256 slippage, uint256 relayerFee, uint32 dstChainDomain, address token, address receiverAddress, bytes32 metadata, bytes callData, address delegate) connextBridgeData)', 'function transformERC20(address inputToken, address outputToken, uint256 inputTokenAmount, uint256 minOutputTokenAmount, (uint32,bytes)[] transformations)', - 'function swapAndBridge(uint32 swapId, bytes swapData, tuple(uint256 toChainId, uint256 slippage, uint256 relayerFee, uint32 dstChainDomain, address receiverAddress, bytes32 metadata, bytes callData, address delegate) connextBridgeData)' + 'function swapAndBridge(uint32 swapId, bytes swapData, tuple(uint256 toChainId, uint256 slippage, uint256 relayerFee, uint32 dstChainDomain, address receiverAddress, bytes32 metadata, bytes callData, address delegate) connextBridgeData)', + 'function swapAndBridge(uint32 swapId, bytes calldata swapData, tuple (address receiverAddress,address senderAddress,uint256 value,uint256 srcPoolId,uint256 dstPoolId,uint256 minReceivedAmt,uint256 destinationGasLimit,bool isNativeSwapRequired,uint16 stargateDstChainId,uint32 swapId,bytes swapData,bytes32 metadata,bytes destinationPayload) acrossBridgeData) payable' + // 'function performActionWithIn(address fromToken, address toToken, uint256 amount, bytes32 metadata, bytes swapExtraData) payable returns (uint256, address)' ]) const matcher = { [`${ @@ -515,6 +517,66 @@ export const SocketModule: HumanizerCallModule = (accountOp: AccountOp, irCalls: ...getRecipientText(accountOp.accountAddr, receiverAddress) ].filter((x) => x) } + }, + [`${ + iface.getFunction( + 'swapAndBridge(uint32 swapId, bytes calldata swapData, tuple (address receiverAddress,address senderAddress,uint256 value,uint256 srcPoolId,uint256 dstPoolId,uint256 minReceivedAmt,uint256 destinationGasLimit,bool isNativeSwapRequired,uint16 stargateDstChainId,uint32 swapId,bytes swapData,bytes32 metadata,bytes destinationPayload) acrossBridgeData)' + )?.selector + }`]: (call: IrCall): IrCall => { + const { + swapId, + swapData, + acrossBridgeData: { + receiverAddress, + senderAddress, + value, + srcPoolId, + dstPoolId, + minReceivedAmt, + destinationGasLimit, + isNativeSwapRequired, + stargateDstChainId, + swapId: innerSwapId, + swapData: innerSwapData, + metadata, + destinationPayload + } + } = iface.parseTransaction(call)!.args + + const dstChain: HumanizerVisualization[] = [] + const tokensData: HumanizerVisualization[] = [] + if (STARGATE_CHAIN_IDS[stargateDstChainId]) + dstChain.push(getChain(STARGATE_CHAIN_IDS[stargateDstChainId])) + if ( + swapData.startsWith( + iface.getFunction( + 'performActionWithIn(address fromToken, address toToken, uint256 amount, bytes32 metadata, bytes swapExtraData) payable returns (uint256, address)' + )?.selector + ) + ) { + const { + fromToken, + toToken, + amount, + metadata: newMeta, + swapExtraData + } = iface.parseTransaction({ + ...call, + data: swapData + })!.args + tokensData.push(getToken(fromToken, amount), getLabel('to'), getToken(toToken, value)) + } + + return { + ...call, + fullVisualization: [ + getAction('Bridge'), + ...tokensData, + getLabel('to'), + ...dstChain, + ...getRecipientText(senderAddress, receiverAddress) + ] + } } } From 83b11fb5a43bd52cf838ac339941388b6c605c18 Mon Sep 17 00:00:00 2001 From: Yosif Hamed Date: Tue, 5 Nov 2024 16:14:09 +0200 Subject: [PATCH 2/4] remove commented out func --- src/libs/humanizer/modules/Socket/socketModules.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/humanizer/modules/Socket/socketModules.ts b/src/libs/humanizer/modules/Socket/socketModules.ts index 41bb65575..9f2cb6119 100644 --- a/src/libs/humanizer/modules/Socket/socketModules.ts +++ b/src/libs/humanizer/modules/Socket/socketModules.ts @@ -45,7 +45,6 @@ export const SocketModule: HumanizerCallModule = (accountOp: AccountOp, irCalls: 'function transformERC20(address inputToken, address outputToken, uint256 inputTokenAmount, uint256 minOutputTokenAmount, (uint32,bytes)[] transformations)', 'function swapAndBridge(uint32 swapId, bytes swapData, tuple(uint256 toChainId, uint256 slippage, uint256 relayerFee, uint32 dstChainDomain, address receiverAddress, bytes32 metadata, bytes callData, address delegate) connextBridgeData)', 'function swapAndBridge(uint32 swapId, bytes calldata swapData, tuple (address receiverAddress,address senderAddress,uint256 value,uint256 srcPoolId,uint256 dstPoolId,uint256 minReceivedAmt,uint256 destinationGasLimit,bool isNativeSwapRequired,uint16 stargateDstChainId,uint32 swapId,bytes swapData,bytes32 metadata,bytes destinationPayload) acrossBridgeData) payable' - // 'function performActionWithIn(address fromToken, address toToken, uint256 amount, bytes32 metadata, bytes swapExtraData) payable returns (uint256, address)' ]) const matcher = { [`${ From b6cbf98f7dcfc8e9682ca346f88a736eceb85a49 Mon Sep 17 00:00:00 2001 From: Yosif Hamed Date: Tue, 5 Nov 2024 18:29:19 +0200 Subject: [PATCH 3/4] remove humanizer fragment type as it is not used --- src/interfaces/userRequest.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/interfaces/userRequest.ts b/src/interfaces/userRequest.ts index 81f824cce..80570d7f0 100644 --- a/src/interfaces/userRequest.ts +++ b/src/interfaces/userRequest.ts @@ -3,7 +3,6 @@ import { TypedDataDomain, TypedDataField } from 'ethers' import { AccountId } from './account' import { DappProviderRequest } from './dapp' -import { HumanizerFragment } from './humanizer' import { NetworkId } from './network' export interface Calls { @@ -34,9 +33,6 @@ export interface Message { networkId: NetworkId content: PlainTextMessage | TypedMessage signature: string | null - // those are the async non global data fragments that are obtained via the humanizer and stored - // in the Message so we can visualize it better and fatter later - humanizerFragments?: HumanizerFragment[] } export interface SignUserRequest { From 2fadcb954f46b9c72bff79f4644a86437a16e2bc Mon Sep 17 00:00:00 2001 From: Yosif Hamed Date: Wed, 6 Nov 2024 17:42:18 +0200 Subject: [PATCH 4/4] Add aave methods --- src/libs/humanizer/const/abis/Aave.ts | 75 ++++++++++++++++++ src/libs/humanizer/const/abis/index.ts | 3 +- src/libs/humanizer/modules/Aave/aaveV3.ts | 77 +++++++++++++++++++ .../modules/Aave/aaveWethGatewayV2.ts | 2 +- src/libs/humanizer/modules/Aave/index.ts | 4 +- 5 files changed, 158 insertions(+), 3 deletions(-) create mode 100644 src/libs/humanizer/modules/Aave/aaveV3.ts diff --git a/src/libs/humanizer/const/abis/Aave.ts b/src/libs/humanizer/const/abis/Aave.ts index 906dcb09c..a43c3d48f 100644 --- a/src/libs/humanizer/const/abis/Aave.ts +++ b/src/libs/humanizer/const/abis/Aave.ts @@ -42,3 +42,78 @@ export const AaveWethGatewayV2 = [ 'function transferOwnership(address newOwner)', 'function withdrawETH(address lendingPool, uint256 amount, address to)' ] + +export const AaveV3Pool = [ + 'function ADDRESSES_PROVIDER() view returns (address)', + 'function BRIDGE_PROTOCOL_FEE() view returns (uint256)', + 'function FLASHLOAN_PREMIUM_TOTAL() view returns (uint128)', + 'function FLASHLOAN_PREMIUM_TO_PROTOCOL() view returns (uint128)', + 'function MAX_NUMBER_RESERVES() view returns (uint16)', + 'function POOL_REVISION() view returns (uint256)', + 'function backUnbacked(address asset, uint256 amount, uint256 fee) returns (uint256)', + 'function borrow(address asset, uint256 amount, uint256 interestRateMode, uint16 referralCode, address onBehalfOf)', + 'function borrow(bytes32 args)', + 'function configureEModeCategory(uint8 id, (uint16 ltv, uint16 liquidationThreshold, uint16 liquidationBonus, string label) category)', + 'function configureEModeCategoryBorrowableBitmap(uint8 id, uint128 borrowableBitmap)', + 'function configureEModeCategoryCollateralBitmap(uint8 id, uint128 collateralBitmap)', + 'function deposit(address asset, uint256 amount, address onBehalfOf, uint16 referralCode)', + 'function dropReserve(address asset)', + 'function finalizeTransfer(address asset, address from, address to, uint256 amount, uint256 balanceFromBefore, uint256 balanceToBefore)', + 'function flashLoan(address receiverAddress, address[] assets, uint256[] amounts, uint256[] interestRateModes, address onBehalfOf, bytes params, uint16 referralCode)', + 'function flashLoanSimple(address receiverAddress, address asset, uint256 amount, bytes params, uint16 referralCode)', + 'function getBorrowLogic() pure returns (address)', + 'function getBridgeLogic() pure returns (address)', + 'function getConfiguration(address asset) view returns ((uint256 data))', + 'function getEModeCategoryBorrowableBitmap(uint8 id) view returns (uint128)', + 'function getEModeCategoryCollateralBitmap(uint8 id) view returns (uint128)', + 'function getEModeCategoryCollateralConfig(uint8 id) view returns ((uint16 ltv, uint16 liquidationThreshold, uint16 liquidationBonus))', + 'function getEModeCategoryData(uint8 id) view returns ((uint16 ltv, uint16 liquidationThreshold, uint16 liquidationBonus, address priceSource, string label))', + 'function getEModeCategoryLabel(uint8 id) view returns (string)', + 'function getEModeLogic() pure returns (address)', + 'function getFlashLoanLogic() pure returns (address)', + 'function getLiquidationGracePeriod(address asset) returns (uint40)', + 'function getLiquidationLogic() pure returns (address)', + 'function getPoolLogic() pure returns (address)', + 'function getReserveAddressById(uint16 id) view returns (address)', + 'function getReserveData(address asset) view returns (((uint256 data) configuration, uint128 liquidityIndex, uint128 currentLiquidityRate, uint128 variableBorrowIndex, uint128 currentVariableBorrowRate, uint128 currentStableBorrowRate, uint40 lastUpdateTimestamp, uint16 id, address aTokenAddress, address stableDebtTokenAddress, address variableDebtTokenAddress, address interestRateStrategyAddress, uint128 accruedToTreasury, uint128 unbacked, uint128 isolationModeTotalDebt))', + 'function getReserveDataExtended(address asset) view returns (((uint256 data) configuration, uint128 liquidityIndex, uint128 currentLiquidityRate, uint128 variableBorrowIndex, uint128 currentVariableBorrowRate, uint128 __deprecatedStableBorrowRate, uint40 lastUpdateTimestamp, uint16 id, uint40 liquidationGracePeriodUntil, address aTokenAddress, address __deprecatedStableDebtTokenAddress, address variableDebtTokenAddress, address interestRateStrategyAddress, uint128 accruedToTreasury, uint128 unbacked, uint128 isolationModeTotalDebt, uint128 virtualUnderlyingBalance))', + 'function getReserveNormalizedIncome(address asset) view returns (uint256)', + 'function getReserveNormalizedVariableDebt(address asset) view returns (uint256)', + 'function getReservesCount() view returns (uint256)', + 'function getReservesList() view returns (address[])', + 'function getSupplyLogic() pure returns (address)', + 'function getUserAccountData(address user) view returns (uint256 totalCollateralBase, uint256 totalDebtBase, uint256 availableBorrowsBase, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor)', + 'function getUserConfiguration(address user) view returns ((uint256 data))', + 'function getUserEMode(address user) view returns (uint256)', + 'function getVirtualUnderlyingBalance(address asset) view returns (uint128)', + 'function initReserve(address asset, address aTokenAddress, address variableDebtAddress, address interestRateStrategyAddress)', + 'function initialize(address provider)', + 'function liquidationCall(address collateralAsset, address debtAsset, address user, uint256 debtToCover, bool receiveAToken)', + 'function liquidationCall(bytes32 args1, bytes32 args2)', + 'function mintToTreasury(address[] assets)', + 'function mintUnbacked(address asset, uint256 amount, address onBehalfOf, uint16 referralCode)', + 'function repay(bytes32 args) returns (uint256)', + 'function repay(address asset, uint256 amount, uint256 interestRateMode, address onBehalfOf) returns (uint256)', + 'function repayWithATokens(address asset, uint256 amount, uint256 interestRateMode) returns (uint256)', + 'function repayWithATokens(bytes32 args) returns (uint256)', + 'function repayWithPermit(bytes32 args, bytes32 r, bytes32 s) returns (uint256)', + 'function repayWithPermit(address asset, uint256 amount, uint256 interestRateMode, address onBehalfOf, uint256 deadline, uint8 permitV, bytes32 permitR, bytes32 permitS) returns (uint256)', + 'function rescueTokens(address token, address to, uint256 amount)', + 'function resetIsolationModeTotalDebt(address asset)', + 'function setConfiguration(address asset, (uint256 data) configuration)', + 'function setLiquidationGracePeriod(address asset, uint40 until)', + 'function setReserveInterestRateStrategyAddress(address asset, address rateStrategyAddress)', + 'function setUserEMode(uint8 categoryId)', + 'function setUserUseReserveAsCollateral(bytes32 args)', + 'function setUserUseReserveAsCollateral(address asset, bool useAsCollateral)', + 'function supply(address asset, uint256 amount, address onBehalfOf, uint16 referralCode)', + 'function supply(bytes32 args)', + 'function supplyWithPermit(address asset, uint256 amount, address onBehalfOf, uint16 referralCode, uint256 deadline, uint8 permitV, bytes32 permitR, bytes32 permitS)', + 'function supplyWithPermit(bytes32 args, bytes32 r, bytes32 s)', + 'function syncIndexesState(address asset)', + 'function syncRatesState(address asset)', + 'function updateBridgeProtocolFee(uint256 protocolFee)', + 'function updateFlashloanPremiums(uint128 flashLoanPremiumTotal, uint128 flashLoanPremiumToProtocol)', + 'function withdraw(address asset, uint256 amount, address to) returns (uint256)', + 'function withdraw(bytes32 args) returns (uint256)' +] diff --git a/src/libs/humanizer/const/abis/index.ts b/src/libs/humanizer/const/abis/index.ts index f06e31f26..ca746dc86 100644 --- a/src/libs/humanizer/const/abis/index.ts +++ b/src/libs/humanizer/const/abis/index.ts @@ -1,5 +1,5 @@ import { OneInch } from './1Inch' -import { AaveLendingPoolV2, AaveWethGatewayV2 } from './Aave' +import { AaveLendingPoolV2, AaveV3Pool, AaveWethGatewayV2 } from './Aave' import { Across } from './Across' import { KyberSwap } from './KyberSwap' import { Legends } from './Legends' @@ -13,6 +13,7 @@ import { StakingPool } from './Wallet' export { AaveLendingPoolV2, AaveWethGatewayV2, + AaveV3Pool, UniswapUniversalRouter, UniV2Router, UniV3Router, diff --git a/src/libs/humanizer/modules/Aave/aaveV3.ts b/src/libs/humanizer/modules/Aave/aaveV3.ts new file mode 100644 index 000000000..a22fd3b2e --- /dev/null +++ b/src/libs/humanizer/modules/Aave/aaveV3.ts @@ -0,0 +1,77 @@ +import { Interface } from 'ethers' + +import { AccountOp } from '../../../accountOp/accountOp' +import { AaveV3Pool } from '../../const/abis' +import { IrCall } from '../../interfaces' +import { + getAction, + getAddressVisualization, + getDeadline, + getLabel, + getOnBehalfOf, + getToken +} from '../../utils' + +export const aaveV3Pool = (): { [key: string]: Function } => { + const iface = new Interface(AaveV3Pool) + return { + [iface.getFunction( + 'supply(address asset, uint256 amount, address onBehalfOf, uint16 referralCode)' + )?.selector!]: (accountOp: AccountOp, call: IrCall) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { asset, amount, onBehalfOf, referralCode } = iface.parseTransaction(call)!.args + return [ + getAction('Deposit'), + getToken(asset, amount), + getLabel('to'), + getAddressVisualization(call.to), + ...getOnBehalfOf(onBehalfOf, accountOp.accountAddr) + ] + }, + [iface.getFunction( + 'flashLoanSimple(address receiverAddress, address asset, uint256 amount, bytes params, uint16 referralCode)' + )?.selector!]: (accountOp: AccountOp, call: IrCall) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { receiverAddress, asset, amount, params, referralCode } = + iface.parseTransaction(call)!.args + + return [ + getAction('Execute Flash Loan'), + getToken(asset, amount), + getLabel('and call'), + getAddressVisualization(receiverAddress) + ] + }, + [iface.getFunction('repayWithATokens(bytes32 args)')?.selector!]: ( + accountOp: AccountOp, + call: IrCall + ) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { args } = iface.parseTransaction(call)!.args + return [getAction('Repay with token A'), getLabel('to'), getAddressVisualization(call.to)] + }, + [iface.getFunction('repayWithPermit(bytes32 args, bytes32 r, bytes32 s)')?.selector!]: ( + accountOp: AccountOp, + call: IrCall + ) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { args } = iface.parseTransaction(call)!.args + return [getAction('Repay with permit'), getLabel('to'), getAddressVisualization(call.to)] + }, + [iface.getFunction( + 'supplyWithPermit(address asset, uint256 amount, address onBehalfOf, uint16 referralCode, uint256 deadline, uint8 permitV, bytes32 permitR, bytes32 permitS)' + )?.selector!]: (accountOp: AccountOp, call: IrCall) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { asset, amount, onBehalfOf, referralCode, deadline, permitV, permitR, bytes32 } = + iface.parseTransaction(call)!.args + return [ + getAction('Supply'), + getToken(asset, amount), + ...(onBehalfOf !== accountOp.accountAddr + ? [getLabel('on behalf of'), getAddressVisualization(onBehalfOf)] + : []), + getDeadline(deadline) + ] + } + } +} diff --git a/src/libs/humanizer/modules/Aave/aaveWethGatewayV2.ts b/src/libs/humanizer/modules/Aave/aaveWethGatewayV2.ts index bd6d165f8..954d9f0be 100644 --- a/src/libs/humanizer/modules/Aave/aaveWethGatewayV2.ts +++ b/src/libs/humanizer/modules/Aave/aaveWethGatewayV2.ts @@ -39,7 +39,7 @@ export const aaveWethGatewayV2 = (): { [key: string]: Function } => { [iface.getFunction('borrowETH')?.selector!]: (accountOp: AccountOp, call: IrCall) => { const [, /* lendingPool */ amount] = iface.parseTransaction(call)?.args || [] return [ - getAction('Borrow '), + getAction('Borrow'), getToken(ZeroAddress, amount), getLabel('from Aave lending pool') ] diff --git a/src/libs/humanizer/modules/Aave/index.ts b/src/libs/humanizer/modules/Aave/index.ts index 1ae6ef355..4a318ddf4 100644 --- a/src/libs/humanizer/modules/Aave/index.ts +++ b/src/libs/humanizer/modules/Aave/index.ts @@ -1,12 +1,14 @@ import { AccountOp } from '../../../accountOp/accountOp' import { HumanizerCallModule, IrCall } from '../../interfaces' import { aaveLendingPoolV2 } from './aaveLendingPoolV2' +import { aaveV3Pool } from './aaveV3' import { aaveWethGatewayV2 } from './aaveWethGatewayV2' export const aaveHumanizer: HumanizerCallModule = (accountOp: AccountOp, irCalls: IrCall[]) => { const matcher = { ...aaveLendingPoolV2(), - ...aaveWethGatewayV2() + ...aaveWethGatewayV2(), + ...aaveV3Pool() } const newCalls = irCalls.map((call) => { const sigHash = call.data.slice(0, 10)