¡El código fuente de este contrato está verificado!
Metadatos del Contrato
Compilador
0.8.19+commit.7dd6d404
Idioma
Solidity
Código Fuente del Contrato
Archivo 1 de 13: 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;
}
}
Código Fuente del Contrato
Archivo 2 de 13: ECDSA.sol
// SPDX-License-Identifier: MITpragmasolidity ^0.8.0;import"@openzeppelin/contracts/interfaces/IERC1271.sol";
libraryECDSA{
// 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.uint256privateconstant _S_BOUNDARY =0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0+1;
uint256privateconstant _COMPACT_S_MASK =0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
uint256privateconstant _COMPACT_V_SHIFT =255;
functionrecover(bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internalviewreturns (address signer) {
assembly ("memory-safe") { // solhint-disable-line no-inline-assemblyiflt(s, _S_BOUNDARY) {
let ptr :=mload(0x40)
mstore(ptr, hash)
mstore(add(ptr, 0x20), v)
mstore(add(ptr, 0x40), r)
mstore(add(ptr, 0x60), s)
mstore(0, 0)
pop(staticcall(gas(), 0x1, ptr, 0x80, 0, 0x20))
signer :=mload(0)
}
}
}
functionrecover(bytes32 hash,
bytes32 r,
bytes32 vs
) internalviewreturns (address signer) {
assembly ("memory-safe") { // solhint-disable-line no-inline-assemblylet s :=and(vs, _COMPACT_S_MASK)
iflt(s, _S_BOUNDARY) {
let ptr :=mload(0x40)
mstore(ptr, hash)
mstore(add(ptr, 0x20), add(27, shr(_COMPACT_V_SHIFT, vs)))
mstore(add(ptr, 0x40), r)
mstore(add(ptr, 0x60), s)
mstore(0, 0)
pop(staticcall(gas(), 0x1, ptr, 0x80, 0, 0x20))
signer :=mload(0)
}
}
}
/// @dev WARNING!!!/// There is a known signature malleability issue with two representations of signatures!/// Even though this function is able to verify both standard 65-byte and compact 64-byte EIP-2098 signatures/// one should never use raw signatures for any kind of invalidation logic in their code./// As the standard and compact representations are interchangeable any invalidation logic that relies on/// signature uniqueness will get rekt./// More info: https://github.com/OpenZeppelin/openzeppelin-contracts/security/advisories/GHSA-4h98-2769-gh6hfunctionrecover(bytes32 hash, bytescalldata signature) internalviewreturns (address signer) {
assembly ("memory-safe") { // solhint-disable-line no-inline-assemblylet ptr :=mload(0x40)
// memory[ptr:ptr+0x80] = (hash, v, r, s)switch signature.lengthcase65 {
// memory[ptr+0x20:ptr+0x80] = (v, r, s)mstore(add(ptr, 0x20), byte(0, calldataload(add(signature.offset, 0x40))))
calldatacopy(add(ptr, 0x40), signature.offset, 0x40)
}
case64 {
// memory[ptr+0x20:ptr+0x80] = (v, r, s)let vs :=calldataload(add(signature.offset, 0x20))
mstore(add(ptr, 0x20), add(27, shr(_COMPACT_V_SHIFT, vs)))
calldatacopy(add(ptr, 0x40), signature.offset, 0x20)
mstore(add(ptr, 0x60), and(vs, _COMPACT_S_MASK))
}
default {
ptr :=0
}
if ptr {
iflt(mload(add(ptr, 0x60)), _S_BOUNDARY) {
// memory[ptr:ptr+0x20] = (hash)mstore(ptr, hash)
mstore(0, 0)
pop(staticcall(gas(), 0x1, ptr, 0x80, 0, 0x20))
signer :=mload(0)
}
}
}
}
functionrecoverOrIsValidSignature(address signer,
bytes32 hash,
bytescalldata signature
) internalviewreturns (bool success) {
if (signer ==address(0)) returnfalse;
if ((signature.length==64|| signature.length==65) && recover(hash, signature) == signer) {
returntrue;
}
return isValidSignature(signer, hash, signature);
}
functionrecoverOrIsValidSignature(address signer,
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internalviewreturns (bool success) {
if (signer ==address(0)) returnfalse;
if (recover(hash, v, r, s) == signer) {
returntrue;
}
return isValidSignature(signer, hash, v, r, s);
}
functionrecoverOrIsValidSignature(address signer,
bytes32 hash,
bytes32 r,
bytes32 vs
) internalviewreturns (bool success) {
if (signer ==address(0)) returnfalse;
if (recover(hash, r, vs) == signer) {
returntrue;
}
return isValidSignature(signer, hash, r, vs);
}
functionrecoverOrIsValidSignature65(address signer,
bytes32 hash,
bytes32 r,
bytes32 vs
) internalviewreturns (bool success) {
if (signer ==address(0)) returnfalse;
if (recover(hash, r, vs) == signer) {
returntrue;
}
return isValidSignature65(signer, hash, r, vs);
}
functionisValidSignature(address signer,
bytes32 hash,
bytescalldata signature
) internalviewreturns (bool success) {
// (bool success, bytes memory data) = signer.staticcall(abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature));// return success && data.length >= 4 && abi.decode(data, (bytes4)) == IERC1271.isValidSignature.selector;bytes4 selector = IERC1271.isValidSignature.selector;
assembly ("memory-safe") { // solhint-disable-line no-inline-assemblylet ptr :=mload(0x40)
mstore(ptr, selector)
mstore(add(ptr, 0x04), hash)
mstore(add(ptr, 0x24), 0x40)
mstore(add(ptr, 0x44), signature.length)
calldatacopy(add(ptr, 0x64), signature.offset, signature.length)
ifstaticcall(gas(), signer, ptr, add(0x64, signature.length), 0, 0x20) {
success :=and(eq(selector, mload(0)), eq(returndatasize(), 0x20))
}
}
}
functionisValidSignature(address signer,
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internalviewreturns (bool success) {
bytes4 selector = IERC1271.isValidSignature.selector;
assembly ("memory-safe") { // solhint-disable-line no-inline-assemblylet ptr :=mload(0x40)
mstore(ptr, selector)
mstore(add(ptr, 0x04), hash)
mstore(add(ptr, 0x24), 0x40)
mstore(add(ptr, 0x44), 65)
mstore(add(ptr, 0x64), r)
mstore(add(ptr, 0x84), s)
mstore8(add(ptr, 0xa4), v)
ifstaticcall(gas(), signer, ptr, 0xa5, 0, 0x20) {
success :=and(eq(selector, mload(0)), eq(returndatasize(), 0x20))
}
}
}
functionisValidSignature(address signer,
bytes32 hash,
bytes32 r,
bytes32 vs
) internalviewreturns (bool success) {
// (bool success, bytes memory data) = signer.staticcall(abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, abi.encodePacked(r, vs)));// return success && data.length >= 4 && abi.decode(data, (bytes4)) == IERC1271.isValidSignature.selector;bytes4 selector = IERC1271.isValidSignature.selector;
assembly ("memory-safe") { // solhint-disable-line no-inline-assemblylet ptr :=mload(0x40)
mstore(ptr, selector)
mstore(add(ptr, 0x04), hash)
mstore(add(ptr, 0x24), 0x40)
mstore(add(ptr, 0x44), 64)
mstore(add(ptr, 0x64), r)
mstore(add(ptr, 0x84), vs)
ifstaticcall(gas(), signer, ptr, 0xa4, 0, 0x20) {
success :=and(eq(selector, mload(0)), eq(returndatasize(), 0x20))
}
}
}
functionisValidSignature65(address signer,
bytes32 hash,
bytes32 r,
bytes32 vs
) internalviewreturns (bool success) {
// (bool success, bytes memory data) = signer.staticcall(abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, abi.encodePacked(r, vs & ~uint256(1 << 255), uint8(vs >> 255))));// return success && data.length >= 4 && abi.decode(data, (bytes4)) == IERC1271.isValidSignature.selector;bytes4 selector = IERC1271.isValidSignature.selector;
assembly ("memory-safe") { // solhint-disable-line no-inline-assemblylet ptr :=mload(0x40)
mstore(ptr, selector)
mstore(add(ptr, 0x04), hash)
mstore(add(ptr, 0x24), 0x40)
mstore(add(ptr, 0x44), 65)
mstore(add(ptr, 0x64), r)
mstore(add(ptr, 0x84), and(vs, _COMPACT_S_MASK))
mstore8(add(ptr, 0xa4), add(27, shr(_COMPACT_V_SHIFT, vs)))
ifstaticcall(gas(), signer, ptr, 0xa5, 0, 0x20) {
success :=and(eq(selector, mload(0)), eq(returndatasize(), 0x20))
}
}
}
functiontoEthSignedMessageHash(bytes32 hash) internalpurereturns (bytes32 res) {
// 32 is the length in bytes of hash, enforced by the type signature above// return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));assembly ("memory-safe") { // solhint-disable-line no-inline-assemblymstore(0, 0x19457468657265756d205369676e6564204d6573736167653a0a333200000000) // "\x19Ethereum Signed Message:\n32"mstore(28, hash)
res :=keccak256(0, 60)
}
}
functiontoTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internalpurereturns (bytes32 res) {
// return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));assembly ("memory-safe") { // solhint-disable-line no-inline-assemblylet ptr :=mload(0x40)
mstore(ptr, 0x1901000000000000000000000000000000000000000000000000000000000000) // "\x19\x01"mstore(add(ptr, 0x02), domainSeparator)
mstore(add(ptr, 0x22), structHash)
res :=keccak256(ptr, 66)
}
}
}
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)pragmasolidity ^0.8.0;/**
* @dev Interface of the ERC1271 standard signature validation method for
* contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].
*
* _Available since v4.1._
*/interfaceIERC1271{
/**
* @dev Should return whether the signature provided is valid for the provided data
* @param hash Hash of the data to be signed
* @param signature Signature byte array associated with _data
*/functionisValidSignature(bytes32 hash, bytesmemory signature) externalviewreturns (bytes4 magicValue);
}
Código Fuente del Contrato
Archivo 5 de 13: IERC20.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)pragmasolidity ^0.8.0;/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/interfaceIERC20{
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/eventTransfer(addressindexedfrom, addressindexed 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.
*/eventApproval(addressindexed owner, addressindexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/functiontotalSupply() externalviewreturns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/functionbalanceOf(address account) externalviewreturns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/functiontransfer(address to, uint256 amount) externalreturns (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.
*/functionallowance(address owner, address spender) externalviewreturns (uint256);
/**
* @dev Sets `amount` 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.
*/functionapprove(address spender, uint256 amount) externalreturns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/functiontransferFrom(addressfrom, address to, uint256 amount) externalreturns (bool);
}
Código Fuente del Contrato
Archivo 6 de 13: IERC20Permit.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)pragmasolidity ^0.8.0;/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*/interfaceIERC20Permit{
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*/functionpermit(address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/functionnonces(address owner) externalviewreturns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/// solhint-disable-next-line func-name-mixedcasefunctionDOMAIN_SEPARATOR() externalviewreturns (bytes32);
}
Código Fuente del Contrato
Archivo 7 de 13: IPermit2.sol
// SPDX-License-Identifier: MITpragmasolidity ^0.8.0;interfaceIPermit2{
structPermitDetails {
// ERC20 token addressaddress token;
// the maximum amount allowed to spenduint160 amount;
// timestamp at which a spender's token allowances become invaliduint48 expiration;
// an incrementing value indexed per owner,token,and spender for each signatureuint48 nonce;
}
/// @notice The permit message signed for a single token allowncestructPermitSingle {
// the permit data for a single token alownce
PermitDetails details;
// address permissioned on the allowed tokensaddress spender;
// deadline on the permit signatureuint256 sigDeadline;
}
/// @notice Packed allowancestructPackedAllowance {
// amount alloweduint160 amount;
// permission expiryuint48 expiration;
// an incrementing value indexed per owner,token,and spender for each signatureuint48 nonce;
}
functiontransferFrom(address user, address spender, uint160 amount, address token) external;
functionpermit(address owner, PermitSingle memory permitSingle, bytescalldata signature) external;
functionallowance(address user, address token, address spender) externalviewreturns (PackedAllowance memory);
}
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.0) (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 Throws if called by any account other than the owner.
*/modifieronlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/functionowner() publicviewvirtualreturns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/function_checkOwner() internalviewvirtual{
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling 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);
}
}
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/draft-IERC20Permit.sol)pragmasolidity ^0.8.0;// EIP-2612 is Final as of 2022-11-01. This file is deprecated.import"./IERC20Permit.sol";