From 797a282c57814625a3431506a87ce51c129e05ad Mon Sep 17 00:00:00 2001 From: nerfZael Date: Fri, 14 Feb 2025 15:57:21 +0100 Subject: [PATCH] implemented strategy for hedgey vesting and lockup contracts --- src/strategies/hedgey-locked/README.md | 17 ++++++++ src/strategies/hedgey-locked/examples.json | 27 ++++++++++++ src/strategies/hedgey-locked/index.ts | 48 +++++++++++++++++++++ src/strategies/hedgey-locked/schema.json | 49 ++++++++++++++++++++++ src/strategies/index.ts | 2 + 5 files changed, 143 insertions(+) create mode 100644 src/strategies/hedgey-locked/README.md create mode 100644 src/strategies/hedgey-locked/examples.json create mode 100644 src/strategies/hedgey-locked/index.ts create mode 100644 src/strategies/hedgey-locked/schema.json diff --git a/src/strategies/hedgey-locked/README.md b/src/strategies/hedgey-locked/README.md new file mode 100644 index 000000000..860a34eb8 --- /dev/null +++ b/src/strategies/hedgey-locked/README.md @@ -0,0 +1,17 @@ +# hedgey-locked + +This strategy calls the lockedBalances function on Hedgey Lockup and Vesting contracts + +It can also apply a multiplier to the value returned + +Here is an example of parameters: + +```json +{ + "contracts": ["0xce7ac66e78aae01d899eb90b63d1f20be2e9c4b1", "0x24f4BC74C00412422C9D2A7c78033fc8Aea8Da18"], + "token": "0xE13FB676E9bdd7AFda91495eC4e027FC63212FC3", + "symbol": "TACO", + "decimals": 18, + "multiplier": 10 +} +``` diff --git a/src/strategies/hedgey-locked/examples.json b/src/strategies/hedgey-locked/examples.json new file mode 100644 index 000000000..52ce2c31f --- /dev/null +++ b/src/strategies/hedgey-locked/examples.json @@ -0,0 +1,27 @@ +[ + { + "name": "Example voting based on hedgey vesting token with a multiplier", + "strategy": { + "name": "hedgey-locked", + "params": { + "contracts": [ + "0x73cD8626b3cD47B009E68380720CFE6679A3Ec3D", + "0x1bb64AF7FE05fc69c740609267d2AbE3e119Ef82" + ], + "token": "0x04E69Ff14A86E1ca9a155A8563E95887973EE175", + "symbol": "AITV", + "decimals": 18, + "multiplier": 1 + } + }, + "network": "1", + "addresses": [ + "0xe90a6EaBEe9162b23edAe465f55327F95d15ae11", + "0xBE54EBB0A14317256f32Aee3Df8a894793960E78", + "0xF0138A76223d93192C9c903520f1cf95c9094065", + "0xDC13Ab880e2AB7b5544a7b927769B5CEc6d62a0b", + "0xe31D847B47465cC2745319dAc9E0c6ac711cA10b" + ], + "snapshot": 21844600 + } +] diff --git a/src/strategies/hedgey-locked/index.ts b/src/strategies/hedgey-locked/index.ts new file mode 100644 index 000000000..eed8d7105 --- /dev/null +++ b/src/strategies/hedgey-locked/index.ts @@ -0,0 +1,48 @@ +import { BigNumber, BigNumberish } from '@ethersproject/bignumber'; +import { formatUnits } from '@ethersproject/units'; +import { Multicaller } from '../../utils'; + +export const author = 'agentcoinorg'; +export const version = '1.0.0'; + +const abi = [ + 'function lockedBalances(address holder, address token) view returns (uint256 lockedBalance)' +]; + +export async function strategy( + space, + network, + provider, + addresses, + options, + snapshot +): Promise> { + const blockTag = typeof snapshot === 'number' ? snapshot : 'latest'; + + const multi = new Multicaller(network, provider, abi, { blockTag }); + + for (const contract of options.contracts) { + for (const address of addresses) { + multi.call(contract + "/" + address, contract, 'lockedBalances', [address, options.token]); + } + } + + const result: Record = await multi.execute(); + + const scores: Record = + Object.entries(result).reduce((acc, [path, value]) => { + const [_, address] = path.split('/'); + const score = BigNumber.from(value).mul(options.multiplier); + return { + ...acc, + [address]: acc[address] ? acc[address].add(score) : score + }; + }, {}); + + return Object.fromEntries( + Object.entries(scores).map(([address, score]) => [ + address, + parseFloat(formatUnits(score.toString(), options.decimals)) + ]) + ); +} diff --git a/src/strategies/hedgey-locked/schema.json b/src/strategies/hedgey-locked/schema.json new file mode 100644 index 000000000..c68efcf78 --- /dev/null +++ b/src/strategies/hedgey-locked/schema.json @@ -0,0 +1,49 @@ +{ + "$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. UNI"], + "maxLength": 16 + }, + "contracts": { + "type": "array", + "title": "Hedgey Contract addresses", + "items": { + "type": "string", + "examples": ["e.g. 0xCe7Ac66E78aAE01d899eb90b63D1f20bE2E9c4B1"], + "pattern": "^0x[a-fA-F0-9]{40}$", + "minLength": 42, + "maxLength": 42 + } + }, + "token": { + "type": "string", + "title": "Token Contract address", + "examples": ["e.g. 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984"], + "pattern": "^0x[a-fA-F0-9]{40}$", + "minLength": 42, + "maxLength": 42 + }, + "decimals": { + "type": "number", + "title": "Decimals", + "examples": ["e.g. 18"] + }, + "multiplier": { + "type": "number", + "title": "Multiplier", + "examples": ["e.g. 1"] + } + }, + "required": ["contracts", "token", "decimals", "multiplier"], + "additionalProperties": false + } + } +} diff --git a/src/strategies/index.ts b/src/strategies/index.ts index f5df229f1..7fa433d87 100644 --- a/src/strategies/index.ts +++ b/src/strategies/index.ts @@ -290,6 +290,7 @@ import * as ethermon721 from './ethermon-erc721'; import * as etherorcsComboBalanceOf from './etherorcs-combo-balanceof'; import * as hedgey from './hedgey'; import * as hedgeyDelegate from './hedgey-delegate'; +import * as hedgeyLocked from './hedgey-locked'; import * as sybilProtection from './sybil-protection'; import * as veBalanceOfAtNFT from './ve-balance-of-at-nft'; import * as genzeesFromSubgraph from './genzees-from-subgraph'; @@ -776,6 +777,7 @@ const strategies = { 'rowdy-roos': rowdyRoos, hedgey, 'hedgey-delegate': hedgeyDelegate, + 'hedgey-locked': hedgeyLocked, 've-balance-of-at-nft': veBalanceOfAtNFT, 'genzees-from-subgraph': genzeesFromSubgraph, 'position-governance-power': positionGovernancePower,