-
Notifications
You must be signed in to change notification settings - Fork 11.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add ERC165Query library #1086
Add ERC165Query library #1086
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @ldub, thanks for your contribution! I'm not sure why we didn't think of adding these, considering we already have support for ERC1655
.
There are some minor things that we should improve, but what worries me the most is the lack of tests. Could you create a couple of mock contracts and test this helper against them? Thanks!
@@ -0,0 +1,83 @@ | |||
pragma solidity ^0.4.20; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please target ^0.4.24
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
*/ | ||
library ERC165Query { | ||
bytes4 constant INVALID_ID = 0xffffffff; | ||
bytes4 constant ERC165_ID = 0x01ffc9a7; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding a comment mentioning that this equals bytes4(keccak256('supportsInterface(bytes4)')
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
uint256 result; | ||
|
||
(success, result) = noThrowCall(_contract, ERC165_ID); | ||
if ((success==0)||(result==0)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add spacing here between the ||
operator to comply with our code style.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
returns (bool) | ||
{ | ||
uint256 success; | ||
uint256 result; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Must these be uint256
? Can't we use bool
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this code came from the spec: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md
I take it that the EIP authors used uint256 here as thats what the inline assembly returns by default when you mload.
We can change the noThrowCall code to return bools, but I would prefer the library code here to stay as close to the spec as possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAIK, that code is not technically part of the specification, but a sample contract to test it. And according to the Solidity docs, staticcall
returns a bool
, as does supportsInterface
according to the 165 spec, so it's not like we're doing anything weird.
Encoding success
and result
in uint256
is confusing IMO, since those are actually boolean values (as evidenced by the fact that they are only compared to 0 and 1). I'd make them bool
from the get go to reduce noise and make our intent 100% clear.
Similarly, I'd add comments on the 3 noThrowCall
calls, indicating what is being done on each one (check that the method exists, check that it returns false for invalid ids, and only then check the actual method that is being queried). I may even go as far as splitting that into two methods, one checking ERC165 support (the first two calls), and one only checking for the requested method (the last one), so that, when checking multiple methods, the first two calls are not needlessly duplicated (saving up to 60k gas per check).
That way, we'll end up with a cleaner query library :)
assembly { | ||
let x := mload(0x40) // Find empty storage location using "free memory pointer" | ||
mstore(x, erc165ID) // Place signature at begining of empty storage | ||
mstore(add(x, 0x04), _interfaceId) // Place first argument directly next to signature |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not an inline assembly expert, but should't we also update the free memory pointer at this point?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We would only need to update the free memory pointer if we wanted to allocate more stuff in memory. But we don't need to do that - we make a staticcall and thats it. So my understanding is we don't want to increment the free memory pointer as we'd just want to decrement it later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, I somehow thought that was as internal call. Thanks!
Still figuring out how to write/run tests for this. Having some trouble getting tests to run - there is no "npm run test" script either. Do you have a wiki anywhere for how the testing is set up in this repo? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ldub that's weird about not being able to run the test suite - are you sure you tried from the project root directory? npm run test
(or even npm test
) should work (it's on the package.json
.
Regarding the tests themselves, full coverage would be a bit tricky since there are 3 calls being made, and each returns 2 booleans (4 possible execution paths). To simplify this, I'd go for these three tests:
- Make an empty mock contract, and check that
doesContractImplementInterface
returns false - Make an ERC165 compliant contract (e.g. inherit from
SupportsInterfaceWithLookup
) and check thatdoesContractImplementInterface
returns true forsupportsInterface(bytes4)
but false for some other signature - Make another ERC165 compliant contract that implements some custom method (whatever you want), and check that
doesContractImplementInterface
returns true for that signature.
Those contracts should be placed in contracts/mocks/ImplementsInterfaceMock.sol
.
@shrugs recently worked on the ERC165 tests, so he may have some ideas on that front.
Thanks for your interest in this topic, and let me know if I can be of help!
hi @ldub sorry I didn't see this earlier! I actually implemented most of this PR as part of #1024 can you cherry-pick the associated contract, tests, mocks, etc and add them here? I also prefer the API used by ERC165Checker ( then we'll also be able to close #1145 |
I made all the changes requested, but the Travis build is now failing like so:
Strange because On my machine:
but travis' |
We've removed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ldub @nventuro I'd prefer that the supportsInterface
method also checks that the contract supports ERC165 as well. Primarily, I'd like developers to be able to write
require(myAddress.supportsInterface(InterfaceId_MyInterface))
and be certain that not only does it support 165 but that it also supports that interface.
Thoughts?
@shrugs I requested that change here, my reasoning was that the split would allow for the general ERC165 check to only be done once. Do you think there's value in doing that (i.e. that a contract may call more than one method on some other contract in a single TX, and save gas by only checking for ERC165 support once)? I'd definitely add a method like this one though:
(that name is awful and should be changed) |
@nventuro The contract should support that use-case yeah. Perhaps we can make it idk, I also arrived at the same name you did, |
Agreed, I think this reads very clearly:
|
* @return true if the contract at _address indicates support of the interface with | ||
* identifier _interfaceId, false otherwise | ||
* @dev Assumes that _address contains a contract that supports ERC165, otherwise | ||
* the behavior of this method is undefined. This precondition can be checked |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nventuro what's our stance on indentation within comments? personally I prefer it, but I remember it being deemed unnecessary as a part of one of the other PRs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tbh I have no idea on whether or not they affect docgen. I'd remove all indentation for consistency, and tackle it in a separate PR if needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: indentation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, pending comment note
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is in a great place @ldub, let's address the final nitpicky comments so that we can move along and merge this! 🎉
// As per the EIP-165 spec, no interface should ever match 0xffffffff | ||
bytes4 private constant InterfaceId_Invalid = 0xffffffff; | ||
|
||
// As per the EIP-165 spec, ERC165_ID == bytes4(keccak256('supportsInterface(bytes4)') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you update this comment to include the '0x01ffc9a7' value? That way there'll be no doubt regarding where it comes from.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually, could we update this to follow the pattern we're using elsewhere for interface ids?
bytes4 internal constant InterfaceId_ERC721 = 0x80ac58cd;
/*
* 0x80ac58cd ===
* bytes4(keccak256('balanceOf(address)')) ^
* bytes4(keccak256('ownerOf(uint256)')) ^
* bytes4(keccak256('approve(address,uint256)')) ^
* bytes4(keccak256('getApproved(uint256)')) ^
* bytes4(keccak256('setApprovalForAll(address,bool)')) ^
* bytes4(keccak256('isApprovedForAll(address,address)')) ^
* bytes4(keccak256('transferFrom(address,address,uint256)')) ^
* bytes4(keccak256('safeTransferFrom(address,address,uint256)')) ^
* bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)'))
*/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, pushing a quick fix for this shortly.
Some strangeness/inconsistency here though
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, agree with you on this. I opened #1182 to address it. Thanks!
requesting changes on interfaceid comment structure
The coverage build is failing for some reason, I'm looking into that. |
assembly { | ||
let x := mload(0x40) // Find empty storage location using "free memory pointer" | ||
mstore(x, erc165ID) // Place signature at begining of empty storage | ||
mstore(add(x, 0x04), _interfaceId) // Place first argument directly next to signature |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this can be done with abi.encodeWithSelector
, and thus remove at least part of the assembly code. Also I'm not a fan of the x
variable name. 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If i understand correctly, you would prefer something like:
function noThrowCall (
address _address,
bytes4 _interfaceId
)
internal
view
returns (bool success, bool result)
{
// encode erc165 selector and first argument (_interfaceId)
bytes memory encodedParams = abi.encodeWithSelector(InterfaceId_ERC165, _interfaceId);
// solium-disable-next-line security/no-inline-assembly
assembly {
let freeMemoryPtr := mload(0x40) // Find empty storage location using "free memory pointer"
mstore(freeMemoryPtr, encodedParams) // Place encoded args at beginning of empty storage
success := staticcall(
30000, // 30k gas
_address, // To addr
freeMemoryPtr, // Inputs are stored at free memory pointer
0x20, // Inputs are 32 bytes long
freeMemoryPtr, // Store output over input (saves space)
0x20) // Outputs are 32 bytes long
result := mload(freeMemoryPtr) // Load the result
}
}
I just tested and this does not work (tests fail). The documentation implies that this should be equivalent to the previous code, but I'm probably misunderstanding something. Can you spot the bug?
I agree that it looks cleaner and am happy to push a change to this PR once I can fix this bug.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The encode
call gives you back a memory pointer to a dynamic byte array. It's already in memory so you don't need to manually mstore
it. However, the dynamic byte array has a 32 byte length before the contents, so you should use add(encodedParams, 4)
where freeMemoryPtr
is being used now. I'm not a fan of storing the output over the input, but I suppose it works.
On second thought, I have a few more doubts about it. Are we sure that the result of abi.encodeWithSelector
is 32 bytes long?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tried what you suggested and it didn't work either.
Spent some time trying to use velma debugger to inspect what exactly abi.encodeWithSelector is giving (as the documentation is kind of sparse on this), but can't seem to get it to work with solidity 0.4.24. Will try with truffle debug and/or hevm tomorrow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ldub I was able to get abi.encodeWithSelector
working on 0.4.24 as follows:
bytes memory encodedParams = abi.encodeWithSelector(InterfaceId_ERC165, _interfaceId);
// solium-disable-next-line security/no-inline-assembly
assembly {
let encodedParams_data := add(0x20, encodedParams)
let encodedParams_size := mload(encodedParams)
let output := mload(0x40) // Find empty storage location using "free memory pointer"
success := staticcall(
30000, // 30k gas
_address, // To addr
encodedParams_data,
encodedParams_size,
output,
0x20) // Outputs are 32 bytes long
result := mload(output) // Load the result
}
@ldub agreed, coverage is confusing; I also think the tests cover those cases, just reading them. I'm ok with a manual merge here, but will test this locally to see if I can convince coverage to include those lines. |
I added two commits, one merging the latest master and another that uses reverts to test the return variables and re-implements SupportsInterfaceWithLookup to avoid the coverage issues we were facing earlier. Waiting on coverage to report back, but should be 100% on these files. I realize now we probably don't have to use the requires to test the booleans since the free memory pointer isn't actually being messed up, so I could reasonably change the tests back to the original format where the mock was returning the booleans. Not sure if it matters too much. opinions, @frangio @ldub ? |
@shrugs Do you know what was happening before if it's not the memory pointer? Is it just that it needs to run through a mock? |
(I'll be changing the requires back to boolean asserts, btw, commit incoming) |
@shrugs Ah interesting, thanks. |
* Interface identification is specified in ERC-165. | ||
*/ | ||
function supportsERC165Interface(address _address, bytes4 _interfaceId) | ||
internal |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had changed this to private
as per @frangio's request: #1086 (comment)
Since we now have the supportsInterfaces
API to help save gas when checking many interfaces, we should make supportsERC165Interface
private.
Let me know if you agree and I can make this change.
@shrugs was trying to see if solidity-coverage could be messing with the pointers, but eventually concluded that the instrumentation only adds events so it couldn't be that, and mentioned this in chat. The
This makes sense because they mutate the blockchain, and in fact Solidity |
huh, @nventuro any thoughts on why the coverage build is failing so hard right now? Looks like a bunch of |
cc @cgewecke any ideas on why coverage is failing right now? Sorry to keep pulling you in like this 😅 |
We figured it is being caused by name clashing with this contract that is duplicated: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work to everyone involved!
}); | ||
}); | ||
|
||
context('account address does not support ERC165', function () { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aren't these tests repeats of context('ERC165 not supported')
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but specifically for EOA accounts, not a contract deployed to the chain
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right, I guess those are different enough to make this a meaningful test, thanks!
🎉 |
Great work @ldub and everyone else! This is now the second most commented PR in OZ! |
Yay! Huge thanks to everybody for the reviews and working with me on this :) |
* Minor test style improvements (#1219) * Changed .eq to .equal * Changed equal(bool) to .to.be.bool * Changed be.bool to equal(bool), disallowed unused expressions. * Add ERC165Query library (#1086) * Add ERC165Query library * Address PR Comments * Add tests and mocks from #1024 and refactor code slightly * Fix javascript and solidity linting errors * Split supportsInterface into three methods as discussed in #1086 * Change InterfaceId_ERC165 comment to match style in the rest of the repo * Fix max-len lint issue on ERC165Checker.sol * Conditionally ignore the asserts during solidity-coverage test * Switch to abi.encodeWithSelector and add test for account addresses * Switch to supportsInterfaces API as suggested by @frangio * Adding ERC165InterfacesSupported.sol * Fix style issues * Add test for supportsInterfaces returning false * Add ERC165Checker.sol newline * feat: fix coverage implementation * fix: solidity linting error * fix: revert to using boolean tests instead of require statements * fix: make supportsERC165Interface private again * rename SupportsInterfaceWithLookupMock to avoid name clashing * Added mint and burn tests for zero amounts. (#1230) * Changed .eq to .equal. (#1231) * ERC721 pausable token (#1154) * ERC721 pausable token * Reuse of ERC721 Basic behavior for Pausable, split view checks in paused state & style fixes * [~] paused token behavior * Add some detail to releasing steps (#1190) * add note about pulling upstream changes to release branch * add comment about upstream changes in merging section * Increase test coverage (#1237) * Fixed a SplitPayment test * Deleted unnecessary function. * Improved PostDeliveryCrowdsale tests. * Improved RefundableCrowdsale tests. * Improved MintedCrowdsale tests. * Improved IncreasingPriceCrowdsale tests. * Fixed a CappedCrowdsale test. * Improved TimedCrowdsale tests. * Improved descriptions of added tests. * ci: trigger docs update on tag (#1186) * MintableToken now uses Roles. * Fixed FinalizableCrowdsale test. * Roles can now be transfered. * Fixed tests related to MintableToken. * Removed Roles.check. * Renamed transferMintPermission. * Moved MinterRole * Fixed RBAC. * Adressed review comments. * Addressed review comments * Fixed linter errors. * Added Events tests of Pausable contract (#1207) * Fixed roles tests. * Rename events to past-tense (#1181) * fix: refactor sign.js and related tests (#1243) * fix: refactor sign.js and related tests * fix: remove unused dep * fix: update package.json correctly * Added "_" sufix to internal variables (#1171) * Added PublicRole test. * Fixed crowdsale tests. * Rename ERC interfaces to I prefix (#1252) * rename ERC20 to IERC20 * move ERC20.sol to IERC20.sol * rename StandardToken to ERC20 * rename StandardTokenMock to ERC20Mock * move StandardToken.sol to ERC20.sol, likewise test and mock files * rename MintableToken to ERC20Mintable * move MintableToken.sol to ERC20Mintable.sol, likewise test and mock files * rename BurnableToken to ERC20Burnable * move BurnableToken.sol to ERC20Burnable.sol, likewise for related files * rename CappedToken to ERC20Capped * move CappedToken.sol to ERC20Capped.sol, likewise for related files * rename PausableToken to ERC20Pausable * move PausableToken.sol to ERC20Pausable.sol, likewise for related files * rename DetailedERC20 to ERC20Detailed * move DetailedERC20.sol to ERC20Detailed.sol, likewise for related files * rename ERC721 to IERC721, and likewise for other related interfaces * move ERC721.sol to IERC721.sol, likewise for other 721 interfaces * rename ERC721Token to ERC721 * move ERC721Token.sol to ERC721.sol, likewise for related files * rename ERC721BasicToken to ERC721Basic * move ERC721BasicToken.sol to ERC721Basic.sol, likewise for related files * rename ERC721PausableToken to ERC721Pausable * move ERC721PausableToken.sol to ERC721Pausable.sol * rename ERC165 to IERC165 * move ERC165.sol to IERC165.sol * amend comment that ERC20 is based on FirstBlood * fix comments mentioning IERC721Receiver * added explicit visibility (#1261) * Remove underscores from event parameters. (#1258) * Remove underscores from event parameters. Fixes #1175 * Add comment about ERC * Move contracts to subdirectories (#1253) * Move contracts to subdirectories Fixes #1177. This Change also removes the LimitBalance contract. * fix import * move MerkleProof to cryptography * Fix import * Remove HasNoEther, HasNoTokens, HasNoContracts, and NoOwner (#1254) * remove HasNoEther, HasNoTokens, HasNoContracts, and NoOwner * remove unused ERC223TokenMock * remove Contactable * remove TokenDestructible * remove DeprecatedERC721 * inline Destructible#destroy in Bounty * remove Destructible * Functions in interfaces changed to "external" (#1263) * Add a leading underscore to internal and private functions. (#1257) * Add a leading underscore to internal and private functions. Fixes #1176 * Remove super * update the ERC721 changes * add missing underscore after merge * Fix mock * Improve encapsulation on SignatureBouncer, Whitelist and RBAC example (#1265) * Improve encapsulation on Whitelist * remove only * update whitelisted crowdsale test * Improve encapsulation on SignatureBouncer * fix missing test * Improve encapsulation on RBAC example * Improve encapsulation on RBAC example * Remove extra visibility * Improve encapsulation on ERC20 Mintable * Improve encapsulation on Superuser * fix lint * add missing constant * Addressed review comments. * Fixed build error.
* Role tests (#1228) * Moved RBAC tests to access. * Added Roles.addMany and tests. * Fixed linter error. * Now using uint256 indexes. * Removed RBAC tokens (#1229) * Deleted RBACCappedTokenMock. * Removed RBACMintableToken. * Removed RBACMintableToken from the MintedCrowdsale tests. * Roles can now be transfered. (#1235) * Roles can now be transfered. * Now explicitly checking support for the null address. * Now rejecting transfer to a role-haver. * Added renounce, roles can no longer be transfered to 0. * Fixed linter errors. * Fixed a Roles test. * True Ownership (#1247) * Added barebones Secondary. * Added transferPrimary * Escrow is now Secondary instead of Ownable. * Now reverting on transfers to 0. * The Secondary's primary is now private. * MintableToken using Roles (#1236) * Minor test style improvements (#1219) * Changed .eq to .equal * Changed equal(bool) to .to.be.bool * Changed be.bool to equal(bool), disallowed unused expressions. * Add ERC165Query library (#1086) * Add ERC165Query library * Address PR Comments * Add tests and mocks from #1024 and refactor code slightly * Fix javascript and solidity linting errors * Split supportsInterface into three methods as discussed in #1086 * Change InterfaceId_ERC165 comment to match style in the rest of the repo * Fix max-len lint issue on ERC165Checker.sol * Conditionally ignore the asserts during solidity-coverage test * Switch to abi.encodeWithSelector and add test for account addresses * Switch to supportsInterfaces API as suggested by @frangio * Adding ERC165InterfacesSupported.sol * Fix style issues * Add test for supportsInterfaces returning false * Add ERC165Checker.sol newline * feat: fix coverage implementation * fix: solidity linting error * fix: revert to using boolean tests instead of require statements * fix: make supportsERC165Interface private again * rename SupportsInterfaceWithLookupMock to avoid name clashing * Added mint and burn tests for zero amounts. (#1230) * Changed .eq to .equal. (#1231) * ERC721 pausable token (#1154) * ERC721 pausable token * Reuse of ERC721 Basic behavior for Pausable, split view checks in paused state & style fixes * [~] paused token behavior * Add some detail to releasing steps (#1190) * add note about pulling upstream changes to release branch * add comment about upstream changes in merging section * Increase test coverage (#1237) * Fixed a SplitPayment test * Deleted unnecessary function. * Improved PostDeliveryCrowdsale tests. * Improved RefundableCrowdsale tests. * Improved MintedCrowdsale tests. * Improved IncreasingPriceCrowdsale tests. * Fixed a CappedCrowdsale test. * Improved TimedCrowdsale tests. * Improved descriptions of added tests. * ci: trigger docs update on tag (#1186) * MintableToken now uses Roles. * Fixed FinalizableCrowdsale test. * Roles can now be transfered. * Fixed tests related to MintableToken. * Removed Roles.check. * Renamed transferMintPermission. * Moved MinterRole * Fixed RBAC. * Adressed review comments. * Addressed review comments * Fixed linter errors. * Added Events tests of Pausable contract (#1207) * Fixed roles tests. * Rename events to past-tense (#1181) * fix: refactor sign.js and related tests (#1243) * fix: refactor sign.js and related tests * fix: remove unused dep * fix: update package.json correctly * Added "_" sufix to internal variables (#1171) * Added PublicRole test. * Fixed crowdsale tests. * Rename ERC interfaces to I prefix (#1252) * rename ERC20 to IERC20 * move ERC20.sol to IERC20.sol * rename StandardToken to ERC20 * rename StandardTokenMock to ERC20Mock * move StandardToken.sol to ERC20.sol, likewise test and mock files * rename MintableToken to ERC20Mintable * move MintableToken.sol to ERC20Mintable.sol, likewise test and mock files * rename BurnableToken to ERC20Burnable * move BurnableToken.sol to ERC20Burnable.sol, likewise for related files * rename CappedToken to ERC20Capped * move CappedToken.sol to ERC20Capped.sol, likewise for related files * rename PausableToken to ERC20Pausable * move PausableToken.sol to ERC20Pausable.sol, likewise for related files * rename DetailedERC20 to ERC20Detailed * move DetailedERC20.sol to ERC20Detailed.sol, likewise for related files * rename ERC721 to IERC721, and likewise for other related interfaces * move ERC721.sol to IERC721.sol, likewise for other 721 interfaces * rename ERC721Token to ERC721 * move ERC721Token.sol to ERC721.sol, likewise for related files * rename ERC721BasicToken to ERC721Basic * move ERC721BasicToken.sol to ERC721Basic.sol, likewise for related files * rename ERC721PausableToken to ERC721Pausable * move ERC721PausableToken.sol to ERC721Pausable.sol * rename ERC165 to IERC165 * move ERC165.sol to IERC165.sol * amend comment that ERC20 is based on FirstBlood * fix comments mentioning IERC721Receiver * added explicit visibility (#1261) * Remove underscores from event parameters. (#1258) * Remove underscores from event parameters. Fixes #1175 * Add comment about ERC * Move contracts to subdirectories (#1253) * Move contracts to subdirectories Fixes #1177. This Change also removes the LimitBalance contract. * fix import * move MerkleProof to cryptography * Fix import * Remove HasNoEther, HasNoTokens, HasNoContracts, and NoOwner (#1254) * remove HasNoEther, HasNoTokens, HasNoContracts, and NoOwner * remove unused ERC223TokenMock * remove Contactable * remove TokenDestructible * remove DeprecatedERC721 * inline Destructible#destroy in Bounty * remove Destructible * Functions in interfaces changed to "external" (#1263) * Add a leading underscore to internal and private functions. (#1257) * Add a leading underscore to internal and private functions. Fixes #1176 * Remove super * update the ERC721 changes * add missing underscore after merge * Fix mock * Improve encapsulation on SignatureBouncer, Whitelist and RBAC example (#1265) * Improve encapsulation on Whitelist * remove only * update whitelisted crowdsale test * Improve encapsulation on SignatureBouncer * fix missing test * Improve encapsulation on RBAC example * Improve encapsulation on RBAC example * Remove extra visibility * Improve encapsulation on ERC20 Mintable * Improve encapsulation on Superuser * fix lint * add missing constant * Addressed review comments. * Fixed build error. * Improved Roles API. (#1280) * Improved Roles API. * fix linter error * Added PauserRole. (#1283) * Remove Claimable, DelayedClaimable, Heritable (#1274) * remove Claimable, DelayedClaimable, Heritable * remove SimpleSavingsWallet example which used Heritable (cherry picked from commit 0dc7117) * Role behavior tests (#1285) * Added role tests. * Added PauserRole tests to contracts that have that role. * Added MinterRole tests to contracts that have that role. * Fixed linter errors. * Migrate Ownable to Roles (#1287) * Added CapperRole. * RefundEscrow is now Secondary. * FinalizableCrowdsale is no longer Ownable. * Removed Whitelist and WhitelistedCrowdsale, redesign needed. * Fixed linter errors, disabled lbrace due to it being buggy. * Remove RBAC, SignatureBouncer refactor (#1289) * Added CapperRole. * RefundEscrow is now Secondary. * FinalizableCrowdsale is no longer Ownable. * Removed Whitelist and WhitelistedCrowdsale, redesign needed. * Fixed linter errors, disabled lbrace due to it being buggy. * Moved SignatureBouncer tests. * Deleted RBAC and Superuser. * Deleted rbac directory. * Updated readme. * SignatureBouncer now uses SignerRole, renamed bouncer to signer. * feat: implement ERC721Mintable and ERC721Burnable (#1276) * feat: implement ERC721Mintable and ERC721Burnable * fix: linting errors * fix: remove unused mintable mock for ERC721BasicMock * fix: add finishMinting tests * fix: catch MintFinished typo * inline ERC721Full behavior * undo pretty formatting * fix lint errors * rename canMint to onlyBeforeMintingFinished for consistency with ERC20Mintable * Fix the merge with the privatization branch * remove duplicate CapperRole test
…meters (#1282) * Role tests (#1228) * Moved RBAC tests to access. * Added Roles.addMany and tests. * Fixed linter error. * Now using uint256 indexes. * Removed RBAC tokens (#1229) * Deleted RBACCappedTokenMock. * Removed RBACMintableToken. * Removed RBACMintableToken from the MintedCrowdsale tests. * Roles can now be transfered. (#1235) * Roles can now be transfered. * Now explicitly checking support for the null address. * Now rejecting transfer to a role-haver. * Added renounce, roles can no longer be transfered to 0. * Fixed linter errors. * Fixed a Roles test. * True Ownership (#1247) * Added barebones Secondary. * Added transferPrimary * Escrow is now Secondary instead of Ownable. * Now reverting on transfers to 0. * The Secondary's primary is now private. * Improve encapsulation on ERC165 * Improve encapsulation on ERC20 * Improve encapsulation on ERC721 * Add tests, use standard getters * fix tests * Fix lint * MintableToken using Roles (#1236) * Minor test style improvements (#1219) * Changed .eq to .equal * Changed equal(bool) to .to.be.bool * Changed be.bool to equal(bool), disallowed unused expressions. * Add ERC165Query library (#1086) * Add ERC165Query library * Address PR Comments * Add tests and mocks from #1024 and refactor code slightly * Fix javascript and solidity linting errors * Split supportsInterface into three methods as discussed in #1086 * Change InterfaceId_ERC165 comment to match style in the rest of the repo * Fix max-len lint issue on ERC165Checker.sol * Conditionally ignore the asserts during solidity-coverage test * Switch to abi.encodeWithSelector and add test for account addresses * Switch to supportsInterfaces API as suggested by @frangio * Adding ERC165InterfacesSupported.sol * Fix style issues * Add test for supportsInterfaces returning false * Add ERC165Checker.sol newline * feat: fix coverage implementation * fix: solidity linting error * fix: revert to using boolean tests instead of require statements * fix: make supportsERC165Interface private again * rename SupportsInterfaceWithLookupMock to avoid name clashing * Added mint and burn tests for zero amounts. (#1230) * Changed .eq to .equal. (#1231) * ERC721 pausable token (#1154) * ERC721 pausable token * Reuse of ERC721 Basic behavior for Pausable, split view checks in paused state & style fixes * [~] paused token behavior * Add some detail to releasing steps (#1190) * add note about pulling upstream changes to release branch * add comment about upstream changes in merging section * Increase test coverage (#1237) * Fixed a SplitPayment test * Deleted unnecessary function. * Improved PostDeliveryCrowdsale tests. * Improved RefundableCrowdsale tests. * Improved MintedCrowdsale tests. * Improved IncreasingPriceCrowdsale tests. * Fixed a CappedCrowdsale test. * Improved TimedCrowdsale tests. * Improved descriptions of added tests. * ci: trigger docs update on tag (#1186) * MintableToken now uses Roles. * Fixed FinalizableCrowdsale test. * Roles can now be transfered. * Fixed tests related to MintableToken. * Removed Roles.check. * Renamed transferMintPermission. * Moved MinterRole * Fixed RBAC. * Adressed review comments. * Addressed review comments * Fixed linter errors. * Added Events tests of Pausable contract (#1207) * Fixed roles tests. * Rename events to past-tense (#1181) * fix: refactor sign.js and related tests (#1243) * fix: refactor sign.js and related tests * fix: remove unused dep * fix: update package.json correctly * Added "_" sufix to internal variables (#1171) * Added PublicRole test. * Fixed crowdsale tests. * Rename ERC interfaces to I prefix (#1252) * rename ERC20 to IERC20 * move ERC20.sol to IERC20.sol * rename StandardToken to ERC20 * rename StandardTokenMock to ERC20Mock * move StandardToken.sol to ERC20.sol, likewise test and mock files * rename MintableToken to ERC20Mintable * move MintableToken.sol to ERC20Mintable.sol, likewise test and mock files * rename BurnableToken to ERC20Burnable * move BurnableToken.sol to ERC20Burnable.sol, likewise for related files * rename CappedToken to ERC20Capped * move CappedToken.sol to ERC20Capped.sol, likewise for related files * rename PausableToken to ERC20Pausable * move PausableToken.sol to ERC20Pausable.sol, likewise for related files * rename DetailedERC20 to ERC20Detailed * move DetailedERC20.sol to ERC20Detailed.sol, likewise for related files * rename ERC721 to IERC721, and likewise for other related interfaces * move ERC721.sol to IERC721.sol, likewise for other 721 interfaces * rename ERC721Token to ERC721 * move ERC721Token.sol to ERC721.sol, likewise for related files * rename ERC721BasicToken to ERC721Basic * move ERC721BasicToken.sol to ERC721Basic.sol, likewise for related files * rename ERC721PausableToken to ERC721Pausable * move ERC721PausableToken.sol to ERC721Pausable.sol * rename ERC165 to IERC165 * move ERC165.sol to IERC165.sol * amend comment that ERC20 is based on FirstBlood * fix comments mentioning IERC721Receiver * added explicit visibility (#1261) * Remove underscores from event parameters. (#1258) * Remove underscores from event parameters. Fixes #1175 * Add comment about ERC * Move contracts to subdirectories (#1253) * Move contracts to subdirectories Fixes #1177. This Change also removes the LimitBalance contract. * fix import * move MerkleProof to cryptography * Fix import * Remove HasNoEther, HasNoTokens, HasNoContracts, and NoOwner (#1254) * remove HasNoEther, HasNoTokens, HasNoContracts, and NoOwner * remove unused ERC223TokenMock * remove Contactable * remove TokenDestructible * remove DeprecatedERC721 * inline Destructible#destroy in Bounty * remove Destructible * Functions in interfaces changed to "external" (#1263) * Add a leading underscore to internal and private functions. (#1257) * Add a leading underscore to internal and private functions. Fixes #1176 * Remove super * update the ERC721 changes * add missing underscore after merge * Fix mock * Improve encapsulation on SignatureBouncer, Whitelist and RBAC example (#1265) * Improve encapsulation on Whitelist * remove only * update whitelisted crowdsale test * Improve encapsulation on SignatureBouncer * fix missing test * Improve encapsulation on RBAC example * Improve encapsulation on RBAC example * Remove extra visibility * Improve encapsulation on ERC20 Mintable * Improve encapsulation on Superuser * fix lint * add missing constant * Addressed review comments. * Fixed build error. * move interface ids to implementation contracts * Do not prefix getters * Improve encapsulation on Crowdsales * add missing tests * remove only * Improve encapsulation on Pausable * add the underscore * Improve encapsulation on ownership * fix rebase * fix ownership * Improve encapsulation on payments * Add missing tests * add missing test * Do not prefix getters * Do not prefix getters * Fix tests. * Update modifiers to call public view functions. Fixes #1179. * Improve encapsulation on BreakInvariantBounty * Make researchers private * Improve encapsulation on Crowdsales * add missing tests * remove only * Improve encapsulation on Pausable * add the underscore * Improve encapsulation on ownership * fix rebase * fix ownership * Improve encapsulation on payments * Add missing tests * add missing test * Do not prefix getters * Do not prefix getters * Do not prefix getters * Fix tests. * tmp * remove isMinter * fix is owner call * fix isOpen * Fix merge * tmp * Improve encapsulation on TimedCrowdsale * Add missing parentheses * Use prefix underscore for state variables and no underscore for parameters * Improved Roles API. (#1280) * Improved Roles API. * fix linter error * Added PauserRole. (#1283) * remove duplicate function definition * Remove Claimable, DelayedClaimable, Heritable (#1274) * remove Claimable, DelayedClaimable, Heritable * remove SimpleSavingsWallet example which used Heritable (cherry picked from commit 0dc7117) * Role behavior tests (#1285) * Added role tests. * Added PauserRole tests to contracts that have that role. * Added MinterRole tests to contracts that have that role. * Fixed linter errors. * Migrate Ownable to Roles (#1287) * Added CapperRole. * RefundEscrow is now Secondary. * FinalizableCrowdsale is no longer Ownable. * Removed Whitelist and WhitelistedCrowdsale, redesign needed. * Fixed linter errors, disabled lbrace due to it being buggy. * Remove RBAC, SignatureBouncer refactor (#1289) * Added CapperRole. * RefundEscrow is now Secondary. * FinalizableCrowdsale is no longer Ownable. * Removed Whitelist and WhitelistedCrowdsale, redesign needed. * Fixed linter errors, disabled lbrace due to it being buggy. * Moved SignatureBouncer tests. * Deleted RBAC and Superuser. * Deleted rbac directory. * Updated readme. * SignatureBouncer now uses SignerRole, renamed bouncer to signer. * feat: implement ERC721Mintable and ERC721Burnable (#1276) * feat: implement ERC721Mintable and ERC721Burnable * fix: linting errors * fix: remove unused mintable mock for ERC721BasicMock * fix: add finishMinting tests * fix: catch MintFinished typo * inline ERC721Full behavior * undo pretty formatting * fix lint errors * rename canMint to onlyBeforeMintingFinished for consistency with ERC20Mintable * Fix the merge with the privatization branch * fix lint * Remove underscore * Delete CapperRole.test.js * fix increaseApproval
🚀 Description
The ERC165 spec contains useful code for calling the supportsInterface function on an unknown contract. I use this code and I expect many others need to use this as well. It would be helpful to have it available in OpenZeppelin.
I have added the example code from the spec to OpenZeppelin.
Modifications:
Notes:
security/no-inline-assembly
warning can't be addressed as the spec uses inline assemblynpm run lint:all:fix
).Fixes #1145