¡El código fuente de este contrato está verificado!
Metadatos del Contrato
Compilador
0.8.0+commit.c7dfd78e
Idioma
Solidity
Código Fuente del Contrato
Archivo 1 de 20: BufferChainlink.sol
// SPDX-License-Identifier: MITpragmasolidity ^0.8.0;/**
* @dev A library for working with mutable byte buffers in Solidity.
*
* Byte buffers are mutable and expandable, and provide a variety of primitives
* for writing to them. At any time you can fetch a bytes object containing the
* current contents of the buffer. The bytes object should not be stored between
* operations, as it may change due to resizing of the buffer.
*/libraryBufferChainlink{
/**
* @dev Represents a mutable buffer. Buffers have a current value (buf) and
* a capacity. The capacity may be longer than the current value, in
* which case it can be extended without the need to allocate more memory.
*/structbuffer {
bytes buf;
uint256 capacity;
}
/**
* @dev Initializes a buffer with an initial capacity.
* @param buf The buffer to initialize.
* @param capacity The number of bytes of space to allocate the buffer.
* @return The buffer, for chaining.
*/functioninit(buffer memory buf, uint256 capacity) internalpurereturns (buffer memory) {
if (capacity %32!=0) {
capacity +=32- (capacity %32);
}
// Allocate space for the buffer data
buf.capacity = capacity;
assembly {
let ptr :=mload(0x40)
mstore(buf, ptr)
mstore(ptr, 0)
mstore(0x40, add(32, add(ptr, capacity)))
}
return buf;
}
/**
* @dev Initializes a new buffer from an existing bytes object.
* Changes to the buffer may mutate the original value.
* @param b The bytes object to initialize the buffer with.
* @return A new buffer.
*/functionfromBytes(bytesmemory b) internalpurereturns (buffer memory) {
buffer memory buf;
buf.buf = b;
buf.capacity = b.length;
return buf;
}
functionresize(buffer memory buf, uint256 capacity) privatepure{
bytesmemory oldbuf = buf.buf;
init(buf, capacity);
append(buf, oldbuf);
}
functionmax(uint256 a, uint256 b) privatepurereturns (uint256) {
if (a > b) {
return a;
}
return b;
}
/**
* @dev Sets buffer length to 0.
* @param buf The buffer to truncate.
* @return The original buffer, for chaining..
*/functiontruncate(buffer memory buf) internalpurereturns (buffer memory) {
assembly {
let bufptr :=mload(buf)
mstore(bufptr, 0)
}
return buf;
}
/**
* @dev Writes a byte string to a buffer. Resizes if doing so would exceed
* the capacity of the buffer.
* @param buf The buffer to append to.
* @param off The start offset to write to.
* @param data The data to append.
* @param len The number of bytes to copy.
* @return The original buffer, for chaining.
*/functionwrite(
buffer memory buf,
uint256 off,
bytesmemory data,
uint256 len
) internalpurereturns (buffer memory) {
require(len <= data.length);
if (off + len > buf.capacity) {
resize(buf, max(buf.capacity, len + off) *2);
}
uint256 dest;
uint256 src;
assembly {
// Memory address of the buffer datalet bufptr :=mload(buf)
// Length of existing buffer datalet buflen :=mload(bufptr)
// Start address = buffer address + offset + sizeof(buffer length)
dest :=add(add(bufptr, 32), off)
// Update buffer length if we're extending itifgt(add(len, off), buflen) {
mstore(bufptr, add(len, off))
}
src :=add(data, 32)
}
// Copy word-length chunks while possiblefor (; len >=32; len -=32) {
assembly {
mstore(dest, mload(src))
}
dest +=32;
src +=32;
}
// Copy remaining bytesunchecked {
uint256 mask = (256**(32- len)) -1;
assembly {
let srcpart :=and(mload(src), not(mask))
let destpart :=and(mload(dest), mask)
mstore(dest, or(destpart, srcpart))
}
}
return buf;
}
/**
* @dev Appends a byte string to a buffer. Resizes if doing so would exceed
* the capacity of the buffer.
* @param buf The buffer to append to.
* @param data The data to append.
* @param len The number of bytes to copy.
* @return The original buffer, for chaining.
*/functionappend(
buffer memory buf,
bytesmemory data,
uint256 len
) internalpurereturns (buffer memory) {
return write(buf, buf.buf.length, data, len);
}
/**
* @dev Appends a byte string to a buffer. Resizes if doing so would exceed
* the capacity of the buffer.
* @param buf The buffer to append to.
* @param data The data to append.
* @return The original buffer, for chaining.
*/functionappend(buffer memory buf, bytesmemory data) internalpurereturns (buffer memory) {
return write(buf, buf.buf.length, data, data.length);
}
/**
* @dev Writes a byte to the buffer. Resizes if doing so would exceed the
* capacity of the buffer.
* @param buf The buffer to append to.
* @param off The offset to write the byte at.
* @param data The data to append.
* @return The original buffer, for chaining.
*/functionwriteUint8(
buffer memory buf,
uint256 off,
uint8 data
) internalpurereturns (buffer memory) {
if (off >= buf.capacity) {
resize(buf, buf.capacity *2);
}
assembly {
// Memory address of the buffer datalet bufptr :=mload(buf)
// Length of existing buffer datalet buflen :=mload(bufptr)
// Address = buffer address + sizeof(buffer length) + offlet dest :=add(add(bufptr, off), 32)
mstore8(dest, data)
// Update buffer length if we extended itifeq(off, buflen) {
mstore(bufptr, add(buflen, 1))
}
}
return buf;
}
/**
* @dev Appends a byte to the buffer. Resizes if doing so would exceed the
* capacity of the buffer.
* @param buf The buffer to append to.
* @param data The data to append.
* @return The original buffer, for chaining.
*/functionappendUint8(buffer memory buf, uint8 data) internalpurereturns (buffer memory) {
return writeUint8(buf, buf.buf.length, data);
}
/**
* @dev Writes up to 32 bytes to the buffer. Resizes if doing so would
* exceed the capacity of the buffer.
* @param buf The buffer to append to.
* @param off The offset to write at.
* @param data The data to append.
* @param len The number of bytes to write (left-aligned).
* @return The original buffer, for chaining.
*/functionwrite(
buffer memory buf,
uint256 off,
bytes32 data,
uint256 len
) privatepurereturns (buffer memory) {
if (len + off > buf.capacity) {
resize(buf, (len + off) *2);
}
unchecked {
uint256 mask = (256**len) -1;
// Right-align data
data = data >> (8* (32- len));
assembly {
// Memory address of the buffer datalet bufptr :=mload(buf)
// Address = buffer address + sizeof(buffer length) + off + lenlet dest :=add(add(bufptr, off), len)
mstore(dest, or(and(mload(dest), not(mask)), data))
// Update buffer length if we extended itifgt(add(off, len), mload(bufptr)) {
mstore(bufptr, add(off, len))
}
}
}
return buf;
}
/**
* @dev Writes a bytes20 to the buffer. Resizes if doing so would exceed the
* capacity of the buffer.
* @param buf The buffer to append to.
* @param off The offset to write at.
* @param data The data to append.
* @return The original buffer, for chaining.
*/functionwriteBytes20(
buffer memory buf,
uint256 off,
bytes20 data
) internalpurereturns (buffer memory) {
return write(buf, off, bytes32(data), 20);
}
/**
* @dev Appends a bytes20 to the buffer. Resizes if doing so would exceed
* the capacity of the buffer.
* @param buf The buffer to append to.
* @param data The data to append.
* @return The original buffer, for chhaining.
*/functionappendBytes20(buffer memory buf, bytes20 data) internalpurereturns (buffer memory) {
return write(buf, buf.buf.length, bytes32(data), 20);
}
/**
* @dev Appends a bytes32 to the buffer. Resizes if doing so would exceed
* the capacity of the buffer.
* @param buf The buffer to append to.
* @param data The data to append.
* @return The original buffer, for chaining.
*/functionappendBytes32(buffer memory buf, bytes32 data) internalpurereturns (buffer memory) {
return write(buf, buf.buf.length, data, 32);
}
/**
* @dev Writes an integer to the buffer. Resizes if doing so would exceed
* the capacity of the buffer.
* @param buf The buffer to append to.
* @param off The offset to write at.
* @param data The data to append.
* @param len The number of bytes to write (right-aligned).
* @return The original buffer, for chaining.
*/functionwriteInt(
buffer memory buf,
uint256 off,
uint256 data,
uint256 len
) privatepurereturns (buffer memory) {
if (len + off > buf.capacity) {
resize(buf, (len + off) *2);
}
uint256 mask = (256**len) -1;
assembly {
// Memory address of the buffer datalet bufptr :=mload(buf)
// Address = buffer address + off + sizeof(buffer length) + lenlet dest :=add(add(bufptr, off), len)
mstore(dest, or(and(mload(dest), not(mask)), data))
// Update buffer length if we extended itifgt(add(off, len), mload(bufptr)) {
mstore(bufptr, add(off, len))
}
}
return buf;
}
/**
* @dev Appends a byte to the end of the buffer. Resizes if doing so would
* exceed the capacity of the buffer.
* @param buf The buffer to append to.
* @param data The data to append.
* @return The original buffer.
*/functionappendInt(
buffer memory buf,
uint256 data,
uint256 len
) internalpurereturns (buffer memory) {
return writeInt(buf, buf.buf.length, data, len);
}
}
// SPDX-License-Identifier: MITpragmasolidity ^0.8.0;import {CBORChainlink} from"./vendor/CBORChainlink.sol";
import {BufferChainlink} from"./vendor/BufferChainlink.sol";
/**
* @title Library for common Chainlink functions
* @dev Uses imported CBOR library for encoding to buffer
*/libraryChainlink{
uint256internalconstant defaultBufferSize =256; // solhint-disable-line const-name-snakecaseusingCBORChainlinkforBufferChainlink.buffer;
structRequest {
bytes32 id;
address callbackAddress;
bytes4 callbackFunctionId;
uint256 nonce;
BufferChainlink.buffer buf;
}
/**
* @notice Initializes a Chainlink request
* @dev Sets the ID, callback address, and callback function signature on the request
* @param self The uninitialized request
* @param jobId The Job Specification ID
* @param callbackAddr The callback address
* @param callbackFunc The callback function signature
* @return The initialized request
*/functioninitialize(
Request memoryself,
bytes32 jobId,
address callbackAddr,
bytes4 callbackFunc
) internalpurereturns (Chainlink.Request memory) {
BufferChainlink.init(self.buf, defaultBufferSize);
self.id = jobId;
self.callbackAddress = callbackAddr;
self.callbackFunctionId = callbackFunc;
returnself;
}
/**
* @notice Sets the data for the buffer without encoding CBOR on-chain
* @dev CBOR can be closed with curly-brackets {} or they can be left off
* @param self The initialized request
* @param data The CBOR data
*/functionsetBuffer(Request memoryself, bytesmemory data) internalpure{
BufferChainlink.init(self.buf, data.length);
BufferChainlink.append(self.buf, data);
}
/**
* @notice Adds a string value to the request with a given key name
* @param self The initialized request
* @param key The name of the key
* @param value The string value to add
*/functionadd(
Request memoryself,
stringmemory key,
stringmemory value
) internalpure{
self.buf.encodeString(key);
self.buf.encodeString(value);
}
/**
* @notice Adds a bytes value to the request with a given key name
* @param self The initialized request
* @param key The name of the key
* @param value The bytes value to add
*/functionaddBytes(
Request memoryself,
stringmemory key,
bytesmemory value
) internalpure{
self.buf.encodeString(key);
self.buf.encodeBytes(value);
}
/**
* @notice Adds a int256 value to the request with a given key name
* @param self The initialized request
* @param key The name of the key
* @param value The int256 value to add
*/functionaddInt(
Request memoryself,
stringmemory key,
int256 value
) internalpure{
self.buf.encodeString(key);
self.buf.encodeInt(value);
}
/**
* @notice Adds a uint256 value to the request with a given key name
* @param self The initialized request
* @param key The name of the key
* @param value The uint256 value to add
*/functionaddUint(
Request memoryself,
stringmemory key,
uint256 value
) internalpure{
self.buf.encodeString(key);
self.buf.encodeUInt(value);
}
/**
* @notice Adds an array of strings to the request with a given key name
* @param self The initialized request
* @param key The name of the key
* @param values The array of string values to add
*/functionaddStringArray(
Request memoryself,
stringmemory key,
string[] memory values
) internalpure{
self.buf.encodeString(key);
self.buf.startArray();
for (uint256 i =0; i < values.length; i++) {
self.buf.encodeString(values[i]);
}
self.buf.endSequence();
}
}
Código Fuente del Contrato
Archivo 4 de 20: ChainlinkClient.sol
// SPDX-License-Identifier: MITpragmasolidity ^0.8.0;import"./Chainlink.sol";
import"./interfaces/ENSInterface.sol";
import"./interfaces/LinkTokenInterface.sol";
import"./interfaces/ChainlinkRequestInterface.sol";
import"./interfaces/OperatorInterface.sol";
import"./interfaces/PointerInterface.sol";
import {ENSResolverasENSResolver_Chainlink} from"./vendor/ENSResolver.sol";
/**
* @title The ChainlinkClient contract
* @notice Contract writers can inherit this contract in order to create requests for the
* Chainlink network
*/abstractcontractChainlinkClient{
usingChainlinkforChainlink.Request;
uint256internalconstant LINK_DIVISIBILITY =10**18;
uint256privateconstant AMOUNT_OVERRIDE =0;
addressprivateconstant SENDER_OVERRIDE =address(0);
uint256privateconstant ORACLE_ARGS_VERSION =1;
uint256privateconstant OPERATOR_ARGS_VERSION =2;
bytes32privateconstant ENS_TOKEN_SUBNAME =keccak256("link");
bytes32privateconstant ENS_ORACLE_SUBNAME =keccak256("oracle");
addressprivateconstant LINK_TOKEN_POINTER =0xC89bD4E1632D3A43CB03AAAd5262cbe4038Bc571;
ENSInterface private s_ens;
bytes32private s_ensNode;
LinkTokenInterface private s_link;
OperatorInterface private s_oracle;
uint256private s_requestCount =1;
mapping(bytes32=>address) private s_pendingRequests;
eventChainlinkRequested(bytes32indexed id);
eventChainlinkFulfilled(bytes32indexed id);
eventChainlinkCancelled(bytes32indexed id);
/**
* @notice Creates a request that can hold additional parameters
* @param specId The Job Specification ID that the request will be created for
* @param callbackAddr address to operate the callback on
* @param callbackFunctionSignature function signature to use for the callback
* @return A Chainlink Request struct in memory
*/functionbuildChainlinkRequest(bytes32 specId,
address callbackAddr,
bytes4 callbackFunctionSignature
) internalpurereturns (Chainlink.Request memory) {
Chainlink.Request memory req;
return req.initialize(specId, callbackAddr, callbackFunctionSignature);
}
/**
* @notice Creates a request that can hold additional parameters
* @param specId The Job Specification ID that the request will be created for
* @param callbackFunctionSignature function signature to use for the callback
* @return A Chainlink Request struct in memory
*/functionbuildOperatorRequest(bytes32 specId, bytes4 callbackFunctionSignature)
internalviewreturns (Chainlink.Request memory)
{
Chainlink.Request memory req;
return req.initialize(specId, address(this), callbackFunctionSignature);
}
/**
* @notice Creates a Chainlink request to the stored oracle address
* @dev Calls `chainlinkRequestTo` with the stored oracle address
* @param req The initialized Chainlink Request
* @param payment The amount of LINK to send for the request
* @return requestId The request ID
*/functionsendChainlinkRequest(Chainlink.Request memory req, uint256 payment) internalreturns (bytes32) {
return sendChainlinkRequestTo(address(s_oracle), req, payment);
}
/**
* @notice Creates a Chainlink request to the specified oracle address
* @dev Generates and stores a request ID, increments the local nonce, and uses `transferAndCall` to
* send LINK which creates a request on the target oracle contract.
* Emits ChainlinkRequested event.
* @param oracleAddress The address of the oracle for the request
* @param req The initialized Chainlink Request
* @param payment The amount of LINK to send for the request
* @return requestId The request ID
*/functionsendChainlinkRequestTo(address oracleAddress,
Chainlink.Request memory req,
uint256 payment
) internalreturns (bytes32 requestId) {
uint256 nonce = s_requestCount;
s_requestCount = nonce +1;
bytesmemory encodedRequest =abi.encodeWithSelector(
ChainlinkRequestInterface.oracleRequest.selector,
SENDER_OVERRIDE, // Sender value - overridden by onTokenTransfer by the requesting contract's address
AMOUNT_OVERRIDE, // Amount value - overridden by onTokenTransfer by the actual amount of LINK sent
req.id,
address(this),
req.callbackFunctionId,
nonce,
ORACLE_ARGS_VERSION,
req.buf.buf
);
return _rawRequest(oracleAddress, nonce, payment, encodedRequest);
}
/**
* @notice Creates a Chainlink request to the stored oracle address
* @dev This function supports multi-word response
* @dev Calls `sendOperatorRequestTo` with the stored oracle address
* @param req The initialized Chainlink Request
* @param payment The amount of LINK to send for the request
* @return requestId The request ID
*/functionsendOperatorRequest(Chainlink.Request memory req, uint256 payment) internalreturns (bytes32) {
return sendOperatorRequestTo(address(s_oracle), req, payment);
}
/**
* @notice Creates a Chainlink request to the specified oracle address
* @dev This function supports multi-word response
* @dev Generates and stores a request ID, increments the local nonce, and uses `transferAndCall` to
* send LINK which creates a request on the target oracle contract.
* Emits ChainlinkRequested event.
* @param oracleAddress The address of the oracle for the request
* @param req The initialized Chainlink Request
* @param payment The amount of LINK to send for the request
* @return requestId The request ID
*/functionsendOperatorRequestTo(address oracleAddress,
Chainlink.Request memory req,
uint256 payment
) internalreturns (bytes32 requestId) {
uint256 nonce = s_requestCount;
s_requestCount = nonce +1;
bytesmemory encodedRequest =abi.encodeWithSelector(
OperatorInterface.operatorRequest.selector,
SENDER_OVERRIDE, // Sender value - overridden by onTokenTransfer by the requesting contract's address
AMOUNT_OVERRIDE, // Amount value - overridden by onTokenTransfer by the actual amount of LINK sent
req.id,
req.callbackFunctionId,
nonce,
OPERATOR_ARGS_VERSION,
req.buf.buf
);
return _rawRequest(oracleAddress, nonce, payment, encodedRequest);
}
/**
* @notice Make a request to an oracle
* @param oracleAddress The address of the oracle for the request
* @param nonce used to generate the request ID
* @param payment The amount of LINK to send for the request
* @param encodedRequest data encoded for request type specific format
* @return requestId The request ID
*/function_rawRequest(address oracleAddress,
uint256 nonce,
uint256 payment,
bytesmemory encodedRequest
) privatereturns (bytes32 requestId) {
requestId =keccak256(abi.encodePacked(this, nonce));
s_pendingRequests[requestId] = oracleAddress;
emit ChainlinkRequested(requestId);
require(s_link.transferAndCall(oracleAddress, payment, encodedRequest), "unable to transferAndCall to oracle");
}
/**
* @notice Allows a request to be cancelled if it has not been fulfilled
* @dev Requires keeping track of the expiration value emitted from the oracle contract.
* Deletes the request from the `pendingRequests` mapping.
* Emits ChainlinkCancelled event.
* @param requestId The request ID
* @param payment The amount of LINK sent for the request
* @param callbackFunc The callback function specified for the request
* @param expiration The time of the expiration for the request
*/functioncancelChainlinkRequest(bytes32 requestId,
uint256 payment,
bytes4 callbackFunc,
uint256 expiration
) internal{
OperatorInterface requested = OperatorInterface(s_pendingRequests[requestId]);
delete s_pendingRequests[requestId];
emit ChainlinkCancelled(requestId);
requested.cancelOracleRequest(requestId, payment, callbackFunc, expiration);
}
/**
* @notice the next request count to be used in generating a nonce
* @dev starts at 1 in order to ensure consistent gas cost
* @return returns the next request count to be used in a nonce
*/functiongetNextRequestCount() internalviewreturns (uint256) {
return s_requestCount;
}
/**
* @notice Sets the stored oracle address
* @param oracleAddress The address of the oracle contract
*/functionsetChainlinkOracle(address oracleAddress) internal{
s_oracle = OperatorInterface(oracleAddress);
}
/**
* @notice Sets the LINK token address
* @param linkAddress The address of the LINK token contract
*/functionsetChainlinkToken(address linkAddress) internal{
s_link = LinkTokenInterface(linkAddress);
}
/**
* @notice Sets the Chainlink token address for the public
* network as given by the Pointer contract
*/functionsetPublicChainlinkToken() internal{
setChainlinkToken(PointerInterface(LINK_TOKEN_POINTER).getAddress());
}
/**
* @notice Retrieves the stored address of the LINK token
* @return The address of the LINK token
*/functionchainlinkTokenAddress() internalviewreturns (address) {
returnaddress(s_link);
}
/**
* @notice Retrieves the stored address of the oracle contract
* @return The address of the oracle contract
*/functionchainlinkOracleAddress() internalviewreturns (address) {
returnaddress(s_oracle);
}
/**
* @notice Allows for a request which was created on another contract to be fulfilled
* on this contract
* @param oracleAddress The address of the oracle contract that will fulfill the request
* @param requestId The request ID used for the response
*/functionaddChainlinkExternalRequest(address oracleAddress, bytes32 requestId) internalnotPendingRequest(requestId) {
s_pendingRequests[requestId] = oracleAddress;
}
/**
* @notice Sets the stored oracle and LINK token contracts with the addresses resolved by ENS
* @dev Accounts for subnodes having different resolvers
* @param ensAddress The address of the ENS contract
* @param node The ENS node hash
*/functionuseChainlinkWithENS(address ensAddress, bytes32 node) internal{
s_ens = ENSInterface(ensAddress);
s_ensNode = node;
bytes32 linkSubnode =keccak256(abi.encodePacked(s_ensNode, ENS_TOKEN_SUBNAME));
ENSResolver_Chainlink resolver = ENSResolver_Chainlink(s_ens.resolver(linkSubnode));
setChainlinkToken(resolver.addr(linkSubnode));
updateChainlinkOracleWithENS();
}
/**
* @notice Sets the stored oracle contract with the address resolved by ENS
* @dev This may be called on its own as long as `useChainlinkWithENS` has been called previously
*/functionupdateChainlinkOracleWithENS() internal{
bytes32 oracleSubnode =keccak256(abi.encodePacked(s_ensNode, ENS_ORACLE_SUBNAME));
ENSResolver_Chainlink resolver = ENSResolver_Chainlink(s_ens.resolver(oracleSubnode));
setChainlinkOracle(resolver.addr(oracleSubnode));
}
/**
* @notice Ensures that the fulfillment is valid for this contract
* @dev Use if the contract developer prefers methods instead of modifiers for validation
* @param requestId The request ID for fulfillment
*/functionvalidateChainlinkCallback(bytes32 requestId)
internalrecordChainlinkFulfillment(requestId)
// solhint-disable-next-line no-empty-blocks{
}
/**
* @dev Reverts if the sender is not the oracle of the request.
* Emits ChainlinkFulfilled event.
* @param requestId The request ID for fulfillment
*/modifierrecordChainlinkFulfillment(bytes32 requestId) {
require(msg.sender== s_pendingRequests[requestId], "Source must be the oracle of the request");
delete s_pendingRequests[requestId];
emit ChainlinkFulfilled(requestId);
_;
}
/**
* @dev Reverts if the request is already pending
* @param requestId The request ID for fulfillment
*/modifiernotPendingRequest(bytes32 requestId) {
require(s_pendingRequests[requestId] ==address(0), "Request is already pending");
_;
}
}
// SPDX-License-Identifier: MITpragmasolidity ^0.8.0;import"./ConfirmedOwnerWithProposal.sol";
/**
* @title The ConfirmedOwner contract
* @notice A contract with helpers for basic contract ownership.
*/contractConfirmedOwnerisConfirmedOwnerWithProposal{
constructor(address newOwner) ConfirmedOwnerWithProposal(newOwner, address(0)) {}
}
Código Fuente del Contrato
Archivo 7 de 20: ConfirmedOwnerWithProposal.sol
// SPDX-License-Identifier: MITpragmasolidity ^0.8.0;import"./interfaces/OwnableInterface.sol";
/**
* @title The ConfirmedOwner contract
* @notice A contract with helpers for basic contract ownership.
*/contractConfirmedOwnerWithProposalisOwnableInterface{
addressprivate s_owner;
addressprivate s_pendingOwner;
eventOwnershipTransferRequested(addressindexedfrom, addressindexed to);
eventOwnershipTransferred(addressindexedfrom, addressindexed to);
constructor(address newOwner, address pendingOwner) {
require(newOwner !=address(0), "Cannot set owner to zero");
s_owner = newOwner;
if (pendingOwner !=address(0)) {
_transferOwnership(pendingOwner);
}
}
/**
* @notice Allows an owner to begin transferring ownership to a new address,
* pending.
*/functiontransferOwnership(address to) publicoverrideonlyOwner{
_transferOwnership(to);
}
/**
* @notice Allows an ownership transfer to be completed by the recipient.
*/functionacceptOwnership() externaloverride{
require(msg.sender== s_pendingOwner, "Must be proposed owner");
address oldOwner = s_owner;
s_owner =msg.sender;
s_pendingOwner =address(0);
emit OwnershipTransferred(oldOwner, msg.sender);
}
/**
* @notice Get the current owner
*/functionowner() publicviewoverridereturns (address) {
return s_owner;
}
/**
* @notice validate, transfer ownership, and emit relevant events
*/function_transferOwnership(address to) private{
require(to !=msg.sender, "Cannot transfer to self");
s_pendingOwner = to;
emit OwnershipTransferRequested(s_owner, to);
}
/**
* @notice validate access
*/function_validateOwnership() internalview{
require(msg.sender== s_owner, "Only callable by owner");
}
/**
* @notice Reverts if called by anyone other than the contract owner.
*/modifieronlyOwner() {
_validateOwnership();
_;
}
}
Código Fuente del Contrato
Archivo 8 de 20: 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 9 de 20: ENSInterface.sol
// SPDX-License-Identifier: MITpragmasolidity ^0.8.0;interfaceENSInterface{
// Logged when the owner of a node assigns a new owner to a subnode.eventNewOwner(bytes32indexed node, bytes32indexed label, address owner);
// Logged when the owner of a node transfers ownership to a new account.eventTransfer(bytes32indexed node, address owner);
// Logged when the resolver for a node changes.eventNewResolver(bytes32indexed node, address resolver);
// Logged when the TTL of a node changeseventNewTTL(bytes32indexed node, uint64 ttl);
functionsetSubnodeOwner(bytes32 node,
bytes32 label,
address owner
) external;
functionsetResolver(bytes32 node, address resolver) external;
functionsetOwner(bytes32 node, address owner) external;
functionsetTTL(bytes32 node, uint64 ttl) external;
functionowner(bytes32 node) externalviewreturns (address);
functionresolver(bytes32 node) externalviewreturns (address);
functionttl(bytes32 node) externalviewreturns (uint64);
}
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/ERC20.sol)pragmasolidity ^0.8.0;import"./IERC20.sol";
import"./extensions/IERC20Metadata.sol";
import"../../utils/Context.sol";
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
* For a generic mechanism see {ERC20PresetMinterPauser}.
*
* TIP: For a detailed writeup see our guide
* https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* We have followed general OpenZeppelin Contracts guidelines: functions revert
* instead returning `false` on failure. This behavior is nonetheless
* conventional and does not conflict with the expectations of ERC20
* applications.
*
* Additionally, an {Approval} event is emitted on calls to {transferFrom}.
* This allows applications to reconstruct the allowance for all accounts just
* by listening to said events. Other implementations of the EIP may not emit
* these events, as it isn't required by the specification.
*
* Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
* functions have been added to mitigate the well-known issues around setting
* allowances. See {IERC20-approve}.
*/contractERC20isContext, IERC20, IERC20Metadata{
mapping(address=>uint256) private _balances;
mapping(address=>mapping(address=>uint256)) private _allowances;
uint256private _totalSupply;
stringprivate _name;
stringprivate _symbol;
/**
* @dev Sets the values for {name} and {symbol}.
*
* The default value of {decimals} is 18. To select a different value for
* {decimals} you should overload it.
*
* All two of these values are immutable: they can only be set once during
* construction.
*/constructor(stringmemory name_, stringmemory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/functionname() publicviewvirtualoverridereturns (stringmemory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/functionsymbol() publicviewvirtualoverridereturns (stringmemory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5.05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the value {ERC20} uses, unless this function is
* overridden;
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/functiondecimals() publicviewvirtualoverridereturns (uint8) {
return18;
}
/**
* @dev See {IERC20-totalSupply}.
*/functiontotalSupply() publicviewvirtualoverridereturns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/functionbalanceOf(address account) publicviewvirtualoverridereturns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/functiontransfer(address to, uint256 amount) publicvirtualoverridereturns (bool) {
address owner = _msgSender();
_transfer(owner, to, amount);
returntrue;
}
/**
* @dev See {IERC20-allowance}.
*/functionallowance(address owner, address spender) publicviewvirtualoverridereturns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
* `transferFrom`. This is semantically equivalent to an infinite approval.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/functionapprove(address spender, uint256 amount) publicvirtualoverridereturns (bool) {
address owner = _msgSender();
_approve(owner, spender, amount);
returntrue;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20}.
*
* NOTE: Does not update the allowance if the current allowance
* is the maximum `uint256`.
*
* Requirements:
*
* - `from` and `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
* - the caller must have allowance for ``from``'s tokens of at least
* `amount`.
*/functiontransferFrom(addressfrom,
address to,
uint256 amount
) publicvirtualoverridereturns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, amount);
_transfer(from, to, amount);
returntrue;
}
/**
* @dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/functionincreaseAllowance(address spender, uint256 addedValue) publicvirtualreturns (bool) {
address owner = _msgSender();
_approve(owner, spender, allowance(owner, spender) + addedValue);
returntrue;
}
/**
* @dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/functiondecreaseAllowance(address spender, uint256 subtractedValue) publicvirtualreturns (bool) {
address owner = _msgSender();
uint256 currentAllowance = allowance(owner, spender);
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(owner, spender, currentAllowance - subtractedValue);
}
returntrue;
}
/**
* @dev Moves `amount` of tokens from `sender` to `recipient`.
*
* This internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
*/function_transfer(addressfrom,
address to,
uint256 amount
) internalvirtual{
require(from!=address(0), "ERC20: transfer from the zero address");
require(to !=address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(from, to, amount);
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
}
_balances[to] += amount;
emit Transfer(from, to, amount);
_afterTokenTransfer(from, to, amount);
}
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/function_mint(address account, uint256 amount) internalvirtual{
require(account !=address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
_balances[account] += amount;
emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
}
/**
* @dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/function_burn(address account, uint256 amount) internalvirtual{
require(account !=address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
_balances[account] = accountBalance - amount;
}
_totalSupply -= amount;
emit Transfer(account, address(0), amount);
_afterTokenTransfer(account, address(0), amount);
}
/**
* @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*/function_approve(address owner,
address spender,
uint256 amount
) internalvirtual{
require(owner !=address(0), "ERC20: approve from the zero address");
require(spender !=address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
/**
* @dev Updates `owner` s allowance for `spender` based on spent `amount`.
*
* Does not update the allowance amount in case of infinite allowance.
* Revert if not enough allowance is available.
*
* Might emit an {Approval} event.
*/function_spendAllowance(address owner,
address spender,
uint256 amount
) internalvirtual{
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance !=type(uint256).max) {
require(currentAllowance >= amount, "ERC20: insufficient allowance");
unchecked {
_approve(owner, spender, currentAllowance - amount);
}
}
}
/**
* @dev Hook that is called before any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/function_beforeTokenTransfer(addressfrom,
address to,
uint256 amount
) internalvirtual{}
/**
* @dev Hook that is called after any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* has been transferred to `to`.
* - when `from` is zero, `amount` tokens have been minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens have been burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/function_afterTokenTransfer(addressfrom,
address to,
uint256 amount
) internalvirtual{}
}
Código Fuente del Contrato
Archivo 12 de 20: ERC20Burnable.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)pragmasolidity ^0.8.0;import"../ERC20.sol";
import"../../../utils/Context.sol";
/**
* @dev Extension of {ERC20} that allows token holders to destroy both their own
* tokens and those that they have an allowance for, in a way that can be
* recognized off-chain (via event analysis).
*/abstractcontractERC20BurnableisContext, ERC20{
/**
* @dev Destroys `amount` tokens from the caller.
*
* See {ERC20-_burn}.
*/functionburn(uint256 amount) publicvirtual{
_burn(_msgSender(), amount);
}
/**
* @dev Destroys `amount` tokens from `account`, deducting from the caller's
* allowance.
*
* See {ERC20-_burn} and {ERC20-allowance}.
*
* Requirements:
*
* - the caller must have allowance for ``accounts``'s tokens of at least
* `amount`.
*/functionburnFrom(address account, uint256 amount) publicvirtual{
_spendAllowance(account, _msgSender(), amount);
_burn(account, amount);
}
}
Código Fuente del Contrato
Archivo 13 de 20: IERC20.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts (last updated v4.6.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 14 de 20: IERC20Metadata.sol
// SPDX-License-Identifier: MIT// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)pragmasolidity ^0.8.0;import"../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/interfaceIERC20MetadataisIERC20{
/**
* @dev Returns the name of the token.
*/functionname() externalviewreturns (stringmemory);
/**
* @dev Returns the symbol of the token.
*/functionsymbol() externalviewreturns (stringmemory);
/**
* @dev Returns the decimals places of the token.
*/functiondecimals() externalviewreturns (uint8);
}