// SPDX-License-Identifier: MITpragmasolidity ^0.8.13;import"@openzeppelin/contracts/access/Ownable.sol";
import"@openzeppelin/contracts/utils/math/SafeMath.sol";
import"@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import"@openzeppelin/contracts/utils/Strings.sol";
/*
░█████╗░██╗░░░░░██████╗░██╗░░██╗░█████╗░ ░██████╗██╗░░██╗░█████╗░██████╗░██╗░░██╗░██████╗
██╔══██╗██║░░░░░██╔══██╗██║░░██║██╔══██╗ ██╔════╝██║░░██║██╔══██╗██╔══██╗██║░██╔╝██╔════╝
███████║██║░░░░░██████╔╝███████║███████║ ╚█████╗░███████║███████║██████╔╝█████═╝░╚█████╗░
██╔══██║██║░░░░░██╔═══╝░██╔══██║██╔══██║ ░╚═══██╗██╔══██║██╔══██║██╔══██╗██╔═██╗░░╚═══██╗
██║░░██║███████╗██║░░░░░██║░░██║██║░░██║ ██████╔╝██║░░██║██║░░██║██║░░██║██║░╚██╗██████╔╝
╚═╝░░╚═╝╚══════╝╚═╝░░░░░╚═╝░░╚═╝╚═╝░░╚═╝ ╚═════╝░╚═╝░░╚═╝╚═╝░░╚═╝╚═╝░░╚═╝╚═╝░░╚═╝╚═════╝░
*/interfaceIAlphaSharksNFT{
functionsafeMint(address, uint256) external;
}
contractAlphaSharksTicketsisOwnable{
usingSafeMathforuint256;
usingStringsforuint256;
usingECDSAforbytes32;
IAlphaSharksNFT public alphaSharksNFT;
/** Phase 1 - Whitelist */boolpublic phaseOneActive =false;
/** Phase 2 - Whitelist */boolpublic phaseTwoActive =false;
/** Phase 3 - Public Sale */boolpublic phaseThreeActive =false;
uint256public maxSupply =5969;
uint256public whitelistSupply =5500;
uint256public maxTicketsPerUserPhaseTwo =1;
uint256public maxTicketsPerUserPhaseThree =2;
/*MINT PRICE FOR WHITELIST*/uint256public whitelistTicketPrice =0.2ether;
/*MINT PRICE FOR PUBLIC*/uint256public publicTicketPrice =0.3ether;
uint256public ticketSales =0;
mapping(address=>uint256) public addressToTickets;
mapping(address=>uint256) public addressToMaxMintWhitelist;
mapping(address=>bool) public addressToIsAllowedPhase3;
mapping(address=>uint256) public addressToPhaseTwoTickets;
mapping(address=>uint256) public addressToPhaseThreeTickets;
/**
Security
*/mapping(address=>uint256) public addressToTicketMints;
constructor() {}
functionsetAlphaSharksNFT(IAlphaSharksNFT _alphaSharksNFT)
externalonlyOwner{
alphaSharksNFT = _alphaSharksNFT;
}
functionuploadWhitelistPhase1Phase2(address[] calldata addresses,
uint256[] calldata counts
) publiconlyOwner{
require(
addresses.length== counts.length,
"NUMBER OF ADDRESSES AND COUNTS ARE NOT EQUAL"
);
for (uint256 i =0; i < addresses.length; i++) {
addressToMaxMintWhitelist[addresses[i]] = counts[i];
}
}
functionuploadWhitelistPhase3(address[] calldata addresses,
bool[] calldata bools
) publiconlyOwner{
require(
addresses.length== bools.length,
"NUMBER OF ADDRESSES AND BOOLS ARE NOT EQUAL"
);
for (uint256 i =0; i < addresses.length; i++) {
addressToIsAllowedPhase3[addresses[i]] = bools[i];
}
}
functionmakePhaseOneActive(bool _val) externalonlyOwner{
phaseOneActive = _val;
phaseTwoActive =false;
phaseThreeActive =false;
}
functionmakePhaseTwoActive(bool _val) externalonlyOwner{
phaseTwoActive = _val;
phaseOneActive =false;
phaseThreeActive =false;
}
functionmakePhaseThreeActive(bool _val) externalonlyOwner{
phaseThreeActive = _val;
phaseOneActive =false;
phaseTwoActive =false;
}
functionupdateMaxTicketsPerUserPhaseTwo(uint256 _val) externalonlyOwner{
maxTicketsPerUserPhaseTwo = _val;
}
functionupdateMaxTicketsPerUserPhaseThree(uint256 _val)
externalonlyOwner{
maxTicketsPerUserPhaseThree = _val;
}
functionphaseOneBuyTickets(uint256 _amount) externalpayable{
/* STEP 1: Check if phase is active */require(phaseOneActive, "PHASE ONE NOT ACTIVE");
/* STEP 2: Check the tickets amount */require(_amount >0, "HAVE TO BUY AT LEAST 1");
require(
ticketSales.add(_amount) <= whitelistSupply,
"MAX TICKETS SOLD"
);
/* STEP 3: Check if user is allowed to buy mint tickets */require(
addressToTickets[msg.sender].add(_amount) <=
addressToMaxMintWhitelist[msg.sender],
"NOT ALLOWED TO MINT THIS AMOUNT"
);
/* STEP 4: Check if user has sent correct amount of ether to buy tickets */require(
msg.value== whitelistTicketPrice.mul(_amount),
"INCORRECT AMOUNT PAID"
);
/* STEP 5: Buy the mint tickets */
addressToTickets[msg.sender] = addressToTickets[msg.sender].add(
_amount
);
ticketSales = ticketSales.add(_amount);
mintAlphaSharks();
}
functionphaseTwoBuyTickets(uint256 _amount) externalpayable{
/* STEP 1: Check if phase is active */require(phaseTwoActive, "PHASE TWO NOT ACTIVE");
/* STEP 2: Check the tickets amount */require(_amount >0, "HAVE TO BUY AT LEAST 1");
require(
ticketSales.add(_amount) <= whitelistSupply,
"MAX TICKETS SOLD"
);
/* STEP 3: Check if user is allowed to buy mint tickets */require(
addressToMaxMintWhitelist[msg.sender] >0,
"NOT ALLOWED TO MINT THIS AMOUNT"
);
require(
addressToPhaseTwoTickets[msg.sender].add(_amount) <=
maxTicketsPerUserPhaseTwo,
"NOT ALLOWED TO MINT THIS AMOUNT"
);
/* STEP 4: Check if user has sent correct amount of ether to buy tickets */require(
msg.value== whitelistTicketPrice.mul(_amount),
"INCORRECT AMOUNT PAID"
);
/* STEP 5: Buy the mint tickets */
addressToPhaseTwoTickets[msg.sender] = addressToPhaseTwoTickets[
msg.sender
].add(_amount);
addressToTickets[msg.sender] = addressToTickets[msg.sender].add(
_amount
);
ticketSales = ticketSales.add(_amount);
mintAlphaSharks();
}
functionphaseThreeBuyTickets(uint256 _amount) externalpayable{
/* STEP 1: Check if phase is active */require(phaseThreeActive, "PHASE THREE NOT ACTIVE");
/* STEP 2: Check the tickets amount */require(_amount >0, "HAVE TO BUY AT LEAST 1");
require(ticketSales.add(_amount) <= maxSupply, "MAX TICKETS SOLD");
/* STEP 3: Check if user is allowed to buy mint tickets */require(
addressToIsAllowedPhase3[msg.sender] ==true,
"NOT ALLOWED TO MINT"
);
require(
addressToPhaseThreeTickets[msg.sender].add(_amount) <=
maxTicketsPerUserPhaseThree,
"NOT ALLOWED TO MINT THIS AMOUNT"
);
/* STEP 4: Check if user has sent correct amount of ether to buy tickets */require(
msg.value== publicTicketPrice.mul(_amount),
"INCORRECT AMOUNT PAID"
);
/* STEP 5: Buy the mint tickets */
addressToPhaseThreeTickets[msg.sender] = addressToPhaseThreeTickets[
msg.sender
].add(_amount);
addressToTickets[msg.sender] = addressToTickets[msg.sender].add(
_amount
);
ticketSales = ticketSales.add(_amount);
mintAlphaSharks();
}
functionmintAlphaSharks() public{
uint256 ticketsOfSender = addressToTickets[msg.sender];
uint256 mintsOfSender = addressToTicketMints[msg.sender];
uint256 mintable = ticketsOfSender.sub(mintsOfSender);
require(mintable >0, "NO MINTABLE TICKETS");
addressToTicketMints[msg.sender] = addressToTicketMints[msg.sender].add(
mintable
);
alphaSharksNFT.safeMint(msg.sender, mintable);
}
functionwithdraw() externalonlyOwner{
payable(msg.sender).transfer(address(this).balance);
}
}
Contract Source Code
File 2 of 6: Context.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)pragmasolidity ^0.8.0;/**
* @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.
*/abstractcontractContext{
function_msgSender() internalviewvirtualreturns (address) {
returnmsg.sender;
}
function_msgData() internalviewvirtualreturns (bytescalldata) {
returnmsg.data;
}
}
Contract Source Code
File 3 of 6: ECDSA.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.5.0) (utils/cryptography/ECDSA.sol)pragmasolidity ^0.8.0;import"../Strings.sol";
/**
* @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
*
* These functions can be used to verify that a message was signed by the holder
* of the private keys of a given address.
*/libraryECDSA{
enumRecoverError {
NoError,
InvalidSignature,
InvalidSignatureLength,
InvalidSignatureS,
InvalidSignatureV
}
function_throwError(RecoverError error) privatepure{
if (error == RecoverError.NoError) {
return; // no error: do nothing
} elseif (error == RecoverError.InvalidSignature) {
revert("ECDSA: invalid signature");
} elseif (error == RecoverError.InvalidSignatureLength) {
revert("ECDSA: invalid signature length");
} elseif (error == RecoverError.InvalidSignatureS) {
revert("ECDSA: invalid signature 's' value");
} elseif (error == RecoverError.InvalidSignatureV) {
revert("ECDSA: invalid signature 'v' value");
}
}
/**
* @dev Returns the address that signed a hashed message (`hash`) with
* `signature` or error string. This address can then be used for verification purposes.
*
* The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
* this function rejects them by requiring the `s` value to be in the lower
* half order, and the `v` value to be either 27 or 28.
*
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
* verification to be secure: it is possible to craft signatures that
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
* this is by receiving a hash of the original message (which may otherwise
* be too long), and then calling {toEthSignedMessageHash} on it.
*
* Documentation for signature generation:
* - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
* - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
*
* _Available since v4.3._
*/functiontryRecover(bytes32 hash, bytesmemory signature) internalpurereturns (address, RecoverError) {
// Check the signature length// - case 65: r,s,v signature (standard)// - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._if (signature.length==65) {
bytes32 r;
bytes32 s;
uint8 v;
// ecrecover takes the signature parameters, and the only way to get them// currently is to use assembly.assembly {
r :=mload(add(signature, 0x20))
s :=mload(add(signature, 0x40))
v :=byte(0, mload(add(signature, 0x60)))
}
return tryRecover(hash, v, r, s);
} elseif (signature.length==64) {
bytes32 r;
bytes32 vs;
// ecrecover takes the signature parameters, and the only way to get them// currently is to use assembly.assembly {
r :=mload(add(signature, 0x20))
vs :=mload(add(signature, 0x40))
}
return tryRecover(hash, r, vs);
} else {
return (address(0), RecoverError.InvalidSignatureLength);
}
}
/**
* @dev Returns the address that signed a hashed message (`hash`) with
* `signature`. This address can then be used for verification purposes.
*
* The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
* this function rejects them by requiring the `s` value to be in the lower
* half order, and the `v` value to be either 27 or 28.
*
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
* verification to be secure: it is possible to craft signatures that
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
* this is by receiving a hash of the original message (which may otherwise
* be too long), and then calling {toEthSignedMessageHash} on it.
*/functionrecover(bytes32 hash, bytesmemory signature) internalpurereturns (address) {
(address recovered, RecoverError error) = tryRecover(hash, signature);
_throwError(error);
return recovered;
}
/**
* @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
*
* See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
*
* _Available since v4.3._
*/functiontryRecover(bytes32 hash,
bytes32 r,
bytes32 vs
) internalpurereturns (address, RecoverError) {
bytes32 s = vs &bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
uint8 v =uint8((uint256(vs) >>255) +27);
return tryRecover(hash, v, r, s);
}
/**
* @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
*
* _Available since v4.2._
*/functionrecover(bytes32 hash,
bytes32 r,
bytes32 vs
) internalpurereturns (address) {
(address recovered, RecoverError error) = tryRecover(hash, r, vs);
_throwError(error);
return recovered;
}
/**
* @dev Overload of {ECDSA-tryRecover} that receives the `v`,
* `r` and `s` signature fields separately.
*
* _Available since v4.3._
*/functiontryRecover(bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internalpurereturns (address, RecoverError) {
// EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature// unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines// the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most// signatures from current libraries generate a unique signature with an s-value in the lower half order.//// If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value// with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or// vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept// these malleable signatures as well.if (uint256(s) >0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
return (address(0), RecoverError.InvalidSignatureS);
}
if (v !=27&& v !=28) {
return (address(0), RecoverError.InvalidSignatureV);
}
// If the signature is valid (and not malleable), return the signer addressaddress signer =ecrecover(hash, v, r, s);
if (signer ==address(0)) {
return (address(0), RecoverError.InvalidSignature);
}
return (signer, RecoverError.NoError);
}
/**
* @dev Overload of {ECDSA-recover} that receives the `v`,
* `r` and `s` signature fields separately.
*/functionrecover(bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internalpurereturns (address) {
(address recovered, RecoverError error) = tryRecover(hash, v, r, s);
_throwError(error);
return recovered;
}
/**
* @dev Returns an Ethereum Signed Message, created from a `hash`. This
* produces hash corresponding to the one signed with the
* https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
* JSON-RPC method as part of EIP-191.
*
* See {recover}.
*/functiontoEthSignedMessageHash(bytes32 hash) internalpurereturns (bytes32) {
// 32 is the length in bytes of hash,// enforced by the type signature abovereturnkeccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
}
/**
* @dev Returns an Ethereum Signed Message, created from `s`. This
* produces hash corresponding to the one signed with the
* https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
* JSON-RPC method as part of EIP-191.
*
* See {recover}.
*/functiontoEthSignedMessageHash(bytesmemory s) internalpurereturns (bytes32) {
returnkeccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
}
/**
* @dev Returns an Ethereum Signed Typed Data, created from a
* `domainSeparator` and a `structHash`. This produces hash corresponding
* to the one signed with the
* https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
* JSON-RPC method as part of EIP-712.
*
* See {recover}.
*/functiontoTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internalpurereturns (bytes32) {
returnkeccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
}
}
Contract Source Code
File 4 of 6: Ownable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)pragmasolidity ^0.8.0;import"../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/abstractcontractOwnableisContext{
addressprivate _owner;
eventOwnershipTransferred(addressindexed previousOwner, addressindexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Returns the address of the current owner.
*/functionowner() publicviewvirtualreturns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/modifieronlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/functionrenounceOwnership() publicvirtualonlyOwner{
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/functiontransferOwnership(address newOwner) publicvirtualonlyOwner{
require(newOwner !=address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/function_transferOwnership(address newOwner) internalvirtual{
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
Contract Source Code
File 5 of 6: SafeMath.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts v4.4.1 (utils/math/SafeMath.sol)pragmasolidity ^0.8.0;// CAUTION// This version of SafeMath should only be used with Solidity 0.8 or later,// because it relies on the compiler's built in overflow checks./**
* @dev Wrappers over Solidity's arithmetic operations.
*
* NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
* now has built in overflow checking.
*/librarySafeMath{
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/functiontryAdd(uint256 a, uint256 b) internalpurereturns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the substraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/functiontrySub(uint256 a, uint256 b) internalpurereturns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/functiontryMul(uint256 a, uint256 b) internalpurereturns (bool, uint256) {
unchecked {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the// benefit is lost if 'b' is also tested.// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522if (a ==0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/functiontryDiv(uint256 a, uint256 b) internalpurereturns (bool, uint256) {
unchecked {
if (b ==0) return (false, 0);
return (true, a / b);
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/functiontryMod(uint256 a, uint256 b) internalpurereturns (bool, uint256) {
unchecked {
if (b ==0) return (false, 0);
return (true, a % b);
}
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/functionadd(uint256 a, uint256 b) internalpurereturns (uint256) {
return a + b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/functionsub(uint256 a, uint256 b) internalpurereturns (uint256) {
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/functionmul(uint256 a, uint256 b) internalpurereturns (uint256) {
return a * b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator.
*
* Requirements:
*
* - The divisor cannot be zero.
*/functiondiv(uint256 a, uint256 b) internalpurereturns (uint256) {
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/functionmod(uint256 a, uint256 b) internalpurereturns (uint256) {
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/functionsub(uint256 a,
uint256 b,
stringmemory errorMessage
) internalpurereturns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/functiondiv(uint256 a,
uint256 b,
stringmemory errorMessage
) internalpurereturns (uint256) {
unchecked {
require(b >0, errorMessage);
return a / b;
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/functionmod(uint256 a,
uint256 b,
stringmemory errorMessage
) internalpurereturns (uint256) {
unchecked {
require(b >0, errorMessage);
return a % b;
}
}
}
Contract Source Code
File 6 of 6: Strings.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)pragmasolidity ^0.8.0;/**
* @dev String operations.
*/libraryStrings{
bytes16privateconstant _HEX_SYMBOLS ="0123456789abcdef";
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/functiontoString(uint256 value) internalpurereturns (stringmemory) {
// Inspired by OraclizeAPI's implementation - MIT licence// https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.solif (value ==0) {
return"0";
}
uint256 temp = value;
uint256 digits;
while (temp !=0) {
digits++;
temp /=10;
}
bytesmemory buffer =newbytes(digits);
while (value !=0) {
digits -=1;
buffer[digits] =bytes1(uint8(48+uint256(value %10)));
value /=10;
}
returnstring(buffer);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/functiontoHexString(uint256 value) internalpurereturns (stringmemory) {
if (value ==0) {
return"0x00";
}
uint256 temp = value;
uint256 length =0;
while (temp !=0) {
length++;
temp >>=8;
}
return toHexString(value, length);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/functiontoHexString(uint256 value, uint256 length) internalpurereturns (stringmemory) {
bytesmemory buffer =newbytes(2* length +2);
buffer[0] ="0";
buffer[1] ="x";
for (uint256 i =2* length +1; i >1; --i) {
buffer[i] = _HEX_SYMBOLS[value &0xf];
value >>=4;
}
require(value ==0, "Strings: hex length insufficient");
returnstring(buffer);
}
}