Contract Name:
AuctionToken
Contract Source Code:
<i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: BSD-3-Clause-Clear
pragma solidity ^0.8.24;
import {FHE} from "@fhevm/solidity/lib/FHE.sol";
import {CoprocessorConfig} from "@fhevm/solidity/lib/Impl.sol";
/**
* @title ZamaConfig.
* @notice This library returns the FHEVM config for different networks
* with the contract addresses for (1) ACL, (2) CoprocessorAddress, (3) KMSVerifier,
* which are deployed & maintained by Zama.
*/
library ZamaConfig {
/// @notice Returned if the Zama protocol is not supported on the current chain
error ZamaProtocolUnsupported();
function getEthereumCoprocessorConfig() internal view returns (CoprocessorConfig memory config) {
if (block.chainid == 1) {
config = _getEthereumConfig();
} else if (block.chainid == 11155111) {
config = _getSepoliaConfig();
} else if (block.chainid == 31337) {
config = _getLocalConfig();
} else {
revert ZamaProtocolUnsupported();
}
}
function getConfidentialProtocolId() internal view returns (uint256) {
if (block.chainid == 1) {
return _getEthereumProtocolId();
} else if (block.chainid == 11155111) {
return _getSepoliaProtocolId();
} else if (block.chainid == 31337) {
return _getLocalProtocolId();
}
return 0;
}
/// @dev chainid == 1
function _getEthereumProtocolId() private pure returns (uint256) {
// Zama Ethereum protocol id is '1'
return 1;
}
/// @dev chainid == 1
function _getEthereumConfig() private pure returns (CoprocessorConfig memory) {
// The addresses below are placeholders and should be replaced with actual addresses
// once deployed on the Ethereum mainnet.
return
CoprocessorConfig({
ACLAddress: 0xcA2E8f1F656CD25C01F05d0b243Ab1ecd4a8ffb6,
CoprocessorAddress: 0xD82385dADa1ae3E969447f20A3164F6213100e75,
KMSVerifierAddress: 0x77627828a55156b04Ac0DC0eb30467f1a552BB03
});
}
/// @dev chainid == 11155111
function _getSepoliaProtocolId() private pure returns (uint256) {
// Zama Ethereum Sepolia protocol id is '10000 + Zama Ethereum protocol id'
return 10001;
}
/// @dev chainid == 11155111
function _getSepoliaConfig() private pure returns (CoprocessorConfig memory) {
return
CoprocessorConfig({
ACLAddress: 0xf0Ffdc93b7E186bC2f8CB3dAA75D86d1930A433D,
CoprocessorAddress: 0x92C920834Ec8941d2C77D188936E1f7A6f49c127,
KMSVerifierAddress: 0xbE0E383937d564D7FF0BC3b46c51f0bF8d5C311A
});
}
/// @dev chainid == 31337
function _getLocalProtocolId() private pure returns (uint256) {
return type(uint256).max;
}
function _getLocalConfig() private pure returns (CoprocessorConfig memory) {
return
CoprocessorConfig({
ACLAddress: 0x50157CFfD6bBFA2DECe204a89ec419c23ef5755D,
CoprocessorAddress: 0xe3a9105a3a932253A70F126eb1E3b589C643dD24,
KMSVerifierAddress: 0x901F8942346f7AB3a01F6D7613119Bca447Bb030
});
}
}
/**
* @title ZamaEthereumConfig.
* @dev This contract can be inherited by a contract wishing to use the FHEVM contracts provided by Zama
* on the Ethereum (mainnet) network (chainId = 1) or Sepolia (testnet) network (chainId = 11155111).
* Other providers may offer similar contracts deployed at different addresses.
* If you wish to use them, you should rely on the instructions from these providers.
*/
abstract contract ZamaEthereumConfig {
constructor() {
FHE.setCoprocessor(ZamaConfig.getEthereumCoprocessorConfig());
}
function confidentialProtocolId() public view returns (uint256) {
return ZamaConfig.getConfidentialProtocolId();
}
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: BSD-3-Clause-Clear
pragma solidity ^0.8.24;
import "./Impl.sol";
import {FheType} from "./FheType.sol";
import "encrypted-types/EncryptedTypes.sol";
/**
* @title IKMSVerifier
* @notice This interface contains the only function required from KMSVerifier.
*/
interface IKMSVerifier {
function verifyDecryptionEIP712KMSSignatures(
bytes32[] memory handlesList,
bytes memory decryptedResult,
bytes memory decryptionProof
) external returns (bool);
}
/**
* @title FHE
* @notice This library is the interaction point for all smart contract developers
* that interact with the FHEVM protocol.
*/
library FHE {
/// @notice Returned if the returned KMS signatures are not valid.
error InvalidKMSSignatures();
/// @notice Returned if the sender is not allowed to use the handle.
error SenderNotAllowedToUseHandle(bytes32 handle, address sender);
/// @notice This event is emitted when public decryption has been successfully verified.
event PublicDecryptionVerified(bytes32[] handlesList, bytes abiEncodedCleartexts);
/**
* @notice Sets the coprocessor addresses.
* @param coprocessorConfig Coprocessor config struct that contains contract addresses.
*/
function setCoprocessor(CoprocessorConfig memory coprocessorConfig) internal {
Impl.setCoprocessor(coprocessorConfig);
}
/**
* @dev Returns true if the encrypted integer is initialized and false otherwise.
*/
function isInitialized(ebool v) internal pure returns (bool) {
return ebool.unwrap(v) != 0;
}
/**
* @dev Returns true if the encrypted integer is initialized and false otherwise.
*/
function isInitialized(euint8 v) internal pure returns (bool) {
return euint8.unwrap(v) != 0;
}
/**
* @dev Returns true if the encrypted integer is initialized and false otherwise.
*/
function isInitialized(euint16 v) internal pure returns (bool) {
return euint16.unwrap(v) != 0;
}
/**
* @dev Returns true if the encrypted integer is initialized and false otherwise.
*/
function isInitialized(euint32 v) internal pure returns (bool) {
return euint32.unwrap(v) != 0;
}
/**
* @dev Returns true if the encrypted integer is initialized and false otherwise.
*/
function isInitialized(euint64 v) internal pure returns (bool) {
return euint64.unwrap(v) != 0;
}
/**
* @dev Returns true if the encrypted integer is initialized and false otherwise.
*/
function isInitialized(euint128 v) internal pure returns (bool) {
return euint128.unwrap(v) != 0;
}
/**
* @dev Returns true if the encrypted integer is initialized and false otherwise.
*/
function isInitialized(eaddress v) internal pure returns (bool) {
return eaddress.unwrap(v) != 0;
}
/**
* @dev Returns true if the encrypted integer is initialized and false otherwise.
*/
function isInitialized(euint256 v) internal pure returns (bool) {
return euint256.unwrap(v) != 0;
}
/**
* @dev Evaluates and(ebool a, ebool b) and returns the result.
*/
function and(ebool a, ebool b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEbool(false);
}
if (!isInitialized(b)) {
b = asEbool(false);
}
return ebool.wrap(Impl.and(ebool.unwrap(a), ebool.unwrap(b), false));
}
/**
* @dev Evaluates or(ebool a, ebool b) and returns the result.
*/
function or(ebool a, ebool b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEbool(false);
}
if (!isInitialized(b)) {
b = asEbool(false);
}
return ebool.wrap(Impl.or(ebool.unwrap(a), ebool.unwrap(b), false));
}
/**
* @dev Evaluates xor(ebool a, ebool b) and returns the result.
*/
function xor(ebool a, ebool b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEbool(false);
}
if (!isInitialized(b)) {
b = asEbool(false);
}
return ebool.wrap(Impl.xor(ebool.unwrap(a), ebool.unwrap(b), false));
}
/**
* @dev Evaluates eq(ebool a, ebool b) and returns the result.
*/
function eq(ebool a, ebool b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEbool(false);
}
if (!isInitialized(b)) {
b = asEbool(false);
}
return ebool.wrap(Impl.eq(ebool.unwrap(a), ebool.unwrap(b), false));
}
/**
* @dev Evaluates ne(ebool a, ebool b) and returns the result.
*/
function ne(ebool a, ebool b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEbool(false);
}
if (!isInitialized(b)) {
b = asEbool(false);
}
return ebool.wrap(Impl.ne(ebool.unwrap(a), ebool.unwrap(b), false));
}
/**
* @dev Evaluates add(euint8 a, euint8 b) and returns the result.
*/
function add(euint8 a, euint8 b) internal returns (euint8) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint8.wrap(Impl.add(euint8.unwrap(a), euint8.unwrap(b), false));
}
/**
* @dev Evaluates sub(euint8 a, euint8 b) and returns the result.
*/
function sub(euint8 a, euint8 b) internal returns (euint8) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint8.wrap(Impl.sub(euint8.unwrap(a), euint8.unwrap(b), false));
}
/**
* @dev Evaluates mul(euint8 a, euint8 b) and returns the result.
*/
function mul(euint8 a, euint8 b) internal returns (euint8) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint8.wrap(Impl.mul(euint8.unwrap(a), euint8.unwrap(b), false));
}
/**
* @dev Evaluates and(euint8 a, euint8 b) and returns the result.
*/
function and(euint8 a, euint8 b) internal returns (euint8) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint8.wrap(Impl.and(euint8.unwrap(a), euint8.unwrap(b), false));
}
/**
* @dev Evaluates or(euint8 a, euint8 b) and returns the result.
*/
function or(euint8 a, euint8 b) internal returns (euint8) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint8.wrap(Impl.or(euint8.unwrap(a), euint8.unwrap(b), false));
}
/**
* @dev Evaluates xor(euint8 a, euint8 b) and returns the result.
*/
function xor(euint8 a, euint8 b) internal returns (euint8) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint8.wrap(Impl.xor(euint8.unwrap(a), euint8.unwrap(b), false));
}
/**
* @dev Evaluates eq(euint8 a, euint8 b) and returns the result.
*/
function eq(euint8 a, euint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.eq(euint8.unwrap(a), euint8.unwrap(b), false));
}
/**
* @dev Evaluates ne(euint8 a, euint8 b) and returns the result.
*/
function ne(euint8 a, euint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.ne(euint8.unwrap(a), euint8.unwrap(b), false));
}
/**
* @dev Evaluates ge(euint8 a, euint8 b) and returns the result.
*/
function ge(euint8 a, euint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.ge(euint8.unwrap(a), euint8.unwrap(b), false));
}
/**
* @dev Evaluates gt(euint8 a, euint8 b) and returns the result.
*/
function gt(euint8 a, euint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.gt(euint8.unwrap(a), euint8.unwrap(b), false));
}
/**
* @dev Evaluates le(euint8 a, euint8 b) and returns the result.
*/
function le(euint8 a, euint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.le(euint8.unwrap(a), euint8.unwrap(b), false));
}
/**
* @dev Evaluates lt(euint8 a, euint8 b) and returns the result.
*/
function lt(euint8 a, euint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.lt(euint8.unwrap(a), euint8.unwrap(b), false));
}
/**
* @dev Evaluates min(euint8 a, euint8 b) and returns the result.
*/
function min(euint8 a, euint8 b) internal returns (euint8) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint8.wrap(Impl.min(euint8.unwrap(a), euint8.unwrap(b), false));
}
/**
* @dev Evaluates max(euint8 a, euint8 b) and returns the result.
*/
function max(euint8 a, euint8 b) internal returns (euint8) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint8.wrap(Impl.max(euint8.unwrap(a), euint8.unwrap(b), false));
}
/**
* @dev Evaluates add(euint8 a, euint16 b) and returns the result.
*/
function add(euint8 a, euint16 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint16.wrap(Impl.add(euint16.unwrap(asEuint16(a)), euint16.unwrap(b), false));
}
/**
* @dev Evaluates sub(euint8 a, euint16 b) and returns the result.
*/
function sub(euint8 a, euint16 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint16.wrap(Impl.sub(euint16.unwrap(asEuint16(a)), euint16.unwrap(b), false));
}
/**
* @dev Evaluates mul(euint8 a, euint16 b) and returns the result.
*/
function mul(euint8 a, euint16 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint16.wrap(Impl.mul(euint16.unwrap(asEuint16(a)), euint16.unwrap(b), false));
}
/**
* @dev Evaluates and(euint8 a, euint16 b) and returns the result.
*/
function and(euint8 a, euint16 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint16.wrap(Impl.and(euint16.unwrap(asEuint16(a)), euint16.unwrap(b), false));
}
/**
* @dev Evaluates or(euint8 a, euint16 b) and returns the result.
*/
function or(euint8 a, euint16 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint16.wrap(Impl.or(euint16.unwrap(asEuint16(a)), euint16.unwrap(b), false));
}
/**
* @dev Evaluates xor(euint8 a, euint16 b) and returns the result.
*/
function xor(euint8 a, euint16 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint16.wrap(Impl.xor(euint16.unwrap(asEuint16(a)), euint16.unwrap(b), false));
}
/**
* @dev Evaluates eq(euint8 a, euint16 b) and returns the result.
*/
function eq(euint8 a, euint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.eq(euint16.unwrap(asEuint16(a)), euint16.unwrap(b), false));
}
/**
* @dev Evaluates ne(euint8 a, euint16 b) and returns the result.
*/
function ne(euint8 a, euint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.ne(euint16.unwrap(asEuint16(a)), euint16.unwrap(b), false));
}
/**
* @dev Evaluates ge(euint8 a, euint16 b) and returns the result.
*/
function ge(euint8 a, euint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.ge(euint16.unwrap(asEuint16(a)), euint16.unwrap(b), false));
}
/**
* @dev Evaluates gt(euint8 a, euint16 b) and returns the result.
*/
function gt(euint8 a, euint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.gt(euint16.unwrap(asEuint16(a)), euint16.unwrap(b), false));
}
/**
* @dev Evaluates le(euint8 a, euint16 b) and returns the result.
*/
function le(euint8 a, euint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.le(euint16.unwrap(asEuint16(a)), euint16.unwrap(b), false));
}
/**
* @dev Evaluates lt(euint8 a, euint16 b) and returns the result.
*/
function lt(euint8 a, euint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.lt(euint16.unwrap(asEuint16(a)), euint16.unwrap(b), false));
}
/**
* @dev Evaluates min(euint8 a, euint16 b) and returns the result.
*/
function min(euint8 a, euint16 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint16.wrap(Impl.min(euint16.unwrap(asEuint16(a)), euint16.unwrap(b), false));
}
/**
* @dev Evaluates max(euint8 a, euint16 b) and returns the result.
*/
function max(euint8 a, euint16 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint16.wrap(Impl.max(euint16.unwrap(asEuint16(a)), euint16.unwrap(b), false));
}
/**
* @dev Evaluates add(euint8 a, euint32 b) and returns the result.
*/
function add(euint8 a, euint32 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint32.wrap(Impl.add(euint32.unwrap(asEuint32(a)), euint32.unwrap(b), false));
}
/**
* @dev Evaluates sub(euint8 a, euint32 b) and returns the result.
*/
function sub(euint8 a, euint32 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint32.wrap(Impl.sub(euint32.unwrap(asEuint32(a)), euint32.unwrap(b), false));
}
/**
* @dev Evaluates mul(euint8 a, euint32 b) and returns the result.
*/
function mul(euint8 a, euint32 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint32.wrap(Impl.mul(euint32.unwrap(asEuint32(a)), euint32.unwrap(b), false));
}
/**
* @dev Evaluates and(euint8 a, euint32 b) and returns the result.
*/
function and(euint8 a, euint32 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint32.wrap(Impl.and(euint32.unwrap(asEuint32(a)), euint32.unwrap(b), false));
}
/**
* @dev Evaluates or(euint8 a, euint32 b) and returns the result.
*/
function or(euint8 a, euint32 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint32.wrap(Impl.or(euint32.unwrap(asEuint32(a)), euint32.unwrap(b), false));
}
/**
* @dev Evaluates xor(euint8 a, euint32 b) and returns the result.
*/
function xor(euint8 a, euint32 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint32.wrap(Impl.xor(euint32.unwrap(asEuint32(a)), euint32.unwrap(b), false));
}
/**
* @dev Evaluates eq(euint8 a, euint32 b) and returns the result.
*/
function eq(euint8 a, euint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.eq(euint32.unwrap(asEuint32(a)), euint32.unwrap(b), false));
}
/**
* @dev Evaluates ne(euint8 a, euint32 b) and returns the result.
*/
function ne(euint8 a, euint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.ne(euint32.unwrap(asEuint32(a)), euint32.unwrap(b), false));
}
/**
* @dev Evaluates ge(euint8 a, euint32 b) and returns the result.
*/
function ge(euint8 a, euint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.ge(euint32.unwrap(asEuint32(a)), euint32.unwrap(b), false));
}
/**
* @dev Evaluates gt(euint8 a, euint32 b) and returns the result.
*/
function gt(euint8 a, euint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.gt(euint32.unwrap(asEuint32(a)), euint32.unwrap(b), false));
}
/**
* @dev Evaluates le(euint8 a, euint32 b) and returns the result.
*/
function le(euint8 a, euint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.le(euint32.unwrap(asEuint32(a)), euint32.unwrap(b), false));
}
/**
* @dev Evaluates lt(euint8 a, euint32 b) and returns the result.
*/
function lt(euint8 a, euint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.lt(euint32.unwrap(asEuint32(a)), euint32.unwrap(b), false));
}
/**
* @dev Evaluates min(euint8 a, euint32 b) and returns the result.
*/
function min(euint8 a, euint32 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint32.wrap(Impl.min(euint32.unwrap(asEuint32(a)), euint32.unwrap(b), false));
}
/**
* @dev Evaluates max(euint8 a, euint32 b) and returns the result.
*/
function max(euint8 a, euint32 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint32.wrap(Impl.max(euint32.unwrap(asEuint32(a)), euint32.unwrap(b), false));
}
/**
* @dev Evaluates add(euint8 a, euint64 b) and returns the result.
*/
function add(euint8 a, euint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.add(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates sub(euint8 a, euint64 b) and returns the result.
*/
function sub(euint8 a, euint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.sub(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates mul(euint8 a, euint64 b) and returns the result.
*/
function mul(euint8 a, euint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.mul(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates and(euint8 a, euint64 b) and returns the result.
*/
function and(euint8 a, euint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.and(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates or(euint8 a, euint64 b) and returns the result.
*/
function or(euint8 a, euint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.or(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates xor(euint8 a, euint64 b) and returns the result.
*/
function xor(euint8 a, euint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.xor(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates eq(euint8 a, euint64 b) and returns the result.
*/
function eq(euint8 a, euint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.eq(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates ne(euint8 a, euint64 b) and returns the result.
*/
function ne(euint8 a, euint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.ne(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates ge(euint8 a, euint64 b) and returns the result.
*/
function ge(euint8 a, euint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.ge(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates gt(euint8 a, euint64 b) and returns the result.
*/
function gt(euint8 a, euint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.gt(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates le(euint8 a, euint64 b) and returns the result.
*/
function le(euint8 a, euint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.le(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates lt(euint8 a, euint64 b) and returns the result.
*/
function lt(euint8 a, euint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.lt(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates min(euint8 a, euint64 b) and returns the result.
*/
function min(euint8 a, euint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.min(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates max(euint8 a, euint64 b) and returns the result.
*/
function max(euint8 a, euint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.max(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates add(euint8 a, euint128 b) and returns the result.
*/
function add(euint8 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.add(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates sub(euint8 a, euint128 b) and returns the result.
*/
function sub(euint8 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.sub(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates mul(euint8 a, euint128 b) and returns the result.
*/
function mul(euint8 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.mul(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates and(euint8 a, euint128 b) and returns the result.
*/
function and(euint8 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.and(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates or(euint8 a, euint128 b) and returns the result.
*/
function or(euint8 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.or(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates xor(euint8 a, euint128 b) and returns the result.
*/
function xor(euint8 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.xor(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates eq(euint8 a, euint128 b) and returns the result.
*/
function eq(euint8 a, euint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.eq(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates ne(euint8 a, euint128 b) and returns the result.
*/
function ne(euint8 a, euint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.ne(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates ge(euint8 a, euint128 b) and returns the result.
*/
function ge(euint8 a, euint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.ge(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates gt(euint8 a, euint128 b) and returns the result.
*/
function gt(euint8 a, euint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.gt(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates le(euint8 a, euint128 b) and returns the result.
*/
function le(euint8 a, euint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.le(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates lt(euint8 a, euint128 b) and returns the result.
*/
function lt(euint8 a, euint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.lt(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates min(euint8 a, euint128 b) and returns the result.
*/
function min(euint8 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.min(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates max(euint8 a, euint128 b) and returns the result.
*/
function max(euint8 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.max(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates and(euint8 a, euint256 b) and returns the result.
*/
function and(euint8 a, euint256 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint256(0);
}
return euint256.wrap(Impl.and(euint256.unwrap(asEuint256(a)), euint256.unwrap(b), false));
}
/**
* @dev Evaluates or(euint8 a, euint256 b) and returns the result.
*/
function or(euint8 a, euint256 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint256(0);
}
return euint256.wrap(Impl.or(euint256.unwrap(asEuint256(a)), euint256.unwrap(b), false));
}
/**
* @dev Evaluates xor(euint8 a, euint256 b) and returns the result.
*/
function xor(euint8 a, euint256 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint256(0);
}
return euint256.wrap(Impl.xor(euint256.unwrap(asEuint256(a)), euint256.unwrap(b), false));
}
/**
* @dev Evaluates eq(euint8 a, euint256 b) and returns the result.
*/
function eq(euint8 a, euint256 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint256(0);
}
return ebool.wrap(Impl.eq(euint256.unwrap(asEuint256(a)), euint256.unwrap(b), false));
}
/**
* @dev Evaluates ne(euint8 a, euint256 b) and returns the result.
*/
function ne(euint8 a, euint256 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint256(0);
}
return ebool.wrap(Impl.ne(euint256.unwrap(asEuint256(a)), euint256.unwrap(b), false));
}
/**
* @dev Evaluates add(euint16 a, euint8 b) and returns the result.
*/
function add(euint16 a, euint8 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint16.wrap(Impl.add(euint16.unwrap(a), euint16.unwrap(asEuint16(b)), false));
}
/**
* @dev Evaluates sub(euint16 a, euint8 b) and returns the result.
*/
function sub(euint16 a, euint8 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint16.wrap(Impl.sub(euint16.unwrap(a), euint16.unwrap(asEuint16(b)), false));
}
/**
* @dev Evaluates mul(euint16 a, euint8 b) and returns the result.
*/
function mul(euint16 a, euint8 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint16.wrap(Impl.mul(euint16.unwrap(a), euint16.unwrap(asEuint16(b)), false));
}
/**
* @dev Evaluates and(euint16 a, euint8 b) and returns the result.
*/
function and(euint16 a, euint8 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint16.wrap(Impl.and(euint16.unwrap(a), euint16.unwrap(asEuint16(b)), false));
}
/**
* @dev Evaluates or(euint16 a, euint8 b) and returns the result.
*/
function or(euint16 a, euint8 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint16.wrap(Impl.or(euint16.unwrap(a), euint16.unwrap(asEuint16(b)), false));
}
/**
* @dev Evaluates xor(euint16 a, euint8 b) and returns the result.
*/
function xor(euint16 a, euint8 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint16.wrap(Impl.xor(euint16.unwrap(a), euint16.unwrap(asEuint16(b)), false));
}
/**
* @dev Evaluates eq(euint16 a, euint8 b) and returns the result.
*/
function eq(euint16 a, euint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.eq(euint16.unwrap(a), euint16.unwrap(asEuint16(b)), false));
}
/**
* @dev Evaluates ne(euint16 a, euint8 b) and returns the result.
*/
function ne(euint16 a, euint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.ne(euint16.unwrap(a), euint16.unwrap(asEuint16(b)), false));
}
/**
* @dev Evaluates ge(euint16 a, euint8 b) and returns the result.
*/
function ge(euint16 a, euint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.ge(euint16.unwrap(a), euint16.unwrap(asEuint16(b)), false));
}
/**
* @dev Evaluates gt(euint16 a, euint8 b) and returns the result.
*/
function gt(euint16 a, euint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.gt(euint16.unwrap(a), euint16.unwrap(asEuint16(b)), false));
}
/**
* @dev Evaluates le(euint16 a, euint8 b) and returns the result.
*/
function le(euint16 a, euint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.le(euint16.unwrap(a), euint16.unwrap(asEuint16(b)), false));
}
/**
* @dev Evaluates lt(euint16 a, euint8 b) and returns the result.
*/
function lt(euint16 a, euint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.lt(euint16.unwrap(a), euint16.unwrap(asEuint16(b)), false));
}
/**
* @dev Evaluates min(euint16 a, euint8 b) and returns the result.
*/
function min(euint16 a, euint8 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint16.wrap(Impl.min(euint16.unwrap(a), euint16.unwrap(asEuint16(b)), false));
}
/**
* @dev Evaluates max(euint16 a, euint8 b) and returns the result.
*/
function max(euint16 a, euint8 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint16.wrap(Impl.max(euint16.unwrap(a), euint16.unwrap(asEuint16(b)), false));
}
/**
* @dev Evaluates add(euint16 a, euint16 b) and returns the result.
*/
function add(euint16 a, euint16 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint16.wrap(Impl.add(euint16.unwrap(a), euint16.unwrap(b), false));
}
/**
* @dev Evaluates sub(euint16 a, euint16 b) and returns the result.
*/
function sub(euint16 a, euint16 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint16.wrap(Impl.sub(euint16.unwrap(a), euint16.unwrap(b), false));
}
/**
* @dev Evaluates mul(euint16 a, euint16 b) and returns the result.
*/
function mul(euint16 a, euint16 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint16.wrap(Impl.mul(euint16.unwrap(a), euint16.unwrap(b), false));
}
/**
* @dev Evaluates and(euint16 a, euint16 b) and returns the result.
*/
function and(euint16 a, euint16 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint16.wrap(Impl.and(euint16.unwrap(a), euint16.unwrap(b), false));
}
/**
* @dev Evaluates or(euint16 a, euint16 b) and returns the result.
*/
function or(euint16 a, euint16 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint16.wrap(Impl.or(euint16.unwrap(a), euint16.unwrap(b), false));
}
/**
* @dev Evaluates xor(euint16 a, euint16 b) and returns the result.
*/
function xor(euint16 a, euint16 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint16.wrap(Impl.xor(euint16.unwrap(a), euint16.unwrap(b), false));
}
/**
* @dev Evaluates eq(euint16 a, euint16 b) and returns the result.
*/
function eq(euint16 a, euint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.eq(euint16.unwrap(a), euint16.unwrap(b), false));
}
/**
* @dev Evaluates ne(euint16 a, euint16 b) and returns the result.
*/
function ne(euint16 a, euint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.ne(euint16.unwrap(a), euint16.unwrap(b), false));
}
/**
* @dev Evaluates ge(euint16 a, euint16 b) and returns the result.
*/
function ge(euint16 a, euint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.ge(euint16.unwrap(a), euint16.unwrap(b), false));
}
/**
* @dev Evaluates gt(euint16 a, euint16 b) and returns the result.
*/
function gt(euint16 a, euint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.gt(euint16.unwrap(a), euint16.unwrap(b), false));
}
/**
* @dev Evaluates le(euint16 a, euint16 b) and returns the result.
*/
function le(euint16 a, euint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.le(euint16.unwrap(a), euint16.unwrap(b), false));
}
/**
* @dev Evaluates lt(euint16 a, euint16 b) and returns the result.
*/
function lt(euint16 a, euint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.lt(euint16.unwrap(a), euint16.unwrap(b), false));
}
/**
* @dev Evaluates min(euint16 a, euint16 b) and returns the result.
*/
function min(euint16 a, euint16 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint16.wrap(Impl.min(euint16.unwrap(a), euint16.unwrap(b), false));
}
/**
* @dev Evaluates max(euint16 a, euint16 b) and returns the result.
*/
function max(euint16 a, euint16 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint16.wrap(Impl.max(euint16.unwrap(a), euint16.unwrap(b), false));
}
/**
* @dev Evaluates add(euint16 a, euint32 b) and returns the result.
*/
function add(euint16 a, euint32 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint32.wrap(Impl.add(euint32.unwrap(asEuint32(a)), euint32.unwrap(b), false));
}
/**
* @dev Evaluates sub(euint16 a, euint32 b) and returns the result.
*/
function sub(euint16 a, euint32 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint32.wrap(Impl.sub(euint32.unwrap(asEuint32(a)), euint32.unwrap(b), false));
}
/**
* @dev Evaluates mul(euint16 a, euint32 b) and returns the result.
*/
function mul(euint16 a, euint32 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint32.wrap(Impl.mul(euint32.unwrap(asEuint32(a)), euint32.unwrap(b), false));
}
/**
* @dev Evaluates and(euint16 a, euint32 b) and returns the result.
*/
function and(euint16 a, euint32 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint32.wrap(Impl.and(euint32.unwrap(asEuint32(a)), euint32.unwrap(b), false));
}
/**
* @dev Evaluates or(euint16 a, euint32 b) and returns the result.
*/
function or(euint16 a, euint32 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint32.wrap(Impl.or(euint32.unwrap(asEuint32(a)), euint32.unwrap(b), false));
}
/**
* @dev Evaluates xor(euint16 a, euint32 b) and returns the result.
*/
function xor(euint16 a, euint32 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint32.wrap(Impl.xor(euint32.unwrap(asEuint32(a)), euint32.unwrap(b), false));
}
/**
* @dev Evaluates eq(euint16 a, euint32 b) and returns the result.
*/
function eq(euint16 a, euint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.eq(euint32.unwrap(asEuint32(a)), euint32.unwrap(b), false));
}
/**
* @dev Evaluates ne(euint16 a, euint32 b) and returns the result.
*/
function ne(euint16 a, euint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.ne(euint32.unwrap(asEuint32(a)), euint32.unwrap(b), false));
}
/**
* @dev Evaluates ge(euint16 a, euint32 b) and returns the result.
*/
function ge(euint16 a, euint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.ge(euint32.unwrap(asEuint32(a)), euint32.unwrap(b), false));
}
/**
* @dev Evaluates gt(euint16 a, euint32 b) and returns the result.
*/
function gt(euint16 a, euint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.gt(euint32.unwrap(asEuint32(a)), euint32.unwrap(b), false));
}
/**
* @dev Evaluates le(euint16 a, euint32 b) and returns the result.
*/
function le(euint16 a, euint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.le(euint32.unwrap(asEuint32(a)), euint32.unwrap(b), false));
}
/**
* @dev Evaluates lt(euint16 a, euint32 b) and returns the result.
*/
function lt(euint16 a, euint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.lt(euint32.unwrap(asEuint32(a)), euint32.unwrap(b), false));
}
/**
* @dev Evaluates min(euint16 a, euint32 b) and returns the result.
*/
function min(euint16 a, euint32 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint32.wrap(Impl.min(euint32.unwrap(asEuint32(a)), euint32.unwrap(b), false));
}
/**
* @dev Evaluates max(euint16 a, euint32 b) and returns the result.
*/
function max(euint16 a, euint32 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint32.wrap(Impl.max(euint32.unwrap(asEuint32(a)), euint32.unwrap(b), false));
}
/**
* @dev Evaluates add(euint16 a, euint64 b) and returns the result.
*/
function add(euint16 a, euint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.add(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates sub(euint16 a, euint64 b) and returns the result.
*/
function sub(euint16 a, euint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.sub(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates mul(euint16 a, euint64 b) and returns the result.
*/
function mul(euint16 a, euint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.mul(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates and(euint16 a, euint64 b) and returns the result.
*/
function and(euint16 a, euint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.and(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates or(euint16 a, euint64 b) and returns the result.
*/
function or(euint16 a, euint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.or(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates xor(euint16 a, euint64 b) and returns the result.
*/
function xor(euint16 a, euint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.xor(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates eq(euint16 a, euint64 b) and returns the result.
*/
function eq(euint16 a, euint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.eq(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates ne(euint16 a, euint64 b) and returns the result.
*/
function ne(euint16 a, euint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.ne(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates ge(euint16 a, euint64 b) and returns the result.
*/
function ge(euint16 a, euint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.ge(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates gt(euint16 a, euint64 b) and returns the result.
*/
function gt(euint16 a, euint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.gt(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates le(euint16 a, euint64 b) and returns the result.
*/
function le(euint16 a, euint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.le(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates lt(euint16 a, euint64 b) and returns the result.
*/
function lt(euint16 a, euint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.lt(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates min(euint16 a, euint64 b) and returns the result.
*/
function min(euint16 a, euint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.min(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates max(euint16 a, euint64 b) and returns the result.
*/
function max(euint16 a, euint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.max(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates add(euint16 a, euint128 b) and returns the result.
*/
function add(euint16 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.add(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates sub(euint16 a, euint128 b) and returns the result.
*/
function sub(euint16 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.sub(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates mul(euint16 a, euint128 b) and returns the result.
*/
function mul(euint16 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.mul(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates and(euint16 a, euint128 b) and returns the result.
*/
function and(euint16 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.and(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates or(euint16 a, euint128 b) and returns the result.
*/
function or(euint16 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.or(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates xor(euint16 a, euint128 b) and returns the result.
*/
function xor(euint16 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.xor(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates eq(euint16 a, euint128 b) and returns the result.
*/
function eq(euint16 a, euint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.eq(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates ne(euint16 a, euint128 b) and returns the result.
*/
function ne(euint16 a, euint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.ne(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates ge(euint16 a, euint128 b) and returns the result.
*/
function ge(euint16 a, euint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.ge(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates gt(euint16 a, euint128 b) and returns the result.
*/
function gt(euint16 a, euint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.gt(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates le(euint16 a, euint128 b) and returns the result.
*/
function le(euint16 a, euint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.le(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates lt(euint16 a, euint128 b) and returns the result.
*/
function lt(euint16 a, euint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.lt(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates min(euint16 a, euint128 b) and returns the result.
*/
function min(euint16 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.min(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates max(euint16 a, euint128 b) and returns the result.
*/
function max(euint16 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.max(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates and(euint16 a, euint256 b) and returns the result.
*/
function and(euint16 a, euint256 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint256(0);
}
return euint256.wrap(Impl.and(euint256.unwrap(asEuint256(a)), euint256.unwrap(b), false));
}
/**
* @dev Evaluates or(euint16 a, euint256 b) and returns the result.
*/
function or(euint16 a, euint256 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint256(0);
}
return euint256.wrap(Impl.or(euint256.unwrap(asEuint256(a)), euint256.unwrap(b), false));
}
/**
* @dev Evaluates xor(euint16 a, euint256 b) and returns the result.
*/
function xor(euint16 a, euint256 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint256(0);
}
return euint256.wrap(Impl.xor(euint256.unwrap(asEuint256(a)), euint256.unwrap(b), false));
}
/**
* @dev Evaluates eq(euint16 a, euint256 b) and returns the result.
*/
function eq(euint16 a, euint256 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint256(0);
}
return ebool.wrap(Impl.eq(euint256.unwrap(asEuint256(a)), euint256.unwrap(b), false));
}
/**
* @dev Evaluates ne(euint16 a, euint256 b) and returns the result.
*/
function ne(euint16 a, euint256 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint256(0);
}
return ebool.wrap(Impl.ne(euint256.unwrap(asEuint256(a)), euint256.unwrap(b), false));
}
/**
* @dev Evaluates add(euint32 a, euint8 b) and returns the result.
*/
function add(euint32 a, euint8 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint32.wrap(Impl.add(euint32.unwrap(a), euint32.unwrap(asEuint32(b)), false));
}
/**
* @dev Evaluates sub(euint32 a, euint8 b) and returns the result.
*/
function sub(euint32 a, euint8 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint32.wrap(Impl.sub(euint32.unwrap(a), euint32.unwrap(asEuint32(b)), false));
}
/**
* @dev Evaluates mul(euint32 a, euint8 b) and returns the result.
*/
function mul(euint32 a, euint8 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint32.wrap(Impl.mul(euint32.unwrap(a), euint32.unwrap(asEuint32(b)), false));
}
/**
* @dev Evaluates and(euint32 a, euint8 b) and returns the result.
*/
function and(euint32 a, euint8 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint32.wrap(Impl.and(euint32.unwrap(a), euint32.unwrap(asEuint32(b)), false));
}
/**
* @dev Evaluates or(euint32 a, euint8 b) and returns the result.
*/
function or(euint32 a, euint8 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint32.wrap(Impl.or(euint32.unwrap(a), euint32.unwrap(asEuint32(b)), false));
}
/**
* @dev Evaluates xor(euint32 a, euint8 b) and returns the result.
*/
function xor(euint32 a, euint8 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint32.wrap(Impl.xor(euint32.unwrap(a), euint32.unwrap(asEuint32(b)), false));
}
/**
* @dev Evaluates eq(euint32 a, euint8 b) and returns the result.
*/
function eq(euint32 a, euint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.eq(euint32.unwrap(a), euint32.unwrap(asEuint32(b)), false));
}
/**
* @dev Evaluates ne(euint32 a, euint8 b) and returns the result.
*/
function ne(euint32 a, euint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.ne(euint32.unwrap(a), euint32.unwrap(asEuint32(b)), false));
}
/**
* @dev Evaluates ge(euint32 a, euint8 b) and returns the result.
*/
function ge(euint32 a, euint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.ge(euint32.unwrap(a), euint32.unwrap(asEuint32(b)), false));
}
/**
* @dev Evaluates gt(euint32 a, euint8 b) and returns the result.
*/
function gt(euint32 a, euint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.gt(euint32.unwrap(a), euint32.unwrap(asEuint32(b)), false));
}
/**
* @dev Evaluates le(euint32 a, euint8 b) and returns the result.
*/
function le(euint32 a, euint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.le(euint32.unwrap(a), euint32.unwrap(asEuint32(b)), false));
}
/**
* @dev Evaluates lt(euint32 a, euint8 b) and returns the result.
*/
function lt(euint32 a, euint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.lt(euint32.unwrap(a), euint32.unwrap(asEuint32(b)), false));
}
/**
* @dev Evaluates min(euint32 a, euint8 b) and returns the result.
*/
function min(euint32 a, euint8 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint32.wrap(Impl.min(euint32.unwrap(a), euint32.unwrap(asEuint32(b)), false));
}
/**
* @dev Evaluates max(euint32 a, euint8 b) and returns the result.
*/
function max(euint32 a, euint8 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint32.wrap(Impl.max(euint32.unwrap(a), euint32.unwrap(asEuint32(b)), false));
}
/**
* @dev Evaluates add(euint32 a, euint16 b) and returns the result.
*/
function add(euint32 a, euint16 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint32.wrap(Impl.add(euint32.unwrap(a), euint32.unwrap(asEuint32(b)), false));
}
/**
* @dev Evaluates sub(euint32 a, euint16 b) and returns the result.
*/
function sub(euint32 a, euint16 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint32.wrap(Impl.sub(euint32.unwrap(a), euint32.unwrap(asEuint32(b)), false));
}
/**
* @dev Evaluates mul(euint32 a, euint16 b) and returns the result.
*/
function mul(euint32 a, euint16 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint32.wrap(Impl.mul(euint32.unwrap(a), euint32.unwrap(asEuint32(b)), false));
}
/**
* @dev Evaluates and(euint32 a, euint16 b) and returns the result.
*/
function and(euint32 a, euint16 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint32.wrap(Impl.and(euint32.unwrap(a), euint32.unwrap(asEuint32(b)), false));
}
/**
* @dev Evaluates or(euint32 a, euint16 b) and returns the result.
*/
function or(euint32 a, euint16 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint32.wrap(Impl.or(euint32.unwrap(a), euint32.unwrap(asEuint32(b)), false));
}
/**
* @dev Evaluates xor(euint32 a, euint16 b) and returns the result.
*/
function xor(euint32 a, euint16 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint32.wrap(Impl.xor(euint32.unwrap(a), euint32.unwrap(asEuint32(b)), false));
}
/**
* @dev Evaluates eq(euint32 a, euint16 b) and returns the result.
*/
function eq(euint32 a, euint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.eq(euint32.unwrap(a), euint32.unwrap(asEuint32(b)), false));
}
/**
* @dev Evaluates ne(euint32 a, euint16 b) and returns the result.
*/
function ne(euint32 a, euint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.ne(euint32.unwrap(a), euint32.unwrap(asEuint32(b)), false));
}
/**
* @dev Evaluates ge(euint32 a, euint16 b) and returns the result.
*/
function ge(euint32 a, euint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.ge(euint32.unwrap(a), euint32.unwrap(asEuint32(b)), false));
}
/**
* @dev Evaluates gt(euint32 a, euint16 b) and returns the result.
*/
function gt(euint32 a, euint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.gt(euint32.unwrap(a), euint32.unwrap(asEuint32(b)), false));
}
/**
* @dev Evaluates le(euint32 a, euint16 b) and returns the result.
*/
function le(euint32 a, euint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.le(euint32.unwrap(a), euint32.unwrap(asEuint32(b)), false));
}
/**
* @dev Evaluates lt(euint32 a, euint16 b) and returns the result.
*/
function lt(euint32 a, euint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.lt(euint32.unwrap(a), euint32.unwrap(asEuint32(b)), false));
}
/**
* @dev Evaluates min(euint32 a, euint16 b) and returns the result.
*/
function min(euint32 a, euint16 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint32.wrap(Impl.min(euint32.unwrap(a), euint32.unwrap(asEuint32(b)), false));
}
/**
* @dev Evaluates max(euint32 a, euint16 b) and returns the result.
*/
function max(euint32 a, euint16 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint32.wrap(Impl.max(euint32.unwrap(a), euint32.unwrap(asEuint32(b)), false));
}
/**
* @dev Evaluates add(euint32 a, euint32 b) and returns the result.
*/
function add(euint32 a, euint32 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint32.wrap(Impl.add(euint32.unwrap(a), euint32.unwrap(b), false));
}
/**
* @dev Evaluates sub(euint32 a, euint32 b) and returns the result.
*/
function sub(euint32 a, euint32 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint32.wrap(Impl.sub(euint32.unwrap(a), euint32.unwrap(b), false));
}
/**
* @dev Evaluates mul(euint32 a, euint32 b) and returns the result.
*/
function mul(euint32 a, euint32 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint32.wrap(Impl.mul(euint32.unwrap(a), euint32.unwrap(b), false));
}
/**
* @dev Evaluates and(euint32 a, euint32 b) and returns the result.
*/
function and(euint32 a, euint32 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint32.wrap(Impl.and(euint32.unwrap(a), euint32.unwrap(b), false));
}
/**
* @dev Evaluates or(euint32 a, euint32 b) and returns the result.
*/
function or(euint32 a, euint32 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint32.wrap(Impl.or(euint32.unwrap(a), euint32.unwrap(b), false));
}
/**
* @dev Evaluates xor(euint32 a, euint32 b) and returns the result.
*/
function xor(euint32 a, euint32 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint32.wrap(Impl.xor(euint32.unwrap(a), euint32.unwrap(b), false));
}
/**
* @dev Evaluates eq(euint32 a, euint32 b) and returns the result.
*/
function eq(euint32 a, euint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.eq(euint32.unwrap(a), euint32.unwrap(b), false));
}
/**
* @dev Evaluates ne(euint32 a, euint32 b) and returns the result.
*/
function ne(euint32 a, euint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.ne(euint32.unwrap(a), euint32.unwrap(b), false));
}
/**
* @dev Evaluates ge(euint32 a, euint32 b) and returns the result.
*/
function ge(euint32 a, euint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.ge(euint32.unwrap(a), euint32.unwrap(b), false));
}
/**
* @dev Evaluates gt(euint32 a, euint32 b) and returns the result.
*/
function gt(euint32 a, euint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.gt(euint32.unwrap(a), euint32.unwrap(b), false));
}
/**
* @dev Evaluates le(euint32 a, euint32 b) and returns the result.
*/
function le(euint32 a, euint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.le(euint32.unwrap(a), euint32.unwrap(b), false));
}
/**
* @dev Evaluates lt(euint32 a, euint32 b) and returns the result.
*/
function lt(euint32 a, euint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.lt(euint32.unwrap(a), euint32.unwrap(b), false));
}
/**
* @dev Evaluates min(euint32 a, euint32 b) and returns the result.
*/
function min(euint32 a, euint32 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint32.wrap(Impl.min(euint32.unwrap(a), euint32.unwrap(b), false));
}
/**
* @dev Evaluates max(euint32 a, euint32 b) and returns the result.
*/
function max(euint32 a, euint32 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint32.wrap(Impl.max(euint32.unwrap(a), euint32.unwrap(b), false));
}
/**
* @dev Evaluates add(euint32 a, euint64 b) and returns the result.
*/
function add(euint32 a, euint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.add(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates sub(euint32 a, euint64 b) and returns the result.
*/
function sub(euint32 a, euint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.sub(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates mul(euint32 a, euint64 b) and returns the result.
*/
function mul(euint32 a, euint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.mul(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates and(euint32 a, euint64 b) and returns the result.
*/
function and(euint32 a, euint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.and(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates or(euint32 a, euint64 b) and returns the result.
*/
function or(euint32 a, euint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.or(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates xor(euint32 a, euint64 b) and returns the result.
*/
function xor(euint32 a, euint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.xor(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates eq(euint32 a, euint64 b) and returns the result.
*/
function eq(euint32 a, euint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.eq(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates ne(euint32 a, euint64 b) and returns the result.
*/
function ne(euint32 a, euint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.ne(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates ge(euint32 a, euint64 b) and returns the result.
*/
function ge(euint32 a, euint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.ge(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates gt(euint32 a, euint64 b) and returns the result.
*/
function gt(euint32 a, euint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.gt(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates le(euint32 a, euint64 b) and returns the result.
*/
function le(euint32 a, euint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.le(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates lt(euint32 a, euint64 b) and returns the result.
*/
function lt(euint32 a, euint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.lt(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates min(euint32 a, euint64 b) and returns the result.
*/
function min(euint32 a, euint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.min(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates max(euint32 a, euint64 b) and returns the result.
*/
function max(euint32 a, euint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.max(euint64.unwrap(asEuint64(a)), euint64.unwrap(b), false));
}
/**
* @dev Evaluates add(euint32 a, euint128 b) and returns the result.
*/
function add(euint32 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.add(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates sub(euint32 a, euint128 b) and returns the result.
*/
function sub(euint32 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.sub(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates mul(euint32 a, euint128 b) and returns the result.
*/
function mul(euint32 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.mul(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates and(euint32 a, euint128 b) and returns the result.
*/
function and(euint32 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.and(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates or(euint32 a, euint128 b) and returns the result.
*/
function or(euint32 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.or(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates xor(euint32 a, euint128 b) and returns the result.
*/
function xor(euint32 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.xor(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates eq(euint32 a, euint128 b) and returns the result.
*/
function eq(euint32 a, euint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.eq(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates ne(euint32 a, euint128 b) and returns the result.
*/
function ne(euint32 a, euint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.ne(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates ge(euint32 a, euint128 b) and returns the result.
*/
function ge(euint32 a, euint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.ge(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates gt(euint32 a, euint128 b) and returns the result.
*/
function gt(euint32 a, euint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.gt(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates le(euint32 a, euint128 b) and returns the result.
*/
function le(euint32 a, euint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.le(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates lt(euint32 a, euint128 b) and returns the result.
*/
function lt(euint32 a, euint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.lt(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates min(euint32 a, euint128 b) and returns the result.
*/
function min(euint32 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.min(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates max(euint32 a, euint128 b) and returns the result.
*/
function max(euint32 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.max(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates and(euint32 a, euint256 b) and returns the result.
*/
function and(euint32 a, euint256 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint256(0);
}
return euint256.wrap(Impl.and(euint256.unwrap(asEuint256(a)), euint256.unwrap(b), false));
}
/**
* @dev Evaluates or(euint32 a, euint256 b) and returns the result.
*/
function or(euint32 a, euint256 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint256(0);
}
return euint256.wrap(Impl.or(euint256.unwrap(asEuint256(a)), euint256.unwrap(b), false));
}
/**
* @dev Evaluates xor(euint32 a, euint256 b) and returns the result.
*/
function xor(euint32 a, euint256 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint256(0);
}
return euint256.wrap(Impl.xor(euint256.unwrap(asEuint256(a)), euint256.unwrap(b), false));
}
/**
* @dev Evaluates eq(euint32 a, euint256 b) and returns the result.
*/
function eq(euint32 a, euint256 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint256(0);
}
return ebool.wrap(Impl.eq(euint256.unwrap(asEuint256(a)), euint256.unwrap(b), false));
}
/**
* @dev Evaluates ne(euint32 a, euint256 b) and returns the result.
*/
function ne(euint32 a, euint256 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint256(0);
}
return ebool.wrap(Impl.ne(euint256.unwrap(asEuint256(a)), euint256.unwrap(b), false));
}
/**
* @dev Evaluates add(euint64 a, euint8 b) and returns the result.
*/
function add(euint64 a, euint8 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint64.wrap(Impl.add(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates sub(euint64 a, euint8 b) and returns the result.
*/
function sub(euint64 a, euint8 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint64.wrap(Impl.sub(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates mul(euint64 a, euint8 b) and returns the result.
*/
function mul(euint64 a, euint8 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint64.wrap(Impl.mul(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates and(euint64 a, euint8 b) and returns the result.
*/
function and(euint64 a, euint8 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint64.wrap(Impl.and(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates or(euint64 a, euint8 b) and returns the result.
*/
function or(euint64 a, euint8 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint64.wrap(Impl.or(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates xor(euint64 a, euint8 b) and returns the result.
*/
function xor(euint64 a, euint8 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint64.wrap(Impl.xor(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates eq(euint64 a, euint8 b) and returns the result.
*/
function eq(euint64 a, euint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.eq(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates ne(euint64 a, euint8 b) and returns the result.
*/
function ne(euint64 a, euint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.ne(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates ge(euint64 a, euint8 b) and returns the result.
*/
function ge(euint64 a, euint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.ge(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates gt(euint64 a, euint8 b) and returns the result.
*/
function gt(euint64 a, euint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.gt(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates le(euint64 a, euint8 b) and returns the result.
*/
function le(euint64 a, euint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.le(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates lt(euint64 a, euint8 b) and returns the result.
*/
function lt(euint64 a, euint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.lt(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates min(euint64 a, euint8 b) and returns the result.
*/
function min(euint64 a, euint8 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint64.wrap(Impl.min(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates max(euint64 a, euint8 b) and returns the result.
*/
function max(euint64 a, euint8 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint64.wrap(Impl.max(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates add(euint64 a, euint16 b) and returns the result.
*/
function add(euint64 a, euint16 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint64.wrap(Impl.add(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates sub(euint64 a, euint16 b) and returns the result.
*/
function sub(euint64 a, euint16 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint64.wrap(Impl.sub(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates mul(euint64 a, euint16 b) and returns the result.
*/
function mul(euint64 a, euint16 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint64.wrap(Impl.mul(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates and(euint64 a, euint16 b) and returns the result.
*/
function and(euint64 a, euint16 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint64.wrap(Impl.and(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates or(euint64 a, euint16 b) and returns the result.
*/
function or(euint64 a, euint16 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint64.wrap(Impl.or(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates xor(euint64 a, euint16 b) and returns the result.
*/
function xor(euint64 a, euint16 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint64.wrap(Impl.xor(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates eq(euint64 a, euint16 b) and returns the result.
*/
function eq(euint64 a, euint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.eq(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates ne(euint64 a, euint16 b) and returns the result.
*/
function ne(euint64 a, euint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.ne(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates ge(euint64 a, euint16 b) and returns the result.
*/
function ge(euint64 a, euint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.ge(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates gt(euint64 a, euint16 b) and returns the result.
*/
function gt(euint64 a, euint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.gt(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates le(euint64 a, euint16 b) and returns the result.
*/
function le(euint64 a, euint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.le(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates lt(euint64 a, euint16 b) and returns the result.
*/
function lt(euint64 a, euint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.lt(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates min(euint64 a, euint16 b) and returns the result.
*/
function min(euint64 a, euint16 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint64.wrap(Impl.min(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates max(euint64 a, euint16 b) and returns the result.
*/
function max(euint64 a, euint16 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint64.wrap(Impl.max(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates add(euint64 a, euint32 b) and returns the result.
*/
function add(euint64 a, euint32 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint64.wrap(Impl.add(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates sub(euint64 a, euint32 b) and returns the result.
*/
function sub(euint64 a, euint32 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint64.wrap(Impl.sub(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates mul(euint64 a, euint32 b) and returns the result.
*/
function mul(euint64 a, euint32 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint64.wrap(Impl.mul(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates and(euint64 a, euint32 b) and returns the result.
*/
function and(euint64 a, euint32 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint64.wrap(Impl.and(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates or(euint64 a, euint32 b) and returns the result.
*/
function or(euint64 a, euint32 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint64.wrap(Impl.or(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates xor(euint64 a, euint32 b) and returns the result.
*/
function xor(euint64 a, euint32 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint64.wrap(Impl.xor(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates eq(euint64 a, euint32 b) and returns the result.
*/
function eq(euint64 a, euint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.eq(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates ne(euint64 a, euint32 b) and returns the result.
*/
function ne(euint64 a, euint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.ne(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates ge(euint64 a, euint32 b) and returns the result.
*/
function ge(euint64 a, euint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.ge(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates gt(euint64 a, euint32 b) and returns the result.
*/
function gt(euint64 a, euint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.gt(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates le(euint64 a, euint32 b) and returns the result.
*/
function le(euint64 a, euint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.le(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates lt(euint64 a, euint32 b) and returns the result.
*/
function lt(euint64 a, euint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.lt(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates min(euint64 a, euint32 b) and returns the result.
*/
function min(euint64 a, euint32 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint64.wrap(Impl.min(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates max(euint64 a, euint32 b) and returns the result.
*/
function max(euint64 a, euint32 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint64.wrap(Impl.max(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates add(euint64 a, euint64 b) and returns the result.
*/
function add(euint64 a, euint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.add(euint64.unwrap(a), euint64.unwrap(b), false));
}
/**
* @dev Evaluates sub(euint64 a, euint64 b) and returns the result.
*/
function sub(euint64 a, euint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.sub(euint64.unwrap(a), euint64.unwrap(b), false));
}
/**
* @dev Evaluates mul(euint64 a, euint64 b) and returns the result.
*/
function mul(euint64 a, euint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.mul(euint64.unwrap(a), euint64.unwrap(b), false));
}
/**
* @dev Evaluates and(euint64 a, euint64 b) and returns the result.
*/
function and(euint64 a, euint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.and(euint64.unwrap(a), euint64.unwrap(b), false));
}
/**
* @dev Evaluates or(euint64 a, euint64 b) and returns the result.
*/
function or(euint64 a, euint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.or(euint64.unwrap(a), euint64.unwrap(b), false));
}
/**
* @dev Evaluates xor(euint64 a, euint64 b) and returns the result.
*/
function xor(euint64 a, euint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.xor(euint64.unwrap(a), euint64.unwrap(b), false));
}
/**
* @dev Evaluates eq(euint64 a, euint64 b) and returns the result.
*/
function eq(euint64 a, euint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.eq(euint64.unwrap(a), euint64.unwrap(b), false));
}
/**
* @dev Evaluates ne(euint64 a, euint64 b) and returns the result.
*/
function ne(euint64 a, euint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.ne(euint64.unwrap(a), euint64.unwrap(b), false));
}
/**
* @dev Evaluates ge(euint64 a, euint64 b) and returns the result.
*/
function ge(euint64 a, euint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.ge(euint64.unwrap(a), euint64.unwrap(b), false));
}
/**
* @dev Evaluates gt(euint64 a, euint64 b) and returns the result.
*/
function gt(euint64 a, euint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.gt(euint64.unwrap(a), euint64.unwrap(b), false));
}
/**
* @dev Evaluates le(euint64 a, euint64 b) and returns the result.
*/
function le(euint64 a, euint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.le(euint64.unwrap(a), euint64.unwrap(b), false));
}
/**
* @dev Evaluates lt(euint64 a, euint64 b) and returns the result.
*/
function lt(euint64 a, euint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.lt(euint64.unwrap(a), euint64.unwrap(b), false));
}
/**
* @dev Evaluates min(euint64 a, euint64 b) and returns the result.
*/
function min(euint64 a, euint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.min(euint64.unwrap(a), euint64.unwrap(b), false));
}
/**
* @dev Evaluates max(euint64 a, euint64 b) and returns the result.
*/
function max(euint64 a, euint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.max(euint64.unwrap(a), euint64.unwrap(b), false));
}
/**
* @dev Evaluates add(euint64 a, euint128 b) and returns the result.
*/
function add(euint64 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.add(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates sub(euint64 a, euint128 b) and returns the result.
*/
function sub(euint64 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.sub(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates mul(euint64 a, euint128 b) and returns the result.
*/
function mul(euint64 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.mul(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates and(euint64 a, euint128 b) and returns the result.
*/
function and(euint64 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.and(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates or(euint64 a, euint128 b) and returns the result.
*/
function or(euint64 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.or(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates xor(euint64 a, euint128 b) and returns the result.
*/
function xor(euint64 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.xor(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates eq(euint64 a, euint128 b) and returns the result.
*/
function eq(euint64 a, euint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.eq(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates ne(euint64 a, euint128 b) and returns the result.
*/
function ne(euint64 a, euint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.ne(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates ge(euint64 a, euint128 b) and returns the result.
*/
function ge(euint64 a, euint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.ge(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates gt(euint64 a, euint128 b) and returns the result.
*/
function gt(euint64 a, euint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.gt(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates le(euint64 a, euint128 b) and returns the result.
*/
function le(euint64 a, euint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.le(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates lt(euint64 a, euint128 b) and returns the result.
*/
function lt(euint64 a, euint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.lt(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates min(euint64 a, euint128 b) and returns the result.
*/
function min(euint64 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.min(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates max(euint64 a, euint128 b) and returns the result.
*/
function max(euint64 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.max(euint128.unwrap(asEuint128(a)), euint128.unwrap(b), false));
}
/**
* @dev Evaluates and(euint64 a, euint256 b) and returns the result.
*/
function and(euint64 a, euint256 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint256(0);
}
return euint256.wrap(Impl.and(euint256.unwrap(asEuint256(a)), euint256.unwrap(b), false));
}
/**
* @dev Evaluates or(euint64 a, euint256 b) and returns the result.
*/
function or(euint64 a, euint256 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint256(0);
}
return euint256.wrap(Impl.or(euint256.unwrap(asEuint256(a)), euint256.unwrap(b), false));
}
/**
* @dev Evaluates xor(euint64 a, euint256 b) and returns the result.
*/
function xor(euint64 a, euint256 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint256(0);
}
return euint256.wrap(Impl.xor(euint256.unwrap(asEuint256(a)), euint256.unwrap(b), false));
}
/**
* @dev Evaluates eq(euint64 a, euint256 b) and returns the result.
*/
function eq(euint64 a, euint256 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint256(0);
}
return ebool.wrap(Impl.eq(euint256.unwrap(asEuint256(a)), euint256.unwrap(b), false));
}
/**
* @dev Evaluates ne(euint64 a, euint256 b) and returns the result.
*/
function ne(euint64 a, euint256 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint256(0);
}
return ebool.wrap(Impl.ne(euint256.unwrap(asEuint256(a)), euint256.unwrap(b), false));
}
/**
* @dev Evaluates add(euint128 a, euint8 b) and returns the result.
*/
function add(euint128 a, euint8 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint128.wrap(Impl.add(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates sub(euint128 a, euint8 b) and returns the result.
*/
function sub(euint128 a, euint8 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint128.wrap(Impl.sub(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates mul(euint128 a, euint8 b) and returns the result.
*/
function mul(euint128 a, euint8 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint128.wrap(Impl.mul(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates and(euint128 a, euint8 b) and returns the result.
*/
function and(euint128 a, euint8 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint128.wrap(Impl.and(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates or(euint128 a, euint8 b) and returns the result.
*/
function or(euint128 a, euint8 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint128.wrap(Impl.or(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates xor(euint128 a, euint8 b) and returns the result.
*/
function xor(euint128 a, euint8 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint128.wrap(Impl.xor(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates eq(euint128 a, euint8 b) and returns the result.
*/
function eq(euint128 a, euint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.eq(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates ne(euint128 a, euint8 b) and returns the result.
*/
function ne(euint128 a, euint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.ne(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates ge(euint128 a, euint8 b) and returns the result.
*/
function ge(euint128 a, euint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.ge(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates gt(euint128 a, euint8 b) and returns the result.
*/
function gt(euint128 a, euint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.gt(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates le(euint128 a, euint8 b) and returns the result.
*/
function le(euint128 a, euint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.le(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates lt(euint128 a, euint8 b) and returns the result.
*/
function lt(euint128 a, euint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.lt(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates min(euint128 a, euint8 b) and returns the result.
*/
function min(euint128 a, euint8 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint128.wrap(Impl.min(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates max(euint128 a, euint8 b) and returns the result.
*/
function max(euint128 a, euint8 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint128.wrap(Impl.max(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates add(euint128 a, euint16 b) and returns the result.
*/
function add(euint128 a, euint16 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint128.wrap(Impl.add(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates sub(euint128 a, euint16 b) and returns the result.
*/
function sub(euint128 a, euint16 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint128.wrap(Impl.sub(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates mul(euint128 a, euint16 b) and returns the result.
*/
function mul(euint128 a, euint16 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint128.wrap(Impl.mul(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates and(euint128 a, euint16 b) and returns the result.
*/
function and(euint128 a, euint16 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint128.wrap(Impl.and(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates or(euint128 a, euint16 b) and returns the result.
*/
function or(euint128 a, euint16 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint128.wrap(Impl.or(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates xor(euint128 a, euint16 b) and returns the result.
*/
function xor(euint128 a, euint16 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint128.wrap(Impl.xor(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates eq(euint128 a, euint16 b) and returns the result.
*/
function eq(euint128 a, euint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.eq(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates ne(euint128 a, euint16 b) and returns the result.
*/
function ne(euint128 a, euint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.ne(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates ge(euint128 a, euint16 b) and returns the result.
*/
function ge(euint128 a, euint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.ge(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates gt(euint128 a, euint16 b) and returns the result.
*/
function gt(euint128 a, euint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.gt(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates le(euint128 a, euint16 b) and returns the result.
*/
function le(euint128 a, euint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.le(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates lt(euint128 a, euint16 b) and returns the result.
*/
function lt(euint128 a, euint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.lt(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates min(euint128 a, euint16 b) and returns the result.
*/
function min(euint128 a, euint16 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint128.wrap(Impl.min(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates max(euint128 a, euint16 b) and returns the result.
*/
function max(euint128 a, euint16 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint128.wrap(Impl.max(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates add(euint128 a, euint32 b) and returns the result.
*/
function add(euint128 a, euint32 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint128.wrap(Impl.add(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates sub(euint128 a, euint32 b) and returns the result.
*/
function sub(euint128 a, euint32 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint128.wrap(Impl.sub(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates mul(euint128 a, euint32 b) and returns the result.
*/
function mul(euint128 a, euint32 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint128.wrap(Impl.mul(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates and(euint128 a, euint32 b) and returns the result.
*/
function and(euint128 a, euint32 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint128.wrap(Impl.and(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates or(euint128 a, euint32 b) and returns the result.
*/
function or(euint128 a, euint32 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint128.wrap(Impl.or(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates xor(euint128 a, euint32 b) and returns the result.
*/
function xor(euint128 a, euint32 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint128.wrap(Impl.xor(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates eq(euint128 a, euint32 b) and returns the result.
*/
function eq(euint128 a, euint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.eq(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates ne(euint128 a, euint32 b) and returns the result.
*/
function ne(euint128 a, euint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.ne(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates ge(euint128 a, euint32 b) and returns the result.
*/
function ge(euint128 a, euint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.ge(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates gt(euint128 a, euint32 b) and returns the result.
*/
function gt(euint128 a, euint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.gt(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates le(euint128 a, euint32 b) and returns the result.
*/
function le(euint128 a, euint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.le(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates lt(euint128 a, euint32 b) and returns the result.
*/
function lt(euint128 a, euint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.lt(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates min(euint128 a, euint32 b) and returns the result.
*/
function min(euint128 a, euint32 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint128.wrap(Impl.min(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates max(euint128 a, euint32 b) and returns the result.
*/
function max(euint128 a, euint32 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint128.wrap(Impl.max(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates add(euint128 a, euint64 b) and returns the result.
*/
function add(euint128 a, euint64 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint128.wrap(Impl.add(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates sub(euint128 a, euint64 b) and returns the result.
*/
function sub(euint128 a, euint64 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint128.wrap(Impl.sub(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates mul(euint128 a, euint64 b) and returns the result.
*/
function mul(euint128 a, euint64 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint128.wrap(Impl.mul(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates and(euint128 a, euint64 b) and returns the result.
*/
function and(euint128 a, euint64 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint128.wrap(Impl.and(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates or(euint128 a, euint64 b) and returns the result.
*/
function or(euint128 a, euint64 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint128.wrap(Impl.or(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates xor(euint128 a, euint64 b) and returns the result.
*/
function xor(euint128 a, euint64 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint128.wrap(Impl.xor(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates eq(euint128 a, euint64 b) and returns the result.
*/
function eq(euint128 a, euint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.eq(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates ne(euint128 a, euint64 b) and returns the result.
*/
function ne(euint128 a, euint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.ne(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates ge(euint128 a, euint64 b) and returns the result.
*/
function ge(euint128 a, euint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.ge(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates gt(euint128 a, euint64 b) and returns the result.
*/
function gt(euint128 a, euint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.gt(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates le(euint128 a, euint64 b) and returns the result.
*/
function le(euint128 a, euint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.le(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates lt(euint128 a, euint64 b) and returns the result.
*/
function lt(euint128 a, euint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.lt(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates min(euint128 a, euint64 b) and returns the result.
*/
function min(euint128 a, euint64 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint128.wrap(Impl.min(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates max(euint128 a, euint64 b) and returns the result.
*/
function max(euint128 a, euint64 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint128.wrap(Impl.max(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates add(euint128 a, euint128 b) and returns the result.
*/
function add(euint128 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.add(euint128.unwrap(a), euint128.unwrap(b), false));
}
/**
* @dev Evaluates sub(euint128 a, euint128 b) and returns the result.
*/
function sub(euint128 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.sub(euint128.unwrap(a), euint128.unwrap(b), false));
}
/**
* @dev Evaluates mul(euint128 a, euint128 b) and returns the result.
*/
function mul(euint128 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.mul(euint128.unwrap(a), euint128.unwrap(b), false));
}
/**
* @dev Evaluates and(euint128 a, euint128 b) and returns the result.
*/
function and(euint128 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.and(euint128.unwrap(a), euint128.unwrap(b), false));
}
/**
* @dev Evaluates or(euint128 a, euint128 b) and returns the result.
*/
function or(euint128 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.or(euint128.unwrap(a), euint128.unwrap(b), false));
}
/**
* @dev Evaluates xor(euint128 a, euint128 b) and returns the result.
*/
function xor(euint128 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.xor(euint128.unwrap(a), euint128.unwrap(b), false));
}
/**
* @dev Evaluates eq(euint128 a, euint128 b) and returns the result.
*/
function eq(euint128 a, euint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.eq(euint128.unwrap(a), euint128.unwrap(b), false));
}
/**
* @dev Evaluates ne(euint128 a, euint128 b) and returns the result.
*/
function ne(euint128 a, euint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.ne(euint128.unwrap(a), euint128.unwrap(b), false));
}
/**
* @dev Evaluates ge(euint128 a, euint128 b) and returns the result.
*/
function ge(euint128 a, euint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.ge(euint128.unwrap(a), euint128.unwrap(b), false));
}
/**
* @dev Evaluates gt(euint128 a, euint128 b) and returns the result.
*/
function gt(euint128 a, euint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.gt(euint128.unwrap(a), euint128.unwrap(b), false));
}
/**
* @dev Evaluates le(euint128 a, euint128 b) and returns the result.
*/
function le(euint128 a, euint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.le(euint128.unwrap(a), euint128.unwrap(b), false));
}
/**
* @dev Evaluates lt(euint128 a, euint128 b) and returns the result.
*/
function lt(euint128 a, euint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.lt(euint128.unwrap(a), euint128.unwrap(b), false));
}
/**
* @dev Evaluates min(euint128 a, euint128 b) and returns the result.
*/
function min(euint128 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.min(euint128.unwrap(a), euint128.unwrap(b), false));
}
/**
* @dev Evaluates max(euint128 a, euint128 b) and returns the result.
*/
function max(euint128 a, euint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.max(euint128.unwrap(a), euint128.unwrap(b), false));
}
/**
* @dev Evaluates and(euint128 a, euint256 b) and returns the result.
*/
function and(euint128 a, euint256 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint256(0);
}
return euint256.wrap(Impl.and(euint256.unwrap(asEuint256(a)), euint256.unwrap(b), false));
}
/**
* @dev Evaluates or(euint128 a, euint256 b) and returns the result.
*/
function or(euint128 a, euint256 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint256(0);
}
return euint256.wrap(Impl.or(euint256.unwrap(asEuint256(a)), euint256.unwrap(b), false));
}
/**
* @dev Evaluates xor(euint128 a, euint256 b) and returns the result.
*/
function xor(euint128 a, euint256 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint256(0);
}
return euint256.wrap(Impl.xor(euint256.unwrap(asEuint256(a)), euint256.unwrap(b), false));
}
/**
* @dev Evaluates eq(euint128 a, euint256 b) and returns the result.
*/
function eq(euint128 a, euint256 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint256(0);
}
return ebool.wrap(Impl.eq(euint256.unwrap(asEuint256(a)), euint256.unwrap(b), false));
}
/**
* @dev Evaluates ne(euint128 a, euint256 b) and returns the result.
*/
function ne(euint128 a, euint256 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint256(0);
}
return ebool.wrap(Impl.ne(euint256.unwrap(asEuint256(a)), euint256.unwrap(b), false));
}
/**
* @dev Evaluates eq(eaddress a, eaddress b) and returns the result.
*/
function eq(eaddress a, eaddress b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEaddress(address(0));
}
if (!isInitialized(b)) {
b = asEaddress(address(0));
}
return ebool.wrap(Impl.eq(eaddress.unwrap(a), eaddress.unwrap(b), false));
}
/**
* @dev Evaluates ne(eaddress a, eaddress b) and returns the result.
*/
function ne(eaddress a, eaddress b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEaddress(address(0));
}
if (!isInitialized(b)) {
b = asEaddress(address(0));
}
return ebool.wrap(Impl.ne(eaddress.unwrap(a), eaddress.unwrap(b), false));
}
/**
* @dev Evaluates and(euint256 a, euint8 b) and returns the result.
*/
function and(euint256 a, euint8 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint256.wrap(Impl.and(euint256.unwrap(a), euint256.unwrap(asEuint256(b)), false));
}
/**
* @dev Evaluates or(euint256 a, euint8 b) and returns the result.
*/
function or(euint256 a, euint8 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint256.wrap(Impl.or(euint256.unwrap(a), euint256.unwrap(asEuint256(b)), false));
}
/**
* @dev Evaluates xor(euint256 a, euint8 b) and returns the result.
*/
function xor(euint256 a, euint8 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint256.wrap(Impl.xor(euint256.unwrap(a), euint256.unwrap(asEuint256(b)), false));
}
/**
* @dev Evaluates eq(euint256 a, euint8 b) and returns the result.
*/
function eq(euint256 a, euint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.eq(euint256.unwrap(a), euint256.unwrap(asEuint256(b)), false));
}
/**
* @dev Evaluates ne(euint256 a, euint8 b) and returns the result.
*/
function ne(euint256 a, euint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.ne(euint256.unwrap(a), euint256.unwrap(asEuint256(b)), false));
}
/**
* @dev Evaluates and(euint256 a, euint16 b) and returns the result.
*/
function and(euint256 a, euint16 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint256.wrap(Impl.and(euint256.unwrap(a), euint256.unwrap(asEuint256(b)), false));
}
/**
* @dev Evaluates or(euint256 a, euint16 b) and returns the result.
*/
function or(euint256 a, euint16 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint256.wrap(Impl.or(euint256.unwrap(a), euint256.unwrap(asEuint256(b)), false));
}
/**
* @dev Evaluates xor(euint256 a, euint16 b) and returns the result.
*/
function xor(euint256 a, euint16 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint256.wrap(Impl.xor(euint256.unwrap(a), euint256.unwrap(asEuint256(b)), false));
}
/**
* @dev Evaluates eq(euint256 a, euint16 b) and returns the result.
*/
function eq(euint256 a, euint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.eq(euint256.unwrap(a), euint256.unwrap(asEuint256(b)), false));
}
/**
* @dev Evaluates ne(euint256 a, euint16 b) and returns the result.
*/
function ne(euint256 a, euint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.ne(euint256.unwrap(a), euint256.unwrap(asEuint256(b)), false));
}
/**
* @dev Evaluates and(euint256 a, euint32 b) and returns the result.
*/
function and(euint256 a, euint32 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint256.wrap(Impl.and(euint256.unwrap(a), euint256.unwrap(asEuint256(b)), false));
}
/**
* @dev Evaluates or(euint256 a, euint32 b) and returns the result.
*/
function or(euint256 a, euint32 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint256.wrap(Impl.or(euint256.unwrap(a), euint256.unwrap(asEuint256(b)), false));
}
/**
* @dev Evaluates xor(euint256 a, euint32 b) and returns the result.
*/
function xor(euint256 a, euint32 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint256.wrap(Impl.xor(euint256.unwrap(a), euint256.unwrap(asEuint256(b)), false));
}
/**
* @dev Evaluates eq(euint256 a, euint32 b) and returns the result.
*/
function eq(euint256 a, euint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.eq(euint256.unwrap(a), euint256.unwrap(asEuint256(b)), false));
}
/**
* @dev Evaluates ne(euint256 a, euint32 b) and returns the result.
*/
function ne(euint256 a, euint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.ne(euint256.unwrap(a), euint256.unwrap(asEuint256(b)), false));
}
/**
* @dev Evaluates and(euint256 a, euint64 b) and returns the result.
*/
function and(euint256 a, euint64 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint256.wrap(Impl.and(euint256.unwrap(a), euint256.unwrap(asEuint256(b)), false));
}
/**
* @dev Evaluates or(euint256 a, euint64 b) and returns the result.
*/
function or(euint256 a, euint64 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint256.wrap(Impl.or(euint256.unwrap(a), euint256.unwrap(asEuint256(b)), false));
}
/**
* @dev Evaluates xor(euint256 a, euint64 b) and returns the result.
*/
function xor(euint256 a, euint64 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint256.wrap(Impl.xor(euint256.unwrap(a), euint256.unwrap(asEuint256(b)), false));
}
/**
* @dev Evaluates eq(euint256 a, euint64 b) and returns the result.
*/
function eq(euint256 a, euint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.eq(euint256.unwrap(a), euint256.unwrap(asEuint256(b)), false));
}
/**
* @dev Evaluates ne(euint256 a, euint64 b) and returns the result.
*/
function ne(euint256 a, euint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.ne(euint256.unwrap(a), euint256.unwrap(asEuint256(b)), false));
}
/**
* @dev Evaluates and(euint256 a, euint128 b) and returns the result.
*/
function and(euint256 a, euint128 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint256.wrap(Impl.and(euint256.unwrap(a), euint256.unwrap(asEuint256(b)), false));
}
/**
* @dev Evaluates or(euint256 a, euint128 b) and returns the result.
*/
function or(euint256 a, euint128 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint256.wrap(Impl.or(euint256.unwrap(a), euint256.unwrap(asEuint256(b)), false));
}
/**
* @dev Evaluates xor(euint256 a, euint128 b) and returns the result.
*/
function xor(euint256 a, euint128 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint256.wrap(Impl.xor(euint256.unwrap(a), euint256.unwrap(asEuint256(b)), false));
}
/**
* @dev Evaluates eq(euint256 a, euint128 b) and returns the result.
*/
function eq(euint256 a, euint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.eq(euint256.unwrap(a), euint256.unwrap(asEuint256(b)), false));
}
/**
* @dev Evaluates ne(euint256 a, euint128 b) and returns the result.
*/
function ne(euint256 a, euint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.ne(euint256.unwrap(a), euint256.unwrap(asEuint256(b)), false));
}
/**
* @dev Evaluates and(euint256 a, euint256 b) and returns the result.
*/
function and(euint256 a, euint256 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
if (!isInitialized(b)) {
b = asEuint256(0);
}
return euint256.wrap(Impl.and(euint256.unwrap(a), euint256.unwrap(b), false));
}
/**
* @dev Evaluates or(euint256 a, euint256 b) and returns the result.
*/
function or(euint256 a, euint256 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
if (!isInitialized(b)) {
b = asEuint256(0);
}
return euint256.wrap(Impl.or(euint256.unwrap(a), euint256.unwrap(b), false));
}
/**
* @dev Evaluates xor(euint256 a, euint256 b) and returns the result.
*/
function xor(euint256 a, euint256 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
if (!isInitialized(b)) {
b = asEuint256(0);
}
return euint256.wrap(Impl.xor(euint256.unwrap(a), euint256.unwrap(b), false));
}
/**
* @dev Evaluates eq(euint256 a, euint256 b) and returns the result.
*/
function eq(euint256 a, euint256 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
if (!isInitialized(b)) {
b = asEuint256(0);
}
return ebool.wrap(Impl.eq(euint256.unwrap(a), euint256.unwrap(b), false));
}
/**
* @dev Evaluates ne(euint256 a, euint256 b) and returns the result.
*/
function ne(euint256 a, euint256 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
if (!isInitialized(b)) {
b = asEuint256(0);
}
return ebool.wrap(Impl.ne(euint256.unwrap(a), euint256.unwrap(b), false));
}
/**
* @dev Evaluates and(ebool a, bool b) and returns the result.
*/
function and(ebool a, bool b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEbool(false);
}
return ebool.wrap(Impl.and(ebool.unwrap(a), bytes32(uint256(b ? 1 : 0)), true));
}
/**
* @dev Evaluates and(bool a, ebool b) and returns the result.
*/
function and(bool a, ebool b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEbool(false);
}
return ebool.wrap(Impl.and(ebool.unwrap(b), bytes32(uint256(a ? 1 : 0)), true));
}
/**
* @dev Evaluates or(ebool a, bool b) and returns the result.
*/
function or(ebool a, bool b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEbool(false);
}
return ebool.wrap(Impl.or(ebool.unwrap(a), bytes32(uint256(b ? 1 : 0)), true));
}
/**
* @dev Evaluates or(bool a, ebool b) and returns the result.
*/
function or(bool a, ebool b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEbool(false);
}
return ebool.wrap(Impl.or(ebool.unwrap(b), bytes32(uint256(a ? 1 : 0)), true));
}
/**
* @dev Evaluates xor(ebool a, bool b) and returns the result.
*/
function xor(ebool a, bool b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEbool(false);
}
return ebool.wrap(Impl.xor(ebool.unwrap(a), bytes32(uint256(b ? 1 : 0)), true));
}
/**
* @dev Evaluates xor(bool a, ebool b) and returns the result.
*/
function xor(bool a, ebool b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEbool(false);
}
return ebool.wrap(Impl.xor(ebool.unwrap(b), bytes32(uint256(a ? 1 : 0)), true));
}
/**
* @dev Evaluates eq(ebool a, bool b) and returns the result.
*/
function eq(ebool a, bool b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEbool(false);
}
return ebool.wrap(Impl.eq(ebool.unwrap(a), bytes32(uint256(b ? 1 : 0)), true));
}
/**
* @dev Evaluates eq(bool a, ebool b) and returns the result.
*/
function eq(bool a, ebool b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEbool(false);
}
return ebool.wrap(Impl.eq(ebool.unwrap(b), bytes32(uint256(a ? 1 : 0)), true));
}
/**
* @dev Evaluates ne(ebool a, bool b) and returns the result.
*/
function ne(ebool a, bool b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEbool(false);
}
return ebool.wrap(Impl.ne(ebool.unwrap(a), bytes32(uint256(b ? 1 : 0)), true));
}
/**
* @dev Evaluates ne(bool a, ebool b) and returns the result.
*/
function ne(bool a, ebool b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEbool(false);
}
return ebool.wrap(Impl.ne(ebool.unwrap(b), bytes32(uint256(a ? 1 : 0)), true));
}
/**
* @dev Evaluates add(euint8 a, uint8 b) and returns the result.
*/
function add(euint8 a, uint8 b) internal returns (euint8) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
return euint8.wrap(Impl.add(euint8.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates add(uint8 a, euint8 b) and returns the result.
*/
function add(uint8 a, euint8 b) internal returns (euint8) {
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint8.wrap(Impl.add(euint8.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates sub(euint8 a, uint8 b) and returns the result.
*/
function sub(euint8 a, uint8 b) internal returns (euint8) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
return euint8.wrap(Impl.sub(euint8.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates sub(uint8 a, euint8 b) and returns the result.
*/
function sub(uint8 a, euint8 b) internal returns (euint8) {
euint8 aEnc = asEuint8(a);
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint8.wrap(Impl.sub(euint8.unwrap(aEnc), euint8.unwrap(b), false));
}
/**
* @dev Evaluates mul(euint8 a, uint8 b) and returns the result.
*/
function mul(euint8 a, uint8 b) internal returns (euint8) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
return euint8.wrap(Impl.mul(euint8.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates mul(uint8 a, euint8 b) and returns the result.
*/
function mul(uint8 a, euint8 b) internal returns (euint8) {
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint8.wrap(Impl.mul(euint8.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates div(euint8 a, uint8 b) and returns the result.
*/
function div(euint8 a, uint8 b) internal returns (euint8) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
return euint8.wrap(Impl.div(euint8.unwrap(a), bytes32(uint256(b))));
}
/**
* @dev Evaluates rem(euint8 a, uint8 b) and returns the result.
*/
function rem(euint8 a, uint8 b) internal returns (euint8) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
return euint8.wrap(Impl.rem(euint8.unwrap(a), bytes32(uint256(b))));
}
/**
* @dev Evaluates and(euint8 a, uint8 b) and returns the result.
*/
function and(euint8 a, uint8 b) internal returns (euint8) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
return euint8.wrap(Impl.and(euint8.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates and(uint8 a, euint8 b) and returns the result.
*/
function and(uint8 a, euint8 b) internal returns (euint8) {
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint8.wrap(Impl.and(euint8.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates or(euint8 a, uint8 b) and returns the result.
*/
function or(euint8 a, uint8 b) internal returns (euint8) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
return euint8.wrap(Impl.or(euint8.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates or(uint8 a, euint8 b) and returns the result.
*/
function or(uint8 a, euint8 b) internal returns (euint8) {
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint8.wrap(Impl.or(euint8.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates xor(euint8 a, uint8 b) and returns the result.
*/
function xor(euint8 a, uint8 b) internal returns (euint8) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
return euint8.wrap(Impl.xor(euint8.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates xor(uint8 a, euint8 b) and returns the result.
*/
function xor(uint8 a, euint8 b) internal returns (euint8) {
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint8.wrap(Impl.xor(euint8.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates eq(euint8 a, uint8 b) and returns the result.
*/
function eq(euint8 a, uint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
return ebool.wrap(Impl.eq(euint8.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates eq(uint8 a, euint8 b) and returns the result.
*/
function eq(uint8 a, euint8 b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.eq(euint8.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates ne(euint8 a, uint8 b) and returns the result.
*/
function ne(euint8 a, uint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
return ebool.wrap(Impl.ne(euint8.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates ne(uint8 a, euint8 b) and returns the result.
*/
function ne(uint8 a, euint8 b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.ne(euint8.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates ge(euint8 a, uint8 b) and returns the result.
*/
function ge(euint8 a, uint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
return ebool.wrap(Impl.ge(euint8.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates ge(uint8 a, euint8 b) and returns the result.
*/
function ge(uint8 a, euint8 b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.le(euint8.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates gt(euint8 a, uint8 b) and returns the result.
*/
function gt(euint8 a, uint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
return ebool.wrap(Impl.gt(euint8.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates gt(uint8 a, euint8 b) and returns the result.
*/
function gt(uint8 a, euint8 b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.lt(euint8.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates le(euint8 a, uint8 b) and returns the result.
*/
function le(euint8 a, uint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
return ebool.wrap(Impl.le(euint8.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates le(uint8 a, euint8 b) and returns the result.
*/
function le(uint8 a, euint8 b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.ge(euint8.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates lt(euint8 a, uint8 b) and returns the result.
*/
function lt(euint8 a, uint8 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
return ebool.wrap(Impl.lt(euint8.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates lt(uint8 a, euint8 b) and returns the result.
*/
function lt(uint8 a, euint8 b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEuint8(0);
}
return ebool.wrap(Impl.gt(euint8.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates min(euint8 a, uint8 b) and returns the result.
*/
function min(euint8 a, uint8 b) internal returns (euint8) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
return euint8.wrap(Impl.min(euint8.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates min(uint8 a, euint8 b) and returns the result.
*/
function min(uint8 a, euint8 b) internal returns (euint8) {
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint8.wrap(Impl.min(euint8.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates max(euint8 a, uint8 b) and returns the result.
*/
function max(euint8 a, uint8 b) internal returns (euint8) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
return euint8.wrap(Impl.max(euint8.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates max(uint8 a, euint8 b) and returns the result.
*/
function max(uint8 a, euint8 b) internal returns (euint8) {
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint8.wrap(Impl.max(euint8.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates add(euint16 a, uint16 b) and returns the result.
*/
function add(euint16 a, uint16 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
return euint16.wrap(Impl.add(euint16.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates add(uint16 a, euint16 b) and returns the result.
*/
function add(uint16 a, euint16 b) internal returns (euint16) {
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint16.wrap(Impl.add(euint16.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates sub(euint16 a, uint16 b) and returns the result.
*/
function sub(euint16 a, uint16 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
return euint16.wrap(Impl.sub(euint16.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates sub(uint16 a, euint16 b) and returns the result.
*/
function sub(uint16 a, euint16 b) internal returns (euint16) {
euint16 aEnc = asEuint16(a);
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint16.wrap(Impl.sub(euint16.unwrap(aEnc), euint16.unwrap(b), false));
}
/**
* @dev Evaluates mul(euint16 a, uint16 b) and returns the result.
*/
function mul(euint16 a, uint16 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
return euint16.wrap(Impl.mul(euint16.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates mul(uint16 a, euint16 b) and returns the result.
*/
function mul(uint16 a, euint16 b) internal returns (euint16) {
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint16.wrap(Impl.mul(euint16.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates div(euint16 a, uint16 b) and returns the result.
*/
function div(euint16 a, uint16 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
return euint16.wrap(Impl.div(euint16.unwrap(a), bytes32(uint256(b))));
}
/**
* @dev Evaluates rem(euint16 a, uint16 b) and returns the result.
*/
function rem(euint16 a, uint16 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
return euint16.wrap(Impl.rem(euint16.unwrap(a), bytes32(uint256(b))));
}
/**
* @dev Evaluates and(euint16 a, uint16 b) and returns the result.
*/
function and(euint16 a, uint16 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
return euint16.wrap(Impl.and(euint16.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates and(uint16 a, euint16 b) and returns the result.
*/
function and(uint16 a, euint16 b) internal returns (euint16) {
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint16.wrap(Impl.and(euint16.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates or(euint16 a, uint16 b) and returns the result.
*/
function or(euint16 a, uint16 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
return euint16.wrap(Impl.or(euint16.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates or(uint16 a, euint16 b) and returns the result.
*/
function or(uint16 a, euint16 b) internal returns (euint16) {
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint16.wrap(Impl.or(euint16.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates xor(euint16 a, uint16 b) and returns the result.
*/
function xor(euint16 a, uint16 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
return euint16.wrap(Impl.xor(euint16.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates xor(uint16 a, euint16 b) and returns the result.
*/
function xor(uint16 a, euint16 b) internal returns (euint16) {
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint16.wrap(Impl.xor(euint16.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates eq(euint16 a, uint16 b) and returns the result.
*/
function eq(euint16 a, uint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
return ebool.wrap(Impl.eq(euint16.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates eq(uint16 a, euint16 b) and returns the result.
*/
function eq(uint16 a, euint16 b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.eq(euint16.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates ne(euint16 a, uint16 b) and returns the result.
*/
function ne(euint16 a, uint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
return ebool.wrap(Impl.ne(euint16.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates ne(uint16 a, euint16 b) and returns the result.
*/
function ne(uint16 a, euint16 b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.ne(euint16.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates ge(euint16 a, uint16 b) and returns the result.
*/
function ge(euint16 a, uint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
return ebool.wrap(Impl.ge(euint16.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates ge(uint16 a, euint16 b) and returns the result.
*/
function ge(uint16 a, euint16 b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.le(euint16.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates gt(euint16 a, uint16 b) and returns the result.
*/
function gt(euint16 a, uint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
return ebool.wrap(Impl.gt(euint16.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates gt(uint16 a, euint16 b) and returns the result.
*/
function gt(uint16 a, euint16 b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.lt(euint16.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates le(euint16 a, uint16 b) and returns the result.
*/
function le(euint16 a, uint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
return ebool.wrap(Impl.le(euint16.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates le(uint16 a, euint16 b) and returns the result.
*/
function le(uint16 a, euint16 b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.ge(euint16.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates lt(euint16 a, uint16 b) and returns the result.
*/
function lt(euint16 a, uint16 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
return ebool.wrap(Impl.lt(euint16.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates lt(uint16 a, euint16 b) and returns the result.
*/
function lt(uint16 a, euint16 b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEuint16(0);
}
return ebool.wrap(Impl.gt(euint16.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates min(euint16 a, uint16 b) and returns the result.
*/
function min(euint16 a, uint16 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
return euint16.wrap(Impl.min(euint16.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates min(uint16 a, euint16 b) and returns the result.
*/
function min(uint16 a, euint16 b) internal returns (euint16) {
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint16.wrap(Impl.min(euint16.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates max(euint16 a, uint16 b) and returns the result.
*/
function max(euint16 a, uint16 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
return euint16.wrap(Impl.max(euint16.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates max(uint16 a, euint16 b) and returns the result.
*/
function max(uint16 a, euint16 b) internal returns (euint16) {
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint16.wrap(Impl.max(euint16.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates add(euint32 a, uint32 b) and returns the result.
*/
function add(euint32 a, uint32 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
return euint32.wrap(Impl.add(euint32.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates add(uint32 a, euint32 b) and returns the result.
*/
function add(uint32 a, euint32 b) internal returns (euint32) {
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint32.wrap(Impl.add(euint32.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates sub(euint32 a, uint32 b) and returns the result.
*/
function sub(euint32 a, uint32 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
return euint32.wrap(Impl.sub(euint32.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates sub(uint32 a, euint32 b) and returns the result.
*/
function sub(uint32 a, euint32 b) internal returns (euint32) {
euint32 aEnc = asEuint32(a);
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint32.wrap(Impl.sub(euint32.unwrap(aEnc), euint32.unwrap(b), false));
}
/**
* @dev Evaluates mul(euint32 a, uint32 b) and returns the result.
*/
function mul(euint32 a, uint32 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
return euint32.wrap(Impl.mul(euint32.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates mul(uint32 a, euint32 b) and returns the result.
*/
function mul(uint32 a, euint32 b) internal returns (euint32) {
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint32.wrap(Impl.mul(euint32.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates div(euint32 a, uint32 b) and returns the result.
*/
function div(euint32 a, uint32 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
return euint32.wrap(Impl.div(euint32.unwrap(a), bytes32(uint256(b))));
}
/**
* @dev Evaluates rem(euint32 a, uint32 b) and returns the result.
*/
function rem(euint32 a, uint32 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
return euint32.wrap(Impl.rem(euint32.unwrap(a), bytes32(uint256(b))));
}
/**
* @dev Evaluates and(euint32 a, uint32 b) and returns the result.
*/
function and(euint32 a, uint32 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
return euint32.wrap(Impl.and(euint32.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates and(uint32 a, euint32 b) and returns the result.
*/
function and(uint32 a, euint32 b) internal returns (euint32) {
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint32.wrap(Impl.and(euint32.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates or(euint32 a, uint32 b) and returns the result.
*/
function or(euint32 a, uint32 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
return euint32.wrap(Impl.or(euint32.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates or(uint32 a, euint32 b) and returns the result.
*/
function or(uint32 a, euint32 b) internal returns (euint32) {
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint32.wrap(Impl.or(euint32.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates xor(euint32 a, uint32 b) and returns the result.
*/
function xor(euint32 a, uint32 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
return euint32.wrap(Impl.xor(euint32.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates xor(uint32 a, euint32 b) and returns the result.
*/
function xor(uint32 a, euint32 b) internal returns (euint32) {
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint32.wrap(Impl.xor(euint32.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates eq(euint32 a, uint32 b) and returns the result.
*/
function eq(euint32 a, uint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
return ebool.wrap(Impl.eq(euint32.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates eq(uint32 a, euint32 b) and returns the result.
*/
function eq(uint32 a, euint32 b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.eq(euint32.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates ne(euint32 a, uint32 b) and returns the result.
*/
function ne(euint32 a, uint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
return ebool.wrap(Impl.ne(euint32.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates ne(uint32 a, euint32 b) and returns the result.
*/
function ne(uint32 a, euint32 b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.ne(euint32.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates ge(euint32 a, uint32 b) and returns the result.
*/
function ge(euint32 a, uint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
return ebool.wrap(Impl.ge(euint32.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates ge(uint32 a, euint32 b) and returns the result.
*/
function ge(uint32 a, euint32 b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.le(euint32.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates gt(euint32 a, uint32 b) and returns the result.
*/
function gt(euint32 a, uint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
return ebool.wrap(Impl.gt(euint32.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates gt(uint32 a, euint32 b) and returns the result.
*/
function gt(uint32 a, euint32 b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.lt(euint32.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates le(euint32 a, uint32 b) and returns the result.
*/
function le(euint32 a, uint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
return ebool.wrap(Impl.le(euint32.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates le(uint32 a, euint32 b) and returns the result.
*/
function le(uint32 a, euint32 b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.ge(euint32.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates lt(euint32 a, uint32 b) and returns the result.
*/
function lt(euint32 a, uint32 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
return ebool.wrap(Impl.lt(euint32.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates lt(uint32 a, euint32 b) and returns the result.
*/
function lt(uint32 a, euint32 b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEuint32(0);
}
return ebool.wrap(Impl.gt(euint32.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates min(euint32 a, uint32 b) and returns the result.
*/
function min(euint32 a, uint32 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
return euint32.wrap(Impl.min(euint32.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates min(uint32 a, euint32 b) and returns the result.
*/
function min(uint32 a, euint32 b) internal returns (euint32) {
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint32.wrap(Impl.min(euint32.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates max(euint32 a, uint32 b) and returns the result.
*/
function max(euint32 a, uint32 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
return euint32.wrap(Impl.max(euint32.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates max(uint32 a, euint32 b) and returns the result.
*/
function max(uint32 a, euint32 b) internal returns (euint32) {
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint32.wrap(Impl.max(euint32.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates add(euint64 a, uint64 b) and returns the result.
*/
function add(euint64 a, uint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
return euint64.wrap(Impl.add(euint64.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates add(uint64 a, euint64 b) and returns the result.
*/
function add(uint64 a, euint64 b) internal returns (euint64) {
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.add(euint64.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates sub(euint64 a, uint64 b) and returns the result.
*/
function sub(euint64 a, uint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
return euint64.wrap(Impl.sub(euint64.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates sub(uint64 a, euint64 b) and returns the result.
*/
function sub(uint64 a, euint64 b) internal returns (euint64) {
euint64 aEnc = asEuint64(a);
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.sub(euint64.unwrap(aEnc), euint64.unwrap(b), false));
}
/**
* @dev Evaluates mul(euint64 a, uint64 b) and returns the result.
*/
function mul(euint64 a, uint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
return euint64.wrap(Impl.mul(euint64.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates mul(uint64 a, euint64 b) and returns the result.
*/
function mul(uint64 a, euint64 b) internal returns (euint64) {
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.mul(euint64.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates div(euint64 a, uint64 b) and returns the result.
*/
function div(euint64 a, uint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
return euint64.wrap(Impl.div(euint64.unwrap(a), bytes32(uint256(b))));
}
/**
* @dev Evaluates rem(euint64 a, uint64 b) and returns the result.
*/
function rem(euint64 a, uint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
return euint64.wrap(Impl.rem(euint64.unwrap(a), bytes32(uint256(b))));
}
/**
* @dev Evaluates and(euint64 a, uint64 b) and returns the result.
*/
function and(euint64 a, uint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
return euint64.wrap(Impl.and(euint64.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates and(uint64 a, euint64 b) and returns the result.
*/
function and(uint64 a, euint64 b) internal returns (euint64) {
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.and(euint64.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates or(euint64 a, uint64 b) and returns the result.
*/
function or(euint64 a, uint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
return euint64.wrap(Impl.or(euint64.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates or(uint64 a, euint64 b) and returns the result.
*/
function or(uint64 a, euint64 b) internal returns (euint64) {
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.or(euint64.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates xor(euint64 a, uint64 b) and returns the result.
*/
function xor(euint64 a, uint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
return euint64.wrap(Impl.xor(euint64.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates xor(uint64 a, euint64 b) and returns the result.
*/
function xor(uint64 a, euint64 b) internal returns (euint64) {
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.xor(euint64.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates eq(euint64 a, uint64 b) and returns the result.
*/
function eq(euint64 a, uint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
return ebool.wrap(Impl.eq(euint64.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates eq(uint64 a, euint64 b) and returns the result.
*/
function eq(uint64 a, euint64 b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.eq(euint64.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates ne(euint64 a, uint64 b) and returns the result.
*/
function ne(euint64 a, uint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
return ebool.wrap(Impl.ne(euint64.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates ne(uint64 a, euint64 b) and returns the result.
*/
function ne(uint64 a, euint64 b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.ne(euint64.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates ge(euint64 a, uint64 b) and returns the result.
*/
function ge(euint64 a, uint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
return ebool.wrap(Impl.ge(euint64.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates ge(uint64 a, euint64 b) and returns the result.
*/
function ge(uint64 a, euint64 b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.le(euint64.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates gt(euint64 a, uint64 b) and returns the result.
*/
function gt(euint64 a, uint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
return ebool.wrap(Impl.gt(euint64.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates gt(uint64 a, euint64 b) and returns the result.
*/
function gt(uint64 a, euint64 b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.lt(euint64.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates le(euint64 a, uint64 b) and returns the result.
*/
function le(euint64 a, uint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
return ebool.wrap(Impl.le(euint64.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates le(uint64 a, euint64 b) and returns the result.
*/
function le(uint64 a, euint64 b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.ge(euint64.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates lt(euint64 a, uint64 b) and returns the result.
*/
function lt(euint64 a, uint64 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
return ebool.wrap(Impl.lt(euint64.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates lt(uint64 a, euint64 b) and returns the result.
*/
function lt(uint64 a, euint64 b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEuint64(0);
}
return ebool.wrap(Impl.gt(euint64.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates min(euint64 a, uint64 b) and returns the result.
*/
function min(euint64 a, uint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
return euint64.wrap(Impl.min(euint64.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates min(uint64 a, euint64 b) and returns the result.
*/
function min(uint64 a, euint64 b) internal returns (euint64) {
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.min(euint64.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates max(euint64 a, uint64 b) and returns the result.
*/
function max(euint64 a, uint64 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
return euint64.wrap(Impl.max(euint64.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates max(uint64 a, euint64 b) and returns the result.
*/
function max(uint64 a, euint64 b) internal returns (euint64) {
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.max(euint64.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates add(euint128 a, uint128 b) and returns the result.
*/
function add(euint128 a, uint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
return euint128.wrap(Impl.add(euint128.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates add(uint128 a, euint128 b) and returns the result.
*/
function add(uint128 a, euint128 b) internal returns (euint128) {
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.add(euint128.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates sub(euint128 a, uint128 b) and returns the result.
*/
function sub(euint128 a, uint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
return euint128.wrap(Impl.sub(euint128.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates sub(uint128 a, euint128 b) and returns the result.
*/
function sub(uint128 a, euint128 b) internal returns (euint128) {
euint128 aEnc = asEuint128(a);
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.sub(euint128.unwrap(aEnc), euint128.unwrap(b), false));
}
/**
* @dev Evaluates mul(euint128 a, uint128 b) and returns the result.
*/
function mul(euint128 a, uint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
return euint128.wrap(Impl.mul(euint128.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates mul(uint128 a, euint128 b) and returns the result.
*/
function mul(uint128 a, euint128 b) internal returns (euint128) {
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.mul(euint128.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates div(euint128 a, uint128 b) and returns the result.
*/
function div(euint128 a, uint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
return euint128.wrap(Impl.div(euint128.unwrap(a), bytes32(uint256(b))));
}
/**
* @dev Evaluates rem(euint128 a, uint128 b) and returns the result.
*/
function rem(euint128 a, uint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
return euint128.wrap(Impl.rem(euint128.unwrap(a), bytes32(uint256(b))));
}
/**
* @dev Evaluates and(euint128 a, uint128 b) and returns the result.
*/
function and(euint128 a, uint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
return euint128.wrap(Impl.and(euint128.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates and(uint128 a, euint128 b) and returns the result.
*/
function and(uint128 a, euint128 b) internal returns (euint128) {
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.and(euint128.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates or(euint128 a, uint128 b) and returns the result.
*/
function or(euint128 a, uint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
return euint128.wrap(Impl.or(euint128.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates or(uint128 a, euint128 b) and returns the result.
*/
function or(uint128 a, euint128 b) internal returns (euint128) {
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.or(euint128.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates xor(euint128 a, uint128 b) and returns the result.
*/
function xor(euint128 a, uint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
return euint128.wrap(Impl.xor(euint128.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates xor(uint128 a, euint128 b) and returns the result.
*/
function xor(uint128 a, euint128 b) internal returns (euint128) {
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.xor(euint128.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates eq(euint128 a, uint128 b) and returns the result.
*/
function eq(euint128 a, uint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
return ebool.wrap(Impl.eq(euint128.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates eq(uint128 a, euint128 b) and returns the result.
*/
function eq(uint128 a, euint128 b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.eq(euint128.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates ne(euint128 a, uint128 b) and returns the result.
*/
function ne(euint128 a, uint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
return ebool.wrap(Impl.ne(euint128.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates ne(uint128 a, euint128 b) and returns the result.
*/
function ne(uint128 a, euint128 b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.ne(euint128.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates ge(euint128 a, uint128 b) and returns the result.
*/
function ge(euint128 a, uint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
return ebool.wrap(Impl.ge(euint128.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates ge(uint128 a, euint128 b) and returns the result.
*/
function ge(uint128 a, euint128 b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.le(euint128.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates gt(euint128 a, uint128 b) and returns the result.
*/
function gt(euint128 a, uint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
return ebool.wrap(Impl.gt(euint128.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates gt(uint128 a, euint128 b) and returns the result.
*/
function gt(uint128 a, euint128 b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.lt(euint128.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates le(euint128 a, uint128 b) and returns the result.
*/
function le(euint128 a, uint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
return ebool.wrap(Impl.le(euint128.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates le(uint128 a, euint128 b) and returns the result.
*/
function le(uint128 a, euint128 b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.ge(euint128.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates lt(euint128 a, uint128 b) and returns the result.
*/
function lt(euint128 a, uint128 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
return ebool.wrap(Impl.lt(euint128.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates lt(uint128 a, euint128 b) and returns the result.
*/
function lt(uint128 a, euint128 b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEuint128(0);
}
return ebool.wrap(Impl.gt(euint128.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates min(euint128 a, uint128 b) and returns the result.
*/
function min(euint128 a, uint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
return euint128.wrap(Impl.min(euint128.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates min(uint128 a, euint128 b) and returns the result.
*/
function min(uint128 a, euint128 b) internal returns (euint128) {
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.min(euint128.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates max(euint128 a, uint128 b) and returns the result.
*/
function max(euint128 a, uint128 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
return euint128.wrap(Impl.max(euint128.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates max(uint128 a, euint128 b) and returns the result.
*/
function max(uint128 a, euint128 b) internal returns (euint128) {
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.max(euint128.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates eq(eaddress a, address b) and returns the result.
*/
function eq(eaddress a, address b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEaddress(address(0));
}
return ebool.wrap(Impl.eq(eaddress.unwrap(a), bytes32(uint256(uint160(b))), true));
}
/**
* @dev Evaluates eq(address a, eaddress b) and returns the result.
*/
function eq(address a, eaddress b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEaddress(address(0));
}
return ebool.wrap(Impl.eq(eaddress.unwrap(b), bytes32(uint256(uint160(a))), true));
}
/**
* @dev Evaluates ne(eaddress a, address b) and returns the result.
*/
function ne(eaddress a, address b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEaddress(address(0));
}
return ebool.wrap(Impl.ne(eaddress.unwrap(a), bytes32(uint256(uint160(b))), true));
}
/**
* @dev Evaluates ne(address a, eaddress b) and returns the result.
*/
function ne(address a, eaddress b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEaddress(address(0));
}
return ebool.wrap(Impl.ne(eaddress.unwrap(b), bytes32(uint256(uint160(a))), true));
}
/**
* @dev Evaluates and(euint256 a, uint256 b) and returns the result.
*/
function and(euint256 a, uint256 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
return euint256.wrap(Impl.and(euint256.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates and(uint256 a, euint256 b) and returns the result.
*/
function and(uint256 a, euint256 b) internal returns (euint256) {
if (!isInitialized(b)) {
b = asEuint256(0);
}
return euint256.wrap(Impl.and(euint256.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates or(euint256 a, uint256 b) and returns the result.
*/
function or(euint256 a, uint256 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
return euint256.wrap(Impl.or(euint256.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates or(uint256 a, euint256 b) and returns the result.
*/
function or(uint256 a, euint256 b) internal returns (euint256) {
if (!isInitialized(b)) {
b = asEuint256(0);
}
return euint256.wrap(Impl.or(euint256.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates xor(euint256 a, uint256 b) and returns the result.
*/
function xor(euint256 a, uint256 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
return euint256.wrap(Impl.xor(euint256.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates xor(uint256 a, euint256 b) and returns the result.
*/
function xor(uint256 a, euint256 b) internal returns (euint256) {
if (!isInitialized(b)) {
b = asEuint256(0);
}
return euint256.wrap(Impl.xor(euint256.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates eq(euint256 a, uint256 b) and returns the result.
*/
function eq(euint256 a, uint256 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
return ebool.wrap(Impl.eq(euint256.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates eq(uint256 a, euint256 b) and returns the result.
*/
function eq(uint256 a, euint256 b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEuint256(0);
}
return ebool.wrap(Impl.eq(euint256.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates ne(euint256 a, uint256 b) and returns the result.
*/
function ne(euint256 a, uint256 b) internal returns (ebool) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
return ebool.wrap(Impl.ne(euint256.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates ne(uint256 a, euint256 b) and returns the result.
*/
function ne(uint256 a, euint256 b) internal returns (ebool) {
if (!isInitialized(b)) {
b = asEuint256(0);
}
return ebool.wrap(Impl.ne(euint256.unwrap(b), bytes32(uint256(a)), true));
}
/**
* @dev Evaluates shl(euint8 a, euint8 b) and returns the result.
*/
function shl(euint8 a, euint8 b) internal returns (euint8) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint8.wrap(Impl.shl(euint8.unwrap(a), euint8.unwrap(b), false));
}
/**
* @dev Evaluates shl(euint8 a, uint8) and returns the result.
*/
function shl(euint8 a, uint8 b) internal returns (euint8) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
return euint8.wrap(Impl.shl(euint8.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates shr(euint8 a, euint8 b) and returns the result.
*/
function shr(euint8 a, euint8 b) internal returns (euint8) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint8.wrap(Impl.shr(euint8.unwrap(a), euint8.unwrap(b), false));
}
/**
* @dev Evaluates shr(euint8 a, uint8) and returns the result.
*/
function shr(euint8 a, uint8 b) internal returns (euint8) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
return euint8.wrap(Impl.shr(euint8.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates rotl(euint8 a, euint8 b) and returns the result.
*/
function rotl(euint8 a, euint8 b) internal returns (euint8) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint8.wrap(Impl.rotl(euint8.unwrap(a), euint8.unwrap(b), false));
}
/**
* @dev Evaluates rotl(euint8 a, uint8) and returns the result.
*/
function rotl(euint8 a, uint8 b) internal returns (euint8) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
return euint8.wrap(Impl.rotl(euint8.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates rotr(euint8 a, euint8 b) and returns the result.
*/
function rotr(euint8 a, euint8 b) internal returns (euint8) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint8.wrap(Impl.rotr(euint8.unwrap(a), euint8.unwrap(b), false));
}
/**
* @dev Evaluates rotr(euint8 a, uint8) and returns the result.
*/
function rotr(euint8 a, uint8 b) internal returns (euint8) {
if (!isInitialized(a)) {
a = asEuint8(0);
}
return euint8.wrap(Impl.rotr(euint8.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates shl(euint16 a, euint8 b) and returns the result.
*/
function shl(euint16 a, euint8 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint16.wrap(Impl.shl(euint16.unwrap(a), euint16.unwrap(asEuint16(b)), false));
}
/**
* @dev Evaluates shl(euint16 a, uint8) and returns the result.
*/
function shl(euint16 a, uint8 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
return euint16.wrap(Impl.shl(euint16.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates shr(euint16 a, euint8 b) and returns the result.
*/
function shr(euint16 a, euint8 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint16.wrap(Impl.shr(euint16.unwrap(a), euint16.unwrap(asEuint16(b)), false));
}
/**
* @dev Evaluates shr(euint16 a, uint8) and returns the result.
*/
function shr(euint16 a, uint8 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
return euint16.wrap(Impl.shr(euint16.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates rotl(euint16 a, euint8 b) and returns the result.
*/
function rotl(euint16 a, euint8 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint16.wrap(Impl.rotl(euint16.unwrap(a), euint16.unwrap(asEuint16(b)), false));
}
/**
* @dev Evaluates rotl(euint16 a, uint8) and returns the result.
*/
function rotl(euint16 a, uint8 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
return euint16.wrap(Impl.rotl(euint16.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates rotr(euint16 a, euint8 b) and returns the result.
*/
function rotr(euint16 a, euint8 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint16.wrap(Impl.rotr(euint16.unwrap(a), euint16.unwrap(asEuint16(b)), false));
}
/**
* @dev Evaluates rotr(euint16 a, uint8) and returns the result.
*/
function rotr(euint16 a, uint8 b) internal returns (euint16) {
if (!isInitialized(a)) {
a = asEuint16(0);
}
return euint16.wrap(Impl.rotr(euint16.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates shl(euint32 a, euint8 b) and returns the result.
*/
function shl(euint32 a, euint8 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint32.wrap(Impl.shl(euint32.unwrap(a), euint32.unwrap(asEuint32(b)), false));
}
/**
* @dev Evaluates shl(euint32 a, uint8) and returns the result.
*/
function shl(euint32 a, uint8 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
return euint32.wrap(Impl.shl(euint32.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates shr(euint32 a, euint8 b) and returns the result.
*/
function shr(euint32 a, euint8 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint32.wrap(Impl.shr(euint32.unwrap(a), euint32.unwrap(asEuint32(b)), false));
}
/**
* @dev Evaluates shr(euint32 a, uint8) and returns the result.
*/
function shr(euint32 a, uint8 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
return euint32.wrap(Impl.shr(euint32.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates rotl(euint32 a, euint8 b) and returns the result.
*/
function rotl(euint32 a, euint8 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint32.wrap(Impl.rotl(euint32.unwrap(a), euint32.unwrap(asEuint32(b)), false));
}
/**
* @dev Evaluates rotl(euint32 a, uint8) and returns the result.
*/
function rotl(euint32 a, uint8 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
return euint32.wrap(Impl.rotl(euint32.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates rotr(euint32 a, euint8 b) and returns the result.
*/
function rotr(euint32 a, euint8 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint32.wrap(Impl.rotr(euint32.unwrap(a), euint32.unwrap(asEuint32(b)), false));
}
/**
* @dev Evaluates rotr(euint32 a, uint8) and returns the result.
*/
function rotr(euint32 a, uint8 b) internal returns (euint32) {
if (!isInitialized(a)) {
a = asEuint32(0);
}
return euint32.wrap(Impl.rotr(euint32.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates shl(euint64 a, euint8 b) and returns the result.
*/
function shl(euint64 a, euint8 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint64.wrap(Impl.shl(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates shl(euint64 a, uint8) and returns the result.
*/
function shl(euint64 a, uint8 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
return euint64.wrap(Impl.shl(euint64.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates shr(euint64 a, euint8 b) and returns the result.
*/
function shr(euint64 a, euint8 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint64.wrap(Impl.shr(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates shr(euint64 a, uint8) and returns the result.
*/
function shr(euint64 a, uint8 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
return euint64.wrap(Impl.shr(euint64.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates rotl(euint64 a, euint8 b) and returns the result.
*/
function rotl(euint64 a, euint8 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint64.wrap(Impl.rotl(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates rotl(euint64 a, uint8) and returns the result.
*/
function rotl(euint64 a, uint8 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
return euint64.wrap(Impl.rotl(euint64.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates rotr(euint64 a, euint8 b) and returns the result.
*/
function rotr(euint64 a, euint8 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint64.wrap(Impl.rotr(euint64.unwrap(a), euint64.unwrap(asEuint64(b)), false));
}
/**
* @dev Evaluates rotr(euint64 a, uint8) and returns the result.
*/
function rotr(euint64 a, uint8 b) internal returns (euint64) {
if (!isInitialized(a)) {
a = asEuint64(0);
}
return euint64.wrap(Impl.rotr(euint64.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates shl(euint128 a, euint8 b) and returns the result.
*/
function shl(euint128 a, euint8 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint128.wrap(Impl.shl(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates shl(euint128 a, uint8) and returns the result.
*/
function shl(euint128 a, uint8 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
return euint128.wrap(Impl.shl(euint128.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates shr(euint128 a, euint8 b) and returns the result.
*/
function shr(euint128 a, euint8 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint128.wrap(Impl.shr(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates shr(euint128 a, uint8) and returns the result.
*/
function shr(euint128 a, uint8 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
return euint128.wrap(Impl.shr(euint128.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates rotl(euint128 a, euint8 b) and returns the result.
*/
function rotl(euint128 a, euint8 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint128.wrap(Impl.rotl(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates rotl(euint128 a, uint8) and returns the result.
*/
function rotl(euint128 a, uint8 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
return euint128.wrap(Impl.rotl(euint128.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates rotr(euint128 a, euint8 b) and returns the result.
*/
function rotr(euint128 a, euint8 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint128.wrap(Impl.rotr(euint128.unwrap(a), euint128.unwrap(asEuint128(b)), false));
}
/**
* @dev Evaluates rotr(euint128 a, uint8) and returns the result.
*/
function rotr(euint128 a, uint8 b) internal returns (euint128) {
if (!isInitialized(a)) {
a = asEuint128(0);
}
return euint128.wrap(Impl.rotr(euint128.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates shl(euint256 a, euint8 b) and returns the result.
*/
function shl(euint256 a, euint8 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint256.wrap(Impl.shl(euint256.unwrap(a), euint256.unwrap(asEuint256(b)), false));
}
/**
* @dev Evaluates shl(euint256 a, uint8) and returns the result.
*/
function shl(euint256 a, uint8 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
return euint256.wrap(Impl.shl(euint256.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates shr(euint256 a, euint8 b) and returns the result.
*/
function shr(euint256 a, euint8 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint256.wrap(Impl.shr(euint256.unwrap(a), euint256.unwrap(asEuint256(b)), false));
}
/**
* @dev Evaluates shr(euint256 a, uint8) and returns the result.
*/
function shr(euint256 a, uint8 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
return euint256.wrap(Impl.shr(euint256.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates rotl(euint256 a, euint8 b) and returns the result.
*/
function rotl(euint256 a, euint8 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint256.wrap(Impl.rotl(euint256.unwrap(a), euint256.unwrap(asEuint256(b)), false));
}
/**
* @dev Evaluates rotl(euint256 a, uint8) and returns the result.
*/
function rotl(euint256 a, uint8 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
return euint256.wrap(Impl.rotl(euint256.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev Evaluates rotr(euint256 a, euint8 b) and returns the result.
*/
function rotr(euint256 a, euint8 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint256.wrap(Impl.rotr(euint256.unwrap(a), euint256.unwrap(asEuint256(b)), false));
}
/**
* @dev Evaluates rotr(euint256 a, uint8) and returns the result.
*/
function rotr(euint256 a, uint8 b) internal returns (euint256) {
if (!isInitialized(a)) {
a = asEuint256(0);
}
return euint256.wrap(Impl.rotr(euint256.unwrap(a), bytes32(uint256(b)), true));
}
/**
* @dev If 'control's value is 'true', the result has the same value as 'ifTrue'.
* If 'control's value is 'false', the result has the same value as 'ifFalse'.
*/
function select(ebool control, ebool a, ebool b) internal returns (ebool) {
if (!isInitialized(control)) {
control = asEbool(false);
}
if (!isInitialized(a)) {
a = asEbool(false);
}
if (!isInitialized(b)) {
b = asEbool(false);
}
return ebool.wrap(Impl.select(ebool.unwrap(control), ebool.unwrap(a), ebool.unwrap(b)));
}
/**
* @dev If 'control's value is 'true', the result has the same value as 'ifTrue'.
* If 'control's value is 'false', the result has the same value as 'ifFalse'.
*/
function select(ebool control, euint8 a, euint8 b) internal returns (euint8) {
if (!isInitialized(control)) {
control = asEbool(false);
}
if (!isInitialized(a)) {
a = asEuint8(0);
}
if (!isInitialized(b)) {
b = asEuint8(0);
}
return euint8.wrap(Impl.select(ebool.unwrap(control), euint8.unwrap(a), euint8.unwrap(b)));
}
/**
* @dev If 'control's value is 'true', the result has the same value as 'ifTrue'.
* If 'control's value is 'false', the result has the same value as 'ifFalse'.
*/
function select(ebool control, euint16 a, euint16 b) internal returns (euint16) {
if (!isInitialized(control)) {
control = asEbool(false);
}
if (!isInitialized(a)) {
a = asEuint16(0);
}
if (!isInitialized(b)) {
b = asEuint16(0);
}
return euint16.wrap(Impl.select(ebool.unwrap(control), euint16.unwrap(a), euint16.unwrap(b)));
}
/**
* @dev If 'control's value is 'true', the result has the same value as 'ifTrue'.
* If 'control's value is 'false', the result has the same value as 'ifFalse'.
*/
function select(ebool control, euint32 a, euint32 b) internal returns (euint32) {
if (!isInitialized(control)) {
control = asEbool(false);
}
if (!isInitialized(a)) {
a = asEuint32(0);
}
if (!isInitialized(b)) {
b = asEuint32(0);
}
return euint32.wrap(Impl.select(ebool.unwrap(control), euint32.unwrap(a), euint32.unwrap(b)));
}
/**
* @dev If 'control's value is 'true', the result has the same value as 'ifTrue'.
* If 'control's value is 'false', the result has the same value as 'ifFalse'.
*/
function select(ebool control, euint64 a, euint64 b) internal returns (euint64) {
if (!isInitialized(control)) {
control = asEbool(false);
}
if (!isInitialized(a)) {
a = asEuint64(0);
}
if (!isInitialized(b)) {
b = asEuint64(0);
}
return euint64.wrap(Impl.select(ebool.unwrap(control), euint64.unwrap(a), euint64.unwrap(b)));
}
/**
* @dev If 'control's value is 'true', the result has the same value as 'ifTrue'.
* If 'control's value is 'false', the result has the same value as 'ifFalse'.
*/
function select(ebool control, euint128 a, euint128 b) internal returns (euint128) {
if (!isInitialized(control)) {
control = asEbool(false);
}
if (!isInitialized(a)) {
a = asEuint128(0);
}
if (!isInitialized(b)) {
b = asEuint128(0);
}
return euint128.wrap(Impl.select(ebool.unwrap(control), euint128.unwrap(a), euint128.unwrap(b)));
}
/**
* @dev If 'control's value is 'true', the result has the same value as 'ifTrue'.
* If 'control's value is 'false', the result has the same value as 'ifFalse'.
*/
function select(ebool control, eaddress a, eaddress b) internal returns (eaddress) {
if (!isInitialized(control)) {
control = asEbool(false);
}
if (!isInitialized(a)) {
a = asEaddress(address(0));
}
if (!isInitialized(b)) {
b = asEaddress(address(0));
}
return eaddress.wrap(Impl.select(ebool.unwrap(control), eaddress.unwrap(a), eaddress.unwrap(b)));
}
/**
* @dev If 'control's value is 'true', the result has the same value as 'ifTrue'.
* If 'control's value is 'false', the result has the same value as 'ifFalse'.
*/
function select(ebool control, euint256 a, euint256 b) internal returns (euint256) {
if (!isInitialized(control)) {
control = asEbool(false);
}
if (!isInitialized(a)) {
a = asEuint256(0);
}
if (!isInitialized(b)) {
b = asEuint256(0);
}
return euint256.wrap(Impl.select(ebool.unwrap(control), euint256.unwrap(a), euint256.unwrap(b)));
}
/**
* @dev Casts an encrypted integer from 'euint16' to 'euint8'.
*/
function asEuint8(euint16 value) internal returns (euint8) {
if (!isInitialized(value)) {
value = asEuint16(0);
}
return euint8.wrap(Impl.cast(euint16.unwrap(value), FheType.Uint8));
}
/**
* @dev Casts an encrypted integer from 'euint32' to 'euint8'.
*/
function asEuint8(euint32 value) internal returns (euint8) {
if (!isInitialized(value)) {
value = asEuint32(0);
}
return euint8.wrap(Impl.cast(euint32.unwrap(value), FheType.Uint8));
}
/**
* @dev Casts an encrypted integer from 'euint64' to 'euint8'.
*/
function asEuint8(euint64 value) internal returns (euint8) {
if (!isInitialized(value)) {
value = asEuint64(0);
}
return euint8.wrap(Impl.cast(euint64.unwrap(value), FheType.Uint8));
}
/**
* @dev Casts an encrypted integer from 'euint128' to 'euint8'.
*/
function asEuint8(euint128 value) internal returns (euint8) {
if (!isInitialized(value)) {
value = asEuint128(0);
}
return euint8.wrap(Impl.cast(euint128.unwrap(value), FheType.Uint8));
}
/**
* @dev Casts an encrypted integer from 'euint256' to 'euint8'.
*/
function asEuint8(euint256 value) internal returns (euint8) {
if (!isInitialized(value)) {
value = asEuint256(0);
}
return euint8.wrap(Impl.cast(euint256.unwrap(value), FheType.Uint8));
}
/**
/**
* @dev Converts an 'ebool' to an 'euint8'.
*/
function asEuint8(ebool b) internal returns (euint8) {
if (!isInitialized(b)) {
b = asEbool(false);
}
return euint8.wrap(Impl.cast(ebool.unwrap(b), FheType.Uint8));
}
/**
* @dev Casts an encrypted integer from 'euint8' to 'ebool'.
*/
function asEbool(euint8 value) internal returns (ebool) {
if (!isInitialized(value)) {
value = asEuint8(0);
}
return ne(value, 0);
}
/**
* @dev Casts an encrypted integer from 'euint8' to 'euint16'.
*/
function asEuint16(euint8 value) internal returns (euint16) {
if (!isInitialized(value)) {
value = asEuint8(0);
}
return euint16.wrap(Impl.cast(euint8.unwrap(value), FheType.Uint16));
}
/**
* @dev Casts an encrypted integer from 'euint32' to 'euint16'.
*/
function asEuint16(euint32 value) internal returns (euint16) {
if (!isInitialized(value)) {
value = asEuint32(0);
}
return euint16.wrap(Impl.cast(euint32.unwrap(value), FheType.Uint16));
}
/**
* @dev Casts an encrypted integer from 'euint64' to 'euint16'.
*/
function asEuint16(euint64 value) internal returns (euint16) {
if (!isInitialized(value)) {
value = asEuint64(0);
}
return euint16.wrap(Impl.cast(euint64.unwrap(value), FheType.Uint16));
}
/**
* @dev Casts an encrypted integer from 'euint128' to 'euint16'.
*/
function asEuint16(euint128 value) internal returns (euint16) {
if (!isInitialized(value)) {
value = asEuint128(0);
}
return euint16.wrap(Impl.cast(euint128.unwrap(value), FheType.Uint16));
}
/**
* @dev Casts an encrypted integer from 'euint256' to 'euint16'.
*/
function asEuint16(euint256 value) internal returns (euint16) {
if (!isInitialized(value)) {
value = asEuint256(0);
}
return euint16.wrap(Impl.cast(euint256.unwrap(value), FheType.Uint16));
}
/**
/**
* @dev Converts an 'ebool' to an 'euint16'.
*/
function asEuint16(ebool b) internal returns (euint16) {
if (!isInitialized(b)) {
b = asEbool(false);
}
return euint16.wrap(Impl.cast(ebool.unwrap(b), FheType.Uint16));
}
/**
* @dev Casts an encrypted integer from 'euint16' to 'ebool'.
*/
function asEbool(euint16 value) internal returns (ebool) {
if (!isInitialized(value)) {
value = asEuint16(0);
}
return ne(value, 0);
}
/**
* @dev Casts an encrypted integer from 'euint8' to 'euint32'.
*/
function asEuint32(euint8 value) internal returns (euint32) {
if (!isInitialized(value)) {
value = asEuint8(0);
}
return euint32.wrap(Impl.cast(euint8.unwrap(value), FheType.Uint32));
}
/**
* @dev Casts an encrypted integer from 'euint16' to 'euint32'.
*/
function asEuint32(euint16 value) internal returns (euint32) {
if (!isInitialized(value)) {
value = asEuint16(0);
}
return euint32.wrap(Impl.cast(euint16.unwrap(value), FheType.Uint32));
}
/**
* @dev Casts an encrypted integer from 'euint64' to 'euint32'.
*/
function asEuint32(euint64 value) internal returns (euint32) {
if (!isInitialized(value)) {
value = asEuint64(0);
}
return euint32.wrap(Impl.cast(euint64.unwrap(value), FheType.Uint32));
}
/**
* @dev Casts an encrypted integer from 'euint128' to 'euint32'.
*/
function asEuint32(euint128 value) internal returns (euint32) {
if (!isInitialized(value)) {
value = asEuint128(0);
}
return euint32.wrap(Impl.cast(euint128.unwrap(value), FheType.Uint32));
}
/**
* @dev Casts an encrypted integer from 'euint256' to 'euint32'.
*/
function asEuint32(euint256 value) internal returns (euint32) {
if (!isInitialized(value)) {
value = asEuint256(0);
}
return euint32.wrap(Impl.cast(euint256.unwrap(value), FheType.Uint32));
}
/**
/**
* @dev Converts an 'ebool' to an 'euint32'.
*/
function asEuint32(ebool b) internal returns (euint32) {
if (!isInitialized(b)) {
b = asEbool(false);
}
return euint32.wrap(Impl.cast(ebool.unwrap(b), FheType.Uint32));
}
/**
* @dev Casts an encrypted integer from 'euint32' to 'ebool'.
*/
function asEbool(euint32 value) internal returns (ebool) {
if (!isInitialized(value)) {
value = asEuint32(0);
}
return ne(value, 0);
}
/**
* @dev Casts an encrypted integer from 'euint8' to 'euint64'.
*/
function asEuint64(euint8 value) internal returns (euint64) {
if (!isInitialized(value)) {
value = asEuint8(0);
}
return euint64.wrap(Impl.cast(euint8.unwrap(value), FheType.Uint64));
}
/**
* @dev Casts an encrypted integer from 'euint16' to 'euint64'.
*/
function asEuint64(euint16 value) internal returns (euint64) {
if (!isInitialized(value)) {
value = asEuint16(0);
}
return euint64.wrap(Impl.cast(euint16.unwrap(value), FheType.Uint64));
}
/**
* @dev Casts an encrypted integer from 'euint32' to 'euint64'.
*/
function asEuint64(euint32 value) internal returns (euint64) {
if (!isInitialized(value)) {
value = asEuint32(0);
}
return euint64.wrap(Impl.cast(euint32.unwrap(value), FheType.Uint64));
}
/**
* @dev Casts an encrypted integer from 'euint128' to 'euint64'.
*/
function asEuint64(euint128 value) internal returns (euint64) {
if (!isInitialized(value)) {
value = asEuint128(0);
}
return euint64.wrap(Impl.cast(euint128.unwrap(value), FheType.Uint64));
}
/**
* @dev Casts an encrypted integer from 'euint256' to 'euint64'.
*/
function asEuint64(euint256 value) internal returns (euint64) {
if (!isInitialized(value)) {
value = asEuint256(0);
}
return euint64.wrap(Impl.cast(euint256.unwrap(value), FheType.Uint64));
}
/**
/**
* @dev Converts an 'ebool' to an 'euint64'.
*/
function asEuint64(ebool b) internal returns (euint64) {
if (!isInitialized(b)) {
b = asEbool(false);
}
return euint64.wrap(Impl.cast(ebool.unwrap(b), FheType.Uint64));
}
/**
* @dev Casts an encrypted integer from 'euint64' to 'ebool'.
*/
function asEbool(euint64 value) internal returns (ebool) {
if (!isInitialized(value)) {
value = asEuint64(0);
}
return ne(value, 0);
}
/**
* @dev Casts an encrypted integer from 'euint8' to 'euint128'.
*/
function asEuint128(euint8 value) internal returns (euint128) {
if (!isInitialized(value)) {
value = asEuint8(0);
}
return euint128.wrap(Impl.cast(euint8.unwrap(value), FheType.Uint128));
}
/**
* @dev Casts an encrypted integer from 'euint16' to 'euint128'.
*/
function asEuint128(euint16 value) internal returns (euint128) {
if (!isInitialized(value)) {
value = asEuint16(0);
}
return euint128.wrap(Impl.cast(euint16.unwrap(value), FheType.Uint128));
}
/**
* @dev Casts an encrypted integer from 'euint32' to 'euint128'.
*/
function asEuint128(euint32 value) internal returns (euint128) {
if (!isInitialized(value)) {
value = asEuint32(0);
}
return euint128.wrap(Impl.cast(euint32.unwrap(value), FheType.Uint128));
}
/**
* @dev Casts an encrypted integer from 'euint64' to 'euint128'.
*/
function asEuint128(euint64 value) internal returns (euint128) {
if (!isInitialized(value)) {
value = asEuint64(0);
}
return euint128.wrap(Impl.cast(euint64.unwrap(value), FheType.Uint128));
}
/**
* @dev Casts an encrypted integer from 'euint256' to 'euint128'.
*/
function asEuint128(euint256 value) internal returns (euint128) {
if (!isInitialized(value)) {
value = asEuint256(0);
}
return euint128.wrap(Impl.cast(euint256.unwrap(value), FheType.Uint128));
}
/**
/**
* @dev Converts an 'ebool' to an 'euint128'.
*/
function asEuint128(ebool b) internal returns (euint128) {
if (!isInitialized(b)) {
b = asEbool(false);
}
return euint128.wrap(Impl.cast(ebool.unwrap(b), FheType.Uint128));
}
/**
* @dev Casts an encrypted integer from 'euint128' to 'ebool'.
*/
function asEbool(euint128 value) internal returns (ebool) {
if (!isInitialized(value)) {
value = asEuint128(0);
}
return ne(value, 0);
}
/**
* @dev Casts an encrypted integer from 'euint8' to 'euint256'.
*/
function asEuint256(euint8 value) internal returns (euint256) {
if (!isInitialized(value)) {
value = asEuint8(0);
}
return euint256.wrap(Impl.cast(euint8.unwrap(value), FheType.Uint256));
}
/**
* @dev Casts an encrypted integer from 'euint16' to 'euint256'.
*/
function asEuint256(euint16 value) internal returns (euint256) {
if (!isInitialized(value)) {
value = asEuint16(0);
}
return euint256.wrap(Impl.cast(euint16.unwrap(value), FheType.Uint256));
}
/**
* @dev Casts an encrypted integer from 'euint32' to 'euint256'.
*/
function asEuint256(euint32 value) internal returns (euint256) {
if (!isInitialized(value)) {
value = asEuint32(0);
}
return euint256.wrap(Impl.cast(euint32.unwrap(value), FheType.Uint256));
}
/**
* @dev Casts an encrypted integer from 'euint64' to 'euint256'.
*/
function asEuint256(euint64 value) internal returns (euint256) {
if (!isInitialized(value)) {
value = asEuint64(0);
}
return euint256.wrap(Impl.cast(euint64.unwrap(value), FheType.Uint256));
}
/**
* @dev Casts an encrypted integer from 'euint128' to 'euint256'.
*/
function asEuint256(euint128 value) internal returns (euint256) {
if (!isInitialized(value)) {
value = asEuint128(0);
}
return euint256.wrap(Impl.cast(euint128.unwrap(value), FheType.Uint256));
}
/**
/**
* @dev Converts an 'ebool' to an 'euint256'.
*/
function asEuint256(ebool b) internal returns (euint256) {
if (!isInitialized(b)) {
b = asEbool(false);
}
return euint256.wrap(Impl.cast(ebool.unwrap(b), FheType.Uint256));
}
/**
* @dev Casts an encrypted integer from 'euint256' to 'ebool'.
*/
function asEbool(euint256 value) internal returns (ebool) {
if (!isInitialized(value)) {
value = asEuint256(0);
}
return ne(value, 0);
}
/**
* @dev Evaluates not(ebool value) and returns the result.
*/
function not(ebool value) internal returns (ebool) {
if (!isInitialized(value)) {
value = asEbool(false);
}
return ebool.wrap(Impl.not(ebool.unwrap(value)));
}
/**
* @dev Evaluates neg(euint8 value) and returns the result.
*/
function neg(euint8 value) internal returns (euint8) {
if (!isInitialized(value)) {
value = asEuint8(0);
}
return euint8.wrap(Impl.neg(euint8.unwrap(value)));
}
/**
* @dev Evaluates not(euint8 value) and returns the result.
*/
function not(euint8 value) internal returns (euint8) {
if (!isInitialized(value)) {
value = asEuint8(0);
}
return euint8.wrap(Impl.not(euint8.unwrap(value)));
}
/**
* @dev Evaluates neg(euint16 value) and returns the result.
*/
function neg(euint16 value) internal returns (euint16) {
if (!isInitialized(value)) {
value = asEuint16(0);
}
return euint16.wrap(Impl.neg(euint16.unwrap(value)));
}
/**
* @dev Evaluates not(euint16 value) and returns the result.
*/
function not(euint16 value) internal returns (euint16) {
if (!isInitialized(value)) {
value = asEuint16(0);
}
return euint16.wrap(Impl.not(euint16.unwrap(value)));
}
/**
* @dev Evaluates neg(euint32 value) and returns the result.
*/
function neg(euint32 value) internal returns (euint32) {
if (!isInitialized(value)) {
value = asEuint32(0);
}
return euint32.wrap(Impl.neg(euint32.unwrap(value)));
}
/**
* @dev Evaluates not(euint32 value) and returns the result.
*/
function not(euint32 value) internal returns (euint32) {
if (!isInitialized(value)) {
value = asEuint32(0);
}
return euint32.wrap(Impl.not(euint32.unwrap(value)));
}
/**
* @dev Evaluates neg(euint64 value) and returns the result.
*/
function neg(euint64 value) internal returns (euint64) {
if (!isInitialized(value)) {
value = asEuint64(0);
}
return euint64.wrap(Impl.neg(euint64.unwrap(value)));
}
/**
* @dev Evaluates not(euint64 value) and returns the result.
*/
function not(euint64 value) internal returns (euint64) {
if (!isInitialized(value)) {
value = asEuint64(0);
}
return euint64.wrap(Impl.not(euint64.unwrap(value)));
}
/**
* @dev Evaluates neg(euint128 value) and returns the result.
*/
function neg(euint128 value) internal returns (euint128) {
if (!isInitialized(value)) {
value = asEuint128(0);
}
return euint128.wrap(Impl.neg(euint128.unwrap(value)));
}
/**
* @dev Evaluates not(euint128 value) and returns the result.
*/
function not(euint128 value) internal returns (euint128) {
if (!isInitialized(value)) {
value = asEuint128(0);
}
return euint128.wrap(Impl.not(euint128.unwrap(value)));
}
/**
* @dev Evaluates neg(euint256 value) and returns the result.
*/
function neg(euint256 value) internal returns (euint256) {
if (!isInitialized(value)) {
value = asEuint256(0);
}
return euint256.wrap(Impl.neg(euint256.unwrap(value)));
}
/**
* @dev Evaluates not(euint256 value) and returns the result.
*/
function not(euint256 value) internal returns (euint256) {
if (!isInitialized(value)) {
value = asEuint256(0);
}
return euint256.wrap(Impl.not(euint256.unwrap(value)));
}
/**
* @dev Convert an inputHandle with corresponding inputProof to an encrypted ebool integer.
* @dev If inputProof is empty, the externalEbool inputHandle can be used as a regular ebool handle if it
* has already been verified and allowed to the sender.
* This could facilitate integrating smart contract accounts with fhevm.
*/
function fromExternal(externalEbool inputHandle, bytes memory inputProof) internal returns (ebool) {
if (inputProof.length != 0) {
return ebool.wrap(Impl.verify(externalEbool.unwrap(inputHandle), inputProof, FheType.Bool));
} else {
bytes32 inputBytes32 = externalEbool.unwrap(inputHandle);
if (!Impl.isAllowed(inputBytes32, msg.sender)) revert SenderNotAllowedToUseHandle(inputBytes32, msg.sender);
return ebool.wrap(inputBytes32);
}
}
/**
* @dev Converts a plaintext boolean to an encrypted boolean.
*/
function asEbool(bool value) internal returns (ebool) {
return ebool.wrap(Impl.trivialEncrypt(value ? 1 : 0, FheType.Bool));
}
/**
* @dev Convert an inputHandle with corresponding inputProof to an encrypted euint8 integer.
* @dev If inputProof is empty, the externalEuint8 inputHandle can be used as a regular euint8 handle if it
* has already been verified and allowed to the sender.
* This could facilitate integrating smart contract accounts with fhevm.
*/
function fromExternal(externalEuint8 inputHandle, bytes memory inputProof) internal returns (euint8) {
if (inputProof.length != 0) {
return euint8.wrap(Impl.verify(externalEuint8.unwrap(inputHandle), inputProof, FheType.Uint8));
} else {
bytes32 inputBytes32 = externalEuint8.unwrap(inputHandle);
if (!Impl.isAllowed(inputBytes32, msg.sender)) revert SenderNotAllowedToUseHandle(inputBytes32, msg.sender);
return euint8.wrap(inputBytes32);
}
}
/**
* @dev Convert a plaintext value to an encrypted euint8 integer.
*/
function asEuint8(uint8 value) internal returns (euint8) {
return euint8.wrap(Impl.trivialEncrypt(uint256(value), FheType.Uint8));
}
/**
* @dev Convert an inputHandle with corresponding inputProof to an encrypted euint16 integer.
* @dev If inputProof is empty, the externalEuint16 inputHandle can be used as a regular euint16 handle if it
* has already been verified and allowed to the sender.
* This could facilitate integrating smart contract accounts with fhevm.
*/
function fromExternal(externalEuint16 inputHandle, bytes memory inputProof) internal returns (euint16) {
if (inputProof.length != 0) {
return euint16.wrap(Impl.verify(externalEuint16.unwrap(inputHandle), inputProof, FheType.Uint16));
} else {
bytes32 inputBytes32 = externalEuint16.unwrap(inputHandle);
if (!Impl.isAllowed(inputBytes32, msg.sender)) revert SenderNotAllowedToUseHandle(inputBytes32, msg.sender);
return euint16.wrap(inputBytes32);
}
}
/**
* @dev Convert a plaintext value to an encrypted euint16 integer.
*/
function asEuint16(uint16 value) internal returns (euint16) {
return euint16.wrap(Impl.trivialEncrypt(uint256(value), FheType.Uint16));
}
/**
* @dev Convert an inputHandle with corresponding inputProof to an encrypted euint32 integer.
* @dev If inputProof is empty, the externalEuint32 inputHandle can be used as a regular euint32 handle if it
* has already been verified and allowed to the sender.
* This could facilitate integrating smart contract accounts with fhevm.
*/
function fromExternal(externalEuint32 inputHandle, bytes memory inputProof) internal returns (euint32) {
if (inputProof.length != 0) {
return euint32.wrap(Impl.verify(externalEuint32.unwrap(inputHandle), inputProof, FheType.Uint32));
} else {
bytes32 inputBytes32 = externalEuint32.unwrap(inputHandle);
if (!Impl.isAllowed(inputBytes32, msg.sender)) revert SenderNotAllowedToUseHandle(inputBytes32, msg.sender);
return euint32.wrap(inputBytes32);
}
}
/**
* @dev Convert a plaintext value to an encrypted euint32 integer.
*/
function asEuint32(uint32 value) internal returns (euint32) {
return euint32.wrap(Impl.trivialEncrypt(uint256(value), FheType.Uint32));
}
/**
* @dev Convert an inputHandle with corresponding inputProof to an encrypted euint64 integer.
* @dev If inputProof is empty, the externalEuint64 inputHandle can be used as a regular euint64 handle if it
* has already been verified and allowed to the sender.
* This could facilitate integrating smart contract accounts with fhevm.
*/
function fromExternal(externalEuint64 inputHandle, bytes memory inputProof) internal returns (euint64) {
if (inputProof.length != 0) {
return euint64.wrap(Impl.verify(externalEuint64.unwrap(inputHandle), inputProof, FheType.Uint64));
} else {
bytes32 inputBytes32 = externalEuint64.unwrap(inputHandle);
if (!Impl.isAllowed(inputBytes32, msg.sender)) revert SenderNotAllowedToUseHandle(inputBytes32, msg.sender);
return euint64.wrap(inputBytes32);
}
}
/**
* @dev Convert a plaintext value to an encrypted euint64 integer.
*/
function asEuint64(uint64 value) internal returns (euint64) {
return euint64.wrap(Impl.trivialEncrypt(uint256(value), FheType.Uint64));
}
/**
* @dev Convert an inputHandle with corresponding inputProof to an encrypted euint128 integer.
* @dev If inputProof is empty, the externalEuint128 inputHandle can be used as a regular euint128 handle if it
* has already been verified and allowed to the sender.
* This could facilitate integrating smart contract accounts with fhevm.
*/
function fromExternal(externalEuint128 inputHandle, bytes memory inputProof) internal returns (euint128) {
if (inputProof.length != 0) {
return euint128.wrap(Impl.verify(externalEuint128.unwrap(inputHandle), inputProof, FheType.Uint128));
} else {
bytes32 inputBytes32 = externalEuint128.unwrap(inputHandle);
if (!Impl.isAllowed(inputBytes32, msg.sender)) revert SenderNotAllowedToUseHandle(inputBytes32, msg.sender);
return euint128.wrap(inputBytes32);
}
}
/**
* @dev Convert a plaintext value to an encrypted euint128 integer.
*/
function asEuint128(uint128 value) internal returns (euint128) {
return euint128.wrap(Impl.trivialEncrypt(uint256(value), FheType.Uint128));
}
/**
* @dev Convert an inputHandle with corresponding inputProof to an encrypted eaddress integer.
* @dev If inputProof is empty, the externalEaddress inputHandle can be used as a regular eaddress handle if it
* has already been verified and allowed to the sender.
* This could facilitate integrating smart contract accounts with fhevm.
*/
function fromExternal(externalEaddress inputHandle, bytes memory inputProof) internal returns (eaddress) {
if (inputProof.length != 0) {
return eaddress.wrap(Impl.verify(externalEaddress.unwrap(inputHandle), inputProof, FheType.Uint160));
} else {
bytes32 inputBytes32 = externalEaddress.unwrap(inputHandle);
if (!Impl.isAllowed(inputBytes32, msg.sender)) revert SenderNotAllowedToUseHandle(inputBytes32, msg.sender);
return eaddress.wrap(inputBytes32);
}
}
/**
* @dev Convert a plaintext value to an encrypted eaddress integer.
*/
function asEaddress(address value) internal returns (eaddress) {
return eaddress.wrap(Impl.trivialEncrypt(uint256(uint160(value)), FheType.Uint160));
}
/**
* @dev Convert an inputHandle with corresponding inputProof to an encrypted euint256 integer.
* @dev If inputProof is empty, the externalEuint256 inputHandle can be used as a regular euint256 handle if it
* has already been verified and allowed to the sender.
* This could facilitate integrating smart contract accounts with fhevm.
*/
function fromExternal(externalEuint256 inputHandle, bytes memory inputProof) internal returns (euint256) {
if (inputProof.length != 0) {
return euint256.wrap(Impl.verify(externalEuint256.unwrap(inputHandle), inputProof, FheType.Uint256));
} else {
bytes32 inputBytes32 = externalEuint256.unwrap(inputHandle);
if (!Impl.isAllowed(inputBytes32, msg.sender)) revert SenderNotAllowedToUseHandle(inputBytes32, msg.sender);
return euint256.wrap(inputBytes32);
}
}
/**
* @dev Convert a plaintext value to an encrypted euint256 integer.
*/
function asEuint256(uint256 value) internal returns (euint256) {
return euint256.wrap(Impl.trivialEncrypt(uint256(value), FheType.Uint256));
}
/**
* @dev Generates a random encrypted value.
*/
function randEbool() internal returns (ebool) {
return ebool.wrap(Impl.rand(FheType.Bool));
}
/**
* @dev Generates a random encrypted value.
*/
function randEuint8() internal returns (euint8) {
return euint8.wrap(Impl.rand(FheType.Uint8));
}
/**
* @dev Generates a random encrypted 8-bit unsigned integer in the [0, upperBound) range.
* The upperBound must be a power of 2.
*/
function randEuint8(uint8 upperBound) internal returns (euint8) {
return euint8.wrap(Impl.randBounded(upperBound, FheType.Uint8));
}
/**
* @dev Generates a random encrypted value.
*/
function randEuint16() internal returns (euint16) {
return euint16.wrap(Impl.rand(FheType.Uint16));
}
/**
* @dev Generates a random encrypted 16-bit unsigned integer in the [0, upperBound) range.
* The upperBound must be a power of 2.
*/
function randEuint16(uint16 upperBound) internal returns (euint16) {
return euint16.wrap(Impl.randBounded(upperBound, FheType.Uint16));
}
/**
* @dev Generates a random encrypted value.
*/
function randEuint32() internal returns (euint32) {
return euint32.wrap(Impl.rand(FheType.Uint32));
}
/**
* @dev Generates a random encrypted 32-bit unsigned integer in the [0, upperBound) range.
* The upperBound must be a power of 2.
*/
function randEuint32(uint32 upperBound) internal returns (euint32) {
return euint32.wrap(Impl.randBounded(upperBound, FheType.Uint32));
}
/**
* @dev Generates a random encrypted value.
*/
function randEuint64() internal returns (euint64) {
return euint64.wrap(Impl.rand(FheType.Uint64));
}
/**
* @dev Generates a random encrypted 64-bit unsigned integer in the [0, upperBound) range.
* The upperBound must be a power of 2.
*/
function randEuint64(uint64 upperBound) internal returns (euint64) {
return euint64.wrap(Impl.randBounded(upperBound, FheType.Uint64));
}
/**
* @dev Generates a random encrypted value.
*/
function randEuint128() internal returns (euint128) {
return euint128.wrap(Impl.rand(FheType.Uint128));
}
/**
* @dev Generates a random encrypted 128-bit unsigned integer in the [0, upperBound) range.
* The upperBound must be a power of 2.
*/
function randEuint128(uint128 upperBound) internal returns (euint128) {
return euint128.wrap(Impl.randBounded(upperBound, FheType.Uint128));
}
/**
* @dev Generates a random encrypted value.
*/
function randEuint256() internal returns (euint256) {
return euint256.wrap(Impl.rand(FheType.Uint256));
}
/**
* @dev Generates a random encrypted 256-bit unsigned integer in the [0, upperBound) range.
* The upperBound must be a power of 2.
*/
function randEuint256(uint256 upperBound) internal returns (euint256) {
return euint256.wrap(Impl.randBounded(upperBound, FheType.Uint256));
}
/**
* @dev This function cleans the transient storage for the ACL (accounts) and the InputVerifier
* (input proofs).
* This could be useful for integration with Account Abstraction when bundling several
* UserOps calling the FHEVMExecutor.
*/
function cleanTransientStorage() internal {
Impl.cleanTransientStorageACL();
Impl.cleanTransientStorageInputVerifier();
}
/**
* @dev Returns whether the account is allowed to use the value.
*/
function isAllowed(ebool value, address account) internal view returns (bool) {
return Impl.isAllowed(ebool.unwrap(value), account);
}
/**
* @dev Returns whether the sender is allowed to use the value.
*/
function isSenderAllowed(ebool value) internal view returns (bool) {
return Impl.isAllowed(ebool.unwrap(value), msg.sender);
}
/**
* @dev Allows the use of value for the address account.
*/
function allow(ebool value, address account) internal returns (ebool) {
if (!isInitialized(value)) {
value = asEbool(false);
}
Impl.allow(ebool.unwrap(value), account);
return value;
}
/**
* @dev Allows the use of value for this address (address(this)).
*/
function allowThis(ebool value) internal returns (ebool) {
if (!isInitialized(value)) {
value = asEbool(false);
}
Impl.allow(ebool.unwrap(value), address(this));
return value;
}
/**
* @dev Allows the use of value by address account for this transaction.
*/
function allowTransient(ebool value, address account) internal returns (ebool) {
if (!isInitialized(value)) {
value = asEbool(false);
}
Impl.allowTransient(ebool.unwrap(value), account);
return value;
}
/**
* @dev Makes the value publicly decryptable.
*/
function makePubliclyDecryptable(ebool value) internal returns (ebool) {
if (!isInitialized(value)) {
value = asEbool(false);
}
Impl.makePubliclyDecryptable(ebool.unwrap(value));
return value;
}
/**
* @dev Returns whether the the value is publicly decryptable.
*/
function isPubliclyDecryptable(ebool value) internal view returns (bool) {
return Impl.isPubliclyDecryptable(ebool.unwrap(value));
}
/**
* @dev Returns whether the account is allowed to use the value.
*/
function isAllowed(euint8 value, address account) internal view returns (bool) {
return Impl.isAllowed(euint8.unwrap(value), account);
}
/**
* @dev Returns whether the sender is allowed to use the value.
*/
function isSenderAllowed(euint8 value) internal view returns (bool) {
return Impl.isAllowed(euint8.unwrap(value), msg.sender);
}
/**
* @dev Allows the use of value for the address account.
*/
function allow(euint8 value, address account) internal returns (euint8) {
if (!isInitialized(value)) {
value = asEuint8(0);
}
Impl.allow(euint8.unwrap(value), account);
return value;
}
/**
* @dev Allows the use of value for this address (address(this)).
*/
function allowThis(euint8 value) internal returns (euint8) {
if (!isInitialized(value)) {
value = asEuint8(0);
}
Impl.allow(euint8.unwrap(value), address(this));
return value;
}
/**
* @dev Allows the use of value by address account for this transaction.
*/
function allowTransient(euint8 value, address account) internal returns (euint8) {
if (!isInitialized(value)) {
value = asEuint8(0);
}
Impl.allowTransient(euint8.unwrap(value), account);
return value;
}
/**
* @dev Makes the value publicly decryptable.
*/
function makePubliclyDecryptable(euint8 value) internal returns (euint8) {
if (!isInitialized(value)) {
value = asEuint8(0);
}
Impl.makePubliclyDecryptable(euint8.unwrap(value));
return value;
}
/**
* @dev Returns whether the the value is publicly decryptable.
*/
function isPubliclyDecryptable(euint8 value) internal view returns (bool) {
return Impl.isPubliclyDecryptable(euint8.unwrap(value));
}
/**
* @dev Returns whether the account is allowed to use the value.
*/
function isAllowed(euint16 value, address account) internal view returns (bool) {
return Impl.isAllowed(euint16.unwrap(value), account);
}
/**
* @dev Returns whether the sender is allowed to use the value.
*/
function isSenderAllowed(euint16 value) internal view returns (bool) {
return Impl.isAllowed(euint16.unwrap(value), msg.sender);
}
/**
* @dev Allows the use of value for the address account.
*/
function allow(euint16 value, address account) internal returns (euint16) {
if (!isInitialized(value)) {
value = asEuint16(0);
}
Impl.allow(euint16.unwrap(value), account);
return value;
}
/**
* @dev Allows the use of value for this address (address(this)).
*/
function allowThis(euint16 value) internal returns (euint16) {
if (!isInitialized(value)) {
value = asEuint16(0);
}
Impl.allow(euint16.unwrap(value), address(this));
return value;
}
/**
* @dev Allows the use of value by address account for this transaction.
*/
function allowTransient(euint16 value, address account) internal returns (euint16) {
if (!isInitialized(value)) {
value = asEuint16(0);
}
Impl.allowTransient(euint16.unwrap(value), account);
return value;
}
/**
* @dev Makes the value publicly decryptable.
*/
function makePubliclyDecryptable(euint16 value) internal returns (euint16) {
if (!isInitialized(value)) {
value = asEuint16(0);
}
Impl.makePubliclyDecryptable(euint16.unwrap(value));
return value;
}
/**
* @dev Returns whether the the value is publicly decryptable.
*/
function isPubliclyDecryptable(euint16 value) internal view returns (bool) {
return Impl.isPubliclyDecryptable(euint16.unwrap(value));
}
/**
* @dev Returns whether the account is allowed to use the value.
*/
function isAllowed(euint32 value, address account) internal view returns (bool) {
return Impl.isAllowed(euint32.unwrap(value), account);
}
/**
* @dev Returns whether the sender is allowed to use the value.
*/
function isSenderAllowed(euint32 value) internal view returns (bool) {
return Impl.isAllowed(euint32.unwrap(value), msg.sender);
}
/**
* @dev Allows the use of value for the address account.
*/
function allow(euint32 value, address account) internal returns (euint32) {
if (!isInitialized(value)) {
value = asEuint32(0);
}
Impl.allow(euint32.unwrap(value), account);
return value;
}
/**
* @dev Allows the use of value for this address (address(this)).
*/
function allowThis(euint32 value) internal returns (euint32) {
if (!isInitialized(value)) {
value = asEuint32(0);
}
Impl.allow(euint32.unwrap(value), address(this));
return value;
}
/**
* @dev Allows the use of value by address account for this transaction.
*/
function allowTransient(euint32 value, address account) internal returns (euint32) {
if (!isInitialized(value)) {
value = asEuint32(0);
}
Impl.allowTransient(euint32.unwrap(value), account);
return value;
}
/**
* @dev Makes the value publicly decryptable.
*/
function makePubliclyDecryptable(euint32 value) internal returns (euint32) {
if (!isInitialized(value)) {
value = asEuint32(0);
}
Impl.makePubliclyDecryptable(euint32.unwrap(value));
return value;
}
/**
* @dev Returns whether the the value is publicly decryptable.
*/
function isPubliclyDecryptable(euint32 value) internal view returns (bool) {
return Impl.isPubliclyDecryptable(euint32.unwrap(value));
}
/**
* @dev Returns whether the account is allowed to use the value.
*/
function isAllowed(euint64 value, address account) internal view returns (bool) {
return Impl.isAllowed(euint64.unwrap(value), account);
}
/**
* @dev Returns whether the sender is allowed to use the value.
*/
function isSenderAllowed(euint64 value) internal view returns (bool) {
return Impl.isAllowed(euint64.unwrap(value), msg.sender);
}
/**
* @dev Allows the use of value for the address account.
*/
function allow(euint64 value, address account) internal returns (euint64) {
if (!isInitialized(value)) {
value = asEuint64(0);
}
Impl.allow(euint64.unwrap(value), account);
return value;
}
/**
* @dev Allows the use of value for this address (address(this)).
*/
function allowThis(euint64 value) internal returns (euint64) {
if (!isInitialized(value)) {
value = asEuint64(0);
}
Impl.allow(euint64.unwrap(value), address(this));
return value;
}
/**
* @dev Allows the use of value by address account for this transaction.
*/
function allowTransient(euint64 value, address account) internal returns (euint64) {
if (!isInitialized(value)) {
value = asEuint64(0);
}
Impl.allowTransient(euint64.unwrap(value), account);
return value;
}
/**
* @dev Makes the value publicly decryptable.
*/
function makePubliclyDecryptable(euint64 value) internal returns (euint64) {
if (!isInitialized(value)) {
value = asEuint64(0);
}
Impl.makePubliclyDecryptable(euint64.unwrap(value));
return value;
}
/**
* @dev Returns whether the the value is publicly decryptable.
*/
function isPubliclyDecryptable(euint64 value) internal view returns (bool) {
return Impl.isPubliclyDecryptable(euint64.unwrap(value));
}
/**
* @dev Returns whether the account is allowed to use the value.
*/
function isAllowed(euint128 value, address account) internal view returns (bool) {
return Impl.isAllowed(euint128.unwrap(value), account);
}
/**
* @dev Returns whether the sender is allowed to use the value.
*/
function isSenderAllowed(euint128 value) internal view returns (bool) {
return Impl.isAllowed(euint128.unwrap(value), msg.sender);
}
/**
* @dev Allows the use of value for the address account.
*/
function allow(euint128 value, address account) internal returns (euint128) {
if (!isInitialized(value)) {
value = asEuint128(0);
}
Impl.allow(euint128.unwrap(value), account);
return value;
}
/**
* @dev Allows the use of value for this address (address(this)).
*/
function allowThis(euint128 value) internal returns (euint128) {
if (!isInitialized(value)) {
value = asEuint128(0);
}
Impl.allow(euint128.unwrap(value), address(this));
return value;
}
/**
* @dev Allows the use of value by address account for this transaction.
*/
function allowTransient(euint128 value, address account) internal returns (euint128) {
if (!isInitialized(value)) {
value = asEuint128(0);
}
Impl.allowTransient(euint128.unwrap(value), account);
return value;
}
/**
* @dev Makes the value publicly decryptable.
*/
function makePubliclyDecryptable(euint128 value) internal returns (euint128) {
if (!isInitialized(value)) {
value = asEuint128(0);
}
Impl.makePubliclyDecryptable(euint128.unwrap(value));
return value;
}
/**
* @dev Returns whether the the value is publicly decryptable.
*/
function isPubliclyDecryptable(euint128 value) internal view returns (bool) {
return Impl.isPubliclyDecryptable(euint128.unwrap(value));
}
/**
* @dev Returns whether the account is allowed to use the value.
*/
function isAllowed(eaddress value, address account) internal view returns (bool) {
return Impl.isAllowed(eaddress.unwrap(value), account);
}
/**
* @dev Returns whether the sender is allowed to use the value.
*/
function isSenderAllowed(eaddress value) internal view returns (bool) {
return Impl.isAllowed(eaddress.unwrap(value), msg.sender);
}
/**
* @dev Allows the use of value for the address account.
*/
function allow(eaddress value, address account) internal returns (eaddress) {
if (!isInitialized(value)) {
value = asEaddress(address(0));
}
Impl.allow(eaddress.unwrap(value), account);
return value;
}
/**
* @dev Allows the use of value for this address (address(this)).
*/
function allowThis(eaddress value) internal returns (eaddress) {
if (!isInitialized(value)) {
value = asEaddress(address(0));
}
Impl.allow(eaddress.unwrap(value), address(this));
return value;
}
/**
* @dev Allows the use of value by address account for this transaction.
*/
function allowTransient(eaddress value, address account) internal returns (eaddress) {
if (!isInitialized(value)) {
value = asEaddress(address(0));
}
Impl.allowTransient(eaddress.unwrap(value), account);
return value;
}
/**
* @dev Makes the value publicly decryptable.
*/
function makePubliclyDecryptable(eaddress value) internal returns (eaddress) {
if (!isInitialized(value)) {
value = asEaddress(address(0));
}
Impl.makePubliclyDecryptable(eaddress.unwrap(value));
return value;
}
/**
* @dev Returns whether the the value is publicly decryptable.
*/
function isPubliclyDecryptable(eaddress value) internal view returns (bool) {
return Impl.isPubliclyDecryptable(eaddress.unwrap(value));
}
/**
* @dev Returns whether the account is allowed to use the value.
*/
function isAllowed(euint256 value, address account) internal view returns (bool) {
return Impl.isAllowed(euint256.unwrap(value), account);
}
/**
* @dev Returns whether the sender is allowed to use the value.
*/
function isSenderAllowed(euint256 value) internal view returns (bool) {
return Impl.isAllowed(euint256.unwrap(value), msg.sender);
}
/**
* @dev Allows the use of value for the address account.
*/
function allow(euint256 value, address account) internal returns (euint256) {
if (!isInitialized(value)) {
value = asEuint256(0);
}
Impl.allow(euint256.unwrap(value), account);
return value;
}
/**
* @dev Allows the use of value for this address (address(this)).
*/
function allowThis(euint256 value) internal returns (euint256) {
if (!isInitialized(value)) {
value = asEuint256(0);
}
Impl.allow(euint256.unwrap(value), address(this));
return value;
}
/**
* @dev Allows the use of value by address account for this transaction.
*/
function allowTransient(euint256 value, address account) internal returns (euint256) {
if (!isInitialized(value)) {
value = asEuint256(0);
}
Impl.allowTransient(euint256.unwrap(value), account);
return value;
}
/**
* @dev Makes the value publicly decryptable.
*/
function makePubliclyDecryptable(euint256 value) internal returns (euint256) {
if (!isInitialized(value)) {
value = asEuint256(0);
}
Impl.makePubliclyDecryptable(euint256.unwrap(value));
return value;
}
/**
* @dev Returns whether the the value is publicly decryptable.
*/
function isPubliclyDecryptable(euint256 value) internal view returns (bool) {
return Impl.isPubliclyDecryptable(euint256.unwrap(value));
}
/**
* @dev Returns whether the account is on the deny list.
*/
function isAccountDenied(address account) internal view returns (bool) {
return Impl.isAccountDenied(account);
}
/// @notice Checks if the `handle` can be decrypted in the given context (`user`, `contractAddress`).
/// @param handle The handle as a bytes32.
/// @param user The account address that is part of the user decryption context.
/// @param contractAddress The address of the contract that is part of the user decryption context.
/// @return False if `user` has not (user, contractAddress) context.
function isUserDecryptable(bytes32 handle, address user, address contractAddress) internal view returns (bool) {
if (user == contractAddress) {
return false;
}
return Impl.persistAllowed(handle, user) && Impl.persistAllowed(handle, contractAddress);
}
/// @notice Checks if the user decryption rights have been delegated by `delegator` to `delegate`
/// in the context of the given `contractAddress`.
/// @param delegator The delegator address
/// @param delegate The account authorized to request user decryptions on behalf of `delegator`
/// @param contractAddress The address of the contract that is part of the user decryption context
/// @param handle The handle as a bytes32
/// @return False if no active delegation exists for the (delegate, contractAddress) context, or if it has expired.
function isDelegatedForUserDecryption(
address delegator,
address delegate,
address contractAddress,
bytes32 handle
) internal view returns (bool) {
return Impl.isDelegatedForUserDecryption(delegator, delegate, contractAddress, handle);
}
/// @notice Delegates the user decryption rights that caller contract (`address(this)`) holds in the context
/// of the given `contractAddress` to a new `delegate` account for a limited amount of time.
/// @dev The ACL grants user decryption permission based on a (User, Contract) pair. If the pair
/// (`address(this)`, `contractAddress`) has permission to decrypt a handle, calling this function grants
/// the temporary permission to the new pair (`delegate`, `contractAddress`) to decrypt the same handle.
/// @param delegate The account that will request a user decryption on behalf of delegator (`address(this)`).
/// @param contractAddress The address of the contract that is part of the user decryption context.
/// @param expirationDate UNIX timestamp when the delegation expires.
///
/// @dev Requirements:
/// - the ACL contract must not be paused.
/// Reverts via an {PausableUpgradeable-EnforcedPause} error otherwise.
///
/// - `expirationDate` must be at least 1 hour in the future.
/// i.e. `expirationDate >= block.timestamp + 1 hours`
/// Reverts with an {IACL-ExpirationDateBeforeOneHour} error otherwise.
///
/// - `expirationDate` must differ from the current value.
/// Reverts with an {IACL-ExpirationDateAlreadySetToSameValue} error otherwise.
///
/// - at most one delegate OR revoke per block for this
/// (address(this), delegate, contractAddress) tuple to avoid racey
/// state updates.
/// Reverts with an {IACL-AlreadyDelegatedOrRevokedInSameBlock} error
/// if a delegate OR revoke operation already occurred in the current
/// block. See {canDelegateOrRevokeNow}
///
/// - The `contractAddress` cannot be the caller contract (`address(this)`).
/// Reverts with an {IACL-SenderCannotBeContractAddress} error if
/// `contractAddress == address(this)`.
///
/// - The `delegate` address cannot be the caller contract (`address(this)`).
/// Reverts with an {IACL-SenderCannotBeDelegate} error if
/// `delegate == address(this)`.
///
/// - The `delegate` address cannot be the `contractAddress`.
/// Reverts with an {IACL-DelegateCannotBeContractAddress} error if
/// `delegate == contractAddress`.
function delegateUserDecryption(address delegate, address contractAddress, uint64 expirationDate) internal {
Impl.delegateForUserDecryption(delegate, contractAddress, expirationDate);
}
/// @notice Permanently delegates the user decryption rights that the caller contract (`address(this)`) holds in the
/// context of the given `contractAddress` to a new `delegate` account.
/// @dev This is the version without expiration of {delegateUserDecryption}. The permission remains active until explicitly
/// revoked by the delegator using {revokeUserDecryptionDelegation}.
/// @param delegate The account that will request a user decryption on behalf of delegator (`address(this)`).
/// @param contractAddress The address of the contract that is part of the user decryption context.
function delegateUserDecryptionWithoutExpiration(address delegate, address contractAddress) internal {
Impl.delegateForUserDecryption(delegate, contractAddress, type(uint64).max);
}
/// @notice Batch delegates the user decryption rights that the caller contract (`address(this)`) holds in the context of the
/// given `contractAddresses[i]` to a new `delegate` account for a limited amount of time.
/// @param delegate The account that will request a user decryption on behalf of delegator (`address(this)`)..
/// @param contractAddresses The array of contract addresses that form the user decryption context tuples
/// (`address(this)`, `contractAddresses[i]`).
/// @param expirationDate UNIX timestamp when the delegation expires.
function delegateUserDecryptions(
address delegate,
address[] memory contractAddresses,
uint64 expirationDate
) internal {
Impl.delegateForUserDecryptions(delegate, contractAddresses, expirationDate);
}
/// @notice Batch delegates user decryption rights without expiration that the caller contract (`address(this)`) holds in the context of
/// the given `contractAddresses[i]` to a new `delegate` account.
/// @param delegate The account that will request a user decryption on behalf of delegator (`address(this)`)..
/// @param contractAddresses The array of contract addresses that form the user decryption context tuples
/// (`address(this)`, `contractAddresses[i]`).
function delegateUserDecryptionsWithoutExpiration(address delegate, address[] memory contractAddresses) internal {
Impl.delegateForUserDecryptions(delegate, contractAddresses, type(uint64).max);
}
/// @notice Revoke an existing delegation from delegator `address(this)` to a (delegate, contractAddress) user
/// decryption context.
/// @param delegate The account that was authorized to request user decryptions on behalf of the caller contract `address(this)`
/// @param contractAddress The address of the contract that is part of the user decryption context
/// @dev Requirements:
/// - the ACL contract must not be paused.
/// Reverts with an {PausableUpgradeable-EnforcedPause} error otherwise.
///
/// - at most one delegate OR revoke per block for this
/// (address(this), delegate, contractAddress) tuple to avoid racey
/// state updates.
/// Reverts with an {IACL-AlreadyDelegatedOrRevokedInSameBlock} error
/// if a delegate OR revoke operation already occurred in the current
/// block.
///
/// - An active delegation must exist for the (delegate, contractAddress)
/// context.
/// Reverts with an {IACL-NotDelegatedYet} error otherwise.
function revokeUserDecryptionDelegation(address delegate, address contractAddress) internal {
Impl.revokeDelegationForUserDecryption(delegate, contractAddress);
}
/// @notice Batch revoke existing delegations from delegator `address(this)` to the given
/// (delegate, contractAddresses[i]) pairs.
/// @param delegate The account that was authorized to request user decryptions on behalf of the caller contract `address(this)`
/// @param contractAddresses The array of contract addresses that form the user decryption context tuples
/// (`address(this)`, `contractAddresses[i]`).
function revokeUserDecryptionDelegations(address delegate, address[] memory contractAddresses) internal {
Impl.revokeDelegationsForUserDecryption(delegate, contractAddresses);
}
/// @notice Get the expiry date of the delegation from delegator to a (delegate, contractAddress) pair.
/// @param delegator The delegator address
/// @param delegate The account authorized to request user decryptions on behalf of delegator
/// @param contractAddress The address of the contract that is part of the user decryption context
/// @return expirationDate The delegation's expiration limit, which can be one of:
/// - 0 : If no delegation is currently active for the (delegate, contractAddress) context.
/// - type(uint64).max : If the delegation is permanent (no expiry).
/// - A strictly positive UNIX timestamp when this delegation expires.
function getDelegatedUserDecryptionExpirationDate(
address delegator,
address delegate,
address contractAddress
) internal view returns (uint64 expirationDate) {
expirationDate = Impl.getUserDecryptionDelegationExpirationDate(delegator, delegate, contractAddress);
}
/// @notice Reverts if the KMS signatures verification against the provided handles and public decryption data
/// fails.
/// @dev The function MUST be called inside a public decryption callback function of a dApp contract
/// to verify the signatures and prevent fake decryption results for being submitted.
/// @param handlesList The list of handles as an array of bytes32 to check
/// @param abiEncodedCleartexts The ABI-encoded list of decrypted values associated with each handle in the `handlesList`.
/// The ABI-encoded list order must match the `handlesList` order.
/// @param decryptionProof The KMS public decryption proof. It includes the KMS signatures, associated metadata,
/// and the context needed for verification.
/// @dev Reverts if any of the following conditions are met:
/// - The `decryptionProof` is empty or has an invalid length.
/// - The number of valid signatures is zero or less than the configured KMS signers threshold.
/// - Any signature is produced by an address that is not a registered KMS signer.
/// - The signatures verification returns false.
function checkSignatures(
bytes32[] memory handlesList,
bytes memory abiEncodedCleartexts,
bytes memory decryptionProof
) internal {
bool isVerified = _verifySignatures(handlesList, abiEncodedCleartexts, decryptionProof);
if (!isVerified) {
revert InvalidKMSSignatures();
}
emit PublicDecryptionVerified(handlesList, abiEncodedCleartexts);
}
/// @notice Verifies KMS signatures against the provided handles and public decryption data.
/// @param handlesList The list of handles as an array of bytes32 to verify
/// @param abiEncodedCleartexts The ABI-encoded list of decrypted values associated with each handle in the `handlesList`.
/// The list order must match the list of handles in `handlesList`
/// @param decryptionProof The KMS public decryption proof computed by the KMS Signers associated to `handlesList` and
/// `abiEncodedCleartexts`
/// @return true if the signatures verification succeeds, false otherwise
/// @dev Private low-level function used to verify the KMS signatures.
/// Warning: this function never reverts, its boolean return value must be checked.
/// The decryptionProof is the numSigners + kmsSignatures + extraData (1 + 65*numSigners + extraData bytes)
/// Only static native solidity types for clear values are supported, so `abiEncodedCleartexts` is the concatenation of all clear values appended to 32 bytes.
/// @dev Reverts if any of the following conditions are met by the underlying KMS verifier:
/// - The `decryptionProof` is empty or has an invalid length.
/// - The number of valid signatures is zero or less than the configured KMS signers threshold.
/// - Any signature is produced by an address that is not a registered KMS signer.
function _verifySignatures(
bytes32[] memory handlesList,
bytes memory abiEncodedCleartexts,
bytes memory decryptionProof
) private returns (bool) {
CoprocessorConfig storage $ = Impl.getCoprocessorConfig();
return
IKMSVerifier($.KMSVerifierAddress).verifyDecryptionEIP712KMSSignatures(
handlesList,
abiEncodedCleartexts,
decryptionProof
);
}
/**
* @dev Converts handle from its custom type to the underlying bytes32. Used when requesting a decryption.
*/
function toBytes32(ebool value) internal pure returns (bytes32 ct) {
ct = ebool.unwrap(value);
}
/**
* @dev Converts handle from its custom type to the underlying bytes32. Used when requesting a decryption.
*/
function toBytes32(euint8 value) internal pure returns (bytes32 ct) {
ct = euint8.unwrap(value);
}
/**
* @dev Converts handle from its custom type to the underlying bytes32. Used when requesting a decryption.
*/
function toBytes32(euint16 value) internal pure returns (bytes32 ct) {
ct = euint16.unwrap(value);
}
/**
* @dev Converts handle from its custom type to the underlying bytes32. Used when requesting a decryption.
*/
function toBytes32(euint32 value) internal pure returns (bytes32 ct) {
ct = euint32.unwrap(value);
}
/**
* @dev Converts handle from its custom type to the underlying bytes32. Used when requesting a decryption.
*/
function toBytes32(euint64 value) internal pure returns (bytes32 ct) {
ct = euint64.unwrap(value);
}
/**
* @dev Converts handle from its custom type to the underlying bytes32. Used when requesting a decryption.
*/
function toBytes32(euint128 value) internal pure returns (bytes32 ct) {
ct = euint128.unwrap(value);
}
/**
* @dev Converts handle from its custom type to the underlying bytes32. Used when requesting a decryption.
*/
function toBytes32(eaddress value) internal pure returns (bytes32 ct) {
ct = eaddress.unwrap(value);
}
/**
* @dev Converts handle from its custom type to the underlying bytes32. Used when requesting a decryption.
*/
function toBytes32(euint256 value) internal pure returns (bytes32 ct) {
ct = euint256.unwrap(value);
}
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: BSD-3-Clause-Clear
pragma solidity ^0.8.24;
enum FheType {
Bool,
Uint4,
Uint8,
Uint16,
Uint32,
Uint64,
Uint128,
Uint160,
Uint256,
Uint512,
Uint1024,
Uint2048,
Uint2,
Uint6,
Uint10,
Uint12,
Uint14,
Int2,
Int4,
Int6,
Int8,
Int10,
Int12,
Int14,
Int16,
Int32,
Int64,
Int128,
Int160,
Int256,
AsciiString,
Int512,
Int1024,
Int2048,
Uint24,
Uint40,
Uint48,
Uint56,
Uint72,
Uint80,
Uint88,
Uint96,
Uint104,
Uint112,
Uint120,
Uint136,
Uint144,
Uint152,
Uint168,
Uint176,
Uint184,
Uint192,
Uint200,
Uint208,
Uint216,
Uint224,
Uint232,
Uint240,
Uint248,
Int24,
Int40,
Int48,
Int56,
Int72,
Int80,
Int88,
Int96,
Int104,
Int112,
Int120,
Int136,
Int144,
Int152,
Int168,
Int176,
Int184,
Int192,
Int200,
Int208,
Int216,
Int224,
Int232,
Int240,
Int248
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: BSD-3-Clause-Clear
pragma solidity ^0.8.24;
import {FheType} from "./FheType.sol";
/**
* @title CoprocessorConfig
* @notice This struct contains all addresses of core contracts, which are needed in a typical dApp.
*/
struct CoprocessorConfig {
address ACLAddress;
address CoprocessorAddress;
address KMSVerifierAddress;
}
/**
* @title IFHEVMExecutor
* @notice This interface contains all functions to conduct FHE operations.
*/
interface IFHEVMExecutor {
/**
* @notice Computes fheAdd operation.
* @param lhs LHS.
* @param rhs RHS.
* @param scalarByte Scalar byte.
* @return result Result.
*/
function fheAdd(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
/**
* @notice Computes fheSub operation.
* @param lhs LHS.
* @param rhs RHS.
* @param scalarByte Scalar byte.
* @return result Result.
*/
function fheSub(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
/**
* @notice Computes fheMul operation.
* @param lhs LHS.
* @param rhs RHS.
* @param scalarByte Scalar byte.
* @return result Result.
*/
function fheMul(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
/**
* @notice Computes fheDiv operation.
* @param lhs LHS.
* @param rhs RHS.
* @param scalarByte Scalar byte.
* @return result Result.
*/
function fheDiv(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
/**
* @notice Computes fheRem operation.
* @param lhs LHS.
* @param rhs RHS.
* @param scalarByte Scalar byte.
* @return result Result.
*/
function fheRem(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
/**
* @notice Computes fheBitAnd operation.
* @param lhs LHS.
* @param rhs RHS.
* @param scalarByte Scalar byte.
* @return result Result.
*/
function fheBitAnd(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
/**
* @notice Computes fheBitOr operation.
* @param lhs LHS.
* @param rhs RHS.
* @param scalarByte Scalar byte.
* @return result Result.
*/
function fheBitOr(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
/**
* @notice Computes fheBitXor operation.
* @param lhs LHS.
* @param rhs RHS.
* @param scalarByte Scalar byte.
* @return result Result.
*/
function fheBitXor(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
/**
* @notice Computes fheShl operation.
* @param lhs LHS.
* @param rhs RHS.
* @param scalarByte Scalar byte.
* @return result Result.
*/
function fheShl(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
/**
* @notice Computes fheShr operation.
* @param lhs LHS.
* @param rhs RHS.
* @param scalarByte Scalar byte.
* @return result Result.
*/
function fheShr(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
/**
* @notice Computes fheRotl operation.
* @param lhs LHS.
* @param rhs RHS.
* @param scalarByte Scalar byte.
* @return result Result.
*/
function fheRotl(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
/**
* @notice Computes fheRotr operation.
* @param lhs LHS.
* @param rhs RHS.
* @param scalarByte Scalar byte.
* @return result Result.
*/
function fheRotr(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
/**
* @notice Computes fheEq operation.
* @param lhs LHS.
* @param rhs RHS.
* @param scalarByte Scalar byte.
* @return result Result.
*/
function fheEq(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
/**
* @notice Computes fheNe operation.
* @param lhs LHS.
* @param rhs RHS.
* @param scalarByte Scalar byte.
* @return result Result.
*/
function fheNe(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
/**
* @notice Computes fheGe operation.
* @param lhs LHS.
* @param rhs RHS.
* @param scalarByte Scalar byte.
* @return result Result.
*/
function fheGe(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
/**
* @notice Computes fheGt operation.
* @param lhs LHS.
* @param rhs RHS.
* @param scalarByte Scalar byte.
* @return result Result.
*/
function fheGt(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
/**
* @notice Computes fheLe operation.
* @param lhs LHS.
* @param rhs RHS.
* @param scalarByte Scalar byte.
* @return result Result.
*/
function fheLe(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
/**
* @notice Computes fheLt operation.
* @param lhs LHS.
* @param rhs RHS.
* @param scalarByte Scalar byte.
* @return result Result.
*/
function fheLt(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
/**
* @notice Computes fheMin operation.
* @param lhs LHS.
* @param rhs RHS.
* @param scalarByte Scalar byte.
* @return result Result.
*/
function fheMin(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
/**
* @notice Computes fheMax operation.
* @param lhs LHS.
* @param rhs RHS.
* @param scalarByte Scalar byte.
* @return result Result.
*/
function fheMax(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
/**
* @notice Computes fheNeg operation.
* @param ct Ct
* @return result Result.
*/
function fheNeg(bytes32 ct) external returns (bytes32 result);
/**
* @notice Computes fheNot operation.
* @param ct Ct
* @return result Result.
*/
function fheNot(bytes32 ct) external returns (bytes32 result);
/**
* @notice Verifies the ciphertext.
* @param inputHandle Input handle.
* @param callerAddress Address of the caller.
* @param inputProof Input proof.
* @param inputType Input type.
* @return result Result.
*/
function verifyInput(
bytes32 inputHandle,
address callerAddress,
bytes memory inputProof,
FheType inputType
) external returns (bytes32 result);
/**
* @notice Performs the casting to a target type.
* @param ct Value to cast.
* @param toType Target type.
* @return result Result value of the target type.
*/
function cast(bytes32 ct, FheType toType) external returns (bytes32 result);
/**
* @notice Does trivial encryption.
* @param ct Value to encrypt.
* @param toType Target type.
* @return result Result value of the target type.
*/
function trivialEncrypt(uint256 ct, FheType toType) external returns (bytes32 result);
/**
* @notice Computes FHEIfThenElse operation.
* @param control Control value.
* @param ifTrue If true.
* @param ifFalse If false.
* @return result Result.
*/
function fheIfThenElse(bytes32 control, bytes32 ifTrue, bytes32 ifFalse) external returns (bytes32 result);
/**
* @notice Computes FHERand operation.
* @param randType Type for the random result.
* @return result Result.
*/
function fheRand(FheType randType) external returns (bytes32 result);
/**
* @notice Computes FHERandBounded operation.
* @param upperBound Upper bound value.
* @param randType Type for the random result.
* @return result Result.
*/
function fheRandBounded(uint256 upperBound, FheType randType) external returns (bytes32 result);
/**
* @notice Returns the address of the InputVerifier contract used by the coprocessor.
* @return inputVerifierAddress Address of the InputVerifier.
*/
function getInputVerifierAddress() external view returns (address);
}
/**
* @title IACL.
* @notice This interface contains all functions that are used to conduct operations
* with the ACL contract.
*/
interface IACL {
/**
* @notice Executes a batch of encoded calls on the ACL contract.
* @param data Array containing the ABI-encoded function calls.
* @return results Return payloads for each call in `data`.
*/
function multicall(bytes[] calldata data) external payable returns (bytes[] memory results);
/**
* @notice Allows the use of handle by address account for this transaction.
* @dev The caller must be allowed to use handle for allowTransient() to succeed.
* If not, allowTransient() reverts.
* The Coprocessor contract can always allowTransient(), contrarily to allow().
* @param ciphertext Ciphertext.
* @param account Address of the account.
*/
function allowTransient(bytes32 ciphertext, address account) external;
/**
* @notice Allows the use of handle for the address account.
* @dev The caller must be allowed to use handle for allow() to succeed. If not, allow() reverts.
* @param handle Handle.
* @param account Address of the account.
*/
function allow(bytes32 handle, address account) external;
/**
* @dev This function removes the transient allowances, which could be useful for integration with
* Account Abstraction when bundling several UserOps calling the FHEVMExecutor Coprocessor.
*/
function cleanTransientStorage() external;
/**
* @notice Returns whether the account is allowed to use the handle, either due to
* allowTransient() or allow().
* @param handle Handle.
* @param account Address of the account.
* @return isAllowed Whether the account can access the handle.
*/
function isAllowed(bytes32 handle, address account) external view returns (bool);
/**
* @notice Allows a list of handles to be decrypted.
* @param handlesList List of handles.
*/
function allowForDecryption(bytes32[] memory handlesList) external;
/**
* @notice Returns wether a handle is allowed to be publicly decrypted.
* @param handle Handle.
* @return isDecryptable Whether the handle can be publicly decrypted.
*/
function isAllowedForDecryption(bytes32 handle) external view returns (bool);
/**
* @notice Returns whether the account is persistently allowed to use the handle.
* @param handle Handle.
* @param account Address of the account.
*/
function persistAllowed(bytes32 handle, address account) external view returns (bool);
/**
* @notice Returns whether the account is on the deny list.
* @param account Address of the account.
* @return isAccountDenied Whether the account is on the deny list.
*/
function isAccountDenied(address account) external view returns (bool);
/**
* @notice Delegates user decryption rights to `delegate` for the specified `contractAddress`.
* @param delegate The delegate account.
* @param contractAddress The contract address forming the user decryption context.
* @param expirationDate UNIX timestamp when the delegation expires.
*/
function delegateForUserDecryption(address delegate, address contractAddress, uint64 expirationDate) external;
/**
* @notice Revokes previously delegated user decryption rights.
* @param delegate The delegate account.
* @param contractAddress The contract address forming the user decryption context.
*/
function revokeDelegationForUserDecryption(address delegate, address contractAddress) external;
/**
* @notice Returns the expiration date for delegated user decryption rights.
* @param delegator The delegator account.
* @param delegate The delegate account.
* @param contractAddress The contract address forming the user decryption context.
*/
function getUserDecryptionDelegationExpirationDate(
address delegator,
address delegate,
address contractAddress
) external view returns (uint64);
/**
* @notice Returns whether an account is delegated to access the handle for user decryption.
* @param delegator The address of the account that delegates access to its handles.
* @param delegate The address of the account that receives the delegation.
* @param contractAddress The contract address to delegate access to.
* @param handle The handle to check for delegated user decryption.
* @return isDelegatedForUserDecryption Whether the handle can be accessed for delegated user decryption.
*/
function isHandleDelegatedForUserDecryption(
address delegator,
address delegate,
address contractAddress,
bytes32 handle
) external view returns (bool);
}
/**
* @title IInputVerifier
* @notice This interface contains the only function required from InputVerifier.
*/
interface IInputVerifier {
/**
* @dev This function removes the transient allowances, which could be useful for integration with
* Account Abstraction when bundling several UserOps calling the FHEVMExecutor Coprocessor.
*/
function cleanTransientStorage() external;
}
/**
* @title Impl
* @notice This library is the core implementation for computing FHE operations (e.g. add, sub, xor).
*/
library Impl {
/// keccak256(abi.encode(uint256(keccak256("confidential.storage.config")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant CoprocessorConfigLocation =
0x9e7b61f58c47dc699ac88507c4f5bb9f121c03808c5676a8078fe583e4649700;
/**
* @dev Returns the Coprocessor config.
*/
function getCoprocessorConfig() internal pure returns (CoprocessorConfig storage $) {
assembly {
$.slot := CoprocessorConfigLocation
}
}
/**
* @notice Sets the coprocessor addresses.
* @param coprocessorConfig Coprocessor config struct that contains contract addresses.
*/
function setCoprocessor(CoprocessorConfig memory coprocessorConfig) internal {
CoprocessorConfig storage $ = getCoprocessorConfig();
$.ACLAddress = coprocessorConfig.ACLAddress;
$.CoprocessorAddress = coprocessorConfig.CoprocessorAddress;
$.KMSVerifierAddress = coprocessorConfig.KMSVerifierAddress;
}
function add(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
bytes1 scalarByte;
if (scalar) {
scalarByte = 0x01;
} else {
scalarByte = 0x00;
}
CoprocessorConfig storage $ = getCoprocessorConfig();
result = IFHEVMExecutor($.CoprocessorAddress).fheAdd(lhs, rhs, scalarByte);
}
function sub(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
bytes1 scalarByte;
if (scalar) {
scalarByte = 0x01;
} else {
scalarByte = 0x00;
}
CoprocessorConfig storage $ = getCoprocessorConfig();
result = IFHEVMExecutor($.CoprocessorAddress).fheSub(lhs, rhs, scalarByte);
}
function mul(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
bytes1 scalarByte;
if (scalar) {
scalarByte = 0x01;
} else {
scalarByte = 0x00;
}
CoprocessorConfig storage $ = getCoprocessorConfig();
result = IFHEVMExecutor($.CoprocessorAddress).fheMul(lhs, rhs, scalarByte);
}
function div(bytes32 lhs, bytes32 rhs) internal returns (bytes32 result) {
bytes1 scalarByte = 0x01;
CoprocessorConfig storage $ = getCoprocessorConfig();
result = IFHEVMExecutor($.CoprocessorAddress).fheDiv(lhs, rhs, scalarByte);
}
function rem(bytes32 lhs, bytes32 rhs) internal returns (bytes32 result) {
bytes1 scalarByte = 0x01;
CoprocessorConfig storage $ = getCoprocessorConfig();
result = IFHEVMExecutor($.CoprocessorAddress).fheRem(lhs, rhs, scalarByte);
}
function and(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
bytes1 scalarByte;
if (scalar) {
scalarByte = 0x01;
} else {
scalarByte = 0x00;
}
CoprocessorConfig storage $ = getCoprocessorConfig();
result = IFHEVMExecutor($.CoprocessorAddress).fheBitAnd(lhs, rhs, scalarByte);
}
function or(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
bytes1 scalarByte;
if (scalar) {
scalarByte = 0x01;
} else {
scalarByte = 0x00;
}
CoprocessorConfig storage $ = getCoprocessorConfig();
result = IFHEVMExecutor($.CoprocessorAddress).fheBitOr(lhs, rhs, scalarByte);
}
function xor(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
bytes1 scalarByte;
if (scalar) {
scalarByte = 0x01;
} else {
scalarByte = 0x00;
}
CoprocessorConfig storage $ = getCoprocessorConfig();
result = IFHEVMExecutor($.CoprocessorAddress).fheBitXor(lhs, rhs, scalarByte);
}
function shl(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
bytes1 scalarByte;
if (scalar) {
scalarByte = 0x01;
} else {
scalarByte = 0x00;
}
CoprocessorConfig storage $ = getCoprocessorConfig();
result = IFHEVMExecutor($.CoprocessorAddress).fheShl(lhs, rhs, scalarByte);
}
function shr(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
bytes1 scalarByte;
if (scalar) {
scalarByte = 0x01;
} else {
scalarByte = 0x00;
}
CoprocessorConfig storage $ = getCoprocessorConfig();
result = IFHEVMExecutor($.CoprocessorAddress).fheShr(lhs, rhs, scalarByte);
}
function rotl(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
bytes1 scalarByte;
if (scalar) {
scalarByte = 0x01;
} else {
scalarByte = 0x00;
}
CoprocessorConfig storage $ = getCoprocessorConfig();
result = IFHEVMExecutor($.CoprocessorAddress).fheRotl(lhs, rhs, scalarByte);
}
function rotr(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
bytes1 scalarByte;
if (scalar) {
scalarByte = 0x01;
} else {
scalarByte = 0x00;
}
CoprocessorConfig storage $ = getCoprocessorConfig();
result = IFHEVMExecutor($.CoprocessorAddress).fheRotr(lhs, rhs, scalarByte);
}
function eq(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
bytes1 scalarByte;
if (scalar) {
scalarByte = 0x01;
} else {
scalarByte = 0x00;
}
CoprocessorConfig storage $ = getCoprocessorConfig();
result = IFHEVMExecutor($.CoprocessorAddress).fheEq(lhs, rhs, scalarByte);
}
function ne(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
bytes1 scalarByte;
if (scalar) {
scalarByte = 0x01;
} else {
scalarByte = 0x00;
}
CoprocessorConfig storage $ = getCoprocessorConfig();
result = IFHEVMExecutor($.CoprocessorAddress).fheNe(lhs, rhs, scalarByte);
}
function ge(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
bytes1 scalarByte;
if (scalar) {
scalarByte = 0x01;
} else {
scalarByte = 0x00;
}
CoprocessorConfig storage $ = getCoprocessorConfig();
result = IFHEVMExecutor($.CoprocessorAddress).fheGe(lhs, rhs, scalarByte);
}
function gt(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
bytes1 scalarByte;
if (scalar) {
scalarByte = 0x01;
} else {
scalarByte = 0x00;
}
CoprocessorConfig storage $ = getCoprocessorConfig();
result = IFHEVMExecutor($.CoprocessorAddress).fheGt(lhs, rhs, scalarByte);
}
function le(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
bytes1 scalarByte;
if (scalar) {
scalarByte = 0x01;
} else {
scalarByte = 0x00;
}
CoprocessorConfig storage $ = getCoprocessorConfig();
result = IFHEVMExecutor($.CoprocessorAddress).fheLe(lhs, rhs, scalarByte);
}
function lt(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
bytes1 scalarByte;
if (scalar) {
scalarByte = 0x01;
} else {
scalarByte = 0x00;
}
CoprocessorConfig storage $ = getCoprocessorConfig();
result = IFHEVMExecutor($.CoprocessorAddress).fheLt(lhs, rhs, scalarByte);
}
function min(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
bytes1 scalarByte;
if (scalar) {
scalarByte = 0x01;
} else {
scalarByte = 0x00;
}
CoprocessorConfig storage $ = getCoprocessorConfig();
result = IFHEVMExecutor($.CoprocessorAddress).fheMin(lhs, rhs, scalarByte);
}
function max(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
bytes1 scalarByte;
if (scalar) {
scalarByte = 0x01;
} else {
scalarByte = 0x00;
}
CoprocessorConfig storage $ = getCoprocessorConfig();
result = IFHEVMExecutor($.CoprocessorAddress).fheMax(lhs, rhs, scalarByte);
}
function neg(bytes32 ct) internal returns (bytes32 result) {
CoprocessorConfig storage $ = getCoprocessorConfig();
result = IFHEVMExecutor($.CoprocessorAddress).fheNeg(ct);
}
function not(bytes32 ct) internal returns (bytes32 result) {
CoprocessorConfig storage $ = getCoprocessorConfig();
result = IFHEVMExecutor($.CoprocessorAddress).fheNot(ct);
}
/**
* @dev If 'control's value is 'true', the result has the same value as 'ifTrue'.
* If 'control's value is 'false', the result has the same value as 'ifFalse'.
*/
function select(bytes32 control, bytes32 ifTrue, bytes32 ifFalse) internal returns (bytes32 result) {
CoprocessorConfig storage $ = getCoprocessorConfig();
result = IFHEVMExecutor($.CoprocessorAddress).fheIfThenElse(control, ifTrue, ifFalse);
}
/**
* @notice Verifies the ciphertext (FHEVMExecutor) and allows transient (ACL).
* @param inputHandle Input handle.
* @param inputProof Input proof.
* @param toType Input type.
* @return result Result.
*/
function verify(bytes32 inputHandle, bytes memory inputProof, FheType toType) internal returns (bytes32 result) {
CoprocessorConfig storage $ = getCoprocessorConfig();
result = IFHEVMExecutor($.CoprocessorAddress).verifyInput(inputHandle, msg.sender, inputProof, toType);
IACL($.ACLAddress).allowTransient(result, msg.sender);
}
/**
* @notice Performs the casting to a target type.
* @param ciphertext Ciphertext to cast.
* @param toType Target type.
* @return result Result value of the target type.
*/
function cast(bytes32 ciphertext, FheType toType) internal returns (bytes32 result) {
CoprocessorConfig storage $ = getCoprocessorConfig();
result = IFHEVMExecutor($.CoprocessorAddress).cast(ciphertext, toType);
}
/**
* @notice Does trivial encryption.
* @param value Value to encrypt.
* @param toType Target type.
* @return result Result value of the target type.
*/
function trivialEncrypt(uint256 value, FheType toType) internal returns (bytes32 result) {
CoprocessorConfig storage $ = getCoprocessorConfig();
result = IFHEVMExecutor($.CoprocessorAddress).trivialEncrypt(value, toType);
}
function rand(FheType randType) internal returns (bytes32 result) {
CoprocessorConfig storage $ = getCoprocessorConfig();
result = IFHEVMExecutor($.CoprocessorAddress).fheRand(randType);
}
function randBounded(uint256 upperBound, FheType randType) internal returns (bytes32 result) {
CoprocessorConfig storage $ = getCoprocessorConfig();
result = IFHEVMExecutor($.CoprocessorAddress).fheRandBounded(upperBound, randType);
}
/**
* @notice Allows the use of handle by address account for this transaction.
* @dev The caller must be allowed to use handle for allowTransient() to succeed.
* If not, allowTransient() reverts.
* The Coprocessor contract can always allowTransient(), contrarily to allow().
* @param handle Handle.
* @param account Address of the account.
*/
function allowTransient(bytes32 handle, address account) internal {
CoprocessorConfig storage $ = getCoprocessorConfig();
IACL($.ACLAddress).allowTransient(handle, account);
}
/**
* @notice Allows the use of handle for the address account.
* @dev The caller must be allowed to use handle for allow() to succeed. If not, allow() reverts.
* @param handle Handle.
* @param account Address of the account.
*/
function allow(bytes32 handle, address account) internal {
CoprocessorConfig storage $ = getCoprocessorConfig();
IACL($.ACLAddress).allow(handle, account);
}
/**
* @notice Allows the handle to be publicly decryptable.
* @dev The caller must be allowed to use handle for makePubliclyDecryptable() to succeed.
* If not, makePubliclyDecryptable() reverts.
* @param handle Handle.
*/
function makePubliclyDecryptable(bytes32 handle) internal {
CoprocessorConfig storage $ = getCoprocessorConfig();
bytes32[] memory handleArray = new bytes32[](1);
handleArray[0] = handle;
IACL($.ACLAddress).allowForDecryption(handleArray);
}
/**
* @dev This function removes the transient allowances in the ACL, which could be useful for integration
* with Account Abstraction when bundling several UserOps calling the FHEVMExecutor Coprocessor.
*/
function cleanTransientStorageACL() internal {
CoprocessorConfig storage $ = getCoprocessorConfig();
IACL($.ACLAddress).cleanTransientStorage();
}
/**
* @dev This function removes the transient proofs in the InputVerifier, which could be useful for integration
* with Account Abstraction when bundling several UserOps calling the FHEVMExecutor Coprocessor.
*/
function cleanTransientStorageInputVerifier() internal {
CoprocessorConfig storage $ = getCoprocessorConfig();
address inputVerifierAddress = IFHEVMExecutor($.CoprocessorAddress).getInputVerifierAddress();
IInputVerifier(inputVerifierAddress).cleanTransientStorage();
}
/**
* @notice Returns whether the account is allowed to use the handle, either due to
* allowTransient() or allow().
* @param handle Handle.
* @param account Address of the account.
* @return isAllowed Whether the account can access the handle.
*/
function isAllowed(bytes32 handle, address account) internal view returns (bool) {
CoprocessorConfig storage $ = getCoprocessorConfig();
return IACL($.ACLAddress).isAllowed(handle, account);
}
/**
* @notice Returns whether the handle is allowed to be publicly decrypted.
* @param handle Handle.
* @return isAllowed Whether the handle can be publicly decrypted.
*/
function isPubliclyDecryptable(bytes32 handle) internal view returns (bool) {
CoprocessorConfig storage $ = getCoprocessorConfig();
return IACL($.ACLAddress).isAllowedForDecryption(handle);
}
/**
* @notice Returns whether the account is persistently allowed to use the handle.
* @param handle Handle.
* @param account Address of the account.
* @return isAllowed Whether the account can access the handle persistently.
*/
function persistAllowed(bytes32 handle, address account) internal view returns (bool) {
CoprocessorConfig storage $ = getCoprocessorConfig();
return IACL($.ACLAddress).persistAllowed(handle, account);
}
/**
* @notice Returns whether the account is on the deny list.
* @param account Address of the account.
* @return isAccountDenied Whether the account is on the deny list.
*/
function isAccountDenied(address account) internal view returns (bool) {
CoprocessorConfig storage $ = getCoprocessorConfig();
return IACL($.ACLAddress).isAccountDenied(account);
}
/**
* @notice Delegates user decryption rights to `delegate` for the specified `contractAddress`.
* @param delegate The delegate account.
* @param contractAddress The contract address forming the user decryption context.
* @param expirationDate UNIX timestamp when the delegation expires.
*/
function delegateForUserDecryption(address delegate, address contractAddress, uint64 expirationDate) internal {
CoprocessorConfig storage $ = getCoprocessorConfig();
IACL($.ACLAddress).delegateForUserDecryption(delegate, contractAddress, expirationDate);
}
/**
* @notice Delegates user decryption rights in batch leveraging the ACL multicall helper.
* @param delegate The delegate account.
* @param contractAddresses Array of contract addresses forming the user decryption contexts.
* @param expirationDate UNIX timestamp when the delegation expires.
*/
function delegateForUserDecryptions(
address delegate,
address[] memory contractAddresses,
uint64 expirationDate
) internal {
uint256 length = contractAddresses.length;
if (length == 0) {
return;
}
CoprocessorConfig storage $ = getCoprocessorConfig();
if (length == 1) {
IACL($.ACLAddress).delegateForUserDecryption(delegate, contractAddresses[0], expirationDate);
return;
}
bytes[] memory calls = new bytes[](length);
for (uint256 i = 0; i < length; ++i) {
calls[i] = abi.encodeCall(IACL.delegateForUserDecryption, (delegate, contractAddresses[i], expirationDate));
}
IACL($.ACLAddress).multicall(calls);
}
/**
* @notice Revokes previously delegated user decryption rights.
* @param delegate The delegate account.
* @param contractAddress The contract address forming the user decryption context.
*/
function revokeDelegationForUserDecryption(address delegate, address contractAddress) internal {
CoprocessorConfig storage $ = getCoprocessorConfig();
IACL($.ACLAddress).revokeDelegationForUserDecryption(delegate, contractAddress);
}
/**
* @notice Revokes delegated user decryption rights in batch leveraging the ACL multicall helper.
* @param delegate The delegate account.
* @param contractAddresses Array of contract addresses forming the user decryption contexts.
*/
function revokeDelegationsForUserDecryption(address delegate, address[] memory contractAddresses) internal {
uint256 length = contractAddresses.length;
if (length == 0) {
return;
}
CoprocessorConfig storage $ = getCoprocessorConfig();
if (length == 1) {
IACL($.ACLAddress).revokeDelegationForUserDecryption(delegate, contractAddresses[0]);
return;
}
bytes[] memory calls = new bytes[](length);
for (uint256 i = 0; i < length; ++i) {
calls[i] = abi.encodeCall(IACL.revokeDelegationForUserDecryption, (delegate, contractAddresses[i]));
}
IACL($.ACLAddress).multicall(calls);
}
/**
* @notice Returns the expiration date for delegated user decryption rights.
* @param delegator The delegator account.
* @param delegate The delegate account.
* @param contractAddress The contract address forming the user decryption context.
* @return expirationDate The UNIX timestamp when the delegation expires.
*/
function getUserDecryptionDelegationExpirationDate(
address delegator,
address delegate,
address contractAddress
) internal view returns (uint64) {
CoprocessorConfig storage $ = getCoprocessorConfig();
return IACL($.ACLAddress).getUserDecryptionDelegationExpirationDate(delegator, delegate, contractAddress);
}
/**
* @notice Returns whether the handle is delegated for user decryption.
* @param delegator The delegator account.
* @param delegate The delegate account.
* @param contractAddress The contract address forming the user decryption context.
* @param handle The handle.
* @return isDelegated Whether the handle is delegated for user decryption.
*/
function isDelegatedForUserDecryption(
address delegator,
address delegate,
address contractAddress,
bytes32 handle
) internal view returns (bool) {
CoprocessorConfig storage $ = getCoprocessorConfig();
return IACL($.ACLAddress).isHandleDelegatedForUserDecryption(delegator, delegate, contractAddress, handle);
}
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
// OpenZeppelin Confidential Contracts (last updated v0.3.0) (interfaces/IERC7984.sol)
pragma solidity ^0.8.24;
import {euint64, externalEuint64} from "@fhevm/solidity/lib/FHE.sol";
import {IERC165} from "@openzeppelin/contracts/interfaces/IERC165.sol";
/// @dev Draft interface for a confidential fungible token standard utilizing the Zama FHE library.
interface IERC7984 is IERC165 {
/**
* @dev Emitted when the expiration timestamp for an operator `operator` is updated for a given `holder`.
* The operator may move any amount of tokens on behalf of the holder until the timestamp `until`.
*/
event OperatorSet(address indexed holder, address indexed operator, uint48 until);
/// @dev Emitted when a confidential transfer is made from `from` to `to` of encrypted amount `amount`.
event ConfidentialTransfer(address indexed from, address indexed to, euint64 indexed amount);
/**
* @dev Emitted when an encrypted amount is disclosed.
*
* Accounts with access to the encrypted amount `encryptedAmount` that is also accessible to this contract
* should be able to disclose the amount. This functionality is implementation specific.
*/
event AmountDisclosed(euint64 indexed encryptedAmount, uint64 amount);
/// @dev Returns the name of the token.
function name() external view returns (string memory);
/// @dev Returns the symbol of the token.
function symbol() external view returns (string memory);
/// @dev Returns the number of decimals of the token. Recommended to be 6.
function decimals() external view returns (uint8);
/// @dev Returns the contract URI. See https://eips.ethereum.org/EIPS/eip-7572[ERC-7572] for details.
function contractURI() external view returns (string memory);
/// @dev Returns the confidential total supply of the token.
function confidentialTotalSupply() external view returns (euint64);
/// @dev Returns the confidential balance of the account `account`.
function confidentialBalanceOf(address account) external view returns (euint64);
/// @dev Returns true if `spender` is currently an operator for `holder`.
function isOperator(address holder, address spender) external view returns (bool);
/**
* @dev Sets `operator` as an operator for `holder` until the timestamp `until`.
*
* NOTE: An operator may transfer any amount of tokens on behalf of a holder while approved.
*/
function setOperator(address operator, uint48 until) external;
/**
* @dev Transfers the encrypted amount `encryptedAmount` to `to` with the given input proof `inputProof`.
*
* Returns the encrypted amount that was actually transferred.
*/
function confidentialTransfer(
address to,
externalEuint64 encryptedAmount,
bytes calldata inputProof
) external returns (euint64);
/**
* @dev Similar to {confidentialTransfer-address-externalEuint64-bytes} but without an input proof. The caller
* *must* already be allowed by ACL for the given `amount`.
*/
function confidentialTransfer(address to, euint64 amount) external returns (euint64 transferred);
/**
* @dev Transfers the encrypted amount `encryptedAmount` from `from` to `to` with the given input proof
* `inputProof`. `msg.sender` must be either `from` or an operator for `from`.
*
* Returns the encrypted amount that was actually transferred.
*/
function confidentialTransferFrom(
address from,
address to,
externalEuint64 encryptedAmount,
bytes calldata inputProof
) external returns (euint64);
/**
* @dev Similar to {confidentialTransferFrom-address-address-externalEuint64-bytes} but without an input proof.
* The caller *must* be already allowed by ACL for the given `amount`.
*/
function confidentialTransferFrom(address from, address to, euint64 amount) external returns (euint64 transferred);
/**
* @dev Similar to {confidentialTransfer-address-externalEuint64-bytes} but with a callback to `to` after
* the transfer.
*
* The callback is made to the {IERC7984Receiver-onConfidentialTransferReceived} function on the
* to address with the actual transferred amount (may differ from the given `encryptedAmount`) and the given
* data `data`.
*/
function confidentialTransferAndCall(
address to,
externalEuint64 encryptedAmount,
bytes calldata inputProof,
bytes calldata data
) external returns (euint64 transferred);
/// @dev Similar to {confidentialTransfer-address-euint64} but with a callback to `to` after the transfer.
function confidentialTransferAndCall(
address to,
euint64 amount,
bytes calldata data
) external returns (euint64 transferred);
/**
* @dev Similar to {confidentialTransferFrom-address-address-externalEuint64-bytes} but with a callback to `to`
* after the transfer.
*/
function confidentialTransferFromAndCall(
address from,
address to,
externalEuint64 encryptedAmount,
bytes calldata inputProof,
bytes calldata data
) external returns (euint64 transferred);
/**
* @dev Similar to {confidentialTransferFrom-address-address-euint64} but with a callback to `to`
* after the transfer.
*
*/
function confidentialTransferFromAndCall(
address from,
address to,
euint64 amount,
bytes calldata data
) external returns (euint64 transferred);
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (access/AccessControl.sol)
pragma solidity ^0.8.20;
import {IAccessControl} from "./IAccessControl.sol";
import {Context} from "../utils/Context.sol";
import {IERC165, ERC165} from "../utils/introspection/ERC165.sol";
/**
* @dev Contract module that allows children to implement role-based access
* control mechanisms. This is a lightweight version that doesn't allow enumerating role
* members except through off-chain means by accessing the contract event logs. Some
* applications may benefit from on-chain enumerability, for those cases see
* {AccessControlEnumerable}.
*
* Roles are referred to by their `bytes32` identifier. These should be exposed
* in the external API and be unique. The best way to achieve this is by
* using `public constant` hash digests:
*
* ```solidity
* bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
* ```
*
* Roles can be used to represent a set of permissions. To restrict access to a
* function call, use {hasRole}:
*
* ```solidity
* function foo() public {
* require(hasRole(MY_ROLE, msg.sender));
* ...
* }
* ```
*
* Roles can be granted and revoked dynamically via the {grantRole} and
* {revokeRole} functions. Each role has an associated admin role, and only
* accounts that have a role's admin role can call {grantRole} and {revokeRole}.
*
* By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
* that only accounts with this role will be able to grant or revoke other
* roles. More complex role relationships can be created by using
* {_setRoleAdmin}.
*
* WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
* grant and revoke this role. Extra precautions should be taken to secure
* accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}
* to enforce additional security measures for this role.
*/
abstract contract AccessControl is Context, IAccessControl, ERC165 {
struct RoleData {
mapping(address account => bool) hasRole;
bytes32 adminRole;
}
mapping(bytes32 role => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
/**
* @dev Modifier that checks that an account has a specific role. Reverts
* with an {AccessControlUnauthorizedAccount} error including the required role.
*/
modifier onlyRole(bytes32 role) {
_checkRole(role);
_;
}
/// @inheritdoc IERC165
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) public view virtual returns (bool) {
return _roles[role].hasRole[account];
}
/**
* @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`
* is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.
*/
function _checkRole(bytes32 role) internal view virtual {
_checkRole(role, _msgSender());
}
/**
* @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`
* is missing `role`.
*/
function _checkRole(bytes32 role, address account) internal view virtual {
if (!hasRole(role, account)) {
revert AccessControlUnauthorizedAccount(account, role);
}
}
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {
return _roles[role].adminRole;
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*
* May emit a {RoleGranted} event.
*/
function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
_grantRole(role, account);
}
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*
* May emit a {RoleRevoked} event.
*/
function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
_revokeRole(role, account);
}
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been revoked `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `callerConfirmation`.
*
* May emit a {RoleRevoked} event.
*/
function renounceRole(bytes32 role, address callerConfirmation) public virtual {
if (callerConfirmation != _msgSender()) {
revert AccessControlBadConfirmation();
}
_revokeRole(role, callerConfirmation);
}
/**
* @dev Sets `adminRole` as ``role``'s admin role.
*
* Emits a {RoleAdminChanged} event.
*/
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
bytes32 previousAdminRole = getRoleAdmin(role);
_roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
/**
* @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.
*
* Internal function without access restriction.
*
* May emit a {RoleGranted} event.
*/
function _grantRole(bytes32 role, address account) internal virtual returns (bool) {
if (!hasRole(role, account)) {
_roles[role].hasRole[account] = true;
emit RoleGranted(role, account, _msgSender());
return true;
} else {
return false;
}
}
/**
* @dev Attempts to revoke `role` from `account` and returns a boolean indicating if `role` was revoked.
*
* Internal function without access restriction.
*
* May emit a {RoleRevoked} event.
*/
function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {
if (hasRole(role, account)) {
_roles[role].hasRole[account] = false;
emit RoleRevoked(role, account, _msgSender());
return true;
} else {
return false;
}
}
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (access/extensions/AccessControlEnumerable.sol)
pragma solidity ^0.8.20;
import {IAccessControlEnumerable} from "./IAccessControlEnumerable.sol";
import {AccessControl} from "../AccessControl.sol";
import {EnumerableSet} from "../../utils/structs/EnumerableSet.sol";
import {IERC165} from "../../utils/introspection/ERC165.sol";
/**
* @dev Extension of {AccessControl} that allows enumerating the members of each role.
*/
abstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl {
using EnumerableSet for EnumerableSet.AddressSet;
mapping(bytes32 role => EnumerableSet.AddressSet) private _roleMembers;
/// @inheritdoc IERC165
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev Returns one of the accounts that have `role`. `index` must be a
* value between 0 and {getRoleMemberCount}, non-inclusive.
*
* Role bearers are not sorted in any particular way, and their ordering may
* change at any point.
*
* WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
* you perform all queries on the same block. See the following
* https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
* for more information.
*/
function getRoleMember(bytes32 role, uint256 index) public view virtual returns (address) {
return _roleMembers[role].at(index);
}
/**
* @dev Returns the number of accounts that have `role`. Can be used
* together with {getRoleMember} to enumerate all bearers of a role.
*/
function getRoleMemberCount(bytes32 role) public view virtual returns (uint256) {
return _roleMembers[role].length();
}
/**
* @dev Return all accounts that have `role`
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function getRoleMembers(bytes32 role) public view virtual returns (address[] memory) {
return _roleMembers[role].values();
}
/**
* @dev Overload {AccessControl-_grantRole} to track enumerable memberships
*/
function _grantRole(bytes32 role, address account) internal virtual override returns (bool) {
bool granted = super._grantRole(role, account);
if (granted) {
_roleMembers[role].add(account);
}
return granted;
}
/**
* @dev Overload {AccessControl-_revokeRole} to track enumerable memberships
*/
function _revokeRole(bytes32 role, address account) internal virtual override returns (bool) {
bool revoked = super._revokeRole(role, account);
if (revoked) {
_roleMembers[role].remove(account);
}
return revoked;
}
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (access/extensions/IAccessControlEnumerable.sol)
pragma solidity >=0.8.4;
import {IAccessControl} from "../IAccessControl.sol";
/**
* @dev External interface of AccessControlEnumerable declared to support ERC-165 detection.
*/
interface IAccessControlEnumerable is IAccessControl {
/**
* @dev Returns one of the accounts that have `role`. `index` must be a
* value between 0 and {getRoleMemberCount}, non-inclusive.
*
* Role bearers are not sorted in any particular way, and their ordering may
* change at any point.
*
* WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
* you perform all queries on the same block. See the following
* https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
* for more information.
*/
function getRoleMember(bytes32 role, uint256 index) external view returns (address);
/**
* @dev Returns the number of accounts that have `role`. Can be used
* together with {getRoleMember} to enumerate all bearers of a role.
*/
function getRoleMemberCount(bytes32 role) external view returns (uint256);
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (access/IAccessControl.sol)
pragma solidity >=0.8.4;
/**
* @dev External interface of AccessControl declared to support ERC-165 detection.
*/
interface IAccessControl {
/**
* @dev The `account` is missing a role.
*/
error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);
/**
* @dev The caller of a function is not the expected one.
*
* NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.
*/
error AccessControlBadConfirmation();
/**
* @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
*
* `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
* {RoleAdminChanged} not being emitted to signal this.
*/
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
/**
* @dev Emitted when `account` is granted `role`.
*
* `sender` is the account that originated the contract call. This account bears the admin role (for the granted role).
* Expected in cases where the role was granted using the internal {AccessControl-_grantRole}.
*/
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Emitted when `account` is revoked `role`.
*
* `sender` is the account that originated the contract call:
* - if using `revokeRole`, it is the admin role bearer
* - if using `renounceRole`, it is the role bearer (i.e. `account`)
*/
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) external view returns (bool);
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {AccessControl-_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) external view returns (bytes32);
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function grantRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function revokeRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been granted `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `callerConfirmation`.
*/
function renounceRole(bytes32 role, address callerConfirmation) external;
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC165.sol)
pragma solidity >=0.4.16;
import {IERC165} from "../utils/introspection/IERC165.sol"; <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (proxy/Clones.sol)
pragma solidity ^0.8.20;
import {Create2} from "../utils/Create2.sol";
import {Errors} from "../utils/Errors.sol";
/**
* @dev https://eips.ethereum.org/EIPS/eip-1167[ERC-1167] is a standard for
* deploying minimal proxy contracts, also known as "clones".
*
* > To simply and cheaply clone contract functionality in an immutable way, this standard specifies
* > a minimal bytecode implementation that delegates all calls to a known, fixed address.
*
* The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`
* (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the
* deterministic method.
*/
library Clones {
error CloneArgumentsTooLong();
/**
* @dev Deploys and returns the address of a clone that mimics the behavior of `implementation`.
*
* This function uses the create opcode, which should never revert.
*
* WARNING: This function does not check if `implementation` has code. A clone that points to an address
* without code cannot be initialized. Initialization calls may appear to be successful when, in reality, they
* have no effect and leave the clone uninitialized, allowing a third party to initialize it later.
*/
function clone(address implementation) internal returns (address instance) {
return clone(implementation, 0);
}
/**
* @dev Same as {xref-Clones-clone-address-}[clone], but with a `value` parameter to send native currency
* to the new contract.
*
* WARNING: This function does not check if `implementation` has code. A clone that points to an address
* without code cannot be initialized. Initialization calls may appear to be successful when, in reality, they
* have no effect and leave the clone uninitialized, allowing a third party to initialize it later.
*
* NOTE: Using a non-zero value at creation will require the contract using this function (e.g. a factory)
* to always have enough balance for new deployments. Consider exposing this function under a payable method.
*/
function clone(address implementation, uint256 value) internal returns (address instance) {
if (address(this).balance < value) {
revert Errors.InsufficientBalance(address(this).balance, value);
}
assembly ("memory-safe") {
// Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes
// of the `implementation` address with the bytecode before the address.
mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))
// Packs the remaining 17 bytes of `implementation` with the bytecode after the address.
mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))
instance := create(value, 0x09, 0x37)
}
if (instance == address(0)) {
revert Errors.FailedDeployment();
}
}
/**
* @dev Deploys and returns the address of a clone that mimics the behavior of `implementation`.
*
* This function uses the create2 opcode and a `salt` to deterministically deploy
* the clone. Using the same `implementation` and `salt` multiple times will revert, since
* the clones cannot be deployed twice at the same address.
*
* WARNING: This function does not check if `implementation` has code. A clone that points to an address
* without code cannot be initialized. Initialization calls may appear to be successful when, in reality, they
* have no effect and leave the clone uninitialized, allowing a third party to initialize it later.
*/
function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {
return cloneDeterministic(implementation, salt, 0);
}
/**
* @dev Same as {xref-Clones-cloneDeterministic-address-bytes32-}[cloneDeterministic], but with
* a `value` parameter to send native currency to the new contract.
*
* WARNING: This function does not check if `implementation` has code. A clone that points to an address
* without code cannot be initialized. Initialization calls may appear to be successful when, in reality, they
* have no effect and leave the clone uninitialized, allowing a third party to initialize it later.
*
* NOTE: Using a non-zero value at creation will require the contract using this function (e.g. a factory)
* to always have enough balance for new deployments. Consider exposing this function under a payable method.
*/
function cloneDeterministic(
address implementation,
bytes32 salt,
uint256 value
) internal returns (address instance) {
if (address(this).balance < value) {
revert Errors.InsufficientBalance(address(this).balance, value);
}
assembly ("memory-safe") {
// Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes
// of the `implementation` address with the bytecode before the address.
mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))
// Packs the remaining 17 bytes of `implementation` with the bytecode after the address.
mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))
instance := create2(value, 0x09, 0x37, salt)
}
if (instance == address(0)) {
revert Errors.FailedDeployment();
}
}
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
*/
function predictDeterministicAddress(
address implementation,
bytes32 salt,
address deployer
) internal pure returns (address predicted) {
assembly ("memory-safe") {
let ptr := mload(0x40)
mstore(add(ptr, 0x38), deployer)
mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff)
mstore(add(ptr, 0x14), implementation)
mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73)
mstore(add(ptr, 0x58), salt)
mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37))
predicted := and(keccak256(add(ptr, 0x43), 0x55), 0xffffffffffffffffffffffffffffffffffffffff)
}
}
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
*/
function predictDeterministicAddress(
address implementation,
bytes32 salt
) internal view returns (address predicted) {
return predictDeterministicAddress(implementation, salt, address(this));
}
/**
* @dev Deploys and returns the address of a clone that mimics the behavior of `implementation` with custom
* immutable arguments. These are provided through `args` and cannot be changed after deployment. To
* access the arguments within the implementation, use {fetchCloneArgs}.
*
* This function uses the create opcode, which should never revert.
*
* WARNING: This function does not check if `implementation` has code. A clone that points to an address
* without code cannot be initialized. Initialization calls may appear to be successful when, in reality, they
* have no effect and leave the clone uninitialized, allowing a third party to initialize it later.
*/
function cloneWithImmutableArgs(address implementation, bytes memory args) internal returns (address instance) {
return cloneWithImmutableArgs(implementation, args, 0);
}
/**
* @dev Same as {xref-Clones-cloneWithImmutableArgs-address-bytes-}[cloneWithImmutableArgs], but with a `value`
* parameter to send native currency to the new contract.
*
* WARNING: This function does not check if `implementation` has code. A clone that points to an address
* without code cannot be initialized. Initialization calls may appear to be successful when, in reality, they
* have no effect and leave the clone uninitialized, allowing a third party to initialize it later.
*
* NOTE: Using a non-zero value at creation will require the contract using this function (e.g. a factory)
* to always have enough balance for new deployments. Consider exposing this function under a payable method.
*/
function cloneWithImmutableArgs(
address implementation,
bytes memory args,
uint256 value
) internal returns (address instance) {
if (address(this).balance < value) {
revert Errors.InsufficientBalance(address(this).balance, value);
}
bytes memory bytecode = _cloneCodeWithImmutableArgs(implementation, args);
assembly ("memory-safe") {
instance := create(value, add(bytecode, 0x20), mload(bytecode))
}
if (instance == address(0)) {
revert Errors.FailedDeployment();
}
}
/**
* @dev Deploys and returns the address of a clone that mimics the behavior of `implementation` with custom
* immutable arguments. These are provided through `args` and cannot be changed after deployment. To
* access the arguments within the implementation, use {fetchCloneArgs}.
*
* This function uses the create2 opcode and a `salt` to deterministically deploy the clone. Using the same
* `implementation`, `args` and `salt` multiple times will revert, since the clones cannot be deployed twice
* at the same address.
*
* WARNING: This function does not check if `implementation` has code. A clone that points to an address
* without code cannot be initialized. Initialization calls may appear to be successful when, in reality, they
* have no effect and leave the clone uninitialized, allowing a third party to initialize it later.
*/
function cloneDeterministicWithImmutableArgs(
address implementation,
bytes memory args,
bytes32 salt
) internal returns (address instance) {
return cloneDeterministicWithImmutableArgs(implementation, args, salt, 0);
}
/**
* @dev Same as {xref-Clones-cloneDeterministicWithImmutableArgs-address-bytes-bytes32-}[cloneDeterministicWithImmutableArgs],
* but with a `value` parameter to send native currency to the new contract.
*
* WARNING: This function does not check if `implementation` has code. A clone that points to an address
* without code cannot be initialized. Initialization calls may appear to be successful when, in reality, they
* have no effect and leave the clone uninitialized, allowing a third party to initialize it later.
*
* NOTE: Using a non-zero value at creation will require the contract using this function (e.g. a factory)
* to always have enough balance for new deployments. Consider exposing this function under a payable method.
*/
function cloneDeterministicWithImmutableArgs(
address implementation,
bytes memory args,
bytes32 salt,
uint256 value
) internal returns (address instance) {
bytes memory bytecode = _cloneCodeWithImmutableArgs(implementation, args);
return Create2.deploy(value, salt, bytecode);
}
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministicWithImmutableArgs}.
*/
function predictDeterministicAddressWithImmutableArgs(
address implementation,
bytes memory args,
bytes32 salt,
address deployer
) internal pure returns (address predicted) {
bytes memory bytecode = _cloneCodeWithImmutableArgs(implementation, args);
return Create2.computeAddress(salt, keccak256(bytecode), deployer);
}
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministicWithImmutableArgs}.
*/
function predictDeterministicAddressWithImmutableArgs(
address implementation,
bytes memory args,
bytes32 salt
) internal view returns (address predicted) {
return predictDeterministicAddressWithImmutableArgs(implementation, args, salt, address(this));
}
/**
* @dev Get the immutable args attached to a clone.
*
* - If `instance` is a clone that was deployed using `clone` or `cloneDeterministic`, this
* function will return an empty array.
* - If `instance` is a clone that was deployed using `cloneWithImmutableArgs` or
* `cloneDeterministicWithImmutableArgs`, this function will return the args array used at
* creation.
* - If `instance` is NOT a clone deployed using this library, the behavior is undefined. This
* function should only be used to check addresses that are known to be clones.
*/
function fetchCloneArgs(address instance) internal view returns (bytes memory) {
bytes memory result = new bytes(instance.code.length - 45); // revert if length is too short
assembly ("memory-safe") {
extcodecopy(instance, add(result, 32), 45, mload(result))
}
return result;
}
/**
* @dev Helper that prepares the initcode of the proxy with immutable args.
*
* An assembly variant of this function requires copying the `args` array, which can be efficiently done using
* `mcopy`. Unfortunately, that opcode is not available before cancun. A pure solidity implementation using
* abi.encodePacked is more expensive but also more portable and easier to review.
*
* NOTE: https://eips.ethereum.org/EIPS/eip-170[EIP-170] limits the length of the contract code to 24576 bytes.
* With the proxy code taking 45 bytes, that limits the length of the immutable args to 24531 bytes.
*/
function _cloneCodeWithImmutableArgs(
address implementation,
bytes memory args
) private pure returns (bytes memory) {
if (args.length > 24531) revert CloneArgumentsTooLong();
return
abi.encodePacked(
hex"61",
uint16(args.length + 45),
hex"3d81600a3d39f3363d3d373d3d3d363d73",
implementation,
hex"5af43d82803e903d91602b57fd5bf3",
args
);
}
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity >=0.6.2;
import {IERC20} from "../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC-20 standard.
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)
pragma solidity >=0.4.16;
/**
* @dev Interface of the ERC-20 standard as defined in the ERC.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (utils/Arrays.sol)
// This file was procedurally generated from scripts/generate/templates/Arrays.js.
pragma solidity ^0.8.20;
import {Comparators} from "./Comparators.sol";
import {SlotDerivation} from "./SlotDerivation.sol";
import {StorageSlot} from "./StorageSlot.sol";
import {Math} from "./math/Math.sol";
/**
* @dev Collection of functions related to array types.
*/
library Arrays {
using SlotDerivation for bytes32;
using StorageSlot for bytes32;
/**
* @dev Sort an array of uint256 (in memory) following the provided comparator function.
*
* This function does the sorting "in place", meaning that it overrides the input. The object is returned for
* convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array.
*
* NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the
* array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful
* when executing this as part of a transaction. If the array being sorted is too large, the sort operation may
* consume more gas than is available in a block, leading to potential DoS.
*
* IMPORTANT: Consider memory side-effects when using custom comparator functions that access memory in an unsafe way.
*/
function sort(
uint256[] memory array,
function(uint256, uint256) pure returns (bool) comp
) internal pure returns (uint256[] memory) {
_quickSort(_begin(array), _end(array), comp);
return array;
}
/**
* @dev Variant of {sort} that sorts an array of uint256 in increasing order.
*/
function sort(uint256[] memory array) internal pure returns (uint256[] memory) {
sort(array, Comparators.lt);
return array;
}
/**
* @dev Sort an array of address (in memory) following the provided comparator function.
*
* This function does the sorting "in place", meaning that it overrides the input. The object is returned for
* convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array.
*
* NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the
* array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful
* when executing this as part of a transaction. If the array being sorted is too large, the sort operation may
* consume more gas than is available in a block, leading to potential DoS.
*
* IMPORTANT: Consider memory side-effects when using custom comparator functions that access memory in an unsafe way.
*/
function sort(
address[] memory array,
function(address, address) pure returns (bool) comp
) internal pure returns (address[] memory) {
sort(_castToUint256Array(array), _castToUint256Comp(comp));
return array;
}
/**
* @dev Variant of {sort} that sorts an array of address in increasing order.
*/
function sort(address[] memory array) internal pure returns (address[] memory) {
sort(_castToUint256Array(array), Comparators.lt);
return array;
}
/**
* @dev Sort an array of bytes32 (in memory) following the provided comparator function.
*
* This function does the sorting "in place", meaning that it overrides the input. The object is returned for
* convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array.
*
* NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the
* array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful
* when executing this as part of a transaction. If the array being sorted is too large, the sort operation may
* consume more gas than is available in a block, leading to potential DoS.
*
* IMPORTANT: Consider memory side-effects when using custom comparator functions that access memory in an unsafe way.
*/
function sort(
bytes32[] memory array,
function(bytes32, bytes32) pure returns (bool) comp
) internal pure returns (bytes32[] memory) {
sort(_castToUint256Array(array), _castToUint256Comp(comp));
return array;
}
/**
* @dev Variant of {sort} that sorts an array of bytes32 in increasing order.
*/
function sort(bytes32[] memory array) internal pure returns (bytes32[] memory) {
sort(_castToUint256Array(array), Comparators.lt);
return array;
}
/**
* @dev Performs a quick sort of a segment of memory. The segment sorted starts at `begin` (inclusive), and stops
* at end (exclusive). Sorting follows the `comp` comparator.
*
* Invariant: `begin <= end`. This is the case when initially called by {sort} and is preserved in subcalls.
*
* IMPORTANT: Memory locations between `begin` and `end` are not validated/zeroed. This function should
* be used only if the limits are within a memory array.
*/
function _quickSort(uint256 begin, uint256 end, function(uint256, uint256) pure returns (bool) comp) private pure {
unchecked {
if (end - begin < 0x40) return;
// Use first element as pivot
uint256 pivot = _mload(begin);
// Position where the pivot should be at the end of the loop
uint256 pos = begin;
for (uint256 it = begin + 0x20; it < end; it += 0x20) {
if (comp(_mload(it), pivot)) {
// If the value stored at the iterator's position comes before the pivot, we increment the
// position of the pivot and move the value there.
pos += 0x20;
_swap(pos, it);
}
}
_swap(begin, pos); // Swap pivot into place
_quickSort(begin, pos, comp); // Sort the left side of the pivot
_quickSort(pos + 0x20, end, comp); // Sort the right side of the pivot
}
}
/**
* @dev Pointer to the memory location of the first element of `array`.
*/
function _begin(uint256[] memory array) private pure returns (uint256 ptr) {
assembly ("memory-safe") {
ptr := add(array, 0x20)
}
}
/**
* @dev Pointer to the memory location of the first memory word (32bytes) after `array`. This is the memory word
* that comes just after the last element of the array.
*/
function _end(uint256[] memory array) private pure returns (uint256 ptr) {
unchecked {
return _begin(array) + array.length * 0x20;
}
}
/**
* @dev Load memory word (as a uint256) at location `ptr`.
*/
function _mload(uint256 ptr) private pure returns (uint256 value) {
assembly {
value := mload(ptr)
}
}
/**
* @dev Swaps the elements memory location `ptr1` and `ptr2`.
*/
function _swap(uint256 ptr1, uint256 ptr2) private pure {
assembly {
let value1 := mload(ptr1)
let value2 := mload(ptr2)
mstore(ptr1, value2)
mstore(ptr2, value1)
}
}
/// @dev Helper: low level cast address memory array to uint256 memory array
function _castToUint256Array(address[] memory input) private pure returns (uint256[] memory output) {
assembly {
output := input
}
}
/// @dev Helper: low level cast bytes32 memory array to uint256 memory array
function _castToUint256Array(bytes32[] memory input) private pure returns (uint256[] memory output) {
assembly {
output := input
}
}
/// @dev Helper: low level cast address comp function to uint256 comp function
function _castToUint256Comp(
function(address, address) pure returns (bool) input
) private pure returns (function(uint256, uint256) pure returns (bool) output) {
assembly {
output := input
}
}
/// @dev Helper: low level cast bytes32 comp function to uint256 comp function
function _castToUint256Comp(
function(bytes32, bytes32) pure returns (bool) input
) private pure returns (function(uint256, uint256) pure returns (bool) output) {
assembly {
output := input
}
}
/**
* @dev Searches a sorted `array` and returns the first index that contains
* a value greater or equal to `element`. If no such index exists (i.e. all
* values in the array are strictly less than `element`), the array length is
* returned. Time complexity O(log n).
*
* NOTE: The `array` is expected to be sorted in ascending order, and to
* contain no repeated elements.
*
* IMPORTANT: Deprecated. This implementation behaves as {lowerBound} but lacks
* support for repeated elements in the array. The {lowerBound} function should
* be used instead.
*/
function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {
uint256 low = 0;
uint256 high = array.length;
if (high == 0) {
return 0;
}
while (low < high) {
uint256 mid = Math.average(low, high);
// Note that mid will always be strictly less than high (i.e. it will be a valid array index)
// because Math.average rounds towards zero (it does integer division with truncation).
if (unsafeAccess(array, mid).value > element) {
high = mid;
} else {
low = mid + 1;
}
}
// At this point `low` is the exclusive upper bound. We will return the inclusive upper bound.
if (low > 0 && unsafeAccess(array, low - 1).value == element) {
return low - 1;
} else {
return low;
}
}
/**
* @dev Searches an `array` sorted in ascending order and returns the first
* index that contains a value greater or equal than `element`. If no such index
* exists (i.e. all values in the array are strictly less than `element`), the array
* length is returned. Time complexity O(log n).
*
* See C++'s https://en.cppreference.com/w/cpp/algorithm/lower_bound[lower_bound].
*/
function lowerBound(uint256[] storage array, uint256 element) internal view returns (uint256) {
uint256 low = 0;
uint256 high = array.length;
if (high == 0) {
return 0;
}
while (low < high) {
uint256 mid = Math.average(low, high);
// Note that mid will always be strictly less than high (i.e. it will be a valid array index)
// because Math.average rounds towards zero (it does integer division with truncation).
if (unsafeAccess(array, mid).value < element) {
// this cannot overflow because mid < high
unchecked {
low = mid + 1;
}
} else {
high = mid;
}
}
return low;
}
/**
* @dev Searches an `array` sorted in ascending order and returns the first
* index that contains a value strictly greater than `element`. If no such index
* exists (i.e. all values in the array are strictly less than `element`), the array
* length is returned. Time complexity O(log n).
*
* See C++'s https://en.cppreference.com/w/cpp/algorithm/upper_bound[upper_bound].
*/
function upperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {
uint256 low = 0;
uint256 high = array.length;
if (high == 0) {
return 0;
}
while (low < high) {
uint256 mid = Math.average(low, high);
// Note that mid will always be strictly less than high (i.e. it will be a valid array index)
// because Math.average rounds towards zero (it does integer division with truncation).
if (unsafeAccess(array, mid).value > element) {
high = mid;
} else {
// this cannot overflow because mid < high
unchecked {
low = mid + 1;
}
}
}
return low;
}
/**
* @dev Same as {lowerBound}, but with an array in memory.
*/
function lowerBoundMemory(uint256[] memory array, uint256 element) internal pure returns (uint256) {
uint256 low = 0;
uint256 high = array.length;
if (high == 0) {
return 0;
}
while (low < high) {
uint256 mid = Math.average(low, high);
// Note that mid will always be strictly less than high (i.e. it will be a valid array index)
// because Math.average rounds towards zero (it does integer division with truncation).
if (unsafeMemoryAccess(array, mid) < element) {
// this cannot overflow because mid < high
unchecked {
low = mid + 1;
}
} else {
high = mid;
}
}
return low;
}
/**
* @dev Same as {upperBound}, but with an array in memory.
*/
function upperBoundMemory(uint256[] memory array, uint256 element) internal pure returns (uint256) {
uint256 low = 0;
uint256 high = array.length;
if (high == 0) {
return 0;
}
while (low < high) {
uint256 mid = Math.average(low, high);
// Note that mid will always be strictly less than high (i.e. it will be a valid array index)
// because Math.average rounds towards zero (it does integer division with truncation).
if (unsafeMemoryAccess(array, mid) > element) {
high = mid;
} else {
// this cannot overflow because mid < high
unchecked {
low = mid + 1;
}
}
}
return low;
}
/**
* @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
*
* WARNING: Only use if you are certain `pos` is lower than the array length.
*/
function unsafeAccess(address[] storage arr, uint256 pos) internal pure returns (StorageSlot.AddressSlot storage) {
bytes32 slot;
assembly ("memory-safe") {
slot := arr.slot
}
return slot.deriveArray().offset(pos).getAddressSlot();
}
/**
* @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
*
* WARNING: Only use if you are certain `pos` is lower than the array length.
*/
function unsafeAccess(bytes32[] storage arr, uint256 pos) internal pure returns (StorageSlot.Bytes32Slot storage) {
bytes32 slot;
assembly ("memory-safe") {
slot := arr.slot
}
return slot.deriveArray().offset(pos).getBytes32Slot();
}
/**
* @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
*
* WARNING: Only use if you are certain `pos` is lower than the array length.
*/
function unsafeAccess(uint256[] storage arr, uint256 pos) internal pure returns (StorageSlot.Uint256Slot storage) {
bytes32 slot;
assembly ("memory-safe") {
slot := arr.slot
}
return slot.deriveArray().offset(pos).getUint256Slot();
}
/**
* @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
*
* WARNING: Only use if you are certain `pos` is lower than the array length.
*/
function unsafeAccess(bytes[] storage arr, uint256 pos) internal pure returns (StorageSlot.BytesSlot storage) {
bytes32 slot;
assembly ("memory-safe") {
slot := arr.slot
}
return slot.deriveArray().offset(pos).getBytesSlot();
}
/**
* @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
*
* WARNING: Only use if you are certain `pos` is lower than the array length.
*/
function unsafeAccess(string[] storage arr, uint256 pos) internal pure returns (StorageSlot.StringSlot storage) {
bytes32 slot;
assembly ("memory-safe") {
slot := arr.slot
}
return slot.deriveArray().offset(pos).getStringSlot();
}
/**
* @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
*
* WARNING: Only use if you are certain `pos` is lower than the array length.
*/
function unsafeMemoryAccess(address[] memory arr, uint256 pos) internal pure returns (address res) {
assembly {
res := mload(add(add(arr, 0x20), mul(pos, 0x20)))
}
}
/**
* @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
*
* WARNING: Only use if you are certain `pos` is lower than the array length.
*/
function unsafeMemoryAccess(bytes32[] memory arr, uint256 pos) internal pure returns (bytes32 res) {
assembly {
res := mload(add(add(arr, 0x20), mul(pos, 0x20)))
}
}
/**
* @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
*
* WARNING: Only use if you are certain `pos` is lower than the array length.
*/
function unsafeMemoryAccess(uint256[] memory arr, uint256 pos) internal pure returns (uint256 res) {
assembly {
res := mload(add(add(arr, 0x20), mul(pos, 0x20)))
}
}
/**
* @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
*
* WARNING: Only use if you are certain `pos` is lower than the array length.
*/
function unsafeMemoryAccess(bytes[] memory arr, uint256 pos) internal pure returns (bytes memory res) {
assembly {
res := mload(add(add(arr, 0x20), mul(pos, 0x20)))
}
}
/**
* @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
*
* WARNING: Only use if you are certain `pos` is lower than the array length.
*/
function unsafeMemoryAccess(string[] memory arr, uint256 pos) internal pure returns (string memory res) {
assembly {
res := mload(add(add(arr, 0x20), mul(pos, 0x20)))
}
}
/**
* @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.
*
* WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.
*/
function unsafeSetLength(address[] storage array, uint256 len) internal {
assembly ("memory-safe") {
sstore(array.slot, len)
}
}
/**
* @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.
*
* WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.
*/
function unsafeSetLength(bytes32[] storage array, uint256 len) internal {
assembly ("memory-safe") {
sstore(array.slot, len)
}
}
/**
* @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.
*
* WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.
*/
function unsafeSetLength(uint256[] storage array, uint256 len) internal {
assembly ("memory-safe") {
sstore(array.slot, len)
}
}
/**
* @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.
*
* WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.
*/
function unsafeSetLength(bytes[] storage array, uint256 len) internal {
assembly ("memory-safe") {
sstore(array.slot, len)
}
}
/**
* @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.
*
* WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.
*/
function unsafeSetLength(string[] storage array, uint256 len) internal {
assembly ("memory-safe") {
sstore(array.slot, len)
}
}
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/Comparators.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides a set of functions to compare values.
*
* _Available since v5.1._
*/
library Comparators {
function lt(uint256 a, uint256 b) internal pure returns (bool) {
return a < b;
}
function gt(uint256 a, uint256 b) internal pure returns (bool) {
return a > b;
}
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/Create2.sol)
pragma solidity ^0.8.20;
import {Errors} from "./Errors.sol";
/**
* @dev Helper to make usage of the `CREATE2` EVM opcode easier and safer.
* `CREATE2` can be used to compute in advance the address where a smart
* contract will be deployed, which allows for interesting new mechanisms known
* as 'counterfactual interactions'.
*
* See the https://eips.ethereum.org/EIPS/eip-1014#motivation[EIP] for more
* information.
*/
library Create2 {
/**
* @dev There's no code to deploy.
*/
error Create2EmptyBytecode();
/**
* @dev Deploys a contract using `CREATE2`. The address where the contract
* will be deployed can be known in advance via {computeAddress}.
*
* The bytecode for a contract can be obtained from Solidity with
* `type(contractName).creationCode`.
*
* Requirements:
*
* - `bytecode` must not be empty.
* - `salt` must have not been used for `bytecode` already.
* - the factory must have a balance of at least `amount`.
* - if `amount` is non-zero, `bytecode` must have a `payable` constructor.
*/
function deploy(uint256 amount, bytes32 salt, bytes memory bytecode) internal returns (address addr) {
if (address(this).balance < amount) {
revert Errors.InsufficientBalance(address(this).balance, amount);
}
if (bytecode.length == 0) {
revert Create2EmptyBytecode();
}
assembly ("memory-safe") {
addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt)
// if no address was created, and returndata is not empty, bubble revert
if and(iszero(addr), not(iszero(returndatasize()))) {
let p := mload(0x40)
returndatacopy(p, 0, returndatasize())
revert(p, returndatasize())
}
}
if (addr == address(0)) {
revert Errors.FailedDeployment();
}
}
/**
* @dev Returns the address where a contract will be stored if deployed via {deploy}. Any change in the
* `bytecodeHash` or `salt` will result in a new destination address.
*/
function computeAddress(bytes32 salt, bytes32 bytecodeHash) internal view returns (address) {
return computeAddress(salt, bytecodeHash, address(this));
}
/**
* @dev Returns the address where a contract will be stored if deployed via {deploy} from a contract located at
* `deployer`. If `deployer` is this contract's address, returns the same value as {computeAddress}.
*/
function computeAddress(bytes32 salt, bytes32 bytecodeHash, address deployer) internal pure returns (address addr) {
assembly ("memory-safe") {
let ptr := mload(0x40) // Get free memory pointer
// | | ↓ ptr ... ↓ ptr + 0x0B (start) ... ↓ ptr + 0x20 ... ↓ ptr + 0x40 ... |
// |-------------------|---------------------------------------------------------------------------|
// | bytecodeHash | CCCCCCCCCCCCC...CC |
// | salt | BBBBBBBBBBBBB...BB |
// | deployer | 000000...0000AAAAAAAAAAAAAAAAAAA...AA |
// | 0xFF | FF |
// |-------------------|---------------------------------------------------------------------------|
// | memory | 000000...00FFAAAAAAAAAAAAAAAAAAA...AABBBBBBBBBBBBB...BBCCCCCCCCCCCCC...CC |
// | keccak(start, 85) | ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ |
mstore(add(ptr, 0x40), bytecodeHash)
mstore(add(ptr, 0x20), salt)
mstore(ptr, deployer) // Right-aligned with 12 preceding garbage bytes
let start := add(ptr, 0x0b) // The hashed data starts at the final garbage byte which we will set to 0xff
mstore8(start, 0xff)
addr := and(keccak256(start, 85), 0xffffffffffffffffffffffffffffffffffffffff)
}
}
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/Errors.sol)
pragma solidity ^0.8.20;
/**
* @dev Collection of common custom errors used in multiple contracts
*
* IMPORTANT: Backwards compatibility is not guaranteed in future versions of the library.
* It is recommended to avoid relying on the error API for critical functionality.
*
* _Available since v5.1._
*/
library Errors {
/**
* @dev The ETH balance of the account is not enough to perform the operation.
*/
error InsufficientBalance(uint256 balance, uint256 needed);
/**
* @dev A call to an address target failed. The target may have reverted.
*/
error FailedCall();
/**
* @dev The deployment failed.
*/
error FailedDeployment();
/**
* @dev A necessary precompile is missing.
*/
error MissingPrecompile(address);
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/ERC165.sol)
pragma solidity ^0.8.20;
import {IERC165} from "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*/
abstract contract ERC165 is IERC165 {
/// @inheritdoc IERC165
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol)
pragma solidity >=0.4.16;
/**
* @dev Interface of the ERC-165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[ERC].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (utils/math/Math.sol)
pragma solidity ^0.8.20;
import {Panic} from "../Panic.sol";
import {SafeCast} from "./SafeCast.sol";
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
enum Rounding {
Floor, // Toward negative infinity
Ceil, // Toward positive infinity
Trunc, // Toward zero
Expand // Away from zero
}
/**
* @dev Return the 512-bit addition of two uint256.
*
* The result is stored in two 256 variables such that sum = high * 2²⁵⁶ + low.
*/
function add512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) {
assembly ("memory-safe") {
low := add(a, b)
high := lt(low, a)
}
}
/**
* @dev Return the 512-bit multiplication of two uint256.
*
* The result is stored in two 256 variables such that product = high * 2²⁵⁶ + low.
*/
function mul512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) {
// 512-bit multiply [high low] = x * y. Compute the product mod 2²⁵⁶ and mod 2²⁵⁶ - 1, then use
// the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = high * 2²⁵⁶ + low.
assembly ("memory-safe") {
let mm := mulmod(a, b, not(0))
low := mul(a, b)
high := sub(sub(mm, low), lt(mm, low))
}
}
/**
* @dev Returns the addition of two unsigned integers, with a success flag (no overflow).
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
unchecked {
uint256 c = a + b;
success = c >= a;
result = c * SafeCast.toUint(success);
}
}
/**
* @dev Returns the subtraction of two unsigned integers, with a success flag (no overflow).
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
unchecked {
uint256 c = a - b;
success = c <= a;
result = c * SafeCast.toUint(success);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with a success flag (no overflow).
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
unchecked {
uint256 c = a * b;
assembly ("memory-safe") {
// Only true when the multiplication doesn't overflow
// (c / a == b) || (a == 0)
success := or(eq(div(c, a), b), iszero(a))
}
// equivalent to: success ? c : 0
result = c * SafeCast.toUint(success);
}
}
/**
* @dev Returns the division of two unsigned integers, with a success flag (no division by zero).
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
unchecked {
success = b > 0;
assembly ("memory-safe") {
// The `DIV` opcode returns zero when the denominator is 0.
result := div(a, b)
}
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a success flag (no division by zero).
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
unchecked {
success = b > 0;
assembly ("memory-safe") {
// The `MOD` opcode returns zero when the denominator is 0.
result := mod(a, b)
}
}
}
/**
* @dev Unsigned saturating addition, bounds to `2²⁵⁶ - 1` instead of overflowing.
*/
function saturatingAdd(uint256 a, uint256 b) internal pure returns (uint256) {
(bool success, uint256 result) = tryAdd(a, b);
return ternary(success, result, type(uint256).max);
}
/**
* @dev Unsigned saturating subtraction, bounds to zero instead of overflowing.
*/
function saturatingSub(uint256 a, uint256 b) internal pure returns (uint256) {
(, uint256 result) = trySub(a, b);
return result;
}
/**
* @dev Unsigned saturating multiplication, bounds to `2²⁵⁶ - 1` instead of overflowing.
*/
function saturatingMul(uint256 a, uint256 b) internal pure returns (uint256) {
(bool success, uint256 result) = tryMul(a, b);
return ternary(success, result, type(uint256).max);
}
/**
* @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant.
*
* IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone.
* However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute
* one branch when needed, making this function more expensive.
*/
function ternary(bool condition, uint256 a, uint256 b) internal pure returns (uint256) {
unchecked {
// branchless ternary works because:
// b ^ (a ^ b) == a
// b ^ 0 == b
return b ^ ((a ^ b) * SafeCast.toUint(condition));
}
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return ternary(a > b, a, b);
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return ternary(a < b, a, b);
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds towards infinity instead
* of rounding towards zero.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
if (b == 0) {
// Guarantee the same behavior as in a regular Solidity division.
Panic.panic(Panic.DIVISION_BY_ZERO);
}
// The following calculation ensures accurate ceiling division without overflow.
// Since a is non-zero, (a - 1) / b will not overflow.
// The largest possible result occurs when (a - 1) / b is type(uint256).max,
// but the largest value we can obtain is type(uint256).max - 1, which happens
// when a = type(uint256).max and b = 1.
unchecked {
return SafeCast.toUint(a > 0) * ((a - 1) / b + 1);
}
}
/**
* @dev Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or
* denominator == 0.
*
* Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by
* Uniswap Labs also under MIT license.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
(uint256 high, uint256 low) = mul512(x, y);
// Handle non-overflow cases, 256 by 256 division.
if (high == 0) {
// Solidity will revert if denominator == 0, unlike the div opcode on its own.
// The surrounding unchecked block does not change this fact.
// See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
return low / denominator;
}
// Make sure the result is less than 2²⁵⁶. Also prevents denominator == 0.
if (denominator <= high) {
Panic.panic(ternary(denominator == 0, Panic.DIVISION_BY_ZERO, Panic.UNDER_OVERFLOW));
}
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [high low].
uint256 remainder;
assembly ("memory-safe") {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
high := sub(high, gt(remainder, low))
low := sub(low, remainder)
}
// Factor powers of two out of denominator and compute largest power of two divisor of denominator.
// Always >= 1. See https://cs.stackexchange.com/q/138556/92363.
uint256 twos = denominator & (0 - denominator);
assembly ("memory-safe") {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [high low] by twos.
low := div(low, twos)
// Flip twos such that it is 2²⁵⁶ / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from high into low.
low |= high * twos;
// Invert denominator mod 2²⁵⁶. Now that denominator is an odd number, it has an inverse modulo 2²⁵⁶ such
// that denominator * inv ≡ 1 mod 2²⁵⁶. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv ≡ 1 mod 2⁴.
uint256 inverse = (3 * denominator) ^ 2;
// Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also
// works in modular arithmetic, doubling the correct bits in each step.
inverse *= 2 - denominator * inverse; // inverse mod 2⁸
inverse *= 2 - denominator * inverse; // inverse mod 2¹⁶
inverse *= 2 - denominator * inverse; // inverse mod 2³²
inverse *= 2 - denominator * inverse; // inverse mod 2⁶⁴
inverse *= 2 - denominator * inverse; // inverse mod 2¹²⁸
inverse *= 2 - denominator * inverse; // inverse mod 2²⁵⁶
// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
// This will give us the correct result modulo 2²⁵⁶. Since the preconditions guarantee that the outcome is
// less than 2²⁵⁶, this is the final result. We don't need to compute the high bits of the result and high
// is no longer required.
result = low * inverse;
return result;
}
}
/**
* @dev Calculates x * y / denominator with full precision, following the selected rounding direction.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
return mulDiv(x, y, denominator) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0);
}
/**
* @dev Calculates floor(x * y >> n) with full precision. Throws if result overflows a uint256.
*/
function mulShr(uint256 x, uint256 y, uint8 n) internal pure returns (uint256 result) {
unchecked {
(uint256 high, uint256 low) = mul512(x, y);
if (high >= 1 << n) {
Panic.panic(Panic.UNDER_OVERFLOW);
}
return (high << (256 - n)) | (low >> n);
}
}
/**
* @dev Calculates x * y >> n with full precision, following the selected rounding direction.
*/
function mulShr(uint256 x, uint256 y, uint8 n, Rounding rounding) internal pure returns (uint256) {
return mulShr(x, y, n) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, 1 << n) > 0);
}
/**
* @dev Calculate the modular multiplicative inverse of a number in Z/nZ.
*
* If n is a prime, then Z/nZ is a field. In that case all elements are inversible, except 0.
* If n is not a prime, then Z/nZ is not a field, and some elements might not be inversible.
*
* If the input value is not inversible, 0 is returned.
*
* NOTE: If you know for sure that n is (big) a prime, it may be cheaper to use Fermat's little theorem and get the
* inverse using `Math.modExp(a, n - 2, n)`. See {invModPrime}.
*/
function invMod(uint256 a, uint256 n) internal pure returns (uint256) {
unchecked {
if (n == 0) return 0;
// The inverse modulo is calculated using the Extended Euclidean Algorithm (iterative version)
// Used to compute integers x and y such that: ax + ny = gcd(a, n).
// When the gcd is 1, then the inverse of a modulo n exists and it's x.
// ax + ny = 1
// ax = 1 + (-y)n
// ax ≡ 1 (mod n) # x is the inverse of a modulo n
// If the remainder is 0 the gcd is n right away.
uint256 remainder = a % n;
uint256 gcd = n;
// Therefore the initial coefficients are:
// ax + ny = gcd(a, n) = n
// 0a + 1n = n
int256 x = 0;
int256 y = 1;
while (remainder != 0) {
uint256 quotient = gcd / remainder;
(gcd, remainder) = (
// The old remainder is the next gcd to try.
remainder,
// Compute the next remainder.
// Can't overflow given that (a % gcd) * (gcd // (a % gcd)) <= gcd
// where gcd is at most n (capped to type(uint256).max)
gcd - remainder * quotient
);
(x, y) = (
// Increment the coefficient of a.
y,
// Decrement the coefficient of n.
// Can overflow, but the result is casted to uint256 so that the
// next value of y is "wrapped around" to a value between 0 and n - 1.
x - y * int256(quotient)
);
}
if (gcd != 1) return 0; // No inverse exists.
return ternary(x < 0, n - uint256(-x), uint256(x)); // Wrap the result if it's negative.
}
}
/**
* @dev Variant of {invMod}. More efficient, but only works if `p` is known to be a prime greater than `2`.
*
* From https://en.wikipedia.org/wiki/Fermat%27s_little_theorem[Fermat's little theorem], we know that if p is
* prime, then `a**(p-1) ≡ 1 mod p`. As a consequence, we have `a * a**(p-2) ≡ 1 mod p`, which means that
* `a**(p-2)` is the modular multiplicative inverse of a in Fp.
*
* NOTE: this function does NOT check that `p` is a prime greater than `2`.
*/
function invModPrime(uint256 a, uint256 p) internal view returns (uint256) {
unchecked {
return Math.modExp(a, p - 2, p);
}
}
/**
* @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m)
*
* Requirements:
* - modulus can't be zero
* - underlying staticcall to precompile must succeed
*
* IMPORTANT: The result is only valid if the underlying call succeeds. When using this function, make
* sure the chain you're using it on supports the precompiled contract for modular exponentiation
* at address 0x05 as specified in https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise,
* the underlying function will succeed given the lack of a revert, but the result may be incorrectly
* interpreted as 0.
*/
function modExp(uint256 b, uint256 e, uint256 m) internal view returns (uint256) {
(bool success, uint256 result) = tryModExp(b, e, m);
if (!success) {
Panic.panic(Panic.DIVISION_BY_ZERO);
}
return result;
}
/**
* @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m).
* It includes a success flag indicating if the operation succeeded. Operation will be marked as failed if trying
* to operate modulo 0 or if the underlying precompile reverted.
*
* IMPORTANT: The result is only valid if the success flag is true. When using this function, make sure the chain
* you're using it on supports the precompiled contract for modular exponentiation at address 0x05 as specified in
* https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, the underlying function will succeed given the lack
* of a revert, but the result may be incorrectly interpreted as 0.
*/
function tryModExp(uint256 b, uint256 e, uint256 m) internal view returns (bool success, uint256 result) {
if (m == 0) return (false, 0);
assembly ("memory-safe") {
let ptr := mload(0x40)
// | Offset | Content | Content (Hex) |
// |-----------|------------|--------------------------------------------------------------------|
// | 0x00:0x1f | size of b | 0x0000000000000000000000000000000000000000000000000000000000000020 |
// | 0x20:0x3f | size of e | 0x0000000000000000000000000000000000000000000000000000000000000020 |
// | 0x40:0x5f | size of m | 0x0000000000000000000000000000000000000000000000000000000000000020 |
// | 0x60:0x7f | value of b | 0x<.............................................................b> |
// | 0x80:0x9f | value of e | 0x<.............................................................e> |
// | 0xa0:0xbf | value of m | 0x<.............................................................m> |
mstore(ptr, 0x20)
mstore(add(ptr, 0x20), 0x20)
mstore(add(ptr, 0x40), 0x20)
mstore(add(ptr, 0x60), b)
mstore(add(ptr, 0x80), e)
mstore(add(ptr, 0xa0), m)
// Given the result < m, it's guaranteed to fit in 32 bytes,
// so we can use the memory scratch space located at offset 0.
success := staticcall(gas(), 0x05, ptr, 0xc0, 0x00, 0x20)
result := mload(0x00)
}
}
/**
* @dev Variant of {modExp} that supports inputs of arbitrary length.
*/
function modExp(bytes memory b, bytes memory e, bytes memory m) internal view returns (bytes memory) {
(bool success, bytes memory result) = tryModExp(b, e, m);
if (!success) {
Panic.panic(Panic.DIVISION_BY_ZERO);
}
return result;
}
/**
* @dev Variant of {tryModExp} that supports inputs of arbitrary length.
*/
function tryModExp(
bytes memory b,
bytes memory e,
bytes memory m
) internal view returns (bool success, bytes memory result) {
if (_zeroBytes(m)) return (false, new bytes(0));
uint256 mLen = m.length;
// Encode call args in result and move the free memory pointer
result = abi.encodePacked(b.length, e.length, mLen, b, e, m);
assembly ("memory-safe") {
let dataPtr := add(result, 0x20)
// Write result on top of args to avoid allocating extra memory.
success := staticcall(gas(), 0x05, dataPtr, mload(result), dataPtr, mLen)
// Overwrite the length.
// result.length > returndatasize() is guaranteed because returndatasize() == m.length
mstore(result, mLen)
// Set the memory pointer after the returned data.
mstore(0x40, add(dataPtr, mLen))
}
}
/**
* @dev Returns whether the provided byte array is zero.
*/
function _zeroBytes(bytes memory byteArray) private pure returns (bool) {
for (uint256 i = 0; i < byteArray.length; ++i) {
if (byteArray[i] != 0) {
return false;
}
}
return true;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded
* towards zero.
*
* This method is based on Newton's method for computing square roots; the algorithm is restricted to only
* using integer operations.
*/
function sqrt(uint256 a) internal pure returns (uint256) {
unchecked {
// Take care of easy edge cases when a == 0 or a == 1
if (a <= 1) {
return a;
}
// In this function, we use Newton's method to get a root of `f(x) := x² - a`. It involves building a
// sequence x_n that converges toward sqrt(a). For each iteration x_n, we also define the error between
// the current value as `ε_n = | x_n - sqrt(a) |`.
//
// For our first estimation, we consider `e` the smallest power of 2 which is bigger than the square root
// of the target. (i.e. `2**(e-1) ≤ sqrt(a) < 2**e`). We know that `e ≤ 128` because `(2¹²⁸)² = 2²⁵⁶` is
// bigger than any uint256.
//
// By noticing that
// `2**(e-1) ≤ sqrt(a) < 2**e → (2**(e-1))² ≤ a < (2**e)² → 2**(2*e-2) ≤ a < 2**(2*e)`
// we can deduce that `e - 1` is `log2(a) / 2`. We can thus compute `x_n = 2**(e-1)` using a method similar
// to the msb function.
uint256 aa = a;
uint256 xn = 1;
if (aa >= (1 << 128)) {
aa >>= 128;
xn <<= 64;
}
if (aa >= (1 << 64)) {
aa >>= 64;
xn <<= 32;
}
if (aa >= (1 << 32)) {
aa >>= 32;
xn <<= 16;
}
if (aa >= (1 << 16)) {
aa >>= 16;
xn <<= 8;
}
if (aa >= (1 << 8)) {
aa >>= 8;
xn <<= 4;
}
if (aa >= (1 << 4)) {
aa >>= 4;
xn <<= 2;
}
if (aa >= (1 << 2)) {
xn <<= 1;
}
// We now have x_n such that `x_n = 2**(e-1) ≤ sqrt(a) < 2**e = 2 * x_n`. This implies ε_n ≤ 2**(e-1).
//
// We can refine our estimation by noticing that the middle of that interval minimizes the error.
// If we move x_n to equal 2**(e-1) + 2**(e-2), then we reduce the error to ε_n ≤ 2**(e-2).
// This is going to be our x_0 (and ε_0)
xn = (3 * xn) >> 1; // ε_0 := | x_0 - sqrt(a) | ≤ 2**(e-2)
// From here, Newton's method give us:
// x_{n+1} = (x_n + a / x_n) / 2
//
// One should note that:
// x_{n+1}² - a = ((x_n + a / x_n) / 2)² - a
// = ((x_n² + a) / (2 * x_n))² - a
// = (x_n⁴ + 2 * a * x_n² + a²) / (4 * x_n²) - a
// = (x_n⁴ + 2 * a * x_n² + a² - 4 * a * x_n²) / (4 * x_n²)
// = (x_n⁴ - 2 * a * x_n² + a²) / (4 * x_n²)
// = (x_n² - a)² / (2 * x_n)²
// = ((x_n² - a) / (2 * x_n))²
// ≥ 0
// Which proves that for all n ≥ 1, sqrt(a) ≤ x_n
//
// This gives us the proof of quadratic convergence of the sequence:
// ε_{n+1} = | x_{n+1} - sqrt(a) |
// = | (x_n + a / x_n) / 2 - sqrt(a) |
// = | (x_n² + a - 2*x_n*sqrt(a)) / (2 * x_n) |
// = | (x_n - sqrt(a))² / (2 * x_n) |
// = | ε_n² / (2 * x_n) |
// = ε_n² / | (2 * x_n) |
//
// For the first iteration, we have a special case where x_0 is known:
// ε_1 = ε_0² / | (2 * x_0) |
// ≤ (2**(e-2))² / (2 * (2**(e-1) + 2**(e-2)))
// ≤ 2**(2*e-4) / (3 * 2**(e-1))
// ≤ 2**(e-3) / 3
// ≤ 2**(e-3-log2(3))
// ≤ 2**(e-4.5)
//
// For the following iterations, we use the fact that, 2**(e-1) ≤ sqrt(a) ≤ x_n:
// ε_{n+1} = ε_n² / | (2 * x_n) |
// ≤ (2**(e-k))² / (2 * 2**(e-1))
// ≤ 2**(2*e-2*k) / 2**e
// ≤ 2**(e-2*k)
xn = (xn + a / xn) >> 1; // ε_1 := | x_1 - sqrt(a) | ≤ 2**(e-4.5) -- special case, see above
xn = (xn + a / xn) >> 1; // ε_2 := | x_2 - sqrt(a) | ≤ 2**(e-9) -- general case with k = 4.5
xn = (xn + a / xn) >> 1; // ε_3 := | x_3 - sqrt(a) | ≤ 2**(e-18) -- general case with k = 9
xn = (xn + a / xn) >> 1; // ε_4 := | x_4 - sqrt(a) | ≤ 2**(e-36) -- general case with k = 18
xn = (xn + a / xn) >> 1; // ε_5 := | x_5 - sqrt(a) | ≤ 2**(e-72) -- general case with k = 36
xn = (xn + a / xn) >> 1; // ε_6 := | x_6 - sqrt(a) | ≤ 2**(e-144) -- general case with k = 72
// Because e ≤ 128 (as discussed during the first estimation phase), we know have reached a precision
// ε_6 ≤ 2**(e-144) < 1. Given we're operating on integers, then we can ensure that xn is now either
// sqrt(a) or sqrt(a) + 1.
return xn - SafeCast.toUint(xn > a / xn);
}
}
/**
* @dev Calculates sqrt(a), following the selected rounding direction.
*/
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + SafeCast.toUint(unsignedRoundsUp(rounding) && result * result < a);
}
}
/**
* @dev Return the log in base 2 of a positive value rounded towards zero.
* Returns 0 if given 0.
*/
function log2(uint256 x) internal pure returns (uint256 r) {
// If value has upper 128 bits set, log2 result is at least 128
r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7;
// If upper 64 bits of 128-bit half set, add 64 to result
r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6;
// If upper 32 bits of 64-bit half set, add 32 to result
r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5;
// If upper 16 bits of 32-bit half set, add 16 to result
r |= SafeCast.toUint((x >> r) > 0xffff) << 4;
// If upper 8 bits of 16-bit half set, add 8 to result
r |= SafeCast.toUint((x >> r) > 0xff) << 3;
// If upper 4 bits of 8-bit half set, add 4 to result
r |= SafeCast.toUint((x >> r) > 0xf) << 2;
// Shifts value right by the current result and use it as an index into this lookup table:
//
// | x (4 bits) | index | table[index] = MSB position |
// |------------|---------|-----------------------------|
// | 0000 | 0 | table[0] = 0 |
// | 0001 | 1 | table[1] = 0 |
// | 0010 | 2 | table[2] = 1 |
// | 0011 | 3 | table[3] = 1 |
// | 0100 | 4 | table[4] = 2 |
// | 0101 | 5 | table[5] = 2 |
// | 0110 | 6 | table[6] = 2 |
// | 0111 | 7 | table[7] = 2 |
// | 1000 | 8 | table[8] = 3 |
// | 1001 | 9 | table[9] = 3 |
// | 1010 | 10 | table[10] = 3 |
// | 1011 | 11 | table[11] = 3 |
// | 1100 | 12 | table[12] = 3 |
// | 1101 | 13 | table[13] = 3 |
// | 1110 | 14 | table[14] = 3 |
// | 1111 | 15 | table[15] = 3 |
//
// The lookup table is represented as a 32-byte value with the MSB positions for 0-15 in the last 16 bytes.
assembly ("memory-safe") {
r := or(r, byte(shr(r, x), 0x0000010102020202030303030303030300000000000000000000000000000000))
}
}
/**
* @dev Return the log in base 2, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << result < value);
}
}
/**
* @dev Return the log in base 10 of a positive value rounded towards zero.
* Returns 0 if given 0.
*/
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 10 ** result < value);
}
}
/**
* @dev Return the log in base 256 of a positive value rounded towards zero.
* Returns 0 if given 0.
*
* Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
*/
function log256(uint256 x) internal pure returns (uint256 r) {
// If value has upper 128 bits set, log2 result is at least 128
r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7;
// If upper 64 bits of 128-bit half set, add 64 to result
r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6;
// If upper 32 bits of 64-bit half set, add 32 to result
r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5;
// If upper 16 bits of 32-bit half set, add 16 to result
r |= SafeCast.toUint((x >> r) > 0xffff) << 4;
// Add 1 if upper 8 bits of 16-bit half set, and divide accumulated result by 8
return (r >> 3) | SafeCast.toUint((x >> r) > 0xff);
}
/**
* @dev Return the log in base 256, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << (result << 3) < value);
}
}
/**
* @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.
*/
function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {
return uint8(rounding) % 2 == 1;
}
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SafeCast.sol)
// This file was procedurally generated from scripts/generate/templates/SafeCast.js.
pragma solidity ^0.8.20;
/**
* @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow
* checks.
*
* Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
* easily result in undesired exploitation or bugs, since developers usually
* assume that overflows raise errors. `SafeCast` restores this intuition by
* reverting the transaction when such an operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeCast {
/**
* @dev Value doesn't fit in an uint of `bits` size.
*/
error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);
/**
* @dev An int value doesn't fit in an uint of `bits` size.
*/
error SafeCastOverflowedIntToUint(int256 value);
/**
* @dev Value doesn't fit in an int of `bits` size.
*/
error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);
/**
* @dev An uint value doesn't fit in an int of `bits` size.
*/
error SafeCastOverflowedUintToInt(uint256 value);
/**
* @dev Returns the downcasted uint248 from uint256, reverting on
* overflow (when the input is greater than largest uint248).
*
* Counterpart to Solidity's `uint248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*/
function toUint248(uint256 value) internal pure returns (uint248) {
if (value > type(uint248).max) {
revert SafeCastOverflowedUintDowncast(248, value);
}
return uint248(value);
}
/**
* @dev Returns the downcasted uint240 from uint256, reverting on
* overflow (when the input is greater than largest uint240).
*
* Counterpart to Solidity's `uint240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*/
function toUint240(uint256 value) internal pure returns (uint240) {
if (value > type(uint240).max) {
revert SafeCastOverflowedUintDowncast(240, value);
}
return uint240(value);
}
/**
* @dev Returns the downcasted uint232 from uint256, reverting on
* overflow (when the input is greater than largest uint232).
*
* Counterpart to Solidity's `uint232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*/
function toUint232(uint256 value) internal pure returns (uint232) {
if (value > type(uint232).max) {
revert SafeCastOverflowedUintDowncast(232, value);
}
return uint232(value);
}
/**
* @dev Returns the downcasted uint224 from uint256, reverting on
* overflow (when the input is greater than largest uint224).
*
* Counterpart to Solidity's `uint224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*/
function toUint224(uint256 value) internal pure returns (uint224) {
if (value > type(uint224).max) {
revert SafeCastOverflowedUintDowncast(224, value);
}
return uint224(value);
}
/**
* @dev Returns the downcasted uint216 from uint256, reverting on
* overflow (when the input is greater than largest uint216).
*
* Counterpart to Solidity's `uint216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*/
function toUint216(uint256 value) internal pure returns (uint216) {
if (value > type(uint216).max) {
revert SafeCastOverflowedUintDowncast(216, value);
}
return uint216(value);
}
/**
* @dev Returns the downcasted uint208 from uint256, reverting on
* overflow (when the input is greater than largest uint208).
*
* Counterpart to Solidity's `uint208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*/
function toUint208(uint256 value) internal pure returns (uint208) {
if (value > type(uint208).max) {
revert SafeCastOverflowedUintDowncast(208, value);
}
return uint208(value);
}
/**
* @dev Returns the downcasted uint200 from uint256, reverting on
* overflow (when the input is greater than largest uint200).
*
* Counterpart to Solidity's `uint200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*/
function toUint200(uint256 value) internal pure returns (uint200) {
if (value > type(uint200).max) {
revert SafeCastOverflowedUintDowncast(200, value);
}
return uint200(value);
}
/**
* @dev Returns the downcasted uint192 from uint256, reverting on
* overflow (when the input is greater than largest uint192).
*
* Counterpart to Solidity's `uint192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*/
function toUint192(uint256 value) internal pure returns (uint192) {
if (value > type(uint192).max) {
revert SafeCastOverflowedUintDowncast(192, value);
}
return uint192(value);
}
/**
* @dev Returns the downcasted uint184 from uint256, reverting on
* overflow (when the input is greater than largest uint184).
*
* Counterpart to Solidity's `uint184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*/
function toUint184(uint256 value) internal pure returns (uint184) {
if (value > type(uint184).max) {
revert SafeCastOverflowedUintDowncast(184, value);
}
return uint184(value);
}
/**
* @dev Returns the downcasted uint176 from uint256, reverting on
* overflow (when the input is greater than largest uint176).
*
* Counterpart to Solidity's `uint176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*/
function toUint176(uint256 value) internal pure returns (uint176) {
if (value > type(uint176).max) {
revert SafeCastOverflowedUintDowncast(176, value);
}
return uint176(value);
}
/**
* @dev Returns the downcasted uint168 from uint256, reverting on
* overflow (when the input is greater than largest uint168).
*
* Counterpart to Solidity's `uint168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*/
function toUint168(uint256 value) internal pure returns (uint168) {
if (value > type(uint168).max) {
revert SafeCastOverflowedUintDowncast(168, value);
}
return uint168(value);
}
/**
* @dev Returns the downcasted uint160 from uint256, reverting on
* overflow (when the input is greater than largest uint160).
*
* Counterpart to Solidity's `uint160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*/
function toUint160(uint256 value) internal pure returns (uint160) {
if (value > type(uint160).max) {
revert SafeCastOverflowedUintDowncast(160, value);
}
return uint160(value);
}
/**
* @dev Returns the downcasted uint152 from uint256, reverting on
* overflow (when the input is greater than largest uint152).
*
* Counterpart to Solidity's `uint152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*/
function toUint152(uint256 value) internal pure returns (uint152) {
if (value > type(uint152).max) {
revert SafeCastOverflowedUintDowncast(152, value);
}
return uint152(value);
}
/**
* @dev Returns the downcasted uint144 from uint256, reverting on
* overflow (when the input is greater than largest uint144).
*
* Counterpart to Solidity's `uint144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*/
function toUint144(uint256 value) internal pure returns (uint144) {
if (value > type(uint144).max) {
revert SafeCastOverflowedUintDowncast(144, value);
}
return uint144(value);
}
/**
* @dev Returns the downcasted uint136 from uint256, reverting on
* overflow (when the input is greater than largest uint136).
*
* Counterpart to Solidity's `uint136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*/
function toUint136(uint256 value) internal pure returns (uint136) {
if (value > type(uint136).max) {
revert SafeCastOverflowedUintDowncast(136, value);
}
return uint136(value);
}
/**
* @dev Returns the downcasted uint128 from uint256, reverting on
* overflow (when the input is greater than largest uint128).
*
* Counterpart to Solidity's `uint128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*/
function toUint128(uint256 value) internal pure returns (uint128) {
if (value > type(uint128).max) {
revert SafeCastOverflowedUintDowncast(128, value);
}
return uint128(value);
}
/**
* @dev Returns the downcasted uint120 from uint256, reverting on
* overflow (when the input is greater than largest uint120).
*
* Counterpart to Solidity's `uint120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*/
function toUint120(uint256 value) internal pure returns (uint120) {
if (value > type(uint120).max) {
revert SafeCastOverflowedUintDowncast(120, value);
}
return uint120(value);
}
/**
* @dev Returns the downcasted uint112 from uint256, reverting on
* overflow (when the input is greater than largest uint112).
*
* Counterpart to Solidity's `uint112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*/
function toUint112(uint256 value) internal pure returns (uint112) {
if (value > type(uint112).max) {
revert SafeCastOverflowedUintDowncast(112, value);
}
return uint112(value);
}
/**
* @dev Returns the downcasted uint104 from uint256, reverting on
* overflow (when the input is greater than largest uint104).
*
* Counterpart to Solidity's `uint104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*/
function toUint104(uint256 value) internal pure returns (uint104) {
if (value > type(uint104).max) {
revert SafeCastOverflowedUintDowncast(104, value);
}
return uint104(value);
}
/**
* @dev Returns the downcasted uint96 from uint256, reverting on
* overflow (when the input is greater than largest uint96).
*
* Counterpart to Solidity's `uint96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*/
function toUint96(uint256 value) internal pure returns (uint96) {
if (value > type(uint96).max) {
revert SafeCastOverflowedUintDowncast(96, value);
}
return uint96(value);
}
/**
* @dev Returns the downcasted uint88 from uint256, reverting on
* overflow (when the input is greater than largest uint88).
*
* Counterpart to Solidity's `uint88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*/
function toUint88(uint256 value) internal pure returns (uint88) {
if (value > type(uint88).max) {
revert SafeCastOverflowedUintDowncast(88, value);
}
return uint88(value);
}
/**
* @dev Returns the downcasted uint80 from uint256, reverting on
* overflow (when the input is greater than largest uint80).
*
* Counterpart to Solidity's `uint80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*/
function toUint80(uint256 value) internal pure returns (uint80) {
if (value > type(uint80).max) {
revert SafeCastOverflowedUintDowncast(80, value);
}
return uint80(value);
}
/**
* @dev Returns the downcasted uint72 from uint256, reverting on
* overflow (when the input is greater than largest uint72).
*
* Counterpart to Solidity's `uint72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*/
function toUint72(uint256 value) internal pure returns (uint72) {
if (value > type(uint72).max) {
revert SafeCastOverflowedUintDowncast(72, value);
}
return uint72(value);
}
/**
* @dev Returns the downcasted uint64 from uint256, reverting on
* overflow (when the input is greater than largest uint64).
*
* Counterpart to Solidity's `uint64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*/
function toUint64(uint256 value) internal pure returns (uint64) {
if (value > type(uint64).max) {
revert SafeCastOverflowedUintDowncast(64, value);
}
return uint64(value);
}
/**
* @dev Returns the downcasted uint56 from uint256, reverting on
* overflow (when the input is greater than largest uint56).
*
* Counterpart to Solidity's `uint56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*/
function toUint56(uint256 value) internal pure returns (uint56) {
if (value > type(uint56).max) {
revert SafeCastOverflowedUintDowncast(56, value);
}
return uint56(value);
}
/**
* @dev Returns the downcasted uint48 from uint256, reverting on
* overflow (when the input is greater than largest uint48).
*
* Counterpart to Solidity's `uint48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*/
function toUint48(uint256 value) internal pure returns (uint48) {
if (value > type(uint48).max) {
revert SafeCastOverflowedUintDowncast(48, value);
}
return uint48(value);
}
/**
* @dev Returns the downcasted uint40 from uint256, reverting on
* overflow (when the input is greater than largest uint40).
*
* Counterpart to Solidity's `uint40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*/
function toUint40(uint256 value) internal pure returns (uint40) {
if (value > type(uint40).max) {
revert SafeCastOverflowedUintDowncast(40, value);
}
return uint40(value);
}
/**
* @dev Returns the downcasted uint32 from uint256, reverting on
* overflow (when the input is greater than largest uint32).
*
* Counterpart to Solidity's `uint32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*/
function toUint32(uint256 value) internal pure returns (uint32) {
if (value > type(uint32).max) {
revert SafeCastOverflowedUintDowncast(32, value);
}
return uint32(value);
}
/**
* @dev Returns the downcasted uint24 from uint256, reverting on
* overflow (when the input is greater than largest uint24).
*
* Counterpart to Solidity's `uint24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*/
function toUint24(uint256 value) internal pure returns (uint24) {
if (value > type(uint24).max) {
revert SafeCastOverflowedUintDowncast(24, value);
}
return uint24(value);
}
/**
* @dev Returns the downcasted uint16 from uint256, reverting on
* overflow (when the input is greater than largest uint16).
*
* Counterpart to Solidity's `uint16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*/
function toUint16(uint256 value) internal pure returns (uint16) {
if (value > type(uint16).max) {
revert SafeCastOverflowedUintDowncast(16, value);
}
return uint16(value);
}
/**
* @dev Returns the downcasted uint8 from uint256, reverting on
* overflow (when the input is greater than largest uint8).
*
* Counterpart to Solidity's `uint8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*/
function toUint8(uint256 value) internal pure returns (uint8) {
if (value > type(uint8).max) {
revert SafeCastOverflowedUintDowncast(8, value);
}
return uint8(value);
}
/**
* @dev Converts a signed int256 into an unsigned uint256.
*
* Requirements:
*
* - input must be greater than or equal to 0.
*/
function toUint256(int256 value) internal pure returns (uint256) {
if (value < 0) {
revert SafeCastOverflowedIntToUint(value);
}
return uint256(value);
}
/**
* @dev Returns the downcasted int248 from int256, reverting on
* overflow (when the input is less than smallest int248 or
* greater than largest int248).
*
* Counterpart to Solidity's `int248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*/
function toInt248(int256 value) internal pure returns (int248 downcasted) {
downcasted = int248(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(248, value);
}
}
/**
* @dev Returns the downcasted int240 from int256, reverting on
* overflow (when the input is less than smallest int240 or
* greater than largest int240).
*
* Counterpart to Solidity's `int240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*/
function toInt240(int256 value) internal pure returns (int240 downcasted) {
downcasted = int240(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(240, value);
}
}
/**
* @dev Returns the downcasted int232 from int256, reverting on
* overflow (when the input is less than smallest int232 or
* greater than largest int232).
*
* Counterpart to Solidity's `int232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*/
function toInt232(int256 value) internal pure returns (int232 downcasted) {
downcasted = int232(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(232, value);
}
}
/**
* @dev Returns the downcasted int224 from int256, reverting on
* overflow (when the input is less than smallest int224 or
* greater than largest int224).
*
* Counterpart to Solidity's `int224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*/
function toInt224(int256 value) internal pure returns (int224 downcasted) {
downcasted = int224(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(224, value);
}
}
/**
* @dev Returns the downcasted int216 from int256, reverting on
* overflow (when the input is less than smallest int216 or
* greater than largest int216).
*
* Counterpart to Solidity's `int216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*/
function toInt216(int256 value) internal pure returns (int216 downcasted) {
downcasted = int216(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(216, value);
}
}
/**
* @dev Returns the downcasted int208 from int256, reverting on
* overflow (when the input is less than smallest int208 or
* greater than largest int208).
*
* Counterpart to Solidity's `int208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*/
function toInt208(int256 value) internal pure returns (int208 downcasted) {
downcasted = int208(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(208, value);
}
}
/**
* @dev Returns the downcasted int200 from int256, reverting on
* overflow (when the input is less than smallest int200 or
* greater than largest int200).
*
* Counterpart to Solidity's `int200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*/
function toInt200(int256 value) internal pure returns (int200 downcasted) {
downcasted = int200(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(200, value);
}
}
/**
* @dev Returns the downcasted int192 from int256, reverting on
* overflow (when the input is less than smallest int192 or
* greater than largest int192).
*
* Counterpart to Solidity's `int192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*/
function toInt192(int256 value) internal pure returns (int192 downcasted) {
downcasted = int192(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(192, value);
}
}
/**
* @dev Returns the downcasted int184 from int256, reverting on
* overflow (when the input is less than smallest int184 or
* greater than largest int184).
*
* Counterpart to Solidity's `int184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*/
function toInt184(int256 value) internal pure returns (int184 downcasted) {
downcasted = int184(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(184, value);
}
}
/**
* @dev Returns the downcasted int176 from int256, reverting on
* overflow (when the input is less than smallest int176 or
* greater than largest int176).
*
* Counterpart to Solidity's `int176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*/
function toInt176(int256 value) internal pure returns (int176 downcasted) {
downcasted = int176(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(176, value);
}
}
/**
* @dev Returns the downcasted int168 from int256, reverting on
* overflow (when the input is less than smallest int168 or
* greater than largest int168).
*
* Counterpart to Solidity's `int168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*/
function toInt168(int256 value) internal pure returns (int168 downcasted) {
downcasted = int168(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(168, value);
}
}
/**
* @dev Returns the downcasted int160 from int256, reverting on
* overflow (when the input is less than smallest int160 or
* greater than largest int160).
*
* Counterpart to Solidity's `int160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*/
function toInt160(int256 value) internal pure returns (int160 downcasted) {
downcasted = int160(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(160, value);
}
}
/**
* @dev Returns the downcasted int152 from int256, reverting on
* overflow (when the input is less than smallest int152 or
* greater than largest int152).
*
* Counterpart to Solidity's `int152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*/
function toInt152(int256 value) internal pure returns (int152 downcasted) {
downcasted = int152(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(152, value);
}
}
/**
* @dev Returns the downcasted int144 from int256, reverting on
* overflow (when the input is less than smallest int144 or
* greater than largest int144).
*
* Counterpart to Solidity's `int144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*/
function toInt144(int256 value) internal pure returns (int144 downcasted) {
downcasted = int144(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(144, value);
}
}
/**
* @dev Returns the downcasted int136 from int256, reverting on
* overflow (when the input is less than smallest int136 or
* greater than largest int136).
*
* Counterpart to Solidity's `int136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*/
function toInt136(int256 value) internal pure returns (int136 downcasted) {
downcasted = int136(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(136, value);
}
}
/**
* @dev Returns the downcasted int128 from int256, reverting on
* overflow (when the input is less than smallest int128 or
* greater than largest int128).
*
* Counterpart to Solidity's `int128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*/
function toInt128(int256 value) internal pure returns (int128 downcasted) {
downcasted = int128(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(128, value);
}
}
/**
* @dev Returns the downcasted int120 from int256, reverting on
* overflow (when the input is less than smallest int120 or
* greater than largest int120).
*
* Counterpart to Solidity's `int120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*/
function toInt120(int256 value) internal pure returns (int120 downcasted) {
downcasted = int120(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(120, value);
}
}
/**
* @dev Returns the downcasted int112 from int256, reverting on
* overflow (when the input is less than smallest int112 or
* greater than largest int112).
*
* Counterpart to Solidity's `int112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*/
function toInt112(int256 value) internal pure returns (int112 downcasted) {
downcasted = int112(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(112, value);
}
}
/**
* @dev Returns the downcasted int104 from int256, reverting on
* overflow (when the input is less than smallest int104 or
* greater than largest int104).
*
* Counterpart to Solidity's `int104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*/
function toInt104(int256 value) internal pure returns (int104 downcasted) {
downcasted = int104(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(104, value);
}
}
/**
* @dev Returns the downcasted int96 from int256, reverting on
* overflow (when the input is less than smallest int96 or
* greater than largest int96).
*
* Counterpart to Solidity's `int96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*/
function toInt96(int256 value) internal pure returns (int96 downcasted) {
downcasted = int96(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(96, value);
}
}
/**
* @dev Returns the downcasted int88 from int256, reverting on
* overflow (when the input is less than smallest int88 or
* greater than largest int88).
*
* Counterpart to Solidity's `int88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*/
function toInt88(int256 value) internal pure returns (int88 downcasted) {
downcasted = int88(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(88, value);
}
}
/**
* @dev Returns the downcasted int80 from int256, reverting on
* overflow (when the input is less than smallest int80 or
* greater than largest int80).
*
* Counterpart to Solidity's `int80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*/
function toInt80(int256 value) internal pure returns (int80 downcasted) {
downcasted = int80(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(80, value);
}
}
/**
* @dev Returns the downcasted int72 from int256, reverting on
* overflow (when the input is less than smallest int72 or
* greater than largest int72).
*
* Counterpart to Solidity's `int72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*/
function toInt72(int256 value) internal pure returns (int72 downcasted) {
downcasted = int72(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(72, value);
}
}
/**
* @dev Returns the downcasted int64 from int256, reverting on
* overflow (when the input is less than smallest int64 or
* greater than largest int64).
*
* Counterpart to Solidity's `int64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*/
function toInt64(int256 value) internal pure returns (int64 downcasted) {
downcasted = int64(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(64, value);
}
}
/**
* @dev Returns the downcasted int56 from int256, reverting on
* overflow (when the input is less than smallest int56 or
* greater than largest int56).
*
* Counterpart to Solidity's `int56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*/
function toInt56(int256 value) internal pure returns (int56 downcasted) {
downcasted = int56(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(56, value);
}
}
/**
* @dev Returns the downcasted int48 from int256, reverting on
* overflow (when the input is less than smallest int48 or
* greater than largest int48).
*
* Counterpart to Solidity's `int48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*/
function toInt48(int256 value) internal pure returns (int48 downcasted) {
downcasted = int48(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(48, value);
}
}
/**
* @dev Returns the downcasted int40 from int256, reverting on
* overflow (when the input is less than smallest int40 or
* greater than largest int40).
*
* Counterpart to Solidity's `int40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*/
function toInt40(int256 value) internal pure returns (int40 downcasted) {
downcasted = int40(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(40, value);
}
}
/**
* @dev Returns the downcasted int32 from int256, reverting on
* overflow (when the input is less than smallest int32 or
* greater than largest int32).
*
* Counterpart to Solidity's `int32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*/
function toInt32(int256 value) internal pure returns (int32 downcasted) {
downcasted = int32(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(32, value);
}
}
/**
* @dev Returns the downcasted int24 from int256, reverting on
* overflow (when the input is less than smallest int24 or
* greater than largest int24).
*
* Counterpart to Solidity's `int24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*/
function toInt24(int256 value) internal pure returns (int24 downcasted) {
downcasted = int24(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(24, value);
}
}
/**
* @dev Returns the downcasted int16 from int256, reverting on
* overflow (when the input is less than smallest int16 or
* greater than largest int16).
*
* Counterpart to Solidity's `int16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*/
function toInt16(int256 value) internal pure returns (int16 downcasted) {
downcasted = int16(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(16, value);
}
}
/**
* @dev Returns the downcasted int8 from int256, reverting on
* overflow (when the input is less than smallest int8 or
* greater than largest int8).
*
* Counterpart to Solidity's `int8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*/
function toInt8(int256 value) internal pure returns (int8 downcasted) {
downcasted = int8(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(8, value);
}
}
/**
* @dev Converts an unsigned uint256 into a signed int256.
*
* Requirements:
*
* - input must be less than or equal to maxInt256.
*/
function toInt256(uint256 value) internal pure returns (int256) {
// Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
if (value > uint256(type(int256).max)) {
revert SafeCastOverflowedUintToInt(value);
}
return int256(value);
}
/**
* @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump.
*/
function toUint(bool b) internal pure returns (uint256 u) {
assembly ("memory-safe") {
u := iszero(iszero(b))
}
}
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/Panic.sol)
pragma solidity ^0.8.20;
/**
* @dev Helper library for emitting standardized panic codes.
*
* ```solidity
* contract Example {
* using Panic for uint256;
*
* // Use any of the declared internal constants
* function foo() { Panic.GENERIC.panic(); }
*
* // Alternatively
* function foo() { Panic.panic(Panic.GENERIC); }
* }
* ```
*
* Follows the list from https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h[libsolutil].
*
* _Available since v5.1._
*/
// slither-disable-next-line unused-state
library Panic {
/// @dev generic / unspecified error
uint256 internal constant GENERIC = 0x00;
/// @dev used by the assert() builtin
uint256 internal constant ASSERT = 0x01;
/// @dev arithmetic underflow or overflow
uint256 internal constant UNDER_OVERFLOW = 0x11;
/// @dev division or modulo by zero
uint256 internal constant DIVISION_BY_ZERO = 0x12;
/// @dev enum conversion error
uint256 internal constant ENUM_CONVERSION_ERROR = 0x21;
/// @dev invalid encoding in storage
uint256 internal constant STORAGE_ENCODING_ERROR = 0x22;
/// @dev empty array pop
uint256 internal constant EMPTY_ARRAY_POP = 0x31;
/// @dev array out of bounds access
uint256 internal constant ARRAY_OUT_OF_BOUNDS = 0x32;
/// @dev resource error (too large allocation or too large array)
uint256 internal constant RESOURCE_ERROR = 0x41;
/// @dev calling invalid internal function
uint256 internal constant INVALID_INTERNAL_FUNCTION = 0x51;
/// @dev Reverts with a panic code. Recommended to use with
/// the internal constants with predefined codes.
function panic(uint256 code) internal pure {
assembly ("memory-safe") {
mstore(0x00, 0x4e487b71)
mstore(0x20, code)
revert(0x1c, 0x24)
}
}
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (utils/Pausable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract Pausable is Context {
bool private _paused;
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
/**
* @dev The operation failed because the contract is paused.
*/
error EnforcedPause();
/**
* @dev The operation failed because the contract is not paused.
*/
error ExpectedPause();
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
_requireNotPaused();
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
_requirePaused();
_;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
return _paused;
}
/**
* @dev Throws if the contract is paused.
*/
function _requireNotPaused() internal view virtual {
if (paused()) {
revert EnforcedPause();
}
}
/**
* @dev Throws if the contract is not paused.
*/
function _requirePaused() internal view virtual {
if (!paused()) {
revert ExpectedPause();
}
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (utils/SlotDerivation.sol)
// This file was procedurally generated from scripts/generate/templates/SlotDerivation.js.
pragma solidity ^0.8.20;
/**
* @dev Library for computing storage (and transient storage) locations from namespaces and deriving slots
* corresponding to standard patterns. The derivation method for array and mapping matches the storage layout used by
* the solidity language / compiler.
*
* See https://docs.soliditylang.org/en/v0.8.20/internals/layout_in_storage.html#mappings-and-dynamic-arrays[Solidity docs for mappings and dynamic arrays.].
*
* Example usage:
* ```solidity
* contract Example {
* // Add the library methods
* using StorageSlot for bytes32;
* using SlotDerivation for bytes32;
*
* // Declare a namespace
* string private constant _NAMESPACE = "<namespace>"; // eg. OpenZeppelin.Slot
*
* function setValueInNamespace(uint256 key, address newValue) internal {
* _NAMESPACE.erc7201Slot().deriveMapping(key).getAddressSlot().value = newValue;
* }
*
* function getValueInNamespace(uint256 key) internal view returns (address) {
* return _NAMESPACE.erc7201Slot().deriveMapping(key).getAddressSlot().value;
* }
* }
* ```
*
* TIP: Consider using this library along with {StorageSlot}.
*
* NOTE: This library provides a way to manipulate storage locations in a non-standard way. Tooling for checking
* upgrade safety will ignore the slots accessed through this library.
*
* _Available since v5.1._
*/
library SlotDerivation {
/**
* @dev Derive an ERC-7201 slot from a string (namespace).
*/
function erc7201Slot(string memory namespace) internal pure returns (bytes32 slot) {
assembly ("memory-safe") {
mstore(0x00, sub(keccak256(add(namespace, 0x20), mload(namespace)), 1))
slot := and(keccak256(0x00, 0x20), not(0xff))
}
}
/**
* @dev Add an offset to a slot to get the n-th element of a structure or an array.
*/
function offset(bytes32 slot, uint256 pos) internal pure returns (bytes32 result) {
unchecked {
return bytes32(uint256(slot) + pos);
}
}
/**
* @dev Derive the location of the first element in an array from the slot where the length is stored.
*/
function deriveArray(bytes32 slot) internal pure returns (bytes32 result) {
assembly ("memory-safe") {
mstore(0x00, slot)
result := keccak256(0x00, 0x20)
}
}
/**
* @dev Derive the location of a mapping element from the key.
*/
function deriveMapping(bytes32 slot, address key) internal pure returns (bytes32 result) {
assembly ("memory-safe") {
mstore(0x00, and(key, shr(96, not(0))))
mstore(0x20, slot)
result := keccak256(0x00, 0x40)
}
}
/**
* @dev Derive the location of a mapping element from the key.
*/
function deriveMapping(bytes32 slot, bool key) internal pure returns (bytes32 result) {
assembly ("memory-safe") {
mstore(0x00, iszero(iszero(key)))
mstore(0x20, slot)
result := keccak256(0x00, 0x40)
}
}
/**
* @dev Derive the location of a mapping element from the key.
*/
function deriveMapping(bytes32 slot, bytes32 key) internal pure returns (bytes32 result) {
assembly ("memory-safe") {
mstore(0x00, key)
mstore(0x20, slot)
result := keccak256(0x00, 0x40)
}
}
/**
* @dev Derive the location of a mapping element from the key.
*/
function deriveMapping(bytes32 slot, uint256 key) internal pure returns (bytes32 result) {
assembly ("memory-safe") {
mstore(0x00, key)
mstore(0x20, slot)
result := keccak256(0x00, 0x40)
}
}
/**
* @dev Derive the location of a mapping element from the key.
*/
function deriveMapping(bytes32 slot, int256 key) internal pure returns (bytes32 result) {
assembly ("memory-safe") {
mstore(0x00, key)
mstore(0x20, slot)
result := keccak256(0x00, 0x40)
}
}
/**
* @dev Derive the location of a mapping element from the key.
*/
function deriveMapping(bytes32 slot, string memory key) internal pure returns (bytes32 result) {
assembly ("memory-safe") {
let length := mload(key)
let begin := add(key, 0x20)
let end := add(begin, length)
let cache := mload(end)
mstore(end, slot)
result := keccak256(begin, add(length, 0x20))
mstore(end, cache)
}
}
/**
* @dev Derive the location of a mapping element from the key.
*/
function deriveMapping(bytes32 slot, bytes memory key) internal pure returns (bytes32 result) {
assembly ("memory-safe") {
let length := mload(key)
let begin := add(key, 0x20)
let end := add(begin, length)
let cache := mload(end)
mstore(end, slot)
result := keccak256(begin, add(length, 0x20))
mstore(end, cache)
}
}
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/StorageSlot.sol)
// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.
pragma solidity ^0.8.20;
/**
* @dev Library for reading and writing primitive types to specific storage slots.
*
* Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
* This library helps with reading and writing to such slots without the need for inline assembly.
*
* The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
*
* Example usage to set ERC-1967 implementation slot:
* ```solidity
* contract ERC1967 {
* // Define the slot. Alternatively, use the SlotDerivation library to derive the slot.
* bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
*
* function _getImplementation() internal view returns (address) {
* return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
* }
*
* function _setImplementation(address newImplementation) internal {
* require(newImplementation.code.length > 0);
* StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
* }
* }
* ```
*
* TIP: Consider using this library along with {SlotDerivation}.
*/
library StorageSlot {
struct AddressSlot {
address value;
}
struct BooleanSlot {
bool value;
}
struct Bytes32Slot {
bytes32 value;
}
struct Uint256Slot {
uint256 value;
}
struct Int256Slot {
int256 value;
}
struct StringSlot {
string value;
}
struct BytesSlot {
bytes value;
}
/**
* @dev Returns an `AddressSlot` with member `value` located at `slot`.
*/
function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns a `BooleanSlot` with member `value` located at `slot`.
*/
function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns a `Bytes32Slot` with member `value` located at `slot`.
*/
function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns a `Uint256Slot` with member `value` located at `slot`.
*/
function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns a `Int256Slot` with member `value` located at `slot`.
*/
function getInt256Slot(bytes32 slot) internal pure returns (Int256Slot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns a `StringSlot` with member `value` located at `slot`.
*/
function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns an `StringSlot` representation of the string storage pointer `store`.
*/
function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
assembly ("memory-safe") {
r.slot := store.slot
}
}
/**
* @dev Returns a `BytesSlot` with member `value` located at `slot`.
*/
function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.
*/
function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
assembly ("memory-safe") {
r.slot := store.slot
}
}
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (utils/structs/EnumerableSet.sol)
// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.
pragma solidity ^0.8.20;
import {Arrays} from "../Arrays.sol";
import {Math} from "../math/Math.sol";
/**
* @dev Library for managing
* https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
* types.
*
* Sets have the following properties:
*
* - Elements are added, removed, and checked for existence in constant time
* (O(1)).
* - Elements are enumerated in O(n). No guarantees are made on the ordering.
* - Set can be cleared (all elements removed) in O(n).
*
* ```solidity
* contract Example {
* // Add the library methods
* using EnumerableSet for EnumerableSet.AddressSet;
*
* // Declare a set state variable
* EnumerableSet.AddressSet private mySet;
* }
* ```
*
* The following types are supported:
*
* - `bytes32` (`Bytes32Set`) since v3.3.0
* - `address` (`AddressSet`) since v3.3.0
* - `uint256` (`UintSet`) since v3.3.0
* - `string` (`StringSet`) since v5.4.0
* - `bytes` (`BytesSet`) since v5.4.0
*
* [WARNING]
* ====
* Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
* unusable.
* See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
*
* In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
* array of EnumerableSet.
* ====
*/
library EnumerableSet {
// To implement this library for multiple types with as little code
// repetition as possible, we write it in terms of a generic Set type with
// bytes32 values.
// The Set implementation uses private functions, and user-facing
// implementations (such as AddressSet) are just wrappers around the
// underlying Set.
// This means that we can only create new EnumerableSets for types that fit
// in bytes32.
struct Set {
// Storage of set values
bytes32[] _values;
// Position is the index of the value in the `values` array plus 1.
// Position 0 is used to mean a value is not in the set.
mapping(bytes32 value => uint256) _positions;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
// The value is stored at length-1, but we add 1 to all indexes
// and use 0 as a sentinel value
set._positions[value] = set._values.length;
return true;
} else {
return false;
}
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function _remove(Set storage set, bytes32 value) private returns (bool) {
// We cache the value's position to prevent multiple reads from the same storage slot
uint256 position = set._positions[value];
if (position != 0) {
// Equivalent to contains(set, value)
// To delete an element from the _values array in O(1), we swap the element to delete with the last one in
// the array, and then remove the last element (sometimes called as 'swap and pop').
// This modifies the order of the array, as noted in {at}.
uint256 valueIndex = position - 1;
uint256 lastIndex = set._values.length - 1;
if (valueIndex != lastIndex) {
bytes32 lastValue = set._values[lastIndex];
// Move the lastValue to the index where the value to delete is
set._values[valueIndex] = lastValue;
// Update the tracked position of the lastValue (that was just moved)
set._positions[lastValue] = position;
}
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the tracked position for the deleted slot
delete set._positions[value];
return true;
} else {
return false;
}
}
/**
* @dev Removes all the values from a set. O(n).
*
* WARNING: This function has an unbounded cost that scales with set size. Developers should keep in mind that
* using it may render the function uncallable if the set grows to the point where clearing it consumes too much
* gas to fit in a block.
*/
function _clear(Set storage set) private {
uint256 len = _length(set);
for (uint256 i = 0; i < len; ++i) {
delete set._positions[set._values[i]];
}
Arrays.unsafeSetLength(set._values, 0);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._positions[value] != 0;
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function _at(Set storage set, uint256 index) private view returns (bytes32) {
return set._values[index];
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function _values(Set storage set) private view returns (bytes32[] memory) {
return set._values;
}
/**
* @dev Return a slice of the set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function _values(Set storage set, uint256 start, uint256 end) private view returns (bytes32[] memory) {
unchecked {
end = Math.min(end, _length(set));
start = Math.min(start, end);
uint256 len = end - start;
bytes32[] memory result = new bytes32[](len);
for (uint256 i = 0; i < len; ++i) {
result[i] = Arrays.unsafeAccess(set._values, start + i).value;
}
return result;
}
}
// Bytes32Set
struct Bytes32Set {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
/**
* @dev Removes all the values from a set. O(n).
*
* WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the
* function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.
*/
function clear(Bytes32Set storage set) internal {
_clear(set._inner);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
bytes32[] memory store = _values(set._inner);
bytes32[] memory result;
assembly ("memory-safe") {
result := store
}
return result;
}
/**
* @dev Return a slice of the set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(Bytes32Set storage set, uint256 start, uint256 end) internal view returns (bytes32[] memory) {
bytes32[] memory store = _values(set._inner, start, end);
bytes32[] memory result;
assembly ("memory-safe") {
result := store
}
return result;
}
// AddressSet
struct AddressSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Removes all the values from a set. O(n).
*
* WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the
* function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.
*/
function clear(AddressSet storage set) internal {
_clear(set._inner);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(AddressSet storage set) internal view returns (address[] memory) {
bytes32[] memory store = _values(set._inner);
address[] memory result;
assembly ("memory-safe") {
result := store
}
return result;
}
/**
* @dev Return a slice of the set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(AddressSet storage set, uint256 start, uint256 end) internal view returns (address[] memory) {
bytes32[] memory store = _values(set._inner, start, end);
address[] memory result;
assembly ("memory-safe") {
result := store
}
return result;
}
// UintSet
struct UintSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
/**
* @dev Removes all the values from a set. O(n).
*
* WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the
* function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.
*/
function clear(UintSet storage set) internal {
_clear(set._inner);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(UintSet storage set) internal view returns (uint256[] memory) {
bytes32[] memory store = _values(set._inner);
uint256[] memory result;
assembly ("memory-safe") {
result := store
}
return result;
}
/**
* @dev Return a slice of the set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(UintSet storage set, uint256 start, uint256 end) internal view returns (uint256[] memory) {
bytes32[] memory store = _values(set._inner, start, end);
uint256[] memory result;
assembly ("memory-safe") {
result := store
}
return result;
}
struct StringSet {
// Storage of set values
string[] _values;
// Position is the index of the value in the `values` array plus 1.
// Position 0 is used to mean a value is not in the set.
mapping(string value => uint256) _positions;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(StringSet storage set, string memory value) internal returns (bool) {
if (!contains(set, value)) {
set._values.push(value);
// The value is stored at length-1, but we add 1 to all indexes
// and use 0 as a sentinel value
set._positions[value] = set._values.length;
return true;
} else {
return false;
}
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(StringSet storage set, string memory value) internal returns (bool) {
// We cache the value's position to prevent multiple reads from the same storage slot
uint256 position = set._positions[value];
if (position != 0) {
// Equivalent to contains(set, value)
// To delete an element from the _values array in O(1), we swap the element to delete with the last one in
// the array, and then remove the last element (sometimes called as 'swap and pop').
// This modifies the order of the array, as noted in {at}.
uint256 valueIndex = position - 1;
uint256 lastIndex = set._values.length - 1;
if (valueIndex != lastIndex) {
string memory lastValue = set._values[lastIndex];
// Move the lastValue to the index where the value to delete is
set._values[valueIndex] = lastValue;
// Update the tracked position of the lastValue (that was just moved)
set._positions[lastValue] = position;
}
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the tracked position for the deleted slot
delete set._positions[value];
return true;
} else {
return false;
}
}
/**
* @dev Removes all the values from a set. O(n).
*
* WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the
* function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.
*/
function clear(StringSet storage set) internal {
uint256 len = length(set);
for (uint256 i = 0; i < len; ++i) {
delete set._positions[set._values[i]];
}
Arrays.unsafeSetLength(set._values, 0);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(StringSet storage set, string memory value) internal view returns (bool) {
return set._positions[value] != 0;
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function length(StringSet storage set) internal view returns (uint256) {
return set._values.length;
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(StringSet storage set, uint256 index) internal view returns (string memory) {
return set._values[index];
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(StringSet storage set) internal view returns (string[] memory) {
return set._values;
}
/**
* @dev Return a slice of the set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(StringSet storage set, uint256 start, uint256 end) internal view returns (string[] memory) {
unchecked {
end = Math.min(end, length(set));
start = Math.min(start, end);
uint256 len = end - start;
string[] memory result = new string[](len);
for (uint256 i = 0; i < len; ++i) {
result[i] = Arrays.unsafeAccess(set._values, start + i).value;
}
return result;
}
}
struct BytesSet {
// Storage of set values
bytes[] _values;
// Position is the index of the value in the `values` array plus 1.
// Position 0 is used to mean a value is not in the set.
mapping(bytes value => uint256) _positions;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(BytesSet storage set, bytes memory value) internal returns (bool) {
if (!contains(set, value)) {
set._values.push(value);
// The value is stored at length-1, but we add 1 to all indexes
// and use 0 as a sentinel value
set._positions[value] = set._values.length;
return true;
} else {
return false;
}
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(BytesSet storage set, bytes memory value) internal returns (bool) {
// We cache the value's position to prevent multiple reads from the same storage slot
uint256 position = set._positions[value];
if (position != 0) {
// Equivalent to contains(set, value)
// To delete an element from the _values array in O(1), we swap the element to delete with the last one in
// the array, and then remove the last element (sometimes called as 'swap and pop').
// This modifies the order of the array, as noted in {at}.
uint256 valueIndex = position - 1;
uint256 lastIndex = set._values.length - 1;
if (valueIndex != lastIndex) {
bytes memory lastValue = set._values[lastIndex];
// Move the lastValue to the index where the value to delete is
set._values[valueIndex] = lastValue;
// Update the tracked position of the lastValue (that was just moved)
set._positions[lastValue] = position;
}
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the tracked position for the deleted slot
delete set._positions[value];
return true;
} else {
return false;
}
}
/**
* @dev Removes all the values from a set. O(n).
*
* WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the
* function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.
*/
function clear(BytesSet storage set) internal {
uint256 len = length(set);
for (uint256 i = 0; i < len; ++i) {
delete set._positions[set._values[i]];
}
Arrays.unsafeSetLength(set._values, 0);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(BytesSet storage set, bytes memory value) internal view returns (bool) {
return set._positions[value] != 0;
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function length(BytesSet storage set) internal view returns (uint256) {
return set._values.length;
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(BytesSet storage set, uint256 index) internal view returns (bytes memory) {
return set._values[index];
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(BytesSet storage set) internal view returns (bytes[] memory) {
return set._values;
}
/**
* @dev Return a slice of the set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(BytesSet storage set, uint256 start, uint256 end) internal view returns (bytes[] memory) {
unchecked {
end = Math.min(end, length(set));
start = Math.min(start, end);
uint256 len = end - start;
bytes[] memory result = new bytes[](len);
for (uint256 i = 0; i < len; ++i) {
result[i] = Arrays.unsafeAccess(set._values, start + i).value;
}
return result;
}
}
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
pragma solidity 0.8.27;
import {AccessControlEnumerable} from "@openzeppelin/contracts/access/extensions/AccessControlEnumerable.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import {IERC7984} from "@openzeppelin/confidential-contracts/contracts/interfaces/IERC7984.sol";
import {Pausable} from "@openzeppelin/contracts/utils/Pausable.sol";
import {ebool, externalEuint64, euint64, FHE} from "@fhevm/solidity/lib/FHE.sol";
import {ZamaEthereumConfig} from "@fhevm/solidity/config/ZamaConfig.sol";
import {IAuctionToken} from "./interfaces/IAuctionToken.sol";
import {IKycAllowlistRegistry} from "./interfaces/IKycAllowlistRegistry.sol";
import {IWalletFactory} from "./interfaces/IWalletFactory.sol";
import {WalletFactory} from "./wallet/WalletFactory.sol";
/// @title Confidential Auction Token Contract
/// @author ecosystem-labs
/// @custom:security-contact security@zama.ai
/// @notice A confidential token auction using FHEVM.
///
/// This contract implements an encrypted auction mechanism, where individual bid quantities
/// remain confidential before, during and after the auction.
///
/// We expect the Zama token auctionned to be a standard ERC20 token.
///
/// ## Price Levels & Ticks
/// The auction defines discrete price levels (ticks) within a limited price range.
/// For each tick, the contract tracks the **cumulative requested token quantity**.
/// This design eliminates the need to iterate over every individual bid during settlement.
/// Instead, the contract only iterates over the defined price levels.
///
/// ## Bidding Process
/// - When a user places a bid, the requested quantity is added to the cumulative total
/// at the chosen price level.
/// - This cumulative data allows the system to quickly determine how much demand exists
/// at each price point without scanning through all bids individually.
/// - Finally, We keep track of each user's submitted bids.
/// - Each user is limited to MAX_ACTIVE_BIDS_PER_USER active bids. This limit is enforced
/// in submitEncryptedBid() and decremented in cancelBid(). External bids are not subject
/// to this limit.
///
/// Users have the option to cancel their bids. When a bid is canceled, the user is refunded,
/// and the auction state is updated to exclude the canceled bid.
///
/// Zama will have the possibility to see all bid information and confidential amounts transferred for
/// compliance purposes. Users can only access their own bids and cannot view other users' bids.
///
/// Users will have a bid quantity limitation defined at the deployment of the auction. This limitation
/// defines the maximum cumulative quantity of tokens a user can request across all their active bids.
///
/// ## Off-chain bids
/// In parallel to the on-chain auction, we will have external partners who will also run an auction off-chain.
/// To integrate their results, we will have a dedicated phase, just after the end of the auction, where an
/// admin-controlled wallet can submit the aggregated off-chain bids.
///
/// For each price level, the admin submits the total requested quantity of token on behalf of the external partners
/// without providing collateral. These bids may later become claimable after the auction
/// concludes, but they are **not eligible for refunds**. Note that when we submit the bids from the external partners
/// we also provide an escrow address controled by Zama and the partner.
///
/// This phase remains open until all necessary off-chain bids have been submitted and the admin explicitly
/// transitions the auction to the settlement phase. Note that it is possible for the admin to cancel submitted
/// off-chain bids in case of errors.
///
/// ## Settlement Logic
/// Before computing the settlement, the admin will have to verify the validity of all the bids, using the
/// compliance address, ensuring that all the users are KYCed and allowed to participate in the auction.
/// The admin will also verify that we do not have a single bids requesting the whole supply of the auction that
/// could eventually control the whole supply auctioned.
/// To do those verifications, the admin can delete regular bids if needed. Notice that it has to be **before**
/// we start the settlement process.
///
/// The settlement process involves different operations:
/// - The computation of the **final clearing price** (the settlement price).
/// - The user allocation and the authorization to decrypt it.
///
/// The settlement logic can be decomposed in 4 steps:
/// 1. Decrypt for each price level the total quantity of tokens bid.
/// 2. Iterate through price levels in descending order until we have no more token to distribute. Here, the last
/// price level will be the settlement price.
/// 3. Iterate over all the winning bids (bid price >= settlement price) to compute the user allocation.
/// 4. Iterate over all the winners to render their allocation publicly decryptable.
///
/// Revealing the quantity per price level reduces the number of FHE operations needed during the settlement.
/// Note that the range of allowed price levels is bounded to ensure predictable computation
/// and to limit iteration during settlement.
/// It is important to note that revealing the total requested quantity per price level can potentially leak
/// user amounts if there is only a single bid at that price level.
///
/// Regarding the computation of the user allocation, we are computing it during the settlement, allowing any
/// user to have his allocation ready at claiming. Users will only need to decrypt this value and have the valid proof
/// from the relayer allowing them to claimed their allocation. This design choice is motivated to reduce the number
/// of FHE operations needed during the claiming phase and avoid any delays at claiming due to FHE computation.
///
/// During this process, we are also verifying that no issue occurred in the smart contract.
///
/// Once the settlement price is computed, the admin can claim and receive the external bids allowing them to distribute
/// the allocation of the partner. Once those tokens are claimed and sent, the admin can explicitly move the auction
/// to the claiming phase.
///
/// ## User Allocation
/// Users allocation is computed based on the bid price:
/// - If a bid’s price is higher than the settlement price, the user receives the requested tokens.
/// - If a bid’s price is lower, the user does not receive tokens.
/// - If a bid's price is equal to the settlement price, the user will received a pro-rata allocation. In that case,
/// each user's allocated quantity at this price level is proportional to their bid relative to the total requested
/// quantity at that price, multiplied by the remaining supply. We can define as:
/// (userBidQuantity / totalRequestedAtPrice) * remainingSupply
/// Note: In a pro-rata allocation, the computation can potentially round down the expected allocation for the user.
/// The final user allocations will be the sum of tokens allocated. The users will pay only for the tokens attributed.
///
/// Depending on the settlement price, users can get refunded accordingly.
/// - Partially if the requested price is above or equal the settlement price.
/// - Fully, if the requested price is below the settlement price.
///
/// ### Claiming phase
/// In the claiming phase, users will have the possibility to:
/// - Claimed their Zama tokens allocated
/// - Get refunded based on their allocation
/// Notice that the user who has an allocation, will need to first claimed their Zama token before being able to get
/// a refund. This design choice is motivated as we want to avoid unecessary FHE operations and we can leverage the
/// clear values used at claiming.
/// During the claiming phase, anyone can call those functions at the moment the proof is valid and the user has not
/// already process it. However, the distribution will still be attributed to the right user.
///
/// Once all the token distributed and all the token refunded, the admin can finalize the auction by withdrawing
/// potential remaining Zama tokens (from an unfulfilled auction or division rounding) and all confidential stablecoins
/// from the sold of the tokens.
///
/// ## Multi-Wallet Architecture
/// To improve scalability and enable parallelization of FHE operations, the auction uses multiple
/// holding wallets instead of a single contract address to store user payments.
///
/// The WalletFactory deploys all wallet clones in the constructor using the minimal proxy pattern
/// with immutable arguments (Clones.cloneWithImmutableArgs). Each AuctionWallet clone stores its
/// configuration (factory, paymentToken, auction) directly in bytecode rather than storage,
/// eliminating storage slot costs and reducing deployment gas. This pattern allows up to 32 wallets
/// to be deployed within the 16M gas limit. Each wallet holds user funds for the ERC7984 payment
/// token and approves the auction contract as operator during initialization.
///
/// Users are deterministically assigned to wallets using a bitwise AND operation on their address
/// with a mask derived from the wallet count (which must be a power of 2).
/// This distributes users across N independent wallets.
///
/// This design avoids creating a single dependency chain for FHE computations. The single-wallet
/// model would force sequential processing of FHE operations. With multiple wallets, each wallet
/// will have its own dependency chain, allowing the coprocessor to process FHE operations
/// on different wallets in parallel.
///
/// ## Pausable
/// At any moment during the auction, the auction can be paused, allowing potential investigation and mitigation.
/// It will freeze all the interactions possible from the users. This pause can be set by any PAUSER_ROLE, but only an
/// admin can unpause the auction.
///
/// ## Cancellation
/// The auction can be canceled by the admin. It can only be canceled before the claiming phase is opened,
/// hence, during the bidding and settlement phases. The cancellation of the auction will be available only when
/// the auction is paused.
/// Once the auction is canceled:
/// - The admin can recover the ZAMA tokens held by the contract to the treasury.
/// - Users can claim refunds for their given bids.
///
/// @dev Payment token contracts are trusted deployments.
/// Those confidential tokens could include a regulated transfer mechanism preventing sanctioned users to transfer
/// tokens. Even if a user is sanctioned, the auction contract must still be able to operate normally
/// and should not be blocked to continue the auction process. Frozen funds remain held by the auction contract
/// and can only be withdrawn or transferred once the restriction is lifted for the affected user.
contract AuctionToken is IAuctionToken, ZamaEthereumConfig, AccessControlEnumerable, Pausable {
/// @notice Role identifier for addresses allowed to pause the auction
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
/// @notice Upper bound for zamaTokenSupply, enforced at deployment
uint64 private constant MAX_AUCTION_SUPPLY = 1_100_000_000;
/// @notice Minimum tick size for bid prices, denominated in cUSDC or cUSDT (6 decimals).
/// @dev All bid prices must be a multiple of this value. Valid prices will be 0.005, 0.01, 0.015, ..., 1.00.
/// @dev When a price is submitted, it will be rounded down to the nearest multiple of the tick size.
uint64 public constant FLOOR_PRICE_VALUE = 5_000; // 0.005 USDC
/// @notice Maximum number of bids allowed in a single transaction
/// @dev Prevents 'HCUTransactionLimitExceeded()' reverts by limiting the number of FHE operations
/// in a single transaction
uint256 internal constant MAX_NUMBER_OF_BIDS = 10;
/// @notice Maximum number of active (non-canceled) bids allowed per user
uint256 public constant MAX_ACTIVE_BIDS_PER_USER = 10;
/// @notice Conversion factor for the Zama token units
/// @dev Used to convert the auctioned token quantity (in whole tokens) to the smallest unit of the
/// Zama token (according to its decimals).
uint256 internal immutable ZAMA_TOKEN_FACTOR;
/// @notice Maximum bid price allowed (in cUSDC or cUSDT, 6 decimals)
/// @dev We limit the input price to avoid overflow issue on encrypted state
uint64 public immutable MAX_PRICE_VALUE;
/// @notice The wallet factory contract
IWalletFactory public immutable WALLET_FACTORY;
/// @notice The configuration parameters for the auction
AuctionConfig public auctionConfig;
/// @notice Auction state data
AuctionState public auctionState;
/// @notice Settlement data used to compute the final settlement price
SettlementData public settlementData;
/// @notice A mapping of bid ID to Bid structure, used to store bid details
mapping(uint256 bidId => Bid bid) private _bids;
/// @notice A mapping of user address to a list of bids
mapping(address userAddress => uint256[] bidIds) private _userBids;
/// @notice A mapping of user address to the count of active (non-canceled) bids
mapping(address userAddress => uint256 activeBidsCount) private _userActiveBidsCount;
/// @notice Tracks the total remaining bid quantity allowed for each user
/// @dev Initialized to `maxCumulativeBidQuantity` for each user upon their first bid.
mapping(address userAddress => euint64 remainingBidQuantity) public eRemainingUserBidQuota;
/// @notice A mapping of price to the total requested quantity at that price
mapping(uint64 priceLevel => euint64 eRequestedQuantity) public eTotalRequestedQuantityByPrice;
/// @notice A mapping of price to the total requested amount at that price in clear
mapping(uint64 priceLevel => uint64 requestedQuantity) internal _totalRequestedQuantityByPrice;
/// @notice Indicate if the requested quantity is revealed for a given price level
/// @dev We cannot use the decrypted value has it could potentially be 0 when a bid is canceled.
mapping(uint64 priceLevel => bool isDecrypted) internal _isRequestedQuantityDecrypted;
/// @notice Mapping from user address to claimed allocation (whole tokens)
mapping(address userAddress => uint64 claimedAmount) private _claimedAllocations;
/// @notice Mapping from price level to the number of bids at that price level
/// @dev Used to compute the number of bids per price level during decryption phase
/// Then we are using it to compute the prefix sum of the price level in decreasing order
/// allowing us to know how many bids need to be computed for the allocation
mapping(uint64 priceLevel => uint64 numberOfBids) public numberOfBidsPerPriceLevel;
/// @notice Mapping from user address to track the total amount paid by the user
/// @dev Used to compute refunds at claiming
mapping(address userAccount => euint64 eTotalPaid) internal _eTotalPaidByUser;
/// @notice Mapping to track regular users (non-external bidder)
/// @dev Used to prevent external bidder to have a refund
mapping(address userAccount => bool isRegularUser) internal _isRegularUser;
/// @notice Mapping from user address to their encrypted allocation
/// @dev The final value will be available once all the bids have been allocated
mapping(address user => euint64 eAllocation) public eUserAllocations;
/// @notice Mapping to track if a user has already claimed their allocation
mapping(address userAddress => bool claimed) public hasClaimedAllocation;
/// @notice Mapping to track if a user has already been refunded
mapping(address userAddress => bool refunded) public hasReceivedRefund;
/// @notice Keep track of all the bid winners
address[] private _winners;
/// @notice Mapping to track the number of tokens sold per wallet generated
mapping(address holdingWallet => uint64 zamaTokensSold) private _tokenSoldPerWallet;
/// @notice Mapping to track the encrypted refund available per user
/// @dev Used to avoid blocking confidential transfer from a freeze account
mapping(address userAddress => euint64 eRefundAvailable) public eRefundAvailable;
//////////////////////////////////////////////////////////////////
/// View Functions
//////////////////////////////////////////////////////////////////
/// @inheritdoc IAuctionToken
function getWalletFactory() external view returns (address) {
return address(WALLET_FACTORY);
}
/// @inheritdoc IAuctionToken
function totalNumberOfBids() external view returns (uint64) {
return auctionState.lastBidId;
}
/// @inheritdoc IAuctionToken
function numberOfBids(address user) external view returns (uint256) {
return _userBids[user].length;
}
/// @inheritdoc IAuctionToken
function numberOfActiveBids(address user) external view returns (uint256) {
return _userActiveBidsCount[user];
}
/// @inheritdoc IAuctionToken
function numberOfWinners() external view returns (uint256) {
return _winners.length;
}
/// @inheritdoc IAuctionToken
function getBid(uint256 bidId) external view returns (Bid memory) {
return _bids[bidId];
}
/// @inheritdoc IAuctionToken
function getUserBids(address user) external view returns (uint256[] memory) {
return _userBids[user];
}
/// @inheritdoc IAuctionToken
function getUserBidsDetail(address user, uint256 start, uint256 limit) external view returns (Bid[] memory bids) {
uint256 _userNbBids = _userBids[user].length;
if (start >= _userNbBids) return new Bid[](0);
if (start + limit > _userNbBids) limit = _userNbBids - start;
bids = new Bid[](limit);
for (uint256 i = 0; i < limit; ++i) {
bids[i] = _bids[_userBids[user][start]];
unchecked {
++start;
}
}
}
/// @inheritdoc IAuctionToken
function isClaimingOpen() external view returns (bool) {
return auctionState.claimingOpen && !auctionState.auctionCanceled && !paused();
}
/// @inheritdoc IAuctionToken
function isSettlementOpen() external view returns (bool) {
return auctionState.settlementOpen && !auctionState.auctionCanceled && !paused();
}
/// @inheritdoc IAuctionToken
function getTotalSettlementIterations() external view returns (uint64) {
return MAX_PRICE_VALUE / FLOOR_PRICE_VALUE;
}
/// @inheritdoc IAuctionToken
function getTotalRequestedQuantityByPrice(uint64 priceLevel) external view returns (uint64) {
require(
!FHE.isInitialized(eTotalRequestedQuantityByPrice[priceLevel]) || _isRequestedQuantityDecrypted[priceLevel],
QuantityNotDecrypted(priceLevel)
);
return _totalRequestedQuantityByPrice[priceLevel];
}
/// @inheritdoc IAuctionToken
function allocatedZamaSupply() public view returns (uint64) {
require(auctionState.settlementPrice != 0, SettlementPriceNotComputed());
return auctionConfig.zamaTokenSupply - auctionState.unallocatedZamaSupply;
}
/// @inheritdoc IAuctionToken
function claimedAllocationOf(address account) external view returns (uint64) {
return _claimedAllocations[account];
}
//////////////////////////////////////////////////////////////////
/// Modifier
//////////////////////////////////////////////////////////////////
modifier activeAuction() {
require(block.timestamp >= auctionConfig.startAuctionTime, AuctionNotStarted());
require(block.timestamp < auctionConfig.endAuctionTime, AuctionEnded());
_;
}
modifier afterAuction() {
require(block.timestamp >= auctionConfig.endAuctionTime, AuctionNotEnded());
_;
}
/// @notice Reverts when the auction is paused or canceled
modifier whenNotStopped() {
_requireNotPaused();
require(!auctionState.auctionCanceled, AuctionCanceledError());
_;
}
//////////////////////////////////////////////////////////////////
/// Constructor
//////////////////////////////////////////////////////////////////
/// @notice Verifies the auction parameters
/// @param _auctionConfig The auction configuration
/// @param _maxPriceValue The maximum price value for a bid
function _verifyParameters(AuctionConfig memory _auctionConfig, uint64 _maxPriceValue) private pure {
require(
_auctionConfig.startAuctionTime < _auctionConfig.endAuctionTime,
InvalidAuctionTimes(_auctionConfig.startAuctionTime, _auctionConfig.endAuctionTime)
);
require(_auctionConfig.zamaTokenSupply != 0, InvalidTokenSupply(_auctionConfig.zamaTokenSupply));
require(
_auctionConfig.zamaTokenSupply <= MAX_AUCTION_SUPPLY,
InvalidTokenSupply(_auctionConfig.zamaTokenSupply)
);
require(
_auctionConfig.maxCumulativeBidQuantity > 0 &&
_auctionConfig.maxCumulativeBidQuantity <= _auctionConfig.zamaTokenSupply,
InvalidMaxCumulativeBidQuantity(_auctionConfig.maxCumulativeBidQuantity)
);
// In case the max price value is above $10.00 we expect to do the change manually in the smart contract
// as it would significantly increase the number of operations needed for the settlement.
// In all the cases, prices below $1.00 should always be invalid.
require(1_000_000 <= _maxPriceValue && _maxPriceValue <= 10_000_000, InvalidMaximumPrice(_maxPriceValue));
require(_maxPriceValue % FLOOR_PRICE_VALUE == 0, InvalidMaximumPrice(_maxPriceValue));
}
/// @notice Verifies that the addresses are valid.
/// @param _zamaTokenAddress The address of the auctioned ZAMA token
/// @param _zamaTreasuryAddress Zama treasury address
/// @param _complianceAddress Compliance authority address
/// @param _kycAllowlistRegistryAddress KYC Allowlist Registry address
/// @param _paymentTokenAddress cUSDC or cUSDT token address
/// @param _roleAdminAddress Default admin address
/// @dev Reverts if any of the input addresses are zero
function _verifyInputAddresses(
address _zamaTokenAddress,
address _zamaTreasuryAddress,
address _complianceAddress,
address _kycAllowlistRegistryAddress,
address _paymentTokenAddress,
address _roleAdminAddress
) private pure {
require(_zamaTokenAddress != address(0), ZeroAddress("_zamaTokenAddress"));
require(_zamaTreasuryAddress != address(0), ZeroAddress("_zamaTreasuryAddress"));
require(_complianceAddress != address(0), ZeroAddress("_complianceAddress"));
require(_kycAllowlistRegistryAddress != address(0), ZeroAddress("_kycAllowlistRegistryAddress"));
require(_paymentTokenAddress != address(0), ZeroAddress("_paymentTokenAddress"));
require(_roleAdminAddress != address(0), ZeroAddress("_roleAdminAddress"));
}
/// @notice Constructor for the auction token contract
/// @param _auctionConfig Auction configuration
/// @param roleAdminAddress Multisig address administering auction roles
/// @param _maxPriceValue Maximum price value for a bid
/// @param pauserAddresses List of pauser addresses
constructor(
AuctionConfig memory _auctionConfig,
address roleAdminAddress,
uint64 _maxPriceValue,
address[] memory pauserAddresses
) {
// Verify the auction parameters and addresses
_verifyParameters(_auctionConfig, _maxPriceValue);
_verifyInputAddresses(
_auctionConfig.zamaTokenAddress,
_auctionConfig.zamaTreasuryAddress,
_auctionConfig.complianceAddress,
_auctionConfig.kycAllowlistRegistryAddress,
_auctionConfig.paymentTokenAddress,
roleAdminAddress
);
auctionConfig = _auctionConfig;
_grantRole(DEFAULT_ADMIN_ROLE, roleAdminAddress);
uint256 _pausersLength = pauserAddresses.length;
require(_pausersLength != 0, NoPausersProvided());
for (uint256 i = 0; i < _pausersLength; ++i) {
require(pauserAddresses[i] != address(0), ZeroAddress("_pauser"));
require(_grantRole(PAUSER_ROLE, pauserAddresses[i]), DuplicatedAddress(pauserAddresses[i]));
}
// Set the maximum bid price value for the auction
MAX_PRICE_VALUE = _maxPriceValue;
// Initialize the factor based on the Zama token decimals
ZAMA_TOKEN_FACTOR = uint256(10 ** IERC20Metadata(auctionConfig.zamaTokenAddress).decimals());
// Initialize auction state
settlementData = SettlementData({
previousDecryptionIteration: MAX_PRICE_VALUE,
remainingSupply: auctionConfig.zamaTokenSupply,
previousSettlementIteration: MAX_PRICE_VALUE,
remainingBidsToBeAllocated: 0,
winnerDecryptionIndex: 0,
remainingAllocationsToClaim: 0,
pendingSettlementPrice: MAX_PRICE_VALUE,
remainingPartnersAllocations: 0
});
// Deploy WalletFactory which will deploy the holding wallets
WALLET_FACTORY = new WalletFactory(_auctionConfig.walletCount, _auctionConfig.paymentTokenAddress);
}
/// @notice Private helper to allow authorizer access to encrypted value
/// @param eValue Encrypted value to authorize
/// @param userAddress Address of the user
/// @param complianceAddress Address of the compliance authority
function _authorizerHelper(euint64 eValue, address userAddress, address complianceAddress) private {
FHE.allowThis(eValue);
FHE.allow(eValue, userAddress);
FHE.allow(eValue, complianceAddress);
}
/// @notice Confidential transfer helper function to transfer from holding wallet to user
/// @param receiver Address of the account to transfer to (refund recipient)
/// @param eAmount Encrypted amount to transfer
/// @return ePaid Encrypted amount transferred authorized for compliance
function _confidentialTransfer(address receiver, euint64 eAmount) private returns (euint64 ePaid) {
// Transfer from holding wallet to user (for refunds)
address holdingWallet = WALLET_FACTORY.getHoldingWalletForUser(receiver);
FHE.allowTransient(eAmount, auctionConfig.paymentTokenAddress);
ePaid = IERC7984(auctionConfig.paymentTokenAddress).confidentialTransferFrom(holdingWallet, receiver, eAmount);
_authorizerHelper(ePaid, receiver, auctionConfig.complianceAddress);
}
//////////////////////////////////////////////////////////////////
/// Bidding process
//////////////////////////////////////////////////////////////////
/// @notice Private function to submit a bid
/// @param bidderAddress Address of the user submitting the bid
/// @param price Bid price level
/// @param eQuantity Encrypted quantity of Zama tokens requested
/// @param ePaid Encrypted amount paid in payment token
/// @param isExternalBid Boolean indicating if the bid is external
function _submitBid(
address bidderAddress,
uint64 price,
euint64 eQuantity,
euint64 ePaid,
bool isExternalBid
) private {
// Store the bid while increasing the number of bids
uint256 bidId = ++auctionState.lastBidId;
_bids[bidId] = Bid({
bidId: bidId,
eQuantity: eQuantity,
ePaid: ePaid,
price: price,
bidder: bidderAddress,
externalBid: isExternalBid,
canceled: false,
allocated: false,
createdAt: uint64(block.timestamp),
canceledAt: 0
});
_userBids[bidderAddress].push(bidId);
if (_userBids[bidderAddress].length == 1) {
++auctionState.totalNumberOfUsers;
}
// Update the total requested quantity of tokens per price used for determining the settlement price
euint64 updatedTotalQuantity = FHE.add(eTotalRequestedQuantityByPrice[price], eQuantity);
eTotalRequestedQuantityByPrice[price] = updatedTotalQuantity;
address complianceAddress = auctionConfig.complianceAddress;
FHE.allowThis(updatedTotalQuantity);
_authorizerHelper(eQuantity, bidderAddress, complianceAddress);
_authorizerHelper(ePaid, bidderAddress, complianceAddress);
++numberOfBidsPerPriceLevel[price];
emit BidSubmitted(bidId, bidderAddress, eQuantity, price, ePaid);
}
/// @inheritdoc IAuctionToken
/// @dev We are limiting the price range to avoid overflow issue on encrypted state
/// @dev In case the encrypted quantity exceed the available supply, we consider the bid quantity
/// to be the maximum supply.
function submitEncryptedBid(
uint64 price,
externalEuint64 encryptedQuantity,
bytes calldata inputProof
) external whenNotStopped activeAuction {
require(
IKycAllowlistRegistry(auctionConfig.kycAllowlistRegistryAddress).isAllowed(msg.sender),
UserNotAllowed(msg.sender)
);
require(_userActiveBidsCount[msg.sender] < MAX_ACTIVE_BIDS_PER_USER, MaxActiveBidsReached(msg.sender));
// Format the price
price = (price / FLOOR_PRICE_VALUE) * FLOOR_PRICE_VALUE;
require(price != 0 && price <= MAX_PRICE_VALUE, InvalidBidPrice(price));
// Get the remaining quantity available for the user
euint64 eRemainingBidQuantity = eRemainingUserBidQuota[msg.sender];
eRemainingBidQuantity = FHE.isInitialized(eRemainingBidQuantity)
? eRemainingBidQuantity
: FHE.asEuint64(auctionConfig.maxCumulativeBidQuantity);
// Verify input quantity and ensure it does not exceed the remaining quantity
euint64 eQuantity = FHE.fromExternal(encryptedQuantity, inputProof);
eQuantity = FHE.min(eQuantity, eRemainingBidQuantity);
euint64 ePaid = FHE.mul(eQuantity, price);
// Transfer confidential payment from user to their assigned holding wallet
address holdingWallet = WALLET_FACTORY.getHoldingWalletForUser(msg.sender);
FHE.allowTransient(ePaid, auctionConfig.paymentTokenAddress);
euint64 eTotalPaid = IERC7984(auctionConfig.paymentTokenAddress).confidentialTransferFrom(
msg.sender,
holdingWallet,
ePaid
);
FHE.allowThis(eTotalPaid); // Allow auction to use this handle
FHE.allow(eTotalPaid, auctionConfig.complianceAddress); // Compliance authorization
ebool eIsPaymentConfirmed = FHE.eq(eTotalPaid, ePaid);
// Track the total amount sent to the contract for this user
_eTotalPaidByUser[msg.sender] = FHE.add(_eTotalPaidByUser[msg.sender], eTotalPaid);
FHE.allowThis(_eTotalPaidByUser[msg.sender]);
// Set the user as a regular user
if (!_isRegularUser[msg.sender]) _isRegularUser[msg.sender] = true;
// If payment not confirmed, set quantity and paid to 0
eQuantity = FHE.select(eIsPaymentConfirmed, eQuantity, FHE.asEuint64(0));
ePaid = FHE.select(eIsPaymentConfirmed, ePaid, FHE.asEuint64(0));
// Update the remaining quantity for the user
eRemainingUserBidQuota[msg.sender] = FHE.sub(eRemainingBidQuantity, eQuantity);
_authorizerHelper(eRemainingUserBidQuota[msg.sender], msg.sender, auctionConfig.complianceAddress);
_submitBid(msg.sender, price, eQuantity, ePaid, false);
++_userActiveBidsCount[msg.sender];
}
/// @notice Private function to cancel a bid
/// @param bid The bid to cancel
/// @dev The authorization to cancel a bid should be check before calling this function
function _cancelBid(Bid storage bid) private {
require(!bid.canceled, BidCanceledError(bid.bidId));
bid.canceled = true;
bid.canceledAt = uint64(block.timestamp);
// Reset the auction state (requested tokens quantity)
euint64 updatedTotalQuantity = FHE.sub(eTotalRequestedQuantityByPrice[bid.price], bid.eQuantity);
eTotalRequestedQuantityByPrice[bid.price] = updatedTotalQuantity;
FHE.allowThis(updatedTotalQuantity);
--numberOfBidsPerPriceLevel[bid.price];
emit BidCanceled(bid.bidId, bid.bidder, bid.ePaid);
}
/// @notice Private function to cancel a regular bid
/// @param bid The bid to cancel
function _cancelRegularBid(Bid storage bid) private {
require(!bid.externalBid, NotRegularBid(bid.bidId));
address bidder = bid.bidder;
// Update the total amount paid by the user
_eTotalPaidByUser[bidder] = FHE.sub(_eTotalPaidByUser[bidder], bid.ePaid);
FHE.allowThis(_eTotalPaidByUser[bidder]);
// Increase the refund available for the user
eRefundAvailable[bidder] = FHE.add(eRefundAvailable[bidder], bid.ePaid);
_authorizerHelper(eRefundAvailable[bidder], bidder, auctionConfig.complianceAddress);
// Update the remaining quantity for the user
eRemainingUserBidQuota[bidder] = FHE.add(eRemainingUserBidQuota[bidder], bid.eQuantity);
_authorizerHelper(eRemainingUserBidQuota[bidder], bidder, auctionConfig.complianceAddress);
// Cancel the bid and refund the user
_cancelBid(bid);
--_userActiveBidsCount[bidder];
}
/// @inheritdoc IAuctionToken
function cancelBid(uint256 bidId) external whenNotStopped activeAuction {
require(
IKycAllowlistRegistry(auctionConfig.kycAllowlistRegistryAddress).isAllowed(msg.sender),
UserNotAllowed(msg.sender)
);
require(bidId != 0 && bidId <= auctionState.lastBidId, InvalidBidId(bidId));
Bid storage bid = _bids[bidId];
require(bid.bidder == msg.sender, NotBidOwner(bidId, msg.sender));
_cancelRegularBid(bid);
}
/// @inheritdoc IAuctionToken
function finalizeRefund(address receiver) external whenNotPaused {
require(FHE.isInitialized(eRefundAvailable[receiver]), RefundNotAvailable(receiver));
// Reset the refund available before doing the confidential transfer
euint64 eAmountToRefund = eRefundAvailable[receiver];
eRefundAvailable[receiver] = euint64.wrap(0);
eAmountToRefund = _confidentialTransfer(receiver, eAmountToRefund);
emit TokenRefunded(receiver, eAmountToRefund);
}
//////////////////////////////////////////////////////////////////
/// Off-chain bids
//////////////////////////////////////////////////////////////////
/// @inheritdoc IAuctionToken
function batchSubmitExternalBids(
address escrowAddress,
uint64[] calldata quantities,
uint64[] calldata prices
) external whenNotStopped afterAuction onlyRole(DEFAULT_ADMIN_ROLE) {
require(!auctionState.settlementOpen && !auctionState.claimingOpen, BiddingPhaseClosed());
// Will be an issue at claiming because escrow should not received any refund
require(escrowAddress != address(0), ZeroAddress("escrowAddress"));
require(!_isRegularUser[escrowAddress], InvalidEscrowAddress(escrowAddress));
uint256 _len = quantities.length;
require(_len != 0 && _len <= MAX_NUMBER_OF_BIDS, InvalidBatchSize());
require(_len == prices.length, ArrayLengthsMismatch(_len, prices.length));
uint64 price;
uint64 quantity;
for (uint256 i = 0; i < _len; ++i) {
// Format the price
price = (prices[i] / FLOOR_PRICE_VALUE) * FLOOR_PRICE_VALUE;
require(price != 0 && price <= MAX_PRICE_VALUE, InvalidBidPrice(price));
// Format the quantity
quantity = quantities[i];
require(quantity != 0 && quantity <= auctionConfig.zamaTokenSupply, InvalidBidQuantity(quantity));
// Add a non-collateralized bids
_submitBid(escrowAddress, price, FHE.asEuint64(quantity), FHE.asEuint64(0), true);
}
}
/// @inheritdoc IAuctionToken
function cancelExternalBids(
uint256[] calldata bidIds
) external whenNotStopped afterAuction onlyRole(DEFAULT_ADMIN_ROLE) {
require(!auctionState.settlementOpen && !auctionState.claimingOpen, BiddingPhaseClosed());
uint256 _len = bidIds.length;
require(_len != 0 && _len <= MAX_NUMBER_OF_BIDS, InvalidBatchSize());
uint256 bidId;
for (uint256 i = 0; i < _len; ++i) {
bidId = bidIds[i];
require(bidId != 0 && bidId <= auctionState.lastBidId, InvalidBidId(bidId));
Bid storage bid = _bids[bidId];
require(bid.externalBid, NotExternalBid(bidId));
_cancelBid(bid);
}
}
//////////////////////////////////////////////////////////////////
/// Settlement process
//////////////////////////////////////////////////////////////////
/// @inheritdoc IAuctionToken
function cancelRegularBid(uint256 bidId) external whenNotStopped onlyRole(DEFAULT_ADMIN_ROLE) {
require(auctionState.settlementOpen, SettlementNotOpened());
require(settlementData.previousDecryptionIteration == MAX_PRICE_VALUE, SettlementHasStarted());
require(bidId != 0 && bidId <= auctionState.lastBidId, InvalidBidId(bidId));
Bid storage bid = _bids[bidId];
_cancelRegularBid(bid);
}
/// @inheritdoc IAuctionToken
function verifyZamaTokenReceived() external whenNotStopped {
require(!auctionState.zamaTokenReceived, ZamaTokenAlreadyConfirmed());
require(
IERC20(auctionConfig.zamaTokenAddress).balanceOf(address(this)) >=
uint256(auctionConfig.zamaTokenSupply) * ZAMA_TOKEN_FACTOR,
ZamaTokenNotReceived()
);
auctionState.zamaTokenReceived = true;
emit ZamaTokenReceived();
}
/// @inheritdoc IAuctionToken
/// @dev Only the admin should start the settlement process, making sure he has verified all bids beforehand
function decryptAllRequestedTokenPerPriceLevel(
uint256 iterationsToProcess
) external whenNotStopped onlyRole(DEFAULT_ADMIN_ROLE) {
require(auctionState.settlementOpen, SettlementNotOpened());
uint64 previousDecryptionIteration = settlementData.previousDecryptionIteration;
require(previousDecryptionIteration != 0, AllPricesProcessed());
euint64 eTotalRequestedQuantity;
uint64 prefixSumNumberBids = numberOfBidsPerPriceLevel[previousDecryptionIteration + FLOOR_PRICE_VALUE];
while (iterationsToProcess > 0 && previousDecryptionIteration > 0) {
// Reveal the requested quantity of token at that price level only if we have bids submitted
eTotalRequestedQuantity = eTotalRequestedQuantityByPrice[previousDecryptionIteration];
if (FHE.isInitialized(eTotalRequestedQuantity)) {
FHE.makePubliclyDecryptable(eTotalRequestedQuantity);
emit PriceLevelDecryptionRequested(previousDecryptionIteration, eTotalRequestedQuantity);
}
// Compute the prefix sum for the number of bids per price level
prefixSumNumberBids += numberOfBidsPerPriceLevel[previousDecryptionIteration];
numberOfBidsPerPriceLevel[previousDecryptionIteration] = prefixSumNumberBids;
unchecked {
previousDecryptionIteration -= FLOOR_PRICE_VALUE;
--iterationsToProcess;
}
}
settlementData.previousDecryptionIteration = previousDecryptionIteration;
}
/// @inheritdoc IAuctionToken
/// @dev It is not possible to have a valid signature for an uninitialized handle
function revealPriceLevelQuantityCallback(
uint64 priceLevel,
bytes memory abiEncodedClearValues,
bytes memory decryptionProof
) external whenNotStopped {
require(auctionState.settlementOpen, SettlementNotOpened());
/// Verify the proof
bytes32[] memory cts = new bytes32[](1);
cts[0] = FHE.toBytes32(eTotalRequestedQuantityByPrice[priceLevel]);
FHE.checkSignatures(cts, abiEncodedClearValues, decryptionProof);
// Decode requested quantity per price level
_totalRequestedQuantityByPrice[priceLevel] = abi.decode(abiEncodedClearValues, (uint64));
_isRequestedQuantityDecrypted[priceLevel] = true;
emit PriceLevelRevealed(priceLevel, _totalRequestedQuantityByPrice[priceLevel]);
}
/// @inheritdoc IAuctionToken
/// @dev This function should only be called when we have revealed the requested quantity of token for the auction.
/// Callable by anyone once requested quantity is revealed.
function processSettlement(uint256 iterationsToProcess) external whenNotStopped {
require(auctionState.settlementOpen, SettlementNotOpened());
require(settlementData.previousSettlementIteration != 0, AllPricesProcessed());
require(auctionState.settlementPrice == 0, SettlementPriceAlreadyComputed());
uint64 requestedQuantity;
uint64 previousSettlementIteration = settlementData.previousSettlementIteration;
while (iterationsToProcess > 0 && previousSettlementIteration > 0) {
// Proceed only levels where we have bids submitted
if (FHE.isInitialized(eTotalRequestedQuantityByPrice[previousSettlementIteration])) {
// Make sure the requested quantity is decrypted
require(_isRequestedQuantityDecrypted[previousSettlementIteration], PendingGatewayDecryption());
requestedQuantity = _totalRequestedQuantityByPrice[previousSettlementIteration];
if (requestedQuantity != 0) {
// Update the remaining supply until we reached zero
if (settlementData.remainingSupply > requestedQuantity) {
settlementData.remainingSupply -= requestedQuantity;
settlementData.pendingSettlementPrice = previousSettlementIteration;
} else {
auctionState.settlementPrice = previousSettlementIteration;
auctionState.unallocatedZamaSupply = 0;
settlementData.remainingBidsToBeAllocated = numberOfBidsPerPriceLevel[
previousSettlementIteration
];
emit AuctionSettled(previousSettlementIteration, allocatedZamaSupply());
return;
}
}
}
unchecked {
previousSettlementIteration -= FLOOR_PRICE_VALUE;
--iterationsToProcess;
}
}
// We did not have enough demand, set the settlement price to the minimum price
if (previousSettlementIteration == 0) {
auctionState.settlementPrice = settlementData.pendingSettlementPrice; // Set to the last know bid price
auctionState.unallocatedZamaSupply = settlementData.remainingSupply;
settlementData.remainingBidsToBeAllocated = numberOfBidsPerPriceLevel[
settlementData.pendingSettlementPrice
];
emit AuctionSettled(auctionState.settlementPrice, allocatedZamaSupply());
}
settlementData.previousSettlementIteration = previousSettlementIteration;
}
/// @notice Compute a bid allocation
/// @param price Price of bid
/// @param eQuantity Encrypted quantity of bid
/// @return eZamaAllocation The allocated quantity of ZAMA token for the bid.
/// @dev We determine the allocation based on the bid price relative to the settlement price:
/// - If the bid price is below the settlement price, the bidder receives no allocation.
/// - If the bid price is above the settlement price, the bidder receives full allocation.
/// - If the bid price equals the settlement price, then the user received a pro-rata distribution
/// based on their requested quantity.
function _computeBidAllocation(uint64 price, euint64 eQuantity) private returns (euint64) {
uint64 settlementPrice = auctionState.settlementPrice;
// Get no allocation
if (price < settlementPrice) return euint64.wrap(0);
// Get a full allocation
if (price > settlementPrice) return eQuantity;
// Now, we have: price == settlementPrice
// We have not fill the auction
if (auctionState.unallocatedZamaSupply > 0) return eQuantity;
// We have fulfill the auction, we need to do a pro-rata distribution
// The pro-rata distribution is based on the user bid quantity and the total requested quantity
// at that price level. We are computing it using
// userAllocation = (userBidQuantity / totalRequestedAtPrice) * remainingSupply
// Note: Here, division can round down the user allocation
// Note: Division here will not overflow because the maximum quantity and remaining supply are
// capped by 1.1b tokens (auction supply). But could be an issue if the auction supply is
// higher than that.
euint64 numerator = FHE.mul(eQuantity, settlementData.remainingSupply);
return FHE.div(numerator, _totalRequestedQuantityByPrice[auctionState.settlementPrice]);
}
/// @notice Compute a bid allocation
/// @param bidId ID of the bid to compute the allocation
function _computeBidAllocation(uint256 bidId) private {
require(bidId != 0 && bidId <= auctionState.lastBidId, InvalidBidId(bidId));
Bid storage _bid = _bids[bidId];
require(!_bid.allocated, AllocationAlreadyProcessed(bidId));
require(!_bid.canceled, BidCanceledError(bidId));
_bid.allocated = true;
// Increase the user allocation only when we have an allocation
euint64 eAllocation = _computeBidAllocation(_bid.price, _bid.eQuantity);
if (FHE.isInitialized(eAllocation)) {
// Check if the bidder is a new winner and track it
if (!FHE.isInitialized(eUserAllocations[_bid.bidder])) {
_winners.push(_bid.bidder);
emit NewBidWinner(_bid.bidder);
}
eUserAllocations[_bid.bidder] = FHE.add(eUserAllocations[_bid.bidder], eAllocation);
FHE.allowThis(eUserAllocations[_bid.bidder]);
// Reduce the number of bids to be allocated
--settlementData.remainingBidsToBeAllocated;
}
emit BidAllocation(bidId, eAllocation);
}
/// @inheritdoc IAuctionToken
function computeBidsAllocation(uint256[] calldata bidIds) external override whenNotStopped {
require(auctionState.settlementOpen, SettlementNotOpened());
require(auctionState.settlementPrice != 0, SettlementPriceNotComputed());
require(settlementData.remainingBidsToBeAllocated > 0, AllAllocationComputed());
for (uint256 i = 0; i < bidIds.length; ++i) {
_computeBidAllocation(bidIds[i]);
}
}
/// @inheritdoc IAuctionToken
function makeUserAllocationDecryptable(uint256 iterationsToProcess) external whenNotStopped {
require(auctionState.settlementOpen, SettlementNotOpened());
require(auctionState.settlementPrice != 0, SettlementPriceNotComputed());
require(settlementData.remainingBidsToBeAllocated == 0, PendingBidAllocations());
uint256 index = settlementData.winnerDecryptionIndex;
uint256 _len = _winners.length;
require(index < _len, AllWinnersAllocationDecrypted());
uint256 allocationCalls = 0;
euint64 eAllocation;
address winner;
while (iterationsToProcess > 0 && index < _len) {
winner = _winners[index];
eAllocation = eUserAllocations[winner];
if (FHE.isInitialized(eAllocation)) {
// Make the allocation decryptable
FHE.makePubliclyDecryptable(eAllocation);
++allocationCalls;
// Track external partners with allocations for claiming phase validation
if (!_isRegularUser[winner]) {
++settlementData.remainingPartnersAllocations;
}
}
unchecked {
++index;
--iterationsToProcess;
}
}
settlementData.winnerDecryptionIndex = index;
settlementData.remainingAllocationsToClaim += allocationCalls;
}
//////////////////////////////////////////////////////////////////
/// Claiming process
//////////////////////////////////////////////////////////////////
/// @notice Private function to claim user allocation
/// @param receiver Address of the receiver token
/// @param abiEncodedClearValues The ABI-encoded list of decrypted values.
/// @param decryptionProof The KMS public decryption proof.
function _claimAllocation(
address receiver,
bytes memory abiEncodedClearValues,
bytes memory decryptionProof
) private {
require(FHE.isInitialized(eUserAllocations[receiver]), NoAllocationForUser(receiver));
require(!hasClaimedAllocation[receiver], AllocationAlreadyClaimed(receiver));
/// Verify the input proof
bytes32[] memory cts = new bytes32[](1);
cts[0] = FHE.toBytes32(eUserAllocations[receiver]);
FHE.checkSignatures(cts, abiEncodedClearValues, decryptionProof);
// Decode the user allocation
uint64 decodedAllocation = abi.decode(abiEncodedClearValues, (uint64));
hasClaimedAllocation[receiver] = true;
--settlementData.remainingAllocationsToClaim;
// Token was sold using confidential payment
if (_isRegularUser[receiver]) {
_tokenSoldPerWallet[WALLET_FACTORY.getHoldingWalletForUser(receiver)] += decodedAllocation;
}
// Transfer the Zama token to the user
_claimedAllocations[receiver] = decodedAllocation;
uint256 userAllocation = uint256(decodedAllocation) * ZAMA_TOKEN_FACTOR;
IERC20(auctionConfig.zamaTokenAddress).transfer(receiver, userAllocation);
emit ZamaTokenDistributed(receiver, userAllocation);
}
/// @inheritdoc IAuctionToken
function claimExternalAllocation(
address receiver,
bytes memory abiEncodedClearValues,
bytes memory decryptionProof
) external whenNotStopped onlyRole(DEFAULT_ADMIN_ROLE) {
require(auctionState.settlementOpen, SettlementNotOpened());
require(settlementData.winnerDecryptionIndex == _winners.length, MissingWinnerDecryption());
require(auctionState.zamaTokenReceived, ZamaTokenNotReceived());
require(!_isRegularUser[receiver], NotExternalPartner(receiver));
--settlementData.remainingPartnersAllocations;
_claimAllocation(receiver, abiEncodedClearValues, decryptionProof);
}
/// @inheritdoc IAuctionToken
function claimAllocation(
address receiver,
bytes memory abiEncodedClearValues,
bytes memory decryptionProof
) external whenNotStopped {
require(auctionState.claimingOpen, ClaimingNotOpened());
require(
IKycAllowlistRegistry(auctionConfig.kycAllowlistRegistryAddress).isAllowed(receiver),
UserNotAllowed(receiver)
);
_claimAllocation(receiver, abiEncodedClearValues, decryptionProof);
}
/// @inheritdoc IAuctionToken
function refundUser(address receiver) external whenNotStopped {
require(auctionState.claimingOpen, ClaimingNotOpened());
require(_isRegularUser[receiver], NotRegularUser(receiver));
require(_userActiveBidsCount[receiver] != 0, NoActiveBids(receiver));
// User with an allocation should first reveal it and claim it before getting a refund
// We need to have `_claimedAllocations[receiver]` initialized
require(
hasClaimedAllocation[receiver] || !FHE.isInitialized(eUserAllocations[receiver]),
ZamaTokenNotClaimed(receiver)
);
require(!hasReceivedRefund[receiver], AlreadyRefunded(receiver));
hasReceivedRefund[receiver] = true;
// Compute the total payment and refund the user the difference
euint64 eTotalRefund = FHE.sub(
_eTotalPaidByUser[receiver],
_claimedAllocations[receiver] * auctionState.settlementPrice
);
eTotalRefund = _confidentialTransfer(receiver, eTotalRefund);
emit TokenRefunded(receiver, eTotalRefund);
}
/// @inheritdoc IAuctionToken
function cancelUserAllocation(address receiver) external whenNotStopped onlyRole(DEFAULT_ADMIN_ROLE) {
require(auctionState.settlementOpen || auctionState.claimingOpen, SettlementNotOpened());
require(settlementData.winnerDecryptionIndex == _winners.length, MissingWinnerDecryption());
require(_isRegularUser[receiver], NotRegularUser(receiver));
require(
!IKycAllowlistRegistry(auctionConfig.kycAllowlistRegistryAddress).isAllowed(receiver),
UserNotAllowed(receiver)
);
require(!hasClaimedAllocation[receiver], AllocationAlreadyClaimed(receiver));
// Nullify the user allocation if any
euint64 eAllocation = eUserAllocations[receiver];
if (FHE.isInitialized(eAllocation)) {
eUserAllocations[receiver] = euint64.wrap(0);
--settlementData.remainingAllocationsToClaim;
hasClaimedAllocation[receiver] = true;
}
require(!hasReceivedRefund[receiver], AlreadyRefunded(receiver));
hasReceivedRefund[receiver] = true;
// Set the refund available for the user
eRefundAvailable[receiver] = FHE.add(eRefundAvailable[receiver], _eTotalPaidByUser[receiver]);
_authorizerHelper(eRefundAvailable[receiver], receiver, auctionConfig.complianceAddress);
emit UserAllocationCanceled(receiver);
}
/// @inheritdoc IAuctionToken
function withdrawZamaTokensToTreasury() external whenNotStopped onlyRole(DEFAULT_ADMIN_ROLE) {
require(auctionState.claimingOpen, ClaimingNotOpened());
require(
settlementData.remainingAllocationsToClaim == 0,
PendingAllocationsWithdrawal(settlementData.remainingAllocationsToClaim)
);
// Withdraw all the remaining Zama tokens to treasury
uint256 unallocatedAmount = IERC20(auctionConfig.zamaTokenAddress).balanceOf(address(this));
IERC20(auctionConfig.zamaTokenAddress).transfer(auctionConfig.zamaTreasuryAddress, unallocatedAmount);
emit ZamaTokensWithdrawnToTreasury(auctionConfig.zamaTreasuryAddress, unallocatedAmount);
}
/// @inheritdoc IAuctionToken
function withdrawConfidentialTokensToTreasuryBatch(
uint256 startIndex,
uint256 endIndex
) external whenNotStopped onlyRole(DEFAULT_ADMIN_ROLE) {
require(auctionState.claimingOpen, ClaimingNotOpened());
uint256 walletCount = WALLET_FACTORY.WALLET_COUNT();
require(startIndex < endIndex, InvalidRange());
require(endIndex <= walletCount, InvalidRange());
// Accumulate confidential transfers across this batch
euint64 eBatchTransferred = FHE.asEuint64(0);
// Process wallets in the specified range
address wallet;
euint64 eAmount;
address treasury = auctionConfig.zamaTreasuryAddress;
uint64 amount;
for (uint256 i = startIndex; i < endIndex; ++i) {
wallet = WALLET_FACTORY.getHoldingWalletByIndex(i);
// Get the number of tokens sold from this wallet
amount = _tokenSoldPerWallet[wallet] * auctionState.settlementPrice;
delete _tokenSoldPerWallet[wallet];
if (amount != 0) {
eAmount = FHE.asEuint64(amount);
FHE.allowTransient(eAmount, auctionConfig.paymentTokenAddress);
eAmount = IERC7984(auctionConfig.paymentTokenAddress).confidentialTransferFrom(
wallet,
treasury,
eAmount
);
eBatchTransferred = FHE.add(eBatchTransferred, eAmount);
}
}
// Authorize compliance to decrypt the batch total
FHE.allowThis(eBatchTransferred);
FHE.allow(eBatchTransferred, auctionConfig.complianceAddress);
emit ConfidentialTokensBatchWithdrawnToTreasury(
auctionConfig.zamaTreasuryAddress,
startIndex,
endIndex,
eBatchTransferred
);
}
//////////////////////////////////////////////////////////////////
/// Phase Opening
//////////////////////////////////////////////////////////////////
/// @inheritdoc IAuctionToken
function openSettlementPhase() external whenNotStopped afterAuction onlyRole(DEFAULT_ADMIN_ROLE) {
require(!auctionState.settlementOpen, SettlementAlreadyOpened());
require(!auctionState.claimingOpen, ClaimingAlreadyOpened());
auctionState.settlementOpen = true;
emit SettlementOpened();
}
/// @inheritdoc IAuctionToken
/// @dev Claiming can be opened only when we have computed the settlement price, the user allocation
/// and render all allocation publicly decryptable. All external allocations need to be claimed before
/// opening the claiming phase.
function openClaimingPhase() external whenNotStopped afterAuction onlyRole(DEFAULT_ADMIN_ROLE) {
require(auctionState.settlementOpen, SettlementNotOpened());
require(!auctionState.claimingOpen, ClaimingAlreadyOpened());
require(auctionState.settlementPrice != 0, SettlementPriceNotComputed());
require(auctionState.zamaTokenReceived, ZamaTokenNotReceived());
require(settlementData.winnerDecryptionIndex == _winners.length, MissingWinnerDecryption());
require(
settlementData.remainingPartnersAllocations == 0,
ExternalAllocationsNotClaimed(settlementData.remainingPartnersAllocations)
);
auctionState.settlementOpen = false;
auctionState.claimingOpen = true;
emit ClaimingOpened();
}
//////////////////////////////////////////////////////////////////
/// Treasury Controls
//////////////////////////////////////////////////////////////////
/// @inheritdoc IAuctionToken
function setZamaTreasuryAddress(address newTreasuryAddress) external onlyRole(DEFAULT_ADMIN_ROLE) {
require(newTreasuryAddress != address(0), ZeroAddress("newTreasuryAddress"));
address previousTreasuryAddress = auctionConfig.zamaTreasuryAddress;
auctionConfig.zamaTreasuryAddress = newTreasuryAddress;
emit TreasuryAddressUpdated(previousTreasuryAddress, newTreasuryAddress);
}
//////////////////////////////////////////////////////////////////
/// Cancel Controls
//////////////////////////////////////////////////////////////////
/// @inheritdoc IAuctionToken
function cancelAuction() external whenPaused onlyRole(DEFAULT_ADMIN_ROLE) {
require(!auctionState.claimingOpen, ClaimingAlreadyOpened());
require(!auctionState.auctionCanceled, AuctionAlreadyCancelled());
auctionState.auctionCanceled = true;
emit AuctionCanceled();
}
/// @inheritdoc IAuctionToken
function recoverZamaTokensOnCancel() external onlyRole(DEFAULT_ADMIN_ROLE) {
require(auctionState.auctionCanceled, AuctionNotCanceled());
IERC20 zamaToken = IERC20(auctionConfig.zamaTokenAddress);
uint256 bal = zamaToken.balanceOf(address(this));
zamaToken.transfer(auctionConfig.zamaTreasuryAddress, bal);
emit ZamaRecoveredOnCancel(auctionConfig.zamaTreasuryAddress, bal);
}
/// @inheritdoc IAuctionToken
function claimCancellationRefund(address receiver) external {
require(auctionState.auctionCanceled, AuctionNotCanceled());
require(_isRegularUser[receiver], NotRegularUser(receiver));
require(!hasReceivedRefund[receiver], AlreadyRefunded(receiver));
// Refund directly the user
hasReceivedRefund[receiver] = true;
euint64 eRefundAmount = _confidentialTransfer(receiver, _eTotalPaidByUser[receiver]);
emit TokenRefunded(receiver, eRefundAmount);
}
//////////////////////////////////////////////////////////////////
/// Pause Controls
//////////////////////////////////////////////////////////////////
/// @inheritdoc IAuctionToken
function pause() external onlyRole(PAUSER_ROLE) {
_pause();
}
/// @inheritdoc IAuctionToken
function unpause() external onlyRole(DEFAULT_ADMIN_ROLE) {
_unpause();
}
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
pragma solidity 0.8.27;
import {externalEuint64, euint64} from "@fhevm/solidity/lib/FHE.sol";
/// @title Confidential Auction Token Contract
/// @author ecosystem-labs
/// @custom:security-contact security@zama.ai
/// @notice A confidential token auction using FHEVM.
interface IAuctionToken {
/// @notice Configuration parameters for the auction
struct AuctionConfig {
/// @notice The timestamp at which the auction starts
uint256 startAuctionTime;
/// @notice The timestamp at which the auction ends
uint256 endAuctionTime;
/// @notice Total supply of the ZAMA token for the auction
uint64 zamaTokenSupply;
/// @notice Maximum cumulative quantity a user can bid across all active bids
uint64 maxCumulativeBidQuantity;
/// @notice Address of the auctioned ZAMA token
/// @dev Zama token should be a clear token (ZAMA)
address zamaTokenAddress;
/// @notice Address of the Zama treasury wallet
address zamaTreasuryAddress;
/// @notice Address authorized to see auction information
address complianceAddress;
/// @notice KYC Allowlist Registry Address
address kycAllowlistRegistryAddress;
/// @notice Address of the confidential token (cUSDC or cUSDT) used for payment
address paymentTokenAddress;
/// @notice Number of wallets to deploy (must be power of 2)
uint256 walletCount;
}
/// @notice Details of a bid placed in the auction
struct Bid {
uint256 bidId;
/// @dev Encrypted quantity of the bid
/// @dev Will be equal to 0 if the quantity is invalid (above available supply) or the user has not enough funds
euint64 eQuantity;
/// @dev Result of the transfer amount of the paymentToken = eQuantity * price.
/// @dev Be equal to 0 if the user has not enough funds
euint64 ePaid;
address bidder;
uint64 price; // Price of the bid
/// @dev Indicate if the bid is assigned to an external partners
bool externalBid;
bool canceled;
/// @dev Indicate we have computed the bid allocation
bool allocated;
uint64 createdAt; // When the bid was submitted
uint64 canceledAt; // When the bid was canceled
}
/// @notice Data related to the auction
struct AuctionState {
/// @notice Settlement price of the auction
/// @dev This value will be set after the auction settlement is finalized.
/// @dev The settlement price will be determined by the last bid price which fills the number
/// of tokens in the auction.
uint64 settlementPrice;
/// @notice Unallocated Zama token defined after the auction
/// @dev This value will be set after the auction settlement is finalized.
uint64 unallocatedZamaSupply;
/// @notice The ID of the most recent bid
/// @dev The first bid should start at 1
/// @dev Can be used to quickly access the total number of bids in the auction
uint64 lastBidId;
/// @notice Indicate the total number of different users in the auction
uint64 totalNumberOfUsers;
/// @notice Indicate the auction contract has received the Zama token
bool zamaTokenReceived;
/// @notice Indicate if the settlement phase is open.
bool settlementOpen;
/// @notice Indicate if the claiming phase is open.
bool claimingOpen;
/// @notice Indicates whether the auction has been canceled
bool auctionCanceled;
}
/// @notice Data related to the settlement computation
struct SettlementData {
/// @notice Indicate the previous price level processed during decryption of the data
uint64 previousDecryptionIteration;
/// @notice Indicate the previous price level processed during settlement computation
uint64 previousSettlementIteration;
/// @notice Track the remaining supply to be allocated
uint64 remainingSupply;
/// @notice Pending settlement price during computation
uint64 pendingSettlementPrice;
/// @notice Track the number of bids that we need to call for the allocation
uint64 remainingBidsToBeAllocated;
/// @notice Index of the winner being processed for public decryption
uint256 winnerDecryptionIndex;
/// @notice Track the number of calls needed for the allocation
uint256 remainingAllocationsToClaim;
/// @notice Track the number of external partners who have allocations and needs to be claimed
uint256 remainingPartnersAllocations;
}
//////////////////////////////////////////////////////////////////
/// View Functions
//////////////////////////////////////////////////////////////////
/// @notice Returns the wallet factory contract address
/// @return The wallet factory contract address
function getWalletFactory() external view returns (address);
/// @notice Returns the total number of bids received in the auction
/// @return totalNumberOfBids Total number of bids
function totalNumberOfBids() external view returns (uint64);
/// @notice Get the total number of bids submitted by the input user
/// @param user The address of the user
/// @return The total number of bids submitted by the user
function numberOfBids(address user) external view returns (uint256);
/// @notice Get the number of active (non-canceled) bids for a user
/// @param user The address of the user
/// @return The number of active bids for the user
function numberOfActiveBids(address user) external view returns (uint256);
/// @notice Get the total number of winners in the auction
/// @return The total number of winners
function numberOfWinners() external view returns (uint256);
/// @notice Get bid information using its ID
/// @param bidId The ID of the bid
/// @return The bid detail
function getBid(uint256 bidId) external view returns (Bid memory);
/// @notice A mapping of user address to a list of bids
/// @param userAddress The address of the user
/// @return bidIds The list of bid IDs associated with the user
function getUserBids(address userAddress) external view returns (uint256[] memory bidIds);
/// @notice Retrieves a paginated list of bids detail submitted by a specific user.
/// @param user The address of the user who has submitted bids.
/// @param start The starting index in the user's bid list (0-based).
/// @param limit The maximum number of bids to return in this call.
/// @return bids An array of `Bid` structs corresponding to the user's bids in the specified range.
function getUserBidsDetail(address user, uint256 start, uint256 limit) external view returns (Bid[] memory bids);
/// @notice Indicate if the claiming phase is open to users
/// @return True when bidders can claim their allocations
function isClaimingOpen() external view returns (bool);
/// @notice Indicate if the settlement phase is open (admin has enabled settlement)
/// @return True when settlement computation is open
function isSettlementOpen() external view returns (bool);
/// @notice Get the total number of iteration needed to settle the auction
/// @return The total number of iterations needed for settlement
function getTotalSettlementIterations() external view returns (uint64);
/// @notice Get total requested quantity for a specific price level
/// @param priceLevel Price level to fetch the total requested quantity
/// @return totalRequestedQuantity The total quantity requested at the given price level.
/// @dev This value will be available after the settlement, once we received the gateway callback.
function getTotalRequestedQuantityByPrice(uint64 priceLevel) external view returns (uint64);
/// @notice Get the total quantity of ZAMA tokens that have been allocated.
/// @return The allocated ZAMA token supply
/// @dev This value will be available after the auction settlement is finalized. Before, it will revert.
function allocatedZamaSupply() external view returns (uint64);
/// @notice Returns the total allocation already claimed by the given user in the auction.
/// @param account The address of the participant.
/// @return claimedAllocation The quantity of tokens claimed by the user (whole units).
function claimedAllocationOf(address account) external view returns (uint64 claimedAllocation);
//////////////////////////////////////////////////////////////////
/// Events
//////////////////////////////////////////////////////////////////
/// @notice Emitted when a new bid is submitted
/// @param bidId The ID of the bid
/// @param bidder The address of the bidder
/// @param eQuantity The encrypted quantity of the bid
/// @param price The price of the bid
/// @param ePaid The encrypted amount paid for the bid
event BidSubmitted(uint256 indexed bidId, address indexed bidder, euint64 eQuantity, uint64 price, euint64 ePaid);
/// @notice Emitted when a bid is canceled
/// @param bidId The ID of the bid
/// @param bidder The address of the bidder
/// @param eRefund Encrypted amount refunded in the bid's payment token
event BidCanceled(uint256 indexed bidId, address indexed bidder, euint64 eRefund);
/// @notice Emitted when we have computed the allocation for a given bid
/// @param bidId The ID of the bid
/// @param eAllocation The encrypted allocation computed for the bid
event BidAllocation(uint256 indexed bidId, euint64 eAllocation);
/// @notice Emitted when the total quantity requested for a price level is publicly decryptable
/// @param priceLevel The price level being processed.
/// @param eTotalRequestedQuantity The encrypted total quantity requested at this price level.
event PriceLevelDecryptionRequested(uint64 indexed priceLevel, euint64 eTotalRequestedQuantity);
/// @notice Emitted during the settlement when we reveal the total requested quantity of token per price level.
/// @param priceLevel The price level that was revealed.
/// @param totalRequestedQuantity The total quantity requested at this price level.
event PriceLevelRevealed(uint64 indexed priceLevel, uint64 totalRequestedQuantity);
/// @notice Emitted when a new bid winner is identified during settlement
/// @param bidder The address of the winning bidder
event NewBidWinner(address indexed bidder);
/// @notice Emitted when the auction has determined the settlement price
/// @param settlementPrice The determined settlement price
/// @param allocatedSupply The determined allocation of Zama token
event AuctionSettled(uint64 settlementPrice, uint64 allocatedSupply);
/// @notice Emitted when the settlement phase is opened
event SettlementOpened();
/// @notice Emitted when the contract confirmed it received the ZAMA tokens for distribution
event ZamaTokenReceived();
/// @notice Emitted when the tokens are refunded to the user
/// @param user The address of the user receiving the tokens
/// @param eTotalRefundAmount Confidential amount of to be refunded to the user
event TokenRefunded(address indexed user, euint64 eTotalRefundAmount);
/// @notice Emitted when the Zama tokens are distributed to a user
/// @param user The address of the user receiving the Zama tokens
/// @param allocation The quantity of Zama tokens distributed
event ZamaTokenDistributed(address indexed user, uint256 allocation);
/// @notice Emitted when a user's allocation is canceled
/// @param receiver The address of the user whose allocation is canceled
event UserAllocationCanceled(address indexed receiver);
/// @notice Emitted when remaining Zama tokens are withdrawn to treasury
/// @param treasuryAddress Zama treasury address
/// @param amount Amount of Zama tokens transferred (in smallest unit)
event ZamaTokensWithdrawnToTreasury(address indexed treasuryAddress, uint256 amount);
/// @notice Emitted when a batch of confidential tokens is withdrawn from wallets to treasury
/// @param treasuryAddress Zama treasury address
/// @param startIndex First wallet index in this batch
/// @param endIndex Last wallet index processed (exclusive)
/// @param eBatchTransferred Encrypted amount of confidential tokens transferred in this batch
event ConfidentialTokensBatchWithdrawnToTreasury(
address indexed treasuryAddress,
uint256 startIndex,
uint256 endIndex,
euint64 eBatchTransferred
);
/// @notice Emitted when the treasury address is updated
/// @param previousTreasuryAddress Treasury address previously configured
/// @param newTreasuryAddress Newly configured treasury address
event TreasuryAddressUpdated(address indexed previousTreasuryAddress, address indexed newTreasuryAddress);
/// @notice Emitted when the claiming phase is opened
event ClaimingOpened();
/// @notice Emitted when the auction is canceled
event AuctionCanceled();
/// @notice Emitted when ZAMA tokens are recovered to the treasury after cancellation
/// @param treasuryAddress The address of the treasury wallet
/// @param amount Amount of ZAMA tokens transferred to the treasury (in smallest unit)
event ZamaRecoveredOnCancel(address indexed treasuryAddress, uint256 amount);
//////////////////////////////////////////////////////////////////
/// Errors
//////////////////////////////////////////////////////////////////
error InvalidTokenSupply(uint256 supply);
error InvalidMaxCumulativeBidQuantity(uint64 maxCumulativeBidQuantity);
error InvalidAuctionTimes(uint256 start, uint256 end);
error InvalidMaximumPrice(uint64);
error AuctionNotStarted();
error AuctionEnded();
error AuctionNotEnded();
error ZeroAddress(string paramName);
error DuplicatedAddress(address duplicatedAddress);
/// @notice Operation blocked because the auction has been canceled
error AuctionCanceledError();
/// @notice Operation requires the auction to be canceled
error AuctionNotCanceled();
/// @notice At least one non-admin pauser address must be provided
error NoPausersProvided();
/// @notice User not allowed to bid due to missing or invalid KYC
error UserNotAllowed(address userAddress);
/// @notice The bid price is invalid (e.g., out of the acceptable range)
error InvalidBidPrice(uint64 price);
/// @notice The bid quantity is invalid (e.g., exceeds available supply)
error InvalidBidQuantity(uint64 quantity);
/// @notice The bid ID does not correspond to any existing bid
error InvalidBidId(uint256 bidId);
/// @notice The user attempted an operation on a bid they do not own
error NotBidOwner(uint256 bidId, address user);
/// @dev Use when a bid is already canceled or when trying to claim a canceled bid.
error BidCanceledError(uint256 bidId);
/// @notice Reverts when a user tries to exceed the maximum number of active bids
error MaxActiveBidsReached(address user);
/// @notice The batch size of submitted bids is invalid (e.g., zero or exceeds maximum)
error InvalidBatchSize();
/// @dev Raised when the lengths of two input arrays do not match
error ArrayLengthsMismatch(uint256 len1, uint256 len2);
/// @dev Raised when the total requested quantity for a price level has not been decrypted yet
error QuantityNotDecrypted(uint256 priceLevel);
/// @dev Raised when the settlement price has already been computed
error SettlementPriceAlreadyComputed();
/// @dev Raised when the settlement price has not been computed
error SettlementPriceNotComputed();
/// @dev Thrown when an action requires the bidding phase to be open, but it is already closed.
error BiddingPhaseClosed();
/// @notice We have iterated over all the prices for the settlement
error AllPricesProcessed();
/// @notice Settlement phase is not yet open
error SettlementNotOpened();
/// @notice Settlement phase has already been opened
error SettlementAlreadyOpened();
/// @dev Thrown when trying to perform an operation while settlement computations have already started
error SettlementHasStarted();
/// @notice The contract has not yet received the ZAMA tokens for distribution
error ZamaTokenNotReceived();
/// @notice The contract has already confirmed receiving the ZAMA tokens
error ZamaTokenAlreadyConfirmed();
/// @notice Claiming phase is not yet open
error ClaimingNotOpened();
/// @notice Claiming phase already opened
error ClaimingAlreadyOpened();
/// @notice Reverts when trying to open claiming phase but not all external allocations are claimed
error ExternalAllocationsNotClaimed(uint256 total);
/// @dev Use when we are waiting for a gateway decryption
error PendingGatewayDecryption();
error AuctionAlreadyCancelled();
/// @dev Thrown all the bid allocation has been computed
error AllAllocationComputed();
/// @dev Thrown when there are pending bid allocations to be computed
error PendingBidAllocations();
/// @dev Thrown when all winners had their allocation decrypted
error AllWinnersAllocationDecrypted();
/// @dev Thrown when we do not have render all the allocation publicly decrypted
error MissingWinnerDecryption();
error InvalidEscrowAddress(address escrowAddress);
error NotExternalPartner(address receiver);
error NotExternalBid(uint256 bidId);
error NoRefundOnExternalBid(uint256 bidId);
error AllocationAlreadyProcessed(uint256 bidId);
error AllocationAlreadyClaimed(address receiver);
error NotRegularUser(address receiver);
error NoAllocationForUser(address user);
error ZamaTokenNotClaimed(address receiver);
error AlreadyRefunded(address receiver);
error PendingAllocationsWithdrawal(uint256 remainingAllocations);
error PendingRefundsWithdrawal(uint256 remainingRefunds);
/// @notice Invalid wallet index range for treasury withdrawal
error InvalidRange();
/// @dev Thrown when trying to delete a bid that is not a regular bid
error NotRegularBid(uint256 bidId);
/// @dev Thrown when a user has no active bids
error NoActiveBids(address receiver);
/// @dev Thrown when there is no refund available for the user
error RefundNotAvailable(address receiver);
//////////////////////////////////////////////////////////////////
/// Functions
//////////////////////////////////////////////////////////////////
/// @notice Submit an encrypted bid for the auction
/// @param price The price of the bid
/// @param encryptedQuantity Encrypted quantity of the bid to submit
/// @param inputProof The associated proof for the encrypted input values
/// @dev When submitting a bid, the user must have previously approved the auction contract as an operator
/// on the confidential payment token contract.
/// @dev The price input parameter of the bid is range limited between ]0; MAX_PRICE_VALUE]
/// @dev The price will be rounded down to the nearest multiple of FLOOR_PRICE_VALUE
/// @dev If the price is above MAX_PRICE_VALUE or equal to 0, the transaction will revert.
/// @dev For the bid payment, we expect the user to have enough funds on the confidential
/// payment token. Notice that confidential transfer will not revert if the user
/// does not have enough funds, but the transferred amount will be 0.
/// @dev In case the payment does not match the expected amount, the bids will be considered as invalid.
/// @dev Here a single bid will be submitted.
function submitEncryptedBid(uint64 price, externalEuint64 encryptedQuantity, bytes calldata inputProof) external;
/// @notice Cancel a submitted bid
/// @param bidId Bid ID to be canceled
/// @dev Only the creator of the bid can cancel it.
/// @dev Can only be called when the auction is active.
/// @dev Refunds the bidder's funds and resets the auction state.
function cancelBid(uint256 bidId) external;
/// @notice Submit a batch of bids from external parties participating in an off-chain auction.
/// @param escrowAddress Address holding the escrow for the external bids.
/// @param quantities Array of quantities corresponding to the bids.
/// @param prices Array of prices corresponding to the bids.
/// @dev Can only be called by the admin address after the on-chain bidding phase is finished.
/// @dev This function can be called multiple times until all external bids are submitted and the
/// off-chain bidding phase is opened.
/// @dev Same limitations as regular bids apply on the quantity and price. Meaning that in a scenario
/// of a demand above the total supply for a given price, the caller must split it into multiple bids
/// accordingly.
/// @dev The inputs are in plaintext and will not be an issue as it will be aggregated bids from external partners.
/// @dev WARNING: There is no limit on the number of submitted bids, which can potentially lead to an overflow in
/// the cumulative encrypted quantity. Admin needs to make sure to not submit too many bids with the maximum
/// quantity (more than ~16 billion transactions at the maximum quantity)
function batchSubmitExternalBids(
address escrowAddress,
uint64[] calldata quantities,
uint64[] calldata prices
) external;
/// @notice Cancel a batch of external submitted bids
/// @param bidIds List of Bid IDs to be canceled
/// @dev Can only be called by the admin address after the on-chain bidding phase is finished.
/// @dev Can only cancel bids from external parties.
/// @dev We can safely assume that the admin will bid only non-collateral bids.
function cancelExternalBids(uint256[] calldata bidIds) external;
/// @notice Cancel a bid from a regular user.
/// @param bidId Bid ID to be canceled
/// @dev Can only be called by the admin address during the settlement phase before the settlement computation
/// starts to remove invalid bids (e.g., bids owned by invalid users as not KYCed, bid with a requested
/// supply too high leading to a control of the whole supply of the auction).
function cancelRegularBid(uint256 bidId) external;
/// @notice Confirm that the contract has received the ZAMA tokens for distribution
/// @dev This function can be called by anyone once the contract has received the ZAMA tokens.
function verifyZamaTokenReceived() external;
/// @notice Decrypt the total requested quantity of token per price level
/// @param iterationsToProcess The number of iterations to process
/// @dev Should be available only after the auction ended.
function decryptAllRequestedTokenPerPriceLevel(uint256 iterationsToProcess) external;
/// @notice Callback to reveal the requested quantity for a given price level
/// @param priceLevel The price level to reveal
/// @param abiEncodedClearValues The ABI-encoded list of decrypted values.
/// @param decryptionProof The KMS public decryption proof.
function revealPriceLevelQuantityCallback(
uint64 priceLevel,
bytes memory abiEncodedClearValues,
bytes memory decryptionProof
) external;
/// @notice Process the computation of the settlement price
/// @param iterationsToProcess The number of iterations to process
/// @dev Should be available only after the auction ended.
/// @dev Should be invoked repeatedly until all prices have been processed. The maximum number of iterations
/// will be defined by the maximum price and the floor price of the auction. This process can be done
/// earlier if the settlement price has been determined.
function processSettlement(uint256 iterationsToProcess) external;
/// @notice Compute the allocation of the bids.
/// @param bidIds ID of the bids to be allocated
/// @dev Needs to be called only on the winning bids
function computeBidsAllocation(uint256[] calldata bidIds) external;
/// @notice Make user allocation decryptable
/// @param iterationsToProcess The number of user allocations to process
/// @dev After the user allocation computed, we need to make them decryptable so users can claim their tokens.
/// By making them decryptable, we allow the gateway to pre-compute all encrypted user allocation, allowing
/// a fair claiming process for the users.
function makeUserAllocationDecryptable(uint256 iterationsToProcess) external;
/// @notice Claim external partner's allocation after the settlement is done
/// @param receiver The address receiving the allocation
/// @param abiEncodedClearValues The ABI-encoded clear allocation values
/// @param decryptionProof The proof associated with the decryption of the allocation
/// @dev Can only be called by the admin address and should be available during the settlement phase,
/// when the auction has been settled.
function claimExternalAllocation(
address receiver,
bytes memory abiEncodedClearValues,
bytes memory decryptionProof
) external;
/// @notice Claim user allocation of Zama tokens.
/// @param receiver Address of the receiver token
/// @param abiEncodedClearValues The ABI-encoded list of decrypted values.
/// @param decryptionProof The KMS public decryption proof.
/// @dev Should revert if not called during the claiming phase or if the user has already claimed.
/// @dev We expect the receiver to be a regular user (not an external partner). The KYC of the user should still
/// be valid to claim his tokens.
/// @dev We can safely assume that in the claiming phase, the ZAMA tokens have been received by the contract.
/// @dev Anyone can force the claim on behalf of the user.
function claimAllocation(
address receiver,
bytes memory abiEncodedClearValues,
bytes memory decryptionProof
) external;
/// @notice Refund the user for his bids after the auction.
/// @param receiver The address of the user receiving the refund
/// @dev Can only be called in the claiming phase.
/// @dev Users need to claimed their allocation before being able to get their refund.
/// @dev We can safely assume that a user who has claimed his allocation, has a valid KYC valid.
/// @dev Anyone can force the refund on behalf of the user.
function refundUser(address receiver) external;
/// @notice Finalize the refund process by transferring the confidential tokens to the user
/// @param receiver Address of the receiver token
/// @dev Can only be called when funds are available for a refund to the user.
/// @dev We split this process in case a user has been sanctioned and blocked in the confidential wrapper.
function finalizeRefund(address receiver) external;
/// @notice Cancel a user's allocation after the auction settlement
/// In case the user is not allowed to receive tokens (e.g., invalid KYC) we need to have
/// a way to cancel his allocation and refund him as we would not be able to distribute tokens to him.
/// By having this function, we make sure that Zama will not be blocked from distributing tokens to
/// the treasury as we expect all the distributions to be done before being able to withdraw the funds.
/// @param receiver Address of the receiver token
/// @dev Can only be called by the admin address after the auction settlement is done.
/// @dev In case the user had already claimed his allocation, we assume that his KYC was valid and thus
/// we cannot cancel his allocation anymore. We should instead call the refund function for this user.
function cancelUserAllocation(address receiver) external;
/// @notice Cancel the auction. After cancellation, no settlement or allocations can occur.
/// @dev Reverts if the claiming phase has already been opened.
function cancelAuction() external;
/// @notice Recover any ZAMA tokens held by this contract to the treasury after cancellation
function recoverZamaTokensOnCancel() external;
/// @notice Claim refunds for the given bids after the auction was canceled
/// @param receiver The address receiving the refund
/// @dev Callable only once the auction is canceled.
function claimCancellationRefund(address receiver) external;
/// @notice Withdraw remaining Zama tokens to the treasury
/// @dev Can only be called after the auction ended, once all allocations and refunds are processed
/// @dev Requires the claiming phase to be opened
function withdrawZamaTokensToTreasury() external;
/// @notice Withdraw confidential tokens from wallets to treasury for a given range
/// @dev Processes wallets from startIndex to endIndex (exclusive)
/// @dev Can be called multiple times with different ranges to cover all wallets
/// @dev Requires the claiming phase to be opened and all refunds processed
/// @param startIndex The starting wallet index (inclusive)
/// @param endIndex The ending wallet index (exclusive)
function withdrawConfidentialTokensToTreasuryBatch(uint256 startIndex, uint256 endIndex) external;
/// @notice Opens the settlement phase so computations can start (admin only)
/// @dev Can only be called by the admin address after the on-chain bidding phase is finished.
function openSettlementPhase() external;
/// @notice Open the claiming phase for bidders
function openClaimingPhase() external;
/// @notice Pause the auction to disable state-changing operations during emergencies
function pause() external;
/// @notice Resume the auction after it has been paused
function unpause() external;
/// @notice Update the treasury address receiving auction funds
/// @param newTreasuryAddress Address of the new treasury wallet
function setZamaTreasuryAddress(address newTreasuryAddress) external;
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
pragma solidity 0.8.27;
/// @title IAuctionWallet Interface
/// @author ecosystem-labs
/// @custom:security-contact security@zama.ai
/// @notice Interface for minimal auction wallet clones that hold user funds
/// @dev These wallets are deployed as ERC-1167 minimal proxies with immutable args
interface IAuctionWallet {
/// @notice Emitted when the auction is approved as operator
/// @param auction The auction address that was approved
event AuctionApproved(address indexed auction);
/// @notice Error thrown when the caller is not the auction
error OnlyAuction();
/// @notice Error thrown when the caller is not the factory
error OnlyFactory();
/// @notice Initializes the wallet: sets up FHE coprocessor and approves auction as operator
/// @dev Can only be called by the factory.
function initialize() external;
/// @notice Returns the factory contract address
/// @return The factory contract address
function getFactory() external view returns (address);
/// @notice Returns the payment token address
/// @return The ERC7984 payment token address
function getPaymentToken() external view returns (address);
/// @notice Returns the auction address
/// @return The auction contract address
function getAuction() external view returns (address);
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
pragma solidity 0.8.27;
/// @title KYC Allowlist Registry Interface
/// @author ecosystem-labs
/// @notice A KYC allowlist registry interface.
/// @custom:security-contact security@zama.ai
interface IKycAllowlistRegistry {
//////////////////////////////////////////////////////////////////
/// View Functions
//////////////////////////////////////////////////////////////////
/// @notice Indicate if a user address is KYCed and not blocked
/// @param userAddress The wallet address to check.
/// @return True if the address is KYCed and not blocked
function isAllowed(address userAddress) external view returns (bool);
/// @notice Indicate if a user address is blocked
/// @param userAddress The wallet address to check.
/// @return True if the address is blocked
function isBlocked(address userAddress) external view returns (bool);
/// @notice Indicate if a user address has verified his KYC on-chain or verified by an admin
/// @param userAddress The wallet address to check.
/// @return True if the address is already verified
function isVerified(address userAddress) external view returns (bool);
//////////////////////////////////////////////////////////////////
/// Events
//////////////////////////////////////////////////////////////////
/// @notice Emitted when a new user is verified via signature or by admin
/// @param userAddress The address of the user that has been verified.
/// @param timestamp The block timestamp when the address was marked as verified.
event AddressVerified(address indexed userAddress, uint256 indexed timestamp);
/// @notice Emitted when an admin blocks a user address.
/// @param userAddress The address of the user that has been blocked.
/// @param timestamp The block timestamp when the address was marked as blocked.
event AddressBlocked(address indexed userAddress, uint256 indexed timestamp);
/// @notice Emitted when an admin unblocks an address.
/// @param userAddress The address of the user that has been unblocked.
/// @param timestamp The block timestamp when the address was removed from the blocked list.
event AddressUnblocked(address indexed userAddress, uint256 indexed timestamp);
/// @notice Emitted when the approver address is updated.
/// @param previousApprover The previous approver address.
/// @param newApprover The new approver address.
event ApproverAddressUpdated(address indexed previousApprover, address indexed newApprover);
//////////////////////////////////////////////////////////////////
/// Errors
//////////////////////////////////////////////////////////////////
/// @dev Thrown if the address is not valid (eg. `address(0)`)
error InvalidApproverAddress(address approver);
/// @dev Thrown when the address has already been verified.
error AlreadyVerified(address user);
/// @dev Thrown if signature verification fails
error InvalidSignature();
/// @dev Thrown if signature is expired
error ExpiredSignature(uint256 timestamp);
/// @dev Thrown if the provided timestamp from the proof is in the future
error InvalidTimestamp(uint256 timestamp);
//////////////////////////////////////////////////////////////////
/// Functions
//////////////////////////////////////////////////////////////////
/// @notice Verify and register a new address
/// @param timestamp used at the creation of the signature
/// @param signature signature created by a controlled address
function verify(uint256 timestamp, bytes calldata signature) external;
/// @notice Admin function to add multiple addresses to the verified list
/// @param userAddresses The list of user addresses to be marked as verified
function addVerifiedAddresses(address[] calldata userAddresses) external;
/// @notice Admin function to block multiple addresses
/// @param userAddresses The list of user addresses to be marked as blocked
function blockAddresses(address[] calldata userAddresses) external;
/// @notice Admin function to unblock multiple addresses
/// @param userAddresses The list of user addresses to remove from the blocked list
function unblockAddresses(address[] calldata userAddresses) external;
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
pragma solidity 0.8.27;
/// @title IWalletFactory Interface
/// @author ecosystem-labs
/// @custom:security-contact security@zama.ai
/// @notice Interface for the factory that deploys and manages auction wallet clones
/// @dev Uses ERC-1167 minimal proxies with immutable arguments for gas-efficient deployment
interface IWalletFactory {
/// @notice Emitted when a new wallet clone is deployed
/// @param index The index of the deployed wallet
/// @param wallet The address of the deployed wallet
event WalletDeployed(uint256 indexed index, address indexed wallet);
/// @notice Emitted when wallets are deployed in a batch
/// @param count The number of wallets deployed
event WalletsBatchDeployed(uint256 count);
/// @notice Error thrown when wallet count is not a power of 2
error WalletCountNotPowerOfTwo();
/// @notice Error thrown when wallet count is zero
error WalletCountZero();
/// @notice Error thrown when wallet index is out of bounds
error WalletIndexOutOfBounds();
/// @notice Error thrown to avoid max gas limit error
error WalletCountExceedsMax();
/// @notice Error thrown when an address parameter is zero
/// @param name The name of the parameter that was zero
error ZeroAddress(string name);
/// @notice Returns the wallet address at the given index
/// @param index The index of the wallet
/// @return The wallet address
function getHoldingWalletByIndex(uint256 index) external view returns (address);
/// @notice Returns the holding wallet address for a given user
/// @param user The user address
/// @return The holding wallet address assigned to this user
function getHoldingWalletForUser(address user) external view returns (address);
/* solhint-disable func-name-mixedcase */
/// @notice Returns the total number of wallets to be deployed
/// @return The wallet count
function WALLET_COUNT() external view returns (uint256);
/* solhint-enable func-name-mixedcase */
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
pragma solidity 0.8.27;
import {IERC7984} from "@openzeppelin/confidential-contracts/contracts/interfaces/IERC7984.sol";
import {FHE} from "@fhevm/solidity/lib/FHE.sol";
import {ZamaEthereumConfig, ZamaConfig} from "@fhevm/solidity/config/ZamaConfig.sol";
import {IAuctionWallet} from "../interfaces/IAuctionWallet.sol";
/// @title AuctionWallet
/// @author ecosystem-labs
/// @custom:security-contact security@zama.ai
/// @notice Minimal wallet implementation for holding auction funds
/// @dev Deployed as ERC-1167 minimal proxy with immutable args.
contract AuctionWallet is IAuctionWallet, ZamaEthereumConfig {
/// @notice The factory contract address
address private immutable FACTORY;
/// @notice The ERC7984 payment token address
address private immutable PAYMENT_TOKEN;
/// @notice The auction contract address
address private immutable AUCTION;
/// @inheritdoc IAuctionWallet
function getFactory() external view returns (address) {
return FACTORY;
}
/// @inheritdoc IAuctionWallet
function getPaymentToken() external view returns (address) {
return PAYMENT_TOKEN;
}
/// @inheritdoc IAuctionWallet
function getAuction() external view returns (address) {
return AUCTION;
}
/// @notice Auction Wallet Constructor.
/// @param factory_ Address of the wallet factory that can initialize this wallet
/// @param paymentToken_ ERC7984 confidential payment token address
/// @param auction_ Address of the auction contract
/// @dev These parameters are stored as immutable in the implementation allowing to be
/// defined once for all the new deployed clones.
constructor(address factory_, address paymentToken_, address auction_) {
FACTORY = factory_;
PAYMENT_TOKEN = paymentToken_;
AUCTION = auction_;
}
/// @notice Initializes the wallet: sets up FHE coprocessor and approves auction as operator
/// @dev This function needs to be called by the factory during deployment of the total architecture
/// of the auction. It is called in the constructor of the WalletFactory which itself is called
/// in the constructor of the AuctionToken.
/// @dev We also need to initialize the FHE coprocessor here since storage is not shared between
/// minimal proxy clones.
function initialize() external {
// Verify caller is the factory
require(msg.sender == FACTORY, OnlyFactory());
// Initialize FHE coprocessor
FHE.setCoprocessor(ZamaConfig.getEthereumCoprocessorConfig());
// Approve auction as operator with max expiry
IERC7984(PAYMENT_TOKEN).setOperator(AUCTION, type(uint48).max);
emit AuctionApproved(AUCTION);
}
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
pragma solidity 0.8.27;
import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol";
import {IWalletFactory} from "../interfaces/IWalletFactory.sol";
import {IAuctionWallet} from "../interfaces/IAuctionWallet.sol";
import {AuctionWallet} from "./AuctionWallet.sol";
/// @title WalletFactory
/// @author ecosystem-labs
/// @custom:security-contact security@zama.ai
/// @notice Deploys a fixed pool of holding wallets that users are deterministically mapped to
/// @dev Uses ERC-1167 minimal proxies with immutable arguments for gas-efficient deployment.
contract WalletFactory is IWalletFactory {
/// @notice Maximum number of wallets that can be deployed
uint256 public constant MAX_WALLET_COUNT = 32;
/// @notice The AuctionWallet implementation contract
address public immutable IMPLEMENTATION;
/// @notice The ERC7984 payment token address
address public immutable PAYMENT_TOKEN;
/// @notice The total number of wallets to be deployed
/// @dev Must be a power of 2
uint256 public immutable WALLET_COUNT;
/// @notice Bitmask for user-to-wallet mapping
uint256 internal immutable WALLET_COUNT_MASK;
/// @notice The auction contract address (deployer)
address public immutable AUCTION;
/// @notice Array of deployed wallet addresses
address[] private _wallets;
/// @notice Creates a new WalletFactory and deploys wallet clones
/// @param walletCount_ The number of wallets to deploy (must be power of 2)
/// @param paymentToken_ The ERC7984 payment token address
constructor(uint256 walletCount_, address paymentToken_) {
require(walletCount_ != 0, WalletCountZero());
require(walletCount_ & (walletCount_ - 1) == 0, WalletCountNotPowerOfTwo());
require(walletCount_ <= MAX_WALLET_COUNT, WalletCountExceedsMax());
require(paymentToken_ != address(0), ZeroAddress("paymentToken_"));
WALLET_COUNT = walletCount_;
WALLET_COUNT_MASK = walletCount_ - 1;
PAYMENT_TOKEN = paymentToken_;
AUCTION = msg.sender;
// Deploy the implementation contract
IMPLEMENTATION = address(new AuctionWallet(address(this), paymentToken_, msg.sender));
// Initialize the wallets array
_wallets = new address[](walletCount_);
// Deploy all wallet clones
_deployWalletsBatch(walletCount_);
}
/// @inheritdoc IWalletFactory
function getHoldingWalletByIndex(uint256 index) external view returns (address) {
require(index < _wallets.length, WalletIndexOutOfBounds());
return _wallets[index];
}
/// @inheritdoc IWalletFactory
function getHoldingWalletForUser(address user) external view returns (address) {
// Use bitwise AND with WALLET_COUNT_MASK to extract lower bits.
// WALLET_COUNT is a power of 2, so (WALLET_COUNT - 1)
// forms a bitmask (e.g., 8 - 1 = 0b111).
uint256 index = uint256(uint160(user)) & WALLET_COUNT_MASK;
return _wallets[index];
}
/// @notice Internal function to deploy all wallet clones
/// @param count The number of wallets to deploy
function _deployWalletsBatch(uint256 count) private {
address wallet;
for (uint256 i = 0; i < count; ++i) {
wallet = Clones.clone(IMPLEMENTATION);
_wallets[i] = wallet;
// Initialize wallet (FHE coprocessor + auction approval)
IAuctionWallet(wallet).initialize();
emit WalletDeployed(i, wallet);
}
emit WalletsBatchDeployed(count);
}
} <i class='far fa-question-circle text-muted ms-2' data-bs-trigger='hover' data-bs-toggle='tooltip' data-bs-html='true' data-bs-title='Click on the check box to select individual contract to compare. Only 1 contract can be selected from each side.'></i>
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
type ebool is bytes32;
type euint8 is bytes32;
type euint16 is bytes32;
type euint24 is bytes32;
type euint32 is bytes32;
type euint40 is bytes32;
type euint48 is bytes32;
type euint56 is bytes32;
type euint64 is bytes32;
type euint72 is bytes32;
type euint80 is bytes32;
type euint88 is bytes32;
type euint96 is bytes32;
type euint104 is bytes32;
type euint112 is bytes32;
type euint120 is bytes32;
type euint128 is bytes32;
type euint136 is bytes32;
type euint144 is bytes32;
type euint152 is bytes32;
type euint160 is bytes32;
type euint168 is bytes32;
type euint176 is bytes32;
type euint184 is bytes32;
type euint192 is bytes32;
type euint200 is bytes32;
type euint208 is bytes32;
type euint216 is bytes32;
type euint224 is bytes32;
type euint232 is bytes32;
type euint240 is bytes32;
type euint248 is bytes32;
type euint256 is bytes32;
type eint8 is bytes32;
type eint16 is bytes32;
type eint24 is bytes32;
type eint32 is bytes32;
type eint40 is bytes32;
type eint48 is bytes32;
type eint56 is bytes32;
type eint64 is bytes32;
type eint72 is bytes32;
type eint80 is bytes32;
type eint88 is bytes32;
type eint96 is bytes32;
type eint104 is bytes32;
type eint112 is bytes32;
type eint120 is bytes32;
type eint128 is bytes32;
type eint136 is bytes32;
type eint144 is bytes32;
type eint152 is bytes32;
type eint160 is bytes32;
type eint168 is bytes32;
type eint176 is bytes32;
type eint184 is bytes32;
type eint192 is bytes32;
type eint200 is bytes32;
type eint208 is bytes32;
type eint216 is bytes32;
type eint224 is bytes32;
type eint232 is bytes32;
type eint240 is bytes32;
type eint248 is bytes32;
type eint256 is bytes32;
type eaddress is bytes32;
type ebytes1 is bytes32;
type ebytes2 is bytes32;
type ebytes3 is bytes32;
type ebytes4 is bytes32;
type ebytes5 is bytes32;
type ebytes6 is bytes32;
type ebytes7 is bytes32;
type ebytes8 is bytes32;
type ebytes9 is bytes32;
type ebytes10 is bytes32;
type ebytes11 is bytes32;
type ebytes12 is bytes32;
type ebytes13 is bytes32;
type ebytes14 is bytes32;
type ebytes15 is bytes32;
type ebytes16 is bytes32;
type ebytes17 is bytes32;
type ebytes18 is bytes32;
type ebytes19 is bytes32;
type ebytes20 is bytes32;
type ebytes21 is bytes32;
type ebytes22 is bytes32;
type ebytes23 is bytes32;
type ebytes24 is bytes32;
type ebytes25 is bytes32;
type ebytes26 is bytes32;
type ebytes27 is bytes32;
type ebytes28 is bytes32;
type ebytes29 is bytes32;
type ebytes30 is bytes32;
type ebytes31 is bytes32;
type ebytes32 is bytes32;
type externalEbool is bytes32;
type externalEuint8 is bytes32;
type externalEuint16 is bytes32;
type externalEuint24 is bytes32;
type externalEuint32 is bytes32;
type externalEuint40 is bytes32;
type externalEuint48 is bytes32;
type externalEuint56 is bytes32;
type externalEuint64 is bytes32;
type externalEuint72 is bytes32;
type externalEuint80 is bytes32;
type externalEuint88 is bytes32;
type externalEuint96 is bytes32;
type externalEuint104 is bytes32;
type externalEuint112 is bytes32;
type externalEuint120 is bytes32;
type externalEuint128 is bytes32;
type externalEuint136 is bytes32;
type externalEuint144 is bytes32;
type externalEuint152 is bytes32;
type externalEuint160 is bytes32;
type externalEuint168 is bytes32;
type externalEuint176 is bytes32;
type externalEuint184 is bytes32;
type externalEuint192 is bytes32;
type externalEuint200 is bytes32;
type externalEuint208 is bytes32;
type externalEuint216 is bytes32;
type externalEuint224 is bytes32;
type externalEuint232 is bytes32;
type externalEuint240 is bytes32;
type externalEuint248 is bytes32;
type externalEuint256 is bytes32;
type externalEint8 is bytes32;
type externalEint16 is bytes32;
type externalEint24 is bytes32;
type externalEint32 is bytes32;
type externalEint40 is bytes32;
type externalEint48 is bytes32;
type externalEint56 is bytes32;
type externalEint64 is bytes32;
type externalEint72 is bytes32;
type externalEint80 is bytes32;
type externalEint88 is bytes32;
type externalEint96 is bytes32;
type externalEint104 is bytes32;
type externalEint112 is bytes32;
type externalEint120 is bytes32;
type externalEint128 is bytes32;
type externalEint136 is bytes32;
type externalEint144 is bytes32;
type externalEint152 is bytes32;
type externalEint160 is bytes32;
type externalEint168 is bytes32;
type externalEint176 is bytes32;
type externalEint184 is bytes32;
type externalEint192 is bytes32;
type externalEint200 is bytes32;
type externalEint208 is bytes32;
type externalEint216 is bytes32;
type externalEint224 is bytes32;
type externalEint232 is bytes32;
type externalEint240 is bytes32;
type externalEint248 is bytes32;
type externalEint256 is bytes32;
type externalEaddress is bytes32;
type externalEbytes1 is bytes32;
type externalEbytes2 is bytes32;
type externalEbytes3 is bytes32;
type externalEbytes4 is bytes32;
type externalEbytes5 is bytes32;
type externalEbytes6 is bytes32;
type externalEbytes7 is bytes32;
type externalEbytes8 is bytes32;
type externalEbytes9 is bytes32;
type externalEbytes10 is bytes32;
type externalEbytes11 is bytes32;
type externalEbytes12 is bytes32;
type externalEbytes13 is bytes32;
type externalEbytes14 is bytes32;
type externalEbytes15 is bytes32;
type externalEbytes16 is bytes32;
type externalEbytes17 is bytes32;
type externalEbytes18 is bytes32;
type externalEbytes19 is bytes32;
type externalEbytes20 is bytes32;
type externalEbytes21 is bytes32;
type externalEbytes22 is bytes32;
type externalEbytes23 is bytes32;
type externalEbytes24 is bytes32;
type externalEbytes25 is bytes32;
type externalEbytes26 is bytes32;
type externalEbytes27 is bytes32;
type externalEbytes28 is bytes32;
type externalEbytes29 is bytes32;
type externalEbytes30 is bytes32;
type externalEbytes31 is bytes32;
type externalEbytes32 is bytes32;