|
8 | 8 |
|
9 | 9 | pragma solidity 0.8.24;
|
10 | 10 |
|
11 |
| -import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; |
12 |
| - |
13 | 11 | import "../KlerosCore.sol";
|
14 | 12 | import "../interfaces/IDisputeKit.sol";
|
15 | 13 | import "../../proxy/UUPSProxiable.sol";
|
16 | 14 | import "../../proxy/Initializable.sol";
|
17 | 15 |
|
18 |
| -interface IToken { |
| 16 | +interface IERC20OrERC721 { |
19 | 17 | /// @dev Returns the number of tokens in `owner` account.
|
20 | 18 | /// @param owner The address of the owner.
|
21 | 19 | /// @return balance The number of tokens in `owner` account.
|
22 | 20 | function balanceOf(address owner) external view returns (uint256 balance);
|
23 | 21 | }
|
24 | 22 |
|
| 23 | +interface IERC1155 { |
| 24 | + /// @dev Returns the balance of an ERC-1155 token. |
| 25 | + /// @param account The address of the token holder |
| 26 | + /// @param id ID of the token |
| 27 | + /// @return The token balance |
| 28 | + function balanceOf(address account, uint256 id) external view returns (uint256); |
| 29 | +} |
| 30 | + |
25 | 31 | /// @title DisputeKitGated
|
26 | 32 | /// Dispute kit implementation adapted from DisputeKitClassic
|
27 |
| -/// - a drawing system: proportional to staked PNK with a non-zero balance of `tokenGate`, |
| 33 | +/// - a drawing system: proportional to staked PNK with a non-zero balance of `tokenGate` where `tokenGate` is an ERC20, ERC721 or ERC1155 |
28 | 34 | /// - a vote aggregation system: plurality,
|
29 | 35 | /// - an incentive system: equal split between coherent votes,
|
30 | 36 | /// - an appeal system: fund 2 choices only, vote on any choice.
|
@@ -76,7 +82,9 @@ contract DisputeKitGated is IDisputeKit, Initializable, UUPSProxiable {
|
76 | 82 | KlerosCore public core; // The Kleros Core arbitrator
|
77 | 83 | Dispute[] public disputes; // Array of the locally created disputes.
|
78 | 84 | mapping(uint256 => uint256) public coreDisputeIDToLocal; // Maps the dispute ID in Kleros Core to the local dispute ID.
|
79 |
| - IToken public tokenGate; // The token used for gating access. |
| 85 | + address public tokenGate; // The token used for gating access. |
| 86 | + uint256 public tokenId; // Only used for ERC-1155 |
| 87 | + bool public isERC1155; // True if the tokenGate is an ERC-1155, false otherwise. |
80 | 88 |
|
81 | 89 | // ************************************* //
|
82 | 90 | // * Events * //
|
@@ -161,10 +169,20 @@ contract DisputeKitGated is IDisputeKit, Initializable, UUPSProxiable {
|
161 | 169 | /// @param _governor The governor's address.
|
162 | 170 | /// @param _core The KlerosCore arbitrator.
|
163 | 171 | /// @param _tokenGate The token used for gating access.
|
164 |
| - function initialize(address _governor, KlerosCore _core, IToken _tokenGate) external reinitializer(1) { |
| 172 | + /// @param _tokenId The token ID for ERC-1155 (ignored for other token types) |
| 173 | + /// @param _isERC1155 Whether the token is ERC-1155 |
| 174 | + function initialize( |
| 175 | + address _governor, |
| 176 | + KlerosCore _core, |
| 177 | + address _tokenGate, |
| 178 | + uint256 _tokenId, |
| 179 | + bool _isERC1155 |
| 180 | + ) external reinitializer(1) { |
165 | 181 | governor = _governor;
|
166 | 182 | core = _core;
|
167 | 183 | tokenGate = _tokenGate;
|
| 184 | + tokenId = _tokenId; |
| 185 | + isERC1155 = _isERC1155; |
168 | 186 | }
|
169 | 187 |
|
170 | 188 | // ************************ //
|
@@ -202,10 +220,20 @@ contract DisputeKitGated is IDisputeKit, Initializable, UUPSProxiable {
|
202 | 220 | core = KlerosCore(_core);
|
203 | 221 | }
|
204 | 222 |
|
205 |
| - /// @dev Changes the `tokenGate` storage variable. |
| 223 | + /// @dev Changes the `tokenGate` to an ERC-20 or ERC-721 token. |
206 | 224 | /// @param _tokenGate The new value for the `tokenGate` storage variable.
|
207 |
| - function changeTokenGate(address _tokenGate) external onlyByGovernor { |
208 |
| - tokenGate = IToken(_tokenGate); |
| 225 | + function changeTokenGateERC20OrERC721(address _tokenGate) external onlyByGovernor { |
| 226 | + tokenGate = _tokenGate; |
| 227 | + isERC1155 = false; |
| 228 | + } |
| 229 | + |
| 230 | + /// @dev Changes the `tokenGate` to an ERC-1155 token. |
| 231 | + /// @param _tokenGate The new value for the `tokenGate` storage variable. |
| 232 | + /// @param _tokenId The new value for the `tokenId` storage variable. |
| 233 | + function changeTokenGateERC1155(address _tokenGate, uint256 _tokenId) external onlyByGovernor { |
| 234 | + tokenGate = _tokenGate; |
| 235 | + tokenId = _tokenId; |
| 236 | + isERC1155 = true; |
209 | 237 | }
|
210 | 238 |
|
211 | 239 | // ************************************* //
|
@@ -630,10 +658,12 @@ contract DisputeKitGated is IDisputeKit, Initializable, UUPSProxiable {
|
630 | 658 | .getRoundInfo(_coreDisputeID, core.getNumberOfRounds(_coreDisputeID) - 1)
|
631 | 659 | .pnkAtStakePerJuror;
|
632 | 660 | (uint256 totalStaked, uint256 totalLocked, , ) = core.sortitionModule().getJurorBalance(_juror, courtID);
|
633 |
| - if (totalStaked < totalLocked + lockedAmountPerJuror) { |
634 |
| - return false; |
| 661 | + if (totalStaked < totalLocked + lockedAmountPerJuror) return false; |
| 662 | + |
| 663 | + if (isERC1155) { |
| 664 | + return IERC1155(tokenGate).balanceOf(_juror, tokenId) > 0; |
635 | 665 | } else {
|
636 |
| - return tokenGate.balanceOf(_juror) > 0; |
| 666 | + return IERC20OrERC721(tokenGate).balanceOf(_juror) > 0; |
637 | 667 | }
|
638 | 668 | }
|
639 | 669 | }
|
0 commit comments