// SPDX-License-Identifier: MIT pragma solidity 0.6.11; pragma experimental ABIEncoderV2; import "./TroveManager.sol"; import "./SortedTroves.sol"; /* Helper contract for grabbing Trove data for the front end. Not part of the core Liquity system. */ contract MultiTroveGetter { struct CombinedTroveData { address owner; uint debt; uint coll; uint stake; uint snapshotETH; uint snapshotLUSDDebt; } TroveManager public troveManager; // XXX Troves missing from ITroveManager? ISortedTroves public sortedTroves; constructor(TroveManager _troveManager, ISortedTroves _sortedTroves) public { troveManager = _troveManager; sortedTroves = _sortedTroves; } function getMultipleSortedTroves(int _startIdx, uint _count) external view returns (CombinedTroveData[] memory _troves) { uint startIdx; bool descend; if (_startIdx >= 0) { startIdx = uint(_startIdx); descend = true; } else { startIdx = uint(-(_startIdx + 1)); descend = false; } uint sortedTrovesSize = sortedTroves.getSize(); if (startIdx >= sortedTrovesSize) { _troves = new CombinedTroveData[](0); } else { uint maxCount = sortedTrovesSize - startIdx; if (_count > maxCount) { _count = maxCount; } if (descend) { _troves = _getMultipleSortedTrovesFromHead(startIdx, _count); } else { _troves = _getMultipleSortedTrovesFromTail(startIdx, _count); } } } function _getMultipleSortedTrovesFromHead(uint _startIdx, uint _count) internal view returns (CombinedTroveData[] memory _troves) { address currentTroveowner = sortedTroves.getFirst(); for (uint idx = 0; idx < _startIdx; ++idx) { currentTroveowner = sortedTroves.getNext(currentTroveowner); } _troves = new CombinedTroveData[](_count); for (uint idx = 0; idx < _count; ++idx) { _troves[idx].owner = currentTroveowner; ( _troves[idx].debt, _troves[idx].coll, _troves[idx].stake, /* status */, /* arrayIndex */ ) = troveManager.Troves(currentTroveowner); ( _troves[idx].snapshotETH, _troves[idx].snapshotLUSDDebt ) = troveManager.rewardSnapshots(currentTroveowner); currentTroveowner = sortedTroves.getNext(currentTroveowner); } } function _getMultipleSortedTrovesFromTail(uint _startIdx, uint _count) internal view returns (CombinedTroveData[] memory _troves) { address currentTroveowner = sortedTroves.getLast(); for (uint idx = 0; idx < _startIdx; ++idx) { currentTroveowner = sortedTroves.getPrev(currentTroveowner); } _troves = new CombinedTroveData[](_count); for (uint idx = 0; idx < _count; ++idx) { _troves[idx].owner = currentTroveowner; ( _troves[idx].debt, _troves[idx].coll, _troves[idx].stake, /* status */, /* arrayIndex */ ) = troveManager.Troves(currentTroveowner); ( _troves[idx].snapshotETH, _troves[idx].snapshotLUSDDebt ) = troveManager.rewardSnapshots(currentTroveowner); currentTroveowner = sortedTroves.getPrev(currentTroveowner); } } }