Created
March 30, 2023 22:36
-
-
Save dbeal-eth/8ffbd992fa9a16319ca7bce0d9eda41a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const ethers = require('ethers'); | |
const address = `${process.argv[2]}`; | |
const api = `${process.env.PROVIDER_URL}`; | |
const provider = new ethers.providers.JsonRpcProvider(api); | |
const ABI = require('./Synthetix.json'); | |
const synthetixAddress = '0x8700daec35af8ff88c16bdf0418774cb3d7599b4'; | |
const synthetixUsdAddress = '0x8c6f28f2F1A3C87F0f938b96d27520d9751ec8d9'; | |
const BATCH_SIZE = 1000000; | |
async function findBlockByNumber(time, start = 0, end = 'latest') { | |
if (end === 'latest') { | |
end = await provider.getBlockNumber(); | |
} | |
if (end - start <= 1) { | |
return start; | |
} | |
const checkBlock = Math.floor((start + end) / 2); | |
console.log('check block', checkBlock); | |
const block = await provider.getBlock(checkBlock); | |
console.log(block.timestamp, '<', time); | |
if (block.timestamp < time) { | |
return await findBlockByNumber(time, checkBlock, end); | |
} else { | |
return await findBlockByNumber(time, start, checkBlock); | |
} | |
} | |
async function sumEvents(contract, filter, startBlock, endBlock) { | |
let summed = ethers.BigNumber.from(0); | |
for (let i = startBlock; i < endBlock; i += BATCH_SIZE) { | |
try { | |
console.log('querying', i, endBlock); | |
const events = await provider.getLogs({ | |
fromBlock: i, | |
toBlock: i + BATCH_SIZE, | |
address: contract, | |
topics: filter | |
}); | |
if (events.length) console.log(`found ${events.length} events`); | |
for (const e of events) { | |
// get the txn associated with this event to make sure it meets a standard | |
const txn = await provider.getTransaction(e.transactionHash); | |
//console.log(txn); | |
// must match function selector | |
if ( | |
txn.data.startsWith('0xaf086c7e') || // issueMaxSynths | |
txn.data.startsWith('0x320223db') || // issue max synths on behalf | |
txn.data.startsWith('0x8a290014') || // issue synths | |
txn.data.startsWith('0xe8e09b8b') || // issue synths on behalf | |
txn.data.startsWith('0x295da87d') || // burn synths | |
txn.data.startsWith('0xc2bf3880') || // burn synths on behalf | |
txn.data.startsWith('0x9741fb22') || // burn synths to target | |
txn.data.startsWith('0x2c955fa7') // burn synths to target on behalf | |
) { | |
//console.log(e); | |
summed = summed.add(ethers.utils.defaultAbiCoder.decode(['uint256'], e.data)[0]); | |
} else { | |
console.log('skip non-matching selector'); | |
} | |
} | |
} catch (err) { | |
console.log('skip', err); | |
} | |
} | |
return summed; | |
} | |
async function calculateStakerPnl(address, taxYear) { | |
const contract = new ethers.Contract(synthetixAddress, ABI, provider); | |
const startTime = Math.floor(Date.parse(taxYear) / 1000); | |
const endTime = taxYear + 31536000; | |
const startBlockTag = await findBlockByNumber(startTime); | |
const endBlockTag = await findBlockByNumber(endTime); | |
const startDebt = await contract.debtBalanceOf(address, ethers.utils.formatBytes32String('sUSD'), { blockTag: startBlockTag }); | |
const endDebt = await contract.debtBalanceOf(address, ethers.utils.formatBytes32String('sUSD'), { blockTag: endBlockTag }); | |
// figure out all the mints and burns in between | |
const minted = await sumEvents(synthetixUsdAddress, [ethers.utils.id('Issued(address,uint256)'), ethers.utils.defaultAbiCoder.encode(['address'], [address])], startBlockTag, endBlockTag); | |
const burned = await sumEvents(synthetixUsdAddress, [ethers.utils.id('Burned(address,uint256)'), ethers.utils.defaultAbiCoder.encode(['address'], [address])], startBlockTag, endBlockTag); | |
console.log('start debt', ethers.utils.formatEther(startDebt)); | |
console.log('end debt', ethers.utils.formatEther(endDebt)); | |
console.log('total mint', ethers.utils.formatEther(minted)); | |
console.log('total burn', ethers.utils.formatEther(burned)); | |
// add it all together | |
const total = minted.add(startDebt).sub(endDebt).sub(burned); | |
console.log('debt pool profit/loss:', ethers.utils.formatEther(total)); | |
return total; | |
} | |
calculateStakerPnl(process.argv[2], process.argv[3]); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment