Bit Packing Library
Library for bit-packing generic and specific values pertinent to Cron-Fi TWAMM into storage-slots efficiently (both for gas use and contract size).
_Many custom representations are used herein (i.e. non native word lengths) and there are a number of explicit checks against the maximum of these non native word lengths. Furthermore there are unchecked operations (this code targets Solidity 0.7.x which didn't yet feature implicit arithmetic checks or have the 'unchecked' block feature) in this library for reasons of efficiency or desired overflow. Wherever they appear they will be documented and accompanied with one of the following tags: - #unchecked - #overUnderFlowIntended Identified risks will be accompanied and described with the following tag: - #RISK
Generic shifting methods were eschewed because of their additional gas use. Conventions in the methods below are as follows:
Suffixes:
- The suffix of a variable name denotes the type contained within the variable.
For instance "uint256 _incrementU96" is a 256-bit unsigned container representing
a 96-bit value, _increment.
In the case of "uint256 _balancerFeeDU1F18", the 256-bit unsigned container is
representing a 19 digit decimal value with 18 fractional digits. In this scenario,
the D=Decimal, U=Unsigned, F=Fractional.
- The suffix of a function name denotes what slot it is proprietary too as a
matter of convention. While unchecked at run-time or by the compiler, the naming
convention easily aids in understanding what slot a packed value is stored within.
For instance the function "unpackFeeShiftS3" unpacks the fee shift from slot 3. If
the value of slot 2 were passed to this method, the unpacked value would be
incorrect.
Bit-Numbering:
- Bits are counted starting with the least-significant bit (LSB) from 1. Thus for
a 256-bit slot, the most-significant bit (MSB) is bit 256 and the LSB is bit 1.
Offsets:
- Offsets are the distance from the LSB to the desired LSB of the word being
placed within a slot. For instance, to store an 8-bit word in a 256-bit slot
at bits 16 down to 9, an offset of 8-bits should be specified.
Pairs
- The following methods which operate upon pairs follow the convention that a
pair consists of two same sized words, with word0 stored above word1 within
a slot. For example, a pair of 96-bit words will be stored with word0
occupying bits 192 downto 97 and word1 occupying bits 96 downto 1. The following
diagram depicts this scenario:
bit-256 bit-192 bit-96 bit-1
| | | |
v v v v
MSB < I ??? II word0 II word1 I > LSB
^ ^
| |
bit-193 bit-97_
packBit
function packBit(uint256 _slot, uint256 _bitU1, uint256 _offsetU8) internal pure returns (uint256 slot)
Packs bit _bitU1 into the provided 256-bit slot, _slot, at location _offsetU8 bits from the provided slot's LSB, bit 1.
_WARNING: No checks of offsetU8 are performed for efficiency!
Parameters
_slot
uint256
A 256-bit container to pack bit _bitU1 within.
_bitU1
uint256
A 1-bit value to pack into the provided slot. Min. = 0, Max. = 1.
_offsetU8
uint256
The distance in bits from the provided slot's LSB to store _bitU1 at. Min. = 0, Max. = 255.
Return Values
slot
uint256
The modified slot containing _bitU1 at bit position _offsetU8 + 1.
unpackBit
function unpackBit(uint256 _slot, uint256 _offsetU8) internal pure returns (uint256 bitU1)
Unpacks bitU1 from the provided 256-bit slot, _slot, at location _offsetU8 bits from the provided slot's LSB, bit 1.
_WARNING: No checks of offsetU8 are performed for efficiency!
Parameters
_slot
uint256
A 256-bit container to unpack bitU1 from.
_offsetU8
uint256
The distance in bits from the provided slot's LSB to unpack bitU1 from. Min. = 0, Max. = 255.
Return Values
bitU1
uint256
The 1-bit value unpacked from the provided slot. Min. = 0, Max. = 1.
packU10
function packU10(uint256 _slot, uint256 _wordU10, uint256 _offsetU8) internal pure returns (uint256 slot)
Packs ten-bit word, _wordU10, into the provided 256-bit slot, _slot, at location _offsetU8 bits from the provided slot's LSB, bit 1.
_WARNING: No checks of offsetU8 are performed for efficiency!
Parameters
_slot
uint256
A 256-bit container to pack bit _wordU10 within.
_wordU10
uint256
A ten-bit word to pack into the provided slot. Min. = 0, Max. = (2**10)-1.
_offsetU8
uint256
The distance in bits from the provided slot's LSB to store _bitU1 at. Min. = 0, Max. = 255.
Return Values
slot
uint256
The modified slot containing _wordU10 at bit position _offsetU8 + 1.
unpackU10
function unpackU10(uint256 _slot, uint256 _offsetU8) internal pure returns (uint256 wordU10)
Unpacks wordU10 from the provided 256-bit slot, _slot, at location _offsetU8 bits from the provided slot's LSB, bit 1.
_WARNING: No checks of offsetU8 are performed for efficiency!
Parameters
_slot
uint256
A 256-bit container to unpack wordU10 from.
_offsetU8
uint256
The distance in bits from the provided slot's LSB to unpack wordU10 from. Min. = 0, Max. = 255.
Return Values
wordU10
uint256
The ten-bit word unpacked from the provided slot. Min. = 0, Max. = (2**10)-1.
incrementPairWithClampU96
function incrementPairWithClampU96(uint256 _slot, uint256 _increment0U96, uint256 _increment1U96) internal pure returns (uint256 slot)
Increments the 96-bit words, word0 and/or word1, stored within the provided 256-bit slot, _slot, by the values provided in _increment0U96 and _increment1U96 respectively. Importantly, if the increment results in overflow, the value will "clamp" to the maximum value (2**96)-1.
See the section on Pairs in the notes on Conventions to understand how the two words are stored within the provided slot.
Parameters
_slot
uint256
A 256-bit container holding two 96-bit words, word0 and word1.
_increment0U96
uint256
The amount to increment word0 by. Min. = 0, Max. = (2**96)-1.
_increment1U96
uint256
The amount to increment word1 by. Min. = 0, Max. = (2**96)-1.
Return Values
slot
uint256
The modified slot containing incremented values of word0 and/or word1.
unpackAndClearPairU96
function unpackAndClearPairU96(uint256 _slot) internal pure returns (uint256 slot, uint256 word0U96, uint256 word1U96)
Unpacks the two 96-bit values, word0 and word1, from the provided slot, _slot, returning them along with the provided slot modified to clear the values or word0 and word1 to zero.
See the section on Pairs in the notes on Conventions to understand how the two words are stored within the provided slot.
Parameters
_slot
uint256
A 256-bit container holding two 96-bit words, word0 and word1.
Return Values
slot
uint256
The modified slot containing cleared values of word0 and word1.
word0U96
uint256
The value of word0 prior to clearing it. Min. = 0, Max. = (2**96)-1.
word1U96
uint256
The value of word1 prior to clearing it. Min. = 0, Max. = (2**96)-1.
unpackPairU96
function unpackPairU96(uint256 _slot) internal pure returns (uint256 word0U96, uint256 word1U96)
Unpacks and returns the two 96-bit values, word0 and word1, from the provided slot.
See the section on Pairs in the notes on Conventions to understand how the two words are stored within the provided slot.
Parameters
_slot
uint256
A 256-bit container holding two 96-bit words, word0 and word1.
Return Values
word0U96
uint256
The value of word0. Min. = 0, Max. = (2**96)-1.
word1U96
uint256
The value of word1. Min. = 0, Max. = (2**96)-1.
packPairU112
function packPairU112(uint256 _slot, uint256 _word0U112, uint256 _word1U112) internal pure returns (uint256 slot)
Packs the two provided 112-bit words, word0 and word1, into the provided 256-bit slot, _slot.
See the section on Pairs in the notes on Conventions to understand how the two words are stored within the provided slot.
Parameters
_slot
uint256
A 256-bit container holding two 112-bit words, word0 and word1.
_word0U112
uint256
The value of word0 to pack. Min. = 0, Max. = (2**112)-1.
_word1U112
uint256
The value of word1 to pack. Min. = 0, Max. = (2**112)-1.
Return Values
slot
uint256
The modified slot containing the values of word0 and word1.
unpackPairU112
function unpackPairU112(uint256 _slot) internal pure returns (uint256 word0U112, uint256 word1U112)
Unpacks and returns the two 112-bit values, word0 and word1, from the provided slot.
See the section on Pairs in the notes on Conventions to understand how the two words are stored within the provided slot.
Parameters
_slot
uint256
A 256-bit container holding two 112-bit words, word0 and word1.
Return Values
word0U112
uint256
The value of word0. Min. = 0, Max. = (2**112)-1.
word1U112
uint256
The value of word1. Min. = 0, Max. = (2**112)-1.
incrementPairU112
function incrementPairU112(uint256 _slot, uint256 _increment0U112, uint256 _increment1U112) internal pure returns (uint256 slot)
Increments the 112-bit words, word0 and/or word1, stored within the provided 256-bit slot, _slot, by the values provided in _increment0U112 and _increment1U112 respectively. Errors on overflow.
See the section on Pairs in the notes on Conventions to understand how the two words are stored within the provided slot.
Parameters
_slot
uint256
A 256-bit container holding two 112-bit words, word0 and word1.
_increment0U112
uint256
The amount to increment word0 by. Min. = 0, Max. = (2**112)-1.
_increment1U112
uint256
The amount to increment word1 by. Min. = 0, Max. = (2**112)-1.
Return Values
slot
uint256
The modified slot containing incremented values of word0 and/or word1.
decrementPairU112
function decrementPairU112(uint256 _slot, uint256 _decrement0U112, uint256 _decrement1U112) internal pure returns (uint256 slot)
Decrements the 112-bit words, word0 and/or word1, stored within the provided 256-bit slot, _slot, by the values provided in _decrement0U112 and _decrement1U112 respectively. Errors on underflow.
See the section on Pairs in the notes on Conventions to understand how the two words are stored within the provided slot.
Parameters
_slot
uint256
A 256-bit container holding two 112-bit words, word0 and word1.
_decrement0U112
uint256
The amount to decrement word0 by. Min. = 0, Max. = (2**112)-1.
_decrement1U112
uint256
The amount to decrement word1 by. Min. = 0, Max. = (2**112)-1.
Return Values
slot
uint256
The modified slot containing decremented values of word0 and/or word1.
unpackU128
function unpackU128(uint256 _slot, bool _isWord0) internal pure returns (uint256 wordU128)
Unpacks and returns the specified 128-bit values, word0 or word1, from the provided slot, depending on the value of isWord0.
See the section on Pairs in the notes on Conventions to understand how the two words are stored within the provided slot.
Parameters
_slot
uint256
A 256-bit container holding two 128-bit words, word0 and word1.
_isWord0
bool
Instructs this method to unpack the upper 128-bits corresponding to word0 when true. Otherwise the lower 128-bits, word1 are unpacked.
Return Values
wordU128
uint256
The value of word0. Min. = 0, Max. = (2**128)-1.
packPairU128
function packPairU128(uint256 _word0U128, uint256 _word1U128) internal pure returns (uint256 slot)
Packs the two provided 128-bit words, word0 and word1, into a 256-bit slot.
See the section on Pairs in the notes on Conventions to understand how the two words are stored within the slot.
Parameters
_word0U128
uint256
The value of word0 to pack. Min. = 0, Max. = (2**128)-1.
_word1U128
uint256
The value of word1 to pack. Min. = 0, Max. = (2**128)-1.
Return Values
slot
uint256
A slot containing the 128-bit values word0 and word1.
unpackPairU128
function unpackPairU128(uint256 _slot) internal pure returns (uint256 word0U128, uint256 word1U128)
Unpacks and returns the two 128-bit values, word0 and word1, from the provided slot.
See the section on Pairs in the notes on Conventions to understand how the two words are stored within the provided slot.
Parameters
_slot
uint256
A 256-bit container holding two 128-bit words, word0 and word1.
Return Values
word0U128
uint256
The value of word0. Min. = 0, Max. = (2**128)-1.
word1U128
uint256
The value of word1. Min. = 0, Max. = (2**128)-1.
packOracleTimeStampS2
function packOracleTimeStampS2(uint256 _slot, uint256 _oracleTimeStampU32) internal pure returns (uint256 slot)
Packs the 32-bit oracle time stamp, _oracleTimeStampU32, into the provided 256-bit slot.
Parameters
_slot
uint256
A 256-bit container to pack the oracle time stamp within.
_oracleTimeStampU32
uint256
The 32-bit oracle time stamp. Min. = 0, Max. = (2**32)-1.
Return Values
slot
uint256
The modified slot containing the oracle time stamp.
unpackOracleTimeStampS2
function unpackOracleTimeStampS2(uint256 _slot) internal pure returns (uint256 oracleTimeStampU32)
Unpacks the 32-bit oracle time stamp, oracleTimeStampU32, from the provided 256-bit slot,
Parameters
_slot
uint256
A 256-bit container to unpack the oracle time stamp from.
Return Values
oracleTimeStampU32
uint256
The 32-bit oracle time stamp. Min. = 0, Max. = (2**32)-1.
packFeeShiftS3
function packFeeShiftS3(uint256 _slot, uint256 _feeShiftU3) internal pure returns (uint256 slot)
Packs the 3-bit fee shift, _feeShiftU3, into the provided 256-bit slot.
Parameters
_slot
uint256
A 256-bit container to pack the fee shift into.
_feeShiftU3
uint256
The 3-bit fee shift. Min. = 0, Max. = 7.
Return Values
slot
uint256
The modified slot containing the new fee shift value.
unpackFeeShiftS3
function unpackFeeShiftS3(uint256 _slot) internal pure returns (uint256 feeShiftU3)
Unpacks the 3-bit fee shift, feeShiftU3, from the provided 256-bit slot,
Parameters
_slot
uint256
A 256-bit container to unpack the fee shift from.
Return Values
feeShiftU3
uint256
The 3-bit fee shift. Min. = 0, Max. = 7.
packBalancerFeeS4
function packBalancerFeeS4(uint256 _slot, uint256 _balancerFeeDU1F18) internal pure returns (uint256 slot)
Packs the balancer fee, _balancerFeeDU1F18, into the provided 256-bit slot.
Parameters
_slot
uint256
A 256-bit container to pack the balancer fee into.
_balancerFeeDU1F18
uint256
The balancer fee representing a 19 decimal digit value with 18 fractional digits, NOT TO EXCEED 1019. Min. = 0, Max. = 1019.
Return Values
slot
uint256
The modified slot containing the new balancer fee value.
unpackBalancerFeeS4
function unpackBalancerFeeS4(uint256 _slot) internal pure returns (uint256 balancerFeeDU1F18)
Unpacks the 60-bit balancer fee representation, balancerFeeDU1F18, from the provided 256-bit slot,
Parameters
_slot
uint256
A 256-bit container to unpack the balancer fee from.
Return Values
balancerFeeDU1F18
uint256
The 60-bit balancer fee representing a 19 decimal digit value with 18 fractional digits. Min. = 0, Max. = (2**60)-1.
Last updated