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 vote #39

Merged
merged 1 commit into from
May 27, 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
14 changes: 14 additions & 0 deletions scripts/utils/create-tetu-bal-proposal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ async function main() {
})

const lastProposal = await getLastTetuSnapshotData();
if (!isCorrectSnapshotTimestamp(lastProposal.start)) {
throw new Error('Should be between 10 and 20 days since last proposal')
}
console.log(`Last proposal is ${lastProposal.title} at ${lastProposal.end}`)

const parsedValue = parseTitle(lastProposal.title)
Expand Down Expand Up @@ -203,6 +206,17 @@ function parseTitle(input: string): { title: string, endDate: string } {
};
}

function isCorrectSnapshotTimestamp(timestamp: number): boolean {
const snapshotDate = new Date(timestamp * 1000);

const now = new Date();

const tenDaysAgo = new Date(now.getTime() - 10 * 24 * 60 * 60 * 1000);
const twentyDaysAgo = new Date(now.getTime() - 20 * 24 * 60 * 60 * 1000);

return snapshotDate >= twentyDaysAgo && snapshotDate <= tenDaysAgo;
}

main()
.then(() => process.exit(0))
.catch(error => {
Expand Down
57 changes: 56 additions & 1 deletion scripts/utils/tetu-bal-vote.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
import axios from "axios";
import {getBalancerGaugesData} from "./tools/voting-utils";
import { getBalancerGaugesData, getLastTetuSnapshotDataByState } from './tools/voting-utils';
import { Vote } from '@snapshot-labs/snapshot.js/dist/sign/types';
import snapshot from '@snapshot-labs/snapshot.js';
import { ethers } from 'hardhat';
import { config as dotEnvConfig } from 'dotenv';
import { Misc } from './tools/Misc';

const FREE_VOTES = 60.12;
const OUR_VOTING_POWER = 271000;
const MIN_VALUE_PER_VOTE = 0.12;
const MIN_TOTAL_VALUE = 100;

dotEnvConfig();
// tslint:disable-next-line:no-var-requires
const argv = require('yargs/yargs')()
.env('TETU')
.options({
privateKey: {
type: "string",
},
}).argv;


// https://snapshot.org/#/tetubal.eth
// const VOTE_MARKET_HH_API = 'https://vm.crvusd.fi/bribes?name=hiddehand';
const HH_API = 'https://api.hiddenhand.finance/proposal/balancer';
Expand All @@ -22,16 +38,55 @@ async function main() {
console.log('Average $ per vote', totalRewards / totalFreeVotes);

let totalUsedVotes = 0;
const poolIdPercent: Record<string, number> = {};
for (const bribe of bribesForVote) {
const ratio = bribe.rewards / totalRewards;
const votes = totalFreeVotes * ratio;
const percent = votes / OUR_VOTING_POWER * 100;

console.log(bribe.proposalOption + ';' + percent.toFixed(2));
const id = bribe.proposalOption.split(';').length > 1 ? bribe.proposalOption.split(';')[1] : '';
poolIdPercent[id] = percent;

totalUsedVotes += percent;
}

try {
const lastProposal = await getLastTetuSnapshotDataByState('active');
const choiceMap: { [key: string]: number } = {};
Object.keys(poolIdPercent).forEach(poolId => {
const index = (lastProposal.choices as string[]).findIndex(c => c.includes(poolId));
if (index != -1) {
choiceMap[`${index + 1}`] = poolIdPercent[poolId];
}
});

if (Object.keys(poolIdPercent).length !== Object.keys(choiceMap).length) {
throw Error('Not all pool ids are mapped to choices');
}

console.log(choiceMap)
const vote: Vote = {
space: 'tetubal.eth',
type: 'weighted',
proposal: lastProposal.id,
choice: choiceMap,
app: 'snapshot',
}

if (Misc.getChainName() === 'hardhat') {
console.log('Dry run, vote below...')
console.log(vote);
return;
}
const client = new snapshot.Client712('https://hub.snapshot.org')
const signer = new ethers.Wallet(argv.privateKey, ethers.provider)
const resp = await client.vote(signer, signer.address, vote);
console.log(resp);
} catch (e) {
console.error(e);
}

// console.log('Total used votes', totalUsedVotes);
}

Expand Down
35 changes: 34 additions & 1 deletion scripts/utils/tools/voting-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,40 @@ export async function getLastTetuSnapshotData(): Promise<any> {
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 getLastTetuSnapshotDataByState(state: string): Promise<any> {
const resp = await request(
SNAPSHOT_GRAPHQL_ENDPOINT,
gql`
query {
proposals (
first: 1,
skip: 0,
where: {
space_in: ["tetubal.eth"],
state: "${state}"
},
orderBy: "created",
orderDirection: desc
Expand Down
Loading