From c9c3e7007054bbaf3c8d6d088e98d816aa39ace4 Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Thu, 20 Mar 2025 00:24:34 -0600 Subject: [PATCH 01/39] remove view restriction from context functions --- contracts/meta/_Context.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/meta/_Context.sol b/contracts/meta/_Context.sol index 303eab6c..3b2f6669 100644 --- a/contracts/meta/_Context.sol +++ b/contracts/meta/_Context.sol @@ -13,7 +13,7 @@ abstract contract _Context is _IContext { * @dev if no Context extension is in use, msg.sender is returned as-is * @return msgSender account contextualized as message sender */ - function _msgSender() internal view virtual returns (address msgSender) { + function _msgSender() internal virtual returns (address msgSender) { msgSender = msg.sender; } @@ -22,7 +22,7 @@ abstract contract _Context is _IContext { * @dev if no Context extension is in use, msg.data is returned as-is * @return msgData message data with suffix removed, if applicable */ - function _msgData() internal view virtual returns (bytes calldata msgData) { + function _msgData() internal virtual returns (bytes calldata msgData) { msgData = msg.data; } From d36ebea3f61e4b06a67bfe020b006bde7a176fdd Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Thu, 20 Mar 2025 12:18:48 -0600 Subject: [PATCH 02/39] remove view restrictions from functions that call context functions --- contracts/access/access_control/_AccessControl.sol | 2 +- contracts/meta/ForwardedMetaTransactionContext.sol | 2 -- contracts/meta/_ForwardedMetaTransactionContext.sol | 2 -- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/contracts/access/access_control/_AccessControl.sol b/contracts/access/access_control/_AccessControl.sol index eb891a4c..ecbcc45f 100644 --- a/contracts/access/access_control/_AccessControl.sol +++ b/contracts/access/access_control/_AccessControl.sol @@ -45,7 +45,7 @@ abstract contract _AccessControl is _IAccessControl, _Context { * @notice revert if sender does not have given role * @param role role to query */ - function _checkRole(bytes32 role) internal view virtual { + function _checkRole(bytes32 role) internal virtual { _checkRole(role, _msgSender()); } diff --git a/contracts/meta/ForwardedMetaTransactionContext.sol b/contracts/meta/ForwardedMetaTransactionContext.sol index 7dc537ad..4a2a09d4 100644 --- a/contracts/meta/ForwardedMetaTransactionContext.sol +++ b/contracts/meta/ForwardedMetaTransactionContext.sol @@ -27,7 +27,6 @@ abstract contract ForwardedMetaTransactionContext is */ function _msgSender() internal - view virtual override(_Context, _ForwardedMetaTransactionContext) returns (address msgSender) @@ -40,7 +39,6 @@ abstract contract ForwardedMetaTransactionContext is */ function _msgData() internal - view virtual override(_Context, _ForwardedMetaTransactionContext) returns (bytes calldata msgData) diff --git a/contracts/meta/_ForwardedMetaTransactionContext.sol b/contracts/meta/_ForwardedMetaTransactionContext.sol index 2b645f38..2fc8ec15 100644 --- a/contracts/meta/_ForwardedMetaTransactionContext.sol +++ b/contracts/meta/_ForwardedMetaTransactionContext.sol @@ -21,7 +21,6 @@ abstract contract _ForwardedMetaTransactionContext is */ function _msgSender() internal - view virtual override returns (address msgSender) @@ -48,7 +47,6 @@ abstract contract _ForwardedMetaTransactionContext is */ function _msgData() internal - view virtual override returns (bytes calldata msgData) From 26137acd39e2270e216b539826b8e301549d3ad0 Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Thu, 20 Mar 2025 13:00:04 -0600 Subject: [PATCH 03/39] set evmVerion to cancun --- hardhat.config.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/hardhat.config.ts b/hardhat.config.ts index 81a0fdcc..3301da64 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -18,6 +18,7 @@ const config: HardhatUserConfig = { solidity: { version: '0.8.28', settings: { + evmVersion: 'cancun', optimizer: { enabled: true, runs: 200, From a7510d4fce83a6012cb34ba001f519471937139a Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Thu, 20 Mar 2025 13:15:20 -0600 Subject: [PATCH 04/39] add draft ECDSAMetaTransactionContext contracts --- .../meta/ECDSAMetaTransactionContext.sol | 59 +++++++ .../meta/IECDSAMetaTransactionContext.sol | 13 ++ .../meta/_ECDSAMetaTransactionContext.sol | 162 ++++++++++++++++++ .../meta/_IECDSAMetaTransactionContext.sol | 8 + 4 files changed, 242 insertions(+) create mode 100644 contracts/meta/ECDSAMetaTransactionContext.sol create mode 100644 contracts/meta/IECDSAMetaTransactionContext.sol create mode 100644 contracts/meta/_ECDSAMetaTransactionContext.sol create mode 100644 contracts/meta/_IECDSAMetaTransactionContext.sol diff --git a/contracts/meta/ECDSAMetaTransactionContext.sol b/contracts/meta/ECDSAMetaTransactionContext.sol new file mode 100644 index 00000000..53ea08af --- /dev/null +++ b/contracts/meta/ECDSAMetaTransactionContext.sol @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.20; + +import { IERC5267 } from '../interfaces/IERC5267.sol'; +import { Context } from './Context.sol'; +import { _Context } from './_Context.sol'; +import { IECDSAMetaTransactionContext } from './IECDSAMetaTransactionContext.sol'; +import { _ECDSAMetaTransactionContext } from './_ECDSAMetaTransactionContext.sol'; + +abstract contract ECDSAMetaTransactionContext is + IECDSAMetaTransactionContext, + _ECDSAMetaTransactionContext, + Context +{ + /** + * @inheritdoc IERC5267 + */ + function eip712Domain() + external + view + returns ( + bytes1 fields, + string memory name, + string memory version, + uint256 chainId, + address verifyingContract, + bytes32 salt, + uint256[] memory extensions + ) + { + return _eip712Domain(); + } + + function _msgSender() + internal + override(_Context, _ECDSAMetaTransactionContext) + returns (address msgSender) + { + msgSender = super._msgSender(); + } + + function _msgData() + internal + override(_Context, _ECDSAMetaTransactionContext) + returns (bytes calldata msgData) + { + msgData = super._msgData(); + } + + function _calldataSuffixLength() + internal + view + override(_Context, _ECDSAMetaTransactionContext) + returns (uint256 length) + { + length = super._calldataSuffixLength(); + } +} diff --git a/contracts/meta/IECDSAMetaTransactionContext.sol b/contracts/meta/IECDSAMetaTransactionContext.sol new file mode 100644 index 00000000..97a769aa --- /dev/null +++ b/contracts/meta/IECDSAMetaTransactionContext.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.20; + +import { IERC5267 } from '../interfaces/IERC5267.sol'; +import { IContext } from './IContext.sol'; +import { _IECDSAMetaTransactionContext } from './_IECDSAMetaTransactionContext.sol'; + +interface IECDSAMetaTransactionContext is + _IECDSAMetaTransactionContext, + IContext, + IERC5267 +{} diff --git a/contracts/meta/_ECDSAMetaTransactionContext.sol b/contracts/meta/_ECDSAMetaTransactionContext.sol new file mode 100644 index 00000000..ea512849 --- /dev/null +++ b/contracts/meta/_ECDSAMetaTransactionContext.sol @@ -0,0 +1,162 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.20; + +import { ECDSA } from '../cryptography/ECDSA.sol'; +import { _Context } from './_Context.sol'; +import { _IECDSAMetaTransactionContext } from './_IECDSAMetaTransactionContext.sol'; + +abstract contract _ECDSAMetaTransactionContext is + _IECDSAMetaTransactionContext, + _Context +{ + using ECDSA for bytes32; + + bytes32 internal constant EIP_712_TYPE_HASH = + keccak256('ECDSAMetaTransaction(bytes msgData,uint256 nonce)'); + + function _eip712Domain() + internal + view + virtual + returns ( + bytes1 fields, + string memory name, + string memory version, + uint256 chainId, + address verifyingContract, + bytes32 salt, + uint256[] memory extensions + ) + { + return ( + hex'0f', // 01100 + '', + '', + block.chainid, + address(this), + bytes32(0), + new uint256[](0) + ); + } + + /** + * @inheritdoc _Context + * @dev sender is read from the calldata context suffix + */ + function _msgSender() + internal + virtual + override + returns (address msgSender) + { + uint256 dataLength = msg.data.length; + uint256 suffixLength = _calldataSuffixLength(); + + if (dataLength >= suffixLength) { + // calldata is long enough that it might have a suffix + // check transient storage to see if sender has been derived already + + assembly { + msgSender := tload(9000) + } + + if (msgSender == address(0)) { + // no sender found in transient storage, so attempt to derive it from signature + + unchecked { + (msgSender, ) = _processCalldata(dataLength - suffixLength); + } + } + } else { + msgSender = super._msgSender(); + } + } + + /** + * @inheritdoc _Context + */ + function _msgData() + internal + virtual + override + returns (bytes calldata msgData) + { + uint256 dataLength = msg.data.length; + uint256 suffixLength = _calldataSuffixLength(); + + if (dataLength >= suffixLength) { + // calldata is long enough that it might have a suffix + // check transient storage to see if msgData split index has been derived already + + uint256 split; + + assembly { + split := tload(9001) + } + + if (split == 0) { + // no msgData split index found in transient storage, so attempt to derive it from signature + + unchecked { + (, split) = _processCalldata(dataLength - suffixLength); + } + } + + msgData = msg.data[:split]; + } else { + msgData = super._msgData(); + } + } + + /** + * @inheritdoc _Context + * @dev this Context extension defines an address suffix with a length of 20 + */ + function _calldataSuffixLength() + internal + view + virtual + override + returns (uint256 length) + { + length = 97; + } + + function _processCalldata( + uint256 split + ) private returns (address msgSender, uint256 msgDataIndex) { + unchecked { + bytes calldata msgData = msg.data[:split]; + uint256 nonce = uint256(bytes32(msg.data[split:split + 32])); + + // TODO: include msg.sender in hash to restrict forwarder + bytes32 hash = keccak256( + abi.encode(EIP_712_TYPE_HASH, keccak256(msgData), nonce) + ); + + bytes calldata signature = msg.data[split + 32:]; + + // TODO: see what happens if split calldata v r s + address signer = hash.recover(signature); + + // TODO: invalidate nonce + + if (signer == address(0)) { + msgSender = super._msgSender(); + msgDataIndex = super._msgData().length; + } else { + msgSender = signer; + msgDataIndex = split; + } + } + + assembly { + // TODO: suppress warning + // TODO: standardize location + // TODO: pack (msgDataIndex as bytes12) + tstore(9000, msgSender) + tstore(9001, msgDataIndex) + } + } +} diff --git a/contracts/meta/_IECDSAMetaTransactionContext.sol b/contracts/meta/_IECDSAMetaTransactionContext.sol new file mode 100644 index 00000000..a9abf4ea --- /dev/null +++ b/contracts/meta/_IECDSAMetaTransactionContext.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.20; + +import { _IERC5267 } from '../interfaces/_IERC5267.sol'; +import { _IContext } from './_IContext.sol'; + +interface _IECDSAMetaTransactionContext is _IContext, _IERC5267 {} From b185260d3cfd5921b1f1638875e86a17aff2bc8d Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Thu, 20 Mar 2025 13:45:08 -0600 Subject: [PATCH 05/39] use non-reverting recover for ECDSA context --- contracts/meta/_ECDSAMetaTransactionContext.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/meta/_ECDSAMetaTransactionContext.sol b/contracts/meta/_ECDSAMetaTransactionContext.sol index ea512849..e2b2f7d2 100644 --- a/contracts/meta/_ECDSAMetaTransactionContext.sol +++ b/contracts/meta/_ECDSAMetaTransactionContext.sol @@ -138,7 +138,7 @@ abstract contract _ECDSAMetaTransactionContext is bytes calldata signature = msg.data[split + 32:]; // TODO: see what happens if split calldata v r s - address signer = hash.recover(signature); + address signer = hash.tryRecover(signature); // TODO: invalidate nonce From 4d633a091024d8e3dab9cc05127c03baee95a403 Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Thu, 20 Mar 2025 14:28:05 -0600 Subject: [PATCH 06/39] fix _eip712Domain output --- contracts/meta/_ECDSAMetaTransactionContext.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/meta/_ECDSAMetaTransactionContext.sol b/contracts/meta/_ECDSAMetaTransactionContext.sol index e2b2f7d2..70daba16 100644 --- a/contracts/meta/_ECDSAMetaTransactionContext.sol +++ b/contracts/meta/_ECDSAMetaTransactionContext.sol @@ -30,7 +30,7 @@ abstract contract _ECDSAMetaTransactionContext is ) { return ( - hex'0f', // 01100 + hex'0c', // 01100 '', '', block.chainid, From 5bef448f69379ff492e3b3c3655f2e43f3b63fde Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Thu, 20 Mar 2025 15:02:15 -0600 Subject: [PATCH 07/39] reference ERC5267 fields constant in ECDSAMetaTransactionContext --- contracts/meta/_ECDSAMetaTransactionContext.sol | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contracts/meta/_ECDSAMetaTransactionContext.sol b/contracts/meta/_ECDSAMetaTransactionContext.sol index 70daba16..4f4f1dd2 100644 --- a/contracts/meta/_ECDSAMetaTransactionContext.sol +++ b/contracts/meta/_ECDSAMetaTransactionContext.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.20; import { ECDSA } from '../cryptography/ECDSA.sol'; +import { EIP712 } from '../cryptography/EIP712.sol'; import { _Context } from './_Context.sol'; import { _IECDSAMetaTransactionContext } from './_IECDSAMetaTransactionContext.sol'; @@ -30,7 +31,7 @@ abstract contract _ECDSAMetaTransactionContext is ) { return ( - hex'0c', // 01100 + EIP712.ERC5267_FIELDS_01100, '', '', block.chainid, From 32e632dea70cb44c78196ebbe701acc6cb45107d Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Thu, 20 Mar 2025 15:07:25 -0600 Subject: [PATCH 08/39] fix hash struct procedure --- .../meta/_ECDSAMetaTransactionContext.sol | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/contracts/meta/_ECDSAMetaTransactionContext.sol b/contracts/meta/_ECDSAMetaTransactionContext.sol index 4f4f1dd2..00e989f7 100644 --- a/contracts/meta/_ECDSAMetaTransactionContext.sol +++ b/contracts/meta/_ECDSAMetaTransactionContext.sol @@ -132,14 +132,45 @@ abstract contract _ECDSAMetaTransactionContext is uint256 nonce = uint256(bytes32(msg.data[split:split + 32])); // TODO: include msg.sender in hash to restrict forwarder - bytes32 hash = keccak256( + // TODO: include msg.value + bytes32 structHash = keccak256( abi.encode(EIP_712_TYPE_HASH, keccak256(msgData), nonce) ); + bytes32 domainSeparator = EIP712.calculateDomainSeparator_01100(); + + bytes32 signedHash; + + assembly { + // assembly block equivalent to: + // + // signedHash = keccak256( + // abi.encodePacked( + // uint16(0x1901), + // domainSeparator, + // structHash + // ) + // ); + + // load free memory pointer + let pointer := mload(64) + + // this magic value is the EIP-191 signed data header, consisting of + // the hardcoded 0x19 and the one-byte version 0x01 + mstore( + pointer, + 0x1901000000000000000000000000000000000000000000000000000000000000 + ) + mstore(add(pointer, 2), domainSeparator) + mstore(add(pointer, 34), structHash) + + signedHash := keccak256(pointer, 66) + } + bytes calldata signature = msg.data[split + 32:]; // TODO: see what happens if split calldata v r s - address signer = hash.tryRecover(signature); + address signer = signedHash.tryRecover(signature); // TODO: invalidate nonce From 86662f601c981d594a185996adf5aad0dfb70662 Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Thu, 20 Mar 2025 15:12:42 -0600 Subject: [PATCH 09/39] test ECDSAMetaTransactionContext --- lib/erc20_permit.ts | 32 ++++- test/meta/ECDSAMetaTransactionContext.ts | 155 +++++++++++++++++++++++ 2 files changed, 183 insertions(+), 4 deletions(-) create mode 100644 test/meta/ECDSAMetaTransactionContext.ts diff --git a/lib/erc20_permit.ts b/lib/erc20_permit.ts index 08c6ac6f..a5dda44a 100644 --- a/lib/erc20_permit.ts +++ b/lib/erc20_permit.ts @@ -1,6 +1,6 @@ import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; import { IERC2612, IERC5267 } from '@solidstate/typechain-types'; -import { Signature } from 'ethers'; +import { BytesLike, Signature } from 'ethers'; import { ethers } from 'hardhat'; interface Domain { @@ -99,9 +99,33 @@ const signERC2612Permit = async ( const signature = await owner.signTypedData(domain, types, values); - const permit = ethers.Signature.from(signature); + return ethers.Signature.from(signature); +}; + +// TODO: rename file or move to new file +const signECDSAMetaTransaction = async ( + instance: IERC5267, + signer: SignerWithAddress, + msgData: BytesLike, + nonce: bigint, +): Promise => { + const domain = await getDomain(instance); + + const types = { + ECDSAMetaTransaction: [ + { name: 'msgData', type: 'bytes' }, + { name: 'nonce', type: 'uint256' }, + ], + }; + + const values = { + msgData, + nonce, + }; + + const signature = await signer.signTypedData(domain, types, values); - return permit; + return ethers.Signature.from(signature); }; -export { signERC2612Permit }; +export { signERC2612Permit, signECDSAMetaTransaction }; diff --git a/test/meta/ECDSAMetaTransactionContext.ts b/test/meta/ECDSAMetaTransactionContext.ts new file mode 100644 index 00000000..931d7289 --- /dev/null +++ b/test/meta/ECDSAMetaTransactionContext.ts @@ -0,0 +1,155 @@ +import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; +import { signECDSAMetaTransaction } from '@solidstate/library'; +import { + $ECDSAMetaTransactionContext, + $ECDSAMetaTransactionContext__factory, +} from '@solidstate/typechain-types'; +import { TypedContractMethod } from '@solidstate/typechain-types/common'; +import { expect } from 'chai'; +import { BytesLike, ContractMethodArgs } from 'ethers'; +import { ethers } from 'hardhat'; + +const callMetaTransaction = async ( + signer: SignerWithAddress, + fn: TypedContractMethod<[], [string], 'nonpayable' | 'payable' | 'view'>, + data: BytesLike, + args: ContractMethodArgs<[]> = [], +) => { + const tx = await fn.populateTransaction(...args); + tx.data = ethers.concat([tx.data, data]); + + const result = await signer.call(tx); + + return new ethers.Interface([fn.fragment]).decodeFunctionResult( + fn.name, + result, + ); +}; + +describe('ECDSAMetaTransactionContext', () => { + let instance: $ECDSAMetaTransactionContext; + let deployer: SignerWithAddress; + let forwarder: SignerWithAddress; + let signer: SignerWithAddress; + + beforeEach(async () => { + [deployer, forwarder, signer] = await ethers.getSigners(); + instance = await new $ECDSAMetaTransactionContext__factory( + deployer, + ).deploy(); + }); + + // TODO: spec + + // TODO: test multiple calls in same tx to validate that transient storage is used correctly + + describe('__internal', () => { + describe('#_msgSender()', () => { + it('returns signer if signature is valid', async () => { + const data = instance.$_msgSender.fragment.selector; + const nonce = 1n; + + const signature = await signECDSAMetaTransaction( + instance, + signer, + data, + nonce, + ); + + const suffix = ethers.concat([ + ethers.toBeHex(nonce, 32), + signature.serialized, + ]); + + expect( + await callMetaTransaction(forwarder, instance.$_msgSender, suffix), + ).to.deep.equal([await signer.getAddress()]); + }); + + it('returns message sender if signature is invalid', async () => { + const suffix = ethers.randomBytes( + Number(await instance.$_calldataSuffixLength.staticCall()), + ); + + expect( + await callMetaTransaction(forwarder, instance.$_msgSender, suffix), + ).to.deep.equal([await forwarder.getAddress()]); + }); + + it('returns message sender if message data length is less than suffix length', async () => { + it('returns message sender if message data length is less than suffix length', async () => { + // account for 4-byte selector when calculting suffix length + const suffix = ethers.randomBytes( + Number( + (await instance.$_calldataSuffixLength.staticCall()) - 4n - 1n, + ), + ); + + expect( + await callMetaTransaction(forwarder, instance.$_msgSender, suffix), + ).to.deep.equal([await forwarder.getAddress()]); + }); + }); + }); + + describe('#_msgData()', () => { + it('returns message data without suffix if signature is valid', async () => { + const nonSuffixedData = instance.$_msgData.fragment.selector; + const nonce = 1n; + + const signature = await signECDSAMetaTransaction( + instance, + signer, + nonSuffixedData, + nonce, + ); + + const suffix = ethers.concat([ + ethers.toBeHex(nonce, 32), + signature.serialized, + ]); + + expect( + await callMetaTransaction(forwarder, instance.$_msgData, suffix), + ).to.deep.equal([nonSuffixedData]); + }); + + it('returns complete message data if signature is invalid', async () => { + const nonSuffixedData = instance.$_msgData.fragment.selector; + const suffix = ethers.randomBytes( + Number(await instance.$_calldataSuffixLength.staticCall()), + ); + + // message data is returned as received, demonstrating the malleability of msg.data + + expect( + await callMetaTransaction(forwarder, instance.$_msgData, suffix), + ).to.deep.equal([ethers.concat([nonSuffixedData, suffix])]); + }); + + it('returns complete message data if message data length is less than suffix length', async () => { + const nonSuffixedData = instance.$_msgData.fragment.selector; + // account for 4-byte selector when calculting suffix length + const suffix = ethers.randomBytes( + Number( + (await instance.$_calldataSuffixLength.staticCall()) - 4n - 1n, + ), + ); + + // message data is returned as received, demonstrating the malleability of msg.data + + expect( + await callMetaTransaction(forwarder, instance.$_msgData, suffix), + ).to.deep.equal([ethers.concat([nonSuffixedData, suffix])]); + }); + }); + + describe('#_calldataSuffixLength()', () => { + it('returns 97', async () => { + expect(await instance.$_calldataSuffixLength.staticCall()).to.equal( + 97n, + ); + }); + }); + }); +}); From be593430a2f76741f5e37daaf5bf3af8ac299329 Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Thu, 20 Mar 2025 15:17:36 -0600 Subject: [PATCH 10/39] fix test nesting --- test/meta/ECDSAMetaTransactionContext.ts | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/test/meta/ECDSAMetaTransactionContext.ts b/test/meta/ECDSAMetaTransactionContext.ts index 931d7289..0a3c3df5 100644 --- a/test/meta/ECDSAMetaTransactionContext.ts +++ b/test/meta/ECDSAMetaTransactionContext.ts @@ -77,18 +77,16 @@ describe('ECDSAMetaTransactionContext', () => { }); it('returns message sender if message data length is less than suffix length', async () => { - it('returns message sender if message data length is less than suffix length', async () => { - // account for 4-byte selector when calculting suffix length - const suffix = ethers.randomBytes( - Number( - (await instance.$_calldataSuffixLength.staticCall()) - 4n - 1n, - ), - ); - - expect( - await callMetaTransaction(forwarder, instance.$_msgSender, suffix), - ).to.deep.equal([await forwarder.getAddress()]); - }); + // account for 4-byte selector when calculting suffix length + const suffix = ethers.randomBytes( + Number( + (await instance.$_calldataSuffixLength.staticCall()) - 4n - 1n, + ), + ); + + expect( + await callMetaTransaction(forwarder, instance.$_msgSender, suffix), + ).to.deep.equal([await forwarder.getAddress()]); }); }); From 054d056b5f1068d0a451dada28a9316cccc6ce5f Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Thu, 20 Mar 2025 15:53:01 -0600 Subject: [PATCH 11/39] use semi-standardized transient storage slot --- .../meta/_ECDSAMetaTransactionContext.sol | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/contracts/meta/_ECDSAMetaTransactionContext.sol b/contracts/meta/_ECDSAMetaTransactionContext.sol index 00e989f7..8e5930a6 100644 --- a/contracts/meta/_ECDSAMetaTransactionContext.sol +++ b/contracts/meta/_ECDSAMetaTransactionContext.sol @@ -16,6 +16,11 @@ abstract contract _ECDSAMetaTransactionContext is bytes32 internal constant EIP_712_TYPE_HASH = keccak256('ECDSAMetaTransaction(bytes msgData,uint256 nonce)'); + bytes32 + internal constant ECDSA_META_TRANSACTION_CONTEXT_TRANSIENT_STORAGE_SLOT = + keccak256(abi.encode(uint256(EIP_712_TYPE_HASH) - 1)) & + ~bytes32(uint256(0xff)); + function _eip712Domain() internal view @@ -58,8 +63,10 @@ abstract contract _ECDSAMetaTransactionContext is // calldata is long enough that it might have a suffix // check transient storage to see if sender has been derived already + bytes32 slot = ECDSA_META_TRANSACTION_CONTEXT_TRANSIENT_STORAGE_SLOT; + assembly { - msgSender := tload(9000) + msgSender := tload(slot) } if (msgSender == address(0)) { @@ -92,8 +99,10 @@ abstract contract _ECDSAMetaTransactionContext is uint256 split; + bytes32 slot = ECDSA_META_TRANSACTION_CONTEXT_TRANSIENT_STORAGE_SLOT; + assembly { - split := tload(9001) + split := tload(add(slot, 1)) } if (split == 0) { @@ -183,12 +192,13 @@ abstract contract _ECDSAMetaTransactionContext is } } + bytes32 slot = ECDSA_META_TRANSACTION_CONTEXT_TRANSIENT_STORAGE_SLOT; + assembly { // TODO: suppress warning - // TODO: standardize location // TODO: pack (msgDataIndex as bytes12) - tstore(9000, msgSender) - tstore(9001, msgDataIndex) + tstore(slot, msgSender) + tstore(add(slot, 1), msgDataIndex) } } } From 6087a18a60196cd1cfb0135f2e39b325d5b388f6 Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Thu, 20 Mar 2025 16:17:29 -0600 Subject: [PATCH 12/39] support msg.value in ECDSAMetaTransactionContext --- contracts/meta/_ECDSAMetaTransactionContext.sol | 17 +++++++++++------ lib/erc20_permit.ts | 3 +++ test/meta/ECDSAMetaTransactionContext.ts | 6 ++++++ 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/contracts/meta/_ECDSAMetaTransactionContext.sol b/contracts/meta/_ECDSAMetaTransactionContext.sol index 8e5930a6..f04ac83a 100644 --- a/contracts/meta/_ECDSAMetaTransactionContext.sol +++ b/contracts/meta/_ECDSAMetaTransactionContext.sol @@ -14,7 +14,9 @@ abstract contract _ECDSAMetaTransactionContext is using ECDSA for bytes32; bytes32 internal constant EIP_712_TYPE_HASH = - keccak256('ECDSAMetaTransaction(bytes msgData,uint256 nonce)'); + keccak256( + 'ECDSAMetaTransaction(bytes msgData,uint256 msgValue,uint256 nonce)' + ); bytes32 internal constant ECDSA_META_TRANSACTION_CONTEXT_TRANSIENT_STORAGE_SLOT = @@ -139,11 +141,16 @@ abstract contract _ECDSAMetaTransactionContext is unchecked { bytes calldata msgData = msg.data[:split]; uint256 nonce = uint256(bytes32(msg.data[split:split + 32])); + bytes calldata signature = msg.data[split + 32:]; - // TODO: include msg.sender in hash to restrict forwarder - // TODO: include msg.value + // TODO: include msg.sender in hash to restrict forwarder? bytes32 structHash = keccak256( - abi.encode(EIP_712_TYPE_HASH, keccak256(msgData), nonce) + abi.encode( + EIP_712_TYPE_HASH, + keccak256(msgData), + msg.value, + nonce + ) ); bytes32 domainSeparator = EIP712.calculateDomainSeparator_01100(); @@ -176,8 +183,6 @@ abstract contract _ECDSAMetaTransactionContext is signedHash := keccak256(pointer, 66) } - bytes calldata signature = msg.data[split + 32:]; - // TODO: see what happens if split calldata v r s address signer = signedHash.tryRecover(signature); diff --git a/lib/erc20_permit.ts b/lib/erc20_permit.ts index a5dda44a..d18defef 100644 --- a/lib/erc20_permit.ts +++ b/lib/erc20_permit.ts @@ -107,6 +107,7 @@ const signECDSAMetaTransaction = async ( instance: IERC5267, signer: SignerWithAddress, msgData: BytesLike, + msgValue: bigint, nonce: bigint, ): Promise => { const domain = await getDomain(instance); @@ -114,12 +115,14 @@ const signECDSAMetaTransaction = async ( const types = { ECDSAMetaTransaction: [ { name: 'msgData', type: 'bytes' }, + { name: 'msgValue', type: 'uint256' }, { name: 'nonce', type: 'uint256' }, ], }; const values = { msgData, + msgValue, nonce, }; diff --git a/test/meta/ECDSAMetaTransactionContext.ts b/test/meta/ECDSAMetaTransactionContext.ts index 0a3c3df5..aa34877f 100644 --- a/test/meta/ECDSAMetaTransactionContext.ts +++ b/test/meta/ECDSAMetaTransactionContext.ts @@ -43,16 +43,20 @@ describe('ECDSAMetaTransactionContext', () => { // TODO: test multiple calls in same tx to validate that transient storage is used correctly + // TODO: test msg.value revert cases + describe('__internal', () => { describe('#_msgSender()', () => { it('returns signer if signature is valid', async () => { const data = instance.$_msgSender.fragment.selector; const nonce = 1n; + const value = 0n; const signature = await signECDSAMetaTransaction( instance, signer, data, + value, nonce, ); @@ -94,11 +98,13 @@ describe('ECDSAMetaTransactionContext', () => { it('returns message data without suffix if signature is valid', async () => { const nonSuffixedData = instance.$_msgData.fragment.selector; const nonce = 1n; + const value = 0n; const signature = await signECDSAMetaTransaction( instance, signer, nonSuffixedData, + value, nonce, ); From e71e5e9aeb2abc2a504b1107c473cf6708d515e9 Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Thu, 20 Mar 2025 16:18:18 -0600 Subject: [PATCH 13/39] add failing nonce revert tests --- test/meta/ECDSAMetaTransactionContext.ts | 66 ++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/test/meta/ECDSAMetaTransactionContext.ts b/test/meta/ECDSAMetaTransactionContext.ts index aa34877f..0fee4dca 100644 --- a/test/meta/ECDSAMetaTransactionContext.ts +++ b/test/meta/ECDSAMetaTransactionContext.ts @@ -26,6 +26,18 @@ const callMetaTransaction = async ( ); }; +const sendMetaTransaction = async ( + signer: SignerWithAddress, + fn: TypedContractMethod<[], [string], 'nonpayable' | 'payable' | 'view'>, + data: BytesLike, + args: ContractMethodArgs<[]> = [], +) => { + const tx = await fn.populateTransaction(...args); + tx.data = ethers.concat([tx.data, data]); + + return await signer.sendTransaction(tx); +}; + describe('ECDSAMetaTransactionContext', () => { let instance: $ECDSAMetaTransactionContext; let deployer: SignerWithAddress; @@ -92,6 +104,33 @@ describe('ECDSAMetaTransactionContext', () => { await callMetaTransaction(forwarder, instance.$_msgSender, suffix), ).to.deep.equal([await forwarder.getAddress()]); }); + + describe('reverts if', () => { + it('nonce has been used', async () => { + const data = instance.$_msgSender.fragment.selector; + const nonce = 1n; + const value = 0n; + + const signature = await signECDSAMetaTransaction( + instance, + signer, + data, + value, + nonce, + ); + + const suffix = ethers.concat([ + ethers.toBeHex(nonce, 32), + signature.serialized, + ]); + + await sendMetaTransaction(forwarder, instance.$_msgSender, suffix); + + await expect( + callMetaTransaction(forwarder, instance.$_msgSender, suffix), + ).to.be.revertedWith('TODO'); + }); + }); }); describe('#_msgData()', () => { @@ -146,6 +185,33 @@ describe('ECDSAMetaTransactionContext', () => { await callMetaTransaction(forwarder, instance.$_msgData, suffix), ).to.deep.equal([ethers.concat([nonSuffixedData, suffix])]); }); + + describe('reverts if', () => { + it('nonce has been used', async () => { + const data = instance.$_msgData.fragment.selector; + const nonce = 1n; + const value = 0n; + + const signature = await signECDSAMetaTransaction( + instance, + signer, + data, + value, + nonce, + ); + + const suffix = ethers.concat([ + ethers.toBeHex(nonce, 32), + signature.serialized, + ]); + + await sendMetaTransaction(forwarder, instance.$_msgData, suffix); + + await expect( + callMetaTransaction(forwarder, instance.$_msgData, suffix), + ).to.be.revertedWith('TODO'); + }); + }); }); describe('#_calldataSuffixLength()', () => { From d1169a54841a40b0487b79d60e57a238814cbdeb Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Thu, 20 Mar 2025 16:22:29 -0600 Subject: [PATCH 14/39] test incorrect msg.value --- test/meta/ECDSAMetaTransactionContext.ts | 29 ++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/test/meta/ECDSAMetaTransactionContext.ts b/test/meta/ECDSAMetaTransactionContext.ts index 0fee4dca..7df8a0f7 100644 --- a/test/meta/ECDSAMetaTransactionContext.ts +++ b/test/meta/ECDSAMetaTransactionContext.ts @@ -26,6 +26,8 @@ const callMetaTransaction = async ( ); }; +// TODO: support msg.value in helper functions + const sendMetaTransaction = async ( signer: SignerWithAddress, fn: TypedContractMethod<[], [string], 'nonpayable' | 'payable' | 'view'>, @@ -55,8 +57,6 @@ describe('ECDSAMetaTransactionContext', () => { // TODO: test multiple calls in same tx to validate that transient storage is used correctly - // TODO: test msg.value revert cases - describe('__internal', () => { describe('#_msgSender()', () => { it('returns signer if signature is valid', async () => { @@ -105,6 +105,31 @@ describe('ECDSAMetaTransactionContext', () => { ).to.deep.equal([await forwarder.getAddress()]); }); + it('returns incorrect signer if message value is incorrect', async () => { + const data = instance.$_msgSender.fragment.selector; + const nonce = 1n; + const value = 1n; + + const signature = await signECDSAMetaTransaction( + instance, + signer, + data, + value, + nonce, + ); + + const suffix = ethers.concat([ + ethers.toBeHex(nonce, 32), + signature.serialized, + ]); + + // a valid address is returned, but it is not the correct signer + + expect( + await callMetaTransaction(forwarder, instance.$_msgSender, suffix), + ).not.to.deep.equal([await signer.getAddress()]); + }); + describe('reverts if', () => { it('nonce has been used', async () => { const data = instance.$_msgSender.fragment.selector; From c88d41130137e890d252bddca225147931a73379 Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Thu, 20 Mar 2025 16:40:34 -0600 Subject: [PATCH 15/39] fix comment --- contracts/meta/_ECDSAMetaTransactionContext.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/meta/_ECDSAMetaTransactionContext.sol b/contracts/meta/_ECDSAMetaTransactionContext.sol index f04ac83a..a4f25895 100644 --- a/contracts/meta/_ECDSAMetaTransactionContext.sol +++ b/contracts/meta/_ECDSAMetaTransactionContext.sol @@ -123,7 +123,7 @@ abstract contract _ECDSAMetaTransactionContext is /** * @inheritdoc _Context - * @dev this Context extension defines an address suffix with a length of 20 + * @dev this Context extension defines an address suffix with a length of 97 */ function _calldataSuffixLength() internal From 5bba739a2d45b167209ab83231a0cd3ecb710537 Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Thu, 20 Mar 2025 16:47:03 -0600 Subject: [PATCH 16/39] replae nonce in suffix with expected signer address --- .../meta/_ECDSAMetaTransactionContext.sol | 18 ++++++++++-------- test/meta/ECDSAMetaTransactionContext.ts | 14 +++++++------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/contracts/meta/_ECDSAMetaTransactionContext.sol b/contracts/meta/_ECDSAMetaTransactionContext.sol index a4f25895..54f60e9e 100644 --- a/contracts/meta/_ECDSAMetaTransactionContext.sol +++ b/contracts/meta/_ECDSAMetaTransactionContext.sol @@ -123,7 +123,7 @@ abstract contract _ECDSAMetaTransactionContext is /** * @inheritdoc _Context - * @dev this Context extension defines an address suffix with a length of 97 + * @dev this Context extension defines an address suffix with a length of 85 */ function _calldataSuffixLength() internal @@ -132,7 +132,7 @@ abstract contract _ECDSAMetaTransactionContext is override returns (uint256 length) { - length = 97; + length = 85; } function _processCalldata( @@ -140,8 +140,11 @@ abstract contract _ECDSAMetaTransactionContext is ) private returns (address msgSender, uint256 msgDataIndex) { unchecked { bytes calldata msgData = msg.data[:split]; - uint256 nonce = uint256(bytes32(msg.data[split:split + 32])); - bytes calldata signature = msg.data[split + 32:]; + msgSender = address(bytes20(msg.data[split:split + 20])); + bytes calldata signature = msg.data[split + 20:]; + + // TODO: lookup nonce + uint256 nonce = 1; // TODO: include msg.sender in hash to restrict forwarder? bytes32 structHash = keccak256( @@ -188,12 +191,11 @@ abstract contract _ECDSAMetaTransactionContext is // TODO: invalidate nonce - if (signer == address(0)) { + if (signer == msgSender) { + msgDataIndex = split; + } else { msgSender = super._msgSender(); msgDataIndex = super._msgData().length; - } else { - msgSender = signer; - msgDataIndex = split; } } diff --git a/test/meta/ECDSAMetaTransactionContext.ts b/test/meta/ECDSAMetaTransactionContext.ts index 7df8a0f7..9b943691 100644 --- a/test/meta/ECDSAMetaTransactionContext.ts +++ b/test/meta/ECDSAMetaTransactionContext.ts @@ -73,7 +73,7 @@ describe('ECDSAMetaTransactionContext', () => { ); const suffix = ethers.concat([ - ethers.toBeHex(nonce, 32), + await signer.getAddress(), signature.serialized, ]); @@ -119,7 +119,7 @@ describe('ECDSAMetaTransactionContext', () => { ); const suffix = ethers.concat([ - ethers.toBeHex(nonce, 32), + await signer.getAddress(), signature.serialized, ]); @@ -145,7 +145,7 @@ describe('ECDSAMetaTransactionContext', () => { ); const suffix = ethers.concat([ - ethers.toBeHex(nonce, 32), + await signer.getAddress(), signature.serialized, ]); @@ -173,7 +173,7 @@ describe('ECDSAMetaTransactionContext', () => { ); const suffix = ethers.concat([ - ethers.toBeHex(nonce, 32), + await signer.getAddress(), signature.serialized, ]); @@ -226,7 +226,7 @@ describe('ECDSAMetaTransactionContext', () => { ); const suffix = ethers.concat([ - ethers.toBeHex(nonce, 32), + await signer.getAddress(), signature.serialized, ]); @@ -240,9 +240,9 @@ describe('ECDSAMetaTransactionContext', () => { }); describe('#_calldataSuffixLength()', () => { - it('returns 97', async () => { + it('returns 85', async () => { expect(await instance.$_calldataSuffixLength.staticCall()).to.equal( - 97n, + 85n, ); }); }); From 8db59a21e5792e5baa4296927b1fd0a395107ac4 Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Thu, 20 Mar 2025 17:06:53 -0600 Subject: [PATCH 17/39] update comments --- contracts/meta/_ECDSAMetaTransactionContext.sol | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/contracts/meta/_ECDSAMetaTransactionContext.sol b/contracts/meta/_ECDSAMetaTransactionContext.sol index 54f60e9e..b3a74b1a 100644 --- a/contracts/meta/_ECDSAMetaTransactionContext.sol +++ b/contracts/meta/_ECDSAMetaTransactionContext.sol @@ -79,6 +79,8 @@ abstract contract _ECDSAMetaTransactionContext is } } } else { + // calldata is too short for this to be a valid meta transaction + // return message sender as-is msgSender = super._msgSender(); } } @@ -117,6 +119,8 @@ abstract contract _ECDSAMetaTransactionContext is msgData = msg.data[:split]; } else { + // calldata is too short for this to be a valid meta transaction + // return message data as-is msgData = super._msgData(); } } @@ -143,7 +147,7 @@ abstract contract _ECDSAMetaTransactionContext is msgSender = address(bytes20(msg.data[split:split + 20])); bytes calldata signature = msg.data[split + 20:]; - // TODO: lookup nonce + // TODO: lookup and invalidate nonce uint256 nonce = 1; // TODO: include msg.sender in hash to restrict forwarder? @@ -189,8 +193,6 @@ abstract contract _ECDSAMetaTransactionContext is // TODO: see what happens if split calldata v r s address signer = signedHash.tryRecover(signature); - // TODO: invalidate nonce - if (signer == msgSender) { msgDataIndex = split; } else { @@ -202,6 +204,8 @@ abstract contract _ECDSAMetaTransactionContext is bytes32 slot = ECDSA_META_TRANSACTION_CONTEXT_TRANSIENT_STORAGE_SLOT; assembly { + // it is necessary to store metadata in transient storage because + // subsequent derivation will fail due to none invalidation // TODO: suppress warning // TODO: pack (msgDataIndex as bytes12) tstore(slot, msgSender) From 3650961d2502868205b190fad680f353598897f3 Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Thu, 20 Mar 2025 17:43:52 -0600 Subject: [PATCH 18/39] use toEIP712RecoverableHash utiltity function in ECDSAMetaTransactionContext --- .../meta/_ECDSAMetaTransactionContext.sol | 35 +++---------------- 1 file changed, 5 insertions(+), 30 deletions(-) diff --git a/contracts/meta/_ECDSAMetaTransactionContext.sol b/contracts/meta/_ECDSAMetaTransactionContext.sol index b3a74b1a..39555669 100644 --- a/contracts/meta/_ECDSAMetaTransactionContext.sol +++ b/contracts/meta/_ECDSAMetaTransactionContext.sol @@ -160,38 +160,13 @@ abstract contract _ECDSAMetaTransactionContext is ) ); - bytes32 domainSeparator = EIP712.calculateDomainSeparator_01100(); - - bytes32 signedHash; - - assembly { - // assembly block equivalent to: - // - // signedHash = keccak256( - // abi.encodePacked( - // uint16(0x1901), - // domainSeparator, - // structHash - // ) - // ); - - // load free memory pointer - let pointer := mload(64) - - // this magic value is the EIP-191 signed data header, consisting of - // the hardcoded 0x19 and the one-byte version 0x01 - mstore( - pointer, - 0x1901000000000000000000000000000000000000000000000000000000000000 - ) - mstore(add(pointer, 2), domainSeparator) - mstore(add(pointer, 34), structHash) - - signedHash := keccak256(pointer, 66) - } + bytes32 recoverableHash = ECDSA.toEIP712RecoverableHash( + EIP712.calculateDomainSeparator_01100(), + structHash + ); // TODO: see what happens if split calldata v r s - address signer = signedHash.tryRecover(signature); + address signer = recoverableHash.tryRecover(signature); if (signer == msgSender) { msgDataIndex = split; From 5511b362218ad5eb124f20bc7e434fe947fd6c66 Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Thu, 20 Mar 2025 18:00:41 -0600 Subject: [PATCH 19/39] fix comment --- contracts/meta/_ECDSAMetaTransactionContext.sol | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/contracts/meta/_ECDSAMetaTransactionContext.sol b/contracts/meta/_ECDSAMetaTransactionContext.sol index 39555669..dcff3f41 100644 --- a/contracts/meta/_ECDSAMetaTransactionContext.sol +++ b/contracts/meta/_ECDSAMetaTransactionContext.sol @@ -180,8 +180,7 @@ abstract contract _ECDSAMetaTransactionContext is assembly { // it is necessary to store metadata in transient storage because - // subsequent derivation will fail due to none invalidation - // TODO: suppress warning + // subsequent derivation will fail due to nonce invalidation // TODO: pack (msgDataIndex as bytes12) tstore(slot, msgSender) tstore(add(slot, 1), msgDataIndex) From aa1e2735cb39e20de053ac1a983fd6fbb6e66dfc Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Tue, 25 Mar 2025 21:01:33 -0600 Subject: [PATCH 20/39] update pragma version statements --- contracts/interfaces/IERC2771.sol | 2 +- contracts/interfaces/_IERC2771.sol | 2 +- contracts/meta/Context.sol | 2 +- contracts/meta/ECDSAMetaTransactionContext.sol | 2 +- contracts/meta/ForwardedMetaTransactionContext.sol | 2 +- contracts/meta/IContext.sol | 2 +- contracts/meta/IECDSAMetaTransactionContext.sol | 2 +- contracts/meta/IForwardedMetaTransactionContext.sol | 2 +- contracts/meta/_Context.sol | 2 +- contracts/meta/_ECDSAMetaTransactionContext.sol | 2 +- contracts/meta/_ForwardedMetaTransactionContext.sol | 2 +- contracts/meta/_IContext.sol | 2 +- contracts/meta/_IECDSAMetaTransactionContext.sol | 2 +- contracts/meta/_IForwardedMetaTransactionContext.sol | 2 +- contracts/storage/ERC2771Storage.sol | 2 +- tasks/generate_eip_712.ts | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/contracts/interfaces/IERC2771.sol b/contracts/interfaces/IERC2771.sol index ead7e2f2..52e65a3a 100644 --- a/contracts/interfaces/IERC2771.sol +++ b/contracts/interfaces/IERC2771.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import { _IERC2771 } from './_IERC2771.sol'; diff --git a/contracts/interfaces/_IERC2771.sol b/contracts/interfaces/_IERC2771.sol index eecfcb36..de6532a9 100644 --- a/contracts/interfaces/_IERC2771.sol +++ b/contracts/interfaces/_IERC2771.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; interface _IERC2771 {} diff --git a/contracts/meta/Context.sol b/contracts/meta/Context.sol index 4b71c514..131db583 100644 --- a/contracts/meta/Context.sol +++ b/contracts/meta/Context.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import { IContext } from './IContext.sol'; import { _Context } from './_Context.sol'; diff --git a/contracts/meta/ECDSAMetaTransactionContext.sol b/contracts/meta/ECDSAMetaTransactionContext.sol index 53ea08af..994b97af 100644 --- a/contracts/meta/ECDSAMetaTransactionContext.sol +++ b/contracts/meta/ECDSAMetaTransactionContext.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import { IERC5267 } from '../interfaces/IERC5267.sol'; import { Context } from './Context.sol'; diff --git a/contracts/meta/ForwardedMetaTransactionContext.sol b/contracts/meta/ForwardedMetaTransactionContext.sol index 4a2a09d4..a06a673d 100644 --- a/contracts/meta/ForwardedMetaTransactionContext.sol +++ b/contracts/meta/ForwardedMetaTransactionContext.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import { IERC2771 } from '../interfaces/IERC2771.sol'; import { Context } from './Context.sol'; diff --git a/contracts/meta/IContext.sol b/contracts/meta/IContext.sol index 8cfd70e1..b089eba4 100644 --- a/contracts/meta/IContext.sol +++ b/contracts/meta/IContext.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import { _IContext } from './_IContext.sol'; diff --git a/contracts/meta/IECDSAMetaTransactionContext.sol b/contracts/meta/IECDSAMetaTransactionContext.sol index 97a769aa..2fdf9d7c 100644 --- a/contracts/meta/IECDSAMetaTransactionContext.sol +++ b/contracts/meta/IECDSAMetaTransactionContext.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import { IERC5267 } from '../interfaces/IERC5267.sol'; import { IContext } from './IContext.sol'; diff --git a/contracts/meta/IForwardedMetaTransactionContext.sol b/contracts/meta/IForwardedMetaTransactionContext.sol index 79e83273..ca2dbbb5 100644 --- a/contracts/meta/IForwardedMetaTransactionContext.sol +++ b/contracts/meta/IForwardedMetaTransactionContext.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import { IERC2771 } from '../interfaces/IERC2771.sol'; import { IContext } from './IContext.sol'; diff --git a/contracts/meta/_Context.sol b/contracts/meta/_Context.sol index 3b2f6669..7fc4ed8e 100644 --- a/contracts/meta/_Context.sol +++ b/contracts/meta/_Context.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import { _IContext } from './_IContext.sol'; diff --git a/contracts/meta/_ECDSAMetaTransactionContext.sol b/contracts/meta/_ECDSAMetaTransactionContext.sol index dcff3f41..c9f61f66 100644 --- a/contracts/meta/_ECDSAMetaTransactionContext.sol +++ b/contracts/meta/_ECDSAMetaTransactionContext.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import { ECDSA } from '../cryptography/ECDSA.sol'; import { EIP712 } from '../cryptography/EIP712.sol'; diff --git a/contracts/meta/_ForwardedMetaTransactionContext.sol b/contracts/meta/_ForwardedMetaTransactionContext.sol index 3cd90d67..c42411bf 100644 --- a/contracts/meta/_ForwardedMetaTransactionContext.sol +++ b/contracts/meta/_ForwardedMetaTransactionContext.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import { ERC2771Storage } from '../storage/ERC2771Storage.sol'; import { Address } from '../utils/Address.sol'; diff --git a/contracts/meta/_IContext.sol b/contracts/meta/_IContext.sol index c1a25789..08e10713 100644 --- a/contracts/meta/_IContext.sol +++ b/contracts/meta/_IContext.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; interface _IContext {} diff --git a/contracts/meta/_IECDSAMetaTransactionContext.sol b/contracts/meta/_IECDSAMetaTransactionContext.sol index a9abf4ea..dbf3702a 100644 --- a/contracts/meta/_IECDSAMetaTransactionContext.sol +++ b/contracts/meta/_IECDSAMetaTransactionContext.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import { _IERC5267 } from '../interfaces/_IERC5267.sol'; import { _IContext } from './_IContext.sol'; diff --git a/contracts/meta/_IForwardedMetaTransactionContext.sol b/contracts/meta/_IForwardedMetaTransactionContext.sol index 861b3f57..d442deaa 100644 --- a/contracts/meta/_IForwardedMetaTransactionContext.sol +++ b/contracts/meta/_IForwardedMetaTransactionContext.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import { _IERC2771 } from '../interfaces/_IERC2771.sol'; import { _IContext } from './_IContext.sol'; diff --git a/contracts/storage/ERC2771Storage.sol b/contracts/storage/ERC2771Storage.sol index 6b86c25d..a388cfd5 100644 --- a/contracts/storage/ERC2771Storage.sol +++ b/contracts/storage/ERC2771Storage.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; library ERC2771Storage { /** diff --git a/tasks/generate_eip_712.ts b/tasks/generate_eip_712.ts index 6461e15a..1b269d9c 100644 --- a/tasks/generate_eip_712.ts +++ b/tasks/generate_eip_712.ts @@ -7,7 +7,7 @@ const name = 'EIP712'; const filepath = 'cryptography'; const TEMPLATE_SOL = ` -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /** * @title Procedurally generated EIP-712 typed structured data hashing and signing library From ef68de5b7fd21da6fd080d514b228db36a912c02 Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Tue, 25 Mar 2025 21:42:17 -0600 Subject: [PATCH 21/39] use Slot for ECDSAMetaTransactionContext --- .../meta/_ECDSAMetaTransactionContext.sol | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/contracts/meta/_ECDSAMetaTransactionContext.sol b/contracts/meta/_ECDSAMetaTransactionContext.sol index c9f61f66..4aa35e85 100644 --- a/contracts/meta/_ECDSAMetaTransactionContext.sol +++ b/contracts/meta/_ECDSAMetaTransactionContext.sol @@ -4,6 +4,8 @@ pragma solidity ^0.8.24; import { ECDSA } from '../cryptography/ECDSA.sol'; import { EIP712 } from '../cryptography/EIP712.sol'; +import { Slot } from '../data/Slot.sol'; +import { Bytes32 } from '../utils/Bytes32.sol'; import { _Context } from './_Context.sol'; import { _IECDSAMetaTransactionContext } from './_IECDSAMetaTransactionContext.sol'; @@ -11,17 +13,20 @@ abstract contract _ECDSAMetaTransactionContext is _IECDSAMetaTransactionContext, _Context { + using Bytes32 for bytes32; using ECDSA for bytes32; + using Slot for Slot.TransientSlot; bytes32 internal constant EIP_712_TYPE_HASH = keccak256( 'ECDSAMetaTransaction(bytes msgData,uint256 msgValue,uint256 nonce)' ); - bytes32 - internal constant ECDSA_META_TRANSACTION_CONTEXT_TRANSIENT_STORAGE_SLOT = - keccak256(abi.encode(uint256(EIP_712_TYPE_HASH) - 1)) & - ~bytes32(uint256(0xff)); + Slot.TransientSlot private constant TRANSIENT_SLOT = + Slot.TransientSlot.wrap( + keccak256(abi.encode(uint256(EIP_712_TYPE_HASH) - 1)) & + ~bytes32(uint256(0xff)) + ); function _eip712Domain() internal @@ -65,11 +70,8 @@ abstract contract _ECDSAMetaTransactionContext is // calldata is long enough that it might have a suffix // check transient storage to see if sender has been derived already - bytes32 slot = ECDSA_META_TRANSACTION_CONTEXT_TRANSIENT_STORAGE_SLOT; - - assembly { - msgSender := tload(slot) - } + // toAddress function strips the packed msgDataIndex data and returns a clean address + msgSender = TRANSIENT_SLOT.read().toAddress(); if (msgSender == address(0)) { // no sender found in transient storage, so attempt to derive it from signature @@ -103,11 +105,8 @@ abstract contract _ECDSAMetaTransactionContext is uint256 split; - bytes32 slot = ECDSA_META_TRANSACTION_CONTEXT_TRANSIENT_STORAGE_SLOT; - - assembly { - split := tload(add(slot, 1)) - } + // unpack the msgDataIndex which is stored alongside msgSender + split = (TRANSIENT_SLOT.read() >> 160).toUint256(); if (split == 0) { // no msgData split index found in transient storage, so attempt to derive it from signature @@ -176,14 +175,15 @@ abstract contract _ECDSAMetaTransactionContext is } } - bytes32 slot = ECDSA_META_TRANSACTION_CONTEXT_TRANSIENT_STORAGE_SLOT; + bytes32 data; assembly { - // it is necessary to store metadata in transient storage because - // subsequent derivation will fail due to nonce invalidation - // TODO: pack (msgDataIndex as bytes12) - tstore(slot, msgSender) - tstore(add(slot, 1), msgDataIndex) + // pack msgDataIndex into the 12 bytes available alongside msgSender + data := and(msgSender, shl(160, msgDataIndex)) } + + // it is necessary to store metadata in transient storage because + // subsequent derivation will fail due to nonce invalidation + TRANSIENT_SLOT.write(data); } } From 6d88bfd40ce717a825990d322cc340898e307136 Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Wed, 26 Mar 2025 21:48:32 -0600 Subject: [PATCH 22/39] add generator for Bytes32Builder library --- hardhat.config.ts | 1 + tasks/generate_bytes32_builder.ts | 246 ++++++++++++++++++++++++++++++ 2 files changed, 247 insertions(+) create mode 100644 tasks/generate_bytes32_builder.ts diff --git a/hardhat.config.ts b/hardhat.config.ts index 80af0d44..c9298264 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -1,3 +1,4 @@ +import './tasks/generate_bytes32_builder'; import './tasks/rename_entity'; import './tasks/scaffold_contract'; import '@nomicfoundation/hardhat-chai-matchers'; diff --git a/tasks/generate_bytes32_builder.ts b/tasks/generate_bytes32_builder.ts new file mode 100644 index 00000000..2ff15f20 --- /dev/null +++ b/tasks/generate_bytes32_builder.ts @@ -0,0 +1,246 @@ +import ejs from 'ejs'; +import fs from 'fs'; +import { task } from 'hardhat/config'; +import path from 'path'; + +const libraryName = 'Bytes32Builder'; +const structName = 'Builder'; +const filepath = 'data'; + +const TEMPLATE_SOL = ` +pragma solidity ^0.8.24; + +import { Address } from '../utils/Address.sol'; +import { Bool } from '../utils/Bool.sol'; +import { Bytes32 } from '../utils/Bytes32.sol'; +import { Int256 } from '../utils/Int256.sol'; +import { Uint256 } from '../utils/Uint256.sol'; + +/** + * @title Procedurally generated library for packing primitive types into bytes32 + **/ +library <%- libraryName %> { + struct <%- structName %> { + bytes32 _data; + uint256 _size; + } + + <%_ for (const type of types) { _%> + /** + * @notice insert <%- type.name %> value to <%- type.size / 8 %>-byte position at end of bytes + * @param self <%- libraryName %> <%- structName %> struct on which to operate + * @param element <%- type.name %> to add + */ + function push<%- type.nameUpcase %>(<%- structName %> memory self, <%- type.name %> element) internal pure { + unchecked { + self._data |= <%- type.castTo %> << self._size; + self._size += <%- type.size %>; + } + } + + /** + * @notice remove last <%- type.size / 8 %>-byte segment from bytes and return as <%- type.name %> + * @param self <%- libraryName %> <%- structName %> struct on which to operate + * @return element <%- type.name %> derived from bytes + */ + function pop<%- type.nameUpcase %>(<%- structName %> memory self) internal pure returns (<%- type.name %> element) { + unchecked { + self._size -= <%- type.size %>; + element = <%- type.name %>(<%= type.castFrom %>(self._data & (bytes32(hex'<%- 'ff'.repeat(type.size / 8) %>') << self._size))); + self._data &= ~(bytes32(0x<%- '00'.repeat((256 - type.size) / 8) + 'ff'.repeat(type.size / 8) %>) << self._size); + } + } + + /** + * @notice remove first <%- type.size / 8 %>-byte segment from bytes and return as <%- type.name %> + * @param self <%- libraryName %> <%- structName %> struct on which to operate + * @return element <%- type.name %> derived from bytes + */ + function shift<%- type.nameUpcase %>(<%- structName %> memory self) internal pure returns (<%- type.name %> element) { + unchecked { + element = <%- type.name %>(<%- type.castFrom %>(self._data & bytes32(0x<%- '00'.repeat((256 - type.size) / 8) + 'ff'.repeat(type.size / 8) %>))); + self._data >>= <%- type.size %>; + self._size -= <%- type.size %>; + } + } + + /** + * @notice insert <%- type.name %> value to <%- type.size / 8 %>-byte position at beginning of bytes + * @param self <%- libraryName %> <%- structName %> struct on which to operate + * @param element <%- type.name %> to add + */ + function unshift<%- type.nameUpcase %>(<%- structName %> memory self, <%- type.name %> element) internal pure { + unchecked { + self._data = (self._data << <%- type.size %>) | <%- type.castTo %>; + self._size += <%- type.size %>; + } + } + <%_ } _%> +} +`; + +const TEMPLATE_SOL_TEST = ` +pragma solidity ^0.8.24; + +import { <%- libraryName %> } from '../<%- filepath %>/<%- libraryName %>.sol'; + +/** + * @title Procedurally generated <%- libraryName %> test contract + * @dev custom solution is required because there is no other way to access memory struct post-operation + **/ +contract <%- libraryName %>Test { + using <%- libraryName %> for <%- libraryName %>.<%- structName %>; + + <%_ for (const type of types) { _%> + function push<%- type.nameUpcase %>(<%- type.name %> element) external pure returns (<%- libraryName %>.<%- structName %> memory output) { + output.push<%- type.nameUpcase %>(element); + } + + function pop<%- type.nameUpcase %>() external pure returns (<%- libraryName %>.<%- structName %> memory output, <%- type.name %> element) { + element = output.pop<%- type.nameUpcase %>(); + } + + function shift<%- type.nameUpcase %>() external pure returns (<%- libraryName %>.<%- structName %> memory output, <%- type.name %> element) { + element = output.shift<%- type.nameUpcase %>(); + } + + function unshift<%- type.nameUpcase %>(<%- type.name %> element) external pure returns (<%- libraryName %>.<%- structName %> memory output) { + output.unshift<%- type.nameUpcase %>(element); + } + <%_ } _%> +} +`; + +const TEMPLATE_TS = ` +import { <%- libraryName %>Test, <%- libraryName %>Test__factory } from '@solidstate/typechain-types'; +import { expect } from 'chai'; +import { ethers } from 'hardhat'; + +describe('<%- libraryName %>', () => { + let instance: <%- libraryName %>Test; + + before(async () => { + const [deployer] = await ethers.getSigners(); + instance = await new <%- libraryName %>Test__factory(deployer).deploy(); + }); + + <%_ for (const type of types) { _%> + describe('#push<%- type.nameUpcase %>(bytes32,<%- type.name %>)', () => { + it.skip('inserts <%- type.name %> at end of bytes', async () => { + expect(await instance.push<%- type.nameUpcase %>) + }); + }); + <%_ } _%> + + <%_ for (const type of types) { _%> + describe('#pop<%- type.nameUpcase %>(bytes32,<%- type.name %>)', () => { + it.skip('removes <%- type.name %> from end of bytes', async () => { + expect(await instance.pop<%- type.nameUpcase %>) + }); + }); + <%_ } _%> + + <%_ for (const type of types) { _%> + describe('#shift<%- type.nameUpcase %>(bytes32,<%- type.name %>)', () => { + it.skip('removes <%- type.name %> from beginning of bytes', async () => { + expect(await instance.shift<%- type.nameUpcase %>) + }); + }); + <%_ } _%> + + <%_ for (const type of types) { _%> + describe('#unshift<%- type.nameUpcase %>(bytes32,<%- type.name %>)', () => { + it.skip('inserts <%- type.name %> at beginning of bytes', async () => { + expect(await instance.unshift<%- type.nameUpcase %>); + }); + }); + <%_ } _%> +}); +`; + +task('generate-bytes32-builder', `Generate ${libraryName}`).setAction( + async (args, hre) => { + const typesBySize = Array(32) + .fill(0) + .map((el, i) => [ + `bytes${i + 1}`, + `int${(i + 1) * 8}`, + `uint${(i + 1) * 8}`, + ]); + + typesBySize[0].push('bool'); + typesBySize[19].push('address'); + + interface Type { + name: string; + nameUpcase: string; + size: number; + castTo: string; + castFrom: string; + } + + const types: Type[] = typesBySize.reduce((acc, typesOfSize, i) => { + return typesOfSize.reduce((acc, type) => { + const name = type; + const size = (i + 1) * 8; + let castTo; + let castFrom; + + if (name.startsWith('bytes')) { + castTo = `bytes32(element) >> ${256 - size}`; + castFrom = ''; + } else if (name.startsWith('int')) { + castTo = 'Int256.toBytes32(element)'; + castFrom = 'Bytes32.toInt256'; + } else if (name.startsWith('uint')) { + castTo = 'Uint256.toBytes32(element)'; + castFrom = 'Bytes32.toUint256'; + } else if (name === 'address') { + castTo = 'Address.toBytes32(element)'; + castFrom = 'Bytes32.toAddress'; + } else if (name === 'bool') { + castTo = 'Bool.toBytes32(element)'; + castFrom = 'Bytes32.toBool'; + } else { + throw 'invalid type'; + } + + acc.push({ + name, + nameUpcase: name.charAt(0).toUpperCase() + name.slice(1), + size, + castTo, + castFrom, + }); + return acc; + }, acc); + }, [] as Type[]); + + const templateData = { + libraryName, + structName, + filepath, + types, + }; + + const generate = async (outputPath: string, content: string) => { + await fs.promises.mkdir(path.dirname(outputPath), { recursive: true }); + await fs.promises.writeFile(outputPath, content); + }; + + await generate( + path.resolve(hre.config.paths.sources, filepath, `${libraryName}.sol`), + ejs.render(TEMPLATE_SOL, templateData), + ); + + await generate( + path.resolve(hre.config.paths.sources, 'test', `${libraryName}Test.sol`), + ejs.render(TEMPLATE_SOL_TEST, templateData), + ); + + await generate( + path.resolve(hre.config.paths.tests, filepath, `${libraryName}.ts`), + ejs.render(TEMPLATE_TS, templateData), + ); + }, +); From 2fc26aa005f1566b425210674e56db83752e782b Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Wed, 26 Mar 2025 21:48:46 -0600 Subject: [PATCH 23/39] allow unlimited contract size on hardhat network --- hardhat.config.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/hardhat.config.ts b/hardhat.config.ts index c9298264..de7bbf8b 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -15,6 +15,12 @@ import { HardhatUserConfig } from 'hardhat/types'; import 'solidity-coverage'; const config: HardhatUserConfig = { + networks: { + hardhat: { + allowUnlimitedContractSize: true, + }, + }, + solidity: { version: '0.8.29', settings: { From 983f584abbdfd2e64b2284d1c902c4426f9e9378 Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Thu, 27 Mar 2025 00:47:16 -0600 Subject: [PATCH 24/39] test and fix push function --- tasks/generate_bytes32_builder.ts | 60 +++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 11 deletions(-) diff --git a/tasks/generate_bytes32_builder.ts b/tasks/generate_bytes32_builder.ts index 2ff15f20..4e8c777e 100644 --- a/tasks/generate_bytes32_builder.ts +++ b/tasks/generate_bytes32_builder.ts @@ -33,7 +33,7 @@ library <%- libraryName %> { */ function push<%- type.nameUpcase %>(<%- structName %> memory self, <%- type.name %> element) internal pure { unchecked { - self._data |= <%- type.castTo %> << self._size; + self._data |= (<%- type.castTo %> & (~bytes32(0) >> <%- 256 - type.size %>)) << self._size; self._size += <%- type.size %>; } } @@ -92,20 +92,24 @@ contract <%- libraryName %>Test { using <%- libraryName %> for <%- libraryName %>.<%- structName %>; <%_ for (const type of types) { _%> - function push<%- type.nameUpcase %>(<%- type.name %> element) external pure returns (<%- libraryName %>.<%- structName %> memory output) { - output.push<%- type.nameUpcase %>(element); + function push<%- type.nameUpcase %>(<%- libraryName %>.<%- structName %> memory self, <%- type.name %> element) external pure returns (<%- libraryName %>.<%- structName %> memory) { + self.push<%- type.nameUpcase %>(element); + return self; } - function pop<%- type.nameUpcase %>() external pure returns (<%- libraryName %>.<%- structName %> memory output, <%- type.name %> element) { - element = output.pop<%- type.nameUpcase %>(); + function pop<%- type.nameUpcase %>(<%- libraryName %>.<%- structName %> memory self) external pure returns (<%- libraryName %>.<%- structName %> memory, <%- type.name %> element) { + element = self.pop<%- type.nameUpcase %>(); + return (self, element); } - function shift<%- type.nameUpcase %>() external pure returns (<%- libraryName %>.<%- structName %> memory output, <%- type.name %> element) { - element = output.shift<%- type.nameUpcase %>(); + function shift<%- type.nameUpcase %>(<%- libraryName %>.<%- structName %> memory self) external pure returns (<%- libraryName %>.<%- structName %> memory, <%- type.name %> element) { + element = self.shift<%- type.nameUpcase %>(); + return (self, element); } - function unshift<%- type.nameUpcase %>(<%- type.name %> element) external pure returns (<%- libraryName %>.<%- structName %> memory output) { - output.unshift<%- type.nameUpcase %>(element); + function unshift<%- type.nameUpcase %>(<%- libraryName %>.<%- structName %> memory self, <%- type.name %> element) external pure returns (<%- libraryName %>.<%- structName %> memory) { + self.unshift<%- type.nameUpcase %>(element); + return self; } <%_ } _%> } @@ -126,8 +130,42 @@ describe('<%- libraryName %>', () => { <%_ for (const type of types) { _%> describe('#push<%- type.nameUpcase %>(bytes32,<%- type.name %>)', () => { - it.skip('inserts <%- type.name %> at end of bytes', async () => { - expect(await instance.push<%- type.nameUpcase %>) + it('inserts <%- type.name %> at end of bytes', async () => { + const size = <%- type.size / 8 %>; + <%_ if (type.name === 'bool') { _%> + const data = '0x01'; + const input = true; + <%_ } else if (type.name.startsWith('int')) { _%> + const data = ethers.hexlify(ethers.randomBytes(size)); + const negative = BigInt(data) >> BigInt(size * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(size * 8) - BigInt(data)) + } else { + input = BigInt(data); + } + <%_ } else { _%> + const data = ethers.hexlify(ethers.randomBytes(size)); + const input = data; + <%_ } _%> + + for (let i = 0; i <= 32 - size; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + } + + const expectedData = ethers.zeroPadValue(ethers.concat([data, ethers.dataSlice(state._data, 32 - state._size / 8, 32)]), 32); + const expectedLength = state._size + size * 8; + + const output = await instance.push<%- type.nameUpcase %>(state, input); + + expect( + output + ).to.deep.equal( + [expectedData, expectedLength] + ); + } }); }); <%_ } _%> From 43b4bbd7de232b1376cb22d88cff36432c5cdac3 Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Thu, 27 Mar 2025 00:50:46 -0600 Subject: [PATCH 25/39] test and fix unshift function --- tasks/generate_bytes32_builder.ts | 42 ++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/tasks/generate_bytes32_builder.ts b/tasks/generate_bytes32_builder.ts index 4e8c777e..edc17d33 100644 --- a/tasks/generate_bytes32_builder.ts +++ b/tasks/generate_bytes32_builder.ts @@ -71,7 +71,7 @@ library <%- libraryName %> { */ function unshift<%- type.nameUpcase %>(<%- structName %> memory self, <%- type.name %> element) internal pure { unchecked { - self._data = (self._data << <%- type.size %>) | <%- type.castTo %>; + self._data = (self._data << <%- type.size %>) | (<%- type.castTo %> & (~bytes32(0) >> <%- 256 - type.size %>)); self._size += <%- type.size %>; } } @@ -181,15 +181,49 @@ describe('<%- libraryName %>', () => { <%_ for (const type of types) { _%> describe('#shift<%- type.nameUpcase %>(bytes32,<%- type.name %>)', () => { it.skip('removes <%- type.name %> from beginning of bytes', async () => { - expect(await instance.shift<%- type.nameUpcase %>) + expect(!await instance.shift<%- type.nameUpcase %>) }); }); <%_ } _%> <%_ for (const type of types) { _%> describe('#unshift<%- type.nameUpcase %>(bytes32,<%- type.name %>)', () => { - it.skip('inserts <%- type.name %> at beginning of bytes', async () => { - expect(await instance.unshift<%- type.nameUpcase %>); + it('inserts <%- type.name %> at beginning of bytes', async () => { + const size = <%- type.size / 8 %>; + <%_ if (type.name === 'bool') { _%> + const data = '0x01'; + const input = true; + <%_ } else if (type.name.startsWith('int')) { _%> + const data = ethers.hexlify(ethers.randomBytes(size)); + const negative = BigInt(data) >> BigInt(size * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(size * 8) - BigInt(data)) + } else { + input = BigInt(data); + } + <%_ } else { _%> + const data = ethers.hexlify(ethers.randomBytes(size)); + const input = data; + <%_ } _%> + + for (let i = 0; i <= 32 - size; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + } + + const expectedData = ethers.zeroPadValue(ethers.concat([ethers.dataSlice(state._data, 32 - state._size / 8, 32), data]), 32); + const expectedLength = state._size + size * 8; + + const output = await instance.unshift<%- type.nameUpcase %>(state, input); + + expect( + output + ).to.deep.equal( + [expectedData, expectedLength] + ); + } }); }); <%_ } _%> From 20927d7ba4db082861b11460f6d9bec0f1041f01 Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Thu, 27 Mar 2025 00:58:20 -0600 Subject: [PATCH 26/39] move masking to int cast fragment --- tasks/generate_bytes32_builder.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tasks/generate_bytes32_builder.ts b/tasks/generate_bytes32_builder.ts index edc17d33..6319b3c5 100644 --- a/tasks/generate_bytes32_builder.ts +++ b/tasks/generate_bytes32_builder.ts @@ -33,7 +33,7 @@ library <%- libraryName %> { */ function push<%- type.nameUpcase %>(<%- structName %> memory self, <%- type.name %> element) internal pure { unchecked { - self._data |= (<%- type.castTo %> & (~bytes32(0) >> <%- 256 - type.size %>)) << self._size; + self._data |= <%- type.castTo %> << self._size; self._size += <%- type.size %>; } } @@ -71,7 +71,7 @@ library <%- libraryName %> { */ function unshift<%- type.nameUpcase %>(<%- structName %> memory self, <%- type.name %> element) internal pure { unchecked { - self._data = (self._data << <%- type.size %>) | (<%- type.castTo %> & (~bytes32(0) >> <%- 256 - type.size %>)); + self._data = (self._data << <%- type.size %>) | <%- type.castTo %>; self._size += <%- type.size %>; } } @@ -181,7 +181,7 @@ describe('<%- libraryName %>', () => { <%_ for (const type of types) { _%> describe('#shift<%- type.nameUpcase %>(bytes32,<%- type.name %>)', () => { it.skip('removes <%- type.name %> from beginning of bytes', async () => { - expect(!await instance.shift<%- type.nameUpcase %>) + expect(await instance.shift<%- type.nameUpcase %>) }); }); <%_ } _%> @@ -262,7 +262,7 @@ task('generate-bytes32-builder', `Generate ${libraryName}`).setAction( castTo = `bytes32(element) >> ${256 - size}`; castFrom = ''; } else if (name.startsWith('int')) { - castTo = 'Int256.toBytes32(element)'; + castTo = `(Int256.toBytes32(element) & (~bytes32(0) >> ${256 - size}))`; castFrom = 'Bytes32.toInt256'; } else if (name.startsWith('uint')) { castTo = 'Uint256.toBytes32(element)'; From 29321d1182cbbe47494e9733dda412e290c6c837 Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Thu, 27 Mar 2025 01:59:09 -0600 Subject: [PATCH 27/39] generate masks --- tasks/generate_bytes32_builder.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tasks/generate_bytes32_builder.ts b/tasks/generate_bytes32_builder.ts index 6319b3c5..a3905a0b 100644 --- a/tasks/generate_bytes32_builder.ts +++ b/tasks/generate_bytes32_builder.ts @@ -25,6 +25,10 @@ library <%- libraryName %> { uint256 _size; } + <%_ for (let i = 1; i <= 32; i++ ) { _%> + bytes32 private constant MASK_<%- i.toString().padStart(2, '0') %> = 0x<%- '00'.repeat(32 - i) + 'ff'.repeat(i) %>; + <%_ } _%> + <%_ for (const type of types) { _%> /** * @notice insert <%- type.name %> value to <%- type.size / 8 %>-byte position at end of bytes @@ -46,8 +50,9 @@ library <%- libraryName %> { function pop<%- type.nameUpcase %>(<%- structName %> memory self) internal pure returns (<%- type.name %> element) { unchecked { self._size -= <%- type.size %>; - element = <%- type.name %>(<%= type.castFrom %>(self._data & (bytes32(hex'<%- 'ff'.repeat(type.size / 8) %>') << self._size))); - self._data &= ~(bytes32(0x<%- '00'.repeat((256 - type.size) / 8) + 'ff'.repeat(type.size / 8) %>) << self._size); + bytes32 mask = MASK_<%- (type.size / 8).toString().padStart(2, '0') %>; + element = <%- type.name %>(<%= type.castFrom %>((self._data >> self._size) & mask)); + self._data &= ~(mask << self._size); } } @@ -58,7 +63,8 @@ library <%- libraryName %> { */ function shift<%- type.nameUpcase %>(<%- structName %> memory self) internal pure returns (<%- type.name %> element) { unchecked { - element = <%- type.name %>(<%- type.castFrom %>(self._data & bytes32(0x<%- '00'.repeat((256 - type.size) / 8) + 'ff'.repeat(type.size / 8) %>))); + bytes32 mask = MASK_<%- (type.size / 8).toString().padStart(2, '0') %>; + element = <%- type.name %>(<%- type.castFrom %>(self._data & mask)); self._data >>= <%- type.size %>; self._size -= <%- type.size %>; } From e24f7b5591f0155252da8ce061e772ed8109fcb7 Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Thu, 27 Mar 2025 02:03:14 -0600 Subject: [PATCH 28/39] clarify size variables --- tasks/generate_bytes32_builder.ts | 73 +++++++++++++++---------------- 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/tasks/generate_bytes32_builder.ts b/tasks/generate_bytes32_builder.ts index a3905a0b..479d191e 100644 --- a/tasks/generate_bytes32_builder.ts +++ b/tasks/generate_bytes32_builder.ts @@ -31,54 +31,54 @@ library <%- libraryName %> { <%_ for (const type of types) { _%> /** - * @notice insert <%- type.name %> value to <%- type.size / 8 %>-byte position at end of bytes + * @notice insert <%- type.name %> value to <%- type.sizeBytes %>-byte position at end of bytes * @param self <%- libraryName %> <%- structName %> struct on which to operate * @param element <%- type.name %> to add */ function push<%- type.nameUpcase %>(<%- structName %> memory self, <%- type.name %> element) internal pure { unchecked { self._data |= <%- type.castTo %> << self._size; - self._size += <%- type.size %>; + self._size += <%- type.sizeBits %>; } } /** - * @notice remove last <%- type.size / 8 %>-byte segment from bytes and return as <%- type.name %> + * @notice remove last <%- type.sizeBytes %>-byte segment from bytes and return as <%- type.name %> * @param self <%- libraryName %> <%- structName %> struct on which to operate * @return element <%- type.name %> derived from bytes */ function pop<%- type.nameUpcase %>(<%- structName %> memory self) internal pure returns (<%- type.name %> element) { unchecked { - self._size -= <%- type.size %>; - bytes32 mask = MASK_<%- (type.size / 8).toString().padStart(2, '0') %>; + self._size -= <%- type.sizeBits %>; + bytes32 mask = MASK_<%- (type.sizeBytes).toString().padStart(2, '0') %>; element = <%- type.name %>(<%= type.castFrom %>((self._data >> self._size) & mask)); self._data &= ~(mask << self._size); } } /** - * @notice remove first <%- type.size / 8 %>-byte segment from bytes and return as <%- type.name %> + * @notice remove first <%- type.sizeBytes %>-byte segment from bytes and return as <%- type.name %> * @param self <%- libraryName %> <%- structName %> struct on which to operate * @return element <%- type.name %> derived from bytes */ function shift<%- type.nameUpcase %>(<%- structName %> memory self) internal pure returns (<%- type.name %> element) { unchecked { - bytes32 mask = MASK_<%- (type.size / 8).toString().padStart(2, '0') %>; + bytes32 mask = MASK_<%- (type.sizeBytes).toString().padStart(2, '0') %>; element = <%- type.name %>(<%- type.castFrom %>(self._data & mask)); - self._data >>= <%- type.size %>; - self._size -= <%- type.size %>; + self._data >>= <%- type.sizeBits %>; + self._size -= <%- type.sizeBits %>; } } /** - * @notice insert <%- type.name %> value to <%- type.size / 8 %>-byte position at beginning of bytes + * @notice insert <%- type.name %> value to <%- type.sizeBytes %>-byte position at beginning of bytes * @param self <%- libraryName %> <%- structName %> struct on which to operate * @param element <%- type.name %> to add */ function unshift<%- type.nameUpcase %>(<%- structName %> memory self, <%- type.name %> element) internal pure { unchecked { - self._data = (self._data << <%- type.size %>) | <%- type.castTo %>; - self._size += <%- type.size %>; + self._data = (self._data << <%- type.sizeBits %>) | <%- type.castTo %>; + self._size += <%- type.sizeBits %>; } } <%_ } _%> @@ -137,37 +137,35 @@ describe('<%- libraryName %>', () => { <%_ for (const type of types) { _%> describe('#push<%- type.nameUpcase %>(bytes32,<%- type.name %>)', () => { it('inserts <%- type.name %> at end of bytes', async () => { - const size = <%- type.size / 8 %>; + const sizeBytes = <%- type.sizeBytes %>; <%_ if (type.name === 'bool') { _%> const data = '0x01'; const input = true; <%_ } else if (type.name.startsWith('int')) { _%> - const data = ethers.hexlify(ethers.randomBytes(size)); - const negative = BigInt(data) >> BigInt(size * 8 - 1) === 1n; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; let input; if (negative) { - input = -(2n ** BigInt(size * 8) - BigInt(data)) + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)) } else { input = BigInt(data); } <%_ } else { _%> - const data = ethers.hexlify(ethers.randomBytes(size)); + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); const input = data; <%_ } _%> - for (let i = 0; i <= 32 - size; i++) { + for (let i = 0; i <= 32 - sizeBytes; i++) { const state = { _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), _size: i * 8, } const expectedData = ethers.zeroPadValue(ethers.concat([data, ethers.dataSlice(state._data, 32 - state._size / 8, 32)]), 32); - const expectedLength = state._size + size * 8; - - const output = await instance.push<%- type.nameUpcase %>(state, input); + const expectedLength = state._size + sizeBytes * 8; expect( - output + await instance.push<%- type.nameUpcase %>(state, input) ).to.deep.equal( [expectedData, expectedLength] ); @@ -195,37 +193,35 @@ describe('<%- libraryName %>', () => { <%_ for (const type of types) { _%> describe('#unshift<%- type.nameUpcase %>(bytes32,<%- type.name %>)', () => { it('inserts <%- type.name %> at beginning of bytes', async () => { - const size = <%- type.size / 8 %>; + const sizeBytes = <%- type.sizeBytes %>; <%_ if (type.name === 'bool') { _%> const data = '0x01'; const input = true; <%_ } else if (type.name.startsWith('int')) { _%> - const data = ethers.hexlify(ethers.randomBytes(size)); - const negative = BigInt(data) >> BigInt(size * 8 - 1) === 1n; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; let input; if (negative) { - input = -(2n ** BigInt(size * 8) - BigInt(data)) + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)) } else { input = BigInt(data); } <%_ } else { _%> - const data = ethers.hexlify(ethers.randomBytes(size)); + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); const input = data; <%_ } _%> - for (let i = 0; i <= 32 - size; i++) { + for (let i = 0; i <= 32 - sizeBytes; i++) { const state = { _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), _size: i * 8, } const expectedData = ethers.zeroPadValue(ethers.concat([ethers.dataSlice(state._data, 32 - state._size / 8, 32), data]), 32); - const expectedLength = state._size + size * 8; - - const output = await instance.unshift<%- type.nameUpcase %>(state, input); + const expectedLength = state._size + sizeBytes * 8; expect( - output + await instance.unshift<%- type.nameUpcase %>(state, input) ).to.deep.equal( [expectedData, expectedLength] ); @@ -252,7 +248,8 @@ task('generate-bytes32-builder', `Generate ${libraryName}`).setAction( interface Type { name: string; nameUpcase: string; - size: number; + sizeBits: number; + sizeBytes: number; castTo: string; castFrom: string; } @@ -260,15 +257,16 @@ task('generate-bytes32-builder', `Generate ${libraryName}`).setAction( const types: Type[] = typesBySize.reduce((acc, typesOfSize, i) => { return typesOfSize.reduce((acc, type) => { const name = type; - const size = (i + 1) * 8; + const sizeBytes = (i = 1); + const sizeBits = sizeBytes * 8; let castTo; let castFrom; if (name.startsWith('bytes')) { - castTo = `bytes32(element) >> ${256 - size}`; + castTo = `bytes32(element) >> ${256 - sizeBits}`; castFrom = ''; } else if (name.startsWith('int')) { - castTo = `(Int256.toBytes32(element) & (~bytes32(0) >> ${256 - size}))`; + castTo = `(Int256.toBytes32(element) & (~bytes32(0) >> ${256 - sizeBits}))`; castFrom = 'Bytes32.toInt256'; } else if (name.startsWith('uint')) { castTo = 'Uint256.toBytes32(element)'; @@ -286,7 +284,8 @@ task('generate-bytes32-builder', `Generate ${libraryName}`).setAction( acc.push({ name, nameUpcase: name.charAt(0).toUpperCase() + name.slice(1), - size, + sizeBits, + sizeBytes, castTo, castFrom, }); From 85030deccf48bf17b898d99a10c87ec51553c10a Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Thu, 27 Mar 2025 02:12:29 -0600 Subject: [PATCH 29/39] fix sizeBytes variable --- tasks/generate_bytes32_builder.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/generate_bytes32_builder.ts b/tasks/generate_bytes32_builder.ts index 479d191e..60ae9ce1 100644 --- a/tasks/generate_bytes32_builder.ts +++ b/tasks/generate_bytes32_builder.ts @@ -257,7 +257,7 @@ task('generate-bytes32-builder', `Generate ${libraryName}`).setAction( const types: Type[] = typesBySize.reduce((acc, typesOfSize, i) => { return typesOfSize.reduce((acc, type) => { const name = type; - const sizeBytes = (i = 1); + const sizeBytes = i + 1; const sizeBits = sizeBytes * 8; let castTo; let castFrom; From 04878425dfdce88fe338b3d191271ca4b640c7e3 Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Thu, 27 Mar 2025 03:17:47 -0600 Subject: [PATCH 30/39] test and fix pop and shift functions --- tasks/generate_bytes32_builder.ts | 98 +++++++++++++++++++++++++++---- 1 file changed, 87 insertions(+), 11 deletions(-) diff --git a/tasks/generate_bytes32_builder.ts b/tasks/generate_bytes32_builder.ts index 60ae9ce1..9c9fd1c5 100644 --- a/tasks/generate_bytes32_builder.ts +++ b/tasks/generate_bytes32_builder.ts @@ -51,7 +51,8 @@ library <%- libraryName %> { unchecked { self._size -= <%- type.sizeBits %>; bytes32 mask = MASK_<%- (type.sizeBytes).toString().padStart(2, '0') %>; - element = <%- type.name %>(<%= type.castFrom %>((self._data >> self._size) & mask)); + bytes32 elementBytes = (self._data >> self._size) & mask; + element = <%- type.castFrom %>; self._data &= ~(mask << self._size); } } @@ -64,7 +65,8 @@ library <%- libraryName %> { function shift<%- type.nameUpcase %>(<%- structName %> memory self) internal pure returns (<%- type.name %> element) { unchecked { bytes32 mask = MASK_<%- (type.sizeBytes).toString().padStart(2, '0') %>; - element = <%- type.name %>(<%- type.castFrom %>(self._data & mask)); + bytes32 elementBytes = self._data & mask; + element = <%- type.castFrom %>; self._data >>= <%- type.sizeBits %>; self._size -= <%- type.sizeBits %>; } @@ -176,16 +178,90 @@ describe('<%- libraryName %>', () => { <%_ for (const type of types) { _%> describe('#pop<%- type.nameUpcase %>(bytes32,<%- type.name %>)', () => { - it.skip('removes <%- type.name %> from end of bytes', async () => { - expect(await instance.pop<%- type.nameUpcase %>) + it('removes <%- type.name %> from end of bytes and returns it', async () => { + const sizeBytes = <%- type.sizeBytes %>; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + } + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue(ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), 32) + const expectedValue = ethers.dataSlice(state._data, 32 - expectedLength / 8 - sizeBytes, 32 - expectedLength / 8); + + const result = await instance.pop<%- type.nameUpcase %>(state); + + expect( + result[0] + ).to.deep.equal( + [expectedData, expectedLength] + ); + + <%_ if (type.name === 'address') { _%> + expect(result[1]).to.eq(ethers.getAddress(expectedValue)) + <%_ } else if (type.name === 'bool') { _%> + expect(result[1]).to.eq(!!BigInt(expectedValue)); + <%_ } else if (type.name.startsWith('int')) { _%> + const negative = BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)) + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output) + <%_ } else { _%> + expect(result[1]).to.eq(expectedValue); + <%_ } _%> + } }); }); <%_ } _%> <%_ for (const type of types) { _%> describe('#shift<%- type.nameUpcase %>(bytes32,<%- type.name %>)', () => { - it.skip('removes <%- type.name %> from beginning of bytes', async () => { - expect(await instance.shift<%- type.nameUpcase %>) + it('removes <%- type.name %> from beginning of bytes and returns it', async () => { + const sizeBytes = <%- type.sizeBytes %>; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + } + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue(ethers.dataSlice(state._data, 0, 32 - sizeBytes), 32) + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shift<%- type.nameUpcase %>(state); + + expect( + result[0] + ).to.deep.equal( + [expectedData, expectedLength] + ); + + <%_ if (type.name === 'address') { _%> + expect(result[1]).to.eq(ethers.getAddress(expectedValue)) + <%_ } else if (type.name === 'bool') { _%> + expect(result[1]).to.eq(!!BigInt(expectedValue)); + <%_ } else if (type.name.startsWith('int')) { _%> + const negative = BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)) + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output) + <%_ } else { _%> + expect(result[1]).to.eq(expectedValue); + <%_ } _%> + } }); }); <%_ } _%> @@ -264,19 +340,19 @@ task('generate-bytes32-builder', `Generate ${libraryName}`).setAction( if (name.startsWith('bytes')) { castTo = `bytes32(element) >> ${256 - sizeBits}`; - castFrom = ''; + castFrom = `${name}(elementBytes << ${256 - sizeBits})`; } else if (name.startsWith('int')) { castTo = `(Int256.toBytes32(element) & (~bytes32(0) >> ${256 - sizeBits}))`; - castFrom = 'Bytes32.toInt256'; + castFrom = `${name}(Bytes32.toInt256(elementBytes))`; } else if (name.startsWith('uint')) { castTo = 'Uint256.toBytes32(element)'; - castFrom = 'Bytes32.toUint256'; + castFrom = `${name}(Bytes32.toUint256(elementBytes))`; } else if (name === 'address') { castTo = 'Address.toBytes32(element)'; - castFrom = 'Bytes32.toAddress'; + castFrom = 'Bytes32.toAddress(elementBytes)'; } else if (name === 'bool') { castTo = 'Bool.toBytes32(element)'; - castFrom = 'Bytes32.toBool'; + castFrom = 'Bytes32.toBool(elementBytes)'; } else { throw 'invalid type'; } From f53393986df19de9b43e4eee2baf6ad84ba81cc3 Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Thu, 27 Mar 2025 03:30:30 -0600 Subject: [PATCH 31/39] use staticCall in tests and update test names --- tasks/generate_bytes32_builder.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tasks/generate_bytes32_builder.ts b/tasks/generate_bytes32_builder.ts index 9c9fd1c5..7c9db828 100644 --- a/tasks/generate_bytes32_builder.ts +++ b/tasks/generate_bytes32_builder.ts @@ -167,7 +167,7 @@ describe('<%- libraryName %>', () => { const expectedLength = state._size + sizeBytes * 8; expect( - await instance.push<%- type.nameUpcase %>(state, input) + await instance.push<%- type.nameUpcase %>.staticCall(state, input) ).to.deep.equal( [expectedData, expectedLength] ); @@ -178,7 +178,7 @@ describe('<%- libraryName %>', () => { <%_ for (const type of types) { _%> describe('#pop<%- type.nameUpcase %>(bytes32,<%- type.name %>)', () => { - it('removes <%- type.name %> from end of bytes and returns it', async () => { + it('removes <%- type.sizeBytes %>-byte segment from end of bytes and returns it as <%- type.name %>', async () => { const sizeBytes = <%- type.sizeBytes %>; for (let i = sizeBytes; i <= 32; i++) { @@ -191,7 +191,7 @@ describe('<%- libraryName %>', () => { const expectedData = ethers.zeroPadValue(ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), 32) const expectedValue = ethers.dataSlice(state._data, 32 - expectedLength / 8 - sizeBytes, 32 - expectedLength / 8); - const result = await instance.pop<%- type.nameUpcase %>(state); + const result = await instance.pop<%- type.nameUpcase %>.staticCall(state); expect( result[0] @@ -223,7 +223,7 @@ describe('<%- libraryName %>', () => { <%_ for (const type of types) { _%> describe('#shift<%- type.nameUpcase %>(bytes32,<%- type.name %>)', () => { - it('removes <%- type.name %> from beginning of bytes and returns it', async () => { + it('removes <%- type.sizeBytes %>-byte segment from beginning of bytes and returns it as <%- type.name %>', async () => { const sizeBytes = <%- type.sizeBytes %>; for (let i = sizeBytes; i <= 32; i++) { @@ -236,7 +236,7 @@ describe('<%- libraryName %>', () => { const expectedData = ethers.zeroPadValue(ethers.dataSlice(state._data, 0, 32 - sizeBytes), 32) const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); - const result = await instance.shift<%- type.nameUpcase %>(state); + const result = await instance.shift<%- type.nameUpcase %>.staticCall(state); expect( result[0] @@ -297,7 +297,7 @@ describe('<%- libraryName %>', () => { const expectedLength = state._size + sizeBytes * 8; expect( - await instance.unshift<%- type.nameUpcase %>(state, input) + await instance.unshift<%- type.nameUpcase %>.staticCall(state, input) ).to.deep.equal( [expectedData, expectedLength] ); From 56bbc87a594b13a7540c0e3203e65a2a40a47ff5 Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Thu, 27 Mar 2025 03:35:23 -0600 Subject: [PATCH 32/39] add generated files --- contracts/data/Bytes32Builder.sol | 5927 ++++++++++++ contracts/test/Bytes32BuilderTest.sol | 2856 ++++++ test/data/Bytes32Builder.ts | 11565 ++++++++++++++++++++++++ 3 files changed, 20348 insertions(+) create mode 100644 contracts/data/Bytes32Builder.sol create mode 100644 contracts/test/Bytes32BuilderTest.sol create mode 100644 test/data/Bytes32Builder.ts diff --git a/contracts/data/Bytes32Builder.sol b/contracts/data/Bytes32Builder.sol new file mode 100644 index 00000000..bd09f62e --- /dev/null +++ b/contracts/data/Bytes32Builder.sol @@ -0,0 +1,5927 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.24; + +import { Address } from '../utils/Address.sol'; +import { Bool } from '../utils/Bool.sol'; +import { Bytes32 } from '../utils/Bytes32.sol'; +import { Int256 } from '../utils/Int256.sol'; +import { Uint256 } from '../utils/Uint256.sol'; + +/** + * @title Procedurally generated library for packing primitive types into bytes32 + **/ +library Bytes32Builder { + struct Builder { + bytes32 _data; + uint256 _size; + } + + bytes32 private constant MASK_01 = + 0x00000000000000000000000000000000000000000000000000000000000000ff; + bytes32 private constant MASK_02 = + 0x000000000000000000000000000000000000000000000000000000000000ffff; + bytes32 private constant MASK_03 = + 0x0000000000000000000000000000000000000000000000000000000000ffffff; + bytes32 private constant MASK_04 = + 0x00000000000000000000000000000000000000000000000000000000ffffffff; + bytes32 private constant MASK_05 = + 0x000000000000000000000000000000000000000000000000000000ffffffffff; + bytes32 private constant MASK_06 = + 0x0000000000000000000000000000000000000000000000000000ffffffffffff; + bytes32 private constant MASK_07 = + 0x00000000000000000000000000000000000000000000000000ffffffffffffff; + bytes32 private constant MASK_08 = + 0x000000000000000000000000000000000000000000000000ffffffffffffffff; + bytes32 private constant MASK_09 = + 0x0000000000000000000000000000000000000000000000ffffffffffffffffff; + bytes32 private constant MASK_10 = + 0x00000000000000000000000000000000000000000000ffffffffffffffffffff; + bytes32 private constant MASK_11 = + 0x000000000000000000000000000000000000000000ffffffffffffffffffffff; + bytes32 private constant MASK_12 = + 0x0000000000000000000000000000000000000000ffffffffffffffffffffffff; + bytes32 private constant MASK_13 = + 0x00000000000000000000000000000000000000ffffffffffffffffffffffffff; + bytes32 private constant MASK_14 = + 0x000000000000000000000000000000000000ffffffffffffffffffffffffffff; + bytes32 private constant MASK_15 = + 0x0000000000000000000000000000000000ffffffffffffffffffffffffffffff; + bytes32 private constant MASK_16 = + 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff; + bytes32 private constant MASK_17 = + 0x000000000000000000000000000000ffffffffffffffffffffffffffffffffff; + bytes32 private constant MASK_18 = + 0x0000000000000000000000000000ffffffffffffffffffffffffffffffffffff; + bytes32 private constant MASK_19 = + 0x00000000000000000000000000ffffffffffffffffffffffffffffffffffffff; + bytes32 private constant MASK_20 = + 0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff; + bytes32 private constant MASK_21 = + 0x0000000000000000000000ffffffffffffffffffffffffffffffffffffffffff; + bytes32 private constant MASK_22 = + 0x00000000000000000000ffffffffffffffffffffffffffffffffffffffffffff; + bytes32 private constant MASK_23 = + 0x000000000000000000ffffffffffffffffffffffffffffffffffffffffffffff; + bytes32 private constant MASK_24 = + 0x0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffff; + bytes32 private constant MASK_25 = + 0x00000000000000ffffffffffffffffffffffffffffffffffffffffffffffffff; + bytes32 private constant MASK_26 = + 0x000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffff; + bytes32 private constant MASK_27 = + 0x0000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffff; + bytes32 private constant MASK_28 = + 0x00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff; + bytes32 private constant MASK_29 = + 0x000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; + bytes32 private constant MASK_30 = + 0x0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; + bytes32 private constant MASK_31 = + 0x00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; + bytes32 private constant MASK_32 = + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; + + /** + * @notice insert bytes1 value to 1-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes1 to add + */ + function pushBytes1(Builder memory self, bytes1 element) internal pure { + unchecked { + self._data |= (bytes32(element) >> 248) << self._size; + self._size += 8; + } + } + + /** + * @notice remove last 1-byte segment from bytes and return as bytes1 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes1 derived from bytes + */ + function popBytes1( + Builder memory self + ) internal pure returns (bytes1 element) { + unchecked { + self._size -= 8; + bytes32 mask = MASK_01; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = bytes1(elementBytes << 248); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 1-byte segment from bytes and return as bytes1 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes1 derived from bytes + */ + function shiftBytes1( + Builder memory self + ) internal pure returns (bytes1 element) { + unchecked { + bytes32 mask = MASK_01; + bytes32 elementBytes = self._data & mask; + element = bytes1(elementBytes << 248); + self._data >>= 8; + self._size -= 8; + } + } + + /** + * @notice insert bytes1 value to 1-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes1 to add + */ + function unshiftBytes1(Builder memory self, bytes1 element) internal pure { + unchecked { + self._data = (self._data << 8) | (bytes32(element) >> 248); + self._size += 8; + } + } + /** + * @notice insert int8 value to 1-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int8 to add + */ + function pushInt8(Builder memory self, int8 element) internal pure { + unchecked { + self._data |= + (Int256.toBytes32(element) & (~bytes32(0) >> 248)) << + self._size; + self._size += 8; + } + } + + /** + * @notice remove last 1-byte segment from bytes and return as int8 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int8 derived from bytes + */ + function popInt8(Builder memory self) internal pure returns (int8 element) { + unchecked { + self._size -= 8; + bytes32 mask = MASK_01; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = int8(Bytes32.toInt256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 1-byte segment from bytes and return as int8 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int8 derived from bytes + */ + function shiftInt8( + Builder memory self + ) internal pure returns (int8 element) { + unchecked { + bytes32 mask = MASK_01; + bytes32 elementBytes = self._data & mask; + element = int8(Bytes32.toInt256(elementBytes)); + self._data >>= 8; + self._size -= 8; + } + } + + /** + * @notice insert int8 value to 1-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int8 to add + */ + function unshiftInt8(Builder memory self, int8 element) internal pure { + unchecked { + self._data = + (self._data << 8) | + (Int256.toBytes32(element) & (~bytes32(0) >> 248)); + self._size += 8; + } + } + /** + * @notice insert uint8 value to 1-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint8 to add + */ + function pushUint8(Builder memory self, uint8 element) internal pure { + unchecked { + self._data |= Uint256.toBytes32(element) << self._size; + self._size += 8; + } + } + + /** + * @notice remove last 1-byte segment from bytes and return as uint8 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint8 derived from bytes + */ + function popUint8( + Builder memory self + ) internal pure returns (uint8 element) { + unchecked { + self._size -= 8; + bytes32 mask = MASK_01; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = uint8(Bytes32.toUint256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 1-byte segment from bytes and return as uint8 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint8 derived from bytes + */ + function shiftUint8( + Builder memory self + ) internal pure returns (uint8 element) { + unchecked { + bytes32 mask = MASK_01; + bytes32 elementBytes = self._data & mask; + element = uint8(Bytes32.toUint256(elementBytes)); + self._data >>= 8; + self._size -= 8; + } + } + + /** + * @notice insert uint8 value to 1-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint8 to add + */ + function unshiftUint8(Builder memory self, uint8 element) internal pure { + unchecked { + self._data = (self._data << 8) | Uint256.toBytes32(element); + self._size += 8; + } + } + /** + * @notice insert bool value to 1-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bool to add + */ + function pushBool(Builder memory self, bool element) internal pure { + unchecked { + self._data |= Bool.toBytes32(element) << self._size; + self._size += 8; + } + } + + /** + * @notice remove last 1-byte segment from bytes and return as bool + * @param self Bytes32Builder Builder struct on which to operate + * @return element bool derived from bytes + */ + function popBool(Builder memory self) internal pure returns (bool element) { + unchecked { + self._size -= 8; + bytes32 mask = MASK_01; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = Bytes32.toBool(elementBytes); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 1-byte segment from bytes and return as bool + * @param self Bytes32Builder Builder struct on which to operate + * @return element bool derived from bytes + */ + function shiftBool( + Builder memory self + ) internal pure returns (bool element) { + unchecked { + bytes32 mask = MASK_01; + bytes32 elementBytes = self._data & mask; + element = Bytes32.toBool(elementBytes); + self._data >>= 8; + self._size -= 8; + } + } + + /** + * @notice insert bool value to 1-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bool to add + */ + function unshiftBool(Builder memory self, bool element) internal pure { + unchecked { + self._data = (self._data << 8) | Bool.toBytes32(element); + self._size += 8; + } + } + /** + * @notice insert bytes2 value to 2-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes2 to add + */ + function pushBytes2(Builder memory self, bytes2 element) internal pure { + unchecked { + self._data |= (bytes32(element) >> 240) << self._size; + self._size += 16; + } + } + + /** + * @notice remove last 2-byte segment from bytes and return as bytes2 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes2 derived from bytes + */ + function popBytes2( + Builder memory self + ) internal pure returns (bytes2 element) { + unchecked { + self._size -= 16; + bytes32 mask = MASK_02; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = bytes2(elementBytes << 240); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 2-byte segment from bytes and return as bytes2 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes2 derived from bytes + */ + function shiftBytes2( + Builder memory self + ) internal pure returns (bytes2 element) { + unchecked { + bytes32 mask = MASK_02; + bytes32 elementBytes = self._data & mask; + element = bytes2(elementBytes << 240); + self._data >>= 16; + self._size -= 16; + } + } + + /** + * @notice insert bytes2 value to 2-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes2 to add + */ + function unshiftBytes2(Builder memory self, bytes2 element) internal pure { + unchecked { + self._data = (self._data << 16) | (bytes32(element) >> 240); + self._size += 16; + } + } + /** + * @notice insert int16 value to 2-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int16 to add + */ + function pushInt16(Builder memory self, int16 element) internal pure { + unchecked { + self._data |= + (Int256.toBytes32(element) & (~bytes32(0) >> 240)) << + self._size; + self._size += 16; + } + } + + /** + * @notice remove last 2-byte segment from bytes and return as int16 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int16 derived from bytes + */ + function popInt16( + Builder memory self + ) internal pure returns (int16 element) { + unchecked { + self._size -= 16; + bytes32 mask = MASK_02; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = int16(Bytes32.toInt256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 2-byte segment from bytes and return as int16 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int16 derived from bytes + */ + function shiftInt16( + Builder memory self + ) internal pure returns (int16 element) { + unchecked { + bytes32 mask = MASK_02; + bytes32 elementBytes = self._data & mask; + element = int16(Bytes32.toInt256(elementBytes)); + self._data >>= 16; + self._size -= 16; + } + } + + /** + * @notice insert int16 value to 2-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int16 to add + */ + function unshiftInt16(Builder memory self, int16 element) internal pure { + unchecked { + self._data = + (self._data << 16) | + (Int256.toBytes32(element) & (~bytes32(0) >> 240)); + self._size += 16; + } + } + /** + * @notice insert uint16 value to 2-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint16 to add + */ + function pushUint16(Builder memory self, uint16 element) internal pure { + unchecked { + self._data |= Uint256.toBytes32(element) << self._size; + self._size += 16; + } + } + + /** + * @notice remove last 2-byte segment from bytes and return as uint16 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint16 derived from bytes + */ + function popUint16( + Builder memory self + ) internal pure returns (uint16 element) { + unchecked { + self._size -= 16; + bytes32 mask = MASK_02; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = uint16(Bytes32.toUint256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 2-byte segment from bytes and return as uint16 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint16 derived from bytes + */ + function shiftUint16( + Builder memory self + ) internal pure returns (uint16 element) { + unchecked { + bytes32 mask = MASK_02; + bytes32 elementBytes = self._data & mask; + element = uint16(Bytes32.toUint256(elementBytes)); + self._data >>= 16; + self._size -= 16; + } + } + + /** + * @notice insert uint16 value to 2-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint16 to add + */ + function unshiftUint16(Builder memory self, uint16 element) internal pure { + unchecked { + self._data = (self._data << 16) | Uint256.toBytes32(element); + self._size += 16; + } + } + /** + * @notice insert bytes3 value to 3-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes3 to add + */ + function pushBytes3(Builder memory self, bytes3 element) internal pure { + unchecked { + self._data |= (bytes32(element) >> 232) << self._size; + self._size += 24; + } + } + + /** + * @notice remove last 3-byte segment from bytes and return as bytes3 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes3 derived from bytes + */ + function popBytes3( + Builder memory self + ) internal pure returns (bytes3 element) { + unchecked { + self._size -= 24; + bytes32 mask = MASK_03; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = bytes3(elementBytes << 232); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 3-byte segment from bytes and return as bytes3 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes3 derived from bytes + */ + function shiftBytes3( + Builder memory self + ) internal pure returns (bytes3 element) { + unchecked { + bytes32 mask = MASK_03; + bytes32 elementBytes = self._data & mask; + element = bytes3(elementBytes << 232); + self._data >>= 24; + self._size -= 24; + } + } + + /** + * @notice insert bytes3 value to 3-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes3 to add + */ + function unshiftBytes3(Builder memory self, bytes3 element) internal pure { + unchecked { + self._data = (self._data << 24) | (bytes32(element) >> 232); + self._size += 24; + } + } + /** + * @notice insert int24 value to 3-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int24 to add + */ + function pushInt24(Builder memory self, int24 element) internal pure { + unchecked { + self._data |= + (Int256.toBytes32(element) & (~bytes32(0) >> 232)) << + self._size; + self._size += 24; + } + } + + /** + * @notice remove last 3-byte segment from bytes and return as int24 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int24 derived from bytes + */ + function popInt24( + Builder memory self + ) internal pure returns (int24 element) { + unchecked { + self._size -= 24; + bytes32 mask = MASK_03; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = int24(Bytes32.toInt256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 3-byte segment from bytes and return as int24 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int24 derived from bytes + */ + function shiftInt24( + Builder memory self + ) internal pure returns (int24 element) { + unchecked { + bytes32 mask = MASK_03; + bytes32 elementBytes = self._data & mask; + element = int24(Bytes32.toInt256(elementBytes)); + self._data >>= 24; + self._size -= 24; + } + } + + /** + * @notice insert int24 value to 3-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int24 to add + */ + function unshiftInt24(Builder memory self, int24 element) internal pure { + unchecked { + self._data = + (self._data << 24) | + (Int256.toBytes32(element) & (~bytes32(0) >> 232)); + self._size += 24; + } + } + /** + * @notice insert uint24 value to 3-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint24 to add + */ + function pushUint24(Builder memory self, uint24 element) internal pure { + unchecked { + self._data |= Uint256.toBytes32(element) << self._size; + self._size += 24; + } + } + + /** + * @notice remove last 3-byte segment from bytes and return as uint24 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint24 derived from bytes + */ + function popUint24( + Builder memory self + ) internal pure returns (uint24 element) { + unchecked { + self._size -= 24; + bytes32 mask = MASK_03; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = uint24(Bytes32.toUint256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 3-byte segment from bytes and return as uint24 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint24 derived from bytes + */ + function shiftUint24( + Builder memory self + ) internal pure returns (uint24 element) { + unchecked { + bytes32 mask = MASK_03; + bytes32 elementBytes = self._data & mask; + element = uint24(Bytes32.toUint256(elementBytes)); + self._data >>= 24; + self._size -= 24; + } + } + + /** + * @notice insert uint24 value to 3-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint24 to add + */ + function unshiftUint24(Builder memory self, uint24 element) internal pure { + unchecked { + self._data = (self._data << 24) | Uint256.toBytes32(element); + self._size += 24; + } + } + /** + * @notice insert bytes4 value to 4-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes4 to add + */ + function pushBytes4(Builder memory self, bytes4 element) internal pure { + unchecked { + self._data |= (bytes32(element) >> 224) << self._size; + self._size += 32; + } + } + + /** + * @notice remove last 4-byte segment from bytes and return as bytes4 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes4 derived from bytes + */ + function popBytes4( + Builder memory self + ) internal pure returns (bytes4 element) { + unchecked { + self._size -= 32; + bytes32 mask = MASK_04; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = bytes4(elementBytes << 224); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 4-byte segment from bytes and return as bytes4 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes4 derived from bytes + */ + function shiftBytes4( + Builder memory self + ) internal pure returns (bytes4 element) { + unchecked { + bytes32 mask = MASK_04; + bytes32 elementBytes = self._data & mask; + element = bytes4(elementBytes << 224); + self._data >>= 32; + self._size -= 32; + } + } + + /** + * @notice insert bytes4 value to 4-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes4 to add + */ + function unshiftBytes4(Builder memory self, bytes4 element) internal pure { + unchecked { + self._data = (self._data << 32) | (bytes32(element) >> 224); + self._size += 32; + } + } + /** + * @notice insert int32 value to 4-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int32 to add + */ + function pushInt32(Builder memory self, int32 element) internal pure { + unchecked { + self._data |= + (Int256.toBytes32(element) & (~bytes32(0) >> 224)) << + self._size; + self._size += 32; + } + } + + /** + * @notice remove last 4-byte segment from bytes and return as int32 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int32 derived from bytes + */ + function popInt32( + Builder memory self + ) internal pure returns (int32 element) { + unchecked { + self._size -= 32; + bytes32 mask = MASK_04; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = int32(Bytes32.toInt256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 4-byte segment from bytes and return as int32 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int32 derived from bytes + */ + function shiftInt32( + Builder memory self + ) internal pure returns (int32 element) { + unchecked { + bytes32 mask = MASK_04; + bytes32 elementBytes = self._data & mask; + element = int32(Bytes32.toInt256(elementBytes)); + self._data >>= 32; + self._size -= 32; + } + } + + /** + * @notice insert int32 value to 4-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int32 to add + */ + function unshiftInt32(Builder memory self, int32 element) internal pure { + unchecked { + self._data = + (self._data << 32) | + (Int256.toBytes32(element) & (~bytes32(0) >> 224)); + self._size += 32; + } + } + /** + * @notice insert uint32 value to 4-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint32 to add + */ + function pushUint32(Builder memory self, uint32 element) internal pure { + unchecked { + self._data |= Uint256.toBytes32(element) << self._size; + self._size += 32; + } + } + + /** + * @notice remove last 4-byte segment from bytes and return as uint32 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint32 derived from bytes + */ + function popUint32( + Builder memory self + ) internal pure returns (uint32 element) { + unchecked { + self._size -= 32; + bytes32 mask = MASK_04; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = uint32(Bytes32.toUint256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 4-byte segment from bytes and return as uint32 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint32 derived from bytes + */ + function shiftUint32( + Builder memory self + ) internal pure returns (uint32 element) { + unchecked { + bytes32 mask = MASK_04; + bytes32 elementBytes = self._data & mask; + element = uint32(Bytes32.toUint256(elementBytes)); + self._data >>= 32; + self._size -= 32; + } + } + + /** + * @notice insert uint32 value to 4-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint32 to add + */ + function unshiftUint32(Builder memory self, uint32 element) internal pure { + unchecked { + self._data = (self._data << 32) | Uint256.toBytes32(element); + self._size += 32; + } + } + /** + * @notice insert bytes5 value to 5-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes5 to add + */ + function pushBytes5(Builder memory self, bytes5 element) internal pure { + unchecked { + self._data |= (bytes32(element) >> 216) << self._size; + self._size += 40; + } + } + + /** + * @notice remove last 5-byte segment from bytes and return as bytes5 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes5 derived from bytes + */ + function popBytes5( + Builder memory self + ) internal pure returns (bytes5 element) { + unchecked { + self._size -= 40; + bytes32 mask = MASK_05; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = bytes5(elementBytes << 216); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 5-byte segment from bytes and return as bytes5 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes5 derived from bytes + */ + function shiftBytes5( + Builder memory self + ) internal pure returns (bytes5 element) { + unchecked { + bytes32 mask = MASK_05; + bytes32 elementBytes = self._data & mask; + element = bytes5(elementBytes << 216); + self._data >>= 40; + self._size -= 40; + } + } + + /** + * @notice insert bytes5 value to 5-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes5 to add + */ + function unshiftBytes5(Builder memory self, bytes5 element) internal pure { + unchecked { + self._data = (self._data << 40) | (bytes32(element) >> 216); + self._size += 40; + } + } + /** + * @notice insert int40 value to 5-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int40 to add + */ + function pushInt40(Builder memory self, int40 element) internal pure { + unchecked { + self._data |= + (Int256.toBytes32(element) & (~bytes32(0) >> 216)) << + self._size; + self._size += 40; + } + } + + /** + * @notice remove last 5-byte segment from bytes and return as int40 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int40 derived from bytes + */ + function popInt40( + Builder memory self + ) internal pure returns (int40 element) { + unchecked { + self._size -= 40; + bytes32 mask = MASK_05; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = int40(Bytes32.toInt256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 5-byte segment from bytes and return as int40 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int40 derived from bytes + */ + function shiftInt40( + Builder memory self + ) internal pure returns (int40 element) { + unchecked { + bytes32 mask = MASK_05; + bytes32 elementBytes = self._data & mask; + element = int40(Bytes32.toInt256(elementBytes)); + self._data >>= 40; + self._size -= 40; + } + } + + /** + * @notice insert int40 value to 5-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int40 to add + */ + function unshiftInt40(Builder memory self, int40 element) internal pure { + unchecked { + self._data = + (self._data << 40) | + (Int256.toBytes32(element) & (~bytes32(0) >> 216)); + self._size += 40; + } + } + /** + * @notice insert uint40 value to 5-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint40 to add + */ + function pushUint40(Builder memory self, uint40 element) internal pure { + unchecked { + self._data |= Uint256.toBytes32(element) << self._size; + self._size += 40; + } + } + + /** + * @notice remove last 5-byte segment from bytes and return as uint40 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint40 derived from bytes + */ + function popUint40( + Builder memory self + ) internal pure returns (uint40 element) { + unchecked { + self._size -= 40; + bytes32 mask = MASK_05; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = uint40(Bytes32.toUint256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 5-byte segment from bytes and return as uint40 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint40 derived from bytes + */ + function shiftUint40( + Builder memory self + ) internal pure returns (uint40 element) { + unchecked { + bytes32 mask = MASK_05; + bytes32 elementBytes = self._data & mask; + element = uint40(Bytes32.toUint256(elementBytes)); + self._data >>= 40; + self._size -= 40; + } + } + + /** + * @notice insert uint40 value to 5-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint40 to add + */ + function unshiftUint40(Builder memory self, uint40 element) internal pure { + unchecked { + self._data = (self._data << 40) | Uint256.toBytes32(element); + self._size += 40; + } + } + /** + * @notice insert bytes6 value to 6-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes6 to add + */ + function pushBytes6(Builder memory self, bytes6 element) internal pure { + unchecked { + self._data |= (bytes32(element) >> 208) << self._size; + self._size += 48; + } + } + + /** + * @notice remove last 6-byte segment from bytes and return as bytes6 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes6 derived from bytes + */ + function popBytes6( + Builder memory self + ) internal pure returns (bytes6 element) { + unchecked { + self._size -= 48; + bytes32 mask = MASK_06; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = bytes6(elementBytes << 208); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 6-byte segment from bytes and return as bytes6 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes6 derived from bytes + */ + function shiftBytes6( + Builder memory self + ) internal pure returns (bytes6 element) { + unchecked { + bytes32 mask = MASK_06; + bytes32 elementBytes = self._data & mask; + element = bytes6(elementBytes << 208); + self._data >>= 48; + self._size -= 48; + } + } + + /** + * @notice insert bytes6 value to 6-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes6 to add + */ + function unshiftBytes6(Builder memory self, bytes6 element) internal pure { + unchecked { + self._data = (self._data << 48) | (bytes32(element) >> 208); + self._size += 48; + } + } + /** + * @notice insert int48 value to 6-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int48 to add + */ + function pushInt48(Builder memory self, int48 element) internal pure { + unchecked { + self._data |= + (Int256.toBytes32(element) & (~bytes32(0) >> 208)) << + self._size; + self._size += 48; + } + } + + /** + * @notice remove last 6-byte segment from bytes and return as int48 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int48 derived from bytes + */ + function popInt48( + Builder memory self + ) internal pure returns (int48 element) { + unchecked { + self._size -= 48; + bytes32 mask = MASK_06; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = int48(Bytes32.toInt256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 6-byte segment from bytes and return as int48 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int48 derived from bytes + */ + function shiftInt48( + Builder memory self + ) internal pure returns (int48 element) { + unchecked { + bytes32 mask = MASK_06; + bytes32 elementBytes = self._data & mask; + element = int48(Bytes32.toInt256(elementBytes)); + self._data >>= 48; + self._size -= 48; + } + } + + /** + * @notice insert int48 value to 6-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int48 to add + */ + function unshiftInt48(Builder memory self, int48 element) internal pure { + unchecked { + self._data = + (self._data << 48) | + (Int256.toBytes32(element) & (~bytes32(0) >> 208)); + self._size += 48; + } + } + /** + * @notice insert uint48 value to 6-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint48 to add + */ + function pushUint48(Builder memory self, uint48 element) internal pure { + unchecked { + self._data |= Uint256.toBytes32(element) << self._size; + self._size += 48; + } + } + + /** + * @notice remove last 6-byte segment from bytes and return as uint48 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint48 derived from bytes + */ + function popUint48( + Builder memory self + ) internal pure returns (uint48 element) { + unchecked { + self._size -= 48; + bytes32 mask = MASK_06; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = uint48(Bytes32.toUint256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 6-byte segment from bytes and return as uint48 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint48 derived from bytes + */ + function shiftUint48( + Builder memory self + ) internal pure returns (uint48 element) { + unchecked { + bytes32 mask = MASK_06; + bytes32 elementBytes = self._data & mask; + element = uint48(Bytes32.toUint256(elementBytes)); + self._data >>= 48; + self._size -= 48; + } + } + + /** + * @notice insert uint48 value to 6-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint48 to add + */ + function unshiftUint48(Builder memory self, uint48 element) internal pure { + unchecked { + self._data = (self._data << 48) | Uint256.toBytes32(element); + self._size += 48; + } + } + /** + * @notice insert bytes7 value to 7-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes7 to add + */ + function pushBytes7(Builder memory self, bytes7 element) internal pure { + unchecked { + self._data |= (bytes32(element) >> 200) << self._size; + self._size += 56; + } + } + + /** + * @notice remove last 7-byte segment from bytes and return as bytes7 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes7 derived from bytes + */ + function popBytes7( + Builder memory self + ) internal pure returns (bytes7 element) { + unchecked { + self._size -= 56; + bytes32 mask = MASK_07; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = bytes7(elementBytes << 200); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 7-byte segment from bytes and return as bytes7 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes7 derived from bytes + */ + function shiftBytes7( + Builder memory self + ) internal pure returns (bytes7 element) { + unchecked { + bytes32 mask = MASK_07; + bytes32 elementBytes = self._data & mask; + element = bytes7(elementBytes << 200); + self._data >>= 56; + self._size -= 56; + } + } + + /** + * @notice insert bytes7 value to 7-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes7 to add + */ + function unshiftBytes7(Builder memory self, bytes7 element) internal pure { + unchecked { + self._data = (self._data << 56) | (bytes32(element) >> 200); + self._size += 56; + } + } + /** + * @notice insert int56 value to 7-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int56 to add + */ + function pushInt56(Builder memory self, int56 element) internal pure { + unchecked { + self._data |= + (Int256.toBytes32(element) & (~bytes32(0) >> 200)) << + self._size; + self._size += 56; + } + } + + /** + * @notice remove last 7-byte segment from bytes and return as int56 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int56 derived from bytes + */ + function popInt56( + Builder memory self + ) internal pure returns (int56 element) { + unchecked { + self._size -= 56; + bytes32 mask = MASK_07; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = int56(Bytes32.toInt256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 7-byte segment from bytes and return as int56 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int56 derived from bytes + */ + function shiftInt56( + Builder memory self + ) internal pure returns (int56 element) { + unchecked { + bytes32 mask = MASK_07; + bytes32 elementBytes = self._data & mask; + element = int56(Bytes32.toInt256(elementBytes)); + self._data >>= 56; + self._size -= 56; + } + } + + /** + * @notice insert int56 value to 7-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int56 to add + */ + function unshiftInt56(Builder memory self, int56 element) internal pure { + unchecked { + self._data = + (self._data << 56) | + (Int256.toBytes32(element) & (~bytes32(0) >> 200)); + self._size += 56; + } + } + /** + * @notice insert uint56 value to 7-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint56 to add + */ + function pushUint56(Builder memory self, uint56 element) internal pure { + unchecked { + self._data |= Uint256.toBytes32(element) << self._size; + self._size += 56; + } + } + + /** + * @notice remove last 7-byte segment from bytes and return as uint56 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint56 derived from bytes + */ + function popUint56( + Builder memory self + ) internal pure returns (uint56 element) { + unchecked { + self._size -= 56; + bytes32 mask = MASK_07; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = uint56(Bytes32.toUint256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 7-byte segment from bytes and return as uint56 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint56 derived from bytes + */ + function shiftUint56( + Builder memory self + ) internal pure returns (uint56 element) { + unchecked { + bytes32 mask = MASK_07; + bytes32 elementBytes = self._data & mask; + element = uint56(Bytes32.toUint256(elementBytes)); + self._data >>= 56; + self._size -= 56; + } + } + + /** + * @notice insert uint56 value to 7-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint56 to add + */ + function unshiftUint56(Builder memory self, uint56 element) internal pure { + unchecked { + self._data = (self._data << 56) | Uint256.toBytes32(element); + self._size += 56; + } + } + /** + * @notice insert bytes8 value to 8-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes8 to add + */ + function pushBytes8(Builder memory self, bytes8 element) internal pure { + unchecked { + self._data |= (bytes32(element) >> 192) << self._size; + self._size += 64; + } + } + + /** + * @notice remove last 8-byte segment from bytes and return as bytes8 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes8 derived from bytes + */ + function popBytes8( + Builder memory self + ) internal pure returns (bytes8 element) { + unchecked { + self._size -= 64; + bytes32 mask = MASK_08; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = bytes8(elementBytes << 192); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 8-byte segment from bytes and return as bytes8 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes8 derived from bytes + */ + function shiftBytes8( + Builder memory self + ) internal pure returns (bytes8 element) { + unchecked { + bytes32 mask = MASK_08; + bytes32 elementBytes = self._data & mask; + element = bytes8(elementBytes << 192); + self._data >>= 64; + self._size -= 64; + } + } + + /** + * @notice insert bytes8 value to 8-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes8 to add + */ + function unshiftBytes8(Builder memory self, bytes8 element) internal pure { + unchecked { + self._data = (self._data << 64) | (bytes32(element) >> 192); + self._size += 64; + } + } + /** + * @notice insert int64 value to 8-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int64 to add + */ + function pushInt64(Builder memory self, int64 element) internal pure { + unchecked { + self._data |= + (Int256.toBytes32(element) & (~bytes32(0) >> 192)) << + self._size; + self._size += 64; + } + } + + /** + * @notice remove last 8-byte segment from bytes and return as int64 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int64 derived from bytes + */ + function popInt64( + Builder memory self + ) internal pure returns (int64 element) { + unchecked { + self._size -= 64; + bytes32 mask = MASK_08; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = int64(Bytes32.toInt256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 8-byte segment from bytes and return as int64 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int64 derived from bytes + */ + function shiftInt64( + Builder memory self + ) internal pure returns (int64 element) { + unchecked { + bytes32 mask = MASK_08; + bytes32 elementBytes = self._data & mask; + element = int64(Bytes32.toInt256(elementBytes)); + self._data >>= 64; + self._size -= 64; + } + } + + /** + * @notice insert int64 value to 8-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int64 to add + */ + function unshiftInt64(Builder memory self, int64 element) internal pure { + unchecked { + self._data = + (self._data << 64) | + (Int256.toBytes32(element) & (~bytes32(0) >> 192)); + self._size += 64; + } + } + /** + * @notice insert uint64 value to 8-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint64 to add + */ + function pushUint64(Builder memory self, uint64 element) internal pure { + unchecked { + self._data |= Uint256.toBytes32(element) << self._size; + self._size += 64; + } + } + + /** + * @notice remove last 8-byte segment from bytes and return as uint64 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint64 derived from bytes + */ + function popUint64( + Builder memory self + ) internal pure returns (uint64 element) { + unchecked { + self._size -= 64; + bytes32 mask = MASK_08; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = uint64(Bytes32.toUint256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 8-byte segment from bytes and return as uint64 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint64 derived from bytes + */ + function shiftUint64( + Builder memory self + ) internal pure returns (uint64 element) { + unchecked { + bytes32 mask = MASK_08; + bytes32 elementBytes = self._data & mask; + element = uint64(Bytes32.toUint256(elementBytes)); + self._data >>= 64; + self._size -= 64; + } + } + + /** + * @notice insert uint64 value to 8-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint64 to add + */ + function unshiftUint64(Builder memory self, uint64 element) internal pure { + unchecked { + self._data = (self._data << 64) | Uint256.toBytes32(element); + self._size += 64; + } + } + /** + * @notice insert bytes9 value to 9-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes9 to add + */ + function pushBytes9(Builder memory self, bytes9 element) internal pure { + unchecked { + self._data |= (bytes32(element) >> 184) << self._size; + self._size += 72; + } + } + + /** + * @notice remove last 9-byte segment from bytes and return as bytes9 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes9 derived from bytes + */ + function popBytes9( + Builder memory self + ) internal pure returns (bytes9 element) { + unchecked { + self._size -= 72; + bytes32 mask = MASK_09; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = bytes9(elementBytes << 184); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 9-byte segment from bytes and return as bytes9 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes9 derived from bytes + */ + function shiftBytes9( + Builder memory self + ) internal pure returns (bytes9 element) { + unchecked { + bytes32 mask = MASK_09; + bytes32 elementBytes = self._data & mask; + element = bytes9(elementBytes << 184); + self._data >>= 72; + self._size -= 72; + } + } + + /** + * @notice insert bytes9 value to 9-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes9 to add + */ + function unshiftBytes9(Builder memory self, bytes9 element) internal pure { + unchecked { + self._data = (self._data << 72) | (bytes32(element) >> 184); + self._size += 72; + } + } + /** + * @notice insert int72 value to 9-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int72 to add + */ + function pushInt72(Builder memory self, int72 element) internal pure { + unchecked { + self._data |= + (Int256.toBytes32(element) & (~bytes32(0) >> 184)) << + self._size; + self._size += 72; + } + } + + /** + * @notice remove last 9-byte segment from bytes and return as int72 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int72 derived from bytes + */ + function popInt72( + Builder memory self + ) internal pure returns (int72 element) { + unchecked { + self._size -= 72; + bytes32 mask = MASK_09; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = int72(Bytes32.toInt256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 9-byte segment from bytes and return as int72 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int72 derived from bytes + */ + function shiftInt72( + Builder memory self + ) internal pure returns (int72 element) { + unchecked { + bytes32 mask = MASK_09; + bytes32 elementBytes = self._data & mask; + element = int72(Bytes32.toInt256(elementBytes)); + self._data >>= 72; + self._size -= 72; + } + } + + /** + * @notice insert int72 value to 9-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int72 to add + */ + function unshiftInt72(Builder memory self, int72 element) internal pure { + unchecked { + self._data = + (self._data << 72) | + (Int256.toBytes32(element) & (~bytes32(0) >> 184)); + self._size += 72; + } + } + /** + * @notice insert uint72 value to 9-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint72 to add + */ + function pushUint72(Builder memory self, uint72 element) internal pure { + unchecked { + self._data |= Uint256.toBytes32(element) << self._size; + self._size += 72; + } + } + + /** + * @notice remove last 9-byte segment from bytes and return as uint72 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint72 derived from bytes + */ + function popUint72( + Builder memory self + ) internal pure returns (uint72 element) { + unchecked { + self._size -= 72; + bytes32 mask = MASK_09; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = uint72(Bytes32.toUint256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 9-byte segment from bytes and return as uint72 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint72 derived from bytes + */ + function shiftUint72( + Builder memory self + ) internal pure returns (uint72 element) { + unchecked { + bytes32 mask = MASK_09; + bytes32 elementBytes = self._data & mask; + element = uint72(Bytes32.toUint256(elementBytes)); + self._data >>= 72; + self._size -= 72; + } + } + + /** + * @notice insert uint72 value to 9-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint72 to add + */ + function unshiftUint72(Builder memory self, uint72 element) internal pure { + unchecked { + self._data = (self._data << 72) | Uint256.toBytes32(element); + self._size += 72; + } + } + /** + * @notice insert bytes10 value to 10-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes10 to add + */ + function pushBytes10(Builder memory self, bytes10 element) internal pure { + unchecked { + self._data |= (bytes32(element) >> 176) << self._size; + self._size += 80; + } + } + + /** + * @notice remove last 10-byte segment from bytes and return as bytes10 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes10 derived from bytes + */ + function popBytes10( + Builder memory self + ) internal pure returns (bytes10 element) { + unchecked { + self._size -= 80; + bytes32 mask = MASK_10; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = bytes10(elementBytes << 176); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 10-byte segment from bytes and return as bytes10 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes10 derived from bytes + */ + function shiftBytes10( + Builder memory self + ) internal pure returns (bytes10 element) { + unchecked { + bytes32 mask = MASK_10; + bytes32 elementBytes = self._data & mask; + element = bytes10(elementBytes << 176); + self._data >>= 80; + self._size -= 80; + } + } + + /** + * @notice insert bytes10 value to 10-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes10 to add + */ + function unshiftBytes10( + Builder memory self, + bytes10 element + ) internal pure { + unchecked { + self._data = (self._data << 80) | (bytes32(element) >> 176); + self._size += 80; + } + } + /** + * @notice insert int80 value to 10-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int80 to add + */ + function pushInt80(Builder memory self, int80 element) internal pure { + unchecked { + self._data |= + (Int256.toBytes32(element) & (~bytes32(0) >> 176)) << + self._size; + self._size += 80; + } + } + + /** + * @notice remove last 10-byte segment from bytes and return as int80 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int80 derived from bytes + */ + function popInt80( + Builder memory self + ) internal pure returns (int80 element) { + unchecked { + self._size -= 80; + bytes32 mask = MASK_10; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = int80(Bytes32.toInt256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 10-byte segment from bytes and return as int80 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int80 derived from bytes + */ + function shiftInt80( + Builder memory self + ) internal pure returns (int80 element) { + unchecked { + bytes32 mask = MASK_10; + bytes32 elementBytes = self._data & mask; + element = int80(Bytes32.toInt256(elementBytes)); + self._data >>= 80; + self._size -= 80; + } + } + + /** + * @notice insert int80 value to 10-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int80 to add + */ + function unshiftInt80(Builder memory self, int80 element) internal pure { + unchecked { + self._data = + (self._data << 80) | + (Int256.toBytes32(element) & (~bytes32(0) >> 176)); + self._size += 80; + } + } + /** + * @notice insert uint80 value to 10-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint80 to add + */ + function pushUint80(Builder memory self, uint80 element) internal pure { + unchecked { + self._data |= Uint256.toBytes32(element) << self._size; + self._size += 80; + } + } + + /** + * @notice remove last 10-byte segment from bytes and return as uint80 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint80 derived from bytes + */ + function popUint80( + Builder memory self + ) internal pure returns (uint80 element) { + unchecked { + self._size -= 80; + bytes32 mask = MASK_10; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = uint80(Bytes32.toUint256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 10-byte segment from bytes and return as uint80 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint80 derived from bytes + */ + function shiftUint80( + Builder memory self + ) internal pure returns (uint80 element) { + unchecked { + bytes32 mask = MASK_10; + bytes32 elementBytes = self._data & mask; + element = uint80(Bytes32.toUint256(elementBytes)); + self._data >>= 80; + self._size -= 80; + } + } + + /** + * @notice insert uint80 value to 10-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint80 to add + */ + function unshiftUint80(Builder memory self, uint80 element) internal pure { + unchecked { + self._data = (self._data << 80) | Uint256.toBytes32(element); + self._size += 80; + } + } + /** + * @notice insert bytes11 value to 11-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes11 to add + */ + function pushBytes11(Builder memory self, bytes11 element) internal pure { + unchecked { + self._data |= (bytes32(element) >> 168) << self._size; + self._size += 88; + } + } + + /** + * @notice remove last 11-byte segment from bytes and return as bytes11 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes11 derived from bytes + */ + function popBytes11( + Builder memory self + ) internal pure returns (bytes11 element) { + unchecked { + self._size -= 88; + bytes32 mask = MASK_11; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = bytes11(elementBytes << 168); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 11-byte segment from bytes and return as bytes11 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes11 derived from bytes + */ + function shiftBytes11( + Builder memory self + ) internal pure returns (bytes11 element) { + unchecked { + bytes32 mask = MASK_11; + bytes32 elementBytes = self._data & mask; + element = bytes11(elementBytes << 168); + self._data >>= 88; + self._size -= 88; + } + } + + /** + * @notice insert bytes11 value to 11-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes11 to add + */ + function unshiftBytes11( + Builder memory self, + bytes11 element + ) internal pure { + unchecked { + self._data = (self._data << 88) | (bytes32(element) >> 168); + self._size += 88; + } + } + /** + * @notice insert int88 value to 11-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int88 to add + */ + function pushInt88(Builder memory self, int88 element) internal pure { + unchecked { + self._data |= + (Int256.toBytes32(element) & (~bytes32(0) >> 168)) << + self._size; + self._size += 88; + } + } + + /** + * @notice remove last 11-byte segment from bytes and return as int88 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int88 derived from bytes + */ + function popInt88( + Builder memory self + ) internal pure returns (int88 element) { + unchecked { + self._size -= 88; + bytes32 mask = MASK_11; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = int88(Bytes32.toInt256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 11-byte segment from bytes and return as int88 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int88 derived from bytes + */ + function shiftInt88( + Builder memory self + ) internal pure returns (int88 element) { + unchecked { + bytes32 mask = MASK_11; + bytes32 elementBytes = self._data & mask; + element = int88(Bytes32.toInt256(elementBytes)); + self._data >>= 88; + self._size -= 88; + } + } + + /** + * @notice insert int88 value to 11-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int88 to add + */ + function unshiftInt88(Builder memory self, int88 element) internal pure { + unchecked { + self._data = + (self._data << 88) | + (Int256.toBytes32(element) & (~bytes32(0) >> 168)); + self._size += 88; + } + } + /** + * @notice insert uint88 value to 11-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint88 to add + */ + function pushUint88(Builder memory self, uint88 element) internal pure { + unchecked { + self._data |= Uint256.toBytes32(element) << self._size; + self._size += 88; + } + } + + /** + * @notice remove last 11-byte segment from bytes and return as uint88 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint88 derived from bytes + */ + function popUint88( + Builder memory self + ) internal pure returns (uint88 element) { + unchecked { + self._size -= 88; + bytes32 mask = MASK_11; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = uint88(Bytes32.toUint256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 11-byte segment from bytes and return as uint88 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint88 derived from bytes + */ + function shiftUint88( + Builder memory self + ) internal pure returns (uint88 element) { + unchecked { + bytes32 mask = MASK_11; + bytes32 elementBytes = self._data & mask; + element = uint88(Bytes32.toUint256(elementBytes)); + self._data >>= 88; + self._size -= 88; + } + } + + /** + * @notice insert uint88 value to 11-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint88 to add + */ + function unshiftUint88(Builder memory self, uint88 element) internal pure { + unchecked { + self._data = (self._data << 88) | Uint256.toBytes32(element); + self._size += 88; + } + } + /** + * @notice insert bytes12 value to 12-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes12 to add + */ + function pushBytes12(Builder memory self, bytes12 element) internal pure { + unchecked { + self._data |= (bytes32(element) >> 160) << self._size; + self._size += 96; + } + } + + /** + * @notice remove last 12-byte segment from bytes and return as bytes12 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes12 derived from bytes + */ + function popBytes12( + Builder memory self + ) internal pure returns (bytes12 element) { + unchecked { + self._size -= 96; + bytes32 mask = MASK_12; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = bytes12(elementBytes << 160); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 12-byte segment from bytes and return as bytes12 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes12 derived from bytes + */ + function shiftBytes12( + Builder memory self + ) internal pure returns (bytes12 element) { + unchecked { + bytes32 mask = MASK_12; + bytes32 elementBytes = self._data & mask; + element = bytes12(elementBytes << 160); + self._data >>= 96; + self._size -= 96; + } + } + + /** + * @notice insert bytes12 value to 12-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes12 to add + */ + function unshiftBytes12( + Builder memory self, + bytes12 element + ) internal pure { + unchecked { + self._data = (self._data << 96) | (bytes32(element) >> 160); + self._size += 96; + } + } + /** + * @notice insert int96 value to 12-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int96 to add + */ + function pushInt96(Builder memory self, int96 element) internal pure { + unchecked { + self._data |= + (Int256.toBytes32(element) & (~bytes32(0) >> 160)) << + self._size; + self._size += 96; + } + } + + /** + * @notice remove last 12-byte segment from bytes and return as int96 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int96 derived from bytes + */ + function popInt96( + Builder memory self + ) internal pure returns (int96 element) { + unchecked { + self._size -= 96; + bytes32 mask = MASK_12; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = int96(Bytes32.toInt256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 12-byte segment from bytes and return as int96 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int96 derived from bytes + */ + function shiftInt96( + Builder memory self + ) internal pure returns (int96 element) { + unchecked { + bytes32 mask = MASK_12; + bytes32 elementBytes = self._data & mask; + element = int96(Bytes32.toInt256(elementBytes)); + self._data >>= 96; + self._size -= 96; + } + } + + /** + * @notice insert int96 value to 12-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int96 to add + */ + function unshiftInt96(Builder memory self, int96 element) internal pure { + unchecked { + self._data = + (self._data << 96) | + (Int256.toBytes32(element) & (~bytes32(0) >> 160)); + self._size += 96; + } + } + /** + * @notice insert uint96 value to 12-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint96 to add + */ + function pushUint96(Builder memory self, uint96 element) internal pure { + unchecked { + self._data |= Uint256.toBytes32(element) << self._size; + self._size += 96; + } + } + + /** + * @notice remove last 12-byte segment from bytes and return as uint96 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint96 derived from bytes + */ + function popUint96( + Builder memory self + ) internal pure returns (uint96 element) { + unchecked { + self._size -= 96; + bytes32 mask = MASK_12; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = uint96(Bytes32.toUint256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 12-byte segment from bytes and return as uint96 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint96 derived from bytes + */ + function shiftUint96( + Builder memory self + ) internal pure returns (uint96 element) { + unchecked { + bytes32 mask = MASK_12; + bytes32 elementBytes = self._data & mask; + element = uint96(Bytes32.toUint256(elementBytes)); + self._data >>= 96; + self._size -= 96; + } + } + + /** + * @notice insert uint96 value to 12-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint96 to add + */ + function unshiftUint96(Builder memory self, uint96 element) internal pure { + unchecked { + self._data = (self._data << 96) | Uint256.toBytes32(element); + self._size += 96; + } + } + /** + * @notice insert bytes13 value to 13-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes13 to add + */ + function pushBytes13(Builder memory self, bytes13 element) internal pure { + unchecked { + self._data |= (bytes32(element) >> 152) << self._size; + self._size += 104; + } + } + + /** + * @notice remove last 13-byte segment from bytes and return as bytes13 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes13 derived from bytes + */ + function popBytes13( + Builder memory self + ) internal pure returns (bytes13 element) { + unchecked { + self._size -= 104; + bytes32 mask = MASK_13; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = bytes13(elementBytes << 152); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 13-byte segment from bytes and return as bytes13 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes13 derived from bytes + */ + function shiftBytes13( + Builder memory self + ) internal pure returns (bytes13 element) { + unchecked { + bytes32 mask = MASK_13; + bytes32 elementBytes = self._data & mask; + element = bytes13(elementBytes << 152); + self._data >>= 104; + self._size -= 104; + } + } + + /** + * @notice insert bytes13 value to 13-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes13 to add + */ + function unshiftBytes13( + Builder memory self, + bytes13 element + ) internal pure { + unchecked { + self._data = (self._data << 104) | (bytes32(element) >> 152); + self._size += 104; + } + } + /** + * @notice insert int104 value to 13-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int104 to add + */ + function pushInt104(Builder memory self, int104 element) internal pure { + unchecked { + self._data |= + (Int256.toBytes32(element) & (~bytes32(0) >> 152)) << + self._size; + self._size += 104; + } + } + + /** + * @notice remove last 13-byte segment from bytes and return as int104 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int104 derived from bytes + */ + function popInt104( + Builder memory self + ) internal pure returns (int104 element) { + unchecked { + self._size -= 104; + bytes32 mask = MASK_13; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = int104(Bytes32.toInt256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 13-byte segment from bytes and return as int104 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int104 derived from bytes + */ + function shiftInt104( + Builder memory self + ) internal pure returns (int104 element) { + unchecked { + bytes32 mask = MASK_13; + bytes32 elementBytes = self._data & mask; + element = int104(Bytes32.toInt256(elementBytes)); + self._data >>= 104; + self._size -= 104; + } + } + + /** + * @notice insert int104 value to 13-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int104 to add + */ + function unshiftInt104(Builder memory self, int104 element) internal pure { + unchecked { + self._data = + (self._data << 104) | + (Int256.toBytes32(element) & (~bytes32(0) >> 152)); + self._size += 104; + } + } + /** + * @notice insert uint104 value to 13-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint104 to add + */ + function pushUint104(Builder memory self, uint104 element) internal pure { + unchecked { + self._data |= Uint256.toBytes32(element) << self._size; + self._size += 104; + } + } + + /** + * @notice remove last 13-byte segment from bytes and return as uint104 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint104 derived from bytes + */ + function popUint104( + Builder memory self + ) internal pure returns (uint104 element) { + unchecked { + self._size -= 104; + bytes32 mask = MASK_13; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = uint104(Bytes32.toUint256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 13-byte segment from bytes and return as uint104 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint104 derived from bytes + */ + function shiftUint104( + Builder memory self + ) internal pure returns (uint104 element) { + unchecked { + bytes32 mask = MASK_13; + bytes32 elementBytes = self._data & mask; + element = uint104(Bytes32.toUint256(elementBytes)); + self._data >>= 104; + self._size -= 104; + } + } + + /** + * @notice insert uint104 value to 13-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint104 to add + */ + function unshiftUint104( + Builder memory self, + uint104 element + ) internal pure { + unchecked { + self._data = (self._data << 104) | Uint256.toBytes32(element); + self._size += 104; + } + } + /** + * @notice insert bytes14 value to 14-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes14 to add + */ + function pushBytes14(Builder memory self, bytes14 element) internal pure { + unchecked { + self._data |= (bytes32(element) >> 144) << self._size; + self._size += 112; + } + } + + /** + * @notice remove last 14-byte segment from bytes and return as bytes14 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes14 derived from bytes + */ + function popBytes14( + Builder memory self + ) internal pure returns (bytes14 element) { + unchecked { + self._size -= 112; + bytes32 mask = MASK_14; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = bytes14(elementBytes << 144); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 14-byte segment from bytes and return as bytes14 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes14 derived from bytes + */ + function shiftBytes14( + Builder memory self + ) internal pure returns (bytes14 element) { + unchecked { + bytes32 mask = MASK_14; + bytes32 elementBytes = self._data & mask; + element = bytes14(elementBytes << 144); + self._data >>= 112; + self._size -= 112; + } + } + + /** + * @notice insert bytes14 value to 14-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes14 to add + */ + function unshiftBytes14( + Builder memory self, + bytes14 element + ) internal pure { + unchecked { + self._data = (self._data << 112) | (bytes32(element) >> 144); + self._size += 112; + } + } + /** + * @notice insert int112 value to 14-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int112 to add + */ + function pushInt112(Builder memory self, int112 element) internal pure { + unchecked { + self._data |= + (Int256.toBytes32(element) & (~bytes32(0) >> 144)) << + self._size; + self._size += 112; + } + } + + /** + * @notice remove last 14-byte segment from bytes and return as int112 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int112 derived from bytes + */ + function popInt112( + Builder memory self + ) internal pure returns (int112 element) { + unchecked { + self._size -= 112; + bytes32 mask = MASK_14; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = int112(Bytes32.toInt256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 14-byte segment from bytes and return as int112 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int112 derived from bytes + */ + function shiftInt112( + Builder memory self + ) internal pure returns (int112 element) { + unchecked { + bytes32 mask = MASK_14; + bytes32 elementBytes = self._data & mask; + element = int112(Bytes32.toInt256(elementBytes)); + self._data >>= 112; + self._size -= 112; + } + } + + /** + * @notice insert int112 value to 14-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int112 to add + */ + function unshiftInt112(Builder memory self, int112 element) internal pure { + unchecked { + self._data = + (self._data << 112) | + (Int256.toBytes32(element) & (~bytes32(0) >> 144)); + self._size += 112; + } + } + /** + * @notice insert uint112 value to 14-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint112 to add + */ + function pushUint112(Builder memory self, uint112 element) internal pure { + unchecked { + self._data |= Uint256.toBytes32(element) << self._size; + self._size += 112; + } + } + + /** + * @notice remove last 14-byte segment from bytes and return as uint112 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint112 derived from bytes + */ + function popUint112( + Builder memory self + ) internal pure returns (uint112 element) { + unchecked { + self._size -= 112; + bytes32 mask = MASK_14; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = uint112(Bytes32.toUint256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 14-byte segment from bytes and return as uint112 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint112 derived from bytes + */ + function shiftUint112( + Builder memory self + ) internal pure returns (uint112 element) { + unchecked { + bytes32 mask = MASK_14; + bytes32 elementBytes = self._data & mask; + element = uint112(Bytes32.toUint256(elementBytes)); + self._data >>= 112; + self._size -= 112; + } + } + + /** + * @notice insert uint112 value to 14-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint112 to add + */ + function unshiftUint112( + Builder memory self, + uint112 element + ) internal pure { + unchecked { + self._data = (self._data << 112) | Uint256.toBytes32(element); + self._size += 112; + } + } + /** + * @notice insert bytes15 value to 15-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes15 to add + */ + function pushBytes15(Builder memory self, bytes15 element) internal pure { + unchecked { + self._data |= (bytes32(element) >> 136) << self._size; + self._size += 120; + } + } + + /** + * @notice remove last 15-byte segment from bytes and return as bytes15 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes15 derived from bytes + */ + function popBytes15( + Builder memory self + ) internal pure returns (bytes15 element) { + unchecked { + self._size -= 120; + bytes32 mask = MASK_15; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = bytes15(elementBytes << 136); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 15-byte segment from bytes and return as bytes15 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes15 derived from bytes + */ + function shiftBytes15( + Builder memory self + ) internal pure returns (bytes15 element) { + unchecked { + bytes32 mask = MASK_15; + bytes32 elementBytes = self._data & mask; + element = bytes15(elementBytes << 136); + self._data >>= 120; + self._size -= 120; + } + } + + /** + * @notice insert bytes15 value to 15-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes15 to add + */ + function unshiftBytes15( + Builder memory self, + bytes15 element + ) internal pure { + unchecked { + self._data = (self._data << 120) | (bytes32(element) >> 136); + self._size += 120; + } + } + /** + * @notice insert int120 value to 15-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int120 to add + */ + function pushInt120(Builder memory self, int120 element) internal pure { + unchecked { + self._data |= + (Int256.toBytes32(element) & (~bytes32(0) >> 136)) << + self._size; + self._size += 120; + } + } + + /** + * @notice remove last 15-byte segment from bytes and return as int120 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int120 derived from bytes + */ + function popInt120( + Builder memory self + ) internal pure returns (int120 element) { + unchecked { + self._size -= 120; + bytes32 mask = MASK_15; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = int120(Bytes32.toInt256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 15-byte segment from bytes and return as int120 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int120 derived from bytes + */ + function shiftInt120( + Builder memory self + ) internal pure returns (int120 element) { + unchecked { + bytes32 mask = MASK_15; + bytes32 elementBytes = self._data & mask; + element = int120(Bytes32.toInt256(elementBytes)); + self._data >>= 120; + self._size -= 120; + } + } + + /** + * @notice insert int120 value to 15-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int120 to add + */ + function unshiftInt120(Builder memory self, int120 element) internal pure { + unchecked { + self._data = + (self._data << 120) | + (Int256.toBytes32(element) & (~bytes32(0) >> 136)); + self._size += 120; + } + } + /** + * @notice insert uint120 value to 15-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint120 to add + */ + function pushUint120(Builder memory self, uint120 element) internal pure { + unchecked { + self._data |= Uint256.toBytes32(element) << self._size; + self._size += 120; + } + } + + /** + * @notice remove last 15-byte segment from bytes and return as uint120 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint120 derived from bytes + */ + function popUint120( + Builder memory self + ) internal pure returns (uint120 element) { + unchecked { + self._size -= 120; + bytes32 mask = MASK_15; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = uint120(Bytes32.toUint256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 15-byte segment from bytes and return as uint120 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint120 derived from bytes + */ + function shiftUint120( + Builder memory self + ) internal pure returns (uint120 element) { + unchecked { + bytes32 mask = MASK_15; + bytes32 elementBytes = self._data & mask; + element = uint120(Bytes32.toUint256(elementBytes)); + self._data >>= 120; + self._size -= 120; + } + } + + /** + * @notice insert uint120 value to 15-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint120 to add + */ + function unshiftUint120( + Builder memory self, + uint120 element + ) internal pure { + unchecked { + self._data = (self._data << 120) | Uint256.toBytes32(element); + self._size += 120; + } + } + /** + * @notice insert bytes16 value to 16-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes16 to add + */ + function pushBytes16(Builder memory self, bytes16 element) internal pure { + unchecked { + self._data |= (bytes32(element) >> 128) << self._size; + self._size += 128; + } + } + + /** + * @notice remove last 16-byte segment from bytes and return as bytes16 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes16 derived from bytes + */ + function popBytes16( + Builder memory self + ) internal pure returns (bytes16 element) { + unchecked { + self._size -= 128; + bytes32 mask = MASK_16; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = bytes16(elementBytes << 128); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 16-byte segment from bytes and return as bytes16 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes16 derived from bytes + */ + function shiftBytes16( + Builder memory self + ) internal pure returns (bytes16 element) { + unchecked { + bytes32 mask = MASK_16; + bytes32 elementBytes = self._data & mask; + element = bytes16(elementBytes << 128); + self._data >>= 128; + self._size -= 128; + } + } + + /** + * @notice insert bytes16 value to 16-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes16 to add + */ + function unshiftBytes16( + Builder memory self, + bytes16 element + ) internal pure { + unchecked { + self._data = (self._data << 128) | (bytes32(element) >> 128); + self._size += 128; + } + } + /** + * @notice insert int128 value to 16-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int128 to add + */ + function pushInt128(Builder memory self, int128 element) internal pure { + unchecked { + self._data |= + (Int256.toBytes32(element) & (~bytes32(0) >> 128)) << + self._size; + self._size += 128; + } + } + + /** + * @notice remove last 16-byte segment from bytes and return as int128 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int128 derived from bytes + */ + function popInt128( + Builder memory self + ) internal pure returns (int128 element) { + unchecked { + self._size -= 128; + bytes32 mask = MASK_16; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = int128(Bytes32.toInt256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 16-byte segment from bytes and return as int128 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int128 derived from bytes + */ + function shiftInt128( + Builder memory self + ) internal pure returns (int128 element) { + unchecked { + bytes32 mask = MASK_16; + bytes32 elementBytes = self._data & mask; + element = int128(Bytes32.toInt256(elementBytes)); + self._data >>= 128; + self._size -= 128; + } + } + + /** + * @notice insert int128 value to 16-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int128 to add + */ + function unshiftInt128(Builder memory self, int128 element) internal pure { + unchecked { + self._data = + (self._data << 128) | + (Int256.toBytes32(element) & (~bytes32(0) >> 128)); + self._size += 128; + } + } + /** + * @notice insert uint128 value to 16-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint128 to add + */ + function pushUint128(Builder memory self, uint128 element) internal pure { + unchecked { + self._data |= Uint256.toBytes32(element) << self._size; + self._size += 128; + } + } + + /** + * @notice remove last 16-byte segment from bytes and return as uint128 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint128 derived from bytes + */ + function popUint128( + Builder memory self + ) internal pure returns (uint128 element) { + unchecked { + self._size -= 128; + bytes32 mask = MASK_16; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = uint128(Bytes32.toUint256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 16-byte segment from bytes and return as uint128 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint128 derived from bytes + */ + function shiftUint128( + Builder memory self + ) internal pure returns (uint128 element) { + unchecked { + bytes32 mask = MASK_16; + bytes32 elementBytes = self._data & mask; + element = uint128(Bytes32.toUint256(elementBytes)); + self._data >>= 128; + self._size -= 128; + } + } + + /** + * @notice insert uint128 value to 16-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint128 to add + */ + function unshiftUint128( + Builder memory self, + uint128 element + ) internal pure { + unchecked { + self._data = (self._data << 128) | Uint256.toBytes32(element); + self._size += 128; + } + } + /** + * @notice insert bytes17 value to 17-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes17 to add + */ + function pushBytes17(Builder memory self, bytes17 element) internal pure { + unchecked { + self._data |= (bytes32(element) >> 120) << self._size; + self._size += 136; + } + } + + /** + * @notice remove last 17-byte segment from bytes and return as bytes17 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes17 derived from bytes + */ + function popBytes17( + Builder memory self + ) internal pure returns (bytes17 element) { + unchecked { + self._size -= 136; + bytes32 mask = MASK_17; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = bytes17(elementBytes << 120); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 17-byte segment from bytes and return as bytes17 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes17 derived from bytes + */ + function shiftBytes17( + Builder memory self + ) internal pure returns (bytes17 element) { + unchecked { + bytes32 mask = MASK_17; + bytes32 elementBytes = self._data & mask; + element = bytes17(elementBytes << 120); + self._data >>= 136; + self._size -= 136; + } + } + + /** + * @notice insert bytes17 value to 17-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes17 to add + */ + function unshiftBytes17( + Builder memory self, + bytes17 element + ) internal pure { + unchecked { + self._data = (self._data << 136) | (bytes32(element) >> 120); + self._size += 136; + } + } + /** + * @notice insert int136 value to 17-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int136 to add + */ + function pushInt136(Builder memory self, int136 element) internal pure { + unchecked { + self._data |= + (Int256.toBytes32(element) & (~bytes32(0) >> 120)) << + self._size; + self._size += 136; + } + } + + /** + * @notice remove last 17-byte segment from bytes and return as int136 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int136 derived from bytes + */ + function popInt136( + Builder memory self + ) internal pure returns (int136 element) { + unchecked { + self._size -= 136; + bytes32 mask = MASK_17; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = int136(Bytes32.toInt256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 17-byte segment from bytes and return as int136 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int136 derived from bytes + */ + function shiftInt136( + Builder memory self + ) internal pure returns (int136 element) { + unchecked { + bytes32 mask = MASK_17; + bytes32 elementBytes = self._data & mask; + element = int136(Bytes32.toInt256(elementBytes)); + self._data >>= 136; + self._size -= 136; + } + } + + /** + * @notice insert int136 value to 17-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int136 to add + */ + function unshiftInt136(Builder memory self, int136 element) internal pure { + unchecked { + self._data = + (self._data << 136) | + (Int256.toBytes32(element) & (~bytes32(0) >> 120)); + self._size += 136; + } + } + /** + * @notice insert uint136 value to 17-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint136 to add + */ + function pushUint136(Builder memory self, uint136 element) internal pure { + unchecked { + self._data |= Uint256.toBytes32(element) << self._size; + self._size += 136; + } + } + + /** + * @notice remove last 17-byte segment from bytes and return as uint136 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint136 derived from bytes + */ + function popUint136( + Builder memory self + ) internal pure returns (uint136 element) { + unchecked { + self._size -= 136; + bytes32 mask = MASK_17; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = uint136(Bytes32.toUint256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 17-byte segment from bytes and return as uint136 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint136 derived from bytes + */ + function shiftUint136( + Builder memory self + ) internal pure returns (uint136 element) { + unchecked { + bytes32 mask = MASK_17; + bytes32 elementBytes = self._data & mask; + element = uint136(Bytes32.toUint256(elementBytes)); + self._data >>= 136; + self._size -= 136; + } + } + + /** + * @notice insert uint136 value to 17-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint136 to add + */ + function unshiftUint136( + Builder memory self, + uint136 element + ) internal pure { + unchecked { + self._data = (self._data << 136) | Uint256.toBytes32(element); + self._size += 136; + } + } + /** + * @notice insert bytes18 value to 18-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes18 to add + */ + function pushBytes18(Builder memory self, bytes18 element) internal pure { + unchecked { + self._data |= (bytes32(element) >> 112) << self._size; + self._size += 144; + } + } + + /** + * @notice remove last 18-byte segment from bytes and return as bytes18 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes18 derived from bytes + */ + function popBytes18( + Builder memory self + ) internal pure returns (bytes18 element) { + unchecked { + self._size -= 144; + bytes32 mask = MASK_18; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = bytes18(elementBytes << 112); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 18-byte segment from bytes and return as bytes18 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes18 derived from bytes + */ + function shiftBytes18( + Builder memory self + ) internal pure returns (bytes18 element) { + unchecked { + bytes32 mask = MASK_18; + bytes32 elementBytes = self._data & mask; + element = bytes18(elementBytes << 112); + self._data >>= 144; + self._size -= 144; + } + } + + /** + * @notice insert bytes18 value to 18-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes18 to add + */ + function unshiftBytes18( + Builder memory self, + bytes18 element + ) internal pure { + unchecked { + self._data = (self._data << 144) | (bytes32(element) >> 112); + self._size += 144; + } + } + /** + * @notice insert int144 value to 18-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int144 to add + */ + function pushInt144(Builder memory self, int144 element) internal pure { + unchecked { + self._data |= + (Int256.toBytes32(element) & (~bytes32(0) >> 112)) << + self._size; + self._size += 144; + } + } + + /** + * @notice remove last 18-byte segment from bytes and return as int144 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int144 derived from bytes + */ + function popInt144( + Builder memory self + ) internal pure returns (int144 element) { + unchecked { + self._size -= 144; + bytes32 mask = MASK_18; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = int144(Bytes32.toInt256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 18-byte segment from bytes and return as int144 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int144 derived from bytes + */ + function shiftInt144( + Builder memory self + ) internal pure returns (int144 element) { + unchecked { + bytes32 mask = MASK_18; + bytes32 elementBytes = self._data & mask; + element = int144(Bytes32.toInt256(elementBytes)); + self._data >>= 144; + self._size -= 144; + } + } + + /** + * @notice insert int144 value to 18-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int144 to add + */ + function unshiftInt144(Builder memory self, int144 element) internal pure { + unchecked { + self._data = + (self._data << 144) | + (Int256.toBytes32(element) & (~bytes32(0) >> 112)); + self._size += 144; + } + } + /** + * @notice insert uint144 value to 18-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint144 to add + */ + function pushUint144(Builder memory self, uint144 element) internal pure { + unchecked { + self._data |= Uint256.toBytes32(element) << self._size; + self._size += 144; + } + } + + /** + * @notice remove last 18-byte segment from bytes and return as uint144 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint144 derived from bytes + */ + function popUint144( + Builder memory self + ) internal pure returns (uint144 element) { + unchecked { + self._size -= 144; + bytes32 mask = MASK_18; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = uint144(Bytes32.toUint256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 18-byte segment from bytes and return as uint144 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint144 derived from bytes + */ + function shiftUint144( + Builder memory self + ) internal pure returns (uint144 element) { + unchecked { + bytes32 mask = MASK_18; + bytes32 elementBytes = self._data & mask; + element = uint144(Bytes32.toUint256(elementBytes)); + self._data >>= 144; + self._size -= 144; + } + } + + /** + * @notice insert uint144 value to 18-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint144 to add + */ + function unshiftUint144( + Builder memory self, + uint144 element + ) internal pure { + unchecked { + self._data = (self._data << 144) | Uint256.toBytes32(element); + self._size += 144; + } + } + /** + * @notice insert bytes19 value to 19-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes19 to add + */ + function pushBytes19(Builder memory self, bytes19 element) internal pure { + unchecked { + self._data |= (bytes32(element) >> 104) << self._size; + self._size += 152; + } + } + + /** + * @notice remove last 19-byte segment from bytes and return as bytes19 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes19 derived from bytes + */ + function popBytes19( + Builder memory self + ) internal pure returns (bytes19 element) { + unchecked { + self._size -= 152; + bytes32 mask = MASK_19; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = bytes19(elementBytes << 104); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 19-byte segment from bytes and return as bytes19 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes19 derived from bytes + */ + function shiftBytes19( + Builder memory self + ) internal pure returns (bytes19 element) { + unchecked { + bytes32 mask = MASK_19; + bytes32 elementBytes = self._data & mask; + element = bytes19(elementBytes << 104); + self._data >>= 152; + self._size -= 152; + } + } + + /** + * @notice insert bytes19 value to 19-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes19 to add + */ + function unshiftBytes19( + Builder memory self, + bytes19 element + ) internal pure { + unchecked { + self._data = (self._data << 152) | (bytes32(element) >> 104); + self._size += 152; + } + } + /** + * @notice insert int152 value to 19-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int152 to add + */ + function pushInt152(Builder memory self, int152 element) internal pure { + unchecked { + self._data |= + (Int256.toBytes32(element) & (~bytes32(0) >> 104)) << + self._size; + self._size += 152; + } + } + + /** + * @notice remove last 19-byte segment from bytes and return as int152 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int152 derived from bytes + */ + function popInt152( + Builder memory self + ) internal pure returns (int152 element) { + unchecked { + self._size -= 152; + bytes32 mask = MASK_19; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = int152(Bytes32.toInt256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 19-byte segment from bytes and return as int152 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int152 derived from bytes + */ + function shiftInt152( + Builder memory self + ) internal pure returns (int152 element) { + unchecked { + bytes32 mask = MASK_19; + bytes32 elementBytes = self._data & mask; + element = int152(Bytes32.toInt256(elementBytes)); + self._data >>= 152; + self._size -= 152; + } + } + + /** + * @notice insert int152 value to 19-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int152 to add + */ + function unshiftInt152(Builder memory self, int152 element) internal pure { + unchecked { + self._data = + (self._data << 152) | + (Int256.toBytes32(element) & (~bytes32(0) >> 104)); + self._size += 152; + } + } + /** + * @notice insert uint152 value to 19-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint152 to add + */ + function pushUint152(Builder memory self, uint152 element) internal pure { + unchecked { + self._data |= Uint256.toBytes32(element) << self._size; + self._size += 152; + } + } + + /** + * @notice remove last 19-byte segment from bytes and return as uint152 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint152 derived from bytes + */ + function popUint152( + Builder memory self + ) internal pure returns (uint152 element) { + unchecked { + self._size -= 152; + bytes32 mask = MASK_19; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = uint152(Bytes32.toUint256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 19-byte segment from bytes and return as uint152 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint152 derived from bytes + */ + function shiftUint152( + Builder memory self + ) internal pure returns (uint152 element) { + unchecked { + bytes32 mask = MASK_19; + bytes32 elementBytes = self._data & mask; + element = uint152(Bytes32.toUint256(elementBytes)); + self._data >>= 152; + self._size -= 152; + } + } + + /** + * @notice insert uint152 value to 19-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint152 to add + */ + function unshiftUint152( + Builder memory self, + uint152 element + ) internal pure { + unchecked { + self._data = (self._data << 152) | Uint256.toBytes32(element); + self._size += 152; + } + } + /** + * @notice insert bytes20 value to 20-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes20 to add + */ + function pushBytes20(Builder memory self, bytes20 element) internal pure { + unchecked { + self._data |= (bytes32(element) >> 96) << self._size; + self._size += 160; + } + } + + /** + * @notice remove last 20-byte segment from bytes and return as bytes20 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes20 derived from bytes + */ + function popBytes20( + Builder memory self + ) internal pure returns (bytes20 element) { + unchecked { + self._size -= 160; + bytes32 mask = MASK_20; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = bytes20(elementBytes << 96); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 20-byte segment from bytes and return as bytes20 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes20 derived from bytes + */ + function shiftBytes20( + Builder memory self + ) internal pure returns (bytes20 element) { + unchecked { + bytes32 mask = MASK_20; + bytes32 elementBytes = self._data & mask; + element = bytes20(elementBytes << 96); + self._data >>= 160; + self._size -= 160; + } + } + + /** + * @notice insert bytes20 value to 20-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes20 to add + */ + function unshiftBytes20( + Builder memory self, + bytes20 element + ) internal pure { + unchecked { + self._data = (self._data << 160) | (bytes32(element) >> 96); + self._size += 160; + } + } + /** + * @notice insert int160 value to 20-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int160 to add + */ + function pushInt160(Builder memory self, int160 element) internal pure { + unchecked { + self._data |= + (Int256.toBytes32(element) & (~bytes32(0) >> 96)) << + self._size; + self._size += 160; + } + } + + /** + * @notice remove last 20-byte segment from bytes and return as int160 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int160 derived from bytes + */ + function popInt160( + Builder memory self + ) internal pure returns (int160 element) { + unchecked { + self._size -= 160; + bytes32 mask = MASK_20; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = int160(Bytes32.toInt256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 20-byte segment from bytes and return as int160 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int160 derived from bytes + */ + function shiftInt160( + Builder memory self + ) internal pure returns (int160 element) { + unchecked { + bytes32 mask = MASK_20; + bytes32 elementBytes = self._data & mask; + element = int160(Bytes32.toInt256(elementBytes)); + self._data >>= 160; + self._size -= 160; + } + } + + /** + * @notice insert int160 value to 20-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int160 to add + */ + function unshiftInt160(Builder memory self, int160 element) internal pure { + unchecked { + self._data = + (self._data << 160) | + (Int256.toBytes32(element) & (~bytes32(0) >> 96)); + self._size += 160; + } + } + /** + * @notice insert uint160 value to 20-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint160 to add + */ + function pushUint160(Builder memory self, uint160 element) internal pure { + unchecked { + self._data |= Uint256.toBytes32(element) << self._size; + self._size += 160; + } + } + + /** + * @notice remove last 20-byte segment from bytes and return as uint160 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint160 derived from bytes + */ + function popUint160( + Builder memory self + ) internal pure returns (uint160 element) { + unchecked { + self._size -= 160; + bytes32 mask = MASK_20; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = uint160(Bytes32.toUint256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 20-byte segment from bytes and return as uint160 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint160 derived from bytes + */ + function shiftUint160( + Builder memory self + ) internal pure returns (uint160 element) { + unchecked { + bytes32 mask = MASK_20; + bytes32 elementBytes = self._data & mask; + element = uint160(Bytes32.toUint256(elementBytes)); + self._data >>= 160; + self._size -= 160; + } + } + + /** + * @notice insert uint160 value to 20-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint160 to add + */ + function unshiftUint160( + Builder memory self, + uint160 element + ) internal pure { + unchecked { + self._data = (self._data << 160) | Uint256.toBytes32(element); + self._size += 160; + } + } + /** + * @notice insert address value to 20-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element address to add + */ + function pushAddress(Builder memory self, address element) internal pure { + unchecked { + self._data |= Address.toBytes32(element) << self._size; + self._size += 160; + } + } + + /** + * @notice remove last 20-byte segment from bytes and return as address + * @param self Bytes32Builder Builder struct on which to operate + * @return element address derived from bytes + */ + function popAddress( + Builder memory self + ) internal pure returns (address element) { + unchecked { + self._size -= 160; + bytes32 mask = MASK_20; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = Bytes32.toAddress(elementBytes); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 20-byte segment from bytes and return as address + * @param self Bytes32Builder Builder struct on which to operate + * @return element address derived from bytes + */ + function shiftAddress( + Builder memory self + ) internal pure returns (address element) { + unchecked { + bytes32 mask = MASK_20; + bytes32 elementBytes = self._data & mask; + element = Bytes32.toAddress(elementBytes); + self._data >>= 160; + self._size -= 160; + } + } + + /** + * @notice insert address value to 20-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element address to add + */ + function unshiftAddress( + Builder memory self, + address element + ) internal pure { + unchecked { + self._data = (self._data << 160) | Address.toBytes32(element); + self._size += 160; + } + } + /** + * @notice insert bytes21 value to 21-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes21 to add + */ + function pushBytes21(Builder memory self, bytes21 element) internal pure { + unchecked { + self._data |= (bytes32(element) >> 88) << self._size; + self._size += 168; + } + } + + /** + * @notice remove last 21-byte segment from bytes and return as bytes21 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes21 derived from bytes + */ + function popBytes21( + Builder memory self + ) internal pure returns (bytes21 element) { + unchecked { + self._size -= 168; + bytes32 mask = MASK_21; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = bytes21(elementBytes << 88); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 21-byte segment from bytes and return as bytes21 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes21 derived from bytes + */ + function shiftBytes21( + Builder memory self + ) internal pure returns (bytes21 element) { + unchecked { + bytes32 mask = MASK_21; + bytes32 elementBytes = self._data & mask; + element = bytes21(elementBytes << 88); + self._data >>= 168; + self._size -= 168; + } + } + + /** + * @notice insert bytes21 value to 21-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes21 to add + */ + function unshiftBytes21( + Builder memory self, + bytes21 element + ) internal pure { + unchecked { + self._data = (self._data << 168) | (bytes32(element) >> 88); + self._size += 168; + } + } + /** + * @notice insert int168 value to 21-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int168 to add + */ + function pushInt168(Builder memory self, int168 element) internal pure { + unchecked { + self._data |= + (Int256.toBytes32(element) & (~bytes32(0) >> 88)) << + self._size; + self._size += 168; + } + } + + /** + * @notice remove last 21-byte segment from bytes and return as int168 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int168 derived from bytes + */ + function popInt168( + Builder memory self + ) internal pure returns (int168 element) { + unchecked { + self._size -= 168; + bytes32 mask = MASK_21; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = int168(Bytes32.toInt256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 21-byte segment from bytes and return as int168 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int168 derived from bytes + */ + function shiftInt168( + Builder memory self + ) internal pure returns (int168 element) { + unchecked { + bytes32 mask = MASK_21; + bytes32 elementBytes = self._data & mask; + element = int168(Bytes32.toInt256(elementBytes)); + self._data >>= 168; + self._size -= 168; + } + } + + /** + * @notice insert int168 value to 21-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int168 to add + */ + function unshiftInt168(Builder memory self, int168 element) internal pure { + unchecked { + self._data = + (self._data << 168) | + (Int256.toBytes32(element) & (~bytes32(0) >> 88)); + self._size += 168; + } + } + /** + * @notice insert uint168 value to 21-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint168 to add + */ + function pushUint168(Builder memory self, uint168 element) internal pure { + unchecked { + self._data |= Uint256.toBytes32(element) << self._size; + self._size += 168; + } + } + + /** + * @notice remove last 21-byte segment from bytes and return as uint168 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint168 derived from bytes + */ + function popUint168( + Builder memory self + ) internal pure returns (uint168 element) { + unchecked { + self._size -= 168; + bytes32 mask = MASK_21; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = uint168(Bytes32.toUint256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 21-byte segment from bytes and return as uint168 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint168 derived from bytes + */ + function shiftUint168( + Builder memory self + ) internal pure returns (uint168 element) { + unchecked { + bytes32 mask = MASK_21; + bytes32 elementBytes = self._data & mask; + element = uint168(Bytes32.toUint256(elementBytes)); + self._data >>= 168; + self._size -= 168; + } + } + + /** + * @notice insert uint168 value to 21-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint168 to add + */ + function unshiftUint168( + Builder memory self, + uint168 element + ) internal pure { + unchecked { + self._data = (self._data << 168) | Uint256.toBytes32(element); + self._size += 168; + } + } + /** + * @notice insert bytes22 value to 22-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes22 to add + */ + function pushBytes22(Builder memory self, bytes22 element) internal pure { + unchecked { + self._data |= (bytes32(element) >> 80) << self._size; + self._size += 176; + } + } + + /** + * @notice remove last 22-byte segment from bytes and return as bytes22 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes22 derived from bytes + */ + function popBytes22( + Builder memory self + ) internal pure returns (bytes22 element) { + unchecked { + self._size -= 176; + bytes32 mask = MASK_22; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = bytes22(elementBytes << 80); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 22-byte segment from bytes and return as bytes22 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes22 derived from bytes + */ + function shiftBytes22( + Builder memory self + ) internal pure returns (bytes22 element) { + unchecked { + bytes32 mask = MASK_22; + bytes32 elementBytes = self._data & mask; + element = bytes22(elementBytes << 80); + self._data >>= 176; + self._size -= 176; + } + } + + /** + * @notice insert bytes22 value to 22-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes22 to add + */ + function unshiftBytes22( + Builder memory self, + bytes22 element + ) internal pure { + unchecked { + self._data = (self._data << 176) | (bytes32(element) >> 80); + self._size += 176; + } + } + /** + * @notice insert int176 value to 22-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int176 to add + */ + function pushInt176(Builder memory self, int176 element) internal pure { + unchecked { + self._data |= + (Int256.toBytes32(element) & (~bytes32(0) >> 80)) << + self._size; + self._size += 176; + } + } + + /** + * @notice remove last 22-byte segment from bytes and return as int176 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int176 derived from bytes + */ + function popInt176( + Builder memory self + ) internal pure returns (int176 element) { + unchecked { + self._size -= 176; + bytes32 mask = MASK_22; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = int176(Bytes32.toInt256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 22-byte segment from bytes and return as int176 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int176 derived from bytes + */ + function shiftInt176( + Builder memory self + ) internal pure returns (int176 element) { + unchecked { + bytes32 mask = MASK_22; + bytes32 elementBytes = self._data & mask; + element = int176(Bytes32.toInt256(elementBytes)); + self._data >>= 176; + self._size -= 176; + } + } + + /** + * @notice insert int176 value to 22-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int176 to add + */ + function unshiftInt176(Builder memory self, int176 element) internal pure { + unchecked { + self._data = + (self._data << 176) | + (Int256.toBytes32(element) & (~bytes32(0) >> 80)); + self._size += 176; + } + } + /** + * @notice insert uint176 value to 22-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint176 to add + */ + function pushUint176(Builder memory self, uint176 element) internal pure { + unchecked { + self._data |= Uint256.toBytes32(element) << self._size; + self._size += 176; + } + } + + /** + * @notice remove last 22-byte segment from bytes and return as uint176 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint176 derived from bytes + */ + function popUint176( + Builder memory self + ) internal pure returns (uint176 element) { + unchecked { + self._size -= 176; + bytes32 mask = MASK_22; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = uint176(Bytes32.toUint256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 22-byte segment from bytes and return as uint176 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint176 derived from bytes + */ + function shiftUint176( + Builder memory self + ) internal pure returns (uint176 element) { + unchecked { + bytes32 mask = MASK_22; + bytes32 elementBytes = self._data & mask; + element = uint176(Bytes32.toUint256(elementBytes)); + self._data >>= 176; + self._size -= 176; + } + } + + /** + * @notice insert uint176 value to 22-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint176 to add + */ + function unshiftUint176( + Builder memory self, + uint176 element + ) internal pure { + unchecked { + self._data = (self._data << 176) | Uint256.toBytes32(element); + self._size += 176; + } + } + /** + * @notice insert bytes23 value to 23-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes23 to add + */ + function pushBytes23(Builder memory self, bytes23 element) internal pure { + unchecked { + self._data |= (bytes32(element) >> 72) << self._size; + self._size += 184; + } + } + + /** + * @notice remove last 23-byte segment from bytes and return as bytes23 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes23 derived from bytes + */ + function popBytes23( + Builder memory self + ) internal pure returns (bytes23 element) { + unchecked { + self._size -= 184; + bytes32 mask = MASK_23; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = bytes23(elementBytes << 72); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 23-byte segment from bytes and return as bytes23 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes23 derived from bytes + */ + function shiftBytes23( + Builder memory self + ) internal pure returns (bytes23 element) { + unchecked { + bytes32 mask = MASK_23; + bytes32 elementBytes = self._data & mask; + element = bytes23(elementBytes << 72); + self._data >>= 184; + self._size -= 184; + } + } + + /** + * @notice insert bytes23 value to 23-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes23 to add + */ + function unshiftBytes23( + Builder memory self, + bytes23 element + ) internal pure { + unchecked { + self._data = (self._data << 184) | (bytes32(element) >> 72); + self._size += 184; + } + } + /** + * @notice insert int184 value to 23-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int184 to add + */ + function pushInt184(Builder memory self, int184 element) internal pure { + unchecked { + self._data |= + (Int256.toBytes32(element) & (~bytes32(0) >> 72)) << + self._size; + self._size += 184; + } + } + + /** + * @notice remove last 23-byte segment from bytes and return as int184 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int184 derived from bytes + */ + function popInt184( + Builder memory self + ) internal pure returns (int184 element) { + unchecked { + self._size -= 184; + bytes32 mask = MASK_23; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = int184(Bytes32.toInt256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 23-byte segment from bytes and return as int184 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int184 derived from bytes + */ + function shiftInt184( + Builder memory self + ) internal pure returns (int184 element) { + unchecked { + bytes32 mask = MASK_23; + bytes32 elementBytes = self._data & mask; + element = int184(Bytes32.toInt256(elementBytes)); + self._data >>= 184; + self._size -= 184; + } + } + + /** + * @notice insert int184 value to 23-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int184 to add + */ + function unshiftInt184(Builder memory self, int184 element) internal pure { + unchecked { + self._data = + (self._data << 184) | + (Int256.toBytes32(element) & (~bytes32(0) >> 72)); + self._size += 184; + } + } + /** + * @notice insert uint184 value to 23-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint184 to add + */ + function pushUint184(Builder memory self, uint184 element) internal pure { + unchecked { + self._data |= Uint256.toBytes32(element) << self._size; + self._size += 184; + } + } + + /** + * @notice remove last 23-byte segment from bytes and return as uint184 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint184 derived from bytes + */ + function popUint184( + Builder memory self + ) internal pure returns (uint184 element) { + unchecked { + self._size -= 184; + bytes32 mask = MASK_23; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = uint184(Bytes32.toUint256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 23-byte segment from bytes and return as uint184 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint184 derived from bytes + */ + function shiftUint184( + Builder memory self + ) internal pure returns (uint184 element) { + unchecked { + bytes32 mask = MASK_23; + bytes32 elementBytes = self._data & mask; + element = uint184(Bytes32.toUint256(elementBytes)); + self._data >>= 184; + self._size -= 184; + } + } + + /** + * @notice insert uint184 value to 23-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint184 to add + */ + function unshiftUint184( + Builder memory self, + uint184 element + ) internal pure { + unchecked { + self._data = (self._data << 184) | Uint256.toBytes32(element); + self._size += 184; + } + } + /** + * @notice insert bytes24 value to 24-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes24 to add + */ + function pushBytes24(Builder memory self, bytes24 element) internal pure { + unchecked { + self._data |= (bytes32(element) >> 64) << self._size; + self._size += 192; + } + } + + /** + * @notice remove last 24-byte segment from bytes and return as bytes24 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes24 derived from bytes + */ + function popBytes24( + Builder memory self + ) internal pure returns (bytes24 element) { + unchecked { + self._size -= 192; + bytes32 mask = MASK_24; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = bytes24(elementBytes << 64); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 24-byte segment from bytes and return as bytes24 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes24 derived from bytes + */ + function shiftBytes24( + Builder memory self + ) internal pure returns (bytes24 element) { + unchecked { + bytes32 mask = MASK_24; + bytes32 elementBytes = self._data & mask; + element = bytes24(elementBytes << 64); + self._data >>= 192; + self._size -= 192; + } + } + + /** + * @notice insert bytes24 value to 24-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes24 to add + */ + function unshiftBytes24( + Builder memory self, + bytes24 element + ) internal pure { + unchecked { + self._data = (self._data << 192) | (bytes32(element) >> 64); + self._size += 192; + } + } + /** + * @notice insert int192 value to 24-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int192 to add + */ + function pushInt192(Builder memory self, int192 element) internal pure { + unchecked { + self._data |= + (Int256.toBytes32(element) & (~bytes32(0) >> 64)) << + self._size; + self._size += 192; + } + } + + /** + * @notice remove last 24-byte segment from bytes and return as int192 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int192 derived from bytes + */ + function popInt192( + Builder memory self + ) internal pure returns (int192 element) { + unchecked { + self._size -= 192; + bytes32 mask = MASK_24; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = int192(Bytes32.toInt256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 24-byte segment from bytes and return as int192 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int192 derived from bytes + */ + function shiftInt192( + Builder memory self + ) internal pure returns (int192 element) { + unchecked { + bytes32 mask = MASK_24; + bytes32 elementBytes = self._data & mask; + element = int192(Bytes32.toInt256(elementBytes)); + self._data >>= 192; + self._size -= 192; + } + } + + /** + * @notice insert int192 value to 24-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int192 to add + */ + function unshiftInt192(Builder memory self, int192 element) internal pure { + unchecked { + self._data = + (self._data << 192) | + (Int256.toBytes32(element) & (~bytes32(0) >> 64)); + self._size += 192; + } + } + /** + * @notice insert uint192 value to 24-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint192 to add + */ + function pushUint192(Builder memory self, uint192 element) internal pure { + unchecked { + self._data |= Uint256.toBytes32(element) << self._size; + self._size += 192; + } + } + + /** + * @notice remove last 24-byte segment from bytes and return as uint192 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint192 derived from bytes + */ + function popUint192( + Builder memory self + ) internal pure returns (uint192 element) { + unchecked { + self._size -= 192; + bytes32 mask = MASK_24; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = uint192(Bytes32.toUint256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 24-byte segment from bytes and return as uint192 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint192 derived from bytes + */ + function shiftUint192( + Builder memory self + ) internal pure returns (uint192 element) { + unchecked { + bytes32 mask = MASK_24; + bytes32 elementBytes = self._data & mask; + element = uint192(Bytes32.toUint256(elementBytes)); + self._data >>= 192; + self._size -= 192; + } + } + + /** + * @notice insert uint192 value to 24-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint192 to add + */ + function unshiftUint192( + Builder memory self, + uint192 element + ) internal pure { + unchecked { + self._data = (self._data << 192) | Uint256.toBytes32(element); + self._size += 192; + } + } + /** + * @notice insert bytes25 value to 25-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes25 to add + */ + function pushBytes25(Builder memory self, bytes25 element) internal pure { + unchecked { + self._data |= (bytes32(element) >> 56) << self._size; + self._size += 200; + } + } + + /** + * @notice remove last 25-byte segment from bytes and return as bytes25 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes25 derived from bytes + */ + function popBytes25( + Builder memory self + ) internal pure returns (bytes25 element) { + unchecked { + self._size -= 200; + bytes32 mask = MASK_25; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = bytes25(elementBytes << 56); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 25-byte segment from bytes and return as bytes25 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes25 derived from bytes + */ + function shiftBytes25( + Builder memory self + ) internal pure returns (bytes25 element) { + unchecked { + bytes32 mask = MASK_25; + bytes32 elementBytes = self._data & mask; + element = bytes25(elementBytes << 56); + self._data >>= 200; + self._size -= 200; + } + } + + /** + * @notice insert bytes25 value to 25-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes25 to add + */ + function unshiftBytes25( + Builder memory self, + bytes25 element + ) internal pure { + unchecked { + self._data = (self._data << 200) | (bytes32(element) >> 56); + self._size += 200; + } + } + /** + * @notice insert int200 value to 25-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int200 to add + */ + function pushInt200(Builder memory self, int200 element) internal pure { + unchecked { + self._data |= + (Int256.toBytes32(element) & (~bytes32(0) >> 56)) << + self._size; + self._size += 200; + } + } + + /** + * @notice remove last 25-byte segment from bytes and return as int200 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int200 derived from bytes + */ + function popInt200( + Builder memory self + ) internal pure returns (int200 element) { + unchecked { + self._size -= 200; + bytes32 mask = MASK_25; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = int200(Bytes32.toInt256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 25-byte segment from bytes and return as int200 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int200 derived from bytes + */ + function shiftInt200( + Builder memory self + ) internal pure returns (int200 element) { + unchecked { + bytes32 mask = MASK_25; + bytes32 elementBytes = self._data & mask; + element = int200(Bytes32.toInt256(elementBytes)); + self._data >>= 200; + self._size -= 200; + } + } + + /** + * @notice insert int200 value to 25-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int200 to add + */ + function unshiftInt200(Builder memory self, int200 element) internal pure { + unchecked { + self._data = + (self._data << 200) | + (Int256.toBytes32(element) & (~bytes32(0) >> 56)); + self._size += 200; + } + } + /** + * @notice insert uint200 value to 25-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint200 to add + */ + function pushUint200(Builder memory self, uint200 element) internal pure { + unchecked { + self._data |= Uint256.toBytes32(element) << self._size; + self._size += 200; + } + } + + /** + * @notice remove last 25-byte segment from bytes and return as uint200 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint200 derived from bytes + */ + function popUint200( + Builder memory self + ) internal pure returns (uint200 element) { + unchecked { + self._size -= 200; + bytes32 mask = MASK_25; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = uint200(Bytes32.toUint256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 25-byte segment from bytes and return as uint200 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint200 derived from bytes + */ + function shiftUint200( + Builder memory self + ) internal pure returns (uint200 element) { + unchecked { + bytes32 mask = MASK_25; + bytes32 elementBytes = self._data & mask; + element = uint200(Bytes32.toUint256(elementBytes)); + self._data >>= 200; + self._size -= 200; + } + } + + /** + * @notice insert uint200 value to 25-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint200 to add + */ + function unshiftUint200( + Builder memory self, + uint200 element + ) internal pure { + unchecked { + self._data = (self._data << 200) | Uint256.toBytes32(element); + self._size += 200; + } + } + /** + * @notice insert bytes26 value to 26-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes26 to add + */ + function pushBytes26(Builder memory self, bytes26 element) internal pure { + unchecked { + self._data |= (bytes32(element) >> 48) << self._size; + self._size += 208; + } + } + + /** + * @notice remove last 26-byte segment from bytes and return as bytes26 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes26 derived from bytes + */ + function popBytes26( + Builder memory self + ) internal pure returns (bytes26 element) { + unchecked { + self._size -= 208; + bytes32 mask = MASK_26; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = bytes26(elementBytes << 48); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 26-byte segment from bytes and return as bytes26 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes26 derived from bytes + */ + function shiftBytes26( + Builder memory self + ) internal pure returns (bytes26 element) { + unchecked { + bytes32 mask = MASK_26; + bytes32 elementBytes = self._data & mask; + element = bytes26(elementBytes << 48); + self._data >>= 208; + self._size -= 208; + } + } + + /** + * @notice insert bytes26 value to 26-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes26 to add + */ + function unshiftBytes26( + Builder memory self, + bytes26 element + ) internal pure { + unchecked { + self._data = (self._data << 208) | (bytes32(element) >> 48); + self._size += 208; + } + } + /** + * @notice insert int208 value to 26-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int208 to add + */ + function pushInt208(Builder memory self, int208 element) internal pure { + unchecked { + self._data |= + (Int256.toBytes32(element) & (~bytes32(0) >> 48)) << + self._size; + self._size += 208; + } + } + + /** + * @notice remove last 26-byte segment from bytes and return as int208 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int208 derived from bytes + */ + function popInt208( + Builder memory self + ) internal pure returns (int208 element) { + unchecked { + self._size -= 208; + bytes32 mask = MASK_26; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = int208(Bytes32.toInt256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 26-byte segment from bytes and return as int208 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int208 derived from bytes + */ + function shiftInt208( + Builder memory self + ) internal pure returns (int208 element) { + unchecked { + bytes32 mask = MASK_26; + bytes32 elementBytes = self._data & mask; + element = int208(Bytes32.toInt256(elementBytes)); + self._data >>= 208; + self._size -= 208; + } + } + + /** + * @notice insert int208 value to 26-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int208 to add + */ + function unshiftInt208(Builder memory self, int208 element) internal pure { + unchecked { + self._data = + (self._data << 208) | + (Int256.toBytes32(element) & (~bytes32(0) >> 48)); + self._size += 208; + } + } + /** + * @notice insert uint208 value to 26-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint208 to add + */ + function pushUint208(Builder memory self, uint208 element) internal pure { + unchecked { + self._data |= Uint256.toBytes32(element) << self._size; + self._size += 208; + } + } + + /** + * @notice remove last 26-byte segment from bytes and return as uint208 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint208 derived from bytes + */ + function popUint208( + Builder memory self + ) internal pure returns (uint208 element) { + unchecked { + self._size -= 208; + bytes32 mask = MASK_26; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = uint208(Bytes32.toUint256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 26-byte segment from bytes and return as uint208 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint208 derived from bytes + */ + function shiftUint208( + Builder memory self + ) internal pure returns (uint208 element) { + unchecked { + bytes32 mask = MASK_26; + bytes32 elementBytes = self._data & mask; + element = uint208(Bytes32.toUint256(elementBytes)); + self._data >>= 208; + self._size -= 208; + } + } + + /** + * @notice insert uint208 value to 26-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint208 to add + */ + function unshiftUint208( + Builder memory self, + uint208 element + ) internal pure { + unchecked { + self._data = (self._data << 208) | Uint256.toBytes32(element); + self._size += 208; + } + } + /** + * @notice insert bytes27 value to 27-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes27 to add + */ + function pushBytes27(Builder memory self, bytes27 element) internal pure { + unchecked { + self._data |= (bytes32(element) >> 40) << self._size; + self._size += 216; + } + } + + /** + * @notice remove last 27-byte segment from bytes and return as bytes27 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes27 derived from bytes + */ + function popBytes27( + Builder memory self + ) internal pure returns (bytes27 element) { + unchecked { + self._size -= 216; + bytes32 mask = MASK_27; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = bytes27(elementBytes << 40); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 27-byte segment from bytes and return as bytes27 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes27 derived from bytes + */ + function shiftBytes27( + Builder memory self + ) internal pure returns (bytes27 element) { + unchecked { + bytes32 mask = MASK_27; + bytes32 elementBytes = self._data & mask; + element = bytes27(elementBytes << 40); + self._data >>= 216; + self._size -= 216; + } + } + + /** + * @notice insert bytes27 value to 27-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes27 to add + */ + function unshiftBytes27( + Builder memory self, + bytes27 element + ) internal pure { + unchecked { + self._data = (self._data << 216) | (bytes32(element) >> 40); + self._size += 216; + } + } + /** + * @notice insert int216 value to 27-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int216 to add + */ + function pushInt216(Builder memory self, int216 element) internal pure { + unchecked { + self._data |= + (Int256.toBytes32(element) & (~bytes32(0) >> 40)) << + self._size; + self._size += 216; + } + } + + /** + * @notice remove last 27-byte segment from bytes and return as int216 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int216 derived from bytes + */ + function popInt216( + Builder memory self + ) internal pure returns (int216 element) { + unchecked { + self._size -= 216; + bytes32 mask = MASK_27; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = int216(Bytes32.toInt256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 27-byte segment from bytes and return as int216 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int216 derived from bytes + */ + function shiftInt216( + Builder memory self + ) internal pure returns (int216 element) { + unchecked { + bytes32 mask = MASK_27; + bytes32 elementBytes = self._data & mask; + element = int216(Bytes32.toInt256(elementBytes)); + self._data >>= 216; + self._size -= 216; + } + } + + /** + * @notice insert int216 value to 27-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int216 to add + */ + function unshiftInt216(Builder memory self, int216 element) internal pure { + unchecked { + self._data = + (self._data << 216) | + (Int256.toBytes32(element) & (~bytes32(0) >> 40)); + self._size += 216; + } + } + /** + * @notice insert uint216 value to 27-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint216 to add + */ + function pushUint216(Builder memory self, uint216 element) internal pure { + unchecked { + self._data |= Uint256.toBytes32(element) << self._size; + self._size += 216; + } + } + + /** + * @notice remove last 27-byte segment from bytes and return as uint216 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint216 derived from bytes + */ + function popUint216( + Builder memory self + ) internal pure returns (uint216 element) { + unchecked { + self._size -= 216; + bytes32 mask = MASK_27; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = uint216(Bytes32.toUint256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 27-byte segment from bytes and return as uint216 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint216 derived from bytes + */ + function shiftUint216( + Builder memory self + ) internal pure returns (uint216 element) { + unchecked { + bytes32 mask = MASK_27; + bytes32 elementBytes = self._data & mask; + element = uint216(Bytes32.toUint256(elementBytes)); + self._data >>= 216; + self._size -= 216; + } + } + + /** + * @notice insert uint216 value to 27-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint216 to add + */ + function unshiftUint216( + Builder memory self, + uint216 element + ) internal pure { + unchecked { + self._data = (self._data << 216) | Uint256.toBytes32(element); + self._size += 216; + } + } + /** + * @notice insert bytes28 value to 28-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes28 to add + */ + function pushBytes28(Builder memory self, bytes28 element) internal pure { + unchecked { + self._data |= (bytes32(element) >> 32) << self._size; + self._size += 224; + } + } + + /** + * @notice remove last 28-byte segment from bytes and return as bytes28 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes28 derived from bytes + */ + function popBytes28( + Builder memory self + ) internal pure returns (bytes28 element) { + unchecked { + self._size -= 224; + bytes32 mask = MASK_28; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = bytes28(elementBytes << 32); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 28-byte segment from bytes and return as bytes28 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes28 derived from bytes + */ + function shiftBytes28( + Builder memory self + ) internal pure returns (bytes28 element) { + unchecked { + bytes32 mask = MASK_28; + bytes32 elementBytes = self._data & mask; + element = bytes28(elementBytes << 32); + self._data >>= 224; + self._size -= 224; + } + } + + /** + * @notice insert bytes28 value to 28-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes28 to add + */ + function unshiftBytes28( + Builder memory self, + bytes28 element + ) internal pure { + unchecked { + self._data = (self._data << 224) | (bytes32(element) >> 32); + self._size += 224; + } + } + /** + * @notice insert int224 value to 28-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int224 to add + */ + function pushInt224(Builder memory self, int224 element) internal pure { + unchecked { + self._data |= + (Int256.toBytes32(element) & (~bytes32(0) >> 32)) << + self._size; + self._size += 224; + } + } + + /** + * @notice remove last 28-byte segment from bytes and return as int224 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int224 derived from bytes + */ + function popInt224( + Builder memory self + ) internal pure returns (int224 element) { + unchecked { + self._size -= 224; + bytes32 mask = MASK_28; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = int224(Bytes32.toInt256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 28-byte segment from bytes and return as int224 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int224 derived from bytes + */ + function shiftInt224( + Builder memory self + ) internal pure returns (int224 element) { + unchecked { + bytes32 mask = MASK_28; + bytes32 elementBytes = self._data & mask; + element = int224(Bytes32.toInt256(elementBytes)); + self._data >>= 224; + self._size -= 224; + } + } + + /** + * @notice insert int224 value to 28-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int224 to add + */ + function unshiftInt224(Builder memory self, int224 element) internal pure { + unchecked { + self._data = + (self._data << 224) | + (Int256.toBytes32(element) & (~bytes32(0) >> 32)); + self._size += 224; + } + } + /** + * @notice insert uint224 value to 28-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint224 to add + */ + function pushUint224(Builder memory self, uint224 element) internal pure { + unchecked { + self._data |= Uint256.toBytes32(element) << self._size; + self._size += 224; + } + } + + /** + * @notice remove last 28-byte segment from bytes and return as uint224 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint224 derived from bytes + */ + function popUint224( + Builder memory self + ) internal pure returns (uint224 element) { + unchecked { + self._size -= 224; + bytes32 mask = MASK_28; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = uint224(Bytes32.toUint256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 28-byte segment from bytes and return as uint224 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint224 derived from bytes + */ + function shiftUint224( + Builder memory self + ) internal pure returns (uint224 element) { + unchecked { + bytes32 mask = MASK_28; + bytes32 elementBytes = self._data & mask; + element = uint224(Bytes32.toUint256(elementBytes)); + self._data >>= 224; + self._size -= 224; + } + } + + /** + * @notice insert uint224 value to 28-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint224 to add + */ + function unshiftUint224( + Builder memory self, + uint224 element + ) internal pure { + unchecked { + self._data = (self._data << 224) | Uint256.toBytes32(element); + self._size += 224; + } + } + /** + * @notice insert bytes29 value to 29-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes29 to add + */ + function pushBytes29(Builder memory self, bytes29 element) internal pure { + unchecked { + self._data |= (bytes32(element) >> 24) << self._size; + self._size += 232; + } + } + + /** + * @notice remove last 29-byte segment from bytes and return as bytes29 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes29 derived from bytes + */ + function popBytes29( + Builder memory self + ) internal pure returns (bytes29 element) { + unchecked { + self._size -= 232; + bytes32 mask = MASK_29; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = bytes29(elementBytes << 24); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 29-byte segment from bytes and return as bytes29 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes29 derived from bytes + */ + function shiftBytes29( + Builder memory self + ) internal pure returns (bytes29 element) { + unchecked { + bytes32 mask = MASK_29; + bytes32 elementBytes = self._data & mask; + element = bytes29(elementBytes << 24); + self._data >>= 232; + self._size -= 232; + } + } + + /** + * @notice insert bytes29 value to 29-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes29 to add + */ + function unshiftBytes29( + Builder memory self, + bytes29 element + ) internal pure { + unchecked { + self._data = (self._data << 232) | (bytes32(element) >> 24); + self._size += 232; + } + } + /** + * @notice insert int232 value to 29-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int232 to add + */ + function pushInt232(Builder memory self, int232 element) internal pure { + unchecked { + self._data |= + (Int256.toBytes32(element) & (~bytes32(0) >> 24)) << + self._size; + self._size += 232; + } + } + + /** + * @notice remove last 29-byte segment from bytes and return as int232 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int232 derived from bytes + */ + function popInt232( + Builder memory self + ) internal pure returns (int232 element) { + unchecked { + self._size -= 232; + bytes32 mask = MASK_29; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = int232(Bytes32.toInt256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 29-byte segment from bytes and return as int232 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int232 derived from bytes + */ + function shiftInt232( + Builder memory self + ) internal pure returns (int232 element) { + unchecked { + bytes32 mask = MASK_29; + bytes32 elementBytes = self._data & mask; + element = int232(Bytes32.toInt256(elementBytes)); + self._data >>= 232; + self._size -= 232; + } + } + + /** + * @notice insert int232 value to 29-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int232 to add + */ + function unshiftInt232(Builder memory self, int232 element) internal pure { + unchecked { + self._data = + (self._data << 232) | + (Int256.toBytes32(element) & (~bytes32(0) >> 24)); + self._size += 232; + } + } + /** + * @notice insert uint232 value to 29-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint232 to add + */ + function pushUint232(Builder memory self, uint232 element) internal pure { + unchecked { + self._data |= Uint256.toBytes32(element) << self._size; + self._size += 232; + } + } + + /** + * @notice remove last 29-byte segment from bytes and return as uint232 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint232 derived from bytes + */ + function popUint232( + Builder memory self + ) internal pure returns (uint232 element) { + unchecked { + self._size -= 232; + bytes32 mask = MASK_29; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = uint232(Bytes32.toUint256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 29-byte segment from bytes and return as uint232 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint232 derived from bytes + */ + function shiftUint232( + Builder memory self + ) internal pure returns (uint232 element) { + unchecked { + bytes32 mask = MASK_29; + bytes32 elementBytes = self._data & mask; + element = uint232(Bytes32.toUint256(elementBytes)); + self._data >>= 232; + self._size -= 232; + } + } + + /** + * @notice insert uint232 value to 29-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint232 to add + */ + function unshiftUint232( + Builder memory self, + uint232 element + ) internal pure { + unchecked { + self._data = (self._data << 232) | Uint256.toBytes32(element); + self._size += 232; + } + } + /** + * @notice insert bytes30 value to 30-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes30 to add + */ + function pushBytes30(Builder memory self, bytes30 element) internal pure { + unchecked { + self._data |= (bytes32(element) >> 16) << self._size; + self._size += 240; + } + } + + /** + * @notice remove last 30-byte segment from bytes and return as bytes30 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes30 derived from bytes + */ + function popBytes30( + Builder memory self + ) internal pure returns (bytes30 element) { + unchecked { + self._size -= 240; + bytes32 mask = MASK_30; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = bytes30(elementBytes << 16); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 30-byte segment from bytes and return as bytes30 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes30 derived from bytes + */ + function shiftBytes30( + Builder memory self + ) internal pure returns (bytes30 element) { + unchecked { + bytes32 mask = MASK_30; + bytes32 elementBytes = self._data & mask; + element = bytes30(elementBytes << 16); + self._data >>= 240; + self._size -= 240; + } + } + + /** + * @notice insert bytes30 value to 30-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes30 to add + */ + function unshiftBytes30( + Builder memory self, + bytes30 element + ) internal pure { + unchecked { + self._data = (self._data << 240) | (bytes32(element) >> 16); + self._size += 240; + } + } + /** + * @notice insert int240 value to 30-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int240 to add + */ + function pushInt240(Builder memory self, int240 element) internal pure { + unchecked { + self._data |= + (Int256.toBytes32(element) & (~bytes32(0) >> 16)) << + self._size; + self._size += 240; + } + } + + /** + * @notice remove last 30-byte segment from bytes and return as int240 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int240 derived from bytes + */ + function popInt240( + Builder memory self + ) internal pure returns (int240 element) { + unchecked { + self._size -= 240; + bytes32 mask = MASK_30; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = int240(Bytes32.toInt256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 30-byte segment from bytes and return as int240 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int240 derived from bytes + */ + function shiftInt240( + Builder memory self + ) internal pure returns (int240 element) { + unchecked { + bytes32 mask = MASK_30; + bytes32 elementBytes = self._data & mask; + element = int240(Bytes32.toInt256(elementBytes)); + self._data >>= 240; + self._size -= 240; + } + } + + /** + * @notice insert int240 value to 30-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int240 to add + */ + function unshiftInt240(Builder memory self, int240 element) internal pure { + unchecked { + self._data = + (self._data << 240) | + (Int256.toBytes32(element) & (~bytes32(0) >> 16)); + self._size += 240; + } + } + /** + * @notice insert uint240 value to 30-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint240 to add + */ + function pushUint240(Builder memory self, uint240 element) internal pure { + unchecked { + self._data |= Uint256.toBytes32(element) << self._size; + self._size += 240; + } + } + + /** + * @notice remove last 30-byte segment from bytes and return as uint240 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint240 derived from bytes + */ + function popUint240( + Builder memory self + ) internal pure returns (uint240 element) { + unchecked { + self._size -= 240; + bytes32 mask = MASK_30; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = uint240(Bytes32.toUint256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 30-byte segment from bytes and return as uint240 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint240 derived from bytes + */ + function shiftUint240( + Builder memory self + ) internal pure returns (uint240 element) { + unchecked { + bytes32 mask = MASK_30; + bytes32 elementBytes = self._data & mask; + element = uint240(Bytes32.toUint256(elementBytes)); + self._data >>= 240; + self._size -= 240; + } + } + + /** + * @notice insert uint240 value to 30-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint240 to add + */ + function unshiftUint240( + Builder memory self, + uint240 element + ) internal pure { + unchecked { + self._data = (self._data << 240) | Uint256.toBytes32(element); + self._size += 240; + } + } + /** + * @notice insert bytes31 value to 31-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes31 to add + */ + function pushBytes31(Builder memory self, bytes31 element) internal pure { + unchecked { + self._data |= (bytes32(element) >> 8) << self._size; + self._size += 248; + } + } + + /** + * @notice remove last 31-byte segment from bytes and return as bytes31 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes31 derived from bytes + */ + function popBytes31( + Builder memory self + ) internal pure returns (bytes31 element) { + unchecked { + self._size -= 248; + bytes32 mask = MASK_31; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = bytes31(elementBytes << 8); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 31-byte segment from bytes and return as bytes31 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes31 derived from bytes + */ + function shiftBytes31( + Builder memory self + ) internal pure returns (bytes31 element) { + unchecked { + bytes32 mask = MASK_31; + bytes32 elementBytes = self._data & mask; + element = bytes31(elementBytes << 8); + self._data >>= 248; + self._size -= 248; + } + } + + /** + * @notice insert bytes31 value to 31-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes31 to add + */ + function unshiftBytes31( + Builder memory self, + bytes31 element + ) internal pure { + unchecked { + self._data = (self._data << 248) | (bytes32(element) >> 8); + self._size += 248; + } + } + /** + * @notice insert int248 value to 31-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int248 to add + */ + function pushInt248(Builder memory self, int248 element) internal pure { + unchecked { + self._data |= + (Int256.toBytes32(element) & (~bytes32(0) >> 8)) << + self._size; + self._size += 248; + } + } + + /** + * @notice remove last 31-byte segment from bytes and return as int248 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int248 derived from bytes + */ + function popInt248( + Builder memory self + ) internal pure returns (int248 element) { + unchecked { + self._size -= 248; + bytes32 mask = MASK_31; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = int248(Bytes32.toInt256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 31-byte segment from bytes and return as int248 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int248 derived from bytes + */ + function shiftInt248( + Builder memory self + ) internal pure returns (int248 element) { + unchecked { + bytes32 mask = MASK_31; + bytes32 elementBytes = self._data & mask; + element = int248(Bytes32.toInt256(elementBytes)); + self._data >>= 248; + self._size -= 248; + } + } + + /** + * @notice insert int248 value to 31-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int248 to add + */ + function unshiftInt248(Builder memory self, int248 element) internal pure { + unchecked { + self._data = + (self._data << 248) | + (Int256.toBytes32(element) & (~bytes32(0) >> 8)); + self._size += 248; + } + } + /** + * @notice insert uint248 value to 31-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint248 to add + */ + function pushUint248(Builder memory self, uint248 element) internal pure { + unchecked { + self._data |= Uint256.toBytes32(element) << self._size; + self._size += 248; + } + } + + /** + * @notice remove last 31-byte segment from bytes and return as uint248 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint248 derived from bytes + */ + function popUint248( + Builder memory self + ) internal pure returns (uint248 element) { + unchecked { + self._size -= 248; + bytes32 mask = MASK_31; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = uint248(Bytes32.toUint256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 31-byte segment from bytes and return as uint248 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint248 derived from bytes + */ + function shiftUint248( + Builder memory self + ) internal pure returns (uint248 element) { + unchecked { + bytes32 mask = MASK_31; + bytes32 elementBytes = self._data & mask; + element = uint248(Bytes32.toUint256(elementBytes)); + self._data >>= 248; + self._size -= 248; + } + } + + /** + * @notice insert uint248 value to 31-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint248 to add + */ + function unshiftUint248( + Builder memory self, + uint248 element + ) internal pure { + unchecked { + self._data = (self._data << 248) | Uint256.toBytes32(element); + self._size += 248; + } + } + /** + * @notice insert bytes32 value to 32-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes32 to add + */ + function pushBytes32(Builder memory self, bytes32 element) internal pure { + unchecked { + self._data |= (bytes32(element) >> 0) << self._size; + self._size += 256; + } + } + + /** + * @notice remove last 32-byte segment from bytes and return as bytes32 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes32 derived from bytes + */ + function popBytes32( + Builder memory self + ) internal pure returns (bytes32 element) { + unchecked { + self._size -= 256; + bytes32 mask = MASK_32; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = bytes32(elementBytes << 0); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 32-byte segment from bytes and return as bytes32 + * @param self Bytes32Builder Builder struct on which to operate + * @return element bytes32 derived from bytes + */ + function shiftBytes32( + Builder memory self + ) internal pure returns (bytes32 element) { + unchecked { + bytes32 mask = MASK_32; + bytes32 elementBytes = self._data & mask; + element = bytes32(elementBytes << 0); + self._data >>= 256; + self._size -= 256; + } + } + + /** + * @notice insert bytes32 value to 32-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element bytes32 to add + */ + function unshiftBytes32( + Builder memory self, + bytes32 element + ) internal pure { + unchecked { + self._data = (self._data << 256) | (bytes32(element) >> 0); + self._size += 256; + } + } + /** + * @notice insert int256 value to 32-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int256 to add + */ + function pushInt256(Builder memory self, int256 element) internal pure { + unchecked { + self._data |= + (Int256.toBytes32(element) & (~bytes32(0) >> 0)) << + self._size; + self._size += 256; + } + } + + /** + * @notice remove last 32-byte segment from bytes and return as int256 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int256 derived from bytes + */ + function popInt256( + Builder memory self + ) internal pure returns (int256 element) { + unchecked { + self._size -= 256; + bytes32 mask = MASK_32; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = int256(Bytes32.toInt256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 32-byte segment from bytes and return as int256 + * @param self Bytes32Builder Builder struct on which to operate + * @return element int256 derived from bytes + */ + function shiftInt256( + Builder memory self + ) internal pure returns (int256 element) { + unchecked { + bytes32 mask = MASK_32; + bytes32 elementBytes = self._data & mask; + element = int256(Bytes32.toInt256(elementBytes)); + self._data >>= 256; + self._size -= 256; + } + } + + /** + * @notice insert int256 value to 32-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element int256 to add + */ + function unshiftInt256(Builder memory self, int256 element) internal pure { + unchecked { + self._data = + (self._data << 256) | + (Int256.toBytes32(element) & (~bytes32(0) >> 0)); + self._size += 256; + } + } + /** + * @notice insert uint256 value to 32-byte position at end of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint256 to add + */ + function pushUint256(Builder memory self, uint256 element) internal pure { + unchecked { + self._data |= Uint256.toBytes32(element) << self._size; + self._size += 256; + } + } + + /** + * @notice remove last 32-byte segment from bytes and return as uint256 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint256 derived from bytes + */ + function popUint256( + Builder memory self + ) internal pure returns (uint256 element) { + unchecked { + self._size -= 256; + bytes32 mask = MASK_32; + bytes32 elementBytes = (self._data >> self._size) & mask; + element = uint256(Bytes32.toUint256(elementBytes)); + self._data &= ~(mask << self._size); + } + } + + /** + * @notice remove first 32-byte segment from bytes and return as uint256 + * @param self Bytes32Builder Builder struct on which to operate + * @return element uint256 derived from bytes + */ + function shiftUint256( + Builder memory self + ) internal pure returns (uint256 element) { + unchecked { + bytes32 mask = MASK_32; + bytes32 elementBytes = self._data & mask; + element = uint256(Bytes32.toUint256(elementBytes)); + self._data >>= 256; + self._size -= 256; + } + } + + /** + * @notice insert uint256 value to 32-byte position at beginning of bytes + * @param self Bytes32Builder Builder struct on which to operate + * @param element uint256 to add + */ + function unshiftUint256( + Builder memory self, + uint256 element + ) internal pure { + unchecked { + self._data = (self._data << 256) | Uint256.toBytes32(element); + self._size += 256; + } + } +} diff --git a/contracts/test/Bytes32BuilderTest.sol b/contracts/test/Bytes32BuilderTest.sol new file mode 100644 index 00000000..fb528121 --- /dev/null +++ b/contracts/test/Bytes32BuilderTest.sol @@ -0,0 +1,2856 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.24; + +import { Bytes32Builder } from '../data/Bytes32Builder.sol'; + +/** + * @title Procedurally generated Bytes32Builder test contract + * @dev custom solution is required because there is no other way to access memory struct post-operation + **/ +contract Bytes32BuilderTest { + using Bytes32Builder for Bytes32Builder.Builder; + + function pushBytes1( + Bytes32Builder.Builder memory self, + bytes1 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushBytes1(element); + return self; + } + + function popBytes1( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes1 element) { + element = self.popBytes1(); + return (self, element); + } + + function shiftBytes1( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes1 element) { + element = self.shiftBytes1(); + return (self, element); + } + + function unshiftBytes1( + Bytes32Builder.Builder memory self, + bytes1 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftBytes1(element); + return self; + } + function pushInt8( + Bytes32Builder.Builder memory self, + int8 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushInt8(element); + return self; + } + + function popInt8( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int8 element) { + element = self.popInt8(); + return (self, element); + } + + function shiftInt8( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int8 element) { + element = self.shiftInt8(); + return (self, element); + } + + function unshiftInt8( + Bytes32Builder.Builder memory self, + int8 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftInt8(element); + return self; + } + function pushUint8( + Bytes32Builder.Builder memory self, + uint8 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushUint8(element); + return self; + } + + function popUint8( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint8 element) { + element = self.popUint8(); + return (self, element); + } + + function shiftUint8( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint8 element) { + element = self.shiftUint8(); + return (self, element); + } + + function unshiftUint8( + Bytes32Builder.Builder memory self, + uint8 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftUint8(element); + return self; + } + function pushBool( + Bytes32Builder.Builder memory self, + bool element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushBool(element); + return self; + } + + function popBool( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bool element) { + element = self.popBool(); + return (self, element); + } + + function shiftBool( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bool element) { + element = self.shiftBool(); + return (self, element); + } + + function unshiftBool( + Bytes32Builder.Builder memory self, + bool element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftBool(element); + return self; + } + function pushBytes2( + Bytes32Builder.Builder memory self, + bytes2 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushBytes2(element); + return self; + } + + function popBytes2( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes2 element) { + element = self.popBytes2(); + return (self, element); + } + + function shiftBytes2( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes2 element) { + element = self.shiftBytes2(); + return (self, element); + } + + function unshiftBytes2( + Bytes32Builder.Builder memory self, + bytes2 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftBytes2(element); + return self; + } + function pushInt16( + Bytes32Builder.Builder memory self, + int16 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushInt16(element); + return self; + } + + function popInt16( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int16 element) { + element = self.popInt16(); + return (self, element); + } + + function shiftInt16( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int16 element) { + element = self.shiftInt16(); + return (self, element); + } + + function unshiftInt16( + Bytes32Builder.Builder memory self, + int16 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftInt16(element); + return self; + } + function pushUint16( + Bytes32Builder.Builder memory self, + uint16 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushUint16(element); + return self; + } + + function popUint16( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint16 element) { + element = self.popUint16(); + return (self, element); + } + + function shiftUint16( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint16 element) { + element = self.shiftUint16(); + return (self, element); + } + + function unshiftUint16( + Bytes32Builder.Builder memory self, + uint16 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftUint16(element); + return self; + } + function pushBytes3( + Bytes32Builder.Builder memory self, + bytes3 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushBytes3(element); + return self; + } + + function popBytes3( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes3 element) { + element = self.popBytes3(); + return (self, element); + } + + function shiftBytes3( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes3 element) { + element = self.shiftBytes3(); + return (self, element); + } + + function unshiftBytes3( + Bytes32Builder.Builder memory self, + bytes3 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftBytes3(element); + return self; + } + function pushInt24( + Bytes32Builder.Builder memory self, + int24 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushInt24(element); + return self; + } + + function popInt24( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int24 element) { + element = self.popInt24(); + return (self, element); + } + + function shiftInt24( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int24 element) { + element = self.shiftInt24(); + return (self, element); + } + + function unshiftInt24( + Bytes32Builder.Builder memory self, + int24 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftInt24(element); + return self; + } + function pushUint24( + Bytes32Builder.Builder memory self, + uint24 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushUint24(element); + return self; + } + + function popUint24( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint24 element) { + element = self.popUint24(); + return (self, element); + } + + function shiftUint24( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint24 element) { + element = self.shiftUint24(); + return (self, element); + } + + function unshiftUint24( + Bytes32Builder.Builder memory self, + uint24 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftUint24(element); + return self; + } + function pushBytes4( + Bytes32Builder.Builder memory self, + bytes4 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushBytes4(element); + return self; + } + + function popBytes4( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes4 element) { + element = self.popBytes4(); + return (self, element); + } + + function shiftBytes4( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes4 element) { + element = self.shiftBytes4(); + return (self, element); + } + + function unshiftBytes4( + Bytes32Builder.Builder memory self, + bytes4 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftBytes4(element); + return self; + } + function pushInt32( + Bytes32Builder.Builder memory self, + int32 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushInt32(element); + return self; + } + + function popInt32( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int32 element) { + element = self.popInt32(); + return (self, element); + } + + function shiftInt32( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int32 element) { + element = self.shiftInt32(); + return (self, element); + } + + function unshiftInt32( + Bytes32Builder.Builder memory self, + int32 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftInt32(element); + return self; + } + function pushUint32( + Bytes32Builder.Builder memory self, + uint32 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushUint32(element); + return self; + } + + function popUint32( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint32 element) { + element = self.popUint32(); + return (self, element); + } + + function shiftUint32( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint32 element) { + element = self.shiftUint32(); + return (self, element); + } + + function unshiftUint32( + Bytes32Builder.Builder memory self, + uint32 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftUint32(element); + return self; + } + function pushBytes5( + Bytes32Builder.Builder memory self, + bytes5 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushBytes5(element); + return self; + } + + function popBytes5( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes5 element) { + element = self.popBytes5(); + return (self, element); + } + + function shiftBytes5( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes5 element) { + element = self.shiftBytes5(); + return (self, element); + } + + function unshiftBytes5( + Bytes32Builder.Builder memory self, + bytes5 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftBytes5(element); + return self; + } + function pushInt40( + Bytes32Builder.Builder memory self, + int40 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushInt40(element); + return self; + } + + function popInt40( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int40 element) { + element = self.popInt40(); + return (self, element); + } + + function shiftInt40( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int40 element) { + element = self.shiftInt40(); + return (self, element); + } + + function unshiftInt40( + Bytes32Builder.Builder memory self, + int40 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftInt40(element); + return self; + } + function pushUint40( + Bytes32Builder.Builder memory self, + uint40 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushUint40(element); + return self; + } + + function popUint40( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint40 element) { + element = self.popUint40(); + return (self, element); + } + + function shiftUint40( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint40 element) { + element = self.shiftUint40(); + return (self, element); + } + + function unshiftUint40( + Bytes32Builder.Builder memory self, + uint40 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftUint40(element); + return self; + } + function pushBytes6( + Bytes32Builder.Builder memory self, + bytes6 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushBytes6(element); + return self; + } + + function popBytes6( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes6 element) { + element = self.popBytes6(); + return (self, element); + } + + function shiftBytes6( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes6 element) { + element = self.shiftBytes6(); + return (self, element); + } + + function unshiftBytes6( + Bytes32Builder.Builder memory self, + bytes6 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftBytes6(element); + return self; + } + function pushInt48( + Bytes32Builder.Builder memory self, + int48 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushInt48(element); + return self; + } + + function popInt48( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int48 element) { + element = self.popInt48(); + return (self, element); + } + + function shiftInt48( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int48 element) { + element = self.shiftInt48(); + return (self, element); + } + + function unshiftInt48( + Bytes32Builder.Builder memory self, + int48 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftInt48(element); + return self; + } + function pushUint48( + Bytes32Builder.Builder memory self, + uint48 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushUint48(element); + return self; + } + + function popUint48( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint48 element) { + element = self.popUint48(); + return (self, element); + } + + function shiftUint48( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint48 element) { + element = self.shiftUint48(); + return (self, element); + } + + function unshiftUint48( + Bytes32Builder.Builder memory self, + uint48 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftUint48(element); + return self; + } + function pushBytes7( + Bytes32Builder.Builder memory self, + bytes7 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushBytes7(element); + return self; + } + + function popBytes7( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes7 element) { + element = self.popBytes7(); + return (self, element); + } + + function shiftBytes7( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes7 element) { + element = self.shiftBytes7(); + return (self, element); + } + + function unshiftBytes7( + Bytes32Builder.Builder memory self, + bytes7 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftBytes7(element); + return self; + } + function pushInt56( + Bytes32Builder.Builder memory self, + int56 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushInt56(element); + return self; + } + + function popInt56( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int56 element) { + element = self.popInt56(); + return (self, element); + } + + function shiftInt56( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int56 element) { + element = self.shiftInt56(); + return (self, element); + } + + function unshiftInt56( + Bytes32Builder.Builder memory self, + int56 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftInt56(element); + return self; + } + function pushUint56( + Bytes32Builder.Builder memory self, + uint56 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushUint56(element); + return self; + } + + function popUint56( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint56 element) { + element = self.popUint56(); + return (self, element); + } + + function shiftUint56( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint56 element) { + element = self.shiftUint56(); + return (self, element); + } + + function unshiftUint56( + Bytes32Builder.Builder memory self, + uint56 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftUint56(element); + return self; + } + function pushBytes8( + Bytes32Builder.Builder memory self, + bytes8 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushBytes8(element); + return self; + } + + function popBytes8( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes8 element) { + element = self.popBytes8(); + return (self, element); + } + + function shiftBytes8( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes8 element) { + element = self.shiftBytes8(); + return (self, element); + } + + function unshiftBytes8( + Bytes32Builder.Builder memory self, + bytes8 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftBytes8(element); + return self; + } + function pushInt64( + Bytes32Builder.Builder memory self, + int64 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushInt64(element); + return self; + } + + function popInt64( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int64 element) { + element = self.popInt64(); + return (self, element); + } + + function shiftInt64( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int64 element) { + element = self.shiftInt64(); + return (self, element); + } + + function unshiftInt64( + Bytes32Builder.Builder memory self, + int64 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftInt64(element); + return self; + } + function pushUint64( + Bytes32Builder.Builder memory self, + uint64 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushUint64(element); + return self; + } + + function popUint64( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint64 element) { + element = self.popUint64(); + return (self, element); + } + + function shiftUint64( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint64 element) { + element = self.shiftUint64(); + return (self, element); + } + + function unshiftUint64( + Bytes32Builder.Builder memory self, + uint64 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftUint64(element); + return self; + } + function pushBytes9( + Bytes32Builder.Builder memory self, + bytes9 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushBytes9(element); + return self; + } + + function popBytes9( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes9 element) { + element = self.popBytes9(); + return (self, element); + } + + function shiftBytes9( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes9 element) { + element = self.shiftBytes9(); + return (self, element); + } + + function unshiftBytes9( + Bytes32Builder.Builder memory self, + bytes9 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftBytes9(element); + return self; + } + function pushInt72( + Bytes32Builder.Builder memory self, + int72 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushInt72(element); + return self; + } + + function popInt72( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int72 element) { + element = self.popInt72(); + return (self, element); + } + + function shiftInt72( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int72 element) { + element = self.shiftInt72(); + return (self, element); + } + + function unshiftInt72( + Bytes32Builder.Builder memory self, + int72 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftInt72(element); + return self; + } + function pushUint72( + Bytes32Builder.Builder memory self, + uint72 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushUint72(element); + return self; + } + + function popUint72( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint72 element) { + element = self.popUint72(); + return (self, element); + } + + function shiftUint72( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint72 element) { + element = self.shiftUint72(); + return (self, element); + } + + function unshiftUint72( + Bytes32Builder.Builder memory self, + uint72 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftUint72(element); + return self; + } + function pushBytes10( + Bytes32Builder.Builder memory self, + bytes10 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushBytes10(element); + return self; + } + + function popBytes10( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes10 element) { + element = self.popBytes10(); + return (self, element); + } + + function shiftBytes10( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes10 element) { + element = self.shiftBytes10(); + return (self, element); + } + + function unshiftBytes10( + Bytes32Builder.Builder memory self, + bytes10 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftBytes10(element); + return self; + } + function pushInt80( + Bytes32Builder.Builder memory self, + int80 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushInt80(element); + return self; + } + + function popInt80( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int80 element) { + element = self.popInt80(); + return (self, element); + } + + function shiftInt80( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int80 element) { + element = self.shiftInt80(); + return (self, element); + } + + function unshiftInt80( + Bytes32Builder.Builder memory self, + int80 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftInt80(element); + return self; + } + function pushUint80( + Bytes32Builder.Builder memory self, + uint80 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushUint80(element); + return self; + } + + function popUint80( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint80 element) { + element = self.popUint80(); + return (self, element); + } + + function shiftUint80( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint80 element) { + element = self.shiftUint80(); + return (self, element); + } + + function unshiftUint80( + Bytes32Builder.Builder memory self, + uint80 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftUint80(element); + return self; + } + function pushBytes11( + Bytes32Builder.Builder memory self, + bytes11 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushBytes11(element); + return self; + } + + function popBytes11( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes11 element) { + element = self.popBytes11(); + return (self, element); + } + + function shiftBytes11( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes11 element) { + element = self.shiftBytes11(); + return (self, element); + } + + function unshiftBytes11( + Bytes32Builder.Builder memory self, + bytes11 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftBytes11(element); + return self; + } + function pushInt88( + Bytes32Builder.Builder memory self, + int88 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushInt88(element); + return self; + } + + function popInt88( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int88 element) { + element = self.popInt88(); + return (self, element); + } + + function shiftInt88( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int88 element) { + element = self.shiftInt88(); + return (self, element); + } + + function unshiftInt88( + Bytes32Builder.Builder memory self, + int88 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftInt88(element); + return self; + } + function pushUint88( + Bytes32Builder.Builder memory self, + uint88 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushUint88(element); + return self; + } + + function popUint88( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint88 element) { + element = self.popUint88(); + return (self, element); + } + + function shiftUint88( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint88 element) { + element = self.shiftUint88(); + return (self, element); + } + + function unshiftUint88( + Bytes32Builder.Builder memory self, + uint88 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftUint88(element); + return self; + } + function pushBytes12( + Bytes32Builder.Builder memory self, + bytes12 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushBytes12(element); + return self; + } + + function popBytes12( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes12 element) { + element = self.popBytes12(); + return (self, element); + } + + function shiftBytes12( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes12 element) { + element = self.shiftBytes12(); + return (self, element); + } + + function unshiftBytes12( + Bytes32Builder.Builder memory self, + bytes12 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftBytes12(element); + return self; + } + function pushInt96( + Bytes32Builder.Builder memory self, + int96 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushInt96(element); + return self; + } + + function popInt96( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int96 element) { + element = self.popInt96(); + return (self, element); + } + + function shiftInt96( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int96 element) { + element = self.shiftInt96(); + return (self, element); + } + + function unshiftInt96( + Bytes32Builder.Builder memory self, + int96 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftInt96(element); + return self; + } + function pushUint96( + Bytes32Builder.Builder memory self, + uint96 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushUint96(element); + return self; + } + + function popUint96( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint96 element) { + element = self.popUint96(); + return (self, element); + } + + function shiftUint96( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint96 element) { + element = self.shiftUint96(); + return (self, element); + } + + function unshiftUint96( + Bytes32Builder.Builder memory self, + uint96 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftUint96(element); + return self; + } + function pushBytes13( + Bytes32Builder.Builder memory self, + bytes13 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushBytes13(element); + return self; + } + + function popBytes13( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes13 element) { + element = self.popBytes13(); + return (self, element); + } + + function shiftBytes13( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes13 element) { + element = self.shiftBytes13(); + return (self, element); + } + + function unshiftBytes13( + Bytes32Builder.Builder memory self, + bytes13 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftBytes13(element); + return self; + } + function pushInt104( + Bytes32Builder.Builder memory self, + int104 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushInt104(element); + return self; + } + + function popInt104( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int104 element) { + element = self.popInt104(); + return (self, element); + } + + function shiftInt104( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int104 element) { + element = self.shiftInt104(); + return (self, element); + } + + function unshiftInt104( + Bytes32Builder.Builder memory self, + int104 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftInt104(element); + return self; + } + function pushUint104( + Bytes32Builder.Builder memory self, + uint104 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushUint104(element); + return self; + } + + function popUint104( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint104 element) { + element = self.popUint104(); + return (self, element); + } + + function shiftUint104( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint104 element) { + element = self.shiftUint104(); + return (self, element); + } + + function unshiftUint104( + Bytes32Builder.Builder memory self, + uint104 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftUint104(element); + return self; + } + function pushBytes14( + Bytes32Builder.Builder memory self, + bytes14 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushBytes14(element); + return self; + } + + function popBytes14( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes14 element) { + element = self.popBytes14(); + return (self, element); + } + + function shiftBytes14( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes14 element) { + element = self.shiftBytes14(); + return (self, element); + } + + function unshiftBytes14( + Bytes32Builder.Builder memory self, + bytes14 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftBytes14(element); + return self; + } + function pushInt112( + Bytes32Builder.Builder memory self, + int112 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushInt112(element); + return self; + } + + function popInt112( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int112 element) { + element = self.popInt112(); + return (self, element); + } + + function shiftInt112( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int112 element) { + element = self.shiftInt112(); + return (self, element); + } + + function unshiftInt112( + Bytes32Builder.Builder memory self, + int112 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftInt112(element); + return self; + } + function pushUint112( + Bytes32Builder.Builder memory self, + uint112 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushUint112(element); + return self; + } + + function popUint112( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint112 element) { + element = self.popUint112(); + return (self, element); + } + + function shiftUint112( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint112 element) { + element = self.shiftUint112(); + return (self, element); + } + + function unshiftUint112( + Bytes32Builder.Builder memory self, + uint112 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftUint112(element); + return self; + } + function pushBytes15( + Bytes32Builder.Builder memory self, + bytes15 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushBytes15(element); + return self; + } + + function popBytes15( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes15 element) { + element = self.popBytes15(); + return (self, element); + } + + function shiftBytes15( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes15 element) { + element = self.shiftBytes15(); + return (self, element); + } + + function unshiftBytes15( + Bytes32Builder.Builder memory self, + bytes15 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftBytes15(element); + return self; + } + function pushInt120( + Bytes32Builder.Builder memory self, + int120 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushInt120(element); + return self; + } + + function popInt120( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int120 element) { + element = self.popInt120(); + return (self, element); + } + + function shiftInt120( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int120 element) { + element = self.shiftInt120(); + return (self, element); + } + + function unshiftInt120( + Bytes32Builder.Builder memory self, + int120 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftInt120(element); + return self; + } + function pushUint120( + Bytes32Builder.Builder memory self, + uint120 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushUint120(element); + return self; + } + + function popUint120( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint120 element) { + element = self.popUint120(); + return (self, element); + } + + function shiftUint120( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint120 element) { + element = self.shiftUint120(); + return (self, element); + } + + function unshiftUint120( + Bytes32Builder.Builder memory self, + uint120 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftUint120(element); + return self; + } + function pushBytes16( + Bytes32Builder.Builder memory self, + bytes16 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushBytes16(element); + return self; + } + + function popBytes16( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes16 element) { + element = self.popBytes16(); + return (self, element); + } + + function shiftBytes16( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes16 element) { + element = self.shiftBytes16(); + return (self, element); + } + + function unshiftBytes16( + Bytes32Builder.Builder memory self, + bytes16 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftBytes16(element); + return self; + } + function pushInt128( + Bytes32Builder.Builder memory self, + int128 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushInt128(element); + return self; + } + + function popInt128( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int128 element) { + element = self.popInt128(); + return (self, element); + } + + function shiftInt128( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int128 element) { + element = self.shiftInt128(); + return (self, element); + } + + function unshiftInt128( + Bytes32Builder.Builder memory self, + int128 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftInt128(element); + return self; + } + function pushUint128( + Bytes32Builder.Builder memory self, + uint128 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushUint128(element); + return self; + } + + function popUint128( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint128 element) { + element = self.popUint128(); + return (self, element); + } + + function shiftUint128( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint128 element) { + element = self.shiftUint128(); + return (self, element); + } + + function unshiftUint128( + Bytes32Builder.Builder memory self, + uint128 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftUint128(element); + return self; + } + function pushBytes17( + Bytes32Builder.Builder memory self, + bytes17 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushBytes17(element); + return self; + } + + function popBytes17( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes17 element) { + element = self.popBytes17(); + return (self, element); + } + + function shiftBytes17( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes17 element) { + element = self.shiftBytes17(); + return (self, element); + } + + function unshiftBytes17( + Bytes32Builder.Builder memory self, + bytes17 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftBytes17(element); + return self; + } + function pushInt136( + Bytes32Builder.Builder memory self, + int136 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushInt136(element); + return self; + } + + function popInt136( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int136 element) { + element = self.popInt136(); + return (self, element); + } + + function shiftInt136( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int136 element) { + element = self.shiftInt136(); + return (self, element); + } + + function unshiftInt136( + Bytes32Builder.Builder memory self, + int136 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftInt136(element); + return self; + } + function pushUint136( + Bytes32Builder.Builder memory self, + uint136 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushUint136(element); + return self; + } + + function popUint136( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint136 element) { + element = self.popUint136(); + return (self, element); + } + + function shiftUint136( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint136 element) { + element = self.shiftUint136(); + return (self, element); + } + + function unshiftUint136( + Bytes32Builder.Builder memory self, + uint136 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftUint136(element); + return self; + } + function pushBytes18( + Bytes32Builder.Builder memory self, + bytes18 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushBytes18(element); + return self; + } + + function popBytes18( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes18 element) { + element = self.popBytes18(); + return (self, element); + } + + function shiftBytes18( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes18 element) { + element = self.shiftBytes18(); + return (self, element); + } + + function unshiftBytes18( + Bytes32Builder.Builder memory self, + bytes18 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftBytes18(element); + return self; + } + function pushInt144( + Bytes32Builder.Builder memory self, + int144 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushInt144(element); + return self; + } + + function popInt144( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int144 element) { + element = self.popInt144(); + return (self, element); + } + + function shiftInt144( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int144 element) { + element = self.shiftInt144(); + return (self, element); + } + + function unshiftInt144( + Bytes32Builder.Builder memory self, + int144 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftInt144(element); + return self; + } + function pushUint144( + Bytes32Builder.Builder memory self, + uint144 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushUint144(element); + return self; + } + + function popUint144( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint144 element) { + element = self.popUint144(); + return (self, element); + } + + function shiftUint144( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint144 element) { + element = self.shiftUint144(); + return (self, element); + } + + function unshiftUint144( + Bytes32Builder.Builder memory self, + uint144 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftUint144(element); + return self; + } + function pushBytes19( + Bytes32Builder.Builder memory self, + bytes19 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushBytes19(element); + return self; + } + + function popBytes19( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes19 element) { + element = self.popBytes19(); + return (self, element); + } + + function shiftBytes19( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes19 element) { + element = self.shiftBytes19(); + return (self, element); + } + + function unshiftBytes19( + Bytes32Builder.Builder memory self, + bytes19 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftBytes19(element); + return self; + } + function pushInt152( + Bytes32Builder.Builder memory self, + int152 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushInt152(element); + return self; + } + + function popInt152( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int152 element) { + element = self.popInt152(); + return (self, element); + } + + function shiftInt152( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int152 element) { + element = self.shiftInt152(); + return (self, element); + } + + function unshiftInt152( + Bytes32Builder.Builder memory self, + int152 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftInt152(element); + return self; + } + function pushUint152( + Bytes32Builder.Builder memory self, + uint152 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushUint152(element); + return self; + } + + function popUint152( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint152 element) { + element = self.popUint152(); + return (self, element); + } + + function shiftUint152( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint152 element) { + element = self.shiftUint152(); + return (self, element); + } + + function unshiftUint152( + Bytes32Builder.Builder memory self, + uint152 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftUint152(element); + return self; + } + function pushBytes20( + Bytes32Builder.Builder memory self, + bytes20 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushBytes20(element); + return self; + } + + function popBytes20( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes20 element) { + element = self.popBytes20(); + return (self, element); + } + + function shiftBytes20( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes20 element) { + element = self.shiftBytes20(); + return (self, element); + } + + function unshiftBytes20( + Bytes32Builder.Builder memory self, + bytes20 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftBytes20(element); + return self; + } + function pushInt160( + Bytes32Builder.Builder memory self, + int160 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushInt160(element); + return self; + } + + function popInt160( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int160 element) { + element = self.popInt160(); + return (self, element); + } + + function shiftInt160( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int160 element) { + element = self.shiftInt160(); + return (self, element); + } + + function unshiftInt160( + Bytes32Builder.Builder memory self, + int160 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftInt160(element); + return self; + } + function pushUint160( + Bytes32Builder.Builder memory self, + uint160 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushUint160(element); + return self; + } + + function popUint160( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint160 element) { + element = self.popUint160(); + return (self, element); + } + + function shiftUint160( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint160 element) { + element = self.shiftUint160(); + return (self, element); + } + + function unshiftUint160( + Bytes32Builder.Builder memory self, + uint160 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftUint160(element); + return self; + } + function pushAddress( + Bytes32Builder.Builder memory self, + address element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushAddress(element); + return self; + } + + function popAddress( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, address element) { + element = self.popAddress(); + return (self, element); + } + + function shiftAddress( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, address element) { + element = self.shiftAddress(); + return (self, element); + } + + function unshiftAddress( + Bytes32Builder.Builder memory self, + address element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftAddress(element); + return self; + } + function pushBytes21( + Bytes32Builder.Builder memory self, + bytes21 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushBytes21(element); + return self; + } + + function popBytes21( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes21 element) { + element = self.popBytes21(); + return (self, element); + } + + function shiftBytes21( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes21 element) { + element = self.shiftBytes21(); + return (self, element); + } + + function unshiftBytes21( + Bytes32Builder.Builder memory self, + bytes21 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftBytes21(element); + return self; + } + function pushInt168( + Bytes32Builder.Builder memory self, + int168 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushInt168(element); + return self; + } + + function popInt168( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int168 element) { + element = self.popInt168(); + return (self, element); + } + + function shiftInt168( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int168 element) { + element = self.shiftInt168(); + return (self, element); + } + + function unshiftInt168( + Bytes32Builder.Builder memory self, + int168 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftInt168(element); + return self; + } + function pushUint168( + Bytes32Builder.Builder memory self, + uint168 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushUint168(element); + return self; + } + + function popUint168( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint168 element) { + element = self.popUint168(); + return (self, element); + } + + function shiftUint168( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint168 element) { + element = self.shiftUint168(); + return (self, element); + } + + function unshiftUint168( + Bytes32Builder.Builder memory self, + uint168 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftUint168(element); + return self; + } + function pushBytes22( + Bytes32Builder.Builder memory self, + bytes22 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushBytes22(element); + return self; + } + + function popBytes22( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes22 element) { + element = self.popBytes22(); + return (self, element); + } + + function shiftBytes22( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes22 element) { + element = self.shiftBytes22(); + return (self, element); + } + + function unshiftBytes22( + Bytes32Builder.Builder memory self, + bytes22 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftBytes22(element); + return self; + } + function pushInt176( + Bytes32Builder.Builder memory self, + int176 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushInt176(element); + return self; + } + + function popInt176( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int176 element) { + element = self.popInt176(); + return (self, element); + } + + function shiftInt176( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int176 element) { + element = self.shiftInt176(); + return (self, element); + } + + function unshiftInt176( + Bytes32Builder.Builder memory self, + int176 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftInt176(element); + return self; + } + function pushUint176( + Bytes32Builder.Builder memory self, + uint176 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushUint176(element); + return self; + } + + function popUint176( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint176 element) { + element = self.popUint176(); + return (self, element); + } + + function shiftUint176( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint176 element) { + element = self.shiftUint176(); + return (self, element); + } + + function unshiftUint176( + Bytes32Builder.Builder memory self, + uint176 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftUint176(element); + return self; + } + function pushBytes23( + Bytes32Builder.Builder memory self, + bytes23 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushBytes23(element); + return self; + } + + function popBytes23( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes23 element) { + element = self.popBytes23(); + return (self, element); + } + + function shiftBytes23( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes23 element) { + element = self.shiftBytes23(); + return (self, element); + } + + function unshiftBytes23( + Bytes32Builder.Builder memory self, + bytes23 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftBytes23(element); + return self; + } + function pushInt184( + Bytes32Builder.Builder memory self, + int184 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushInt184(element); + return self; + } + + function popInt184( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int184 element) { + element = self.popInt184(); + return (self, element); + } + + function shiftInt184( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int184 element) { + element = self.shiftInt184(); + return (self, element); + } + + function unshiftInt184( + Bytes32Builder.Builder memory self, + int184 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftInt184(element); + return self; + } + function pushUint184( + Bytes32Builder.Builder memory self, + uint184 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushUint184(element); + return self; + } + + function popUint184( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint184 element) { + element = self.popUint184(); + return (self, element); + } + + function shiftUint184( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint184 element) { + element = self.shiftUint184(); + return (self, element); + } + + function unshiftUint184( + Bytes32Builder.Builder memory self, + uint184 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftUint184(element); + return self; + } + function pushBytes24( + Bytes32Builder.Builder memory self, + bytes24 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushBytes24(element); + return self; + } + + function popBytes24( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes24 element) { + element = self.popBytes24(); + return (self, element); + } + + function shiftBytes24( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes24 element) { + element = self.shiftBytes24(); + return (self, element); + } + + function unshiftBytes24( + Bytes32Builder.Builder memory self, + bytes24 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftBytes24(element); + return self; + } + function pushInt192( + Bytes32Builder.Builder memory self, + int192 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushInt192(element); + return self; + } + + function popInt192( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int192 element) { + element = self.popInt192(); + return (self, element); + } + + function shiftInt192( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int192 element) { + element = self.shiftInt192(); + return (self, element); + } + + function unshiftInt192( + Bytes32Builder.Builder memory self, + int192 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftInt192(element); + return self; + } + function pushUint192( + Bytes32Builder.Builder memory self, + uint192 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushUint192(element); + return self; + } + + function popUint192( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint192 element) { + element = self.popUint192(); + return (self, element); + } + + function shiftUint192( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint192 element) { + element = self.shiftUint192(); + return (self, element); + } + + function unshiftUint192( + Bytes32Builder.Builder memory self, + uint192 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftUint192(element); + return self; + } + function pushBytes25( + Bytes32Builder.Builder memory self, + bytes25 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushBytes25(element); + return self; + } + + function popBytes25( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes25 element) { + element = self.popBytes25(); + return (self, element); + } + + function shiftBytes25( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes25 element) { + element = self.shiftBytes25(); + return (self, element); + } + + function unshiftBytes25( + Bytes32Builder.Builder memory self, + bytes25 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftBytes25(element); + return self; + } + function pushInt200( + Bytes32Builder.Builder memory self, + int200 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushInt200(element); + return self; + } + + function popInt200( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int200 element) { + element = self.popInt200(); + return (self, element); + } + + function shiftInt200( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int200 element) { + element = self.shiftInt200(); + return (self, element); + } + + function unshiftInt200( + Bytes32Builder.Builder memory self, + int200 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftInt200(element); + return self; + } + function pushUint200( + Bytes32Builder.Builder memory self, + uint200 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushUint200(element); + return self; + } + + function popUint200( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint200 element) { + element = self.popUint200(); + return (self, element); + } + + function shiftUint200( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint200 element) { + element = self.shiftUint200(); + return (self, element); + } + + function unshiftUint200( + Bytes32Builder.Builder memory self, + uint200 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftUint200(element); + return self; + } + function pushBytes26( + Bytes32Builder.Builder memory self, + bytes26 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushBytes26(element); + return self; + } + + function popBytes26( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes26 element) { + element = self.popBytes26(); + return (self, element); + } + + function shiftBytes26( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes26 element) { + element = self.shiftBytes26(); + return (self, element); + } + + function unshiftBytes26( + Bytes32Builder.Builder memory self, + bytes26 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftBytes26(element); + return self; + } + function pushInt208( + Bytes32Builder.Builder memory self, + int208 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushInt208(element); + return self; + } + + function popInt208( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int208 element) { + element = self.popInt208(); + return (self, element); + } + + function shiftInt208( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int208 element) { + element = self.shiftInt208(); + return (self, element); + } + + function unshiftInt208( + Bytes32Builder.Builder memory self, + int208 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftInt208(element); + return self; + } + function pushUint208( + Bytes32Builder.Builder memory self, + uint208 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushUint208(element); + return self; + } + + function popUint208( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint208 element) { + element = self.popUint208(); + return (self, element); + } + + function shiftUint208( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint208 element) { + element = self.shiftUint208(); + return (self, element); + } + + function unshiftUint208( + Bytes32Builder.Builder memory self, + uint208 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftUint208(element); + return self; + } + function pushBytes27( + Bytes32Builder.Builder memory self, + bytes27 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushBytes27(element); + return self; + } + + function popBytes27( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes27 element) { + element = self.popBytes27(); + return (self, element); + } + + function shiftBytes27( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes27 element) { + element = self.shiftBytes27(); + return (self, element); + } + + function unshiftBytes27( + Bytes32Builder.Builder memory self, + bytes27 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftBytes27(element); + return self; + } + function pushInt216( + Bytes32Builder.Builder memory self, + int216 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushInt216(element); + return self; + } + + function popInt216( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int216 element) { + element = self.popInt216(); + return (self, element); + } + + function shiftInt216( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int216 element) { + element = self.shiftInt216(); + return (self, element); + } + + function unshiftInt216( + Bytes32Builder.Builder memory self, + int216 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftInt216(element); + return self; + } + function pushUint216( + Bytes32Builder.Builder memory self, + uint216 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushUint216(element); + return self; + } + + function popUint216( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint216 element) { + element = self.popUint216(); + return (self, element); + } + + function shiftUint216( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint216 element) { + element = self.shiftUint216(); + return (self, element); + } + + function unshiftUint216( + Bytes32Builder.Builder memory self, + uint216 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftUint216(element); + return self; + } + function pushBytes28( + Bytes32Builder.Builder memory self, + bytes28 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushBytes28(element); + return self; + } + + function popBytes28( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes28 element) { + element = self.popBytes28(); + return (self, element); + } + + function shiftBytes28( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes28 element) { + element = self.shiftBytes28(); + return (self, element); + } + + function unshiftBytes28( + Bytes32Builder.Builder memory self, + bytes28 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftBytes28(element); + return self; + } + function pushInt224( + Bytes32Builder.Builder memory self, + int224 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushInt224(element); + return self; + } + + function popInt224( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int224 element) { + element = self.popInt224(); + return (self, element); + } + + function shiftInt224( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int224 element) { + element = self.shiftInt224(); + return (self, element); + } + + function unshiftInt224( + Bytes32Builder.Builder memory self, + int224 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftInt224(element); + return self; + } + function pushUint224( + Bytes32Builder.Builder memory self, + uint224 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushUint224(element); + return self; + } + + function popUint224( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint224 element) { + element = self.popUint224(); + return (self, element); + } + + function shiftUint224( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint224 element) { + element = self.shiftUint224(); + return (self, element); + } + + function unshiftUint224( + Bytes32Builder.Builder memory self, + uint224 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftUint224(element); + return self; + } + function pushBytes29( + Bytes32Builder.Builder memory self, + bytes29 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushBytes29(element); + return self; + } + + function popBytes29( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes29 element) { + element = self.popBytes29(); + return (self, element); + } + + function shiftBytes29( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes29 element) { + element = self.shiftBytes29(); + return (self, element); + } + + function unshiftBytes29( + Bytes32Builder.Builder memory self, + bytes29 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftBytes29(element); + return self; + } + function pushInt232( + Bytes32Builder.Builder memory self, + int232 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushInt232(element); + return self; + } + + function popInt232( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int232 element) { + element = self.popInt232(); + return (self, element); + } + + function shiftInt232( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int232 element) { + element = self.shiftInt232(); + return (self, element); + } + + function unshiftInt232( + Bytes32Builder.Builder memory self, + int232 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftInt232(element); + return self; + } + function pushUint232( + Bytes32Builder.Builder memory self, + uint232 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushUint232(element); + return self; + } + + function popUint232( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint232 element) { + element = self.popUint232(); + return (self, element); + } + + function shiftUint232( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint232 element) { + element = self.shiftUint232(); + return (self, element); + } + + function unshiftUint232( + Bytes32Builder.Builder memory self, + uint232 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftUint232(element); + return self; + } + function pushBytes30( + Bytes32Builder.Builder memory self, + bytes30 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushBytes30(element); + return self; + } + + function popBytes30( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes30 element) { + element = self.popBytes30(); + return (self, element); + } + + function shiftBytes30( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes30 element) { + element = self.shiftBytes30(); + return (self, element); + } + + function unshiftBytes30( + Bytes32Builder.Builder memory self, + bytes30 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftBytes30(element); + return self; + } + function pushInt240( + Bytes32Builder.Builder memory self, + int240 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushInt240(element); + return self; + } + + function popInt240( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int240 element) { + element = self.popInt240(); + return (self, element); + } + + function shiftInt240( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int240 element) { + element = self.shiftInt240(); + return (self, element); + } + + function unshiftInt240( + Bytes32Builder.Builder memory self, + int240 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftInt240(element); + return self; + } + function pushUint240( + Bytes32Builder.Builder memory self, + uint240 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushUint240(element); + return self; + } + + function popUint240( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint240 element) { + element = self.popUint240(); + return (self, element); + } + + function shiftUint240( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint240 element) { + element = self.shiftUint240(); + return (self, element); + } + + function unshiftUint240( + Bytes32Builder.Builder memory self, + uint240 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftUint240(element); + return self; + } + function pushBytes31( + Bytes32Builder.Builder memory self, + bytes31 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushBytes31(element); + return self; + } + + function popBytes31( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes31 element) { + element = self.popBytes31(); + return (self, element); + } + + function shiftBytes31( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes31 element) { + element = self.shiftBytes31(); + return (self, element); + } + + function unshiftBytes31( + Bytes32Builder.Builder memory self, + bytes31 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftBytes31(element); + return self; + } + function pushInt248( + Bytes32Builder.Builder memory self, + int248 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushInt248(element); + return self; + } + + function popInt248( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int248 element) { + element = self.popInt248(); + return (self, element); + } + + function shiftInt248( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int248 element) { + element = self.shiftInt248(); + return (self, element); + } + + function unshiftInt248( + Bytes32Builder.Builder memory self, + int248 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftInt248(element); + return self; + } + function pushUint248( + Bytes32Builder.Builder memory self, + uint248 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushUint248(element); + return self; + } + + function popUint248( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint248 element) { + element = self.popUint248(); + return (self, element); + } + + function shiftUint248( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint248 element) { + element = self.shiftUint248(); + return (self, element); + } + + function unshiftUint248( + Bytes32Builder.Builder memory self, + uint248 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftUint248(element); + return self; + } + function pushBytes32( + Bytes32Builder.Builder memory self, + bytes32 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushBytes32(element); + return self; + } + + function popBytes32( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes32 element) { + element = self.popBytes32(); + return (self, element); + } + + function shiftBytes32( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, bytes32 element) { + element = self.shiftBytes32(); + return (self, element); + } + + function unshiftBytes32( + Bytes32Builder.Builder memory self, + bytes32 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftBytes32(element); + return self; + } + function pushInt256( + Bytes32Builder.Builder memory self, + int256 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushInt256(element); + return self; + } + + function popInt256( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int256 element) { + element = self.popInt256(); + return (self, element); + } + + function shiftInt256( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, int256 element) { + element = self.shiftInt256(); + return (self, element); + } + + function unshiftInt256( + Bytes32Builder.Builder memory self, + int256 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftInt256(element); + return self; + } + function pushUint256( + Bytes32Builder.Builder memory self, + uint256 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.pushUint256(element); + return self; + } + + function popUint256( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint256 element) { + element = self.popUint256(); + return (self, element); + } + + function shiftUint256( + Bytes32Builder.Builder memory self + ) external pure returns (Bytes32Builder.Builder memory, uint256 element) { + element = self.shiftUint256(); + return (self, element); + } + + function unshiftUint256( + Bytes32Builder.Builder memory self, + uint256 element + ) external pure returns (Bytes32Builder.Builder memory) { + self.unshiftUint256(element); + return self; + } +} diff --git a/test/data/Bytes32Builder.ts b/test/data/Bytes32Builder.ts new file mode 100644 index 00000000..3b2ba9d1 --- /dev/null +++ b/test/data/Bytes32Builder.ts @@ -0,0 +1,11565 @@ +import { + Bytes32BuilderTest, + Bytes32BuilderTest__factory, +} from '@solidstate/typechain-types'; +import { expect } from 'chai'; +import { ethers } from 'hardhat'; + +describe('Bytes32Builder', () => { + let instance: Bytes32BuilderTest; + + before(async () => { + const [deployer] = await ethers.getSigners(); + instance = await new Bytes32BuilderTest__factory(deployer).deploy(); + }); + + describe('#pushBytes1(bytes32,bytes1)', () => { + it('inserts bytes1 at end of bytes', async () => { + const sizeBytes = 1; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushBytes1.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushInt8(bytes32,int8)', () => { + it('inserts int8 at end of bytes', async () => { + const sizeBytes = 1; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect(await instance.pushInt8.staticCall(state, input)).to.deep.equal([ + expectedData, + expectedLength, + ]); + } + }); + }); + describe('#pushUint8(bytes32,uint8)', () => { + it('inserts uint8 at end of bytes', async () => { + const sizeBytes = 1; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect(await instance.pushUint8.staticCall(state, input)).to.deep.equal( + [expectedData, expectedLength], + ); + } + }); + }); + describe('#pushBool(bytes32,bool)', () => { + it('inserts bool at end of bytes', async () => { + const sizeBytes = 1; + const data = '0x01'; + const input = true; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect(await instance.pushBool.staticCall(state, input)).to.deep.equal([ + expectedData, + expectedLength, + ]); + } + }); + }); + describe('#pushBytes2(bytes32,bytes2)', () => { + it('inserts bytes2 at end of bytes', async () => { + const sizeBytes = 2; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushBytes2.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushInt16(bytes32,int16)', () => { + it('inserts int16 at end of bytes', async () => { + const sizeBytes = 2; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect(await instance.pushInt16.staticCall(state, input)).to.deep.equal( + [expectedData, expectedLength], + ); + } + }); + }); + describe('#pushUint16(bytes32,uint16)', () => { + it('inserts uint16 at end of bytes', async () => { + const sizeBytes = 2; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushUint16.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushBytes3(bytes32,bytes3)', () => { + it('inserts bytes3 at end of bytes', async () => { + const sizeBytes = 3; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushBytes3.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushInt24(bytes32,int24)', () => { + it('inserts int24 at end of bytes', async () => { + const sizeBytes = 3; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect(await instance.pushInt24.staticCall(state, input)).to.deep.equal( + [expectedData, expectedLength], + ); + } + }); + }); + describe('#pushUint24(bytes32,uint24)', () => { + it('inserts uint24 at end of bytes', async () => { + const sizeBytes = 3; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushUint24.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushBytes4(bytes32,bytes4)', () => { + it('inserts bytes4 at end of bytes', async () => { + const sizeBytes = 4; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushBytes4.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushInt32(bytes32,int32)', () => { + it('inserts int32 at end of bytes', async () => { + const sizeBytes = 4; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect(await instance.pushInt32.staticCall(state, input)).to.deep.equal( + [expectedData, expectedLength], + ); + } + }); + }); + describe('#pushUint32(bytes32,uint32)', () => { + it('inserts uint32 at end of bytes', async () => { + const sizeBytes = 4; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushUint32.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushBytes5(bytes32,bytes5)', () => { + it('inserts bytes5 at end of bytes', async () => { + const sizeBytes = 5; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushBytes5.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushInt40(bytes32,int40)', () => { + it('inserts int40 at end of bytes', async () => { + const sizeBytes = 5; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect(await instance.pushInt40.staticCall(state, input)).to.deep.equal( + [expectedData, expectedLength], + ); + } + }); + }); + describe('#pushUint40(bytes32,uint40)', () => { + it('inserts uint40 at end of bytes', async () => { + const sizeBytes = 5; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushUint40.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushBytes6(bytes32,bytes6)', () => { + it('inserts bytes6 at end of bytes', async () => { + const sizeBytes = 6; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushBytes6.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushInt48(bytes32,int48)', () => { + it('inserts int48 at end of bytes', async () => { + const sizeBytes = 6; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect(await instance.pushInt48.staticCall(state, input)).to.deep.equal( + [expectedData, expectedLength], + ); + } + }); + }); + describe('#pushUint48(bytes32,uint48)', () => { + it('inserts uint48 at end of bytes', async () => { + const sizeBytes = 6; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushUint48.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushBytes7(bytes32,bytes7)', () => { + it('inserts bytes7 at end of bytes', async () => { + const sizeBytes = 7; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushBytes7.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushInt56(bytes32,int56)', () => { + it('inserts int56 at end of bytes', async () => { + const sizeBytes = 7; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect(await instance.pushInt56.staticCall(state, input)).to.deep.equal( + [expectedData, expectedLength], + ); + } + }); + }); + describe('#pushUint56(bytes32,uint56)', () => { + it('inserts uint56 at end of bytes', async () => { + const sizeBytes = 7; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushUint56.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushBytes8(bytes32,bytes8)', () => { + it('inserts bytes8 at end of bytes', async () => { + const sizeBytes = 8; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushBytes8.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushInt64(bytes32,int64)', () => { + it('inserts int64 at end of bytes', async () => { + const sizeBytes = 8; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect(await instance.pushInt64.staticCall(state, input)).to.deep.equal( + [expectedData, expectedLength], + ); + } + }); + }); + describe('#pushUint64(bytes32,uint64)', () => { + it('inserts uint64 at end of bytes', async () => { + const sizeBytes = 8; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushUint64.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushBytes9(bytes32,bytes9)', () => { + it('inserts bytes9 at end of bytes', async () => { + const sizeBytes = 9; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushBytes9.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushInt72(bytes32,int72)', () => { + it('inserts int72 at end of bytes', async () => { + const sizeBytes = 9; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect(await instance.pushInt72.staticCall(state, input)).to.deep.equal( + [expectedData, expectedLength], + ); + } + }); + }); + describe('#pushUint72(bytes32,uint72)', () => { + it('inserts uint72 at end of bytes', async () => { + const sizeBytes = 9; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushUint72.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushBytes10(bytes32,bytes10)', () => { + it('inserts bytes10 at end of bytes', async () => { + const sizeBytes = 10; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushBytes10.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushInt80(bytes32,int80)', () => { + it('inserts int80 at end of bytes', async () => { + const sizeBytes = 10; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect(await instance.pushInt80.staticCall(state, input)).to.deep.equal( + [expectedData, expectedLength], + ); + } + }); + }); + describe('#pushUint80(bytes32,uint80)', () => { + it('inserts uint80 at end of bytes', async () => { + const sizeBytes = 10; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushUint80.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushBytes11(bytes32,bytes11)', () => { + it('inserts bytes11 at end of bytes', async () => { + const sizeBytes = 11; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushBytes11.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushInt88(bytes32,int88)', () => { + it('inserts int88 at end of bytes', async () => { + const sizeBytes = 11; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect(await instance.pushInt88.staticCall(state, input)).to.deep.equal( + [expectedData, expectedLength], + ); + } + }); + }); + describe('#pushUint88(bytes32,uint88)', () => { + it('inserts uint88 at end of bytes', async () => { + const sizeBytes = 11; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushUint88.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushBytes12(bytes32,bytes12)', () => { + it('inserts bytes12 at end of bytes', async () => { + const sizeBytes = 12; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushBytes12.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushInt96(bytes32,int96)', () => { + it('inserts int96 at end of bytes', async () => { + const sizeBytes = 12; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect(await instance.pushInt96.staticCall(state, input)).to.deep.equal( + [expectedData, expectedLength], + ); + } + }); + }); + describe('#pushUint96(bytes32,uint96)', () => { + it('inserts uint96 at end of bytes', async () => { + const sizeBytes = 12; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushUint96.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushBytes13(bytes32,bytes13)', () => { + it('inserts bytes13 at end of bytes', async () => { + const sizeBytes = 13; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushBytes13.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushInt104(bytes32,int104)', () => { + it('inserts int104 at end of bytes', async () => { + const sizeBytes = 13; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushInt104.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushUint104(bytes32,uint104)', () => { + it('inserts uint104 at end of bytes', async () => { + const sizeBytes = 13; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushUint104.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushBytes14(bytes32,bytes14)', () => { + it('inserts bytes14 at end of bytes', async () => { + const sizeBytes = 14; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushBytes14.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushInt112(bytes32,int112)', () => { + it('inserts int112 at end of bytes', async () => { + const sizeBytes = 14; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushInt112.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushUint112(bytes32,uint112)', () => { + it('inserts uint112 at end of bytes', async () => { + const sizeBytes = 14; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushUint112.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushBytes15(bytes32,bytes15)', () => { + it('inserts bytes15 at end of bytes', async () => { + const sizeBytes = 15; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushBytes15.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushInt120(bytes32,int120)', () => { + it('inserts int120 at end of bytes', async () => { + const sizeBytes = 15; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushInt120.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushUint120(bytes32,uint120)', () => { + it('inserts uint120 at end of bytes', async () => { + const sizeBytes = 15; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushUint120.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushBytes16(bytes32,bytes16)', () => { + it('inserts bytes16 at end of bytes', async () => { + const sizeBytes = 16; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushBytes16.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushInt128(bytes32,int128)', () => { + it('inserts int128 at end of bytes', async () => { + const sizeBytes = 16; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushInt128.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushUint128(bytes32,uint128)', () => { + it('inserts uint128 at end of bytes', async () => { + const sizeBytes = 16; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushUint128.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushBytes17(bytes32,bytes17)', () => { + it('inserts bytes17 at end of bytes', async () => { + const sizeBytes = 17; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushBytes17.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushInt136(bytes32,int136)', () => { + it('inserts int136 at end of bytes', async () => { + const sizeBytes = 17; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushInt136.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushUint136(bytes32,uint136)', () => { + it('inserts uint136 at end of bytes', async () => { + const sizeBytes = 17; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushUint136.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushBytes18(bytes32,bytes18)', () => { + it('inserts bytes18 at end of bytes', async () => { + const sizeBytes = 18; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushBytes18.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushInt144(bytes32,int144)', () => { + it('inserts int144 at end of bytes', async () => { + const sizeBytes = 18; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushInt144.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushUint144(bytes32,uint144)', () => { + it('inserts uint144 at end of bytes', async () => { + const sizeBytes = 18; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushUint144.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushBytes19(bytes32,bytes19)', () => { + it('inserts bytes19 at end of bytes', async () => { + const sizeBytes = 19; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushBytes19.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushInt152(bytes32,int152)', () => { + it('inserts int152 at end of bytes', async () => { + const sizeBytes = 19; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushInt152.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushUint152(bytes32,uint152)', () => { + it('inserts uint152 at end of bytes', async () => { + const sizeBytes = 19; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushUint152.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushBytes20(bytes32,bytes20)', () => { + it('inserts bytes20 at end of bytes', async () => { + const sizeBytes = 20; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushBytes20.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushInt160(bytes32,int160)', () => { + it('inserts int160 at end of bytes', async () => { + const sizeBytes = 20; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushInt160.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushUint160(bytes32,uint160)', () => { + it('inserts uint160 at end of bytes', async () => { + const sizeBytes = 20; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushUint160.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushAddress(bytes32,address)', () => { + it('inserts address at end of bytes', async () => { + const sizeBytes = 20; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushAddress.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushBytes21(bytes32,bytes21)', () => { + it('inserts bytes21 at end of bytes', async () => { + const sizeBytes = 21; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushBytes21.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushInt168(bytes32,int168)', () => { + it('inserts int168 at end of bytes', async () => { + const sizeBytes = 21; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushInt168.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushUint168(bytes32,uint168)', () => { + it('inserts uint168 at end of bytes', async () => { + const sizeBytes = 21; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushUint168.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushBytes22(bytes32,bytes22)', () => { + it('inserts bytes22 at end of bytes', async () => { + const sizeBytes = 22; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushBytes22.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushInt176(bytes32,int176)', () => { + it('inserts int176 at end of bytes', async () => { + const sizeBytes = 22; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushInt176.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushUint176(bytes32,uint176)', () => { + it('inserts uint176 at end of bytes', async () => { + const sizeBytes = 22; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushUint176.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushBytes23(bytes32,bytes23)', () => { + it('inserts bytes23 at end of bytes', async () => { + const sizeBytes = 23; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushBytes23.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushInt184(bytes32,int184)', () => { + it('inserts int184 at end of bytes', async () => { + const sizeBytes = 23; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushInt184.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushUint184(bytes32,uint184)', () => { + it('inserts uint184 at end of bytes', async () => { + const sizeBytes = 23; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushUint184.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushBytes24(bytes32,bytes24)', () => { + it('inserts bytes24 at end of bytes', async () => { + const sizeBytes = 24; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushBytes24.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushInt192(bytes32,int192)', () => { + it('inserts int192 at end of bytes', async () => { + const sizeBytes = 24; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushInt192.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushUint192(bytes32,uint192)', () => { + it('inserts uint192 at end of bytes', async () => { + const sizeBytes = 24; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushUint192.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushBytes25(bytes32,bytes25)', () => { + it('inserts bytes25 at end of bytes', async () => { + const sizeBytes = 25; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushBytes25.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushInt200(bytes32,int200)', () => { + it('inserts int200 at end of bytes', async () => { + const sizeBytes = 25; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushInt200.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushUint200(bytes32,uint200)', () => { + it('inserts uint200 at end of bytes', async () => { + const sizeBytes = 25; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushUint200.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushBytes26(bytes32,bytes26)', () => { + it('inserts bytes26 at end of bytes', async () => { + const sizeBytes = 26; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushBytes26.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushInt208(bytes32,int208)', () => { + it('inserts int208 at end of bytes', async () => { + const sizeBytes = 26; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushInt208.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushUint208(bytes32,uint208)', () => { + it('inserts uint208 at end of bytes', async () => { + const sizeBytes = 26; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushUint208.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushBytes27(bytes32,bytes27)', () => { + it('inserts bytes27 at end of bytes', async () => { + const sizeBytes = 27; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushBytes27.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushInt216(bytes32,int216)', () => { + it('inserts int216 at end of bytes', async () => { + const sizeBytes = 27; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushInt216.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushUint216(bytes32,uint216)', () => { + it('inserts uint216 at end of bytes', async () => { + const sizeBytes = 27; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushUint216.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushBytes28(bytes32,bytes28)', () => { + it('inserts bytes28 at end of bytes', async () => { + const sizeBytes = 28; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushBytes28.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushInt224(bytes32,int224)', () => { + it('inserts int224 at end of bytes', async () => { + const sizeBytes = 28; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushInt224.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushUint224(bytes32,uint224)', () => { + it('inserts uint224 at end of bytes', async () => { + const sizeBytes = 28; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushUint224.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushBytes29(bytes32,bytes29)', () => { + it('inserts bytes29 at end of bytes', async () => { + const sizeBytes = 29; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushBytes29.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushInt232(bytes32,int232)', () => { + it('inserts int232 at end of bytes', async () => { + const sizeBytes = 29; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushInt232.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushUint232(bytes32,uint232)', () => { + it('inserts uint232 at end of bytes', async () => { + const sizeBytes = 29; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushUint232.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushBytes30(bytes32,bytes30)', () => { + it('inserts bytes30 at end of bytes', async () => { + const sizeBytes = 30; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushBytes30.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushInt240(bytes32,int240)', () => { + it('inserts int240 at end of bytes', async () => { + const sizeBytes = 30; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushInt240.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushUint240(bytes32,uint240)', () => { + it('inserts uint240 at end of bytes', async () => { + const sizeBytes = 30; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushUint240.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushBytes31(bytes32,bytes31)', () => { + it('inserts bytes31 at end of bytes', async () => { + const sizeBytes = 31; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushBytes31.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushInt248(bytes32,int248)', () => { + it('inserts int248 at end of bytes', async () => { + const sizeBytes = 31; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushInt248.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushUint248(bytes32,uint248)', () => { + it('inserts uint248 at end of bytes', async () => { + const sizeBytes = 31; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushUint248.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushBytes32(bytes32,bytes32)', () => { + it('inserts bytes32 at end of bytes', async () => { + const sizeBytes = 32; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushBytes32.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushInt256(bytes32,int256)', () => { + it('inserts int256 at end of bytes', async () => { + const sizeBytes = 32; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushInt256.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#pushUint256(bytes32,uint256)', () => { + it('inserts uint256 at end of bytes', async () => { + const sizeBytes = 32; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + data, + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.pushUint256.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + + describe('#popBytes1(bytes32,bytes1)', () => { + it('removes bytes1 from end of bytes and returns it', async () => { + const sizeBytes = 1; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popBytes1.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popInt8(bytes32,int8)', () => { + it('removes int8 from end of bytes and returns it', async () => { + const sizeBytes = 1; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popInt8.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#popUint8(bytes32,uint8)', () => { + it('removes uint8 from end of bytes and returns it', async () => { + const sizeBytes = 1; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popUint8.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popBool(bytes32,bool)', () => { + it('removes bool from end of bytes and returns it', async () => { + const sizeBytes = 1; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popBool.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(!!BigInt(expectedValue)); + } + }); + }); + describe('#popBytes2(bytes32,bytes2)', () => { + it('removes bytes2 from end of bytes and returns it', async () => { + const sizeBytes = 2; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popBytes2.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popInt16(bytes32,int16)', () => { + it('removes int16 from end of bytes and returns it', async () => { + const sizeBytes = 2; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popInt16.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#popUint16(bytes32,uint16)', () => { + it('removes uint16 from end of bytes and returns it', async () => { + const sizeBytes = 2; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popUint16.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popBytes3(bytes32,bytes3)', () => { + it('removes bytes3 from end of bytes and returns it', async () => { + const sizeBytes = 3; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popBytes3.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popInt24(bytes32,int24)', () => { + it('removes int24 from end of bytes and returns it', async () => { + const sizeBytes = 3; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popInt24.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#popUint24(bytes32,uint24)', () => { + it('removes uint24 from end of bytes and returns it', async () => { + const sizeBytes = 3; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popUint24.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popBytes4(bytes32,bytes4)', () => { + it('removes bytes4 from end of bytes and returns it', async () => { + const sizeBytes = 4; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popBytes4.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popInt32(bytes32,int32)', () => { + it('removes int32 from end of bytes and returns it', async () => { + const sizeBytes = 4; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popInt32.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#popUint32(bytes32,uint32)', () => { + it('removes uint32 from end of bytes and returns it', async () => { + const sizeBytes = 4; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popUint32.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popBytes5(bytes32,bytes5)', () => { + it('removes bytes5 from end of bytes and returns it', async () => { + const sizeBytes = 5; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popBytes5.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popInt40(bytes32,int40)', () => { + it('removes int40 from end of bytes and returns it', async () => { + const sizeBytes = 5; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popInt40.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#popUint40(bytes32,uint40)', () => { + it('removes uint40 from end of bytes and returns it', async () => { + const sizeBytes = 5; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popUint40.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popBytes6(bytes32,bytes6)', () => { + it('removes bytes6 from end of bytes and returns it', async () => { + const sizeBytes = 6; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popBytes6.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popInt48(bytes32,int48)', () => { + it('removes int48 from end of bytes and returns it', async () => { + const sizeBytes = 6; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popInt48.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#popUint48(bytes32,uint48)', () => { + it('removes uint48 from end of bytes and returns it', async () => { + const sizeBytes = 6; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popUint48.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popBytes7(bytes32,bytes7)', () => { + it('removes bytes7 from end of bytes and returns it', async () => { + const sizeBytes = 7; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popBytes7.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popInt56(bytes32,int56)', () => { + it('removes int56 from end of bytes and returns it', async () => { + const sizeBytes = 7; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popInt56.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#popUint56(bytes32,uint56)', () => { + it('removes uint56 from end of bytes and returns it', async () => { + const sizeBytes = 7; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popUint56.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popBytes8(bytes32,bytes8)', () => { + it('removes bytes8 from end of bytes and returns it', async () => { + const sizeBytes = 8; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popBytes8.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popInt64(bytes32,int64)', () => { + it('removes int64 from end of bytes and returns it', async () => { + const sizeBytes = 8; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popInt64.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#popUint64(bytes32,uint64)', () => { + it('removes uint64 from end of bytes and returns it', async () => { + const sizeBytes = 8; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popUint64.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popBytes9(bytes32,bytes9)', () => { + it('removes bytes9 from end of bytes and returns it', async () => { + const sizeBytes = 9; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popBytes9.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popInt72(bytes32,int72)', () => { + it('removes int72 from end of bytes and returns it', async () => { + const sizeBytes = 9; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popInt72.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#popUint72(bytes32,uint72)', () => { + it('removes uint72 from end of bytes and returns it', async () => { + const sizeBytes = 9; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popUint72.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popBytes10(bytes32,bytes10)', () => { + it('removes bytes10 from end of bytes and returns it', async () => { + const sizeBytes = 10; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popBytes10.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popInt80(bytes32,int80)', () => { + it('removes int80 from end of bytes and returns it', async () => { + const sizeBytes = 10; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popInt80.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#popUint80(bytes32,uint80)', () => { + it('removes uint80 from end of bytes and returns it', async () => { + const sizeBytes = 10; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popUint80.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popBytes11(bytes32,bytes11)', () => { + it('removes bytes11 from end of bytes and returns it', async () => { + const sizeBytes = 11; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popBytes11.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popInt88(bytes32,int88)', () => { + it('removes int88 from end of bytes and returns it', async () => { + const sizeBytes = 11; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popInt88.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#popUint88(bytes32,uint88)', () => { + it('removes uint88 from end of bytes and returns it', async () => { + const sizeBytes = 11; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popUint88.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popBytes12(bytes32,bytes12)', () => { + it('removes bytes12 from end of bytes and returns it', async () => { + const sizeBytes = 12; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popBytes12.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popInt96(bytes32,int96)', () => { + it('removes int96 from end of bytes and returns it', async () => { + const sizeBytes = 12; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popInt96.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#popUint96(bytes32,uint96)', () => { + it('removes uint96 from end of bytes and returns it', async () => { + const sizeBytes = 12; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popUint96.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popBytes13(bytes32,bytes13)', () => { + it('removes bytes13 from end of bytes and returns it', async () => { + const sizeBytes = 13; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popBytes13.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popInt104(bytes32,int104)', () => { + it('removes int104 from end of bytes and returns it', async () => { + const sizeBytes = 13; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popInt104.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#popUint104(bytes32,uint104)', () => { + it('removes uint104 from end of bytes and returns it', async () => { + const sizeBytes = 13; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popUint104.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popBytes14(bytes32,bytes14)', () => { + it('removes bytes14 from end of bytes and returns it', async () => { + const sizeBytes = 14; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popBytes14.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popInt112(bytes32,int112)', () => { + it('removes int112 from end of bytes and returns it', async () => { + const sizeBytes = 14; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popInt112.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#popUint112(bytes32,uint112)', () => { + it('removes uint112 from end of bytes and returns it', async () => { + const sizeBytes = 14; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popUint112.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popBytes15(bytes32,bytes15)', () => { + it('removes bytes15 from end of bytes and returns it', async () => { + const sizeBytes = 15; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popBytes15.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popInt120(bytes32,int120)', () => { + it('removes int120 from end of bytes and returns it', async () => { + const sizeBytes = 15; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popInt120.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#popUint120(bytes32,uint120)', () => { + it('removes uint120 from end of bytes and returns it', async () => { + const sizeBytes = 15; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popUint120.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popBytes16(bytes32,bytes16)', () => { + it('removes bytes16 from end of bytes and returns it', async () => { + const sizeBytes = 16; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popBytes16.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popInt128(bytes32,int128)', () => { + it('removes int128 from end of bytes and returns it', async () => { + const sizeBytes = 16; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popInt128.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#popUint128(bytes32,uint128)', () => { + it('removes uint128 from end of bytes and returns it', async () => { + const sizeBytes = 16; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popUint128.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popBytes17(bytes32,bytes17)', () => { + it('removes bytes17 from end of bytes and returns it', async () => { + const sizeBytes = 17; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popBytes17.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popInt136(bytes32,int136)', () => { + it('removes int136 from end of bytes and returns it', async () => { + const sizeBytes = 17; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popInt136.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#popUint136(bytes32,uint136)', () => { + it('removes uint136 from end of bytes and returns it', async () => { + const sizeBytes = 17; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popUint136.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popBytes18(bytes32,bytes18)', () => { + it('removes bytes18 from end of bytes and returns it', async () => { + const sizeBytes = 18; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popBytes18.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popInt144(bytes32,int144)', () => { + it('removes int144 from end of bytes and returns it', async () => { + const sizeBytes = 18; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popInt144.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#popUint144(bytes32,uint144)', () => { + it('removes uint144 from end of bytes and returns it', async () => { + const sizeBytes = 18; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popUint144.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popBytes19(bytes32,bytes19)', () => { + it('removes bytes19 from end of bytes and returns it', async () => { + const sizeBytes = 19; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popBytes19.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popInt152(bytes32,int152)', () => { + it('removes int152 from end of bytes and returns it', async () => { + const sizeBytes = 19; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popInt152.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#popUint152(bytes32,uint152)', () => { + it('removes uint152 from end of bytes and returns it', async () => { + const sizeBytes = 19; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popUint152.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popBytes20(bytes32,bytes20)', () => { + it('removes bytes20 from end of bytes and returns it', async () => { + const sizeBytes = 20; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popBytes20.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popInt160(bytes32,int160)', () => { + it('removes int160 from end of bytes and returns it', async () => { + const sizeBytes = 20; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popInt160.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#popUint160(bytes32,uint160)', () => { + it('removes uint160 from end of bytes and returns it', async () => { + const sizeBytes = 20; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popUint160.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popAddress(bytes32,address)', () => { + it('removes address from end of bytes and returns it', async () => { + const sizeBytes = 20; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popAddress.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(ethers.getAddress(expectedValue)); + } + }); + }); + describe('#popBytes21(bytes32,bytes21)', () => { + it('removes bytes21 from end of bytes and returns it', async () => { + const sizeBytes = 21; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popBytes21.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popInt168(bytes32,int168)', () => { + it('removes int168 from end of bytes and returns it', async () => { + const sizeBytes = 21; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popInt168.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#popUint168(bytes32,uint168)', () => { + it('removes uint168 from end of bytes and returns it', async () => { + const sizeBytes = 21; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popUint168.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popBytes22(bytes32,bytes22)', () => { + it('removes bytes22 from end of bytes and returns it', async () => { + const sizeBytes = 22; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popBytes22.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popInt176(bytes32,int176)', () => { + it('removes int176 from end of bytes and returns it', async () => { + const sizeBytes = 22; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popInt176.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#popUint176(bytes32,uint176)', () => { + it('removes uint176 from end of bytes and returns it', async () => { + const sizeBytes = 22; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popUint176.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popBytes23(bytes32,bytes23)', () => { + it('removes bytes23 from end of bytes and returns it', async () => { + const sizeBytes = 23; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popBytes23.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popInt184(bytes32,int184)', () => { + it('removes int184 from end of bytes and returns it', async () => { + const sizeBytes = 23; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popInt184.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#popUint184(bytes32,uint184)', () => { + it('removes uint184 from end of bytes and returns it', async () => { + const sizeBytes = 23; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popUint184.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popBytes24(bytes32,bytes24)', () => { + it('removes bytes24 from end of bytes and returns it', async () => { + const sizeBytes = 24; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popBytes24.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popInt192(bytes32,int192)', () => { + it('removes int192 from end of bytes and returns it', async () => { + const sizeBytes = 24; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popInt192.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#popUint192(bytes32,uint192)', () => { + it('removes uint192 from end of bytes and returns it', async () => { + const sizeBytes = 24; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popUint192.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popBytes25(bytes32,bytes25)', () => { + it('removes bytes25 from end of bytes and returns it', async () => { + const sizeBytes = 25; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popBytes25.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popInt200(bytes32,int200)', () => { + it('removes int200 from end of bytes and returns it', async () => { + const sizeBytes = 25; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popInt200.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#popUint200(bytes32,uint200)', () => { + it('removes uint200 from end of bytes and returns it', async () => { + const sizeBytes = 25; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popUint200.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popBytes26(bytes32,bytes26)', () => { + it('removes bytes26 from end of bytes and returns it', async () => { + const sizeBytes = 26; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popBytes26.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popInt208(bytes32,int208)', () => { + it('removes int208 from end of bytes and returns it', async () => { + const sizeBytes = 26; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popInt208.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#popUint208(bytes32,uint208)', () => { + it('removes uint208 from end of bytes and returns it', async () => { + const sizeBytes = 26; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popUint208.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popBytes27(bytes32,bytes27)', () => { + it('removes bytes27 from end of bytes and returns it', async () => { + const sizeBytes = 27; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popBytes27.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popInt216(bytes32,int216)', () => { + it('removes int216 from end of bytes and returns it', async () => { + const sizeBytes = 27; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popInt216.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#popUint216(bytes32,uint216)', () => { + it('removes uint216 from end of bytes and returns it', async () => { + const sizeBytes = 27; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popUint216.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popBytes28(bytes32,bytes28)', () => { + it('removes bytes28 from end of bytes and returns it', async () => { + const sizeBytes = 28; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popBytes28.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popInt224(bytes32,int224)', () => { + it('removes int224 from end of bytes and returns it', async () => { + const sizeBytes = 28; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popInt224.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#popUint224(bytes32,uint224)', () => { + it('removes uint224 from end of bytes and returns it', async () => { + const sizeBytes = 28; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popUint224.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popBytes29(bytes32,bytes29)', () => { + it('removes bytes29 from end of bytes and returns it', async () => { + const sizeBytes = 29; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popBytes29.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popInt232(bytes32,int232)', () => { + it('removes int232 from end of bytes and returns it', async () => { + const sizeBytes = 29; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popInt232.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#popUint232(bytes32,uint232)', () => { + it('removes uint232 from end of bytes and returns it', async () => { + const sizeBytes = 29; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popUint232.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popBytes30(bytes32,bytes30)', () => { + it('removes bytes30 from end of bytes and returns it', async () => { + const sizeBytes = 30; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popBytes30.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popInt240(bytes32,int240)', () => { + it('removes int240 from end of bytes and returns it', async () => { + const sizeBytes = 30; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popInt240.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#popUint240(bytes32,uint240)', () => { + it('removes uint240 from end of bytes and returns it', async () => { + const sizeBytes = 30; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popUint240.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popBytes31(bytes32,bytes31)', () => { + it('removes bytes31 from end of bytes and returns it', async () => { + const sizeBytes = 31; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popBytes31.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popInt248(bytes32,int248)', () => { + it('removes int248 from end of bytes and returns it', async () => { + const sizeBytes = 31; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popInt248.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#popUint248(bytes32,uint248)', () => { + it('removes uint248 from end of bytes and returns it', async () => { + const sizeBytes = 31; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popUint248.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popBytes32(bytes32,bytes32)', () => { + it('removes bytes32 from end of bytes and returns it', async () => { + const sizeBytes = 32; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popBytes32.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#popInt256(bytes32,int256)', () => { + it('removes int256 from end of bytes and returns it', async () => { + const sizeBytes = 32; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popInt256.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#popUint256(bytes32,uint256)', () => { + it('removes uint256 from end of bytes and returns it', async () => { + const sizeBytes = 32; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 32 - expectedLength / 8, 32), + 32, + ); + const expectedValue = ethers.dataSlice( + state._data, + 32 - expectedLength / 8 - sizeBytes, + 32 - expectedLength / 8, + ); + + const result = await instance.popUint256.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + + describe('#shiftBytes1(bytes32,bytes1)', () => { + it('removes bytes1 from beginning of bytes and returns it', async () => { + const sizeBytes = 1; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftBytes1.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftInt8(bytes32,int8)', () => { + it('removes int8 from beginning of bytes and returns it', async () => { + const sizeBytes = 1; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftInt8.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#shiftUint8(bytes32,uint8)', () => { + it('removes uint8 from beginning of bytes and returns it', async () => { + const sizeBytes = 1; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftUint8.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftBool(bytes32,bool)', () => { + it('removes bool from beginning of bytes and returns it', async () => { + const sizeBytes = 1; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftBool.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(!!BigInt(expectedValue)); + } + }); + }); + describe('#shiftBytes2(bytes32,bytes2)', () => { + it('removes bytes2 from beginning of bytes and returns it', async () => { + const sizeBytes = 2; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftBytes2.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftInt16(bytes32,int16)', () => { + it('removes int16 from beginning of bytes and returns it', async () => { + const sizeBytes = 2; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftInt16.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#shiftUint16(bytes32,uint16)', () => { + it('removes uint16 from beginning of bytes and returns it', async () => { + const sizeBytes = 2; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftUint16.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftBytes3(bytes32,bytes3)', () => { + it('removes bytes3 from beginning of bytes and returns it', async () => { + const sizeBytes = 3; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftBytes3.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftInt24(bytes32,int24)', () => { + it('removes int24 from beginning of bytes and returns it', async () => { + const sizeBytes = 3; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftInt24.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#shiftUint24(bytes32,uint24)', () => { + it('removes uint24 from beginning of bytes and returns it', async () => { + const sizeBytes = 3; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftUint24.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftBytes4(bytes32,bytes4)', () => { + it('removes bytes4 from beginning of bytes and returns it', async () => { + const sizeBytes = 4; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftBytes4.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftInt32(bytes32,int32)', () => { + it('removes int32 from beginning of bytes and returns it', async () => { + const sizeBytes = 4; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftInt32.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#shiftUint32(bytes32,uint32)', () => { + it('removes uint32 from beginning of bytes and returns it', async () => { + const sizeBytes = 4; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftUint32.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftBytes5(bytes32,bytes5)', () => { + it('removes bytes5 from beginning of bytes and returns it', async () => { + const sizeBytes = 5; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftBytes5.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftInt40(bytes32,int40)', () => { + it('removes int40 from beginning of bytes and returns it', async () => { + const sizeBytes = 5; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftInt40.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#shiftUint40(bytes32,uint40)', () => { + it('removes uint40 from beginning of bytes and returns it', async () => { + const sizeBytes = 5; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftUint40.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftBytes6(bytes32,bytes6)', () => { + it('removes bytes6 from beginning of bytes and returns it', async () => { + const sizeBytes = 6; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftBytes6.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftInt48(bytes32,int48)', () => { + it('removes int48 from beginning of bytes and returns it', async () => { + const sizeBytes = 6; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftInt48.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#shiftUint48(bytes32,uint48)', () => { + it('removes uint48 from beginning of bytes and returns it', async () => { + const sizeBytes = 6; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftUint48.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftBytes7(bytes32,bytes7)', () => { + it('removes bytes7 from beginning of bytes and returns it', async () => { + const sizeBytes = 7; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftBytes7.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftInt56(bytes32,int56)', () => { + it('removes int56 from beginning of bytes and returns it', async () => { + const sizeBytes = 7; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftInt56.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#shiftUint56(bytes32,uint56)', () => { + it('removes uint56 from beginning of bytes and returns it', async () => { + const sizeBytes = 7; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftUint56.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftBytes8(bytes32,bytes8)', () => { + it('removes bytes8 from beginning of bytes and returns it', async () => { + const sizeBytes = 8; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftBytes8.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftInt64(bytes32,int64)', () => { + it('removes int64 from beginning of bytes and returns it', async () => { + const sizeBytes = 8; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftInt64.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#shiftUint64(bytes32,uint64)', () => { + it('removes uint64 from beginning of bytes and returns it', async () => { + const sizeBytes = 8; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftUint64.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftBytes9(bytes32,bytes9)', () => { + it('removes bytes9 from beginning of bytes and returns it', async () => { + const sizeBytes = 9; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftBytes9.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftInt72(bytes32,int72)', () => { + it('removes int72 from beginning of bytes and returns it', async () => { + const sizeBytes = 9; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftInt72.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#shiftUint72(bytes32,uint72)', () => { + it('removes uint72 from beginning of bytes and returns it', async () => { + const sizeBytes = 9; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftUint72.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftBytes10(bytes32,bytes10)', () => { + it('removes bytes10 from beginning of bytes and returns it', async () => { + const sizeBytes = 10; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftBytes10.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftInt80(bytes32,int80)', () => { + it('removes int80 from beginning of bytes and returns it', async () => { + const sizeBytes = 10; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftInt80.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#shiftUint80(bytes32,uint80)', () => { + it('removes uint80 from beginning of bytes and returns it', async () => { + const sizeBytes = 10; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftUint80.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftBytes11(bytes32,bytes11)', () => { + it('removes bytes11 from beginning of bytes and returns it', async () => { + const sizeBytes = 11; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftBytes11.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftInt88(bytes32,int88)', () => { + it('removes int88 from beginning of bytes and returns it', async () => { + const sizeBytes = 11; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftInt88.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#shiftUint88(bytes32,uint88)', () => { + it('removes uint88 from beginning of bytes and returns it', async () => { + const sizeBytes = 11; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftUint88.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftBytes12(bytes32,bytes12)', () => { + it('removes bytes12 from beginning of bytes and returns it', async () => { + const sizeBytes = 12; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftBytes12.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftInt96(bytes32,int96)', () => { + it('removes int96 from beginning of bytes and returns it', async () => { + const sizeBytes = 12; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftInt96.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#shiftUint96(bytes32,uint96)', () => { + it('removes uint96 from beginning of bytes and returns it', async () => { + const sizeBytes = 12; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftUint96.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftBytes13(bytes32,bytes13)', () => { + it('removes bytes13 from beginning of bytes and returns it', async () => { + const sizeBytes = 13; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftBytes13.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftInt104(bytes32,int104)', () => { + it('removes int104 from beginning of bytes and returns it', async () => { + const sizeBytes = 13; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftInt104.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#shiftUint104(bytes32,uint104)', () => { + it('removes uint104 from beginning of bytes and returns it', async () => { + const sizeBytes = 13; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftUint104.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftBytes14(bytes32,bytes14)', () => { + it('removes bytes14 from beginning of bytes and returns it', async () => { + const sizeBytes = 14; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftBytes14.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftInt112(bytes32,int112)', () => { + it('removes int112 from beginning of bytes and returns it', async () => { + const sizeBytes = 14; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftInt112.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#shiftUint112(bytes32,uint112)', () => { + it('removes uint112 from beginning of bytes and returns it', async () => { + const sizeBytes = 14; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftUint112.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftBytes15(bytes32,bytes15)', () => { + it('removes bytes15 from beginning of bytes and returns it', async () => { + const sizeBytes = 15; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftBytes15.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftInt120(bytes32,int120)', () => { + it('removes int120 from beginning of bytes and returns it', async () => { + const sizeBytes = 15; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftInt120.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#shiftUint120(bytes32,uint120)', () => { + it('removes uint120 from beginning of bytes and returns it', async () => { + const sizeBytes = 15; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftUint120.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftBytes16(bytes32,bytes16)', () => { + it('removes bytes16 from beginning of bytes and returns it', async () => { + const sizeBytes = 16; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftBytes16.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftInt128(bytes32,int128)', () => { + it('removes int128 from beginning of bytes and returns it', async () => { + const sizeBytes = 16; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftInt128.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#shiftUint128(bytes32,uint128)', () => { + it('removes uint128 from beginning of bytes and returns it', async () => { + const sizeBytes = 16; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftUint128.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftBytes17(bytes32,bytes17)', () => { + it('removes bytes17 from beginning of bytes and returns it', async () => { + const sizeBytes = 17; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftBytes17.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftInt136(bytes32,int136)', () => { + it('removes int136 from beginning of bytes and returns it', async () => { + const sizeBytes = 17; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftInt136.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#shiftUint136(bytes32,uint136)', () => { + it('removes uint136 from beginning of bytes and returns it', async () => { + const sizeBytes = 17; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftUint136.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftBytes18(bytes32,bytes18)', () => { + it('removes bytes18 from beginning of bytes and returns it', async () => { + const sizeBytes = 18; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftBytes18.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftInt144(bytes32,int144)', () => { + it('removes int144 from beginning of bytes and returns it', async () => { + const sizeBytes = 18; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftInt144.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#shiftUint144(bytes32,uint144)', () => { + it('removes uint144 from beginning of bytes and returns it', async () => { + const sizeBytes = 18; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftUint144.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftBytes19(bytes32,bytes19)', () => { + it('removes bytes19 from beginning of bytes and returns it', async () => { + const sizeBytes = 19; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftBytes19.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftInt152(bytes32,int152)', () => { + it('removes int152 from beginning of bytes and returns it', async () => { + const sizeBytes = 19; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftInt152.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#shiftUint152(bytes32,uint152)', () => { + it('removes uint152 from beginning of bytes and returns it', async () => { + const sizeBytes = 19; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftUint152.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftBytes20(bytes32,bytes20)', () => { + it('removes bytes20 from beginning of bytes and returns it', async () => { + const sizeBytes = 20; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftBytes20.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftInt160(bytes32,int160)', () => { + it('removes int160 from beginning of bytes and returns it', async () => { + const sizeBytes = 20; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftInt160.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#shiftUint160(bytes32,uint160)', () => { + it('removes uint160 from beginning of bytes and returns it', async () => { + const sizeBytes = 20; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftUint160.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftAddress(bytes32,address)', () => { + it('removes address from beginning of bytes and returns it', async () => { + const sizeBytes = 20; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftAddress.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(ethers.getAddress(expectedValue)); + } + }); + }); + describe('#shiftBytes21(bytes32,bytes21)', () => { + it('removes bytes21 from beginning of bytes and returns it', async () => { + const sizeBytes = 21; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftBytes21.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftInt168(bytes32,int168)', () => { + it('removes int168 from beginning of bytes and returns it', async () => { + const sizeBytes = 21; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftInt168.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#shiftUint168(bytes32,uint168)', () => { + it('removes uint168 from beginning of bytes and returns it', async () => { + const sizeBytes = 21; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftUint168.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftBytes22(bytes32,bytes22)', () => { + it('removes bytes22 from beginning of bytes and returns it', async () => { + const sizeBytes = 22; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftBytes22.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftInt176(bytes32,int176)', () => { + it('removes int176 from beginning of bytes and returns it', async () => { + const sizeBytes = 22; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftInt176.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#shiftUint176(bytes32,uint176)', () => { + it('removes uint176 from beginning of bytes and returns it', async () => { + const sizeBytes = 22; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftUint176.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftBytes23(bytes32,bytes23)', () => { + it('removes bytes23 from beginning of bytes and returns it', async () => { + const sizeBytes = 23; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftBytes23.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftInt184(bytes32,int184)', () => { + it('removes int184 from beginning of bytes and returns it', async () => { + const sizeBytes = 23; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftInt184.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#shiftUint184(bytes32,uint184)', () => { + it('removes uint184 from beginning of bytes and returns it', async () => { + const sizeBytes = 23; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftUint184.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftBytes24(bytes32,bytes24)', () => { + it('removes bytes24 from beginning of bytes and returns it', async () => { + const sizeBytes = 24; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftBytes24.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftInt192(bytes32,int192)', () => { + it('removes int192 from beginning of bytes and returns it', async () => { + const sizeBytes = 24; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftInt192.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#shiftUint192(bytes32,uint192)', () => { + it('removes uint192 from beginning of bytes and returns it', async () => { + const sizeBytes = 24; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftUint192.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftBytes25(bytes32,bytes25)', () => { + it('removes bytes25 from beginning of bytes and returns it', async () => { + const sizeBytes = 25; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftBytes25.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftInt200(bytes32,int200)', () => { + it('removes int200 from beginning of bytes and returns it', async () => { + const sizeBytes = 25; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftInt200.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#shiftUint200(bytes32,uint200)', () => { + it('removes uint200 from beginning of bytes and returns it', async () => { + const sizeBytes = 25; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftUint200.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftBytes26(bytes32,bytes26)', () => { + it('removes bytes26 from beginning of bytes and returns it', async () => { + const sizeBytes = 26; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftBytes26.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftInt208(bytes32,int208)', () => { + it('removes int208 from beginning of bytes and returns it', async () => { + const sizeBytes = 26; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftInt208.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#shiftUint208(bytes32,uint208)', () => { + it('removes uint208 from beginning of bytes and returns it', async () => { + const sizeBytes = 26; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftUint208.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftBytes27(bytes32,bytes27)', () => { + it('removes bytes27 from beginning of bytes and returns it', async () => { + const sizeBytes = 27; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftBytes27.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftInt216(bytes32,int216)', () => { + it('removes int216 from beginning of bytes and returns it', async () => { + const sizeBytes = 27; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftInt216.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#shiftUint216(bytes32,uint216)', () => { + it('removes uint216 from beginning of bytes and returns it', async () => { + const sizeBytes = 27; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftUint216.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftBytes28(bytes32,bytes28)', () => { + it('removes bytes28 from beginning of bytes and returns it', async () => { + const sizeBytes = 28; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftBytes28.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftInt224(bytes32,int224)', () => { + it('removes int224 from beginning of bytes and returns it', async () => { + const sizeBytes = 28; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftInt224.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#shiftUint224(bytes32,uint224)', () => { + it('removes uint224 from beginning of bytes and returns it', async () => { + const sizeBytes = 28; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftUint224.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftBytes29(bytes32,bytes29)', () => { + it('removes bytes29 from beginning of bytes and returns it', async () => { + const sizeBytes = 29; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftBytes29.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftInt232(bytes32,int232)', () => { + it('removes int232 from beginning of bytes and returns it', async () => { + const sizeBytes = 29; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftInt232.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#shiftUint232(bytes32,uint232)', () => { + it('removes uint232 from beginning of bytes and returns it', async () => { + const sizeBytes = 29; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftUint232.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftBytes30(bytes32,bytes30)', () => { + it('removes bytes30 from beginning of bytes and returns it', async () => { + const sizeBytes = 30; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftBytes30.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftInt240(bytes32,int240)', () => { + it('removes int240 from beginning of bytes and returns it', async () => { + const sizeBytes = 30; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftInt240.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#shiftUint240(bytes32,uint240)', () => { + it('removes uint240 from beginning of bytes and returns it', async () => { + const sizeBytes = 30; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftUint240.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftBytes31(bytes32,bytes31)', () => { + it('removes bytes31 from beginning of bytes and returns it', async () => { + const sizeBytes = 31; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftBytes31.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftInt248(bytes32,int248)', () => { + it('removes int248 from beginning of bytes and returns it', async () => { + const sizeBytes = 31; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftInt248.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#shiftUint248(bytes32,uint248)', () => { + it('removes uint248 from beginning of bytes and returns it', async () => { + const sizeBytes = 31; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftUint248.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftBytes32(bytes32,bytes32)', () => { + it('removes bytes32 from beginning of bytes and returns it', async () => { + const sizeBytes = 32; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftBytes32.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + describe('#shiftInt256(bytes32,int256)', () => { + it('removes int256 from beginning of bytes and returns it', async () => { + const sizeBytes = 32; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftInt256.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + const negative = + BigInt(expectedValue) >> BigInt(sizeBytes * 8 - 1) === 1n; + let output; + if (negative) { + output = -(2n ** BigInt(sizeBytes * 8) - BigInt(expectedValue)); + } else { + output = BigInt(expectedValue); + } + + expect(result[1]).to.eq(output); + } + }); + }); + describe('#shiftUint256(bytes32,uint256)', () => { + it('removes uint256 from beginning of bytes and returns it', async () => { + const sizeBytes = 32; + + for (let i = sizeBytes; i <= 32; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedLength = state._size - sizeBytes * 8; + const expectedData = ethers.zeroPadValue( + ethers.dataSlice(state._data, 0, 32 - sizeBytes), + 32, + ); + const expectedValue = ethers.dataSlice(state._data, 32 - sizeBytes, 32); + + const result = await instance.shiftUint256.staticCall(state); + + expect(result[0]).to.deep.equal([expectedData, expectedLength]); + + expect(result[1]).to.eq(expectedValue); + } + }); + }); + + describe('#unshiftBytes1(bytes32,bytes1)', () => { + it('inserts bytes1 at beginning of bytes', async () => { + const sizeBytes = 1; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftBytes1.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftInt8(bytes32,int8)', () => { + it('inserts int8 at beginning of bytes', async () => { + const sizeBytes = 1; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftInt8.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftUint8(bytes32,uint8)', () => { + it('inserts uint8 at beginning of bytes', async () => { + const sizeBytes = 1; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftUint8.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftBool(bytes32,bool)', () => { + it('inserts bool at beginning of bytes', async () => { + const sizeBytes = 1; + const data = '0x01'; + const input = true; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftBool.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftBytes2(bytes32,bytes2)', () => { + it('inserts bytes2 at beginning of bytes', async () => { + const sizeBytes = 2; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftBytes2.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftInt16(bytes32,int16)', () => { + it('inserts int16 at beginning of bytes', async () => { + const sizeBytes = 2; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftInt16.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftUint16(bytes32,uint16)', () => { + it('inserts uint16 at beginning of bytes', async () => { + const sizeBytes = 2; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftUint16.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftBytes3(bytes32,bytes3)', () => { + it('inserts bytes3 at beginning of bytes', async () => { + const sizeBytes = 3; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftBytes3.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftInt24(bytes32,int24)', () => { + it('inserts int24 at beginning of bytes', async () => { + const sizeBytes = 3; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftInt24.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftUint24(bytes32,uint24)', () => { + it('inserts uint24 at beginning of bytes', async () => { + const sizeBytes = 3; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftUint24.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftBytes4(bytes32,bytes4)', () => { + it('inserts bytes4 at beginning of bytes', async () => { + const sizeBytes = 4; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftBytes4.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftInt32(bytes32,int32)', () => { + it('inserts int32 at beginning of bytes', async () => { + const sizeBytes = 4; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftInt32.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftUint32(bytes32,uint32)', () => { + it('inserts uint32 at beginning of bytes', async () => { + const sizeBytes = 4; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftUint32.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftBytes5(bytes32,bytes5)', () => { + it('inserts bytes5 at beginning of bytes', async () => { + const sizeBytes = 5; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftBytes5.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftInt40(bytes32,int40)', () => { + it('inserts int40 at beginning of bytes', async () => { + const sizeBytes = 5; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftInt40.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftUint40(bytes32,uint40)', () => { + it('inserts uint40 at beginning of bytes', async () => { + const sizeBytes = 5; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftUint40.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftBytes6(bytes32,bytes6)', () => { + it('inserts bytes6 at beginning of bytes', async () => { + const sizeBytes = 6; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftBytes6.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftInt48(bytes32,int48)', () => { + it('inserts int48 at beginning of bytes', async () => { + const sizeBytes = 6; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftInt48.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftUint48(bytes32,uint48)', () => { + it('inserts uint48 at beginning of bytes', async () => { + const sizeBytes = 6; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftUint48.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftBytes7(bytes32,bytes7)', () => { + it('inserts bytes7 at beginning of bytes', async () => { + const sizeBytes = 7; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftBytes7.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftInt56(bytes32,int56)', () => { + it('inserts int56 at beginning of bytes', async () => { + const sizeBytes = 7; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftInt56.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftUint56(bytes32,uint56)', () => { + it('inserts uint56 at beginning of bytes', async () => { + const sizeBytes = 7; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftUint56.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftBytes8(bytes32,bytes8)', () => { + it('inserts bytes8 at beginning of bytes', async () => { + const sizeBytes = 8; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftBytes8.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftInt64(bytes32,int64)', () => { + it('inserts int64 at beginning of bytes', async () => { + const sizeBytes = 8; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftInt64.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftUint64(bytes32,uint64)', () => { + it('inserts uint64 at beginning of bytes', async () => { + const sizeBytes = 8; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftUint64.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftBytes9(bytes32,bytes9)', () => { + it('inserts bytes9 at beginning of bytes', async () => { + const sizeBytes = 9; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftBytes9.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftInt72(bytes32,int72)', () => { + it('inserts int72 at beginning of bytes', async () => { + const sizeBytes = 9; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftInt72.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftUint72(bytes32,uint72)', () => { + it('inserts uint72 at beginning of bytes', async () => { + const sizeBytes = 9; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftUint72.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftBytes10(bytes32,bytes10)', () => { + it('inserts bytes10 at beginning of bytes', async () => { + const sizeBytes = 10; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftBytes10.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftInt80(bytes32,int80)', () => { + it('inserts int80 at beginning of bytes', async () => { + const sizeBytes = 10; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftInt80.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftUint80(bytes32,uint80)', () => { + it('inserts uint80 at beginning of bytes', async () => { + const sizeBytes = 10; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftUint80.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftBytes11(bytes32,bytes11)', () => { + it('inserts bytes11 at beginning of bytes', async () => { + const sizeBytes = 11; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftBytes11.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftInt88(bytes32,int88)', () => { + it('inserts int88 at beginning of bytes', async () => { + const sizeBytes = 11; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftInt88.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftUint88(bytes32,uint88)', () => { + it('inserts uint88 at beginning of bytes', async () => { + const sizeBytes = 11; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftUint88.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftBytes12(bytes32,bytes12)', () => { + it('inserts bytes12 at beginning of bytes', async () => { + const sizeBytes = 12; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftBytes12.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftInt96(bytes32,int96)', () => { + it('inserts int96 at beginning of bytes', async () => { + const sizeBytes = 12; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftInt96.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftUint96(bytes32,uint96)', () => { + it('inserts uint96 at beginning of bytes', async () => { + const sizeBytes = 12; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftUint96.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftBytes13(bytes32,bytes13)', () => { + it('inserts bytes13 at beginning of bytes', async () => { + const sizeBytes = 13; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftBytes13.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftInt104(bytes32,int104)', () => { + it('inserts int104 at beginning of bytes', async () => { + const sizeBytes = 13; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftInt104.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftUint104(bytes32,uint104)', () => { + it('inserts uint104 at beginning of bytes', async () => { + const sizeBytes = 13; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftUint104.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftBytes14(bytes32,bytes14)', () => { + it('inserts bytes14 at beginning of bytes', async () => { + const sizeBytes = 14; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftBytes14.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftInt112(bytes32,int112)', () => { + it('inserts int112 at beginning of bytes', async () => { + const sizeBytes = 14; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftInt112.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftUint112(bytes32,uint112)', () => { + it('inserts uint112 at beginning of bytes', async () => { + const sizeBytes = 14; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftUint112.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftBytes15(bytes32,bytes15)', () => { + it('inserts bytes15 at beginning of bytes', async () => { + const sizeBytes = 15; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftBytes15.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftInt120(bytes32,int120)', () => { + it('inserts int120 at beginning of bytes', async () => { + const sizeBytes = 15; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftInt120.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftUint120(bytes32,uint120)', () => { + it('inserts uint120 at beginning of bytes', async () => { + const sizeBytes = 15; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftUint120.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftBytes16(bytes32,bytes16)', () => { + it('inserts bytes16 at beginning of bytes', async () => { + const sizeBytes = 16; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftBytes16.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftInt128(bytes32,int128)', () => { + it('inserts int128 at beginning of bytes', async () => { + const sizeBytes = 16; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftInt128.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftUint128(bytes32,uint128)', () => { + it('inserts uint128 at beginning of bytes', async () => { + const sizeBytes = 16; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftUint128.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftBytes17(bytes32,bytes17)', () => { + it('inserts bytes17 at beginning of bytes', async () => { + const sizeBytes = 17; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftBytes17.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftInt136(bytes32,int136)', () => { + it('inserts int136 at beginning of bytes', async () => { + const sizeBytes = 17; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftInt136.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftUint136(bytes32,uint136)', () => { + it('inserts uint136 at beginning of bytes', async () => { + const sizeBytes = 17; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftUint136.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftBytes18(bytes32,bytes18)', () => { + it('inserts bytes18 at beginning of bytes', async () => { + const sizeBytes = 18; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftBytes18.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftInt144(bytes32,int144)', () => { + it('inserts int144 at beginning of bytes', async () => { + const sizeBytes = 18; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftInt144.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftUint144(bytes32,uint144)', () => { + it('inserts uint144 at beginning of bytes', async () => { + const sizeBytes = 18; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftUint144.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftBytes19(bytes32,bytes19)', () => { + it('inserts bytes19 at beginning of bytes', async () => { + const sizeBytes = 19; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftBytes19.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftInt152(bytes32,int152)', () => { + it('inserts int152 at beginning of bytes', async () => { + const sizeBytes = 19; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftInt152.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftUint152(bytes32,uint152)', () => { + it('inserts uint152 at beginning of bytes', async () => { + const sizeBytes = 19; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftUint152.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftBytes20(bytes32,bytes20)', () => { + it('inserts bytes20 at beginning of bytes', async () => { + const sizeBytes = 20; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftBytes20.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftInt160(bytes32,int160)', () => { + it('inserts int160 at beginning of bytes', async () => { + const sizeBytes = 20; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftInt160.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftUint160(bytes32,uint160)', () => { + it('inserts uint160 at beginning of bytes', async () => { + const sizeBytes = 20; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftUint160.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftAddress(bytes32,address)', () => { + it('inserts address at beginning of bytes', async () => { + const sizeBytes = 20; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftAddress.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftBytes21(bytes32,bytes21)', () => { + it('inserts bytes21 at beginning of bytes', async () => { + const sizeBytes = 21; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftBytes21.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftInt168(bytes32,int168)', () => { + it('inserts int168 at beginning of bytes', async () => { + const sizeBytes = 21; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftInt168.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftUint168(bytes32,uint168)', () => { + it('inserts uint168 at beginning of bytes', async () => { + const sizeBytes = 21; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftUint168.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftBytes22(bytes32,bytes22)', () => { + it('inserts bytes22 at beginning of bytes', async () => { + const sizeBytes = 22; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftBytes22.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftInt176(bytes32,int176)', () => { + it('inserts int176 at beginning of bytes', async () => { + const sizeBytes = 22; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftInt176.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftUint176(bytes32,uint176)', () => { + it('inserts uint176 at beginning of bytes', async () => { + const sizeBytes = 22; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftUint176.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftBytes23(bytes32,bytes23)', () => { + it('inserts bytes23 at beginning of bytes', async () => { + const sizeBytes = 23; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftBytes23.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftInt184(bytes32,int184)', () => { + it('inserts int184 at beginning of bytes', async () => { + const sizeBytes = 23; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftInt184.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftUint184(bytes32,uint184)', () => { + it('inserts uint184 at beginning of bytes', async () => { + const sizeBytes = 23; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftUint184.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftBytes24(bytes32,bytes24)', () => { + it('inserts bytes24 at beginning of bytes', async () => { + const sizeBytes = 24; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftBytes24.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftInt192(bytes32,int192)', () => { + it('inserts int192 at beginning of bytes', async () => { + const sizeBytes = 24; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftInt192.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftUint192(bytes32,uint192)', () => { + it('inserts uint192 at beginning of bytes', async () => { + const sizeBytes = 24; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftUint192.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftBytes25(bytes32,bytes25)', () => { + it('inserts bytes25 at beginning of bytes', async () => { + const sizeBytes = 25; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftBytes25.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftInt200(bytes32,int200)', () => { + it('inserts int200 at beginning of bytes', async () => { + const sizeBytes = 25; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftInt200.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftUint200(bytes32,uint200)', () => { + it('inserts uint200 at beginning of bytes', async () => { + const sizeBytes = 25; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftUint200.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftBytes26(bytes32,bytes26)', () => { + it('inserts bytes26 at beginning of bytes', async () => { + const sizeBytes = 26; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftBytes26.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftInt208(bytes32,int208)', () => { + it('inserts int208 at beginning of bytes', async () => { + const sizeBytes = 26; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftInt208.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftUint208(bytes32,uint208)', () => { + it('inserts uint208 at beginning of bytes', async () => { + const sizeBytes = 26; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftUint208.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftBytes27(bytes32,bytes27)', () => { + it('inserts bytes27 at beginning of bytes', async () => { + const sizeBytes = 27; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftBytes27.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftInt216(bytes32,int216)', () => { + it('inserts int216 at beginning of bytes', async () => { + const sizeBytes = 27; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftInt216.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftUint216(bytes32,uint216)', () => { + it('inserts uint216 at beginning of bytes', async () => { + const sizeBytes = 27; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftUint216.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftBytes28(bytes32,bytes28)', () => { + it('inserts bytes28 at beginning of bytes', async () => { + const sizeBytes = 28; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftBytes28.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftInt224(bytes32,int224)', () => { + it('inserts int224 at beginning of bytes', async () => { + const sizeBytes = 28; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftInt224.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftUint224(bytes32,uint224)', () => { + it('inserts uint224 at beginning of bytes', async () => { + const sizeBytes = 28; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftUint224.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftBytes29(bytes32,bytes29)', () => { + it('inserts bytes29 at beginning of bytes', async () => { + const sizeBytes = 29; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftBytes29.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftInt232(bytes32,int232)', () => { + it('inserts int232 at beginning of bytes', async () => { + const sizeBytes = 29; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftInt232.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftUint232(bytes32,uint232)', () => { + it('inserts uint232 at beginning of bytes', async () => { + const sizeBytes = 29; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftUint232.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftBytes30(bytes32,bytes30)', () => { + it('inserts bytes30 at beginning of bytes', async () => { + const sizeBytes = 30; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftBytes30.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftInt240(bytes32,int240)', () => { + it('inserts int240 at beginning of bytes', async () => { + const sizeBytes = 30; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftInt240.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftUint240(bytes32,uint240)', () => { + it('inserts uint240 at beginning of bytes', async () => { + const sizeBytes = 30; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftUint240.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftBytes31(bytes32,bytes31)', () => { + it('inserts bytes31 at beginning of bytes', async () => { + const sizeBytes = 31; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftBytes31.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftInt248(bytes32,int248)', () => { + it('inserts int248 at beginning of bytes', async () => { + const sizeBytes = 31; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftInt248.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftUint248(bytes32,uint248)', () => { + it('inserts uint248 at beginning of bytes', async () => { + const sizeBytes = 31; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftUint248.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftBytes32(bytes32,bytes32)', () => { + it('inserts bytes32 at beginning of bytes', async () => { + const sizeBytes = 32; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftBytes32.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftInt256(bytes32,int256)', () => { + it('inserts int256 at beginning of bytes', async () => { + const sizeBytes = 32; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const negative = BigInt(data) >> BigInt(sizeBytes * 8 - 1) === 1n; + let input; + if (negative) { + input = -(2n ** BigInt(sizeBytes * 8) - BigInt(data)); + } else { + input = BigInt(data); + } + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftInt256.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); + describe('#unshiftUint256(bytes32,uint256)', () => { + it('inserts uint256 at beginning of bytes', async () => { + const sizeBytes = 32; + const data = ethers.hexlify(ethers.randomBytes(sizeBytes)); + const input = data; + + for (let i = 0; i <= 32 - sizeBytes; i++) { + const state = { + _data: ethers.zeroPadValue(ethers.hexlify(ethers.randomBytes(i)), 32), + _size: i * 8, + }; + + const expectedData = ethers.zeroPadValue( + ethers.concat([ + ethers.dataSlice(state._data, 32 - state._size / 8, 32), + data, + ]), + 32, + ); + const expectedLength = state._size + sizeBytes * 8; + + expect( + await instance.unshiftUint256.staticCall(state, input), + ).to.deep.equal([expectedData, expectedLength]); + } + }); + }); +}); From acc279b66cd2c4fbadf264fea2a296f580c7e354 Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Thu, 27 Mar 2025 17:12:02 -0600 Subject: [PATCH 33/39] add Bytes32 toBuilder functions --- contracts/utils/Bytes32.sol | 26 ++++++++++++++++++++++++++ test/utils/Bytes32.ts | 23 +++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/contracts/utils/Bytes32.sol b/contracts/utils/Bytes32.sol index d5f11ffb..c945a5c7 100644 --- a/contracts/utils/Bytes32.sol +++ b/contracts/utils/Bytes32.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.24; +import { Bytes32Builder } from '../data/Bytes32Builder.sol'; import { Uint256 } from './Uint256.sol'; /** @@ -61,4 +62,29 @@ library Bytes32 { ) internal pure returns (string memory output) { output = Uint256.toHexString(uint256(value), 32); } + + /** + * @notice create a Bytes32Builder object from data payload + * @dev if length is not specified, it is assumed to be 256 bits + * @param data underlying data payload + * @return builder builder struct + */ + function toBuilder( + bytes32 data + ) internal pure returns (Bytes32Builder.Builder memory builder) { + builder = toBuilder(data, 256); + } + + /** + * @notice create a Bytes32Builder object from data payload + * @param data underlying data payload + * @param length bit length of usable data + * @return builder builder struct + */ + function toBuilder( + bytes32 data, + uint256 length + ) internal pure returns (Bytes32Builder.Builder memory builder) { + builder = Bytes32Builder.Builder(data, length); + } } diff --git a/test/utils/Bytes32.ts b/test/utils/Bytes32.ts index f102f107..11098d06 100644 --- a/test/utils/Bytes32.ts +++ b/test/utils/Bytes32.ts @@ -111,5 +111,28 @@ describe('Bytes32', async () => { expect(await instance.$toString.staticCall(value)).to.eq(value); }); }); + + describe('#toBuilder(bytes32)', () => { + it('returns Bytes32Builder struct with max length', async () => { + const data = ethers.hexlify(ethers.randomBytes(32)); + + expect(await instance['$toBuilder(bytes32)'](data)).to.deep.eq([ + data, + 256, + ]); + }); + }); + + describe('#toBuilder(bytes32,uint256)', () => { + it('returns Bytes32Builder struct with specified length', async () => { + const data = ethers.hexlify(ethers.randomBytes(32)); + + for (let i = 0n; i <= 256n; i += 8n) { + expect( + await instance['$toBuilder(bytes32,uint256)'](data, i), + ).to.deep.eq([data, i]); + } + }); + }); }); }); From 7ea318ed5a0cc56ea4e2a406048ada43d59fdd9e Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Thu, 27 Mar 2025 17:25:09 -0600 Subject: [PATCH 34/39] use Bytes32Builder for ECDSAMetaTransactionContext storage --- .../meta/_ECDSAMetaTransactionContext.sol | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/contracts/meta/_ECDSAMetaTransactionContext.sol b/contracts/meta/_ECDSAMetaTransactionContext.sol index 4aa35e85..ad6f62b3 100644 --- a/contracts/meta/_ECDSAMetaTransactionContext.sol +++ b/contracts/meta/_ECDSAMetaTransactionContext.sol @@ -6,6 +6,7 @@ import { ECDSA } from '../cryptography/ECDSA.sol'; import { EIP712 } from '../cryptography/EIP712.sol'; import { Slot } from '../data/Slot.sol'; import { Bytes32 } from '../utils/Bytes32.sol'; +import { Bytes32Builder } from '../data/Bytes32Builder.sol'; import { _Context } from './_Context.sol'; import { _IECDSAMetaTransactionContext } from './_IECDSAMetaTransactionContext.sol'; @@ -14,6 +15,7 @@ abstract contract _ECDSAMetaTransactionContext is _Context { using Bytes32 for bytes32; + using Bytes32Builder for Bytes32Builder.Builder; using ECDSA for bytes32; using Slot for Slot.TransientSlot; @@ -71,7 +73,7 @@ abstract contract _ECDSAMetaTransactionContext is // check transient storage to see if sender has been derived already // toAddress function strips the packed msgDataIndex data and returns a clean address - msgSender = TRANSIENT_SLOT.read().toAddress(); + msgSender = TRANSIENT_SLOT.read().toBuilder().shiftAddress(); if (msgSender == address(0)) { // no sender found in transient storage, so attempt to derive it from signature @@ -106,7 +108,7 @@ abstract contract _ECDSAMetaTransactionContext is uint256 split; // unpack the msgDataIndex which is stored alongside msgSender - split = (TRANSIENT_SLOT.read() >> 160).toUint256(); + split = TRANSIENT_SLOT.read().toBuilder().popUint96(); if (split == 0) { // no msgData split index found in transient storage, so attempt to derive it from signature @@ -175,15 +177,14 @@ abstract contract _ECDSAMetaTransactionContext is } } - bytes32 data; - - assembly { - // pack msgDataIndex into the 12 bytes available alongside msgSender - data := and(msgSender, shl(160, msgDataIndex)) - } - // it is necessary to store metadata in transient storage because // subsequent derivation will fail due to nonce invalidation - TRANSIENT_SLOT.write(data); + + Bytes32Builder.Builder memory builder; + + builder.pushAddress(msgSender); + builder.pushUint96(uint96(msgDataIndex)); + + TRANSIENT_SLOT.write(builder._data); } } From 96aa9b73960de626b9d01300028194bdcd4522b8 Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Thu, 27 Mar 2025 18:47:50 -0600 Subject: [PATCH 35/39] integrate TransientReentrancyGuard into ECDSAMetaTransactionContext to clear cached context at end of transaction --- .../meta/ECDSAMetaTransactionContext.sol | 31 +++++++++++++++++- .../meta/IECDSAMetaTransactionContext.sol | 2 ++ .../meta/_ECDSAMetaTransactionContext.sol | 32 +++++++++++++++---- .../meta/_IECDSAMetaTransactionContext.sol | 7 +++- 4 files changed, 63 insertions(+), 9 deletions(-) diff --git a/contracts/meta/ECDSAMetaTransactionContext.sol b/contracts/meta/ECDSAMetaTransactionContext.sol index 994b97af..6f3ba2db 100644 --- a/contracts/meta/ECDSAMetaTransactionContext.sol +++ b/contracts/meta/ECDSAMetaTransactionContext.sol @@ -3,6 +3,8 @@ pragma solidity ^0.8.24; import { IERC5267 } from '../interfaces/IERC5267.sol'; +import { TransientReentrancyGuard } from '../security/reentrancy_guard/TransientReentrancyGuard.sol'; +import { _TransientReentrancyGuard } from '../security/reentrancy_guard/_TransientReentrancyGuard.sol'; import { Context } from './Context.sol'; import { _Context } from './_Context.sol'; import { IECDSAMetaTransactionContext } from './IECDSAMetaTransactionContext.sol'; @@ -11,7 +13,8 @@ import { _ECDSAMetaTransactionContext } from './_ECDSAMetaTransactionContext.sol abstract contract ECDSAMetaTransactionContext is IECDSAMetaTransactionContext, _ECDSAMetaTransactionContext, - Context + Context, + TransientReentrancyGuard { /** * @inheritdoc IERC5267 @@ -56,4 +59,30 @@ abstract contract ECDSAMetaTransactionContext is { length = super._calldataSuffixLength(); } + + function _isReentrancyGuardLocked() + internal + view + virtual + override(_TransientReentrancyGuard, TransientReentrancyGuard) + returns (bool status) + { + status = super._isReentrancyGuardLocked(); + } + + function _lockReentrancyGuard() + internal + virtual + override(TransientReentrancyGuard, _ECDSAMetaTransactionContext) + { + super._lockReentrancyGuard(); + } + + function _unlockReentrancyGuard() + internal + virtual + override(_TransientReentrancyGuard, TransientReentrancyGuard) + { + super._unlockReentrancyGuard(); + } } diff --git a/contracts/meta/IECDSAMetaTransactionContext.sol b/contracts/meta/IECDSAMetaTransactionContext.sol index 2fdf9d7c..93795091 100644 --- a/contracts/meta/IECDSAMetaTransactionContext.sol +++ b/contracts/meta/IECDSAMetaTransactionContext.sol @@ -3,11 +3,13 @@ pragma solidity ^0.8.24; import { IERC5267 } from '../interfaces/IERC5267.sol'; +import { ITransientReentrancyGuard } from '../security/reentrancy_guard/ITransientReentrancyGuard.sol'; import { IContext } from './IContext.sol'; import { _IECDSAMetaTransactionContext } from './_IECDSAMetaTransactionContext.sol'; interface IECDSAMetaTransactionContext is _IECDSAMetaTransactionContext, IContext, + ITransientReentrancyGuard, IERC5267 {} diff --git a/contracts/meta/_ECDSAMetaTransactionContext.sol b/contracts/meta/_ECDSAMetaTransactionContext.sol index ad6f62b3..896f94ec 100644 --- a/contracts/meta/_ECDSAMetaTransactionContext.sol +++ b/contracts/meta/_ECDSAMetaTransactionContext.sol @@ -5,6 +5,7 @@ pragma solidity ^0.8.24; import { ECDSA } from '../cryptography/ECDSA.sol'; import { EIP712 } from '../cryptography/EIP712.sol'; import { Slot } from '../data/Slot.sol'; +import { _TransientReentrancyGuard } from '../security/reentrancy_guard/_TransientReentrancyGuard.sol'; import { Bytes32 } from '../utils/Bytes32.sol'; import { Bytes32Builder } from '../data/Bytes32Builder.sol'; import { _Context } from './_Context.sol'; @@ -12,7 +13,8 @@ import { _IECDSAMetaTransactionContext } from './_IECDSAMetaTransactionContext.s abstract contract _ECDSAMetaTransactionContext is _IECDSAMetaTransactionContext, - _Context + _Context, + _TransientReentrancyGuard { using Bytes32 for bytes32; using Bytes32Builder for Bytes32Builder.Builder; @@ -68,7 +70,11 @@ abstract contract _ECDSAMetaTransactionContext is uint256 dataLength = msg.data.length; uint256 suffixLength = _calldataSuffixLength(); - if (dataLength >= suffixLength) { + // context is cached in transient storage, which is not cleared until the end of the transaction + // this enables the possibility of replay attacks within a single transaction which calls this contract multiple times + // therefore, all functions which use context must be nonReentrant, and the lock must be set before context is accessed + + if (dataLength >= suffixLength && _isReentrancyGuardLocked()) { // calldata is long enough that it might have a suffix // check transient storage to see if sender has been derived already @@ -101,14 +107,16 @@ abstract contract _ECDSAMetaTransactionContext is uint256 dataLength = msg.data.length; uint256 suffixLength = _calldataSuffixLength(); - if (dataLength >= suffixLength) { + // context is cached in transient storage, which is not cleared until the end of the transaction + // this enables the possibility of replay attacks within a single transaction which calls this contract multiple times + // therefore, all functions which use context must be nonReentrant, and the lock must be set before context is accessed + + if (dataLength >= suffixLength && _isReentrancyGuardLocked()) { // calldata is long enough that it might have a suffix // check transient storage to see if msgData split index has been derived already - uint256 split; - // unpack the msgDataIndex which is stored alongside msgSender - split = TRANSIENT_SLOT.read().toBuilder().popUint96(); + uint256 split = TRANSIENT_SLOT.read().toBuilder().popUint96(); if (split == 0) { // no msgData split index found in transient storage, so attempt to derive it from signature @@ -128,7 +136,7 @@ abstract contract _ECDSAMetaTransactionContext is /** * @inheritdoc _Context - * @dev this Context extension defines an address suffix with a length of 85 + * @dev this Context extension defines a suffix with a length of 85 */ function _calldataSuffixLength() internal @@ -187,4 +195,14 @@ abstract contract _ECDSAMetaTransactionContext is TRANSIENT_SLOT.write(builder._data); } + + /** + * @inheritdoc _TransientReentrancyGuard + * @dev clear the cached context to prevent replay attacks + */ + function _lockReentrancyGuard() internal virtual override { + TRANSIENT_SLOT.write(bytes32(0)); + TRANSIENT_SLOT.next().write(bytes32(0)); + super._lockReentrancyGuard(); + } } diff --git a/contracts/meta/_IECDSAMetaTransactionContext.sol b/contracts/meta/_IECDSAMetaTransactionContext.sol index dbf3702a..739f4c4f 100644 --- a/contracts/meta/_IECDSAMetaTransactionContext.sol +++ b/contracts/meta/_IECDSAMetaTransactionContext.sol @@ -3,6 +3,11 @@ pragma solidity ^0.8.24; import { _IERC5267 } from '../interfaces/_IERC5267.sol'; +import { _ITransientReentrancyGuard } from '../security/reentrancy_guard/_ITransientReentrancyGuard.sol'; import { _IContext } from './_IContext.sol'; -interface _IECDSAMetaTransactionContext is _IContext, _IERC5267 {} +interface _IECDSAMetaTransactionContext is + _IContext, + _ITransientReentrancyGuard, + _IERC5267 +{} From 272176d08fff486f8b61c81408d8ac6e7ebb77c0 Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Thu, 27 Mar 2025 19:00:14 -0600 Subject: [PATCH 36/39] add Slot clear functions --- contracts/data/Slot.sol | 20 ++++++++++++++++++++ contracts/test/SlotTest.sol | 11 ++++++++++- test/data/Slot.ts | 34 +++++++++++++++++++++++++++++++--- 3 files changed, 61 insertions(+), 4 deletions(-) diff --git a/contracts/data/Slot.sol b/contracts/data/Slot.sol index 39e3c9b9..ae11b518 100644 --- a/contracts/data/Slot.sol +++ b/contracts/data/Slot.sol @@ -202,6 +202,26 @@ library Slot { } } + /** + * @notice clearn contents of storage slot + * @param slot storage slot to clear + */ + function clear(StorageSlot slot) internal { + assembly { + sstore(slot, 0) + } + } + + /** + * @notice clearn contents of transient storage slot + * @param slot transient storage slot to clear + */ + function clear(TransientSlot slot) internal { + assembly { + tstore(slot, 0) + } + } + /** * @notice calculate the slot of an index of an array * @param slot array declaration slot where its length is stored diff --git a/contracts/test/SlotTest.sol b/contracts/test/SlotTest.sol index 1b896dbe..ea0dc1e9 100644 --- a/contracts/test/SlotTest.sol +++ b/contracts/test/SlotTest.sol @@ -5,11 +5,20 @@ pragma solidity ^0.8.24; import { Slot } from '../data/Slot.sol'; contract SlotTest { - function writeAndRead( + function transientWriteTest( Slot.TransientSlot slot, bytes32 input ) external returns (bytes32 output) { Slot.write(slot, input); output = Slot.read(slot); } + + function transientClearTest( + Slot.TransientSlot slot, + bytes32 input + ) external returns (bytes32 output) { + Slot.write(slot, input); + Slot.clear(slot); + output = Slot.read(slot); + } } diff --git a/test/data/Slot.ts b/test/data/Slot.ts index 8f0f1ada..eab82289 100644 --- a/test/data/Slot.ts +++ b/test/data/Slot.ts @@ -129,6 +129,21 @@ describe('Slot', () => { ); }); }); + + describe('#clear(uint256)', () => { + it('clears data from arbitrary storage slot', async () => { + const slot = seedToStorageSlot('solidstate.contracts.storage.Ownable'); + const data = ethers.zeroPadValue(deployer.address, 32); + + await instance.$write_Slot_StorageSlot(slot, data); + + await instance.$clear_Slot_StorageSlot(slot); + + expect(await instance.$read_Slot_StorageSlot.staticCall(slot)).to.equal( + ethers.ZeroHash, + ); + }); + }); }); describe('TransientSlot', () => { @@ -240,9 +255,22 @@ describe('Slot', () => { const slot = seedToStorageSlot('solidstate.contracts.storage.Ownable'); const data = ethers.zeroPadValue(deployer.address, 32); - expect(await testInstance.writeAndRead.staticCall(slot, data)).to.eq( - data, - ); + expect( + await testInstance.transientWriteTest.staticCall(slot, data), + ).to.eq(data); + }); + }); + + describe('#clear(uint256)', () => { + it('clears data from arbitrary transient slot', async () => { + const testInstance = await new SlotTest__factory(deployer).deploy(); + + const slot = seedToStorageSlot('solidstate.contracts.storage.Ownable'); + const data = ethers.zeroPadValue(deployer.address, 32); + + expect( + await testInstance.transientClearTest.staticCall(slot, data), + ).to.eq(ethers.ZeroHash); }); }); }); From c6a246b2060d6b2ed6f81d57ffc5accc78a1355f Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Thu, 27 Mar 2025 19:03:20 -0600 Subject: [PATCH 37/39] fix inconsistent test headers --- test/data/Slot.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/data/Slot.ts b/test/data/Slot.ts index eab82289..fd6c390b 100644 --- a/test/data/Slot.ts +++ b/test/data/Slot.ts @@ -96,7 +96,7 @@ describe('Slot', () => { }); }); - describe('#read(uint256)', () => { + describe('#read()', () => { it('reads bytes32 data from arbitrary storage slot', async () => { const slot = ethers.hexlify(ethers.randomBytes(32)); const data = ethers.ZeroHash; @@ -113,7 +113,7 @@ describe('Slot', () => { }); }); - describe('#write(uint256,bytes32)', () => { + describe('#write(bytes32)', () => { it('writes bytes32 data to arbitrary storage slot', async () => { const slot = seedToStorageSlot('solidstate.contracts.storage.Ownable'); const data = ethers.zeroPadValue(deployer.address, 32); @@ -130,7 +130,7 @@ describe('Slot', () => { }); }); - describe('#clear(uint256)', () => { + describe('#clear()', () => { it('clears data from arbitrary storage slot', async () => { const slot = seedToStorageSlot('solidstate.contracts.storage.Ownable'); const data = ethers.zeroPadValue(deployer.address, 32); @@ -225,7 +225,7 @@ describe('Slot', () => { }); }); - describe('#read(uint256)', () => { + describe('#read()', () => { it('reads bytes32 data from arbitrary transient slot', async () => { const slot = ethers.hexlify(ethers.randomBytes(32)); const data = ethers.ZeroHash; @@ -248,7 +248,7 @@ describe('Slot', () => { }); }); - describe('#write(uint256,bytes32)', () => { + describe('#write(bytes32)', () => { it('writes bytes32 data to arbitrary transient slot', async () => { const testInstance = await new SlotTest__factory(deployer).deploy(); @@ -261,7 +261,7 @@ describe('Slot', () => { }); }); - describe('#clear(uint256)', () => { + describe('#clear()', () => { it('clears data from arbitrary transient slot', async () => { const testInstance = await new SlotTest__factory(deployer).deploy(); From cdaed4b459289f027cf3fcb396f8fe838f2d5d81 Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Thu, 27 Mar 2025 19:04:54 -0600 Subject: [PATCH 38/39] use Slot clear function on context data, remove duplicate deletion --- contracts/meta/_ECDSAMetaTransactionContext.sol | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/contracts/meta/_ECDSAMetaTransactionContext.sol b/contracts/meta/_ECDSAMetaTransactionContext.sol index 896f94ec..00f70994 100644 --- a/contracts/meta/_ECDSAMetaTransactionContext.sol +++ b/contracts/meta/_ECDSAMetaTransactionContext.sol @@ -201,8 +201,7 @@ abstract contract _ECDSAMetaTransactionContext is * @dev clear the cached context to prevent replay attacks */ function _lockReentrancyGuard() internal virtual override { - TRANSIENT_SLOT.write(bytes32(0)); - TRANSIENT_SLOT.next().write(bytes32(0)); + TRANSIENT_SLOT.clear(); super._lockReentrancyGuard(); } } From 3ff058752e9df4237f620a3d0119a7326f703800 Mon Sep 17 00:00:00 2001 From: Nick Barry Date: Thu, 27 Mar 2025 19:16:12 -0600 Subject: [PATCH 39/39] connect clear functions to write functions internally --- contracts/data/Slot.sol | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/contracts/data/Slot.sol b/contracts/data/Slot.sol index ae11b518..3358d837 100644 --- a/contracts/data/Slot.sol +++ b/contracts/data/Slot.sol @@ -203,23 +203,19 @@ library Slot { } /** - * @notice clearn contents of storage slot + * @notice clear contents of storage slot * @param slot storage slot to clear */ function clear(StorageSlot slot) internal { - assembly { - sstore(slot, 0) - } + write(slot, bytes32(0)); } /** - * @notice clearn contents of transient storage slot + * @notice clear contents of transient storage slot * @param slot transient storage slot to clear */ function clear(TransientSlot slot) internal { - assembly { - tstore(slot, 0) - } + write(slot, bytes32(0)); } /**