mirror of
https://github.com/luxfi/uma.git
synced 2026-10-30 15:14:44 +00:00
68 lines
3.1 KiB
Solidity
68 lines
3.1 KiB
Solidity
// SPDX-License-Identifier: AGPL-3.0-only
|
|
pragma solidity 0.8.16;
|
|
|
|
/**
|
|
* @title Library to construct admin identifiers.
|
|
*/
|
|
library AdminIdentifierLib {
|
|
// Returns a UTF-8 identifier representing a particular admin proposal.
|
|
// The identifier is of the form "Admin n", where n is the proposal id provided.
|
|
function _constructIdentifier(uint256 id) internal pure returns (bytes32) {
|
|
bytes32 bytesId = _uintToUtf8(id);
|
|
return _addPrefix(bytesId, "Admin ", 6);
|
|
}
|
|
|
|
// This method converts the integer `v` into a base-10, UTF-8 representation stored in a `bytes32` type.
|
|
// If the input cannot be represented by 32 base-10 digits, it returns only the highest 32 digits.
|
|
// This method is based off of this code: https://ethereum.stackexchange.com/a/6613/47801.
|
|
function _uintToUtf8(uint256 v) internal pure returns (bytes32) {
|
|
bytes32 ret;
|
|
if (v == 0) {
|
|
// Handle 0 case explicitly.
|
|
ret = "0";
|
|
} else {
|
|
// Constants.
|
|
uint256 bitsPerByte = 8;
|
|
uint256 base = 10; // Note: the output should be base-10. The below implementation will not work for bases > 10.
|
|
uint256 utf8NumberOffset = 48;
|
|
while (v > 0) {
|
|
// Downshift the entire bytes32 to allow the new digit to be added at the "front" of the bytes32, which
|
|
// translates to the beginning of the UTF-8 representation.
|
|
ret = ret >> bitsPerByte;
|
|
|
|
// Separate the last digit that remains in v by modding by the base of desired output representation.
|
|
uint256 leastSignificantDigit = v % base;
|
|
|
|
// Digits 0-9 are represented by 48-57 in UTF-8, so an offset must be added to create the character.
|
|
bytes32 utf8Digit = bytes32(leastSignificantDigit + utf8NumberOffset);
|
|
|
|
// The top byte of ret has already been cleared to make room for the new digit.
|
|
// Upshift by 31 bytes to put it in position, and OR it with ret to leave the other characters untouched.
|
|
ret |= utf8Digit << (31 * bitsPerByte);
|
|
|
|
// Divide v by the base to remove the digit that was just added.
|
|
v /= base;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
// This method takes two UTF-8 strings represented as bytes32 and outputs one as a prefixed by the other.
|
|
// `input` is the UTF-8 that should have the prefix prepended.
|
|
// `prefix` is the UTF-8 that should be prepended onto input.
|
|
// `prefixLength` is number of UTF-8 characters represented by `prefix`.
|
|
// Notes:
|
|
// 1. If the resulting UTF-8 is larger than 32 characters, then only the first 32 characters will be represented
|
|
// by the bytes32 output.
|
|
// 2. If `prefix` has more characters than `prefixLength`, the function will produce an invalid result.
|
|
function _addPrefix(
|
|
bytes32 input,
|
|
bytes32 prefix,
|
|
uint256 prefixLength
|
|
) internal pure returns (bytes32) {
|
|
// Downshift `input` to open space at the "front" of the bytes32
|
|
bytes32 shiftedInput = input >> (prefixLength * 8);
|
|
return shiftedInput | prefix;
|
|
}
|
|
}
|