From c4442e45452b8fbc09432ceae4738709ea8df783 Mon Sep 17 00:00:00 2001 From: siftal Date: Wed, 15 Dec 2021 08:40:21 -0500 Subject: [PATCH 1/5] v6 BrightID contract --- BrightID.sol | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/BrightID.sol b/BrightID.sol index 6eaee3c..665755b 100644 --- a/BrightID.sol +++ b/BrightID.sol @@ -1,16 +1,18 @@ pragma solidity ^0.6.3; -import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol"; -import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol"; +import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.0.0/contracts/access/Ownable.sol"; +import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.0.0/contracts/token/ERC20/ERC20.sol"; import "https://github.com/BrightID/BrightID-SmartContract/blob/master/IBrightID.sol"; contract BrightID is Ownable, IBrightID { IERC20 public verifierToken; bytes32 public app; + bytes32 public verificationHash; + bool public useVerificationHash; - event Verified(address indexed addr); event VerifierTokenSet(IERC20 verifierToken); event AppSet(bytes32 _app); + event VerificationHashSet(bytes32 verificationHash); struct Verification { uint256 time; @@ -37,6 +39,16 @@ contract BrightID is Ownable, IBrightID { emit AppSet(_app); } + /** + * @notice Set verification hash + * @param _verificationHash sha256 of the verification expression + */ + function setVerificationHash(bytes32 _verificationHash) public onlyOwner { + useVerificationHash = true; + verificationHash = _verificationHash; + emit VerificationHashSet(_verificationHash); + } + /** * @notice Set verifier token * @param _verifierToken verifier token @@ -48,34 +60,31 @@ contract BrightID is Ownable, IBrightID { /** * @notice Register a user by BrightID verification - * @param addrs The history of addresses used by this user in the app + * @param addr address used by this user in the app * @param timestamp The BrightID node's verification timestamp * @param v Component of signature * @param r Component of signature * @param s Component of signature */ function verify( - address[] memory addrs, + address addr, uint timestamp, uint8 v, bytes32 r, bytes32 s ) public { - require(verifications[addrs[0]].time < timestamp, "newer verification registered before"); - - bytes32 message = keccak256(abi.encodePacked(app, addrs, timestamp)); + bytes32 message; + if (useVerificationHash) { + message = keccak256(abi.encodePacked(app, addr, verificationHash, timestamp)); + } else { + message = keccak256(abi.encodePacked(app, addr, timestamp)); + } address signer = ecrecover(message, v, r, s); require(verifierToken.balanceOf(signer) > 0, "not authorized"); - verifications[addrs[0]].time = timestamp; - verifications[addrs[0]].isVerified = true; - for(uint i = 1; i < addrs.length; i++) { - verifications[addrs[i]].time = timestamp; - verifications[addrs[i]].isVerified = false; - history[addrs[i - 1]] = addrs[i]; - } - history[addrs[i-1]] = address(0); - emit Verified(addrs[0]); + verifications[addr].time = timestamp; + verifications[addr].isVerified = true; + emit Verified(addr); } /** From 09279a177528374fe0d21cc233c1a4c61b4d4d82 Mon Sep 17 00:00:00 2001 From: siftal Date: Wed, 15 Dec 2021 09:05:33 -0500 Subject: [PATCH 2/5] remove history --- IBrightID.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/IBrightID.sol b/IBrightID.sol index acf90e7..fa82fc7 100644 --- a/IBrightID.sol +++ b/IBrightID.sol @@ -3,5 +3,4 @@ pragma solidity ^0.6.3; interface IBrightID { event Verified(address indexed addr); function isVerified(address addr) external view returns (bool); - function history(address addr) external view returns (address); } From 5a6eaf5bd3e10fe345b6787a254ad946cf34cd30 Mon Sep 17 00:00:00 2001 From: siftal Date: Wed, 15 Dec 2021 09:09:48 -0500 Subject: [PATCH 3/5] v6 StoppableBrightID contract --- BrightID.sol | 5 ++-- StoppableBrightID.sol | 58 +++++++++++++++++++++++++++---------------- 2 files changed, 39 insertions(+), 24 deletions(-) diff --git a/BrightID.sol b/BrightID.sol index 665755b..12bf204 100644 --- a/BrightID.sol +++ b/BrightID.sol @@ -2,7 +2,7 @@ pragma solidity ^0.6.3; import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.0.0/contracts/access/Ownable.sol"; import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.0.0/contracts/token/ERC20/ERC20.sol"; -import "https://github.com/BrightID/BrightID-SmartContract/blob/master/IBrightID.sol"; +import "https://github.com/BrightID/BrightID-SmartContract/blob/dev/IBrightID.sol"; contract BrightID is Ownable, IBrightID { IERC20 public verifierToken; @@ -19,7 +19,6 @@ contract BrightID is Ownable, IBrightID { bool isVerified; } mapping(address => Verification) public verifications; - mapping(address => address) override public history; /** * @param _verifierToken verifier token @@ -60,7 +59,7 @@ contract BrightID is Ownable, IBrightID { /** * @notice Register a user by BrightID verification - * @param addr address used by this user in the app + * @param addr The address used by this user in the app * @param timestamp The BrightID node's verification timestamp * @param v Component of signature * @param r Component of signature diff --git a/StoppableBrightID.sol b/StoppableBrightID.sol index e5d21d3..cc25ff3 100644 --- a/StoppableBrightID.sol +++ b/StoppableBrightID.sol @@ -1,13 +1,15 @@ pragma solidity ^0.6.3; -import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol"; -import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol"; -import "https://github.com/BrightID/BrightID-SmartContract/blob/master/IBrightID.sol"; +import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.0.0/contracts/access/Ownable.sol"; +import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.0.0/contracts/token/ERC20/ERC20.sol"; +import "https://github.com/BrightID/BrightID-SmartContract/blob/dev/IBrightID.sol"; contract StoppableBrightID is Ownable, IBrightID { IERC20 public supervisorToken; IERC20 public proposerToken; bytes32 public app; + bytes32 public verificationHash; + bool public useVerificationHash; event Verified(address indexed addr); event Proposed(address indexed addr); @@ -16,6 +18,7 @@ contract StoppableBrightID is Ownable, IBrightID { event TimingSet(uint waiting, uint timeout); event MembershipTokensSet(IERC20 supervisorToken, IERC20 proposerToken); event AppSet(bytes32 _app); + event VerificationHashSet(bytes32 verificationHash); bool public stopped = false; uint public waiting; @@ -27,7 +30,6 @@ contract StoppableBrightID is Ownable, IBrightID { } mapping(address => Verification) public verifications; mapping(bytes32 => uint) public proposals; - mapping(address => address) override public history; /** * @param _supervisorToken supervisor ERC20 token @@ -59,6 +61,16 @@ contract StoppableBrightID is Ownable, IBrightID { emit AppSet(_app); } + /** + * @notice Set verification hash + * @param _verificationHash sha256 of the verification expression + */ + function setVerificationHash(bytes32 _verificationHash) public onlyOwner { + useVerificationHash = true; + verificationHash = _verificationHash; + emit VerificationHashSet(_verificationHash); + } + /** * @notice Set supervisor and proposer Tokens * @param _supervisorToken supervisor ERC20 token @@ -100,14 +112,14 @@ contract StoppableBrightID is Ownable, IBrightID { /** * @notice Propose a registration - * @param addrs The history of addresses used by this user in the app + * @param addr The address used by this user in the app * @param timestamp The BrightID node's verification timestamp * @param v Component of signature * @param r Component of signature * @param s Component of signature */ function propose( - address[] memory addrs, + address addr, uint timestamp, uint8 v, bytes32 r, @@ -115,41 +127,45 @@ contract StoppableBrightID is Ownable, IBrightID { ) public { require(!stopped, "contract is stopped"); - bytes32 message = keccak256(abi.encodePacked(app, addrs, timestamp)); + bytes32 message; + if (useVerificationHash) { + message = keccak256(abi.encodePacked(app, addr, verificationHash, timestamp)); + } else { + message = keccak256(abi.encodePacked(app, addr, timestamp)); + } address signer = ecrecover(message, v, r, s); require(proposerToken.balanceOf(signer) > 0, "not authorized"); proposals[message] = block.number; - emit Proposed(addrs[0]); + emit Proposed(addr); } /** * @notice Verify a registration - * @param addrs The history of addresses used by this user in the app + * @param addr The address used by this user in the app * @param timestamp The BrightID node's verification timestamp */ function verify( - address[] memory addrs, + address addr, uint timestamp ) public { require(!stopped, "contract is stopped"); - require(verifications[addrs[0]].time < timestamp, "newer verification registered before"); - bytes32 message = keccak256(abi.encodePacked(app, addrs, timestamp)); + + bytes32 message; + if (useVerificationHash) { + message = keccak256(abi.encodePacked(app, addr, verificationHash, timestamp)); + } else { + message = keccak256(abi.encodePacked(app, addr, timestamp)); + } uint pblock = proposals[message]; require(pblock > 0, "not proposed"); require(block.number - pblock > waiting, "proposal is waiting"); require(block.number - pblock < timeout, "proposal timed out"); - verifications[addrs[0]].time = timestamp; - verifications[addrs[0]].isVerified = true; - for(uint i = 1; i < addrs.length; i++) { - verifications[addrs[i]].time = timestamp; - verifications[addrs[i]].isVerified = false; - history[addrs[i - 1]] = addrs[i]; - } - history[addrs[i-1]] = address(0); - emit Verified(addrs[0]); + verifications[addr].time = timestamp; + verifications[addr].isVerified = true; + emit Verified(addr); } /** From b14ae9087934d038d61aa50ff0d549bad587160f Mon Sep 17 00:00:00 2001 From: siftal Date: Wed, 15 Dec 2021 15:30:46 -0500 Subject: [PATCH 4/5] update imports --- BrightID.sol | 2 +- Distribution.sol | 6 +++--- StoppableBrightID.sol | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/BrightID.sol b/BrightID.sol index 12bf204..16d59f7 100644 --- a/BrightID.sol +++ b/BrightID.sol @@ -2,7 +2,7 @@ pragma solidity ^0.6.3; import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.0.0/contracts/access/Ownable.sol"; import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.0.0/contracts/token/ERC20/ERC20.sol"; -import "https://github.com/BrightID/BrightID-SmartContract/blob/dev/IBrightID.sol"; +import "./IBrightID.sol"; contract BrightID is Ownable, IBrightID { IERC20 public verifierToken; diff --git a/Distribution.sol b/Distribution.sol index 8b01ba1..885296e 100644 --- a/Distribution.sol +++ b/Distribution.sol @@ -1,8 +1,8 @@ pragma solidity ^0.6.3; -import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol"; -import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/math/SafeMath.sol"; -import "https://github.com/BrightID/BrightID-SmartContract/blob/master/IBrightID.sol"; +import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.0.0/contracts/access/Ownable.sol"; +import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.0.0/contracts/token/ERC20/ERC20.sol"; +import "./IBrightID.sol"; contract Distribution is Ownable { using SafeMath for uint256; diff --git a/StoppableBrightID.sol b/StoppableBrightID.sol index cc25ff3..addfa42 100644 --- a/StoppableBrightID.sol +++ b/StoppableBrightID.sol @@ -2,7 +2,7 @@ pragma solidity ^0.6.3; import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.0.0/contracts/access/Ownable.sol"; import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.0.0/contracts/token/ERC20/ERC20.sol"; -import "https://github.com/BrightID/BrightID-SmartContract/blob/dev/IBrightID.sol"; +import "./IBrightID.sol"; contract StoppableBrightID is Ownable, IBrightID { IERC20 public supervisorToken; From 39eff599c7a613ce27cb087591d77b7da111d8e6 Mon Sep 17 00:00:00 2001 From: siftal Date: Wed, 15 Dec 2021 15:50:42 -0500 Subject: [PATCH 5/5] make the 'verificationHash' required --- BrightID.sol | 13 ++++--------- StoppableBrightID.sol | 22 ++++++---------------- 2 files changed, 10 insertions(+), 25 deletions(-) diff --git a/BrightID.sol b/BrightID.sol index 16d59f7..e88574b 100644 --- a/BrightID.sol +++ b/BrightID.sol @@ -8,7 +8,6 @@ contract BrightID is Ownable, IBrightID { IERC20 public verifierToken; bytes32 public app; bytes32 public verificationHash; - bool public useVerificationHash; event VerifierTokenSet(IERC20 verifierToken); event AppSet(bytes32 _app); @@ -23,10 +22,12 @@ contract BrightID is Ownable, IBrightID { /** * @param _verifierToken verifier token * @param _app BrightID app used for verifying users + * @param _verificationHash sha256 of the verification expression */ - constructor(IERC20 _verifierToken, bytes32 _app) public { + constructor(IERC20 _verifierToken, bytes32 _app, bytes32 _verificationHash) public { verifierToken = _verifierToken; app = _app; + verificationHash = _verificationHash; } /** @@ -43,7 +44,6 @@ contract BrightID is Ownable, IBrightID { * @param _verificationHash sha256 of the verification expression */ function setVerificationHash(bytes32 _verificationHash) public onlyOwner { - useVerificationHash = true; verificationHash = _verificationHash; emit VerificationHashSet(_verificationHash); } @@ -72,12 +72,7 @@ contract BrightID is Ownable, IBrightID { bytes32 r, bytes32 s ) public { - bytes32 message; - if (useVerificationHash) { - message = keccak256(abi.encodePacked(app, addr, verificationHash, timestamp)); - } else { - message = keccak256(abi.encodePacked(app, addr, timestamp)); - } + bytes32 message = keccak256(abi.encodePacked(app, addr, verificationHash, timestamp)); address signer = ecrecover(message, v, r, s); require(verifierToken.balanceOf(signer) > 0, "not authorized"); diff --git a/StoppableBrightID.sol b/StoppableBrightID.sol index addfa42..2fe1c93 100644 --- a/StoppableBrightID.sol +++ b/StoppableBrightID.sol @@ -9,7 +9,6 @@ contract StoppableBrightID is Ownable, IBrightID { IERC20 public proposerToken; bytes32 public app; bytes32 public verificationHash; - bool public useVerificationHash; event Verified(address indexed addr); event Proposed(address indexed addr); @@ -37,19 +36,22 @@ contract StoppableBrightID is Ownable, IBrightID { * @param _app BrightID app used for verifying users * @param _waiting The waiting amount in block number * @param _timeout The timeout amount in block number + * @param _verificationHash sha256 of the verification expression */ constructor( IERC20 _supervisorToken, IERC20 _proposerToken, bytes32 _app, uint _waiting, - uint _timeout + uint _timeout, + bytes32 _verificationHash ) public { supervisorToken = _supervisorToken; proposerToken = _proposerToken; app = _app; waiting = _waiting; timeout = _timeout; + verificationHash = _verificationHash; } /** @@ -66,7 +68,6 @@ contract StoppableBrightID is Ownable, IBrightID { * @param _verificationHash sha256 of the verification expression */ function setVerificationHash(bytes32 _verificationHash) public onlyOwner { - useVerificationHash = true; verificationHash = _verificationHash; emit VerificationHashSet(_verificationHash); } @@ -127,12 +128,7 @@ contract StoppableBrightID is Ownable, IBrightID { ) public { require(!stopped, "contract is stopped"); - bytes32 message; - if (useVerificationHash) { - message = keccak256(abi.encodePacked(app, addr, verificationHash, timestamp)); - } else { - message = keccak256(abi.encodePacked(app, addr, timestamp)); - } + bytes32 message = keccak256(abi.encodePacked(app, addr, verificationHash, timestamp)); address signer = ecrecover(message, v, r, s); require(proposerToken.balanceOf(signer) > 0, "not authorized"); @@ -151,13 +147,7 @@ contract StoppableBrightID is Ownable, IBrightID { ) public { require(!stopped, "contract is stopped"); - - bytes32 message; - if (useVerificationHash) { - message = keccak256(abi.encodePacked(app, addr, verificationHash, timestamp)); - } else { - message = keccak256(abi.encodePacked(app, addr, timestamp)); - } + bytes32 message = keccak256(abi.encodePacked(app, addr, verificationHash, timestamp)); uint pblock = proposals[message]; require(pblock > 0, "not proposed"); require(block.number - pblock > waiting, "proposal is waiting");