Repository: DefiLlama/dimension-adapters
Pull request #2883: Add mellow LRTs fees adapter
Author: login: noateden
Created: 2025-04-14T05:10:00Z | Merged: 2025-04-14T12:47:20Z

- Add fees adapter for Mellow Protocol LRTs
- Also add a helper function for ERC4626 vaults


Diff:
diff --git a/fees/mellow.ts b/fees/mellow.ts
new file mode 100644
index 0000000000..eac7bbde31
--- /dev/null
+++ b/fees/mellow.ts
@@ -0,0 +1,111 @@
+import { FetchOptions, FetchResultV2, SimpleAdapter } from "../adapters/types";
+import { CHAIN } from "../helpers/chains";
+import { ChainApi } from "@defillama/sdk";
+import { getERC4626VaultsInfo } from "../helpers/erc4626";
+import { getConfig } from "../helpers/cache";
+
+const methodology = {
+  Fees: "Fees generated from staking assets in LRT vaults.",
+  SupplySideRevenue: "Fees are distributed to supply side depositors.",
+};
+
+const MellowAbis: any = {
+  configurator: 'address:configurator',
+  priceOracle: 'address:priceOracle',
+  baseTokens: 'function baseTokens(address) view returns (address)',
+  underlyingTvl: 'function underlyingTvl() view returns (address[] tokens, uint256[] amounts)',
+  getPrice: 'function getPrice(address, address) view returns (uint256 answer, uint8 decimals)',
+  totalSupply: 'uint256:totalSupply',
+  decimals: 'uint8:decimals',
+}
+
+// get active vaults from Mellow API
+// https://points.mellow.finance/v1/vaults
+const DVstETHVault = '0x5E362eb2c0706Bd1d134689eC75176018385430B'
+const DVstETHPriceOracle = '0x39D5F9aEbBEcba99ED5d707b11d790387B5acB63'
+async function getActiveVaults(): Promise<Array<string>> {
+  return ((await getConfig('mellow', 'https://points.mellow.finance/v1/vaults')).map((item: any) => item.address) as Array<string>)
+  .filter((vault: string) => String(vault).toLowerCase() !== String(DVstETHVault).toLowerCase())
+}
+
+async function getVaultInfo(usingApi: ChainApi, vault: string, priceOracle: string): Promise<{
+  totalBaseTokenDeposited: number
+  totalVaultSupply: number;
+}> {
+  let totalBaseTokenDeposited = 0;
+
+  const [tokens, amounts]: any = await usingApi.call({
+    abi: MellowAbis.underlyingTvl,
+    target: vault,
+  })
+  for (let tokenIndex = 0; tokenIndex < tokens.length; tokenIndex++) {
+    const token = tokens[tokenIndex]
+    const balance = amounts[tokenIndex]
+
+    const {answer, decimals} = await usingApi.call({
+      abi: MellowAbis.getPrice,
+      target: priceOracle,
+      params: [vault, token]
+    })
+
+    totalBaseTokenDeposited += Number(balance) * Number(answer) / 1e18
+  }
+
+  const totalSupply: bigint = await usingApi.call({
+    abi: MellowAbis.totalSupply,
+    target: vault,
+  })
+
+  return {
+    totalBaseTokenDeposited,
+    totalVaultSupply: Number(totalSupply),
+  }
+}
+
+const fetch = async (options: FetchOptions): Promise<FetchResultV2> => {
+  const dailyFees = options.createBalances()
+
+  // DVstETHVault
+  const DVstETHVaultInfoOld = await getVaultInfo(options.fromApi, DVstETHVault, DVstETHPriceOracle)
+  const DVstETHVaultInfoNew = await getVaultInfo(options.toApi, DVstETHVault, DVstETHPriceOracle)
+
+  const lrtRateOld = DVstETHVaultInfoOld.totalBaseTokenDeposited / DVstETHVaultInfoOld.totalVaultSupply
+  const lrtRateNew = DVstETHVaultInfoNew.totalBaseTokenDeposited / DVstETHVaultInfoNew.totalVaultSupply
+  const lrtRateIncrease = lrtRateNew - lrtRateOld
+
+  // token ETH
+  dailyFees.addGasToken(DVstETHVaultInfoOld.totalBaseTokenDeposited * lrtRateIncrease)
+
+  const vaults = await getActiveVaults()
+  const vaultInfosOld = await getERC4626VaultsInfo(options.fromApi, vaults)
+  const vaultInfosNew = await getERC4626VaultsInfo(options.toApi, vaults)
+
+  for (const [vault, vaultInfoOld] of Object.entries(vaultInfosOld)) {
+    const vaultInfoNew = vaultInfosNew[vault]
+    if (vaultInfoOld && vaultInfoNew) {
+      const vaultRateIncrease = vaultInfoNew.assetsPerShare - vaultInfoOld.assetsPerShare
+      dailyFees.add(vaultInfoOld.asset, vaultInfoOld.totalAssets * vaultRateIncrease / BigInt(1e18))
+    }
+  }
+
+  return {
+    dailyFees,
+    dailyRevenue: 0,
+    dailySupplySideRevenue: dailyFees,
+  }
+}
+
+const adapter: SimpleAdapter = {
+  version: 2,
+  adapter: {
+    [CHAIN.ETHEREUM]: {
+      fetch: fetch,
+      meta: {
+        methodology,
+      },
+      start: '2024-09-01',
+    },
+  },
+};
+
+export default adapter;
diff --git a/helpers/erc4626.ts b/helpers/erc4626.ts
new file mode 100644
index 0000000000..ed73b51327
--- /dev/null
+++ b/helpers/erc4626.ts
@@ -0,0 +1,71 @@
+import { ChainApi } from "@defillama/sdk";
+import { normalizeAddress } from "@defillama/sdk/build/util";
+
+// helper for ERC4626-vaults
+// https://docs.openzeppelin.com/contracts/4.x/erc4626
+
+const ERC4626Abis: any = {
+  asset: 'address:asset',
+  decimals: 'uint8:decimals',
+  totalAssets: 'uint256:totalSupply',
+  assetsPerShare: 'function convertToAssets(uint256 shares) view returns (uint256 assets)',
+}
+
+interface ERC4626VaultInfo {
+  asset: string;
+  assetDecimals: number;
+  totalAssets: bigint;
+  assetsPerShare: bigint;
+}
+
+// return info of a list of ERC4626 vaults
+export async function getERC4626VaultsInfo(usingApi: ChainApi, vaults: Array<string>): Promise<{
+  // vault address => ERC4626VaultInfo | null
+  [key: string]: ERC4626VaultInfo | null;
+}> {
+  const vaultInfos: {[key: string]: ERC4626VaultInfo| null} = {}
+
+  const assets: Array<string> = await usingApi.multiCall({
+    abi: ERC4626Abis.asset,
+    permitFailure: true,
+    calls: vaults,
+  })
+  const decimals: Array<string> = await usingApi.multiCall({
+    abi: ERC4626Abis.decimals,
+    permitFailure: true,
+    calls: vaults,
+  })
+  const totalAssets: Array<string> = await usingApi.multiCall({
+    abi: ERC4626Abis.totalAssets,
+    permitFailure: true,
+    calls: vaults,
+  })
+  const assetsPerShares: Array<string> = await usingApi.multiCall({
+    abi: ERC4626Abis.assetsPerShare,
+    permitFailure: true,
+    calls: vaults.map(vault => {
+      return {
+        target: vault,
+        params: ['1000000000000000000'],
+      }
+    }),
+  })
+
+  for (let i = 0; i < vaults.length; i++) {
+    const vault = vaults[i].toLowerCase()
+    const asset = assets[i]
+
+    if (asset) {
+      vaultInfos[vault.toLowerCase()] = {
+        asset: asset,
+        assetDecimals: Number(decimals[i]),
+        totalAssets: BigInt(totalAssets[i]),
+        assetsPerShare: BigInt(assetsPerShares[i]),
+      }
+    } else {
+      vaultInfos[vault] = null
+    }
+  }
+
+  return vaultInfos
+}
\ No newline at end of file


