diff --git a/src/strategies/index.ts b/src/strategies/index.ts index dc67a5046..fb77cc64a 100644 --- a/src/strategies/index.ts +++ b/src/strategies/index.ts @@ -486,6 +486,7 @@ import * as pufferGetPastVotes from './puffer-getpastvotes'; import * as prlInSpRL2Balance from './prl-in-sprl2-balance'; import * as edenOnlineOverride from './eden-online-override'; import * as forteStaking from './forte-staking'; +import * as overtime from './overtime'; import { DEFAULT_SUPPORTED_PROTOCOLS } from '../constants'; @@ -985,7 +986,8 @@ const strategies = { 'puffer-getpastvotes': pufferGetPastVotes, 'prl-in-sprl2-balance': prlInSpRL2Balance, 'eden-online-override': edenOnlineOverride, - 'forte-staking': forteStaking + 'forte-staking': forteStaking, + overtime }; Object.keys(strategies).forEach(function (strategyName) { diff --git a/src/strategies/overtime/README.md b/src/strategies/overtime/README.md new file mode 100644 index 000000000..076af0bf8 --- /dev/null +++ b/src/strategies/overtime/README.md @@ -0,0 +1,17 @@ +# Overtime Strategy + +A governance strategy designed for Overtime. +Voting power is determined by the $OVER token balance. If the address is a smart contract account, the voting power is assigned to their externally owned account (EOA) owner. + +## Examples + +Here is an example of parameters: + +```JSON +{ + "address": "0xedf38688b27036816a50185caa430d5479e1c63e", + "symbol": "OVER", + "decimals": 18, + "eoaToSmartAccountMapApi": "https://overdrop.overtime.io/eoa-smart-account-map" +} +``` diff --git a/src/strategies/overtime/examples.json b/src/strategies/overtime/examples.json new file mode 100644 index 000000000..474db78c7 --- /dev/null +++ b/src/strategies/overtime/examples.json @@ -0,0 +1,25 @@ +[ + { + "name": "Example query OP", + "strategy": { + "name": "overtime", + "params": { + "address": "0xedf38688b27036816a50185caa430d5479e1c63e", + "symbol": "OVER", + "decimals": 18, + "eoaToSmartAccountMapApi": "https://overdrop.overtime.io/eoa-smart-account-map" + } + }, + "network": "10", + "addresses": [ + "0x9f8e4ee788D9b00A3409584E18034aA7B736C396", + "0x3e09230ed70b667256BBaf1FDf949050D312D066", + "0x7d2824F1825da25072011B3e326025172E404b15", + "0x3320EE0189aAD77b3aB570a00464Ce7a45B6E465", + "0x28b2Be30b0AE526aF0cB94984B750d4C35e913c0", + "0xc8038Fb922764405aF919A02BDd2792A36566074", + "0x0D858351A5FB419C9A3760647900d2F7aD526c83" + ], + "snapshot": 137587693 + } +] diff --git a/src/strategies/overtime/index.ts b/src/strategies/overtime/index.ts new file mode 100644 index 000000000..b67377f7d --- /dev/null +++ b/src/strategies/overtime/index.ts @@ -0,0 +1,43 @@ +import { customFetch } from '../../utils'; +import { strategy as erc20BalanceOfStrategy } from '../erc20-balance-of'; + +export const author = 'thales-markets'; +export const version = '1.0.0'; + +export async function strategy( + space, + network, + provider, + addresses, + options, + snapshot +): Promise> { + const scores = await erc20BalanceOfStrategy( + space, + network, + provider, + addresses, + options, + snapshot + ); + + const response = await customFetch(options.eoaToSmartAccountMapApi, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json' + } + }); + const eoaToSmartAccountMapping = await response.json(); + + for (let i = 0; i < Object.keys(scores).length; i++) { + const address = Object.keys(scores)[i]; + const smartAccount = eoaToSmartAccountMapping[address]; + // If the current address has a mapped smart account, add the smart account's score to the owner's score + if (smartAccount !== undefined) { + scores[address] = scores[address] + scores[smartAccount]; + } + } + + return scores; +}