@eulerxyz/euler-v2-sdk 0.1.1-beta → 0.1.3-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/README.md +11 -9
- package/dist/src/entities/Account.d.ts +26 -9
- package/dist/src/entities/Account.d.ts.map +1 -0
- package/dist/src/entities/Account.js +61 -44
- package/dist/src/entities/Account.js.map +1 -1
- package/dist/src/entities/ERC4626Vault.d.ts +1 -0
- package/dist/src/entities/ERC4626Vault.d.ts.map +1 -0
- package/dist/src/entities/EVault.d.ts +1 -0
- package/dist/src/entities/EVault.d.ts.map +1 -0
- package/dist/src/entities/EulerEarn.d.ts +1 -0
- package/dist/src/entities/EulerEarn.d.ts.map +1 -0
- package/dist/src/entities/EulerLabels.d.ts +6 -11
- package/dist/src/entities/EulerLabels.d.ts.map +1 -0
- package/dist/src/entities/Portfolio.d.ts +133 -0
- package/dist/src/entities/Portfolio.d.ts.map +1 -0
- package/dist/src/entities/Portfolio.js +304 -0
- package/dist/src/entities/Portfolio.js.map +1 -0
- package/dist/src/entities/SecuritizeCollateralVault.d.ts +1 -0
- package/dist/src/entities/SecuritizeCollateralVault.d.ts.map +1 -0
- package/dist/src/entities/Wallet.d.ts +1 -0
- package/dist/src/entities/Wallet.d.ts.map +1 -0
- package/dist/src/index.d.ts +5 -1
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +4 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/plugins/batchSimulation.d.ts +1 -0
- package/dist/src/plugins/batchSimulation.d.ts.map +1 -0
- package/dist/src/plugins/index.d.ts +1 -0
- package/dist/src/plugins/index.d.ts.map +1 -0
- package/dist/src/plugins/keyring/index.d.ts +1 -0
- package/dist/src/plugins/keyring/index.d.ts.map +1 -0
- package/dist/src/plugins/keyring/keyringPlugin.d.ts +2 -1
- package/dist/src/plugins/keyring/keyringPlugin.d.ts.map +1 -0
- package/dist/src/plugins/keyring/keyringPlugin.js +12 -3
- package/dist/src/plugins/keyring/keyringPlugin.js.map +1 -1
- package/dist/src/plugins/pyth/index.d.ts +1 -0
- package/dist/src/plugins/pyth/index.d.ts.map +1 -0
- package/dist/src/plugins/pyth/pythPlugin.d.ts +1 -0
- package/dist/src/plugins/pyth/pythPlugin.d.ts.map +1 -0
- package/dist/src/plugins/types.d.ts +1 -0
- package/dist/src/plugins/types.d.ts.map +1 -0
- package/dist/src/sdk/buildSDK.d.ts +4 -3
- package/dist/src/sdk/buildSDK.d.ts.map +1 -0
- package/dist/src/sdk/buildSDK.js +15 -7
- package/dist/src/sdk/buildSDK.js.map +1 -1
- package/dist/src/sdk/defaultConfig.d.ts +1 -0
- package/dist/src/sdk/defaultConfig.d.ts.map +1 -0
- package/dist/src/sdk/defaultConfig.js +27 -28
- package/dist/src/sdk/defaultConfig.js.map +1 -1
- package/dist/src/sdk/sdk.d.ts +6 -5
- package/dist/src/sdk/sdk.d.ts.map +1 -0
- package/dist/src/sdk/sdk.js +2 -2
- package/dist/src/sdk/sdk.js.map +1 -1
- package/dist/src/services/abiService/abiService.d.ts +1 -0
- package/dist/src/services/abiService/abiService.d.ts.map +1 -0
- package/dist/src/services/abiService/index.d.ts +1 -0
- package/dist/src/services/abiService/index.d.ts.map +1 -0
- package/dist/src/services/accountService/accountService.d.ts +1 -0
- package/dist/src/services/accountService/accountService.d.ts.map +1 -0
- package/dist/src/services/accountService/accountService.js.map +1 -1
- package/dist/src/services/accountService/accountServiceConfig.d.ts +1 -0
- package/dist/src/services/accountService/accountServiceConfig.d.ts.map +1 -0
- package/dist/src/services/accountService/adapters/accountOnchainAdapter/abis/accountLensAbi.d.ts +1 -0
- package/dist/src/services/accountService/adapters/accountOnchainAdapter/abis/accountLensAbi.d.ts.map +1 -0
- package/dist/src/services/accountService/adapters/accountOnchainAdapter/accountInfoConverter.d.ts +1 -0
- package/dist/src/services/accountService/adapters/accountOnchainAdapter/accountInfoConverter.d.ts.map +1 -0
- package/dist/src/services/accountService/adapters/accountOnchainAdapter/accountInfoConverter.js +23 -8
- package/dist/src/services/accountService/adapters/accountOnchainAdapter/accountInfoConverter.js.map +1 -1
- package/dist/src/services/accountService/adapters/accountOnchainAdapter/accountLensTypes.d.ts +1 -0
- package/dist/src/services/accountService/adapters/accountOnchainAdapter/accountLensTypes.d.ts.map +1 -0
- package/dist/src/services/accountService/adapters/accountOnchainAdapter/accountOnchainAdapter.d.ts +1 -0
- package/dist/src/services/accountService/adapters/accountOnchainAdapter/accountOnchainAdapter.d.ts.map +1 -0
- package/dist/src/services/accountService/adapters/accountOnchainAdapter/accountVaultsSubgraphAdapter.d.ts +1 -0
- package/dist/src/services/accountService/adapters/accountOnchainAdapter/accountVaultsSubgraphAdapter.d.ts.map +1 -0
- package/dist/src/services/accountService/adapters/accountOutputNormalization.d.ts +1 -0
- package/dist/src/services/accountService/adapters/accountOutputNormalization.d.ts.map +1 -0
- package/dist/src/services/accountService/adapters/accountV3Adapter/accountV3Adapter.d.ts +8 -1
- package/dist/src/services/accountService/adapters/accountV3Adapter/accountV3Adapter.d.ts.map +1 -0
- package/dist/src/services/accountService/adapters/accountV3Adapter/accountV3Adapter.js +109 -19
- package/dist/src/services/accountService/adapters/accountV3Adapter/accountV3Adapter.js.map +1 -1
- package/dist/src/services/accountService/adapters/accountVaultsSubgraphAdapter/accountVaultsSubgraphAdapter.d.ts +1 -0
- package/dist/src/services/accountService/adapters/accountVaultsSubgraphAdapter/accountVaultsSubgraphAdapter.d.ts.map +1 -0
- package/dist/src/services/accountService/index.d.ts +1 -0
- package/dist/src/services/accountService/index.d.ts.map +1 -0
- package/dist/src/services/deploymentService/deploymentService.d.ts +1 -0
- package/dist/src/services/deploymentService/deploymentService.d.ts.map +1 -0
- package/dist/src/services/deploymentService/index.d.ts +1 -0
- package/dist/src/services/deploymentService/index.d.ts.map +1 -0
- package/dist/src/services/eulerLabelsService/eulerLabelsService.d.ts +2 -10
- package/dist/src/services/eulerLabelsService/eulerLabelsService.d.ts.map +1 -0
- package/dist/src/services/eulerLabelsService/eulerLabelsService.js +43 -53
- package/dist/src/services/eulerLabelsService/eulerLabelsService.js.map +1 -1
- package/dist/src/services/eulerLabelsService/index.d.ts +1 -0
- package/dist/src/services/eulerLabelsService/index.d.ts.map +1 -0
- package/dist/src/services/executionService/abis/eVaultAbi.d.ts +1 -0
- package/dist/src/services/executionService/abis/eVaultAbi.d.ts.map +1 -0
- package/dist/src/services/executionService/abis/ethereumVaultConnectorAbi.d.ts +1 -0
- package/dist/src/services/executionService/abis/ethereumVaultConnectorAbi.d.ts.map +1 -0
- package/dist/src/services/executionService/abis/permit2PermitAbi.d.ts +1 -0
- package/dist/src/services/executionService/abis/permit2PermitAbi.d.ts.map +1 -0
- package/dist/src/services/executionService/abis/swapVerifierAbi.d.ts +1 -0
- package/dist/src/services/executionService/abis/swapVerifierAbi.d.ts.map +1 -0
- package/dist/src/services/executionService/abis/swapperAbi.d.ts +1 -0
- package/dist/src/services/executionService/abis/swapperAbi.d.ts.map +1 -0
- package/dist/src/services/executionService/encode.d.ts +30 -0
- package/dist/src/services/executionService/encode.d.ts.map +1 -0
- package/dist/src/services/executionService/encode.js +841 -0
- package/dist/src/services/executionService/encode.js.map +1 -0
- package/dist/src/services/executionService/execute.d.ts +64 -0
- package/dist/src/services/executionService/execute.d.ts.map +1 -0
- package/dist/src/services/executionService/execute.js +181 -0
- package/dist/src/services/executionService/execute.js.map +1 -0
- package/dist/src/services/executionService/executionService.d.ts +192 -38
- package/dist/src/services/executionService/executionService.d.ts.map +1 -0
- package/dist/src/services/executionService/executionService.js +557 -864
- package/dist/src/services/executionService/executionService.js.map +1 -1
- package/dist/src/services/executionService/executionServiceTypes.d.ts +106 -9
- package/dist/src/services/executionService/executionServiceTypes.d.ts.map +1 -0
- package/dist/src/services/executionService/executionServiceTypes.js +6 -0
- package/dist/src/services/executionService/executionServiceTypes.js.map +1 -1
- package/dist/src/services/executionService/index.d.ts +6 -2
- package/dist/src/services/executionService/index.d.ts.map +1 -0
- package/dist/src/services/executionService/index.js +3 -1
- package/dist/src/services/executionService/index.js.map +1 -1
- package/dist/src/services/{simulationService/simulationService.d.ts → executionService/simulate.d.ts} +31 -37
- package/dist/src/services/executionService/simulate.d.ts.map +1 -0
- package/dist/src/services/executionService/simulate.js +531 -0
- package/dist/src/services/executionService/simulate.js.map +1 -0
- package/dist/src/services/feeFlowService/feeFlowService.d.ts +1 -0
- package/dist/src/services/feeFlowService/feeFlowService.d.ts.map +1 -0
- package/dist/src/services/feeFlowService/feeFlowServiceTypes.d.ts +1 -0
- package/dist/src/services/feeFlowService/feeFlowServiceTypes.d.ts.map +1 -0
- package/dist/src/services/feeFlowService/index.d.ts +1 -0
- package/dist/src/services/feeFlowService/index.d.ts.map +1 -0
- package/dist/src/services/intrinsicApyService/adapters/intrinsicApyV3Adapter/index.d.ts +1 -0
- package/dist/src/services/intrinsicApyService/adapters/intrinsicApyV3Adapter/index.d.ts.map +1 -0
- package/dist/src/services/intrinsicApyService/adapters/intrinsicApyV3Adapter/intrinsicApyV3Adapter.d.ts +1 -0
- package/dist/src/services/intrinsicApyService/adapters/intrinsicApyV3Adapter/intrinsicApyV3Adapter.d.ts.map +1 -0
- package/dist/src/services/intrinsicApyService/adapters/intrinsicApyV3Adapter/intrinsicApyV3AdapterTypes.d.ts +2 -1
- package/dist/src/services/intrinsicApyService/adapters/intrinsicApyV3Adapter/intrinsicApyV3AdapterTypes.d.ts.map +1 -0
- package/dist/src/services/intrinsicApyService/index.d.ts +1 -0
- package/dist/src/services/intrinsicApyService/index.d.ts.map +1 -0
- package/dist/src/services/intrinsicApyService/intrinsicApyService.d.ts +1 -0
- package/dist/src/services/intrinsicApyService/intrinsicApyService.d.ts.map +1 -0
- package/dist/src/services/oracleAdapterService/index.d.ts +1 -0
- package/dist/src/services/oracleAdapterService/index.d.ts.map +1 -0
- package/dist/src/services/oracleAdapterService/oracleAdapterService.d.ts +1 -0
- package/dist/src/services/oracleAdapterService/oracleAdapterService.d.ts.map +1 -0
- package/dist/src/services/portfolioService/index.d.ts +3 -0
- package/dist/src/services/portfolioService/index.d.ts.map +1 -0
- package/dist/src/services/portfolioService/index.js +2 -0
- package/dist/src/services/portfolioService/index.js.map +1 -0
- package/dist/src/services/portfolioService/portfolioService.d.ts +18 -0
- package/dist/src/services/portfolioService/portfolioService.d.ts.map +1 -0
- package/dist/src/services/portfolioService/portfolioService.js +21 -0
- package/dist/src/services/portfolioService/portfolioService.js.map +1 -0
- package/dist/src/services/priceService/backendClient.d.ts +1 -2
- package/dist/src/services/priceService/backendClient.d.ts.map +1 -0
- package/dist/src/services/priceService/backendClient.js.map +1 -1
- package/dist/src/services/priceService/index.d.ts +1 -0
- package/dist/src/services/priceService/index.d.ts.map +1 -0
- package/dist/src/services/priceService/priceService.d.ts +1 -0
- package/dist/src/services/priceService/priceService.d.ts.map +1 -0
- package/dist/src/services/priceService/utilsLensPriceAbi.d.ts +1 -0
- package/dist/src/services/priceService/utilsLensPriceAbi.d.ts.map +1 -0
- package/dist/src/services/providerService/index.d.ts +1 -0
- package/dist/src/services/providerService/index.d.ts.map +1 -0
- package/dist/src/services/providerService/providerService.d.ts +1 -0
- package/dist/src/services/providerService/providerService.d.ts.map +1 -0
- package/dist/src/services/rewardsService/adapters/rewardsDirectAdapter/index.d.ts +1 -0
- package/dist/src/services/rewardsService/adapters/rewardsDirectAdapter/index.d.ts.map +1 -0
- package/dist/src/services/rewardsService/adapters/rewardsDirectAdapter/rewardsDirectAdapter.d.ts +1 -0
- package/dist/src/services/rewardsService/adapters/rewardsDirectAdapter/rewardsDirectAdapter.d.ts.map +1 -0
- package/dist/src/services/rewardsService/adapters/rewardsV3Adapter/index.d.ts +1 -0
- package/dist/src/services/rewardsService/adapters/rewardsV3Adapter/index.d.ts.map +1 -0
- package/dist/src/services/rewardsService/adapters/rewardsV3Adapter/rewardsV3Adapter.d.ts +1 -0
- package/dist/src/services/rewardsService/adapters/rewardsV3Adapter/rewardsV3Adapter.d.ts.map +1 -0
- package/dist/src/services/rewardsService/adapters/rewardsV3Adapter/rewardsV3Adapter.js +26 -13
- package/dist/src/services/rewardsService/adapters/rewardsV3Adapter/rewardsV3Adapter.js.map +1 -1
- package/dist/src/services/rewardsService/adapters/rewardsV3Adapter/rewardsV3AdapterTypes.d.ts +11 -10
- package/dist/src/services/rewardsService/adapters/rewardsV3Adapter/rewardsV3AdapterTypes.d.ts.map +1 -0
- package/dist/src/services/rewardsService/index.d.ts +1 -0
- package/dist/src/services/rewardsService/index.d.ts.map +1 -0
- package/dist/src/services/rewardsService/rewardsService.d.ts +1 -0
- package/dist/src/services/rewardsService/rewardsService.d.ts.map +1 -0
- package/dist/src/services/rewardsService/rewardsServiceTypes.d.ts +6 -5
- package/dist/src/services/rewardsService/rewardsServiceTypes.d.ts.map +1 -0
- package/dist/src/services/swapService/index.d.ts +2 -1
- package/dist/src/services/swapService/index.d.ts.map +1 -0
- package/dist/src/services/swapService/swapService.d.ts +34 -2
- package/dist/src/services/swapService/swapService.d.ts.map +1 -0
- package/dist/src/services/swapService/swapService.js +123 -4
- package/dist/src/services/swapService/swapService.js.map +1 -1
- package/dist/src/services/swapService/swapServiceTypes.d.ts +12 -0
- package/dist/src/services/swapService/swapServiceTypes.d.ts.map +1 -0
- package/dist/src/services/swapService/swapVerifierAbi.d.ts +1 -0
- package/dist/src/services/swapService/swapVerifierAbi.d.ts.map +1 -0
- package/dist/src/services/tokenlistService/index.d.ts +1 -0
- package/dist/src/services/tokenlistService/index.d.ts.map +1 -0
- package/dist/src/services/tokenlistService/tokenlistService.d.ts +1 -0
- package/dist/src/services/tokenlistService/tokenlistService.d.ts.map +1 -0
- package/dist/src/services/tokenlistService/tokenlistServiceTypes.d.ts +1 -0
- package/dist/src/services/tokenlistService/tokenlistServiceTypes.d.ts.map +1 -0
- package/dist/src/services/vaults/IVaultService.d.ts +1 -0
- package/dist/src/services/vaults/IVaultService.d.ts.map +1 -0
- package/dist/src/services/vaults/eVaultService/adapters/eVaultOnchainAdapter/abis/vaultLensAbi.d.ts +1 -0
- package/dist/src/services/vaults/eVaultService/adapters/eVaultOnchainAdapter/abis/vaultLensAbi.d.ts.map +1 -0
- package/dist/src/services/vaults/eVaultService/adapters/eVaultOnchainAdapter/eVaultLensTypes.d.ts +1 -0
- package/dist/src/services/vaults/eVaultService/adapters/eVaultOnchainAdapter/eVaultLensTypes.d.ts.map +1 -0
- package/dist/src/services/vaults/eVaultService/adapters/eVaultOnchainAdapter/eVaultOnchainAdapter.d.ts +1 -0
- package/dist/src/services/vaults/eVaultService/adapters/eVaultOnchainAdapter/eVaultOnchainAdapter.d.ts.map +1 -0
- package/dist/src/services/vaults/eVaultService/adapters/eVaultOnchainAdapter/vaultInfoConverter.d.ts +1 -0
- package/dist/src/services/vaults/eVaultService/adapters/eVaultOnchainAdapter/vaultInfoConverter.d.ts.map +1 -0
- package/dist/src/services/vaults/eVaultService/adapters/eVaultV3Adapter/eVaultV3Adapter.d.ts +2 -0
- package/dist/src/services/vaults/eVaultService/adapters/eVaultV3Adapter/eVaultV3Adapter.d.ts.map +1 -0
- package/dist/src/services/vaults/eVaultService/adapters/eVaultV3Adapter/eVaultV3Adapter.js +20 -3
- package/dist/src/services/vaults/eVaultService/adapters/eVaultV3Adapter/eVaultV3Adapter.js.map +1 -1
- package/dist/src/services/vaults/eVaultService/adapters/eVaultV3Adapter/eVaultV3AdapterConversions.d.ts +1 -0
- package/dist/src/services/vaults/eVaultService/adapters/eVaultV3Adapter/eVaultV3AdapterConversions.d.ts.map +1 -0
- package/dist/src/services/vaults/eVaultService/adapters/eVaultV3Adapter/eVaultV3AdapterConversions.js +30 -58
- package/dist/src/services/vaults/eVaultService/adapters/eVaultV3Adapter/eVaultV3AdapterConversions.js.map +1 -1
- package/dist/src/services/vaults/eVaultService/adapters/eVaultV3Adapter/eVaultV3AdapterTypes.d.ts +8 -0
- package/dist/src/services/vaults/eVaultService/adapters/eVaultV3Adapter/eVaultV3AdapterTypes.d.ts.map +1 -0
- package/dist/src/services/vaults/eVaultService/eVaultService.d.ts +1 -0
- package/dist/src/services/vaults/eVaultService/eVaultService.d.ts.map +1 -0
- package/dist/src/services/vaults/eVaultService/eVaultServiceConfig.d.ts +2 -1
- package/dist/src/services/vaults/eVaultService/eVaultServiceConfig.d.ts.map +1 -0
- package/dist/src/services/vaults/eVaultService/index.d.ts +1 -0
- package/dist/src/services/vaults/eVaultService/index.d.ts.map +1 -0
- package/dist/src/services/vaults/eulerEarnService/adapters/abis/eulerEarnVaultLensAbi.d.ts +1 -0
- package/dist/src/services/vaults/eulerEarnService/adapters/abis/eulerEarnVaultLensAbi.d.ts.map +1 -0
- package/dist/src/services/vaults/eulerEarnService/adapters/eulerEarnInfoConverter.d.ts +1 -0
- package/dist/src/services/vaults/eulerEarnService/adapters/eulerEarnInfoConverter.d.ts.map +1 -0
- package/dist/src/services/vaults/eulerEarnService/adapters/eulerEarnLensTypes.d.ts +1 -0
- package/dist/src/services/vaults/eulerEarnService/adapters/eulerEarnLensTypes.d.ts.map +1 -0
- package/dist/src/services/vaults/eulerEarnService/adapters/eulerEarnOnchainAdapter.d.ts +1 -0
- package/dist/src/services/vaults/eulerEarnService/adapters/eulerEarnOnchainAdapter.d.ts.map +1 -0
- package/dist/src/services/vaults/eulerEarnService/adapters/eulerEarnV3Adapter.d.ts +1 -0
- package/dist/src/services/vaults/eulerEarnService/adapters/eulerEarnV3Adapter.d.ts.map +1 -0
- package/dist/src/services/vaults/eulerEarnService/eulerEarnService.d.ts +1 -0
- package/dist/src/services/vaults/eulerEarnService/eulerEarnService.d.ts.map +1 -0
- package/dist/src/services/vaults/eulerEarnService/eulerEarnServiceConfig.d.ts +2 -1
- package/dist/src/services/vaults/eulerEarnService/eulerEarnServiceConfig.d.ts.map +1 -0
- package/dist/src/services/vaults/eulerEarnService/index.d.ts +1 -0
- package/dist/src/services/vaults/eulerEarnService/index.d.ts.map +1 -0
- package/dist/src/services/vaults/index.d.ts +1 -0
- package/dist/src/services/vaults/index.d.ts.map +1 -0
- package/dist/src/services/vaults/securitizeVaultService/adapters/abis/erc4626EvcCollateralSecuritizeAbi.d.ts +1 -0
- package/dist/src/services/vaults/securitizeVaultService/adapters/abis/erc4626EvcCollateralSecuritizeAbi.d.ts.map +1 -0
- package/dist/src/services/vaults/securitizeVaultService/adapters/abis/utilsLensAbi.d.ts +1 -0
- package/dist/src/services/vaults/securitizeVaultService/adapters/abis/utilsLensAbi.d.ts.map +1 -0
- package/dist/src/services/vaults/securitizeVaultService/adapters/securitizeVaultInfoConverter.d.ts +1 -0
- package/dist/src/services/vaults/securitizeVaultService/adapters/securitizeVaultInfoConverter.d.ts.map +1 -0
- package/dist/src/services/vaults/securitizeVaultService/adapters/securitizeVaultLensTypes.d.ts +1 -0
- package/dist/src/services/vaults/securitizeVaultService/adapters/securitizeVaultLensTypes.d.ts.map +1 -0
- package/dist/src/services/vaults/securitizeVaultService/adapters/securitizeVaultOnchainAdapter.d.ts +1 -0
- package/dist/src/services/vaults/securitizeVaultService/adapters/securitizeVaultOnchainAdapter.d.ts.map +1 -0
- package/dist/src/services/vaults/securitizeVaultService/index.d.ts +1 -0
- package/dist/src/services/vaults/securitizeVaultService/index.d.ts.map +1 -0
- package/dist/src/services/vaults/securitizeVaultService/securitizeVaultService.d.ts +1 -0
- package/dist/src/services/vaults/securitizeVaultService/securitizeVaultService.d.ts.map +1 -0
- package/dist/src/services/vaults/vaultMetaService/adapters/IVaultTypeAdapter.d.ts +1 -0
- package/dist/src/services/vaults/vaultMetaService/adapters/IVaultTypeAdapter.d.ts.map +1 -0
- package/dist/src/services/vaults/vaultMetaService/adapters/VaultTypeSubgraphAdapter.d.ts +1 -0
- package/dist/src/services/vaults/vaultMetaService/adapters/VaultTypeSubgraphAdapter.d.ts.map +1 -0
- package/dist/src/services/vaults/vaultMetaService/adapters/VaultTypeV3Adapter.d.ts +2 -1
- package/dist/src/services/vaults/vaultMetaService/adapters/VaultTypeV3Adapter.d.ts.map +1 -0
- package/dist/src/services/vaults/vaultMetaService/index.d.ts +1 -0
- package/dist/src/services/vaults/vaultMetaService/index.d.ts.map +1 -0
- package/dist/src/services/vaults/vaultMetaService/vaultMetaService.d.ts +1 -0
- package/dist/src/services/vaults/vaultMetaService/vaultMetaService.d.ts.map +1 -0
- package/dist/src/services/walletService/adapters/walletOnchainAdapter.d.ts +1 -0
- package/dist/src/services/walletService/adapters/walletOnchainAdapter.d.ts.map +1 -0
- package/dist/src/services/walletService/index.d.ts +1 -0
- package/dist/src/services/walletService/index.d.ts.map +1 -0
- package/dist/src/services/walletService/walletService.d.ts +1 -0
- package/dist/src/services/walletService/walletService.d.ts.map +1 -0
- package/dist/src/utils/accountComputations.d.ts +59 -1
- package/dist/src/utils/accountComputations.d.ts.map +1 -0
- package/dist/src/utils/accountComputations.js +184 -3
- package/dist/src/utils/accountComputations.js.map +1 -1
- package/dist/src/utils/accountPositionClassification.d.ts +15 -0
- package/dist/src/utils/accountPositionClassification.d.ts.map +1 -0
- package/dist/src/utils/accountPositionClassification.js +27 -0
- package/dist/src/utils/accountPositionClassification.js.map +1 -0
- package/dist/src/utils/batch.d.ts +1 -0
- package/dist/src/utils/batch.d.ts.map +1 -0
- package/dist/src/utils/buildQuery.d.ts +1 -0
- package/dist/src/utils/buildQuery.d.ts.map +1 -0
- package/dist/src/utils/callBundler.d.ts +1 -0
- package/dist/src/utils/callBundler.d.ts.map +1 -0
- package/dist/src/utils/decodeSmartContractErrors.d.ts +1 -0
- package/dist/src/utils/decodeSmartContractErrors.d.ts.map +1 -0
- package/dist/src/utils/entityDiagnostics.d.ts +1 -0
- package/dist/src/utils/entityDiagnostics.d.ts.map +1 -0
- package/dist/src/utils/eulerErrorSelectors.d.ts +1 -0
- package/dist/src/utils/eulerErrorSelectors.d.ts.map +1 -0
- package/dist/src/utils/irm.d.ts +1 -0
- package/dist/src/utils/irm.d.ts.map +1 -0
- package/dist/src/utils/normalization.d.ts +1 -0
- package/dist/src/utils/normalization.d.ts.map +1 -0
- package/dist/src/utils/oracle.d.ts +1 -0
- package/dist/src/utils/oracle.d.ts.map +1 -0
- package/dist/src/utils/parsing.d.ts +1 -0
- package/dist/src/utils/parsing.d.ts.map +1 -0
- package/dist/src/utils/queryNames.d.ts +1 -0
- package/dist/src/utils/queryNames.d.ts.map +1 -0
- package/dist/src/utils/stateOverrides/accessList.d.ts +1 -0
- package/dist/src/utils/stateOverrides/accessList.d.ts.map +1 -0
- package/dist/src/utils/stateOverrides/approvalOverrides.d.ts +1 -0
- package/dist/src/utils/stateOverrides/approvalOverrides.d.ts.map +1 -0
- package/dist/src/utils/stateOverrides/balanceOverrides.d.ts +1 -0
- package/dist/src/utils/stateOverrides/balanceOverrides.d.ts.map +1 -0
- package/dist/src/utils/stateOverrides/getStateOverrides.d.ts +1 -0
- package/dist/src/utils/stateOverrides/getStateOverrides.d.ts.map +1 -0
- package/dist/src/utils/stateOverrides/index.d.ts +1 -0
- package/dist/src/utils/stateOverrides/index.d.ts.map +1 -0
- package/dist/src/utils/stateOverrides/mergeStateOverrides.d.ts +1 -0
- package/dist/src/utils/stateOverrides/mergeStateOverrides.d.ts.map +1 -0
- package/dist/src/utils/stateOverrides/types.d.ts +1 -0
- package/dist/src/utils/stateOverrides/types.d.ts.map +1 -0
- package/dist/src/utils/subAccounts.d.ts +14 -0
- package/dist/src/utils/subAccounts.d.ts.map +1 -0
- package/dist/src/utils/subAccounts.js +39 -3
- package/dist/src/utils/subAccounts.js.map +1 -1
- package/dist/src/utils/types.d.ts +1 -0
- package/dist/src/utils/types.d.ts.map +1 -0
- package/package.json +9 -4
- package/dist/src/services/simulationService/index.d.ts +0 -2
- package/dist/src/services/simulationService/index.js +0 -2
- package/dist/src/services/simulationService/index.js.map +0 -1
- package/dist/src/services/simulationService/simulationService.js +0 -497
- package/dist/src/services/simulationService/simulationService.js.map +0 -1
|
@@ -1,28 +1,120 @@
|
|
|
1
|
-
import { encodeFunctionData, getAddress, maxUint256,
|
|
1
|
+
import { decodeFunctionData, encodeFunctionData, erc20Abi, getAddress, maxUint256, maxUint160, } from "viem";
|
|
2
|
+
import { resolveBorrowCollateralPositions } from "../../utils/accountPositionClassification.js";
|
|
2
3
|
import { ethereumVaultConnectorAbi } from "./abis/ethereumVaultConnectorAbi.js";
|
|
3
4
|
import { eVaultAbi } from "./abis/eVaultAbi.js";
|
|
4
5
|
import { permit2PermitAbi } from "./abis/permit2PermitAbi.js";
|
|
5
6
|
import { swapperAbi } from "./abis/swapperAbi.js";
|
|
6
7
|
import { swapVerifierAbi } from "./abis/swapVerifierAbi.js";
|
|
7
|
-
import
|
|
8
|
-
|
|
8
|
+
import * as encodeHelpers from "./encode.js";
|
|
9
|
+
import { isEVCBatchOperation } from "./executionServiceTypes.js";
|
|
10
|
+
import { executeTransactionPlan, } from "./execute.js";
|
|
11
|
+
import { deriveStateOverrides, estimateGasForTransactionPlan, simulateTransactionPlan, } from "./simulate.js";
|
|
12
|
+
const TOKENS_REQUIRING_ZERO_APPROVAL_RESET = {
|
|
13
|
+
1: [getAddress("0xdAC17F958D2ee523a2206206994597C13D831ec7")],
|
|
14
|
+
};
|
|
15
|
+
function requiresZeroApprovalReset(chainId, token) {
|
|
16
|
+
return (TOKENS_REQUIRING_ZERO_APPROVAL_RESET[chainId]?.some((resetToken) => resetToken === getAddress(token)) ?? false);
|
|
17
|
+
}
|
|
18
|
+
function isSavingsCollateral(collateral) {
|
|
19
|
+
return collateral?.source === "savings";
|
|
20
|
+
}
|
|
21
|
+
function isWalletCollateral(collateral) {
|
|
22
|
+
return !!collateral && !isSavingsCollateral(collateral);
|
|
23
|
+
}
|
|
24
|
+
function cloneBatchEntries(entries) {
|
|
25
|
+
return entries.map((entry) => "type" in entry && entry.type === "operation"
|
|
26
|
+
? { type: "operation", name: entry.name, items: [...entry.items] }
|
|
27
|
+
: entry);
|
|
28
|
+
}
|
|
9
29
|
const WAD = 10n ** 18n;
|
|
10
30
|
// TODO explain how this service is coupled to the concrete abis of ERC4626, permit2 and EVK.
|
|
11
31
|
// this is a helper service, not a generic one.
|
|
12
32
|
export class ExecutionService {
|
|
13
33
|
deploymentService;
|
|
14
|
-
walletService;
|
|
15
34
|
plugins = [];
|
|
16
|
-
|
|
35
|
+
walletService;
|
|
36
|
+
providerService;
|
|
37
|
+
vaultMetaService;
|
|
38
|
+
priceService;
|
|
39
|
+
rewardsService;
|
|
40
|
+
intrinsicApyService;
|
|
41
|
+
eulerLabelsService;
|
|
42
|
+
constructor(deploymentService, walletService, providerService, vaultMetaService, priceService, rewardsService, intrinsicApyService, eulerLabelsService) {
|
|
17
43
|
this.deploymentService = deploymentService;
|
|
18
44
|
this.walletService = walletService;
|
|
45
|
+
this.providerService = providerService;
|
|
46
|
+
this.vaultMetaService = vaultMetaService;
|
|
47
|
+
this.priceService = priceService;
|
|
48
|
+
this.rewardsService = rewardsService;
|
|
49
|
+
this.intrinsicApyService = intrinsicApyService;
|
|
50
|
+
this.eulerLabelsService = eulerLabelsService;
|
|
19
51
|
}
|
|
20
52
|
setWalletService(walletService) {
|
|
21
53
|
this.walletService = walletService;
|
|
22
54
|
}
|
|
55
|
+
setProviderService(providerService) {
|
|
56
|
+
this.providerService = providerService;
|
|
57
|
+
}
|
|
58
|
+
setVaultMetaService(vaultMetaService) {
|
|
59
|
+
this.vaultMetaService = vaultMetaService;
|
|
60
|
+
}
|
|
61
|
+
setPriceService(priceService) {
|
|
62
|
+
this.priceService = priceService;
|
|
63
|
+
}
|
|
64
|
+
setRewardsService(rewardsService) {
|
|
65
|
+
this.rewardsService = rewardsService;
|
|
66
|
+
}
|
|
67
|
+
setIntrinsicApyService(intrinsicApyService) {
|
|
68
|
+
this.intrinsicApyService = intrinsicApyService;
|
|
69
|
+
}
|
|
70
|
+
setEulerLabelsService(eulerLabelsService) {
|
|
71
|
+
this.eulerLabelsService = eulerLabelsService;
|
|
72
|
+
}
|
|
23
73
|
setPlugins(plugins) {
|
|
24
74
|
this.plugins = plugins;
|
|
25
75
|
}
|
|
76
|
+
/** Derive storage overrides needed to simulate the plan against the current account state. */
|
|
77
|
+
async deriveStateOverrides(chainId, account, transactionPlan, options) {
|
|
78
|
+
return deriveStateOverrides(this.getSimulationContext(), chainId, account, transactionPlan, options);
|
|
79
|
+
}
|
|
80
|
+
/** Simulate the full transaction plan, including approval resolution and plugin-aware batch execution. */
|
|
81
|
+
async simulateTransactionPlan(chainId, account, transactionPlan, options) {
|
|
82
|
+
return simulateTransactionPlan(this.getSimulationContext(), chainId, account, transactionPlan, options);
|
|
83
|
+
}
|
|
84
|
+
/** Estimate gas for the full transaction plan after applying the same simulation pipeline used for execution. */
|
|
85
|
+
async estimateGasForTransactionPlan(chainId, account, transactionPlan, options) {
|
|
86
|
+
return estimateGasForTransactionPlan(this.getSimulationContext(), chainId, account, transactionPlan, options);
|
|
87
|
+
}
|
|
88
|
+
/** Execute a transaction plan using caller-provided signing and send callbacks. */
|
|
89
|
+
async executeTransactionPlan(args) {
|
|
90
|
+
const { providerService } = this;
|
|
91
|
+
if (!providerService) {
|
|
92
|
+
throw new Error("ExecutionService.executeTransactionPlan requires a providerService. Pass it to the ExecutionService constructor or call setProviderService().");
|
|
93
|
+
}
|
|
94
|
+
const helperArgs = {
|
|
95
|
+
...args,
|
|
96
|
+
executionService: this,
|
|
97
|
+
deploymentService: this.deploymentService,
|
|
98
|
+
providerService,
|
|
99
|
+
};
|
|
100
|
+
return executeTransactionPlan(helperArgs);
|
|
101
|
+
}
|
|
102
|
+
getSimulationContext() {
|
|
103
|
+
return {
|
|
104
|
+
deploymentService: this.deploymentService,
|
|
105
|
+
walletService: this.walletService,
|
|
106
|
+
providerService: this.providerService,
|
|
107
|
+
vaultMetaService: this.vaultMetaService,
|
|
108
|
+
priceService: this.priceService,
|
|
109
|
+
rewardsService: this.rewardsService,
|
|
110
|
+
intrinsicApyService: this.intrinsicApyService,
|
|
111
|
+
eulerLabelsService: this.eulerLabelsService,
|
|
112
|
+
describeBatch: (batch) => this.describeBatch(batch),
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
getCoreAddresses(chainId) {
|
|
116
|
+
return this.deploymentService.getDeployment(chainId).addresses.coreAddrs;
|
|
117
|
+
}
|
|
26
118
|
/**
|
|
27
119
|
* Encodes an array of EVC batch items into a single calldata hex for `EVC.batch()`.
|
|
28
120
|
*
|
|
@@ -30,11 +122,7 @@ export class ExecutionService {
|
|
|
30
122
|
* @returns Encoded calldata hex for the EVC batch call
|
|
31
123
|
*/
|
|
32
124
|
encodeBatch(items) {
|
|
33
|
-
return
|
|
34
|
-
abi: ethereumVaultConnectorAbi,
|
|
35
|
-
functionName: "batch",
|
|
36
|
-
args: [items],
|
|
37
|
-
});
|
|
125
|
+
return encodeHelpers.encodeBatch(items);
|
|
38
126
|
}
|
|
39
127
|
/**
|
|
40
128
|
* Encodes EVC batch items for depositing underlying assets into a vault (mints shares to receiver).
|
|
@@ -49,33 +137,9 @@ export class ExecutionService {
|
|
|
49
137
|
* @param args.permit2 - Optional Permit2 message + signature; if set, prepends a permit2 permit call so transferFrom can be used
|
|
50
138
|
* @returns Array of EVC batch items (optional permit2, optional enableCollateral, deposit)
|
|
51
139
|
*/
|
|
52
|
-
encodeDeposit({ chainId,
|
|
53
|
-
const
|
|
54
|
-
|
|
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;
|
|
140
|
+
encodeDeposit({ chainId, ...args }) {
|
|
141
|
+
const { evc, permit2 } = this.getCoreAddresses(chainId);
|
|
142
|
+
return encodeHelpers.encodeDeposit(evc, permit2, { chainId, ...args });
|
|
79
143
|
}
|
|
80
144
|
/**
|
|
81
145
|
* Encodes EVC batch items for minting vault shares by depositing underlying assets.
|
|
@@ -90,33 +154,9 @@ export class ExecutionService {
|
|
|
90
154
|
* @param args.permit2 - Optional Permit2 message + signature for transferFrom
|
|
91
155
|
* @returns Array of EVC batch items (optional permit2, optional enableCollateral, mint)
|
|
92
156
|
*/
|
|
93
|
-
encodeMint({ chainId,
|
|
94
|
-
const
|
|
95
|
-
|
|
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;
|
|
157
|
+
encodeMint({ chainId, ...args }) {
|
|
158
|
+
const { evc, permit2 } = this.getCoreAddresses(chainId);
|
|
159
|
+
return encodeHelpers.encodeMint(evc, permit2, { chainId, ...args });
|
|
120
160
|
}
|
|
121
161
|
/**
|
|
122
162
|
* Encodes EVC batch items for withdrawing underlying assets from a vault (burns shares).
|
|
@@ -130,24 +170,9 @@ export class ExecutionService {
|
|
|
130
170
|
* @param args.disableCollateral - If true, appends disableCollateral( owner, vault ) via EVC before withdraw
|
|
131
171
|
* @returns Array of EVC batch items (optional disableCollateral, withdraw)
|
|
132
172
|
*/
|
|
133
|
-
encodeWithdraw({ chainId,
|
|
134
|
-
const
|
|
135
|
-
|
|
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;
|
|
173
|
+
encodeWithdraw({ chainId, ...args }) {
|
|
174
|
+
const { evc } = this.getCoreAddresses(chainId);
|
|
175
|
+
return encodeHelpers.encodeWithdraw(evc, { chainId, ...args });
|
|
151
176
|
}
|
|
152
177
|
/**
|
|
153
178
|
* Encodes EVC batch items for redeeming vault shares for underlying assets.
|
|
@@ -161,24 +186,9 @@ export class ExecutionService {
|
|
|
161
186
|
* @param args.disableCollateral - If true, prepends disableCollateral( owner, vault ) via EVC
|
|
162
187
|
* @returns Array of EVC batch items (optional disableCollateral, redeem)
|
|
163
188
|
*/
|
|
164
|
-
encodeRedeem({ chainId,
|
|
165
|
-
const
|
|
166
|
-
|
|
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;
|
|
189
|
+
encodeRedeem({ chainId, ...args }) {
|
|
190
|
+
const { evc } = this.getCoreAddresses(chainId);
|
|
191
|
+
return encodeHelpers.encodeRedeem(evc, { chainId, ...args });
|
|
182
192
|
}
|
|
183
193
|
/**
|
|
184
194
|
* Encodes EVC batch items for borrowing from a liability vault, optionally depositing collateral in the same batch.
|
|
@@ -199,42 +209,8 @@ export class ExecutionService {
|
|
|
199
209
|
* @returns Array of EVC batch items (optional deposit, optional disableController, optional enableController, borrow)
|
|
200
210
|
*/
|
|
201
211
|
encodeBorrow(args) {
|
|
202
|
-
const {
|
|
203
|
-
|
|
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;
|
|
212
|
+
const { evc, permit2 } = this.getCoreAddresses(args.chainId);
|
|
213
|
+
return encodeHelpers.encodeBorrow(evc, permit2, args);
|
|
238
214
|
}
|
|
239
215
|
/**
|
|
240
216
|
* Encodes EVC batch items for liquidating an undercollateralized account (repay debt, seize collateral).
|
|
@@ -251,28 +227,9 @@ export class ExecutionService {
|
|
|
251
227
|
* @param args.enableCollateral - If true, enables collateral vault for liquidator sub-account after liquidate (default true)
|
|
252
228
|
* @returns Array of EVC batch items (optional enableController, liquidate, optional enableCollateral)
|
|
253
229
|
*/
|
|
254
|
-
encodeLiquidation({ chainId,
|
|
255
|
-
const
|
|
256
|
-
|
|
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;
|
|
230
|
+
encodeLiquidation({ chainId, ...args }) {
|
|
231
|
+
const { evc } = this.getCoreAddresses(chainId);
|
|
232
|
+
return encodeHelpers.encodeLiquidation(evc, { chainId, ...args });
|
|
276
233
|
}
|
|
277
234
|
/**
|
|
278
235
|
* Encodes EVC batch items for pulling debt from one sub-account to another on the same liability vault.
|
|
@@ -286,24 +243,9 @@ export class ExecutionService {
|
|
|
286
243
|
* @param args.enableController - If true, enables vault as controller for `to` via EVC before pullDebt (default true)
|
|
287
244
|
* @returns Array of EVC batch items (optional enableController, pullDebt)
|
|
288
245
|
*/
|
|
289
|
-
encodePullDebt({ chainId,
|
|
290
|
-
const
|
|
291
|
-
|
|
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;
|
|
246
|
+
encodePullDebt({ chainId, ...args }) {
|
|
247
|
+
const { evc } = this.getCoreAddresses(chainId);
|
|
248
|
+
return encodeHelpers.encodePullDebt(evc, { chainId, ...args });
|
|
307
249
|
}
|
|
308
250
|
/**
|
|
309
251
|
* Encodes EVC batch items for a multiply/leverage operation when liability and long asset differ (swap required).
|
|
@@ -327,77 +269,8 @@ export class ExecutionService {
|
|
|
327
269
|
* @returns Array of EVC batch items
|
|
328
270
|
*/
|
|
329
271
|
encodeMultiplyWithSwap(args) {
|
|
330
|
-
const {
|
|
331
|
-
|
|
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;
|
|
272
|
+
const { evc, permit2 } = this.getCoreAddresses(args.chainId);
|
|
273
|
+
return encodeHelpers.encodeMultiplyWithSwap(evc, permit2, args);
|
|
401
274
|
}
|
|
402
275
|
/**
|
|
403
276
|
* Encodes EVC batch items for a multiply/leverage operation when liability and long asset are the same (no swap).
|
|
@@ -420,71 +293,8 @@ export class ExecutionService {
|
|
|
420
293
|
* @returns Array of EVC batch items
|
|
421
294
|
*/
|
|
422
295
|
encodeMultiplySameAsset(args) {
|
|
423
|
-
const {
|
|
424
|
-
|
|
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;
|
|
296
|
+
const { evc, permit2 } = this.getCoreAddresses(args.chainId);
|
|
297
|
+
return encodeHelpers.encodeMultiplySameAsset(evc, permit2, args);
|
|
488
298
|
}
|
|
489
299
|
/**
|
|
490
300
|
* Encodes EVC batch items for repaying debt using assets from the sender's wallet (transferFrom to vault then repay).
|
|
@@ -501,41 +311,16 @@ export class ExecutionService {
|
|
|
501
311
|
* @returns Array of EVC batch items (optional permit2, repay, optional disableController)
|
|
502
312
|
*/
|
|
503
313
|
encodeRepayFromWallet(args) {
|
|
504
|
-
const {
|
|
505
|
-
|
|
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;
|
|
314
|
+
const { permit2 } = this.getCoreAddresses(args.chainId);
|
|
315
|
+
return encodeHelpers.encodeRepayFromWallet(permit2, args);
|
|
532
316
|
}
|
|
533
317
|
/**
|
|
534
318
|
* Encodes EVC batch items for repaying debt from a deposit (same-asset only).
|
|
535
|
-
* Path 1: same asset and same vault → repayWithShares.
|
|
319
|
+
* Path 1: same asset and same vault → repayWithShares.
|
|
320
|
+
* Path 2: same asset, different vault → withdraw to liability vault, skim, then repayWithShares.
|
|
536
321
|
*
|
|
537
322
|
* @param args - Repay-from-deposit encoding arguments
|
|
538
|
-
* @param args.chainId - Chain ID
|
|
323
|
+
* @param args.chainId - Chain ID used for EVC controller calls
|
|
539
324
|
* @param args.liabilityVault - Vault (liability) to repay debt to
|
|
540
325
|
* @param args.liabilityAsset - Underlying asset address of the liability vault
|
|
541
326
|
* @param args.liabilityAmount - Amount of liability to repay (maxUint256 with isMax for full repay)
|
|
@@ -545,37 +330,10 @@ export class ExecutionService {
|
|
|
545
330
|
* @param args.fromAsset - Underlying asset of fromVault (must equal liabilityAsset)
|
|
546
331
|
* @param args.disableControllerOnMax - When isMax, whether to disable controller for receiver (default true)
|
|
547
332
|
* @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
333
|
* @returns Array of EVC batch items. Throws if fromAsset !== liabilityAsset.
|
|
550
334
|
*/
|
|
551
335
|
encodeRepayFromDeposit(args) {
|
|
552
|
-
|
|
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");
|
|
336
|
+
return encodeHelpers.encodeRepayFromDeposit(args);
|
|
579
337
|
}
|
|
580
338
|
/**
|
|
581
339
|
* Encodes EVC batch items for repaying debt by swapping collateral (withdraw from vaultIn → swap → verify/repay debtMax).
|
|
@@ -590,50 +348,7 @@ export class ExecutionService {
|
|
|
590
348
|
* @returns Array of EVC batch items (withdraw, swap, verify/repay, optional disableController)
|
|
591
349
|
*/
|
|
592
350
|
encodeRepayWithSwap(args) {
|
|
593
|
-
|
|
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;
|
|
351
|
+
return encodeHelpers.encodeRepayWithSwap(args);
|
|
637
352
|
}
|
|
638
353
|
/**
|
|
639
354
|
* Encodes EVC batch items for depositing into a vault using tokens from the user's wallet, going through a swap.
|
|
@@ -648,42 +363,24 @@ export class ExecutionService {
|
|
|
648
363
|
* @returns Array of EVC batch items (transferFromSender, swap, verify, optional enableCollateral)
|
|
649
364
|
*/
|
|
650
365
|
encodeDepositWithSwapFromWallet(args) {
|
|
651
|
-
const {
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
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;
|
|
366
|
+
const { evc } = this.getCoreAddresses(args.chainId);
|
|
367
|
+
return encodeHelpers.encodeDepositWithSwapFromWallet(evc, args);
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Encodes EVC batch items for swapping a token from the sender's wallet into another token
|
|
371
|
+
* and transferring the output to `swapQuote.receiver`.
|
|
372
|
+
* The approval is given to SwapVerifier, then transferFromSender pulls tokens to Swapper,
|
|
373
|
+
* swap executes, and verifyAmountMinAndTransfer sends the output to the receiver wallet.
|
|
374
|
+
*
|
|
375
|
+
* @param args - Wallet-swap encoding arguments
|
|
376
|
+
* @param args.chainId - Chain ID (unused, kept for encode API symmetry)
|
|
377
|
+
* @param args.swapQuote - Quote with swap and verify steps (verify type transferMin)
|
|
378
|
+
* @param args.amount - Amount of input token to transfer from wallet to swapper
|
|
379
|
+
* @param args.sender - Wallet address providing the tokens (onBehalfOfAccount for transferFromSender)
|
|
380
|
+
* @returns Array of EVC batch items (transferFromSender, swap, verify)
|
|
381
|
+
*/
|
|
382
|
+
encodeSwapFromWallet(args) {
|
|
383
|
+
return encodeHelpers.encodeSwapFromWallet(args);
|
|
687
384
|
}
|
|
688
385
|
/**
|
|
689
386
|
* Encodes EVC batch items for swapping collateral: withdraw from vaultIn → swap → verify/skim to receiver; optional enable/disable collateral.
|
|
@@ -698,50 +395,8 @@ export class ExecutionService {
|
|
|
698
395
|
* @returns Array of EVC batch items (withdraw, swap, verify/skim, optional disableCollateral, optional enableCollateral)
|
|
699
396
|
*/
|
|
700
397
|
encodeSwapCollateral(args) {
|
|
701
|
-
const {
|
|
702
|
-
|
|
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;
|
|
398
|
+
const { evc } = this.getCoreAddresses(args.chainId);
|
|
399
|
+
return encodeHelpers.encodeSwapCollateral(evc, args);
|
|
745
400
|
}
|
|
746
401
|
/**
|
|
747
402
|
* Encodes EVC batch items for swapping debt: enableController → borrow from vaultIn → swap → verify/repay (debtMax).
|
|
@@ -755,46 +410,51 @@ export class ExecutionService {
|
|
|
755
410
|
* @param args.isMax - If true, treats as full debt swap (can trigger disableControllerOnMax)
|
|
756
411
|
* @returns Array of EVC batch items (optional enableController, borrow, swap, verify/repay, optional disableController)
|
|
757
412
|
*/
|
|
758
|
-
encodeSwapDebt(
|
|
759
|
-
const
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
413
|
+
encodeSwapDebt(args) {
|
|
414
|
+
const { evc } = this.getCoreAddresses(args.chainId);
|
|
415
|
+
return encodeHelpers.encodeSwapDebt(evc, args);
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Encodes EVC batch items for migrating a supplied/collateral position between two same-asset vaults.
|
|
419
|
+
* Partial migration uses withdraw(amount, toVault, account) then skim(amount, account).
|
|
420
|
+
* Max migration uses redeem(maxShares || maxUint256, toVault, account) then skim(amount, account).
|
|
421
|
+
*
|
|
422
|
+
* @param args - Same-asset collateral migration encoding arguments
|
|
423
|
+
* @param args.chainId - Chain ID (used for EVC enable/disable collateral)
|
|
424
|
+
* @param args.fromVault - Source vault holding the supplied shares
|
|
425
|
+
* @param args.toVault - Destination vault with the same underlying asset
|
|
426
|
+
* @param args.amount - Asset amount expected to arrive at the destination vault and be skimmed
|
|
427
|
+
* @param args.account - Sub-account that owns the source shares and receives destination shares
|
|
428
|
+
* @param args.isMax - If true, redeems shares instead of withdrawing assets
|
|
429
|
+
* @param args.maxShares - Optional exact share amount for max migration; defaults to maxUint256
|
|
430
|
+
* @param args.enableCollateralTo - If true, enables the destination vault as collateral after skim
|
|
431
|
+
* @param args.disableCollateralFrom - If true, disables the source vault as collateral after enabling the destination
|
|
432
|
+
* @returns Array of EVC batch items
|
|
433
|
+
*/
|
|
434
|
+
encodeMigrateSameAssetCollateral(args) {
|
|
435
|
+
const { evc } = this.getCoreAddresses(args.chainId);
|
|
436
|
+
return encodeHelpers.encodeMigrateSameAssetCollateral(evc, args);
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Encodes EVC batch items for migrating a full debt position between two same-asset liability vaults.
|
|
440
|
+
* Flow: enable new controller → borrow with interest cushion to old vault → skim → repay old debt with shares
|
|
441
|
+
* → disable old controller → optionally sweep cushion to the new vault → optionally transfer remaining new-vault shares.
|
|
442
|
+
*
|
|
443
|
+
* @param args - Same-asset debt migration encoding arguments
|
|
444
|
+
* @param args.chainId - Chain ID (used for EVC enable controller)
|
|
445
|
+
* @param args.oldLiabilityVault - Existing debt vault to fully repay and disable
|
|
446
|
+
* @param args.newLiabilityVault - New same-asset debt vault to borrow from
|
|
447
|
+
* @param args.amount - Current debt amount before applying the 0.01% interest cushion
|
|
448
|
+
* @param args.account - Sub-account that owns the debt position
|
|
449
|
+
* @param args.enableController - If true, enables the new liability vault as controller first
|
|
450
|
+
* @param args.disableController - If true, disables the old liability vault after repayment
|
|
451
|
+
* @param args.sweepExcess - If true, redeems any old-vault cushion shares back to the new vault and skims them
|
|
452
|
+
* @param args.transferRemainingSharesTo - If set, transfers all new-vault shares from the sub-account to this address
|
|
453
|
+
* @returns Array of EVC batch items
|
|
454
|
+
*/
|
|
455
|
+
encodeMigrateSameAssetDebt(args) {
|
|
456
|
+
const { evc } = this.getCoreAddresses(args.chainId);
|
|
457
|
+
return encodeHelpers.encodeMigrateSameAssetDebt(evc, args);
|
|
798
458
|
}
|
|
799
459
|
/**
|
|
800
460
|
* Encodes EVC batch items for transferring vault shares between sub-accounts.
|
|
@@ -809,28 +469,9 @@ export class ExecutionService {
|
|
|
809
469
|
* @param args.disableCollateralFrom - If true, prepends disableCollateral( from, vault ) via EVC before transfer
|
|
810
470
|
* @returns Array of EVC batch items (optional disableCollateralFrom, transfer, optional enableCollateralTo)
|
|
811
471
|
*/
|
|
812
|
-
encodeTransfer({ chainId,
|
|
813
|
-
const
|
|
814
|
-
|
|
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;
|
|
472
|
+
encodeTransfer({ chainId, ...args }) {
|
|
473
|
+
const { evc } = this.getCoreAddresses(chainId);
|
|
474
|
+
return encodeHelpers.encodeTransfer(evc, { chainId, ...args });
|
|
834
475
|
}
|
|
835
476
|
/**
|
|
836
477
|
* Encodes a single EVC batch item that calls Permit2's `permit` with the given message and signature.
|
|
@@ -844,73 +485,23 @@ export class ExecutionService {
|
|
|
844
485
|
* @returns Single EVC batch item (targetContract = Permit2, permit call)
|
|
845
486
|
*/
|
|
846
487
|
encodePermit2Call(args) {
|
|
847
|
-
const {
|
|
848
|
-
|
|
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
|
-
};
|
|
488
|
+
const { permit2 } = this.getCoreAddresses(args.chainId);
|
|
489
|
+
return encodeHelpers.encodePermit2Call(permit2, args);
|
|
860
490
|
}
|
|
861
491
|
encodeEnableCollateral(chainId, account, vault) {
|
|
862
|
-
const
|
|
863
|
-
|
|
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
|
-
};
|
|
492
|
+
const { evc } = this.getCoreAddresses(chainId);
|
|
493
|
+
return encodeHelpers.encodeEnableCollateral(evc, account, vault);
|
|
874
494
|
}
|
|
875
495
|
encodeDisableCollateral(chainId, account, vault) {
|
|
876
|
-
const
|
|
877
|
-
|
|
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
|
-
};
|
|
496
|
+
const { evc } = this.getCoreAddresses(chainId);
|
|
497
|
+
return encodeHelpers.encodeDisableCollateral(evc, account, vault);
|
|
888
498
|
}
|
|
889
499
|
encodeEnableController(chainId, account, vault) {
|
|
890
|
-
const
|
|
891
|
-
|
|
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
|
-
};
|
|
500
|
+
const { evc } = this.getCoreAddresses(chainId);
|
|
501
|
+
return encodeHelpers.encodeEnableController(evc, account, vault);
|
|
902
502
|
}
|
|
903
503
|
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
|
-
};
|
|
504
|
+
return encodeHelpers.encodeDisableController(vault, account);
|
|
914
505
|
}
|
|
915
506
|
/**
|
|
916
507
|
* Builds EIP-712 typed data for a Permit2 PermitSingle signature (token approval for a spender).
|
|
@@ -927,46 +518,10 @@ export class ExecutionService {
|
|
|
927
518
|
* @returns EIP-712 typed data (domain, types, primaryType, message) for signing
|
|
928
519
|
*/
|
|
929
520
|
getPermit2TypedData(args) {
|
|
930
|
-
const
|
|
931
|
-
|
|
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
|
-
};
|
|
521
|
+
const { permit2 } = this.getCoreAddresses(args.chainId);
|
|
522
|
+
return encodeHelpers.getPermit2TypedData(permit2, args);
|
|
954
523
|
}
|
|
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
524
|
describeBatch(batch, extraAbis) {
|
|
969
|
-
const decodedBatchItems = [];
|
|
970
525
|
const executionDecodeAbis = [
|
|
971
526
|
...(extraAbis ?? []),
|
|
972
527
|
ethereumVaultConnectorAbi,
|
|
@@ -975,7 +530,7 @@ export class ExecutionService {
|
|
|
975
530
|
swapperAbi,
|
|
976
531
|
swapVerifierAbi,
|
|
977
532
|
];
|
|
978
|
-
|
|
533
|
+
const decodeBatchItem = (item) => {
|
|
979
534
|
let decoded = false;
|
|
980
535
|
for (const abi of executionDecodeAbis) {
|
|
981
536
|
try {
|
|
@@ -1000,14 +555,13 @@ export class ExecutionService {
|
|
|
1000
555
|
}
|
|
1001
556
|
});
|
|
1002
557
|
}
|
|
1003
|
-
|
|
558
|
+
decoded = true;
|
|
559
|
+
return {
|
|
1004
560
|
targetContract: item.targetContract,
|
|
1005
561
|
onBehalfOfAccount: item.onBehalfOfAccount,
|
|
1006
562
|
functionName: decodedData.functionName,
|
|
1007
563
|
args: namedArgs,
|
|
1008
|
-
}
|
|
1009
|
-
decoded = true;
|
|
1010
|
-
break;
|
|
564
|
+
};
|
|
1011
565
|
}
|
|
1012
566
|
catch { }
|
|
1013
567
|
}
|
|
@@ -1019,29 +573,35 @@ export class ExecutionService {
|
|
|
1019
573
|
try {
|
|
1020
574
|
const result = plugin.decodeBatchItem(item);
|
|
1021
575
|
if (result) {
|
|
1022
|
-
decodedBatchItems.push(result);
|
|
1023
576
|
decoded = true;
|
|
1024
|
-
|
|
577
|
+
return result;
|
|
1025
578
|
}
|
|
1026
579
|
}
|
|
1027
580
|
catch { }
|
|
1028
581
|
}
|
|
1029
582
|
}
|
|
1030
583
|
if (!decoded) {
|
|
1031
|
-
|
|
584
|
+
return {
|
|
1032
585
|
targetContract: item.targetContract,
|
|
1033
586
|
onBehalfOfAccount: item.onBehalfOfAccount,
|
|
1034
587
|
functionName: "Unknown",
|
|
1035
588
|
args: {},
|
|
1036
|
-
}
|
|
589
|
+
};
|
|
1037
590
|
}
|
|
1038
|
-
|
|
1039
|
-
|
|
591
|
+
throw new Error("unreachable batch item decode state");
|
|
592
|
+
};
|
|
593
|
+
return batch.map((entry) => isEVCBatchOperation(entry)
|
|
594
|
+
? {
|
|
595
|
+
type: "operation",
|
|
596
|
+
name: entry.name,
|
|
597
|
+
items: entry.items.map(decodeBatchItem),
|
|
598
|
+
}
|
|
599
|
+
: decodeBatchItem(entry));
|
|
1040
600
|
}
|
|
1041
601
|
/**
|
|
1042
602
|
* Merges multiple transaction plans into a single plan.
|
|
1043
603
|
* Required approvals for the same (token, owner, spender) are summed.
|
|
1044
|
-
* Executable items are preserved in order; adjacent EVC
|
|
604
|
+
* Executable items are preserved in order; adjacent EVC batches are concatenated without flattening operation groupings.
|
|
1045
605
|
* Can be used to construct a transaction queue.
|
|
1046
606
|
*
|
|
1047
607
|
* @param plans - Array of transaction plans to merge
|
|
@@ -1067,19 +627,37 @@ export class ExecutionService {
|
|
|
1067
627
|
else if (item.type === "evcBatch") {
|
|
1068
628
|
const previous = executableItems[executableItems.length - 1];
|
|
1069
629
|
if (previous?.type === "evcBatch") {
|
|
1070
|
-
previous.items.push(...item.items);
|
|
630
|
+
previous.items.push(...cloneBatchEntries(item.items));
|
|
1071
631
|
}
|
|
1072
632
|
else {
|
|
1073
|
-
executableItems.push({
|
|
633
|
+
executableItems.push({
|
|
634
|
+
type: "evcBatch",
|
|
635
|
+
items: cloneBatchEntries(item.items),
|
|
636
|
+
});
|
|
1074
637
|
}
|
|
1075
638
|
}
|
|
1076
639
|
else {
|
|
1077
|
-
|
|
640
|
+
throw new Error("ExecutionService.mergePlans cannot merge contractCall plan items. Merge these plans manually to preserve call boundaries.");
|
|
1078
641
|
}
|
|
1079
642
|
}
|
|
1080
643
|
}
|
|
1081
644
|
return [...approvalByKey.values(), ...executableItems];
|
|
1082
645
|
}
|
|
646
|
+
/**
|
|
647
|
+
* Appends a raw batch item to the last EVC batch in the plan, or creates one.
|
|
648
|
+
* Mutates and returns the provided plan.
|
|
649
|
+
*/
|
|
650
|
+
addBatchItemToPlan(plan, item) {
|
|
651
|
+
for (let index = plan.length - 1; index >= 0; index--) {
|
|
652
|
+
const planItem = plan[index];
|
|
653
|
+
if (planItem?.type === "evcBatch") {
|
|
654
|
+
planItem.items.push(item);
|
|
655
|
+
return plan;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
plan.push({ type: "evcBatch", items: [item] });
|
|
659
|
+
return plan;
|
|
660
|
+
}
|
|
1083
661
|
/**
|
|
1084
662
|
* Converts EVC batch items into a transaction plan.
|
|
1085
663
|
* Returns a plan with a single evcBatch containing the given items (no required approvals).
|
|
@@ -1088,117 +666,50 @@ export class ExecutionService {
|
|
|
1088
666
|
* @param items - EVC batch items to wrap in a plan
|
|
1089
667
|
* @returns Transaction plan containing one evcBatch with the items
|
|
1090
668
|
*/
|
|
1091
|
-
convertBatchItemsToPlan(items) {
|
|
669
|
+
convertBatchItemsToPlan(items, operationName) {
|
|
1092
670
|
if (items.length === 0)
|
|
1093
671
|
return [];
|
|
672
|
+
if (operationName) {
|
|
673
|
+
return [
|
|
674
|
+
{
|
|
675
|
+
type: "evcBatch",
|
|
676
|
+
items: [{ type: "operation", name: operationName, items }],
|
|
677
|
+
},
|
|
678
|
+
];
|
|
679
|
+
}
|
|
1094
680
|
return [{ type: "evcBatch", items }];
|
|
1095
681
|
}
|
|
1096
|
-
|
|
1097
|
-
|
|
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;
|
|
682
|
+
encodeTransferFromMax(vault, from, to) {
|
|
683
|
+
return encodeHelpers.encodeTransferFromMax(vault, from, to);
|
|
1117
684
|
}
|
|
1118
685
|
/**
|
|
1119
|
-
*
|
|
686
|
+
* Appends post-full-repay cleanup calls owned by plan builders:
|
|
687
|
+
* disable each active collateral used by the repaid borrow, transfer those collateral shares to the owner,
|
|
688
|
+
* and, when a source deposit funded the repay, transfer any remaining source-vault shares to the owner.
|
|
1120
689
|
*/
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
const
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
if (
|
|
1133
|
-
|
|
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));
|
|
690
|
+
appendMaxRepayCleanup(args) {
|
|
691
|
+
const { account, liabilityPosition, receiver, batchItems, sourceAccount, sourceVault, } = args;
|
|
692
|
+
const receiverSubAccount = typeof account.getSubAccount === "function"
|
|
693
|
+
? account.getSubAccount(receiver)
|
|
694
|
+
: undefined;
|
|
695
|
+
const activeCollaterals = receiverSubAccount
|
|
696
|
+
? resolveBorrowCollateralPositions(receiverSubAccount, liabilityPosition)
|
|
697
|
+
: [];
|
|
698
|
+
const transferredPositions = new Set();
|
|
699
|
+
for (const collateral of activeCollaterals) {
|
|
700
|
+
batchItems.push(this.encodeDisableCollateral(account.chainId, receiver, collateral.vaultAddress));
|
|
701
|
+
if (getAddress(receiver) !== getAddress(account.owner)) {
|
|
702
|
+
batchItems.push(this.encodeTransferFromMax(collateral.vaultAddress, receiver, account.owner));
|
|
1173
703
|
}
|
|
704
|
+
transferredPositions.add(`${getAddress(receiver)}:${getAddress(collateral.vaultAddress)}`);
|
|
1174
705
|
}
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
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);
|
|
706
|
+
if (sourceAccount && sourceVault) {
|
|
707
|
+
const sourcePositionKey = `${getAddress(sourceAccount)}:${getAddress(sourceVault)}`;
|
|
708
|
+
if (getAddress(sourceAccount) !== getAddress(account.owner) &&
|
|
709
|
+
!transferredPositions.has(sourcePositionKey)) {
|
|
710
|
+
batchItems.push(this.encodeTransferFromMax(sourceVault, sourceAccount, account.owner));
|
|
711
|
+
}
|
|
1200
712
|
}
|
|
1201
|
-
return items;
|
|
1202
713
|
}
|
|
1203
714
|
/**
|
|
1204
715
|
* Resolves RequiredApproval items in a transaction plan by filling in each item's `resolved` field.
|
|
@@ -1237,6 +748,13 @@ export class ExecutionService {
|
|
|
1237
748
|
args: [approvalSpender, approvalAmount],
|
|
1238
749
|
}),
|
|
1239
750
|
});
|
|
751
|
+
const addApproveWithOptionalReset = (approvalSpender, approvalAmount, currentAllowance) => {
|
|
752
|
+
if (currentAllowance > 0n &&
|
|
753
|
+
requiresZeroApprovalReset(chainId, token)) {
|
|
754
|
+
resolvedItems.push(makeApprove(approvalSpender, 0n));
|
|
755
|
+
}
|
|
756
|
+
resolvedItems.push(makeApprove(approvalSpender, approvalAmount));
|
|
757
|
+
};
|
|
1240
758
|
const makePermit2 = (permit2Spender, permit2Amount) => ({
|
|
1241
759
|
type: "permit2",
|
|
1242
760
|
token,
|
|
@@ -1275,7 +793,7 @@ export class ExecutionService {
|
|
|
1275
793
|
}
|
|
1276
794
|
// If assetForPermit2 is insufficient, we need both approval and permit2 signature
|
|
1277
795
|
if (!hasSufficientPermit2Allowance) {
|
|
1278
|
-
|
|
796
|
+
addApproveWithOptionalReset(permit2, unlimitedApproval ? maxUint256 : amount, assetForPermit2);
|
|
1279
797
|
resolvedItems.push(makePermit2(spender, unlimitedApproval ? maxUint160 : amount));
|
|
1280
798
|
}
|
|
1281
799
|
else {
|
|
@@ -1293,7 +811,7 @@ export class ExecutionService {
|
|
|
1293
811
|
approval.resolved = [];
|
|
1294
812
|
continue;
|
|
1295
813
|
}
|
|
1296
|
-
|
|
814
|
+
addApproveWithOptionalReset(spender, unlimitedApproval ? maxUint256 : amount, assetForVault);
|
|
1297
815
|
approval.resolved = resolvedItems;
|
|
1298
816
|
}
|
|
1299
817
|
}
|
|
@@ -1314,6 +832,9 @@ export class ExecutionService {
|
|
|
1314
832
|
*/
|
|
1315
833
|
async resolveRequiredApprovals(args) {
|
|
1316
834
|
const { plan, chainId, account, usePermit2 = true, unlimitedApproval = false, } = args;
|
|
835
|
+
if (!this.walletService) {
|
|
836
|
+
throw new Error("ExecutionService.resolveRequiredApprovals requires a walletService. Pass it to the ExecutionService constructor or call setWalletService().");
|
|
837
|
+
}
|
|
1317
838
|
// Filter transaction plan for only RequiredApproval items
|
|
1318
839
|
const requiredApprovals = plan.filter((item) => item.type === "requiredApproval");
|
|
1319
840
|
// Transform RequiredApprovals into AssetWithSpenders
|
|
@@ -1378,10 +899,7 @@ export class ExecutionService {
|
|
|
1378
899
|
enableCollateral: !isCollateralEnabled && enableCollateral,
|
|
1379
900
|
// Permit2 is handled separately in the plan
|
|
1380
901
|
});
|
|
1381
|
-
plan.push(
|
|
1382
|
-
type: "evcBatch",
|
|
1383
|
-
items: batchItems,
|
|
1384
|
-
});
|
|
902
|
+
plan.push(...this.convertBatchItemsToPlan(batchItems, "deposit"));
|
|
1385
903
|
return plan;
|
|
1386
904
|
}
|
|
1387
905
|
/**
|
|
@@ -1423,10 +941,7 @@ export class ExecutionService {
|
|
|
1423
941
|
enableCollateral: !isCollateralEnabled && enableCollateral,
|
|
1424
942
|
// Permit2 is handled separately in the plan
|
|
1425
943
|
});
|
|
1426
|
-
plan.push(
|
|
1427
|
-
type: "evcBatch",
|
|
1428
|
-
items: batchItems,
|
|
1429
|
-
});
|
|
944
|
+
plan.push(...this.convertBatchItemsToPlan(batchItems, "mint"));
|
|
1430
945
|
return plan;
|
|
1431
946
|
}
|
|
1432
947
|
/**
|
|
@@ -1455,10 +970,7 @@ export class ExecutionService {
|
|
|
1455
970
|
owner,
|
|
1456
971
|
disableCollateral: disableCollateral && (!position || position.isCollateral),
|
|
1457
972
|
});
|
|
1458
|
-
plan.push(
|
|
1459
|
-
type: "evcBatch",
|
|
1460
|
-
items: batchItems,
|
|
1461
|
-
});
|
|
973
|
+
plan.push(...this.convertBatchItemsToPlan(batchItems, "withdraw"));
|
|
1462
974
|
return plan;
|
|
1463
975
|
}
|
|
1464
976
|
/**
|
|
@@ -1488,10 +1000,7 @@ export class ExecutionService {
|
|
|
1488
1000
|
owner,
|
|
1489
1001
|
disableCollateral: disableCollateral && (!position || position.isCollateral),
|
|
1490
1002
|
});
|
|
1491
|
-
plan.push(
|
|
1492
|
-
type: "evcBatch",
|
|
1493
|
-
items: batchItems,
|
|
1494
|
-
});
|
|
1003
|
+
plan.push(...this.convertBatchItemsToPlan(batchItems, "redeem"));
|
|
1495
1004
|
return plan;
|
|
1496
1005
|
}
|
|
1497
1006
|
/**
|
|
@@ -1513,6 +1022,12 @@ export class ExecutionService {
|
|
|
1513
1022
|
planBorrow(args) {
|
|
1514
1023
|
const { vault, amount, receiver, borrowAccount, account, collateral } = args;
|
|
1515
1024
|
const plan = [];
|
|
1025
|
+
const savingsCollateral = isSavingsCollateral(collateral)
|
|
1026
|
+
? collateral
|
|
1027
|
+
: undefined;
|
|
1028
|
+
const walletCollateral = isWalletCollateral(collateral)
|
|
1029
|
+
? collateral
|
|
1030
|
+
: undefined;
|
|
1516
1031
|
const enableCollateral = collateral && collateral.amount > 0n
|
|
1517
1032
|
? !(account?.isCollateralEnabled(borrowAccount, collateral.vault) ??
|
|
1518
1033
|
false)
|
|
@@ -1521,15 +1036,15 @@ export class ExecutionService {
|
|
|
1521
1036
|
// Default: controller is not enabled when account/sub-account is not available
|
|
1522
1037
|
const currentController = account?.getCurrentController(borrowAccount);
|
|
1523
1038
|
const enableController = !(account?.isControllerEnabled(borrowAccount, vault) ?? false);
|
|
1524
|
-
if (
|
|
1039
|
+
if (walletCollateral && walletCollateral.amount > 0n) {
|
|
1525
1040
|
// Approval is needed from the account owner (who owns the wallet tokens)
|
|
1526
1041
|
// Add approval requirement (will be resolved later with Wallet data)
|
|
1527
1042
|
plan.push({
|
|
1528
1043
|
type: "requiredApproval",
|
|
1529
|
-
token:
|
|
1044
|
+
token: walletCollateral.asset,
|
|
1530
1045
|
owner: account.owner,
|
|
1531
|
-
spender:
|
|
1532
|
-
amount:
|
|
1046
|
+
spender: walletCollateral.vault,
|
|
1047
|
+
amount: walletCollateral.amount,
|
|
1533
1048
|
});
|
|
1534
1049
|
}
|
|
1535
1050
|
const batchItems = this.encodeBorrow({
|
|
@@ -1543,12 +1058,18 @@ export class ExecutionService {
|
|
|
1543
1058
|
currentController: currentController || undefined,
|
|
1544
1059
|
enableCollateral,
|
|
1545
1060
|
collateralVault: collateral?.vault,
|
|
1546
|
-
collateralAmount:
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1061
|
+
collateralAmount: walletCollateral?.amount,
|
|
1062
|
+
collateralShareSource: savingsCollateral
|
|
1063
|
+
? {
|
|
1064
|
+
from: savingsCollateral.from,
|
|
1065
|
+
shares: savingsCollateral.amount,
|
|
1066
|
+
disableCollateralFrom: savingsCollateral.disableCollateralFrom &&
|
|
1067
|
+
(account?.isCollateralEnabled(savingsCollateral.from, savingsCollateral.vault) ??
|
|
1068
|
+
false),
|
|
1069
|
+
}
|
|
1070
|
+
: undefined,
|
|
1551
1071
|
});
|
|
1072
|
+
plan.push(...this.convertBatchItemsToPlan(batchItems, "borrow"));
|
|
1552
1073
|
return plan;
|
|
1553
1074
|
}
|
|
1554
1075
|
/**
|
|
@@ -1592,10 +1113,7 @@ export class ExecutionService {
|
|
|
1592
1113
|
enableController,
|
|
1593
1114
|
enableCollateral,
|
|
1594
1115
|
});
|
|
1595
|
-
plan.push(
|
|
1596
|
-
type: "evcBatch",
|
|
1597
|
-
items: batchItems,
|
|
1598
|
-
});
|
|
1116
|
+
plan.push(...this.convertBatchItemsToPlan(batchItems, "liquidation"));
|
|
1599
1117
|
return plan;
|
|
1600
1118
|
}
|
|
1601
1119
|
/**
|
|
@@ -1607,10 +1125,11 @@ export class ExecutionService {
|
|
|
1607
1125
|
* @param args.liabilityAmount - Amount of liability asset to repay (use maxUint256 for "repay all")
|
|
1608
1126
|
* @param args.receiver - Sub-account address whose debt is being repaid
|
|
1609
1127
|
* @param args.account - Account entity; used for chainId, owner, and position (to resolve liability asset)
|
|
1128
|
+
* @param args.cleanupOnMax - When true and liabilityAmount is maxUint256, the batch disables active collaterals on the repaid sub-account and transfers their shares to the owner account (default false)
|
|
1610
1129
|
* @returns Array of transaction plan items (approval + EVC batch)
|
|
1611
1130
|
*/
|
|
1612
1131
|
planRepayFromWallet(args) {
|
|
1613
|
-
const { liabilityVault, liabilityAmount, receiver, account } = args;
|
|
1132
|
+
const { liabilityVault, liabilityAmount, receiver, account, cleanupOnMax = false, } = args;
|
|
1614
1133
|
const plan = [];
|
|
1615
1134
|
// Get position to determine asset
|
|
1616
1135
|
const position = account?.getPosition(receiver, liabilityVault);
|
|
@@ -1625,6 +1144,7 @@ export class ExecutionService {
|
|
|
1625
1144
|
spender: liabilityVault,
|
|
1626
1145
|
amount: liabilityAmount,
|
|
1627
1146
|
});
|
|
1147
|
+
const isMax = liabilityAmount === maxUint256;
|
|
1628
1148
|
// Build EVC batch items
|
|
1629
1149
|
const batchItems = this.encodeRepayFromWallet({
|
|
1630
1150
|
chainId: account.chainId,
|
|
@@ -1633,18 +1153,28 @@ export class ExecutionService {
|
|
|
1633
1153
|
liabilityAmount,
|
|
1634
1154
|
receiver,
|
|
1635
1155
|
disableControllerOnMax: true,
|
|
1636
|
-
isMax
|
|
1156
|
+
isMax,
|
|
1637
1157
|
// Permit2 is handled separately in the plan
|
|
1638
1158
|
});
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1159
|
+
if (cleanupOnMax && isMax) {
|
|
1160
|
+
this.appendMaxRepayCleanup({
|
|
1161
|
+
account,
|
|
1162
|
+
liabilityPosition: position,
|
|
1163
|
+
receiver,
|
|
1164
|
+
batchItems,
|
|
1165
|
+
});
|
|
1166
|
+
}
|
|
1167
|
+
plan.push(...this.convertBatchItemsToPlan(batchItems, "repayFromWallet"));
|
|
1643
1168
|
return plan;
|
|
1644
1169
|
}
|
|
1645
1170
|
/**
|
|
1646
1171
|
* Builds a transaction plan for repaying debt using assets from another vault deposit (same asset only).
|
|
1647
|
-
* Use `maxUint256` for `liabilityAmount` to
|
|
1172
|
+
* Use `maxUint256` for `liabilityAmount` to perform a full repay.
|
|
1173
|
+
* Full repay can opt into cleanup. For different-vault full repays, cleanup only redeems
|
|
1174
|
+
* liability-vault shares left from the repay cushion when the account snapshot shows no pre-existing liability-vault deposit;
|
|
1175
|
+
* otherwise those shares are preserved in the liability vault instead of being migrated to the source vault.
|
|
1176
|
+
* Cleanup also disables active collaterals on the repaid sub-account, transfers those collateral shares to the owner
|
|
1177
|
+
* account, and transfers any remaining source-vault shares from the source sub-account to the owner account.
|
|
1648
1178
|
*
|
|
1649
1179
|
* @param args - Repay-from-deposit plan arguments
|
|
1650
1180
|
* @param args.liabilityVault - Address of the liability vault (debt is repaid to this vault)
|
|
@@ -1653,10 +1183,11 @@ export class ExecutionService {
|
|
|
1653
1183
|
* @param args.fromVault - Vault to withdraw assets from (must be same underlying asset as liability for this plan)
|
|
1654
1184
|
* @param args.fromAccount - Sub-account that holds the deposit in `fromVault`
|
|
1655
1185
|
* @param args.account - Account entity; used for chainId, owner, and positions (to resolve assets and eligibility)
|
|
1656
|
-
* @
|
|
1186
|
+
* @param args.cleanupOnMax - Whether max repay should append repay-cushion, collateral, and source-share cleanup (default false)
|
|
1187
|
+
* @returns Array of transaction plan items (EVC batch only). Throws if asset differs between fromVault and liabilityVault; use planRepayWithSwap for cross-asset.
|
|
1657
1188
|
*/
|
|
1658
1189
|
planRepayFromDeposit(args) {
|
|
1659
|
-
const { liabilityVault, liabilityAmount, receiver, fromVault, fromAccount, account, } = args;
|
|
1190
|
+
const { liabilityVault, liabilityAmount, receiver, fromVault, fromAccount, account, cleanupOnMax = false, } = args;
|
|
1660
1191
|
const plan = [];
|
|
1661
1192
|
// Get positions
|
|
1662
1193
|
const liabilityPosition = account?.getPosition(receiver, liabilityVault);
|
|
@@ -1668,40 +1199,65 @@ export class ExecutionService {
|
|
|
1668
1199
|
}
|
|
1669
1200
|
const liabilityAsset = liabilityPosition.asset;
|
|
1670
1201
|
const fromAsset = fromPosition.asset;
|
|
1671
|
-
//
|
|
1202
|
+
// Cross-asset repay requires a swap path; this planner only builds same-asset batches.
|
|
1672
1203
|
if (fromAsset !== liabilityAsset) {
|
|
1673
1204
|
// This path requires a swap, which is handled by planRepayWithSwap
|
|
1674
1205
|
throw new Error("planRepayFromDeposit only supports same-asset paths. Use planRepayWithSwap for different assets.");
|
|
1675
1206
|
}
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
token: liabilityAsset,
|
|
1682
|
-
owner: account.owner,
|
|
1683
|
-
spender: liabilityVault,
|
|
1684
|
-
amount: liabilityAmount,
|
|
1685
|
-
});
|
|
1686
|
-
}
|
|
1207
|
+
const isMax = liabilityAmount === maxUint256;
|
|
1208
|
+
const amount = isMax && fromVault !== liabilityVault
|
|
1209
|
+
? liabilityPosition.borrowed
|
|
1210
|
+
: liabilityAmount;
|
|
1211
|
+
const hasPreExistingLiabilityDeposit = (liabilityPosition.assets ?? 0n) > 0n;
|
|
1687
1212
|
// Build EVC batch items
|
|
1688
1213
|
const batchItems = this.encodeRepayFromDeposit({
|
|
1689
1214
|
chainId: account.chainId,
|
|
1690
1215
|
liabilityVault,
|
|
1691
1216
|
liabilityAsset,
|
|
1692
|
-
liabilityAmount,
|
|
1693
|
-
from:
|
|
1217
|
+
liabilityAmount: amount,
|
|
1218
|
+
from: fromAccount,
|
|
1694
1219
|
receiver,
|
|
1695
1220
|
fromVault,
|
|
1696
1221
|
fromAsset,
|
|
1697
1222
|
disableControllerOnMax: true,
|
|
1698
|
-
isMax
|
|
1223
|
+
isMax,
|
|
1699
1224
|
// Permit2 is handled separately in the plan
|
|
1700
1225
|
});
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1226
|
+
if (cleanupOnMax && isMax) {
|
|
1227
|
+
if (fromVault !== liabilityVault && !hasPreExistingLiabilityDeposit) {
|
|
1228
|
+
// Sweep only the repay cushion. If liability shares existed before this batch,
|
|
1229
|
+
// redeem(max) would also migrate that unrelated deposit into the source vault.
|
|
1230
|
+
batchItems.push({
|
|
1231
|
+
targetContract: liabilityVault,
|
|
1232
|
+
onBehalfOfAccount: receiver,
|
|
1233
|
+
value: 0n,
|
|
1234
|
+
data: encodeFunctionData({
|
|
1235
|
+
abi: eVaultAbi,
|
|
1236
|
+
functionName: "redeem",
|
|
1237
|
+
args: [maxUint256, fromVault, receiver],
|
|
1238
|
+
}),
|
|
1239
|
+
});
|
|
1240
|
+
batchItems.push({
|
|
1241
|
+
targetContract: fromVault,
|
|
1242
|
+
onBehalfOfAccount: fromAccount,
|
|
1243
|
+
value: 0n,
|
|
1244
|
+
data: encodeFunctionData({
|
|
1245
|
+
abi: eVaultAbi,
|
|
1246
|
+
functionName: "skim",
|
|
1247
|
+
args: [maxUint256, fromAccount],
|
|
1248
|
+
}),
|
|
1249
|
+
});
|
|
1250
|
+
}
|
|
1251
|
+
this.appendMaxRepayCleanup({
|
|
1252
|
+
account,
|
|
1253
|
+
liabilityPosition,
|
|
1254
|
+
receiver,
|
|
1255
|
+
batchItems,
|
|
1256
|
+
sourceAccount: fromAccount,
|
|
1257
|
+
sourceVault: fromVault,
|
|
1258
|
+
});
|
|
1259
|
+
}
|
|
1260
|
+
plan.push(...this.convertBatchItemsToPlan(batchItems, "repayFromDeposit"));
|
|
1705
1261
|
return plan;
|
|
1706
1262
|
}
|
|
1707
1263
|
/**
|
|
@@ -1711,10 +1267,11 @@ export class ExecutionService {
|
|
|
1711
1267
|
* @param args - Repay-with-swap plan arguments
|
|
1712
1268
|
* @param args.swapQuote - Quote from swap service (e.g. fetchRepayQuotes); defines vaultIn, accountIn, accountOut, receiver, swap and verify steps
|
|
1713
1269
|
* @param args.account - Account entity; used for chainId and positions (to compute isMax and maxWithdraw)
|
|
1270
|
+
* @param args.cleanupOnMax - When true and the quote repays the full debt, the batch disables active collaterals on the repaid sub-account, transfers their shares to the owner account, and transfers remaining source-vault shares to the owner account (default false)
|
|
1714
1271
|
* @returns Array of transaction plan items (EVC batch: withdraw, swap, verify/repay). Throws if positions not found or liability is zero.
|
|
1715
1272
|
*/
|
|
1716
1273
|
planRepayWithSwap(args) {
|
|
1717
|
-
const { swapQuote, account } = args;
|
|
1274
|
+
const { swapQuote, account, cleanupOnMax = false } = args;
|
|
1718
1275
|
const plan = [];
|
|
1719
1276
|
const liabilityPosition = account?.getPosition(swapQuote.accountOut, swapQuote.receiver);
|
|
1720
1277
|
const fromPosition = account?.getPosition(swapQuote.accountIn, swapQuote.vaultIn);
|
|
@@ -1733,10 +1290,17 @@ export class ExecutionService {
|
|
|
1733
1290
|
isMax,
|
|
1734
1291
|
disableControllerOnMax: true,
|
|
1735
1292
|
});
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1293
|
+
if (cleanupOnMax && isMax) {
|
|
1294
|
+
this.appendMaxRepayCleanup({
|
|
1295
|
+
account,
|
|
1296
|
+
liabilityPosition,
|
|
1297
|
+
receiver: swapQuote.accountOut,
|
|
1298
|
+
batchItems,
|
|
1299
|
+
sourceAccount: swapQuote.accountIn,
|
|
1300
|
+
sourceVault: swapQuote.vaultIn,
|
|
1301
|
+
});
|
|
1302
|
+
}
|
|
1303
|
+
plan.push(...this.convertBatchItemsToPlan(batchItems, "repayWithSwap"));
|
|
1740
1304
|
return plan;
|
|
1741
1305
|
}
|
|
1742
1306
|
/**
|
|
@@ -1778,10 +1342,37 @@ export class ExecutionService {
|
|
|
1778
1342
|
sender: account.owner,
|
|
1779
1343
|
enableCollateral: shouldEnableCollateral,
|
|
1780
1344
|
});
|
|
1345
|
+
plan.push(...this.convertBatchItemsToPlan(batchItems, "depositWithSwapFromWallet"));
|
|
1346
|
+
return plan;
|
|
1347
|
+
}
|
|
1348
|
+
/**
|
|
1349
|
+
* Builds a transaction plan for swapping a token from the sender's wallet into another
|
|
1350
|
+
* token and transferring the output to the quote receiver.
|
|
1351
|
+
*
|
|
1352
|
+
* @param args - Wallet-swap plan arguments
|
|
1353
|
+
* @param args.swapQuote - Quote from swap service; must use transferOutputToReceiver / transferMin verification
|
|
1354
|
+
* @param args.amount - Amount of input token to transfer from wallet
|
|
1355
|
+
* @param args.tokenIn - Input token address (for approval to SwapVerifier)
|
|
1356
|
+
* @param args.account - Account entity; used for chainId and owner
|
|
1357
|
+
* @returns Array of transaction plan items (approval to SwapVerifier + EVC batch)
|
|
1358
|
+
*/
|
|
1359
|
+
planSwapFromWallet(args) {
|
|
1360
|
+
const { swapQuote, amount, tokenIn, account } = args;
|
|
1361
|
+
const plan = [];
|
|
1781
1362
|
plan.push({
|
|
1782
|
-
type: "
|
|
1783
|
-
|
|
1363
|
+
type: "requiredApproval",
|
|
1364
|
+
token: tokenIn,
|
|
1365
|
+
owner: account.owner,
|
|
1366
|
+
spender: swapQuote.verify.verifierAddress,
|
|
1367
|
+
amount,
|
|
1784
1368
|
});
|
|
1369
|
+
const batchItems = this.encodeSwapFromWallet({
|
|
1370
|
+
chainId: account.chainId,
|
|
1371
|
+
swapQuote,
|
|
1372
|
+
amount,
|
|
1373
|
+
sender: account.owner,
|
|
1374
|
+
});
|
|
1375
|
+
plan.push(...this.convertBatchItemsToPlan(batchItems, "swapFromWallet"));
|
|
1785
1376
|
return plan;
|
|
1786
1377
|
}
|
|
1787
1378
|
/**
|
|
@@ -1813,10 +1404,7 @@ export class ExecutionService {
|
|
|
1813
1404
|
disableCollateralOnMax: true,
|
|
1814
1405
|
isMax,
|
|
1815
1406
|
});
|
|
1816
|
-
plan.push(
|
|
1817
|
-
type: "evcBatch",
|
|
1818
|
-
items: batchItems,
|
|
1819
|
-
});
|
|
1407
|
+
plan.push(...this.convertBatchItemsToPlan(batchItems, "swapCollateral"));
|
|
1820
1408
|
return plan;
|
|
1821
1409
|
}
|
|
1822
1410
|
/**
|
|
@@ -1844,10 +1432,103 @@ export class ExecutionService {
|
|
|
1844
1432
|
disableControllerOnMax: true,
|
|
1845
1433
|
isMax,
|
|
1846
1434
|
});
|
|
1847
|
-
plan.push(
|
|
1848
|
-
|
|
1849
|
-
|
|
1435
|
+
plan.push(...this.convertBatchItemsToPlan(batchItems, "swapDebt"));
|
|
1436
|
+
return plan;
|
|
1437
|
+
}
|
|
1438
|
+
/**
|
|
1439
|
+
* Builds a transaction plan for migrating a supplied/collateral position between two same-asset vaults.
|
|
1440
|
+
* This is the no-swap path for moving shares from one vault to another vault with the same underlying asset.
|
|
1441
|
+
*
|
|
1442
|
+
* @param args - Same-asset collateral migration plan arguments
|
|
1443
|
+
* @param args.fromVault - Source vault holding the supplied shares
|
|
1444
|
+
* @param args.toVault - Destination vault with the same underlying asset
|
|
1445
|
+
* @param args.amount - Asset amount to withdraw/redeem and skim into the destination vault
|
|
1446
|
+
* @param args.positionAccount - Sub-account that owns the source shares and receives destination shares
|
|
1447
|
+
* @param args.fromAsset - Optional source underlying asset; defaults to the account position asset
|
|
1448
|
+
* @param args.toAsset - Destination underlying asset, used to verify this is a same-asset migration
|
|
1449
|
+
* @param args.isMax - If true, redeems shares instead of withdrawing assets
|
|
1450
|
+
* @param args.maxShares - Optional exact share amount for max migration
|
|
1451
|
+
* @param args.enableCollateralTo - Optional override for enabling destination collateral
|
|
1452
|
+
* @param args.disableCollateralFrom - Optional override for disabling source collateral
|
|
1453
|
+
* @returns Array of transaction plan items (EVC batch; no token approvals)
|
|
1454
|
+
*/
|
|
1455
|
+
planMigrateSameAssetCollateral(args) {
|
|
1456
|
+
const { account, fromVault, toVault, amount, positionAccount, fromAsset, toAsset, isMax = false, maxShares, enableCollateralTo, disableCollateralFrom, } = args;
|
|
1457
|
+
const plan = [];
|
|
1458
|
+
const sourcePosition = account?.getPosition(positionAccount, fromVault);
|
|
1459
|
+
const resolvedFromAsset = fromAsset ?? sourcePosition?.asset;
|
|
1460
|
+
if (!resolvedFromAsset) {
|
|
1461
|
+
throw new Error(`Position not found. From vault: ${fromVault}, Account: ${positionAccount}. Source asset is required when position is not available.`);
|
|
1462
|
+
}
|
|
1463
|
+
if (getAddress(resolvedFromAsset) !== getAddress(toAsset)) {
|
|
1464
|
+
throw new Error("planMigrateSameAssetCollateral only supports same-asset vault migrations. Use planSwapCollateral for cross-asset migrations.");
|
|
1465
|
+
}
|
|
1466
|
+
const shouldEnableCollateralTo = enableCollateralTo ??
|
|
1467
|
+
!account.isCollateralEnabled(positionAccount, toVault);
|
|
1468
|
+
const shouldDisableCollateralFrom = disableCollateralFrom ??
|
|
1469
|
+
(isMax && account.isCollateralEnabled(positionAccount, fromVault));
|
|
1470
|
+
const batchItems = this.encodeMigrateSameAssetCollateral({
|
|
1471
|
+
chainId: account.chainId,
|
|
1472
|
+
fromVault,
|
|
1473
|
+
toVault,
|
|
1474
|
+
amount,
|
|
1475
|
+
account: positionAccount,
|
|
1476
|
+
isMax,
|
|
1477
|
+
maxShares: maxShares ?? (isMax ? sourcePosition?.shares : undefined),
|
|
1478
|
+
enableCollateralTo: shouldEnableCollateralTo,
|
|
1479
|
+
disableCollateralFrom: shouldDisableCollateralFrom,
|
|
1480
|
+
});
|
|
1481
|
+
plan.push(...this.convertBatchItemsToPlan(batchItems, "migrateSameAssetCollateral"));
|
|
1482
|
+
return plan;
|
|
1483
|
+
}
|
|
1484
|
+
/**
|
|
1485
|
+
* Builds a transaction plan for migrating a full same-asset debt position from one liability vault to another.
|
|
1486
|
+
* This is the no-swap path for debt vault migration and repays the old vault with shares after borrowing
|
|
1487
|
+
* slightly more from the new vault to cover interest accrual.
|
|
1488
|
+
*
|
|
1489
|
+
* @param args - Same-asset debt migration plan arguments
|
|
1490
|
+
* @param args.oldLiabilityVault - Existing debt vault to fully repay and disable
|
|
1491
|
+
* @param args.newLiabilityVault - New same-asset debt vault to borrow from
|
|
1492
|
+
* @param args.liabilityAccount - Sub-account that owns the debt position
|
|
1493
|
+
* @param args.liabilityAmount - Current debt amount; defaults to the old-vault borrowed amount in account data
|
|
1494
|
+
* @param args.oldLiabilityAsset - Optional old liability asset; defaults to the old-vault account position asset
|
|
1495
|
+
* @param args.newLiabilityAsset - New liability underlying asset, used to verify this is a same-asset migration
|
|
1496
|
+
* @param args.sweepExcess - Whether to redeem and skim the migration cushion back into the new vault (default true)
|
|
1497
|
+
* @param args.transferRemainingSharesToOwner - Whether to transfer new-vault shares to the owner when liabilityAccount differs from owner (default true)
|
|
1498
|
+
* @returns Array of transaction plan items (EVC batch; no token approvals)
|
|
1499
|
+
*/
|
|
1500
|
+
planMigrateSameAssetDebt(args) {
|
|
1501
|
+
const { account, oldLiabilityVault, newLiabilityVault, liabilityAccount, liabilityAmount, oldLiabilityAsset, newLiabilityAsset, sweepExcess = true, transferRemainingSharesToOwner = true, } = args;
|
|
1502
|
+
const plan = [];
|
|
1503
|
+
const oldPosition = account?.getPosition(liabilityAccount, oldLiabilityVault);
|
|
1504
|
+
const resolvedOldAsset = oldLiabilityAsset ?? oldPosition?.asset;
|
|
1505
|
+
if (!resolvedOldAsset) {
|
|
1506
|
+
throw new Error(`Position not found. Old liability vault: ${oldLiabilityVault}, Account: ${liabilityAccount}. Old liability asset is required when position is not available.`);
|
|
1507
|
+
}
|
|
1508
|
+
if (getAddress(resolvedOldAsset) !== getAddress(newLiabilityAsset)) {
|
|
1509
|
+
throw new Error("planMigrateSameAssetDebt only supports same-asset debt migrations. Use planSwapDebt for cross-asset migrations.");
|
|
1510
|
+
}
|
|
1511
|
+
const amount = liabilityAmount ?? oldPosition?.borrowed;
|
|
1512
|
+
if (!amount || amount <= 0n) {
|
|
1513
|
+
throw new Error(`Debt position not found or liability is 0. Old liability vault: ${oldLiabilityVault}, Account: ${liabilityAccount}`);
|
|
1514
|
+
}
|
|
1515
|
+
const enableController = !account.isControllerEnabled(liabilityAccount, newLiabilityVault);
|
|
1516
|
+
const transferRemainingSharesTo = transferRemainingSharesToOwner &&
|
|
1517
|
+
getAddress(liabilityAccount) !== getAddress(account.owner)
|
|
1518
|
+
? account.owner
|
|
1519
|
+
: undefined;
|
|
1520
|
+
const batchItems = this.encodeMigrateSameAssetDebt({
|
|
1521
|
+
chainId: account.chainId,
|
|
1522
|
+
oldLiabilityVault,
|
|
1523
|
+
newLiabilityVault,
|
|
1524
|
+
amount,
|
|
1525
|
+
account: liabilityAccount,
|
|
1526
|
+
enableController,
|
|
1527
|
+
disableController: true,
|
|
1528
|
+
sweepExcess,
|
|
1529
|
+
transferRemainingSharesTo,
|
|
1850
1530
|
});
|
|
1531
|
+
plan.push(...this.convertBatchItemsToPlan(batchItems, "migrateSameAssetDebt"));
|
|
1851
1532
|
return plan;
|
|
1852
1533
|
}
|
|
1853
1534
|
/**
|
|
@@ -1878,10 +1559,7 @@ export class ExecutionService {
|
|
|
1878
1559
|
disableCollateralFrom: disableCollateralFrom &&
|
|
1879
1560
|
(account?.isCollateralEnabled(from, vault) ?? false),
|
|
1880
1561
|
});
|
|
1881
|
-
plan.push(
|
|
1882
|
-
type: "evcBatch",
|
|
1883
|
-
items: batchItems,
|
|
1884
|
-
});
|
|
1562
|
+
plan.push(...this.convertBatchItemsToPlan(batchItems, "transfer"));
|
|
1885
1563
|
return plan;
|
|
1886
1564
|
}
|
|
1887
1565
|
/**
|
|
@@ -1908,10 +1586,7 @@ export class ExecutionService {
|
|
|
1908
1586
|
to,
|
|
1909
1587
|
enableController,
|
|
1910
1588
|
});
|
|
1911
|
-
plan.push(
|
|
1912
|
-
type: "evcBatch",
|
|
1913
|
-
items: batchItems,
|
|
1914
|
-
});
|
|
1589
|
+
plan.push(...this.convertBatchItemsToPlan(batchItems, "pullDebt"));
|
|
1915
1590
|
return plan;
|
|
1916
1591
|
}
|
|
1917
1592
|
/**
|
|
@@ -1927,10 +1602,10 @@ export class ExecutionService {
|
|
|
1927
1602
|
* @returns Array of transaction plan items (optional approval + EVC batch). Throws if swapQuote.accountIn !== swapQuote.accountOut.
|
|
1928
1603
|
*/
|
|
1929
1604
|
planMultiplyWithSwap(args) {
|
|
1930
|
-
const { collateralVault, collateralAmount, collateralAsset, account, swapQuote, } = args;
|
|
1605
|
+
const { collateralVault, collateralAmount, collateralAsset, collateralShareSource, account, swapQuote, } = args;
|
|
1931
1606
|
const plan = [];
|
|
1932
1607
|
// 1. Check if collateral approval is needed (only if depositing collateral)
|
|
1933
|
-
if (collateralAmount > 0n) {
|
|
1608
|
+
if (!collateralShareSource && collateralAmount > 0n) {
|
|
1934
1609
|
// Add approval requirement (will be resolved later with Wallet data)
|
|
1935
1610
|
plan.push({
|
|
1936
1611
|
type: "requiredApproval",
|
|
@@ -1948,8 +1623,19 @@ export class ExecutionService {
|
|
|
1948
1623
|
const longVault = swapQuote.receiver;
|
|
1949
1624
|
const liabilityAmount = BigInt(swapQuote.amountIn);
|
|
1950
1625
|
// 2. Determine if collateral needs to be enabled
|
|
1951
|
-
const
|
|
1626
|
+
const hasCollateralInput = collateralShareSource
|
|
1627
|
+
? collateralShareSource.shares > 0n
|
|
1628
|
+
: collateralAmount > 0n;
|
|
1629
|
+
const enableCollateral = hasCollateralInput &&
|
|
1952
1630
|
!(account?.isCollateralEnabled(receiver, collateralVault) ?? false);
|
|
1631
|
+
const resolvedCollateralShareSource = collateralShareSource
|
|
1632
|
+
? {
|
|
1633
|
+
...collateralShareSource,
|
|
1634
|
+
disableCollateralFrom: collateralShareSource.disableCollateralFrom &&
|
|
1635
|
+
(account?.isCollateralEnabled(collateralShareSource.from, collateralVault) ??
|
|
1636
|
+
false),
|
|
1637
|
+
}
|
|
1638
|
+
: undefined;
|
|
1953
1639
|
// 3. Determine if controller needs to be enabled
|
|
1954
1640
|
const enableController = !(account?.isControllerEnabled(receiver, liabilityVault) ?? false);
|
|
1955
1641
|
// 4. Get current controller (may need to disable if different)
|
|
@@ -1967,13 +1653,11 @@ export class ExecutionService {
|
|
|
1967
1653
|
enableCollateral,
|
|
1968
1654
|
currentController: currentController || undefined,
|
|
1969
1655
|
enableController,
|
|
1656
|
+
collateralShareSource: resolvedCollateralShareSource,
|
|
1970
1657
|
swapQuote,
|
|
1971
1658
|
// Permit2 is handled separately in the plan
|
|
1972
1659
|
});
|
|
1973
|
-
plan.push(
|
|
1974
|
-
type: "evcBatch",
|
|
1975
|
-
items: batchItems,
|
|
1976
|
-
});
|
|
1660
|
+
plan.push(...this.convertBatchItemsToPlan(batchItems, "multiplyWithSwap"));
|
|
1977
1661
|
return plan;
|
|
1978
1662
|
}
|
|
1979
1663
|
/**
|
|
@@ -1992,10 +1676,10 @@ export class ExecutionService {
|
|
|
1992
1676
|
* @returns Array of transaction plan items (optional approval + EVC batch)
|
|
1993
1677
|
*/
|
|
1994
1678
|
planMultiplySameAsset(args) {
|
|
1995
|
-
const { collateralVault, collateralAmount, collateralAsset, liabilityVault, liabilityAmount, longVault, receiver, account, } = args;
|
|
1679
|
+
const { collateralVault, collateralAmount, collateralAsset, collateralShareSource, liabilityVault, liabilityAmount, longVault, receiver, account, } = args;
|
|
1996
1680
|
const plan = [];
|
|
1997
1681
|
// 1. Check if collateral approval is needed (only if depositing collateral)
|
|
1998
|
-
if (collateralAmount > 0n) {
|
|
1682
|
+
if (!collateralShareSource && collateralAmount > 0n) {
|
|
1999
1683
|
// Add approval requirement (will be resolved later with Wallet data)
|
|
2000
1684
|
plan.push({
|
|
2001
1685
|
type: "requiredApproval",
|
|
@@ -2006,8 +1690,19 @@ export class ExecutionService {
|
|
|
2006
1690
|
});
|
|
2007
1691
|
}
|
|
2008
1692
|
// 2. Determine if collateral needs to be enabled
|
|
2009
|
-
const
|
|
1693
|
+
const hasCollateralInput = collateralShareSource
|
|
1694
|
+
? collateralShareSource.shares > 0n
|
|
1695
|
+
: collateralAmount > 0n;
|
|
1696
|
+
const enableCollateral = hasCollateralInput &&
|
|
2010
1697
|
!(account?.isCollateralEnabled(receiver, collateralVault) ?? false);
|
|
1698
|
+
const resolvedCollateralShareSource = collateralShareSource
|
|
1699
|
+
? {
|
|
1700
|
+
...collateralShareSource,
|
|
1701
|
+
disableCollateralFrom: collateralShareSource.disableCollateralFrom &&
|
|
1702
|
+
(account?.isCollateralEnabled(collateralShareSource.from, collateralVault) ??
|
|
1703
|
+
false),
|
|
1704
|
+
}
|
|
1705
|
+
: undefined;
|
|
2011
1706
|
// 3. Determine if controller needs to be enabled
|
|
2012
1707
|
const enableController = !(account?.isControllerEnabled(receiver, liabilityVault) ?? false);
|
|
2013
1708
|
// 4. Get current controller (may need to disable if different)
|
|
@@ -2025,12 +1720,10 @@ export class ExecutionService {
|
|
|
2025
1720
|
enableCollateral,
|
|
2026
1721
|
currentController: currentController || undefined,
|
|
2027
1722
|
enableController,
|
|
1723
|
+
collateralShareSource: resolvedCollateralShareSource,
|
|
2028
1724
|
// Permit2 is handled separately in the plan
|
|
2029
1725
|
});
|
|
2030
|
-
plan.push(
|
|
2031
|
-
type: "evcBatch",
|
|
2032
|
-
items: batchItems,
|
|
2033
|
-
});
|
|
1726
|
+
plan.push(...this.convertBatchItemsToPlan(batchItems, "multiplySameAsset"));
|
|
2034
1727
|
return plan;
|
|
2035
1728
|
}
|
|
2036
1729
|
}
|