diff --git a/src/strategies/index.ts b/src/strategies/index.ts index 512bbe9ca..e46ecf2e3 100644 --- a/src/strategies/index.ts +++ b/src/strategies/index.ts @@ -468,6 +468,7 @@ import * as fountainhead from './fountainhead'; import * as naymsStaking from './nayms-staking'; import * as morphoDelegation from './morpho-delegation'; import * as lizcoinStrategy2024 from './lizcoin-strategy-2024'; +import * as realt from './realt'; const strategies = { 'delegatexyz-erc721-balance-of': delegatexyzErc721BalanceOf, @@ -946,7 +947,8 @@ const strategies = { fountainhead, 'nayms-staking': naymsStaking, 'morpho-delegation': morphoDelegation, - 'lizcoin-strategy-2024': lizcoinStrategy2024 + 'lizcoin-strategy-2024': lizcoinStrategy2024, + realt }; Object.keys(strategies).forEach(function (strategyName) { diff --git a/src/strategies/realt/README.md b/src/strategies/realt/README.md new file mode 100644 index 000000000..bc38be178 --- /dev/null +++ b/src/strategies/realt/README.md @@ -0,0 +1,5 @@ +# reALT + +## Description + +The reALT strategy calculates the total balance of a user's holdings in the reALT token and their shares in the reALT Strategy on the Ethereum mainnet. diff --git a/src/strategies/realt/examples.json b/src/strategies/realt/examples.json new file mode 100644 index 000000000..161df7e3e --- /dev/null +++ b/src/strategies/realt/examples.json @@ -0,0 +1,20 @@ +[ + { + "name": "Example query", + "strategy": { + "name": "realt", + "params": { + "address": "0xf96798f49936efb1a56f99ceae924b6b8359affb", + "symbol": "reALT", + "decimals": 18 + } + }, + "network": "1", + "addresses": [ + "0x15de7B6a83ee7735EA00Dc4a0506059cDA4Bef49", + "0x16Ce1B15ed1278921d7Cae34Bf60a81227CFC295", + "0x16f665dA6D806760aFC317ee29Ef2feF2Ff4976E" + ], + "snapshot": 21488157 + } +] diff --git a/src/strategies/realt/index.ts b/src/strategies/realt/index.ts new file mode 100644 index 000000000..8651608e8 --- /dev/null +++ b/src/strategies/realt/index.ts @@ -0,0 +1,51 @@ +import { BigNumberish, BigNumber } from '@ethersproject/bignumber'; +import { formatUnits } from '@ethersproject/units'; +import { Multicaller } from '../../utils'; + +export const author = 'altlayer'; +export const version = '0.1.0'; + +export async function strategy( + space, + network, + provider, + addresses, + options, + snapshot +): Promise> { + const blockTag = typeof snapshot === 'number' ? snapshot : 'latest'; + const reAltStrategy = "0x6075546538c3eFbD607ea6aFC24149fCcFb2edF4"; // reALT Strategy Mainnet + + const balanceOfMulticaller = new Multicaller(network, provider, [ + 'function balanceOf(address account) external view returns (uint256)', + ], { blockTag }); + + addresses.forEach((address) => + balanceOfMulticaller.call(address, options.address, 'balanceOf', [address]) + ); + + const sharesMulticaller = new Multicaller(network, provider, [ + 'function shares(address user) external view returns (uint256)', + ], { blockTag }); + + addresses.forEach((address) => + sharesMulticaller.call(address, reAltStrategy, 'shares', [address]) + ); + + const [balanceOfResults, sharesResults]: [Record, Record] = await Promise.all([ + balanceOfMulticaller.execute(), + sharesMulticaller.execute() + ]); + + return Object.fromEntries( + addresses.map((address) => { + const balanceOf = balanceOfResults[address] || BigNumber.from(0); + const shares = sharesResults[address] || BigNumber.from(0); + const totalBalance = BigNumber.from(balanceOf).add(BigNumber.from(shares)); + return [ + address, + parseFloat(formatUnits(totalBalance, options.decimals)) + ]; + }) + ); +} diff --git a/src/strategies/realt/schema.json b/src/strategies/realt/schema.json new file mode 100644 index 000000000..e5beefb92 --- /dev/null +++ b/src/strategies/realt/schema.json @@ -0,0 +1,34 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$ref": "#/definitions/Strategy", + "definitions": { + "Strategy": { + "title": "Strategy", + "type": "object", + "properties": { + "symbol": { + "type": "string", + "title": "Symbol", + "examples": ["e.g. reALT"], + "maxLength": 16 + }, + "address": { + "type": "string", + "title": "Contract address", + "examples": ["e.g. 0xf96798f49936efb1a56f99ceae924b6b8359affb"], + "pattern": "^0x[a-fA-F0-9]{40}$", + "minLength": 42, + "maxLength": 42 + }, + "decimals": { + "type": "number", + "title": "Decimals", + "examples": ["e.g. 18"], + "minimum": 0 + } + }, + "required": ["address", "decimals"], + "additionalProperties": false + } + } +}