Skip to content

Instantly share code, notes, and snippets.

@Cooops
Created November 11, 2023 15:35
Show Gist options
  • Save Cooops/14940c1bb2b7ecb1b4c7248b05cd53ea to your computer and use it in GitHub Desktop.
Save Cooops/14940c1bb2b7ecb1b4c7248b05cd53ea to your computer and use it in GitHub Desktop.
// copied from here: https://github.com/Lodestar-Finance/lodestar-staking/blob/main/scripts/create-handler.js
const tokenAddresses = [
"0x5d27cFf80dF09f28534bb37d386D43aA60f88e25", //DPX
"0xD12d43Cdf498e377D3bfa2c6217f05B466E14228", //FRAX
"0xf21Ef887CB667f84B8eC5934C1713A7Ade8c38Cf", //MAGIC
"0xeA0a73c17323d1a9457D722F10E7baB22dc0cB83", //plvGLP
"0x4C9aAed3b8c443b4b634D1A189a5e25C604768dE", //USDC
"0x1ca530f02DD0487cef4943c674342c5aEa08922F", //USDC.e
"0x9365181A7df82a1cC578eAE443EFd89f00dbb643", //USDT
"0xC37896BF3EE5a2c62Cdbd674035069776f721668", //wBTC
"0x4987782da9a63bC3ABace48648B15546D821c720", //DAI
"0x2193c45244AF12C280941281c8aa67dD08be0a64", //ETH
"0x8991d64fe388fA79A4f7Aa7826E8dA09F0c3C96a", //ARB
"0xfECe754D92bd956F681A941Cef4632AB65710495", //wstETH
"0x79B6c5e1A7C0aD507E1dB81eC7cF269062BAb4Eb" //GMXß
];
const tokenNames = [
"DPX",
"FRAX",
"MAGIC",
"plvGLP",
"USDC",
"USDC.e",
"USDT",
"WBTC",
"DAI",
"ETH",
"ARB",
"wstETH",
"GMX"
];
const baseSupplySpeeds = [
"6027397260273970", //DPX
"12054794520547900", //FRAX
"12054794520547900", //MAGIC
"12054794520547900", //plvGLP
"12054794520547900", //USDC
"48219178082191800", //USDC.e
"24109589041095900", //USDT
"24109589041095900", //WBTC
"12054794520547900", //DAI
"24109589041095900", //ETH
"12054794520547900", //ARB
"24109589041095900", //WSTETH
"12054794520547900" //GMX
];
const baseBorrowSpeeds = [
"6027397260273970", //DPX
"12054794520547900", //FRAX
"12054794520547900", //MAGIC
"0", //plvGLP
"12054794520547900", //USDC
"48219178082191800", //USDC.e
"60273972602739700", //USDT
"60273972602739700", //WBTC
"60273972602739700", //DAI
"60273972602739700", //ETH
"12054794520547900", //ARB
"12054794520547900", //wstETH
"12054794520547900" //GMX
];
const ARBITRUM_BLOCK_SPEED = "0.26" // seconds
// the base speeds (without factoring in the other 50% from the voting gauge) sum up to the following:
// SUPPLY //
// DPX: 0.02410958904109588 tokens per second
// FRAX: 0.04821917808219178 tokens per second
// MAGIC: 0.04821917808219178 tokens per second
// plvGLP: 0.04821917808219178 tokens per second
// USDC: 0.04821917808219178 tokens per second
// USDC.e: 0.19287671232876712 tokens per second
// USDT: 0.09643835616438356 tokens per second
// WBTC: 0.09643835616438356 tokens per second
// DAI: 0.04821917808219178 tokens per second
// ETH: 0.09643835616438356 tokens per second
// ARB: 0.04821917808219178 tokens per second
// WSTETH: 0.09643835616438356 tokens per second
// GMX: 0.04821917808219178 tokens per second
// BORROW //
// DPX: 0.02410958904109588 tokens per second
// FRAX: 0.04821917808219178 tokens per second
// MAGIC: 0.04821917808219178 tokens per second
// plvGLP: 0 tokens per second
// USDC: 0.04821917808219178 tokens per second
// USDC.e: 0.19287671232876712 tokens per second
// USDT: 0.2410958904109589 tokens per second
// WBTC: 0.2410958904109589 tokens per second
// DAI: 0.2410958904109589 tokens per second
// ETH: 0.2410958904109589 tokens per second
// ARB: 0.04821917808219178 tokens per second
// wstETH: 0.04821917808219178 tokens per second
// GMX: 0.04821917808219178 tokens per second
const LODE_SPEED = 602739726000000000n;
// gather votingpower breakdowns and compute with above base lode speed to find emission buckets
const votingPowerABI = require('./votingPowerABI.json');
const dotenv = require('dotenv').config();
const ethers = require('ethers');
const provider = new ethers.AlchemyProvider("arbitrum", process.env.ALCHEMY_API_KEY_ARBITRUM);
const votingPowerAddress = '0xFf4eF7844fAFF2bb20a8ba5E479b0a67d8642146';
const votingPowerContract = new ethers.Contract(votingPowerAddress, votingPowerABI, provider);
async function gatherVotingResults() {
try {
const votingResults = await votingPowerContract.getResults();
const [tokens, voteStatuses, amounts] = votingResults;
// Calculate the total votes for supply and borrow
let totalSupplyVotes = BigInt(0);
let totalBorrowVotes = BigInt(0);
for (let i = 0; i < amounts.length; i += 2) {
totalSupplyVotes += amounts[i];
totalBorrowVotes += amounts[i + 1];
}
let totalVotes = totalSupplyVotes + totalBorrowVotes;
// console.log('totalSupplyVotes:', totalSupplyVotes);
// console.log('totalBorrowVotes:', totalBorrowVotes);
// console.log('totalVotes:', totalVotes);
// Create a dictionary to hold the results
const resultsDictionary = {};
// Sum the computed lode speeds from the voting gauge
let totalComputedSupplyLodeSpeed = BigInt(0);
let totalComputedBorrowLodeSpeed = BigInt(0);
// Sum the base speeds
let totalBaseSupplySpeed = BigInt(0);
let totalBaseBorrowSpeed = BigInt(0);
for (let i = 0; i < baseSupplySpeeds.length; i++) {
totalBaseSupplySpeed += BigInt(baseSupplySpeeds[i]);
totalBaseBorrowSpeed += BigInt(baseBorrowSpeeds[i]);
}
// Loop through the tokens and populate the dictionary with percentages
for (let i = 0; i < tokens.length; i++) {
const tokenAddress = tokens[i]; // Use the token address as the key
const supplyVotes = amounts[i * 2];
const borrowVotes = amounts[i * 2 + 1];
// Calculate the percentage of votes for each token with higher precision
const supplyVotesPercentage = totalSupplyVotes > 0 ? (supplyVotes * BigInt(1e18) / totalVotes) : BigInt(0);
const borrowVotesPercentage = totalBorrowVotes > 0 ? (borrowVotes * BigInt(1e18) / totalVotes) : BigInt(0);
// Multiply first by LODE_SPEED and then divide by 1000000 to minimize rounding errors
const computedSupplyLodeSpeedFromVotingGauge = (LODE_SPEED * supplyVotesPercentage) / BigInt(1e18);
const computedBorrowLodeSpeedFromVotingGauge = (LODE_SPEED * borrowVotesPercentage) / BigInt(1e18);
// Add the token and its corresponding data to the dictionary
resultsDictionary[tokenAddress] = {
supplyVotesPercentage: ((supplyVotesPercentage / BigInt(1e14)) / BigInt(100)).toString() + '.' + (supplyVotesPercentage % BigInt(100)).toString().padStart(2, '0'),
borrowVotesPercentage: ((borrowVotesPercentage / BigInt(1e14)) / BigInt(100)).toString() + '.' + (borrowVotesPercentage % BigInt(100)).toString().padStart(2, '0'),
computedSupplyLodeSpeedFromVotingGauge: computedSupplyLodeSpeedFromVotingGauge.toString(),
computedBorrowLodeSpeedFromVotingGauge: computedBorrowLodeSpeedFromVotingGauge.toString()
};
}
for (const tokenData of Object.values(resultsDictionary)) {
totalComputedSupplyLodeSpeed += BigInt(tokenData.computedSupplyLodeSpeedFromVotingGauge);
totalComputedBorrowLodeSpeed += BigInt(tokenData.computedBorrowLodeSpeedFromVotingGauge);
}
const totalLodeSpeedAdjusted = totalComputedSupplyLodeSpeed + totalComputedBorrowLodeSpeed;
// console.log(`Total Computed Supply Lode Speed: ${totalComputedSupplyLodeSpeed.toString()}`);
// console.log(`Total Computed Borrow Lode Speed: ${totalComputedBorrowLodeSpeed.toString()}`);
console.log(`Total Computed Lode Speed: ${totalLodeSpeedAdjusted.toString()}`);
console.log(`Total Expected Lode Speed: ${LODE_SPEED.toString()}`);
console.log(`Discrepency: ${LODE_SPEED.toString() - totalLodeSpeedAdjusted.toString()}`)
console.table(Object.entries(resultsDictionary).map(([token, data]) => ({
Token: token,
...data
})));
// Prepare data for the base speeds table
const baseSpeedsTableData = tokenAddresses.map((tokenAddress, index) => {
const tokenName = tokenNames[index];
const baseSupplySpeed = BigInt(baseSupplySpeeds[index]);
const baseBorrowSpeed = BigInt(baseBorrowSpeeds[index]);
// Retrieve computed speeds from the resultsDictionary using the token address
const computedData = resultsDictionary[tokenName];
if (!computedData) {
// console.log('resultsDictionary', resultsDictionary)
// console.error(`No computed data found for token address: ${tokenAddress}`);
return {
Token: tokenName,
BaseSupplySpeed: baseSupplySpeed.toString(),
BaseBorrowSpeed: baseBorrowSpeed.toString(),
SupplyLodeSpeedFromVoting: '0',
BorrowLodeSpeedFromVoting: '0',
TotalSupplySpeed: baseSupplySpeed.toString(),
TotalBorrowSpeed: baseBorrowSpeed.toString()
};
}
// Parse the computed speeds as BigInt for arithmetic operations
const computedSupplySpeed = BigInt(computedData.computedSupplyLodeSpeedFromVotingGauge);
const computedBorrowSpeed = BigInt(computedData.computedBorrowLodeSpeedFromVotingGauge);
// Add the base speed and computed speed
const totalSupplySpeed = baseSupplySpeed + computedSupplySpeed;
const totalBorrowSpeed = baseBorrowSpeed + computedBorrowSpeed;
return {
Token: tokenName,
BaseSupplySpeed: baseSupplySpeed.toString(),
BaseBorrowSpeed: baseBorrowSpeed.toString(),
SupplyLodeSpeedFromVoting: computedSupplySpeed.toString(),
BorrowLodeSpeedFromVoting: computedBorrowSpeed.toString(),
TotalSupplySpeed: totalSupplySpeed.toString(),
TotalBorrowSpeed: totalBorrowSpeed.toString()
};
});
// Display the base speeds table with additional computed speeds
console.log('Base Speeds Table with Computed Speeds (per block):');
console.table(baseSpeedsTableData);
// Create a master dictionary combining both tables
const masterDictionary = {};
baseSpeedsTableData.forEach((data, index) => {
const tokenAddress = tokenAddresses[index];
masterDictionary[tokenAddress] = { ...data };
});
// Log the master dictionary
console.log('Master Dictionary:');
console.log(masterDictionary);
} catch (error) {
console.error('Error gathering voting results:', error);
}
}
(async function main() {
await gatherVotingResults();
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment