Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- ErinaceusVRFWrapper
- Optimization enabled
- false
- Compiler version
- v0.8.20+commit.a1b79de6
- EVM Version
- paris
- Verified at
- 2024-05-20T14:55:38.110791Z
Constructor Arguments
0000000000000000000000004084ab20f8ffca76c19aaf854fb5fe9de6217fbb0000000000000000000000002fc32019e6d3d8dc6702b9e99da9a18ed118d3de
Arg [0] (<b>address</b>) : <a href="{#{address_path(@conn, :show, @address)}}">0x4084ab20f8ffca76c19aaf854fb5fe9de6217fbb</a> Arg [1] (<b>address</b>) : <a href="{#{address_path(@conn, :show, @address)}}">0x2fc32019e6d3d8dc6702b9e99da9a18ed118d3de</a>
contracts/vrf/ErinaceusVRFWrapper.sol
// SPDX-License-Identifier: MIT
// solhint-disable-next-line one-contract-per-file
pragma solidity ^0.8.6;
import {ErinaceusVRFWrapperInterface} from "./interfaces/ErinaceusVRFWrapperInterface.sol";
import {ErinaceusVRFInterface} from "./interfaces/ErinaceusVRFInterface.sol";
import {VRFV2WrapperConsumerBase} from "./VRFV2WrapperConsumerBase.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {VRFConsumerBaseV2} from "./VRFConsumerBaseV2.sol";
import {IWFTN} from "../interfaces/IWFTN.sol";
import "hardhat/console.sol";
/**
* @notice A wrapper for VRFCoordinatorV2 that provides an interface better suited to one-off
* @notice requests for randomness.
*/
contract ErinaceusVRFWrapper is Ownable, VRFConsumerBaseV2, ErinaceusVRFWrapperInterface {
event WrapperFulfillmentFailed(uint256 indexed requestId, address indexed consumer);
IWFTN public immutable wFTN;
ExtendedErinaceusVRFInterface public immutable COORDINATOR;
uint64 public immutable SUBSCRIPTION_ID;
/// @dev this is the size of a VRF v2 fulfillment's calldata abi-encoded in bytes.
/// @dev proofSize = 13 words = 13 * 256 = 3328 bits
/// @dev commitmentSize = 5 words = 5 * 256 = 1280 bits
/// @dev dataSize = proofSize + commitmentSize = 4608 bits
/// @dev selector = 32 bits
/// @dev total data size = 4608 bits + 32 bits = 4640 bits = 580 bytes
uint32 public s_fulfillmentTxSizeBytes = 580;
// 5k is plenty for an EXTCODESIZE call (2600) + warm CALL (100)
// and some arithmetic operations.
uint256 private constant GAS_FOR_CALL_EXACT_CHECK = 5_000;
// lastRequestId is the request ID of the most recent VRF V2 request made by this wrapper. This
// should only be relied on within the same transaction the request was made.
uint256 public override lastRequestId;
// Configuration fetched from VRFCoordinatorV2
// s_configured tracks whether this contract has been configured. If not configured, randomness
// requests cannot be made.
bool public s_configured;
// s_disabled disables the contract when true. When disabled, new VRF requests cannot be made
// but existing ones can still be fulfilled.
bool public s_disabled;
// s_fulfillmentFlatFeeWFTNPPM is the flat fee in millionths of wFTN that VRFCoordinatorV2
// charges.
uint32 private s_fulfillmentFlatFeeWFTNPPM;
// Other configuration
// s_wrapperGasOverhead reflects the gas overhead of the wrapper's fulfillRandomWords
// function. The cost for this gas is passed to the user.
uint32 private s_wrapperGasOverhead;
// s_coordinatorGasOverhead reflects the gas overhead of the coordinator's fulfillRandomWords
// function. The cost for this gas is billed to the subscription, and must therefor be included
// in the pricing for wrapped requests. This includes the gas costs of proof verification and
// payment calculation in the coordinator.
uint32 private s_coordinatorGasOverhead;
// s_wrapperPremiumPercentage is the premium ratio in percentage. For example, a value of 0
// indicates no premium. A value of 15 indicates a 15 percent premium.
uint8 private s_wrapperPremiumPercentage;
// s_keyHash is the key hash to use when requesting randomness. Fees are paid based on current gas
// fees, so this should be set to the highest gas lane on the network.
bytes32 internal s_keyHash;
// s_maxNumWords is the max number of words that can be requested in a single wrapped VRF request.
uint8 internal s_maxNumWords;
struct Callback {
address callbackAddress;
uint32 callbackGasLimit;
uint256 requestGasPrice;
uint256 juelsPaid;
}
mapping(uint256 => Callback) /* requestID */ /* callback */ public s_callbacks;
constructor(
address payable _wFTN,
address _coordinator
) VRFConsumerBaseV2(_coordinator) {
wFTN = IWFTN(_wFTN);
COORDINATOR = ExtendedErinaceusVRFInterface(_coordinator);
// Create this wrapper's subscription and add itself as a consumer.
uint64 subId = ExtendedErinaceusVRFInterface(_coordinator).createSubscription();
SUBSCRIPTION_ID = subId;
ExtendedErinaceusVRFInterface(_coordinator).addConsumer(subId, address(this));
_transferOwnership(msg.sender);
}
/**
* @notice setFulfillmentTxSize sets the size of the fulfillment transaction in bytes.
* @param size is the size of the fulfillment transaction in bytes.
*/
function setFulfillmentTxSize(uint32 size) external onlyOwner {
s_fulfillmentTxSizeBytes = size;
}
/**
* @notice setConfig configures VRFV2Wrapper.
*
* @dev Sets wrapper-specific configuration based on the given parameters, and fetches any needed
* @dev VRFCoordinatorV2 configuration from the coordinator.
*
* @param _wrapperGasOverhead reflects the gas overhead of the wrapper's fulfillRandomWords
* function.
*
* @param _coordinatorGasOverhead reflects the gas overhead of the coordinator's
* fulfillRandomWords function.
*
* @param _wrapperPremiumPercentage is the premium ratio in percentage for wrapper requests.
*
* @param _keyHash to use for requesting randomness.
*/
function setConfig(
uint32 _wrapperGasOverhead,
uint32 _coordinatorGasOverhead,
uint8 _wrapperPremiumPercentage,
bytes32 _keyHash,
uint8 _maxNumWords
) external onlyOwner {
s_wrapperGasOverhead = _wrapperGasOverhead;
s_coordinatorGasOverhead = _coordinatorGasOverhead;
s_wrapperPremiumPercentage = _wrapperPremiumPercentage;
s_keyHash = _keyHash;
s_maxNumWords = _maxNumWords;
s_configured = true;
(s_fulfillmentFlatFeeWFTNPPM, , , , , , , , ) = COORDINATOR.getFeeConfig();
}
/**
* @notice getConfig returns the current VRFV2Wrapper configuration.
*
* @return fulfillmentFlatFeeWFTNPPM is the flat fee in millionths of wFTN that VRFCoordinatorV2
* charges.
*
* @return wrapperGasOverhead reflects the gas overhead of the wrapper's fulfillRandomWords
* function. The cost for this gas is passed to the user.
*
* @return coordinatorGasOverhead reflects the gas overhead of the coordinator's
* fulfillRandomWords function.
*
* @return wrapperPremiumPercentage is the premium ratio in percentage. For example, a value of 0
* indicates no premium. A value of 15 indicates a 15 percent premium.
*
* @return keyHash is the key hash to use when requesting randomness. Fees are paid based on
* current gas fees, so this should be set to the highest gas lane on the network.
*
* @return maxNumWords is the max number of words that can be requested in a single wrapped VRF
* request.
*/
function getConfig()
external
view
returns (
uint32 fulfillmentFlatFeeWFTNPPM,
uint32 wrapperGasOverhead,
uint32 coordinatorGasOverhead,
uint8 wrapperPremiumPercentage,
bytes32 keyHash,
uint8 maxNumWords
)
{
return (
s_fulfillmentFlatFeeWFTNPPM,
s_wrapperGasOverhead,
s_coordinatorGasOverhead,
s_wrapperPremiumPercentage,
s_keyHash,
s_maxNumWords
);
}
/**
* @notice Calculates the price of a VRF request with the given callbackGasLimit at the current
* @notice block.
*
* @dev This function relies on the transaction gas price which is not automatically set during
* @dev simulation. To estimate the price at a specific gas price, use the estimatePrice function.
*
* @param _callbackGasLimit is the gas limit used to estimate the price.
*/
function calculateRequestPrice(
uint32 _callbackGasLimit
) external view override onlyConfiguredNotDisabled returns (uint256) {
console.log(" ~ )externalviewoverrideonlyConfiguredNotDisabledreturns ~ tx.gasprice:", tx.gasprice);
return _calculateRequestPrice(_callbackGasLimit, tx.gasprice);
}
/**
* @notice Estimates the price of a VRF request with a specific gas limit and gas price.
*
* @dev This is a convenience function that can be called in simulation to better understand
* @dev pricing.
*
* @param _callbackGasLimit is the gas limit used to estimate the price.
* @param _requestGasPriceWei is the gas price in wei used for the estimation.
*/
function estimateRequestPrice(
uint32 _callbackGasLimit,
uint256 _requestGasPriceWei
) external view override onlyConfiguredNotDisabled returns (uint256) {
return _calculateRequestPrice(_callbackGasLimit, _requestGasPriceWei);
}
function _calculateRequestPrice(
uint256 _gas,
uint256 _requestGasPrice
) internal view returns (uint256) {
// costWei is the base fee denominated in wei (native)
uint256 costWei = _requestGasPrice *
(_gas + s_wrapperGasOverhead + s_coordinatorGasOverhead);
// feeWithPremium is the fee after the percentage premium is applied
uint256 feeWithPremium = (costWei * (s_wrapperPremiumPercentage + 100)) / 100;
// feeWithFlatFee is the fee after the flat fee is applied on top of the premium
uint256 feeWithFlatFee = feeWithPremium + (1e12 * uint256(s_fulfillmentFlatFeeWFTNPPM));
return feeWithFlatFee;
}
/**
* @dev Requests randomness .
*
* @param callbackGasLimit is the gas limit that should be used when calling the consumer's
* fulfillRandomWords function.
* @param requestConfirmations is the number of confirmations to wait before fulfilling the
* request. A higher number of confirmations increases security by reducing the likelihood
* that a chain re-org changes a published randomness outcome.
* @param numWords is the number of random words to request.
*/
function requestRandomWords(uint32 callbackGasLimit, uint16 requestConfirmations, uint32 numWords) external onlyConfiguredNotDisabled {
uint32 eip150Overhead = _getEIP150Overhead(callbackGasLimit);
uint256 price = _calculateRequestPrice(callbackGasLimit, tx.gasprice);
// solhint-disable-next-line custom-errors
require(numWords <= s_maxNumWords, "numWords too high");
wFTN.transferFrom(msg.sender, address(this), price);
uint256 requestId = COORDINATOR.requestRandomWords(
s_keyHash,
SUBSCRIPTION_ID,
requestConfirmations,
callbackGasLimit + eip150Overhead + s_wrapperGasOverhead,
numWords
);
s_callbacks[requestId] = Callback({
callbackAddress: msg.sender,
callbackGasLimit: callbackGasLimit,
requestGasPrice: tx.gasprice,
juelsPaid: price
});
lastRequestId = requestId;
}
/**
* @notice withdraw is used by the VRFV2Wrapper's owner to withdraw wFTN revenue.
*
* @param _recipient is the address that should receive the wFTN funds.
*
* @param _amount is the amount of wFTN in Juels that should be withdrawn.
*/
function withdraw(address _recipient, uint256 _amount) external onlyOwner {
wFTN.transfer(_recipient, _amount);
}
/**
* @notice enable this contract so that new requests can be accepted.
*/
function enable() external onlyOwner {
s_disabled = false;
}
/**
* @notice disable this contract so that new requests will be rejected. When disabled, new requests
* @notice will revert but existing requests can still be fulfilled.
*/
function disable() external onlyOwner {
s_disabled = true;
}
function fulfillRandomWords(uint256 _requestId, uint256[] memory _randomWords) internal override {
Callback memory callback = s_callbacks[_requestId];
delete s_callbacks[_requestId];
// solhint-disable-next-line custom-errors
require(callback.callbackAddress != address(0), "request not found"); // This should never happen
VRFV2WrapperConsumerBase c;
bytes memory resp = abi.encodeWithSelector(c.rawFulfillRandomWords.selector, _requestId, _randomWords);
bool success = _callWithExactGas(callback.callbackGasLimit, callback.callbackAddress, resp);
if (!success) {
emit WrapperFulfillmentFailed(_requestId, callback.callbackAddress);
}
}
/**
* @dev Calculates extra amount of gas required for running an assembly call() post-EIP150.
*/
function _getEIP150Overhead(uint32 gas) private pure returns (uint32) {
return gas / 63 + 1;
}
/**
* @dev calls target address with exactly gasAmount gas and data as calldata
* or reverts if at least gasAmount gas is not available.
*/
function _callWithExactGas(uint256 gasAmount, address target, bytes memory data) private returns (bool success) {
assembly {
let g := gas()
// Compute g -= GAS_FOR_CALL_EXACT_CHECK and check for underflow
// The gas actually passed to the callee is min(gasAmount, 63//64*gas available).
// We want to ensure that we revert if gasAmount > 63//64*gas available
// as we do not want to provide them with less, however that check itself costs
// gas. GAS_FOR_CALL_EXACT_CHECK ensures we have at least enough gas to be able
// to revert if gasAmount > 63//64*gas available.
if lt(g, GAS_FOR_CALL_EXACT_CHECK) {
revert(0, 0)
}
g := sub(g, GAS_FOR_CALL_EXACT_CHECK)
// if g - g//64 <= gasAmount, revert
// (we subtract g//64 because of EIP-150)
if iszero(gt(sub(g, div(g, 64)), gasAmount)) {
revert(0, 0)
}
// solidity calls check that a contract actually exists at the destination, so we do the same
if iszero(extcodesize(target)) {
revert(0, 0)
}
// call and return whether we succeeded. ignore return data
// call(gas,addr,value,argsOffset,argsLength,retOffset,retLength)
success := call(gasAmount, target, 0, add(data, 0x20), mload(data), 0, 0)
}
return success;
}
// function typeAndVersion() external pure virtual override returns (string memory) {
// return "VRFV2Wrapper 1.0.0";
// }
modifier onlyConfiguredNotDisabled() {
// solhint-disable-next-line custom-errors
require(s_configured, "wrapper is not configured");
// solhint-disable-next-line custom-errors
require(!s_disabled, "wrapper is disabled");
_;
}
}
interface ExtendedErinaceusVRFInterface is ErinaceusVRFInterface {
function getConfig()
external
view
returns (
uint16 minimumRequestConfirmations,
uint32 maxGasLimit,
uint32 gasAfterPaymentCalculation
);
function getFeeConfig()
external
view
returns (
uint32 fulfillmentFlatFeeWFTNPPMTier1,
uint32 fulfillmentFlatFeeWFTNPPMTier2,
uint32 fulfillmentFlatFeeWFTNPPMTier3,
uint32 fulfillmentFlatFeeWFTNPPMTier4,
uint32 fulfillmentFlatFeeWFTNPPMTier5,
uint24 reqsForTier2,
uint24 reqsForTier3,
uint24 reqsForTier4,
uint24 reqsForTier5
);
}
@openzeppelin/contracts/access/Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
@openzeppelin/contracts/utils/Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
contracts/interfaces/IWFTN.sol
// SPDX-License-Identifier: MIT
// Copyright (C) 2024 Fasttoken
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
pragma solidity ^0.8.6;
interface IWFTN {
receive() external payable;
function deposit() external payable;
function withdraw(uint256 amount_) external;
function balanceOf(address account) external view returns (uint256);
function totalSupply() external view returns (uint256);
function approve(address to_, uint256 amount_) external returns (bool);
function transfer(address to_, uint256 amount_) external returns (bool);
function transferFrom(address src_, address to_, uint256 amount_)
external
returns (bool);
}
contracts/vrf/VRFConsumerBaseV2.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
/** ****************************************************************************
* @notice Interface for contracts using VRF randomness
* *****************************************************************************
* @dev PURPOSE
*
* @dev Reggie the Random Oracle (not his real job) wants to provide randomness
* @dev to Vera the verifier in such a way that Vera can be sure he's not
* @dev making his output up to suit himself. Reggie provides Vera a public key
* @dev to which he knows the secret key. Each time Vera provides a seed to
* @dev Reggie, he gives back a value which is computed completely
* @dev deterministically from the seed and the secret key.
*
* @dev Reggie provides a proof by which Vera can verify that the output was
* @dev correctly computed once Reggie tells it to her, but without that proof,
* @dev the output is indistinguishable to her from a uniform random sample
* @dev from the output space.
*
* @dev The purpose of this contract is to make it easy for unrelated contracts
* @dev to talk to Vera the verifier about the work Reggie is doing, to provide
* @dev simple access to a verifiable source of randomness. It ensures 2 things:
* @dev 1. The fulfillment came from the ErinaceusVRF
* @dev 2. The consumer contract implements fulfillRandomWords.
* *****************************************************************************
* @dev USAGE
*
* @dev Calling contracts must inherit from VRFConsumerBase, and can
* @dev initialize VRFConsumerBase's attributes in their constructor as
* @dev shown:
*
* @dev contract VRFConsumer {
* @dev constructor(<other arguments>, address _erinaceusVRF, address _link)
* @dev VRFConsumerBase(_erinaceusVRF) public {
* @dev <initialization with other arguments goes here>
* @dev }
* @dev }
*
* @dev The oracle will have given you an ID for the VRF keypair they have
* @dev committed to (let's call it keyHash). Create subscription, fund it
* @dev and your consumer contract as a consumer of it (see ErinaceusVRFInterface
* @dev subscription management functions).
* @dev Call requestRandomWords(keyHash, subId, minimumRequestConfirmations,
* @dev callbackGasLimit, numWords),
* @dev see (ErinaceusVRFInterface for a description of the arguments).
*
* @dev Once the ErinaceusVRF has received and validated the oracle's response
* @dev to your request, it will call your contract's fulfillRandomWords method.
*
* @dev The randomness argument to fulfillRandomWords is a set of random words
* @dev generated from your requestId and the blockHash of the request.
*
* @dev If your contract could have concurrent requests open, you can use the
* @dev requestId returned from requestRandomWords to track which response is associated
* @dev with which randomness request.
* @dev See "SECURITY CONSIDERATIONS" for principles to keep in mind,
* @dev if your contract could have multiple requests in flight simultaneously.
*
* @dev Colliding `requestId`s are cryptographically impossible as long as seeds
* @dev differ.
*
* *****************************************************************************
* @dev SECURITY CONSIDERATIONS
*
* @dev A method with the ability to call your fulfillRandomness method directly
* @dev could spoof a VRF response with any random value, so it's critical that
* @dev it cannot be directly called by anything other than this base contract
* @dev (specifically, by the VRFConsumerBase.rawFulfillRandomness method).
*
* @dev For your users to trust that your contract's random behavior is free
* @dev from malicious interference, it's best if you can write it so that all
* @dev behaviors implied by a VRF response are executed *during* your
* @dev fulfillRandomness method. If your contract must store the response (or
* @dev anything derived from it) and use it later, you must ensure that any
* @dev user-significant behavior which depends on that stored value cannot be
* @dev manipulated by a subsequent VRF request.
*
* @dev Similarly, both miners and the VRF oracle itself have some influence
* @dev over the order in which VRF responses appear on the blockchain, so if
* @dev your contract could have multiple VRF requests in flight simultaneously,
* @dev you must ensure that the order in which the VRF responses arrive cannot
* @dev be used to manipulate your contract's user-significant behavior.
*
* @dev Since the block hash of the block which contains the requestRandomness
* @dev call is mixed into the input to the VRF *last*, a sufficiently powerful
* @dev miner could, in principle, fork the blockchain to evict the block
* @dev containing the request, forcing the request to be included in a
* @dev different block with a different hash, and therefore a different input
* @dev to the VRF. However, such an attack would incur a substantial economic
* @dev cost. This cost scales with the number of blocks the VRF oracle waits
* @dev until it calls responds to a request. It is for this reason that
* @dev that you can signal to an oracle you'd like them to wait longer before
* @dev responding to the request (however this is not enforced in the contract
* @dev and so remains effective only in the case of unmodified oracle software).
*/
abstract contract VRFConsumerBaseV2 {
error OnlyErinaceusCanFulfill(address have, address want);
// solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i
address private immutable erinaceusVRF;
/**
* @param _erinaceusVRF address of ErinaceusVRF contract
*/
constructor(address _erinaceusVRF) {
erinaceusVRF = _erinaceusVRF;
}
/**
* @notice fulfillRandomness handles the VRF response. Your contract must
* @notice implement it. See "SECURITY CONSIDERATIONS" above for important
* @notice principles to keep in mind when implementing your fulfillRandomness
* @notice method.
*
* @dev VRFConsumerBaseV2 expects its subcontracts to have a method with this
* @dev signature, and will call it once it has verified the proof
* @dev associated with the randomness. (It is triggered via a call to
* @dev rawFulfillRandomness, below.)
*
* @param requestId The Id initially returned by requestRandomness
* @param randomWords the VRF output expanded to the requested number of words
*/
// solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore
function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal virtual;
// rawFulfillRandomness is called by ErinaceusVRF when it receives a valid VRF
// proof. rawFulfillRandomness then calls fulfillRandomness, after validating
// the origin of the call
function rawFulfillRandomWords(uint256 requestId, uint256[] memory randomWords) external {
if (msg.sender != erinaceusVRF) {
revert OnlyErinaceusCanFulfill(msg.sender, erinaceusVRF);
}
fulfillRandomWords(requestId, randomWords);
}
}
contracts/vrf/VRFV2WrapperConsumerBase.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
// import {LinkTokenInterface} from "../shared/interfaces/LinkTokenInterface.sol";
import {ErinaceusVRFWrapperInterface} from "./interfaces/ErinaceusVRFWrapperInterface.sol";
import {IWFTN} from "../interfaces/IWFTN.sol";
/** *******************************************************************************
* @notice Interface for contracts using VRF randomness through the VRF V2 wrapper
* ********************************************************************************
* @dev PURPOSE
*
* @dev Create VRF V2 requests without the need for subscription management. Rather than creating
* @dev and funding a VRF V2 subscription, a user can use this wrapper to create one off requests,
* @dev paying up front rather than at fulfillment.
*
* @dev Since the price is determined using the gas price of the request transaction rather than
* @dev the fulfillment transaction, the wrapper charges an additional premium on callback gas
* @dev usage, in addition to some extra overhead costs associated with the VRFV2Wrapper contract.
* *****************************************************************************
* @dev USAGE
*
* @dev Calling contracts must inherit from VRFV2WrapperConsumerBase. The consumer must be funded
* @dev with enough LINK to make the request, otherwise requests will revert. To request randomness,
* @dev call the 'requestRandomness' function with the desired VRF parameters. This function handles
* @dev paying for the request based on the current pricing.
*
* @dev Consumers must implement the fullfillRandomWords function, which will be called during
* @dev fulfillment with the randomness result.
*/
abstract contract VRFV2WrapperConsumerBase {
IWFTN internal immutable wFTN;
ErinaceusVRFWrapperInterface internal immutable ERINACEUS_VRF_WRAPPER;
/**
* @param _wFTN is the address of LinkToken
* @param _vrfV2Wrapper is the address of the VRFV2Wrapper contract
*/
constructor(address payable _wFTN, address _vrfV2Wrapper) {
wFTN = IWFTN(_wFTN);
ERINACEUS_VRF_WRAPPER = ErinaceusVRFWrapperInterface(_vrfV2Wrapper);
}
/**
* @dev Requests randomness from the VRF V2 wrapper.
*
* @param _callbackGasLimit is the gas limit that should be used when calling the consumer's
* fulfillRandomWords function.
* @param _requestConfirmations is the number of confirmations to wait before fulfilling the
* request. A higher number of confirmations increases security by reducing the likelihood
* that a chain re-org changes a published randomness outcome.
* @param _numWords is the number of random words to request.
*
* @return requestId is the VRF V2 request ID of the newly created randomness request.
*/
function requestRandomness(
uint32 _callbackGasLimit,
uint16 _requestConfirmations,
uint32 _numWords
) internal returns (uint256 requestId) {
wFTN.transferFrom(msg.sender, address(this), ERINACEUS_VRF_WRAPPER.calculateRequestPrice(_callbackGasLimit));
wFTN.approve(address(ERINACEUS_VRF_WRAPPER), ERINACEUS_VRF_WRAPPER.calculateRequestPrice(_callbackGasLimit));
ERINACEUS_VRF_WRAPPER.requestRandomWords(_callbackGasLimit, _requestConfirmations, _numWords);
return ERINACEUS_VRF_WRAPPER.lastRequestId();
}
/**
* @notice fulfillRandomWords handles the VRF V2 wrapper response. The consuming contract must
* @notice implement it.
*
* @param _requestId is the VRF V2 request ID.
* @param _randomWords is the randomness result.
*/
function fulfillRandomWords(uint256 _requestId, uint256[] memory _randomWords) internal virtual;
function rawFulfillRandomWords(uint256 _requestId, uint256[] memory _randomWords) external {
// solhint-disable-next-line custom-errors
require(msg.sender == address(ERINACEUS_VRF_WRAPPER), "only VRF V2 wrapper can fulfill");
fulfillRandomWords(_requestId, _randomWords);
}
}
contracts/vrf/interfaces/ErinaceusVRFInterface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface ErinaceusVRFInterface {
/**
* @notice Get configuration relevant for making requests
* @return minimumRequestConfirmations global min for request confirmations
* @return maxGasLimit global max for request gas limit
* @return s_provingKeyHashes list of registered key hashes
*/
function getRequestConfig() external view returns (uint16, uint32, bytes32[] memory);
/**
* @notice Request a set of random words.
* @param keyHash - Corresponds to a particular oracle job which uses
* that key for generating the VRF proof. Different keyHash's have different gas price
* ceilings, so you can select a specific one to bound your maximum per request cost.
* @param subId - The ID of the VRF subscription. Must be funded
* with the minimum subscription balance required for the selected keyHash.
* @param minimumRequestConfirmations - How many blocks you'd like the
* oracle to wait before responding to the request. See SECURITY CONSIDERATIONS
* for why you may want to request more. The acceptable range is
* [minimumRequestBlockConfirmations, 200].
* @param callbackGasLimit - How much gas you'd like to receive in your
* fulfillRandomWords callback. Note that gasleft() inside fulfillRandomWords
* may be slightly less than this amount because of gas used calling the function
* (argument decoding etc.), so you may need to request slightly more than you expect
* to have inside fulfillRandomWords. The acceptable range is
* [0, maxGasLimit]
* @param numWords - The number of uint256 random values you'd like to receive
* in your fulfillRandomWords callback. Note these numbers are expanded in a
* secure way by the ErinaceusVRF from a single random value supplied by the oracle.
* @return requestId - A unique identifier of the request. Can be used to match
* a request to a response in fulfillRandomWords.
*/
function requestRandomWords(
bytes32 keyHash,
uint64 subId,
uint16 minimumRequestConfirmations,
uint32 callbackGasLimit,
uint32 numWords
) external returns (uint256 requestId);
/**
* @notice Create a VRF subscription.
* @return subId - A unique subscription id.
* @dev You can manage the consumer set dynamically with addConsumer/removeConsumer.
* @dev Note to fund the subscription, use transferAndCall. For example
* @dev LINKTOKEN.transferAndCall(
* @dev address(ERINACEUS),
* @dev amount,
* @dev abi.encode(subId));
*/
function createSubscription() external returns (uint64 subId);
/**
* @notice Get a VRF subscription.
* @param subId - ID of the subscription
* @return balance - LINK balance of the subscription in juels.
* @return reqCount - number of requests for this subscription, determines fee tier.
* @return owner - owner of the subscription.
* @return consumers - list of consumer address which are able to use this subscription.
*/
function getSubscription(
uint64 subId
) external view returns (uint256 balance, uint256 reqCount, address owner, address[] memory consumers);
/**
* @notice Request subscription owner transfer.
* @param subId - ID of the subscription
* @param newOwner - proposed new owner of the subscription
*/
function requestSubscriptionOwnerTransfer(uint64 subId, address newOwner) external;
/**
* @notice Request subscription owner transfer.
* @param subId - ID of the subscription
* @dev will revert if original owner of subId has
* not requested that msg.sender become the new owner.
*/
function acceptSubscriptionOwnerTransfer(uint64 subId) external;
/**
* @notice Add a consumer to a VRF subscription.
* @param subId - ID of the subscription
* @param consumer - New consumer which can use the subscription
*/
function addConsumer(uint64 subId, address consumer) external;
/**
* @notice Remove a consumer from a VRF subscription.
* @param subId - ID of the subscription
* @param consumer - Consumer to remove from the subscription
*/
function removeConsumer(uint64 subId, address consumer) external;
/**
* @notice Cancel a subscription
* @param subId - ID of the subscription
* @param to - Where to send the remaining LINK to
*/
function cancelSubscription(uint64 subId, address to) external;
/*
* @notice Check to see if there exists a request commitment consumers
* for all consumers and keyhashes for a given sub.
* @param subId - ID of the subscription
* @return true if there exists at least one unfulfilled request for the subscription, false
* otherwise.
*/
function pendingRequestExists(uint64 subId) external view returns (bool);
}
contracts/vrf/interfaces/ErinaceusVRFWrapperInterface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.6;
interface ErinaceusVRFWrapperInterface {
/**
* @return the request ID of the most recent VRF V2 request made by this wrapper. This should only
* be relied option within the same transaction that the request was made.
*/
function lastRequestId() external view returns (uint256);
function requestRandomWords(uint32 callbackGasLimit, uint16 requestConfirmations, uint32 numWords) external;
/**
* @notice Calculates the price of a VRF request with the given callbackGasLimit at the current
* @notice block.
*
* @dev This function relies on the transaction gas price which is not automatically set during
* @dev simulation. To estimate the price at a specific gas price, use the estimatePrice function.
*
* @param _callbackGasLimit is the gas limit used to estimate the price.
*/
function calculateRequestPrice(uint32 _callbackGasLimit) external view returns (uint256);
/**
* @notice Estimates the price of a VRF request with a specific gas limit and gas price.
*
* @dev This is a convenience function that can be called in simulation to better understand
* @dev pricing.
*
* @param _callbackGasLimit is the gas limit used to estimate the price.
* @param _requestGasPriceWei is the gas price in wei used for the estimation.
*/
function estimateRequestPrice(uint32 _callbackGasLimit, uint256 _requestGasPriceWei) external view returns (uint256);
}
hardhat/console.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;
library console {
address constant CONSOLE_ADDRESS =
0x000000000000000000636F6e736F6c652e6c6f67;
function _sendLogPayloadImplementation(bytes memory payload) internal view {
address consoleAddress = CONSOLE_ADDRESS;
/// @solidity memory-safe-assembly
assembly {
pop(
staticcall(
gas(),
consoleAddress,
add(payload, 32),
mload(payload),
0,
0
)
)
}
}
function _castToPure(
function(bytes memory) internal view fnIn
) internal pure returns (function(bytes memory) pure fnOut) {
assembly {
fnOut := fnIn
}
}
function _sendLogPayload(bytes memory payload) internal pure {
_castToPure(_sendLogPayloadImplementation)(payload);
}
function log() internal pure {
_sendLogPayload(abi.encodeWithSignature("log()"));
}
function logInt(int256 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(int256)", p0));
}
function logUint(uint256 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256)", p0));
}
function logString(string memory p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string)", p0));
}
function logBool(bool p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
}
function logAddress(address p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address)", p0));
}
function logBytes(bytes memory p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes)", p0));
}
function logBytes1(bytes1 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0));
}
function logBytes2(bytes2 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0));
}
function logBytes3(bytes3 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0));
}
function logBytes4(bytes4 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0));
}
function logBytes5(bytes5 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0));
}
function logBytes6(bytes6 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0));
}
function logBytes7(bytes7 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0));
}
function logBytes8(bytes8 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0));
}
function logBytes9(bytes9 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0));
}
function logBytes10(bytes10 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0));
}
function logBytes11(bytes11 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0));
}
function logBytes12(bytes12 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0));
}
function logBytes13(bytes13 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0));
}
function logBytes14(bytes14 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0));
}
function logBytes15(bytes15 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0));
}
function logBytes16(bytes16 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0));
}
function logBytes17(bytes17 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0));
}
function logBytes18(bytes18 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0));
}
function logBytes19(bytes19 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0));
}
function logBytes20(bytes20 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0));
}
function logBytes21(bytes21 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0));
}
function logBytes22(bytes22 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0));
}
function logBytes23(bytes23 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0));
}
function logBytes24(bytes24 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0));
}
function logBytes25(bytes25 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0));
}
function logBytes26(bytes26 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0));
}
function logBytes27(bytes27 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0));
}
function logBytes28(bytes28 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0));
}
function logBytes29(bytes29 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0));
}
function logBytes30(bytes30 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0));
}
function logBytes31(bytes31 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0));
}
function logBytes32(bytes32 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0));
}
function log(uint256 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256)", p0));
}
function log(string memory p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string)", p0));
}
function log(bool p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
}
function log(address p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address)", p0));
}
function log(uint256 p0, uint256 p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256)", p0, p1));
}
function log(uint256 p0, string memory p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string)", p0, p1));
}
function log(uint256 p0, bool p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool)", p0, p1));
}
function log(uint256 p0, address p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address)", p0, p1));
}
function log(string memory p0, uint256 p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256)", p0, p1));
}
function log(string memory p0, string memory p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1));
}
function log(string memory p0, bool p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1));
}
function log(string memory p0, address p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1));
}
function log(bool p0, uint256 p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256)", p0, p1));
}
function log(bool p0, string memory p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1));
}
function log(bool p0, bool p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1));
}
function log(bool p0, address p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1));
}
function log(address p0, uint256 p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256)", p0, p1));
}
function log(address p0, string memory p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1));
}
function log(address p0, bool p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1));
}
function log(address p0, address p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1));
}
function log(uint256 p0, uint256 p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256)", p0, p1, p2));
}
function log(uint256 p0, uint256 p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string)", p0, p1, p2));
}
function log(uint256 p0, uint256 p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool)", p0, p1, p2));
}
function log(uint256 p0, uint256 p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address)", p0, p1, p2));
}
function log(uint256 p0, string memory p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256)", p0, p1, p2));
}
function log(uint256 p0, string memory p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,string)", p0, p1, p2));
}
function log(uint256 p0, string memory p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool)", p0, p1, p2));
}
function log(uint256 p0, string memory p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,address)", p0, p1, p2));
}
function log(uint256 p0, bool p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256)", p0, p1, p2));
}
function log(uint256 p0, bool p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string)", p0, p1, p2));
}
function log(uint256 p0, bool p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool)", p0, p1, p2));
}
function log(uint256 p0, bool p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address)", p0, p1, p2));
}
function log(uint256 p0, address p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256)", p0, p1, p2));
}
function log(uint256 p0, address p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,string)", p0, p1, p2));
}
function log(uint256 p0, address p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool)", p0, p1, p2));
}
function log(uint256 p0, address p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,address)", p0, p1, p2));
}
function log(string memory p0, uint256 p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256)", p0, p1, p2));
}
function log(string memory p0, uint256 p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,string)", p0, p1, p2));
}
function log(string memory p0, uint256 p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool)", p0, p1, p2));
}
function log(string memory p0, uint256 p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,address)", p0, p1, p2));
}
function log(string memory p0, string memory p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint256)", p0, p1, p2));
}
function log(string memory p0, string memory p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2));
}
function log(string memory p0, string memory p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2));
}
function log(string memory p0, string memory p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2));
}
function log(string memory p0, bool p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256)", p0, p1, p2));
}
function log(string memory p0, bool p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2));
}
function log(string memory p0, bool p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2));
}
function log(string memory p0, bool p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2));
}
function log(string memory p0, address p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint256)", p0, p1, p2));
}
function log(string memory p0, address p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2));
}
function log(string memory p0, address p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2));
}
function log(string memory p0, address p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2));
}
function log(bool p0, uint256 p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256)", p0, p1, p2));
}
function log(bool p0, uint256 p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string)", p0, p1, p2));
}
function log(bool p0, uint256 p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool)", p0, p1, p2));
}
function log(bool p0, uint256 p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address)", p0, p1, p2));
}
function log(bool p0, string memory p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256)", p0, p1, p2));
}
function log(bool p0, string memory p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2));
}
function log(bool p0, string memory p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2));
}
function log(bool p0, string memory p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2));
}
function log(bool p0, bool p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256)", p0, p1, p2));
}
function log(bool p0, bool p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2));
}
function log(bool p0, bool p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2));
}
function log(bool p0, bool p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2));
}
function log(bool p0, address p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256)", p0, p1, p2));
}
function log(bool p0, address p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2));
}
function log(bool p0, address p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2));
}
function log(bool p0, address p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2));
}
function log(address p0, uint256 p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256)", p0, p1, p2));
}
function log(address p0, uint256 p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,string)", p0, p1, p2));
}
function log(address p0, uint256 p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool)", p0, p1, p2));
}
function log(address p0, uint256 p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,address)", p0, p1, p2));
}
function log(address p0, string memory p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint256)", p0, p1, p2));
}
function log(address p0, string memory p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2));
}
function log(address p0, string memory p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2));
}
function log(address p0, string memory p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2));
}
function log(address p0, bool p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256)", p0, p1, p2));
}
function log(address p0, bool p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2));
}
function log(address p0, bool p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2));
}
function log(address p0, bool p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2));
}
function log(address p0, address p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint256)", p0, p1, p2));
}
function log(address p0, address p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2));
}
function log(address p0, address p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2));
}
function log(address p0, address p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2));
}
function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,string)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,address)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,string)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,address)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,string)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,address)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,string)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,address)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,string)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,address)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,string)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,address)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,string)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,address)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,string)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,address)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,string)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,address)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,string)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,address)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,string)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,address)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,string)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,address)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,string)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,address)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,string)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,address)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,string)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,address)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,string)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,string)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,bool)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,string)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,bool)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,string)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,bool)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,uint256)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,string)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,address)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,uint256)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,string)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,address)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,uint256)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,uint256)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,string)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,uint256)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,string)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,bool)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint256)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint256)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint256)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,uint256)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint256)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint256)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint256)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,uint256)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint256)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint256)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint256)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,uint256)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,string)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,bool)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,address)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,uint256)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,string)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,bool)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,address)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,uint256)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,string)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,address)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,uint256)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,string)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,bool)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,uint256)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,string)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,bool)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint256)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint256)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint256)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,uint256)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint256)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint256)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint256)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,uint256)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint256)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint256)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint256)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3));
}
}
Compiler Settings
{"outputSelection":{"*":{"*":["*"],"":["*"]}},"optimizer":{"runs":200,"enabled":false},"metadata":{"useLiteralContent":true},"libraries":{},"evmVersion":"paris"}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_wFTN","internalType":"address payable"},{"type":"address","name":"_coordinator","internalType":"address"}]},{"type":"error","name":"OnlyErinaceusCanFulfill","inputs":[{"type":"address","name":"have","internalType":"address"},{"type":"address","name":"want","internalType":"address"}]},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"WrapperFulfillmentFailed","inputs":[{"type":"uint256","name":"requestId","internalType":"uint256","indexed":true},{"type":"address","name":"consumer","internalType":"address","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract ExtendedErinaceusVRFInterface"}],"name":"COORDINATOR","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint64","name":"","internalType":"uint64"}],"name":"SUBSCRIPTION_ID","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"calculateRequestPrice","inputs":[{"type":"uint32","name":"_callbackGasLimit","internalType":"uint32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"disable","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"enable","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"estimateRequestPrice","inputs":[{"type":"uint32","name":"_callbackGasLimit","internalType":"uint32"},{"type":"uint256","name":"_requestGasPriceWei","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"fulfillmentFlatFeeWFTNPPM","internalType":"uint32"},{"type":"uint32","name":"wrapperGasOverhead","internalType":"uint32"},{"type":"uint32","name":"coordinatorGasOverhead","internalType":"uint32"},{"type":"uint8","name":"wrapperPremiumPercentage","internalType":"uint8"},{"type":"bytes32","name":"keyHash","internalType":"bytes32"},{"type":"uint8","name":"maxNumWords","internalType":"uint8"}],"name":"getConfig","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lastRequestId","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"rawFulfillRandomWords","inputs":[{"type":"uint256","name":"requestId","internalType":"uint256"},{"type":"uint256[]","name":"randomWords","internalType":"uint256[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"requestRandomWords","inputs":[{"type":"uint32","name":"callbackGasLimit","internalType":"uint32"},{"type":"uint16","name":"requestConfirmations","internalType":"uint16"},{"type":"uint32","name":"numWords","internalType":"uint32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"callbackAddress","internalType":"address"},{"type":"uint32","name":"callbackGasLimit","internalType":"uint32"},{"type":"uint256","name":"requestGasPrice","internalType":"uint256"},{"type":"uint256","name":"juelsPaid","internalType":"uint256"}],"name":"s_callbacks","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"s_configured","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"s_disabled","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"s_fulfillmentTxSizeBytes","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setConfig","inputs":[{"type":"uint32","name":"_wrapperGasOverhead","internalType":"uint32"},{"type":"uint32","name":"_coordinatorGasOverhead","internalType":"uint32"},{"type":"uint8","name":"_wrapperPremiumPercentage","internalType":"uint8"},{"type":"bytes32","name":"_keyHash","internalType":"bytes32"},{"type":"uint8","name":"_maxNumWords","internalType":"uint8"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setFulfillmentTxSize","inputs":[{"type":"uint32","name":"size","internalType":"uint32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IWFTN"}],"name":"wFTN","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdraw","inputs":[{"type":"address","name":"_recipient","internalType":"address"},{"type":"uint256","name":"_amount","internalType":"uint256"}]}]
Contract Creation Code
0x610100604052610244600060146101000a81548163ffffffff021916908363ffffffff1602179055503480156200003557600080fd5b5060405162002a5638038062002a5683398181016040528101906200005b9190620003b3565b806200007c620000706200023860201b60201c565b6200024060201b60201c565b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1681525050508173ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff16815250508073ffffffffffffffffffffffffffffffffffffffff1660c08173ffffffffffffffffffffffffffffffffffffffff168152505060008173ffffffffffffffffffffffffffffffffffffffff1663a21a23e46040518163ffffffff1660e01b81526004016020604051808303816000875af115801562000169573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200018f91906200043f565b90508067ffffffffffffffff1660e08167ffffffffffffffff16815250508173ffffffffffffffffffffffffffffffffffffffff16637341c10c82306040518363ffffffff1660e01b8152600401620001ea92919062000493565b600060405180830381600087803b1580156200020557600080fd5b505af11580156200021a573d6000803e3d6000fd5b505050506200022f336200024060201b60201c565b505050620004c0565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620003368262000309565b9050919050565b620003488162000329565b81146200035457600080fd5b50565b60008151905062000368816200033d565b92915050565b60006200037b8262000309565b9050919050565b6200038d816200036e565b81146200039957600080fd5b50565b600081519050620003ad8162000382565b92915050565b60008060408385031215620003cd57620003cc62000304565b5b6000620003dd8582860162000357565b9250506020620003f0858286016200039c565b9150509250929050565b600067ffffffffffffffff82169050919050565b6200041981620003fa565b81146200042557600080fd5b50565b60008151905062000439816200040e565b92915050565b60006020828403121562000458576200045762000304565b5b6000620004688482850162000428565b91505092915050565b6200047c81620003fa565b82525050565b6200048d816200036e565b82525050565b6000604082019050620004aa600083018562000471565b620004b9602083018462000482565b9392505050565b60805160a05160c05160e05161253262000524600039600081816103aa015261080e0152600081816104b3015281816107cf0152610bd601526000818161072c01528181610ae40152610dcc0152600081816103ce015261042201526125326000f3fe608060405234801561001057600080fd5b50600436106101375760003560e01c80638da5cb5b116100b8578063c15ce4d71161007c578063c15ce4d7146102f5578063c3f909d414610311578063cdd8d88514610334578063f2fde38b14610352578063f3fef3a31461036e578063fc2a88c31461038a57610137565b80638da5cb5b14610275578063a3907d7114610293578063a608a1e11461029d578063b7e2a68a146102bb578063bf17e559146102d957610137565b806348baa1c5116100ff57806348baa1c5146101ce5780634b494dc01461020157806357a8070a1461021d578063715018a61461023b5780637fb5d19d1461024557610137565b8063030932bb1461013c5780631fe543e31461015a5780632f2770db146101765780633b2bcbf1146101805780634306d3541461019e575b600080fd5b6101446103a8565b6040516101519190611486565b60405180910390f35b610174600480360381019061016f9190611644565b6103cc565b005b61017e61048c565b005b6101886104b1565b604051610195919061171f565b60405180910390f35b6101b860048036038101906101b39190611776565b6104d5565b6040516101c591906117b2565b60405180910390f35b6101e860048036038101906101e391906117cd565b6105af565b6040516101f8949392919061182a565b60405180910390f35b61021b600480360381019061021691906118a9565b61060f565b005b6102256109a1565b6040516102329190611917565b60405180910390f35b6102436109b4565b005b61025f600480360381019061025a9190611932565b6109c8565b60405161026c91906117b2565b60405180910390f35b61027d610a81565b60405161028a9190611972565b60405180910390f35b61029b610aaa565b005b6102a5610acf565b6040516102b29190611917565b60405180910390f35b6102c3610ae2565b6040516102d091906119c0565b60405180910390f35b6102f360048036038101906102ee9190611776565b610b06565b005b61030f600480360381019061030a9190611a4a565b610b32565b005b610319610cb2565b60405161032b96959493929190611ae3565b60405180910390f35b61033c610d29565b6040516103499190611b44565b60405180910390f35b61036c60048036038101906103679190611b8b565b610d3f565b005b61038860048036038101906103839190611bb8565b610dc2565b005b610392610e6d565b60405161039f91906117b2565b60405180910390f35b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461047e57337f00000000000000000000000000000000000000000000000000000000000000006040517f1cdc5ebb000000000000000000000000000000000000000000000000000000008152600401610475929190611bf8565b60405180910390fd5b6104888282610e73565b5050565b6104946110ec565b6001600260016101000a81548160ff021916908315150217905550565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000600260009054906101000a900460ff16610526576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161051d90611c7e565b60405180910390fd5b600260019054906101000a900460ff1615610576576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161056d90611cea565b60405180910390fd5b6105986040518060800160405280604781526020016124b6604791393a61116a565b6105a88263ffffffff163a611206565b9050919050565b60056020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060000160149054906101000a900463ffffffff16908060010154908060020154905084565b600260009054906101000a900460ff1661065e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161065590611c7e565b60405180910390fd5b600260019054906101000a900460ff16156106ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106a590611cea565b60405180910390fd5b60006106b9846112d8565b905060006106cd8563ffffffff163a611206565b9050600460009054906101000a900460ff1660ff168363ffffffff16111561072a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161072190611d56565b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166323b872dd3330846040518463ffffffff1660e01b815260040161078793929190611d76565b6020604051808303816000875af11580156107a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ca9190611dd9565b5060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16635d3b1d306003547f000000000000000000000000000000000000000000000000000000000000000088600260069054906101000a900463ffffffff16888c61084d9190611e35565b6108579190611e35565b896040518663ffffffff1660e01b8152600401610878959493929190611e7c565b6020604051808303816000875af1158015610897573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108bb9190611ee4565b905060405180608001604052803373ffffffffffffffffffffffffffffffffffffffff1681526020018763ffffffff1681526020013a8152602001838152506005600083815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548163ffffffff021916908363ffffffff160217905550604082015181600101556060820151816002015590505080600181905550505050505050565b600260009054906101000a900460ff1681565b6109bc6110ec565b6109c660006112fa565b565b6000600260009054906101000a900460ff16610a19576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a1090611c7e565b60405180910390fd5b600260019054906101000a900460ff1615610a69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a6090611cea565b60405180910390fd5b610a798363ffffffff1683611206565b905092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b610ab26110ec565b6000600260016101000a81548160ff021916908315150217905550565b600260019054906101000a900460ff1681565b7f000000000000000000000000000000000000000000000000000000000000000081565b610b0e6110ec565b80600060146101000a81548163ffffffff021916908363ffffffff16021790555050565b610b3a6110ec565b84600260066101000a81548163ffffffff021916908363ffffffff160217905550836002600a6101000a81548163ffffffff021916908363ffffffff160217905550826002600e6101000a81548160ff021916908360ff1602179055508160038190555080600460006101000a81548160ff021916908360ff1602179055506001600260006101000a81548160ff0219169083151502179055507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16635fbbc0d26040518163ffffffff1660e01b815260040161012060405180830381865afa158015610c40573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c649190611f61565b9091929394959650909192939495509091929394509091929350909192509091509050506002808291906101000a81548163ffffffff021916908363ffffffff160217905550505050505050565b60008060008060008060028054906101000a900463ffffffff16600260069054906101000a900463ffffffff166002600a9054906101000a900463ffffffff166002600e9054906101000a900460ff16600354600460009054906101000a900460ff16955095509550955095509550909192939495565b600060149054906101000a900463ffffffff1681565b610d476110ec565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610db6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dad9061209d565b60405180910390fd5b610dbf816112fa565b50565b610dca6110ec565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb83836040518363ffffffff1660e01b8152600401610e259291906120bd565b6020604051808303816000875af1158015610e44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e689190611dd9565b505050565b60015481565b6000600560008481526020019081526020016000206040518060800160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900463ffffffff1663ffffffff1663ffffffff16815260200160018201548152602001600282015481525050905060056000848152602001908152602001600020600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000820160146101000a81549063ffffffff0219169055600182016000905560028201600090555050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1603610ffc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ff390612132565b60405180910390fd5b600080631fe543e360e01b858560405160240161101a929190612210565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000611094846020015163ffffffff168560000151846113be565b9050806110e457836000015173ffffffffffffffffffffffffffffffffffffffff16867fc551b83c151f2d1c7eeb938ac59008e0409f1c1dc1e2f112449d4d79b458902260405160405180910390a35b505050505050565b6110f461140b565b73ffffffffffffffffffffffffffffffffffffffff16611112610a81565b73ffffffffffffffffffffffffffffffffffffffff1614611168576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161115f9061228c565b60405180910390fd5b565b611202828260405160240161118092919061231a565b6040516020818303038152906040527fb60e72cc000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611413565b5050565b6000806002600a9054906101000a900463ffffffff1663ffffffff16600260069054906101000a900463ffffffff1663ffffffff1685611246919061234a565b611250919061234a565b8361125b919061237e565b905060006064806002600e9054906101000a900460ff1661127c91906123c0565b60ff168361128a919061237e565b6112949190612424565b9050600060028054906101000a900463ffffffff1663ffffffff1664e8d4a510006112bf919061237e565b826112ca919061234a565b905080935050505092915050565b60006001603f836112e99190612455565b6112f39190611e35565b9050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60005a6113888110156113d057600080fd5b6113888103905084604082048203116113e857600080fd5b833b6113f357600080fd5b6000808451602086016000888af19150509392505050565b600033905090565b61142a8161142261142d61144e565b63ffffffff16565b50565b60006a636f6e736f6c652e6c6f679050600080835160208501845afa505050565b611459819050919050565b611461612486565b565b600067ffffffffffffffff82169050919050565b61148081611463565b82525050565b600060208201905061149b6000830184611477565b92915050565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b6114c8816114b5565b81146114d357600080fd5b50565b6000813590506114e5816114bf565b92915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b611539826114f0565b810181811067ffffffffffffffff8211171561155857611557611501565b5b80604052505050565b600061156b6114a1565b90506115778282611530565b919050565b600067ffffffffffffffff82111561159757611596611501565b5b602082029050602081019050919050565b600080fd5b60006115c06115bb8461157c565b611561565b905080838252602082019050602084028301858111156115e3576115e26115a8565b5b835b8181101561160c57806115f888826114d6565b8452602084019350506020810190506115e5565b5050509392505050565b600082601f83011261162b5761162a6114eb565b5b813561163b8482602086016115ad565b91505092915050565b6000806040838503121561165b5761165a6114ab565b5b6000611669858286016114d6565b925050602083013567ffffffffffffffff81111561168a576116896114b0565b5b61169685828601611616565b9150509250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006116e56116e06116db846116a0565b6116c0565b6116a0565b9050919050565b60006116f7826116ca565b9050919050565b6000611709826116ec565b9050919050565b611719816116fe565b82525050565b60006020820190506117346000830184611710565b92915050565b600063ffffffff82169050919050565b6117538161173a565b811461175e57600080fd5b50565b6000813590506117708161174a565b92915050565b60006020828403121561178c5761178b6114ab565b5b600061179a84828501611761565b91505092915050565b6117ac816114b5565b82525050565b60006020820190506117c760008301846117a3565b92915050565b6000602082840312156117e3576117e26114ab565b5b60006117f1848285016114d6565b91505092915050565b6000611805826116a0565b9050919050565b611815816117fa565b82525050565b6118248161173a565b82525050565b600060808201905061183f600083018761180c565b61184c602083018661181b565b61185960408301856117a3565b61186660608301846117a3565b95945050505050565b600061ffff82169050919050565b6118868161186f565b811461189157600080fd5b50565b6000813590506118a38161187d565b92915050565b6000806000606084860312156118c2576118c16114ab565b5b60006118d086828701611761565b93505060206118e186828701611894565b92505060406118f286828701611761565b9150509250925092565b60008115159050919050565b611911816118fc565b82525050565b600060208201905061192c6000830184611908565b92915050565b60008060408385031215611949576119486114ab565b5b600061195785828601611761565b9250506020611968858286016114d6565b9150509250929050565b6000602082019050611987600083018461180c565b92915050565b6000611998826116ca565b9050919050565b60006119aa8261198d565b9050919050565b6119ba8161199f565b82525050565b60006020820190506119d560008301846119b1565b92915050565b600060ff82169050919050565b6119f1816119db565b81146119fc57600080fd5b50565b600081359050611a0e816119e8565b92915050565b6000819050919050565b611a2781611a14565b8114611a3257600080fd5b50565b600081359050611a4481611a1e565b92915050565b600080600080600060a08688031215611a6657611a656114ab565b5b6000611a7488828901611761565b9550506020611a8588828901611761565b9450506040611a96888289016119ff565b9350506060611aa788828901611a35565b9250506080611ab8888289016119ff565b9150509295509295909350565b611ace816119db565b82525050565b611add81611a14565b82525050565b600060c082019050611af8600083018961181b565b611b05602083018861181b565b611b12604083018761181b565b611b1f6060830186611ac5565b611b2c6080830185611ad4565b611b3960a0830184611ac5565b979650505050505050565b6000602082019050611b59600083018461181b565b92915050565b611b68816117fa565b8114611b7357600080fd5b50565b600081359050611b8581611b5f565b92915050565b600060208284031215611ba157611ba06114ab565b5b6000611baf84828501611b76565b91505092915050565b60008060408385031215611bcf57611bce6114ab565b5b6000611bdd85828601611b76565b9250506020611bee858286016114d6565b9150509250929050565b6000604082019050611c0d600083018561180c565b611c1a602083018461180c565b9392505050565b600082825260208201905092915050565b7f77726170706572206973206e6f7420636f6e6669677572656400000000000000600082015250565b6000611c68601983611c21565b9150611c7382611c32565b602082019050919050565b60006020820190508181036000830152611c9781611c5b565b9050919050565b7f777261707065722069732064697361626c656400000000000000000000000000600082015250565b6000611cd4601383611c21565b9150611cdf82611c9e565b602082019050919050565b60006020820190508181036000830152611d0381611cc7565b9050919050565b7f6e756d576f72647320746f6f2068696768000000000000000000000000000000600082015250565b6000611d40601183611c21565b9150611d4b82611d0a565b602082019050919050565b60006020820190508181036000830152611d6f81611d33565b9050919050565b6000606082019050611d8b600083018661180c565b611d98602083018561180c565b611da560408301846117a3565b949350505050565b611db6816118fc565b8114611dc157600080fd5b50565b600081519050611dd381611dad565b92915050565b600060208284031215611def57611dee6114ab565b5b6000611dfd84828501611dc4565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611e408261173a565b9150611e4b8361173a565b9250828201905063ffffffff811115611e6757611e66611e06565b5b92915050565b611e768161186f565b82525050565b600060a082019050611e916000830188611ad4565b611e9e6020830187611477565b611eab6040830186611e6d565b611eb8606083018561181b565b611ec5608083018461181b565b9695505050505050565b600081519050611ede816114bf565b92915050565b600060208284031215611efa57611ef96114ab565b5b6000611f0884828501611ecf565b91505092915050565b600081519050611f208161174a565b92915050565b600062ffffff82169050919050565b611f3e81611f26565b8114611f4957600080fd5b50565b600081519050611f5b81611f35565b92915050565b60008060008060008060008060006101208a8c031215611f8457611f836114ab565b5b6000611f928c828d01611f11565b9950506020611fa38c828d01611f11565b9850506040611fb48c828d01611f11565b9750506060611fc58c828d01611f11565b9650506080611fd68c828d01611f11565b95505060a0611fe78c828d01611f4c565b94505060c0611ff88c828d01611f4c565b93505060e06120098c828d01611f4c565b92505061010061201b8c828d01611f4c565b9150509295985092959850929598565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000612087602683611c21565b91506120928261202b565b604082019050919050565b600060208201905081810360008301526120b68161207a565b9050919050565b60006040820190506120d2600083018561180c565b6120df60208301846117a3565b9392505050565b7f72657175657374206e6f7420666f756e64000000000000000000000000000000600082015250565b600061211c601183611c21565b9150612127826120e6565b602082019050919050565b6000602082019050818103600083015261214b8161210f565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b612187816114b5565b82525050565b6000612199838361217e565b60208301905092915050565b6000602082019050919050565b60006121bd82612152565b6121c7818561215d565b93506121d28361216e565b8060005b838110156122035781516121ea888261218d565b97506121f5836121a5565b9250506001810190506121d6565b5085935050505092915050565b600060408201905061222560008301856117a3565b818103602083015261223781846121b2565b90509392505050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000612276602083611c21565b915061228182612240565b602082019050919050565b600060208201905081810360008301526122a581612269565b9050919050565b600081519050919050565b60005b838110156122d55780820151818401526020810190506122ba565b60008484015250505050565b60006122ec826122ac565b6122f68185611c21565b93506123068185602086016122b7565b61230f816114f0565b840191505092915050565b6000604082019050818103600083015261233481856122e1565b905061234360208301846117a3565b9392505050565b6000612355826114b5565b9150612360836114b5565b925082820190508082111561237857612377611e06565b5b92915050565b6000612389826114b5565b9150612394836114b5565b92508282026123a2816114b5565b915082820484148315176123b9576123b8611e06565b5b5092915050565b60006123cb826119db565b91506123d6836119db565b9250828201905060ff8111156123ef576123ee611e06565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061242f826114b5565b915061243a836114b5565b92508261244a576124496123f5565b5b828204905092915050565b60006124608261173a565b915061246b8361173a565b92508261247b5761247a6123f5565b5b828204905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052605160045260246000fdfe207e202965787465726e616c766965776f766572726964656f6e6c79436f6e666967757265644e6f7444697361626c656472657475726e73207e2074782e67617370726963653aa2646970667358221220bb454fb14b698e95c7ef137973cc0aac554f300fb34b0310d00d337469878a7564736f6c634300081400330000000000000000000000004084ab20f8ffca76c19aaf854fb5fe9de6217fbb0000000000000000000000002fc32019e6d3d8dc6702b9e99da9a18ed118d3de
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106101375760003560e01c80638da5cb5b116100b8578063c15ce4d71161007c578063c15ce4d7146102f5578063c3f909d414610311578063cdd8d88514610334578063f2fde38b14610352578063f3fef3a31461036e578063fc2a88c31461038a57610137565b80638da5cb5b14610275578063a3907d7114610293578063a608a1e11461029d578063b7e2a68a146102bb578063bf17e559146102d957610137565b806348baa1c5116100ff57806348baa1c5146101ce5780634b494dc01461020157806357a8070a1461021d578063715018a61461023b5780637fb5d19d1461024557610137565b8063030932bb1461013c5780631fe543e31461015a5780632f2770db146101765780633b2bcbf1146101805780634306d3541461019e575b600080fd5b6101446103a8565b6040516101519190611486565b60405180910390f35b610174600480360381019061016f9190611644565b6103cc565b005b61017e61048c565b005b6101886104b1565b604051610195919061171f565b60405180910390f35b6101b860048036038101906101b39190611776565b6104d5565b6040516101c591906117b2565b60405180910390f35b6101e860048036038101906101e391906117cd565b6105af565b6040516101f8949392919061182a565b60405180910390f35b61021b600480360381019061021691906118a9565b61060f565b005b6102256109a1565b6040516102329190611917565b60405180910390f35b6102436109b4565b005b61025f600480360381019061025a9190611932565b6109c8565b60405161026c91906117b2565b60405180910390f35b61027d610a81565b60405161028a9190611972565b60405180910390f35b61029b610aaa565b005b6102a5610acf565b6040516102b29190611917565b60405180910390f35b6102c3610ae2565b6040516102d091906119c0565b60405180910390f35b6102f360048036038101906102ee9190611776565b610b06565b005b61030f600480360381019061030a9190611a4a565b610b32565b005b610319610cb2565b60405161032b96959493929190611ae3565b60405180910390f35b61033c610d29565b6040516103499190611b44565b60405180910390f35b61036c60048036038101906103679190611b8b565b610d3f565b005b61038860048036038101906103839190611bb8565b610dc2565b005b610392610e6d565b60405161039f91906117b2565b60405180910390f35b7f000000000000000000000000000000000000000000000000000000000000000181565b7f0000000000000000000000002fc32019e6d3d8dc6702b9e99da9a18ed118d3de73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461047e57337f0000000000000000000000002fc32019e6d3d8dc6702b9e99da9a18ed118d3de6040517f1cdc5ebb000000000000000000000000000000000000000000000000000000008152600401610475929190611bf8565b60405180910390fd5b6104888282610e73565b5050565b6104946110ec565b6001600260016101000a81548160ff021916908315150217905550565b7f0000000000000000000000002fc32019e6d3d8dc6702b9e99da9a18ed118d3de81565b6000600260009054906101000a900460ff16610526576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161051d90611c7e565b60405180910390fd5b600260019054906101000a900460ff1615610576576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161056d90611cea565b60405180910390fd5b6105986040518060800160405280604781526020016124b6604791393a61116a565b6105a88263ffffffff163a611206565b9050919050565b60056020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060000160149054906101000a900463ffffffff16908060010154908060020154905084565b600260009054906101000a900460ff1661065e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161065590611c7e565b60405180910390fd5b600260019054906101000a900460ff16156106ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106a590611cea565b60405180910390fd5b60006106b9846112d8565b905060006106cd8563ffffffff163a611206565b9050600460009054906101000a900460ff1660ff168363ffffffff16111561072a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161072190611d56565b60405180910390fd5b7f0000000000000000000000004084ab20f8ffca76c19aaf854fb5fe9de6217fbb73ffffffffffffffffffffffffffffffffffffffff166323b872dd3330846040518463ffffffff1660e01b815260040161078793929190611d76565b6020604051808303816000875af11580156107a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ca9190611dd9565b5060007f0000000000000000000000002fc32019e6d3d8dc6702b9e99da9a18ed118d3de73ffffffffffffffffffffffffffffffffffffffff16635d3b1d306003547f000000000000000000000000000000000000000000000000000000000000000188600260069054906101000a900463ffffffff16888c61084d9190611e35565b6108579190611e35565b896040518663ffffffff1660e01b8152600401610878959493929190611e7c565b6020604051808303816000875af1158015610897573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108bb9190611ee4565b905060405180608001604052803373ffffffffffffffffffffffffffffffffffffffff1681526020018763ffffffff1681526020013a8152602001838152506005600083815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548163ffffffff021916908363ffffffff160217905550604082015181600101556060820151816002015590505080600181905550505050505050565b600260009054906101000a900460ff1681565b6109bc6110ec565b6109c660006112fa565b565b6000600260009054906101000a900460ff16610a19576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a1090611c7e565b60405180910390fd5b600260019054906101000a900460ff1615610a69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a6090611cea565b60405180910390fd5b610a798363ffffffff1683611206565b905092915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b610ab26110ec565b6000600260016101000a81548160ff021916908315150217905550565b600260019054906101000a900460ff1681565b7f0000000000000000000000004084ab20f8ffca76c19aaf854fb5fe9de6217fbb81565b610b0e6110ec565b80600060146101000a81548163ffffffff021916908363ffffffff16021790555050565b610b3a6110ec565b84600260066101000a81548163ffffffff021916908363ffffffff160217905550836002600a6101000a81548163ffffffff021916908363ffffffff160217905550826002600e6101000a81548160ff021916908360ff1602179055508160038190555080600460006101000a81548160ff021916908360ff1602179055506001600260006101000a81548160ff0219169083151502179055507f0000000000000000000000002fc32019e6d3d8dc6702b9e99da9a18ed118d3de73ffffffffffffffffffffffffffffffffffffffff16635fbbc0d26040518163ffffffff1660e01b815260040161012060405180830381865afa158015610c40573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c649190611f61565b9091929394959650909192939495509091929394509091929350909192509091509050506002808291906101000a81548163ffffffff021916908363ffffffff160217905550505050505050565b60008060008060008060028054906101000a900463ffffffff16600260069054906101000a900463ffffffff166002600a9054906101000a900463ffffffff166002600e9054906101000a900460ff16600354600460009054906101000a900460ff16955095509550955095509550909192939495565b600060149054906101000a900463ffffffff1681565b610d476110ec565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610db6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dad9061209d565b60405180910390fd5b610dbf816112fa565b50565b610dca6110ec565b7f0000000000000000000000004084ab20f8ffca76c19aaf854fb5fe9de6217fbb73ffffffffffffffffffffffffffffffffffffffff1663a9059cbb83836040518363ffffffff1660e01b8152600401610e259291906120bd565b6020604051808303816000875af1158015610e44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e689190611dd9565b505050565b60015481565b6000600560008481526020019081526020016000206040518060800160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900463ffffffff1663ffffffff1663ffffffff16815260200160018201548152602001600282015481525050905060056000848152602001908152602001600020600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000820160146101000a81549063ffffffff0219169055600182016000905560028201600090555050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff1603610ffc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ff390612132565b60405180910390fd5b600080631fe543e360e01b858560405160240161101a929190612210565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000611094846020015163ffffffff168560000151846113be565b9050806110e457836000015173ffffffffffffffffffffffffffffffffffffffff16867fc551b83c151f2d1c7eeb938ac59008e0409f1c1dc1e2f112449d4d79b458902260405160405180910390a35b505050505050565b6110f461140b565b73ffffffffffffffffffffffffffffffffffffffff16611112610a81565b73ffffffffffffffffffffffffffffffffffffffff1614611168576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161115f9061228c565b60405180910390fd5b565b611202828260405160240161118092919061231a565b6040516020818303038152906040527fb60e72cc000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611413565b5050565b6000806002600a9054906101000a900463ffffffff1663ffffffff16600260069054906101000a900463ffffffff1663ffffffff1685611246919061234a565b611250919061234a565b8361125b919061237e565b905060006064806002600e9054906101000a900460ff1661127c91906123c0565b60ff168361128a919061237e565b6112949190612424565b9050600060028054906101000a900463ffffffff1663ffffffff1664e8d4a510006112bf919061237e565b826112ca919061234a565b905080935050505092915050565b60006001603f836112e99190612455565b6112f39190611e35565b9050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60005a6113888110156113d057600080fd5b6113888103905084604082048203116113e857600080fd5b833b6113f357600080fd5b6000808451602086016000888af19150509392505050565b600033905090565b61142a8161142261142d61144e565b63ffffffff16565b50565b60006a636f6e736f6c652e6c6f679050600080835160208501845afa505050565b611459819050919050565b611461612486565b565b600067ffffffffffffffff82169050919050565b61148081611463565b82525050565b600060208201905061149b6000830184611477565b92915050565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b6114c8816114b5565b81146114d357600080fd5b50565b6000813590506114e5816114bf565b92915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b611539826114f0565b810181811067ffffffffffffffff8211171561155857611557611501565b5b80604052505050565b600061156b6114a1565b90506115778282611530565b919050565b600067ffffffffffffffff82111561159757611596611501565b5b602082029050602081019050919050565b600080fd5b60006115c06115bb8461157c565b611561565b905080838252602082019050602084028301858111156115e3576115e26115a8565b5b835b8181101561160c57806115f888826114d6565b8452602084019350506020810190506115e5565b5050509392505050565b600082601f83011261162b5761162a6114eb565b5b813561163b8482602086016115ad565b91505092915050565b6000806040838503121561165b5761165a6114ab565b5b6000611669858286016114d6565b925050602083013567ffffffffffffffff81111561168a576116896114b0565b5b61169685828601611616565b9150509250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006116e56116e06116db846116a0565b6116c0565b6116a0565b9050919050565b60006116f7826116ca565b9050919050565b6000611709826116ec565b9050919050565b611719816116fe565b82525050565b60006020820190506117346000830184611710565b92915050565b600063ffffffff82169050919050565b6117538161173a565b811461175e57600080fd5b50565b6000813590506117708161174a565b92915050565b60006020828403121561178c5761178b6114ab565b5b600061179a84828501611761565b91505092915050565b6117ac816114b5565b82525050565b60006020820190506117c760008301846117a3565b92915050565b6000602082840312156117e3576117e26114ab565b5b60006117f1848285016114d6565b91505092915050565b6000611805826116a0565b9050919050565b611815816117fa565b82525050565b6118248161173a565b82525050565b600060808201905061183f600083018761180c565b61184c602083018661181b565b61185960408301856117a3565b61186660608301846117a3565b95945050505050565b600061ffff82169050919050565b6118868161186f565b811461189157600080fd5b50565b6000813590506118a38161187d565b92915050565b6000806000606084860312156118c2576118c16114ab565b5b60006118d086828701611761565b93505060206118e186828701611894565b92505060406118f286828701611761565b9150509250925092565b60008115159050919050565b611911816118fc565b82525050565b600060208201905061192c6000830184611908565b92915050565b60008060408385031215611949576119486114ab565b5b600061195785828601611761565b9250506020611968858286016114d6565b9150509250929050565b6000602082019050611987600083018461180c565b92915050565b6000611998826116ca565b9050919050565b60006119aa8261198d565b9050919050565b6119ba8161199f565b82525050565b60006020820190506119d560008301846119b1565b92915050565b600060ff82169050919050565b6119f1816119db565b81146119fc57600080fd5b50565b600081359050611a0e816119e8565b92915050565b6000819050919050565b611a2781611a14565b8114611a3257600080fd5b50565b600081359050611a4481611a1e565b92915050565b600080600080600060a08688031215611a6657611a656114ab565b5b6000611a7488828901611761565b9550506020611a8588828901611761565b9450506040611a96888289016119ff565b9350506060611aa788828901611a35565b9250506080611ab8888289016119ff565b9150509295509295909350565b611ace816119db565b82525050565b611add81611a14565b82525050565b600060c082019050611af8600083018961181b565b611b05602083018861181b565b611b12604083018761181b565b611b1f6060830186611ac5565b611b2c6080830185611ad4565b611b3960a0830184611ac5565b979650505050505050565b6000602082019050611b59600083018461181b565b92915050565b611b68816117fa565b8114611b7357600080fd5b50565b600081359050611b8581611b5f565b92915050565b600060208284031215611ba157611ba06114ab565b5b6000611baf84828501611b76565b91505092915050565b60008060408385031215611bcf57611bce6114ab565b5b6000611bdd85828601611b76565b9250506020611bee858286016114d6565b9150509250929050565b6000604082019050611c0d600083018561180c565b611c1a602083018461180c565b9392505050565b600082825260208201905092915050565b7f77726170706572206973206e6f7420636f6e6669677572656400000000000000600082015250565b6000611c68601983611c21565b9150611c7382611c32565b602082019050919050565b60006020820190508181036000830152611c9781611c5b565b9050919050565b7f777261707065722069732064697361626c656400000000000000000000000000600082015250565b6000611cd4601383611c21565b9150611cdf82611c9e565b602082019050919050565b60006020820190508181036000830152611d0381611cc7565b9050919050565b7f6e756d576f72647320746f6f2068696768000000000000000000000000000000600082015250565b6000611d40601183611c21565b9150611d4b82611d0a565b602082019050919050565b60006020820190508181036000830152611d6f81611d33565b9050919050565b6000606082019050611d8b600083018661180c565b611d98602083018561180c565b611da560408301846117a3565b949350505050565b611db6816118fc565b8114611dc157600080fd5b50565b600081519050611dd381611dad565b92915050565b600060208284031215611def57611dee6114ab565b5b6000611dfd84828501611dc4565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611e408261173a565b9150611e4b8361173a565b9250828201905063ffffffff811115611e6757611e66611e06565b5b92915050565b611e768161186f565b82525050565b600060a082019050611e916000830188611ad4565b611e9e6020830187611477565b611eab6040830186611e6d565b611eb8606083018561181b565b611ec5608083018461181b565b9695505050505050565b600081519050611ede816114bf565b92915050565b600060208284031215611efa57611ef96114ab565b5b6000611f0884828501611ecf565b91505092915050565b600081519050611f208161174a565b92915050565b600062ffffff82169050919050565b611f3e81611f26565b8114611f4957600080fd5b50565b600081519050611f5b81611f35565b92915050565b60008060008060008060008060006101208a8c031215611f8457611f836114ab565b5b6000611f928c828d01611f11565b9950506020611fa38c828d01611f11565b9850506040611fb48c828d01611f11565b9750506060611fc58c828d01611f11565b9650506080611fd68c828d01611f11565b95505060a0611fe78c828d01611f4c565b94505060c0611ff88c828d01611f4c565b93505060e06120098c828d01611f4c565b92505061010061201b8c828d01611f4c565b9150509295985092959850929598565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000612087602683611c21565b91506120928261202b565b604082019050919050565b600060208201905081810360008301526120b68161207a565b9050919050565b60006040820190506120d2600083018561180c565b6120df60208301846117a3565b9392505050565b7f72657175657374206e6f7420666f756e64000000000000000000000000000000600082015250565b600061211c601183611c21565b9150612127826120e6565b602082019050919050565b6000602082019050818103600083015261214b8161210f565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b612187816114b5565b82525050565b6000612199838361217e565b60208301905092915050565b6000602082019050919050565b60006121bd82612152565b6121c7818561215d565b93506121d28361216e565b8060005b838110156122035781516121ea888261218d565b97506121f5836121a5565b9250506001810190506121d6565b5085935050505092915050565b600060408201905061222560008301856117a3565b818103602083015261223781846121b2565b90509392505050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000612276602083611c21565b915061228182612240565b602082019050919050565b600060208201905081810360008301526122a581612269565b9050919050565b600081519050919050565b60005b838110156122d55780820151818401526020810190506122ba565b60008484015250505050565b60006122ec826122ac565b6122f68185611c21565b93506123068185602086016122b7565b61230f816114f0565b840191505092915050565b6000604082019050818103600083015261233481856122e1565b905061234360208301846117a3565b9392505050565b6000612355826114b5565b9150612360836114b5565b925082820190508082111561237857612377611e06565b5b92915050565b6000612389826114b5565b9150612394836114b5565b92508282026123a2816114b5565b915082820484148315176123b9576123b8611e06565b5b5092915050565b60006123cb826119db565b91506123d6836119db565b9250828201905060ff8111156123ef576123ee611e06565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061242f826114b5565b915061243a836114b5565b92508261244a576124496123f5565b5b828204905092915050565b60006124608261173a565b915061246b8361173a565b92508261247b5761247a6123f5565b5b828204905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052605160045260246000fdfe207e202965787465726e616c766965776f766572726964656f6e6c79436f6e666967757265644e6f7444697361626c656472657475726e73207e2074782e67617370726963653aa2646970667358221220bb454fb14b698e95c7ef137973cc0aac554f300fb34b0310d00d337469878a7564736f6c63430008140033