Source Code
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Latest 13 internal transactions
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 10767238 | 476 days ago | Contract Creation | 0 FRAX | |||
| 9985752 | 494 days ago | Contract Creation | 0 FRAX | |||
| 9083369 | 515 days ago | Contract Creation | 0 FRAX | |||
| 9023494 | 517 days ago | Contract Creation | 0 FRAX | |||
| 9022563 | 517 days ago | Contract Creation | 0 FRAX | |||
| 8987328 | 517 days ago | Contract Creation | 0 FRAX | |||
| 8947362 | 518 days ago | Contract Creation | 0 FRAX | |||
| 8947318 | 518 days ago | Contract Creation | 0 FRAX | |||
| 8947252 | 518 days ago | Contract Creation | 0 FRAX | |||
| 8684190 | 524 days ago | Contract Creation | 0 FRAX | |||
| 8674180 | 525 days ago | Contract Creation | 0 FRAX | |||
| 8674079 | 525 days ago | Contract Creation | 0 FRAX | |||
| 8673823 | 525 days ago | Contract Creation | 0 FRAX |
Cross-Chain Transactions
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
RevestVeFXS
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GNU-GPL v3.0 or later
pragma solidity ^0.8.0;
import "./interfaces/IAddressRegistry.sol";
import "./interfaces/IOutputReceiverV3.sol";
import "./interfaces/ITokenVault.sol";
import "./interfaces/IRevest.sol";
import "./interfaces/IFNFTHandler.sol";
import "./interfaces/ILockManager.sol";
import "./interfaces/IRewardsHandler.sol";
import "./interfaces/IVotingEscrow.sol";
import "./interfaces/IFeeReporter.sol";
import "./interfaces/IRevestVeFXS.sol";
import "./VestedEscrowSmartWallet.sol";
import "./SmartWalletWhitelistV2.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/proxy/Clones.sol";
// Libraries
import "./lib/RevestHelper.sol";
/**
* @title Revest FNFT for veFXS
* @author RobAnon
* @author Ekkila
* @author Nikola
*/
contract RevestVeFXS is IRevestVeFXS, IOutputReceiverV3, Ownable, ERC165, IFeeReporter, ReentrancyGuard {
using SafeERC20 for IERC20;
// Where to find the Revest address registry that contains info about what contracts live where
address public addressRegistry;
// Address of voting escrow contract
address public immutable VOTING_ESCROW;
// Token used for voting escrow
address public immutable TOKEN;
address public immutable REWARD_TOKEN;
// Distributor for rewards address
address[] public distributors;
// Revest Admin Account
address public adminWallet;
// Vault address
address public immutable VAULT;
// Template address for VE wallets
address public immutable TEMPLATE;
// The file which tells our frontend how to visually represent such an FNFT
string public METADATA = "https://revest.mypinata.cloud/ipfs/QmdBWbQ9AAfKQgxtz24J1ZhnzCs6PFTR99esvs6gEV1Pq2";
// Constant used for approval
uint256 private constant MAX_LOCKUP = 4 * 365 days;
uint256 private constant PRECISION = 1000;
// Performance fee
uint256 private PERFORMANCE_FEE = 100; // 10%
// Management fee
uint256 private MANAGEMENT_FEE = 5; // 0.5%
// Control variable to let all users utilize smart wallets for proxy execution
bool public globalProxyEnabled;
// Control variable to enable a given FNFT to utilize their smart wallet for proxy execution
mapping(uint256 => bool) public proxyEnabled;
// Mapping fnftId to lockId for each user
mapping(uint256 => uint128) public lockId;
// Initialize the contract with the needed valeus
constructor(address _provider, address _vE, address _distributor, address _revestAdmin) {
require(_provider != address(0), "Invalid provider address!");
require(_vE != address(0), "Invalid voting escrow address!");
require(_distributor != address(0), "Invalid distributor address!");
require(_revestAdmin != address(0), "Invalid revest admin address!");
addressRegistry = _provider;
VOTING_ESCROW = _vE;
TOKEN = IVotingEscrow(_vE).token();
REWARD_TOKEN = IVotingEscrow(_vE).token();
adminWallet = _revestAdmin;
VAULT = IAddressRegistry(_provider).getTokenVault();
distributors.push(_distributor);
VestedEscrowSmartWallet wallet = new VestedEscrowSmartWallet(_vE);
TEMPLATE = address(wallet);
}
modifier onlyVault() {
require(msg.sender == VAULT, "Only Vault Access!");
_;
}
modifier onlyRevestController() {
require(msg.sender == IAddressRegistry(addressRegistry).getRevest(), "Unauthorized Access!");
_;
}
modifier onlyTokenHolder(uint256 fnftId) {
IAddressRegistry reg = IAddressRegistry(addressRegistry);
require(IFNFTHandler(reg.getRevestFNFT()).getBalance(msg.sender, fnftId) > 0, "E064");
_;
}
// Allows core Revest contracts to make sure this contract can do what is needed
// Mandatory method
function supportsInterface(bytes4 interfaceId) public view override(ERC165, IERC165) returns (bool) {
return interfaceId == type(IOutputReceiver).interfaceId || interfaceId == type(IOutputReceiverV2).interfaceId
|| interfaceId == type(IOutputReceiverV3).interfaceId || super.supportsInterface(interfaceId);
}
// _________________________________________________________USER FUNCTION_________________________________________________________
/**
* @notice Locks the tokens for a certain period of time and mints a FNFT for the user
* @param endTime Time ends for the lock
* @param amountToLock Amount of tokens to lock
*/
function lockTokens(uint256 endTime, uint256 amountToLock) external nonReentrant returns (uint256 fnftId) {
//Taking management fee
amountToLock = _claimFee(msg.sender, amountToLock);
/// Mint FNFT
fnftId = mintFNFT(endTime);
// Lock tokens through smart wallet
(address smartWallet, VestedEscrowSmartWallet wallet) = _createWallet(fnftId);
// Transfer the tokens from the user to the smart wallet
IERC20(TOKEN).safeTransferFrom(msg.sender, smartWallet, amountToLock);
// We deposit our funds into the wallet
(uint128 index,) = wallet.createLock(amountToLock, endTime, distributors[distributors.length - 1]);
lockId[fnftId] = index;
emit DepositERC20OutputReceiver(msg.sender, TOKEN, amountToLock, fnftId, abi.encode(smartWallet));
emit DepositToken(msg.sender, fnftId, TOKEN, amountToLock, endTime);
}
/**
* @notice Extends the lockup period for a certain FNFT
* @param fnftId Current FNFT id to extend
* @param expiration New expiration time
*/
function handleTimelockExtensions(uint256 fnftId, uint256 expiration, address)
external
override
onlyRevestController
{
require(expiration - block.timestamp <= MAX_LOCKUP, "Max lockup is 4 years");
(, VestedEscrowSmartWallet wallet) = _getWallets(fnftId);
wallet.increaseUnlockTime(expiration, lockId[fnftId], distributors[distributors.length - 1]);
emit TimeLockExtension(fnftId, expiration);
}
/**
* @notice Handles additional deposits to the smart wallet for a certain FNFT
* @param fnftId Current FNFT id to deposit
* @param amountToDeposit Extra amount tokens to deposit
* @param caller Caller of the function
*/
function handleAdditionalDeposit(uint256 fnftId, uint256 amountToDeposit, uint256, address caller)
external
override
nonReentrant
onlyRevestController
{
(address smartWallet, VestedEscrowSmartWallet wallet) = _getWallets(fnftId);
amountToDeposit = _claimFee(caller, amountToDeposit);
IERC20(TOKEN).safeTransferFrom(caller, smartWallet, amountToDeposit);
wallet.increaseAmount(amountToDeposit, lockId[fnftId], distributors[distributors.length - 1]);
emit DepositERC20OutputReceiver(caller, TOKEN, amountToDeposit, fnftId, abi.encode(smartWallet));
emit DepositAdditionalToken(fnftId, TOKEN, amountToDeposit);
}
/**
* @notice Claims the yield for a certain FNFT
* @param fnftId Id of FNFT to earn yield on
*/
function triggerOutputReceiverUpdate(uint256 fnftId, bytes memory) external override onlyTokenHolder(fnftId) {
_claimAllRewards(msg.sender, fnftId);
}
/**
* @notice Claimed yields and withdraw locked tokens
* @param fnftId Id of FNFT to withdraw
* @param owner Owner of the FNFT
*/
function receiveRevestOutput(uint256 fnftId, address, address payable owner, uint256)
external
override
onlyVault
nonReentrant
{
(address smartWallet, VestedEscrowSmartWallet wallet) = _getWallets(fnftId);
// Claim fee and distribute output
_claimAllRewards(owner, fnftId);
// Withdraw the fund
wallet.withdraw(lockId[fnftId]);
uint256 balance = IERC20(TOKEN).balanceOf(address(this));
IERC20(TOKEN).safeTransfer(owner, balance);
emit WithdrawERC20OutputReceiver(owner, TOKEN, balance, fnftId, abi.encode(smartWallet));
}
/**
* @notice Allows you to proxy execute a function on the smart wallet, this does not include moving REWARD_TOKEN
* @param fnftId Id of FNFT to withdraw
* @param destination Address of the contract to call
* @param data Data to send to the contract
*/
function proxyExecute(uint256 fnftId, address destination, bytes memory data)
external
payable
onlyTokenHolder(fnftId)
returns (bytes memory dataOut)
{
require(globalProxyEnabled || proxyEnabled[fnftId], "Proxy access not enabled!");
require(destination != REWARD_TOKEN, "Proxy call does not allow interaction with REWARD_TOKEN");
for (uint256 i = 0; i < distributors.length; i++) {
require(destination != distributors[i], "Proxy call does not allow interaction with DISTRIBUTOR");
}
(, VestedEscrowSmartWallet wallet) = _getWallets(fnftId);
dataOut = wallet.proxyExecute{value: msg.value}(destination, data);
}
/**
* @notice A function created to claim REWARD TOKENS in case of any left over tokens in smart wallet
* @param fnftId Id of FNFT to withdraw
* @param owner Owner of the FNFT
*/
function claimRewards(uint256 fnftId, address owner) external onlyTokenHolder(fnftId) nonReentrant {
_claimAllRewards(owner, fnftId);
}
/**
* @notice A function for FNFT owner to checkpoint their positions on a distributor
* @param fnftId Id of FNFT to withdraw
*/
function checkpoint(uint256 fnftId, address distritbutor) external onlyTokenHolder(fnftId) nonReentrant {
(, VestedEscrowSmartWallet wallet) = _getWallets(fnftId);
wallet.checkpoint(distritbutor);
}
// _________________________________________________________ADMIN FUNCTION_________________________________________________________
function setAddressRegistry(address addressRegistry_) external override onlyOwner {
require(addressRegistry_ != address(0), "Error: Invalid address registry address!");
addressRegistry = addressRegistry_;
}
function setRevestAdmin(address _admin) external onlyOwner {
require(_admin != address(0), "Error: Invalid admin address!");
adminWallet = _admin;
}
function setMetadata(string memory _meta) external onlyOwner {
METADATA = _meta;
}
function setGlobalProxyEnabled(bool enable) external onlyOwner {
globalProxyEnabled = enable;
}
function setProxyStatusForFNFT(uint256 fnftId, bool status) external onlyOwner {
proxyEnabled[fnftId] = status;
}
function setPerformanceFee(uint256 fee) external onlyOwner {
require(fee <= 1000, "Performance fee must be less than 100%");
PERFORMANCE_FEE = fee;
}
function setManagementFee(uint256 fee) external onlyOwner {
require(fee <= 1000, "Management fee must be less than 100%");
MANAGEMENT_FEE = fee;
}
function addDistributor(address distributor) external onlyOwner {
require(distributor != address(0), "Invalid distributor address!");
distributors.push(distributor);
}
/// If funds are mistakenly sent to smart wallets, this will allow the owner to assist in rescue
function rescueNativeFunds() external onlyOwner {
payable(msg.sender).transfer(address(this).balance);
}
/// Under no circumstances should this contract ever contain ERC-20 tokens at the end of a transaction
/// If it does, someone has mistakenly sent funds to the contract, and this function can rescue their tokens
function rescueERC20(address token) external onlyOwner {
uint256 amount = IERC20(token).balanceOf(address(this));
IERC20(token).safeTransfer(msg.sender, amount);
}
/// View Functions
function getCustomMetadata(uint256) external view override returns (string memory) {
return METADATA;
}
// Will give balance in veFXS
function getValue(uint256 fnftId) public view override returns (uint256) {
return IVotingEscrow(VOTING_ESCROW).balanceOf(
Clones.predictDeterministicAddress(TEMPLATE, keccak256(abi.encode(TOKEN, fnftId)))
);
}
// Must always be in native token
function getAsset(uint256) external view override returns (address) {
return VOTING_ESCROW;
}
function getOutputDisplayValues(uint256 fnftId) external view override returns (bytes memory displayData) {
//calculate yield output for certain FNFT
uint256 yield = IYieldDistributor(distributors[distributors.length - 1]).earned(
Clones.predictDeterministicAddress(TEMPLATE, keccak256(abi.encode(TOKEN, fnftId)))
);
bool hasRewards = yield > 0;
string memory rewardsDesc;
if (hasRewards) {
string memory par1 = string(abi.encodePacked(RevestHelper.getName(REWARD_TOKEN), ": "));
string memory par2 = string(
abi.encodePacked(
RevestHelper.amountToDecimal(yield, REWARD_TOKEN),
" [",
RevestHelper.getTicker(REWARD_TOKEN),
"] Tokens Available"
)
);
rewardsDesc = string(abi.encodePacked(par1, par2));
}
address smartWallet = getAddressForFNFT(fnftId);
uint256 maxExtension = (block.timestamp / (1 weeks)) * (1 weeks) + MAX_LOCKUP;
(int128 lockedBalance,) = IVotingEscrow(VOTING_ESCROW).lockedByIndex(smartWallet, lockId[fnftId]);
displayData = abi.encode(smartWallet, rewardsDesc, hasRewards, maxExtension, TOKEN, lockedBalance);
}
function getAddressRegistry() external view override returns (address) {
return addressRegistry;
}
function getFlatWeiFee(address) external view override returns (uint256) {
return PERFORMANCE_FEE;
}
function getERC20Fee(address) external view override returns (uint256) {
return MANAGEMENT_FEE;
}
function getAddressForFNFT(uint256 fnftId) public view returns (address smartWallet) {
smartWallet = Clones.predictDeterministicAddress(TEMPLATE, keccak256(abi.encode(TOKEN, fnftId)));
}
// _________________________________________________________HELPER FUNCTIONS_______________________________________________________
function mintFNFT(uint256 endTime) private returns (uint256 fnftId) {
IRevest.FNFTConfig memory fnftConfig;
// Want FNFT to be extendable and support multiple deposits
fnftConfig.isMulti = true;
fnftConfig.maturityExtension = true;
// Will result in the asset being sent back to this contract upon withdrawal
// Results solely in a callback
fnftConfig.pipeToContract = address(this);
// Set these two arrays according to Revest specifications to say
// Who gets these FNFTs and how many copies of them we should create
address[] memory recipients = new address[](1);
recipients[0] = _msgSender();
uint256[] memory quantities = new uint256[](1);
quantities[0] = 1;
address revest = IAddressRegistry(addressRegistry).getRevest();
fnftId = IRevest(revest).mintTimeLock(endTime, recipients, quantities, fnftConfig);
}
function _getWallets(uint256 fnftId) private view returns (address smartWallet, VestedEscrowSmartWallet wallet) {
smartWallet = Clones.predictDeterministicAddress(TEMPLATE, keccak256(abi.encode(TOKEN, fnftId)));
wallet = VestedEscrowSmartWallet(smartWallet);
}
function _createWallet(uint256 fnftId) private returns (address smartWallet, VestedEscrowSmartWallet wallet) {
smartWallet = Clones.cloneDeterministic(TEMPLATE, keccak256(abi.encode(TOKEN, fnftId)));
wallet = VestedEscrowSmartWallet(smartWallet);
}
function _claimAllRewards(address owner, uint256 fnftId) private {
(, VestedEscrowSmartWallet wallet) = _getWallets(fnftId);
for (uint256 i = 0; i <= distributors.length - 1; i++) {
wallet.claimRewards(owner, adminWallet, PERFORMANCE_FEE, distributors[i]);
}
}
function _claimFee(address owner, uint256 amountToLock) private returns (uint256 amountAfterFee) {
uint256 fxsFee = (amountToLock * MANAGEMENT_FEE) / PRECISION;
if (fxsFee > 0) {
IERC20(TOKEN).safeTransferFrom(owner, adminWallet, fxsFee);
amountAfterFee = amountToLock - fxsFee;
emit FeeCollection(address(TOKEN), fxsFee);
}
}
// _________________________________________________________NOT APPLICABLE_________________________________________________________
function handleSplitOperation(uint256 fnftId, uint256[] memory proportions, uint256 quantity, address caller)
external
override
{
revert("Not applicable!");
}
function handleFNFTRemaps(uint256, uint256[] memory, address, bool) external pure override {
revert("Not applicable!");
}
function receiveSecondaryCallback(
uint256 fnftId,
address payable owner,
uint256 quantity,
IRevest.FNFTConfig memory config,
bytes memory args
) external payable override {
require(false, "Not applicable!");
}
}// SPDX-License-Identifier: GNU-GPL v3.0 or later
pragma solidity >=0.8.0;
/**
* @title Provider interface for Revest FNFTs
* @dev
*
*/
interface IAddressRegistry {
function initialize(
address lock_manager_,
address liquidity_,
address revest_token_,
address token_vault_,
address revest_,
address fnft_,
address metadata_,
address admin_,
address rewards_
) external;
function getAdmin() external view returns (address);
function setAdmin(address admin) external;
function getLockManager() external view returns (address);
function setLockManager(address manager) external;
function getTokenVault() external view returns (address);
function setTokenVault(address vault) external;
function getRevestFNFT() external view returns (address);
function setRevestFNFT(address fnft) external;
function getMetadataHandler() external view returns (address);
function setMetadataHandler(address metadata) external;
function getRevest() external view returns (address);
function setRevest(address revest) external;
function getDEX(uint256 index) external view returns (address);
function setDex(address dex) external;
function getRevestToken() external view returns (address);
function setRevestToken(address token) external;
function getRewardsHandler() external view returns (address);
function setRewardsHandler(address esc) external;
function getAddress(bytes32 id) external view returns (address);
function getLPs() external view returns (address);
function setLPs(address liquidToken) external;
}// SPDX-License-Identifier: GNU-GPL v3.0 or later
pragma solidity >=0.8.0;
import "./IOutputReceiverV2.sol";
/**
* @title Provider interface for Revest FNFTs
*/
interface IOutputReceiverV3 is IOutputReceiverV2 {
event DepositERC20OutputReceiver(
address indexed mintTo, address indexed token, uint256 amountTokens, uint256 indexed fnftId, bytes extraData
);
event DepositERC721OutputReceiver(
address indexed mintTo, address indexed token, uint256[] tokenIds, uint256 indexed fnftId, bytes extraData
);
event DepositERC1155OutputReceiver(
address indexed mintTo,
address indexed token,
uint256 tokenId,
uint256 amountTokens,
uint256 indexed fnftId,
bytes extraData
);
event WithdrawERC20OutputReceiver(
address indexed caller, address indexed token, uint256 amountTokens, uint256 indexed fnftId, bytes extraData
);
event WithdrawERC721OutputReceiver(
address indexed caller, address indexed token, uint256[] tokenIds, uint256 indexed fnftId, bytes extraData
);
event WithdrawERC1155OutputReceiver(
address indexed caller,
address indexed token,
uint256 tokenId,
uint256 amountTokens,
uint256 indexed fnftId,
bytes extraData
);
function handleTimelockExtensions(uint256 fnftId, uint256 expiration, address caller) external;
function handleAdditionalDeposit(uint256 fnftId, uint256 amountToDeposit, uint256 quantity, address caller)
external;
function handleSplitOperation(uint256 fnftId, uint256[] memory proportions, uint256 quantity, address caller)
external;
}// SPDX-License-Identifier: GNU-GPL v3.0 or later
pragma solidity >=0.8.0;
import "./IRevest.sol";
interface ITokenVault {
function createFNFT(uint256 fnftId, IRevest.FNFTConfig memory fnftConfig, uint256 quantity, address from)
external;
function withdrawToken(uint256 fnftId, uint256 quantity, address user) external;
function depositToken(uint256 fnftId, uint256 amount, uint256 quantity) external;
function cloneFNFTConfig(IRevest.FNFTConfig memory old) external returns (IRevest.FNFTConfig memory);
function mapFNFTToToken(uint256 fnftId, IRevest.FNFTConfig memory fnftConfig) external;
function handleMultipleDeposits(uint256 fnftId, uint256 newFNFTId, uint256 amount) external;
function splitFNFT(uint256 fnftId, uint256[] memory newFNFTIds, uint256[] memory proportions, uint256 quantity)
external;
function getFNFT(uint256 fnftId) external view returns (IRevest.FNFTConfig memory);
function getFNFTCurrentValue(uint256 fnftId) external view returns (uint256);
function getNontransferable(uint256 fnftId) external view returns (bool);
function getSplitsRemaining(uint256 fnftId) external view returns (uint256);
}// SPDX-License-Identifier: GNU-GPL v3.0 or later
pragma solidity >=0.8.0;
interface IRevest {
event FNFTTimeLockMinted(
address indexed asset,
address indexed from,
uint256 indexed fnftId,
uint256 endTime,
uint256[] quantities,
FNFTConfig fnftConfig
);
event FNFTValueLockMinted(
address indexed asset,
address indexed from,
uint256 indexed fnftId,
address compareTo,
address oracleDispatch,
uint256[] quantities,
FNFTConfig fnftConfig
);
event FNFTAddressLockMinted(
address indexed asset,
address indexed from,
uint256 indexed fnftId,
address trigger,
uint256[] quantities,
FNFTConfig fnftConfig
);
event FNFTWithdrawn(address indexed from, uint256 indexed fnftId, uint256 indexed quantity);
event FNFTSplit(address indexed from, uint256[] indexed newFNFTId, uint256[] indexed proportions, uint256 quantity);
event FNFTUnlocked(address indexed from, uint256 indexed fnftId);
event FNFTMaturityExtended(address indexed from, uint256 indexed fnftId, uint256 indexed newExtendedTime);
event FNFTAddionalDeposited(
address indexed from, uint256 indexed newFNFTId, uint256 indexed quantity, uint256 amount
);
struct FNFTConfig {
address asset; // The token being stored
address pipeToContract; // Indicates if FNFT will pipe to another contract
uint256 depositAmount; // How many tokens
uint256 depositMul; // Deposit multiplier
uint256 split; // Number of splits remaining
uint256 depositStopTime; //
bool maturityExtension;
// Maturity extensions remaining
bool isMulti; //
bool nontransferrable; // False by default (transferrable) //
}
// Refers to the global balance for an ERC20, encompassing possibly many FNFTs
struct TokenTracker {
uint256 lastBalance;
uint256 lastMul;
}
enum LockType {
DoesNotExist,
TimeLock,
ValueLock,
AddressLock
}
struct LockParam {
address addressLock;
uint256 timeLockExpiry;
LockType lockType;
ValueLock valueLock;
}
struct Lock {
address addressLock;
LockType lockType;
ValueLock valueLock;
uint256 timeLockExpiry;
uint256 creationTime;
bool unlocked;
}
struct ValueLock {
address asset;
address compareTo;
address oracle;
uint256 unlockValue;
bool unlockRisingEdge;
}
function mintTimeLock(
uint256 endTime,
address[] memory recipients,
uint256[] memory quantities,
IRevest.FNFTConfig memory fnftConfig
) external payable returns (uint256);
function mintValueLock(
address primaryAsset,
address compareTo,
uint256 unlockValue,
bool unlockRisingEdge,
address oracleDispatch,
address[] memory recipients,
uint256[] memory quantities,
IRevest.FNFTConfig memory fnftConfig
) external payable returns (uint256);
function mintAddressLock(
address trigger,
bytes memory arguments,
address[] memory recipients,
uint256[] memory quantities,
IRevest.FNFTConfig memory fnftConfig
) external payable returns (uint256);
function withdrawFNFT(uint256 tokenUID, uint256 quantity) external;
function unlockFNFT(uint256 tokenUID) external;
function splitFNFT(uint256 fnftId, uint256[] memory proportions, uint256 quantity)
external
returns (uint256[] memory newFNFTIds);
function depositAdditionalToFNFT(uint256 fnftId, uint256 amount, uint256 quantity) external returns (uint256);
function extendFNFTMaturity(uint256 fnftId, uint256 endTime) external returns (uint256);
function setFlatWeiFee(uint256 wethFee) external;
function setERC20Fee(uint256 erc20) external;
function getFlatWeiFee() external view returns (uint256);
function getERC20Fee() external view returns (uint256);
}// SPDX-License-Identifier: GNU-GPL v3.0 or later
pragma solidity >=0.8.0;
interface IFNFTHandler {
function mint(address account, uint256 id, uint256 amount, bytes memory data) external;
function mintBatchRec(
address[] memory recipients,
uint256[] memory quantities,
uint256 id,
uint256 newSupply,
bytes memory data
) external;
function mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) external;
function setURI(string memory newuri) external;
function burn(address account, uint256 id, uint256 amount) external;
function burnBatch(address account, uint256[] memory ids, uint256[] memory amounts) external;
function getBalance(address tokenHolder, uint256 id) external view returns (uint256);
function getSupply(uint256 fnftId) external view returns (uint256);
function getNextId() external view returns (uint256);
}// SPDX-License-Identifier: GNU-GPL v3.0 or later
pragma solidity >=0.8.0;
import "./IRevest.sol";
interface ILockManager {
function createLock(uint256 fnftId, IRevest.LockParam memory lock) external returns (uint256);
function getLock(uint256 lockId) external view returns (IRevest.Lock memory);
function fnftIdToLockId(uint256 fnftId) external view returns (uint256);
function fnftIdToLock(uint256 fnftId) external view returns (IRevest.Lock memory);
function pointFNFTToLock(uint256 fnftId, uint256 lockId) external;
function lockTypes(uint256 tokenId) external view returns (IRevest.LockType);
function unlockFNFT(uint256 fnftId, address sender) external returns (bool);
function getLockMaturity(uint256 fnftId) external view returns (bool);
}// SPDX-License-Identifier: GNU-GPL v3.0 or later
pragma solidity >=0.8.0;
interface IRewardsHandler {
struct UserBalance {
uint256 allocPoint; // Allocation points
uint256 lastMul;
}
function receiveFee(address token, uint256 amount) external;
function updateLPShares(uint256 fnftId, uint256 newShares) external;
function updateBasicShares(uint256 fnftId, uint256 newShares) external;
function getAllocPoint(uint256 fnftId, address token, bool isBasic) external view returns (uint256);
function claimRewards(uint256 fnftId, address caller) external returns (uint256);
function setStakingContract(address stake) external;
function getRewards(uint256 fnftId, address token) external view returns (uint256);
}// SPDX-License-Identifier: GNU-GPL v3.0 or later
pragma solidity >=0.8.0;
import "./IRegistryProvider.sol";
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
/**
* @title Provider interface for Revest FNFTs
*/
interface IVotingEscrow {
struct Point {
int128 bias;
int128 slope;
uint256 ts;
uint256 blk;
}
function createLock(address _addr, uint256 _value, uint128 _unlock_time) external returns (uint128, uint256);
function increaseAmount(uint256 _value, uint128 _lockIndex) external;
function increaseUnlockTime(uint128 _unlock_time, uint128 _lockIndex) external;
function withdraw(uint128 _lockIndex) external;
function token() external view returns (address tok);
function lockedByIndex(address _addr, uint128 index) external view returns (int128 amount, uint256 end);
function balanceOf(address _addr) external view returns (uint256 balance);
}// SPDX-License-Identifier: GNU-GPL v3.0 or later
pragma solidity >=0.8.0;
interface IFeeReporter {
function getFlatWeiFee(address asset) external view returns (uint256);
function getERC20Fee(address asset) external view returns (uint256);
event FeeCollection(address indexed token, uint256 indexed amount);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IRevestVeFXS {
event DepositToken(
address indexed mintTo, uint256 indexed fnftId, address indexed token, uint256 amountTokens, uint256 expiration
);
event DepositAdditionalToken(uint256 indexed fnftId, address indexed token, uint256 amountTokens);
event TimeLockExtension(uint256 indexed fnftId, uint256 newExpiration);
event ClaimYield(uint256 indexed fnftId, uint256 indexed token, uint256 amountTokens);
}// SPDX-License-Identifier: GNU-GPL v3.0 or later
import "./interfaces/IVotingEscrow.sol";
import "./interfaces/IRewardsHandler.sol";
import "./interfaces/IYieldDistributor.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "../lib/forge-std/src/console.sol";
pragma solidity ^0.8.0;
/// @author RobAnon
contract VestedEscrowSmartWallet {
using SafeERC20 for IERC20;
uint256 private constant MAX_INT = type(uint256).max;
address private immutable MASTER;
address private immutable LOCK_TOKEN;
address private immutable REWARD_TOKEN;
address private immutable VOTING_ESCROW;
uint256 private constant PERCENTAGE = 1000;
constructor(address _votingEscrow) {
MASTER = msg.sender;
VOTING_ESCROW = _votingEscrow;
LOCK_TOKEN = IVotingEscrow(_votingEscrow).token();
REWARD_TOKEN = IVotingEscrow(_votingEscrow).token();
}
modifier onlyMaster() {
require(msg.sender == MASTER, "Unauthorized!");
_;
}
function createLock(uint256 value, uint256 unlockTime, address distributor)
external
onlyMaster
returns (uint128 _index, uint256 _newLockId)
{
// Single-use approval system
if (IERC20(LOCK_TOKEN).allowance(address(this), VOTING_ESCROW) != MAX_INT) {
IERC20(LOCK_TOKEN).approve(VOTING_ESCROW, MAX_INT);
}
// Create the lock
(_index, _newLockId) = IVotingEscrow(VOTING_ESCROW).createLock(address(this), value, uint128(unlockTime));
IYieldDistributor(distributor).checkpoint();
}
function increaseAmount(uint256 value, uint128 lockId, address distributor) external onlyMaster {
IVotingEscrow(VOTING_ESCROW).increaseAmount(value, lockId);
IYieldDistributor(distributor).checkpoint();
}
function increaseUnlockTime(uint256 unlockTime, uint128 lockId, address distributor) external onlyMaster {
IVotingEscrow(VOTING_ESCROW).increaseUnlockTime(uint128(unlockTime), lockId);
IYieldDistributor(distributor).checkpoint();
}
/**
* @notice Withdraws the locked tokens
* @dev The lock id is required to withdraw tokens since new veFXS system requires specifying the lock id.
* @dev Lock id is now managed within our Revest VeFXS contract
* @param lockId The lock id to withdraw from
*/
function withdraw(uint128 lockId) external onlyMaster {
IVotingEscrow(VOTING_ESCROW).withdraw(lockId);
uint256 tokenBalance = IERC20(LOCK_TOKEN).balanceOf(address(this));
IERC20(LOCK_TOKEN).safeTransfer(MASTER, tokenBalance);
}
/**
* @notice Claims rewards from yield distributor and distributes them to the FNFT owner
* @param caller Caller of the function
* @param adminWallet Address receiving the performance fee
* @param performanceFee Percent of the rewards to be collected as fee
* @param distributor Address of the yield distributor
*/
function claimRewards(
address caller,
address adminWallet,
uint256 performanceFee,
address distributor //address that receives the fee
) external onlyMaster returns (uint256 reward) {
// Claim yield from yieldDistributor
reward = IYieldDistributor(distributor).getYield();
// Performance Fee Collection
uint256 tokenBalance = IERC20(REWARD_TOKEN).balanceOf(address(this));
uint256 fee = (tokenBalance * performanceFee) / PERCENTAGE;
tokenBalance -= fee;
IERC20(REWARD_TOKEN).safeTransfer(adminWallet, fee);
emit FeeCollection(REWARD_TOKEN, fee);
// Distritbute yield claim
IERC20(REWARD_TOKEN).safeTransfer(caller, tokenBalance);
}
function checkpoint(address distributor) external onlyMaster {
IYieldDistributor(distributor).checkpoint();
}
/// Proxy function to send arbitrary messages. Useful for delegating votes and similar activities
function proxyExecute(address destination, bytes memory data)
external
payable
onlyMaster
returns (bytes memory dataOut)
{
(bool success, bytes memory dataTemp) = destination.call{value: msg.value}(data);
require(success, "Proxy call failed!");
dataOut = dataTemp;
}
event FeeCollection(address indexed token, uint256 indexed amount);
}// SPDX-License-Identifier: GNU-GPL v3.0 or later
pragma solidity ^0.8.0;
interface SmartWalletChecker {
function check(address) external view returns (bool);
}
/// @author RobAnon
contract SmartWalletWhitelistV2 {
mapping(address => bool) public wallets;
bytes32 public constant ADMIN = "ADMIN";
bytes32 public constant SUPER_ADMIN = "SUPER_ADMIN";
mapping(address => bytes32) public roles;
address public checker;
address public future_checker;
event ApproveWallet(address);
event RevokeWallet(address);
constructor(address _admin) {
roles[_admin] = ADMIN;
roles[msg.sender] = SUPER_ADMIN;
}
function commitSetChecker(address _checker) external {
require(isAdmin(msg.sender), "!admin");
future_checker = _checker;
}
function changeAdmin(address _admin, bool validAdmin) external {
require(isAdmin(msg.sender), "!admin");
require(!isSuperAdmin(_admin), "!auth"); // Overwrite protection
if (validAdmin) {
roles[_admin] = ADMIN;
} else {
roles[_admin] = 0x0;
}
}
function transferSuperAdmin(address _newAdmin) external {
require(isSuperAdmin(msg.sender), "!sAdmin");
roles[msg.sender] = 0x0;
roles[_newAdmin] = SUPER_ADMIN;
}
function applySetChecker() external {
require(isAdmin(msg.sender), "!admin");
checker = future_checker;
}
function approveWallet(address _wallet) public {
require(isAdmin(msg.sender), "!admin");
wallets[_wallet] = true;
emit ApproveWallet(_wallet);
}
function batchApproveWallets(address[] memory _wallets) public {
require(isAdmin(msg.sender), "!admin");
for (uint256 i = 0; i < _wallets.length; i++) {
wallets[_wallets[i]] = true;
emit ApproveWallet(_wallets[i]);
}
}
function revokeWallet(address _wallet) external {
require(isAdmin(msg.sender), "!admin");
wallets[_wallet] = false;
emit RevokeWallet(_wallet);
}
function check(address _wallet) external view returns (bool) {
bool _check = wallets[_wallet];
if (_check) {
return _check;
} else {
if (checker != address(0)) {
return SmartWalletChecker(checker).check(_wallet);
}
}
return false;
}
function isAdmin(address checkAdd) internal view returns (bool valid) {
valid = roles[checkAdd] == ADMIN || roles[checkAdd] == SUPER_ADMIN;
}
function isSuperAdmin(address checkAdd) internal view returns (bool valid) {
valid = roles[checkAdd] == SUPER_ADMIN;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and make it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
// On the first call to nonReentrant, _notEntered will be true
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
// Return data is optional
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}// SPDX-License-Identifier: MIT
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() {
_setOwner(_msgSender());
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_setOwner(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");
_setOwner(newOwner);
}
function _setOwner(address newOwner) private {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for
* deploying minimal proxy contracts, also known as "clones".
*
* > To simply and cheaply clone contract functionality in an immutable way, this standard specifies
* > a minimal bytecode implementation that delegates all calls to a known, fixed address.
*
* The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`
* (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the
* deterministic method.
*
* _Available since v3.4._
*/
library Clones {
/**
* @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
*
* This function uses the create opcode, which should never revert.
*/
function clone(address implementation) internal returns (address instance) {
assembly {
let ptr := mload(0x40)
mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
mstore(add(ptr, 0x14), shl(0x60, implementation))
mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
instance := create(0, ptr, 0x37)
}
require(instance != address(0), "ERC1167: create failed");
}
/**
* @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
*
* This function uses the create2 opcode and a `salt` to deterministically deploy
* the clone. Using the same `implementation` and `salt` multiple time will revert, since
* the clones cannot be deployed twice at the same address.
*/
function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {
assembly {
let ptr := mload(0x40)
mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
mstore(add(ptr, 0x14), shl(0x60, implementation))
mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
instance := create2(0, ptr, 0x37, salt)
}
require(instance != address(0), "ERC1167: create2 failed");
}
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
*/
function predictDeterministicAddress(
address implementation,
bytes32 salt,
address deployer
) internal pure returns (address predicted) {
assembly {
let ptr := mload(0x40)
mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
mstore(add(ptr, 0x14), shl(0x60, implementation))
mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf3ff00000000000000000000000000000000)
mstore(add(ptr, 0x38), shl(0x60, deployer))
mstore(add(ptr, 0x4c), salt)
mstore(add(ptr, 0x6c), keccak256(ptr, 0x37))
predicted := keccak256(add(ptr, 0x37), 0x55)
}
}
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
*/
function predictDeterministicAddress(address implementation, bytes32 salt)
internal
view
returns (address predicted)
{
return predictDeterministicAddress(implementation, salt, address(this));
}
}// SPDX-License-Identifier: GNU-GPL v3.0 or later
pragma solidity ^0.8.0;
import "../interfaces/ITokenVault.sol";
import "../interfaces/ILockManager.sol";
import "../interfaces/IRevest.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
library RevestHelper {
function boolToString(bool arg) internal pure returns (string memory boolean) {
boolean = arg ? "true" : "false";
}
function getLockType(IRevest.LockType lock) internal pure returns (string memory lockType) {
if (lock == IRevest.LockType.TimeLock) {
lockType = "Time";
}
if (lock == IRevest.LockType.TimeLock) {
lockType = "Value";
}
if (lock == IRevest.LockType.TimeLock) {
lockType = "Address";
}
}
function getTicker(address asset) internal view returns (string memory ticker) {
try IERC20Metadata(asset).symbol() returns (string memory tick) {
ticker = tick;
} catch {
ticker = "???";
}
}
function getName(address asset) internal view returns (string memory ticker) {
try IERC20Metadata(asset).name() returns (string memory tick) {
ticker = tick;
} catch {
ticker = "Unknown Token";
}
}
function amountToDecimal(uint256 amt, address asset) internal view returns (string memory decStr) {
uint8 decimals;
try IERC20Metadata(asset).decimals() returns (uint8 dec) {
decimals = dec;
} catch {
decimals = 18;
}
decStr = decimalString(amt, decimals);
}
function toString(uint256 _i) internal pure returns (string memory _uintAsString) {
if (_i == 0) {
return "0";
}
uint256 j = _i;
uint256 len;
while (j != 0) {
len++;
j /= 10;
}
bytes memory bstr = new bytes(len);
uint256 k = len;
while (_i != 0) {
k = k - 1;
uint8 temp = (48 + uint8(_i - _i / 10 * 10));
bytes1 b1 = bytes1(temp);
bstr[k] = b1;
_i /= 10;
}
return string(bstr);
}
function decimalString(uint256 number, uint8 decimals) internal pure returns (string memory) {
uint256 tenPowDecimals = 10 ** decimals;
uint256 temp = number;
uint8 digits;
uint8 numSigfigs;
while (temp != 0) {
if (numSigfigs > 0) {
// count all digits preceding least significant figure
numSigfigs++;
} else if (temp % 10 != 0) {
numSigfigs++;
}
digits++;
temp /= 10;
}
DecimalStringParams memory params;
if ((digits - numSigfigs) >= decimals) {
// no decimals, ensure we preserve all trailing zeros
params.sigfigs = number / tenPowDecimals;
params.sigfigIndex = digits - decimals;
params.bufferLength = params.sigfigIndex;
} else {
// chop all trailing zeros for numbers with decimals
params.sigfigs = number / (10 ** (digits - numSigfigs));
if (tenPowDecimals > number) {
// number is less tahn one
// in this case, there may be leading zeros after the decimal place
// that need to be added
// offset leading zeros by two to account for leading '0.'
params.zerosStartIndex = 2;
params.zerosEndIndex = decimals - digits + 2;
params.sigfigIndex = numSigfigs + params.zerosEndIndex;
params.bufferLength = params.sigfigIndex;
params.isLessThanOne = true;
} else {
// In this case, there are digits before and
// after the decimal place
params.sigfigIndex = numSigfigs + 1;
params.decimalIndex = digits - decimals + 1;
}
}
params.bufferLength = params.sigfigIndex;
return generateDecimalString(params);
}
// With modifications, the below taken
// from https://github.com/Uniswap/uniswap-v3-periphery/blob/main/contracts/libraries/NFTDescriptor.sol#L189-L231
struct DecimalStringParams {
// significant figures of decimal
uint256 sigfigs;
// length of decimal string
uint8 bufferLength;
// ending index for significant figures (funtion works backwards when copying sigfigs)
uint8 sigfigIndex;
// index of decimal place (0 if no decimal)
uint8 decimalIndex;
// start index for trailing/leading 0's for very small/large numbers
uint8 zerosStartIndex;
// end index for trailing/leading 0's for very small/large numbers
uint8 zerosEndIndex;
// true if decimal number is less than one
bool isLessThanOne;
}
function generateDecimalString(DecimalStringParams memory params) private pure returns (string memory) {
bytes memory buffer = new bytes(params.bufferLength);
if (params.isLessThanOne) {
buffer[0] = "0";
buffer[1] = ".";
}
// add leading/trailing 0's
for (uint256 zerosCursor = params.zerosStartIndex; zerosCursor < params.zerosEndIndex; zerosCursor++) {
buffer[zerosCursor] = bytes1(uint8(48));
}
// add sigfigs
while (params.sigfigs > 0) {
if (params.decimalIndex > 0 && params.sigfigIndex == params.decimalIndex) {
buffer[--params.sigfigIndex] = ".";
}
buffer[--params.sigfigIndex] = bytes1(uint8(uint256(48) + (params.sigfigs % 10)));
params.sigfigs /= 10;
}
return string(buffer);
}
}// SPDX-License-Identifier: GNU-GPL v3.0 or later
pragma solidity >=0.8.0;
import "./IOutputReceiver.sol";
import "./IRevest.sol";
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
/**
* @title Provider interface for Revest FNFTs
*/
interface IOutputReceiverV2 is IOutputReceiver {
// Future proofing for secondary callbacks during withdrawal
// Could just use triggerOutputReceiverUpdate and call withdrawal function
// But deliberately using reentry is poor form and reminds me too much of OAuth 2.0
function receiveSecondaryCallback(
uint256 fnftId,
address payable owner,
uint256 quantity,
IRevest.FNFTConfig memory config,
bytes memory args
) external payable;
// Allows for similar function to address lock, updating state while still locked
// Called by the user directly
function triggerOutputReceiverUpdate(
uint256 fnftId,
bytes memory args
) external;
// This function should only ever be called when a split or additional deposit has occurred
function handleFNFTRemaps(
uint256 fnftId,
uint256[] memory newFNFTIds,
address caller,
bool cleanup
) external;
}// SPDX-License-Identifier: GNU-GPL v3.0 or later
pragma solidity ^0.8.0;
interface IRegistryProvider {
function setAddressRegistry(address revest) external;
function getAddressRegistry() external view returns (address);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: GNU-GPL v3.0 or later
pragma solidity >=0.8.0;
interface IYieldDistributor {
function earned(address account) external view returns (uint256);
function getYield() external returns (uint256 yield0);
function yields(address) external view returns (uint256 yield0);
function checkpoint() external;
function checkpointOtherUser(address user_addr) external;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;
library console {
address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);
function _sendLogPayload(bytes memory payload) private view {
uint256 payloadLength = payload.length;
address consoleAddress = CONSOLE_ADDRESS;
/// @solidity memory-safe-assembly
assembly {
let payloadStart := add(payload, 32)
let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)
}
}
function log() internal view {
_sendLogPayload(abi.encodeWithSignature("log()"));
}
function logInt(int p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(int)", p0));
}
function logUint(uint p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint)", p0));
}
function logString(string memory p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string)", p0));
}
function logBool(bool p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
}
function logAddress(address p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address)", p0));
}
function logBytes(bytes memory p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes)", p0));
}
function logBytes1(bytes1 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0));
}
function logBytes2(bytes2 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0));
}
function logBytes3(bytes3 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0));
}
function logBytes4(bytes4 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0));
}
function logBytes5(bytes5 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0));
}
function logBytes6(bytes6 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0));
}
function logBytes7(bytes7 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0));
}
function logBytes8(bytes8 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0));
}
function logBytes9(bytes9 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0));
}
function logBytes10(bytes10 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0));
}
function logBytes11(bytes11 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0));
}
function logBytes12(bytes12 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0));
}
function logBytes13(bytes13 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0));
}
function logBytes14(bytes14 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0));
}
function logBytes15(bytes15 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0));
}
function logBytes16(bytes16 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0));
}
function logBytes17(bytes17 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0));
}
function logBytes18(bytes18 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0));
}
function logBytes19(bytes19 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0));
}
function logBytes20(bytes20 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0));
}
function logBytes21(bytes21 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0));
}
function logBytes22(bytes22 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0));
}
function logBytes23(bytes23 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0));
}
function logBytes24(bytes24 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0));
}
function logBytes25(bytes25 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0));
}
function logBytes26(bytes26 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0));
}
function logBytes27(bytes27 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0));
}
function logBytes28(bytes28 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0));
}
function logBytes29(bytes29 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0));
}
function logBytes30(bytes30 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0));
}
function logBytes31(bytes31 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0));
}
function logBytes32(bytes32 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0));
}
function log(uint p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint)", p0));
}
function log(string memory p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string)", p0));
}
function log(bool p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
}
function log(address p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address)", p0));
}
function log(uint p0, uint p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint)", p0, p1));
}
function log(uint p0, string memory p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string)", p0, p1));
}
function log(uint p0, bool p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool)", p0, p1));
}
function log(uint p0, address p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address)", p0, p1));
}
function log(string memory p0, uint p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint)", p0, p1));
}
function log(string memory p0, string memory p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1));
}
function log(string memory p0, bool p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1));
}
function log(string memory p0, address p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1));
}
function log(bool p0, uint p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint)", p0, p1));
}
function log(bool p0, string memory p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1));
}
function log(bool p0, bool p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1));
}
function log(bool p0, address p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1));
}
function log(address p0, uint p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint)", p0, p1));
}
function log(address p0, string memory p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1));
}
function log(address p0, bool p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1));
}
function log(address p0, address p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1));
}
function log(uint p0, uint p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint)", p0, p1, p2));
}
function log(uint p0, uint p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,string)", p0, p1, p2));
}
function log(uint p0, uint p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool)", p0, p1, p2));
}
function log(uint p0, uint p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,address)", p0, p1, p2));
}
function log(uint p0, string memory p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,uint)", p0, p1, p2));
}
function log(uint p0, string memory p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,string)", p0, p1, p2));
}
function log(uint p0, string memory p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,bool)", p0, p1, p2));
}
function log(uint p0, string memory p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,address)", p0, p1, p2));
}
function log(uint p0, bool p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint)", p0, p1, p2));
}
function log(uint p0, bool p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,string)", p0, p1, p2));
}
function log(uint p0, bool p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool)", p0, p1, p2));
}
function log(uint p0, bool p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,address)", p0, p1, p2));
}
function log(uint p0, address p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,uint)", p0, p1, p2));
}
function log(uint p0, address p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,string)", p0, p1, p2));
}
function log(uint p0, address p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,bool)", p0, p1, p2));
}
function log(uint p0, address p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,address)", p0, p1, p2));
}
function log(string memory p0, uint p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,uint)", p0, p1, p2));
}
function log(string memory p0, uint p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,string)", p0, p1, p2));
}
function log(string memory p0, uint p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,bool)", p0, p1, p2));
}
function log(string memory p0, uint p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,address)", p0, p1, p2));
}
function log(string memory p0, string memory p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint)", p0, p1, p2));
}
function log(string memory p0, string memory p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2));
}
function log(string memory p0, string memory p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2));
}
function log(string memory p0, string memory p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2));
}
function log(string memory p0, bool p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint)", p0, p1, p2));
}
function log(string memory p0, bool p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2));
}
function log(string memory p0, bool p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2));
}
function log(string memory p0, bool p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2));
}
function log(string memory p0, address p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint)", p0, p1, p2));
}
function log(string memory p0, address p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2));
}
function log(string memory p0, address p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2));
}
function log(string memory p0, address p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2));
}
function log(bool p0, uint p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint)", p0, p1, p2));
}
function log(bool p0, uint p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,string)", p0, p1, p2));
}
function log(bool p0, uint p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool)", p0, p1, p2));
}
function log(bool p0, uint p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,address)", p0, p1, p2));
}
function log(bool p0, string memory p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint)", p0, p1, p2));
}
function log(bool p0, string memory p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2));
}
function log(bool p0, string memory p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2));
}
function log(bool p0, string memory p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2));
}
function log(bool p0, bool p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint)", p0, p1, p2));
}
function log(bool p0, bool p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2));
}
function log(bool p0, bool p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2));
}
function log(bool p0, bool p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2));
}
function log(bool p0, address p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint)", p0, p1, p2));
}
function log(bool p0, address p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2));
}
function log(bool p0, address p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2));
}
function log(bool p0, address p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2));
}
function log(address p0, uint p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,uint)", p0, p1, p2));
}
function log(address p0, uint p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,string)", p0, p1, p2));
}
function log(address p0, uint p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,bool)", p0, p1, p2));
}
function log(address p0, uint p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,address)", p0, p1, p2));
}
function log(address p0, string memory p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint)", p0, p1, p2));
}
function log(address p0, string memory p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2));
}
function log(address p0, string memory p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2));
}
function log(address p0, string memory p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2));
}
function log(address p0, bool p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint)", p0, p1, p2));
}
function log(address p0, bool p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2));
}
function log(address p0, bool p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2));
}
function log(address p0, bool p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2));
}
function log(address p0, address p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint)", p0, p1, p2));
}
function log(address p0, address p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2));
}
function log(address p0, address p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2));
}
function log(address p0, address p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2));
}
function log(uint p0, uint p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,uint)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,string)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,bool)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,address)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,uint)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,string)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,bool)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,address)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,uint)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,string)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,bool)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,address)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,uint)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,string)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,bool)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,address)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,uint)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,string)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,bool)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,address)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,string,uint)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,string,string)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,string,bool)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,string,address)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,uint)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,string)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,bool)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,address)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,address,uint)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,address,string)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,address,bool)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,address,address)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,uint)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,string)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,bool)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,address)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,uint)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,string)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,bool)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,address)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,uint)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,string)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,bool)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,address)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,uint)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,string)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,bool)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,address)", p0, p1, p2, p3));
}
function log(uint p0, address p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,uint)", p0, p1, p2, p3));
}
function log(uint p0, address p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,string)", p0, p1, p2, p3));
}
function log(uint p0, address p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,bool)", p0, p1, p2, p3));
}
function log(uint p0, address p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,address)", p0, p1, p2, p3));
}
function log(uint p0, address p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,string,uint)", p0, p1, p2, p3));
}
function log(uint p0, address p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,string,string)", p0, p1, p2, p3));
}
function log(uint p0, address p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,string,bool)", p0, p1, p2, p3));
}
function log(uint p0, address p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,string,address)", p0, p1, p2, p3));
}
function log(uint p0, address p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,uint)", p0, p1, p2, p3));
}
function log(uint p0, address p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,string)", p0, p1, p2, p3));
}
function log(uint p0, address p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,bool)", p0, p1, p2, p3));
}
function log(uint p0, address p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,address)", p0, p1, p2, p3));
}
function log(uint p0, address p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,address,uint)", p0, p1, p2, p3));
}
function log(uint p0, address p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,address,string)", p0, p1, p2, p3));
}
function log(uint p0, address p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,address,bool)", p0, p1, p2, p3));
}
function log(uint p0, address p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,uint)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,string,uint)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,string,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,string,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,uint)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,address,uint)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,address,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,address,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint,uint)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint,string)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint,bool)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {
_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 view {
_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 view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, bool p2, string memory p3) internal view {
_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 view {
_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 view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, address p2, string memory p3) internal view {
_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 view {
_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 view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,uint)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,string)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,bool)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, string memory p2, string memory p3) internal view {
_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 view {
_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 view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint,uint)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint,string)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint,bool)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, string memory p2, string memory p3) internal view {
_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 view {
_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 view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,uint)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,string)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,address)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,uint)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,string)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,address)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,uint)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,uint)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,string)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,uint)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,string)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,bool)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, string memory p2, string memory p3) internal view {
_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 view {
_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 view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,uint)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,uint)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3));
}
function log(address p0, uint p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,uint)", p0, p1, p2, p3));
}
function log(address p0, uint p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,string)", p0, p1, p2, p3));
}
function log(address p0, uint p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,bool)", p0, p1, p2, p3));
}
function log(address p0, uint p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,address)", p0, p1, p2, p3));
}
function log(address p0, uint p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,string,uint)", p0, p1, p2, p3));
}
function log(address p0, uint p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,string,string)", p0, p1, p2, p3));
}
function log(address p0, uint p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,string,bool)", p0, p1, p2, p3));
}
function log(address p0, uint p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,string,address)", p0, p1, p2, p3));
}
function log(address p0, uint p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,uint)", p0, p1, p2, p3));
}
function log(address p0, uint p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,string)", p0, p1, p2, p3));
}
function log(address p0, uint p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, uint p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,address)", p0, p1, p2, p3));
}
function log(address p0, uint p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,address,uint)", p0, p1, p2, p3));
}
function log(address p0, uint p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,address,string)", p0, p1, p2, p3));
}
function log(address p0, uint p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,address,bool)", p0, p1, p2, p3));
}
function log(address p0, uint p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,address,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint,uint)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint,string)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint,bool)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, string memory p2, string memory p3) internal view {
_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 view {
_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 view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,uint)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint,uint)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3));
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return _verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) private pure returns (bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}// SPDX-License-Identifier: MIT
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;
}
}// SPDX-License-Identifier: GNU-GPL v3.0 or later
pragma solidity >=0.8.0;
import "./IRegistryProvider.sol";
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
/**
* @title Provider interface for Revest FNFTs
*/
interface IOutputReceiver is IRegistryProvider, IERC165 {
function receiveRevestOutput(uint256 fnftId, address asset, address payable owner, uint256 quantity) external;
function getCustomMetadata(uint256 fnftId) external view returns (string memory);
function getValue(uint256 fnftId) external view returns (uint256);
function getAsset(uint256 fnftId) external view returns (address);
function getOutputDisplayValues(uint256 fnftId) external view returns (bytes memory);
}{
"remappings": [
"ds-test/=lib/forge-std/lib/ds-test/src/",
"forge-std/=lib/forge-std/src/",
"@ensdomains/=node_modules/@ensdomains/",
"@openzeppelin/=node_modules/@openzeppelin/",
"@uniswap/=node_modules/@uniswap/",
"base64-sol/=node_modules/base64-sol/",
"hardhat-deploy/=node_modules/hardhat-deploy/",
"hardhat/=node_modules/hardhat/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "paris",
"viaIR": false,
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_provider","type":"address"},{"internalType":"address","name":"_vE","type":"address"},{"internalType":"address","name":"_distributor","type":"address"},{"internalType":"address","name":"_revestAdmin","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fnftId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"token","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountTokens","type":"uint256"}],"name":"ClaimYield","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fnftId","type":"uint256"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountTokens","type":"uint256"}],"name":"DepositAdditionalToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"mintTo","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountTokens","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"fnftId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"extraData","type":"bytes"}],"name":"DepositERC1155OutputReceiver","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"mintTo","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountTokens","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"fnftId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"extraData","type":"bytes"}],"name":"DepositERC20OutputReceiver","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"mintTo","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"indexed":true,"internalType":"uint256","name":"fnftId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"extraData","type":"bytes"}],"name":"DepositERC721OutputReceiver","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"mintTo","type":"address"},{"indexed":true,"internalType":"uint256","name":"fnftId","type":"uint256"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountTokens","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"expiration","type":"uint256"}],"name":"DepositToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"FeeCollection","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fnftId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newExpiration","type":"uint256"}],"name":"TimeLockExtension","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountTokens","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"fnftId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"extraData","type":"bytes"}],"name":"WithdrawERC1155OutputReceiver","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountTokens","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"fnftId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"extraData","type":"bytes"}],"name":"WithdrawERC20OutputReceiver","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"indexed":true,"internalType":"uint256","name":"fnftId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"extraData","type":"bytes"}],"name":"WithdrawERC721OutputReceiver","type":"event"},{"inputs":[],"name":"METADATA","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REWARD_TOKEN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TEMPLATE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TOKEN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VAULT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VOTING_ESCROW","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"distributor","type":"address"}],"name":"addDistributor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"addressRegistry","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"adminWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"fnftId","type":"uint256"},{"internalType":"address","name":"distritbutor","type":"address"}],"name":"checkpoint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"fnftId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"name":"claimRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"distributors","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"fnftId","type":"uint256"}],"name":"getAddressForFNFT","outputs":[{"internalType":"address","name":"smartWallet","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAddressRegistry","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"getAsset","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"getCustomMetadata","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"getERC20Fee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"getFlatWeiFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"fnftId","type":"uint256"}],"name":"getOutputDisplayValues","outputs":[{"internalType":"bytes","name":"displayData","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"fnftId","type":"uint256"}],"name":"getValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"globalProxyEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"fnftId","type":"uint256"},{"internalType":"uint256","name":"amountToDeposit","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"caller","type":"address"}],"name":"handleAdditionalDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"address","name":"","type":"address"},{"internalType":"bool","name":"","type":"bool"}],"name":"handleFNFTRemaps","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"fnftId","type":"uint256"},{"internalType":"uint256[]","name":"proportions","type":"uint256[]"},{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"address","name":"caller","type":"address"}],"name":"handleSplitOperation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"fnftId","type":"uint256"},{"internalType":"uint256","name":"expiration","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"handleTimelockExtensions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"lockId","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"uint256","name":"amountToLock","type":"uint256"}],"name":"lockTokens","outputs":[{"internalType":"uint256","name":"fnftId","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"proxyEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"fnftId","type":"uint256"},{"internalType":"address","name":"destination","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"proxyExecute","outputs":[{"internalType":"bytes","name":"dataOut","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"fnftId","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"address payable","name":"owner","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"receiveRevestOutput","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"fnftId","type":"uint256"},{"internalType":"address payable","name":"owner","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"},{"components":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"address","name":"pipeToContract","type":"address"},{"internalType":"uint256","name":"depositAmount","type":"uint256"},{"internalType":"uint256","name":"depositMul","type":"uint256"},{"internalType":"uint256","name":"split","type":"uint256"},{"internalType":"uint256","name":"depositStopTime","type":"uint256"},{"internalType":"bool","name":"maturityExtension","type":"bool"},{"internalType":"bool","name":"isMulti","type":"bool"},{"internalType":"bool","name":"nontransferrable","type":"bool"}],"internalType":"struct IRevest.FNFTConfig","name":"config","type":"tuple"},{"internalType":"bytes","name":"args","type":"bytes"}],"name":"receiveSecondaryCallback","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"rescueERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rescueNativeFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addressRegistry_","type":"address"}],"name":"setAddressRegistry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"enable","type":"bool"}],"name":"setGlobalProxyEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"fee","type":"uint256"}],"name":"setManagementFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_meta","type":"string"}],"name":"setMetadata","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"fee","type":"uint256"}],"name":"setPerformanceFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"fnftId","type":"uint256"},{"internalType":"bool","name":"status","type":"bool"}],"name":"setProxyStatusForFNFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_admin","type":"address"}],"name":"setRevestAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"fnftId","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"triggerOutputReceiverUpdate","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
6101a060405260516101208181529062005e7c610140396005906200002590826200050e565b50606460065560056007553480156200003d57600080fd5b5060405162005ecd38038062005ecd8339810160408190526200006091620005f7565b6200006b336200040b565b600180556001600160a01b038416620000cb5760405162461bcd60e51b815260206004820152601960248201527f496e76616c69642070726f76696465722061646472657373210000000000000060448201526064015b60405180910390fd5b6001600160a01b038316620001235760405162461bcd60e51b815260206004820152601e60248201527f496e76616c696420766f74696e6720657363726f7720616464726573732100006044820152606401620000c2565b6001600160a01b0382166200017b5760405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206469737472696275746f72206164647265737321000000006044820152606401620000c2565b6001600160a01b038116620001d35760405162461bcd60e51b815260206004820152601d60248201527f496e76616c6964207265766573742061646d696e2061646472657373210000006044820152606401620000c2565b600280546001600160a01b0319166001600160a01b03868116919091179091558316608081905260408051637e062a3560e11b8152905163fc0c546a916004808201926020929091908290030181865afa15801562000236573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200025c919062000654565b6001600160a01b031660a0816001600160a01b031681525050826001600160a01b031663fc0c546a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002b4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002da919062000654565b6001600160a01b0390811660c052600480546001600160a01b031916838316178155604080516354f2f7af60e01b81529051928716926354f2f7af928281019260209291908290030181865afa15801562000339573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200035f919062000654565b6001600160a01b0390811660e0526003805460018101825560009182527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b031916928516929092179091556040518490620003c4906200045b565b6001600160a01b039091168152602001604051809103906000f080158015620003f1573d6000803e3d6000fd5b506001600160a01b03166101005250620006799350505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6113f58062004a8783390190565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200049457607f821691505b602082108103620004b557634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200050957600081815260208120601f850160051c81016020861015620004e45750805b601f850160051c820191505b818110156200050557828155600101620004f0565b5050505b505050565b81516001600160401b038111156200052a576200052a62000469565b62000542816200053b84546200047f565b84620004bb565b602080601f8311600181146200057a5760008415620005615750858301515b600019600386901b1c1916600185901b17855562000505565b600085815260208120601f198616915b82811015620005ab578886015182559484019460019091019084016200058a565b5085821015620005ca5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b80516001600160a01b0381168114620005f257600080fd5b919050565b600080600080608085870312156200060e57600080fd5b6200061985620005da565b93506200062960208601620005da565b92506200063960408601620005da565b91506200064960608601620005da565b905092959194509250565b6000602082840312156200066757600080fd5b6200067282620005da565b9392505050565b60805160a05160c05160e051610100516142f762000790600039600081816106b8015281816109dd01528181611d940152818161238a015281816127300152612bf60152600081816104d301526120c80152600081816107480152818161159b01528181611e5f01528181611eac0152611ed5015260008181610664015281816109fe01528181610e9501528181610f9d0152818161100d01528181611b3a01528181611c7a01528181611cea01528181611dba01528181612032015281816121f501528181612278015281816122a2015281816123ab01528181612751015281816127c2015281816127fc0152612c1701526000818161037001528181610848015281816109ab0152611fbd01526142f76000f3fe6080604052600436106102725760003560e01c8063715018a61161014f57806399248ea7116100c1578063d25514121161007a578063d25514121461080a578063eac8f5b81461082a578063f2fde38b1461086a578063f3ad65f41461088a578063f48fe050146108aa578063fe56e232146108b857600080fd5b806399248ea714610736578063a49a1e7d1461076a578063aca1c6651461078a578063b4927da3146107aa578063ba156bcb146107ca578063ccec3716146107ea57600080fd5b806382bfefc81161011357806382bfefc81461065257806389158d8e146106865780638bfd9174146106a65780638d9d6705146106da5780638da5cb5b146106f85780638ecacb1b1461071657600080fd5b8063715018a6146105c85780637250e224146105dd57806376da63f3146105fd5780637d1b15dd146106185780637e5af5b81461063857600080fd5b806336b19cd7116101e857806350b492ba116101ac57806350b492ba146105155780635b0fe12014610535578063609d1fb314610555578063644bf7d8146105685780636c7b69cb1461058857806370897b23146105a857600080fd5b806336b19cd71461046a57806338c3df071461048a5780633ea5665f1461049f578063411557d1146104c157806344f5c938146104f557600080fd5b80631d1457211161023a5780631d1457211461033e5780631f87f3331461035e5780631fd2cf06146103aa5780632036e7ce146103da5780632799cde0146103fc57806327c7812c1461044a57600080fd5b806301ffc9a714610277578063063c27f8146102ac5780630ff4c916146102c35780631355f7ab146102f157806316f49e8a14610311575b600080fd5b34801561028357600080fd5b506102976102923660046134a3565b6108d8565b60405190151581526020015b60405180910390f35b3480156102b857600080fd5b506102c1610945565b005b3480156102cf57600080fd5b506102e36102de3660046134cd565b6109a7565b6040519081526020016102a3565b3480156102fd57600080fd5b506102c161030c366004613506565b610ab2565b34801561031d57600080fd5b5061033161032c3660046134cd565b610cec565b6040516102a3919061358f565b34801561034a57600080fd5b506102c16103593660046135a2565b610d80565b34801561036a57600080fd5b506103927f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016102a3565b3480156103b657600080fd5b506102976103c53660046134cd565b60096020526000908152604090205460ff1681565b3480156103e657600080fd5b506102e36103f53660046135e3565b5060075490565b34801561040857600080fd5b506104326104173660046134cd565b600a602052600090815260409020546001600160801b031681565b6040516001600160801b0390911681526020016102a3565b34801561045657600080fd5b506102c16104653660046135e3565b61107b565b34801561047657600080fd5b50600454610392906001600160a01b031681565b34801561049657600080fd5b5061033161112e565b3480156104ab57600080fd5b506102e36104ba3660046135e3565b5060065490565b3480156104cd57600080fd5b506103927f000000000000000000000000000000000000000000000000000000000000000081565b34801561050157600080fd5b506102c16105103660046135e3565b6111bc565b34801561052157600080fd5b506103926105303660046134cd565b61125e565b34801561054157600080fd5b506102c1610550366004613600565b611288565b610331610563366004613724565b611422565b34801561057457600080fd5b506102c1610583366004613809565b611788565b34801561059457600080fd5b506102c16105a3366004613600565b6117c2565b3480156105b457600080fd5b506102c16105c33660046134cd565b6118fa565b3480156105d457600080fd5b506102c161198a565b3480156105e957600080fd5b506102c16105f83660046135e3565b6119c0565b34801561060957600080fd5b506102c1610583366004613869565b34801561062457600080fd5b506102c16106333660046138c0565b611a92565b34801561064457600080fd5b506008546102979060ff1681565b34801561065e57600080fd5b506103927f000000000000000000000000000000000000000000000000000000000000000081565b34801561069257600080fd5b506102e36106a13660046138e5565b611adc565b3480156106b257600080fd5b506103927f000000000000000000000000000000000000000000000000000000000000000081565b3480156106e657600080fd5b506002546001600160a01b0316610392565b34801561070457600080fd5b506000546001600160a01b0316610392565b34801561072257600080fd5b506103316107313660046134cd565b611d47565b34801561074257600080fd5b506103927f000000000000000000000000000000000000000000000000000000000000000081565b34801561077657600080fd5b506102c1610785366004613907565b612083565b34801561079657600080fd5b506102c16107a536600461394f565b6120bd565b3480156107b657600080fd5b506102c16107c5366004613997565b612346565b3480156107d657600080fd5b506103926107e53660046134cd565b612383565b3480156107f657600080fd5b506102c16108053660046135e3565b6123dc565b34801561081657600080fd5b506102c16108253660046139b4565b612487565b34801561083657600080fd5b506103926108453660046134cd565b507f000000000000000000000000000000000000000000000000000000000000000090565b34801561087657600080fd5b506102c16108853660046135e3565b612594565b34801561089657600080fd5b50600254610392906001600160a01b031681565b6102c16105833660046139fa565b3480156108c457600080fd5b506102c16108d33660046134cd565b61262c565b60006001600160e01b031982166368d1d7ad60e11b148061090957506001600160e01b0319821663214881cd60e11b145b8061092457506001600160e01b0319821663789bc37960e01b145b8061093f57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6000546001600160a01b031633146109785760405162461bcd60e51b815260040161096f90613aff565b60405180910390fd5b60405133904780156108fc02916000818181858888f193505050501580156109a4573d6000803e3d6000fd5b50565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166370a08231610a4a7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000086604051602001610a2f929190613b34565b604051602081830303815290604052805190602001206126bb565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015610a8e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093f9190613b4d565b600260009054906101000a90046001600160a01b03166001600160a01b031663f97e7d746040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b299190613b66565b6001600160a01b0316336001600160a01b031614610b805760405162461bcd60e51b8152602060048201526014602482015273556e617574686f72697a6564204163636573732160601b604482015260640161096f565b630784ce00610b8f4284613b99565b1115610bd55760405162461bcd60e51b81526020600482015260156024820152744d6178206c6f636b7570206973203420796561727360581b604482015260640161096f565b6000610be084612728565b6000868152600a6020526040902054600380549294506001600160a01b03851693506331ffe6159287926001600160801b03169190610c2190600190613b99565b81548110610c3157610c31613bac565b60009182526020909120015460405160e085901b6001600160e01b031916815260048101939093526001600160801b0390911660248301526001600160a01b03166044820152606401600060405180830381600087803b158015610c9457600080fd5b505af1158015610ca8573d6000803e3d6000fd5b50505050837feeecc86f805a6a63ba2f3ceec31a166720d5f516c1afefe746db898be453d07b84604051610cde91815260200190565b60405180910390a250505050565b606060058054610cfb90613bc2565b80601f0160208091040260200160405190810160405280929190818152602001828054610d2790613bc2565b8015610d745780601f10610d4957610100808354040283529160200191610d74565b820191906000526020600020905b815481529060010190602001808311610d5757829003601f168201915b50505050509050919050565b600260015403610da25760405162461bcd60e51b815260040161096f90613bfc565b600260018190555460408051633e5f9f5d60e21b815290516001600160a01b039092169163f97e7d74916004808201926020929091908290030181865afa158015610df1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e159190613b66565b6001600160a01b0316336001600160a01b031614610e6c5760405162461bcd60e51b8152602060048201526014602482015273556e617574686f72697a6564204163636573732160601b604482015260640161096f565b600080610e7886612728565b91509150610e86838661278b565b9450610ebd6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016848488612858565b6000868152600a6020526040902054600380546001600160a01b0384169263f6a3ecfc9289926001600160801b0390921691610efb90600190613b99565b81548110610f0b57610f0b613bac565b60009182526020909120015460405160e085901b6001600160e01b031916815260048101939093526001600160801b0390911660248301526001600160a01b03166044820152606401600060405180830381600087803b158015610f6e57600080fd5b505af1158015610f82573d6000803e3d6000fd5b5050604080516001600160a01b0386811660208301528a94507f0000000000000000000000000000000000000000000000000000000000000000811693508716917f5bed1f834b92cc21cec09497afa47d36952b8a037e988eca6e9ecffeb497b227918a910160408051601f19818403018152908290526110039291613c33565b60405180910390a47f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316867fa6fb986371a2b2b124f881dfaf4a151317bb38bbc3070e1ee1271a46c29436bc8760405161106791815260200190565b60405180910390a350506001805550505050565b6000546001600160a01b031633146110a55760405162461bcd60e51b815260040161096f90613aff565b6001600160a01b03811661110c5760405162461bcd60e51b815260206004820152602860248201527f4572726f723a20496e76616c6964206164647265737320726567697374727920604482015267616464726573732160c01b606482015260840161096f565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6005805461113b90613bc2565b80601f016020809104026020016040519081016040528092919081815260200182805461116790613bc2565b80156111b45780601f10611189576101008083540402835291602001916111b4565b820191906000526020600020905b81548152906001019060200180831161119757829003601f168201915b505050505081565b6000546001600160a01b031633146111e65760405162461bcd60e51b815260040161096f90613aff565b6001600160a01b03811661123c5760405162461bcd60e51b815260206004820152601d60248201527f4572726f723a20496e76616c69642061646d696e206164647265737321000000604482015260640161096f565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6003818154811061126e57600080fd5b6000918252602090912001546001600160a01b0316905081565b60025460408051636acf14b760e11b8152905184926001600160a01b031691600091839163d59e296e9160048083019260209291908290030181865afa1580156112d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112fa9190613b66565b6001600160a01b0316632b04e84033856040518363ffffffff1660e01b8152600401611327929190613b34565b602060405180830381865afa158015611344573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113689190613b4d565b116113855760405162461bcd60e51b815260040161096f90613c4c565b6002600154036113a75760405162461bcd60e51b815260040161096f90613bfc565b600260015560006113b785612728565b6040516354b94c2f60e11b81526001600160a01b038781166004830152919350908316915063a972985e90602401600060405180830381600087803b1580156113ff57600080fd5b505af1158015611413573d6000803e3d6000fd5b50506001805550505050505050565b6060836000600260009054906101000a90046001600160a01b031690506000816001600160a01b031663d59e296e6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561147f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114a39190613b66565b6001600160a01b0316632b04e84033856040518363ffffffff1660e01b81526004016114d0929190613b34565b602060405180830381865afa1580156114ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115119190613b4d565b1161152e5760405162461bcd60e51b815260040161096f90613c4c565b60085460ff168061154d575060008681526009602052604090205460ff165b6115995760405162461bcd60e51b815260206004820152601960248201527f50726f787920616363657373206e6f7420656e61626c65642100000000000000604482015260640161096f565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316856001600160a01b0316036116405760405162461bcd60e51b815260206004820152603760248201527f50726f78792063616c6c20646f6573206e6f7420616c6c6f7720696e7465726160448201527f6374696f6e2077697468205245574152445f544f4b454e000000000000000000606482015260840161096f565b60005b6003548110156116f8576003818154811061166057611660613bac565b6000918252602090912001546001600160a01b03908116908716036116e65760405162461bcd60e51b815260206004820152603660248201527f50726f78792063616c6c20646f6573206e6f7420616c6c6f7720696e7465726160448201527531ba34b7b7103bb4ba34102224a9aa2924a12aaa27a960511b606482015260840161096f565b806116f081613c6a565b915050611643565b50600061170487612728565b915050806001600160a01b03166332cae16e3488886040518463ffffffff1660e01b8152600401611736929190613c83565b60006040518083038185885af1158015611754573d6000803e3d6000fd5b50505050506040513d6000823e601f3d908101601f1916820160405261177d9190810190613cd7565b979650505050505050565b60405162461bcd60e51b815260206004820152600f60248201526e4e6f74206170706c696361626c652160881b604482015260640161096f565b60025460408051636acf14b760e11b8152905184926001600160a01b031691600091839163d59e296e9160048083019260209291908290030181865afa158015611810573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118349190613b66565b6001600160a01b0316632b04e84033856040518363ffffffff1660e01b8152600401611861929190613b34565b602060405180830381865afa15801561187e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118a29190613b4d565b116118bf5760405162461bcd60e51b815260040161096f90613c4c565b6002600154036118e15760405162461bcd60e51b815260040161096f90613bfc565b60026001556118f083856128c3565b5050600180555050565b6000546001600160a01b031633146119245760405162461bcd60e51b815260040161096f90613aff565b6103e88111156119855760405162461bcd60e51b815260206004820152602660248201527f506572666f726d616e636520666565206d757374206265206c657373207468616044820152656e203130302560d01b606482015260840161096f565b600655565b6000546001600160a01b031633146119b45760405162461bcd60e51b815260040161096f90613aff565b6119be60006129c7565b565b6000546001600160a01b031633146119ea5760405162461bcd60e51b815260040161096f90613aff565b6001600160a01b038116611a405760405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206469737472696275746f7220616464726573732100000000604482015260640161096f565b600380546001810182556000919091527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b03163314611abc5760405162461bcd60e51b815260040161096f90613aff565b600091825260096020526040909120805460ff1916911515919091179055565b6000600260015403611b005760405162461bcd60e51b815260040161096f90613bfc565b6002600155611b0f338361278b565b9150611b1a83612a17565b9050600080611b2883612bee565b9092509050611b626001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016338487612858565b6000816001600160a01b0316633c4f8dd8868860036001600380549050611b899190613b99565b81548110611b9957611b99613bac565b60009182526020909120015460405160e085901b6001600160e01b0319168152600481019390935260248301919091526001600160a01b0316604482015260640160408051808303816000875af1158015611bf8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c1c9190613d1f565b506000858152600a602090815260409182902080546fffffffffffffffffffffffffffffffff19166001600160801b03851617905581516001600160a01b0387811682840152835180830390930183529083019283905292935086927f0000000000000000000000000000000000000000000000000000000000000000169133917f5bed1f834b92cc21cec09497afa47d36952b8a037e988eca6e9ecffeb497b22791611cca918b91613c33565b60405180910390a460408051868152602081018890526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691869133917f60403aa430a4d07f2b527d083643f3f4cbdab6a4d8e333693913508a69efb6e2910160405180910390a45050600180555092915050565b60038054606091600091611d5d90600190613b99565b81548110611d6d57611d6d613bac565b600091825260209182902001546040516001600160a01b0390911691628cc26291611de2917f000000000000000000000000000000000000000000000000000000000000000091610a2f917f0000000000000000000000000000000000000000000000000000000000000000918a9101613b34565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015611e26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e4a9190613b4d565b90508015801590606090611f42576000611e837f0000000000000000000000000000000000000000000000000000000000000000612c63565b604051602001611e939190613d59565b60405160208183030381529060405290506000611ed0857f0000000000000000000000000000000000000000000000000000000000000000612cf9565b611ef97f0000000000000000000000000000000000000000000000000000000000000000612d78565b604051602001611f0a929190613d7f565b60405160208183030381529060405290508181604051602001611f2e929190613ddb565b604051602081830303815290604052925050505b6000611f4d86612383565b90506000630784ce00611f6362093a8042613e20565b611f709062093a80613e34565b611f7a9190613e4b565b6000888152600a60205260408082205490516321c984e960e01b81526001600160a01b0386811660048301526001600160801b03909216602482015292935090917f0000000000000000000000000000000000000000000000000000000000000000909116906321c984e9906044016040805180830381865afa158015612005573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120299190613e5e565b509050828486847f00000000000000000000000000000000000000000000000000000000000000008560405160200161206796959493929190613e82565b6040516020818303038152906040529650505050505050919050565b6000546001600160a01b031633146120ad5760405162461bcd60e51b815260040161096f90613aff565b60056120b98282613f1e565b5050565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461212a5760405162461bcd60e51b81526020600482015260126024820152714f6e6c79205661756c74204163636573732160701b604482015260640161096f565b60026001540361214c5760405162461bcd60e51b815260040161096f90613bfc565b600260015560008061215d86612728565b9150915061216b84876128c3565b6000868152600a6020526040908190205490516302387a7b60e01b81526001600160801b0390911660048201526001600160a01b038216906302387a7b90602401600060405180830381600087803b1580156121c657600080fd5b505af11580156121da573d6000803e3d6000fd5b50506040516370a0823160e01b8152306004820152600092507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031691506370a0823190602401602060405180830381865afa158015612245573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122699190613b4d565b905061229f6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168683612dfc565b867f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316866001600160a01b03167ff2b6e7f64080f438239b56473f2cd92b33165c88688fd898e1d99082bd0eb954848760405160200161231691906001600160a01b0391909116815260200190565b60408051601f19818403018152908290526123319291613c33565b60405180910390a45050600180555050505050565b6000546001600160a01b031633146123705760405162461bcd60e51b815260040161096f90613aff565b6008805460ff1916911515919091179055565b600061093f7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000084604051602001610a2f929190613b34565b6000546001600160a01b031633146124065760405162461bcd60e51b815260040161096f90613aff565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa15801561244d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124719190613b4d565b90506120b96001600160a01b0383163383612dfc565b60025460408051636acf14b760e11b8152905184926001600160a01b031691600091839163d59e296e9160048083019260209291908290030181865afa1580156124d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f99190613b66565b6001600160a01b0316632b04e84033856040518363ffffffff1660e01b8152600401612526929190613b34565b602060405180830381865afa158015612543573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125679190613b4d565b116125845760405162461bcd60e51b815260040161096f90613c4c565b61258e33856128c3565b50505050565b6000546001600160a01b031633146125be5760405162461bcd60e51b815260040161096f90613aff565b6001600160a01b0381166126235760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161096f565b6109a4816129c7565b6000546001600160a01b031633146126565760405162461bcd60e51b815260040161096f90613aff565b6103e88111156126b65760405162461bcd60e51b815260206004820152602560248201527f4d616e6167656d656e7420666565206d757374206265206c657373207468616e604482015264203130302560d81b606482015260840161096f565b600755565b6000612721838330604051733d602d80600a3d3981f3363d3d373d3d3d363d7360601b8152606093841b60148201526f5af43d82803e903d91602b57fd5bf3ff60801b6028820152921b6038830152604c8201526037808220606c830152605591012090565b9392505050565b6000806127827f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000085604051602001610a2f929190613b34565b93849350915050565b6000806103e86007548461279f9190613e34565b6127a99190613e20565b90508015612851576004546127ed906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169187911684612858565b6127f78184613b99565b9150807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f5b369813f138995818116377909787d51cbdc0c2957db33f1719a36bad521f7e60405160405180910390a35b5092915050565b6040516001600160a01b038085166024830152831660448201526064810182905261258e9085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612e20565b60006128ce82612728565b91505060005b6003546128e390600190613b99565b811161258e57816001600160a01b031663380440cb85600460009054906101000a90046001600160a01b03166006546003868154811061292557612925613bac565b60009182526020909120015460405160e086901b6001600160e01b03191681526001600160a01b039485166004820152928416602484015260448301919091529190911660648201526084016020604051808303816000875af1158015612990573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129b49190613b4d565b50806129bf81613c6a565b9150506128d4565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60408051610120810182526000808252818301819052606082018190526080820181905260a082018190526101008201819052600160e0830181905260c083018190523060208401528351818152808501909452909283918160200160208202803683370190505090503381600081518110612a9557612a95613bac565b6001600160a01b039290921660209283029190910190910152604080516001808252818301909252600091816020016020820280368337019050509050600181600081518110612ae757612ae7613bac565b6020026020010181815250506000600260009054906101000a90046001600160a01b03166001600160a01b031663f97e7d746040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b6c9190613b66565b6040516305a7c08f60e41b81529091506001600160a01b03821690635a7c08f090612ba1908990879087908a90600401614052565b6020604051808303816000875af1158015612bc0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612be49190613b4d565b9695505050505050565b6000806127827f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000085604051602001612c48929190613b34565b60405160208183030381529060405280519060200120612ef2565b6060816001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa925050508015612cc457506040513d6000823e601f3d908101601f19168201604052612cc19190810190613cd7565b60015b612cf157505060408051808201909152600d81526c2ab735b737bbb7102a37b5b2b760991b602082015290565b90505b919050565b60606000826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612d57575060408051601f3d908101601f19168201909252612d54918101906140f0565b60015b612d6357506012612d66565b90505b612d708482612f92565b949350505050565b6060816001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa925050508015612dd957506040513d6000823e601f3d908101601f19168201604052612dd69190810190613cd7565b60015b612cf15750506040805180820190915260038152623f3f3f60e81b602082015290565b612e1b8363a9059cbb60e01b848460405160240161288c929190613b34565b505050565b6000612e75826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166131479092919063ffffffff16565b805190915015612e1b5780806020019051810190612e939190614113565b612e1b5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161096f565b6000604051733d602d80600a3d3981f3363d3d373d3d3d363d7360601b81528360601b60148201526e5af43d82803e903d91602b57fd5bf360881b6028820152826037826000f59150506001600160a01b03811661093f5760405162461bcd60e51b815260206004820152601760248201527f455243313136373a2063726561746532206661696c6564000000000000000000604482015260640161096f565b60606000612fa183600a614214565b9050836000805b82156130075760ff811615612fc95780612fc181614223565b915050612fe7565b612fd4600a84614242565b15612fe75780612fe381614223565b9150505b81612ff181614223565b92506130009050600a84613e20565b9250612fa8565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081019190915260ff871661304e8385614256565b60ff1610613080576130608589613e20565b815261306c8784614256565b60ff16604082018190526020820152613125565b61308a8284614256565b61309590600a614214565b61309f9089613e20565b8152878511156130f457600260808201526130ba8388614256565b6130c590600261426f565b60ff1660a082018190526130d9908361426f565b60ff16604082018190526020820152600160c0820152613125565b6130ff82600161426f565b60ff1660408201526131118784614256565b61311c90600161426f565b60ff1660608201525b604081015160ff16602082015261313b81613156565b98975050505050505050565b6060612d708484600085613352565b60606000826020015160ff166001600160401b0381111561317957613179613630565b6040519080825280601f01601f1916602001820160405280156131a3576020820181803683370190505b5090508260c001511561320f57600360fc1b816000815181106131c8576131c8613bac565b60200101906001600160f81b031916908160001a905350601760f91b816001815181106131f7576131f7613bac565b60200101906001600160f81b031916908160001a9053505b608083015160ff165b8360a0015160ff1681101561326757603060f81b82828151811061323e5761323e613bac565b60200101906001600160f81b031916908160001a9053508061325f81613c6a565b915050613218565b505b825115612cf1576000836060015160ff161180156132945750826060015160ff16836040015160ff16145b156132dd57601760f91b818460400180516132ae90614288565b60ff1690819052815181106132c5576132c5613bac565b60200101906001600160f81b031916908160001a9053505b82516132eb90600a90614242565b6132f6906030613e4b565b60f81b8184604001805161330990614288565b60ff16908190528151811061332057613320613bac565b60200101906001600160f81b031916908160001a905350600a8360000181815161334a9190613e20565b905250613269565b6060824710156133b35760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161096f565b843b6134015760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161096f565b600080866001600160a01b0316858760405161341d91906142a5565b60006040518083038185875af1925050503d806000811461345a576040519150601f19603f3d011682016040523d82523d6000602084013e61345f565b606091505b509150915061177d82828660608315613479575081612721565b8251156134895782518084602001fd5b8160405162461bcd60e51b815260040161096f919061358f565b6000602082840312156134b557600080fd5b81356001600160e01b03198116811461272157600080fd5b6000602082840312156134df57600080fd5b5035919050565b6001600160a01b03811681146109a457600080fd5b8035612cf4816134e6565b60008060006060848603121561351b57600080fd5b83359250602084013591506040840135613534816134e6565b809150509250925092565b60005b8381101561355a578181015183820152602001613542565b50506000910152565b6000815180845261357b81602086016020860161353f565b601f01601f19169290920160200192915050565b6020815260006127216020830184613563565b600080600080608085870312156135b857600080fd5b84359350602085013592506040850135915060608501356135d8816134e6565b939692955090935050565b6000602082840312156135f557600080fd5b8135612721816134e6565b6000806040838503121561361357600080fd5b823591506020830135613625816134e6565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b60405161012081016001600160401b038111828210171561366957613669613630565b60405290565b604051601f8201601f191681016001600160401b038111828210171561369757613697613630565b604052919050565b60006001600160401b038211156136b8576136b8613630565b50601f01601f191660200190565b60006136d96136d48461369f565b61366f565b90508281528383830111156136ed57600080fd5b828260208301376000602084830101529392505050565b600082601f83011261371557600080fd5b612721838335602085016136c6565b60008060006060848603121561373957600080fd5b83359250602084013561374b816134e6565b915060408401356001600160401b0381111561376657600080fd5b61377286828701613704565b9150509250925092565b600082601f83011261378d57600080fd5b813560206001600160401b038211156137a8576137a8613630565b8160051b6137b782820161366f565b92835284810182019282810190878511156137d157600080fd5b83870192505b8483101561177d578235825291830191908301906137d7565b80151581146109a457600080fd5b8035612cf4816137f0565b6000806000806080858703121561381f57600080fd5b8435935060208501356001600160401b0381111561383c57600080fd5b6138488782880161377c565b9350506040850135613859816134e6565b915060608501356135d8816137f0565b6000806000806080858703121561387f57600080fd5b8435935060208501356001600160401b0381111561389c57600080fd5b6138a88782880161377c565b9350506040850135915060608501356135d8816134e6565b600080604083850312156138d357600080fd5b823591506020830135613625816137f0565b600080604083850312156138f857600080fd5b50508035926020909101359150565b60006020828403121561391957600080fd5b81356001600160401b0381111561392f57600080fd5b8201601f8101841361394057600080fd5b612d70848235602084016136c6565b6000806000806080858703121561396557600080fd5b843593506020850135613977816134e6565b92506040850135613987816134e6565b9396929550929360600135925050565b6000602082840312156139a957600080fd5b8135612721816137f0565b600080604083850312156139c757600080fd5b8235915060208301356001600160401b038111156139e457600080fd5b6139f085828601613704565b9150509250929050565b60008060008060008587036101a0811215613a1457600080fd5b863595506020870135613a26816134e6565b945060408701359350610120605f198201811315613a4357600080fd5b613a4b613646565b9150613a59606089016134fb565b8252613a67608089016134fb565b602083015260a0880135604083015260c0880135606083015260e088013560808301526101008089013560a0840152613aa1828a016137fe565b60c0840152613ab36101408a016137fe565b60e0840152613ac56101608a016137fe565b908301525091506101808601356001600160401b03811115613ae657600080fd5b613af288828901613704565b9150509295509295909350565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6001600160a01b03929092168252602082015260400190565b600060208284031215613b5f57600080fd5b5051919050565b600060208284031215613b7857600080fd5b8151612721816134e6565b634e487b7160e01b600052601160045260246000fd5b8181038181111561093f5761093f613b83565b634e487b7160e01b600052603260045260246000fd5b600181811c90821680613bd657607f821691505b602082108103613bf657634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b828152604060208201526000612d706040830184613563565b602080825260049082015263114c0d8d60e21b604082015260600190565b600060018201613c7c57613c7c613b83565b5060010190565b6001600160a01b0383168152604060208201819052600090612d7090830184613563565b6000613cb56136d48461369f565b9050828152838383011115613cc957600080fd5b61272183602083018461353f565b600060208284031215613ce957600080fd5b81516001600160401b03811115613cff57600080fd5b8201601f81018413613d1057600080fd5b612d7084825160208401613ca7565b60008060408385031215613d3257600080fd5b82516001600160801b0381168114613d4957600080fd5b6020939093015192949293505050565b60008251613d6b81846020870161353f565b6101d160f51b920191825250600201919050565b60008351613d9181846020880161353f565b61205b60f01b9083019081528351613db081600284016020880161353f565b715d20546f6b656e7320417661696c61626c6560701b60029290910191820152601401949350505050565b60008351613ded81846020880161353f565b835190830190613e0181836020880161353f565b01949350505050565b634e487b7160e01b600052601260045260246000fd5b600082613e2f57613e2f613e0a565b500490565b808202811582820484141761093f5761093f613b83565b8082018082111561093f5761093f613b83565b60008060408385031215613e7157600080fd5b825180600f0b8114613d4957600080fd5b600060018060a01b03808916835260c06020840152613ea460c0840189613563565b9615156040840152606083019590955250919092166080820152600f9190910b60a09091015292915050565b601f821115612e1b57600081815260208120601f850160051c81016020861015613ef75750805b601f850160051c820191505b81811015613f1657828155600101613f03565b505050505050565b81516001600160401b03811115613f3757613f37613630565b613f4b81613f458454613bc2565b84613ed0565b602080601f831160018114613f805760008415613f685750858301515b600019600386901b1c1916600185901b178555613f16565b600085815260208120601f198616915b82811015613faf57888601518255948401946001909101908401613f90565b5085821015613fcd5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60018060a01b038082511683528060208301511660208401525060408101516040830152606081015160608301526080810151608083015260a081015160a083015260c0810151151560c083015260e081015161403e60e084018215159052565b50610100818101518015158483015261258e565b848152610180602080830182905285519183018290526000916101a084019187810191845b8181101561409c5783516001600160a01b031685529382019392820192600101614077565b505084830360408601528651808452818801938201925060005b818110156140d2578451845293820193928201926001016140b6565b50505080925050506140e76060830184613fdd565b95945050505050565b60006020828403121561410257600080fd5b815160ff8116811461272157600080fd5b60006020828403121561412557600080fd5b8151612721816137f0565b600181815b8085111561416b57816000190482111561415157614151613b83565b8085161561415e57918102915b93841c9390800290614135565b509250929050565b6000826141825750600161093f565b8161418f5750600061093f565b81600181146141a557600281146141af576141cb565b600191505061093f565b60ff8411156141c0576141c0613b83565b50506001821b61093f565b5060208310610133831016604e8410600b84101617156141ee575081810a61093f565b6141f88383614130565b806000190482111561420c5761420c613b83565b029392505050565b600061272160ff841683614173565b600060ff821660ff810361423957614239613b83565b60010192915050565b60008261425157614251613e0a565b500690565b60ff828116828216039081111561093f5761093f613b83565b60ff818116838216019081111561093f5761093f613b83565b600060ff82168061429b5761429b613b83565b6000190192915050565b600082516142b781846020870161353f565b919091019291505056fea2646970667358221220611b1e0a236db42be9c817e004ef333e6ec81840dacafa4c172658304d56f9c964736f6c6343000813003361010060405234801561001157600080fd5b506040516113f53803806113f58339810160408190526100309161012f565b336080526001600160a01b03811660e081905260408051637e062a3560e11b8152905163fc0c546a916004808201926020929091908290030181865afa15801561007e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100a2919061012f565b6001600160a01b031660a0816001600160a01b031681525050806001600160a01b031663fc0c546a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061011d919061012f565b6001600160a01b031660c0525061015f565b60006020828403121561014157600080fd5b81516001600160a01b038116811461015857600080fd5b9392505050565b60805160a05160c05160e0516111df610216600039600081816101fc015281816103b3015281816107fc015281816108b10152818161097b0152610b5d015260008181610638015281816106d90152818161070f0152610763015260008181610277015281816102fa0152818161082801526108e10152600081816101980152818161031c015281816103500152818161047d01528181610574015281816107a201528181610a5d0152610afb01526111df6000f3fe6080604052600436106100705760003560e01c8063380440cb1161004e578063380440cb146100e05780633c4f8dd81461010e578063a972985e1461014d578063f6a3ecfc1461016d57600080fd5b806302387a7b1461007557806331ffe6151461009757806332cae16e146100b7575b600080fd5b34801561008157600080fd5b50610095610090366004610e4f565b61018d565b005b3480156100a357600080fd5b506100956100b2366004610e88565b610345565b6100ca6100c5366004610edc565b610470565b6040516100d79190610fee565b60405180910390f35b3480156100ec57600080fd5b506101006100fb366004611001565b610567565b6040519081526020016100d7565b34801561011a57600080fd5b5061012e61012936600461104e565b610794565b604080516001600160801b0390931683526020830191909152016100d7565b34801561015957600080fd5b5061009561016836600461107a565b610a52565b34801561017957600080fd5b50610095610188366004610e88565b610af0565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146101de5760405162461bcd60e51b81526004016101d590611095565b60405180910390fd5b6040516302387a7b60e01b81526001600160801b03821660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906302387a7b90602401600060405180830381600087803b15801561024857600080fd5b505af115801561025c573d6000803e3d6000fd5b50506040516370a0823160e01b8152306004820152600092507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031691506370a0823190602401602060405180830381865afa1580156102c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102eb91906110bc565b90506103416001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f000000000000000000000000000000000000000000000000000000000000000083610b94565b5050565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461038d5760405162461bcd60e51b81526004016101d590611095565b604051631c27aff360e31b81526001600160801b038085166004830152831660248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e13d7f98906044015b600060405180830381600087803b15801561040057600080fd5b505af1158015610414573d6000803e3d6000fd5b50505050806001600160a01b031663c2c4c5c16040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561045357600080fd5b505af1158015610467573d6000803e3d6000fd5b50505050505050565b6060336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146104ba5760405162461bcd60e51b81526004016101d590611095565b600080846001600160a01b031634856040516104d691906110d5565b60006040518083038185875af1925050503d8060008114610513576040519150601f19603f3d011682016040523d82523d6000602084013e610518565b606091505b50915091508161055f5760405162461bcd60e51b815260206004820152601260248201527150726f78792063616c6c206661696c65642160701b60448201526064016101d5565b949350505050565b6000336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146105b15760405162461bcd60e51b81526004016101d590611095565b816001600160a01b0316637c2628716040518163ffffffff1660e01b81526004016020604051808303816000875af11580156105f1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061591906110bc565b6040516370a0823160e01b81523060048201529091506000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa15801561067f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106a391906110bc565b905060006103e86106b48684611107565b6106be9190611124565b90506106ca8183611146565b91506107006001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168783610b94565b60405181906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016907f5b369813f138995818116377909787d51cbdc0c2957db33f1719a36bad521f7e90600090a361078a6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168884610b94565b5050949350505050565b600080336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146107df5760405162461bcd60e51b81526004016101d590611095565b604051636eb1769f60e11b81523060048201526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166024830152600019917f00000000000000000000000000000000000000000000000000000000000000009091169063dd62ed3e90604401602060405180830381865afa158015610871573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061089591906110bc565b146109505760405163095ea7b360e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015260001960248301527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303816000875af115801561092a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061094e9190611159565b505b60405163d41a464160e01b8152306004820152602481018690526001600160801b03851660448201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063d41a46419060640160408051808303816000875af11580156109cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ef919061117b565b8092508193505050826001600160a01b031663c2c4c5c16040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610a3257600080fd5b505af1158015610a46573d6000803e3d6000fd5b50505050935093915050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610a9a5760405162461bcd60e51b81526004016101d590611095565b806001600160a01b031663c2c4c5c16040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610ad557600080fd5b505af1158015610ae9573d6000803e3d6000fd5b5050505050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610b385760405162461bcd60e51b81526004016101d590611095565b60405163929edf4560e01b8152600481018490526001600160801b03831660248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063929edf45906044016103e6565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610be6908490610beb565b505050565b6000610c40826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316610cbd9092919063ffffffff16565b805190915015610be65780806020019051810190610c5e9190611159565b610be65760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016101d5565b6060610ccc8484600085610cd6565b90505b9392505050565b606082471015610d375760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016101d5565b843b610d855760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016101d5565b600080866001600160a01b03168587604051610da191906110d5565b60006040518083038185875af1925050503d8060008114610dde576040519150601f19603f3d011682016040523d82523d6000602084013e610de3565b606091505b5091509150610df3828286610dfe565b979650505050505050565b60608315610e0d575081610ccf565b825115610e1d5782518084602001fd5b8160405162461bcd60e51b81526004016101d59190610fee565b6001600160801b0381168114610e4c57600080fd5b50565b600060208284031215610e6157600080fd5b8135610ccf81610e37565b80356001600160a01b0381168114610e8357600080fd5b919050565b600080600060608486031215610e9d57600080fd5b833592506020840135610eaf81610e37565b9150610ebd60408501610e6c565b90509250925092565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215610eef57600080fd5b610ef883610e6c565b9150602083013567ffffffffffffffff80821115610f1557600080fd5b818501915085601f830112610f2957600080fd5b813581811115610f3b57610f3b610ec6565b604051601f8201601f19908116603f01168101908382118183101715610f6357610f63610ec6565b81604052828152886020848701011115610f7c57600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b60005b83811015610fb9578181015183820152602001610fa1565b50506000910152565b60008151808452610fda816020860160208601610f9e565b601f01601f19169290920160200192915050565b602081526000610ccf6020830184610fc2565b6000806000806080858703121561101757600080fd5b61102085610e6c565b935061102e60208601610e6c565b92506040850135915061104360608601610e6c565b905092959194509250565b60008060006060848603121561106357600080fd5b8335925060208401359150610ebd60408501610e6c565b60006020828403121561108c57600080fd5b610ccf82610e6c565b6020808252600d908201526c556e617574686f72697a65642160981b604082015260600190565b6000602082840312156110ce57600080fd5b5051919050565b600082516110e7818460208701610f9e565b9190910192915050565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761111e5761111e6110f1565b92915050565b60008261114157634e487b7160e01b600052601260045260246000fd5b500490565b8181038181111561111e5761111e6110f1565b60006020828403121561116b57600080fd5b81518015158114610ccf57600080fd5b6000806040838503121561118e57600080fd5b825161119981610e37565b602093909301519294929350505056fea2646970667358221220a9ed426d9a7752233982bbcfb0cca0a2c62565f2e420dfde4356d6f7e253c0cb64736f6c6343000813003368747470733a2f2f7265766573742e6d7970696e6174612e636c6f75642f697066732f516d6442576251394141664b516778747a32344a315a686e7a437336504654523939657376733667455631507132000000000000000000000000a68d2a210c29437a6fe5d5cb65f961858e20f3b7000000000000000000000000007fd070a7e1b0fa1364044a373ac1339bad89cf00000000000000000000000021359d1697e610e25c8229b2c57907378ed09a2e00000000000000000000000007245e57ff68b163748c6b3044f7825fdcdd9dca
Deployed Bytecode
0x6080604052600436106102725760003560e01c8063715018a61161014f57806399248ea7116100c1578063d25514121161007a578063d25514121461080a578063eac8f5b81461082a578063f2fde38b1461086a578063f3ad65f41461088a578063f48fe050146108aa578063fe56e232146108b857600080fd5b806399248ea714610736578063a49a1e7d1461076a578063aca1c6651461078a578063b4927da3146107aa578063ba156bcb146107ca578063ccec3716146107ea57600080fd5b806382bfefc81161011357806382bfefc81461065257806389158d8e146106865780638bfd9174146106a65780638d9d6705146106da5780638da5cb5b146106f85780638ecacb1b1461071657600080fd5b8063715018a6146105c85780637250e224146105dd57806376da63f3146105fd5780637d1b15dd146106185780637e5af5b81461063857600080fd5b806336b19cd7116101e857806350b492ba116101ac57806350b492ba146105155780635b0fe12014610535578063609d1fb314610555578063644bf7d8146105685780636c7b69cb1461058857806370897b23146105a857600080fd5b806336b19cd71461046a57806338c3df071461048a5780633ea5665f1461049f578063411557d1146104c157806344f5c938146104f557600080fd5b80631d1457211161023a5780631d1457211461033e5780631f87f3331461035e5780631fd2cf06146103aa5780632036e7ce146103da5780632799cde0146103fc57806327c7812c1461044a57600080fd5b806301ffc9a714610277578063063c27f8146102ac5780630ff4c916146102c35780631355f7ab146102f157806316f49e8a14610311575b600080fd5b34801561028357600080fd5b506102976102923660046134a3565b6108d8565b60405190151581526020015b60405180910390f35b3480156102b857600080fd5b506102c1610945565b005b3480156102cf57600080fd5b506102e36102de3660046134cd565b6109a7565b6040519081526020016102a3565b3480156102fd57600080fd5b506102c161030c366004613506565b610ab2565b34801561031d57600080fd5b5061033161032c3660046134cd565b610cec565b6040516102a3919061358f565b34801561034a57600080fd5b506102c16103593660046135a2565b610d80565b34801561036a57600080fd5b506103927f000000000000000000000000007fd070a7e1b0fa1364044a373ac1339bad89cf81565b6040516001600160a01b0390911681526020016102a3565b3480156103b657600080fd5b506102976103c53660046134cd565b60096020526000908152604090205460ff1681565b3480156103e657600080fd5b506102e36103f53660046135e3565b5060075490565b34801561040857600080fd5b506104326104173660046134cd565b600a602052600090815260409020546001600160801b031681565b6040516001600160801b0390911681526020016102a3565b34801561045657600080fd5b506102c16104653660046135e3565b61107b565b34801561047657600080fd5b50600454610392906001600160a01b031681565b34801561049657600080fd5b5061033161112e565b3480156104ab57600080fd5b506102e36104ba3660046135e3565b5060065490565b3480156104cd57600080fd5b506103927f000000000000000000000000a9260e283e5f9c7d15a54225d20a07181a89af1581565b34801561050157600080fd5b506102c16105103660046135e3565b6111bc565b34801561052157600080fd5b506103926105303660046134cd565b61125e565b34801561054157600080fd5b506102c1610550366004613600565b611288565b610331610563366004613724565b611422565b34801561057457600080fd5b506102c1610583366004613809565b611788565b34801561059457600080fd5b506102c16105a3366004613600565b6117c2565b3480156105b457600080fd5b506102c16105c33660046134cd565b6118fa565b3480156105d457600080fd5b506102c161198a565b3480156105e957600080fd5b506102c16105f83660046135e3565b6119c0565b34801561060957600080fd5b506102c1610583366004613869565b34801561062457600080fd5b506102c16106333660046138c0565b611a92565b34801561064457600080fd5b506008546102979060ff1681565b34801561065e57600080fd5b506103927f000000000000000000000000fc0000000000000000000000000000000000000281565b34801561069257600080fd5b506102e36106a13660046138e5565b611adc565b3480156106b257600080fd5b506103927f0000000000000000000000007ccaf46afac57b68b9bbdeb51936af04e27939af81565b3480156106e657600080fd5b506002546001600160a01b0316610392565b34801561070457600080fd5b506000546001600160a01b0316610392565b34801561072257600080fd5b506103316107313660046134cd565b611d47565b34801561074257600080fd5b506103927f000000000000000000000000fc0000000000000000000000000000000000000281565b34801561077657600080fd5b506102c1610785366004613907565b612083565b34801561079657600080fd5b506102c16107a536600461394f565b6120bd565b3480156107b657600080fd5b506102c16107c5366004613997565b612346565b3480156107d657600080fd5b506103926107e53660046134cd565b612383565b3480156107f657600080fd5b506102c16108053660046135e3565b6123dc565b34801561081657600080fd5b506102c16108253660046139b4565b612487565b34801561083657600080fd5b506103926108453660046134cd565b507f000000000000000000000000007fd070a7e1b0fa1364044a373ac1339bad89cf90565b34801561087657600080fd5b506102c16108853660046135e3565b612594565b34801561089657600080fd5b50600254610392906001600160a01b031681565b6102c16105833660046139fa565b3480156108c457600080fd5b506102c16108d33660046134cd565b61262c565b60006001600160e01b031982166368d1d7ad60e11b148061090957506001600160e01b0319821663214881cd60e11b145b8061092457506001600160e01b0319821663789bc37960e01b145b8061093f57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6000546001600160a01b031633146109785760405162461bcd60e51b815260040161096f90613aff565b60405180910390fd5b60405133904780156108fc02916000818181858888f193505050501580156109a4573d6000803e3d6000fd5b50565b60007f000000000000000000000000007fd070a7e1b0fa1364044a373ac1339bad89cf6001600160a01b03166370a08231610a4a7f0000000000000000000000007ccaf46afac57b68b9bbdeb51936af04e27939af7f000000000000000000000000fc0000000000000000000000000000000000000286604051602001610a2f929190613b34565b604051602081830303815290604052805190602001206126bb565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015610a8e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093f9190613b4d565b600260009054906101000a90046001600160a01b03166001600160a01b031663f97e7d746040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b299190613b66565b6001600160a01b0316336001600160a01b031614610b805760405162461bcd60e51b8152602060048201526014602482015273556e617574686f72697a6564204163636573732160601b604482015260640161096f565b630784ce00610b8f4284613b99565b1115610bd55760405162461bcd60e51b81526020600482015260156024820152744d6178206c6f636b7570206973203420796561727360581b604482015260640161096f565b6000610be084612728565b6000868152600a6020526040902054600380549294506001600160a01b03851693506331ffe6159287926001600160801b03169190610c2190600190613b99565b81548110610c3157610c31613bac565b60009182526020909120015460405160e085901b6001600160e01b031916815260048101939093526001600160801b0390911660248301526001600160a01b03166044820152606401600060405180830381600087803b158015610c9457600080fd5b505af1158015610ca8573d6000803e3d6000fd5b50505050837feeecc86f805a6a63ba2f3ceec31a166720d5f516c1afefe746db898be453d07b84604051610cde91815260200190565b60405180910390a250505050565b606060058054610cfb90613bc2565b80601f0160208091040260200160405190810160405280929190818152602001828054610d2790613bc2565b8015610d745780601f10610d4957610100808354040283529160200191610d74565b820191906000526020600020905b815481529060010190602001808311610d5757829003601f168201915b50505050509050919050565b600260015403610da25760405162461bcd60e51b815260040161096f90613bfc565b600260018190555460408051633e5f9f5d60e21b815290516001600160a01b039092169163f97e7d74916004808201926020929091908290030181865afa158015610df1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e159190613b66565b6001600160a01b0316336001600160a01b031614610e6c5760405162461bcd60e51b8152602060048201526014602482015273556e617574686f72697a6564204163636573732160601b604482015260640161096f565b600080610e7886612728565b91509150610e86838661278b565b9450610ebd6001600160a01b037f000000000000000000000000fc0000000000000000000000000000000000000216848488612858565b6000868152600a6020526040902054600380546001600160a01b0384169263f6a3ecfc9289926001600160801b0390921691610efb90600190613b99565b81548110610f0b57610f0b613bac565b60009182526020909120015460405160e085901b6001600160e01b031916815260048101939093526001600160801b0390911660248301526001600160a01b03166044820152606401600060405180830381600087803b158015610f6e57600080fd5b505af1158015610f82573d6000803e3d6000fd5b5050604080516001600160a01b0386811660208301528a94507f000000000000000000000000fc00000000000000000000000000000000000002811693508716917f5bed1f834b92cc21cec09497afa47d36952b8a037e988eca6e9ecffeb497b227918a910160408051601f19818403018152908290526110039291613c33565b60405180910390a47f000000000000000000000000fc000000000000000000000000000000000000026001600160a01b0316867fa6fb986371a2b2b124f881dfaf4a151317bb38bbc3070e1ee1271a46c29436bc8760405161106791815260200190565b60405180910390a350506001805550505050565b6000546001600160a01b031633146110a55760405162461bcd60e51b815260040161096f90613aff565b6001600160a01b03811661110c5760405162461bcd60e51b815260206004820152602860248201527f4572726f723a20496e76616c6964206164647265737320726567697374727920604482015267616464726573732160c01b606482015260840161096f565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6005805461113b90613bc2565b80601f016020809104026020016040519081016040528092919081815260200182805461116790613bc2565b80156111b45780601f10611189576101008083540402835291602001916111b4565b820191906000526020600020905b81548152906001019060200180831161119757829003601f168201915b505050505081565b6000546001600160a01b031633146111e65760405162461bcd60e51b815260040161096f90613aff565b6001600160a01b03811661123c5760405162461bcd60e51b815260206004820152601d60248201527f4572726f723a20496e76616c69642061646d696e206164647265737321000000604482015260640161096f565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6003818154811061126e57600080fd5b6000918252602090912001546001600160a01b0316905081565b60025460408051636acf14b760e11b8152905184926001600160a01b031691600091839163d59e296e9160048083019260209291908290030181865afa1580156112d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112fa9190613b66565b6001600160a01b0316632b04e84033856040518363ffffffff1660e01b8152600401611327929190613b34565b602060405180830381865afa158015611344573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113689190613b4d565b116113855760405162461bcd60e51b815260040161096f90613c4c565b6002600154036113a75760405162461bcd60e51b815260040161096f90613bfc565b600260015560006113b785612728565b6040516354b94c2f60e11b81526001600160a01b038781166004830152919350908316915063a972985e90602401600060405180830381600087803b1580156113ff57600080fd5b505af1158015611413573d6000803e3d6000fd5b50506001805550505050505050565b6060836000600260009054906101000a90046001600160a01b031690506000816001600160a01b031663d59e296e6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561147f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114a39190613b66565b6001600160a01b0316632b04e84033856040518363ffffffff1660e01b81526004016114d0929190613b34565b602060405180830381865afa1580156114ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115119190613b4d565b1161152e5760405162461bcd60e51b815260040161096f90613c4c565b60085460ff168061154d575060008681526009602052604090205460ff165b6115995760405162461bcd60e51b815260206004820152601960248201527f50726f787920616363657373206e6f7420656e61626c65642100000000000000604482015260640161096f565b7f000000000000000000000000fc000000000000000000000000000000000000026001600160a01b0316856001600160a01b0316036116405760405162461bcd60e51b815260206004820152603760248201527f50726f78792063616c6c20646f6573206e6f7420616c6c6f7720696e7465726160448201527f6374696f6e2077697468205245574152445f544f4b454e000000000000000000606482015260840161096f565b60005b6003548110156116f8576003818154811061166057611660613bac565b6000918252602090912001546001600160a01b03908116908716036116e65760405162461bcd60e51b815260206004820152603660248201527f50726f78792063616c6c20646f6573206e6f7420616c6c6f7720696e7465726160448201527531ba34b7b7103bb4ba34102224a9aa2924a12aaa27a960511b606482015260840161096f565b806116f081613c6a565b915050611643565b50600061170487612728565b915050806001600160a01b03166332cae16e3488886040518463ffffffff1660e01b8152600401611736929190613c83565b60006040518083038185885af1158015611754573d6000803e3d6000fd5b50505050506040513d6000823e601f3d908101601f1916820160405261177d9190810190613cd7565b979650505050505050565b60405162461bcd60e51b815260206004820152600f60248201526e4e6f74206170706c696361626c652160881b604482015260640161096f565b60025460408051636acf14b760e11b8152905184926001600160a01b031691600091839163d59e296e9160048083019260209291908290030181865afa158015611810573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118349190613b66565b6001600160a01b0316632b04e84033856040518363ffffffff1660e01b8152600401611861929190613b34565b602060405180830381865afa15801561187e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118a29190613b4d565b116118bf5760405162461bcd60e51b815260040161096f90613c4c565b6002600154036118e15760405162461bcd60e51b815260040161096f90613bfc565b60026001556118f083856128c3565b5050600180555050565b6000546001600160a01b031633146119245760405162461bcd60e51b815260040161096f90613aff565b6103e88111156119855760405162461bcd60e51b815260206004820152602660248201527f506572666f726d616e636520666565206d757374206265206c657373207468616044820152656e203130302560d01b606482015260840161096f565b600655565b6000546001600160a01b031633146119b45760405162461bcd60e51b815260040161096f90613aff565b6119be60006129c7565b565b6000546001600160a01b031633146119ea5760405162461bcd60e51b815260040161096f90613aff565b6001600160a01b038116611a405760405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206469737472696275746f7220616464726573732100000000604482015260640161096f565b600380546001810182556000919091527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b03163314611abc5760405162461bcd60e51b815260040161096f90613aff565b600091825260096020526040909120805460ff1916911515919091179055565b6000600260015403611b005760405162461bcd60e51b815260040161096f90613bfc565b6002600155611b0f338361278b565b9150611b1a83612a17565b9050600080611b2883612bee565b9092509050611b626001600160a01b037f000000000000000000000000fc0000000000000000000000000000000000000216338487612858565b6000816001600160a01b0316633c4f8dd8868860036001600380549050611b899190613b99565b81548110611b9957611b99613bac565b60009182526020909120015460405160e085901b6001600160e01b0319168152600481019390935260248301919091526001600160a01b0316604482015260640160408051808303816000875af1158015611bf8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c1c9190613d1f565b506000858152600a602090815260409182902080546fffffffffffffffffffffffffffffffff19166001600160801b03851617905581516001600160a01b0387811682840152835180830390930183529083019283905292935086927f000000000000000000000000fc00000000000000000000000000000000000002169133917f5bed1f834b92cc21cec09497afa47d36952b8a037e988eca6e9ecffeb497b22791611cca918b91613c33565b60405180910390a460408051868152602081018890526001600160a01b037f000000000000000000000000fc000000000000000000000000000000000000021691869133917f60403aa430a4d07f2b527d083643f3f4cbdab6a4d8e333693913508a69efb6e2910160405180910390a45050600180555092915050565b60038054606091600091611d5d90600190613b99565b81548110611d6d57611d6d613bac565b600091825260209182902001546040516001600160a01b0390911691628cc26291611de2917f0000000000000000000000007ccaf46afac57b68b9bbdeb51936af04e27939af91610a2f917f000000000000000000000000fc00000000000000000000000000000000000002918a9101613b34565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015611e26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e4a9190613b4d565b90508015801590606090611f42576000611e837f000000000000000000000000fc00000000000000000000000000000000000002612c63565b604051602001611e939190613d59565b60405160208183030381529060405290506000611ed0857f000000000000000000000000fc00000000000000000000000000000000000002612cf9565b611ef97f000000000000000000000000fc00000000000000000000000000000000000002612d78565b604051602001611f0a929190613d7f565b60405160208183030381529060405290508181604051602001611f2e929190613ddb565b604051602081830303815290604052925050505b6000611f4d86612383565b90506000630784ce00611f6362093a8042613e20565b611f709062093a80613e34565b611f7a9190613e4b565b6000888152600a60205260408082205490516321c984e960e01b81526001600160a01b0386811660048301526001600160801b03909216602482015292935090917f000000000000000000000000007fd070a7e1b0fa1364044a373ac1339bad89cf909116906321c984e9906044016040805180830381865afa158015612005573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120299190613e5e565b509050828486847f000000000000000000000000fc000000000000000000000000000000000000028560405160200161206796959493929190613e82565b6040516020818303038152906040529650505050505050919050565b6000546001600160a01b031633146120ad5760405162461bcd60e51b815260040161096f90613aff565b60056120b98282613f1e565b5050565b336001600160a01b037f000000000000000000000000a9260e283e5f9c7d15a54225d20a07181a89af15161461212a5760405162461bcd60e51b81526020600482015260126024820152714f6e6c79205661756c74204163636573732160701b604482015260640161096f565b60026001540361214c5760405162461bcd60e51b815260040161096f90613bfc565b600260015560008061215d86612728565b9150915061216b84876128c3565b6000868152600a6020526040908190205490516302387a7b60e01b81526001600160801b0390911660048201526001600160a01b038216906302387a7b90602401600060405180830381600087803b1580156121c657600080fd5b505af11580156121da573d6000803e3d6000fd5b50506040516370a0823160e01b8152306004820152600092507f000000000000000000000000fc000000000000000000000000000000000000026001600160a01b031691506370a0823190602401602060405180830381865afa158015612245573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122699190613b4d565b905061229f6001600160a01b037f000000000000000000000000fc00000000000000000000000000000000000002168683612dfc565b867f000000000000000000000000fc000000000000000000000000000000000000026001600160a01b0316866001600160a01b03167ff2b6e7f64080f438239b56473f2cd92b33165c88688fd898e1d99082bd0eb954848760405160200161231691906001600160a01b0391909116815260200190565b60408051601f19818403018152908290526123319291613c33565b60405180910390a45050600180555050505050565b6000546001600160a01b031633146123705760405162461bcd60e51b815260040161096f90613aff565b6008805460ff1916911515919091179055565b600061093f7f0000000000000000000000007ccaf46afac57b68b9bbdeb51936af04e27939af7f000000000000000000000000fc0000000000000000000000000000000000000284604051602001610a2f929190613b34565b6000546001600160a01b031633146124065760405162461bcd60e51b815260040161096f90613aff565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa15801561244d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124719190613b4d565b90506120b96001600160a01b0383163383612dfc565b60025460408051636acf14b760e11b8152905184926001600160a01b031691600091839163d59e296e9160048083019260209291908290030181865afa1580156124d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f99190613b66565b6001600160a01b0316632b04e84033856040518363ffffffff1660e01b8152600401612526929190613b34565b602060405180830381865afa158015612543573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125679190613b4d565b116125845760405162461bcd60e51b815260040161096f90613c4c565b61258e33856128c3565b50505050565b6000546001600160a01b031633146125be5760405162461bcd60e51b815260040161096f90613aff565b6001600160a01b0381166126235760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161096f565b6109a4816129c7565b6000546001600160a01b031633146126565760405162461bcd60e51b815260040161096f90613aff565b6103e88111156126b65760405162461bcd60e51b815260206004820152602560248201527f4d616e6167656d656e7420666565206d757374206265206c657373207468616e604482015264203130302560d81b606482015260840161096f565b600755565b6000612721838330604051733d602d80600a3d3981f3363d3d373d3d3d363d7360601b8152606093841b60148201526f5af43d82803e903d91602b57fd5bf3ff60801b6028820152921b6038830152604c8201526037808220606c830152605591012090565b9392505050565b6000806127827f0000000000000000000000007ccaf46afac57b68b9bbdeb51936af04e27939af7f000000000000000000000000fc0000000000000000000000000000000000000285604051602001610a2f929190613b34565b93849350915050565b6000806103e86007548461279f9190613e34565b6127a99190613e20565b90508015612851576004546127ed906001600160a01b037f000000000000000000000000fc0000000000000000000000000000000000000281169187911684612858565b6127f78184613b99565b9150807f000000000000000000000000fc000000000000000000000000000000000000026001600160a01b03167f5b369813f138995818116377909787d51cbdc0c2957db33f1719a36bad521f7e60405160405180910390a35b5092915050565b6040516001600160a01b038085166024830152831660448201526064810182905261258e9085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612e20565b60006128ce82612728565b91505060005b6003546128e390600190613b99565b811161258e57816001600160a01b031663380440cb85600460009054906101000a90046001600160a01b03166006546003868154811061292557612925613bac565b60009182526020909120015460405160e086901b6001600160e01b03191681526001600160a01b039485166004820152928416602484015260448301919091529190911660648201526084016020604051808303816000875af1158015612990573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129b49190613b4d565b50806129bf81613c6a565b9150506128d4565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60408051610120810182526000808252818301819052606082018190526080820181905260a082018190526101008201819052600160e0830181905260c083018190523060208401528351818152808501909452909283918160200160208202803683370190505090503381600081518110612a9557612a95613bac565b6001600160a01b039290921660209283029190910190910152604080516001808252818301909252600091816020016020820280368337019050509050600181600081518110612ae757612ae7613bac565b6020026020010181815250506000600260009054906101000a90046001600160a01b03166001600160a01b031663f97e7d746040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b6c9190613b66565b6040516305a7c08f60e41b81529091506001600160a01b03821690635a7c08f090612ba1908990879087908a90600401614052565b6020604051808303816000875af1158015612bc0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612be49190613b4d565b9695505050505050565b6000806127827f0000000000000000000000007ccaf46afac57b68b9bbdeb51936af04e27939af7f000000000000000000000000fc0000000000000000000000000000000000000285604051602001612c48929190613b34565b60405160208183030381529060405280519060200120612ef2565b6060816001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa925050508015612cc457506040513d6000823e601f3d908101601f19168201604052612cc19190810190613cd7565b60015b612cf157505060408051808201909152600d81526c2ab735b737bbb7102a37b5b2b760991b602082015290565b90505b919050565b60606000826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612d57575060408051601f3d908101601f19168201909252612d54918101906140f0565b60015b612d6357506012612d66565b90505b612d708482612f92565b949350505050565b6060816001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa925050508015612dd957506040513d6000823e601f3d908101601f19168201604052612dd69190810190613cd7565b60015b612cf15750506040805180820190915260038152623f3f3f60e81b602082015290565b612e1b8363a9059cbb60e01b848460405160240161288c929190613b34565b505050565b6000612e75826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166131479092919063ffffffff16565b805190915015612e1b5780806020019051810190612e939190614113565b612e1b5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161096f565b6000604051733d602d80600a3d3981f3363d3d373d3d3d363d7360601b81528360601b60148201526e5af43d82803e903d91602b57fd5bf360881b6028820152826037826000f59150506001600160a01b03811661093f5760405162461bcd60e51b815260206004820152601760248201527f455243313136373a2063726561746532206661696c6564000000000000000000604482015260640161096f565b60606000612fa183600a614214565b9050836000805b82156130075760ff811615612fc95780612fc181614223565b915050612fe7565b612fd4600a84614242565b15612fe75780612fe381614223565b9150505b81612ff181614223565b92506130009050600a84613e20565b9250612fa8565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081019190915260ff871661304e8385614256565b60ff1610613080576130608589613e20565b815261306c8784614256565b60ff16604082018190526020820152613125565b61308a8284614256565b61309590600a614214565b61309f9089613e20565b8152878511156130f457600260808201526130ba8388614256565b6130c590600261426f565b60ff1660a082018190526130d9908361426f565b60ff16604082018190526020820152600160c0820152613125565b6130ff82600161426f565b60ff1660408201526131118784614256565b61311c90600161426f565b60ff1660608201525b604081015160ff16602082015261313b81613156565b98975050505050505050565b6060612d708484600085613352565b60606000826020015160ff166001600160401b0381111561317957613179613630565b6040519080825280601f01601f1916602001820160405280156131a3576020820181803683370190505b5090508260c001511561320f57600360fc1b816000815181106131c8576131c8613bac565b60200101906001600160f81b031916908160001a905350601760f91b816001815181106131f7576131f7613bac565b60200101906001600160f81b031916908160001a9053505b608083015160ff165b8360a0015160ff1681101561326757603060f81b82828151811061323e5761323e613bac565b60200101906001600160f81b031916908160001a9053508061325f81613c6a565b915050613218565b505b825115612cf1576000836060015160ff161180156132945750826060015160ff16836040015160ff16145b156132dd57601760f91b818460400180516132ae90614288565b60ff1690819052815181106132c5576132c5613bac565b60200101906001600160f81b031916908160001a9053505b82516132eb90600a90614242565b6132f6906030613e4b565b60f81b8184604001805161330990614288565b60ff16908190528151811061332057613320613bac565b60200101906001600160f81b031916908160001a905350600a8360000181815161334a9190613e20565b905250613269565b6060824710156133b35760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161096f565b843b6134015760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161096f565b600080866001600160a01b0316858760405161341d91906142a5565b60006040518083038185875af1925050503d806000811461345a576040519150601f19603f3d011682016040523d82523d6000602084013e61345f565b606091505b509150915061177d82828660608315613479575081612721565b8251156134895782518084602001fd5b8160405162461bcd60e51b815260040161096f919061358f565b6000602082840312156134b557600080fd5b81356001600160e01b03198116811461272157600080fd5b6000602082840312156134df57600080fd5b5035919050565b6001600160a01b03811681146109a457600080fd5b8035612cf4816134e6565b60008060006060848603121561351b57600080fd5b83359250602084013591506040840135613534816134e6565b809150509250925092565b60005b8381101561355a578181015183820152602001613542565b50506000910152565b6000815180845261357b81602086016020860161353f565b601f01601f19169290920160200192915050565b6020815260006127216020830184613563565b600080600080608085870312156135b857600080fd5b84359350602085013592506040850135915060608501356135d8816134e6565b939692955090935050565b6000602082840312156135f557600080fd5b8135612721816134e6565b6000806040838503121561361357600080fd5b823591506020830135613625816134e6565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b60405161012081016001600160401b038111828210171561366957613669613630565b60405290565b604051601f8201601f191681016001600160401b038111828210171561369757613697613630565b604052919050565b60006001600160401b038211156136b8576136b8613630565b50601f01601f191660200190565b60006136d96136d48461369f565b61366f565b90508281528383830111156136ed57600080fd5b828260208301376000602084830101529392505050565b600082601f83011261371557600080fd5b612721838335602085016136c6565b60008060006060848603121561373957600080fd5b83359250602084013561374b816134e6565b915060408401356001600160401b0381111561376657600080fd5b61377286828701613704565b9150509250925092565b600082601f83011261378d57600080fd5b813560206001600160401b038211156137a8576137a8613630565b8160051b6137b782820161366f565b92835284810182019282810190878511156137d157600080fd5b83870192505b8483101561177d578235825291830191908301906137d7565b80151581146109a457600080fd5b8035612cf4816137f0565b6000806000806080858703121561381f57600080fd5b8435935060208501356001600160401b0381111561383c57600080fd5b6138488782880161377c565b9350506040850135613859816134e6565b915060608501356135d8816137f0565b6000806000806080858703121561387f57600080fd5b8435935060208501356001600160401b0381111561389c57600080fd5b6138a88782880161377c565b9350506040850135915060608501356135d8816134e6565b600080604083850312156138d357600080fd5b823591506020830135613625816137f0565b600080604083850312156138f857600080fd5b50508035926020909101359150565b60006020828403121561391957600080fd5b81356001600160401b0381111561392f57600080fd5b8201601f8101841361394057600080fd5b612d70848235602084016136c6565b6000806000806080858703121561396557600080fd5b843593506020850135613977816134e6565b92506040850135613987816134e6565b9396929550929360600135925050565b6000602082840312156139a957600080fd5b8135612721816137f0565b600080604083850312156139c757600080fd5b8235915060208301356001600160401b038111156139e457600080fd5b6139f085828601613704565b9150509250929050565b60008060008060008587036101a0811215613a1457600080fd5b863595506020870135613a26816134e6565b945060408701359350610120605f198201811315613a4357600080fd5b613a4b613646565b9150613a59606089016134fb565b8252613a67608089016134fb565b602083015260a0880135604083015260c0880135606083015260e088013560808301526101008089013560a0840152613aa1828a016137fe565b60c0840152613ab36101408a016137fe565b60e0840152613ac56101608a016137fe565b908301525091506101808601356001600160401b03811115613ae657600080fd5b613af288828901613704565b9150509295509295909350565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6001600160a01b03929092168252602082015260400190565b600060208284031215613b5f57600080fd5b5051919050565b600060208284031215613b7857600080fd5b8151612721816134e6565b634e487b7160e01b600052601160045260246000fd5b8181038181111561093f5761093f613b83565b634e487b7160e01b600052603260045260246000fd5b600181811c90821680613bd657607f821691505b602082108103613bf657634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b828152604060208201526000612d706040830184613563565b602080825260049082015263114c0d8d60e21b604082015260600190565b600060018201613c7c57613c7c613b83565b5060010190565b6001600160a01b0383168152604060208201819052600090612d7090830184613563565b6000613cb56136d48461369f565b9050828152838383011115613cc957600080fd5b61272183602083018461353f565b600060208284031215613ce957600080fd5b81516001600160401b03811115613cff57600080fd5b8201601f81018413613d1057600080fd5b612d7084825160208401613ca7565b60008060408385031215613d3257600080fd5b82516001600160801b0381168114613d4957600080fd5b6020939093015192949293505050565b60008251613d6b81846020870161353f565b6101d160f51b920191825250600201919050565b60008351613d9181846020880161353f565b61205b60f01b9083019081528351613db081600284016020880161353f565b715d20546f6b656e7320417661696c61626c6560701b60029290910191820152601401949350505050565b60008351613ded81846020880161353f565b835190830190613e0181836020880161353f565b01949350505050565b634e487b7160e01b600052601260045260246000fd5b600082613e2f57613e2f613e0a565b500490565b808202811582820484141761093f5761093f613b83565b8082018082111561093f5761093f613b83565b60008060408385031215613e7157600080fd5b825180600f0b8114613d4957600080fd5b600060018060a01b03808916835260c06020840152613ea460c0840189613563565b9615156040840152606083019590955250919092166080820152600f9190910b60a09091015292915050565b601f821115612e1b57600081815260208120601f850160051c81016020861015613ef75750805b601f850160051c820191505b81811015613f1657828155600101613f03565b505050505050565b81516001600160401b03811115613f3757613f37613630565b613f4b81613f458454613bc2565b84613ed0565b602080601f831160018114613f805760008415613f685750858301515b600019600386901b1c1916600185901b178555613f16565b600085815260208120601f198616915b82811015613faf57888601518255948401946001909101908401613f90565b5085821015613fcd5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60018060a01b038082511683528060208301511660208401525060408101516040830152606081015160608301526080810151608083015260a081015160a083015260c0810151151560c083015260e081015161403e60e084018215159052565b50610100818101518015158483015261258e565b848152610180602080830182905285519183018290526000916101a084019187810191845b8181101561409c5783516001600160a01b031685529382019392820192600101614077565b505084830360408601528651808452818801938201925060005b818110156140d2578451845293820193928201926001016140b6565b50505080925050506140e76060830184613fdd565b95945050505050565b60006020828403121561410257600080fd5b815160ff8116811461272157600080fd5b60006020828403121561412557600080fd5b8151612721816137f0565b600181815b8085111561416b57816000190482111561415157614151613b83565b8085161561415e57918102915b93841c9390800290614135565b509250929050565b6000826141825750600161093f565b8161418f5750600061093f565b81600181146141a557600281146141af576141cb565b600191505061093f565b60ff8411156141c0576141c0613b83565b50506001821b61093f565b5060208310610133831016604e8410600b84101617156141ee575081810a61093f565b6141f88383614130565b806000190482111561420c5761420c613b83565b029392505050565b600061272160ff841683614173565b600060ff821660ff810361423957614239613b83565b60010192915050565b60008261425157614251613e0a565b500690565b60ff828116828216039081111561093f5761093f613b83565b60ff818116838216019081111561093f5761093f613b83565b600060ff82168061429b5761429b613b83565b6000190192915050565b600082516142b781846020870161353f565b919091019291505056fea2646970667358221220611b1e0a236db42be9c817e004ef333e6ec81840dacafa4c172658304d56f9c964736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000a68d2a210c29437a6fe5d5cb65f961858e20f3b7000000000000000000000000007fd070a7e1b0fa1364044a373ac1339bad89cf00000000000000000000000021359d1697e610e25c8229b2c57907378ed09a2e00000000000000000000000007245e57ff68b163748c6b3044f7825fdcdd9dca
-----Decoded View---------------
Arg [0] : _provider (address): 0xa68D2a210c29437a6fE5d5CB65f961858e20f3B7
Arg [1] : _vE (address): 0x007FD070a7E1B0fA1364044a373Ac1339bAD89CF
Arg [2] : _distributor (address): 0x21359d1697e610e25C8229B2C57907378eD09A2E
Arg [3] : _revestAdmin (address): 0x07245E57FF68b163748C6B3044f7825FDcDd9DCA
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000a68d2a210c29437a6fe5d5cb65f961858e20f3b7
Arg [1] : 000000000000000000000000007fd070a7e1b0fa1364044a373ac1339bad89cf
Arg [2] : 00000000000000000000000021359d1697e610e25c8229b2c57907378ed09a2e
Arg [3] : 00000000000000000000000007245e57ff68b163748c6b3044f7825fdcdd9dca
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in FRAX
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.