diff --git a/src/strategies/erc20-staked-at/README.md b/src/strategies/erc20-staked-at/README.md new file mode 100644 index 000000000..8fe1f4115 --- /dev/null +++ b/src/strategies/erc20-staked-at/README.md @@ -0,0 +1,27 @@ +# Snapshot.org Staking Strategy + +This strategy is designed to calculate the total amount of tokens a user has staked in a staking contract. Originally developed for **Paal**, it can be adapted for use with any other staking contract, provided it is compatible with this structure. + +### Key Features +- Calculates the staked token balance for each user. +- Flexible and adaptable to various staking contracts. + +### Parameters + +{ + "address": "0x85e253162c7e97275b703980f6b6fa8c0469d624", + "symbol": "PAAL", + "decimals": 9 +} + +### Functionality + +This strategy utilizes the `shares()` function in Paal smart contracts, which takes a user's address as a parameter and returns two `uint256` values: `amountOfTokens` (the number of tokens staked) and `initTimestamp` (the timestamp when the staking began). + +Feel free to integrate it into your project if the contract adheres to a similar staking model. + + + + + + diff --git a/src/strategies/erc20-staked-at/examples.json b/src/strategies/erc20-staked-at/examples.json new file mode 100644 index 000000000..a20c13ba7 --- /dev/null +++ b/src/strategies/erc20-staked-at/examples.json @@ -0,0 +1,21 @@ +[ + { + "name": "Get staked tokens at", + "strategy": { + "name": "erc20-staked-at", + "params": { + "address": "0x85e253162c7e97275b703980f6b6fa8c0469d624", + "symbol": "PAAL", + "decimals": 9 + } + }, + "network": "1", + "addresses": [ + "0x1029898f7D7f8cEf3a347A6D7342Cdf42f11532e", + "0xa57FAe92A541B19Cbc03A8c5fe67FBDdBB53D79e", + "0x29dE41D2a9270241629e94dE3B72985e577D91A9" + ], + "snapshot": 20995910 + } + ] + \ No newline at end of file diff --git a/src/strategies/erc20-staked-at/index.ts b/src/strategies/erc20-staked-at/index.ts new file mode 100644 index 000000000..f7ccb4ec2 --- /dev/null +++ b/src/strategies/erc20-staked-at/index.ts @@ -0,0 +1,44 @@ + +import { multicall } from '../../utils'; +import { formatUnits } from '@ethersproject/units'; + +export const author = 'jscrui'; +export const version = '0.1.1'; + +const abi = ['function shares(address account) view returns (uint256, uint256)']; + +/** + * This strategy is designed to calculate voting power based on + * the Staked ERC20 tokens in a given contract. + */ +export async function strategy( + space, + network, + provider, + addresses, + options, + snapshot +) { + const blockTag = typeof snapshot === 'number' ? snapshot : 'latest'; + + const response = await multicall( + network, + provider, + abi, + addresses.map((address: any) => [ + options.address, + 'shares', + [address] + ]), + { blockTag } + ); + + return Object.fromEntries( + response.map((value, i) => { + // Format the voting power using the token decimals + const votingPower = parseFloat(formatUnits(value[0], options.decimals)); // Convert using formatUnits + //console.log(`${addresses[i]}: ${votingPower} (${symbol})`); + return [addresses[i], votingPower]; + }) + ); +} \ No newline at end of file diff --git a/src/strategies/erc20-staked-at/schema.json b/src/strategies/erc20-staked-at/schema.json new file mode 100644 index 000000000..decae7810 --- /dev/null +++ b/src/strategies/erc20-staked-at/schema.json @@ -0,0 +1,33 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$ref": "#/definitions/Strategy", + "definitions": { + "Strategy": { + "title": "ERC20 Staked At", + "type": "object", + "properties": { + "symbol": { + "type": "string", + "title": "Symbol", + "examples": ["e.g. PAAL"], + "maxLength": 16 + }, + "address": { + "type": "string", + "title": "Contract address", + "examples": ["e.g. 0x85e253162c7e97275b703980f6b6fa8c0469d624"], + "pattern": "^0x[a-fA-F0-9]{40}$", + "minLength": 42, + "maxLength": 42 + }, + "decimals": { + "type": "number", + "title": "Decimals", + "examples": ["e.g. 9"] + } + }, + "required": ["symbol", "address", "decimals"], + "additionalProperties": false + } + } + } \ No newline at end of file diff --git a/src/strategies/index.ts b/src/strategies/index.ts index 770673547..34a6dc280 100644 --- a/src/strategies/index.ts +++ b/src/strategies/index.ts @@ -461,6 +461,8 @@ import * as snxMultichain from './snx-multichain'; import * as moxie from './moxie' import * as stakingAmountDurationLinear from './staking-amount-duration-linear'; import * as stakingAmountDurationExponential from './staking-amount-duration-exponential'; +import * as erc20StakedAt from './erc20-staked-at'; + const strategies = { 'delegatexyz-erc721-balance-of': delegatexyzErc721BalanceOf, @@ -932,7 +934,8 @@ const strategies = { 'snx-multichain': snxMultichain, 'moxie': moxie, 'staking-amount-duration-linear': stakingAmountDurationLinear, - 'staking-amount-duration-exponential': stakingAmountDurationExponential + 'staking-amount-duration-exponential': stakingAmountDurationExponential, + 'erc20-staked-at': erc20StakedAt }; Object.keys(strategies).forEach(function (strategyName) {