Skip to content

Commit ec8fb28

Browse files
committed
Add revert requirement for Attribute Registry implementations
1 parent 7bfcc59 commit ec8fb28

File tree

5 files changed

+74
-6
lines changed

5 files changed

+74
-6
lines changed

contracts/AttributeRegistryInterface.sol

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
pragma solidity ^0.4.25;
22

3-
43
/**
54
* @title Attribute Registry interface. EIP-165 ID: 0x5f46473f
65
*/
76
interface AttributeRegistryInterface {
87
/**
98
* @notice Check if an attribute of the type with ID `attributeTypeID` has
10-
* been assigned to the account at `account` and is still valid.
9+
* been assigned to the account at `account` and is currently valid.
1110
* @param account address The account to check for a valid attribute.
1211
* @param attributeTypeID uint256 The ID of the attribute type to check for.
1312
* @return True if the attribute is assigned and valid, false otherwise.
13+
* @dev This function MUST return either true or false - i.e. calling this
14+
* function MUST NOT cause the caller to revert.
1415
*/
1516
function hasAttribute(
1617
address account,
@@ -23,6 +24,9 @@ interface AttributeRegistryInterface {
2324
* @param account address The account to check for the given attribute value.
2425
* @param attributeTypeID uint256 The ID of the attribute type to check for.
2526
* @return The attribute value if the attribute is valid, reverts otherwise.
27+
* @dev This function MUST revert if a directly preceding or subsequent
28+
* function call to `hasAttribute` with identical `account` and
29+
* `attributeTypeID` parameters would return false.
2630
*/
2731
function getAttributeValue(
2832
address account,
@@ -32,13 +36,19 @@ interface AttributeRegistryInterface {
3236
/**
3337
* @notice Count the number of attribute types defined by the registry.
3438
* @return The number of available attribute types.
39+
* @dev This function MUST return a positive integer value - i.e. calling
40+
* this function MUST NOT cause the caller to revert.
3541
*/
3642
function countAttributeTypes() external view returns (uint256);
3743

3844
/**
3945
* @notice Get the ID of the attribute type at index `index`.
4046
* @param index uint256 The index of the attribute type in question.
4147
* @return The ID of the attribute type.
48+
* @dev This function MUST revert if the provided `index` value falls outside
49+
* of the range of the value returned from a directly preceding or subsequent
50+
* function call to `countAttributeTypes`. It MUST NOT revert if the provided
51+
* `index` value falls inside said range.
4252
*/
4353
function getAttributeTypeID(uint256 index) external view returns (uint256);
4454
}

contracts/BasicJurisdiction.sol

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -398,10 +398,12 @@ contract BasicJurisdiction is Ownable, Pausable, AttributeRegistryInterface, Bas
398398

399399
/**
400400
* @notice Check if an attribute of the type with ID `attributeTypeID` has
401-
* been assigned to the account at `account` and is still valid.
401+
* been assigned to the account at `account` and is currently valid.
402402
* @param account address The account to check for a valid attribute.
403403
* @param attributeTypeID uint256 The ID of the attribute type to check for.
404404
* @return True if the attribute is assigned and valid, false otherwise.
405+
* @dev This function MUST return either true or false - i.e. calling this
406+
* function MUST NOT cause the caller to revert.
405407
*/
406408
function hasAttribute(
407409
address account,
@@ -421,6 +423,9 @@ contract BasicJurisdiction is Ownable, Pausable, AttributeRegistryInterface, Bas
421423
* @param account address The account to check for the given attribute value.
422424
* @param attributeTypeID uint256 The ID of the attribute type to check for.
423425
* @return The attribute value if the attribute is valid, reverts otherwise.
426+
* @dev This function MUST revert if a directly preceding or subsequent
427+
* function call to `hasAttribute` with identical `account` and
428+
* `attributeTypeID` parameters would return false.
424429
*/
425430
function getAttributeValue(
426431
address account,
@@ -503,8 +508,10 @@ contract BasicJurisdiction is Ownable, Pausable, AttributeRegistryInterface, Bas
503508
}
504509

505510
/**
506-
* @notice Count the number of attribute types defined by the jurisdiction.
511+
* @notice Count the number of attribute types defined by the registry.
507512
* @return The number of available attribute types.
513+
* @dev This function MUST return a positive integer value - i.e. calling
514+
* this function MUST NOT cause the caller to revert.
508515
*/
509516
function countAttributeTypes() external view returns (uint256) {
510517
return _attributeIDs.length;
@@ -514,8 +521,17 @@ contract BasicJurisdiction is Ownable, Pausable, AttributeRegistryInterface, Bas
514521
* @notice Get the ID of the attribute type at index `index`.
515522
* @param index uint256 The index of the attribute type in question.
516523
* @return The ID of the attribute type.
524+
* @dev This function MUST revert if the provided `index` value falls outside
525+
* of the range of the value returned from a directly preceding or subsequent
526+
* function call to `countAttributeTypes`. It MUST NOT revert if the provided
527+
* `index` value falls inside said range.
517528
*/
518529
function getAttributeTypeID(uint256 index) external view returns (uint256) {
530+
require(
531+
index < _attributeIDs.length,
532+
"provided index is outside of the range of defined attribute type IDs"
533+
);
534+
519535
return _attributeIDs[index];
520536
}
521537

contracts/ExtendedJurisdiction.sol

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,10 +1071,12 @@ contract ExtendedJurisdiction is Ownable, Pausable, AttributeRegistryInterface,
10711071

10721072
/**
10731073
* @notice Check if an attribute of the type with ID `attributeTypeID` has
1074-
* been assigned to the account at `account` and is still valid.
1074+
* been assigned to the account at `account` and is currently valid.
10751075
* @param account address The account to check for a valid attribute.
10761076
* @param attributeTypeID uint256 The ID of the attribute type to check for.
10771077
* @return True if the attribute is assigned and valid, false otherwise.
1078+
* @dev This function MUST return either true or false - i.e. calling this
1079+
* function MUST NOT cause the caller to revert.
10781080
*/
10791081
function hasAttribute(
10801082
address account,
@@ -1103,6 +1105,9 @@ contract ExtendedJurisdiction is Ownable, Pausable, AttributeRegistryInterface,
11031105
* @param account address The account to check for the given attribute value.
11041106
* @param attributeTypeID uint256 The ID of the attribute type to check for.
11051107
* @return The attribute value if the attribute is valid, reverts otherwise.
1108+
* @dev This function MUST revert if a directly preceding or subsequent
1109+
* function call to `hasAttribute` with identical `account` and
1110+
* `attributeTypeID` parameters would return false.
11061111
*/
11071112
function getAttributeValue(
11081113
address account,
@@ -1247,8 +1252,10 @@ contract ExtendedJurisdiction is Ownable, Pausable, AttributeRegistryInterface,
12471252
}
12481253

12491254
/**
1250-
* @notice Count the number of attribute types defined by the jurisdiction.
1255+
* @notice Count the number of attribute types defined by the registry.
12511256
* @return The number of available attribute types.
1257+
* @dev This function MUST return a positive integer value - i.e. calling
1258+
* this function MUST NOT cause the caller to revert.
12521259
*/
12531260
function countAttributeTypes() external view returns (uint256) {
12541261
return _attributeIDs.length;
@@ -1258,8 +1265,17 @@ contract ExtendedJurisdiction is Ownable, Pausable, AttributeRegistryInterface,
12581265
* @notice Get the ID of the attribute type at index `index`.
12591266
* @param index uint256 The index of the attribute type in question.
12601267
* @return The ID of the attribute type.
1268+
* @dev This function MUST revert if the provided `index` value falls outside
1269+
* of the range of the value returned from a directly preceding or subsequent
1270+
* function call to `countAttributeTypes`. It MUST NOT revert if the provided
1271+
* `index` value falls inside said range.
12611272
*/
12621273
function getAttributeTypeID(uint256 index) external view returns (uint256) {
1274+
require(
1275+
index < _attributeIDs.length,
1276+
"provided index is outside of the range of defined attribute type IDs"
1277+
);
1278+
12631279
return _attributeIDs[index];
12641280
}
12651281

scripts/testBasic.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,19 @@ module.exports = {test: async function (provider, testingContext) {
945945
failed++
946946
})
947947

948+
await Jurisdiction.methods.getAttributeTypeID(
949+
2
950+
).call({
951+
from: address,
952+
gas: 5000000,
953+
gasPrice: 10 ** 1
954+
}).catch(error => {
955+
console.log(
956+
" ✓ - Out-of-range attribute type IDs revert"
957+
)
958+
passed++
959+
})
960+
948961
await Jurisdiction.methods.getValidatorDescription(
949962
validator.address
950963
).call({

scripts/testExtended.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2005,6 +2005,19 @@ module.exports = {test: async function (provider, testingContext) {
20052005
failed++
20062006
})
20072007

2008+
await Jurisdiction.methods.getAttributeTypeID(
2009+
2
2010+
).call({
2011+
from: address,
2012+
gas: 5000000,
2013+
gasPrice: 10 ** 1
2014+
}).catch(error => {
2015+
console.log(
2016+
" ✓ - Out-of-range attribute type IDs revert"
2017+
)
2018+
passed++
2019+
})
2020+
20082021
await Jurisdiction.methods.removeAttributeType(
20092022
attribute.attributeId
20102023
).send({

0 commit comments

Comments
 (0)