文件 1 的 20:BufferChainlink.sol
pragma solidity ^0.8.0;
library BufferChainlink {
struct buffer {
bytes buf;
uint256 capacity;
}
function init(buffer memory buf, uint256 capacity) internal pure returns (buffer memory) {
if (capacity % 32 != 0) {
capacity += 32 - (capacity % 32);
}
buf.capacity = capacity;
assembly {
let ptr := mload(0x40)
mstore(buf, ptr)
mstore(ptr, 0)
mstore(0x40, add(32, add(ptr, capacity)))
}
return buf;
}
function fromBytes(bytes memory b) internal pure returns (buffer memory) {
buffer memory buf;
buf.buf = b;
buf.capacity = b.length;
return buf;
}
function resize(buffer memory buf, uint256 capacity) private pure {
bytes memory oldbuf = buf.buf;
init(buf, capacity);
append(buf, oldbuf);
}
function max(uint256 a, uint256 b) private pure returns (uint256) {
if (a > b) {
return a;
}
return b;
}
function truncate(buffer memory buf) internal pure returns (buffer memory) {
assembly {
let bufptr := mload(buf)
mstore(bufptr, 0)
}
return buf;
}
function write(
buffer memory buf,
uint256 off,
bytes memory data,
uint256 len
) internal pure returns (buffer memory) {
require(len <= data.length);
if (off + len > buf.capacity) {
resize(buf, max(buf.capacity, len + off) * 2);
}
uint256 dest;
uint256 src;
assembly {
let bufptr := mload(buf)
let buflen := mload(bufptr)
dest := add(add(bufptr, 32), off)
if gt(add(len, off), buflen) {
mstore(bufptr, add(len, off))
}
src := add(data, 32)
}
for (; len >= 32; len -= 32) {
assembly {
mstore(dest, mload(src))
}
dest += 32;
src += 32;
}
unchecked {
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;
}
function append(
buffer memory buf,
bytes memory data,
uint256 len
) internal pure returns (buffer memory) {
return write(buf, buf.buf.length, data, len);
}
function append(buffer memory buf, bytes memory data) internal pure returns (buffer memory) {
return write(buf, buf.buf.length, data, data.length);
}
function writeUint8(
buffer memory buf,
uint256 off,
uint8 data
) internal pure returns (buffer memory) {
if (off >= buf.capacity) {
resize(buf, buf.capacity * 2);
}
assembly {
let bufptr := mload(buf)
let buflen := mload(bufptr)
let dest := add(add(bufptr, off), 32)
mstore8(dest, data)
if eq(off, buflen) {
mstore(bufptr, add(buflen, 1))
}
}
return buf;
}
function appendUint8(buffer memory buf, uint8 data) internal pure returns (buffer memory) {
return writeUint8(buf, buf.buf.length, data);
}
function write(
buffer memory buf,
uint256 off,
bytes32 data,
uint256 len
) private pure returns (buffer memory) {
if (len + off > buf.capacity) {
resize(buf, (len + off) * 2);
}
unchecked {
uint256 mask = (256**len) - 1;
data = data >> (8 * (32 - len));
assembly {
let bufptr := mload(buf)
let dest := add(add(bufptr, off), len)
mstore(dest, or(and(mload(dest), not(mask)), data))
if gt(add(off, len), mload(bufptr)) {
mstore(bufptr, add(off, len))
}
}
}
return buf;
}
function writeBytes20(
buffer memory buf,
uint256 off,
bytes20 data
) internal pure returns (buffer memory) {
return write(buf, off, bytes32(data), 20);
}
function appendBytes20(buffer memory buf, bytes20 data) internal pure returns (buffer memory) {
return write(buf, buf.buf.length, bytes32(data), 20);
}
function appendBytes32(buffer memory buf, bytes32 data) internal pure returns (buffer memory) {
return write(buf, buf.buf.length, data, 32);
}
function writeInt(
buffer memory buf,
uint256 off,
uint256 data,
uint256 len
) private pure returns (buffer memory) {
if (len + off > buf.capacity) {
resize(buf, (len + off) * 2);
}
uint256 mask = (256**len) - 1;
assembly {
let bufptr := mload(buf)
let dest := add(add(bufptr, off), len)
mstore(dest, or(and(mload(dest), not(mask)), data))
if gt(add(off, len), mload(bufptr)) {
mstore(bufptr, add(off, len))
}
}
return buf;
}
function appendInt(
buffer memory buf,
uint256 data,
uint256 len
) internal pure returns (buffer memory) {
return writeInt(buf, buf.buf.length, data, len);
}
}
文件 2 的 20:CBORChainlink.sol
pragma solidity >=0.4.19;
import {BufferChainlink} from "./BufferChainlink.sol";
library CBORChainlink {
using BufferChainlink for BufferChainlink.buffer;
uint8 private constant MAJOR_TYPE_INT = 0;
uint8 private constant MAJOR_TYPE_NEGATIVE_INT = 1;
uint8 private constant MAJOR_TYPE_BYTES = 2;
uint8 private constant MAJOR_TYPE_STRING = 3;
uint8 private constant MAJOR_TYPE_ARRAY = 4;
uint8 private constant MAJOR_TYPE_MAP = 5;
uint8 private constant MAJOR_TYPE_TAG = 6;
uint8 private constant MAJOR_TYPE_CONTENT_FREE = 7;
uint8 private constant TAG_TYPE_BIGNUM = 2;
uint8 private constant TAG_TYPE_NEGATIVE_BIGNUM = 3;
function encodeFixedNumeric(BufferChainlink.buffer memory buf, uint8 major, uint64 value) private pure {
if(value <= 23) {
buf.appendUint8(uint8((major << 5) | value));
} else if (value <= 0xFF) {
buf.appendUint8(uint8((major << 5) | 24));
buf.appendInt(value, 1);
} else if (value <= 0xFFFF) {
buf.appendUint8(uint8((major << 5) | 25));
buf.appendInt(value, 2);
} else if (value <= 0xFFFFFFFF) {
buf.appendUint8(uint8((major << 5) | 26));
buf.appendInt(value, 4);
} else {
buf.appendUint8(uint8((major << 5) | 27));
buf.appendInt(value, 8);
}
}
function encodeIndefiniteLengthType(BufferChainlink.buffer memory buf, uint8 major) private pure {
buf.appendUint8(uint8((major << 5) | 31));
}
function encodeUInt(BufferChainlink.buffer memory buf, uint value) internal pure {
if(value > 0xFFFFFFFFFFFFFFFF) {
encodeBigNum(buf, value);
} else {
encodeFixedNumeric(buf, MAJOR_TYPE_INT, uint64(value));
}
}
function encodeInt(BufferChainlink.buffer memory buf, int value) internal pure {
if(value < -0x10000000000000000) {
encodeSignedBigNum(buf, value);
} else if(value > 0xFFFFFFFFFFFFFFFF) {
encodeBigNum(buf, uint(value));
} else if(value >= 0) {
encodeFixedNumeric(buf, MAJOR_TYPE_INT, uint64(uint256(value)));
} else {
encodeFixedNumeric(buf, MAJOR_TYPE_NEGATIVE_INT, uint64(uint256(-1 - value)));
}
}
function encodeBytes(BufferChainlink.buffer memory buf, bytes memory value) internal pure {
encodeFixedNumeric(buf, MAJOR_TYPE_BYTES, uint64(value.length));
buf.append(value);
}
function encodeBigNum(BufferChainlink.buffer memory buf, uint value) internal pure {
buf.appendUint8(uint8((MAJOR_TYPE_TAG << 5) | TAG_TYPE_BIGNUM));
encodeBytes(buf, abi.encode(value));
}
function encodeSignedBigNum(BufferChainlink.buffer memory buf, int input) internal pure {
buf.appendUint8(uint8((MAJOR_TYPE_TAG << 5) | TAG_TYPE_NEGATIVE_BIGNUM));
encodeBytes(buf, abi.encode(uint256(-1 - input)));
}
function encodeString(BufferChainlink.buffer memory buf, string memory value) internal pure {
encodeFixedNumeric(buf, MAJOR_TYPE_STRING, uint64(bytes(value).length));
buf.append(bytes(value));
}
function startArray(BufferChainlink.buffer memory buf) internal pure {
encodeIndefiniteLengthType(buf, MAJOR_TYPE_ARRAY);
}
function startMap(BufferChainlink.buffer memory buf) internal pure {
encodeIndefiniteLengthType(buf, MAJOR_TYPE_MAP);
}
function endSequence(BufferChainlink.buffer memory buf) internal pure {
encodeIndefiniteLengthType(buf, MAJOR_TYPE_CONTENT_FREE);
}
}
文件 3 的 20:Chainlink.sol
pragma solidity ^0.8.0;
import {CBORChainlink} from "./vendor/CBORChainlink.sol";
import {BufferChainlink} from "./vendor/BufferChainlink.sol";
library Chainlink {
uint256 internal constant defaultBufferSize = 256;
using CBORChainlink for BufferChainlink.buffer;
struct Request {
bytes32 id;
address callbackAddress;
bytes4 callbackFunctionId;
uint256 nonce;
BufferChainlink.buffer buf;
}
function initialize(
Request memory self,
bytes32 jobId,
address callbackAddr,
bytes4 callbackFunc
) internal pure returns (Chainlink.Request memory) {
BufferChainlink.init(self.buf, defaultBufferSize);
self.id = jobId;
self.callbackAddress = callbackAddr;
self.callbackFunctionId = callbackFunc;
return self;
}
function setBuffer(Request memory self, bytes memory data) internal pure {
BufferChainlink.init(self.buf, data.length);
BufferChainlink.append(self.buf, data);
}
function add(
Request memory self,
string memory key,
string memory value
) internal pure {
self.buf.encodeString(key);
self.buf.encodeString(value);
}
function addBytes(
Request memory self,
string memory key,
bytes memory value
) internal pure {
self.buf.encodeString(key);
self.buf.encodeBytes(value);
}
function addInt(
Request memory self,
string memory key,
int256 value
) internal pure {
self.buf.encodeString(key);
self.buf.encodeInt(value);
}
function addUint(
Request memory self,
string memory key,
uint256 value
) internal pure {
self.buf.encodeString(key);
self.buf.encodeUInt(value);
}
function addStringArray(
Request memory self,
string memory key,
string[] memory values
) internal pure {
self.buf.encodeString(key);
self.buf.startArray();
for (uint256 i = 0; i < values.length; i++) {
self.buf.encodeString(values[i]);
}
self.buf.endSequence();
}
}
文件 4 的 20:ChainlinkClient.sol
pragma solidity ^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 {ENSResolver as ENSResolver_Chainlink} from "./vendor/ENSResolver.sol";
abstract contract ChainlinkClient {
using Chainlink for Chainlink.Request;
uint256 internal constant LINK_DIVISIBILITY = 10**18;
uint256 private constant AMOUNT_OVERRIDE = 0;
address private constant SENDER_OVERRIDE = address(0);
uint256 private constant ORACLE_ARGS_VERSION = 1;
uint256 private constant OPERATOR_ARGS_VERSION = 2;
bytes32 private constant ENS_TOKEN_SUBNAME = keccak256("link");
bytes32 private constant ENS_ORACLE_SUBNAME = keccak256("oracle");
address private constant LINK_TOKEN_POINTER = 0xC89bD4E1632D3A43CB03AAAd5262cbe4038Bc571;
ENSInterface private s_ens;
bytes32 private s_ensNode;
LinkTokenInterface private s_link;
OperatorInterface private s_oracle;
uint256 private s_requestCount = 1;
mapping(bytes32 => address) private s_pendingRequests;
event ChainlinkRequested(bytes32 indexed id);
event ChainlinkFulfilled(bytes32 indexed id);
event ChainlinkCancelled(bytes32 indexed id);
function buildChainlinkRequest(
bytes32 specId,
address callbackAddr,
bytes4 callbackFunctionSignature
) internal pure returns (Chainlink.Request memory) {
Chainlink.Request memory req;
return req.initialize(specId, callbackAddr, callbackFunctionSignature);
}
function buildOperatorRequest(bytes32 specId, bytes4 callbackFunctionSignature)
internal
view
returns (Chainlink.Request memory)
{
Chainlink.Request memory req;
return req.initialize(specId, address(this), callbackFunctionSignature);
}
function sendChainlinkRequest(Chainlink.Request memory req, uint256 payment) internal returns (bytes32) {
return sendChainlinkRequestTo(address(s_oracle), req, payment);
}
function sendChainlinkRequestTo(
address oracleAddress,
Chainlink.Request memory req,
uint256 payment
) internal returns (bytes32 requestId) {
uint256 nonce = s_requestCount;
s_requestCount = nonce + 1;
bytes memory encodedRequest = abi.encodeWithSelector(
ChainlinkRequestInterface.oracleRequest.selector,
SENDER_OVERRIDE,
AMOUNT_OVERRIDE,
req.id,
address(this),
req.callbackFunctionId,
nonce,
ORACLE_ARGS_VERSION,
req.buf.buf
);
return _rawRequest(oracleAddress, nonce, payment, encodedRequest);
}
function sendOperatorRequest(Chainlink.Request memory req, uint256 payment) internal returns (bytes32) {
return sendOperatorRequestTo(address(s_oracle), req, payment);
}
function sendOperatorRequestTo(
address oracleAddress,
Chainlink.Request memory req,
uint256 payment
) internal returns (bytes32 requestId) {
uint256 nonce = s_requestCount;
s_requestCount = nonce + 1;
bytes memory encodedRequest = abi.encodeWithSelector(
OperatorInterface.operatorRequest.selector,
SENDER_OVERRIDE,
AMOUNT_OVERRIDE,
req.id,
req.callbackFunctionId,
nonce,
OPERATOR_ARGS_VERSION,
req.buf.buf
);
return _rawRequest(oracleAddress, nonce, payment, encodedRequest);
}
function _rawRequest(
address oracleAddress,
uint256 nonce,
uint256 payment,
bytes memory encodedRequest
) private returns (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");
}
function cancelChainlinkRequest(
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);
}
function getNextRequestCount() internal view returns (uint256) {
return s_requestCount;
}
function setChainlinkOracle(address oracleAddress) internal {
s_oracle = OperatorInterface(oracleAddress);
}
function setChainlinkToken(address linkAddress) internal {
s_link = LinkTokenInterface(linkAddress);
}
function setPublicChainlinkToken() internal {
setChainlinkToken(PointerInterface(LINK_TOKEN_POINTER).getAddress());
}
function chainlinkTokenAddress() internal view returns (address) {
return address(s_link);
}
function chainlinkOracleAddress() internal view returns (address) {
return address(s_oracle);
}
function addChainlinkExternalRequest(address oracleAddress, bytes32 requestId) internal notPendingRequest(requestId) {
s_pendingRequests[requestId] = oracleAddress;
}
function useChainlinkWithENS(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();
}
function updateChainlinkOracleWithENS() internal {
bytes32 oracleSubnode = keccak256(abi.encodePacked(s_ensNode, ENS_ORACLE_SUBNAME));
ENSResolver_Chainlink resolver = ENSResolver_Chainlink(s_ens.resolver(oracleSubnode));
setChainlinkOracle(resolver.addr(oracleSubnode));
}
function validateChainlinkCallback(bytes32 requestId)
internal
recordChainlinkFulfillment(requestId)
{
}
modifier recordChainlinkFulfillment(bytes32 requestId) {
require(msg.sender == s_pendingRequests[requestId], "Source must be the oracle of the request");
delete s_pendingRequests[requestId];
emit ChainlinkFulfilled(requestId);
_;
}
modifier notPendingRequest(bytes32 requestId) {
require(s_pendingRequests[requestId] == address(0), "Request is already pending");
_;
}
}
文件 5 的 20:ChainlinkRequestInterface.sol
pragma solidity ^0.8.0;
interface ChainlinkRequestInterface {
function oracleRequest(
address sender,
uint256 requestPrice,
bytes32 serviceAgreementID,
address callbackAddress,
bytes4 callbackFunctionId,
uint256 nonce,
uint256 dataVersion,
bytes calldata data
) external;
function cancelOracleRequest(
bytes32 requestId,
uint256 payment,
bytes4 callbackFunctionId,
uint256 expiration
) external;
}
文件 6 的 20:ConfirmedOwner.sol
pragma solidity ^0.8.0;
import "./ConfirmedOwnerWithProposal.sol";
contract ConfirmedOwner is ConfirmedOwnerWithProposal {
constructor(address newOwner) ConfirmedOwnerWithProposal(newOwner, address(0)) {}
}
文件 7 的 20:ConfirmedOwnerWithProposal.sol
pragma solidity ^0.8.0;
import "./interfaces/OwnableInterface.sol";
contract ConfirmedOwnerWithProposal is OwnableInterface {
address private s_owner;
address private s_pendingOwner;
event OwnershipTransferRequested(address indexed from, address indexed to);
event OwnershipTransferred(address indexed from, address indexed to);
constructor(address newOwner, address pendingOwner) {
require(newOwner != address(0), "Cannot set owner to zero");
s_owner = newOwner;
if (pendingOwner != address(0)) {
_transferOwnership(pendingOwner);
}
}
function transferOwnership(address to) public override onlyOwner {
_transferOwnership(to);
}
function acceptOwnership() external override {
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);
}
function owner() public view override returns (address) {
return s_owner;
}
function _transferOwnership(address to) private {
require(to != msg.sender, "Cannot transfer to self");
s_pendingOwner = to;
emit OwnershipTransferRequested(s_owner, to);
}
function _validateOwnership() internal view {
require(msg.sender == s_owner, "Only callable by owner");
}
modifier onlyOwner() {
_validateOwnership();
_;
}
}
文件 8 的 20:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 9 的 20:ENSInterface.sol
pragma solidity ^0.8.0;
interface ENSInterface {
event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);
event Transfer(bytes32 indexed node, address owner);
event NewResolver(bytes32 indexed node, address resolver);
event NewTTL(bytes32 indexed node, uint64 ttl);
function setSubnodeOwner(
bytes32 node,
bytes32 label,
address owner
) external;
function setResolver(bytes32 node, address resolver) external;
function setOwner(bytes32 node, address owner) external;
function setTTL(bytes32 node, uint64 ttl) external;
function owner(bytes32 node) external view returns (address);
function resolver(bytes32 node) external view returns (address);
function ttl(bytes32 node) external view returns (uint64);
}
文件 10 的 20:ENSResolver.sol
pragma solidity ^0.8.0;
abstract contract ENSResolver {
function addr(bytes32 node) public view virtual returns (address);
}
文件 11 的 20:ERC20.sol
pragma solidity ^0.8.0;
import "./IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "../../utils/Context.sol";
contract ERC20 is Context, IERC20, IERC20Metadata {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
function name() public view virtual override returns (string memory) {
return _name;
}
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
function decimals() public view virtual override returns (uint8) {
return 18;
}
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
function transfer(address to, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_transfer(owner, to, amount);
return true;
}
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
function approve(address spender, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_approve(owner, spender, amount);
return true;
}
function transferFrom(
address from,
address to,
uint256 amount
) public virtual override returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, amount);
_transfer(from, to, amount);
return true;
}
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, allowance(owner, spender) + addedValue);
return true;
}
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
address owner = _msgSender();
uint256 currentAllowance = allowance(owner, spender);
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(owner, spender, currentAllowance - subtractedValue);
}
return true;
}
function _transfer(
address from,
address to,
uint256 amount
) internal virtual {
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);
}
function _mint(address account, uint256 amount) internal virtual {
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);
}
function _burn(address account, uint256 amount) internal virtual {
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);
}
function _approve(
address owner,
address spender,
uint256 amount
) internal virtual {
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);
}
function _spendAllowance(
address owner,
address spender,
uint256 amount
) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
require(currentAllowance >= amount, "ERC20: insufficient allowance");
unchecked {
_approve(owner, spender, currentAllowance - amount);
}
}
}
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
function _afterTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
}
文件 12 的 20:ERC20Burnable.sol
pragma solidity ^0.8.0;
import "../ERC20.sol";
import "../../../utils/Context.sol";
abstract contract ERC20Burnable is Context, ERC20 {
function burn(uint256 amount) public virtual {
_burn(_msgSender(), amount);
}
function burnFrom(address account, uint256 amount) public virtual {
_spendAllowance(account, _msgSender(), amount);
_burn(account, amount);
}
}
文件 13 的 20:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}
文件 14 的 20:IERC20Metadata.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
interface IERC20Metadata is IERC20 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
}
文件 15 的 20:LinkTokenInterface.sol
pragma solidity ^0.8.0;
interface LinkTokenInterface {
function allowance(address owner, address spender) external view returns (uint256 remaining);
function approve(address spender, uint256 value) external returns (bool success);
function balanceOf(address owner) external view returns (uint256 balance);
function decimals() external view returns (uint8 decimalPlaces);
function decreaseApproval(address spender, uint256 addedValue) external returns (bool success);
function increaseApproval(address spender, uint256 subtractedValue) external;
function name() external view returns (string memory tokenName);
function symbol() external view returns (string memory tokenSymbol);
function totalSupply() external view returns (uint256 totalTokensIssued);
function transfer(address to, uint256 value) external returns (bool success);
function transferAndCall(
address to,
uint256 value,
bytes calldata data
) external returns (bool success);
function transferFrom(
address from,
address to,
uint256 value
) external returns (bool success);
}
文件 16 的 20:OperatorInterface.sol
pragma solidity ^0.8.0;
import "./OracleInterface.sol";
import "./ChainlinkRequestInterface.sol";
interface OperatorInterface is OracleInterface, ChainlinkRequestInterface {
function operatorRequest(
address sender,
uint256 payment,
bytes32 specId,
bytes4 callbackFunctionId,
uint256 nonce,
uint256 dataVersion,
bytes calldata data
) external;
function fulfillOracleRequest2(
bytes32 requestId,
uint256 payment,
address callbackAddress,
bytes4 callbackFunctionId,
uint256 expiration,
bytes calldata data
) external returns (bool);
function ownerTransferAndCall(
address to,
uint256 value,
bytes calldata data
) external returns (bool success);
function distributeFunds(address payable[] calldata receivers, uint256[] calldata amounts) external payable;
function getAuthorizedSenders() external returns (address[] memory);
function setAuthorizedSenders(address[] calldata senders) external;
function getForwarder() external returns (address);
}
文件 17 的 20:OracleInterface.sol
pragma solidity ^0.8.0;
interface OracleInterface {
function fulfillOracleRequest(
bytes32 requestId,
uint256 payment,
address callbackAddress,
bytes4 callbackFunctionId,
uint256 expiration,
bytes32 data
) external returns (bool);
function isAuthorizedSender(address node) external view returns (bool);
function withdraw(address recipient, uint256 amount) external;
function withdrawable() external view returns (uint256);
}
文件 18 的 20:OwnableInterface.sol
pragma solidity ^0.8.0;
interface OwnableInterface {
function owner() external returns (address);
function transferOwnership(address recipient) external;
function acceptOwnership() external;
}
文件 19 的 20:PointerInterface.sol
pragma solidity ^0.8.0;
interface PointerInterface {
function getAddress() external view returns (address);
}
文件 20 的 20:Wait.sol
pragma solidity >=0.8.0;
import '@chainlink/contracts/src/v0.8/ChainlinkClient.sol';
import '@chainlink/contracts/src/v0.8/ConfirmedOwner.sol';
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
contract Wait is ERC20, ERC20Burnable, ChainlinkClient, ConfirmedOwner{
using Chainlink for Chainlink.Request;
address manager;
address timeKeeper = 0x20d7acED31E7C947faB0C3aD62C2D426D152C399;
uint256 public totalSacs = 8;
bool public minting = true;
bytes32 private jobId;
event Reload(
address _user
);
mapping (uint => mapping(address => bool)) public InData;
mapping (uint => mapping(address => bool)) public Claimed;
mapping (uint => mapping(address => uint)) public ClaimedAmount;
mapping(uint => uint) public totalWait;
mapping(uint => uint) public totalPeople;
mapping(uint => uint) public mintedPeople;
mapping(uint => uint) public unclaimedWait;
mapping(uint => uint) public sacTimes;
mapping(address => bool) public checked;
constructor() ERC20("Wait", "WAIT") ConfirmedOwner(msg.sender){
manager = 0x25B6106149284b0269C44BE6beda5ec59C89753a;
totalPeople[0] = 55374;
totalPeople[1] = 124815;
totalPeople[2] = 9465;
totalPeople[3] = 230;
totalPeople[4] = 839;
totalPeople[5] = 2937;
totalPeople[6] = 653;
totalPeople[7] = 1241;
sacTimes[0] = 1627948800;
sacTimes[1] = 1645660800;
sacTimes[2] = 1647907200;
sacTimes[3] = 1646092800;
sacTimes[4] = 1654041600;
sacTimes[5] = 1647561600;
sacTimes[6] = 1654387200;
sacTimes[7] = 1647734400;
setChainlinkToken(0x514910771AF9Ca656af840dff83E8264EcF986CA);
setChainlinkOracle(0x2e973758d5f319ED4768570182cA601e970ff549);
jobId = '233eae6ef5c34ad2a0fe2eaed75b5f44';
}
modifier manager_function(){
require(msg.sender==manager,"Only the manager can call this function");
_;}
modifier minting_on(){
require(minting == true,"Minting Wait has been turned off, go claim the unclaimed Wait");
_;}
function decimals() public pure override returns (uint8) {
return 0;
}
function checkDatabase(string memory _address) public returns (bytes32 requestId) {
Chainlink.Request memory req = buildChainlinkRequest(jobId, address(this), this.fulfill.selector);
req.add('address', _address);
req.add('path',"bro");
req.add('path1',"man");
sendOperatorRequest(req, 0);
}
function fulfill(bytes32 _requestId, address user, uint binary) public recordChainlinkFulfillment(_requestId) {
uint yes = binary;
emit Reload(user);
checked[user]=true;
if(yes>=128){
InData[7][user]=true;
yes-=128;
}
if(yes>=64){
InData[6][user]=true;
yes-=64;
}
if(yes>=32){
InData[5][user]=true;
yes-=32;
}
if(yes>=16){
InData[4][user]=true;
yes-=16;
}
if(yes>=8){
InData[3][user]=true;
yes-=8;
}
if(yes>=4){
InData[2][user]=true;
yes-=4;
}
if(yes>=2){
InData[1][user]=true;
yes-=2;
}
if(yes>=1){
InData[0][user]=true;
yes-=1;
}
require(yes==0,"Something went wrong here");
}
function inDatabase() public view returns(bool[8] memory) {
return [InData[0][msg.sender],
InData[1][msg.sender],
InData[2][msg.sender],
InData[3][msg.sender],
InData[4][msg.sender],
InData[5][msg.sender],
InData[6][msg.sender],
InData[7][msg.sender]];
}
function haveClaimed() public view returns(bool[8] memory) {
return [Claimed[0][msg.sender],
Claimed[1][msg.sender],
Claimed[2][msg.sender],
Claimed[3][msg.sender],
Claimed[4][msg.sender],
Claimed[5][msg.sender],
Claimed[6][msg.sender],
Claimed[7][msg.sender]];
}
function mintableWait(uint sac) public view minting_on returns(uint){
require(sac < totalSacs, "Not an accurate sacrifice");
require(InData[sac][msg.sender] == true, "You were not in the specific sacrifice or you need to check!");
require(Claimed[sac][msg.sender] == false, "You already minted your wait for this sacrifice!");
return (block.timestamp - sacTimes[sac]) / 3600;
}
function mintWait(uint sac) public minting_on {
require(sac < totalSacs, "Not an accurate sacrifice");
require(Claimed[sac][msg.sender] == false, "You already minted your wait for this sacrifice!");
require(InData[sac][msg.sender] == true, "You were not in this sacrifice or you haven't checked the database yet!");
Claimed[sac][msg.sender] = true;
mintedPeople[sac]++;
uint mintableWait1 = (block.timestamp - sacTimes[sac]) / 3600;
ClaimedAmount[sac][msg.sender] = mintableWait1;
totalWait[sac] += mintableWait1;
_mint(msg.sender, mintableWait1);
}
function mintableAllWait() public view minting_on returns (uint[] memory) {
uint[] memory testing = new uint[](8);
for(uint i; i < totalSacs; i++) {
if(!Claimed[i][msg.sender] && InData[i][msg.sender]) {
testing[i] = (block.timestamp - sacTimes[i]) / 3600;
}
}
return testing;
}
function hasChecked() public view returns(bool){
return checked[msg.sender];
}
function mintAllWait() public minting_on {
uint mintableWait1 = 0;
for(uint i; i < totalSacs; i++) {
if(!Claimed[i][msg.sender] && InData[i][msg.sender]) {
Claimed[i][msg.sender] = true;
mintedPeople[i]++;
ClaimedAmount[i][msg.sender] = (block.timestamp - sacTimes[i]) / 3600;
totalWait[i] += ClaimedAmount[i][msg.sender];
mintableWait1 += ClaimedAmount[i][msg.sender];
}
}
_mint(msg.sender, mintableWait1);
}
function midnightBonus() public manager_function minting_on {
minting = false;
uint waitAmount;
for(uint i; i < totalSacs; i++) {
unclaimedWait[i] = (totalPeople[i] - mintedPeople[i]) * ((block.timestamp - sacTimes[i]) / 3600) / 2;
waitAmount += unclaimedWait[i];
}
_mint(timeKeeper, waitAmount);
}
function mintableUnclaimedWait(uint sac) public view returns (uint waitAmount) {
require(sac<totalSacs, "not an accurate sacrifice");
require(!minting, "Minting is still on");
require(Claimed[sac][msg.sender], "You never claimed your wait or already claimed the unclaimed wait");
waitAmount = unclaimedWait[sac] * ClaimedAmount[sac][msg.sender] / totalWait[sac];
}
function mintUnclaimedWait(uint sac) public {
require(sac<totalSacs, "not an accurate sacrifice");
require(!minting, "Minting is still on");
require(Claimed[sac][msg.sender], "You never claimed your wait or already claimed the unclaimed wait");
Claimed[sac][msg.sender] = false;
uint waitAmount;
waitAmount = unclaimedWait[sac] * ClaimedAmount[sac][msg.sender] / totalWait[sac];
_mint(msg.sender, waitAmount);
}
function mintableAllUnclaimedWait() public view returns(uint waitAmount) {
require(!minting, "Minting is still on");
for(uint i; i < totalSacs; i++) {
if(Claimed[i][msg.sender]) {
waitAmount += unclaimedWait[i] * ClaimedAmount[i][msg.sender] / totalWait[i];
}
}
}
function mintAllUnclaimedWait() public {
require(!minting, "Minting is still on");
uint waitAmount = 0;
for(uint i; i < totalSacs; i++) {
if(Claimed[i][msg.sender]) {
Claimed[i][msg.sender] = false;
waitAmount += unclaimedWait[i] * ClaimedAmount[i][msg.sender] / totalWait[i];
}
}
_mint(msg.sender, waitAmount);
}
}
{
"compilationTarget": {
"contracts/Wait.sol": "Wait"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": false,
"runs": 200
},
"remappings": []
}
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"ChainlinkCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"ChainlinkFulfilled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"ChainlinkRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"OwnershipTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_user","type":"address"}],"name":"Reload","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"Claimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"ClaimedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"InData","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_address","type":"string"}],"name":"checkDatabase","outputs":[{"internalType":"bytes32","name":"requestId","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"checked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_requestId","type":"bytes32"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"binary","type":"uint256"}],"name":"fulfill","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"hasChecked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"haveClaimed","outputs":[{"internalType":"bool[8]","name":"","type":"bool[8]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"inDatabase","outputs":[{"internalType":"bool[8]","name":"","type":"bool[8]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"midnightBonus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintAllUnclaimedWait","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintAllWait","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"sac","type":"uint256"}],"name":"mintUnclaimedWait","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"sac","type":"uint256"}],"name":"mintWait","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintableAllUnclaimedWait","outputs":[{"internalType":"uint256","name":"waitAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintableAllWait","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"sac","type":"uint256"}],"name":"mintableUnclaimedWait","outputs":[{"internalType":"uint256","name":"waitAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"sac","type":"uint256"}],"name":"mintableWait","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"mintedPeople","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minting","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"sacTimes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"totalPeople","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSacs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"totalWait","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"unclaimedWait","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]