1+ // SPDX-License-Identifier: MIT
2+
3+ /// @custom:authors: [@unknownunknown1, @mtsalenc*]
4+ /// @custom:reviewers: []
5+ /// @custom:auditors: []
6+ /// @custom:bounties: []
7+ /// @custom:deployments: []
8+
9+ pragma solidity 0.8.18 ;
10+
11+ import {Curate, IArbitratorV2} from "./CurateV2.sol " ;
12+
13+ /// @title CurateView
14+ /// A view contract to fetch, batch, parse and return Curate contract data efficiently.
15+ /// This contract includes functions that can halt execution due to out-of-gas exceptions. Because of this it should never be relied upon by other contracts.
16+ contract CurateView {
17+ struct QueryResult {
18+ bytes32 ID;
19+ Curate.Status status;
20+ bool disputed;
21+ bool resolved;
22+ uint256 disputeID;
23+ Curate.Party ruling;
24+ address requester;
25+ address challenger;
26+ address arbitrator;
27+ bytes arbitratorExtraData;
28+ uint256 submissionTime;
29+ uint256 numberOfRequests;
30+ }
31+
32+ struct ArbitrableData {
33+ address governor;
34+ address arbitrator;
35+ bytes arbitratorExtraData;
36+ address relayerContract;
37+ uint256 submissionBaseDeposit;
38+ uint256 removalBaseDeposit;
39+ uint256 submissionChallengeBaseDeposit;
40+ uint256 removalChallengeBaseDeposit;
41+ uint256 challengePeriodDuration;
42+ address templateRegistry;
43+ uint256 templateIdRegistration;
44+ uint256 templateIdRemoval;
45+ uint256 arbitrationCost;
46+ }
47+
48+ /// @dev Fetch Curate storage in a single call.
49+ /// @param _address The address of the Curate contract to query.
50+ /// @return result The latest storage data.
51+ function fetchArbitrable (address _address ) external view returns (ArbitrableData memory result ) {
52+ Curate curate = Curate (_address);
53+ result.governor = curate.governor ();
54+ result.arbitrator = address (curate.getArbitrator ());
55+ result.arbitratorExtraData = curate.getArbitratorExtraData ();
56+ result.relayerContract = curate.relayerContract ();
57+ result.submissionBaseDeposit = curate.submissionBaseDeposit ();
58+ result.removalBaseDeposit = curate.removalBaseDeposit ();
59+ result.submissionChallengeBaseDeposit = curate.submissionChallengeBaseDeposit ();
60+ result.removalChallengeBaseDeposit = curate.removalChallengeBaseDeposit ();
61+ result.challengePeriodDuration = curate.challengePeriodDuration ();
62+ result.templateRegistry = address (curate.templateRegistry ());
63+ result.templateIdRegistration = curate.templateIdRegistration ();
64+ result.templateIdRemoval = curate.templateIdRemoval ();
65+ result.arbitrationCost = IArbitratorV2 (result.arbitrator).arbitrationCost (result.arbitratorExtraData);
66+ }
67+
68+ /// @dev Fetch the latest data on an item in a single call.
69+ /// @param _address The address of the Curate contract to query.
70+ /// @param _itemID The ID of the item to query.
71+ /// @return result The item data.
72+ function getItem (address _address , bytes32 _itemID ) public view returns (QueryResult memory result ) {
73+ RequestData memory request = getLatestRequestData (_address, _itemID);
74+ result = QueryResult ({
75+ ID: _itemID,
76+ status: request.item.status,
77+ disputed: request.disputed,
78+ resolved: request.resolved,
79+ disputeID: request.disputeID,
80+ ruling: request.ruling,
81+ requester: request.parties[uint256 (Curate.Party.Requester)],
82+ challenger: request.parties[uint256 (Curate.Party.Challenger)],
83+ arbitrator: address (request.arbitrator),
84+ arbitratorExtraData: request.arbitratorExtraData,
85+ submissionTime: request.submissionTime,
86+ numberOfRequests: request.item.numberOfRequests
87+ });
88+ }
89+
90+ struct ItemRequest {
91+ bool disputed;
92+ uint256 disputeID;
93+ uint256 submissionTime;
94+ bool resolved;
95+ address requester;
96+ address challenger;
97+ address arbitrator;
98+ bytes arbitratorExtraData;
99+ }
100+
101+ /// @dev Fetch all requests for an item.
102+ /// @param _address The address of the Curate contract to query.
103+ /// @param _itemID The ID of the item to query.
104+ /// @return requests The items requests.
105+ function getItemRequests (address _address , bytes32 _itemID ) external view returns (ItemRequest[] memory requests ) {
106+ Curate curate = Curate (_address);
107+ ItemData memory itemData = getItemData (_address, _itemID);
108+ requests = new ItemRequest [](itemData.numberOfRequests);
109+ for (uint256 i = 0 ; i < itemData.numberOfRequests; i++ ) {
110+ (
111+ bool disputed ,
112+ uint256 disputeID ,
113+ uint256 submissionTime ,
114+ bool resolved ,
115+ address payable [3 ] memory parties ,
116+ ,
117+ IArbitratorV2 arbitrator ,
118+ bytes memory arbitratorExtraData
119+ ) = curate.getRequestInfo (_itemID, i);
120+
121+ // Sort requests by newest first.
122+ requests[itemData.numberOfRequests - i - 1 ] = ItemRequest ({
123+ disputed: disputed,
124+ disputeID: disputeID,
125+ submissionTime: submissionTime,
126+ resolved: resolved,
127+ requester: parties[uint256 (Curate.Party.Requester)],
128+ challenger: parties[uint256 (Curate.Party.Challenger)],
129+ arbitrator: address (arbitrator),
130+ arbitratorExtraData: arbitratorExtraData
131+ });
132+ }
133+ }
134+
135+ // Functions and structs below used mainly to avoid stack limit.
136+ struct ItemData {
137+ Curate.Status status;
138+ uint256 numberOfRequests;
139+ }
140+
141+ struct RequestData {
142+ ItemData item;
143+ bool disputed;
144+ uint256 disputeID;
145+ uint256 submissionTime;
146+ bool resolved;
147+ address payable [3 ] parties;
148+ Curate.Party ruling;
149+ IArbitratorV2 arbitrator;
150+ bytes arbitratorExtraData;
151+ }
152+
153+ /// @dev Fetch data of the an item and return a struct.
154+ /// @param _address The address of the Curate contract to query.
155+ /// @param _itemID The ID of the item to query.
156+ /// @return item The item data.
157+ function getItemData (address _address , bytes32 _itemID ) public view returns (ItemData memory item ) {
158+ Curate curate = Curate (_address);
159+ (Curate.Status status , uint256 numberOfRequests , ) = curate.getItemInfo (_itemID);
160+ item = ItemData (status, numberOfRequests);
161+ }
162+
163+ /// @dev Fetch the latest request of an item.
164+ /// @param _address The address of the Curate contract to query.
165+ /// @param _itemID The ID of the item to query.
166+ /// @return request The request data.
167+ function getLatestRequestData (address _address , bytes32 _itemID ) public view returns (RequestData memory request ) {
168+ Curate curate = Curate (_address);
169+ ItemData memory item = getItemData (_address, _itemID);
170+ (
171+ bool disputed ,
172+ uint256 disputeID ,
173+ uint256 submissionTime ,
174+ bool resolved ,
175+ address payable [3 ] memory parties ,
176+ Curate.Party ruling ,
177+ IArbitratorV2 arbitrator ,
178+ bytes memory arbitratorExtraData
179+ ) = curate.getRequestInfo (_itemID, item.numberOfRequests - 1 );
180+ request = RequestData (
181+ item,
182+ disputed,
183+ disputeID,
184+ submissionTime,
185+ resolved,
186+ parties,
187+ ruling,
188+ arbitrator,
189+ arbitratorExtraData
190+ );
191+ }
192+ }
0 commit comments