Contract Source Code:
// SPDX-License-Identifier: MIT
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;
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {OracleInterface} from "./OracleInterface.sol";
import {ChainlinkRequestInterface} from "./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;
}
// SPDX-License-Identifier: MIT
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 withdraw(address recipient, uint256 amount) external;
function withdrawable() external view returns (uint256);
}
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
import {IAuthorizedReceiver} from "./interfaces/IAuthorizedReceiver.sol";
// solhint-disable gas-custom-errors
abstract contract AuthorizedReceiver is IAuthorizedReceiver {
mapping(address sender => bool authorized) private s_authorizedSenders;
address[] private s_authorizedSenderList;
event AuthorizedSendersChanged(address[] senders, address changedBy);
// @notice Sets the fulfillment permission for a given node. Use `true` to allow, `false` to disallow.
// @param senders The addresses of the authorized Chainlink node
function setAuthorizedSenders(address[] calldata senders) external override validateAuthorizedSenderSetter {
require(senders.length > 0, "Must have at least 1 sender");
// Set previous authorized senders to false
uint256 authorizedSendersLength = s_authorizedSenderList.length;
for (uint256 i = 0; i < authorizedSendersLength; ++i) {
s_authorizedSenders[s_authorizedSenderList[i]] = false;
}
// Set new to true
for (uint256 i = 0; i < senders.length; ++i) {
require(s_authorizedSenders[senders[i]] == false, "Must not have duplicate senders");
s_authorizedSenders[senders[i]] = true;
}
// Replace list
s_authorizedSenderList = senders;
emit AuthorizedSendersChanged(senders, msg.sender);
}
// @notice Retrieve a list of authorized senders
// @return array of addresses
function getAuthorizedSenders() external view override returns (address[] memory) {
return s_authorizedSenderList;
}
// @notice Use this to check if a node is authorized for fulfilling requests
// @param sender The address of the Chainlink node
// @return The authorization status of the node
function isAuthorizedSender(address sender) public view override returns (bool) {
return s_authorizedSenders[sender];
}
// @notice customizable guard of who can update the authorized sender list
// @return bool whether sender can update authorized sender list
function _canSetAuthorizedSenders() internal virtual returns (bool);
// @notice validates the sender is an authorized sender
function _validateIsAuthorizedSender() internal view {
require(isAuthorizedSender(msg.sender), "Not authorized sender");
}
// @notice prevents non-authorized addresses from calling this method
modifier validateAuthorizedSender() {
_validateIsAuthorizedSender();
_;
}
// @notice prevents non-authorized addresses from calling this method
modifier validateAuthorizedSenderSetter() {
require(_canSetAuthorizedSenders(), "Cannot set authorized senders");
_;
}
}
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
// solhint-disable gas-custom-errors
abstract contract LinkTokenReceiver {
// @notice Called when LINK is sent to the contract via `transferAndCall`
// @dev The data payload's first 2 words will be overwritten by the `sender` and `amount`
// values to ensure correctness. Calls oracleRequest.
// @param sender Address of the sender
// @param amount Amount of LINK sent (specified in wei)
// @param data Payload of the transaction
function onTokenTransfer(
address sender,
uint256 amount,
bytes memory data
) public validateFromLINK permittedFunctionsForLINK(data) {
assembly {
// solhint-disable-next-line avoid-low-level-calls
mstore(add(data, 36), sender) // ensure correct sender is passed
// solhint-disable-next-line avoid-low-level-calls
mstore(add(data, 68), amount) // ensure correct amount is passed0.8.19
}
// solhint-disable-next-line avoid-low-level-calls
(bool success, ) = address(this).delegatecall(data); // calls oracleRequest
require(success, "Unable to create request");
}
function getChainlinkToken() public view virtual returns (address);
// @notice Validate the function called on token transfer
function _validateTokenTransferAction(bytes4 funcSelector, bytes memory data) internal virtual;
// @dev Reverts if not sent from the LINK token
modifier validateFromLINK() {
require(msg.sender == getChainlinkToken(), "Must use LINK token");
_;
}
// @dev Reverts if the given data does not begin with the `oracleRequest` function selector
// @param data The data payload of the request
modifier permittedFunctionsForLINK(bytes memory data) {
bytes4 funcSelector;
assembly {
// solhint-disable-next-line avoid-low-level-calls
funcSelector := mload(add(data, 32))
}
_validateTokenTransferAction(funcSelector, data);
_;
}
}
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
import {AuthorizedReceiver} from "./AuthorizedReceiver.sol";
import {LinkTokenReceiver} from "./LinkTokenReceiver.sol";
import {ConfirmedOwner} from "../shared/access/ConfirmedOwner.sol";
import {LinkTokenInterface} from "../shared/interfaces/LinkTokenInterface.sol";
import {IAuthorizedReceiver} from "./interfaces/IAuthorizedReceiver.sol";
import {OperatorInterface} from "../interfaces/OperatorInterface.sol";
import {IOwnable} from "../shared/interfaces/IOwnable.sol";
import {IWithdrawal} from "./interfaces/IWithdrawal.sol";
import {OracleInterface} from "../interfaces/OracleInterface.sol";
import {SafeCast} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/math/SafeCast.sol";
// @title The Chainlink Operator contract
// @notice Node operators can deploy this contract to fulfill requests sent to them
// solhint-disable gas-custom-errors
contract Operator is AuthorizedReceiver, ConfirmedOwner, LinkTokenReceiver, OperatorInterface, IWithdrawal {
struct Commitment {
bytes31 paramsHash;
uint8 dataVersion;
}
uint256 public constant EXPIRYTIME = 5 minutes;
uint256 private constant MAXIMUM_DATA_VERSION = 256;
uint256 private constant MINIMUM_CONSUMER_GAS_LIMIT = 400000;
uint256 private constant SELECTOR_LENGTH = 4;
uint256 private constant EXPECTED_REQUEST_WORDS = 2;
uint256 private constant MINIMUM_REQUEST_LENGTH = SELECTOR_LENGTH + (32 * EXPECTED_REQUEST_WORDS);
// We initialize fields to 1 instead of 0 so that the first invocation
// does not cost more gas.
uint256 private constant ONE_FOR_CONSISTENT_GAS_COST = 1;
// oracleRequest is intended for version 1, enabling single word responses
bytes4 private constant ORACLE_REQUEST_SELECTOR = this.oracleRequest.selector;
// operatorRequest is intended for version 2, enabling multi-word responses
bytes4 private constant OPERATOR_REQUEST_SELECTOR = this.operatorRequest.selector;
LinkTokenInterface internal immutable i_linkToken;
mapping(bytes32 => Commitment) private s_commitments;
mapping(address => bool) private s_owned;
// Tokens sent for requests that have not been fulfilled yet
uint256 private s_tokensInEscrow = ONE_FOR_CONSISTENT_GAS_COST;
event OracleRequest(
bytes32 indexed specId,
address requester,
bytes32 requestId,
uint256 payment,
address callbackAddr,
bytes4 callbackFunctionId,
uint256 cancelExpiration,
uint256 dataVersion,
bytes data
);
event CancelOracleRequest(bytes32 indexed requestId);
event OracleResponse(bytes32 indexed requestId);
event OwnableContractAccepted(address indexed acceptedContract);
event TargetsUpdatedAuthorizedSenders(address[] targets, address[] senders, address changedBy);
// @notice Deploy with the address of the LINK token
// @dev Sets the LinkToken address for the imported LinkTokenInterface
// @param link The address of the LINK token
// @param owner The address of the owner
constructor(address link, address owner) ConfirmedOwner(owner) {
i_linkToken = LinkTokenInterface(link); // external but already deployed and unalterable
}
string public constant typeAndVersion = "Operator 1.0.0";
// @notice Creates the Chainlink request. This is a backwards compatible API
// with the Oracle.sol contract, but the behavior changes because
// callbackAddress is assumed to be the same as the request sender.
// @param callbackAddress The consumer of the request
// @param payment The amount of payment given (specified in wei)
// @param specId The Job Specification ID
// @param callbackAddress The address the oracle data will be sent to
// @param callbackFunctionId The callback function ID for the response
// @param nonce The nonce sent by the requester
// @param dataVersion The specified data version
// @param data The extra request parameters
function oracleRequest(
address sender,
uint256 payment,
bytes32 specId,
address callbackAddress,
bytes4 callbackFunctionId,
uint256 nonce,
uint256 dataVersion,
bytes calldata data
) external override validateFromLINK {
(bytes32 requestId, uint256 expiration) = _verifyAndProcessOracleRequest(
sender,
payment,
callbackAddress,
callbackFunctionId,
nonce,
dataVersion
);
emit OracleRequest(specId, sender, requestId, payment, sender, callbackFunctionId, expiration, dataVersion, data);
}
// @notice Creates the Chainlink request
// @dev Stores the hash of the params as the on-chain commitment for the request.
// Emits OracleRequest event for the Chainlink node to detect.
// @param sender The sender of the request
// @param payment The amount of payment given (specified in wei)
// @param specId The Job Specification ID
// @param callbackFunctionId The callback function ID for the response
// @param nonce The nonce sent by the requester
// @param dataVersion The specified data version
// @param data The extra request parameters
function operatorRequest(
address sender,
uint256 payment,
bytes32 specId,
bytes4 callbackFunctionId,
uint256 nonce,
uint256 dataVersion,
bytes calldata data
) external override validateFromLINK {
(bytes32 requestId, uint256 expiration) = _verifyAndProcessOracleRequest(
sender,
payment,
sender,
callbackFunctionId,
nonce,
dataVersion
);
emit OracleRequest(specId, sender, requestId, payment, sender, callbackFunctionId, expiration, dataVersion, data);
}
// @notice Called by the Chainlink node to fulfill requests
// @dev Given params must hash back to the commitment stored from `oracleRequest`.
// Will call the callback address' callback function without bubbling up error
// checking in a `require` so that the node can get paid.
// @param requestId The fulfillment request ID that must match the requester's
// @param payment The payment amount that will be released for the oracle (specified in wei)
// @param callbackAddress The callback address to call for fulfillment
// @param callbackFunctionId The callback function ID to use for fulfillment
// @param expiration The expiration that the node should respond by before the requester can cancel
// @param data The data to return to the consuming contract
// @return Status if the external call was successful
function fulfillOracleRequest(
bytes32 requestId,
uint256 payment,
address callbackAddress,
bytes4 callbackFunctionId,
uint256 expiration,
bytes32 data
)
external
override
validateAuthorizedSender
validateRequestId(requestId)
validateCallbackAddress(callbackAddress)
returns (bool)
{
_verifyOracleRequestAndProcessPayment(requestId, payment, callbackAddress, callbackFunctionId, expiration, 1);
emit OracleResponse(requestId);
require(gasleft() >= MINIMUM_CONSUMER_GAS_LIMIT, "Must provide consumer enough gas");
// All updates to the oracle's fulfillment should come before calling the
// callback(addr+functionId) as it is untrusted.
// See: https://solidity.readthedocs.io/en/develop/security-considerations.html#use-the-checks-effects-interactions-pattern
(bool success, ) = callbackAddress.call(abi.encodeWithSelector(callbackFunctionId, requestId, data)); // solhint-disable-line avoid-low-level-calls
return success;
}
// @notice Called by the Chainlink node to fulfill requests with multi-word support
// @dev Given params must hash back to the commitment stored from `oracleRequest`.
// Will call the callback address' callback function without bubbling up error
// checking in a `require` so that the node can get paid.
// @param requestId The fulfillment request ID that must match the requester's
// @param payment The payment amount that will be released for the oracle (specified in wei)
// @param callbackAddress The callback address to call for fulfillment
// @param callbackFunctionId The callback function ID to use for fulfillment
// @param expiration The expiration that the node should respond by before the requester can cancel
// @param data The data to return to the consuming contract
// @return Status if the external call was successful
function fulfillOracleRequest2(
bytes32 requestId,
uint256 payment,
address callbackAddress,
bytes4 callbackFunctionId,
uint256 expiration,
bytes calldata data
)
external
override
validateAuthorizedSender
validateRequestId(requestId)
validateCallbackAddress(callbackAddress)
validateMultiWordResponseId(requestId, data)
returns (bool)
{
_verifyOracleRequestAndProcessPayment(requestId, payment, callbackAddress, callbackFunctionId, expiration, 2);
emit OracleResponse(requestId);
require(gasleft() >= MINIMUM_CONSUMER_GAS_LIMIT, "Must provide consumer enough gas");
// All updates to the oracle's fulfillment should come before calling the
// callback(addr+functionId) as it is untrusted.
// See: https://solidity.readthedocs.io/en/develop/security-considerations.html#use-the-checks-effects-interactions-pattern
(bool success, ) = callbackAddress.call(abi.encodePacked(callbackFunctionId, data)); // solhint-disable-line avoid-low-level-calls
return success;
}
// @notice Transfer the ownership of ownable contracts. This is primarily
// intended for Authorized Forwarders but could possibly be extended to work
// with future contracts.OracleInterface
// @param ownable list of addresses to transfer
// @param newOwner address to transfer ownership to
function transferOwnableContracts(address[] calldata ownable, address newOwner) external onlyOwner {
for (uint256 i = 0; i < ownable.length; ++i) {
s_owned[ownable[i]] = false;
IOwnable(ownable[i]).transferOwnership(newOwner);
}
}
// @notice Accept the ownership of an ownable contract. This is primarily
// intended for Authorized Forwarders but could possibly be extended to work
// with future contracts.
// @dev Must be the pending owner on the contract
// @param ownable list of addresses of Ownable contracts to accept
function acceptOwnableContracts(address[] calldata ownable) public validateAuthorizedSenderSetter {
for (uint256 i = 0; i < ownable.length; ++i) {
s_owned[ownable[i]] = true;
emit OwnableContractAccepted(ownable[i]);
IOwnable(ownable[i]).acceptOwnership();
}
}
// @notice Sets the fulfillment permission for
// @param targets The addresses to set permissions on
// @param senders The addresses that are allowed to send updates
function setAuthorizedSendersOn(
address[] calldata targets,
address[] calldata senders
) public validateAuthorizedSenderSetter {
emit TargetsUpdatedAuthorizedSenders(targets, senders, msg.sender);
for (uint256 i = 0; i < targets.length; ++i) {
IAuthorizedReceiver(targets[i]).setAuthorizedSenders(senders);
}
}
// @notice Accepts ownership of ownable contracts and then immediately sets
// the authorized sender list on each of the newly owned contracts. This is
// primarily intended for Authorized Forwarders but could possibly be
// extended to work with future contracts.
// @param targets The addresses to set permissions on
// @param senders The addresses that are allowed to send updates
function acceptAuthorizedReceivers(
address[] calldata targets,
address[] calldata senders
) external validateAuthorizedSenderSetter {
acceptOwnableContracts(targets);
setAuthorizedSendersOn(targets, senders);
}
// @notice Allows the node operator to withdraw earned LINK to a given address
// @dev The owner of the contract can be another wallet and does not have to be a Chainlink node
// @param recipient The address to send the LINK token to
// @param amount The amount to send (specified in wei)
function withdraw(
address recipient,
uint256 amount
) external override(OracleInterface, IWithdrawal) onlyOwner validateAvailableFunds(amount) {
assert(i_linkToken.transfer(recipient, amount));
}
// @notice Displays the amount of LINK that is available for the node operator to withdraw
// @dev We use `ONE_FOR_CONSISTENT_GAS_COST` in place of 0 in storage
// @return The amount of withdrawable LINK on the contract
function withdrawable() external view override(OracleInterface, IWithdrawal) returns (uint256) {
return _fundsAvailable();
}
// @notice Forward a call to another contract
// @dev Only callable by the owner
// @param to address
// @param data to forward
function ownerForward(address to, bytes calldata data) external onlyOwner validateNotToLINK(to) {
require(to.code.length != 0, "Must forward to a contract");
// solhint-disable-next-line avoid-low-level-calls
(bool status, ) = to.call(data);
require(status, "Forwarded call failed");
}
// @notice Interact with other LinkTokenReceiver contracts by calling transferAndCall
// @param to The address to transfer to.
// @param value The amount to be transferred.
// @param data The extra data to be passed to the receiving contract.
// @return success bool
function ownerTransferAndCall(
address to,
uint256 value,
bytes calldata data
) external override onlyOwner validateAvailableFunds(value) returns (bool success) {
return i_linkToken.transferAndCall(to, value, data);
}
// @notice Distribute funds to multiple addresses using ETH send
// to this payable function.
// @dev Array length must be equal, ETH sent must equal the sum of amounts.
// A malicious receiver could cause the distribution to revert, in which case
// it is expected that the address is removed from the list.
// @param receivers list of addresses
// @param amounts list of amounts
function distributeFunds(address payable[] calldata receivers, uint256[] calldata amounts) external payable {
require(receivers.length > 0 && receivers.length == amounts.length, "Invalid array length(s)");
uint256 valueRemaining = msg.value;
for (uint256 i = 0; i < receivers.length; ++i) {
uint256 sendAmount = amounts[i];
valueRemaining = valueRemaining - sendAmount;
(bool success, ) = receivers[i].call{value: sendAmount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
require(valueRemaining == 0, "Too much ETH sent");
}
// @notice Allows recipient to cancel requests sent to this oracle contract.
// Will transfer the LINK sent for the request back to the recipient address.
// @dev Given params must hash to a commitment stored on the contract in order
// for the request to be valid. Emits CancelOracleRequest event.
// @param requestId The request ID
// @param payment The amount of payment given (specified in wei)
// @param callbackFunc The requester's specified callback function selector
// @param expiration The time of the expiration for the request
function cancelOracleRequest(
bytes32 requestId,
uint256 payment,
bytes4 callbackFunc,
uint256 expiration
) public override {
bytes31 paramsHash = _buildParamsHash(payment, msg.sender, callbackFunc, expiration);
require(s_commitments[requestId].paramsHash == paramsHash, "Params do not match request ID");
// solhint-disable-next-line not-rely-on-time
require(expiration <= block.timestamp, "Request is not expired");
delete s_commitments[requestId];
emit CancelOracleRequest(requestId);
// Free up the escrowed funds, as we're sending them back to the requester
s_tokensInEscrow -= payment;
i_linkToken.transfer(msg.sender, payment);
}
// @notice Allows requester to cancel requests sent to this oracle contract.
// Will transfer the LINK sent for the request back to the recipient address.
// @dev Given params must hash to a commitment stored on the contract in order
// for the request to be valid. Emits CancelOracleRequest event.
// @param nonce The nonce used to generate the request ID
// @param payment The amount of payment given (specified in wei)
// @param callbackFunc The requester's specified callback function selector
// @param expiration The time of the expiration for the request
function cancelOracleRequestByRequester(
uint256 nonce,
uint256 payment,
bytes4 callbackFunc,
uint256 expiration
) external {
cancelOracleRequest(keccak256(abi.encodePacked(msg.sender, nonce)), payment, callbackFunc, expiration);
}
// @notice Returns the address of the LINK token
// @dev This is the public implementation for chainlinkTokenAddress, which is
// an internal method of the ChainlinkClient contract
function getChainlinkToken() public view override returns (address) {
return address(i_linkToken);
}
// @notice Require that the token transfer action is valid
// @dev OPERATOR_REQUEST_SELECTOR = multiword, ORACLE_REQUEST_SELECTOR = singleword
function _validateTokenTransferAction(bytes4 funcSelector, bytes memory data) internal pure override {
require(data.length >= MINIMUM_REQUEST_LENGTH, "Invalid request length");
require(
funcSelector == OPERATOR_REQUEST_SELECTOR || funcSelector == ORACLE_REQUEST_SELECTOR,
"Must use whitelisted functions"
);
}
// @notice Verify the Oracle Request and record necessary information
// @param sender The sender of the request
// @param payment The amount of payment given (specified in wei)
// @param callbackAddress The callback address for the response
// @param callbackFunctionId The callback function ID for the response
// @param nonce The nonce sent by the requester
function _verifyAndProcessOracleRequest(
address sender,
uint256 payment,
address callbackAddress,
bytes4 callbackFunctionId,
uint256 nonce,
uint256 dataVersion
) private validateNotToLINK(callbackAddress) returns (bytes32 requestId, uint256 expiration) {
requestId = keccak256(abi.encodePacked(sender, nonce));
require(s_commitments[requestId].paramsHash == 0, "Must use a unique ID");
// solhint-disable-next-line not-rely-on-time
expiration = block.timestamp + EXPIRYTIME;
bytes31 paramsHash = _buildParamsHash(payment, callbackAddress, callbackFunctionId, expiration);
s_commitments[requestId] = Commitment(paramsHash, SafeCast.toUint8(dataVersion));
s_tokensInEscrow = s_tokensInEscrow + payment;
return (requestId, expiration);
}
// @notice Verify the Oracle request and unlock escrowed payment
// @param requestId The fulfillment request ID that must match the requester's
// @param payment The payment amount that will be released for the oracle (specified in wei)
// @param callbackAddress The callback address to call for fulfillment
// @param callbackFunctionId The callback function ID to use for fulfillment
// @param expiration The expiration that the node should respond by before the requester can cancel
function _verifyOracleRequestAndProcessPayment(
bytes32 requestId,
uint256 payment,
address callbackAddress,
bytes4 callbackFunctionId,
uint256 expiration,
uint256 dataVersion
) internal {
bytes31 paramsHash = _buildParamsHash(payment, callbackAddress, callbackFunctionId, expiration);
require(s_commitments[requestId].paramsHash == paramsHash, "Params do not match request ID");
require(s_commitments[requestId].dataVersion <= SafeCast.toUint8(dataVersion), "Data versions must match");
s_tokensInEscrow = s_tokensInEscrow - payment;
delete s_commitments[requestId];
}
// @notice Build the bytes31 hash from the payment, callback and expiration.
// @param payment The payment amount that will be released for the oracle (specified in wei)
// @param callbackAddress The callback address to call for fulfillment
// @param callbackFunctionId The callback function ID to use for fulfillment
// @param expiration The expiration that the node should respond by before the requester can cancel
// @return hash bytes31
function _buildParamsHash(
uint256 payment,
address callbackAddress,
bytes4 callbackFunctionId,
uint256 expiration
) internal pure returns (bytes31) {
return bytes31(keccak256(abi.encodePacked(payment, callbackAddress, callbackFunctionId, expiration)));
}
// @notice Returns the LINK available in this contract, not locked in escrow
// @return uint256 LINK tokens available
function _fundsAvailable() private view returns (uint256) {
return i_linkToken.balanceOf(address(this)) - (s_tokensInEscrow - ONE_FOR_CONSISTENT_GAS_COST);
}
// @notice concrete implementation of AuthorizedReceiver
// @return bool of whether sender is authorized
function _canSetAuthorizedSenders() internal view override returns (bool) {
return isAuthorizedSender(msg.sender) || owner() == msg.sender;
}
// MODIFIERS
// @dev Reverts if the first 32 bytes of the bytes array is not equal to requestId
// @param requestId bytes32
// @param data bytes
modifier validateMultiWordResponseId(bytes32 requestId, bytes calldata data) {
require(data.length >= 32, "Response must be > 32 bytes");
bytes32 firstDataWord;
assembly {
firstDataWord := calldataload(data.offset)
}
require(requestId == firstDataWord, "First word must be requestId");
_;
}
// @dev Reverts if amount requested is greater than withdrawable balance
// @param amount The given amount to compare to `s_withdrawableTokens`
modifier validateAvailableFunds(uint256 amount) {
require(_fundsAvailable() >= amount, "Amount requested is greater than withdrawable balance");
_;
}
// @dev Reverts if request ID does not exist
// @param requestId The given request ID to check in stored `commitments`
modifier validateRequestId(bytes32 requestId) {
require(s_commitments[requestId].paramsHash != 0, "Must have a valid requestId");
_;
}
// @dev Reverts if the callback address is the LINK token
// @param to The callback address
modifier validateNotToLINK(address to) {
require(to != address(i_linkToken), "Cannot call to LINK");
_;
}
// @dev Reverts if the target address is owned by the operator
modifier validateCallbackAddress(address callbackAddress) {
require(!s_owned[callbackAddress], "Cannot call owned contract");
_;
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IAuthorizedReceiver {
function isAuthorizedSender(address sender) external view returns (bool);
function getAuthorizedSenders() external returns (address[] memory);
function setAuthorizedSenders(address[] calldata senders) external;
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IWithdrawal {
// @notice transfer LINK held by the contract belonging to msg.sender to
// another address
// @param recipient is the address to send the LINK to
// @param amount is the amount of LINK to send
function withdraw(address recipient, uint256 amount) external;
// @notice query the available amount of LINK to withdraw by msg.sender
function withdrawable() external view returns (uint256);
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {ConfirmedOwnerWithProposal} from "./ConfirmedOwnerWithProposal.sol";
/// @title The ConfirmedOwner contract
/// @notice A contract with helpers for basic contract ownership.
contract ConfirmedOwner is ConfirmedOwnerWithProposal {
constructor(address newOwner) ConfirmedOwnerWithProposal(newOwner, address(0)) {}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IOwnable} from "../interfaces/IOwnable.sol";
/// @title The ConfirmedOwner contract
/// @notice A contract with helpers for basic contract ownership.
contract ConfirmedOwnerWithProposal is IOwnable {
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) {
// solhint-disable-next-line gas-custom-errors
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.
function transferOwnership(address to) public override onlyOwner {
_transferOwnership(to);
}
/// @notice Allows an ownership transfer to be completed by the recipient.
function acceptOwnership() external override {
// solhint-disable-next-line gas-custom-errors
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
function owner() public view override returns (address) {
return s_owner;
}
/// @notice validate, transfer ownership, and emit relevant events
function _transferOwnership(address to) private {
// solhint-disable-next-line gas-custom-errors
require(to != msg.sender, "Cannot transfer to self");
s_pendingOwner = to;
emit OwnershipTransferRequested(s_owner, to);
}
/// @notice validate access
function _validateOwnership() internal view {
// solhint-disable-next-line gas-custom-errors
require(msg.sender == s_owner, "Only callable by owner");
}
/// @notice Reverts if called by anyone other than the contract owner.
modifier onlyOwner() {
_validateOwnership();
_;
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IOwnable {
function owner() external returns (address);
function transferOwnership(address recipient) external;
function acceptOwnership() external;
}
// SPDX-License-Identifier: MIT
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);
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)
// This file was procedurally generated from scripts/generate/templates/SafeCast.js.
pragma solidity ^0.8.0;
/**
* @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
* checks.
*
* Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
* easily result in undesired exploitation or bugs, since developers usually
* assume that overflows raise errors. `SafeCast` restores this intuition by
* reverting the transaction when such an operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*
* Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
* all math on `uint256` and `int256` and then downcasting.
*/
library SafeCast {
/**
* @dev Returns the downcasted uint248 from uint256, reverting on
* overflow (when the input is greater than largest uint248).
*
* Counterpart to Solidity's `uint248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*
* _Available since v4.7._
*/
function toUint248(uint256 value) internal pure returns (uint248) {
require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits");
return uint248(value);
}
/**
* @dev Returns the downcasted uint240 from uint256, reverting on
* overflow (when the input is greater than largest uint240).
*
* Counterpart to Solidity's `uint240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*
* _Available since v4.7._
*/
function toUint240(uint256 value) internal pure returns (uint240) {
require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits");
return uint240(value);
}
/**
* @dev Returns the downcasted uint232 from uint256, reverting on
* overflow (when the input is greater than largest uint232).
*
* Counterpart to Solidity's `uint232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*
* _Available since v4.7._
*/
function toUint232(uint256 value) internal pure returns (uint232) {
require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits");
return uint232(value);
}
/**
* @dev Returns the downcasted uint224 from uint256, reverting on
* overflow (when the input is greater than largest uint224).
*
* Counterpart to Solidity's `uint224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*
* _Available since v4.2._
*/
function toUint224(uint256 value) internal pure returns (uint224) {
require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits");
return uint224(value);
}
/**
* @dev Returns the downcasted uint216 from uint256, reverting on
* overflow (when the input is greater than largest uint216).
*
* Counterpart to Solidity's `uint216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*
* _Available since v4.7._
*/
function toUint216(uint256 value) internal pure returns (uint216) {
require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits");
return uint216(value);
}
/**
* @dev Returns the downcasted uint208 from uint256, reverting on
* overflow (when the input is greater than largest uint208).
*
* Counterpart to Solidity's `uint208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*
* _Available since v4.7._
*/
function toUint208(uint256 value) internal pure returns (uint208) {
require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits");
return uint208(value);
}
/**
* @dev Returns the downcasted uint200 from uint256, reverting on
* overflow (when the input is greater than largest uint200).
*
* Counterpart to Solidity's `uint200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*
* _Available since v4.7._
*/
function toUint200(uint256 value) internal pure returns (uint200) {
require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits");
return uint200(value);
}
/**
* @dev Returns the downcasted uint192 from uint256, reverting on
* overflow (when the input is greater than largest uint192).
*
* Counterpart to Solidity's `uint192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*
* _Available since v4.7._
*/
function toUint192(uint256 value) internal pure returns (uint192) {
require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits");
return uint192(value);
}
/**
* @dev Returns the downcasted uint184 from uint256, reverting on
* overflow (when the input is greater than largest uint184).
*
* Counterpart to Solidity's `uint184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*
* _Available since v4.7._
*/
function toUint184(uint256 value) internal pure returns (uint184) {
require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits");
return uint184(value);
}
/**
* @dev Returns the downcasted uint176 from uint256, reverting on
* overflow (when the input is greater than largest uint176).
*
* Counterpart to Solidity's `uint176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*
* _Available since v4.7._
*/
function toUint176(uint256 value) internal pure returns (uint176) {
require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits");
return uint176(value);
}
/**
* @dev Returns the downcasted uint168 from uint256, reverting on
* overflow (when the input is greater than largest uint168).
*
* Counterpart to Solidity's `uint168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*
* _Available since v4.7._
*/
function toUint168(uint256 value) internal pure returns (uint168) {
require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits");
return uint168(value);
}
/**
* @dev Returns the downcasted uint160 from uint256, reverting on
* overflow (when the input is greater than largest uint160).
*
* Counterpart to Solidity's `uint160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*
* _Available since v4.7._
*/
function toUint160(uint256 value) internal pure returns (uint160) {
require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits");
return uint160(value);
}
/**
* @dev Returns the downcasted uint152 from uint256, reverting on
* overflow (when the input is greater than largest uint152).
*
* Counterpart to Solidity's `uint152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*
* _Available since v4.7._
*/
function toUint152(uint256 value) internal pure returns (uint152) {
require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits");
return uint152(value);
}
/**
* @dev Returns the downcasted uint144 from uint256, reverting on
* overflow (when the input is greater than largest uint144).
*
* Counterpart to Solidity's `uint144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*
* _Available since v4.7._
*/
function toUint144(uint256 value) internal pure returns (uint144) {
require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits");
return uint144(value);
}
/**
* @dev Returns the downcasted uint136 from uint256, reverting on
* overflow (when the input is greater than largest uint136).
*
* Counterpart to Solidity's `uint136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*
* _Available since v4.7._
*/
function toUint136(uint256 value) internal pure returns (uint136) {
require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits");
return uint136(value);
}
/**
* @dev Returns the downcasted uint128 from uint256, reverting on
* overflow (when the input is greater than largest uint128).
*
* Counterpart to Solidity's `uint128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*
* _Available since v2.5._
*/
function toUint128(uint256 value) internal pure returns (uint128) {
require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits");
return uint128(value);
}
/**
* @dev Returns the downcasted uint120 from uint256, reverting on
* overflow (when the input is greater than largest uint120).
*
* Counterpart to Solidity's `uint120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*
* _Available since v4.7._
*/
function toUint120(uint256 value) internal pure returns (uint120) {
require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits");
return uint120(value);
}
/**
* @dev Returns the downcasted uint112 from uint256, reverting on
* overflow (when the input is greater than largest uint112).
*
* Counterpart to Solidity's `uint112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*
* _Available since v4.7._
*/
function toUint112(uint256 value) internal pure returns (uint112) {
require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits");
return uint112(value);
}
/**
* @dev Returns the downcasted uint104 from uint256, reverting on
* overflow (when the input is greater than largest uint104).
*
* Counterpart to Solidity's `uint104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*
* _Available since v4.7._
*/
function toUint104(uint256 value) internal pure returns (uint104) {
require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits");
return uint104(value);
}
/**
* @dev Returns the downcasted uint96 from uint256, reverting on
* overflow (when the input is greater than largest uint96).
*
* Counterpart to Solidity's `uint96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*
* _Available since v4.2._
*/
function toUint96(uint256 value) internal pure returns (uint96) {
require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits");
return uint96(value);
}
/**
* @dev Returns the downcasted uint88 from uint256, reverting on
* overflow (when the input is greater than largest uint88).
*
* Counterpart to Solidity's `uint88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*
* _Available since v4.7._
*/
function toUint88(uint256 value) internal pure returns (uint88) {
require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits");
return uint88(value);
}
/**
* @dev Returns the downcasted uint80 from uint256, reverting on
* overflow (when the input is greater than largest uint80).
*
* Counterpart to Solidity's `uint80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*
* _Available since v4.7._
*/
function toUint80(uint256 value) internal pure returns (uint80) {
require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits");
return uint80(value);
}
/**
* @dev Returns the downcasted uint72 from uint256, reverting on
* overflow (when the input is greater than largest uint72).
*
* Counterpart to Solidity's `uint72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*
* _Available since v4.7._
*/
function toUint72(uint256 value) internal pure returns (uint72) {
require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits");
return uint72(value);
}
/**
* @dev Returns the downcasted uint64 from uint256, reverting on
* overflow (when the input is greater than largest uint64).
*
* Counterpart to Solidity's `uint64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*
* _Available since v2.5._
*/
function toUint64(uint256 value) internal pure returns (uint64) {
require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits");
return uint64(value);
}
/**
* @dev Returns the downcasted uint56 from uint256, reverting on
* overflow (when the input is greater than largest uint56).
*
* Counterpart to Solidity's `uint56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*
* _Available since v4.7._
*/
function toUint56(uint256 value) internal pure returns (uint56) {
require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits");
return uint56(value);
}
/**
* @dev Returns the downcasted uint48 from uint256, reverting on
* overflow (when the input is greater than largest uint48).
*
* Counterpart to Solidity's `uint48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*
* _Available since v4.7._
*/
function toUint48(uint256 value) internal pure returns (uint48) {
require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits");
return uint48(value);
}
/**
* @dev Returns the downcasted uint40 from uint256, reverting on
* overflow (when the input is greater than largest uint40).
*
* Counterpart to Solidity's `uint40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*
* _Available since v4.7._
*/
function toUint40(uint256 value) internal pure returns (uint40) {
require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits");
return uint40(value);
}
/**
* @dev Returns the downcasted uint32 from uint256, reverting on
* overflow (when the input is greater than largest uint32).
*
* Counterpart to Solidity's `uint32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*
* _Available since v2.5._
*/
function toUint32(uint256 value) internal pure returns (uint32) {
require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits");
return uint32(value);
}
/**
* @dev Returns the downcasted uint24 from uint256, reverting on
* overflow (when the input is greater than largest uint24).
*
* Counterpart to Solidity's `uint24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*
* _Available since v4.7._
*/
function toUint24(uint256 value) internal pure returns (uint24) {
require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits");
return uint24(value);
}
/**
* @dev Returns the downcasted uint16 from uint256, reverting on
* overflow (when the input is greater than largest uint16).
*
* Counterpart to Solidity's `uint16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*
* _Available since v2.5._
*/
function toUint16(uint256 value) internal pure returns (uint16) {
require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits");
return uint16(value);
}
/**
* @dev Returns the downcasted uint8 from uint256, reverting on
* overflow (when the input is greater than largest uint8).
*
* Counterpart to Solidity's `uint8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*
* _Available since v2.5._
*/
function toUint8(uint256 value) internal pure returns (uint8) {
require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits");
return uint8(value);
}
/**
* @dev Converts a signed int256 into an unsigned uint256.
*
* Requirements:
*
* - input must be greater than or equal to 0.
*
* _Available since v3.0._
*/
function toUint256(int256 value) internal pure returns (uint256) {
require(value >= 0, "SafeCast: value must be positive");
return uint256(value);
}
/**
* @dev Returns the downcasted int248 from int256, reverting on
* overflow (when the input is less than smallest int248 or
* greater than largest int248).
*
* Counterpart to Solidity's `int248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*
* _Available since v4.7._
*/
function toInt248(int256 value) internal pure returns (int248 downcasted) {
downcasted = int248(value);
require(downcasted == value, "SafeCast: value doesn't fit in 248 bits");
}
/**
* @dev Returns the downcasted int240 from int256, reverting on
* overflow (when the input is less than smallest int240 or
* greater than largest int240).
*
* Counterpart to Solidity's `int240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*
* _Available since v4.7._
*/
function toInt240(int256 value) internal pure returns (int240 downcasted) {
downcasted = int240(value);
require(downcasted == value, "SafeCast: value doesn't fit in 240 bits");
}
/**
* @dev Returns the downcasted int232 from int256, reverting on
* overflow (when the input is less than smallest int232 or
* greater than largest int232).
*
* Counterpart to Solidity's `int232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*
* _Available since v4.7._
*/
function toInt232(int256 value) internal pure returns (int232 downcasted) {
downcasted = int232(value);
require(downcasted == value, "SafeCast: value doesn't fit in 232 bits");
}
/**
* @dev Returns the downcasted int224 from int256, reverting on
* overflow (when the input is less than smallest int224 or
* greater than largest int224).
*
* Counterpart to Solidity's `int224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*
* _Available since v4.7._
*/
function toInt224(int256 value) internal pure returns (int224 downcasted) {
downcasted = int224(value);
require(downcasted == value, "SafeCast: value doesn't fit in 224 bits");
}
/**
* @dev Returns the downcasted int216 from int256, reverting on
* overflow (when the input is less than smallest int216 or
* greater than largest int216).
*
* Counterpart to Solidity's `int216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*
* _Available since v4.7._
*/
function toInt216(int256 value) internal pure returns (int216 downcasted) {
downcasted = int216(value);
require(downcasted == value, "SafeCast: value doesn't fit in 216 bits");
}
/**
* @dev Returns the downcasted int208 from int256, reverting on
* overflow (when the input is less than smallest int208 or
* greater than largest int208).
*
* Counterpart to Solidity's `int208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*
* _Available since v4.7._
*/
function toInt208(int256 value) internal pure returns (int208 downcasted) {
downcasted = int208(value);
require(downcasted == value, "SafeCast: value doesn't fit in 208 bits");
}
/**
* @dev Returns the downcasted int200 from int256, reverting on
* overflow (when the input is less than smallest int200 or
* greater than largest int200).
*
* Counterpart to Solidity's `int200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*
* _Available since v4.7._
*/
function toInt200(int256 value) internal pure returns (int200 downcasted) {
downcasted = int200(value);
require(downcasted == value, "SafeCast: value doesn't fit in 200 bits");
}
/**
* @dev Returns the downcasted int192 from int256, reverting on
* overflow (when the input is less than smallest int192 or
* greater than largest int192).
*
* Counterpart to Solidity's `int192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*
* _Available since v4.7._
*/
function toInt192(int256 value) internal pure returns (int192 downcasted) {
downcasted = int192(value);
require(downcasted == value, "SafeCast: value doesn't fit in 192 bits");
}
/**
* @dev Returns the downcasted int184 from int256, reverting on
* overflow (when the input is less than smallest int184 or
* greater than largest int184).
*
* Counterpart to Solidity's `int184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*
* _Available since v4.7._
*/
function toInt184(int256 value) internal pure returns (int184 downcasted) {
downcasted = int184(value);
require(downcasted == value, "SafeCast: value doesn't fit in 184 bits");
}
/**
* @dev Returns the downcasted int176 from int256, reverting on
* overflow (when the input is less than smallest int176 or
* greater than largest int176).
*
* Counterpart to Solidity's `int176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*
* _Available since v4.7._
*/
function toInt176(int256 value) internal pure returns (int176 downcasted) {
downcasted = int176(value);
require(downcasted == value, "SafeCast: value doesn't fit in 176 bits");
}
/**
* @dev Returns the downcasted int168 from int256, reverting on
* overflow (when the input is less than smallest int168 or
* greater than largest int168).
*
* Counterpart to Solidity's `int168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*
* _Available since v4.7._
*/
function toInt168(int256 value) internal pure returns (int168 downcasted) {
downcasted = int168(value);
require(downcasted == value, "SafeCast: value doesn't fit in 168 bits");
}
/**
* @dev Returns the downcasted int160 from int256, reverting on
* overflow (when the input is less than smallest int160 or
* greater than largest int160).
*
* Counterpart to Solidity's `int160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*
* _Available since v4.7._
*/
function toInt160(int256 value) internal pure returns (int160 downcasted) {
downcasted = int160(value);
require(downcasted == value, "SafeCast: value doesn't fit in 160 bits");
}
/**
* @dev Returns the downcasted int152 from int256, reverting on
* overflow (when the input is less than smallest int152 or
* greater than largest int152).
*
* Counterpart to Solidity's `int152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*
* _Available since v4.7._
*/
function toInt152(int256 value) internal pure returns (int152 downcasted) {
downcasted = int152(value);
require(downcasted == value, "SafeCast: value doesn't fit in 152 bits");
}
/**
* @dev Returns the downcasted int144 from int256, reverting on
* overflow (when the input is less than smallest int144 or
* greater than largest int144).
*
* Counterpart to Solidity's `int144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*
* _Available since v4.7._
*/
function toInt144(int256 value) internal pure returns (int144 downcasted) {
downcasted = int144(value);
require(downcasted == value, "SafeCast: value doesn't fit in 144 bits");
}
/**
* @dev Returns the downcasted int136 from int256, reverting on
* overflow (when the input is less than smallest int136 or
* greater than largest int136).
*
* Counterpart to Solidity's `int136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*
* _Available since v4.7._
*/
function toInt136(int256 value) internal pure returns (int136 downcasted) {
downcasted = int136(value);
require(downcasted == value, "SafeCast: value doesn't fit in 136 bits");
}
/**
* @dev Returns the downcasted int128 from int256, reverting on
* overflow (when the input is less than smallest int128 or
* greater than largest int128).
*
* Counterpart to Solidity's `int128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*
* _Available since v3.1._
*/
function toInt128(int256 value) internal pure returns (int128 downcasted) {
downcasted = int128(value);
require(downcasted == value, "SafeCast: value doesn't fit in 128 bits");
}
/**
* @dev Returns the downcasted int120 from int256, reverting on
* overflow (when the input is less than smallest int120 or
* greater than largest int120).
*
* Counterpart to Solidity's `int120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*
* _Available since v4.7._
*/
function toInt120(int256 value) internal pure returns (int120 downcasted) {
downcasted = int120(value);
require(downcasted == value, "SafeCast: value doesn't fit in 120 bits");
}
/**
* @dev Returns the downcasted int112 from int256, reverting on
* overflow (when the input is less than smallest int112 or
* greater than largest int112).
*
* Counterpart to Solidity's `int112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*
* _Available since v4.7._
*/
function toInt112(int256 value) internal pure returns (int112 downcasted) {
downcasted = int112(value);
require(downcasted == value, "SafeCast: value doesn't fit in 112 bits");
}
/**
* @dev Returns the downcasted int104 from int256, reverting on
* overflow (when the input is less than smallest int104 or
* greater than largest int104).
*
* Counterpart to Solidity's `int104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*
* _Available since v4.7._
*/
function toInt104(int256 value) internal pure returns (int104 downcasted) {
downcasted = int104(value);
require(downcasted == value, "SafeCast: value doesn't fit in 104 bits");
}
/**
* @dev Returns the downcasted int96 from int256, reverting on
* overflow (when the input is less than smallest int96 or
* greater than largest int96).
*
* Counterpart to Solidity's `int96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*
* _Available since v4.7._
*/
function toInt96(int256 value) internal pure returns (int96 downcasted) {
downcasted = int96(value);
require(downcasted == value, "SafeCast: value doesn't fit in 96 bits");
}
/**
* @dev Returns the downcasted int88 from int256, reverting on
* overflow (when the input is less than smallest int88 or
* greater than largest int88).
*
* Counterpart to Solidity's `int88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*
* _Available since v4.7._
*/
function toInt88(int256 value) internal pure returns (int88 downcasted) {
downcasted = int88(value);
require(downcasted == value, "SafeCast: value doesn't fit in 88 bits");
}
/**
* @dev Returns the downcasted int80 from int256, reverting on
* overflow (when the input is less than smallest int80 or
* greater than largest int80).
*
* Counterpart to Solidity's `int80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*
* _Available since v4.7._
*/
function toInt80(int256 value) internal pure returns (int80 downcasted) {
downcasted = int80(value);
require(downcasted == value, "SafeCast: value doesn't fit in 80 bits");
}
/**
* @dev Returns the downcasted int72 from int256, reverting on
* overflow (when the input is less than smallest int72 or
* greater than largest int72).
*
* Counterpart to Solidity's `int72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*
* _Available since v4.7._
*/
function toInt72(int256 value) internal pure returns (int72 downcasted) {
downcasted = int72(value);
require(downcasted == value, "SafeCast: value doesn't fit in 72 bits");
}
/**
* @dev Returns the downcasted int64 from int256, reverting on
* overflow (when the input is less than smallest int64 or
* greater than largest int64).
*
* Counterpart to Solidity's `int64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*
* _Available since v3.1._
*/
function toInt64(int256 value) internal pure returns (int64 downcasted) {
downcasted = int64(value);
require(downcasted == value, "SafeCast: value doesn't fit in 64 bits");
}
/**
* @dev Returns the downcasted int56 from int256, reverting on
* overflow (when the input is less than smallest int56 or
* greater than largest int56).
*
* Counterpart to Solidity's `int56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*
* _Available since v4.7._
*/
function toInt56(int256 value) internal pure returns (int56 downcasted) {
downcasted = int56(value);
require(downcasted == value, "SafeCast: value doesn't fit in 56 bits");
}
/**
* @dev Returns the downcasted int48 from int256, reverting on
* overflow (when the input is less than smallest int48 or
* greater than largest int48).
*
* Counterpart to Solidity's `int48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*
* _Available since v4.7._
*/
function toInt48(int256 value) internal pure returns (int48 downcasted) {
downcasted = int48(value);
require(downcasted == value, "SafeCast: value doesn't fit in 48 bits");
}
/**
* @dev Returns the downcasted int40 from int256, reverting on
* overflow (when the input is less than smallest int40 or
* greater than largest int40).
*
* Counterpart to Solidity's `int40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*
* _Available since v4.7._
*/
function toInt40(int256 value) internal pure returns (int40 downcasted) {
downcasted = int40(value);
require(downcasted == value, "SafeCast: value doesn't fit in 40 bits");
}
/**
* @dev Returns the downcasted int32 from int256, reverting on
* overflow (when the input is less than smallest int32 or
* greater than largest int32).
*
* Counterpart to Solidity's `int32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*
* _Available since v3.1._
*/
function toInt32(int256 value) internal pure returns (int32 downcasted) {
downcasted = int32(value);
require(downcasted == value, "SafeCast: value doesn't fit in 32 bits");
}
/**
* @dev Returns the downcasted int24 from int256, reverting on
* overflow (when the input is less than smallest int24 or
* greater than largest int24).
*
* Counterpart to Solidity's `int24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*
* _Available since v4.7._
*/
function toInt24(int256 value) internal pure returns (int24 downcasted) {
downcasted = int24(value);
require(downcasted == value, "SafeCast: value doesn't fit in 24 bits");
}
/**
* @dev Returns the downcasted int16 from int256, reverting on
* overflow (when the input is less than smallest int16 or
* greater than largest int16).
*
* Counterpart to Solidity's `int16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*
* _Available since v3.1._
*/
function toInt16(int256 value) internal pure returns (int16 downcasted) {
downcasted = int16(value);
require(downcasted == value, "SafeCast: value doesn't fit in 16 bits");
}
/**
* @dev Returns the downcasted int8 from int256, reverting on
* overflow (when the input is less than smallest int8 or
* greater than largest int8).
*
* Counterpart to Solidity's `int8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*
* _Available since v3.1._
*/
function toInt8(int256 value) internal pure returns (int8 downcasted) {
downcasted = int8(value);
require(downcasted == value, "SafeCast: value doesn't fit in 8 bits");
}
/**
* @dev Converts an unsigned uint256 into a signed int256.
*
* Requirements:
*
* - input must be less than or equal to maxInt256.
*
* _Available since v3.0._
*/
function toInt256(uint256 value) internal pure returns (int256) {
// Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256");
return int256(value);
}
}