// SPDX-License-Identifier: MIT pragma solidity 0.6.11; pragma experimental ABIEncoderV2; import "./TroveManager.sol"; import "./SortedTroves.sol"; import "./MultiTroveGetterStorage.sol"; /** Helper contract for grabbing Trove data for the front end. Not part of the core Zero system. */ contract MultiTroveGetter is MultiTroveGetterStorage { struct CombinedTroveData { address owner; uint256 debt; uint256 coll; uint256 stake; uint256 snapshotETH; uint256 snapshotZUSDDebt; } function setAddresses(TroveManager _troveManager, ISortedTroves _sortedTroves) public onlyOwner { troveManager = _troveManager; sortedTroves = _sortedTroves; } function getMultipleSortedTroves(int256 _startIdx, uint256 _count) external view returns (CombinedTroveData[] memory _troves) { uint256 startIdx; bool descend; if (_startIdx >= 0) { startIdx = uint256(_startIdx); descend = true; } else { startIdx = uint256(-(_startIdx + 1)); descend = false; } uint256 sortedTrovesSize = sortedTroves.getSize(); if (startIdx >= sortedTrovesSize) { _troves = new CombinedTroveData[](0); } else { uint256 maxCount = sortedTrovesSize - startIdx; if (_count > maxCount) { _count = maxCount; } if (descend) { _troves = _getMultipleSortedTrovesFromHead(startIdx, _count); } else { _troves = _getMultipleSortedTrovesFromTail(startIdx, _count); } } } function _getMultipleSortedTrovesFromHead(uint256 _startIdx, uint256 _count) internal view returns (CombinedTroveData[] memory _troves) { address currentTroveowner = sortedTroves.getFirst(); for (uint256 idx = 0; idx < _startIdx; ++idx) { currentTroveowner = sortedTroves.getNext(currentTroveowner); } _troves = new CombinedTroveData[](_count); for (uint256 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].snapshotZUSDDebt) = troveManager .rewardSnapshots(currentTroveowner); currentTroveowner = sortedTroves.getNext(currentTroveowner); } } function _getMultipleSortedTrovesFromTail(uint256 _startIdx, uint256 _count) internal view returns (CombinedTroveData[] memory _troves) { address currentTroveowner = sortedTroves.getLast(); for (uint256 idx = 0; idx < _startIdx; ++idx) { currentTroveowner = sortedTroves.getPrev(currentTroveowner); } _troves = new CombinedTroveData[](_count); for (uint256 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].snapshotZUSDDebt) = troveManager .rewardSnapshots(currentTroveowner); currentTroveowner = sortedTroves.getPrev(currentTroveowner); } } }