A Pen by justin j. moses on CodePen.
Created
October 20, 2019 16:53
-
-
Save jjgonecrypto/8c8550e36916de3946a7b20aad6ac64e to your computer and use it in GitHub Desktop.
Synthetix top holders lock status
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
| <header><img src="https://developer.synthetix.io/api/img/logo.png" /></header> | |
| <main> | |
| <p class="helper-text">Note: these results aren't strictly ordered to increase performance.</p> | |
| <button name="begin">Begin</button> | |
| <button name="stop">Stop</button> | |
| <ul> | |
| <li id="tokenHolders"><strong>Token Holders:</strong><var>?</var></li> | |
| <li id="neverIssued"><strong>Never Issued:</strong><var>?</var></li> | |
| <li id="snxPrice"><strong>SNX Price:</strong><var>?</var></li> | |
| <li id="snxTotal"><strong>SNX Total:</strong><var>?</var></li> | |
| <li id="snxLocked"><strong>SNX Locked:</strong><var>?</var></li> | |
| <li id="pcentLocked"><strong> </strong><var>?</var></li> | |
| <li id="networkRatio"><strong>Network Ratio:</strong><var>?</var></li> | |
| <li id="activeRatio"><strong>Active Ratio:</strong><var>?</var></li> | |
| </ul> | |
| <table> | |
| <thead><tr><th></th><th>Address</th><th>Balance</th><th>CRatio</th><th>Locked SNX</th><th>Debt Balance</th></tr></thead> | |
| <tbody><tr><td colspan="100" class="helper-text">Press Begin to start....</td></tr></tbody> | |
| </table> | |
| </main> |
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
| window.CP.PenTimer.MAX_TIME_IN_LOOP_WO_EXIT = 60e3; // 1min timeout on for loop below | |
| const snxjs = new SynthetixJs.SynthetixJs(); | |
| const toUtf8Bytes = SynthetixJs.SynthetixJs.utils.formatBytes32String; | |
| const tbody = document.querySelector('tbody'); | |
| const beginBtn = document.querySelector('button[name="begin"]'); | |
| const stopBtn = document.querySelector('button[name="stop"]'); | |
| const tokenHoldersTarget = document.querySelector('#tokenHolders var'); | |
| const snxPriceTarget = document.querySelector('#snxPrice var'); | |
| const snxTotalTarget = document.querySelector('#snxTotal var'); | |
| const snxLockedTarget = document.querySelector('#snxLocked var'); | |
| const pcentLockedTarget = document.querySelector('#pcentLocked var'); | |
| const neverIssuedTarget = document.querySelector('#neverIssued var'); | |
| const networkRatioTarget = document.querySelector('#networkRatio var'); | |
| const activeRatioTarget = document.querySelector('#activeRatio var'); | |
| let stopFlag = false; | |
| stopBtn.addEventListener('click', () => stopFlag = true); | |
| const lookup = async () => { | |
| tbody.innerHTML = '<img src="https://media.giphy.com/media/TvLuZ00OIADoQ/giphy.gif" width=150 />'; | |
| beginBtn.setAttribute('disabled', true); | |
| try { | |
| tokenHoldersTarget.innerHTML = 0; | |
| neverIssuedTarget.innerHTML = 0; | |
| tbody.innerHTML = '<tr><td colspan=100 class="helper-text">loading...</td></tr>'; | |
| const holders = await snxData.snx.holders({ max: 24000 }); | |
| const escrowContracts = await Promise.all([snxjs.Synthetix.escrow(), snxjs.Synthetix.rewardEscrow()]); | |
| const exchangeWalletsReq = await fetch('https://raw.githubusercontent.com/whjn011205/ScoreEngine/fe383336db49a7601f1793b8ad570a8d0a8fb6df/src/data/goodList.json'); | |
| const exchangeWallets = await exchangeWalletsReq.json(); | |
| // const issuanceRatioToAvoidPenalty = Number(snxjs.utils.formatEther(await snxjs.FeePool.getPenaltyThresholdRatio())); | |
| const issuanceRatio = Number(snxjs.utils.formatEther(await snxjs.SynthetixState.issuanceRatio())); | |
| const results = holders.filter(({ address }) => escrowContracts.indexOf(address.toLowerCase()) === -1); | |
| //const sleep = ms => new Promise(res => setTimeout(res, ms)); | |
| const usdToSnxPrice = snxjs.utils.formatEther(await snxjs.Depot.usdToSnxPrice()); | |
| snxPriceTarget.innerHTML = `$${Number(usdToSnxPrice).toFixed(5)}`; | |
| let snxTotal = 0; | |
| let snxLocked = 0; | |
| let activeStakers = 0; | |
| let snxHolders = 0; | |
| let networkRatio = []; | |
| let activeRatio = []; | |
| const updateTotals = ({ balance, lockedSnx, collateralRatio }) => { | |
| snxHolders++; | |
| if (Number(collateralRatio) > 0) { | |
| activeStakers++; | |
| activeRatio.push(Number(collateralRatio)); | |
| } | |
| networkRatio.push(Number(collateralRatio)); | |
| neverIssuedTarget.innerHTML = Number(neverIssuedTarget.innerHTML) + (Number(lockedSnx) > 0 ? 0 : 1); | |
| tokenHoldersTarget.innerHTML = Number(tokenHoldersTarget.innerHTML) + 1; | |
| snxTotal += Number(balance); | |
| snxLocked += Number(lockedSnx); | |
| snxTotalTarget.innerHTML = `${numbro(snxTotal).format('0,000.00')} (${numbro(snxTotal * usdToSnxPrice).format('0,0.00')} USD)`; | |
| snxLockedTarget.innerHTML = `${numbro(snxLocked).format('0,000.00')} (${numbro(snxLocked * usdToSnxPrice).format('0,0.00')} USD)`; | |
| pcentLockedTarget.innerHTML=`${Number(snxLocked/snxTotal*100).toFixed(2)}%`; | |
| networkRatioTarget.innerHTML=`${Number(1/(networkRatio.reduce((a,b) => a+b)/snxHolders)*100).toFixed(2)}%`; | |
| activeRatioTarget.innerHTML=`${Number(1/(activeRatio.reduce((a,b) => a+b)/activeStakers)*100).toFixed(2)}%`; | |
| } | |
| let row = 1; | |
| for (const { address, collateral } of results) { | |
| const addressLink = `<a target="_blank" href="https://etherscan.io/address/${address}">${address}</a>`; | |
| const promises = await Promise.all([snxjs.Synthetix.collateral(address), snxjs.Synthetix.collateralisationRatio(address), snxjs.Synthetix.debtBalanceOf(address, toUtf8Bytes('sUSD'))]); | |
| const [ balance, collateralRatio,debtBalance] = promises.map(snxjs.utils.formatEther); | |
| // ignore if 0 balance | |
| console.log('skip'); | |
| if (Number(balance) <= 0) continue; | |
| const exchangeWallet = exchangeWallets.find(({ exchange }) => exchange.toLowerCase() === address.toLowerCase()); | |
| const balanceFormatted = numbro(balance).format('0,000.00'); | |
| const balanceUSD = numbro(balance * usdToSnxPrice); | |
| const balanceUSDFormatted = numbro(balanceUSD).format('0,000.00'); | |
| const lockedSnx = balance * Math.min(1, collateralRatio/issuanceRatio); | |
| updateTotals({ balance, lockedSnx, collateralRatio }); | |
| const currentCRatio = collateralRatio > 0 ? (1/collateralRatio)*100 : 0; | |
| tbody.innerHTML += `<tr><td>${row++}.</td><td>${exchangeWallet ? `<strong>${exchangeWallet.name}</strong>` : ''} ${addressLink}</td><td>${balanceFormatted} ($${balanceUSDFormatted})</td><td>${Math.round(currentCRatio)}%</td><td>${Math.round((lockedSnx/balance) * 100)}%</td><td>${numbro(debtBalance).format('0,0.00')}</tr>`; | |
| if (stopFlag) break; | |
| } | |
| stopFlag = false; | |
| } catch (err) { | |
| tbody.innerHTML = `<span style="color:red">${err}</span>`; | |
| } | |
| tbody.querySelector('tr:first-child>td').innerHTML = ''; | |
| beginBtn.removeAttribute('disabled'); | |
| }; | |
| beginBtn.addEventListener('click', () => { | |
| lookup(); | |
| }); |
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
| <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.29/browser-polyfill.min.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.29/browser.min.js"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/synthetix-js/dist/main.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/numbro/2.0.5/numbro.min.js"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/[email protected]/index.min.js"></script> |
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
| @snx-color: #0b0816; | |
| body { | |
| font-family: 'Helvetica'; | |
| font-size: 14px; | |
| padding: 0; | |
| margin: 0; | |
| } | |
| header { | |
| background-color: @snx-color; | |
| min-height: 50px; | |
| img { | |
| padding: 8px; | |
| } | |
| } | |
| main { | |
| padding: 20px; | |
| } | |
| button { | |
| margin: 0px 0px 20px 0; | |
| padding: 10px 20px; | |
| font-size: 14px; | |
| border-radius: 4px; | |
| background-color: @snx-color; | |
| color: white; | |
| font-weight: bold; | |
| opacity: 0.8; | |
| cursor: pointer; | |
| &:hover { | |
| opacity: 1 | |
| } | |
| &[name=stop] { | |
| background-color: red; | |
| } | |
| } | |
| ul { | |
| padding: 0; | |
| li { | |
| padding-left: 3px; | |
| list-style-type: none; | |
| strong { | |
| display: inline-block; | |
| width: 120px; | |
| } | |
| } | |
| } | |
| var { | |
| font-family: "Courier New", "Courier"; | |
| font-size: 18px; | |
| } | |
| .leaderboard { | |
| display: flex; | |
| > * { | |
| width: 50%; | |
| } | |
| } | |
| a { | |
| color: @snx-color; | |
| } | |
| table { | |
| width: 100%; | |
| th, td { | |
| text-align: right; | |
| } | |
| tr:nth-child(even) { | |
| background-color: #e8e8e8; | |
| } | |
| } | |
| .helper-text { | |
| color: #aaa; | |
| font-size: 12px; | |
| } | |
| .error-text { | |
| color: red; | |
| } | |
| .success-text { | |
| color: green; | |
| a { | |
| color: darkgreen; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment