Skip to content

Conversation

HanzCEO
Copy link

@HanzCEO HanzCEO commented Jun 24, 2025

Protocol Information

Summary of Integration

Provide a brief overview of your integration:

  • What does your protocol do?
    • Tokemak's Autopilot was developed to address the many challenges liquidity providers (LPs) face when optimizing for best performance. No protocol currently offers fully autonomous, transparent and sophisticated rebalance solution focused solely on liquidity provision.
  • What type of liquidity does it provide (DEX, lending, yield farming, etc.)?
    • Liquidity Provision Yield Vault
  • Any unique features that GlueX should consider?
    • n/a

Implementation Details

Execution Functions Required

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

interface AutopoolETH {
    function deposit(uint256 assets, address receiver) external returns (uint256 shares);
    function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets);
}

Functions Implemented

  • get_amount_out()
  • get_amount_in()
  • get_apy()
  • get_tvl()

Dynamic States Required for AMM Calculations

  • oldestDebtReporting - Obtained from AutoPool.oldestDebtReporting()
  • totalSupply - AutoPool.totalSupply()
  • assetBreakdown - A dict, explained below. Obtained from AutoPool.getAssetBreakdown()
    • totalIdle - The amount of baseAsset deposited into the contract pending deployment
    • totalDebt - The current (though cached) value of assets we've deployed
    • totalDebtMax - The current (though cached) value of assets we use for valuing during deposits
    • totalDebtMin - The current (though cached) value of assets we use for valuing during withdrawals
  • previousAssetBreakdown - The same dict as assetBreakdown but N days ago
  • previousTotalSupply - The same as totalSupply but N days ago
  • days - N of days between previous* and current states
  • paused - AutoPool.paused()
  • shutdown - AutoPool.isShutdown()
  • profitUnlockSettings - A dict explained below. Obtained from AutoPool.getProfitUnlockSettings()
    • fullProfitUnlockTime - Time at which all profit will have been unlocked
    • profitUnlockRate - Per second rate at which profit shares unlocks. Rate when calculated is denominated in MAX_BPS_PROFIT
    • lastProfitUnlockTime - Last time profits were unlocked
  • debtReportQueue - Array of Addresses of destination vaults (obtained from AutoPool.getDebtReportingQueue())
  • destinationInfo - Custom map of destVaultAddr => destInfo, with destInfo explained below:
    • lastReport - Derived from the lastReport key of the value of AutoPool.getDestinationInfo()
    • ownedShares - Derived from the ownedShares key of the value of AutoPool.getDestinationInfo()
    • cachedMaxDebtValue - Derived from the cachedMaxDebtValue key of the value of AutoPool.getDestinationInfo()
    • cachedMinDebtValue - Derived from the cachedMinDebtValue key of the value of AutoPool.getDestinationInfo()
    • currentShares - destVaultAddr.balanceOf(currentPoolAddr) in uint256
    • underlyerCeilingPrice - destVaultAddr.getUnderlyerCeilingPrice() in uint256
    • underlyerFloorPrice - destVaultAddr.getUnderlyerFloorPrice() in uint256
    • ONE - destVaultAddr.ONE() in uint256

Static States Required for AMM Calculations

  • vaultTokenAddress - Current in-operation ERC4626 vault address
  • asset - Current in-operation vault's underlying token address

Dependencies

N/A

Other Requirements

  • API Keys: n/a
  • Special Access Requirements: n/a

Test Results

Click to view test results
=========================================================================================================== test session starts ============================================================================================================
platform linux -- Python 3.13.2, pytest-8.3.5, pluggy-1.6.0 -- /home/hanz/Work/Bounty/liquidity-module-self-integration/venv/bin/python3
cachedir: .pytest_cache
rootdir: /home/hanz/Work/Bounty/liquidity-module-self-integration
plugins: cov-6.1.1
collected 16 items                                                                                                                                                                                                                         

tests/testtokemak_liquidity_module.py::test_get_amount_out_general PASSED                                                                                                                                                            [  6%]
tests/testtokemak_liquidity_module.py::test_get_amount_out_deposit_exact PASSED                                                                                                                                                      [ 12%]
tests/testtokemak_liquidity_module.py::test_get_amount_out_redeem_exact PASSED                                                                                                                                                       [ 18%]
tests/testtokemak_liquidity_module.py::test_get_amount_out_stale PASSED                                                                                                                                                              [ 25%]
tests/testtokemak_liquidity_module.py::test_get_amount_out_vault_to_asset PASSED                                                                                                                                                     [ 31%]
tests/testtokemak_liquidity_module.py::test_get_amount_in_general PASSED                                                                                                                                                             [ 37%]
tests/testtokemak_liquidity_module.py::test_get_amount_in_exact PASSED                                                                                                                                                               [ 43%]
tests/testtokemak_liquidity_module.py::test_get_amount_in_deposit_exact PASSED                                                                                                                                                       [ 50%]
tests/testtokemak_liquidity_module.py::test_get_amount_in_redeem_exact PASSED                                                                                                                                                        [ 56%]
tests/testtokemak_liquidity_module.py::test_get_amount_in_stale PASSED                                                                                                                                                               [ 62%]
tests/testtokemak_liquidity_module.py::test_get_apy_zero_days PASSED                                                                                                                                                                 [ 68%]
tests/testtokemak_liquidity_module.py::test_get_apy_exact PASSED                                                                                                                                                                     [ 75%]
tests/testtokemak_liquidity_module.py::test_get_apy_stale PASSED                                                                                                                                                                     [ 81%]
tests/testtokemak_liquidity_module.py::test_get_tvl_general PASSED                                                                                                                                                                   [ 87%]
tests/testtokemak_liquidity_module.py::test_get_tvl_exact PASSED                                                                                                                                                                     [ 93%]
tests/testtokemak_liquidity_module.py::test_get_tvl_no_token PASSED                                                                                                                                                                  [100%]

