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/contracts/libs/EnumerableMapEnrollment.sol

116 lines
3.4 KiB

// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity >=0.6.11;
// ============ External Imports ============
import "@openzeppelin/contracts/utils/structs/EnumerableMap.sol";
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
// ============ Internal Imports ============
import {TypeCasts} from "./TypeCasts.sol";
enum EnrollmentStatus {
UNENROLLED,
ENROLLED,
PENDING_UNENROLLMENT
}
struct Enrollment {
EnrollmentStatus status;
uint248 unenrollmentStartBlock;
}
// extends EnumerableMap with address => bytes32 type
// modelled after https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.8.0/contracts/utils/structs/EnumerableMap.sol
library EnumerableMapEnrollment {
using EnumerableMap for EnumerableMap.Bytes32ToBytes32Map;
using EnumerableSet for EnumerableSet.Bytes32Set;
using TypeCasts for address;
using TypeCasts for bytes32;
struct AddressToEnrollmentMap {
EnumerableMap.Bytes32ToBytes32Map _inner;
}
// ============ Library Functions ============
function encode(
Enrollment memory enrollment
) public pure returns (bytes32) {
return
bytes32(
abi.encodePacked(
uint8(enrollment.status),
enrollment.unenrollmentStartBlock
)
);
}
function decode(bytes32 encoded) public pure returns (Enrollment memory) {
uint8 status = uint8(encoded[0]);
uint248 unenrollmentStartBlock = uint248(uint256((encoded << 8) >> 8));
return Enrollment(EnrollmentStatus(status), unenrollmentStartBlock);
}
function keys(
AddressToEnrollmentMap storage map
) internal view returns (address[] memory _keys) {
uint256 _length = map._inner.length();
_keys = new address[](_length);
for (uint256 i = 0; i < _length; i++) {
_keys[i] = address(uint160(uint256(map._inner._keys.at(i))));
}
}
function set(
AddressToEnrollmentMap storage map,
address key,
Enrollment memory value
) internal returns (bool) {
return map._inner.set(key.addressToBytes32(), encode(value));
}
function get(
AddressToEnrollmentMap storage map,
address key
) internal view returns (Enrollment memory) {
return decode(map._inner.get(key.addressToBytes32()));
}
function tryGet(
AddressToEnrollmentMap storage map,
address key
) internal view returns (bool, Enrollment memory) {
(bool success, bytes32 value) = map._inner.tryGet(
key.addressToBytes32()
);
return (success, decode(value));
}
function remove(
AddressToEnrollmentMap storage map,
address key
) internal returns (bool) {
return map._inner.remove(key.addressToBytes32());
}
function contains(
AddressToEnrollmentMap storage map,
address key
) internal view returns (bool) {
return map._inner.contains(key.addressToBytes32());
}
function length(
AddressToEnrollmentMap storage map
) internal view returns (uint256) {
return map._inner.length();
}
function at(
AddressToEnrollmentMap storage map,
uint256 index
) internal view returns (uint256, Enrollment memory) {
(bytes32 key, bytes32 value) = map._inner.at(index);
return (uint256(key), decode(value));
}
}