diff --git a/bindings/eonkeypublish.go b/bindings/eonkeypublish.go index 50251f1..39ccaf9 100644 --- a/bindings/eonkeypublish.go +++ b/bindings/eonkeypublish.go @@ -31,7 +31,7 @@ var ( // EonKeyPublishMetaData contains all meta data concerning the EonKeyPublish contract. var EonKeyPublishMetaData = &bind.MetaData{ - ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_keyperSet\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_broadcaster\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_eon\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"eonKeyConfirmed\",\"inputs\":[{\"name\":\"eonKey\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"publishEonKey\",\"inputs\":[{\"name\":\"eonKey\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"keyperId\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"EonVoteRegistered\",\"inputs\":[{\"name\":\"eon\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"},{\"name\":\"key\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AlreadyVoted\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidKey\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"KeyperSetNotFinalized\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotAllowed\",\"inputs\":[]}]", + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_keyperSet\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_broadcaster\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_eon\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"eonKeyConfirmed\",\"inputs\":[{\"name\":\"eonKey\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"hasKeyperVoted\",\"inputs\":[{\"name\":\"keyper\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"publishEonKey\",\"inputs\":[{\"name\":\"eonKey\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"keyperId\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"EonVoteRegistered\",\"inputs\":[{\"name\":\"eon\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"},{\"name\":\"key\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AlreadyVoted\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidKey\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"KeyperSetNotFinalized\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotAllowed\",\"inputs\":[]}]", } // EonKeyPublishABI is the input ABI used to generate the binding from. @@ -211,6 +211,37 @@ func (_EonKeyPublish *EonKeyPublishCallerSession) EonKeyConfirmed(eonKey []byte) return _EonKeyPublish.Contract.EonKeyConfirmed(&_EonKeyPublish.CallOpts, eonKey) } +// HasKeyperVoted is a free data retrieval call binding the contract method 0xb118b6ed. +// +// Solidity: function hasKeyperVoted(address keyper) view returns(bool) +func (_EonKeyPublish *EonKeyPublishCaller) HasKeyperVoted(opts *bind.CallOpts, keyper common.Address) (bool, error) { + var out []interface{} + err := _EonKeyPublish.contract.Call(opts, &out, "hasKeyperVoted", keyper) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// HasKeyperVoted is a free data retrieval call binding the contract method 0xb118b6ed. +// +// Solidity: function hasKeyperVoted(address keyper) view returns(bool) +func (_EonKeyPublish *EonKeyPublishSession) HasKeyperVoted(keyper common.Address) (bool, error) { + return _EonKeyPublish.Contract.HasKeyperVoted(&_EonKeyPublish.CallOpts, keyper) +} + +// HasKeyperVoted is a free data retrieval call binding the contract method 0xb118b6ed. +// +// Solidity: function hasKeyperVoted(address keyper) view returns(bool) +func (_EonKeyPublish *EonKeyPublishCallerSession) HasKeyperVoted(keyper common.Address) (bool, error) { + return _EonKeyPublish.Contract.HasKeyperVoted(&_EonKeyPublish.CallOpts, keyper) +} + // PublishEonKey is a paid mutator transaction binding the contract method 0xa1dd75ba. // // Solidity: function publishEonKey(bytes eonKey, uint64 keyperId) returns() diff --git a/src/EonKeyPublish.sol b/src/EonKeyPublish.sol index 8837c13..f333e3d 100644 --- a/src/EonKeyPublish.sol +++ b/src/EonKeyPublish.sol @@ -29,6 +29,10 @@ contract EonKeyPublish is EonKeyPublisher { return false; } + function hasKeyperVoted(address keyper) public view returns (bool) { + return hasVoted[keyper]; + } + function publishEonKey(bytes memory eonKey, uint64 keyperId) public { if (eonKey.length == 0) { revert InvalidKey(); diff --git a/test/EonKeyPublish.t.sol b/test/EonKeyPublish.t.sol index fd75e7d..c612f07 100644 --- a/test/EonKeyPublish.t.sol +++ b/test/EonKeyPublish.t.sol @@ -192,4 +192,37 @@ contract EonKeyPublishTest is Test { assertEq(broadcastContract.getEonKey(eon), bytes("deadbeef")); vm.stopPrank(); } + + function testHasVoted() public { + uint64 eon = 1; + address[] memory members = new address[](5); + members[0] = address(61); + members[1] = address(62); + members[2] = address(63); + members[3] = address(64); + members[4] = address(65); + keyperSet.addMembers(members); + keyperSet.setThreshold(2); + keyperSet.setPublisher(address(eonKeyPublish)); + keyperSet.setFinalized(); + assertEq(keyperSet.getThreshold(), 2); + bytes memory key = bytes("deadbeef"); + vm.startPrank(dao); + manager.addKeyperSet(uint64(block.number + 10), address(keyperSet)); + vm.stopPrank(); + for (uint i = 0; i < members.length; i++) { + assertEq(eonKeyPublish.hasKeyperVoted(members[i]), false); + } + for (uint i = 0; i < keyperSet.getThreshold(); i++) { + vm.prank(members[i]); + eonKeyPublish.publishEonKey(key, uint64(i)); + + for (uint j = 0; j <= i; j++) { + assertEq(eonKeyPublish.hasKeyperVoted(members[j]), true); + } + for (uint j = i + 1; j < members.length; j++) { + assertEq(eonKeyPublish.hasKeyperVoted(members[j]), false); + } + } + } }