Skip to content

Instantly share code, notes, and snippets.

@godsflaw
Last active July 31, 2019 14:04
Show Gist options
  • Save godsflaw/24a70331ebb06ef4df0807f1a2315531 to your computer and use it in GitHub Desktop.
Save godsflaw/24a70331ebb06ef4df0807f1a2315531 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
import json
import click
import appdirs
import requests
from pathlib import Path
from graphqlclient import GraphQLClient
from web3.auto import w3
#
# WEB3_PROVIDER_URI=https://parity.expotrading.com/
#
TUB = '0x448a5065aebb8e423f0896e6c5d525c040f59af3'
GQLURL = 'https://sai-mainnet.makerfoundation.com/v1'
QUERY = '''
{
allCups(condition: {deleted: false}, filter: {art: {greaterThan: "1.00"}}, orderBy: ID_ASC) {
nodes {
id
ire
art
}
}
}
'''
cache = Path(appdirs.user_cache_dir('contracts'))
cache.mkdir(exist_ok=True)
def to_32byte_hex(val):
return w3.toHex(w3.toBytes(val).rjust(32, b'\0'))
def wad(val):
return val/1000000000000000000000000000
def get_contract(address):
'''Get contract interface and cache it.'''
f = cache / f'{address}.json'
if not f.exists():
# cache the response
abi = get_contract_abi(address)
f.write_text(json.dumps(abi))
abi = json.loads(f.read_text())
return w3.eth.contract(w3.toChecksumAddress(address), abi=abi)
def get_contract_abi(address):
'''Get contract interface from Etherscan.'''
resp = requests.get('http://api.etherscan.io/api', params={
'module': 'contract',
'action': 'getabi',
'format': 'raw',
'address': address,
})
try:
return resp.json()
except json.JSONDecodeError:
return
def output_cdp_sf_over_liquidation(cdps):
'''output cdps with SF over the liquidation penalty of 13% in red'''
tub = get_contract(TUB)
click.secho(
f'{"id":>6} {"◈ Debt":>12} {"◈ LP":>12} {"◈ Fee":>12}',
fg='cyan',
bold=True
)
click.secho(
f'==============================================',
fg='cyan',
bold=True
)
for cdp in cdps:
uncollected_fees = 0.0
uncollected_fees = 0.0
debt = float(cdp["art"])
lp = debt * 0.13
ire = float(cdp["ire"])
rhi = wad(tub.functions.rhi().call())
fee = (ire * rhi) - debt;
if fee <= lp:
click.secho(
f'{cdp["id"]:>6}: {debt:>12,.2f} {lp:>12,.2f} {fee:>12,.2f}',
fg='green' if fee/lp <= .75 else 'yellow',
bold=True
)
else:
uncollected_fees += (fee - lp);
click.secho(
f'{cdp["id"]:>6}: {debt:>12,.2f} {lp:>12,.2f} {fee:>12,.2f}',
fg='orange' if lp/fee >= .1 else 'red',
bold=True
)
click.secho(
f'==============================================',
fg='cyan',
bold=True
)
click.secho(
f'Uncollected Fees: ◈{uncollected_fees}DAI',
fg='green' if uncollected_fees == 0.0 else 'red',
bold=True
)
def main():
client = GraphQLClient(GQLURL)
result = client.execute(QUERY)
data = json.loads(result)
output_cdp_sf_over_liquidation(data["data"]["allCups"]["nodes"])
if __name__ == '__main__':
main()
@godsflaw
Copy link
Author

run with:

WEB3_PROVIDER_URI=https://parity.expotrading.com/
./get-cdp-sf-over-liquidation.py 
    id        ◈ Debt         ◈ LP        ◈ Fee
==============================================
    17:    57,318.13     7,451.36     3,314.95
    36:       490.55        63.77        27.33
    41:       500.00        65.00        29.43
    42:     4,660.22       605.83       311.44
    47:     1,381.00       179.53        79.09
    51:   659,312.73    85,710.66    41,943.35
    52:    10,000.00     1,300.00       649.93
    70:    12,499.79     1,624.97       510.28
    72:     3,991.81       518.94       168.19
    82:       370.00        48.10        24.93
   118:       430.99        56.03        24.24
   124:    12,495.12     1,624.37       732.27
   135:   144,000.00    18,720.00     5,694.06
   148:        10.00         1.30         0.68
   162:       168.60        21.92        10.96
   177:         8.00         1.04         0.55
   185:     1,500.00       195.00        76.83
   196:    15,175.02     1,972.75       977.68
   213:         7.00         0.91         0.48
   227:         7.26         0.94         0.49
   229:     2,405.00       312.65       130.95
   238:     4,528.29       588.68        63.65
   242:     3,500.00       455.00       164.30
   245:     8,054.49     1,047.08       542.34
   250:    10,100.00     1,313.00       368.76
   271:    25,738.00     3,345.94       640.58
   290:     1,300.00       169.00        83.57
   340:    59,983.13     7,797.81     3,790.88
   352:    70,000.00     9,100.00     4,725.66
   356:   164,800.00    21,424.00    10,316.94
   362:     1,190.00       154.70        69.66
   367:     3,500.00       455.00       197.13
   377:     5,280.53       686.47       358.97
   378:       856.78       111.38        57.16
   405:    11,451.86     1,488.74       413.55
   410:     5,973.00       776.49       112.23
   420:       100.00        13.00         4.99
   474:    14,371.00     1,868.23       364.80
   489:     2,062.08       268.07       131.97
   528:     4,850.00       630.50       231.63
==============================================
Uncollected Fees: ◈0.0DAI

colors:

  • green indicates healthy
  • yellow indicates the CDP's fees are 75% to the liquidation penalty
  • orange indicates over the liquidation penalty by 10%
  • red indicates over the liquidation penalty by more than 10%

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment