Skip to content

Commit

Permalink
Add simple whitelist strategy (#24)
Browse files Browse the repository at this point in the history
* Add simple whitelist strategy

* refactor: move members to params
  • Loading branch information
pscott authored Jan 24, 2023
1 parent 0da83f3 commit ef22a88
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 0 deletions.
54 changes: 54 additions & 0 deletions src/voting-strategies/WhitelistStrategy.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.15;

import "../interfaces/IVotingStrategy.sol";

contract WhitelistStrategy is IVotingStrategy {
struct Member {
address addy;
uint256 vp;
}

/**
* @notice Binary search through `members` to find the voting power of `voterAddress`
* @param voterAddress The voter address
* @param params The list of members. Needs to be sorted in ascending `addy` order
* @return uint256 The voting power of `voterAddress` if it exists: else 0
*/
function _getVotingPower(address voterAddress, bytes calldata params) internal returns (uint256) {
Member[] memory members = abi.decode(params, (Member[]));

uint256 high = members.length - 1;
uint256 low = 0;
uint256 mid;
address currentAddress;

while (low < high) {
mid = (high + low) / 2; // Expecting high and low to never overflow
currentAddress = members[mid].addy;

if (currentAddress < voterAddress) {
low = mid + 1;
} else {
high = mid;
}
}
if (high > members.length) {
return (0);
} else if (members[high].addy == voterAddress) {
return (members[high].vp);
} else {
return (0);
}
}

function getVotingPower(
uint32 /* timestamp */,
address voterAddress,
bytes calldata params, // Need to be sorted by ascending `addy`s
bytes calldata /* userParams */
) external override returns (uint256) {
return _getVotingPower(voterAddress, params);
}
}
51 changes: 51 additions & 0 deletions test/WhitelistStrategy.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;

import "forge-std/Test.sol";
import "../src/voting-strategies/WhitelistStrategy.sol";

contract WhitelistStrategyTest is Test {
WhitelistStrategy public whitelistStrategy;

function testWhitelistVotingPower() public {
WhitelistStrategy.Member[] memory members = new WhitelistStrategy.Member[](3);
members[0] = WhitelistStrategy.Member(address(1), 11);
members[1] = WhitelistStrategy.Member(address(3), 33);
members[2] = WhitelistStrategy.Member(address(5), 55);
whitelistStrategy = new WhitelistStrategy();

bytes memory params = abi.encode(members);

assertEq(whitelistStrategy.getVotingPower(0, members[0].addy, params, ""), members[0].vp);
assertEq(whitelistStrategy.getVotingPower(0, members[1].addy, params, ""), members[1].vp);
assertEq(whitelistStrategy.getVotingPower(0, members[2].addy, params, ""), members[2].vp);

// Index 0
assertEq(whitelistStrategy.getVotingPower(0, address(0), params, ""), 0);
// Index 2
assertEq(whitelistStrategy.getVotingPower(0, address(2), params, ""), 0);
// 4
assertEq(whitelistStrategy.getVotingPower(0, address(4), params, ""), 0);
// Last index
assertEq(whitelistStrategy.getVotingPower(0, address(6), params, ""), 0);
}

function testWhitelistVotingPowerSmall() public {
WhitelistStrategy.Member[] memory members = new WhitelistStrategy.Member[](3);
members[0] = WhitelistStrategy.Member(address(1), 11);
members[1] = WhitelistStrategy.Member(address(3), 33);
whitelistStrategy = new WhitelistStrategy();

bytes memory params = abi.encode(members);

assertEq(whitelistStrategy.getVotingPower(0, members[0].addy, params, ""), members[0].vp);
assertEq(whitelistStrategy.getVotingPower(0, members[1].addy, params, ""), members[1].vp);

// Index 0
assertEq(whitelistStrategy.getVotingPower(0, address(0), params, ""), 0);
// Index 2
assertEq(whitelistStrategy.getVotingPower(0, address(2), params, ""), 0);
// Last index
assertEq(whitelistStrategy.getVotingPower(0, address(4), params, ""), 0);
}
}

0 comments on commit ef22a88

Please sign in to comment.