@eulerxyz/euler-v2-sdk 0.1.0-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +115 -0
- package/dist/src/entities/Account.d.ts +242 -0
- package/dist/src/entities/Account.js +509 -0
- package/dist/src/entities/Account.js.map +1 -0
- package/dist/src/entities/ERC4626Vault.d.ts +56 -0
- package/dist/src/entities/ERC4626Vault.js +94 -0
- package/dist/src/entities/ERC4626Vault.js.map +1 -0
- package/dist/src/entities/EVault.d.ts +159 -0
- package/dist/src/entities/EVault.js +224 -0
- package/dist/src/entities/EVault.js.map +1 -0
- package/dist/src/entities/EulerEarn.d.ts +69 -0
- package/dist/src/entities/EulerEarn.js +89 -0
- package/dist/src/entities/EulerEarn.js.map +1 -0
- package/dist/src/entities/EulerLabels.d.ts +53 -0
- package/dist/src/entities/EulerLabels.js +2 -0
- package/dist/src/entities/EulerLabels.js.map +1 -0
- package/dist/src/entities/SecuritizeCollateralVault.d.ts +16 -0
- package/dist/src/entities/SecuritizeCollateralVault.js +22 -0
- package/dist/src/entities/SecuritizeCollateralVault.js.map +1 -0
- package/dist/src/entities/Wallet.d.ts +27 -0
- package/dist/src/entities/Wallet.js +21 -0
- package/dist/src/entities/Wallet.js.map +1 -0
- package/dist/src/index.d.ts +43 -0
- package/dist/src/index.js +46 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/plugins/batchSimulation.d.ts +34 -0
- package/dist/src/plugins/batchSimulation.js +83 -0
- package/dist/src/plugins/batchSimulation.js.map +1 -0
- package/dist/src/plugins/index.d.ts +4 -0
- package/dist/src/plugins/index.js +5 -0
- package/dist/src/plugins/index.js.map +1 -0
- package/dist/src/plugins/keyring/index.d.ts +1 -0
- package/dist/src/plugins/keyring/index.js +2 -0
- package/dist/src/plugins/keyring/index.js.map +1 -0
- package/dist/src/plugins/keyring/keyringPlugin.d.ts +41 -0
- package/dist/src/plugins/keyring/keyringPlugin.js +182 -0
- package/dist/src/plugins/keyring/keyringPlugin.js.map +1 -0
- package/dist/src/plugins/pyth/index.d.ts +1 -0
- package/dist/src/plugins/pyth/index.js +2 -0
- package/dist/src/plugins/pyth/index.js.map +1 -0
- package/dist/src/plugins/pyth/pythPlugin.d.ts +29 -0
- package/dist/src/plugins/pyth/pythPlugin.js +190 -0
- package/dist/src/plugins/pyth/pythPlugin.js.map +1 -0
- package/dist/src/plugins/types.d.ts +39 -0
- package/dist/src/plugins/types.js +16 -0
- package/dist/src/plugins/types.js.map +1 -0
- package/dist/src/sdk/buildSDK.d.ts +77 -0
- package/dist/src/sdk/buildSDK.js +366 -0
- package/dist/src/sdk/buildSDK.js.map +1 -0
- package/dist/src/sdk/defaultConfig.d.ts +26 -0
- package/dist/src/sdk/defaultConfig.js +68 -0
- package/dist/src/sdk/defaultConfig.js.map +1 -0
- package/dist/src/sdk/sdk.d.ts +73 -0
- package/dist/src/sdk/sdk.js +67 -0
- package/dist/src/sdk/sdk.js.map +1 -0
- package/dist/src/services/abiService/abiService.d.ts +13 -0
- package/dist/src/services/abiService/abiService.js +25 -0
- package/dist/src/services/abiService/abiService.js.map +1 -0
- package/dist/src/services/abiService/index.d.ts +2 -0
- package/dist/src/services/abiService/index.js +2 -0
- package/dist/src/services/abiService/index.js.map +1 -0
- package/dist/src/services/accountService/accountService.d.ts +44 -0
- package/dist/src/services/accountService/accountService.js +193 -0
- package/dist/src/services/accountService/accountService.js.map +1 -0
- package/dist/src/services/accountService/accountServiceConfig.d.ts +15 -0
- package/dist/src/services/accountService/accountServiceConfig.js +2 -0
- package/dist/src/services/accountService/accountServiceConfig.js.map +1 -0
- package/dist/src/services/accountService/adapters/accountOnchainAdapter/abis/accountLensAbi.d.ts +960 -0
- package/dist/src/services/accountService/adapters/accountOnchainAdapter/abis/accountLensAbi.js +1230 -0
- package/dist/src/services/accountService/adapters/accountOnchainAdapter/abis/accountLensAbi.js.map +1 -0
- package/dist/src/services/accountService/adapters/accountOnchainAdapter/accountInfoConverter.d.ts +17 -0
- package/dist/src/services/accountService/adapters/accountOnchainAdapter/accountInfoConverter.js +158 -0
- package/dist/src/services/accountService/adapters/accountOnchainAdapter/accountInfoConverter.js.map +1 -0
- package/dist/src/services/accountService/adapters/accountOnchainAdapter/accountLensTypes.d.ts +48 -0
- package/dist/src/services/accountService/adapters/accountOnchainAdapter/accountLensTypes.js +2 -0
- package/dist/src/services/accountService/adapters/accountOnchainAdapter/accountLensTypes.js.map +1 -0
- package/dist/src/services/accountService/adapters/accountOnchainAdapter/accountOnchainAdapter.d.ts +210 -0
- package/dist/src/services/accountService/adapters/accountOnchainAdapter/accountOnchainAdapter.js +287 -0
- package/dist/src/services/accountService/adapters/accountOnchainAdapter/accountOnchainAdapter.js.map +1 -0
- package/dist/src/services/accountService/adapters/accountOnchainAdapter/accountVaultsSubgraphAdapter.d.ts +22 -0
- package/dist/src/services/accountService/adapters/accountOnchainAdapter/accountVaultsSubgraphAdapter.js +80 -0
- package/dist/src/services/accountService/adapters/accountOnchainAdapter/accountVaultsSubgraphAdapter.js.map +1 -0
- package/dist/src/services/accountService/adapters/accountOutputNormalization.d.ts +8 -0
- package/dist/src/services/accountService/adapters/accountOutputNormalization.js +50 -0
- package/dist/src/services/accountService/adapters/accountOutputNormalization.js.map +1 -0
- package/dist/src/services/accountService/adapters/accountV3Adapter/accountV3Adapter.d.ts +62 -0
- package/dist/src/services/accountService/adapters/accountV3Adapter/accountV3Adapter.js +287 -0
- package/dist/src/services/accountService/adapters/accountV3Adapter/accountV3Adapter.js.map +1 -0
- package/dist/src/services/accountService/adapters/accountVaultsSubgraphAdapter/accountVaultsSubgraphAdapter.d.ts +1 -0
- package/dist/src/services/accountService/adapters/accountVaultsSubgraphAdapter/accountVaultsSubgraphAdapter.js +2 -0
- package/dist/src/services/accountService/adapters/accountVaultsSubgraphAdapter/accountVaultsSubgraphAdapter.js.map +1 -0
- package/dist/src/services/accountService/index.d.ts +5 -0
- package/dist/src/services/accountService/index.js +4 -0
- package/dist/src/services/accountService/index.js.map +1 -0
- package/dist/src/services/deploymentService/deploymentService.d.ts +116 -0
- package/dist/src/services/deploymentService/deploymentService.js +44 -0
- package/dist/src/services/deploymentService/deploymentService.js.map +1 -0
- package/dist/src/services/deploymentService/index.d.ts +2 -0
- package/dist/src/services/deploymentService/index.js +2 -0
- package/dist/src/services/deploymentService/index.js.map +1 -0
- package/dist/src/services/eulerLabelsService/eulerLabelsService.d.ts +54 -0
- package/dist/src/services/eulerLabelsService/eulerLabelsService.js +178 -0
- package/dist/src/services/eulerLabelsService/eulerLabelsService.js.map +1 -0
- package/dist/src/services/eulerLabelsService/index.d.ts +2 -0
- package/dist/src/services/eulerLabelsService/index.js +2 -0
- package/dist/src/services/eulerLabelsService/index.js.map +1 -0
- package/dist/src/services/executionService/abis/eVaultAbi.d.ts +1948 -0
- package/dist/src/services/executionService/abis/eVaultAbi.js +2517 -0
- package/dist/src/services/executionService/abis/eVaultAbi.js.map +1 -0
- package/dist/src/services/executionService/abis/ethereumVaultConnectorAbi.d.ts +1070 -0
- package/dist/src/services/executionService/abis/ethereumVaultConnectorAbi.js +1387 -0
- package/dist/src/services/executionService/abis/ethereumVaultConnectorAbi.js.map +1 -0
- package/dist/src/services/executionService/abis/permit2PermitAbi.d.ts +52 -0
- package/dist/src/services/executionService/abis/permit2PermitAbi.js +36 -0
- package/dist/src/services/executionService/abis/permit2PermitAbi.js.map +1 -0
- package/dist/src/services/executionService/abis/swapVerifierAbi.d.ts +139 -0
- package/dist/src/services/executionService/abis/swapVerifierAbi.js +70 -0
- package/dist/src/services/executionService/abis/swapVerifierAbi.js.map +1 -0
- package/dist/src/services/executionService/abis/swapperAbi.d.ts +270 -0
- package/dist/src/services/executionService/abis/swapperAbi.js +152 -0
- package/dist/src/services/executionService/abis/swapperAbi.js.map +1 -0
- package/dist/src/services/executionService/executionService.d.ts +619 -0
- package/dist/src/services/executionService/executionService.js +2037 -0
- package/dist/src/services/executionService/executionService.js.map +1 -0
- package/dist/src/services/executionService/executionServiceTypes.d.ts +423 -0
- package/dist/src/services/executionService/executionServiceTypes.js +14 -0
- package/dist/src/services/executionService/executionServiceTypes.js.map +1 -0
- package/dist/src/services/executionService/index.d.ts +7 -0
- package/dist/src/services/executionService/index.js +7 -0
- package/dist/src/services/executionService/index.js.map +1 -0
- package/dist/src/services/feeFlowService/feeFlowService.d.ts +22 -0
- package/dist/src/services/feeFlowService/feeFlowService.js +239 -0
- package/dist/src/services/feeFlowService/feeFlowService.js.map +1 -0
- package/dist/src/services/feeFlowService/feeFlowServiceTypes.d.ts +42 -0
- package/dist/src/services/feeFlowService/feeFlowServiceTypes.js +2 -0
- package/dist/src/services/feeFlowService/feeFlowServiceTypes.js.map +1 -0
- package/dist/src/services/feeFlowService/index.d.ts +2 -0
- package/dist/src/services/feeFlowService/index.js +2 -0
- package/dist/src/services/feeFlowService/index.js.map +1 -0
- package/dist/src/services/intrinsicApyService/adapters/intrinsicApyV3Adapter/index.d.ts +2 -0
- package/dist/src/services/intrinsicApyService/adapters/intrinsicApyV3Adapter/index.js +2 -0
- package/dist/src/services/intrinsicApyService/adapters/intrinsicApyV3Adapter/index.js.map +1 -0
- package/dist/src/services/intrinsicApyService/adapters/intrinsicApyV3Adapter/intrinsicApyV3Adapter.d.ts +21 -0
- package/dist/src/services/intrinsicApyService/adapters/intrinsicApyV3Adapter/intrinsicApyV3Adapter.js +125 -0
- package/dist/src/services/intrinsicApyService/adapters/intrinsicApyV3Adapter/intrinsicApyV3Adapter.js.map +1 -0
- package/dist/src/services/intrinsicApyService/adapters/intrinsicApyV3Adapter/intrinsicApyV3AdapterTypes.d.ts +30 -0
- package/dist/src/services/intrinsicApyService/adapters/intrinsicApyV3Adapter/intrinsicApyV3AdapterTypes.js +2 -0
- package/dist/src/services/intrinsicApyService/adapters/intrinsicApyV3Adapter/intrinsicApyV3AdapterTypes.js.map +1 -0
- package/dist/src/services/intrinsicApyService/index.d.ts +4 -0
- package/dist/src/services/intrinsicApyService/index.js +3 -0
- package/dist/src/services/intrinsicApyService/index.js.map +1 -0
- package/dist/src/services/intrinsicApyService/intrinsicApyService.d.ts +28 -0
- package/dist/src/services/intrinsicApyService/intrinsicApyService.js +42 -0
- package/dist/src/services/intrinsicApyService/intrinsicApyService.js.map +1 -0
- package/dist/src/services/oracleAdapterService/index.d.ts +1 -0
- package/dist/src/services/oracleAdapterService/index.js +2 -0
- package/dist/src/services/oracleAdapterService/index.js.map +1 -0
- package/dist/src/services/oracleAdapterService/oracleAdapterService.d.ts +40 -0
- package/dist/src/services/oracleAdapterService/oracleAdapterService.js +65 -0
- package/dist/src/services/oracleAdapterService/oracleAdapterService.js.map +1 -0
- package/dist/src/services/priceService/backendClient.d.ts +70 -0
- package/dist/src/services/priceService/backendClient.js +108 -0
- package/dist/src/services/priceService/backendClient.js.map +1 -0
- package/dist/src/services/priceService/index.d.ts +2 -0
- package/dist/src/services/priceService/index.js +3 -0
- package/dist/src/services/priceService/index.js.map +1 -0
- package/dist/src/services/priceService/priceService.d.ts +133 -0
- package/dist/src/services/priceService/priceService.js +499 -0
- package/dist/src/services/priceService/priceService.js.map +1 -0
- package/dist/src/services/priceService/utilsLensPriceAbi.d.ts +60 -0
- package/dist/src/services/priceService/utilsLensPriceAbi.js +31 -0
- package/dist/src/services/priceService/utilsLensPriceAbi.js.map +1 -0
- package/dist/src/services/providerService/index.d.ts +2 -0
- package/dist/src/services/providerService/index.js +2 -0
- package/dist/src/services/providerService/index.js.map +1 -0
- package/dist/src/services/providerService/providerService.d.ts +11 -0
- package/dist/src/services/providerService/providerService.js +61 -0
- package/dist/src/services/providerService/providerService.js.map +1 -0
- package/dist/src/services/rewardsService/adapters/rewardsDirectAdapter/index.d.ts +2 -0
- package/dist/src/services/rewardsService/adapters/rewardsDirectAdapter/index.js +2 -0
- package/dist/src/services/rewardsService/adapters/rewardsDirectAdapter/index.js.map +1 -0
- package/dist/src/services/rewardsService/adapters/rewardsDirectAdapter/rewardsDirectAdapter.d.ts +48 -0
- package/dist/src/services/rewardsService/adapters/rewardsDirectAdapter/rewardsDirectAdapter.js +391 -0
- package/dist/src/services/rewardsService/adapters/rewardsDirectAdapter/rewardsDirectAdapter.js.map +1 -0
- package/dist/src/services/rewardsService/adapters/rewardsV3Adapter/index.d.ts +2 -0
- package/dist/src/services/rewardsService/adapters/rewardsV3Adapter/index.js +2 -0
- package/dist/src/services/rewardsService/adapters/rewardsV3Adapter/index.js.map +1 -0
- package/dist/src/services/rewardsService/adapters/rewardsV3Adapter/rewardsV3Adapter.d.ts +23 -0
- package/dist/src/services/rewardsService/adapters/rewardsV3Adapter/rewardsV3Adapter.js +296 -0
- package/dist/src/services/rewardsService/adapters/rewardsV3Adapter/rewardsV3Adapter.js.map +1 -0
- package/dist/src/services/rewardsService/adapters/rewardsV3Adapter/rewardsV3AdapterTypes.d.ts +110 -0
- package/dist/src/services/rewardsService/adapters/rewardsV3Adapter/rewardsV3AdapterTypes.js +2 -0
- package/dist/src/services/rewardsService/adapters/rewardsV3Adapter/rewardsV3AdapterTypes.js.map +1 -0
- package/dist/src/services/rewardsService/index.d.ts +5 -0
- package/dist/src/services/rewardsService/index.js +4 -0
- package/dist/src/services/rewardsService/index.js.map +1 -0
- package/dist/src/services/rewardsService/rewardsService.d.ts +34 -0
- package/dist/src/services/rewardsService/rewardsService.js +298 -0
- package/dist/src/services/rewardsService/rewardsService.js.map +1 -0
- package/dist/src/services/rewardsService/rewardsServiceTypes.d.ts +270 -0
- package/dist/src/services/rewardsService/rewardsServiceTypes.js +2 -0
- package/dist/src/services/rewardsService/rewardsServiceTypes.js.map +1 -0
- package/dist/src/services/simulationService/index.d.ts +2 -0
- package/dist/src/services/simulationService/index.js +2 -0
- package/dist/src/services/simulationService/index.js.map +1 -0
- package/dist/src/services/simulationService/simulationService.d.ts +88 -0
- package/dist/src/services/simulationService/simulationService.js +497 -0
- package/dist/src/services/simulationService/simulationService.js.map +1 -0
- package/dist/src/services/swapService/index.d.ts +3 -0
- package/dist/src/services/swapService/index.js +3 -0
- package/dist/src/services/swapService/index.js.map +1 -0
- package/dist/src/services/swapService/swapService.d.ts +121 -0
- package/dist/src/services/swapService/swapService.js +329 -0
- package/dist/src/services/swapService/swapService.js.map +1 -0
- package/dist/src/services/swapService/swapServiceTypes.d.ts +130 -0
- package/dist/src/services/swapService/swapServiceTypes.js +16 -0
- package/dist/src/services/swapService/swapServiceTypes.js.map +1 -0
- package/dist/src/services/swapService/swapVerifierAbi.d.ts +139 -0
- package/dist/src/services/swapService/swapVerifierAbi.js +178 -0
- package/dist/src/services/swapService/swapVerifierAbi.js.map +1 -0
- package/dist/src/services/tokenlistService/index.d.ts +3 -0
- package/dist/src/services/tokenlistService/index.js +2 -0
- package/dist/src/services/tokenlistService/index.js.map +1 -0
- package/dist/src/services/tokenlistService/tokenlistService.d.ts +31 -0
- package/dist/src/services/tokenlistService/tokenlistService.js +56 -0
- package/dist/src/services/tokenlistService/tokenlistService.js.map +1 -0
- package/dist/src/services/tokenlistService/tokenlistServiceTypes.d.ts +33 -0
- package/dist/src/services/tokenlistService/tokenlistServiceTypes.js +2 -0
- package/dist/src/services/tokenlistService/tokenlistServiceTypes.js.map +1 -0
- package/dist/src/services/vaults/IVaultService.d.ts +47 -0
- package/dist/src/services/vaults/IVaultService.js +2 -0
- package/dist/src/services/vaults/IVaultService.js.map +1 -0
- package/dist/src/services/vaults/eVaultService/adapters/eVaultOnchainAdapter/abis/vaultLensAbi.d.ts +1280 -0
- package/dist/src/services/vaults/eVaultService/adapters/eVaultOnchainAdapter/abis/vaultLensAbi.js +1640 -0
- package/dist/src/services/vaults/eVaultService/adapters/eVaultOnchainAdapter/abis/vaultLensAbi.js.map +1 -0
- package/dist/src/services/vaults/eVaultService/adapters/eVaultOnchainAdapter/eVaultLensTypes.d.ts +97 -0
- package/dist/src/services/vaults/eVaultService/adapters/eVaultOnchainAdapter/eVaultLensTypes.js +9 -0
- package/dist/src/services/vaults/eVaultService/adapters/eVaultOnchainAdapter/eVaultLensTypes.js.map +1 -0
- package/dist/src/services/vaults/eVaultService/adapters/eVaultOnchainAdapter/eVaultOnchainAdapter.d.ts +141 -0
- package/dist/src/services/vaults/eVaultService/adapters/eVaultOnchainAdapter/eVaultOnchainAdapter.js +189 -0
- package/dist/src/services/vaults/eVaultService/adapters/eVaultOnchainAdapter/eVaultOnchainAdapter.js.map +1 -0
- package/dist/src/services/vaults/eVaultService/adapters/eVaultOnchainAdapter/vaultInfoConverter.d.ts +10 -0
- package/dist/src/services/vaults/eVaultService/adapters/eVaultOnchainAdapter/vaultInfoConverter.js +454 -0
- package/dist/src/services/vaults/eVaultService/adapters/eVaultOnchainAdapter/vaultInfoConverter.js.map +1 -0
- package/dist/src/services/vaults/eVaultService/adapters/eVaultV3Adapter/eVaultV3Adapter.d.ts +25 -0
- package/dist/src/services/vaults/eVaultService/adapters/eVaultV3Adapter/eVaultV3Adapter.js +214 -0
- package/dist/src/services/vaults/eVaultService/adapters/eVaultV3Adapter/eVaultV3Adapter.js.map +1 -0
- package/dist/src/services/vaults/eVaultService/adapters/eVaultV3Adapter/eVaultV3AdapterConversions.d.ts +5 -0
- package/dist/src/services/vaults/eVaultService/adapters/eVaultV3Adapter/eVaultV3AdapterConversions.js +795 -0
- package/dist/src/services/vaults/eVaultService/adapters/eVaultV3Adapter/eVaultV3AdapterConversions.js.map +1 -0
- package/dist/src/services/vaults/eVaultService/adapters/eVaultV3Adapter/eVaultV3AdapterTypes.d.ts +146 -0
- package/dist/src/services/vaults/eVaultService/adapters/eVaultV3Adapter/eVaultV3AdapterTypes.js +2 -0
- package/dist/src/services/vaults/eVaultService/adapters/eVaultV3Adapter/eVaultV3AdapterTypes.js.map +1 -0
- package/dist/src/services/vaults/eVaultService/eVaultService.d.ts +74 -0
- package/dist/src/services/vaults/eVaultService/eVaultService.js +362 -0
- package/dist/src/services/vaults/eVaultService/eVaultService.js.map +1 -0
- package/dist/src/services/vaults/eVaultService/eVaultServiceConfig.d.ts +15 -0
- package/dist/src/services/vaults/eVaultService/eVaultServiceConfig.js +2 -0
- package/dist/src/services/vaults/eVaultService/eVaultServiceConfig.js.map +1 -0
- package/dist/src/services/vaults/eVaultService/index.d.ts +5 -0
- package/dist/src/services/vaults/eVaultService/index.js +4 -0
- package/dist/src/services/vaults/eVaultService/index.js.map +1 -0
- package/dist/src/services/vaults/eulerEarnService/adapters/abis/eulerEarnVaultLensAbi.d.ts +468 -0
- package/dist/src/services/vaults/eulerEarnService/adapters/abis/eulerEarnVaultLensAbi.js +600 -0
- package/dist/src/services/vaults/eulerEarnService/adapters/abis/eulerEarnVaultLensAbi.js.map +1 -0
- package/dist/src/services/vaults/eulerEarnService/adapters/eulerEarnInfoConverter.d.ts +10 -0
- package/dist/src/services/vaults/eulerEarnService/adapters/eulerEarnInfoConverter.js +151 -0
- package/dist/src/services/vaults/eulerEarnService/adapters/eulerEarnInfoConverter.js.map +1 -0
- package/dist/src/services/vaults/eulerEarnService/adapters/eulerEarnLensTypes.d.ts +55 -0
- package/dist/src/services/vaults/eulerEarnService/adapters/eulerEarnLensTypes.js +2 -0
- package/dist/src/services/vaults/eulerEarnService/adapters/eulerEarnLensTypes.js.map +1 -0
- package/dist/src/services/vaults/eulerEarnService/adapters/eulerEarnOnchainAdapter.d.ts +109 -0
- package/dist/src/services/vaults/eulerEarnService/adapters/eulerEarnOnchainAdapter.js +238 -0
- package/dist/src/services/vaults/eulerEarnService/adapters/eulerEarnOnchainAdapter.js.map +1 -0
- package/dist/src/services/vaults/eulerEarnService/adapters/eulerEarnV3Adapter.d.ts +100 -0
- package/dist/src/services/vaults/eulerEarnService/adapters/eulerEarnV3Adapter.js +373 -0
- package/dist/src/services/vaults/eulerEarnService/adapters/eulerEarnV3Adapter.js.map +1 -0
- package/dist/src/services/vaults/eulerEarnService/eulerEarnService.d.ts +77 -0
- package/dist/src/services/vaults/eulerEarnService/eulerEarnService.js +298 -0
- package/dist/src/services/vaults/eulerEarnService/eulerEarnService.js.map +1 -0
- package/dist/src/services/vaults/eulerEarnService/eulerEarnServiceConfig.d.ts +13 -0
- package/dist/src/services/vaults/eulerEarnService/eulerEarnServiceConfig.js +2 -0
- package/dist/src/services/vaults/eulerEarnService/eulerEarnServiceConfig.js.map +1 -0
- package/dist/src/services/vaults/eulerEarnService/index.d.ts +5 -0
- package/dist/src/services/vaults/eulerEarnService/index.js +4 -0
- package/dist/src/services/vaults/eulerEarnService/index.js.map +1 -0
- package/dist/src/services/vaults/index.d.ts +1 -0
- package/dist/src/services/vaults/index.js +2 -0
- package/dist/src/services/vaults/index.js.map +1 -0
- package/dist/src/services/vaults/securitizeVaultService/adapters/abis/erc4626EvcCollateralSecuritizeAbi.d.ts +22 -0
- package/dist/src/services/vaults/securitizeVaultService/adapters/abis/erc4626EvcCollateralSecuritizeAbi.js +18 -0
- package/dist/src/services/vaults/securitizeVaultService/adapters/abis/erc4626EvcCollateralSecuritizeAbi.js.map +1 -0
- package/dist/src/services/vaults/securitizeVaultService/adapters/abis/utilsLensAbi.d.ts +64 -0
- package/dist/src/services/vaults/securitizeVaultService/adapters/abis/utilsLensAbi.js +30 -0
- package/dist/src/services/vaults/securitizeVaultService/adapters/abis/utilsLensAbi.js.map +1 -0
- package/dist/src/services/vaults/securitizeVaultService/adapters/securitizeVaultInfoConverter.d.ts +4 -0
- package/dist/src/services/vaults/securitizeVaultService/adapters/securitizeVaultInfoConverter.js +53 -0
- package/dist/src/services/vaults/securitizeVaultService/adapters/securitizeVaultInfoConverter.js.map +1 -0
- package/dist/src/services/vaults/securitizeVaultService/adapters/securitizeVaultLensTypes.d.ts +16 -0
- package/dist/src/services/vaults/securitizeVaultService/adapters/securitizeVaultLensTypes.js +2 -0
- package/dist/src/services/vaults/securitizeVaultService/adapters/securitizeVaultLensTypes.js.map +1 -0
- package/dist/src/services/vaults/securitizeVaultService/adapters/securitizeVaultOnchainAdapter.d.ts +37 -0
- package/dist/src/services/vaults/securitizeVaultService/adapters/securitizeVaultOnchainAdapter.js +113 -0
- package/dist/src/services/vaults/securitizeVaultService/adapters/securitizeVaultOnchainAdapter.js.map +1 -0
- package/dist/src/services/vaults/securitizeVaultService/index.d.ts +2 -0
- package/dist/src/services/vaults/securitizeVaultService/index.js +3 -0
- package/dist/src/services/vaults/securitizeVaultService/index.js.map +1 -0
- package/dist/src/services/vaults/securitizeVaultService/securitizeVaultService.d.ts +52 -0
- package/dist/src/services/vaults/securitizeVaultService/securitizeVaultService.js +190 -0
- package/dist/src/services/vaults/securitizeVaultService/securitizeVaultService.js.map +1 -0
- package/dist/src/services/vaults/vaultMetaService/adapters/IVaultTypeAdapter.d.ts +29 -0
- package/dist/src/services/vaults/vaultMetaService/adapters/IVaultTypeAdapter.js +2 -0
- package/dist/src/services/vaults/vaultMetaService/adapters/IVaultTypeAdapter.js.map +1 -0
- package/dist/src/services/vaults/vaultMetaService/adapters/VaultTypeSubgraphAdapter.d.ts +18 -0
- package/dist/src/services/vaults/vaultMetaService/adapters/VaultTypeSubgraphAdapter.js +82 -0
- package/dist/src/services/vaults/vaultMetaService/adapters/VaultTypeSubgraphAdapter.js.map +1 -0
- package/dist/src/services/vaults/vaultMetaService/adapters/VaultTypeV3Adapter.d.ts +35 -0
- package/dist/src/services/vaults/vaultMetaService/adapters/VaultTypeV3Adapter.js +154 -0
- package/dist/src/services/vaults/vaultMetaService/adapters/VaultTypeV3Adapter.js.map +1 -0
- package/dist/src/services/vaults/vaultMetaService/index.d.ts +4 -0
- package/dist/src/services/vaults/vaultMetaService/index.js +4 -0
- package/dist/src/services/vaults/vaultMetaService/index.js.map +1 -0
- package/dist/src/services/vaults/vaultMetaService/vaultMetaService.d.ts +71 -0
- package/dist/src/services/vaults/vaultMetaService/vaultMetaService.js +283 -0
- package/dist/src/services/vaults/vaultMetaService/vaultMetaService.js.map +1 -0
- package/dist/src/services/walletService/adapters/walletOnchainAdapter.d.ts +20 -0
- package/dist/src/services/walletService/adapters/walletOnchainAdapter.js +222 -0
- package/dist/src/services/walletService/adapters/walletOnchainAdapter.js.map +1 -0
- package/dist/src/services/walletService/index.d.ts +3 -0
- package/dist/src/services/walletService/index.js +2 -0
- package/dist/src/services/walletService/index.js.map +1 -0
- package/dist/src/services/walletService/walletService.d.ts +19 -0
- package/dist/src/services/walletService/walletService.js +37 -0
- package/dist/src/services/walletService/walletService.js.map +1 -0
- package/dist/src/utils/accountComputations.d.ts +96 -0
- package/dist/src/utils/accountComputations.js +297 -0
- package/dist/src/utils/accountComputations.js.map +1 -0
- package/dist/src/utils/batch.d.ts +2 -0
- package/dist/src/utils/batch.js +51 -0
- package/dist/src/utils/batch.js.map +1 -0
- package/dist/src/utils/buildQuery.d.ts +19 -0
- package/dist/src/utils/buildQuery.js +72 -0
- package/dist/src/utils/buildQuery.js.map +1 -0
- package/dist/src/utils/callBundler.d.ts +32 -0
- package/dist/src/utils/callBundler.js +93 -0
- package/dist/src/utils/callBundler.js.map +1 -0
- package/dist/src/utils/decodeSmartContractErrors.d.ts +13 -0
- package/dist/src/utils/decodeSmartContractErrors.js +311 -0
- package/dist/src/utils/decodeSmartContractErrors.js.map +1 -0
- package/dist/src/utils/entityDiagnostics.d.ts +28 -0
- package/dist/src/utils/entityDiagnostics.js +72 -0
- package/dist/src/utils/entityDiagnostics.js.map +1 -0
- package/dist/src/utils/eulerErrorSelectors.d.ts +226 -0
- package/dist/src/utils/eulerErrorSelectors.js +227 -0
- package/dist/src/utils/eulerErrorSelectors.js.map +1 -0
- package/dist/src/utils/irm.d.ts +60 -0
- package/dist/src/utils/irm.js +213 -0
- package/dist/src/utils/irm.js.map +1 -0
- package/dist/src/utils/normalization.d.ts +30 -0
- package/dist/src/utils/normalization.js +79 -0
- package/dist/src/utils/normalization.js.map +1 -0
- package/dist/src/utils/oracle.d.ts +107 -0
- package/dist/src/utils/oracle.js +437 -0
- package/dist/src/utils/oracle.js.map +1 -0
- package/dist/src/utils/parsing.d.ts +29 -0
- package/dist/src/utils/parsing.js +199 -0
- package/dist/src/utils/parsing.js.map +1 -0
- package/dist/src/utils/queryNames.d.ts +28 -0
- package/dist/src/utils/queryNames.js +2 -0
- package/dist/src/utils/queryNames.js.map +1 -0
- package/dist/src/utils/stateOverrides/accessList.d.ts +14 -0
- package/dist/src/utils/stateOverrides/accessList.js +24 -0
- package/dist/src/utils/stateOverrides/accessList.js.map +1 -0
- package/dist/src/utils/stateOverrides/approvalOverrides.d.ts +20 -0
- package/dist/src/utils/stateOverrides/approvalOverrides.js +111 -0
- package/dist/src/utils/stateOverrides/approvalOverrides.js.map +1 -0
- package/dist/src/utils/stateOverrides/balanceOverrides.d.ts +13 -0
- package/dist/src/utils/stateOverrides/balanceOverrides.js +145 -0
- package/dist/src/utils/stateOverrides/balanceOverrides.js.map +1 -0
- package/dist/src/utils/stateOverrides/getStateOverrides.d.ts +31 -0
- package/dist/src/utils/stateOverrides/getStateOverrides.js +86 -0
- package/dist/src/utils/stateOverrides/getStateOverrides.js.map +1 -0
- package/dist/src/utils/stateOverrides/index.d.ts +4 -0
- package/dist/src/utils/stateOverrides/index.js +5 -0
- package/dist/src/utils/stateOverrides/index.js.map +1 -0
- package/dist/src/utils/stateOverrides/mergeStateOverrides.d.ts +6 -0
- package/dist/src/utils/stateOverrides/mergeStateOverrides.js +40 -0
- package/dist/src/utils/stateOverrides/mergeStateOverrides.js.map +1 -0
- package/dist/src/utils/stateOverrides/types.d.ts +5 -0
- package/dist/src/utils/stateOverrides/types.js +2 -0
- package/dist/src/utils/stateOverrides/types.js.map +1 -0
- package/dist/src/utils/subAccounts.d.ts +6 -0
- package/dist/src/utils/subAccounts.js +24 -0
- package/dist/src/utils/subAccounts.js.map +1 -0
- package/dist/src/utils/types.d.ts +20 -0
- package/dist/src/utils/types.js +8 -0
- package/dist/src/utils/types.js.map +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1,2037 @@
|
|
|
1
|
+
import { encodeFunctionData, getAddress, maxUint256, zeroAddress, maxUint160, maxUint48, erc20Abi, decodeFunctionData, } from "viem";
|
|
2
|
+
import { ethereumVaultConnectorAbi } from "./abis/ethereumVaultConnectorAbi.js";
|
|
3
|
+
import { eVaultAbi } from "./abis/eVaultAbi.js";
|
|
4
|
+
import { permit2PermitAbi } from "./abis/permit2PermitAbi.js";
|
|
5
|
+
import { swapperAbi } from "./abis/swapperAbi.js";
|
|
6
|
+
import { swapVerifierAbi } from "./abis/swapVerifierAbi.js";
|
|
7
|
+
import { PERMIT2_TYPES, } from "./executionServiceTypes.js";
|
|
8
|
+
const PERMIT2_SIG_WINDOW = 60n * 60n;
|
|
9
|
+
const WAD = 10n ** 18n;
|
|
10
|
+
// TODO explain how this service is coupled to the concrete abis of ERC4626, permit2 and EVK.
|
|
11
|
+
// this is a helper service, not a generic one.
|
|
12
|
+
export class ExecutionService {
|
|
13
|
+
deploymentService;
|
|
14
|
+
walletService;
|
|
15
|
+
plugins = [];
|
|
16
|
+
constructor(deploymentService, walletService) {
|
|
17
|
+
this.deploymentService = deploymentService;
|
|
18
|
+
this.walletService = walletService;
|
|
19
|
+
}
|
|
20
|
+
setWalletService(walletService) {
|
|
21
|
+
this.walletService = walletService;
|
|
22
|
+
}
|
|
23
|
+
setPlugins(plugins) {
|
|
24
|
+
this.plugins = plugins;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Encodes an array of EVC batch items into a single calldata hex for `EVC.batch()`.
|
|
28
|
+
*
|
|
29
|
+
* @param items - Array of batch items (targetContract, onBehalfOfAccount, value, data) to execute atomically
|
|
30
|
+
* @returns Encoded calldata hex for the EVC batch call
|
|
31
|
+
*/
|
|
32
|
+
encodeBatch(items) {
|
|
33
|
+
return encodeFunctionData({
|
|
34
|
+
abi: ethereumVaultConnectorAbi,
|
|
35
|
+
functionName: "batch",
|
|
36
|
+
args: [items],
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Encodes EVC batch items for depositing underlying assets into a vault (mints shares to receiver).
|
|
41
|
+
*
|
|
42
|
+
* @param args - Deposit encoding arguments
|
|
43
|
+
* @param args.chainId - Chain ID (used for EVC/permit2 addresses)
|
|
44
|
+
* @param args.vault - Address of the vault to deposit into
|
|
45
|
+
* @param args.amount - Amount of underlying assets to deposit
|
|
46
|
+
* @param args.receiver - Sub-account address that receives the vault shares
|
|
47
|
+
* @param args.owner - Address that owns the assets and authorizes the deposit (onBehalfOfAccount)
|
|
48
|
+
* @param args.enableCollateral - If true, prepends enableCollateral( receiver, vault ) via EVC
|
|
49
|
+
* @param args.permit2 - Optional Permit2 message + signature; if set, prepends a permit2 permit call so transferFrom can be used
|
|
50
|
+
* @returns Array of EVC batch items (optional permit2, optional enableCollateral, deposit)
|
|
51
|
+
*/
|
|
52
|
+
encodeDeposit({ chainId, vault, amount, receiver, owner, enableCollateral, permit2, }) {
|
|
53
|
+
const items = [];
|
|
54
|
+
if (permit2) {
|
|
55
|
+
const permit2Call = this.encodePermit2Call({
|
|
56
|
+
chainId,
|
|
57
|
+
owner,
|
|
58
|
+
message: permit2.message,
|
|
59
|
+
signature: permit2.signature,
|
|
60
|
+
});
|
|
61
|
+
items.push(permit2Call);
|
|
62
|
+
}
|
|
63
|
+
// Add enable collateral if flag is set
|
|
64
|
+
if (enableCollateral) {
|
|
65
|
+
items.push(this.encodeEnableCollateral(chainId, receiver, vault));
|
|
66
|
+
}
|
|
67
|
+
// Add deposit operation
|
|
68
|
+
items.push({
|
|
69
|
+
targetContract: vault,
|
|
70
|
+
onBehalfOfAccount: owner,
|
|
71
|
+
value: 0n,
|
|
72
|
+
data: encodeFunctionData({
|
|
73
|
+
abi: eVaultAbi,
|
|
74
|
+
functionName: "deposit",
|
|
75
|
+
args: [amount, receiver],
|
|
76
|
+
}),
|
|
77
|
+
});
|
|
78
|
+
return items;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Encodes EVC batch items for minting vault shares by depositing underlying assets.
|
|
82
|
+
*
|
|
83
|
+
* @param args - Mint encoding arguments
|
|
84
|
+
* @param args.chainId - Chain ID (used for EVC/permit2 addresses)
|
|
85
|
+
* @param args.vault - Address of the vault to mint from
|
|
86
|
+
* @param args.shares - Number of vault shares to mint
|
|
87
|
+
* @param args.receiver - Sub-account address that receives the shares
|
|
88
|
+
* @param args.owner - Address that owns the assets and authorizes the mint (onBehalfOfAccount)
|
|
89
|
+
* @param args.enableCollateral - If true, prepends enableCollateral( receiver, vault ) via EVC
|
|
90
|
+
* @param args.permit2 - Optional Permit2 message + signature for transferFrom
|
|
91
|
+
* @returns Array of EVC batch items (optional permit2, optional enableCollateral, mint)
|
|
92
|
+
*/
|
|
93
|
+
encodeMint({ chainId, vault, shares, receiver, owner, enableCollateral, permit2, }) {
|
|
94
|
+
const items = [];
|
|
95
|
+
if (permit2) {
|
|
96
|
+
const permit2Call = this.encodePermit2Call({
|
|
97
|
+
chainId,
|
|
98
|
+
owner,
|
|
99
|
+
message: permit2.message,
|
|
100
|
+
signature: permit2.signature,
|
|
101
|
+
});
|
|
102
|
+
items.push(permit2Call);
|
|
103
|
+
}
|
|
104
|
+
// Add enable collateral if flag is set
|
|
105
|
+
if (enableCollateral) {
|
|
106
|
+
items.push(this.encodeEnableCollateral(chainId, receiver, vault));
|
|
107
|
+
}
|
|
108
|
+
// Add mint operation
|
|
109
|
+
items.push({
|
|
110
|
+
targetContract: vault,
|
|
111
|
+
onBehalfOfAccount: owner,
|
|
112
|
+
value: 0n,
|
|
113
|
+
data: encodeFunctionData({
|
|
114
|
+
abi: eVaultAbi,
|
|
115
|
+
functionName: "mint",
|
|
116
|
+
args: [shares, receiver],
|
|
117
|
+
}),
|
|
118
|
+
});
|
|
119
|
+
return items;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Encodes EVC batch items for withdrawing underlying assets from a vault (burns shares).
|
|
123
|
+
*
|
|
124
|
+
* @param args - Withdraw encoding arguments
|
|
125
|
+
* @param args.chainId - Chain ID (used for EVC when disabling collateral)
|
|
126
|
+
* @param args.vault - Address of the vault to withdraw from
|
|
127
|
+
* @param args.assets - Amount of underlying assets to withdraw
|
|
128
|
+
* @param args.receiver - Address that receives the withdrawn underlying assets
|
|
129
|
+
* @param args.owner - Sub-account address whose vault shares are withdrawn (onBehalfOfAccount)
|
|
130
|
+
* @param args.disableCollateral - If true, appends disableCollateral( owner, vault ) via EVC before withdraw
|
|
131
|
+
* @returns Array of EVC batch items (optional disableCollateral, withdraw)
|
|
132
|
+
*/
|
|
133
|
+
encodeWithdraw({ chainId, vault, assets, receiver, owner, disableCollateral, }) {
|
|
134
|
+
const items = [];
|
|
135
|
+
// Add disable collateral if flag is set
|
|
136
|
+
if (disableCollateral) {
|
|
137
|
+
items.push(this.encodeDisableCollateral(chainId, owner, vault));
|
|
138
|
+
}
|
|
139
|
+
// Add withdraw operation
|
|
140
|
+
items.push({
|
|
141
|
+
targetContract: vault,
|
|
142
|
+
onBehalfOfAccount: owner,
|
|
143
|
+
value: 0n,
|
|
144
|
+
data: encodeFunctionData({
|
|
145
|
+
abi: eVaultAbi,
|
|
146
|
+
functionName: "withdraw",
|
|
147
|
+
args: [assets, receiver, owner],
|
|
148
|
+
}),
|
|
149
|
+
});
|
|
150
|
+
return items;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Encodes EVC batch items for redeeming vault shares for underlying assets.
|
|
154
|
+
*
|
|
155
|
+
* @param args - Redeem encoding arguments
|
|
156
|
+
* @param args.chainId - Chain ID (used for EVC when disabling collateral)
|
|
157
|
+
* @param args.vault - Address of the vault to redeem from
|
|
158
|
+
* @param args.shares - Number of vault shares to redeem
|
|
159
|
+
* @param args.receiver - Address that receives the underlying assets
|
|
160
|
+
* @param args.owner - Sub-account address whose shares are redeemed (onBehalfOfAccount)
|
|
161
|
+
* @param args.disableCollateral - If true, prepends disableCollateral( owner, vault ) via EVC
|
|
162
|
+
* @returns Array of EVC batch items (optional disableCollateral, redeem)
|
|
163
|
+
*/
|
|
164
|
+
encodeRedeem({ chainId, vault, shares, receiver, owner, disableCollateral, }) {
|
|
165
|
+
const items = [];
|
|
166
|
+
// Add disable collateral if flag is set
|
|
167
|
+
if (disableCollateral) {
|
|
168
|
+
items.push(this.encodeDisableCollateral(chainId, owner, vault));
|
|
169
|
+
}
|
|
170
|
+
// Add redeem operation
|
|
171
|
+
items.push({
|
|
172
|
+
targetContract: vault,
|
|
173
|
+
onBehalfOfAccount: owner,
|
|
174
|
+
value: 0n,
|
|
175
|
+
data: encodeFunctionData({
|
|
176
|
+
abi: eVaultAbi,
|
|
177
|
+
functionName: "redeem",
|
|
178
|
+
args: [shares, receiver, owner],
|
|
179
|
+
}),
|
|
180
|
+
});
|
|
181
|
+
return items;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Encodes EVC batch items for borrowing from a liability vault, optionally depositing collateral in the same batch.
|
|
185
|
+
*
|
|
186
|
+
* @param args - Borrow encoding arguments
|
|
187
|
+
* @param args.chainId - Chain ID (used for EVC and optional deposit)
|
|
188
|
+
* @param args.vault - Address of the liability (borrow) vault to borrow from
|
|
189
|
+
* @param args.amount - Amount of underlying assets to borrow
|
|
190
|
+
* @param args.owner - Address that owns collateral assets when depositing (onBehalfOfAccount for deposit)
|
|
191
|
+
* @param args.borrowAccount - Sub-account that takes the debt and receives collateral if any
|
|
192
|
+
* @param args.receiver - Address that receives the borrowed assets
|
|
193
|
+
* @param args.enableController - If true, enables this vault as controller for borrowAccount via EVC before borrow (default true)
|
|
194
|
+
* @param args.currentController - If set and different from vault, disables it before enabling the new controller
|
|
195
|
+
* @param args.collateralVault - Optional vault to deposit collateral into (same batch)
|
|
196
|
+
* @param args.collateralAmount - Optional amount of collateral to deposit (requires collateralVault)
|
|
197
|
+
* @param args.enableCollateral - When depositing collateral, whether to enable it for borrowAccount (default true)
|
|
198
|
+
* @param args.collateralPermit2 - Optional Permit2 data for the collateral deposit
|
|
199
|
+
* @returns Array of EVC batch items (optional deposit, optional disableController, optional enableController, borrow)
|
|
200
|
+
*/
|
|
201
|
+
encodeBorrow(args) {
|
|
202
|
+
const { chainId, vault, amount, owner, borrowAccount, receiver, enableController = true, currentController, collateralVault, collateralAmount, enableCollateral = true, collateralPermit2, } = args;
|
|
203
|
+
const items = [];
|
|
204
|
+
// Add collateral if provided
|
|
205
|
+
if (collateralVault &&
|
|
206
|
+
collateralAmount !== undefined &&
|
|
207
|
+
collateralAmount > 0n) {
|
|
208
|
+
const depositItems = this.encodeDeposit({
|
|
209
|
+
chainId,
|
|
210
|
+
vault: collateralVault,
|
|
211
|
+
amount: collateralAmount,
|
|
212
|
+
receiver: borrowAccount,
|
|
213
|
+
enableCollateral,
|
|
214
|
+
permit2: collateralPermit2,
|
|
215
|
+
owner: owner,
|
|
216
|
+
});
|
|
217
|
+
items.push(...depositItems);
|
|
218
|
+
}
|
|
219
|
+
// Add disable controller if there's a different controller enabled
|
|
220
|
+
if (currentController && currentController !== vault) {
|
|
221
|
+
items.push(this.encodeDisableController(currentController, borrowAccount));
|
|
222
|
+
}
|
|
223
|
+
if (enableController) {
|
|
224
|
+
items.push(this.encodeEnableController(chainId, borrowAccount, vault));
|
|
225
|
+
}
|
|
226
|
+
// Add borrow operation
|
|
227
|
+
items.push({
|
|
228
|
+
targetContract: vault,
|
|
229
|
+
onBehalfOfAccount: borrowAccount,
|
|
230
|
+
value: 0n,
|
|
231
|
+
data: encodeFunctionData({
|
|
232
|
+
abi: eVaultAbi,
|
|
233
|
+
functionName: "borrow",
|
|
234
|
+
args: [amount, receiver],
|
|
235
|
+
}),
|
|
236
|
+
});
|
|
237
|
+
return items;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Encodes EVC batch items for liquidating an undercollateralized account (repay debt, seize collateral).
|
|
241
|
+
*
|
|
242
|
+
* @param args - Liquidation encoding arguments
|
|
243
|
+
* @param args.chainId - Chain ID (used for EVC enableController/enableCollateral)
|
|
244
|
+
* @param args.vault - Address of the liability vault (debt is repaid to this vault)
|
|
245
|
+
* @param args.violator - Sub-account address of the account being liquidated
|
|
246
|
+
* @param args.collateral - Address of the collateral vault from which collateral is seized
|
|
247
|
+
* @param args.repayAssets - Amount of liability asset the liquidator repays
|
|
248
|
+
* @param args.minYieldBalance - Minimum yield balance the liquidator requires; liquidation can revert if not met
|
|
249
|
+
* @param args.liquidatorSubAccountAddress - Sub-account that repays and receives seized collateral (onBehalfOfAccount)
|
|
250
|
+
* @param args.enableController - If true, enables vault as controller for liquidator sub-account before liquidate (default true)
|
|
251
|
+
* @param args.enableCollateral - If true, enables collateral vault for liquidator sub-account after liquidate (default true)
|
|
252
|
+
* @returns Array of EVC batch items (optional enableController, liquidate, optional enableCollateral)
|
|
253
|
+
*/
|
|
254
|
+
encodeLiquidation({ chainId, vault, violator, collateral, repayAssets, minYieldBalance, liquidatorSubAccountAddress, enableCollateral = true, enableController = true, }) {
|
|
255
|
+
const items = [];
|
|
256
|
+
// Optionally enable controller for the liquidator account on the liability vault
|
|
257
|
+
if (enableController) {
|
|
258
|
+
items.push(this.encodeEnableController(chainId, liquidatorSubAccountAddress, vault));
|
|
259
|
+
}
|
|
260
|
+
// Perform the liquidation
|
|
261
|
+
items.push({
|
|
262
|
+
targetContract: vault,
|
|
263
|
+
onBehalfOfAccount: liquidatorSubAccountAddress,
|
|
264
|
+
value: 0n,
|
|
265
|
+
data: encodeFunctionData({
|
|
266
|
+
abi: eVaultAbi,
|
|
267
|
+
functionName: "liquidate",
|
|
268
|
+
args: [violator, collateral, repayAssets, minYieldBalance],
|
|
269
|
+
}),
|
|
270
|
+
});
|
|
271
|
+
// Optionally enable collateral for the seized collateral vault on the liquidator account
|
|
272
|
+
if (enableCollateral) {
|
|
273
|
+
items.push(this.encodeEnableCollateral(chainId, liquidatorSubAccountAddress, collateral));
|
|
274
|
+
}
|
|
275
|
+
return items;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Encodes EVC batch items for pulling debt from one sub-account to another on the same liability vault.
|
|
279
|
+
*
|
|
280
|
+
* @param args - Pull-debt encoding arguments
|
|
281
|
+
* @param args.chainId - Chain ID (used for EVC when enabling controller)
|
|
282
|
+
* @param args.vault - Address of the liability vault
|
|
283
|
+
* @param args.amount - Amount of debt to pull
|
|
284
|
+
* @param args.from - Sub-account address from which debt is pulled
|
|
285
|
+
* @param args.to - Sub-account address that receives the debt (onBehalfOfAccount)
|
|
286
|
+
* @param args.enableController - If true, enables vault as controller for `to` via EVC before pullDebt (default true)
|
|
287
|
+
* @returns Array of EVC batch items (optional enableController, pullDebt)
|
|
288
|
+
*/
|
|
289
|
+
encodePullDebt({ chainId, vault, amount, from, to, enableController = true, }) {
|
|
290
|
+
const items = [];
|
|
291
|
+
// Add enable controller if flag is set
|
|
292
|
+
if (enableController) {
|
|
293
|
+
items.push(this.encodeEnableController(chainId, to, vault));
|
|
294
|
+
}
|
|
295
|
+
// Add pullDebt operation
|
|
296
|
+
items.push({
|
|
297
|
+
targetContract: vault,
|
|
298
|
+
onBehalfOfAccount: to,
|
|
299
|
+
value: 0n,
|
|
300
|
+
data: encodeFunctionData({
|
|
301
|
+
abi: eVaultAbi,
|
|
302
|
+
functionName: "pullDebt",
|
|
303
|
+
args: [amount, from],
|
|
304
|
+
}),
|
|
305
|
+
});
|
|
306
|
+
return items;
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Encodes EVC batch items for a multiply/leverage operation when liability and long asset differ (swap required).
|
|
310
|
+
* Order: optional permit2 → optional deposit + enable collateral → optional disableController → enableController → borrow → swap → verify/skim → optional enableCollateral on long vault.
|
|
311
|
+
*
|
|
312
|
+
* @param args - Multiply-with-swap encoding arguments
|
|
313
|
+
* @param args.chainId - Chain ID (used for EVC and permit2)
|
|
314
|
+
* @param args.collateralVault - Vault to deposit initial collateral into (can use 0n amount to skip)
|
|
315
|
+
* @param args.collateralAmount - Amount of collateral to deposit (0n to skip)
|
|
316
|
+
* @param args.liabilityVault - Vault to borrow from (liability)
|
|
317
|
+
* @param args.liabilityAmount - Amount to borrow (sent to swapper)
|
|
318
|
+
* @param args.longVault - Vault that receives the swapped assets (verify type must be skimMin)
|
|
319
|
+
* @param args.owner - Address that owns collateral (onBehalfOfAccount for deposit)
|
|
320
|
+
* @param args.receiver - Sub-account that holds the position (receives collateral, long and debt)
|
|
321
|
+
* @param args.enableCollateral - When depositing collateral, whether to enable it for receiver (default true)
|
|
322
|
+
* @param args.enableCollateralLong - Whether to enable long vault as collateral for receiver (default true)
|
|
323
|
+
* @param args.currentController - If set and different from liabilityVault, disables it first
|
|
324
|
+
* @param args.enableController - Whether to enable liability vault as controller for receiver (default true)
|
|
325
|
+
* @param args.collateralPermit2 - Optional Permit2 data for collateral deposit
|
|
326
|
+
* @param args.swapQuote - Quote with swap and verify (skimMin) steps; borrow is sent to swapQuote.swap.swapperAddress
|
|
327
|
+
* @returns Array of EVC batch items
|
|
328
|
+
*/
|
|
329
|
+
encodeMultiplyWithSwap(args) {
|
|
330
|
+
const { chainId, collateralVault, collateralAmount, liabilityVault, liabilityAmount, longVault, owner, receiver, enableCollateral = true, enableCollateralLong = true, currentController, enableController = true, collateralPermit2, swapQuote, } = args;
|
|
331
|
+
const items = [];
|
|
332
|
+
// 1. Add permit2 for collateral if provided
|
|
333
|
+
if (collateralPermit2) {
|
|
334
|
+
const permit2Call = this.encodePermit2Call({
|
|
335
|
+
chainId,
|
|
336
|
+
owner,
|
|
337
|
+
message: collateralPermit2.message,
|
|
338
|
+
signature: collateralPermit2.signature,
|
|
339
|
+
});
|
|
340
|
+
items.push(permit2Call);
|
|
341
|
+
}
|
|
342
|
+
// 2. Deposit initial collateral if amount > 0
|
|
343
|
+
if (collateralAmount > 0n) {
|
|
344
|
+
// Enable collateral for collateral vault
|
|
345
|
+
if (enableCollateral) {
|
|
346
|
+
items.push(this.encodeEnableCollateral(chainId, receiver, collateralVault));
|
|
347
|
+
}
|
|
348
|
+
// Deposit collateral
|
|
349
|
+
items.push({
|
|
350
|
+
targetContract: collateralVault,
|
|
351
|
+
onBehalfOfAccount: owner,
|
|
352
|
+
value: 0n,
|
|
353
|
+
data: encodeFunctionData({
|
|
354
|
+
abi: eVaultAbi,
|
|
355
|
+
functionName: "deposit",
|
|
356
|
+
args: [collateralAmount, receiver],
|
|
357
|
+
}),
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
// 3. Disable current controller if there's a different one enabled
|
|
361
|
+
if (currentController && currentController !== liabilityVault) {
|
|
362
|
+
items.push(this.encodeDisableController(currentController, receiver));
|
|
363
|
+
}
|
|
364
|
+
// 4. Enable controller for liability vault
|
|
365
|
+
if (enableController) {
|
|
366
|
+
items.push(this.encodeEnableController(chainId, receiver, liabilityVault));
|
|
367
|
+
}
|
|
368
|
+
// 5. Borrow from liability vault to swapper
|
|
369
|
+
items.push({
|
|
370
|
+
targetContract: liabilityVault,
|
|
371
|
+
onBehalfOfAccount: receiver,
|
|
372
|
+
value: 0n,
|
|
373
|
+
data: encodeFunctionData({
|
|
374
|
+
abi: eVaultAbi,
|
|
375
|
+
functionName: "borrow",
|
|
376
|
+
args: [liabilityAmount, swapQuote.swap.swapperAddress],
|
|
377
|
+
}),
|
|
378
|
+
});
|
|
379
|
+
// 6. Execute swap multicall
|
|
380
|
+
items.push({
|
|
381
|
+
targetContract: swapQuote.swap.swapperAddress,
|
|
382
|
+
onBehalfOfAccount: receiver,
|
|
383
|
+
value: 0n,
|
|
384
|
+
data: swapQuote.swap.swapperData,
|
|
385
|
+
});
|
|
386
|
+
// 7. Verify swap and skim to long vault
|
|
387
|
+
if (swapQuote.verify.type !== "skimMin") {
|
|
388
|
+
throw new Error("Invalid swap quote type for multiply - must be skimMin");
|
|
389
|
+
}
|
|
390
|
+
items.push({
|
|
391
|
+
targetContract: swapQuote.verify.verifierAddress,
|
|
392
|
+
onBehalfOfAccount: receiver,
|
|
393
|
+
value: 0n,
|
|
394
|
+
data: swapQuote.verify.verifierData,
|
|
395
|
+
});
|
|
396
|
+
// 8. Enable collateral on long vault
|
|
397
|
+
if (enableCollateralLong && collateralVault !== longVault) {
|
|
398
|
+
items.push(this.encodeEnableCollateral(chainId, receiver, longVault));
|
|
399
|
+
}
|
|
400
|
+
return items;
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Encodes EVC batch items for a multiply/leverage operation when liability and long asset are the same (no swap).
|
|
404
|
+
* Order: optional permit2 → optional deposit + enable collateral → optional disableController → enableController → borrow to longVault → skim → enableCollateral on long vault.
|
|
405
|
+
*
|
|
406
|
+
* @param args - Multiply-same-asset encoding arguments
|
|
407
|
+
* @param args.chainId - Chain ID (used for EVC and permit2)
|
|
408
|
+
* @param args.collateralVault - Vault to deposit initial collateral into (can use 0n to skip)
|
|
409
|
+
* @param args.collateralAmount - Amount of collateral to deposit (0n to skip)
|
|
410
|
+
* @param args.liabilityVault - Vault to borrow from (same asset as longVault)
|
|
411
|
+
* @param args.liabilityAmount - Amount to borrow (sent to longVault)
|
|
412
|
+
* @param args.longVault - Vault that receives the borrowed assets (skim + enable collateral)
|
|
413
|
+
* @param args.owner - Address that owns collateral (onBehalfOfAccount for deposit)
|
|
414
|
+
* @param args.receiver - Sub-account that holds the position
|
|
415
|
+
* @param args.enableCollateral - When depositing collateral, whether to enable it (default true)
|
|
416
|
+
* @param args.enableCollateralLong - Whether to enable long vault as collateral (default true)
|
|
417
|
+
* @param args.currentController - If set and different from liabilityVault, disables it first
|
|
418
|
+
* @param args.enableController - Whether to enable liability vault as controller (default true)
|
|
419
|
+
* @param args.collateralPermit2 - Optional Permit2 data for collateral deposit
|
|
420
|
+
* @returns Array of EVC batch items
|
|
421
|
+
*/
|
|
422
|
+
encodeMultiplySameAsset(args) {
|
|
423
|
+
const { chainId, collateralVault, collateralAmount, liabilityVault, liabilityAmount, longVault, owner, receiver, enableCollateral = true, enableCollateralLong = true, enableController = true, currentController, collateralPermit2, } = args;
|
|
424
|
+
const items = [];
|
|
425
|
+
// 1. Add permit2 for collateral if provided
|
|
426
|
+
if (collateralPermit2) {
|
|
427
|
+
const permit2Call = this.encodePermit2Call({
|
|
428
|
+
chainId,
|
|
429
|
+
owner,
|
|
430
|
+
message: collateralPermit2.message,
|
|
431
|
+
signature: collateralPermit2.signature,
|
|
432
|
+
});
|
|
433
|
+
items.push(permit2Call);
|
|
434
|
+
}
|
|
435
|
+
// 2. Deposit initial collateral if amount > 0
|
|
436
|
+
if (collateralAmount > 0n) {
|
|
437
|
+
// Enable collateral for collateral vault
|
|
438
|
+
if (enableCollateral) {
|
|
439
|
+
items.push(this.encodeEnableCollateral(chainId, receiver, collateralVault));
|
|
440
|
+
}
|
|
441
|
+
// Deposit collateral
|
|
442
|
+
items.push({
|
|
443
|
+
targetContract: collateralVault,
|
|
444
|
+
onBehalfOfAccount: owner,
|
|
445
|
+
value: 0n,
|
|
446
|
+
data: encodeFunctionData({
|
|
447
|
+
abi: eVaultAbi,
|
|
448
|
+
functionName: "deposit",
|
|
449
|
+
args: [collateralAmount, receiver],
|
|
450
|
+
}),
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
// 3. Disable current controller if there's a different one enabled
|
|
454
|
+
if (currentController && currentController !== liabilityVault) {
|
|
455
|
+
items.push(this.encodeDisableController(currentController, receiver));
|
|
456
|
+
}
|
|
457
|
+
// 4. Enable controller for liability vault
|
|
458
|
+
if (enableController) {
|
|
459
|
+
items.push(this.encodeEnableController(chainId, receiver, liabilityVault));
|
|
460
|
+
}
|
|
461
|
+
// 5. Borrow from liability vault directly to long vault
|
|
462
|
+
items.push({
|
|
463
|
+
targetContract: liabilityVault,
|
|
464
|
+
onBehalfOfAccount: receiver,
|
|
465
|
+
value: 0n,
|
|
466
|
+
data: encodeFunctionData({
|
|
467
|
+
abi: eVaultAbi,
|
|
468
|
+
functionName: "borrow",
|
|
469
|
+
args: [liabilityAmount, longVault],
|
|
470
|
+
}),
|
|
471
|
+
});
|
|
472
|
+
// 6. Skim borrowed assets to position
|
|
473
|
+
items.push({
|
|
474
|
+
targetContract: longVault,
|
|
475
|
+
onBehalfOfAccount: receiver,
|
|
476
|
+
value: 0n,
|
|
477
|
+
data: encodeFunctionData({
|
|
478
|
+
abi: eVaultAbi,
|
|
479
|
+
functionName: "skim",
|
|
480
|
+
args: [liabilityAmount, receiver],
|
|
481
|
+
}),
|
|
482
|
+
});
|
|
483
|
+
// 7. Enable collateral on long vault
|
|
484
|
+
if (enableCollateralLong) {
|
|
485
|
+
items.push(this.encodeEnableCollateral(chainId, receiver, longVault));
|
|
486
|
+
}
|
|
487
|
+
return items;
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* Encodes EVC batch items for repaying debt using assets from the sender's wallet (transferFrom to vault then repay).
|
|
491
|
+
*
|
|
492
|
+
* @param args - Repay-from-wallet encoding arguments
|
|
493
|
+
* @param args.chainId - Chain ID (used for permit2 when provided)
|
|
494
|
+
* @param args.sender - Address that sends the liability asset and authorizes the repay (onBehalfOfAccount)
|
|
495
|
+
* @param args.liabilityVault - Vault (liability) to repay debt to
|
|
496
|
+
* @param args.liabilityAmount - Amount to repay (use maxUint256 with isMax for "repay all")
|
|
497
|
+
* @param args.receiver - Sub-account whose debt is repaid
|
|
498
|
+
* @param args.disableControllerOnMax - If true and isMax, appends disableController for receiver on liabilityVault (default true)
|
|
499
|
+
* @param args.isMax - If true, repays max (amount is ignored and maxUint256 is passed to repay)
|
|
500
|
+
* @param args.permit2 - Optional Permit2 message + signature so transferFrom can be used without prior approve
|
|
501
|
+
* @returns Array of EVC batch items (optional permit2, repay, optional disableController)
|
|
502
|
+
*/
|
|
503
|
+
encodeRepayFromWallet(args) {
|
|
504
|
+
const { chainId, sender, liabilityVault, liabilityAmount, receiver, disableControllerOnMax = true, isMax = false, permit2, } = args;
|
|
505
|
+
const items = [];
|
|
506
|
+
if (permit2) {
|
|
507
|
+
const permit2Call = this.encodePermit2Call({
|
|
508
|
+
chainId,
|
|
509
|
+
owner: sender,
|
|
510
|
+
message: permit2.message,
|
|
511
|
+
signature: permit2.signature,
|
|
512
|
+
});
|
|
513
|
+
items.push(permit2Call);
|
|
514
|
+
}
|
|
515
|
+
// Repay operation
|
|
516
|
+
items.push({
|
|
517
|
+
targetContract: liabilityVault,
|
|
518
|
+
onBehalfOfAccount: sender,
|
|
519
|
+
value: 0n,
|
|
520
|
+
data: encodeFunctionData({
|
|
521
|
+
abi: eVaultAbi,
|
|
522
|
+
functionName: "repay",
|
|
523
|
+
args: [isMax ? maxUint256 : liabilityAmount, receiver],
|
|
524
|
+
}),
|
|
525
|
+
});
|
|
526
|
+
// Disable controller if needed (for max repay)
|
|
527
|
+
// Sender must be allowed to act on behalf of receiver (sender is subaccount of receiver or is an operator)
|
|
528
|
+
if (disableControllerOnMax && isMax) {
|
|
529
|
+
items.push(this.encodeDisableController(liabilityVault, receiver));
|
|
530
|
+
}
|
|
531
|
+
return items;
|
|
532
|
+
}
|
|
533
|
+
/**
|
|
534
|
+
* Encodes EVC batch items for repaying debt from a deposit (same-asset only).
|
|
535
|
+
* Path 1: same asset and same vault → repayWithShares. Path 2: same asset, different vault → withdraw then repay/skim/repayWithShares as needed.
|
|
536
|
+
*
|
|
537
|
+
* @param args - Repay-from-deposit encoding arguments
|
|
538
|
+
* @param args.chainId - Chain ID (used for EVC and optional permit2)
|
|
539
|
+
* @param args.liabilityVault - Vault (liability) to repay debt to
|
|
540
|
+
* @param args.liabilityAsset - Underlying asset address of the liability vault
|
|
541
|
+
* @param args.liabilityAmount - Amount of liability to repay (maxUint256 with isMax for full repay)
|
|
542
|
+
* @param args.from - Sub-account address that holds the source deposit (withdraw/shares source)
|
|
543
|
+
* @param args.receiver - Sub-account whose debt is repaid
|
|
544
|
+
* @param args.fromVault - Vault to withdraw/source assets from (must be same asset as liability for this encoder)
|
|
545
|
+
* @param args.fromAsset - Underlying asset of fromVault (must equal liabilityAsset)
|
|
546
|
+
* @param args.disableControllerOnMax - When isMax, whether to disable controller for receiver (default true)
|
|
547
|
+
* @param args.isMax - If true, repays full debt (amount used for withdraw sizing where applicable)
|
|
548
|
+
* @param args.liabilityPermit2 - Optional Permit2 for liability asset when path uses transfer/repay
|
|
549
|
+
* @returns Array of EVC batch items. Throws if fromAsset !== liabilityAsset.
|
|
550
|
+
*/
|
|
551
|
+
encodeRepayFromDeposit(args) {
|
|
552
|
+
const { chainId, liabilityVault, liabilityAsset, liabilityAmount, from, receiver, fromVault, fromAsset, disableControllerOnMax = true, isMax = false, liabilityPermit2, } = args;
|
|
553
|
+
// PATH 1: Same asset, same vault - use repayWithShares
|
|
554
|
+
if (fromAsset === liabilityAsset && fromVault === liabilityVault) {
|
|
555
|
+
return this.encodeRepayWithSharesSameAssetAndVault({
|
|
556
|
+
chainId,
|
|
557
|
+
vault: liabilityVault,
|
|
558
|
+
amount: liabilityAmount,
|
|
559
|
+
receiver,
|
|
560
|
+
from,
|
|
561
|
+
disableController: isMax && disableControllerOnMax,
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
// PATH 2: Same asset, different vault
|
|
565
|
+
if (fromAsset === liabilityAsset) {
|
|
566
|
+
return this.encodeRepayWithSharesSameAssetDifferentVault({
|
|
567
|
+
chainId,
|
|
568
|
+
fromVault,
|
|
569
|
+
toVault: liabilityVault,
|
|
570
|
+
amount: liabilityAmount,
|
|
571
|
+
receiver,
|
|
572
|
+
from,
|
|
573
|
+
isMax,
|
|
574
|
+
disableControllerOnMax,
|
|
575
|
+
permit2: liabilityPermit2,
|
|
576
|
+
});
|
|
577
|
+
}
|
|
578
|
+
throw new Error("encodeRepayFromDeposit only supports same-asset paths");
|
|
579
|
+
}
|
|
580
|
+
/**
|
|
581
|
+
* Encodes EVC batch items for repaying debt by swapping collateral (withdraw from vaultIn → swap → verify/repay debtMax).
|
|
582
|
+
* Swap quote must come from swapService.fetchRepayQuotes() or match the same structure (verify type debtMax).
|
|
583
|
+
*
|
|
584
|
+
* @param args - Repay-with-swap encoding arguments
|
|
585
|
+
* @param args.chainId - Chain ID (used for EVC disableController when applicable)
|
|
586
|
+
* @param args.swapQuote - Quote with vaultIn, accountIn, accountOut, receiver, swap and verify (debtMax) steps
|
|
587
|
+
* @param args.maxWithdraw - Optional cap on withdraw amount (e.g. available collateral); if less than quote amountInMax, that value is used
|
|
588
|
+
* @param args.isMax - If true, disables controller on max repay when disableControllerOnMax is true (default true)
|
|
589
|
+
* @param args.disableControllerOnMax - When isMax, whether to append disableController for accountOut on receiver (default true)
|
|
590
|
+
* @returns Array of EVC batch items (withdraw, swap, verify/repay, optional disableController)
|
|
591
|
+
*/
|
|
592
|
+
encodeRepayWithSwap(args) {
|
|
593
|
+
const { swapQuote, maxWithdraw, isMax = false, disableControllerOnMax = true, } = args;
|
|
594
|
+
const items = [];
|
|
595
|
+
// Determine withdraw amount (cap to available amount if provided)
|
|
596
|
+
const withdrawAmount = maxWithdraw &&
|
|
597
|
+
maxWithdraw < BigInt(swapQuote.amountInMax || swapQuote.amountIn)
|
|
598
|
+
? maxWithdraw
|
|
599
|
+
: BigInt(swapQuote.amountInMax || swapQuote.amountIn);
|
|
600
|
+
// 1. Withdraw collateral from vault to swapper
|
|
601
|
+
items.push({
|
|
602
|
+
targetContract: swapQuote.vaultIn,
|
|
603
|
+
onBehalfOfAccount: swapQuote.accountIn,
|
|
604
|
+
value: 0n,
|
|
605
|
+
data: encodeFunctionData({
|
|
606
|
+
abi: eVaultAbi,
|
|
607
|
+
functionName: "withdraw",
|
|
608
|
+
args: [
|
|
609
|
+
withdrawAmount,
|
|
610
|
+
swapQuote.swap.swapperAddress,
|
|
611
|
+
swapQuote.accountIn,
|
|
612
|
+
],
|
|
613
|
+
}),
|
|
614
|
+
});
|
|
615
|
+
// 2. Execute swap multicall
|
|
616
|
+
items.push({
|
|
617
|
+
targetContract: swapQuote.swap.swapperAddress,
|
|
618
|
+
onBehalfOfAccount: swapQuote.accountIn,
|
|
619
|
+
value: 0n,
|
|
620
|
+
data: swapQuote.swap.swapperData,
|
|
621
|
+
});
|
|
622
|
+
// 3. Verify swap and repay (verifyDebtMax handles the repay)
|
|
623
|
+
if (swapQuote.verify.type !== "debtMax") {
|
|
624
|
+
throw new Error("Invalid swap quote type for repay - must be debtMax");
|
|
625
|
+
}
|
|
626
|
+
items.push({
|
|
627
|
+
targetContract: swapQuote.verify.verifierAddress,
|
|
628
|
+
onBehalfOfAccount: swapQuote.verify.account,
|
|
629
|
+
value: 0n,
|
|
630
|
+
data: swapQuote.verify.verifierData,
|
|
631
|
+
});
|
|
632
|
+
// 4. Disable controller if needed (for max repay)
|
|
633
|
+
if (isMax && disableControllerOnMax) {
|
|
634
|
+
items.push(this.encodeDisableController(swapQuote.receiver, swapQuote.accountOut));
|
|
635
|
+
}
|
|
636
|
+
return items;
|
|
637
|
+
}
|
|
638
|
+
/**
|
|
639
|
+
* Encodes EVC batch items for depositing into a vault using tokens from the user's wallet, going through a swap.
|
|
640
|
+
* The approval is given to SwapVerifier, then transferFromSender pulls tokens to Swapper, swap executes, and output is deposited.
|
|
641
|
+
*
|
|
642
|
+
* @param args - Deposit-with-swap-from-wallet encoding arguments
|
|
643
|
+
* @param args.chainId - Chain ID (used for EVC and deployment addresses)
|
|
644
|
+
* @param args.swapQuote - Quote with swap and verify steps (verify type skimMin or transferMin)
|
|
645
|
+
* @param args.amount - Amount of input token to transfer from wallet to swapper
|
|
646
|
+
* @param args.sender - Wallet address providing the tokens (onBehalfOfAccount for transferFromSender)
|
|
647
|
+
* @param args.enableCollateral - If true, enables receiver vault as collateral for accountOut (default true)
|
|
648
|
+
* @returns Array of EVC batch items (transferFromSender, swap, verify, optional enableCollateral)
|
|
649
|
+
*/
|
|
650
|
+
encodeDepositWithSwapFromWallet(args) {
|
|
651
|
+
const { chainId, swapQuote, amount, sender, enableCollateral = true, } = args;
|
|
652
|
+
const items = [];
|
|
653
|
+
// 1. Transfer tokens from sender's wallet to swapper via SwapVerifier.transferFromSender
|
|
654
|
+
items.push({
|
|
655
|
+
targetContract: swapQuote.verify.verifierAddress,
|
|
656
|
+
onBehalfOfAccount: sender,
|
|
657
|
+
value: 0n,
|
|
658
|
+
data: encodeFunctionData({
|
|
659
|
+
abi: swapVerifierAbi,
|
|
660
|
+
functionName: "transferFromSender",
|
|
661
|
+
args: [
|
|
662
|
+
swapQuote.tokenIn.address,
|
|
663
|
+
amount,
|
|
664
|
+
swapQuote.swap.swapperAddress,
|
|
665
|
+
],
|
|
666
|
+
}),
|
|
667
|
+
});
|
|
668
|
+
// 2. Execute swap multicall
|
|
669
|
+
items.push({
|
|
670
|
+
targetContract: swapQuote.swap.swapperAddress,
|
|
671
|
+
onBehalfOfAccount: sender,
|
|
672
|
+
value: 0n,
|
|
673
|
+
data: swapQuote.swap.swapperData,
|
|
674
|
+
});
|
|
675
|
+
// 3. Verify swap
|
|
676
|
+
items.push({
|
|
677
|
+
targetContract: swapQuote.verify.verifierAddress,
|
|
678
|
+
onBehalfOfAccount: swapQuote.accountOut || sender,
|
|
679
|
+
value: 0n,
|
|
680
|
+
data: swapQuote.verify.verifierData,
|
|
681
|
+
});
|
|
682
|
+
// 4. Enable collateral if needed
|
|
683
|
+
if (enableCollateral && swapQuote.receiver) {
|
|
684
|
+
items.push(this.encodeEnableCollateral(chainId, swapQuote.accountOut || sender, swapQuote.receiver));
|
|
685
|
+
}
|
|
686
|
+
return items;
|
|
687
|
+
}
|
|
688
|
+
/**
|
|
689
|
+
* Encodes EVC batch items for swapping collateral: withdraw from vaultIn → swap → verify/skim to receiver; optional enable/disable collateral.
|
|
690
|
+
* Swap quote should come from swapService.fetchDepositQuote() or match the same structure (verify type skimMin).
|
|
691
|
+
*
|
|
692
|
+
* @param args - Swap-collateral encoding arguments
|
|
693
|
+
* @param args.chainId - Chain ID (used for EVC enableCollateral/disableCollateral)
|
|
694
|
+
* @param args.swapQuote - Quote with vaultIn, accountIn, accountOut, receiver, swap and verify (skimMin) steps
|
|
695
|
+
* @param args.enableCollateral - If true, enables receiver vault as collateral for accountOut (default true)
|
|
696
|
+
* @param args.disableCollateralOnMax - When isMax, whether to disable collateral for accountIn on vaultIn (default true)
|
|
697
|
+
* @param args.isMax - If true, treats as full swap (can trigger disableCollateralOnMax)
|
|
698
|
+
* @returns Array of EVC batch items (withdraw, swap, verify/skim, optional disableCollateral, optional enableCollateral)
|
|
699
|
+
*/
|
|
700
|
+
encodeSwapCollateral(args) {
|
|
701
|
+
const { chainId, swapQuote, enableCollateral = true, disableCollateralOnMax = true, isMax = false, } = args;
|
|
702
|
+
const items = [];
|
|
703
|
+
// 1. Withdraw from source vault to swapper
|
|
704
|
+
const withdrawAmount = BigInt(swapQuote.amountInMax || swapQuote.amountIn);
|
|
705
|
+
items.push({
|
|
706
|
+
targetContract: swapQuote.vaultIn,
|
|
707
|
+
onBehalfOfAccount: swapQuote.accountIn,
|
|
708
|
+
value: 0n,
|
|
709
|
+
data: encodeFunctionData({
|
|
710
|
+
abi: eVaultAbi,
|
|
711
|
+
functionName: "withdraw",
|
|
712
|
+
args: [
|
|
713
|
+
withdrawAmount,
|
|
714
|
+
swapQuote.swap.swapperAddress,
|
|
715
|
+
swapQuote.accountIn,
|
|
716
|
+
],
|
|
717
|
+
}),
|
|
718
|
+
});
|
|
719
|
+
// 2. Execute swap multicall
|
|
720
|
+
items.push({
|
|
721
|
+
targetContract: swapQuote.swap.swapperAddress,
|
|
722
|
+
onBehalfOfAccount: swapQuote.accountIn,
|
|
723
|
+
value: 0n,
|
|
724
|
+
data: swapQuote.swap.swapperData,
|
|
725
|
+
});
|
|
726
|
+
// 3. Verify swap and skim
|
|
727
|
+
if (swapQuote.verify.type !== "skimMin") {
|
|
728
|
+
throw new Error("Invalid swap quote type for swap collateral - must be skimMin");
|
|
729
|
+
}
|
|
730
|
+
items.push({
|
|
731
|
+
targetContract: swapQuote.verify.verifierAddress,
|
|
732
|
+
onBehalfOfAccount: swapQuote.accountOut,
|
|
733
|
+
value: 0n,
|
|
734
|
+
data: swapQuote.verify.verifierData,
|
|
735
|
+
});
|
|
736
|
+
// 4. Disable collateral if needed (for max swap)
|
|
737
|
+
if (isMax && disableCollateralOnMax) {
|
|
738
|
+
items.push(this.encodeDisableCollateral(chainId, swapQuote.accountIn, swapQuote.vaultIn));
|
|
739
|
+
}
|
|
740
|
+
// 5. Enable collateral if needed
|
|
741
|
+
if (enableCollateral) {
|
|
742
|
+
items.push(this.encodeEnableCollateral(chainId, swapQuote.accountOut, swapQuote.receiver));
|
|
743
|
+
}
|
|
744
|
+
return items;
|
|
745
|
+
}
|
|
746
|
+
/**
|
|
747
|
+
* Encodes EVC batch items for swapping debt: enableController → borrow from vaultIn → swap → verify/repay (debtMax).
|
|
748
|
+
* Swap quote should come from swapService.fetchRepayQuotes() or match the same structure (verify type debtMax).
|
|
749
|
+
*
|
|
750
|
+
* @param args - Swap-debt encoding arguments
|
|
751
|
+
* @param args.chainId - Chain ID (used for EVC enableController/disableController)
|
|
752
|
+
* @param args.swapQuote - Quote with vaultIn, accountIn, accountOut, receiver, swap and verify (debtMax) steps
|
|
753
|
+
* @param args.enableController - If true, enables vaultIn as controller for accountOut before borrow (default true)
|
|
754
|
+
* @param args.disableControllerOnMax - When isMax, whether to disable controller for accountIn on receiver (default true)
|
|
755
|
+
* @param args.isMax - If true, treats as full debt swap (can trigger disableControllerOnMax)
|
|
756
|
+
* @returns Array of EVC batch items (optional enableController, borrow, swap, verify/repay, optional disableController)
|
|
757
|
+
*/
|
|
758
|
+
encodeSwapDebt({ chainId, swapQuote, enableController = true, disableControllerOnMax = true, isMax = false, }) {
|
|
759
|
+
const items = [];
|
|
760
|
+
// Enable controller if needed
|
|
761
|
+
if (enableController) {
|
|
762
|
+
items.push(this.encodeEnableController(chainId, swapQuote.accountOut, swapQuote.vaultIn));
|
|
763
|
+
}
|
|
764
|
+
// Borrow from source vault
|
|
765
|
+
const borrowAmount = BigInt(swapQuote.amountInMax);
|
|
766
|
+
items.push({
|
|
767
|
+
targetContract: swapQuote.vaultIn,
|
|
768
|
+
onBehalfOfAccount: swapQuote.accountIn,
|
|
769
|
+
value: 0n,
|
|
770
|
+
data: encodeFunctionData({
|
|
771
|
+
abi: eVaultAbi,
|
|
772
|
+
functionName: "borrow",
|
|
773
|
+
args: [borrowAmount, swapQuote.swap.swapperAddress],
|
|
774
|
+
}),
|
|
775
|
+
});
|
|
776
|
+
// Execute swap multicall
|
|
777
|
+
items.push({
|
|
778
|
+
targetContract: swapQuote.swap.swapperAddress,
|
|
779
|
+
onBehalfOfAccount: swapQuote.accountIn,
|
|
780
|
+
value: 0n,
|
|
781
|
+
data: swapQuote.swap.swapperData,
|
|
782
|
+
});
|
|
783
|
+
// Verify swap and skim
|
|
784
|
+
if (swapQuote.verify.type !== "debtMax") {
|
|
785
|
+
throw new Error("Invalid swap quote type for repay - must be debtMax");
|
|
786
|
+
}
|
|
787
|
+
items.push({
|
|
788
|
+
targetContract: swapQuote.verify.verifierAddress,
|
|
789
|
+
onBehalfOfAccount: swapQuote.accountOut,
|
|
790
|
+
value: 0n,
|
|
791
|
+
data: swapQuote.verify.verifierData,
|
|
792
|
+
});
|
|
793
|
+
// Disable controller if needed (for max swap)
|
|
794
|
+
if (isMax && disableControllerOnMax) {
|
|
795
|
+
items.push(this.encodeDisableController(swapQuote.receiver, swapQuote.accountIn));
|
|
796
|
+
}
|
|
797
|
+
return items;
|
|
798
|
+
}
|
|
799
|
+
/**
|
|
800
|
+
* Encodes EVC batch items for transferring vault shares between sub-accounts.
|
|
801
|
+
*
|
|
802
|
+
* @param args - Transfer encoding arguments
|
|
803
|
+
* @param args.chainId - Chain ID (used for EVC when enabling/disabling collateral)
|
|
804
|
+
* @param args.vault - Address of the vault
|
|
805
|
+
* @param args.from - Sub-account address sending the shares (onBehalfOfAccount)
|
|
806
|
+
* @param args.to - Sub-account address receiving the shares
|
|
807
|
+
* @param args.amount - Amount of vault shares to transfer
|
|
808
|
+
* @param args.enableCollateralTo - If true, appends enableCollateral( to, vault ) via EVC after transfer
|
|
809
|
+
* @param args.disableCollateralFrom - If true, prepends disableCollateral( from, vault ) via EVC before transfer
|
|
810
|
+
* @returns Array of EVC batch items (optional disableCollateralFrom, transfer, optional enableCollateralTo)
|
|
811
|
+
*/
|
|
812
|
+
encodeTransfer({ chainId, vault, to, amount, from, enableCollateralTo, disableCollateralFrom, }) {
|
|
813
|
+
const items = [];
|
|
814
|
+
// Add disable collateral from sender if flag is set
|
|
815
|
+
if (disableCollateralFrom) {
|
|
816
|
+
items.push(this.encodeDisableCollateral(chainId, from, vault));
|
|
817
|
+
}
|
|
818
|
+
// Add transfer operation
|
|
819
|
+
items.push({
|
|
820
|
+
targetContract: vault,
|
|
821
|
+
onBehalfOfAccount: from,
|
|
822
|
+
value: 0n,
|
|
823
|
+
data: encodeFunctionData({
|
|
824
|
+
abi: eVaultAbi,
|
|
825
|
+
functionName: "transfer",
|
|
826
|
+
args: [to, amount],
|
|
827
|
+
}),
|
|
828
|
+
});
|
|
829
|
+
// Add enable collateral to receiver if flag is set
|
|
830
|
+
if (enableCollateralTo) {
|
|
831
|
+
items.push(this.encodeEnableCollateral(chainId, to, vault));
|
|
832
|
+
}
|
|
833
|
+
return items;
|
|
834
|
+
}
|
|
835
|
+
/**
|
|
836
|
+
* Encodes a single EVC batch item that calls Permit2's `permit` with the given message and signature.
|
|
837
|
+
* Used to authorize a token transfer for a subsequent contract call in the same batch.
|
|
838
|
+
*
|
|
839
|
+
* @param args - Permit2 call encoding arguments
|
|
840
|
+
* @param args.chainId - Chain ID (used to resolve Permit2 contract address)
|
|
841
|
+
* @param args.owner - Token owner that signed the permit (onBehalfOfAccount)
|
|
842
|
+
* @param args.message - Permit2 PermitSingle message (details + spender + sigDeadline)
|
|
843
|
+
* @param args.signature - Signature over the permit message
|
|
844
|
+
* @returns Single EVC batch item (targetContract = Permit2, permit call)
|
|
845
|
+
*/
|
|
846
|
+
encodePermit2Call(args) {
|
|
847
|
+
const { chainId, owner, message, signature } = args;
|
|
848
|
+
const deployment = this.deploymentService.getDeployment(chainId);
|
|
849
|
+
const permit2 = deployment.addresses.coreAddrs.permit2;
|
|
850
|
+
return {
|
|
851
|
+
targetContract: permit2,
|
|
852
|
+
onBehalfOfAccount: owner,
|
|
853
|
+
value: 0n,
|
|
854
|
+
data: encodeFunctionData({
|
|
855
|
+
abi: permit2PermitAbi,
|
|
856
|
+
functionName: "permit",
|
|
857
|
+
args: [owner, message, signature],
|
|
858
|
+
}),
|
|
859
|
+
};
|
|
860
|
+
}
|
|
861
|
+
encodeEnableCollateral(chainId, account, vault) {
|
|
862
|
+
const deployment = this.deploymentService.getDeployment(chainId);
|
|
863
|
+
const evc = deployment.addresses.coreAddrs.evc;
|
|
864
|
+
return {
|
|
865
|
+
targetContract: evc,
|
|
866
|
+
onBehalfOfAccount: zeroAddress,
|
|
867
|
+
value: 0n,
|
|
868
|
+
data: encodeFunctionData({
|
|
869
|
+
abi: ethereumVaultConnectorAbi,
|
|
870
|
+
functionName: "enableCollateral",
|
|
871
|
+
args: [account, vault],
|
|
872
|
+
}),
|
|
873
|
+
};
|
|
874
|
+
}
|
|
875
|
+
encodeDisableCollateral(chainId, account, vault) {
|
|
876
|
+
const deployment = this.deploymentService.getDeployment(chainId);
|
|
877
|
+
const evc = deployment.addresses.coreAddrs.evc;
|
|
878
|
+
return {
|
|
879
|
+
targetContract: evc,
|
|
880
|
+
onBehalfOfAccount: zeroAddress,
|
|
881
|
+
value: 0n,
|
|
882
|
+
data: encodeFunctionData({
|
|
883
|
+
abi: ethereumVaultConnectorAbi,
|
|
884
|
+
functionName: "disableCollateral",
|
|
885
|
+
args: [account, vault],
|
|
886
|
+
}),
|
|
887
|
+
};
|
|
888
|
+
}
|
|
889
|
+
encodeEnableController(chainId, account, vault) {
|
|
890
|
+
const deployment = this.deploymentService.getDeployment(chainId);
|
|
891
|
+
const evc = deployment.addresses.coreAddrs.evc;
|
|
892
|
+
return {
|
|
893
|
+
targetContract: evc,
|
|
894
|
+
onBehalfOfAccount: zeroAddress,
|
|
895
|
+
value: 0n,
|
|
896
|
+
data: encodeFunctionData({
|
|
897
|
+
abi: ethereumVaultConnectorAbi,
|
|
898
|
+
functionName: "enableController",
|
|
899
|
+
args: [account, vault],
|
|
900
|
+
}),
|
|
901
|
+
};
|
|
902
|
+
}
|
|
903
|
+
encodeDisableController(vault, account) {
|
|
904
|
+
return {
|
|
905
|
+
targetContract: vault,
|
|
906
|
+
onBehalfOfAccount: account,
|
|
907
|
+
value: 0n,
|
|
908
|
+
data: encodeFunctionData({
|
|
909
|
+
abi: eVaultAbi,
|
|
910
|
+
functionName: "disableController",
|
|
911
|
+
args: [],
|
|
912
|
+
}),
|
|
913
|
+
};
|
|
914
|
+
}
|
|
915
|
+
/**
|
|
916
|
+
* Builds EIP-712 typed data for a Permit2 PermitSingle signature (token approval for a spender).
|
|
917
|
+
* Use with signTypedData (e.g. wagmi) then pass the signed message to encodePermit2Call or plan flows.
|
|
918
|
+
*
|
|
919
|
+
* @param args - Permit2 typed data arguments
|
|
920
|
+
* @param args.chainId - Chain ID (used to resolve Permit2 contract for domain)
|
|
921
|
+
* @param args.token - Token address to approve
|
|
922
|
+
* @param args.amount - Amount to approve (capped to maxUint160 in the message if larger)
|
|
923
|
+
* @param args.spender - Address that will be allowed to transfer the token (e.g. vault or Permit2)
|
|
924
|
+
* @param args.nonce - Unique nonce for this permit (e.g. from Permit2 nonce(owner, token, spender))
|
|
925
|
+
* @param args.sigDeadline - Signature deadline (defaults to now + 1 hour if omitted)
|
|
926
|
+
* @param args.expiration - Permit expiration (defaults to maxUint48 if omitted)
|
|
927
|
+
* @returns EIP-712 typed data (domain, types, primaryType, message) for signing
|
|
928
|
+
*/
|
|
929
|
+
getPermit2TypedData(args) {
|
|
930
|
+
const nowInSeconds = () => BigInt(Math.floor(Date.now() / 1000));
|
|
931
|
+
const { chainId, token, amount, spender, nonce, sigDeadline, expiration } = args;
|
|
932
|
+
const deployment = this.deploymentService.getDeployment(chainId);
|
|
933
|
+
const permit2 = deployment.addresses.coreAddrs.permit2;
|
|
934
|
+
const permitSingle = {
|
|
935
|
+
details: {
|
|
936
|
+
token,
|
|
937
|
+
amount: amount > maxUint160 ? maxUint160 : amount,
|
|
938
|
+
expiration: expiration ?? Number(maxUint48),
|
|
939
|
+
nonce,
|
|
940
|
+
},
|
|
941
|
+
spender,
|
|
942
|
+
sigDeadline: sigDeadline ?? nowInSeconds() + PERMIT2_SIG_WINDOW,
|
|
943
|
+
};
|
|
944
|
+
return {
|
|
945
|
+
domain: {
|
|
946
|
+
name: "Permit2",
|
|
947
|
+
chainId,
|
|
948
|
+
verifyingContract: permit2,
|
|
949
|
+
},
|
|
950
|
+
types: PERMIT2_TYPES,
|
|
951
|
+
primaryType: "PermitSingle",
|
|
952
|
+
message: permitSingle,
|
|
953
|
+
};
|
|
954
|
+
}
|
|
955
|
+
/**
|
|
956
|
+
* Decodes EVC batch items into human-readable function names and named arguments.
|
|
957
|
+
* Tries known ABIs (EVC, eVault, Permit2, swapper, swapVerifier) to decode each item's data.
|
|
958
|
+
*
|
|
959
|
+
* @param batch - Array of EVC batch items (targetContract, onBehalfOfAccount, value, data) to decode
|
|
960
|
+
* @param extraAbis - Optional extra ABIs to try first when decoding unknown batch items.
|
|
961
|
+
* @returns Array of decoded items with targetContract, onBehalfOfAccount, functionName, and args (record of param name to value). Throws if any item cannot be decoded.
|
|
962
|
+
* @example
|
|
963
|
+
* const batchItems = executionService.encodeDeposit({ ... });
|
|
964
|
+
* const described = executionService.describeBatch(batchItems);
|
|
965
|
+
* console.log(described[0].functionName); // "deposit"
|
|
966
|
+
* console.log(described[0].args); // { amount: 1000n, receiver: "0x..." }
|
|
967
|
+
*/
|
|
968
|
+
describeBatch(batch, extraAbis) {
|
|
969
|
+
const decodedBatchItems = [];
|
|
970
|
+
const executionDecodeAbis = [
|
|
971
|
+
...(extraAbis ?? []),
|
|
972
|
+
ethereumVaultConnectorAbi,
|
|
973
|
+
eVaultAbi,
|
|
974
|
+
permit2PermitAbi,
|
|
975
|
+
swapperAbi,
|
|
976
|
+
swapVerifierAbi,
|
|
977
|
+
];
|
|
978
|
+
for (const item of batch) {
|
|
979
|
+
let decoded = false;
|
|
980
|
+
for (const abi of executionDecodeAbis) {
|
|
981
|
+
try {
|
|
982
|
+
const decodedData = decodeFunctionData({
|
|
983
|
+
abi: abi,
|
|
984
|
+
data: item.data,
|
|
985
|
+
});
|
|
986
|
+
// Convert args array to named object
|
|
987
|
+
const functionAbi = abi.find((abiItem) => abiItem.type === "function" &&
|
|
988
|
+
abiItem.name === decodedData.functionName);
|
|
989
|
+
if (!functionAbi || functionAbi.type !== "function") {
|
|
990
|
+
continue;
|
|
991
|
+
}
|
|
992
|
+
// Create named arguments object
|
|
993
|
+
const namedArgs = {};
|
|
994
|
+
if (functionAbi.inputs &&
|
|
995
|
+
Array.isArray(decodedData.args) &&
|
|
996
|
+
decodedData.args.length > 0) {
|
|
997
|
+
functionAbi.inputs.forEach((input, index) => {
|
|
998
|
+
if (input.name) {
|
|
999
|
+
namedArgs[input.name] = decodedData.args?.[index];
|
|
1000
|
+
}
|
|
1001
|
+
});
|
|
1002
|
+
}
|
|
1003
|
+
decodedBatchItems.push({
|
|
1004
|
+
targetContract: item.targetContract,
|
|
1005
|
+
onBehalfOfAccount: item.onBehalfOfAccount,
|
|
1006
|
+
functionName: decodedData.functionName,
|
|
1007
|
+
args: namedArgs,
|
|
1008
|
+
});
|
|
1009
|
+
decoded = true;
|
|
1010
|
+
break;
|
|
1011
|
+
}
|
|
1012
|
+
catch { }
|
|
1013
|
+
}
|
|
1014
|
+
// Fall back to plugins
|
|
1015
|
+
if (!decoded) {
|
|
1016
|
+
for (const plugin of this.plugins) {
|
|
1017
|
+
if (!plugin.decodeBatchItem)
|
|
1018
|
+
continue;
|
|
1019
|
+
try {
|
|
1020
|
+
const result = plugin.decodeBatchItem(item);
|
|
1021
|
+
if (result) {
|
|
1022
|
+
decodedBatchItems.push(result);
|
|
1023
|
+
decoded = true;
|
|
1024
|
+
break;
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
catch { }
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
if (!decoded) {
|
|
1031
|
+
decodedBatchItems.push({
|
|
1032
|
+
targetContract: item.targetContract,
|
|
1033
|
+
onBehalfOfAccount: item.onBehalfOfAccount,
|
|
1034
|
+
functionName: "Unknown",
|
|
1035
|
+
args: {},
|
|
1036
|
+
});
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
return decodedBatchItems;
|
|
1040
|
+
}
|
|
1041
|
+
/**
|
|
1042
|
+
* Merges multiple transaction plans into a single plan.
|
|
1043
|
+
* Required approvals for the same (token, owner, spender) are summed.
|
|
1044
|
+
* Executable items are preserved in order; adjacent EVC batch items are concatenated.
|
|
1045
|
+
* Can be used to construct a transaction queue.
|
|
1046
|
+
*
|
|
1047
|
+
* @param plans - Array of transaction plans to merge
|
|
1048
|
+
* @returns Single plan: summed required approvals first, followed by executable items in order
|
|
1049
|
+
*/
|
|
1050
|
+
mergePlans(plans) {
|
|
1051
|
+
const approvalByKey = new Map();
|
|
1052
|
+
const executableItems = [];
|
|
1053
|
+
for (const plan of plans) {
|
|
1054
|
+
for (const item of plan) {
|
|
1055
|
+
if (item.type === "requiredApproval") {
|
|
1056
|
+
const key = `${getAddress(item.token)}:${getAddress(item.owner)}:${getAddress(item.spender)}`;
|
|
1057
|
+
const existing = approvalByKey.get(key);
|
|
1058
|
+
if (existing) {
|
|
1059
|
+
existing.amount += item.amount;
|
|
1060
|
+
existing.resolved = undefined;
|
|
1061
|
+
}
|
|
1062
|
+
else {
|
|
1063
|
+
const { resolved: _r, ...rest } = item;
|
|
1064
|
+
approvalByKey.set(key, { ...rest, resolved: undefined });
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
else if (item.type === "evcBatch") {
|
|
1068
|
+
const previous = executableItems[executableItems.length - 1];
|
|
1069
|
+
if (previous?.type === "evcBatch") {
|
|
1070
|
+
previous.items.push(...item.items);
|
|
1071
|
+
}
|
|
1072
|
+
else {
|
|
1073
|
+
executableItems.push({ type: "evcBatch", items: [...item.items] });
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
else {
|
|
1077
|
+
executableItems.push(item);
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
return [...approvalByKey.values(), ...executableItems];
|
|
1082
|
+
}
|
|
1083
|
+
/**
|
|
1084
|
+
* Converts EVC batch items into a transaction plan.
|
|
1085
|
+
* Returns a plan with a single evcBatch containing the given items (no required approvals).
|
|
1086
|
+
* Returns an empty plan if items is empty.
|
|
1087
|
+
*
|
|
1088
|
+
* @param items - EVC batch items to wrap in a plan
|
|
1089
|
+
* @returns Transaction plan containing one evcBatch with the items
|
|
1090
|
+
*/
|
|
1091
|
+
convertBatchItemsToPlan(items) {
|
|
1092
|
+
if (items.length === 0)
|
|
1093
|
+
return [];
|
|
1094
|
+
return [{ type: "evcBatch", items }];
|
|
1095
|
+
}
|
|
1096
|
+
/**
|
|
1097
|
+
* Encodes batch items for repaying with shares from the same asset and vault
|
|
1098
|
+
*/
|
|
1099
|
+
encodeRepayWithSharesSameAssetAndVault({ chainId: _chainId, vault, amount, from, receiver, disableController, }) {
|
|
1100
|
+
const items = [];
|
|
1101
|
+
// Repay with shares
|
|
1102
|
+
items.push({
|
|
1103
|
+
targetContract: vault,
|
|
1104
|
+
onBehalfOfAccount: from,
|
|
1105
|
+
value: 0n,
|
|
1106
|
+
data: encodeFunctionData({
|
|
1107
|
+
abi: eVaultAbi,
|
|
1108
|
+
functionName: "repayWithShares",
|
|
1109
|
+
args: [amount, receiver],
|
|
1110
|
+
}),
|
|
1111
|
+
});
|
|
1112
|
+
// Disable controller if needed (for max repay)
|
|
1113
|
+
if (disableController) {
|
|
1114
|
+
items.push(this.encodeDisableController(vault, receiver));
|
|
1115
|
+
}
|
|
1116
|
+
return items;
|
|
1117
|
+
}
|
|
1118
|
+
/**
|
|
1119
|
+
* Encodes batch items for repaying with shares from same asset but different vault
|
|
1120
|
+
*/
|
|
1121
|
+
encodeRepayWithSharesSameAssetDifferentVault({ chainId, fromVault, toVault, amount, // if isMax, this should be the total current debt
|
|
1122
|
+
receiver, from, isMax, disableControllerOnMax, permit2, }) {
|
|
1123
|
+
const items = [];
|
|
1124
|
+
if (isMax) {
|
|
1125
|
+
// if amount was max uint, skim and repay with shares would not revert if after withdraw funds were skimmed
|
|
1126
|
+
// by other party
|
|
1127
|
+
if (amount == maxUint256) {
|
|
1128
|
+
throw new Error("Amount is maxUint256, cannot be used for max repay");
|
|
1129
|
+
}
|
|
1130
|
+
// For max repay: withdraw full debt amount +1 BPS to cover interest, then skim, then repayWithShares max
|
|
1131
|
+
const amountWithExtra = (amount * 10001n) / 10000n;
|
|
1132
|
+
if (amountWithExtra >= maxUint256) {
|
|
1133
|
+
throw new Error("Amount with extra exceeds maxUint256");
|
|
1134
|
+
}
|
|
1135
|
+
// 1. Withdraw from collateral vault
|
|
1136
|
+
items.push({
|
|
1137
|
+
targetContract: fromVault,
|
|
1138
|
+
onBehalfOfAccount: from,
|
|
1139
|
+
value: 0n,
|
|
1140
|
+
data: encodeFunctionData({
|
|
1141
|
+
abi: eVaultAbi,
|
|
1142
|
+
functionName: "withdraw",
|
|
1143
|
+
args: [amountWithExtra, toVault, from],
|
|
1144
|
+
}),
|
|
1145
|
+
});
|
|
1146
|
+
// 2. Skim exact withdrawal amount to liability vault
|
|
1147
|
+
items.push({
|
|
1148
|
+
targetContract: toVault,
|
|
1149
|
+
onBehalfOfAccount: from,
|
|
1150
|
+
value: 0n,
|
|
1151
|
+
data: encodeFunctionData({
|
|
1152
|
+
abi: eVaultAbi,
|
|
1153
|
+
functionName: "skim",
|
|
1154
|
+
args: [amountWithExtra, receiver],
|
|
1155
|
+
}),
|
|
1156
|
+
});
|
|
1157
|
+
// 3. Repay with shares (max)
|
|
1158
|
+
items.push({
|
|
1159
|
+
targetContract: toVault,
|
|
1160
|
+
onBehalfOfAccount: receiver,
|
|
1161
|
+
value: 0n,
|
|
1162
|
+
data: encodeFunctionData({
|
|
1163
|
+
abi: eVaultAbi,
|
|
1164
|
+
functionName: "repayWithShares",
|
|
1165
|
+
// max is ok now, because skim deposited exact amount and it is the full debt,
|
|
1166
|
+
// so pre-existing balance will not be consumed
|
|
1167
|
+
args: [maxUint256, receiver],
|
|
1168
|
+
}),
|
|
1169
|
+
});
|
|
1170
|
+
// 4. Disable controller if needed
|
|
1171
|
+
if (disableControllerOnMax) {
|
|
1172
|
+
items.push(this.encodeDisableController(toVault, receiver));
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
else {
|
|
1176
|
+
// For partial repay: withdraw, then repay exact amount
|
|
1177
|
+
// 1. Withdraw from collateral vault
|
|
1178
|
+
items.push({
|
|
1179
|
+
targetContract: fromVault,
|
|
1180
|
+
onBehalfOfAccount: from,
|
|
1181
|
+
value: 0n,
|
|
1182
|
+
data: encodeFunctionData({
|
|
1183
|
+
abi: eVaultAbi,
|
|
1184
|
+
functionName: "withdraw",
|
|
1185
|
+
args: [amount, from, from],
|
|
1186
|
+
}),
|
|
1187
|
+
});
|
|
1188
|
+
// 2. Repay exact amount
|
|
1189
|
+
const repayItems = this.encodeRepayFromWallet({
|
|
1190
|
+
chainId,
|
|
1191
|
+
sender: from,
|
|
1192
|
+
liabilityVault: toVault,
|
|
1193
|
+
liabilityAmount: amount,
|
|
1194
|
+
receiver,
|
|
1195
|
+
disableControllerOnMax,
|
|
1196
|
+
isMax,
|
|
1197
|
+
permit2,
|
|
1198
|
+
});
|
|
1199
|
+
items.push(...repayItems);
|
|
1200
|
+
}
|
|
1201
|
+
return items;
|
|
1202
|
+
}
|
|
1203
|
+
/**
|
|
1204
|
+
* Resolves RequiredApproval items in a transaction plan by filling in each item's `resolved` field.
|
|
1205
|
+
* Uses wallet allowances (and optional Permit2 state) to decide whether to add approve/permit2 steps.
|
|
1206
|
+
* Mutates the plan in place and returns it.
|
|
1207
|
+
*
|
|
1208
|
+
* @param args - Resolve-with-wallet arguments
|
|
1209
|
+
* @param args.plan - Transaction plan containing requiredApproval items (e.g. from planDeposit, planBorrow)
|
|
1210
|
+
* @param args.chainId - Chain ID (used to resolve Permit2 address when usePermit2 is true)
|
|
1211
|
+
* @param args.wallet - Wallet entity with token balances and allowances (assetForVault, assetForPermit2, etc.)
|
|
1212
|
+
* @param args.usePermit2 - If true, prefer Permit2 path (approve Permit2 + sign PermitSingle) when allowance is insufficient (default true)
|
|
1213
|
+
* @param args.unlimitedApproval - If true, approval/permit amounts use maxUint256/maxUint160 (default true)
|
|
1214
|
+
* @returns The same plan array with requiredApproval[].resolved populated (approve and/or permit2 data to sign)
|
|
1215
|
+
*/
|
|
1216
|
+
resolveRequiredApprovalsWithWallet(args) {
|
|
1217
|
+
const { plan, wallet, chainId, usePermit2 = true, unlimitedApproval = true, } = args;
|
|
1218
|
+
const deployment = this.deploymentService.getDeployment(chainId);
|
|
1219
|
+
const permit2 = deployment.addresses.coreAddrs.permit2;
|
|
1220
|
+
for (const item of plan) {
|
|
1221
|
+
if (item.type === "requiredApproval") {
|
|
1222
|
+
const approval = item;
|
|
1223
|
+
const { token, owner, spender, amount } = approval;
|
|
1224
|
+
// Get wallet asset and allowances for the specific spender
|
|
1225
|
+
const walletAsset = wallet.getAsset(token);
|
|
1226
|
+
const allowances = walletAsset?.allowances[spender];
|
|
1227
|
+
const resolvedItems = [];
|
|
1228
|
+
const makeApprove = (approvalSpender, approvalAmount) => ({
|
|
1229
|
+
type: "approve",
|
|
1230
|
+
token,
|
|
1231
|
+
owner,
|
|
1232
|
+
spender: approvalSpender,
|
|
1233
|
+
amount: approvalAmount,
|
|
1234
|
+
data: encodeFunctionData({
|
|
1235
|
+
abi: erc20Abi,
|
|
1236
|
+
functionName: "approve",
|
|
1237
|
+
args: [approvalSpender, approvalAmount],
|
|
1238
|
+
}),
|
|
1239
|
+
});
|
|
1240
|
+
const makePermit2 = (permit2Spender, permit2Amount) => ({
|
|
1241
|
+
type: "permit2",
|
|
1242
|
+
token,
|
|
1243
|
+
owner,
|
|
1244
|
+
spender: permit2Spender,
|
|
1245
|
+
amount: permit2Amount,
|
|
1246
|
+
});
|
|
1247
|
+
// If no wallet asset data, assume approval is needed
|
|
1248
|
+
if (!walletAsset || !allowances) {
|
|
1249
|
+
if (usePermit2) {
|
|
1250
|
+
// Need approval to permit2 and permit2 signature
|
|
1251
|
+
resolvedItems.push(makeApprove(permit2, unlimitedApproval ? maxUint256 : amount));
|
|
1252
|
+
resolvedItems.push(makePermit2(spender, unlimitedApproval ? maxUint160 : amount));
|
|
1253
|
+
}
|
|
1254
|
+
else {
|
|
1255
|
+
// Regular approval
|
|
1256
|
+
resolvedItems.push(makeApprove(spender, unlimitedApproval ? maxUint256 : amount));
|
|
1257
|
+
}
|
|
1258
|
+
approval.resolved = resolvedItems;
|
|
1259
|
+
continue;
|
|
1260
|
+
}
|
|
1261
|
+
if (usePermit2) {
|
|
1262
|
+
// Check permit2 allowances
|
|
1263
|
+
const assetForPermit2 = allowances.assetForPermit2;
|
|
1264
|
+
const assetForVaultInPermit2 = allowances.assetForVaultInPermit2;
|
|
1265
|
+
const permit2ExpirationTime = allowances.permit2ExpirationTime;
|
|
1266
|
+
// Check if permit2 signature has expired
|
|
1267
|
+
const currentTime = Math.floor(Date.now() / 1000);
|
|
1268
|
+
const isPermit2Expired = permit2ExpirationTime > 0 && currentTime >= permit2ExpirationTime;
|
|
1269
|
+
const hasSufficientPermit2Allowance = assetForPermit2 >= amount;
|
|
1270
|
+
const hasSufficientVaultAllowance = assetForVaultInPermit2 >= amount && !isPermit2Expired;
|
|
1271
|
+
// If both are sufficient, no approval needed
|
|
1272
|
+
if (hasSufficientPermit2Allowance && hasSufficientVaultAllowance) {
|
|
1273
|
+
approval.resolved = [];
|
|
1274
|
+
continue;
|
|
1275
|
+
}
|
|
1276
|
+
// If assetForPermit2 is insufficient, we need both approval and permit2 signature
|
|
1277
|
+
if (!hasSufficientPermit2Allowance) {
|
|
1278
|
+
resolvedItems.push(makeApprove(permit2, unlimitedApproval ? maxUint256 : amount));
|
|
1279
|
+
resolvedItems.push(makePermit2(spender, unlimitedApproval ? maxUint160 : amount));
|
|
1280
|
+
}
|
|
1281
|
+
else {
|
|
1282
|
+
// assetForPermit2 is sufficient, but vault allowance is insufficient or expired
|
|
1283
|
+
// Only need permit2 signature
|
|
1284
|
+
resolvedItems.push(makePermit2(spender, unlimitedApproval ? maxUint160 : amount));
|
|
1285
|
+
}
|
|
1286
|
+
approval.resolved = resolvedItems;
|
|
1287
|
+
}
|
|
1288
|
+
else {
|
|
1289
|
+
// Regular approval (non-permit2 path)
|
|
1290
|
+
const assetForVault = allowances.assetForVault;
|
|
1291
|
+
const needsDirectApproval = assetForVault < amount;
|
|
1292
|
+
if (!needsDirectApproval) {
|
|
1293
|
+
approval.resolved = [];
|
|
1294
|
+
continue;
|
|
1295
|
+
}
|
|
1296
|
+
resolvedItems.push(makeApprove(spender, unlimitedApproval ? maxUint256 : amount));
|
|
1297
|
+
approval.resolved = resolvedItems;
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
return plan;
|
|
1302
|
+
}
|
|
1303
|
+
/**
|
|
1304
|
+
* Resolves RequiredApproval items in a transaction plan by fetching wallet data then filling in approvals.
|
|
1305
|
+
* Collects (token, spender) from plan's requiredApproval items, fetches wallet via WalletService, then calls resolveRequiredApprovalsWithWallet.
|
|
1306
|
+
*
|
|
1307
|
+
* @param args - Resolve arguments
|
|
1308
|
+
* @param args.plan - Transaction plan containing requiredApproval items
|
|
1309
|
+
* @param args.chainId - Chain ID (used for deployment and wallet fetch)
|
|
1310
|
+
* @param args.account - Account address (owner) used to fetch wallet and allowances
|
|
1311
|
+
* @param args.usePermit2 - If true, use Permit2 path when needed (default true)
|
|
1312
|
+
* @param args.unlimitedApproval - If true, use max amounts for approvals (default false)
|
|
1313
|
+
* @returns Promise of the plan with requiredApproval[].resolved populated
|
|
1314
|
+
*/
|
|
1315
|
+
async resolveRequiredApprovals(args) {
|
|
1316
|
+
const { plan, chainId, account, usePermit2 = true, unlimitedApproval = false, } = args;
|
|
1317
|
+
// Filter transaction plan for only RequiredApproval items
|
|
1318
|
+
const requiredApprovals = plan.filter((item) => item.type === "requiredApproval");
|
|
1319
|
+
// Transform RequiredApprovals into AssetWithSpenders
|
|
1320
|
+
const assetSpendersMap = new Map();
|
|
1321
|
+
for (const approval of requiredApprovals) {
|
|
1322
|
+
const asset = getAddress(approval.token);
|
|
1323
|
+
const spender = getAddress(approval.spender);
|
|
1324
|
+
if (!assetSpendersMap.has(asset)) {
|
|
1325
|
+
assetSpendersMap.set(asset, new Set());
|
|
1326
|
+
}
|
|
1327
|
+
assetSpendersMap.get(asset).add(spender);
|
|
1328
|
+
}
|
|
1329
|
+
// Convert map to AssetWithSpenders array
|
|
1330
|
+
const assetsWithSpenders = Array.from(assetSpendersMap.entries()).map(([asset, spenders]) => ({
|
|
1331
|
+
asset,
|
|
1332
|
+
spenders: Array.from(spenders),
|
|
1333
|
+
}));
|
|
1334
|
+
const walletFetch = await this.walletService.fetchWallet(chainId, account, assetsWithSpenders);
|
|
1335
|
+
const wallet = walletFetch.result;
|
|
1336
|
+
return this.resolveRequiredApprovalsWithWallet({
|
|
1337
|
+
plan,
|
|
1338
|
+
wallet,
|
|
1339
|
+
chainId,
|
|
1340
|
+
usePermit2,
|
|
1341
|
+
unlimitedApproval,
|
|
1342
|
+
});
|
|
1343
|
+
}
|
|
1344
|
+
// ========== Transaction plan functions ==========
|
|
1345
|
+
/**
|
|
1346
|
+
* Builds a transaction plan for depositing assets into a vault.
|
|
1347
|
+
* Use `maxUint256` for `amount` to deposit all available assets from the wallet.
|
|
1348
|
+
*
|
|
1349
|
+
* @param args - Deposit plan arguments
|
|
1350
|
+
* @param args.vault - Address of the vault to deposit into
|
|
1351
|
+
* @param args.amount - Amount of underlying assets to deposit (use maxUint256 for "deposit all")
|
|
1352
|
+
* @param args.receiver - Sub-account address that will receive the vault shares (and count as collateral if enabled)
|
|
1353
|
+
* @param args.account - Account entity (owner + positions); used for chainId, owner, and collateral state
|
|
1354
|
+
* @param args.asset - Address of the underlying ERC20 asset being deposited (used for approval requirement)
|
|
1355
|
+
* @param args.enableCollateral - If true, enables this vault as collateral for `receiver` when not already enabled
|
|
1356
|
+
* @returns Array of transaction plan items (required approvals + EVC batch)
|
|
1357
|
+
*/
|
|
1358
|
+
planDeposit(args) {
|
|
1359
|
+
const { vault, amount, receiver, account, asset, enableCollateral } = args;
|
|
1360
|
+
const plan = [];
|
|
1361
|
+
// Default: collateral is not enabled when account/position is not available
|
|
1362
|
+
const isCollateralEnabled = account?.isCollateralEnabled(receiver, vault) ?? false;
|
|
1363
|
+
// Add approval requirement (will be resolved later with Wallet data)
|
|
1364
|
+
plan.push({
|
|
1365
|
+
type: "requiredApproval",
|
|
1366
|
+
token: asset,
|
|
1367
|
+
owner: account.owner,
|
|
1368
|
+
spender: vault,
|
|
1369
|
+
amount,
|
|
1370
|
+
});
|
|
1371
|
+
// Build EVC batch items
|
|
1372
|
+
const batchItems = this.encodeDeposit({
|
|
1373
|
+
chainId: account.chainId,
|
|
1374
|
+
vault,
|
|
1375
|
+
amount,
|
|
1376
|
+
receiver,
|
|
1377
|
+
owner: account.owner,
|
|
1378
|
+
enableCollateral: !isCollateralEnabled && enableCollateral,
|
|
1379
|
+
// Permit2 is handled separately in the plan
|
|
1380
|
+
});
|
|
1381
|
+
plan.push({
|
|
1382
|
+
type: "evcBatch",
|
|
1383
|
+
items: batchItems,
|
|
1384
|
+
});
|
|
1385
|
+
return plan;
|
|
1386
|
+
}
|
|
1387
|
+
/**
|
|
1388
|
+
* Builds a transaction plan for minting vault shares by depositing assets.
|
|
1389
|
+
*
|
|
1390
|
+
* @param args - Mint plan arguments
|
|
1391
|
+
* @param args.vault - Address of the vault to mint shares from
|
|
1392
|
+
* @param args.shares - Number of vault shares to mint
|
|
1393
|
+
* @param args.receiver - Sub-account address that will receive the shares (and count as collateral if enabled)
|
|
1394
|
+
* @param args.account - Account entity (owner + positions); used for chainId, owner, and collateral state
|
|
1395
|
+
* @param args.asset - Address of the underlying ERC20 asset (used for approval requirement)
|
|
1396
|
+
* @param args.enableCollateral - If true, enables this vault as collateral for `receiver` when not already enabled
|
|
1397
|
+
* @param args.sharesToAssetsExchangeRateWad - Optional exchange rate (WAD) to estimate asset amount for approval when minting by shares. Default 1.
|
|
1398
|
+
* @returns Array of transaction plan items (required approvals + EVC batch)
|
|
1399
|
+
*/
|
|
1400
|
+
planMint(args) {
|
|
1401
|
+
const { vault, shares, receiver, account, asset, enableCollateral, sharesToAssetsExchangeRateWad, } = args;
|
|
1402
|
+
const plan = [];
|
|
1403
|
+
// Default: collateral is not enabled when account/position is not available
|
|
1404
|
+
const isCollateralEnabled = account?.isCollateralEnabled(receiver, vault) ?? false;
|
|
1405
|
+
const estimatedAssetAmount = sharesToAssetsExchangeRateWad
|
|
1406
|
+
? (shares * sharesToAssetsExchangeRateWad) / WAD
|
|
1407
|
+
: shares;
|
|
1408
|
+
// Add approval requirement (will be resolved later with Wallet data)
|
|
1409
|
+
plan.push({
|
|
1410
|
+
type: "requiredApproval",
|
|
1411
|
+
token: asset,
|
|
1412
|
+
owner: account.owner,
|
|
1413
|
+
spender: vault,
|
|
1414
|
+
amount: estimatedAssetAmount,
|
|
1415
|
+
});
|
|
1416
|
+
// Build EVC batch items
|
|
1417
|
+
const batchItems = this.encodeMint({
|
|
1418
|
+
chainId: account.chainId,
|
|
1419
|
+
vault,
|
|
1420
|
+
shares,
|
|
1421
|
+
receiver,
|
|
1422
|
+
owner: account.owner,
|
|
1423
|
+
enableCollateral: !isCollateralEnabled && enableCollateral,
|
|
1424
|
+
// Permit2 is handled separately in the plan
|
|
1425
|
+
});
|
|
1426
|
+
plan.push({
|
|
1427
|
+
type: "evcBatch",
|
|
1428
|
+
items: batchItems,
|
|
1429
|
+
});
|
|
1430
|
+
return plan;
|
|
1431
|
+
}
|
|
1432
|
+
/**
|
|
1433
|
+
* Builds a transaction plan for withdrawing assets from a vault.
|
|
1434
|
+
*
|
|
1435
|
+
* @param args - Withdraw plan arguments
|
|
1436
|
+
* @param args.vault - Address of the vault to withdraw from
|
|
1437
|
+
* @param args.assets - Amount of underlying assets to withdraw
|
|
1438
|
+
* @param args.owner - Sub-account address whose vault shares are being withdrawn
|
|
1439
|
+
* @param args.receiver - Address that will receive the withdrawn underlying assets
|
|
1440
|
+
* @param args.account - Account entity; used for chainId and position/collateral state
|
|
1441
|
+
* @param args.disableCollateral - If true, disables this vault as collateral for `owner` when the position is fully withdrawn and was collateral
|
|
1442
|
+
* @returns Array of transaction plan items (EVC batch; no approvals needed for withdraw)
|
|
1443
|
+
*/
|
|
1444
|
+
planWithdraw(args) {
|
|
1445
|
+
const { vault, assets, receiver, owner, account, disableCollateral = false, } = args;
|
|
1446
|
+
const plan = [];
|
|
1447
|
+
// Get position to check collateral state
|
|
1448
|
+
const position = account?.getPosition(owner, vault);
|
|
1449
|
+
// Build EVC batch items
|
|
1450
|
+
const batchItems = this.encodeWithdraw({
|
|
1451
|
+
chainId: account.chainId,
|
|
1452
|
+
vault,
|
|
1453
|
+
assets,
|
|
1454
|
+
receiver,
|
|
1455
|
+
owner,
|
|
1456
|
+
disableCollateral: disableCollateral && (!position || position.isCollateral),
|
|
1457
|
+
});
|
|
1458
|
+
plan.push({
|
|
1459
|
+
type: "evcBatch",
|
|
1460
|
+
items: batchItems,
|
|
1461
|
+
});
|
|
1462
|
+
return plan;
|
|
1463
|
+
}
|
|
1464
|
+
/**
|
|
1465
|
+
* Builds a transaction plan for redeeming vault shares for underlying assets.
|
|
1466
|
+
* Use `maxUint256` for `shares` to redeem all available shares.
|
|
1467
|
+
*
|
|
1468
|
+
* @param args - Redeem plan arguments
|
|
1469
|
+
* @param args.vault - Address of the vault to redeem shares from
|
|
1470
|
+
* @param args.shares - Number of vault shares to redeem (use maxUint256 for "redeem all")
|
|
1471
|
+
* @param args.owner - Sub-account address whose shares are being redeemed
|
|
1472
|
+
* @param args.receiver - Address that will receive the underlying assets
|
|
1473
|
+
* @param args.account - Account entity; used for chainId and position/collateral state
|
|
1474
|
+
* @param args.disableCollateral - If true, disables this vault as collateral for `owner` when the position is fully redeemed and was collateral
|
|
1475
|
+
* @returns Array of transaction plan items (EVC batch; no approvals needed for redeem)
|
|
1476
|
+
*/
|
|
1477
|
+
planRedeem(args) {
|
|
1478
|
+
const { vault, shares, receiver, owner, account, disableCollateral = false, } = args;
|
|
1479
|
+
const plan = [];
|
|
1480
|
+
// Get position to check collateral state
|
|
1481
|
+
const position = account?.getPosition(owner, vault);
|
|
1482
|
+
// Build EVC batch items
|
|
1483
|
+
const batchItems = this.encodeRedeem({
|
|
1484
|
+
chainId: account.chainId,
|
|
1485
|
+
vault,
|
|
1486
|
+
shares,
|
|
1487
|
+
receiver,
|
|
1488
|
+
owner,
|
|
1489
|
+
disableCollateral: disableCollateral && (!position || position.isCollateral),
|
|
1490
|
+
});
|
|
1491
|
+
plan.push({
|
|
1492
|
+
type: "evcBatch",
|
|
1493
|
+
items: batchItems,
|
|
1494
|
+
});
|
|
1495
|
+
return plan;
|
|
1496
|
+
}
|
|
1497
|
+
/**
|
|
1498
|
+
* Builds a transaction plan for borrowing from a liability vault.
|
|
1499
|
+
* Use `maxUint256` for `collateral.amount` to deposit all available collateral asset from the wallet.
|
|
1500
|
+
*
|
|
1501
|
+
* @param args - Borrow plan arguments
|
|
1502
|
+
* @param args.vault - Address of the liability (borrow) vault to borrow from
|
|
1503
|
+
* @param args.amount - Amount of underlying assets to borrow
|
|
1504
|
+
* @param args.borrowAccount - Sub-account address that will take the debt (and hold collateral if any)
|
|
1505
|
+
* @param args.receiver - Address that will receive the borrowed assets
|
|
1506
|
+
* @param args.account - Account entity; used for chainId, owner, controller/collateral state
|
|
1507
|
+
* @param args.collateral - Optional: deposit collateral in the same batch; use maxUint256 for amount to deposit all available
|
|
1508
|
+
* @param args.collateral.vault - Collateral vault to deposit into
|
|
1509
|
+
* @param args.collateral.amount - Amount of collateral asset to deposit
|
|
1510
|
+
* @param args.collateral.asset - Underlying asset address of the collateral (for approval)
|
|
1511
|
+
* @returns Array of transaction plan items (optional approval + EVC batch)
|
|
1512
|
+
*/
|
|
1513
|
+
planBorrow(args) {
|
|
1514
|
+
const { vault, amount, receiver, borrowAccount, account, collateral } = args;
|
|
1515
|
+
const plan = [];
|
|
1516
|
+
const enableCollateral = collateral && collateral.amount > 0n
|
|
1517
|
+
? !(account?.isCollateralEnabled(borrowAccount, collateral.vault) ??
|
|
1518
|
+
false)
|
|
1519
|
+
: false;
|
|
1520
|
+
// Check if controller needs to be enabled
|
|
1521
|
+
// Default: controller is not enabled when account/sub-account is not available
|
|
1522
|
+
const currentController = account?.getCurrentController(borrowAccount);
|
|
1523
|
+
const enableController = !(account?.isControllerEnabled(borrowAccount, vault) ?? false);
|
|
1524
|
+
if (collateral && collateral.amount > 0n) {
|
|
1525
|
+
// Approval is needed from the account owner (who owns the wallet tokens)
|
|
1526
|
+
// Add approval requirement (will be resolved later with Wallet data)
|
|
1527
|
+
plan.push({
|
|
1528
|
+
type: "requiredApproval",
|
|
1529
|
+
token: collateral.asset,
|
|
1530
|
+
owner: account.owner,
|
|
1531
|
+
spender: collateral.vault,
|
|
1532
|
+
amount: collateral.amount,
|
|
1533
|
+
});
|
|
1534
|
+
}
|
|
1535
|
+
const batchItems = this.encodeBorrow({
|
|
1536
|
+
chainId: account.chainId,
|
|
1537
|
+
vault,
|
|
1538
|
+
amount,
|
|
1539
|
+
owner: account.owner,
|
|
1540
|
+
borrowAccount,
|
|
1541
|
+
receiver,
|
|
1542
|
+
enableController,
|
|
1543
|
+
currentController: currentController || undefined,
|
|
1544
|
+
enableCollateral,
|
|
1545
|
+
collateralVault: collateral?.vault,
|
|
1546
|
+
collateralAmount: collateral?.amount,
|
|
1547
|
+
});
|
|
1548
|
+
plan.push({
|
|
1549
|
+
type: "evcBatch",
|
|
1550
|
+
items: batchItems,
|
|
1551
|
+
});
|
|
1552
|
+
return plan;
|
|
1553
|
+
}
|
|
1554
|
+
/**
|
|
1555
|
+
* Builds a transaction plan for liquidating an undercollateralized account.
|
|
1556
|
+
*
|
|
1557
|
+
* @param args - Liquidation plan arguments
|
|
1558
|
+
* @param args.account - Liquidator's account entity; used for chainId, owner, and controller/collateral state on liquidator sub-account
|
|
1559
|
+
* @param args.liquidatorSubAccountAddress - Sub-account address that will repay debt and receive seized collateral
|
|
1560
|
+
* @param args.vault - Address of the liability vault (debt is repaid to this vault)
|
|
1561
|
+
* @param args.asset - Address of the liability vault's underlying asset (used for approval of repay amount)
|
|
1562
|
+
* @param args.violator - Sub-account address of the undercollateralized account being liquidated
|
|
1563
|
+
* @param args.collateral - Address of the collateral vault from which collateral is seized
|
|
1564
|
+
* @param args.repayAssets - Amount of liability asset the liquidator will repay (and receive collateral up to the liquidation incentive)
|
|
1565
|
+
* @param args.minYieldBalance - Minimum yield balance the liquidator requires; liquidation may revert if not met
|
|
1566
|
+
* @returns Array of transaction plan items (approval for repay asset + EVC batch)
|
|
1567
|
+
*/
|
|
1568
|
+
planLiquidation(args) {
|
|
1569
|
+
const { account, liquidatorSubAccountAddress, vault, asset, violator, collateral, repayAssets, minYieldBalance, } = args;
|
|
1570
|
+
const plan = [];
|
|
1571
|
+
// Add approval requirement for the liability asset the liquidator will repay
|
|
1572
|
+
plan.push({
|
|
1573
|
+
type: "requiredApproval",
|
|
1574
|
+
token: asset,
|
|
1575
|
+
owner: account.owner,
|
|
1576
|
+
spender: vault,
|
|
1577
|
+
amount: repayAssets,
|
|
1578
|
+
});
|
|
1579
|
+
// Check if controller needs to be enabled for the liquidator account on the liability vault
|
|
1580
|
+
const enableController = !(account?.isControllerEnabled(liquidatorSubAccountAddress, vault) ?? false);
|
|
1581
|
+
// Check if collateral needs to be enabled for the seized collateral vault on the liquidator account
|
|
1582
|
+
const enableCollateral = !(account?.isCollateralEnabled(liquidatorSubAccountAddress, collateral) ??
|
|
1583
|
+
false);
|
|
1584
|
+
const batchItems = this.encodeLiquidation({
|
|
1585
|
+
chainId: account.chainId,
|
|
1586
|
+
vault,
|
|
1587
|
+
violator,
|
|
1588
|
+
collateral,
|
|
1589
|
+
repayAssets,
|
|
1590
|
+
minYieldBalance,
|
|
1591
|
+
liquidatorSubAccountAddress,
|
|
1592
|
+
enableController,
|
|
1593
|
+
enableCollateral,
|
|
1594
|
+
});
|
|
1595
|
+
plan.push({
|
|
1596
|
+
type: "evcBatch",
|
|
1597
|
+
items: batchItems,
|
|
1598
|
+
});
|
|
1599
|
+
return plan;
|
|
1600
|
+
}
|
|
1601
|
+
/**
|
|
1602
|
+
* Builds a transaction plan for repaying debt using assets from the wallet.
|
|
1603
|
+
* Use `maxUint256` for `liabilityAmount` to repay all available debt.
|
|
1604
|
+
*
|
|
1605
|
+
* @param args - Repay-from-wallet plan arguments
|
|
1606
|
+
* @param args.liabilityVault - Address of the liability vault (debt is repaid to this vault)
|
|
1607
|
+
* @param args.liabilityAmount - Amount of liability asset to repay (use maxUint256 for "repay all")
|
|
1608
|
+
* @param args.receiver - Sub-account address whose debt is being repaid
|
|
1609
|
+
* @param args.account - Account entity; used for chainId, owner, and position (to resolve liability asset)
|
|
1610
|
+
* @returns Array of transaction plan items (approval + EVC batch)
|
|
1611
|
+
*/
|
|
1612
|
+
planRepayFromWallet(args) {
|
|
1613
|
+
const { liabilityVault, liabilityAmount, receiver, account } = args;
|
|
1614
|
+
const plan = [];
|
|
1615
|
+
// Get position to determine asset
|
|
1616
|
+
const position = account?.getPosition(receiver, liabilityVault);
|
|
1617
|
+
if (!position) {
|
|
1618
|
+
throw new Error(`Position not found. Liability vault: ${liabilityVault}, Account: ${receiver}`);
|
|
1619
|
+
}
|
|
1620
|
+
// Add approval requirement (will be resolved later with Wallet data)
|
|
1621
|
+
plan.push({
|
|
1622
|
+
type: "requiredApproval",
|
|
1623
|
+
token: position.asset,
|
|
1624
|
+
owner: account.owner,
|
|
1625
|
+
spender: liabilityVault,
|
|
1626
|
+
amount: liabilityAmount,
|
|
1627
|
+
});
|
|
1628
|
+
// Build EVC batch items
|
|
1629
|
+
const batchItems = this.encodeRepayFromWallet({
|
|
1630
|
+
chainId: account.chainId,
|
|
1631
|
+
sender: account.owner,
|
|
1632
|
+
liabilityVault,
|
|
1633
|
+
liabilityAmount,
|
|
1634
|
+
receiver,
|
|
1635
|
+
disableControllerOnMax: true,
|
|
1636
|
+
isMax: liabilityAmount === maxUint256,
|
|
1637
|
+
// Permit2 is handled separately in the plan
|
|
1638
|
+
});
|
|
1639
|
+
plan.push({
|
|
1640
|
+
type: "evcBatch",
|
|
1641
|
+
items: batchItems,
|
|
1642
|
+
});
|
|
1643
|
+
return plan;
|
|
1644
|
+
}
|
|
1645
|
+
/**
|
|
1646
|
+
* Builds a transaction plan for repaying debt using assets from another vault deposit (same asset only).
|
|
1647
|
+
* Use `maxUint256` for `liabilityAmount` to repay all available debt or up to the available deposit.
|
|
1648
|
+
*
|
|
1649
|
+
* @param args - Repay-from-deposit plan arguments
|
|
1650
|
+
* @param args.liabilityVault - Address of the liability vault (debt is repaid to this vault)
|
|
1651
|
+
* @param args.liabilityAmount - Amount of liability to repay (use maxUint256 for max repay)
|
|
1652
|
+
* @param args.receiver - Sub-account address whose debt is being repaid (and from whose deposit we may withdraw when fromAccount === receiver)
|
|
1653
|
+
* @param args.fromVault - Vault to withdraw assets from (must be same underlying asset as liability for this plan)
|
|
1654
|
+
* @param args.fromAccount - Sub-account that holds the deposit in `fromVault`
|
|
1655
|
+
* @param args.account - Account entity; used for chainId, owner, and positions (to resolve assets and eligibility)
|
|
1656
|
+
* @returns Array of transaction plan items (optional approval + EVC batch). Throws if asset differs between fromVault and liabilityVault; use planRepayWithSwap for cross-asset.
|
|
1657
|
+
*/
|
|
1658
|
+
planRepayFromDeposit(args) {
|
|
1659
|
+
const { liabilityVault, liabilityAmount, receiver, fromVault, fromAccount, account, } = args;
|
|
1660
|
+
const plan = [];
|
|
1661
|
+
// Get positions
|
|
1662
|
+
const liabilityPosition = account?.getPosition(receiver, liabilityVault);
|
|
1663
|
+
const fromPosition = account?.getPosition(fromAccount, fromVault);
|
|
1664
|
+
// If positions are not available, we can't determine asset addresses
|
|
1665
|
+
// We'll need to throw an error or require asset addresses to be provided
|
|
1666
|
+
if (!liabilityPosition || !fromPosition) {
|
|
1667
|
+
throw new Error(`Positions not found. Liability vault: ${liabilityVault}, From vault: ${fromVault}, Account: ${receiver}. Asset addresses are required when positions are not available.`);
|
|
1668
|
+
}
|
|
1669
|
+
const liabilityAsset = liabilityPosition.asset;
|
|
1670
|
+
const fromAsset = fromPosition.asset;
|
|
1671
|
+
// Check if approval is needed (only if different assets and we need to swap/withdraw)
|
|
1672
|
+
if (fromAsset !== liabilityAsset) {
|
|
1673
|
+
// This path requires a swap, which is handled by planRepayWithSwap
|
|
1674
|
+
throw new Error("planRepayFromDeposit only supports same-asset paths. Use planRepayWithSwap for different assets.");
|
|
1675
|
+
}
|
|
1676
|
+
// If same asset, different vault, we might need approval for the withdraw/repay path
|
|
1677
|
+
if (fromVault !== liabilityVault) {
|
|
1678
|
+
// Add approval requirement (will be resolved later with Wallet data)
|
|
1679
|
+
plan.push({
|
|
1680
|
+
type: "requiredApproval",
|
|
1681
|
+
token: liabilityAsset,
|
|
1682
|
+
owner: account.owner,
|
|
1683
|
+
spender: liabilityVault,
|
|
1684
|
+
amount: liabilityAmount,
|
|
1685
|
+
});
|
|
1686
|
+
}
|
|
1687
|
+
// Build EVC batch items
|
|
1688
|
+
const batchItems = this.encodeRepayFromDeposit({
|
|
1689
|
+
chainId: account.chainId,
|
|
1690
|
+
liabilityVault,
|
|
1691
|
+
liabilityAsset,
|
|
1692
|
+
liabilityAmount,
|
|
1693
|
+
from: receiver,
|
|
1694
|
+
receiver,
|
|
1695
|
+
fromVault,
|
|
1696
|
+
fromAsset,
|
|
1697
|
+
disableControllerOnMax: true,
|
|
1698
|
+
isMax: liabilityAmount === maxUint256,
|
|
1699
|
+
// Permit2 is handled separately in the plan
|
|
1700
|
+
});
|
|
1701
|
+
plan.push({
|
|
1702
|
+
type: "evcBatch",
|
|
1703
|
+
items: batchItems,
|
|
1704
|
+
});
|
|
1705
|
+
return plan;
|
|
1706
|
+
}
|
|
1707
|
+
/**
|
|
1708
|
+
* Builds a transaction plan for repaying debt by swapping collateral (e.g. withdraw collateral → swap → repay).
|
|
1709
|
+
* Use when the repayment asset differs from the collateral asset.
|
|
1710
|
+
*
|
|
1711
|
+
* @param args - Repay-with-swap plan arguments
|
|
1712
|
+
* @param args.swapQuote - Quote from swap service (e.g. fetchRepayQuotes); defines vaultIn, accountIn, accountOut, receiver, swap and verify steps
|
|
1713
|
+
* @param args.account - Account entity; used for chainId and positions (to compute isMax and maxWithdraw)
|
|
1714
|
+
* @returns Array of transaction plan items (EVC batch: withdraw, swap, verify/repay). Throws if positions not found or liability is zero.
|
|
1715
|
+
*/
|
|
1716
|
+
planRepayWithSwap(args) {
|
|
1717
|
+
const { swapQuote, account } = args;
|
|
1718
|
+
const plan = [];
|
|
1719
|
+
const liabilityPosition = account?.getPosition(swapQuote.accountOut, swapQuote.receiver);
|
|
1720
|
+
const fromPosition = account?.getPosition(swapQuote.accountIn, swapQuote.vaultIn);
|
|
1721
|
+
if (!liabilityPosition ||
|
|
1722
|
+
!fromPosition ||
|
|
1723
|
+
liabilityPosition.borrowed <= 0n) {
|
|
1724
|
+
throw new Error(`Positions not found or liability is 0. Liability vault: ${swapQuote.receiver}, From vault: ${swapQuote.vaultIn}, Account: ${swapQuote.accountOut}`);
|
|
1725
|
+
}
|
|
1726
|
+
const isMax = liabilityPosition.borrowed <= BigInt(swapQuote.amountOutMin);
|
|
1727
|
+
const maxWithdraw = fromPosition.assets;
|
|
1728
|
+
// Build EVC batch items
|
|
1729
|
+
const batchItems = this.encodeRepayWithSwap({
|
|
1730
|
+
chainId: account.chainId,
|
|
1731
|
+
swapQuote,
|
|
1732
|
+
maxWithdraw,
|
|
1733
|
+
isMax,
|
|
1734
|
+
disableControllerOnMax: true,
|
|
1735
|
+
});
|
|
1736
|
+
plan.push({
|
|
1737
|
+
type: "evcBatch",
|
|
1738
|
+
items: batchItems,
|
|
1739
|
+
});
|
|
1740
|
+
return plan;
|
|
1741
|
+
}
|
|
1742
|
+
/**
|
|
1743
|
+
* Builds a transaction plan for depositing into a vault using tokens from the user's wallet, going through a swap.
|
|
1744
|
+
* The approval is given to SwapVerifier (not the vault), then transferFromSender is used in the batch
|
|
1745
|
+
* to provide the tokens to the Swapper from the user's wallet.
|
|
1746
|
+
*
|
|
1747
|
+
* @param args - Deposit-with-swap-from-wallet plan arguments
|
|
1748
|
+
* @param args.swapQuote - Quote from swap service; defines swap and verify steps
|
|
1749
|
+
* @param args.amount - Amount of input token to transfer from wallet
|
|
1750
|
+
* @param args.tokenIn - Input token address (for approval to SwapVerifier)
|
|
1751
|
+
* @param args.account - Account entity; used for chainId, owner, and collateral state
|
|
1752
|
+
* @param args.enableCollateral - If true, enables receiver vault as collateral for accountOut
|
|
1753
|
+
* @returns Array of transaction plan items (approval to SwapVerifier + EVC batch)
|
|
1754
|
+
*/
|
|
1755
|
+
planDepositWithSwapFromWallet(args) {
|
|
1756
|
+
const { swapQuote, amount, tokenIn, account, enableCollateral } = args;
|
|
1757
|
+
const plan = [];
|
|
1758
|
+
// Approval goes to the transferFromSender contract (which uses permit2 transferFrom internally)
|
|
1759
|
+
plan.push({
|
|
1760
|
+
type: "requiredApproval",
|
|
1761
|
+
token: tokenIn,
|
|
1762
|
+
owner: account.owner,
|
|
1763
|
+
spender: swapQuote.verify.verifierAddress,
|
|
1764
|
+
amount,
|
|
1765
|
+
});
|
|
1766
|
+
// Check if collateral needs to be enabled
|
|
1767
|
+
const receiverVault = swapQuote.receiver;
|
|
1768
|
+
const accountOut = swapQuote.accountOut || account.owner;
|
|
1769
|
+
const isCollateralEnabled = account?.isCollateralEnabled(accountOut, receiverVault) ?? false;
|
|
1770
|
+
const shouldEnableCollateral = enableCollateral !== undefined
|
|
1771
|
+
? enableCollateral && !isCollateralEnabled
|
|
1772
|
+
: !isCollateralEnabled;
|
|
1773
|
+
// Build EVC batch items
|
|
1774
|
+
const batchItems = this.encodeDepositWithSwapFromWallet({
|
|
1775
|
+
chainId: account.chainId,
|
|
1776
|
+
swapQuote,
|
|
1777
|
+
amount,
|
|
1778
|
+
sender: account.owner,
|
|
1779
|
+
enableCollateral: shouldEnableCollateral,
|
|
1780
|
+
});
|
|
1781
|
+
plan.push({
|
|
1782
|
+
type: "evcBatch",
|
|
1783
|
+
items: batchItems,
|
|
1784
|
+
});
|
|
1785
|
+
return plan;
|
|
1786
|
+
}
|
|
1787
|
+
/**
|
|
1788
|
+
* Builds a transaction plan for swapping collateral from one vault to another (withdraw → swap → deposit/skim).
|
|
1789
|
+
*
|
|
1790
|
+
* @param args - Swap-collateral plan arguments
|
|
1791
|
+
* @param args.swapQuote - Quote from swap service (e.g. fetchDepositQuote); defines vaultIn, accountIn, accountOut, receiver, swap and verify (skimMin) steps
|
|
1792
|
+
* @param args.account - Account entity; used for chainId and positions (to determine isMax and whether to enable collateral on destination)
|
|
1793
|
+
* @returns Array of transaction plan items (EVC batch: withdraw, swap, verify/skim, optional enable/disable collateral)
|
|
1794
|
+
*/
|
|
1795
|
+
planSwapCollateral(args) {
|
|
1796
|
+
const { swapQuote, account } = args;
|
|
1797
|
+
const plan = [];
|
|
1798
|
+
// Check if source collateral needs to be disabled (when all is swapped)
|
|
1799
|
+
// Default: when position is not available, assume amounts are zero, so we don't disable collateral
|
|
1800
|
+
const sourcePosition = account?.getPosition(swapQuote.accountIn, swapQuote.vaultIn);
|
|
1801
|
+
const isMax = sourcePosition
|
|
1802
|
+
? sourcePosition.assets <= BigInt(swapQuote.amountIn)
|
|
1803
|
+
: false;
|
|
1804
|
+
// Check if destination collateral needs to be enabled
|
|
1805
|
+
// Default: collateral is not enabled when account/sub-account is not available
|
|
1806
|
+
const enableCollateral = !(account?.isCollateralEnabled(swapQuote.accountOut, swapQuote.receiver) ??
|
|
1807
|
+
false);
|
|
1808
|
+
// Build EVC batch items
|
|
1809
|
+
const batchItems = this.encodeSwapCollateral({
|
|
1810
|
+
chainId: account.chainId,
|
|
1811
|
+
swapQuote,
|
|
1812
|
+
enableCollateral,
|
|
1813
|
+
disableCollateralOnMax: true,
|
|
1814
|
+
isMax,
|
|
1815
|
+
});
|
|
1816
|
+
plan.push({
|
|
1817
|
+
type: "evcBatch",
|
|
1818
|
+
items: batchItems,
|
|
1819
|
+
});
|
|
1820
|
+
return plan;
|
|
1821
|
+
}
|
|
1822
|
+
/**
|
|
1823
|
+
* Builds a transaction plan for swapping debt from one liability vault to another (borrow from source → swap → repay to destination).
|
|
1824
|
+
*
|
|
1825
|
+
* @param args - Swap-debt plan arguments
|
|
1826
|
+
* @param args.swapQuote - Quote from swap service (e.g. fetchRepayQuotes for the new debt); defines vaultIn, accountIn, accountOut, swap and verify (debtMax) steps
|
|
1827
|
+
* @param args.account - Account entity; used for chainId and controller state (enableController, isMax, disableControllerOnMax)
|
|
1828
|
+
* @returns Array of transaction plan items (EVC batch: enableController, borrow, swap, verify/repay, optional disableController)
|
|
1829
|
+
*/
|
|
1830
|
+
planSwapDebt(args) {
|
|
1831
|
+
const { swapQuote, account } = args;
|
|
1832
|
+
const plan = [];
|
|
1833
|
+
const sourcePosition = account?.getPosition(swapQuote.accountIn, swapQuote.vaultIn);
|
|
1834
|
+
const isMax = sourcePosition
|
|
1835
|
+
? sourcePosition.borrowed <= BigInt(swapQuote.amountOutMin)
|
|
1836
|
+
: false;
|
|
1837
|
+
const enableController = !(account?.isControllerEnabled(swapQuote.accountOut, swapQuote.vaultIn) ??
|
|
1838
|
+
false);
|
|
1839
|
+
// Build EVC batch items
|
|
1840
|
+
const batchItems = this.encodeSwapDebt({
|
|
1841
|
+
chainId: account.chainId,
|
|
1842
|
+
swapQuote,
|
|
1843
|
+
enableController,
|
|
1844
|
+
disableControllerOnMax: true,
|
|
1845
|
+
isMax,
|
|
1846
|
+
});
|
|
1847
|
+
plan.push({
|
|
1848
|
+
type: "evcBatch",
|
|
1849
|
+
items: batchItems,
|
|
1850
|
+
});
|
|
1851
|
+
return plan;
|
|
1852
|
+
}
|
|
1853
|
+
/**
|
|
1854
|
+
* Builds a transaction plan for transferring vault shares between sub-accounts.
|
|
1855
|
+
*
|
|
1856
|
+
* @param args - Transfer plan arguments
|
|
1857
|
+
* @param args.vault - Address of the vault
|
|
1858
|
+
* @param args.from - Sub-account address sending the shares
|
|
1859
|
+
* @param args.to - Sub-account address receiving the shares
|
|
1860
|
+
* @param args.amount - Amount of vault shares to transfer
|
|
1861
|
+
* @param args.account - Account entity; used for chainId and collateral state for from/to
|
|
1862
|
+
* @param args.enableCollateralTo - If true, enables the vault as collateral for `to` when not already enabled
|
|
1863
|
+
* @param args.disableCollateralFrom - If true, disables the vault as collateral for `from` when it was enabled
|
|
1864
|
+
* @returns Array of transaction plan items (EVC batch; no approvals needed)
|
|
1865
|
+
*/
|
|
1866
|
+
planTransfer(args) {
|
|
1867
|
+
const { vault, to, amount, from, account, enableCollateralTo, disableCollateralFrom, } = args;
|
|
1868
|
+
const plan = [];
|
|
1869
|
+
// Build EVC batch items
|
|
1870
|
+
const batchItems = this.encodeTransfer({
|
|
1871
|
+
chainId: account.chainId,
|
|
1872
|
+
vault,
|
|
1873
|
+
to,
|
|
1874
|
+
amount,
|
|
1875
|
+
from,
|
|
1876
|
+
enableCollateralTo: enableCollateralTo &&
|
|
1877
|
+
!(account?.isCollateralEnabled(to, vault) ?? false),
|
|
1878
|
+
disableCollateralFrom: disableCollateralFrom &&
|
|
1879
|
+
(account?.isCollateralEnabled(from, vault) ?? false),
|
|
1880
|
+
});
|
|
1881
|
+
plan.push({
|
|
1882
|
+
type: "evcBatch",
|
|
1883
|
+
items: batchItems,
|
|
1884
|
+
});
|
|
1885
|
+
return plan;
|
|
1886
|
+
}
|
|
1887
|
+
/**
|
|
1888
|
+
* Builds a transaction plan for pulling debt from one sub-account to another (same liability vault).
|
|
1889
|
+
*
|
|
1890
|
+
* @param args - Pull-debt plan arguments
|
|
1891
|
+
* @param args.vault - Address of the liability vault
|
|
1892
|
+
* @param args.amount - Amount of debt to pull
|
|
1893
|
+
* @param args.from - Sub-account address from which debt is pulled
|
|
1894
|
+
* @param args.to - Sub-account address that will receive the debt (and receive the borrowed assets if any)
|
|
1895
|
+
* @param args.account - Account entity; used for chainId and controller state (enableController for `to` if needed)
|
|
1896
|
+
* @returns Array of transaction plan items (EVC batch: optional enableController + pullDebt)
|
|
1897
|
+
*/
|
|
1898
|
+
planPullDebt(args) {
|
|
1899
|
+
const { vault, amount, from, to, account } = args;
|
|
1900
|
+
const plan = [];
|
|
1901
|
+
const enableController = !(account?.isControllerEnabled(to, vault) ?? false);
|
|
1902
|
+
// Build EVC batch items
|
|
1903
|
+
const batchItems = this.encodePullDebt({
|
|
1904
|
+
chainId: account.chainId,
|
|
1905
|
+
vault,
|
|
1906
|
+
amount,
|
|
1907
|
+
from,
|
|
1908
|
+
to,
|
|
1909
|
+
enableController,
|
|
1910
|
+
});
|
|
1911
|
+
plan.push({
|
|
1912
|
+
type: "evcBatch",
|
|
1913
|
+
items: batchItems,
|
|
1914
|
+
});
|
|
1915
|
+
return plan;
|
|
1916
|
+
}
|
|
1917
|
+
/**
|
|
1918
|
+
* Builds a transaction plan for a multiply/leverage position when liability and long asset differ (requires a swap).
|
|
1919
|
+
* Flow: optional collateral deposit → enable controller → borrow → swap → enable collateral on long vault.
|
|
1920
|
+
*
|
|
1921
|
+
* @param args - Multiply-with-swap plan arguments
|
|
1922
|
+
* @param args.collateralVault - Vault to deposit initial collateral into (optional; omit amount or use 0 to skip)
|
|
1923
|
+
* @param args.collateralAmount - Amount of collateral asset to deposit (0n to skip deposit)
|
|
1924
|
+
* @param args.collateralAsset - Underlying asset address of collateral (for approval when collateralAmount > 0)
|
|
1925
|
+
* @param args.swapQuote - Quote describing borrow vault (vaultIn), long vault (receiver), amounts, swap and verify (skimMin) steps; accountIn must equal accountOut
|
|
1926
|
+
* @param args.account - Account entity; used for chainId, owner, and collateral/controller state
|
|
1927
|
+
* @returns Array of transaction plan items (optional approval + EVC batch). Throws if swapQuote.accountIn !== swapQuote.accountOut.
|
|
1928
|
+
*/
|
|
1929
|
+
planMultiplyWithSwap(args) {
|
|
1930
|
+
const { collateralVault, collateralAmount, collateralAsset, account, swapQuote, } = args;
|
|
1931
|
+
const plan = [];
|
|
1932
|
+
// 1. Check if collateral approval is needed (only if depositing collateral)
|
|
1933
|
+
if (collateralAmount > 0n) {
|
|
1934
|
+
// Add approval requirement (will be resolved later with Wallet data)
|
|
1935
|
+
plan.push({
|
|
1936
|
+
type: "requiredApproval",
|
|
1937
|
+
token: collateralAsset,
|
|
1938
|
+
owner: account.owner,
|
|
1939
|
+
spender: collateralVault,
|
|
1940
|
+
amount: collateralAmount,
|
|
1941
|
+
});
|
|
1942
|
+
}
|
|
1943
|
+
if (swapQuote.accountIn !== swapQuote.accountOut) {
|
|
1944
|
+
throw new Error("Account in and account out must be the same");
|
|
1945
|
+
}
|
|
1946
|
+
const receiver = swapQuote.accountIn;
|
|
1947
|
+
const liabilityVault = swapQuote.vaultIn;
|
|
1948
|
+
const longVault = swapQuote.receiver;
|
|
1949
|
+
const liabilityAmount = BigInt(swapQuote.amountIn);
|
|
1950
|
+
// 2. Determine if collateral needs to be enabled
|
|
1951
|
+
const enableCollateral = collateralAmount > 0n &&
|
|
1952
|
+
!(account?.isCollateralEnabled(receiver, collateralVault) ?? false);
|
|
1953
|
+
// 3. Determine if controller needs to be enabled
|
|
1954
|
+
const enableController = !(account?.isControllerEnabled(receiver, liabilityVault) ?? false);
|
|
1955
|
+
// 4. Get current controller (may need to disable if different)
|
|
1956
|
+
const currentController = account?.getCurrentController(receiver);
|
|
1957
|
+
// 5. Build EVC batch items
|
|
1958
|
+
const batchItems = this.encodeMultiplyWithSwap({
|
|
1959
|
+
chainId: account.chainId,
|
|
1960
|
+
collateralVault,
|
|
1961
|
+
collateralAmount,
|
|
1962
|
+
liabilityVault,
|
|
1963
|
+
liabilityAmount,
|
|
1964
|
+
longVault,
|
|
1965
|
+
owner: account.owner,
|
|
1966
|
+
receiver,
|
|
1967
|
+
enableCollateral,
|
|
1968
|
+
currentController: currentController || undefined,
|
|
1969
|
+
enableController,
|
|
1970
|
+
swapQuote,
|
|
1971
|
+
// Permit2 is handled separately in the plan
|
|
1972
|
+
});
|
|
1973
|
+
plan.push({
|
|
1974
|
+
type: "evcBatch",
|
|
1975
|
+
items: batchItems,
|
|
1976
|
+
});
|
|
1977
|
+
return plan;
|
|
1978
|
+
}
|
|
1979
|
+
/**
|
|
1980
|
+
* Builds a transaction plan for a multiply/leverage position when liability and long asset are the same (no swap).
|
|
1981
|
+
* Flow: optional collateral deposit → enable controller → borrow to long vault → skim → enable collateral on long vault.
|
|
1982
|
+
*
|
|
1983
|
+
* @param args - Multiply-same-asset plan arguments
|
|
1984
|
+
* @param args.collateralVault - Vault to deposit initial collateral into (optional; use 0n for collateralAmount to skip)
|
|
1985
|
+
* @param args.collateralAmount - Amount of collateral asset to deposit (0n to skip)
|
|
1986
|
+
* @param args.collateralAsset - Underlying asset address of collateral (for approval when collateralAmount > 0)
|
|
1987
|
+
* @param args.liabilityVault - Liability vault to borrow from
|
|
1988
|
+
* @param args.liabilityAmount - Amount to borrow (same asset as long vault)
|
|
1989
|
+
* @param args.longVault - Vault to deposit borrowed assets into (same asset as liability)
|
|
1990
|
+
* @param args.receiver - Sub-account address that holds the position (collateral + debt)
|
|
1991
|
+
* @param args.account - Account entity; used for chainId, owner, and collateral/controller state
|
|
1992
|
+
* @returns Array of transaction plan items (optional approval + EVC batch)
|
|
1993
|
+
*/
|
|
1994
|
+
planMultiplySameAsset(args) {
|
|
1995
|
+
const { collateralVault, collateralAmount, collateralAsset, liabilityVault, liabilityAmount, longVault, receiver, account, } = args;
|
|
1996
|
+
const plan = [];
|
|
1997
|
+
// 1. Check if collateral approval is needed (only if depositing collateral)
|
|
1998
|
+
if (collateralAmount > 0n) {
|
|
1999
|
+
// Add approval requirement (will be resolved later with Wallet data)
|
|
2000
|
+
plan.push({
|
|
2001
|
+
type: "requiredApproval",
|
|
2002
|
+
token: collateralAsset,
|
|
2003
|
+
owner: account.owner,
|
|
2004
|
+
spender: collateralVault,
|
|
2005
|
+
amount: collateralAmount,
|
|
2006
|
+
});
|
|
2007
|
+
}
|
|
2008
|
+
// 2. Determine if collateral needs to be enabled
|
|
2009
|
+
const enableCollateral = collateralAmount > 0n &&
|
|
2010
|
+
!(account?.isCollateralEnabled(receiver, collateralVault) ?? false);
|
|
2011
|
+
// 3. Determine if controller needs to be enabled
|
|
2012
|
+
const enableController = !(account?.isControllerEnabled(receiver, liabilityVault) ?? false);
|
|
2013
|
+
// 4. Get current controller (may need to disable if different)
|
|
2014
|
+
const currentController = account?.getCurrentController(receiver);
|
|
2015
|
+
// 5. Build EVC batch items
|
|
2016
|
+
const batchItems = this.encodeMultiplySameAsset({
|
|
2017
|
+
chainId: account.chainId,
|
|
2018
|
+
collateralVault,
|
|
2019
|
+
collateralAmount,
|
|
2020
|
+
liabilityVault,
|
|
2021
|
+
liabilityAmount,
|
|
2022
|
+
longVault,
|
|
2023
|
+
owner: account.owner,
|
|
2024
|
+
receiver,
|
|
2025
|
+
enableCollateral,
|
|
2026
|
+
currentController: currentController || undefined,
|
|
2027
|
+
enableController,
|
|
2028
|
+
// Permit2 is handled separately in the plan
|
|
2029
|
+
});
|
|
2030
|
+
plan.push({
|
|
2031
|
+
type: "evcBatch",
|
|
2032
|
+
items: batchItems,
|
|
2033
|
+
});
|
|
2034
|
+
return plan;
|
|
2035
|
+
}
|
|
2036
|
+
}
|
|
2037
|
+
//# sourceMappingURL=executionService.js.map
|