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