Skip to content

Commit 22b10fa

Browse files
feat(Curate): add view contract
1 parent 4ee0bf8 commit 22b10fa

File tree

2 files changed

+193
-0
lines changed

2 files changed

+193
-0
lines changed

contracts/src/CurateV2.sol

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ contract Curate is IArbitrableV2 {
5656
address payable requester; // Address of the requester.
5757
// Pack the requester together with the other parameters, as they are written in the same request.
5858
address payable challenger; // Address of the challenger, if any.
59+
// TODO: store templateRegistry in case it's changed?
5960
}
6061

6162
struct DisputeData {

contracts/src/CurateView.sol

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
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

Comments
 (0)