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