Technical Incident Report: Staking Logic Vulnerability and Exploitation
Executive Summary
Significant exploitation of the Harmony blockchain’s staking logic was detected, activating an emergency response hard-forking update. This report provides an in-depth technical analysis and a comprehensive response chronology.
Background
A critical vulnerability was identified in Harmony’s staking contract logic on December 7th. This flaw permitted unintended token generation and manipulation during undelegation, diverging from the protocol’s designed operations.
Technical Details
Vulnerability Overview
The defect was located in the undelegation portion of the staking logic, which unintentionally allowed for the minting and manipulation of tokens outside the designed protocol parameters.
Technical Findings
- The Harmony Improvement Proposal (HIP-30) introduced a network-wide minimum commission rate for validators. Validators were required to increase their commission rates if they were below this minimum. However, a critical flaw was discovered in implementing this feature: validators with a
MaxRate
lower than the enforced minimum were not correctly processed due to theSanityCheck
function. - During the
SanityCheck
, the system checks whether the validator’s Rate does not exceed theMaxRate
. Because of the new minimum commission rate, validators who had set theirMaxRate
below this network-wide minimum failed theSanityCheck
. As a result, the new state that included the increased commission rate could not be committed to disk. - This failure to update the state due to the
SanityCheck
error meant that undelegations, which were supposed to be finalized and removed, persisted incorrectly in the system’s state. Not recognizing this error, the protocol continued to payout for these undelegations. - The error propagated with each epoch: matured undelegations were repeatedly included in payouts because they were not cleared from the state, creating new tokens without proper validation and resulting in the inflation of the circulating supply.
Hard Fork Information
- Version: 2023.4.0
- Epoch Activation: 1733
- Block Height Activation: 51118080
- Time Estimate: Dec 17, 2023 ~4:30 am US Pacific Time
- Github: Release Mainnet Release 2023.4.0 · harmony-one/harmony · GitHub
Quantitative Data
- Total delegator addresses involved: 74
- Total Tokens Minted: 146,279,995.61211874 ONE
- Validators affected:
- H1, Tr4ck3r, SargatxetPool, and Husaria
- Known validator addresses that received faulty ONE:
- Tr4ck3r Validator: one1rxdtt9fvgdcy3n5sy6e4zxg0s4hn4shaqf4qtp
- Minted 393k ONE before blacklist
- ~120k ONE sold or transferred
- Modulo.so: one1rzj676wlcqkuj58h2d9wj7scpu6twht6qqvw54
- Minted 51.2 million ONE
- ~16.4 million ONE sold or transferred
- 42,599,891.99 ONE Burned to Date
- SargatxetPool: one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq
- Minted 434k ONE before blacklist
- ~404k ONE sold or transferred
- Tr4ck3r Validator: one1rxdtt9fvgdcy3n5sy6e4zxg0s4hn4shaqf4qtp
Response Timeline
Thursday 12/7:
- Issue Reported: Modulo.so disclosed that he witnessed another delegator getting extra rewards from another delegator after an undelegation. This seemed like an isolated incident at the time, and initial investigations began to verify these claims. No other information was provided.
Friday 12/8:
- Team Reminded: Modulo.so notified the team again about the issue but only confirmed the undelegation amount was deposited in the other delagators wallet the subsequent epoch. No other information was provided.
- Continued Testing: The team struggled to replicate the anomaly due to limited information.
Monday 12/11:
- Issue Replication: The team dedicated the day to replicating the bug reported the week prior. They meticulously combed through transaction logs and the staking module’s logic to identify the exploit’s mechanism.
- Source Hunting: Simultaneously, efforts were made to trace the source of the vulnerability within the codebase, which involved reviewing recent commits and changes that might have introduced the flaw.
- No Solution: Since the team didn’t have a consistent pattern, they could not figure out exactly where the issue was in the codebase or duplicate it in local test environments.
Tuesday 12/12:
- Further Disclosure: Modulo.so disclosed more information about the vulnerability, emphasizing the need for an emergency patch. He disclosed that only 3 validators were affected and that it was “good news” that it “…only started to happen recently” and that the “…impacted amounts are sufficiently “small” to not cause significant damage”. We reported this preassessment from modulo.so up to Stephen.
- Communication: Since the issue was likely due to the delegation logic’s 5% minimum validator fee portion, code references were exchanged while communication channels were established.
- Team Expansion: In response to the urgency, Max, the original code owner for the affected module, was brought back onto the team for his expertise and familiarity with the code.
- Code Review and Brainstorming: Max and the team reviewed the code together, discussing potential solutions and approaches to patch the vulnerability effectively.
- Analytics: Modulo.so began running and developing scripts to understand the damage.
Wednesday 12/13:
- Solution Development: With a clearer understanding of the issue, the team formulated a set of potential solutions. The focus was on not just quick fixes but sustainable changes that would prevent similar incidents in the future.
Thursday 12/14:
- Testing Phase: The developed solutions were subjected to rigorous testing scenarios, including attempts to exploit the staking in a controlled environment. The goal was to ensure the patch’s effectiveness and that it introduced no new vulnerabilities.
- Discovery: While testing was underway, investigations revealed that Modulo.so was receiving about 4.4 million ONE tokens per epoch due to the flaw. Approximately 16.4 million ONE tokens were moved to an exchange between 12/8 and 12/10, heightening security concerns.
- Community: The team started to engage and prepare key validators for the hard fork and update. A vote was created among the active validator community, and 1-3 days from release to hard fork epoch was agreed.
Friday 12/15:
- Patch Release: The team finalized the testing and optimization of the patch and rolled it out early in the morning. An announcement was made to all validators and node operators to update their software promptly.
- Post-Release Monitoring: After the patch release, the network was closely monitored. The team remained on high alert to quickly address any issues resulting from the patch or any unusual network behavior.
Blacklisted Addresses
We implemented temporary measures to secure the network and protect its integrity in response to the incident. This included blacklisting several addresses linked to the exploitation. These measures are not punitive but preventative, ensuring the stability and security of the network during our investigation. We are actively working on a fair and transparent process for reviewing these blacklists, focusing on restoring normal operations while upholding the network’s integrity.
Ethical Considerations
This recent incident has raised significant ethical questions within our Harmony community and offered valuable lessons. Our foundation is built on trust, transparency, and collaborative effort. When these core principles are tested, it is an opportunity for us to collectively strengthen our commitment to these values.
One key lesson from this incident is the critical importance of complete and upfront disclosure in security-related matters. Full transparency during the initial reporting phase could have expedited our response and potentially minimized the impact of the exploit. It underscores the need for clear communication channels and protocols that encourage and facilitate immediate and comprehensive reporting of vulnerabilities.
Moreover, the actions of selling the exploited tokens, while within the technical possibilities of the network, were not in alignment with the ethical standards and the spirit of collective responsibility we uphold in our community. This behavior not only undermines trust but also complicates accountability and resolution efforts. It highlights the necessity for a robust ethical framework that guides actions, especially when the network’s integrity is at stake.
We recognize the urgency to fortify our community governance with stronger ethical guidelines in light of these events. We are committed to engaging in open discussions with our community members, drawing valuable input on effectively addressing such challenges in the future. Our focus remains on ensuring that our responses to these situations are not just technically sound, but also ethically aligned with the ethos of Harmony.
By learning from this incident, we aim to enhance our protocols and community guidelines, ensuring that Harmony thrives as a transparent, trust-based, and collaboratively governed blockchain ecosystem.
Recommendations
- Short-Term: Deployment of automated monitoring tools for the staking logic. Atomic release of unlocked funds and the corresponding undelegation(s) removal. Continue to promote the burning of unintended generated tokens. Improve and expand the Harmony protocol unit and staking behavioral tests.
- Long-Term: Creation of a structured framework for security disclosure and incident response, including incentive mechanisms for ethical behavior and repercussions for exploitation post-disclosure. Implement a rigorous process for creating automated tests for every feature in development.
Conclusion
The recent exploitation incident within the Harmony network has been a crucial learning experience, underscoring the importance of robust security measures and ethical governance in the blockchain ecosystem. This event tested our network’s resilience, revealing areas where our security protocols and crisis management strategies can be further strengthened.
Our team’s response to the incident was prompt and technically adept, effectively mitigating the vulnerability. However, the situation highlighted the need for a more comprehensive approach to ethical conduct and governance within our community. It has become clear that while technical solutions are fundamental, they must be complemented by strong ethical guidelines and community-driven governance to ensure the long-term security and integrity of the ecosystem.
Moving forward, we are committed to implementing the lessons learned from this incident. This includes enhancing our monitoring capabilities, refining our response protocols, and fostering a culture of ethical transparency. By engaging our community in these efforts and establishing clear standards of conduct, we aim to reinforce trust and collaboration within Harmony, making our network not only technologically robust but also ethically resilient.
In conclusion, this incident, while challenging, has provided us with valuable insights and an opportunity to grow stronger. We remain dedicated to our mission of building a secure and ethically sound blockchain ecosystem, one that is capable of facing and overcoming the complexities of the evolving web3 landscape.
Bad Delegator Script:
#!/usr/bin/env python3
from pyhmy import (
blockchain,
staking,
util,
account,
)
import json
endpoint = "https://a.api.s0.t.hmny.io"
max_rate_epoch = 1733
first_block_max_rate_epoch = 51118080
hip_30_epoch = 1673
# if i undelegate at n, i will get back at the beginning of n + 9
lock_period = 7
lock_period_offset = 2
blk = {}
cur_epoch = blockchain.get_current_epoch( endpoint )
# cur_epoch is used to calculate so-far-loss and shouldn't be more than max_rate_epoch - 1
cur_epoch = max_rate_epoch - 1 if cur_epoch >= max_rate_epoch else cur_epoch # since we are now past 1733
addrs = staking.get_all_validator_addresses( endpoint ) # to check all validator
# below to focus on the 4 bad validators
addrs = ["one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq",
"one1qv82h8dzjmm09tqwdwe3evjgmzz84fqmqskkzk",
"one1rxdtt9fvgdcy3n5sy6e4zxg0s4hn4shaqf4qtp",
"one1xrtkrcpx7edw40zxpp26up939gc68u8hwepvnx"]
for addr in addrs:
validator_info = staking.get_validator_information_by_block_number( addr, first_block_max_rate_epoch - 2, endpoint )
rate = float( validator_info[ 'validator' ][ 'rate' ] )
max_rate = float( validator_info[ 'validator' ][ 'max-rate' ] )
if rate < 0.07 and max_rate < 0.07:
print( "Small rate", addr, rate )
delegations = validator_info[ 'validator' ][ 'delegations' ]
for delegation in delegations:
for undelegation in delegation[ 'undelegations' ]:
epoch = undelegation[ 'epoch' ]
# if i undelegate anytime during epoch 1671
# it is recorded as d.Undelegations[j].Epoch
# at the end of 1678, i get back my funds
# if header.IsLastBlockInEpoch() {
# curEpoch = header.Epoch()
# epochsSinceUndelegation = big.NewInt(0).Sub(curEpoch, d.Undelegations[j].Epoch)
# }
# or the beginning of 1679
# so it is a difference of 8
maturity_epoch = epoch + lock_period + 1
if maturity_epoch >= hip_30_epoch and maturity_epoch < max_rate_epoch:
print( "Blacklist", delegation[ 'delegator-address' ] )
if delegation[ 'delegator-address' ] not in blk:
blk[ delegation[ 'delegator-address' ] ] = [ ]
blk[ delegation[ 'delegator-address' ] ].append(
{
'validator-address': addr,
'amount': undelegation[ 'amount' ] / 1e18,
# middle of this epoch
'epoch': epoch,
# beginning of this epoch
'maturity-epoch': maturity_epoch,
}
)
aaron = util.convert_hex_to_one(
'0x18a5af69dfc02dc950f7534ae97a180f34b75d7a'
)
res = {
'max-loss': 0.0,
'max-loss-excluding-aaron': 0.0,
'max-loss-aaron': 0.0,
}
for blk_addr in blk:
for item in blk[ blk_addr ]:
# for maturity at the beginning of 1679
# 1679 beginning should give you the funds if no bug
# at beginning of these we get extra funds
# 1680, 1681, ...., 1732
# count = 1732 - 1680 + 1
# (max_rate_epoch - 1) - (maturity_epoch + 1) + 1
# max_rate_epoch - maturity_epoch - 2 + 1
# max_rate_epoch - maturity_epoch - 1
item[ 'max-loss' ] = item[ 'amount' ] * (
max_rate_epoch - item[ 'maturity-epoch' ] - 1
)
res[ 'max-loss' ] += item[ 'max-loss' ]
if blk_addr == aaron:
res[ 'max-loss-aaron' ] += item[ 'max-loss' ]
else:
res[ 'max-loss-excluding-aaron' ] += item[ 'max-loss' ]
print( "Details-by-bad-delegator:" )
for blk_addr in blk:
for item in blk[ blk_addr ]:
print( f"'{blk_addr}' : {item}" )
print()
print( blk[ aaron ] )
print()
print( "Summary:" )
res = { k: v / 1000000 for k, v in res.items() }
print( res )
print( "final json:" )
final_result = {}
for blk_addr in blk:
final_result[blk_addr]={}
# get current balance
balance = account.get_balance(blk_addr, endpoint="https://api.harmony.one")
final_result[blk_addr]["balance"] = balance
final_result[blk_addr]["bad-delegation"] = blk[ blk_addr ]
final_resultjson = json.dumps(final_result)
print(final_resultjson)
Output:
Details-by-bad-delegator:
'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq' : {'validator-address': 'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq', 'amount': 8000.0, 'epoch': 1673, 'maturity-epoch': 1681, 'max-loss': 408000.0}
'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq' : {'validator-address': 'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq', 'amount': 2000.0, 'epoch': 1711, 'maturity-epoch': 1719, 'max-loss': 26000.0}
'one1hhkwvqy0nxye6q7f3zufm3xtggs7plgxjhm9uv' : {'validator-address': 'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq', 'amount': 1.7957826, 'epoch': 1687, 'maturity-epoch': 1695, 'max-loss': 66.4439562}
'one1td6g8sh02r7skyqtl46qdlgu0ed5lp259uut7x' : {'validator-address': 'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq', 'amount': 5853.95, 'epoch': 1687, 'maturity-epoch': 1695, 'max-loss': 216596.15}
'one1upw0kwk0znhvzmajmg68natnvwwtfdmkq6x83j' : {'validator-address': 'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq', 'amount': 1825.0, 'epoch': 1710, 'maturity-epoch': 1718, 'max-loss': 25550.0}
'one13sqcelgdcf0ss573jq5qekw24tp9srqhsc5rz6' : {'validator-address': 'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq', 'amount': 9337.583892, 'epoch': 1683, 'maturity-epoch': 1691, 'max-loss': 382840.939572}
'one1zehlukl282w4d2yfagxfrtjxxgg87z0c0y8jx5' : {'validator-address': 'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq', 'amount': 998.0, 'epoch': 1722, 'maturity-epoch': 1730, 'max-loss': 1996.0}
'one1lentd4wxugn03fvp5spmzpw5j3vjftyhjv5usv' : {'validator-address': 'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq', 'amount': 499.998, 'epoch': 1719, 'maturity-epoch': 1727, 'max-loss': 2499.99}
'one14de246690z4pptymlwm5qsuae52ju6pzw2nhhc' : {'validator-address': 'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq', 'amount': 66236.5436724, 'epoch': 1685, 'maturity-epoch': 1693, 'max-loss': 2583225.2032236}
'one1n0ex306uv0ds6wwxg876hkqkkygt8zdk45mekq' : {'validator-address': 'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq', 'amount': 710.0, 'epoch': 1687, 'maturity-epoch': 1695, 'max-loss': 26270.0}
'one1fjeduxklq45e4c594kc6u6vfn9unvfrjt29wcd' : {'validator-address': 'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq', 'amount': 2827.2227066, 'epoch': 1693, 'maturity-epoch': 1701, 'max-loss': 87643.9039046}
'one12zyyam39rqrkne37c6y0f48v7ly36nptzjpdvx' : {'validator-address': 'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq', 'amount': 33454.0, 'epoch': 1714, 'maturity-epoch': 1722, 'max-loss': 334540.0}
'one14ahr2v4ut9fjswx2qa68r75zzmz9rq7fdg22an' : {'validator-address': 'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq', 'amount': 16630.0, 'epoch': 1680, 'maturity-epoch': 1688, 'max-loss': 731720.0}
'one1wupttflsngz3s9j6vqhmxq2yfrknqud3fh0dqd' : {'validator-address': 'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq', 'amount': 10150.0, 'epoch': 1683, 'maturity-epoch': 1691, 'max-loss': 416150.0}
'one1deescw460fec49e70z8a3fxkmh3gdckaj7ht5v' : {'validator-address': 'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq', 'amount': 660.6300000000001, 'epoch': 1724, 'maturity-epoch': 1732, 'max-loss': 0.0}
'one1nte43uzsr0rhd07sklp6hfxerhsjaywprwx3jw' : {'validator-address': 'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq', 'amount': 45.0, 'epoch': 1683, 'maturity-epoch': 1691, 'max-loss': 1845.0}
'one15s8pu2jlgnvu9dxf09z3ugnczg2zkz44dgu4hs' : {'validator-address': 'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq', 'amount': 15.1358774, 'epoch': 1684, 'maturity-epoch': 1692, 'max-loss': 605.435096}
'one1cy5jyyfe2rft0rhavlcj7jpk97tr6fr6wpxphx' : {'validator-address': 'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq', 'amount': 650.0, 'epoch': 1691, 'maturity-epoch': 1699, 'max-loss': 21450.0}
'one1nr25mye2630q8uwjh22laehl7hc5ja6hwsul60' : {'validator-address': 'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq', 'amount': 5524.935146, 'epoch': 1687, 'maturity-epoch': 1695, 'max-loss': 204422.60040199998}
'one1ca3gg53q8n8punl9yjrtzf4jjw2hz3lmxn2ccv' : {'validator-address': 'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq', 'amount': 2599.0420065000003, 'epoch': 1696, 'maturity-epoch': 1704, 'max-loss': 72773.17618200001}
'one1ca3gg53q8n8punl9yjrtzf4jjw2hz3lmxn2ccv' : {'validator-address': 'one1rxdtt9fvgdcy3n5sy6e4zxg0s4hn4shaqf4qtp', 'amount': 1007.896247, 'epoch': 1696, 'maturity-epoch': 1704, 'max-loss': 28221.094916000002}
'one1m4zfulx43jcwxfyqjnvdz6a3347taqh6r564ec' : {'validator-address': 'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq', 'amount': 10000.0, 'epoch': 1705, 'maturity-epoch': 1713, 'max-loss': 190000.0}
'one1hwxk85w66wt5udx6q89aaf5agm5g359455vw9h' : {'validator-address': 'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq', 'amount': 8935.0, 'epoch': 1721, 'maturity-epoch': 1729, 'max-loss': 26805.0}
'one1hwcnqd6wzkg0qsllfcn2uvczmyw9e6qtcw3gu9' : {'validator-address': 'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq', 'amount': 6351.0, 'epoch': 1719, 'maturity-epoch': 1727, 'max-loss': 31755.0}
'one1yp77tdlzzd4vqay4gczlr0t0d06q76r3fj9xqf' : {'validator-address': 'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq', 'amount': 10391.9807421, 'epoch': 1693, 'maturity-epoch': 1701, 'max-loss': 322151.40300510003}
'one1ayzdgkknxylhce0h6cdklnasyempyg4e27c8p0' : {'validator-address': 'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq', 'amount': 4540.0, 'epoch': 1713, 'maturity-epoch': 1721, 'max-loss': 49940.0}
'one10c3hwcyqfr27xk277rhuhxhv0hrcwnpakskc89' : {'validator-address': 'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq', 'amount': 0.000592, 'epoch': 1692, 'maturity-epoch': 1700, 'max-loss': 0.018944}
'one1958rkn62v5saegyufkpfl7r3ymjac4egnq5wac' : {'validator-address': 'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq', 'amount': 4.664e-05, 'epoch': 1688, 'maturity-epoch': 1696, 'max-loss': 0.0016790400000000001}
'one13fgzlk57kjn9u9fzxyt2cuessf3zq2d064gu55' : {'validator-address': 'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq', 'amount': 174.572278, 'epoch': 1712, 'maturity-epoch': 1720, 'max-loss': 2094.8673360000003}
'one1n969dd4pafq0xfmpzawq3p7nry3g6g2vauzdsr' : {'validator-address': 'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq', 'amount': 0.879273, 'epoch': 1681, 'maturity-epoch': 1689, 'max-loss': 37.808738999999996}
'one127s4m8h6dx6p4chz4d7s9wpwyx4yzph3c2v8ju' : {'validator-address': 'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq', 'amount': 3100.0, 'epoch': 1667, 'maturity-epoch': 1675, 'max-loss': 176700.0}
'one1ex8lws5wy7l2jeq0gsed7gh09c3fsl3ym36ude' : {'validator-address': 'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq', 'amount': 14102.0, 'epoch': 1699, 'maturity-epoch': 1707, 'max-loss': 352550.0}
'one1xa7d58udz6j5dr8y7j5sta8667hym3avpe4vvm' : {'validator-address': 'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq', 'amount': 4464.9703565, 'epoch': 1718, 'maturity-epoch': 1726, 'max-loss': 26789.822139}
'one125sfutf4r4u72dn4sr0fc9ag5wmlyfe0gcv8tq' : {'validator-address': 'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq', 'amount': 6081.3501264, 'epoch': 1722, 'maturity-epoch': 1730, 'max-loss': 12162.7002528}
'one198wag3t0dfy0nn57fhnrz0vs0degjwtsvyssj4' : {'validator-address': 'one132ggm0mgxdt4l8etud9e5gzpv8psgx30p7hxsq', 'amount': 3548.44, 'epoch': 1704, 'maturity-epoch': 1712, 'max-loss': 70968.8}
'one15g86zugpwg7n86pag75a0jk3xe46fjuydxmpa4' : {'validator-address': 'one1qv82h8dzjmm09tqwdwe3evjgmzz84fqmqskkzk', 'amount': 41.0, 'epoch': 1697, 'maturity-epoch': 1705, 'max-loss': 1107.0}
'one1gukv49ntzx2p4wfrzj33dh894rrgec6st4lxwp' : {'validator-address': 'one1qv82h8dzjmm09tqwdwe3evjgmzz84fqmqskkzk', 'amount': 31559.999999999996, 'epoch': 1721, 'maturity-epoch': 1729, 'max-loss': 94679.99999999999}
'one1dp2v0hgfutcagepp28av7v3k7p8xspe9qqxgez' : {'validator-address': 'one1qv82h8dzjmm09tqwdwe3evjgmzz84fqmqskkzk', 'amount': 11566.0, 'epoch': 1706, 'maturity-epoch': 1714, 'max-loss': 208188.0}
'one1rzj676wlcqkuj58h2d9wj7scpu6twht6qqvw54' : {'validator-address': 'one1qv82h8dzjmm09tqwdwe3evjgmzz84fqmqskkzk', 'amount': 1400000.0, 'epoch': 1711, 'maturity-epoch': 1719, 'max-loss': 18200000.0}
'one1rzj676wlcqkuj58h2d9wj7scpu6twht6qqvw54' : {'validator-address': 'one1qv82h8dzjmm09tqwdwe3evjgmzz84fqmqskkzk', 'amount': 3000000.0, 'epoch': 1713, 'maturity-epoch': 1721, 'max-loss': 33000000.0}
'one1uq03je2asmsllm3v0tvqe8v8farjk6ethkt9qp' : {'validator-address': 'one1qv82h8dzjmm09tqwdwe3evjgmzz84fqmqskkzk', 'amount': 5800.0, 'epoch': 1717, 'maturity-epoch': 1725, 'max-loss': 40600.0}
'one1y7wxexz67yjfv73jm2q6yvq6vxarngc46hgrvm' : {'validator-address': 'one1qv82h8dzjmm09tqwdwe3evjgmzz84fqmqskkzk', 'amount': 9000.0, 'epoch': 1693, 'maturity-epoch': 1701, 'max-loss': 279000.0}
'one1y7wxexz67yjfv73jm2q6yvq6vxarngc46hgrvm' : {'validator-address': 'one1xrtkrcpx7edw40zxpp26up939gc68u8hwepvnx', 'amount': 73000.0, 'epoch': 1693, 'maturity-epoch': 1701, 'max-loss': 2263000.0}
'one1lnyyvxy96ceux2a4lff5qlu3vqawmhwwy893gy' : {'validator-address': 'one1qv82h8dzjmm09tqwdwe3evjgmzz84fqmqskkzk', 'amount': 12775.0, 'epoch': 1724, 'maturity-epoch': 1732, 'max-loss': 0.0}
'one135fjlv8f72q0mxrmsq0hhmdjjz7t972lz69h0n' : {'validator-address': 'one1qv82h8dzjmm09tqwdwe3evjgmzz84fqmqskkzk', 'amount': 45680.588437022074, 'epoch': 1679, 'maturity-epoch': 1687, 'max-loss': 2055626.4796659932}
'one1593c36lmvhkwsrjzk8qj0f2d9vc7uqf53dcfuz' : {'validator-address': 'one1qv82h8dzjmm09tqwdwe3evjgmzz84fqmqskkzk', 'amount': 10627.184829, 'epoch': 1712, 'maturity-epoch': 1720, 'max-loss': 127526.217948}
'one1v8hj9r9fm7nfu07sqq8y8gla2gmug3hunk3fum' : {'validator-address': 'one1qv82h8dzjmm09tqwdwe3evjgmzz84fqmqskkzk', 'amount': 55750.0, 'epoch': 1684, 'maturity-epoch': 1692, 'max-loss': 2230000.0}
'one1j2gl3hjm2jgvamukhm97nsrzxcqkm5hjgp6zuv' : {'validator-address': 'one1qv82h8dzjmm09tqwdwe3evjgmzz84fqmqskkzk', 'amount': 900240.58401, 'epoch': 1704, 'maturity-epoch': 1712, 'max-loss': 18004811.6802}
'one1467ulp5s8jjl28mjqgrjnp0jm9u0e0htvrlrsv' : {'validator-address': 'one1qv82h8dzjmm09tqwdwe3evjgmzz84fqmqskkzk', 'amount': 12200.0, 'epoch': 1677, 'maturity-epoch': 1685, 'max-loss': 573400.0}
'one1467ulp5s8jjl28mjqgrjnp0jm9u0e0htvrlrsv' : {'validator-address': 'one1xrtkrcpx7edw40zxpp26up939gc68u8hwepvnx', 'amount': 6200.0, 'epoch': 1677, 'maturity-epoch': 1685, 'max-loss': 291400.0}
'one17pvy6ht2nkp0t5yvuaryklq05m9ehhtfz0tanc' : {'validator-address': 'one1qv82h8dzjmm09tqwdwe3evjgmzz84fqmqskkzk', 'amount': 1900.0, 'epoch': 1721, 'maturity-epoch': 1729, 'max-loss': 5700.0}
'one1g44sf2xlkkmv5x5uarwdxy0j228rwqz365zlv3' : {'validator-address': 'one1qv82h8dzjmm09tqwdwe3evjgmzz84fqmqskkzk', 'amount': 1800000.0, 'epoch': 1702, 'maturity-epoch': 1710, 'max-loss': 39600000.0}
'one1g44sf2xlkkmv5x5uarwdxy0j228rwqz365zlv3' : {'validator-address': 'one1rxdtt9fvgdcy3n5sy6e4zxg0s4hn4shaqf4qtp', 'amount': 4775.0, 'epoch': 1689, 'maturity-epoch': 1697, 'max-loss': 167125.0}
'one1jzl3yymvevrewrntlqlgrzpahpkg97hmxd0j88' : {'validator-address': 'one1qv82h8dzjmm09tqwdwe3evjgmzz84fqmqskkzk', 'amount': 6006.000000000001, 'epoch': 1694, 'maturity-epoch': 1702, 'max-loss': 180180.00000000003}
'one10f7cjygrt90pt065wsr3z0ay8cgrdxrg4px4rk' : {'validator-address': 'one1qv82h8dzjmm09tqwdwe3evjgmzz84fqmqskkzk', 'amount': 1.0, 'epoch': 1709, 'maturity-epoch': 1717, 'max-loss': 15.0}
'one1rxdtt9fvgdcy3n5sy6e4zxg0s4hn4shaqf4qtp' : {'validator-address': 'one1rxdtt9fvgdcy3n5sy6e4zxg0s4hn4shaqf4qtp', 'amount': 13100.000000000002, 'epoch': 1694, 'maturity-epoch': 1702, 'max-loss': 393000.00000000006}
'one1luq9z3l0fg8gxk8wzd37yhrrcx3fmd3tcfs48h' : {'validator-address': 'one1rxdtt9fvgdcy3n5sy6e4zxg0s4hn4shaqf4qtp', 'amount': 7600.0, 'epoch': 1694, 'maturity-epoch': 1702, 'max-loss': 228000.0}
'one1ymcnvsrm8a6jd598l0n3jqjf0nfgrycdndut0k' : {'validator-address': 'one1rxdtt9fvgdcy3n5sy6e4zxg0s4hn4shaqf4qtp', 'amount': 1982.0, 'epoch': 1694, 'maturity-epoch': 1702, 'max-loss': 59460.0}
'one14gn8krn0qakek4psfgxsyy48qx4y4appuxpt48' : {'validator-address': 'one1rxdtt9fvgdcy3n5sy6e4zxg0s4hn4shaqf4qtp', 'amount': 9975.0, 'epoch': 1675, 'maturity-epoch': 1683, 'max-loss': 488775.0}
'one1459uca74wc2e6zxc8eyvm2n6cs3aexhk5hundm' : {'validator-address': 'one1rxdtt9fvgdcy3n5sy6e4zxg0s4hn4shaqf4qtp', 'amount': 1000.0, 'epoch': 1721, 'maturity-epoch': 1729, 'max-loss': 3000.0}
'one1whtcu6xnmrzw2jqd2pjc26u8hx33w5j628vpnj' : {'validator-address': 'one1rxdtt9fvgdcy3n5sy6e4zxg0s4hn4shaqf4qtp', 'amount': 157.0, 'epoch': 1675, 'maturity-epoch': 1683, 'max-loss': 7693.0}
'one10jfp29j49elw5zxq99qrd0xk6q2zq5pzty6hkq' : {'validator-address': 'one1rxdtt9fvgdcy3n5sy6e4zxg0s4hn4shaqf4qtp', 'amount': 2303.2297817999997, 'epoch': 1721, 'maturity-epoch': 1729, 'max-loss': 6909.689345399999}
'one1p5zpmgy7cdls3nqnnfezhx0h602plf0kv2ylkt' : {'validator-address': 'one1rxdtt9fvgdcy3n5sy6e4zxg0s4hn4shaqf4qtp', 'amount': 2000.0, 'epoch': 1700, 'maturity-epoch': 1708, 'max-loss': 48000.0}
'one1daqq3k8fm2z4zm0g9ke9elhsrp2jgrma07a49d' : {'validator-address': 'one1rxdtt9fvgdcy3n5sy6e4zxg0s4hn4shaqf4qtp', 'amount': 1576.0, 'epoch': 1711, 'maturity-epoch': 1719, 'max-loss': 20488.0}
'one10d3qqqxegdexjyzvyewa5krhgkcgl57xs6y9gm' : {'validator-address': 'one1rxdtt9fvgdcy3n5sy6e4zxg0s4hn4shaqf4qtp', 'amount': 292032.89880100003, 'epoch': 1712, 'maturity-epoch': 1720, 'max-loss': 3504394.785612}
'one1gtm05wkdm25srn7zpvfmgfs765nawyl7tm3n5a' : {'validator-address': 'one1xrtkrcpx7edw40zxpp26up939gc68u8hwepvnx', 'amount': 1e-13, 'epoch': 1698, 'maturity-epoch': 1706, 'max-loss': 2.6000000000000002e-12}
'one1ydljrztmu0dxlwavus4henup0e3y526vljhhut' : {'validator-address': 'one1xrtkrcpx7edw40zxpp26up939gc68u8hwepvnx', 'amount': 21520.0, 'epoch': 1722, 'maturity-epoch': 1730, 'max-loss': 43040.0}
'one1jgclstnfnya0hq97kc234g8xjtzfnet83jyjng' : {'validator-address': 'one1xrtkrcpx7edw40zxpp26up939gc68u8hwepvnx', 'amount': 5425.999999999999, 'epoch': 1723, 'maturity-epoch': 1731, 'max-loss': 5425.999999999999}
'one1qgz640f2klk0y9rww6j26t3t6ruxkqera9ugpt' : {'validator-address': 'one1xrtkrcpx7edw40zxpp26up939gc68u8hwepvnx', 'amount': 110000.0, 'epoch': 1690, 'maturity-epoch': 1698, 'max-loss': 3740000.0}
'one1ltdxgdnwm39utvvdcuxcpnpjc2k7539pxe4rut' : {'validator-address': 'one1xrtkrcpx7edw40zxpp26up939gc68u8hwepvnx', 'amount': 1510.0, 'epoch': 1682, 'maturity-epoch': 1690, 'max-loss': 63420.0}
'one14lguy2xurkank0sj7he6zsu0yglzu6mp6s57xn' : {'validator-address': 'one1xrtkrcpx7edw40zxpp26up939gc68u8hwepvnx', 'amount': 66700.0, 'epoch': 1705, 'maturity-epoch': 1713, 'max-loss': 1267300.0}
'one1y7lkm3nr292hcjcczwqakhs56uwx4drsjrcn6q' : {'validator-address': 'one1xrtkrcpx7edw40zxpp26up939gc68u8hwepvnx', 'amount': 16175.0, 'epoch': 1708, 'maturity-epoch': 1716, 'max-loss': 258800.0}
'one162ya6spps6s8zhnt67pllraaf9f3qz9gzku8hn' : {'validator-address': 'one1xrtkrcpx7edw40zxpp26up939gc68u8hwepvnx', 'amount': 420.0, 'epoch': 1666, 'maturity-epoch': 1674, 'max-loss': 24360.0}
'one1wg4ls662ahw7nwjc6fwmclmfjpjceff4he0rzc' : {'validator-address': 'one1xrtkrcpx7edw40zxpp26up939gc68u8hwepvnx', 'amount': 500.0, 'epoch': 1705, 'maturity-epoch': 1713, 'max-loss': 9500.0}
'one1zp6zfmkzhv997fy2ygu8ekd4n4v64z98wezz8e' : {'validator-address': 'one1xrtkrcpx7edw40zxpp26up939gc68u8hwepvnx', 'amount': 300.1, 'epoch': 1670, 'maturity-epoch': 1678, 'max-loss': 16205.400000000001}
'one1j0c7se5yn3cqjcn7cjqter5fwer0kqvhasrswr' : {'validator-address': 'one1xrtkrcpx7edw40zxpp26up939gc68u8hwepvnx', 'amount': 10000.0, 'epoch': 1677, 'maturity-epoch': 1685, 'max-loss': 470000.0}
'one1wk8arta8v5r3nmycz2g40h68yea8rjqg0s0n6s' : {'validator-address': 'one1xrtkrcpx7edw40zxpp26up939gc68u8hwepvnx', 'amount': 250000.0, 'epoch': 1684, 'maturity-epoch': 1692, 'max-loss': 10000000.0}
'one1rz3lpwfd4za6sqjky4ackvkwhfyxmyhdfn5l2r' : {'validator-address': 'one1xrtkrcpx7edw40zxpp26up939gc68u8hwepvnx', 'amount': 2200.0, 'epoch': 1717, 'maturity-epoch': 1725, 'max-loss': 15400.0}
'one12n23j0g3m3rccdngyfzledw87s26at9g5lfjes' : {'validator-address': 'one1xrtkrcpx7edw40zxpp26up939gc68u8hwepvnx', 'amount': 144431.0, 'epoch': 1721, 'maturity-epoch': 1729, 'max-loss': 433293.0}
'one12n23j0g3m3rccdngyfzledw87s26at9g5lfjes' : {'validator-address': 'one1xrtkrcpx7edw40zxpp26up939gc68u8hwepvnx', 'amount': 500000.0, 'epoch': 1722, 'maturity-epoch': 1730, 'max-loss': 1000000.0}
'one14p7vhuka533g20nqjw3kwz0kxky2cnh9v72lcm' : {'validator-address': 'one1xrtkrcpx7edw40zxpp26up939gc68u8hwepvnx', 'amount': 400.0, 'epoch': 1682, 'maturity-epoch': 1690, 'max-loss': 16800.0}
[{'validator-address': 'one1qv82h8dzjmm09tqwdwe3evjgmzz84fqmqskkzk', 'amount': 1400000.0, 'epoch': 1711, 'maturity-epoch': 1719, 'max-loss': 18200000.0}, {'validator-address': 'one1qv82h8dzjmm09tqwdwe3evjgmzz84fqmqskkzk', 'amount': 3000000.0, 'epoch': 1713, 'maturity-epoch': 1721, 'max-loss': 33000000.0}]
Summary:
{'max-loss': 146.27999561211874, 'max-loss-excluding-aaron': 95.07999561211875, 'max-loss-aaron': 51.2}