Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automate tetu bal proposal #37

Merged
merged 1 commit into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all 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: 1 addition & 1 deletion gql/.graphqlconfig
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"user-agent": "JS GraphQL"
},
"introspect": false,
"url": "https://api.thegraph.com/subgraphs/name/alexandersazonof/tetubal"
"url": "https://api.studio.thegraph.com/query/48757/tetu-bal/version/latest"
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion gql/codegen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ generates:
BigInt: string
Bytes: string
Int8: number
schema: https://api.thegraph.com/subgraphs/name/alexandersazonof/tetubal
Timestamp: string
schema: https://api.studio.thegraph.com/query/48757/tetu-bal/version/latest
13 changes: 11 additions & 2 deletions scripts/graphql/graph-service.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { UserEntity } from '../../generated/gql';
import { TetuBlockSnapshot, UserEntity } from '../../generated/gql';
import { ApolloClient, createHttpLink, InMemoryCache } from '@apollo/client/core';
import { getAllUsersOnBlockQuery } from './all-users-on-block';
import { getTetuBalBestSnapshotQuery } from './tetu-bal-best-snopashot';

function getSubgraphUrl() {
return process.env.TETU_SUBGRAPH_URL ?? 'https://api.thegraph.com/subgraphs/name/alexandersazonof/tetubal';
return process.env.TETU_SUBGRAPH_URL ?? 'https://api.studio.thegraph.com/query/48757/tetu-bal/version/latest';
}


Expand Down Expand Up @@ -41,3 +42,11 @@ export async function getAllUsersOnBlock(block: number): Promise<UserEntity[]> {

return allUsers;
}

export async function getTetuBalBestSnapshot(timestamp: number): Promise<TetuBlockSnapshot[]> {
const { data } = await client.query({
variables: { timestamp },
query: getTetuBalBestSnapshotQuery(),
});
return data.tetuBlockSnapshots;
}
18 changes: 18 additions & 0 deletions scripts/graphql/tetu-bal-best-snopashot.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { DocumentNode, gql } from '@apollo/client/core';

export function getTetuBalBestSnapshotQuery(): DocumentNode {
return gql`
query GetTetuBalBestSnapshot($timestamp: Int!) {
tetuBlockSnapshots(
where: {timestamp_gt:$timestamp}
orderBy: tetuBalPercent
orderDirection: desc
first: 1
) {
tetuBalPercent
tetuBalPowerPercent
block
}
}
`;
}
67 changes: 63 additions & 4 deletions scripts/utils/create-tetu-bal-proposal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import {config as dotEnvConfig} from "dotenv";

import snapshot from "@snapshot-labs/snapshot.js";
import {Proposal} from "@snapshot-labs/snapshot.js/src/sign/types";
import {getBalancerGaugesData} from "./tools/voting-utils";
import { getBalancerGaugesData, getLastTetuSnapshotData } from './tools/voting-utils';
import { getTetuBalBestSnapshot } from '../graphql/graph-service';

// !!!!!!!!!!!!!!!!!!!!!!!! CHANGE ME !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
const POLYGON_SNAPSHOT_BLOCK_NUMBER = 56752282; // use the-best-block-for-snapshot.ts script
Expand Down Expand Up @@ -90,16 +91,34 @@ async function main() {
return 1
})

const lastProposal = await getLastTetuSnapshotData();
console.log(`Last proposal is ${lastProposal.title} at ${lastProposal.end}`)

const parsedValue = parseTitle(lastProposal.title)
const endDate = Math.floor((new Date(parsedValue.endDate)).getTime() / 1000)
console.log(`New proposal title is ${parsedValue.title}\n New proposal end date is ${parsedValue.endDate}`)

const tetuBalSnapshot = await getTetuBalBestSnapshot(lastProposal.end);
let block = 0;

if (tetuBalSnapshot.length > 0) {
const snapshot = tetuBalSnapshot[0]
console.log(`Best block is ${snapshot.block} tetuBal percent ${(+snapshot.tetuBalPercent).toFixed(4)}\n`)
block = +snapshot.block;
} else {
throw new Error('No tetuBal snapshot found');
}

try {
const proposal: Proposal = {
space: 'tetubal.eth',
type: 'weighted',
title: TITLE,
title: parsedValue.title,
body: BODY,
choices,
start: START_UNIX,
end: END_UNIX,
snapshot: POLYGON_SNAPSHOT_BLOCK_NUMBER,
end: endDate,
snapshot: block,
plugins: '{}',
app: 'snapshot',
discussion: ''
Expand Down Expand Up @@ -144,6 +163,46 @@ async function getGaugeChoices(): Promise<string[]> {
return Array.from(gaugeChoices.values()).sort();
}

function parseTitle(input: string): { title: string, endDate: string } {
const regex = /(BRV-)(\d+): Gauge Weights for (\d{1,2}) (\w+) - (\d{1,2}) (\w+) (\d{4})/;
const match = input.match(regex);

if (!match) {
throw Error('Input string does not match the expected format.');
}

const [, prefix, number, startDay, startMonth, endDay, endMonth, year] = match;

const newNumber: number = +number + 1;
const formattedNumber: string = newNumber.toString().padStart(number.length, '0');

const startDate: Date = new Date(`${startMonth} ${startDay}, ${year}`);
const endDate: Date = new Date(`${endMonth} ${endDay}, ${year}`);

startDate.setDate(startDate.getDate() + 14);
endDate.setDate(endDate.getDate() + 14);

const newYear: number = endDate.getFullYear();

const options: Intl.DateTimeFormatOptions = { day: 'numeric', month: 'long' };
const newStartDate: string = startDate.toLocaleDateString('en-US', options);
const newEndDate: string = endDate.toLocaleDateString('en-US', options);

const [newStartDay, newStartMonth]: string[] = newStartDate.split(' ');
const [newEndDay, newEndMonth]: string[] = newEndDate.split(' ');

// new date logic
startDate.setDate(startDate.getDate() - 2);
const formattedNewStartDate = startDate.toUTCString();
const dateParts = formattedNewStartDate.split(' ');
const newDateText = `${dateParts[2]} ${dateParts[1]} ${dateParts[3]} 20:00:00 UTC`;

return {
title: `${prefix}${formattedNumber}: Gauge Weights for ${newStartDay} ${newStartMonth} - ${newEndDay} ${newEndMonth} ${newYear}`,
endDate: newDateText,
};
}

main()
.then(() => process.exit(0))
.catch(error => {
Expand Down
34 changes: 34 additions & 0 deletions scripts/utils/tools/voting-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,40 @@ export async function getSnapshotData(proposalId: string): Promise<any> {
return resp.proposals[0]
}

// tslint:disable-next-line:no-any
export async function getLastTetuSnapshotData(): Promise<any> {
const resp = await request(
SNAPSHOT_GRAPHQL_ENDPOINT,
gql`
query {
proposals (
first: 1,
skip: 0,
where: {
space_in: ["tetubal.eth"],
state: "closed"
},
orderBy: "created",
orderDirection: desc
) {
id
title
choices
start
end
scores
space {
id
name
}
}
}
`
)

return resp.proposals[0]
}

// tslint:disable-next-line:no-any
export async function getSnapshotVoters(proposalId: string, voter: string): Promise<any> {
const resp = await request(
Expand Down
Loading