============================================================================================================== tests coverage ==============================================================================================================
_____________________________________________________________________________________________ coverage: platform linux, python 3.13.2-final-0 ______________________________________________________________________________________________

Name                                    Stmts   Miss  Cover
-----------------------------------------------------------
modules/helpers/autopool4626.py            56     11    80%
modules/helpers/autopooldebt.py            37     19    49%
modules/helpers/autopoolfees.py            14      2    86%
modules/helpers/block.py                    2      0   100%
modules/tokemak_liquidity_module.py        69      2    97%
templates/liquidity_module.py              22      4    82%
tests/testtokemak_liquidity_module.py     128      8    94%
-----------------------------------------------------------
TOTAL                                     328     46    86%
============================================================================================================ 16 passed in 0.12s ============================================================================================================

@HanzCEO HanzCEO marked this pull request as ready for review June 28, 2025 14:16
@HanzCEO HanzCEO marked this pull request as draft July 7, 2025 00:56
@HanzCEO HanzCEO marked this pull request as ready for review July 23, 2025 16:26
full_time = profit_unlock_settings.get('fullProfitUnlockTime', 0)
profit_unlock_rate = profit_unlock_settings.get('profitUnlockRate', 0)
last_profit_unlock_time = profit_unlock_settings.get('lastProfitUnlockTime', 0)
self_balance = pool_state.get('selfBalance', 0) # this.balanceOf(address(this))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this refers to the AutopoolFees contract itself, we’ll need the on-chain address of the AutopoolFees contract to correctly fetch this balance. Could you clarify where we should be sourcing that address from.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AutopoolFees are a library which is used on the Autopool contract.

Thus, any state that is in autopoolfees.py is in Autopuul contract.

image

self_balance is IERC20(address(this)).balanceOf(address(this))

break

# currentShares is destVault.balanceOf(address(this)) where `this` is the autopool contract
current_shares = destination_info[dest_vault].get('currentShares', 0)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this refers to the AutopoolDebtcontract itself, we’ll need the on-chain address of the AutopoolDebt contract to correctly fetch this balance. Could you clarify where we should be sourcing that address from.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AutopoolDebt is a library which is used on the Autopool contract.

Thus, any state that is in autopooldebt.py is in Autopool contract.

Regarding the destination_info Dict, it is a mapping of address => DestVaultInfo. The address keys can be obtained from calling Autopool.getDestinations() which returns an array of addresses. The struct of a DestVaultInfo has been described here:

image


destination_info[destl]["currentShares"] = currentShares
destination_info[destl]["underlyerCeilingPrice"] = underlyerCeilingPrice
destination_info[destl]["underlyerFloorPrice"] = underlyerFloorPrice
Copy link

@Ishita-GlueX Ishita-GlueX Aug 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For fetching each state we have a max computation units set to 1000000. While fetching underlyerCeilingPrice its taking more than the max computation units.
Here is the tenderly simulation you can have a look.

https://www.tdly.co/shared/simulation/73ccb525-6a4f-43cf-9f0a-ce0ec44dac98

Because of this limitation, we won’t be able to integrate this.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will devise a solution that fits this constraint

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Ishita-GlueX is it possible that the computation unit be increased by 100k? That specific pool is directed towards institutional usage and is a new addition to the Tokemak catalogue.

image

You can see here after the 100k CU limit addition, the function call actually requires less than 1M CU:
https://www.tdly.co/shared/simulation/01424017-c55a-45df-8ccb-1c5078d60f17

Copy link

@Ishita-GlueX Ishita-GlueX Aug 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0x4b1ea6f0e97cb0e859b1521a4548fbd0a94e6a63 is a destination vault address, not a pool address.
Fetching getUnderlyerCeilingPrice() from this is consuming too much gas (over 100k).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand, fetching each state such as DestinationVault.underlyerCeilingPrice() has a limit of 1M CU. However, DestinationVault.underlyerCeilingPrice() actually did not use more than that (1M CU). Instead, tenderly fails for some reason with gaslimit=1M. So, I increased the limit by 100k, essentially using gaslimit=1.1M. This, works and the result shows that underlyerCeillingPrice actually did not use more than 1M CU, but somehow blocked by a factor unknown.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The behavior is not always consistent — sometimes the call goes through under 1M, and other times it fails unless given some extra buffer. So it’s not a fixed threshold.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Ishita-GlueX This Silo institutional pool was new and is not under my watch when I implement this integration. The only pools that does this is Silo Institutional's, there are 2 of them. Other pools only need about 200k CU to fetch DestinationVault.underlyerCeilingPrice().

@HanzCEO HanzCEO requested a review from Ishita-GlueX September 9, 2025 06:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants