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

Return Values

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

Return Values

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

Return Values

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

Return Values

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

Return Values

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

Return Values

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

Return Values

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

Return Values

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

Return Values

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

Return Values

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

Return Values

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

Return Values

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

Return Values

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

Return Values

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

Return Values

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

Return Values

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

Return Values

unpackFeeShiftS3

function unpackFeeShiftS3(uint256 _slot) internal pure returns (uint256 feeShiftU3)

Unpacks the 3-bit fee shift, feeShiftU3, from the provided 256-bit slot,

Parameters

Return Values

packBalancerFeeS4

function packBalancerFeeS4(uint256 _slot, uint256 _balancerFeeDU1F18) internal pure returns (uint256 slot)

Packs the balancer fee, _balancerFeeDU1F18, into the provided 256-bit slot.

Parameters

Return Values

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

Return Values

Last updated