diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..606b157 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,374 @@ +# Changelog - TermMax Contract + +All notable changes to this project are documented in this file. + +## 2026-04-16 - dev + +### Added +- Extended `ITermMax4626Pool` with `currentIncomeAssets()` and updated `TermMaxViewer` to use current income asset data. + +### Fixed +- Fixed a logic issue in `TermMaxViewer`. + +## 2026-04-16 - PR #25 (feat/pharos_oracle_adapter) + +### Added +- Added `IPharosOracle`, `TermMaxPharosPriceFeedAdapter`, `TermMaxPharosPriceFeedAdapterFactory`, and integration test coverage for the Pharos oracle adapter. + + +## 2026-04-14 - PR #24 (feat/whitelist_check) + +### Added +- Added market and pool whitelist checks to `TermMaxRouterV2`, `MakerHelper`, `TermMaxVaultV2`. +- Added automatic whitelist register to factories. +- Added order expiry timestamp management with related errors, events, and tests. +- Added stable ERC4626 access-control support and related test coverage. + +### Fixed +- Fixed predict order address issue. + +## 2026-03-20 - PR #21 (from dev) + +### Deployments +- Updated contract deployment information. + +## 2026-03-20 - PR #20 (from dev) + +### Refactor +- Removed unused swap adapter contracts and cleaned up related code. + +## 2026-03-20 - PR #19 (fix/uniswap_adapter_v2) + +### Fixed +- Fixed an issue in the Uniswap V2 adapter. + +### Added +- Added a maximum update interval to the Ondo price feed adapter. +- Refactored `ERC20SwapAdapterV2` to inherit from `ERC20SwapAdapterV1` and improved swap behavior for compatibility with the v1 router. + +## 2026-03-20 - PR #18 (feature/lifi_swap_adapter) + +### Added +- Added the `LifiSwapAdapter` as a LiFi aggregation swap adapter with selector validation and error handling. + +### Fixed +- Fixed an allowance-related DoS issue. +- Fixed the adapter refund mechanism to prevent tokens from being locked in the GT contract. + +## 2026-03-20 - PR #17 (fix/ondo_pricefeed_timestamp) + +### Added +- Added a maximum update interval to the Ondo price feed adapter. + +## 2026-03-02 - PR #15 (from dev) + +### Added +- Added `TermMaxBeefySharePriceFeedAdapter` to retrieve Beefy Vault share prices. +- Used fair price calculations for LP token valuation. + +### Fixed +- Fixed related issues and documentation wording. + +## 2026-02-25 - PR #14 (from dev) + +### Added +- Added the `ISupraSValueFeed` interface and `TermMaxB2TokenPriceFeedAdapter` for B2 chain price data. +- Added `TermMaxUSPCPriceFeedAdapter` and its integration tests. +- Added an Ondo protocol price feed adapter under `feat/ondo_pricefeed_adapter`. +- Added `StableERC4626ForVenus` for Venus deposits, withdrawals, and yield accounting. +- Added `StableERC4626ForCustomize` and factory support for custom ERC4626 pools. +- Updated `OKX ScaleHelper` and related tests. + +### Fixed +- Removed redundant storage from the price feed converter. +- Set the refund address to `msg.sender` when `address(0)` is provided. +- Accrued interest before deposits and withdrawals. +- Enhanced `OndoSwapAdapter` to track `USDon` balances and improve swap logic. + +## 2026-02-10 - PR #11, #12, #13 (from dev / fix/ondo_adapter) + +### Added +- Added `StableERC4626ForVenus` under `feat/venus` with buffer management and income asset handling. +- Added `FactoryErrorsV2` and `StableERC4626ForCustomize` support in `TermMax4626Factory` under `feat/customize_pool`. +- Upgraded the OKX swap adapter under `update/okx_adapter_20260121`. + +### Fixed +- Fixed the `address(0)` refund logic in the Ondo adapter in PR #12 (`fix/ondo_adapter_20260210`). + +## 2026-02-02 - PR #10 (from dev) + +### Added +- Added `StableERC4626ForVenus` and `StableERC4626ForCustomize` with buffer management and income asset handling. +- Enhanced `OkxSwapHelper`. +- Enhanced `OndoSwapAdapter` with `USDon` refunds and improved swap behavior. +- Added `FactoryErrorsV2` and dynamic implementation management to `TermMax4626Factory`. +- Added asset withdrawal and initialization events in `ERC4626TokenEvents`. + +### Fixed +- Cleared `tstore` state after use. + +## 2026-01-22 - PR #9 (temp/merge_dev_before_fix) + +### Added +- Added `OneInchSwapAdapter` and related tests. +- Added `OndoSwapAdapter` to compute net `USDC` and `USDT` outputs. +- Added refund address support to `TermMaxSwapAdapter`. +- Added a price feed adapter for the `DUSD` token. +- Added an OFT version of the TMX token contract. + +### Fixed +- Fixed issues in the rollover flow under `fix/rollover_issue_20260120`. +- Fixed refund logic for exact-output swaps in `TermMaxSwapAdapter`. +- Fixed the contract title in `OneInchSwapAdapter`. + +## 2025-12-04 - PR #7 (from feat/order_earn_interest) + +### Added +- Added `PancakeSmartAdapter`, Pancake helper utilities, and full test coverage. +- Added rollover support to the router contract. + +### Fixed +- Fixed event definition issues. +- Fixed related issues and removed the Stroom adapter. + +## 2025-12-02 - PR #5 (from feat/order_earn_interest) + +### Added +- Added `ITermMax4626Pool`, `ITermMaxVault`, and the `TermMaxViewer` contract with tests. +- Added exact-position leverage and updated flash loan handling. +- Added `TermMaxWeETHPriceCapAdapter` based on AAVE's `WeETHPriceCapAdapter`, along with deployment scripts and fork tests. +- Added `IKodiakRouter` and `KodiakSwapAdapter`. +- Added an OKX swap adapter. +- Added `SimpleAggregator` for price retrieval and oracle management. +- Added an `srUSDe` oracle adapter. +- Deployed the TMX token contract. +- Updated `RouterV1.1.2` with: + - upgradeable reentrancy protection via `ReentrancyGuardUpgradeable` and `nonReentrant` on critical external entry points; + - support for the `EXACT_POSITION` flash loan type for exact-position leverage; + - stronger callback validation through `onlyCallbackAddress` and `T_CALLBACK_ADDRESS_STORE`; + - new or extended routing methods including `swapExactTokenToTokenWithDex`, `sellCall`, `flashRepayFromColl` with `expectedOutput`, and `flashRepayToGetCollateral`; + - stricter adapter whitelist checks and selected `delegatecall` flows for `approveOutputToken`; + - a refactored `executeOperation` flow split between `_exactPositionLeverage` and `_generalLeverage`; + - reentrancy guard initialization through `__ReentrancyGuard_init_unchained()` in `initialize`. + +### Fixed +- Added collateral checks to `GearingTokenWithERC20V2`. +- Allowed full liquidation when collateral cannot fully cover debt. +- Refactored `maxRedeem` to use the minimum of `userAssets` and `totalBadDebt`. +- Set `debtInAmt` to `0` in the `IssueGt` event for clarity. +- Removed unnecessary reverts for empty swap units in `TermMaxRouter`. +- Replaced `safeIncreaseAllowance` with `safeApprove` in swap adapters. + +## 2025-10-20 - PR #3 (from feat/order_earn_interest) + +### Added +- Added Uniswap V3 and PancakeSwap TWAP oracle contracts and tests. +- Added `OnlyDeliveryGearingToken`, a delivery-only GT that cannot be liquidated, remove collateral, or increase debt. +- Added support for flash repay to obtain collateral tokens. +- Added exact-output support to the Uniswap adapter. + +### Deployments +- Deployed markets and vaults to HyperEVM, Ethereum, Arbitrum, and BNB. +- Upgraded routers on Ethereum, Arbitrum, and BNB. +- Added deployment scripts for Pancake and Uniswap price feeds. +- Deployed Stable ERC4626 for 4626. + +## 2025-10-13 - PR #2 (from feat/order_earn_interest) + +### Added +- Emitted the actual debt token input amount in events. + +### Fixed +- Removed partial flash repay and rollover logic from `RouterV2` to fix partial flash repay issues. +- Fixed the issue that allowed GT positions to repay or remove collateral after maturity. +- Fixed a potential `badDebt` overflow. +- Fixed Chainlink dependency issues. + +### Deployments +- Deployed V2 core contracts to Ethereum, Arbitrum, and BNB mainnets. +- Deployed the BNB AAVE pool and vault. + +## 2025-09-25 - PR #1 (from feat/order_earn_interest) + +### Added +- Added `WhitelistManager` to protect users. +- Added versioned functionality to `AccessManagerV2`. +- Deployed `MakerHelper` to Ethereum, Arbitrum, and BNB. +- Allowed `updateOrder` and liquidity withdrawals while the vault is paused. + +### Fixed +- Fixed an issue where GT could potentially be stolen. +- Fixed an issue where force approve could be used with ERC721 tokens. +- Added reentrancy protection to `TermMaxRouter`. +- Fixed missing checks when redeeming orders from the vault. +- Fixed zero-debt loans being unable to remove collateral. +- Fixed an issue blocking pool share withdrawals from orders. +- Fixed non-atomic updates between virtual XT reserve and curve update functions. +- Updated `repayAndRemoveCollateral` so it no longer burns GT tokens. +- Fixed CVF audit issues: CVF-2, CVF-3, CVF-13, CVF-16, CVF-60, CVF-65, CVF-69, CVF-84, CVF-85, CVF-88, and CVF-89. +- Added FT balance checks to orders. + +## 2025-07-03 + +### Added +- Added a special swap adapter for the V1 protocol under `v1_special_adapter`. + +## 2025-06-04 + +### Added +- Added the `VersionV2` version management mechanism under `feat/version_managenent`. + +## 2025-05-26 + +### Added +- Added the `PreTMX` token contract under `feat/preTMX`. + +## 2025-05-21 + +### Added +- Added Gearing Token rollup support under `feat/gt_roll_up`. +- Added batch pause and unpause support under `batch_swtich`. +- Updated price feed related contracts under `update_price_feed`. + +## 2025-04-08 + +### Added +- Configured dependency management under `config_dependencies`. + +## 2025-03-24 + +### Added +- Added a Pendle PT redeem adapter under `adapter_pt_redeem`. + +## 2025-03-23 + +### Added +- Added `AccessManagerV2` with whitelist management under `feat/add_access_manager`. + +## 2025-03-21 + +### Added +- Added `TermMaxPriceFeedConverter` under `pPriceFeed_converter`. + +## 2025-03-20 + +### Added +- Added leverage fee support under `feat/leverage_fee`. + +## 2025-03-07 to 2025-03-11 + +### Fixed +- Fixed the curve guessing algorithm under `curve-guess` and `fix/curve-guess`. + +## 2025-02-05 to 2025-03-05 + +### Fixed +- Applied multiple rounds of fixes for issues identified in the Cetina security audit under `v2_fix_cetina_issues`. + +## 2025-02-14 + +### Tests +- Added end-to-end loop tests under `v2_e2e_loop_test`. + +## 2025-02-06 + +### Added +- Added the V2 proof-of-concept base contracts under `v2_poc_base`. +- Added vault deployment scripts under `v2_vault_deploy_script`. + +## 2025-02-04 + +### Refactor +- Split the vault into `OrderManager` and `TermMaxVault` under `v2_split_vault_contract`. + +## 2025-02-03 + +### Fixed +- Fixed review comments under `v2_fix_nic_sugesstions`. + +## 2025-01-24 + +### Added +- Added curve parameter validation under `v2_check_curve`. + +## 2025-01-23 + +### Added +- Added the V2 access control framework under `v2_access_control`. + +## 2025-01-22 + +### Added +- Added routing logic for borrowing workflows under `borrow_story_router`. +- Added vault initialization under `poc/feat/vault_initialize`. + +## 2025-01-06 + +### Fixed +- Fixed reserve accounting during `issueFt` under `fix_issueFt_error_reserve`. + +## 2024-12-30 + +### Fixed +- Fixed issues from the Catina Solo audit under `audit/fix_catina_solo`. + +## 2024-12-18 + +### Added +- Added the Market Curator role and related mechanics under `market_curator`. + +### Fixed +- Fixed issues from audit round #10 under `fix_audit_10`. + +## 2024-12-16 + +### Refactor +- Renamed PT price feed related contracts under `Rename-pt-with-price-feed`. +- Removed permit functionality under `Remove-permit-function`. + +## 2024-12-15 + +### Added +- Added withdrawal limits for excess FT and XT under `add-limit-to-withdraw-excess-ft-and-xt`. +- Added oracle add and remove functions under `add_remove_oracle_functions`. + +## 2024-12-13 + +### Fixed +- Fixed issues identified during the audit under `fix_audit`. + +## 2024-12-12 + +### Refactor +- Removed the enlarged LP mechanism under `remove-enlarged-lp`. + +## 2024-12-06 + +### Added +- Added `OracleAggregator` with multi-oracle aggregation support under `oracle_aggregator`. +- Added a liquidity provider whitelist under `add-provider-whitelist`. + +## 2024-12-05 + +### Added +- Added the `MarketViewer` contract for market data queries under `feat/market-viewer`. +- Added flash repay through FT under `flash_repay_through_ft`. + +### Fixed +- Fixed issues identified in the Spearbit competition audit under `fix_audit_spearbit_competetion_issues`. + +## 2024-11-19 to 2024-11-20 + +### Added +- Added leveraged position opening with flash loan strategies under `feat/lever-evan`. + +## 2024-11-02 to 2024-11-05 + +### Added +- Merged the V2 MVP contracts into `main` under `2410-ya-mvp`, including the core Market, Order, and Router logic. +- Added the `TermMaxRouter` contract under `feat/router`. + +## 2024-10-01 + +### Initial +- Initialized the V2 development branch by merging `dev` into `main`. diff --git a/README.md b/README.md index 1d7e2f2..98bbd82 100644 --- a/README.md +++ b/README.md @@ -78,3 +78,228 @@ Add configurations to your .vscode/settings.json ```shell $ npm ci ``` + +## Gas Report + +Below are gas-report summaries for key contracts. Use the overview table for deployment comparisons, then expand each contract section for per-function stats. + +| Contract | Source | Deploy Cost | Deploy Size | +|---|---|---:|---:| +| TermMaxMarketV2 | contracts/v2/TermMaxMarketV2.sol | 3,342,898 | 15,520 | +| TermMaxOrderV2 | contracts/v2/TermMaxOrderV2.sol | 5,381,106 | 24,722 | +| MakerHelper | contracts/v2/router/MakerHelper.sol | 2,458,785 | 11,377 | +| TermMaxRouterV2 | contracts/v2/loader/TermMaxRouterV2.sol | 4,907,139 | 22,737 | +| GearingTokenWithERC20V2 | contracts/v2/tokens/GearingTokenWithERC20V2.sol | 5,096,680 | 23,407 | +| TermMaxVaultV2 | contracts/v2/vault/TermMaxVaultV2.sol | 4,736,478 | 22,022 | + +
+TermMaxMarketV2 - contracts/v2/TermMaxMarketV2.sol + +| Function | Min | Avg | Median | Max | Calls | +|---|---:|---:|---:|---:|---:| +| acceptOwnership | 12,313 | 12,313 | 12,313 | 12,313 | 25 | +| burn(address,address,uint256) | 8,152 | 44,110 | 40,097 | 88,097 | 4 | +| burn(address,uint256) | 27,602 | 69,503 | 71,602 | 87,902 | 2,225 | +| config | 1,838 | 4,215 | 3,838 | 5,838 | 10,113 | +| createOrder((address,address,address,address,address,uint256,address,uint64,(((uint256,uint256,int256)[],(uint256,uint256,int256)[]),uint256,uint256,address,(uint32,uint32,uint32,uint32,uint32,uint32)))) | 784,349 | 1,061,596 | 1,205,737 | 2,503,377 | 3,343 | +| createOrder(...,uint256) | 1,169,360 | 1,195,109 | 1,195,160 | 1,195,160 | 513 | +| createOrder(address,uint256,address,((uint256,uint256,int256)[],(uint256,uint256,int256)[])) | 6,900 | 1,152,335 | 1,159,950 | 1,159,950 | 153 | +| initialize | 75,027 | 960,040 | 961,469 | 961,469 | 2,422 | +| issueFt | 8,319 | 410,459 | 420,059 | 455,449 | 2,383 | +| issueFtByExistedGt | 7,661 | 149,196 | 147,330 | 201,430 | 518 | +| leverageByXt(address,address,uint128,bytes) | 482,882 | 514,448 | 531,682 | 531,682 | 515 | +| leverageByXt(address,uint128,bytes) | 8,237 | 512,271 | 510,301 | 531,901 | 515 | +| mint | 7,653 | 112,425 | 109,068 | 160,368 | 8,587 | +| mintGtFeeRatio | 1,052 | 5,045 | 5,052 | 5,052 | 1,804 | +| name | 2,786 | 2,786 | 2,786 | 2,786 | 1 | +| predictOrderAddress | 10,359 | 10,359 | 10,359 | 10,359 | 130 | +| previewRedeem | 47,220 | 47,220 | 47,220 | 47,220 | 1 | +| redeem(address,address,uint256) | 21,041 | 58,743 | 21,041 | 134,148 | 3 | +| redeem(uint256,address) | 99,075 | 110,526 | 116,175 | 127,380 | 761 | +| tokens | 5,245 | 11,236 | 11,245 | 11,245 | 4,259 | +| transferOwnership | 26,800 | 26,800 | 26,800 | 26,800 | 25 | +| updateGtConfig | 22,398 | 22,398 | 22,398 | 22,398 | 1 | +| updateMarketConfig | 2,590 | 15,061 | 3,424 | 34,423 | 5 | +| updateOrderFeeRate | 12,316 | 12,316 | 12,316 | 12,316 | 1 | + +
+ +
+TermMaxOrderV2 - contracts/v2/TermMaxOrderV2.sol + +| Function | Min | Avg | Median | Max | Calls | +|---|---:|---:|---:|---:|---:| +| addLiquidity | 35,437 | 126,353 | 126,890 | 147,024 | 133 | +| apr | 30,936 | 44,540 | 30,936 | 71,748 | 3 | +| borrowToken | 7,848 | 98,030 | 68,929 | 246,413 | 4 | +| getRealReserves | 19,927 | 27,849 | 28,322 | 35,427 | 60 | +| initialize | 715,363 | 1,012,118 | 1,134,172 | 2,424,027 | 3,948 | +| maker | 2,515 | 2,515 | 2,515 | 2,515 | 385 | +| market | 2,747 | 2,747 | 2,747 | 2,747 | 1 | +| orderConfig | 15,877 | 86,775 | 105,877 | 110,877 | 1,327 | +| orderExpiryTimestamp | 2,345 | 2,345 | 2,345 | 2,345 | 6 | +| owner | 2,823 | 2,823 | 2,823 | 2,823 | 2 | +| pause | 2,832 | 14,517 | 14,517 | 26,202 | 2 | +| paused | 2,635 | 2,635 | 2,635 | 2,635 | 2 | +| pool | 329 | 1,344 | 2,329 | 2,329 | 528 | +| redeemAll | 223,403 | 292,932 | 330,903 | 348,003 | 1,281 | +| removeLiquidity | 42,513 | 191,231 | 196,335 | 196,335 | 268 | +| setCurveAndPrice | 5,506 | 66,624 | 9,995 | 219,286 | 571 | +| setExpiryTimestamp | 2,774 | 21,028 | 23,730 | 23,730 | 10 | +| setGeneralConfig | 2,776 | 34,925 | 28,445 | 48,345 | 776 | +| setPool | 192,724 | 237,865 | 238,115 | 249,266 | 137 | +| swapExactTokenToToken | 8,012 | 310,958 | 351,422 | 500,659 | 2,122 | +| swapTokenToExactToken | 10,600 | 367,504 | 382,282 | 577,327 | 1,065 | +| unpause | 8,544 | 8,544 | 8,544 | 8,544 | 1 | +| updateFeeConfig | 3,297 | 3,297 | 3,297 | 3,298 | 2 | +| virtualXtReserve | 2,253 | 2,253 | 2,253 | 2,253 | 425 | +| withdrawAllAssetsBeforeMaturity | 115,430 | 155,346 | 141,091 | 172,700 | 256 | +| withdrawAssets | 23,640 | 32,652 | 38,082 | 40,740 | 7 | + +
+ +
+MakerHelper - contracts/v2/router/MakerHelper.sol + +| Function | Min | Avg | Median | Max | Calls | +|---|---:|---:|---:|---:|---:| +| initialize | 50,700 | 50,700 | 50,700 | 50,700 | 6 | +| placeOrderForV1 | 16,220 | 895,925 | 895,925 | 1,775,630 | 2 | +| placeOrderForV2 | 21,208 | 909,579 | 840,178 | 1,883,573 | 1,024 | + +
+ +
+TermMaxRouterV2 - contracts/v2/loader/TermMaxRouterV2.sol + +| Function | Min | Avg | Median | Max | Calls | +|---|---:|---:|---:|---:|---:| +| acceptOwnership | 12,280 | 12,280 | 12,280 | 12,280 | 26 | +| borrowTokenFromCollateral | 958,476 | 958,476 | 958,476 | 958,476 | 1 | +| borrowTokenFromCollateralAndXt | 676,873 | 704,351 | 729,763 | 729,763 | 256 | +| executeOperation(address,address,uint256,bytes) | 75,401 | 106,526 | 116,901 | 116,901 | 1,024 | +| executeOperation(address,uint128,address,bytes,bytes) | 97,381 | 219,102 | 97,381 | 462,545 | 3 | +| flashRepayFromColl | 348,149 | 539,792 | 539,792 | 731,436 | 2 | +| flashRepayToGetCollateral | 348,747 | 348,747 | 348,747 | 348,747 | 1 | +| initialize | 75,674 | 75,674 | 75,674 | 75,674 | 48 | +| initializeV2 | 9,116 | 9,116 | 9,116 | 9,116 | 1 | +| leverage | 665,703 | 800,811 | 692,400 | 1,149,691 | 1,024 | +| onERC721Received | 766 | 766 | 766 | 766 | 260 | +| owner | 2,636 | 2,636 | 2,636 | 2,636 | 1 | +| pause | 2,645 | 20,172 | 26,015 | 26,015 | 4 | +| paused | 2,492 | 2,492 | 2,492 | 2,492 | 6 | +| proxiableUUID | 394 | 394 | 394 | 394 | 2 | +| swapAndRepay | 535,507 | 575,440 | 575,440 | 615,374 | 2 | +| swapTokens | 49,878 | 434,353 | 585,691 | 805,103 | 7 | +| transferOwnership | 26,811 | 26,811 | 26,811 | 26,811 | 26 | +| unpause | 8,561 | 8,561 | 8,561 | 8,561 | 3 | +| upgradeToAndCall | 10,925 | 15,667 | 15,667 | 20,410 | 2 | + +
+ +
+GearingTokenWithERC20V2 - contracts/v2/tokens/GearingTokenWithERC20V2.sol + +| Function | Min | Avg | Median | Max | Calls | +|---|---:|---:|---:|---:|---:| +| DOMAIN_SEPARATOR | 6,019 | 6,019 | 6,019 | 6,019 | 267 | +| addCollateral | 8,925 | 33,653 | 46,018 | 46,018 | 3 | +| approve | 26,874 | 26,874 | 26,874 | 26,874 | 7 | +| augmentDebt | 94,078 | 96,989 | 96,878 | 113,978 | 517 | +| balanceOf | 3,040 | 3,040 | 3,040 | 3,040 | 7 | +| collateralCapacity | 3,188 | 3,188 | 3,188 | 3,188 | 1 | +| delivery | 34,011 | 34,084 | 34,011 | 45,216 | 762 | +| flashRepay(uint256,bool,bytes) | 199,751 | 327,401 | 199,751 | 582,702 | 3 | +| flashRepay(uint256,uint128,bool,bytes,bytes) | 17,698 | 100,053 | 102,745 | 177,023 | 4 | +| getGtConfig | 12,841 | 12,841 | 12,841 | 12,841 | 3 | +| getLiquidationInfo | 14,390 | 14,913 | 14,390 | 82,162 | 1,033 | +| initialize | 25,189 | 331,884 | 332,138 | 332,138 | 2,419 | +| isDelegate | 3,039 | 3,039 | 3,039 | 3,039 | 145 | +| liquidatable | 3,049 | 3,049 | 3,049 | 3,049 | 765 | +| liquidate | 54,631 | 177,626 | 183,905 | 248,958 | 526 | +| loanInfo | 2,374 | 7,187 | 10,374 | 10,374 | 2,596 | +| merge | 23,630 | 77,856 | 87,888 | 148,457 | 5 | +| mint | 28,085 | 337,956 | 337,059 | 349,159 | 3,411 | +| nonces | 3,058 | 3,058 | 3,058 | 3,058 | 284 | +| ownerOf | 2,984 | 2,984 | 2,984 | 2,984 | 1 | +| previewDelivery | 8,791 | 8,791 | 8,791 | 8,791 | 1 | +| removeCollateral | 10,984 | 66,785 | 66,608 | 131,569 | 264 | +| repay | 17,374 | 87,770 | 82,818 | 149,607 | 12 | +| repayAndRemoveCollateral | 11,433 | 92,963 | 94,239 | 177,368 | 265 | +| safeTransferFrom(address,address,uint256) | 52,432 | 52,432 | 52,432 | 52,432 | 257 | +| safeTransferFrom(address,address,uint256,bytes) | 7,275 | 67,865 | 76,259 | 76,871 | 8 | +| setDelegate | 702 | 20,720 | 24,894 | 24,894 | 27 | +| setDelegateWithSignature | 953 | 54,821 | 57,205 | 57,205 | 139 | +| setTreasurer | 7,975 | 7,975 | 7,975 | 7,975 | 2 | +| tokenOfOwnerByIndex | 3,079 | 3,079 | 3,079 | 3,079 | 1 | +| totalSupply | 2,422 | 2,422 | 2,422 | 2,422 | 256 | +| updateConfig | 11,241 | 11,241 | 11,241 | 11,241 | 1 | + +
+ +
+TermMaxVaultV2 - contracts/v2/vault/TermMaxVaultV2.sol + +| Function | Min | Avg | Median | Max | Calls | +|---|---:|---:|---:|---:|---:| +| acceptGuardian | 3,706 | 9,969 | 13,101 | 13,101 | 3 | +| acceptMarket | 4,436 | 41,849 | 42,111 | 42,111 | 144 | +| acceptPendingMinApy | 2,504 | 7,234 | 7,238 | 11,955 | 4 | +| acceptPerformanceFeeRate | 29,506 | 29,506 | 29,506 | 29,506 | 1 | +| acceptPool | 8,948 | 121,383 | 139,148 | 198,288 | 4 | +| acceptTimelock | 3,384 | 8,072 | 8,076 | 12,751 | 4 | +| accretingPrincipal | 12,304 | 12,304 | 12,304 | 12,304 | 1 | +| afterSwap | 4,129 | 166,375 | 206,501 | 255,413 | 30 | +| annualizedInterest | 4,138 | 4,138 | 4,138 | 4,138 | 13 | +| approve | 24,458 | 24,458 | 24,458 | 24,458 | 1 | +| apy | 7,108 | 7,108 | 7,108 | 7,108 | 14 | +| badDebtMapping | 3,111 | 3,111 | 3,111 | 3,111 | 8 | +| balanceOf | 3,255 | 3,255 | 3,255 | 3,255 | 11 | +| createOrder | 15,505 | 1,289,631 | 1,278,011 | 1,312,411 | 1,119 | +| curator | 4,176 | 4,176 | 4,176 | 4,176 | 3 | +| dealBadDebt | 8,666 | 55,126 | 54,485 | 87,090 | 12 | +| deposit | 77,866 | 181,614 | 158,663 | 266,018 | 79 | +| guardian | 2,855 | 2,855 | 2,855 | 2,855 | 4 | +| initialize | 246,103 | 286,475 | 285,903 | 319,691 | 87 | +| marketWhitelist | 2,705 | 2,705 | 2,705 | 2,705 | 5 | +| minApy | 2,636 | 2,636 | 2,636 | 2,636 | 5 | +| pause | 26,690 | 27,620 | 26,690 | 28,862 | 7 | +| paused | 2,983 | 2,983 | 2,983 | 2,983 | 2 | +| pendingGuardian | 3,579 | 3,579 | 3,579 | 3,579 | 1 | +| pendingMarkets | 3,406 | 3,406 | 3,406 | 3,406 | 2 | +| pendingMinApy | 4,378 | 4,378 | 4,378 | 4,378 | 19 | +| pendingPerformanceFeeRate | 3,146 | 3,146 | 3,146 | 3,146 | 1 | +| pendingPool | 4,173 | 4,173 | 4,173 | 4,173 | 18 | +| pendingTimelock | 3,630 | 3,630 | 3,630 | 3,630 | 2 | +| performanceFeeRate | 2,454 | 2,454 | 2,454 | 2,454 | 2 | +| pool | 2,526 | 2,526 | 2,526 | 2,526 | 3 | +| previewDeposit | 11,188 | 12,839 | 11,188 | 16,143 | 6 | +| previewRedeem | 14,823 | 16,675 | 14,823 | 19,455 | 15 | +| previewWithdraw | 13,838 | 14,061 | 13,838 | 14,360 | 7 | +| redeem | 83,527 | 105,735 | 107,128 | 130,730 | 12 | +| redeemOrder | 259,100 | 329,255 | 261,238 | 476,130 | 1,030 | +| removeLiquidityFromOrders | 173,063 | 209,636 | 209,636 | 246,210 | 4 | +| revokePendingGuardian | 8,739 | 9,825 | 9,825 | 10,911 | 2 | +| revokePendingMarket | 10,816 | 11,902 | 11,902 | 12,988 | 2 | +| revokePendingMinApy | 5,517 | 8,984 | 9,465 | 11,637 | 5 | +| revokePendingPerformanceFeeRate | 9,421 | 9,421 | 9,421 | 9,421 | 1 | +| revokePendingPool | 5,231 | 7,908 | 8,551 | 11,351 | 5 | +| revokePendingTimelock | 10,081 | 11,167 | 11,167 | 12,253 | 2 | +| setCurator | 10,588 | 10,588 | 10,588 | 10,588 | 4 | +| submitGuardian | 3,735 | 22,005 | 30,953 | 32,145 | 8 | +| submitMarket | 4,811 | 42,545 | 44,235 | 44,235 | 151 | +| submitPendingMinApy | 5,636 | 18,566 | 12,366 | 31,760 | 19 | +| submitPendingPool | 5,105 | 30,157 | 42,155 | 68,252 | 12 | +| submitPerformanceFeeRate | 5,983 | 20,292 | 28,791 | 32,196 | 9 | +| submitTimelock | 5,327 | 16,594 | 11,975 | 29,331 | 13 | +| timelock | 3,998 | 3,998 | 3,998 | 3,998 | 6 | +| totalAssets | 6,677 | 11,554 | 11,632 | 16,264 | 30 | +| totalFt | 3,038 | 3,038 | 3,038 | 3,038 | 12 | +| totalSupply | 2,553 | 2,553 | 2,553 | 2,553 | 10 | +| unpause | 8,928 | 9,362 | 8,928 | 11,100 | 5 | +| updateOrdersConfiguration | 342,779 | 342,779 | 342,779 | 342,779 | 4 | +| withdraw | 68,513 | 96,190 | 95,601 | 125,048 | 4 | +| withdrawFts | 23,132 | 72,229 | 71,432 | 122,923 | 4 | + +
+ diff --git a/contracts/v2/oracle/adapters/xaue/TermMaxXauePricefeedAdapter.sol b/contracts/v2/oracle/adapters/xaue/TermMaxXauePricefeedAdapter.sol new file mode 100644 index 0000000..6e6e82b --- /dev/null +++ b/contracts/v2/oracle/adapters/xaue/TermMaxXauePricefeedAdapter.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.27; + +import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; +import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; + +interface IXaueOracle { + function getLatestPrice() external view returns (uint256 price); + function lastUpdateTimestamp() external view returns (uint256 timestamp); +} + +/** + * @title TermMaxXauePricefeedAdapter + * @notice Adapter that wraps XAUE oracle to provide Chainlink AggregatorV3Interface + */ +contract TermMaxXauePricefeedAdapter is AggregatorV3Interface { + using SafeCast for *; + + IXaueOracle public constant xaueOracle = IXaueOracle(0x0618BD112C396060d2b37B537b3d92e757644169); + + function decimals() external pure override returns (uint8) { + return 18; + } + + function description() external view override returns (string memory) { + return "TermMax price feed: XAUE/XAUT"; + } + + function version() external pure override returns (uint256) { + return 1; + } + + function getRoundData(uint80) external pure override returns (uint80, int256, uint256, uint256, uint80) { + revert("GetRoundDataNotSupported"); + } + + function latestRoundData() external view override returns (uint80, int256, uint256, uint256, uint80) { + uint256 timestamp = xaueOracle.lastUpdateTimestamp(); + int256 answer = xaueOracle.getLatestPrice().toInt256(); + // For simplicity, we return the same timestamp for startedAt and updatedAt, and set roundId and answeredInRound to 1 + return (1, answer, timestamp, timestamp, 1); + } +} diff --git a/test/v2/integration/ForkXauePriceFeedAdapter.t.sol b/test/v2/integration/ForkXauePriceFeedAdapter.t.sol new file mode 100644 index 0000000..9c757de --- /dev/null +++ b/test/v2/integration/ForkXauePriceFeedAdapter.t.sol @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.27; + +import {Test} from "forge-std/Test.sol"; +import { + TermMaxXauePricefeedAdapter, + IXaueOracle, + AggregatorV3Interface +} from "contracts/v2/oracle/adapters/xaue/TermMaxXauePricefeedAdapter.sol"; +import {console} from "forge-std/console.sol"; +import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; +import {TermMaxPriceFeedFactoryV2} from "contracts/v2/factory/TermMaxPricefeedFactoryV2.sol"; + +/** + * @title ForkXauePriceFeedAdapterTest + * @notice Fork integration test for TermMaxXauePriceFeedAdapter using XAUE/XAUT pair + */ +contract ForkXauePriceFeedAdapterTest is Test { + using SafeCast for uint256; + + TermMaxXauePricefeedAdapter public adapter; + IXaueOracle public xaueOracle; + + // keep using existing env key in repo's fork tests + string internal MAINNET_RPC_URL = vm.envString("MAINNET_RPC_URL"); + + function setUp() public { + uint256 forkId = vm.createFork(MAINNET_RPC_URL); + vm.selectFork(forkId); + + adapter = new TermMaxXauePricefeedAdapter(); + xaueOracle = adapter.xaueOracle(); + } + + function testLatestPrice() public view { + (, int256 answer, uint256 timestamp,,) = adapter.latestRoundData(); + console.log("Adapter price:", answer); + console.log("Adapter timestamp:", timestamp); + uint256 oraclePrice = xaueOracle.getLatestPrice(); + assertEq(uint256(answer), oraclePrice, "Adapter price should match oracle price"); + assertEq(timestamp, xaueOracle.lastUpdateTimestamp(), "Adapter timestamp should match oracle timestamp"); + } + + function testInegration() public { + TermMaxPriceFeedFactoryV2 factory = TermMaxPriceFeedFactoryV2(0xFD9B5ee419C56f5ED3E86ba70953342906a7dE2B); + address xaue = 0xd5D6840ed95F58FAf537865DcA15D5f99195F87a; + address xautOracle = 0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6; + AggregatorV3Interface priceFeed = + AggregatorV3Interface(factory.createPriceFeedConverter(address(adapter), xautOracle, xaue)); + (, int256 answer, uint256 timestamp,,) = priceFeed.latestRoundData(); + uint8 decimals = priceFeed.decimals(); + console.log("Price feed decimals:", decimals); + console.log("Description:", priceFeed.description()); + console.log("Adapter price feed price:", answer); + console.log("Adapter price feed timestamp:", timestamp); + console.log("Price with decimals 8:", uint256(answer) * 10 ** (8 - decimals)); + } +}