diff --git a/BrightID.sol b/BrightID.sol index 7c719cd..e88574b 100644 --- a/BrightID.sol +++ b/BrightID.sol @@ -7,25 +7,27 @@ import "./IBrightID.sol"; contract BrightID is Ownable, IBrightID { IERC20 public verifierToken; bytes32 public app; + bytes32 public verificationHash; - event Verified(address indexed addr); event VerifierTokenSet(IERC20 verifierToken); event AppSet(bytes32 _app); + event VerificationHashSet(bytes32 verificationHash); struct Verification { uint256 time; bool isVerified; } mapping(address => Verification) public verifications; - mapping(address => address) override public history; /** * @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; } /** @@ -37,6 +39,15 @@ 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 { + verificationHash = _verificationHash; + emit VerificationHashSet(_verificationHash); + } + /** * @notice Set verifier token * @param _verifierToken verifier token @@ -48,34 +59,26 @@ 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 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 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 = keccak256(abi.encodePacked(app, addr, verificationHash, 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); } /** 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); } diff --git a/StoppableBrightID.sol b/StoppableBrightID.sol index 136c73c..2fe1c93 100644 --- a/StoppableBrightID.sol +++ b/StoppableBrightID.sol @@ -8,6 +8,7 @@ contract StoppableBrightID is Ownable, IBrightID { IERC20 public supervisorToken; IERC20 public proposerToken; bytes32 public app; + bytes32 public verificationHash; event Verified(address indexed addr); event Proposed(address indexed addr); @@ -16,6 +17,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 +29,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 @@ -35,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; } /** @@ -59,6 +63,15 @@ 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 { + verificationHash = _verificationHash; + emit VerificationHashSet(_verificationHash); + } + /** * @notice Set supervisor and proposer Tokens * @param _supervisorToken supervisor ERC20 token @@ -100,14 +113,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 +128,34 @@ contract StoppableBrightID is Ownable, IBrightID { ) public { require(!stopped, "contract is stopped"); - bytes32 message = keccak256(abi.encodePacked(app, addrs, timestamp)); + bytes32 message = keccak256(abi.encodePacked(app, addr, verificationHash, 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 = keccak256(abi.encodePacked(app, addr, verificationHash, 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); } /**