The home for Hyperlane core contracts, sdk packages, and other infrastructure
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
hyperlane-monorepo/solidity/test/isms/MOfNTestUtils.sol

60 lines
1.6 KiB

// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity >=0.8.0;
library MOfNTestUtils {
function choose(
uint8 m,
uint256[] memory choices,
bytes32 seed
) internal pure returns (uint256[] memory) {
uint256 bitmask = _bitmask(m, uint8(choices.length), seed);
uint256[] memory ret = new uint256[](m);
uint256 j = 0;
for (uint256 i = 0; i < choices.length; i++) {
bool chosen = (bitmask & (1 << i)) > 0;
if (chosen) {
ret[j] = choices[i];
j += 1;
}
}
return ret;
}
function choose(
uint8 m,
address[] memory choices,
bytes32 seed
) internal pure returns (address[] memory) {
uint256 bitmask = _bitmask(m, uint8(choices.length), seed);
address[] memory ret = new address[](m);
uint256 j = 0;
for (uint256 i = 0; i < choices.length; i++) {
bool chosen = (bitmask & (1 << i)) > 0;
if (chosen) {
ret[j] = choices[i];
j += 1;
}
}
return ret;
}
function _bitmask(
uint8 m,
uint8 n,
bytes32 seed
) private pure returns (uint256) {
uint8 chosen = 0;
uint256 bitmask = 0;
bytes32 randomness = seed;
while (chosen < m) {
randomness = keccak256(abi.encodePacked(randomness));
uint256 choice = (1 << (uint256(randomness) % n));
if ((bitmask & choice) == 0) {
bitmask = bitmask | choice;
chosen += 1;
}
}
return bitmask;
}
}