Reviews:
user: login: g1nt0ki
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-14T08:51:20Z
user: login: g1nt0ki
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-14T08:52:14Z
user: login: g1nt0ki
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-14T12:10:19Z
user: login: g1nt0ki
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-14T12:12:23Z
user: login: g1nt0ki
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-14T12:12:48Z
user: login: g1nt0ki
state: APPROVED
author_association: MEMBER
submitted_at: 2025-04-14T12:46:58Z

Review comments:
diff_hunk: @@ -0,0 +1,109 @@
+//  Maverick v1 fee
+import { FetchOptions, FetchResultV2, SimpleAdapter } from "../adapters/types";
+import { CHAIN } from "../helpers/chains";
+import { ChainApi } from "@defillama/sdk";
+import { httpGet } from "../utils/fetchURL";
+import { getERC4626VaultInfo } from "../helpers/erc4626";
+
+const methodology = {
+  Fees: "Fees generated from staking assets in LRT vaults.",
+  SupplySideRevenue: "Fees are distributed to supply side depositors.",
+};
+
+const MellowAbis: any = {
+  configurator: 'address:configurator',
+  priceOracle: 'address:priceOracle',
+  baseTokens: 'function baseTokens(address) view returns (address)',
+  underlyingTvl: 'function underlyingTvl() view returns (address[] tokens, uint256[] amounts)',
+  getPrice: 'function getPrice(address, address) view returns (uint256 answer, uint8 decimals)',
+  totalSupply: 'uint256:totalSupply',
+  decimals: 'uint8:decimals',
+}
+
+// get active vaults from Mellow API
+// https://points.mellow.finance/v1/vaults
+const DVstETHVault = '0x5E362eb2c0706Bd1d134689eC75176018385430B'
+const DVstETHPriceOracle = '0x39D5F9aEbBEcba99ED5d707b11d790387B5acB63'
+async function getActiveVaults(): Promise<Array<string>> {
+  return ((await httpGet('https://points.mellow.finance/v1/vaults')).map((item: any) => item.address) as Array<string>)
path: fees/mellow.ts
user: login: g1nt0ki
body: better to use [`getConfig`](https://github.com/DefiLlama/dimension-adapters/blob/master/helpers/cache.ts#L50) here, this way, if the endpoint is not reachable we have cached data.
created_at: 2025-04-14T08:51:20Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,52 @@
+import { ChainApi } from "@defillama/sdk";
+
+// helper for ERC4626-vaults
+// https://docs.openzeppelin.com/contracts/4.x/erc4626
+
+const ERC4626Abis: any = {
+  asset: 'address:asset',
+  decimals: 'uint8:decimals',
+  totalAssets: 'uint256:totalSupply',
+  assetsPerShare: 'function convertToAssets(uint256 shares) view returns (uint256 assets)',
+}
+
+interface ERC4626VaultInfo {
+  asset: string;
+  assetDecimals: number;
+  totalAssets: bigint;
+  assetsPerShare: bigint;
+}
+
+// return info of given ERC4626 vault
+export async function getERC4626VaultInfo(usingApi: ChainApi, vault: string): Promise<ERC4626VaultInfo | null> {
+  const asset = await usingApi.call({
path: helpers/erc4626.ts
user: login: g1nt0ki
body: better to use vault array here, that way we can use `multiCall`and cut down the number of calls
created_at: 2025-04-14T08:52:13Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,111 @@
+//  Maverick v1 fee
path: fees/mellow.ts
user: login: g1nt0ki
body: maverick v1 fee?
created_at: 2025-04-14T12:10:19Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,111 @@
+//  Maverick v1 fee
+import { FetchOptions, FetchResultV2, SimpleAdapter } from "../adapters/types";
+import { CHAIN } from "../helpers/chains";
+import { ChainApi } from "@defillama/sdk";
+import { getERC4626VaultsInfo } from "../helpers/erc4626";
+import { getConfig } from "../helpers/cache";
+
+const methodology = {
+  Fees: "Fees generated from staking assets in LRT vaults.",
+  SupplySideRevenue: "Fees are distributed to supply side depositors.",
+};
+
+const MellowAbis: any = {
+  configurator: 'address:configurator',
+  priceOracle: 'address:priceOracle',
+  baseTokens: 'function baseTokens(address) view returns (address)',
+  underlyingTvl: 'function underlyingTvl() view returns (address[] tokens, uint256[] amounts)',
+  getPrice: 'function getPrice(address, address) view returns (uint256 answer, uint8 decimals)',
+  totalSupply: 'uint256:totalSupply',
+  decimals: 'uint8:decimals',
+}
+
+// get active vaults from Mellow API
+// https://points.mellow.finance/v1/vaults
+const DVstETHVault = '0x5E362eb2c0706Bd1d134689eC75176018385430B'
+const DVstETHPriceOracle = '0x39D5F9aEbBEcba99ED5d707b11d790387B5acB63'
+async function getActiveVaults(): Promise<Array<string>> {
+  return ((await getConfig('mellow', 'https://points.mellow.finance/v1/vaults')).map((item: any) => item.address) as Array<string>)
+  .filter((vault: string) => String(vault).toLowerCase() !== String(DVstETHVault).toLowerCase())
+}
+
+async function getVaultInfo(usingApi: ChainApi, vault: string, priceOracle: string): Promise<{
+  totalBaseTokenDeposited: number
+  totalVaultSupply: number;
+}> {
+  let totalBaseTokenDeposited = 0;
+
+  const [tokens, amounts]: any = await usingApi.call({
+    abi: MellowAbis.underlyingTvl,
+    target: vault,
+  })
+  for (let tokenIndex = 0; tokenIndex < tokens.length; tokenIndex++) {
+    const token = tokens[tokenIndex]
+    const balance = amounts[tokenIndex]
+
+    const {answer, decimals} = await usingApi.call({
+      abi: MellowAbis.getPrice,
+      target: priceOracle,
+      params: [vault, token]
+    })
+
+    totalBaseTokenDeposited += Number(balance) * Number(answer) / 1e18
+  }
+
+  const totalSupply: bigint = await usingApi.call({
+    abi: MellowAbis.totalSupply,
+    target: vault,
+  })
+
+  return {
+    totalBaseTokenDeposited,
+    totalVaultSupply: Number(totalSupply),
+  }
+}
+
+const fetch = async (options: FetchOptions): Promise<FetchResultV2> => {
+  const dailyFees = options.createBalances()
+
+  // DVstETHVault
+  const DVstETHVaultInfoOld = await getVaultInfo(options.fromApi, DVstETHVault, DVstETHPriceOracle)
+  const DVstETHVaultInfoNew = await getVaultInfo(options.toApi, DVstETHVault, DVstETHPriceOracle)
+
+  const lrtRateOld = DVstETHVaultInfoOld.totalBaseTokenDeposited / DVstETHVaultInfoOld.totalVaultSupply
+  const lrtRateNew = DVstETHVaultInfoNew.totalBaseTokenDeposited / DVstETHVaultInfoNew.totalVaultSupply
+  const lrtRateIncrease = lrtRateNew - lrtRateOld
+
+  // token ETH
+  dailyFees.addGasToken(DVstETHVaultInfoOld.totalBaseTokenDeposited * lrtRateIncrease)
+
+  const vaults = await getActiveVaults()
+  const vaultInfosOld = await getERC4626VaultsInfo(options.fromApi, vaults)
+  const vaultInfosNew = await getERC4626VaultsInfo(options.toApi, vaults)
+
+  for (const [vault, vaultInfoOld] of Object.entries(vaultInfosOld)) {
+    const vaultInfoNew = vaultInfosNew[vault]
+    if (vaultInfoOld && vaultInfoNew) {
+      const vaultRateIncrease = vaultInfoNew.assetsPerShare - vaultInfoOld.assetsPerShare
+      dailyFees.add(vaultInfoOld.asset, Number(vaultInfoOld.totalAssets * vaultRateIncrease / BigInt(1e18)))
+    }
+  }
+
+  return {
+    dailyFees,
path: fees/mellow.ts
user: login: g1nt0ki
body: can you add dailyRevenue: 0 here, this way we let the users know that protocol charges no fee atm
created_at: 2025-04-14T12:12:23Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,111 @@
+//  Maverick v1 fee
+import { FetchOptions, FetchResultV2, SimpleAdapter } from "../adapters/types";
+import { CHAIN } from "../helpers/chains";
+import { ChainApi } from "@defillama/sdk";
+import { getERC4626VaultsInfo } from "../helpers/erc4626";
+import { getConfig } from "../helpers/cache";
+
+const methodology = {
+  Fees: "Fees generated from staking assets in LRT vaults.",
+  SupplySideRevenue: "Fees are distributed to supply side depositors.",
+};
+
+const MellowAbis: any = {
+  configurator: 'address:configurator',
+  priceOracle: 'address:priceOracle',
+  baseTokens: 'function baseTokens(address) view returns (address)',
+  underlyingTvl: 'function underlyingTvl() view returns (address[] tokens, uint256[] amounts)',
+  getPrice: 'function getPrice(address, address) view returns (uint256 answer, uint8 decimals)',
+  totalSupply: 'uint256:totalSupply',
+  decimals: 'uint8:decimals',
+}
+
+// get active vaults from Mellow API
+// https://points.mellow.finance/v1/vaults
+const DVstETHVault = '0x5E362eb2c0706Bd1d134689eC75176018385430B'
+const DVstETHPriceOracle = '0x39D5F9aEbBEcba99ED5d707b11d790387B5acB63'
+async function getActiveVaults(): Promise<Array<string>> {
+  return ((await getConfig('mellow', 'https://points.mellow.finance/v1/vaults')).map((item: any) => item.address) as Array<string>)
+  .filter((vault: string) => String(vault).toLowerCase() !== String(DVstETHVault).toLowerCase())
+}
+
+async function getVaultInfo(usingApi: ChainApi, vault: string, priceOracle: string): Promise<{
+  totalBaseTokenDeposited: number
+  totalVaultSupply: number;
+}> {
+  let totalBaseTokenDeposited = 0;
+
+  const [tokens, amounts]: any = await usingApi.call({
+    abi: MellowAbis.underlyingTvl,
+    target: vault,
+  })
+  for (let tokenIndex = 0; tokenIndex < tokens.length; tokenIndex++) {
+    const token = tokens[tokenIndex]
+    const balance = amounts[tokenIndex]
+
+    const {answer, decimals} = await usingApi.call({
+      abi: MellowAbis.getPrice,
+      target: priceOracle,
+      params: [vault, token]
+    })
+
+    totalBaseTokenDeposited += Number(balance) * Number(answer) / 1e18
+  }
+
+  const totalSupply: bigint = await usingApi.call({
+    abi: MellowAbis.totalSupply,
+    target: vault,
+  })
+
+  return {
+    totalBaseTokenDeposited,
+    totalVaultSupply: Number(totalSupply),
+  }
+}
+
+const fetch = async (options: FetchOptions): Promise<FetchResultV2> => {
+  const dailyFees = options.createBalances()
+
+  // DVstETHVault
+  const DVstETHVaultInfoOld = await getVaultInfo(options.fromApi, DVstETHVault, DVstETHPriceOracle)
+  const DVstETHVaultInfoNew = await getVaultInfo(options.toApi, DVstETHVault, DVstETHPriceOracle)
+
+  const lrtRateOld = DVstETHVaultInfoOld.totalBaseTokenDeposited / DVstETHVaultInfoOld.totalVaultSupply
+  const lrtRateNew = DVstETHVaultInfoNew.totalBaseTokenDeposited / DVstETHVaultInfoNew.totalVaultSupply
+  const lrtRateIncrease = lrtRateNew - lrtRateOld
+
+  // token ETH
+  dailyFees.addGasToken(DVstETHVaultInfoOld.totalBaseTokenDeposited * lrtRateIncrease)
+
+  const vaults = await getActiveVaults()
+  const vaultInfosOld = await getERC4626VaultsInfo(options.fromApi, vaults)
+  const vaultInfosNew = await getERC4626VaultsInfo(options.toApi, vaults)
+
+  for (const [vault, vaultInfoOld] of Object.entries(vaultInfosOld)) {
+    const vaultInfoNew = vaultInfosNew[vault]
+    if (vaultInfoOld && vaultInfoNew) {
+      const vaultRateIncrease = vaultInfoNew.assetsPerShare - vaultInfoOld.assetsPerShare
+      dailyFees.add(vaultInfoOld.asset, Number(vaultInfoOld.totalAssets * vaultRateIncrease / BigInt(1e18)))
path: fees/mellow.ts
user: login: g1nt0ki
body: no need to convert BigInt into number? https://github.com/DefiLlama/defillama-sdk/blob/master/src/generalUtil.ts#L72
created_at: 2025-04-14T12:12:48Z
author_association: MEMBER

PR comments:
user: login: llamabutler
created_at: 2025-04-14T05:11:27Z
body: The mellow.ts adapter exports:
        
 
 
    > adapters@1.0.0 test
    > ts-node --transpile-only cli/testAdapter.ts fees mellow.ts
    
    🦙 Running MELLOW.TS adapter 🦙
    ---------------------------------------------------
    Start Date:	Sun, 13 Apr 2025 02:40:22 GMT
    End Date:	Mon, 14 Apr 2025 02:40:22 GMT
    ---------------------------------------------------
    
    ETHEREUM 👇
    Backfill start time not defined
    Daily fees: 789
    End timestamp: 1744598421 (2025-04-14T02:40:21.000Z)
    
    
    
    
    
author_association: NONE
user: login: llamabutler
created_at: 2025-04-14T06:11:12Z
body: The mellow.ts adapter exports:
        
 
 
    > adapters@1.0.0 test
    > ts-node --transpile-only cli/testAdapter.ts fees mellow.ts
    
    🦙 Running MELLOW.TS adapter 🦙
    ---------------------------------------------------
    Start Date:	Sun, 13 Apr 2025 03:40:03 GMT
    End Date:	Mon, 14 Apr 2025 03:40:03 GMT
    ---------------------------------------------------
    
    ETHEREUM 👇
    Backfill start time not defined
    Daily fees: 781
    Daily supply side revenue: 781
    End timestamp: 1744602002 (2025-04-14T03:40:02.000Z)
    
    
    
    
    
author_association: NONE
user: login: llamabutler
created_at: 2025-04-14T09:50:37Z
body: The mellow.ts adapter exports:
        
 
 
    > adapters@1.0.0 test
    > ts-node --transpile-only cli/testAdapter.ts fees mellow.ts
    
    🦙 Running MELLOW.TS adapter 🦙
    ---------------------------------------------------
    Start Date:	Sun, 13 Apr 2025 07:20:27 GMT
    End Date:	Mon, 14 Apr 2025 07:20:27 GMT
    ---------------------------------------------------
    
    ETHEREUM 👇
    Backfill start time not defined
    Daily fees: 788
    Daily supply side revenue: 788
    End timestamp: 1744615226 (2025-04-14T07:20:26.000Z)
    
    
    
    
    
author_association: NONE
user: login: llamabutler
created_at: 2025-04-14T10:02:39Z
body: The mellow.ts adapter exports:
        
 
 
    > adapters@1.0.0 test
    > ts-node --transpile-only cli/testAdapter.ts fees mellow.ts
    
    🦙 Running MELLOW.TS adapter 🦙
    ---------------------------------------------------
    Start Date:	Sun, 13 Apr 2025 07:32:30 GMT
    End Date:	Mon, 14 Apr 2025 07:32:30 GMT
    ---------------------------------------------------
    
    ETHEREUM 👇
    Backfill start time: 1/9/2024
    Daily fees: 792
    Daily supply side revenue: 792
    End timestamp: 1744615949 (2025-04-14T07:32:29.000Z)
    
    
    
    
    
author_association: NONE
user: login: llamabutler
created_at: 2025-04-14T12:26:31Z
body: The mellow.ts adapter exports:
        
 
 
    > adapters@1.0.0 test
    > ts-node --transpile-only cli/testAdapter.ts fees mellow.ts
    
    🦙 Running MELLOW.TS adapter 🦙
    ---------------------------------------------------
    Start Date:	Sun, 13 Apr 2025 09:56:21 GMT
    End Date:	Mon, 14 Apr 2025 09:56:21 GMT
    ---------------------------------------------------
    
    ETHEREUM 👇
    Backfill start time: 1/9/2024
    Daily fees: 806
    Daily revenue: 0
    Daily supply side revenue: 806
    End timestamp: 1744624580 (2025-04-14T09:56:20.000Z)
    
    
    
    
    
author_association: NONE