Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
Latest 21 from a total of 21 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Batch Execute | 22347549 | 339 days ago | IN | 0 ETH | 0.00054427 | ||||
| Migrate | 22342706 | 340 days ago | IN | 0 ETH | 0.00005115 | ||||
| Piggyback Tick | 22341281 | 340 days ago | IN | 0 ETH | 0.00004617 | ||||
| Queue Task | 22340970 | 340 days ago | IN | 0 ETH | 0.00051744 | ||||
| Piggyback Tick | 22314367 | 344 days ago | IN | 0 ETH | 0.00046654 | ||||
| Piggyback Tick | 22305859 | 345 days ago | IN | 0 ETH | 0.00032729 | ||||
| Piggyback Tick | 22305445 | 345 days ago | IN | 0 ETH | 0.00016504 | ||||
| Piggyback Tick | 22305256 | 345 days ago | IN | 0 ETH | 0.00040045 | ||||
| Queue Task | 22299681 | 346 days ago | IN | 0 ETH | 0.00023842 | ||||
| Piggyback Tick | 22256189 | 352 days ago | IN | 0 ETH | 0.00007035 | ||||
| Queue Task | 22256173 | 352 days ago | IN | 0 ETH | 0.00009609 | ||||
| Queue Task | 22256167 | 352 days ago | IN | 0 ETH | 0.00010835 | ||||
| Piggyback Tick | 22256152 | 352 days ago | IN | 0 ETH | 0.0000573 | ||||
| Queue Task | 22256147 | 352 days ago | IN | 0 ETH | 0.00012205 | ||||
| Piggyback Tick | 22256135 | 352 days ago | IN | 0 ETH | 0.00005482 | ||||
| Queue Task | 22256127 | 352 days ago | IN | 0 ETH | 0.00012081 | ||||
| Piggyback Tick | 22256107 | 352 days ago | IN | 0 ETH | 0.00012743 | ||||
| Queue Task | 22256100 | 352 days ago | IN | 0 ETH | 0.00011138 | ||||
| Queue Task | 22256075 | 352 days ago | IN | 0 ETH | 0.0001162 | ||||
| Queue Task | 22256073 | 352 days ago | IN | 0 ETH | 0.00012961 | ||||
| Set Automation T... | 22256054 | 352 days ago | IN | 0 ETH | 0.00007051 |
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| 0x60806040 | 22256036 | 352 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
TaskEngine
Compiler Version
v0.8.26+commit.8a97fa7a
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: Unliscense
pragma solidity 0.8.26;
/*
* NUCLEAR MAN'S TASK ENGINE V1 for AUTOMATION TOKEN
*
* This contract is designed to facilitate automated transaction execution on the blockchain.
*
* Discord server: discord.gg *slash* DYEcm *then* buy2v (I need to do this to prevent spam, just add the parts of the link together)
* My CMC account: https://coinmarketcap.com/community/profile/Nuclear_Man_D/
*
* This contract allows for automatic transaction execution on the blockchain. Essentially, this allows you to execute arbitrary
* tasks later, without manually creating a transaction off-chain.
*
* This contract allows automated market makers, trading bots, and other on-chain automation requiring constant execution.
* With AUT token, **contracts can run their code completely autonomously, instead of relying on some external entity to trigger them.**
*
* This contract will be interesting to you if you are a developer wanting to build automation on the Ethereum blockchain.
*
* HOW DOES IT WORK?
*
* This contract is meant to work with a token contract, which is already deployed at 0x7FE47Bc309D29Eea7552e4526d8BcBB1AFE4C3c1
*
* The AUT token and this TaskEngine work together to match queued 'tasks' with real transactions,
* so that contract code can execute autonomously. The token provides transaction volume, visibility, and a fluid marketplace
* to determine how much tasks should cost. The TaskEngine is responsible for organizing and queueing tasks, handing fees to
* accounts that provide transaction volume, determining what tasks execute when, and protecting the network from malicious tasks.
*
* The AutomationToken is used to pay fees to transaction executors. The token also calls the
* task engine from functions like approve, transfer, and transferFrom, in a process I call "transaction piggybacking". The code is
* written to prevent this from increasing the gas costs to insane levels - the TaskEngine only handles up to one task per piggyback,
* and it institutes limits on how much gas a task is allowed to spend, to protect AUT owners from excessive transaction fees. Whoever
* creates the transaction that executes a task earns the fee for that task (fees are sent to tx.origin).
*
* The TaskEngine uses a FIFO to queue tasks. Each time the task engine is ticked, it scans through some of the FIFO to see what
* task needs to be executed next. If the task isn't ready to execute yet, then the task is sent to the back of the task queue.
* As transactions come in and the AutomationToken ticks the TaskEngine, it scans through the queue, executing tasks when they need
* to be executed. For larger tasks, an external executor may select which tasks in the FIFO to execute, in an attempt to earn fees
* from the tasks. Naturally, the executor will select the tasks with the highest paying fees first, allowing users to bid to have
* their tasks prioritized.
*
* Each task is a combination of a Checker and Executor. The Checker determines when the task should execute (after a particular time,
* when Eth reaches a certain price, at a random and unpredictable time, etc). Once it is determined that the task should execute and it
* is ready to do so, the Executor is called, and the task is completed.
*
* Read the source of the involved contracts to see the nitty-gritty details. There are interfaces somewhere near the top of each contract,
* which you can use for interacting with these contracts and writing your own contract. I do not recommend interacting with the TaskEngine
* directly, as it may be migrated in the future if I find a bug or it needs new features. Instead, the AutomationToken contract has the
* important functions wrapped so that you can just interact with the token contract without worrying about what TaskEngine manages your task.
*
* There are minimums for fees paid, to protect AUT users from somebody scheduling tasks with a low-ball bid. The minimum is designed to align
* with gas costs. Additionally, to prevent the queue from being bloated with tasks that will never execute, all transactions must expire,
* and the maximum expiration time is set to one week. There are also gas limits on tasks to prevent gas griefing and such. The caller is
* also protected against transaction reversions, so a bad actor cannot crash the TaskEngine. If I missed anything please let me know on the
* discord so I can fix the contract.
*
* I expect to migrate this contract in the future once the ecosystem improves and I learn more about the design tradeoffs. This is also a
* rather complex contract, which means a lot can go wrong. I wrote all of this and the token contract in a 24h period, and although I've gone
* through it and had ChatGPT take a look at it and all that, there still could be some bugs. If I find any I'll just run a migration to
* a new TaskEngine contract, no big deal.
*
*
* WHO CREATED THIS?
*
* Online I am known as Nuclear Man. And yes, I do actually love all things nuclear, always have. This is the first actual legit protocol
* I've launched, the rest were meme coins and a lot of experimentation.
*
* Anyway, here's some info for reaching me and for getting updates on the token:
* CoinMarketCap account: https://coinmarketcap.com/community/profile/Nuclear_Man_D/
*
*
* LEGAL STUFF
*
* This project, including the AutomationToken (AUT) and associated TaskEngine contract, is offered strictly as a utility token and on-chain
* automation tool. It is **not** a security, investment vehicle, or financial product. Nothing in this documentation, the codebase, or
* associated communication channels (including Discord and CoinMarketCap) constitutes financial advice, a recommendation to invest, or a
* solicitation to purchase any security or token.
*
* By interacting with the AutomationToken, the TaskEngine, or any related smart contracts, you acknowledge and agree to the following:
* 1. There is no guarantee of profit, return, appreciation in value, or even functionality. Smart contracts are inherently risky, may contain
* bugs, and may behave unpredictably due to network congestion, external contract interaction, or future protocol changes.
* 2. You assume **full responsibility** for all actions taken with this token or protocol. This includes (but is not limited to) loss of funds,
* failed transactions, high gas fees, contract vulnerabilities, or misuse of the protocol. Always DYOR (Do Your Own Research).
* 3. This system is decentralized. Once deployed, the contracts cannot be controlled or altered by the creator beyond what is built into the smart
* contracts themselves. No party guarantees uptime, access, or success of queued tasks.
* 4. You are solely responsible for ensuring that your use of the token and interaction with the protocol complies with local laws, regulations,
* and tax obligations. The creator makes no warranties that this project complies with the laws of any jurisdiction.
* 5. The software is provided "as is", without warranty of any kind - express or implied - including but not limited to merchantability, fitness
* for a particular purpose, and non-infringement.
* 6. While the creator (Nuclear Man) is actively developing tools and systems that use the AutomationToken, this does not imply any guarantee of
* continued support, future development, or market activity. The community is free to adopt or fork the system at any time.
*
* By participating in this project, you release the creator and all contributors from any and all liability arising from your use of the protocol,
* the AUT token, or any derivative thereof. By interacting with the smart contract you are agreeing to these terms.
*/
import "contracts/ExcessivelySafeCall.sol";
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
constructor() {
_transferOwnership(_msgSender());
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function decimals() external pure returns (uint8);
function allowance(
address owner,
address spender
) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
interface RunnableTask {
function execute(uint256 handle) external;
}
interface RunnableChecker {
function shouldExecute(uint256 handle) external view returns (bool);
}
abstract contract ITaskEngine is Ownable, RunnableChecker {
struct QueuedTask {
address refundTo;
RunnableTask task;
RunnableChecker checker;
uint256 handle;
uint256 operationBid; // How much we're paying to execute the operation
uint256 gasNeeded;
uint256 gasUsed;
uint expiration; // Queued tasks must eventually expire to prevent clogging
uint256 nextTaskIdx;
uint256 previousTaskIdx;
uint8 outcome;
}
uint8 constant public OUTCOME_NOT_YET = 0;
uint8 constant public OUTCOME_SUCCESS = 1;
uint8 constant public OUTCOME_FAILED = 2;
uint8 constant public OUTCOME_EXPIRED = 3;
uint8 constant public OUTCOME_CHECKER_FAILED = 4;
function getTaskById(uint256 _id) external virtual view returns (QueuedTask memory task);
// Ticking and Execution functions
function piggybackTick() external virtual;
function tick(uint64 maxExecutions) external virtual;
function batchExecute(uint256[] calldata taskIndices) external virtual;
// Queueing functions
function queueTask(RunnableTask task, RunnableChecker checker, uint256 handle, uint256 operationBid, uint256 gasNeeded, uint256 expiration) external virtual returns (uint256 _id);
// Getting data about task bid rates
function minBidFor(uint256 gasNeeded) external virtual view returns (uint256);
function marketTaskBid(uint256 gasNeeded) external virtual view returns (uint256);
// Fee collection functions
function ownerCollectFees() external virtual;
event TaskQueued(uint256 id, uint256 operationBid, uint256 gasNeeded, uint256 expiration);
event TaskExecuted(uint256 id, uint256 gasUsed, uint256 refund);
event TaskErrored(uint256 id, uint256 gasUsed);
event TaskExpired(uint256 id, uint256 expiration, uint256 refund);
event ContractMigration(address newContract);
event ContractMigrationCancelled(address other);
}
interface IAutomationToken is IERC20 {
function getCirculatingSupply() external view returns (uint256);
function transferFallback(address recipient, uint256 amount) external returns (bool);
function approveFallback(address spender, uint256 amount) external returns (bool);
function transferFromFallback(address sender, address recipient, uint256 amount) external returns (bool);
function getTaskEngine() external returns (ITaskEngine taskEngine);
}
contract TaskEngine is ITaskEngine {
using ExcessivelySafeCall for address;
mapping (uint256 => QueuedTask) queue;
uint256 public taskCursor = 0;
uint64 public nTasks = 0;
uint256 public totalTasksEverQueued = 0;
uint64 constant public MAX_INSPECTIONS_PER_TICK = 16;
uint256 constant public MAX_GAS_PER_INSPECTION = 32678;
uint256 constant public MAX_GAS_PER_PIGGYBACK = 1250000;
uint256 constant public LONGEST_ALLOWED_EXPIRATION = 1 weeks;
IAutomationToken automationToken;
uint256 ownerFeePool = 0;
// This is used to help compute the minimum fees that someone
// is allowed to pay to use the protocol
uint256 megaWeiGasCost = 900;
uint256 tokensPerEth = 160000;
// For tracking the market price of queueing tasks
// This is the ratio from
uint256 marketRate = (megaWeiGasCost * 1 gwei * tokensPerEth) / 1000;
// Migration related variables
bool public isMigrated = false;
ITaskEngine public newTaskEngine;
// PUBLIC FUNCTIONS FOR TICKING THE TASK ENGINE
// These pay you fees!!
function piggybackTick() public override {
if (isMigrated && ((block.number & 1) == 1))
newTaskEngine.piggybackTick();
else
tickInternal(true, 1);
}
function tick(uint64 maxExecutions) public override {
tickInternal(false, maxExecutions);
if (isMigrated)
newTaskEngine.tick(maxExecutions);
}
function batchExecute(uint256[] calldata taskIndices) public override {
// Don't execute if there's no tasks left
if (nTasks == 0)
return;
// Don't execute if we are re-entering recursively
// Don't execute if we've already executed within the same block and tx.origin
uint256 locker = uint160(tx.origin) + block.number;
require(locker != transactionLock, "Attempted recursive call.");
transactionLock = locker;
uint256 feesCollected = 0;
for (uint64 i = 0; i < taskIndices.length;) {
QueuedTask storage task = queue[taskIndices[i]];
if (task.outcome == OUTCOME_NOT_YET) {
(, uint256 addedFee) = attemptToProcessTask(taskIndices[i], task);
feesCollected += addedFee;
}
unchecked { i++; }
}
if (feesCollected > 0)
distributeFee(feesCollected);
}
// BIDDING DATA FUNCTIONS
function marketTaskBid(uint256 gasNeeded) external override view returns (uint256 bid) {
bid = (gasNeeded * marketRate) / (10**(18 - automationToken.decimals()));
if (bid < minBidFor(gasNeeded))
return minBidFor(gasNeeded);
}
function updateMarketPrice(uint256 bid, uint256 gasNeeded) internal {
uint256 oneTimeMarketRate = bid * (10**(18 - automationToken.decimals())) / gasNeeded;
marketRate = (31 * marketRate + oneTimeMarketRate) / 32;
}
function minBidFor(uint256 gasNeeded) public override view returns (uint256) {
if (isMigrated)
return newTaskEngine.minBidFor(gasNeeded);
uint256 costInEth = (gasNeeded * megaWeiGasCost) * (1 gwei / 1000);
uint256 costInTokens = costInEth * tokensPerEth / (10**(18 - automationToken.decimals()));
return costInTokens;
}
// QUEUEING
function queueTask(RunnableTask task, RunnableChecker checker, uint256 handle, uint256 operationBid, uint256 gasNeeded, uint256 expiration) external override returns (uint256) {
if (isMigrated)
return newTaskEngine.queueTask(task, checker, handle, operationBid, gasNeeded, expiration);
require(minBidFor(gasNeeded) <= operationBid, "Bid is not high enough.");
require(expiration == 0 || expiration <= block.timestamp + LONGEST_ALLOWED_EXPIRATION, "Expiration is too far in the future.");
automationToken.transferFromFallback(msg.sender, address(this), operationBid);
// This allows the caller to simply use '0' to indicate that they want the longest expiry.
if (expiration == 0)
expiration = block.timestamp + LONGEST_ALLOWED_EXPIRATION;
uint256 id = appendTask(task, checker, handle, operationBid, gasNeeded, expiration);
emit TaskQueued(id, operationBid, gasNeeded, expiration);
return id;
}
// DATA
function getTaskById(uint256 _id) external override view returns (QueuedTask memory task) {
require(_id < totalTasksEverQueued, "Invalid task ID");
return queue[_id];
}
// INTERNAL TASK ENGINE LOGIC
function attemptToProcessTask(uint256 index, QueuedTask storage task) internal returns (bool didExecute, uint256 addedFee) {
didExecute = false;
addedFee = 0;
uint256 feeSize = task.operationBid;
// Check if this is supposed to execute yet
(bool success, bytes memory retval) = address(task.checker).excessivelySafeStaticCall(
MAX_GAS_PER_INSPECTION, 32,
abi.encodeWithSelector(RunnableChecker.shouldExecute.selector, task.handle)
);
bool shouldPop = true;
if (success) {
if (abi.decode(retval, (bool))) {
// Execute the task
uint256 gasUsed = gasleft();
(success,) = address(task.task).excessivelySafeCall(
task.gasNeeded, 0, 0,
abi.encodeWithSelector(RunnableTask.execute.selector, task.handle)
);
gasUsed -= gasleft();
task.gasUsed = gasUsed;
// Save the outcome so it can be inspected by the caller
if (success) {
task.outcome = OUTCOME_SUCCESS;
// Refund the unused fees, but only if the task didn't revert and the gas level is less
// Gas could be slightly more in a certain edge case where gasUsed measures some gas used by this contract
if (gasUsed*10 < task.gasNeeded*9) {
feeSize = (task.operationBid * gasUsed) / task.gasNeeded;
automationToken.transfer(task.refundTo, task.operationBid - feeSize);
}
emit TaskExecuted(index, gasUsed, task.operationBid - feeSize);
} else {
task.outcome = OUTCOME_FAILED;
emit TaskErrored(index, gasUsed);
}
didExecute = true;
updateMarketPrice(task.operationBid, task.gasNeeded);
} else if (task.expiration > block.timestamp)
shouldPop = false;
else {
// If the task expired refund some of the fee, but not all
// This discourages people from queueing tasks that clog the system by expiring
feeSize = feeSize / 2;
automationToken.transfer(task.refundTo, task.operationBid - feeSize);
task.outcome = OUTCOME_EXPIRED;
emit TaskExpired(index, task.expiration, task.operationBid - feeSize);
}
} else {
task.outcome = OUTCOME_CHECKER_FAILED;
emit TaskErrored(index, 0);
}
// Handle outcomes
if (shouldPop) {
addedFee = feeSize;
unqueueTask(index);
} else if (index == taskCursor)
taskCursor = task.nextTaskIdx;
}
uint256 transactionLock;
function tickInternal(bool isPiggyback, uint64 maxExecutions) internal {
// Don't execute if we are re-entering recursively
// Don't execute if there's no tasks left
// Don't execute if we've already executed within the same block and tx.origin
uint256 locker = uint160(tx.origin) + block.number;
if (locker == transactionLock || nTasks == 0)
return;
transactionLock = locker;
uint64 tasksToInspect = nTasks;
if (tasksToInspect > MAX_INSPECTIONS_PER_TICK)
tasksToInspect = MAX_INSPECTIONS_PER_TICK;
if (maxExecutions > nTasks)
maxExecutions = nTasks;
if (tasksToInspect < maxExecutions)
tasksToInspect = maxExecutions;
uint256 feesCollected = 0;
for (uint64 i = 0; i < tasksToInspect && maxExecutions > 0;) {
QueuedTask storage task = peekNextTask();
// Don't abuse gas given to us by piggybacks
if ((!isPiggyback) || task.gasNeeded <= MAX_GAS_PER_PIGGYBACK) {
(bool didExecute, uint256 addedFee) = attemptToProcessTask(taskCursor, task);
unchecked { feesCollected += addedFee; }
if (didExecute) {
// Reduce the number of operations remaining
unchecked { maxExecutions--; }
}
}
unchecked { i++; }
}
if (feesCollected > 0)
distributeFee(feesCollected);
}
function distributeFee(uint256 totalFee) internal {
if (owner() == address(0x0))
automationToken.transfer(tx.origin, totalFee);
else {
// 2% goes to the owner, the rest goes to tx.origin
// tx.origin is deprecated because it was used to check for owner,
// which resulted in tx.origin attacks (long story). It is OK here
// because we intend on sending tokens to the one who created the
// transaction, because that's who paid the transaction fee.
// This also helps distribute tokens more.
uint256 ownerFee = (totalFee * 2) / 100;
uint256 txOriginFee = totalFee - ownerFee;
ownerFeePool += ownerFee;
automationToken.transfer(tx.origin, txOriginFee);
}
}
// ADMINISTRATION FUNCTIONS
function setAutomationToken(address tokenAddress) public onlyOwner {
require(IAutomationToken(tokenAddress).getCirculatingSupply() > 1000000, "This token does not appear legitimate.");
automationToken = IAutomationToken(tokenAddress);
}
// This is used so I can migrate to a new TaskEngine contract should the need arise.
// Calling these functions does not stop/hinder the execution of tasks queued on this contract.
function migrate(address newContract) public onlyOwner {
isMigrated = true;
newTaskEngine = ITaskEngine(newContract);
emit ContractMigration(newContract);
}
// In case some disaster happens
function undoMigration() public onlyOwner {
isMigrated = false;
emit ContractMigrationCancelled(address(newTaskEngine));
}
function ownerCollectFees() public override {
if (owner() != address(0x0) && ownerFeePool > 0 && address(automationToken) != address(0x0)) {
automationToken.transfer(owner(), ownerFeePool);
ownerFeePool = 0;
}
}
function setBiddingCharacteristics(uint256 newMegaWeiGasCost, uint256 newTokensPerEth) public onlyOwner {
megaWeiGasCost = newMegaWeiGasCost;
tokensPerEth = newTokensPerEth;
}
function _transferOwnership(address newOwner) internal virtual override {
ownerCollectFees();
Ownable._transferOwnership(newOwner);
}
// LINKED LIST TASK QUEUE IMPLEMENTATION
function appendTask(RunnableTask task, RunnableChecker checker, uint256 handle, uint256 operationBid, uint256 gasNeeded, uint expiration) internal returns (uint256 id) {
if (nTasks == 0)
taskCursor = totalTasksEverQueued;
uint256 nextIdx = taskCursor;
uint256 prevIdx = taskCursor;
if (nTasks > 0)
prevIdx = queue[taskCursor].previousTaskIdx;
id = totalTasksEverQueued;
queue[id] = QueuedTask(msg.sender, task, checker, handle, operationBid, gasNeeded, 0, expiration, nextIdx, prevIdx, OUTCOME_NOT_YET);
if (nTasks > 0) {
queue[prevIdx].nextTaskIdx = totalTasksEverQueued;
queue[taskCursor].previousTaskIdx = id;
}
unchecked {
totalTasksEverQueued++;
nTasks++;
}
}
function nextTask() public view returns (QueuedTask memory) {
return queue[taskCursor];
}
// This is more gas-efficient but only works for internal calls
function peekNextTask() internal view returns (QueuedTask storage) {
return queue[taskCursor];
}
function unqueueTask(uint256 index) internal returns (QueuedTask storage out) {
require(nTasks > 0);
out = queue[index];
nTasks--;
if (index == taskCursor)
taskCursor = out.nextTaskIdx;
if (nTasks != 0) {
queue[out.previousTaskIdx].nextTaskIdx = out.nextTaskIdx;
queue[out.nextTaskIdx].previousTaskIdx = out.previousTaskIdx;
}
}
// This just provides a convenient way to create a timer to execute a task at a particular time.
// Just use this contract as the RunnableChecker and set your handle to the desired execution timestamp.
// Consider making your execution timestamp early if it shouldn't execute late; this contract only
// garuntees that the execution will happen *after* the timestamp, not necessarily at or shortly before!
function shouldExecute(uint256 handle) external view returns (bool) {
return handle <= block.timestamp;
}
}// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity >=0.7.6;
library ExcessivelySafeCall {
uint256 constant LOW_28_MASK =
0x00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
/// @notice Use when you _really_ really _really_ don't trust the called
/// contract. This prevents the called contract from causing reversion of
/// the caller in as many ways as we can.
/// @dev The main difference between this and a solidity low-level call is
/// that we limit the number of bytes that the callee can cause to be
/// copied to caller memory. This prevents stupid things like malicious
/// contracts returning 10,000,000 bytes causing a local OOG when copying
/// to memory.
/// @param _target The address to call
/// @param _gas The amount of gas to forward to the remote contract
/// @param _value The value in wei to send to the remote contract
/// @param _maxCopy The maximum number of bytes of returndata to copy
/// to memory.
/// @param _calldata The data to send to the remote contract
/// @return success and returndata, as `.call()`. Returndata is capped to
/// `_maxCopy` bytes.
function excessivelySafeCall(
address _target,
uint256 _gas,
uint256 _value,
uint16 _maxCopy,
bytes memory _calldata
) internal returns (bool, bytes memory) {
// set up for assembly call
uint256 _toCopy;
bool _success;
bytes memory _returnData = new bytes(_maxCopy);
// dispatch message to recipient
// by assembly calling "handle" function
// we call via assembly to avoid memcopying a very large returndata
// returned by a malicious contract
assembly {
_success := call(
_gas, // gas
_target, // recipient
_value, // ether value
add(_calldata, 0x20), // inloc
mload(_calldata), // inlen
0, // outloc
0 // outlen
)
// limit our copy to 256 bytes
_toCopy := returndatasize()
if gt(_toCopy, _maxCopy) {
_toCopy := _maxCopy
}
// Store the length of the copied bytes
mstore(_returnData, _toCopy)
// copy the bytes from returndata[0:_toCopy]
returndatacopy(add(_returnData, 0x20), 0, _toCopy)
}
return (_success, _returnData);
}
/// @notice Use when you _really_ really _really_ don't trust the called
/// contract. This prevents the called contract from causing reversion of
/// the caller in as many ways as we can.
/// @dev The main difference between this and a solidity low-level call is
/// that we limit the number of bytes that the callee can cause to be
/// copied to caller memory. This prevents stupid things like malicious
/// contracts returning 10,000,000 bytes causing a local OOG when copying
/// to memory.
/// @param _target The address to call
/// @param _gas The amount of gas to forward to the remote contract
/// @param _maxCopy The maximum number of bytes of returndata to copy
/// to memory.
/// @param _calldata The data to send to the remote contract
/// @return success and returndata, as `.call()`. Returndata is capped to
/// `_maxCopy` bytes.
function excessivelySafeStaticCall(
address _target,
uint256 _gas,
uint16 _maxCopy,
bytes memory _calldata
) internal view returns (bool, bytes memory) {
// set up for assembly call
uint256 _toCopy;
bool _success;
bytes memory _returnData = new bytes(_maxCopy);
// dispatch message to recipient
// by assembly calling "handle" function
// we call via assembly to avoid memcopying a very large returndata
// returned by a malicious contract
assembly {
_success := staticcall(
_gas, // gas
_target, // recipient
add(_calldata, 0x20), // inloc
mload(_calldata), // inlen
0, // outloc
0 // outlen
)
// limit our copy to 256 bytes
_toCopy := returndatasize()
if gt(_toCopy, _maxCopy) {
_toCopy := _maxCopy
}
// Store the length of the copied bytes
mstore(_returnData, _toCopy)
// copy the bytes from returndata[0:_toCopy]
returndatacopy(add(_returnData, 0x20), 0, _toCopy)
}
return (_success, _returnData);
}
/**
* @notice Swaps function selectors in encoded contract calls
* @dev Allows reuse of encoded calldata for functions with identical
* argument types but different names. It simply swaps out the first 4 bytes
* for the new selector. This function modifies memory in place, and should
* only be used with caution.
* @param _newSelector The new 4-byte selector
* @param _buf The encoded contract args
*/
function swapSelector(bytes4 _newSelector, bytes memory _buf)
internal
pure
{
require(_buf.length >= 4);
uint256 _mask = LOW_28_MASK;
assembly {
// load the first word of
let _word := mload(add(_buf, 0x20))
// mask out the top 4 bytes
// /x
_word := and(_word, _mask)
_word := or(_newSelector, _word)
mstore(add(_buf, 0x20), _word)
}
}
}{
"optimizer": {
"enabled": false,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"remappings": []
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newContract","type":"address"}],"name":"ContractMigration","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"other","type":"address"}],"name":"ContractMigrationCancelled","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":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"gasUsed","type":"uint256"}],"name":"TaskErrored","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"gasUsed","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"refund","type":"uint256"}],"name":"TaskExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"expiration","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"refund","type":"uint256"}],"name":"TaskExpired","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"operationBid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"gasNeeded","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"expiration","type":"uint256"}],"name":"TaskQueued","type":"event"},{"inputs":[],"name":"LONGEST_ALLOWED_EXPIRATION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_GAS_PER_INSPECTION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_GAS_PER_PIGGYBACK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_INSPECTIONS_PER_TICK","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OUTCOME_CHECKER_FAILED","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OUTCOME_EXPIRED","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OUTCOME_FAILED","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OUTCOME_NOT_YET","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OUTCOME_SUCCESS","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"taskIndices","type":"uint256[]"}],"name":"batchExecute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"getTaskById","outputs":[{"components":[{"internalType":"address","name":"refundTo","type":"address"},{"internalType":"contract RunnableTask","name":"task","type":"address"},{"internalType":"contract RunnableChecker","name":"checker","type":"address"},{"internalType":"uint256","name":"handle","type":"uint256"},{"internalType":"uint256","name":"operationBid","type":"uint256"},{"internalType":"uint256","name":"gasNeeded","type":"uint256"},{"internalType":"uint256","name":"gasUsed","type":"uint256"},{"internalType":"uint256","name":"expiration","type":"uint256"},{"internalType":"uint256","name":"nextTaskIdx","type":"uint256"},{"internalType":"uint256","name":"previousTaskIdx","type":"uint256"},{"internalType":"uint8","name":"outcome","type":"uint8"}],"internalType":"struct ITaskEngine.QueuedTask","name":"task","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isMigrated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"gasNeeded","type":"uint256"}],"name":"marketTaskBid","outputs":[{"internalType":"uint256","name":"bid","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newContract","type":"address"}],"name":"migrate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"gasNeeded","type":"uint256"}],"name":"minBidFor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nTasks","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"newTaskEngine","outputs":[{"internalType":"contract ITaskEngine","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextTask","outputs":[{"components":[{"internalType":"address","name":"refundTo","type":"address"},{"internalType":"contract RunnableTask","name":"task","type":"address"},{"internalType":"contract RunnableChecker","name":"checker","type":"address"},{"internalType":"uint256","name":"handle","type":"uint256"},{"internalType":"uint256","name":"operationBid","type":"uint256"},{"internalType":"uint256","name":"gasNeeded","type":"uint256"},{"internalType":"uint256","name":"gasUsed","type":"uint256"},{"internalType":"uint256","name":"expiration","type":"uint256"},{"internalType":"uint256","name":"nextTaskIdx","type":"uint256"},{"internalType":"uint256","name":"previousTaskIdx","type":"uint256"},{"internalType":"uint8","name":"outcome","type":"uint8"}],"internalType":"struct ITaskEngine.QueuedTask","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ownerCollectFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"piggybackTick","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract RunnableTask","name":"task","type":"address"},{"internalType":"contract RunnableChecker","name":"checker","type":"address"},{"internalType":"uint256","name":"handle","type":"uint256"},{"internalType":"uint256","name":"operationBid","type":"uint256"},{"internalType":"uint256","name":"gasNeeded","type":"uint256"},{"internalType":"uint256","name":"expiration","type":"uint256"}],"name":"queueTask","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"setAutomationToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMegaWeiGasCost","type":"uint256"},{"internalType":"uint256","name":"newTokensPerEth","type":"uint256"}],"name":"setBiddingCharacteristics","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"handle","type":"uint256"}],"name":"shouldExecute","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"taskCursor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"maxExecutions","type":"uint64"}],"name":"tick","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalTasksEverQueued","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"undoMigration","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60806040525f6002555f60035f6101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505f6004555f600655610384600755620271006008556103e8600854633b9aca0060075461005d919061035d565b610067919061035d565b61007191906103cb565b6009555f600a5f6101000a81548160ff021916908315150217905550348015610098575f80fd5b506100b56100aa6100ba60201b60201c565b6100c160201b60201c565b6104d4565b5f33905090565b6100cf6100e160201b60201c565b6100de8161023f60201b60201c565b50565b5f73ffffffffffffffffffffffffffffffffffffffff1661010661030060201b60201c565b73ffffffffffffffffffffffffffffffffffffffff161415801561012b57505f600654115b801561018457505f73ffffffffffffffffffffffffffffffffffffffff1660055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b1561023d5760055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb6101d461030060201b60201c565b6006546040518363ffffffff1660e01b81526004016101f4929190610449565b6020604051808303815f875af1158015610210573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023491906104a9565b505f6006819055505b565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b5f819050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61036782610327565b915061037283610327565b925082820261038081610327565b9150828204841483151761039757610396610330565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f6103d582610327565b91506103e083610327565b9250826103f0576103ef61039e565b5b828204905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610424826103fb565b9050919050565b6104348161041a565b82525050565b61044381610327565b82525050565b5f60408201905061045c5f83018561042b565b610469602083018461043a565b9392505050565b5f80fd5b5f8115159050919050565b61048881610474565b8114610492575f80fd5b50565b5f815190506104a38161047f565b92915050565b5f602082840312156104be576104bd610470565b5b5f6104cb84828501610495565b91505092915050565b6136cc806104e15f395ff3fe608060405234801561000f575f80fd5b50600436106101e2575f3560e01c80637ffe4fb01161010d578063b14c1031116100a0578063e2c530751161006f578063e2c53075146104fe578063f1bf51091461051c578063f2fde38b1461053a578063f9fd1a0414610556576101e2565b8063b14c103114610476578063bc0d984d14610494578063c2e418e5146104c4578063ce5494bb146104e2576101e2565b80639e1dbfa0116100dc5780639e1dbfa0146104145780639f9a58651461041e578063a34ea0fb1461043a578063b06faf6214610458576101e2565b80637ffe4fb01461038e5780638da5cb5b146103aa578063976217cd146103c85780639c18e6bd146103f8576101e2565b8063375188dc11610185578063561a352211610154578063561a35221461032a57806364452804146103485780636cae22e314610366578063715018a614610384576101e2565b8063375188dc146102b457806337e5df1c146102d2578063386e047c146102f057806347e25f21146102fa576101e2565b80631352d3e3116101c15780631352d3e31461025057806326cd41261461025a578063324cc5b21461027857806334dd105d14610296576101e2565b8062a0d28f146101e6578063048e92f6146102025780630f30d94714610232575b5f80fd5b61020060048036038101906101fb9190612790565b610586565b005b61021c6004803603810190610217919061280e565b6106f2565b6040516102299190612853565b60405180910390f35b61023a6106fe565b604051610247919061287b565b60405180910390f35b610258610705565b005b6102626107b7565b60405161026f91906128b6565b60405180910390f35b6102806107bc565b60405161028d919061287b565b60405180910390f35b61029e6107c2565b6040516102ab919061287b565b60405180910390f35b6102bc6107c8565b6040516102c99190612a92565b60405180910390f35b6102da610954565b6040516102e79190612abb565b60405180910390f35b6102f8610959565b005b610314600480360381019061030f919061280e565b610aab565b604051610321919061287b565b60405180910390f35b610332610c4c565b60405161033f9190612abb565b60405180910390f35b610350610c51565b60405161035d919061287b565b60405180910390f35b61036e610c58565b60405161037b919061287b565b60405180910390f35b61038c610c5e565b005b6103a860048036038101906103a39190612afe565b610c71565b005b6103b2610d1b565b6040516103bf9190612b38565b60405180910390f35b6103e260048036038101906103dd919061280e565b610d42565b6040516103ef9190612a92565b60405180910390f35b610412600480360381019061040d9190612b51565b610f12565b005b61041c610f2c565b005b61043860048036038101906104339190612bb9565b610fa8565b005b6104426110a4565b60405161044f9190612c04565b60405180910390f35b6104606110ca565b60405161046d9190612853565b60405180910390f35b61047e6110dc565b60405161048b9190612abb565b60405180910390f35b6104ae60048036038101906104a99190612c93565b6110e1565b6040516104bb919061287b565b60405180910390f35b6104cc61135d565b6040516104d99190612abb565b60405180910390f35b6104fc60048036038101906104f79190612bb9565b611362565b005b6105066113ff565b60405161051391906128b6565b60405180910390f35b610524611418565b6040516105319190612abb565b60405180910390f35b610554600480360381019061054f9190612bb9565b61141c565b005b610570600480360381019061056b919061280e565b61149e565b60405161057d919061287b565b60405180910390f35b5f60035f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1603156106ee575f433273ffffffffffffffffffffffffffffffffffffffff166105d09190612d49565b9050600b548103610616576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060d90612dd6565b60405180910390fd5b80600b819055505f805b848490508167ffffffffffffffff1610156106d8575f60015f87878567ffffffffffffffff1681811061065657610655612df4565b5b9050602002013581526020019081526020015f2090505f60ff1681600a015f9054906101000a900460ff1660ff16036106ca575f6106b787878567ffffffffffffffff168181106106aa576106a9612df4565b5b9050602002013583611585565b91505080846106c69190612d49565b9350505b818060010192505050610620565b505f8111156106eb576106ea81611b66565b5b50505b5050565b5f428211159050919050565b62093a8081565b600a5f9054906101000a900460ff16801561072257506001804316145b156107a957600a60019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631352d3e36040518163ffffffff1660e01b81526004015f604051808303815f87803b15801561078e575f80fd5b505af11580156107a0573d5f803e3d5ffd5b505050506107b5565b6107b4600180611d28565b5b565b601081565b60045481565b617fa681565b6107d0612693565b60015f60025481526020019081526020015f20604051806101600160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600282015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201548152602001600a82015f9054906101000a900460ff1660ff1660ff1681525050905090565b600281565b5f73ffffffffffffffffffffffffffffffffffffffff16610978610d1b565b73ffffffffffffffffffffffffffffffffffffffff161415801561099d57505f600654115b80156109f657505f73ffffffffffffffffffffffffffffffffffffffff1660055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b15610aa95760055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb610a40610d1b565b6006546040518363ffffffff1660e01b8152600401610a60929190612e21565b6020604051808303815f875af1158015610a7c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610aa09190612e72565b505f6006819055505b565b5f600a5f9054906101000a900460ff1615610b6157600a60019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166347e25f21836040518263ffffffff1660e01b8152600401610b1b919061287b565b602060405180830381865afa158015610b36573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b5a9190612eb1565b9050610c47565b5f620f424060075484610b749190612edc565b610b7e9190612edc565b90505f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610beb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c0f9190612f47565b6012610c1b9190612f72565b600a610c2791906130d5565b60085483610c359190612edc565b610c3f919061314c565b905080925050505b919050565b600381565b621312d081565b60025481565b610c66611edd565b610c6f5f611f5b565b565b610c7b5f82611d28565b600a5f9054906101000a900460ff1615610d1857600a60019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637ffe4fb0826040518263ffffffff1660e01b8152600401610cea91906128b6565b5f604051808303815f87803b158015610d01575f80fd5b505af1158015610d13573d5f803e3d5ffd5b505050505b50565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b610d4a612693565b6004548210610d8e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d85906131c6565b60405180910390fd5b60015f8381526020019081526020015f20604051806101600160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600282015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201548152602001600a82015f9054906101000a900460ff1660ff1660ff16815250509050919050565b610f1a611edd565b81600781905550806008819055505050565b610f34611edd565b5f600a5f6101000a81548160ff0219169083151502179055507f33d3294ee83efa3b0e0f3373c10717726cd68d96901468972bc5e8f90b5a01a8600a60019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051610f9e9190612b38565b60405180910390a1565b610fb0611edd565b620f42408173ffffffffffffffffffffffffffffffffffffffff16632b112e496040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ffd573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110219190612eb1565b11611061576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105890613254565b60405180910390fd5b8060055f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600a60019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600a5f9054906101000a900460ff1681565b600181565b5f600a5f9054906101000a900460ff16156111a257600a60019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bc0d984d8888888888886040518763ffffffff1660e01b815260040161115b96959493929190613290565b6020604051808303815f875af1158015611177573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061119b9190612eb1565b9050611353565b836111ac84610aab565b11156111ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111e490613339565b60405180910390fd5b5f821480611209575062093a80426112059190612d49565b8211155b611248576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161123f906133c7565b60405180910390fd5b60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636aed1e5e3330876040518463ffffffff1660e01b81526004016112a6939291906133e5565b6020604051808303815f875af11580156112c2573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112e69190612e72565b505f82036113005762093a80426112fd9190612d49565b91505b5f61130f888888888888611f6f565b90507f1c0c76ed64695ce438a21e9c57fe7345196acd9370cdc07475e43b065a33588481868686604051611346949392919061341a565b60405180910390a1809150505b9695505050505050565b600481565b61136a611edd565b6001600a5f6101000a81548160ff02191690831515021790555080600a60016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f7de5c3a31d66d47148fa6afb64723e5c4f6ca52ce5d5a49b8dbff80c2aa3aefb816040516113f49190612b38565b60405180910390a150565b60035f9054906101000a900467ffffffffffffffff1681565b5f81565b611424611edd565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611492576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611489906134cd565b60405180910390fd5b61149b81611f5b565b50565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611509573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061152d9190612f47565b60126115399190612f72565b600a61154591906130d5565b600954836115539190612edc565b61155d919061314c565b905061156882610aab565b81101561157f5761157882610aab565b9050611580565b5b919050565b5f805f91505f90505f836004015490505f80611663617fa6602063048e92f660e01b89600301546040516024016115bc919061287b565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050896002015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16612291909392919063ffffffff16565b915091505f600190508215611ad657818060200190518101906116869190612e72565b15611973575f5a905061175e88600501545f8063fe0d94c160e01b8c600301546040516024016116b6919061287b565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050508c6001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1661232290949392919063ffffffff16565b50809450505a8161176f91906134eb565b9050808860060181905550831561190057600188600a015f6101000a81548160ff021916908360ff160217905550600988600501546117ae9190612edc565b600a826117bb9190612edc565b10156118b15787600501548189600401546117d69190612edc565b6117e0919061314c565b945060055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb895f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16878b6004015461185291906134eb565b6040518363ffffffff1660e01b815260040161186f929190612e21565b6020604051808303815f875af115801561188b573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118af9190612e72565b505b7f46e85e43091f3f18d88f41f5187e2f8912c73eaa67031658316ff96b9e1b2a1b8982878b600401546118e491906134eb565b6040516118f39392919061351e565b60405180910390a1611957565b600288600a015f6101000a81548160ff021916908360ff1602179055507f8f097d83ebfb2118681ddf8238df40d78d50c6bd2b0241e3899b6e6983d7c1f5898260405161194e929190613553565b60405180910390a15b6001965061196d886004015489600501546123b5565b50611ad1565b4287600701541115611987575f9050611ad0565b600284611994919061314c565b935060055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb885f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16868a60040154611a0691906134eb565b6040518363ffffffff1660e01b8152600401611a23929190612e21565b6020604051808303815f875af1158015611a3f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a639190612e72565b50600387600a015f6101000a81548160ff021916908360ff1602179055507f3c3dd59c5090f956c1bcb8074f9d1672980e21024e7cabff4e6e21c051daff1e888860070154868a60040154611ab891906134eb565b604051611ac79392919061351e565b60405180910390a15b5b611b2d565b600487600a015f6101000a81548160ff021916908360ff1602179055507f8f097d83ebfb2118681ddf8238df40d78d50c6bd2b0241e3899b6e6983d7c1f5885f604051611b249291906135b3565b60405180910390a15b8015611b4557839450611b3f886124a5565b50611b5b565b6002548803611b5a5786600801546002819055505b5b505050509250929050565b5f73ffffffffffffffffffffffffffffffffffffffff16611b85610d1b565b73ffffffffffffffffffffffffffffffffffffffff1603611c425760055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb32836040518363ffffffff1660e01b8152600401611bfc929190612e21565b6020604051808303815f875af1158015611c18573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c3c9190612e72565b50611d25565b5f6064600283611c529190612edc565b611c5c919061314c565b90505f8183611c6b91906134eb565b90508160065f828254611c7e9190612d49565b9250508190555060055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb32836040518363ffffffff1660e01b8152600401611ce1929190612e21565b6020604051808303815f875af1158015611cfd573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d219190612e72565b5050505b50565b5f433273ffffffffffffffffffffffffffffffffffffffff16611d4b9190612d49565b9050600b54811480611d7b57505f60035f9054906101000a900467ffffffffffffffff1667ffffffffffffffff16145b15611d865750611ed9565b80600b819055505f60035f9054906101000a900467ffffffffffffffff169050601067ffffffffffffffff168167ffffffffffffffff161115611dc857601090505b60035f9054906101000a900467ffffffffffffffff1667ffffffffffffffff168367ffffffffffffffff161115611e125760035f9054906101000a900467ffffffffffffffff1692505b8267ffffffffffffffff168167ffffffffffffffff161015611e32578290505b5f805b8267ffffffffffffffff168167ffffffffffffffff16108015611e6157505f8567ffffffffffffffff16115b15611ec2575f611e6f6125b2565b9050861580611e855750621312d0816005015411155b15611eb4575f80611e9860025484611585565b9150915080850194508115611eb1578780600190039850505b50505b818060010192505050611e35565b505f811115611ed557611ed481611b66565b5b5050505b5050565b611ee56125cb565b73ffffffffffffffffffffffffffffffffffffffff16611f03610d1b565b73ffffffffffffffffffffffffffffffffffffffff1614611f59576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f5090613624565b60405180910390fd5b565b611f63610959565b611f6c816125d2565b50565b5f8060035f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1603611fa0576004546002819055505b5f60025490505f60025490505f60035f9054906101000a900467ffffffffffffffff1667ffffffffffffffff161115611fed5760015f60025481526020019081526020015f206009015490505b60045492506040518061016001604052803373ffffffffffffffffffffffffffffffffffffffff1681526020018a73ffffffffffffffffffffffffffffffffffffffff1681526020018973ffffffffffffffffffffffffffffffffffffffff1681526020018881526020018781526020018681526020015f81526020018581526020018381526020018281526020015f60ff1681525060015f8581526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506040820151816002015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e082015181600701556101008201518160080155610120820151816009015561014082015181600a015f6101000a81548160ff021916908360ff1602179055509050505f60035f9054906101000a900467ffffffffffffffff1667ffffffffffffffff16111561222e5760045460015f8381526020019081526020015f20600801819055508260015f60025481526020019081526020015f20600901819055505b60045f815480929190600101919050555060035f81819054906101000a900467ffffffffffffffff168092919060010191906101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505050509695505050505050565b5f60605f805f8661ffff1667ffffffffffffffff8111156122b5576122b4613642565b5b6040519080825280601f01601f1916602001820160405280156122e75781602001600182028036833780820191505090505b5090505f808751602089018c8cfa91503d925086831115612306578692505b828152825f602083013e81819450945050505094509492505050565b5f60605f805f8661ffff1667ffffffffffffffff81111561234657612345613642565b5b6040519080825280601f01601f1916602001820160405280156123785781602001600182028036833780820191505090505b5090505f808751602089018b8e8ef191503d925086831115612398578692505b828152825f602083013e8181945094505050509550959350505050565b5f8160055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015612421573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124459190612f47565b60126124519190612f72565b600a61245d91906130d5565b846124689190612edc565b612472919061314c565b9050602081600954601f6124869190612edc565b6124909190612d49565b61249a919061314c565b600981905550505050565b5f8060035f9054906101000a900467ffffffffffffffff1667ffffffffffffffff16116124d0575f80fd5b60015f8381526020019081526020015f20905060035f81819054906101000a900467ffffffffffffffff16809291906125089061366f565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505060025482036125445780600801546002819055505b5f60035f9054906101000a900467ffffffffffffffff1667ffffffffffffffff16146125ad57806008015460015f836009015481526020019081526020015f2060080181905550806009015460015f836008015481526020019081526020015f20600901819055505b919050565b5f60015f60025481526020019081526020015f20905090565b5f33905090565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6040518061016001604052805f73ffffffffffffffffffffffffffffffffffffffff1681526020015f73ffffffffffffffffffffffffffffffffffffffff1681526020015f73ffffffffffffffffffffffffffffffffffffffff1681526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f60ff1681525090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f8083601f8401126127505761274f61272f565b5b8235905067ffffffffffffffff81111561276d5761276c612733565b5b60208301915083602082028301111561278957612788612737565b5b9250929050565b5f80602083850312156127a6576127a5612727565b5b5f83013567ffffffffffffffff8111156127c3576127c261272b565b5b6127cf8582860161273b565b92509250509250929050565b5f819050919050565b6127ed816127db565b81146127f7575f80fd5b50565b5f81359050612808816127e4565b92915050565b5f6020828403121561282357612822612727565b5b5f612830848285016127fa565b91505092915050565b5f8115159050919050565b61284d81612839565b82525050565b5f6020820190506128665f830184612844565b92915050565b612875816127db565b82525050565b5f60208201905061288e5f83018461286c565b92915050565b5f67ffffffffffffffff82169050919050565b6128b081612894565b82525050565b5f6020820190506128c95f8301846128a7565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6128f8826128cf565b9050919050565b612908816128ee565b82525050565b5f819050919050565b5f61293161292c612927846128cf565b61290e565b6128cf565b9050919050565b5f61294282612917565b9050919050565b5f61295382612938565b9050919050565b61296381612949565b82525050565b5f61297382612938565b9050919050565b61298381612969565b82525050565b612992816127db565b82525050565b5f60ff82169050919050565b6129ad81612998565b82525050565b61016082015f8201516129c85f8501826128ff565b5060208201516129db602085018261295a565b5060408201516129ee604085018261297a565b506060820151612a016060850182612989565b506080820151612a146080850182612989565b5060a0820151612a2760a0850182612989565b5060c0820151612a3a60c0850182612989565b5060e0820151612a4d60e0850182612989565b50610100820151612a62610100850182612989565b50610120820151612a77610120850182612989565b50610140820151612a8c6101408501826129a4565b50505050565b5f61016082019050612aa65f8301846129b3565b92915050565b612ab581612998565b82525050565b5f602082019050612ace5f830184612aac565b92915050565b612add81612894565b8114612ae7575f80fd5b50565b5f81359050612af881612ad4565b92915050565b5f60208284031215612b1357612b12612727565b5b5f612b2084828501612aea565b91505092915050565b612b32816128ee565b82525050565b5f602082019050612b4b5f830184612b29565b92915050565b5f8060408385031215612b6757612b66612727565b5b5f612b74858286016127fa565b9250506020612b85858286016127fa565b9150509250929050565b612b98816128ee565b8114612ba2575f80fd5b50565b5f81359050612bb381612b8f565b92915050565b5f60208284031215612bce57612bcd612727565b5b5f612bdb84828501612ba5565b91505092915050565b5f612bee82612938565b9050919050565b612bfe81612be4565b82525050565b5f602082019050612c175f830184612bf5565b92915050565b5f612c27826128ee565b9050919050565b612c3781612c1d565b8114612c41575f80fd5b50565b5f81359050612c5281612c2e565b92915050565b5f612c62826128ee565b9050919050565b612c7281612c58565b8114612c7c575f80fd5b50565b5f81359050612c8d81612c69565b92915050565b5f805f805f8060c08789031215612cad57612cac612727565b5b5f612cba89828a01612c44565b9650506020612ccb89828a01612c7f565b9550506040612cdc89828a016127fa565b9450506060612ced89828a016127fa565b9350506080612cfe89828a016127fa565b92505060a0612d0f89828a016127fa565b9150509295509295509295565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612d53826127db565b9150612d5e836127db565b9250828201905080821115612d7657612d75612d1c565b5b92915050565b5f82825260208201905092915050565b7f417474656d70746564207265637572736976652063616c6c2e000000000000005f82015250565b5f612dc0601983612d7c565b9150612dcb82612d8c565b602082019050919050565b5f6020820190508181035f830152612ded81612db4565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f604082019050612e345f830185612b29565b612e41602083018461286c565b9392505050565b612e5181612839565b8114612e5b575f80fd5b50565b5f81519050612e6c81612e48565b92915050565b5f60208284031215612e8757612e86612727565b5b5f612e9484828501612e5e565b91505092915050565b5f81519050612eab816127e4565b92915050565b5f60208284031215612ec657612ec5612727565b5b5f612ed384828501612e9d565b91505092915050565b5f612ee6826127db565b9150612ef1836127db565b9250828202612eff816127db565b91508282048414831517612f1657612f15612d1c565b5b5092915050565b612f2681612998565b8114612f30575f80fd5b50565b5f81519050612f4181612f1d565b92915050565b5f60208284031215612f5c57612f5b612727565b5b5f612f6984828501612f33565b91505092915050565b5f612f7c82612998565b9150612f8783612998565b9250828203905060ff811115612fa057612f9f612d1c565b5b92915050565b5f8160011c9050919050565b5f808291508390505b6001851115612ffb57808604811115612fd757612fd6612d1c565b5b6001851615612fe65780820291505b8081029050612ff485612fa6565b9450612fbb565b94509492505050565b5f8261301357600190506130ce565b81613020575f90506130ce565b816001811461303657600281146130405761306f565b60019150506130ce565b60ff84111561305257613051612d1c565b5b8360020a91508482111561306957613068612d1c565b5b506130ce565b5060208310610133831016604e8410600b84101617156130a45782820a90508381111561309f5761309e612d1c565b5b6130ce565b6130b18484846001612fb2565b925090508184048111156130c8576130c7612d1c565b5b81810290505b9392505050565b5f6130df826127db565b91506130ea83612998565b92506131177fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484613004565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f613156826127db565b9150613161836127db565b9250826131715761317061311f565b5b828204905092915050565b7f496e76616c6964207461736b20494400000000000000000000000000000000005f82015250565b5f6131b0600f83612d7c565b91506131bb8261317c565b602082019050919050565b5f6020820190508181035f8301526131dd816131a4565b9050919050565b7f5468697320746f6b656e20646f6573206e6f7420617070656172206c656769745f8201527f696d6174652e0000000000000000000000000000000000000000000000000000602082015250565b5f61323e602683612d7c565b9150613249826131e4565b604082019050919050565b5f6020820190508181035f83015261326b81613232565b9050919050565b61327b81612949565b82525050565b61328a81612969565b82525050565b5f60c0820190506132a35f830189613272565b6132b06020830188613281565b6132bd604083018761286c565b6132ca606083018661286c565b6132d7608083018561286c565b6132e460a083018461286c565b979650505050505050565b7f426964206973206e6f74206869676820656e6f7567682e0000000000000000005f82015250565b5f613323601783612d7c565b915061332e826132ef565b602082019050919050565b5f6020820190508181035f83015261335081613317565b9050919050565b7f45787069726174696f6e20697320746f6f2066617220696e20746865206675745f8201527f7572652e00000000000000000000000000000000000000000000000000000000602082015250565b5f6133b1602483612d7c565b91506133bc82613357565b604082019050919050565b5f6020820190508181035f8301526133de816133a5565b9050919050565b5f6060820190506133f85f830186612b29565b6134056020830185612b29565b613412604083018461286c565b949350505050565b5f60808201905061342d5f83018761286c565b61343a602083018661286c565b613447604083018561286c565b613454606083018461286c565b95945050505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f20615f8201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b5f6134b7602683612d7c565b91506134c28261345d565b604082019050919050565b5f6020820190508181035f8301526134e4816134ab565b9050919050565b5f6134f5826127db565b9150613500836127db565b925082820390508181111561351857613517612d1c565b5b92915050565b5f6060820190506135315f83018661286c565b61353e602083018561286c565b61354b604083018461286c565b949350505050565b5f6040820190506135665f83018561286c565b613573602083018461286c565b9392505050565b5f819050919050565b5f61359d6135986135938461357a565b61290e565b6127db565b9050919050565b6135ad81613583565b82525050565b5f6040820190506135c65f83018561286c565b6135d360208301846135a4565b9392505050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725f82015250565b5f61360e602083612d7c565b9150613619826135da565b602082019050919050565b5f6020820190508181035f83015261363b81613602565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f61367982612894565b91505f820361368b5761368a612d1c565b5b60018203905091905056fea26469706673582212206e5df5938ea13a63584778edb31deed50deaf24adce45a8a26e2ca1b2b1abd3a64736f6c634300081a0033
Deployed Bytecode
0x608060405234801561000f575f80fd5b50600436106101e2575f3560e01c80637ffe4fb01161010d578063b14c1031116100a0578063e2c530751161006f578063e2c53075146104fe578063f1bf51091461051c578063f2fde38b1461053a578063f9fd1a0414610556576101e2565b8063b14c103114610476578063bc0d984d14610494578063c2e418e5146104c4578063ce5494bb146104e2576101e2565b80639e1dbfa0116100dc5780639e1dbfa0146104145780639f9a58651461041e578063a34ea0fb1461043a578063b06faf6214610458576101e2565b80637ffe4fb01461038e5780638da5cb5b146103aa578063976217cd146103c85780639c18e6bd146103f8576101e2565b8063375188dc11610185578063561a352211610154578063561a35221461032a57806364452804146103485780636cae22e314610366578063715018a614610384576101e2565b8063375188dc146102b457806337e5df1c146102d2578063386e047c146102f057806347e25f21146102fa576101e2565b80631352d3e3116101c15780631352d3e31461025057806326cd41261461025a578063324cc5b21461027857806334dd105d14610296576101e2565b8062a0d28f146101e6578063048e92f6146102025780630f30d94714610232575b5f80fd5b61020060048036038101906101fb9190612790565b610586565b005b61021c6004803603810190610217919061280e565b6106f2565b6040516102299190612853565b60405180910390f35b61023a6106fe565b604051610247919061287b565b60405180910390f35b610258610705565b005b6102626107b7565b60405161026f91906128b6565b60405180910390f35b6102806107bc565b60405161028d919061287b565b60405180910390f35b61029e6107c2565b6040516102ab919061287b565b60405180910390f35b6102bc6107c8565b6040516102c99190612a92565b60405180910390f35b6102da610954565b6040516102e79190612abb565b60405180910390f35b6102f8610959565b005b610314600480360381019061030f919061280e565b610aab565b604051610321919061287b565b60405180910390f35b610332610c4c565b60405161033f9190612abb565b60405180910390f35b610350610c51565b60405161035d919061287b565b60405180910390f35b61036e610c58565b60405161037b919061287b565b60405180910390f35b61038c610c5e565b005b6103a860048036038101906103a39190612afe565b610c71565b005b6103b2610d1b565b6040516103bf9190612b38565b60405180910390f35b6103e260048036038101906103dd919061280e565b610d42565b6040516103ef9190612a92565b60405180910390f35b610412600480360381019061040d9190612b51565b610f12565b005b61041c610f2c565b005b61043860048036038101906104339190612bb9565b610fa8565b005b6104426110a4565b60405161044f9190612c04565b60405180910390f35b6104606110ca565b60405161046d9190612853565b60405180910390f35b61047e6110dc565b60405161048b9190612abb565b60405180910390f35b6104ae60048036038101906104a99190612c93565b6110e1565b6040516104bb919061287b565b60405180910390f35b6104cc61135d565b6040516104d99190612abb565b60405180910390f35b6104fc60048036038101906104f79190612bb9565b611362565b005b6105066113ff565b60405161051391906128b6565b60405180910390f35b610524611418565b6040516105319190612abb565b60405180910390f35b610554600480360381019061054f9190612bb9565b61141c565b005b610570600480360381019061056b919061280e565b61149e565b60405161057d919061287b565b60405180910390f35b5f60035f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1603156106ee575f433273ffffffffffffffffffffffffffffffffffffffff166105d09190612d49565b9050600b548103610616576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060d90612dd6565b60405180910390fd5b80600b819055505f805b848490508167ffffffffffffffff1610156106d8575f60015f87878567ffffffffffffffff1681811061065657610655612df4565b5b9050602002013581526020019081526020015f2090505f60ff1681600a015f9054906101000a900460ff1660ff16036106ca575f6106b787878567ffffffffffffffff168181106106aa576106a9612df4565b5b9050602002013583611585565b91505080846106c69190612d49565b9350505b818060010192505050610620565b505f8111156106eb576106ea81611b66565b5b50505b5050565b5f428211159050919050565b62093a8081565b600a5f9054906101000a900460ff16801561072257506001804316145b156107a957600a60019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631352d3e36040518163ffffffff1660e01b81526004015f604051808303815f87803b15801561078e575f80fd5b505af11580156107a0573d5f803e3d5ffd5b505050506107b5565b6107b4600180611d28565b5b565b601081565b60045481565b617fa681565b6107d0612693565b60015f60025481526020019081526020015f20604051806101600160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600282015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201548152602001600a82015f9054906101000a900460ff1660ff1660ff1681525050905090565b600281565b5f73ffffffffffffffffffffffffffffffffffffffff16610978610d1b565b73ffffffffffffffffffffffffffffffffffffffff161415801561099d57505f600654115b80156109f657505f73ffffffffffffffffffffffffffffffffffffffff1660055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b15610aa95760055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb610a40610d1b565b6006546040518363ffffffff1660e01b8152600401610a60929190612e21565b6020604051808303815f875af1158015610a7c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610aa09190612e72565b505f6006819055505b565b5f600a5f9054906101000a900460ff1615610b6157600a60019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166347e25f21836040518263ffffffff1660e01b8152600401610b1b919061287b565b602060405180830381865afa158015610b36573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b5a9190612eb1565b9050610c47565b5f620f424060075484610b749190612edc565b610b7e9190612edc565b90505f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610beb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c0f9190612f47565b6012610c1b9190612f72565b600a610c2791906130d5565b60085483610c359190612edc565b610c3f919061314c565b905080925050505b919050565b600381565b621312d081565b60025481565b610c66611edd565b610c6f5f611f5b565b565b610c7b5f82611d28565b600a5f9054906101000a900460ff1615610d1857600a60019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637ffe4fb0826040518263ffffffff1660e01b8152600401610cea91906128b6565b5f604051808303815f87803b158015610d01575f80fd5b505af1158015610d13573d5f803e3d5ffd5b505050505b50565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b610d4a612693565b6004548210610d8e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d85906131c6565b60405180910390fd5b60015f8381526020019081526020015f20604051806101600160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600282015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201548152602001600a82015f9054906101000a900460ff1660ff1660ff16815250509050919050565b610f1a611edd565b81600781905550806008819055505050565b610f34611edd565b5f600a5f6101000a81548160ff0219169083151502179055507f33d3294ee83efa3b0e0f3373c10717726cd68d96901468972bc5e8f90b5a01a8600a60019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051610f9e9190612b38565b60405180910390a1565b610fb0611edd565b620f42408173ffffffffffffffffffffffffffffffffffffffff16632b112e496040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ffd573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110219190612eb1565b11611061576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105890613254565b60405180910390fd5b8060055f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600a60019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600a5f9054906101000a900460ff1681565b600181565b5f600a5f9054906101000a900460ff16156111a257600a60019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bc0d984d8888888888886040518763ffffffff1660e01b815260040161115b96959493929190613290565b6020604051808303815f875af1158015611177573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061119b9190612eb1565b9050611353565b836111ac84610aab565b11156111ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111e490613339565b60405180910390fd5b5f821480611209575062093a80426112059190612d49565b8211155b611248576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161123f906133c7565b60405180910390fd5b60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636aed1e5e3330876040518463ffffffff1660e01b81526004016112a6939291906133e5565b6020604051808303815f875af11580156112c2573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112e69190612e72565b505f82036113005762093a80426112fd9190612d49565b91505b5f61130f888888888888611f6f565b90507f1c0c76ed64695ce438a21e9c57fe7345196acd9370cdc07475e43b065a33588481868686604051611346949392919061341a565b60405180910390a1809150505b9695505050505050565b600481565b61136a611edd565b6001600a5f6101000a81548160ff02191690831515021790555080600a60016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f7de5c3a31d66d47148fa6afb64723e5c4f6ca52ce5d5a49b8dbff80c2aa3aefb816040516113f49190612b38565b60405180910390a150565b60035f9054906101000a900467ffffffffffffffff1681565b5f81565b611424611edd565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611492576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611489906134cd565b60405180910390fd5b61149b81611f5b565b50565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611509573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061152d9190612f47565b60126115399190612f72565b600a61154591906130d5565b600954836115539190612edc565b61155d919061314c565b905061156882610aab565b81101561157f5761157882610aab565b9050611580565b5b919050565b5f805f91505f90505f836004015490505f80611663617fa6602063048e92f660e01b89600301546040516024016115bc919061287b565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050896002015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16612291909392919063ffffffff16565b915091505f600190508215611ad657818060200190518101906116869190612e72565b15611973575f5a905061175e88600501545f8063fe0d94c160e01b8c600301546040516024016116b6919061287b565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050508c6001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1661232290949392919063ffffffff16565b50809450505a8161176f91906134eb565b9050808860060181905550831561190057600188600a015f6101000a81548160ff021916908360ff160217905550600988600501546117ae9190612edc565b600a826117bb9190612edc565b10156118b15787600501548189600401546117d69190612edc565b6117e0919061314c565b945060055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb895f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16878b6004015461185291906134eb565b6040518363ffffffff1660e01b815260040161186f929190612e21565b6020604051808303815f875af115801561188b573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118af9190612e72565b505b7f46e85e43091f3f18d88f41f5187e2f8912c73eaa67031658316ff96b9e1b2a1b8982878b600401546118e491906134eb565b6040516118f39392919061351e565b60405180910390a1611957565b600288600a015f6101000a81548160ff021916908360ff1602179055507f8f097d83ebfb2118681ddf8238df40d78d50c6bd2b0241e3899b6e6983d7c1f5898260405161194e929190613553565b60405180910390a15b6001965061196d886004015489600501546123b5565b50611ad1565b4287600701541115611987575f9050611ad0565b600284611994919061314c565b935060055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb885f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16868a60040154611a0691906134eb565b6040518363ffffffff1660e01b8152600401611a23929190612e21565b6020604051808303815f875af1158015611a3f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a639190612e72565b50600387600a015f6101000a81548160ff021916908360ff1602179055507f3c3dd59c5090f956c1bcb8074f9d1672980e21024e7cabff4e6e21c051daff1e888860070154868a60040154611ab891906134eb565b604051611ac79392919061351e565b60405180910390a15b5b611b2d565b600487600a015f6101000a81548160ff021916908360ff1602179055507f8f097d83ebfb2118681ddf8238df40d78d50c6bd2b0241e3899b6e6983d7c1f5885f604051611b249291906135b3565b60405180910390a15b8015611b4557839450611b3f886124a5565b50611b5b565b6002548803611b5a5786600801546002819055505b5b505050509250929050565b5f73ffffffffffffffffffffffffffffffffffffffff16611b85610d1b565b73ffffffffffffffffffffffffffffffffffffffff1603611c425760055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb32836040518363ffffffff1660e01b8152600401611bfc929190612e21565b6020604051808303815f875af1158015611c18573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c3c9190612e72565b50611d25565b5f6064600283611c529190612edc565b611c5c919061314c565b90505f8183611c6b91906134eb565b90508160065f828254611c7e9190612d49565b9250508190555060055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb32836040518363ffffffff1660e01b8152600401611ce1929190612e21565b6020604051808303815f875af1158015611cfd573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d219190612e72565b5050505b50565b5f433273ffffffffffffffffffffffffffffffffffffffff16611d4b9190612d49565b9050600b54811480611d7b57505f60035f9054906101000a900467ffffffffffffffff1667ffffffffffffffff16145b15611d865750611ed9565b80600b819055505f60035f9054906101000a900467ffffffffffffffff169050601067ffffffffffffffff168167ffffffffffffffff161115611dc857601090505b60035f9054906101000a900467ffffffffffffffff1667ffffffffffffffff168367ffffffffffffffff161115611e125760035f9054906101000a900467ffffffffffffffff1692505b8267ffffffffffffffff168167ffffffffffffffff161015611e32578290505b5f805b8267ffffffffffffffff168167ffffffffffffffff16108015611e6157505f8567ffffffffffffffff16115b15611ec2575f611e6f6125b2565b9050861580611e855750621312d0816005015411155b15611eb4575f80611e9860025484611585565b9150915080850194508115611eb1578780600190039850505b50505b818060010192505050611e35565b505f811115611ed557611ed481611b66565b5b5050505b5050565b611ee56125cb565b73ffffffffffffffffffffffffffffffffffffffff16611f03610d1b565b73ffffffffffffffffffffffffffffffffffffffff1614611f59576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f5090613624565b60405180910390fd5b565b611f63610959565b611f6c816125d2565b50565b5f8060035f9054906101000a900467ffffffffffffffff1667ffffffffffffffff1603611fa0576004546002819055505b5f60025490505f60025490505f60035f9054906101000a900467ffffffffffffffff1667ffffffffffffffff161115611fed5760015f60025481526020019081526020015f206009015490505b60045492506040518061016001604052803373ffffffffffffffffffffffffffffffffffffffff1681526020018a73ffffffffffffffffffffffffffffffffffffffff1681526020018973ffffffffffffffffffffffffffffffffffffffff1681526020018881526020018781526020018681526020015f81526020018581526020018381526020018281526020015f60ff1681525060015f8581526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506040820151816002015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e082015181600701556101008201518160080155610120820151816009015561014082015181600a015f6101000a81548160ff021916908360ff1602179055509050505f60035f9054906101000a900467ffffffffffffffff1667ffffffffffffffff16111561222e5760045460015f8381526020019081526020015f20600801819055508260015f60025481526020019081526020015f20600901819055505b60045f815480929190600101919050555060035f81819054906101000a900467ffffffffffffffff168092919060010191906101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505050509695505050505050565b5f60605f805f8661ffff1667ffffffffffffffff8111156122b5576122b4613642565b5b6040519080825280601f01601f1916602001820160405280156122e75781602001600182028036833780820191505090505b5090505f808751602089018c8cfa91503d925086831115612306578692505b828152825f602083013e81819450945050505094509492505050565b5f60605f805f8661ffff1667ffffffffffffffff81111561234657612345613642565b5b6040519080825280601f01601f1916602001820160405280156123785781602001600182028036833780820191505090505b5090505f808751602089018b8e8ef191503d925086831115612398578692505b828152825f602083013e8181945094505050509550959350505050565b5f8160055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015612421573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124459190612f47565b60126124519190612f72565b600a61245d91906130d5565b846124689190612edc565b612472919061314c565b9050602081600954601f6124869190612edc565b6124909190612d49565b61249a919061314c565b600981905550505050565b5f8060035f9054906101000a900467ffffffffffffffff1667ffffffffffffffff16116124d0575f80fd5b60015f8381526020019081526020015f20905060035f81819054906101000a900467ffffffffffffffff16809291906125089061366f565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505060025482036125445780600801546002819055505b5f60035f9054906101000a900467ffffffffffffffff1667ffffffffffffffff16146125ad57806008015460015f836009015481526020019081526020015f2060080181905550806009015460015f836008015481526020019081526020015f20600901819055505b919050565b5f60015f60025481526020019081526020015f20905090565b5f33905090565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6040518061016001604052805f73ffffffffffffffffffffffffffffffffffffffff1681526020015f73ffffffffffffffffffffffffffffffffffffffff1681526020015f73ffffffffffffffffffffffffffffffffffffffff1681526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81526020015f60ff1681525090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f8083601f8401126127505761274f61272f565b5b8235905067ffffffffffffffff81111561276d5761276c612733565b5b60208301915083602082028301111561278957612788612737565b5b9250929050565b5f80602083850312156127a6576127a5612727565b5b5f83013567ffffffffffffffff8111156127c3576127c261272b565b5b6127cf8582860161273b565b92509250509250929050565b5f819050919050565b6127ed816127db565b81146127f7575f80fd5b50565b5f81359050612808816127e4565b92915050565b5f6020828403121561282357612822612727565b5b5f612830848285016127fa565b91505092915050565b5f8115159050919050565b61284d81612839565b82525050565b5f6020820190506128665f830184612844565b92915050565b612875816127db565b82525050565b5f60208201905061288e5f83018461286c565b92915050565b5f67ffffffffffffffff82169050919050565b6128b081612894565b82525050565b5f6020820190506128c95f8301846128a7565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6128f8826128cf565b9050919050565b612908816128ee565b82525050565b5f819050919050565b5f61293161292c612927846128cf565b61290e565b6128cf565b9050919050565b5f61294282612917565b9050919050565b5f61295382612938565b9050919050565b61296381612949565b82525050565b5f61297382612938565b9050919050565b61298381612969565b82525050565b612992816127db565b82525050565b5f60ff82169050919050565b6129ad81612998565b82525050565b61016082015f8201516129c85f8501826128ff565b5060208201516129db602085018261295a565b5060408201516129ee604085018261297a565b506060820151612a016060850182612989565b506080820151612a146080850182612989565b5060a0820151612a2760a0850182612989565b5060c0820151612a3a60c0850182612989565b5060e0820151612a4d60e0850182612989565b50610100820151612a62610100850182612989565b50610120820151612a77610120850182612989565b50610140820151612a8c6101408501826129a4565b50505050565b5f61016082019050612aa65f8301846129b3565b92915050565b612ab581612998565b82525050565b5f602082019050612ace5f830184612aac565b92915050565b612add81612894565b8114612ae7575f80fd5b50565b5f81359050612af881612ad4565b92915050565b5f60208284031215612b1357612b12612727565b5b5f612b2084828501612aea565b91505092915050565b612b32816128ee565b82525050565b5f602082019050612b4b5f830184612b29565b92915050565b5f8060408385031215612b6757612b66612727565b5b5f612b74858286016127fa565b9250506020612b85858286016127fa565b9150509250929050565b612b98816128ee565b8114612ba2575f80fd5b50565b5f81359050612bb381612b8f565b92915050565b5f60208284031215612bce57612bcd612727565b5b5f612bdb84828501612ba5565b91505092915050565b5f612bee82612938565b9050919050565b612bfe81612be4565b82525050565b5f602082019050612c175f830184612bf5565b92915050565b5f612c27826128ee565b9050919050565b612c3781612c1d565b8114612c41575f80fd5b50565b5f81359050612c5281612c2e565b92915050565b5f612c62826128ee565b9050919050565b612c7281612c58565b8114612c7c575f80fd5b50565b5f81359050612c8d81612c69565b92915050565b5f805f805f8060c08789031215612cad57612cac612727565b5b5f612cba89828a01612c44565b9650506020612ccb89828a01612c7f565b9550506040612cdc89828a016127fa565b9450506060612ced89828a016127fa565b9350506080612cfe89828a016127fa565b92505060a0612d0f89828a016127fa565b9150509295509295509295565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612d53826127db565b9150612d5e836127db565b9250828201905080821115612d7657612d75612d1c565b5b92915050565b5f82825260208201905092915050565b7f417474656d70746564207265637572736976652063616c6c2e000000000000005f82015250565b5f612dc0601983612d7c565b9150612dcb82612d8c565b602082019050919050565b5f6020820190508181035f830152612ded81612db4565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f604082019050612e345f830185612b29565b612e41602083018461286c565b9392505050565b612e5181612839565b8114612e5b575f80fd5b50565b5f81519050612e6c81612e48565b92915050565b5f60208284031215612e8757612e86612727565b5b5f612e9484828501612e5e565b91505092915050565b5f81519050612eab816127e4565b92915050565b5f60208284031215612ec657612ec5612727565b5b5f612ed384828501612e9d565b91505092915050565b5f612ee6826127db565b9150612ef1836127db565b9250828202612eff816127db565b91508282048414831517612f1657612f15612d1c565b5b5092915050565b612f2681612998565b8114612f30575f80fd5b50565b5f81519050612f4181612f1d565b92915050565b5f60208284031215612f5c57612f5b612727565b5b5f612f6984828501612f33565b91505092915050565b5f612f7c82612998565b9150612f8783612998565b9250828203905060ff811115612fa057612f9f612d1c565b5b92915050565b5f8160011c9050919050565b5f808291508390505b6001851115612ffb57808604811115612fd757612fd6612d1c565b5b6001851615612fe65780820291505b8081029050612ff485612fa6565b9450612fbb565b94509492505050565b5f8261301357600190506130ce565b81613020575f90506130ce565b816001811461303657600281146130405761306f565b60019150506130ce565b60ff84111561305257613051612d1c565b5b8360020a91508482111561306957613068612d1c565b5b506130ce565b5060208310610133831016604e8410600b84101617156130a45782820a90508381111561309f5761309e612d1c565b5b6130ce565b6130b18484846001612fb2565b925090508184048111156130c8576130c7612d1c565b5b81810290505b9392505050565b5f6130df826127db565b91506130ea83612998565b92506131177fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484613004565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f613156826127db565b9150613161836127db565b9250826131715761317061311f565b5b828204905092915050565b7f496e76616c6964207461736b20494400000000000000000000000000000000005f82015250565b5f6131b0600f83612d7c565b91506131bb8261317c565b602082019050919050565b5f6020820190508181035f8301526131dd816131a4565b9050919050565b7f5468697320746f6b656e20646f6573206e6f7420617070656172206c656769745f8201527f696d6174652e0000000000000000000000000000000000000000000000000000602082015250565b5f61323e602683612d7c565b9150613249826131e4565b604082019050919050565b5f6020820190508181035f83015261326b81613232565b9050919050565b61327b81612949565b82525050565b61328a81612969565b82525050565b5f60c0820190506132a35f830189613272565b6132b06020830188613281565b6132bd604083018761286c565b6132ca606083018661286c565b6132d7608083018561286c565b6132e460a083018461286c565b979650505050505050565b7f426964206973206e6f74206869676820656e6f7567682e0000000000000000005f82015250565b5f613323601783612d7c565b915061332e826132ef565b602082019050919050565b5f6020820190508181035f83015261335081613317565b9050919050565b7f45787069726174696f6e20697320746f6f2066617220696e20746865206675745f8201527f7572652e00000000000000000000000000000000000000000000000000000000602082015250565b5f6133b1602483612d7c565b91506133bc82613357565b604082019050919050565b5f6020820190508181035f8301526133de816133a5565b9050919050565b5f6060820190506133f85f830186612b29565b6134056020830185612b29565b613412604083018461286c565b949350505050565b5f60808201905061342d5f83018761286c565b61343a602083018661286c565b613447604083018561286c565b613454606083018461286c565b95945050505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f20615f8201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b5f6134b7602683612d7c565b91506134c28261345d565b604082019050919050565b5f6020820190508181035f8301526134e4816134ab565b9050919050565b5f6134f5826127db565b9150613500836127db565b925082820390508181111561351857613517612d1c565b5b92915050565b5f6060820190506135315f83018661286c565b61353e602083018561286c565b61354b604083018461286c565b949350505050565b5f6040820190506135665f83018561286c565b613573602083018461286c565b9392505050565b5f819050919050565b5f61359d6135986135938461357a565b61290e565b6127db565b9050919050565b6135ad81613583565b82525050565b5f6040820190506135c65f83018561286c565b6135d360208301846135a4565b9392505050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725f82015250565b5f61360e602083612d7c565b9150613619826135da565b602082019050919050565b5f6020820190508181035f83015261363b81613602565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f61367982612894565b91505f820361368b5761368a612d1c565b5b60018203905091905056fea26469706673582212206e5df5938ea13a63584778edb31deed50deaf24adce45a8a26e2ca1b2b1abd3a64736f6c634300081a0033
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ 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.