Skip to content

Commit

Permalink
chore: pyth paradeen feed script
Browse files Browse the repository at this point in the history
  • Loading branch information
wow-alpaca committed Mar 15, 2024
1 parent 3a318d9 commit 20c4635
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 0 deletions.
125 changes: 125 additions & 0 deletions deploy/trade-mining/paradeen-feed-pyth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { DeployFunction } from "hardhat-deploy/types";
import { ethers } from "hardhat";
import { getConfig } from "../utils/config";
import { BigNumber } from "ethers";
import { AP__factory, Paradeen__factory } from "../../typechain";
import * as readlineSync from "readline-sync";
import { getCoinGeckoPriceUSD } from "../utils/price";
import { formatEther } from "ethers/lib/utils";

interface FeedParadeenParams {
weekTimestamp: BigNumber;
amount: BigNumber;
}

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const config = getConfig();
const signer = (await ethers.getSigners())[0];
const pythExponent = BigNumber.from(10).pow(6);

// contracts
const ap = AP__factory.connect(config.TradeMining.AP, ethers.provider);
const paradeen = Paradeen__factory.connect(
config.TradeMining.paradeen,
signer
);

// constants
const E18 = BigNumber.from(10).pow(18);
const WEEK = BigNumber.from(604800);

// configs
const tradingFeeBps = 9;
const weeklyFeeThreshold = BigNumber.from(20000).mul(E18);

console.log(`> Prepare data...`);

const currentBlock = await ethers.provider.getBlock("latest");
const weekCursor = BigNumber.from(currentBlock.timestamp).div(WEEK).mul(WEEK);

const weeklyTradingVolume = await ap.weeklyTotalSupply(weekCursor);
const tradingFeeCollected = weeklyTradingVolume
.mul(tradingFeeBps)
.mul(2) // account closing volume assure
.div(10000);
const pythPrice = await getCoinGeckoPriceUSD("pyth-network");

console.log(`> Weekly trading volume: ${formatEther(weeklyTradingVolume)}`);
console.log(`> Trading fee collected: ${formatEther(tradingFeeCollected)}`);
console.log(`> Pyth price: ${formatEther(pythPrice)}\n`);

let amountToFeed = BigNumber.from(0);

if (tradingFeeCollected.lt(weeklyFeeThreshold)) {
console.log(
`> Trading fee collected is < ${formatEther(weeklyFeeThreshold)} USD`
);
amountToFeed = tradingFeeCollected.mul(E18).div(pythPrice);
} else {
console.log(
`> Trading fee collected is > ${formatEther(weeklyFeeThreshold)} USD`
);
amountToFeed = weeklyFeeThreshold.mul(E18).div(pythPrice);
}

console.log(`> Amount to feed: ${formatEther(amountToFeed)} Pyth`);

const PARAMS_INPUT: Array<FeedParadeenParams> = [
{
weekTimestamp: weekCursor,
amount: amountToFeed.mul(pythExponent).div(E18),
},
];

// Check feed timestamp
const weeklyReward = await paradeen.tokensPerWeek(weekCursor);
if (weeklyReward.gt(0)) {
console.log(
`> Weekly reward for ${weekCursor}: ${formatEther(weeklyReward)}`
);
console.log(`> Already fed for this week`);
const goNext = readlineSync.question("Confirm to re-feed? (y/n): ");
switch (goNext.toLowerCase()) {
case "y":
break;
case "n":
console.log("Aborting");
return;
default:
console.log("Invalid input");
return;
}
}

// Ask for confirmation
console.table(PARAMS_INPUT);
const confirm = readlineSync.question("Confirm? (y/n): ");
switch (confirm.toLowerCase()) {
case "y":
break;
case "n":
console.log("Aborting");
return;
default:
console.log("Invalid input");
return;
}

const timestamps = PARAMS_INPUT.map((p) =>
p.weekTimestamp.div(WEEK).mul(WEEK)
);
const amounts = PARAMS_INPUT.map((p) => p.amount);

console.log("> Feeding rewards to Paradeen");
const tx = await paradeen.feed(timestamps, amounts, {
gasLimit: 10000000000,
});
console.log(`> ⛓ Tx submitted: ${tx.hash}`);
console.log(`> Waiting tx to be mined...`);
await tx.wait();
console.log(`> Tx mined!`);
};

export default func;
func.tags = ["FeedParadeenPyth"];
19 changes: 19 additions & 0 deletions deploy/utils/price.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import axios from "axios";
import { BigNumber } from "ethers";
import { parseEther } from "ethers/lib/utils";

export async function getCoinGeckoPriceUSD(
assetId: string
): Promise<BigNumber> {
let tokenPrice = BigNumber.from(0);
try {
const response = await axios.get(
`https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&ids=${assetId}`
);
tokenPrice = parseEther(response.data[0]["current_price"].toString());
} catch (error) {
throw new Error(`Error fetching price for ${assetId}: ${error}`);
}

return tokenPrice;
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@
"deploy:mainnet:trade-mining:ap-token:upgrade:ap-token": "hardhat --network mainnet deploy --no-compile --reset --tags UpgradeAPToken",
"deploy:mainnet:trade-mining:paradeen": "hardhat --network mainnet deploy --no-compile --reset --tags Paradeen",
"deploy:mainnet:trade-mining:feed-paradeen": "hardhat --network mainnet deploy --no-compile --reset --tags FeedParadeen",
"deploy:mainnet:trade-mining:feed-paradeen-pyth": "hardhat --network mainnet deploy --no-compile --reset --tags FeedParadeenPyth",
"deploy:mainnet:trade-mining:set_mineable": "hardhat --network mainnet deploy --no-compile --reset --tags SetMiningManagerMinable",
"deploy:mainnet:trade-mining:set_miner_manager_auth": "hardhat --network mainnet deploy --no-compile --reset --tags SetMiningManagerAuth",
"deploy:mainnet:trade-mining:set_miner_manager_point": "hardhat --network mainnet deploy --no-compile --reset --tags SetMiningManagerPoint",
Expand Down

0 comments on commit 20c4635

Please sign in to comment.