Skip to content
This repository was archived by the owner on Aug 22, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/strategies/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,7 @@ import * as dappcomposerGetVotingUnits from './dappcomposer-getvotingunits';
import * as erc20BalanceOfSaevo from './erc20-balance-of-saevo';
import * as apecoinStaking from './apecoin-staking';
import * as shroomyVotingPower from './shroomy-voting-power';
import * as pufferGetPastVotes from './puffer-getpastvotes';
import * as prlInSpRL2Balance from './prl-in-sprl2-balance';
import * as edenOnlineOverride from './eden-online-override';

Expand Down Expand Up @@ -974,6 +975,7 @@ const strategies = {
'superfluid-vesting': superfluidVesting,
synapse,
'dappcomposer-getvotingunits': dappcomposerGetVotingUnits,
'puffer-getpastvotes': pufferGetPastVotes,
'prl-in-sprl2-balance': prlInSpRL2Balance,
'eden-online-override': edenOnlineOverride
};
Expand Down
5 changes: 5 additions & 0 deletions src/strategies/puffer-getpastvotes/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Puffer Governance: Voting

In Puffer, the voting power is calculated using the amount of `$vlPUFFER` delegated to user at the end of the previous period.

This strategy is used to get the voting power at the end of the previous period.
19 changes: 19 additions & 0 deletions src/strategies/puffer-getpastvotes/examples.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[
{
"name": "vlPUFFER Example",
"strategy": {
"name": "puffer-getpastvotes",
"params": {
"address": "0xcD1adFB7Ae5E08F7494cdE2EA6666CeF5cc4804c",
"decimals": 18
}
},
"network": "11155111",
"addresses": [
"0xe19cBAAa2e546f8C6175892190d1f26279d19995",
"0xDDDeAfB492752FC64220ddB3E7C9f1d5CcCdFdF0",
"0x65d2dd7A66a2733a36559fE900A236280A05FBD6"
],
"snapshot": 8310195
}
]
51 changes: 51 additions & 0 deletions src/strategies/puffer-getpastvotes/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { BigNumberish } from '@ethersproject/bignumber';
import { formatUnits } from '@ethersproject/units';
import { Multicaller } from '../../utils';

export const author = 'bxmmm1';
export const version = '0.1.0';

const abi = [
'function getPastVotes(address account, uint256 timepoint) view returns (uint256)'
];

export async function strategy(
_space,
network,
provider,
addresses,
options
): Promise<Record<string, number>> {
// We want to use `getPastVotes` because of the delegation happening on the contract
// We want to use the past timestamp to get the votes at the start of the previous week

// Calculate the timestamp at the end of the most recent complete 7-day period
// This ensures alignment with contract's 7-day voting periods
const SECONDS_PER_WEEK = 7 * 24 * 60 * 60;
// Get the current timestamp in seconds
const currentTimestampInSeconds = Math.floor(Date.now() / 1000);
// Calculate the current period based on the current timestamp
const currentPeriod = Math.floor(
currentTimestampInSeconds / SECONDS_PER_WEEK
);
// Calculate the timestamp at the end of the previous period
const previousPeriodEnd = currentPeriod * SECONDS_PER_WEEK - 1;

const multi = new Multicaller(network, provider, abi);

addresses.forEach((address) =>
multi.call(address, options.address, 'getPastVotes', [
address,
previousPeriodEnd.toString()
])
);

const result: Record<string, BigNumberish> = await multi.execute();

return Object.fromEntries(
Object.entries(result).map(([address, balance]) => [
address,
parseFloat(formatUnits(balance, options.decimals))
])
);
}
28 changes: 28 additions & 0 deletions src/strategies/puffer-getpastvotes/schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$ref": "#/definitions/Strategy",
"definitions": {
"Strategy": {
"title": "Strategy",
"type": "object",
"properties": {
"address": {
"type": "string",
"title": "Contract address",
"examples": ["e.g. 0xcD1adFB7Ae5E08F7494cdE2EA6666CeF5cc4804c"],
"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
}
}
}