More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 1,948 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Finalize Redeem | 19077538 | 330 days ago | IN | 0 ETH | 0.00077554 | ||||
Finalize Redeem | 19077534 | 330 days ago | IN | 0 ETH | 0.00079132 | ||||
Finalize Redeem | 19077530 | 330 days ago | IN | 0 ETH | 0.0010954 | ||||
Initiate Redeem | 19033655 | 336 days ago | IN | 0 ETH | 0.00283668 | ||||
Initiate Redeem | 19033651 | 336 days ago | IN | 0 ETH | 0.00277535 | ||||
Initiate Redeem | 19033646 | 336 days ago | IN | 0 ETH | 0.00283467 | ||||
Finalize Redeem | 17336490 | 574 days ago | IN | 0 ETH | 0.00287263 | ||||
Initiate Redeem | 17335996 | 574 days ago | IN | 0 ETH | 0.00255768 | ||||
Finalize Redeem | 17320860 | 577 days ago | IN | 0 ETH | 0.0020343 | ||||
Initiate Redeem | 16905703 | 635 days ago | IN | 0 ETH | 0.00161152 | ||||
Finalize Redeem | 16903444 | 636 days ago | IN | 0 ETH | 0.00107304 | ||||
Finalize Redeem | 16903358 | 636 days ago | IN | 0 ETH | 0.00087338 | ||||
Initiate Redeem | 16903352 | 636 days ago | IN | 0 ETH | 0.00134472 | ||||
Finalize Redeem | 16903345 | 636 days ago | IN | 0 ETH | 0.00081919 | ||||
Initiate Redeem | 16903338 | 636 days ago | IN | 0 ETH | 0.00157689 | ||||
Finalize Redeem | 16903331 | 636 days ago | IN | 0 ETH | 0.00088004 | ||||
Initiate Redeem | 16903322 | 636 days ago | IN | 0 ETH | 0.00134373 | ||||
Finalize Redeem | 16899221 | 636 days ago | IN | 0 ETH | 0.00168763 | ||||
Finalize Redeem | 16899214 | 636 days ago | IN | 0 ETH | 0.00170684 | ||||
Initiate Redeem | 16899209 | 636 days ago | IN | 0 ETH | 0.001931 | ||||
Initiate Redeem | 16899205 | 636 days ago | IN | 0 ETH | 0.00190424 | ||||
Finalize Redeem | 16899178 | 636 days ago | IN | 0 ETH | 0.00169165 | ||||
Initiate Redeem | 16899166 | 636 days ago | IN | 0 ETH | 0.00193759 | ||||
Finalize Redeem | 16898354 | 636 days ago | IN | 0 ETH | 0.00100513 | ||||
Initiate Redeem | 16898350 | 636 days ago | IN | 0 ETH | 0.00321684 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
16893131 | 637 days ago | 0.36661322 ETH | ||||
16893129 | 637 days ago | 0.28922363 ETH | ||||
16893124 | 637 days ago | 0.4656187 ETH | ||||
16892645 | 637 days ago | 0.00221891 ETH | ||||
16892464 | 637 days ago | 0.00216753 ETH | ||||
16892043 | 637 days ago | 0.00249617 ETH | ||||
16891352 | 637 days ago | 0.00261596 ETH | ||||
16890760 | 637 days ago | 0.00183257 ETH | ||||
16890758 | 637 days ago | 0.00177321 ETH | ||||
16885489 | 638 days ago | 0.00260496 ETH | ||||
16885205 | 638 days ago | 0.00211302 ETH | ||||
16884890 | 638 days ago | 0.00187005 ETH | ||||
16884298 | 638 days ago | 0.00175117 ETH | ||||
16884290 | 638 days ago | 0.00173573 ETH | ||||
16883695 | 638 days ago | 0.00174237 ETH | ||||
16883407 | 638 days ago | 0.00145473 ETH | ||||
16883103 | 638 days ago | 0.00128158 ETH | ||||
16882510 | 638 days ago | 0.00100842 ETH | ||||
16882509 | 638 days ago | 0.00094115 ETH | ||||
16879670 | 639 days ago | 0.00099986 ETH | ||||
16879384 | 639 days ago | 0.00094843 ETH | ||||
16878787 | 639 days ago | 0.00103316 ETH | ||||
16878779 | 639 days ago | 0.00113939 ETH | ||||
16878189 | 639 days ago | 0.00134562 ETH | ||||
16877886 | 639 days ago | 0.00151095 ETH |
Loading...
Loading
Contract Name:
PPAgentV2
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 200000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "./PPAgentV2Flags.sol"; library ConfigFlags { function check(uint256 cfg, uint256 flag) internal pure returns (bool) { return (cfg & flag) != 0; } } interface IPPAgentV2Executor { function execute_44g58pv() external; } interface IPPAgentV2Viewer { struct Job { uint8 config; bytes4 selector; uint88 credits; uint16 maxBaseFeeGwei; uint16 rewardPct; uint32 fixedReward; uint8 calldataSource; // For interval jobs uint24 intervalSeconds; uint32 lastExecutionAt; } struct Resolver { address resolverAddress; bytes resolverCalldata; } function getConfig() external view returns ( uint256 minKeeperCvp_, uint256 pendingWithdrawalTimeoutSeconds_, uint256 feeTotal_, uint256 feePpm_, uint256 lastKeeperId_ ); function getKeeper(uint256 keeperId_) external view returns ( address admin, address worker, uint256 currentStake, uint256 slashedStake, uint256 compensation, uint256 pendingWithdrawalAmount, uint256 pendingWithdrawalEndAt ); function getKeeperWorkerAndStake(uint256 keeperId_) external view returns ( address worker, uint256 currentStake ); function getJob(bytes32 jobKey_) external view returns ( address owner, address pendingTransfer, uint256 jobLevelMinKeeperCvp, Job memory details, bytes memory preDefinedCalldata, Resolver memory resolver ); function getJobRaw(bytes32 jobKey_) external view returns (uint256 rawJob); function jobOwnerCredits(address owner_) external view returns (uint256 credits); } /** * @title PowerAgentLite * @author PowerPool */ contract PPAgentV2 is IPPAgentV2Executor, IPPAgentV2Viewer, PPAgentV2Flags, Ownable { error OnlyOwner(); error NonEOASender(); error InsufficientKeeperStake(); error InsufficientJobScopedKeeperStake(); error KeeperWorkerNotAuthorized(); error InsufficientJobCredits(uint256 actual, uint256 wanted); error InsufficientJobOwnerCredits(uint256 actual, uint256 wanted); error InactiveJob(bytes32 jobKey); error JobIdOverflow(); error OnlyJobOwner(); error JobWithoutOwner(); error MissingJobAddress(); error MissingMaxBaseFeeGwei(); error NoFixedNorPremiumPctReward(); error CreditsDepositOverflow(); error CreditsWithdrawalUnderflow(); error MissingDeposit(); error IntervalNotReached(uint256 lastExecutedAt, uint256 interval, uint256 _now); error BaseFeeGtGasPrice(uint256 baseFee, uint256 jobMaxBaseFeeGwei); error InvalidCalldataSource(); error MissingInputCalldata(); error SelectorCheckFailed(); error JobCallRevertedWithoutDetails(); error InsufficientAmountToCoverSlashedStake(uint256 wanted, uint256 actual); error AmountGtStake(uint256 wanted, uint256 actualStake, uint256 actualSlashedStake); error WithdrawalTimoutNotReached(); error NoPendingWithdrawal(); error MissingAmount(); error WithdrawAmountExceedsAvailable(uint256 wanted, uint256 actual); error JobShouldHaveInterval(); error InvalidJobAddress(); error MissingResolverAddress(); error NotSupportedByJobCalldataSource(); error OnlyKeeperAdmin(); error OnlyKeeperAdminOrWorker(); error TimeoutTooBig(); error FeeTooBig(); error InsufficientAmount(); error OnlyPendingOwner(); error WorkerAlreadyAssigned(); string public constant VERSION = "2.2.0"; uint256 internal constant MAX_PENDING_WITHDRAWAL_TIMEOUT_SECONDS = 30 days; uint256 internal constant MAX_FEE_PPM = 5e4; uint256 internal constant FIXED_PAYMENT_MULTIPLIER = 1e15; uint256 internal constant JOB_RUN_GAS_OVERHEAD = 40_000; enum CalldataSourceType { SELECTOR, PRE_DEFINED, RESOLVER } IERC20 public immutable CVP; event Execute( bytes32 indexed jobKey, address indexed job, uint256 keeperId, uint256 gasUsed, uint256 baseFee, uint256 gasPrice, uint256 compensation, bytes32 binJobAfter ); event WithdrawFees(address indexed to, uint256 amount); event Slash(uint256 indexed keeperId, address indexed to, uint256 currentAmount, uint256 pendingAmount); event RegisterAsKeeper(uint256 indexed keeperId, address indexed keeperAdmin, address indexed keeperWorker); event SetWorkerAddress(uint256 indexed keeperId, address indexed prev, address indexed worker); event Stake(uint256 indexed keeperId, uint256 amount, address staker); event InitiateRedeem(uint256 indexed keeperId, uint256 redeemAmount, uint256 stakeAmount, uint256 slashedStakeAmount); event FinalizeRedeem(uint256 indexed keeperId, address indexed beneficiary, uint256 amount); event WithdrawCompensation(uint256 indexed keeperId, address indexed to, uint256 amount); event DepositJobCredits(bytes32 indexed jobKey, address indexed depositor, uint256 amount, uint256 fee); event WithdrawJobCredits(bytes32 indexed jobKey, address indexed owner, address indexed to, uint256 amount); event DepositJobOwnerCredits(address indexed jobOwner, address indexed depositor, uint256 amount, uint256 fee); event WithdrawJobOwnerCredits(address indexed jobOwner, address indexed to, uint256 amount); event InitiateJobTransfer(bytes32 indexed jobKey, address indexed from, address indexed to); event AcceptJobTransfer(bytes32 indexed jobKey_, address indexed to_); event SetJobConfig(bytes32 indexed jobKey, bool isActive_, bool useJobOwnerCredits_, bool assertResolverSelector_); event SetJobResolver(bytes32 indexed jobKey, address resolverAddress, bytes resolverCalldata); event SetJobPreDefinedCalldata(bytes32 indexed jobKey, bytes preDefinedCalldata); event SetAgentParams(uint256 minKeeperCvp_, uint256 timeoutSeconds_, uint256 feePct_); event RegisterJob( bytes32 indexed jobKey, address indexed jobAddress, uint256 indexed jobId, address owner, RegisterJobParams params ); event JobUpdate( bytes32 indexed jobKey, uint256 maxBaseFeeGwei, uint256 rewardPct, uint256 fixedReward, uint256 jobMinCvp, uint256 intervalSeconds ); struct Keeper { address worker; uint96 cvpStake; } uint256 internal minKeeperCvp; uint256 internal pendingWithdrawalTimeoutSeconds; uint256 internal feeTotal; uint256 internal feePpm; uint256 internal lastKeeperId; // keccak256(jobAddress, id) => ethBalance mapping(bytes32 => Job) internal jobs; // keccak256(jobAddress, id) => customCalldata mapping(bytes32 => bytes) internal preDefinedCalldatas; // keccak256(jobAddress, id) => minKeeperCvpStake mapping(bytes32 => uint256) internal jobMinKeeperCvp; // keccak256(jobAddress, id) => owner mapping(bytes32 => address) internal jobOwners; // keccak256(jobAddress, id) => resolver(address,calldata) mapping(bytes32 => Resolver) internal resolvers; // keccak256(jobAddress, id) => pendingAddress mapping(bytes32 => address) internal jobPendingTransfers; // jobAddress => lastIdRegistered(actually uint24) mapping(address => uint256) public jobLastIds; // keeperId => (worker,CVP stake) mapping(uint256 => Keeper) internal keepers; // keeperId => admin mapping(uint256 => address) internal keeperAdmins; // keeperId => the slashed CVP amount mapping(uint256 => uint256) internal slashedStakeOf; // keeperId => native token compensation mapping(uint256 => uint256) internal compensations; // keeperId => pendingWithdrawalCVP amount mapping(uint256 => uint256) internal pendingWithdrawalAmounts; // keeperId => pendingWithdrawalEndsAt timestamp mapping(uint256 => uint256) internal pendingWithdrawalEndsAt; // owner => credits mapping(address => uint256) public jobOwnerCredits; // worker => keeperIs mapping(address => uint256) public workerKeeperIds; /*** PSEUDO-MODIFIERS ***/ function _assertOnlyOwner() internal view { if (msg.sender != owner()) { revert OnlyOwner(); } } function _assertOnlyJobOwner(bytes32 jobKey_) internal view { if (msg.sender != jobOwners[jobKey_]) { revert OnlyJobOwner(); } } function _assertOnlyKeeperAdmin(uint256 keeperId_) internal view { if (msg.sender != keeperAdmins[keeperId_]) { revert OnlyKeeperAdmin(); } } function _assertOnlyKeeperAdminOrWorker(uint256 keeperId_) internal view { if (msg.sender != keeperAdmins[keeperId_] && msg.sender != keepers[keeperId_].worker) { revert OnlyKeeperAdminOrWorker(); } } function _assertWorkerNotAssigned(address worker_) internal view { if (workerKeeperIds[worker_] != 0) { revert WorkerAlreadyAssigned(); } } function _assertNonZeroAmount(uint256 amount_) internal pure { if (amount_ == 0) { revert MissingAmount(); } } function _assertNonZeroValue() internal view { if (msg.value == 0) { revert MissingDeposit(); } } function _assertJobCalldataSource(bytes32 jobKey_, CalldataSourceType source_) internal view { if (CalldataSourceType(jobs[jobKey_].calldataSource) != source_) { revert NotSupportedByJobCalldataSource(); } } function _assertJobParams(uint256 maxBaseFeeGwei_, uint256 fixedReward_, uint256 rewardPct_) internal pure { if (maxBaseFeeGwei_ == 0) { revert MissingMaxBaseFeeGwei(); } if (fixedReward_ == 0 && rewardPct_ == 0) { revert NoFixedNorPremiumPctReward(); } } function _assertInterval(uint256 interval_, CalldataSourceType calldataSource_) internal pure { if (interval_ == 0 && (calldataSource_ == CalldataSourceType.SELECTOR || calldataSource_ == CalldataSourceType.PRE_DEFINED)) { revert JobShouldHaveInterval(); } } constructor(address owner_, address cvp_, uint256 minKeeperCvp_, uint256 pendingWithdrawalTimeoutSeconds_) { minKeeperCvp = minKeeperCvp_; CVP = IERC20(cvp_); pendingWithdrawalTimeoutSeconds = pendingWithdrawalTimeoutSeconds_; _transferOwnership(owner_); } /*** UPKEEP INTERFACE ***/ /** * Executes a job. * The method arguments a tightly coupled with a custom layout in order to save some gas. * The calldata has the following layout : * 0x 00000000 1b48315d66ba5267aac8d0ab63c49038b56b1dbc 0000f1 03 00001a 402b2eed11 * name selector jobContractAddress jobId config keeperId calldata (optional) * size b bytes4 bytes20 uint24 uint8 uint24 any * size u uint32 uint160 bytes3 bytes1 bytes3 any * bits 0-3 4-23 24-26 27-27 28-30 31+ */ function execute_44g58pv() external { uint256 gasStart = gasleft(); bytes32 jobKey; assembly ("memory-safe") { // size of (address(bytes20)+id(uint24/bytes3)) let size := 23 // keccack256(address+id(uint24)) to memory to generate jobKey calldatacopy(0, 4, size) jobKey := keccak256(0, size) } address jobAddress; uint256 keeperId; uint256 cfg; assembly ("memory-safe") { // load jobAddress, cfg, and keeperId from calldata to the stack jobAddress := shr(96, calldataload(4)) cfg := shr(248, calldataload(27)) keeperId := shr(232, calldataload(28)) } // 0. Keeper has sufficient stake { Keeper memory keeper = keepers[keeperId]; if (keeper.worker != msg.sender) { revert KeeperWorkerNotAuthorized(); } if (keeper.cvpStake < minKeeperCvp) { revert InsufficientKeeperStake(); } } uint256 binJob = getJobRaw(jobKey); // 1. Assert the job is active { if (!ConfigFlags.check(binJob, CFG_ACTIVE)) { revert InactiveJob(jobKey); } } // 2. Assert job-scoped keeper's minimum CVP deposit if (ConfigFlags.check(binJob, CFG_CHECK_KEEPER_MIN_CVP_DEPOSIT) && keepers[keeperId].cvpStake < jobMinKeeperCvp[jobKey]) { revert InsufficientJobScopedKeeperStake(); } // 3. For interval job ensure the interval has passed { uint256 intervalSeconds = (binJob << 32) >> 232; if (intervalSeconds > 0) { uint256 lastExecutionAt = binJob >> 224; if (lastExecutionAt > 0) { uint256 nextExecutionAt; unchecked { nextExecutionAt = lastExecutionAt + intervalSeconds; } if (nextExecutionAt > block.timestamp) { revert IntervalNotReached(lastExecutionAt, intervalSeconds, block.timestamp); } } } } // 4. Ensure gas price fits base fee uint256 maxBaseFee; { unchecked { maxBaseFee = ((binJob << 112) >> 240) * 1 gwei; } if (block.basefee > maxBaseFee && !ConfigFlags.check(cfg, FLAG_ACCEPT_MAX_BASE_FEE_LIMIT)) { revert BaseFeeGtGasPrice(block.basefee, maxBaseFee); } } // 5. Ensure msg.sender is EOA if (msg.sender != tx.origin) { revert NonEOASender(); } bool ok; uint256 jobGas = gasleft() - 50_000; // Source: Selector CalldataSourceType calldataSource = CalldataSourceType((binJob << 56) >> 248); if (calldataSource == CalldataSourceType.SELECTOR) { bytes4 selector; assembly { selector := shl(224, shr(8, binJob)) } (ok,) = jobAddress.call{ gas: jobGas }(abi.encode(selector)); // Source: Bytes } else if (calldataSource == CalldataSourceType.PRE_DEFINED) { (ok,) = jobAddress.call{ gas: jobGas }(preDefinedCalldatas[jobKey]); // Source: Resolver } else if (calldataSource == CalldataSourceType.RESOLVER) { assembly ("memory-safe") { let cdInCdSize := calldatasize() // calldata offset is 31 let beforeCdSize := 31 let ptr := mload(0x40) if lt(cdInCdSize, beforeCdSize) { // revert MissingInputCalldata() mstore(ptr, 0x47a0bafb00000000000000000000000000000000000000000000000000000000) revert(ptr, 4) } let cdSize := sub(cdInCdSize, beforeCdSize) mstore(0x40, add(ptr, cdSize)) calldatacopy(ptr, beforeCdSize, cdSize) // CFG_ASSERT_RESOLVER_SELECTOR = 0x04 from PPAgentLiteFlags if and(binJob, 0x04) { if iszero(eq( // actual shl(224, shr(224, calldataload(31))), // expected shl(224, shr(8, binJob)) )) { // revert SelectorCheckFailed() mstore(ptr, 0x84fb827500000000000000000000000000000000000000000000000000000000) revert(ptr, 4) } } // The remaining gas could not be less than 50_000 ok := call(jobGas, jobAddress, 0, ptr, cdSize, 0x0, 0x0) } } else { // Should never be reached revert InvalidCalldataSource(); } // Transaction succeeded if (ok) { binJob = getJobRaw(jobKey); uint256 gasUsed; unchecked { gasUsed = gasStart - gasleft(); } uint256 compensation; { uint256 min = block.basefee; if (maxBaseFee < min) { min = maxBaseFee; } compensation = _calculateCompensation(binJob, min, gasUsed); } { bool jobChanged; if (ConfigFlags.check(binJob, CFG_USE_JOB_OWNER_CREDITS)) { // use job owner credits _useJobOwnerCredits(jobKey, compensation); } else { // use job credits uint256 creditsBefore = (binJob << 128) >> 168; if (creditsBefore < compensation) { revert InsufficientJobCredits(creditsBefore, compensation); } uint256 creditsAfter; unchecked { creditsAfter = creditsBefore - compensation; } // update job credits binJob = binJob & BM_CLEAR_CREDITS | (creditsAfter << 40); jobChanged = true; } if (ConfigFlags.check(cfg, FLAG_ACCRUE_REWARD)) { compensations[keeperId] += compensation; } else { payable(msg.sender).transfer(compensation); } // Update lastExecutionAt for interval jobs { uint256 intervalSeconds = (binJob << 32) >> 232; if (intervalSeconds > 0) { uint256 lastExecutionAt = uint32(block.timestamp); binJob = binJob & BM_CLEAR_LAST_UPDATE_AT | (lastExecutionAt << 224); jobChanged = true; } } if (jobChanged) { _updateRawJob(jobKey, binJob); } } emit Execute( jobKey, jobAddress, keeperId, gasUsed, block.basefee, tx.gasprice, compensation, bytes32(binJob) ); // Tx reverted } else { uint256 size; assembly ("memory-safe") { size := returndatasize() } if (size == 0) { revert JobCallRevertedWithoutDetails(); } assembly ("memory-safe") { let p := mload(0x40) returndatacopy(p, 0, size) revert(p, size) } } } function _calculateCompensation(uint256 job_, uint256 gasPrice_, uint256 gasUsed_) internal pure returns (uint256) { uint256 fixedReward = (job_ << 64) >> 224; uint256 rewardPct = (job_ << 96) >> 240; return calculateCompensationPure(rewardPct, fixedReward, gasPrice_, gasUsed_); } function _useJobOwnerCredits(bytes32 jobKey_, uint256 compensation_) internal { uint256 jobOwnerCreditsBefore = jobOwnerCredits[jobOwners[jobKey_]]; if (jobOwnerCreditsBefore < compensation_) { revert InsufficientJobOwnerCredits(jobOwnerCreditsBefore, compensation_); } unchecked { jobOwnerCredits[jobOwners[jobKey_]] = jobOwnerCreditsBefore - compensation_; } } struct RegisterJobParams { address jobAddress; bytes4 jobSelector; bool useJobOwnerCredits; bool assertResolverSelector; uint16 maxBaseFeeGwei; uint16 rewardPct; uint32 fixedReward; uint256 jobMinCvp; uint8 calldataSource; uint24 intervalSeconds; } /*** JOB OWNER INTERFACE ***/ /** * Registers a new job. * * Job id is unique counter for a given job address. Up to 2**24-1 jobs per address. * Job key is a keccak256(address, jobId). * The following options are immutable: * - `params_.jobaddress` * - `params_.calldataSource` * If you need to modify one of the immutable options above later consider creating a new job. * * @param params_ Job-specific params * @param resolver_ Resolver details(address, calldata), required only for CALLDATA_SOURCE_RESOLVER * job type. Use empty values for the other job types. * @param preDefinedCalldata_ Calldata to call a job with, required only for CALLDATA_SOURCE_PRE_DEFINED * job type. Keep empty for the other job types. */ function registerJob( RegisterJobParams calldata params_, Resolver calldata resolver_, bytes calldata preDefinedCalldata_ ) external payable returns (bytes32 jobKey, uint256 jobId){ jobId = jobLastIds[params_.jobAddress] + 1; if (jobId > type(uint24).max) { revert JobIdOverflow(); } if (msg.value > type(uint88).max) { revert CreditsDepositOverflow(); } if (params_.jobAddress == address(0)) { revert MissingJobAddress(); } if (params_.calldataSource > 2) { revert InvalidCalldataSource(); } if (params_.jobAddress == address(CVP)) { revert InvalidJobAddress(); } _assertInterval(params_.intervalSeconds, CalldataSourceType(params_.calldataSource)); _assertJobParams(params_.maxBaseFeeGwei, params_.fixedReward, params_.rewardPct); jobKey = getJobKey(params_.jobAddress, jobId); emit RegisterJob( jobKey, params_.jobAddress, jobId, msg.sender, params_ ); if (CalldataSourceType(params_.calldataSource) == CalldataSourceType.PRE_DEFINED) { _setJobPreDefinedCalldata(jobKey, preDefinedCalldata_); } else if (CalldataSourceType(params_.calldataSource) == CalldataSourceType.RESOLVER) { _setJobResolver(jobKey, resolver_); } { bytes4 selector = 0x00000000; if (CalldataSourceType(params_.calldataSource) != CalldataSourceType.PRE_DEFINED) { selector = params_.jobSelector; } uint256 config = CFG_ACTIVE; if (params_.useJobOwnerCredits) { config = config | CFG_USE_JOB_OWNER_CREDITS; } if (params_.assertResolverSelector) { config = config | CFG_ASSERT_RESOLVER_SELECTOR; } if (params_.jobMinCvp > 0) { config = config | CFG_CHECK_KEEPER_MIN_CVP_DEPOSIT; } jobs[jobKey] = Job({ config: uint8(config), selector: selector, credits: 0, maxBaseFeeGwei: params_.maxBaseFeeGwei, fixedReward: params_.fixedReward, rewardPct: params_.rewardPct, calldataSource: params_.calldataSource, // For interval jobs intervalSeconds: params_.intervalSeconds, lastExecutionAt: 0 }); jobMinKeeperCvp[jobKey] = params_.jobMinCvp; } jobLastIds[params_.jobAddress] = jobId; jobOwners[jobKey] = msg.sender; if (msg.value > 0) { if (params_.useJobOwnerCredits) { _processJobOwnerCreditsDeposit(msg.sender); } else { _processJobCreditsDeposit(jobKey); } } } /** * Updates a job details. * * The following options are immutable: * - `jobAddress` * - `job.selector` * - `job.calldataSource` * If you need to modify one of the immutable options above later consider creating a new job. * * @param jobKey_ The job key * @param maxBaseFeeGwei_ The maximum basefee in gwei to use for a job compensation * @param rewardPct_ The reward premium in pct, where 1 == 1% * @param fixedReward_ The fixed reward divided by FIXED_PAYMENT_MULTIPLIER * @param jobMinCvp_ The keeper minimal CVP stake to be eligible to execute this job * @param intervalSeconds_ The interval for a job execution */ function updateJob( bytes32 jobKey_, uint16 maxBaseFeeGwei_, uint16 rewardPct_, uint32 fixedReward_, uint256 jobMinCvp_, uint24 intervalSeconds_ ) external { _assertOnlyJobOwner(jobKey_); _assertJobParams(maxBaseFeeGwei_, fixedReward_, rewardPct_); Job memory job = jobs[jobKey_]; _assertInterval(intervalSeconds_, CalldataSourceType(job.calldataSource)); uint256 cfg = job.config; if (jobMinCvp_ > 0 && !ConfigFlags.check(job.config, CFG_CHECK_KEEPER_MIN_CVP_DEPOSIT)) { cfg = cfg | CFG_CHECK_KEEPER_MIN_CVP_DEPOSIT; } if (jobMinCvp_ == 0 && ConfigFlags.check(job.config, CFG_CHECK_KEEPER_MIN_CVP_DEPOSIT)) { cfg = cfg ^ CFG_CHECK_KEEPER_MIN_CVP_DEPOSIT; } jobs[jobKey_].config = uint8(cfg); jobMinKeeperCvp[jobKey_] = jobMinCvp_; jobs[jobKey_].maxBaseFeeGwei = maxBaseFeeGwei_; jobs[jobKey_].rewardPct = rewardPct_; jobs[jobKey_].fixedReward = fixedReward_; jobs[jobKey_].intervalSeconds = intervalSeconds_; emit JobUpdate(jobKey_, maxBaseFeeGwei_, rewardPct_, fixedReward_, jobMinCvp_, intervalSeconds_); } /** * A job owner updates job resolver details. * * @param jobKey_ The jobKey * @param resolver_ The new job resolver details */ function setJobResolver(bytes32 jobKey_, Resolver calldata resolver_) external { _assertOnlyJobOwner(jobKey_); _assertJobCalldataSource(jobKey_, CalldataSourceType.RESOLVER); _setJobResolver(jobKey_, resolver_); } function _setJobResolver(bytes32 jobKey_, Resolver calldata resolver_) internal { if (resolver_.resolverAddress == address(0)) { revert MissingResolverAddress(); } resolvers[jobKey_] = resolver_; emit SetJobResolver(jobKey_, resolver_.resolverAddress, resolver_.resolverCalldata); } /** * A job owner updates pre-defined calldata. * * @param jobKey_ The jobKey * @param preDefinedCalldata_ The new job pre-defined calldata */ function setJobPreDefinedCalldata(bytes32 jobKey_, bytes calldata preDefinedCalldata_) external { _assertOnlyJobOwner(jobKey_); _assertJobCalldataSource(jobKey_, CalldataSourceType.PRE_DEFINED); _setJobPreDefinedCalldata(jobKey_, preDefinedCalldata_); } function _setJobPreDefinedCalldata(bytes32 jobKey_, bytes calldata preDefinedCalldata_) internal { preDefinedCalldatas[jobKey_] = preDefinedCalldata_; emit SetJobPreDefinedCalldata(jobKey_, preDefinedCalldata_); } /** * A job owner updates a job config flag. * * @param jobKey_ The jobKey * @param isActive_ Whether the job is active or not * @param useJobOwnerCredits_ The useJobOwnerCredits flag * @param assertResolverSelector_ The assertResolverSelector flag */ function setJobConfig( bytes32 jobKey_, bool isActive_, bool useJobOwnerCredits_, bool assertResolverSelector_ ) external { _assertOnlyJobOwner(jobKey_); uint256 newConfig = 0; if (isActive_) { newConfig = newConfig | CFG_ACTIVE; } if (useJobOwnerCredits_) { newConfig = newConfig | CFG_USE_JOB_OWNER_CREDITS; } if (assertResolverSelector_) { newConfig = newConfig | CFG_ASSERT_RESOLVER_SELECTOR; } uint256 job = getJobRaw(jobKey_) & BM_CLEAR_CONFIG | newConfig; _updateRawJob(jobKey_, job); emit SetJobConfig(jobKey_, isActive_, useJobOwnerCredits_, assertResolverSelector_); } function _updateRawJob(bytes32 jobKey_, uint256 job_) internal { Job storage job = jobs[jobKey_]; assembly { sstore(job.slot, job_) } } /** * A job owner initiates the job transfer to a new owner. * The actual owner doesn't update until the pending owner accepts the transfer. * * @param jobKey_ The jobKey * @param to_ The new job owner */ function initiateJobTransfer(bytes32 jobKey_, address to_) external { _assertOnlyJobOwner(jobKey_); jobPendingTransfers[jobKey_] = to_; emit InitiateJobTransfer(jobKey_, msg.sender, to_); } /** * A pending job owner accepts the job transfer. * * @param jobKey_ The jobKey */ function acceptJobTransfer(bytes32 jobKey_) external { if (msg.sender != jobPendingTransfers[jobKey_]) { revert OnlyPendingOwner(); } jobOwners[jobKey_] = msg.sender; delete jobPendingTransfers[jobKey_]; emit AcceptJobTransfer(jobKey_, msg.sender); } /** * Top-ups the job credits in NATIVE tokens. * * @param jobKey_ The jobKey to deposit for */ function depositJobCredits(bytes32 jobKey_) external payable { _assertNonZeroValue(); if (jobOwners[jobKey_] == address(0)) { revert JobWithoutOwner(); } _processJobCreditsDeposit(jobKey_); } function _processJobCreditsDeposit(bytes32 jobKey_) internal { (uint256 fee, uint256 amount) = _calculateDepositFee(); uint256 creditsAfter = jobs[jobKey_].credits + amount; if (creditsAfter > type(uint88).max) { revert CreditsDepositOverflow(); } unchecked { feeTotal += fee; } jobs[jobKey_].credits = uint88(creditsAfter); emit DepositJobCredits(jobKey_, msg.sender, amount, fee); } function _calculateDepositFee() internal view returns (uint256 fee, uint256 amount) { fee = msg.value * feePpm / 1e6 /* 100% in ppm */; amount = msg.value - fee; } /** * A job owner withdraws the job credits in NATIVE tokens. * * @param jobKey_ The jobKey * @param to_ The address to send NATIVE tokens to * @param amount_ The amount to withdraw. Use type(uint256).max for the total available credits withdrawal. */ function withdrawJobCredits( bytes32 jobKey_, address payable to_, uint256 amount_ ) external { uint88 creditsBefore = jobs[jobKey_].credits; if (amount_ == type(uint256).max) { amount_ = creditsBefore; } _assertOnlyJobOwner(jobKey_); _assertNonZeroAmount(amount_); if (creditsBefore < amount_) { revert CreditsWithdrawalUnderflow(); } unchecked { jobs[jobKey_].credits = creditsBefore - uint88(amount_); } to_.transfer(amount_); emit WithdrawJobCredits(jobKey_, msg.sender, to_, amount_); } /** * Top-ups the job owner credits in NATIVE tokens. * * @param for_ The job owner address to deposit for */ function depositJobOwnerCredits(address for_) external payable { _assertNonZeroValue(); _processJobOwnerCreditsDeposit(for_); } function _processJobOwnerCreditsDeposit(address for_) internal { (uint256 fee, uint256 amount) = _calculateDepositFee(); unchecked { feeTotal += fee; jobOwnerCredits[for_] += amount; } emit DepositJobOwnerCredits(for_, msg.sender, amount, fee); } /** * A job owner withdraws the job owner credits in NATIVE tokens. * * @param to_ The address to send NATIVE tokens to * @param amount_ The amount to withdraw. Use type(uint256).max for the total available credits withdrawal. */ function withdrawJobOwnerCredits(address payable to_, uint256 amount_) external { uint256 creditsBefore = jobOwnerCredits[msg.sender]; if (amount_ == type(uint256).max) { amount_ = creditsBefore; } _assertNonZeroAmount(amount_); if (creditsBefore < amount_) { revert CreditsWithdrawalUnderflow(); } unchecked { jobOwnerCredits[msg.sender] = creditsBefore - amount_; } to_.transfer(amount_); emit WithdrawJobOwnerCredits(msg.sender, to_, amount_); } /*** KEEPER INTERFACE ***/ /** * Actor registers as a keeper. * One keeper address could have multiple keeper IDs. Requires at least `minKeepCvp` as an initial CVP deposit. * * @dev Overflow-safe only for CVP which total supply is less than type(uint96).max * @dev Maximum 2^24-1 keepers supported. There is no explicit check for overflow, but the keepers with ID >= 2^24 * won't be able to perform upkeep operations. * * @param worker_ The worker address * @param initialDepositAmount_ The initial CVP deposit. Should be no less than `minKeepCvp` * @return keeperId The registered keeper ID */ function registerAsKeeper(address worker_, uint256 initialDepositAmount_) external returns (uint256 keeperId) { _assertWorkerNotAssigned(worker_); if (initialDepositAmount_ < minKeeperCvp) { revert InsufficientAmount(); } keeperId = ++lastKeeperId; keeperAdmins[keeperId] = msg.sender; keepers[keeperId] = Keeper(worker_, 0); workerKeeperIds[worker_] = keeperId; emit RegisterAsKeeper(keeperId, msg.sender, worker_); _stake(keeperId, initialDepositAmount_); } /** * A keeper updates a keeper worker address * * @param keeperId_ The keeper ID * @param worker_ The new worker address */ function setWorkerAddress(uint256 keeperId_, address worker_) external { _assertOnlyKeeperAdmin(keeperId_); _assertWorkerNotAssigned(worker_); address prev = keepers[keeperId_].worker; delete workerKeeperIds[prev]; workerKeeperIds[worker_] = keeperId_; keepers[keeperId_].worker = worker_; emit SetWorkerAddress(keeperId_, prev, worker_); } /** * A keeper withdraws NATIVE token rewards. * * @param keeperId_ The keeper ID * @param to_ The address to withdraw to * @param amount_ The amount to withdraw. Use type(uint256).max for the total available compensation withdrawal. */ function withdrawCompensation(uint256 keeperId_, address payable to_, uint256 amount_) external { uint256 available = compensations[keeperId_]; if (amount_ == type(uint256).max) { amount_ = available; } _assertNonZeroAmount(amount_); _assertOnlyKeeperAdminOrWorker(keeperId_); if (amount_ > available) { revert WithdrawAmountExceedsAvailable(amount_, available); } unchecked { compensations[keeperId_] = available - amount_; } to_.transfer(amount_); emit WithdrawCompensation(keeperId_, to_, amount_); } /** * Deposits CVP for the given keeper ID. The beneficiary receives a derivative erc20 token in exchange of CVP. * Accounts the staking amount on the beneficiary's stakeOf balance. * * @param keeperId_ The keeper ID * @param amount_ The amount to stake */ function stake(uint256 keeperId_, uint256 amount_) external { _assertNonZeroAmount(amount_); _stake(keeperId_, amount_); } function _stake(uint256 keeperId_, uint256 amount_) internal { CVP.transferFrom(msg.sender, address(this), amount_); keepers[keeperId_].cvpStake += uint96(amount_); emit Stake(keeperId_, amount_, msg.sender); } /** * A keeper initiates CVP withdrawal. * The given CVP amount needs to go through the cooldown stage. After the cooldown is complete this amount could be * withdrawn using `finalizeRedeem()` method. * The msg.sender burns the paCVP token in exchange of the corresponding CVP amount. * Accumulates the existing pending for withdrawal amounts and re-initiates cooldown period. * If there is any slashed amount for the msg.sender, it should be compensated within the first initiateRedeem transaction * by burning the equivalent amount of paCVP tokens. The remaining CVP tokens won't be redeemed unless the slashed * amount is compensated. * * @param keeperId_ The keeper ID * @param amount_ The amount to cooldown * @return pendingWithdrawalAfter The total pending for withdrawal amount */ function initiateRedeem(uint256 keeperId_, uint256 amount_) external returns (uint256 pendingWithdrawalAfter) { _assertOnlyKeeperAdmin(keeperId_); _assertNonZeroAmount(amount_); uint256 stakeOfBefore = keepers[keeperId_].cvpStake; uint256 slashedStakeOfBefore = slashedStakeOf[keeperId_]; uint256 totalStakeBefore = stakeOfBefore + slashedStakeOfBefore; // Should burn at least the total slashed stake if (amount_ < slashedStakeOfBefore) { revert InsufficientAmountToCoverSlashedStake(amount_, slashedStakeOfBefore); } if (amount_ > totalStakeBefore) { revert AmountGtStake(amount_, stakeOfBefore, slashedStakeOfBefore); } slashedStakeOf[keeperId_] = 0; uint256 stakeOfToReduceAmount; unchecked { stakeOfToReduceAmount = amount_ - slashedStakeOfBefore; keepers[keeperId_].cvpStake = uint96(stakeOfBefore - stakeOfToReduceAmount); pendingWithdrawalAmounts[keeperId_] += stakeOfToReduceAmount; } pendingWithdrawalAfter = block.timestamp + pendingWithdrawalTimeoutSeconds; pendingWithdrawalEndsAt[keeperId_] = pendingWithdrawalAfter; emit InitiateRedeem(keeperId_, amount_, stakeOfToReduceAmount, slashedStakeOfBefore); } /** * A keeper finalizes CVP withdrawal and receives the staked CVP tokens. * * @param keeperId_ The keeper ID * @param to_ The address to transfer CVP to * @return redeemedCvp The redeemed CVP amount */ function finalizeRedeem(uint256 keeperId_, address to_) external returns (uint256 redeemedCvp) { _assertOnlyKeeperAdmin(keeperId_); if (pendingWithdrawalEndsAt[keeperId_] > block.timestamp) { revert WithdrawalTimoutNotReached(); } redeemedCvp = pendingWithdrawalAmounts[keeperId_]; if (redeemedCvp == 0) { revert NoPendingWithdrawal(); } pendingWithdrawalAmounts[keeperId_] = 0; CVP.transfer(to_, redeemedCvp); emit FinalizeRedeem(keeperId_, to_, redeemedCvp); } /*** CONTRACT OWNER INTERFACE ***/ /** * Slashes any keeper_ for an amount within keeper's deposit. * Penalises a keeper for malicious behaviour like sandwitching upkeep transactions. * * @param keeperId_ The keeper ID to slash * @param to_ The address to send the slashed CVP to * @param currentAmount_ The amount to slash from the current keeper.cvpStake balance * @param pendingAmount_ The amount to slash from the pendingWithdrawals balance */ function slash(uint256 keeperId_, address to_, uint256 currentAmount_, uint256 pendingAmount_) external { _assertOnlyOwner(); uint256 totalAmount = currentAmount_ + pendingAmount_; _assertNonZeroAmount(totalAmount); if (currentAmount_ > 0) { keepers[keeperId_].cvpStake -= uint96(currentAmount_); slashedStakeOf[keeperId_] += currentAmount_; } if (pendingAmount_ > 0) { pendingWithdrawalAmounts[keeperId_] -= pendingAmount_; } CVP.transfer(to_, totalAmount); emit Slash(keeperId_, to_, currentAmount_, pendingAmount_); } /** * Owner withdraws all the accrued rewards in native tokens to the provided address. * * @param to_ The address to send rewards to */ function withdrawFees(address payable to_) external { _assertOnlyOwner(); uint256 amount = feeTotal; feeTotal = 0; to_.transfer(amount); emit WithdrawFees(to_, amount); } /** * Owner updates minKeeperCVP value * * @param minKeeperCvp_ The new minKeeperCVP value */ function setAgentParams( uint256 minKeeperCvp_, uint256 timeoutSeconds_, uint256 feePpm_ ) external { _assertOnlyOwner(); if (timeoutSeconds_ > MAX_PENDING_WITHDRAWAL_TIMEOUT_SECONDS) { revert TimeoutTooBig(); } if (feePpm_ > MAX_FEE_PPM) { revert FeeTooBig(); } minKeeperCvp = minKeeperCvp_; pendingWithdrawalTimeoutSeconds = timeoutSeconds_; feePpm = feePpm_; emit SetAgentParams(minKeeperCvp_, timeoutSeconds_, feePpm_); } /*** GETTERS ***/ /** * Pure method that calculates keeper compensation based on a dynamic and a fixed multipliers. * DANGER: could overflow when used externally * * @param rewardPct_ The fixed percent. uint16. 0 == 0%, 100 == 100%, 500 == 500%, max 56535 == 56535% * @param fixedReward_ The fixed reward. uint32. Always multiplied by 1e15 (FIXED_PAYMENT_MULTIPLIER). * For ex. 2 == 2e15, 1_000 = 1e18, max 4294967295 == 4_294_967.295e18 * @param blockBaseFee_ The block.basefee value. * @param gasUsed_ The gas used in wei. * */ function calculateCompensationPure( uint256 rewardPct_, uint256 fixedReward_, uint256 blockBaseFee_, uint256 gasUsed_ ) public pure returns (uint256) { unchecked { return (gasUsed_ + JOB_RUN_GAS_OVERHEAD) * blockBaseFee_ * rewardPct_ / 100 + fixedReward_ * FIXED_PAYMENT_MULTIPLIER; } } function getKeeperWorkerAndStake(uint256 keeperId_) external view returns ( address worker, uint256 currentStake ) { Keeper memory keeper = keepers[keeperId_]; return ( keeper.worker, keeper.cvpStake ); } function getConfig() external view returns ( uint256 minKeeperCvp_, uint256 pendingWithdrawalTimeoutSeconds_, uint256 feeTotal_, uint256 feePpm_, uint256 lastKeeperId_ ) { return ( minKeeperCvp, pendingWithdrawalTimeoutSeconds, feeTotal, feePpm, lastKeeperId ); } function getKeeper(uint256 keeperId_) external view returns ( address admin, address worker, uint256 currentStake, uint256 slashedStake, uint256 compensation, uint256 pendingWithdrawalAmount, uint256 pendingWithdrawalEndAt ) { return ( keeperAdmins[keeperId_], keepers[keeperId_].worker, keepers[keeperId_].cvpStake, slashedStakeOf[keeperId_], compensations[keeperId_], pendingWithdrawalAmounts[keeperId_], pendingWithdrawalEndsAt[keeperId_] ); } function getJob(bytes32 jobKey_) external view returns ( address owner, address pendingTransfer, uint256 jobLevelMinKeeperCvp, Job memory details, bytes memory preDefinedCalldata, Resolver memory resolver ) { return ( jobOwners[jobKey_], jobPendingTransfers[jobKey_], jobMinKeeperCvp[jobKey_], jobs[jobKey_], preDefinedCalldatas[jobKey_], resolvers[jobKey_] ); } /** * Returns the principal job data stored in a single EVM slot. * @notice To get parsed job data use `getJob()` method instead. * * The job slot data layout: * 0x0000000000000a000000000a002300640000000de0b6b3a7640000d09de08a01 * 0x 00000000 00000a 00 0000000a 0023 0064 0000000de0b6b3a7640000 d09de08a 01 * name lastExecAt interval calldataSource fixedReward rewardPct maxBaseFeeGwei nativeCredits selector config bitmask * size b bytes4 bytes3 bytes4 bytes4 bytes2 bytes2 bytes11 bytes4 bytes1 * size u uint32 uint24 uint8 uint32 uint16 uint16 uint88 uint32 uint8 * bits 0-3 4-6 7-7 8-11 12-13 14-15 16-26 27-30 31-31 */ function getJobRaw(bytes32 jobKey_) public view returns (uint256 rawJob) { Job storage job = jobs[jobKey_]; assembly { rawJob := sload(job.slot) } } function getJobKey(address jobAddress_, uint256 jobId_) public pure returns (bytes32 jobKey) { assembly { mstore(0, shl(96, jobAddress_)) mstore(20, shl(232, jobId_)) jobKey := keccak256(0, 23) } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; contract PPAgentV2Flags { // Keeper pass this flags withing execute() transaction uint256 internal constant FLAG_ACCEPT_MAX_BASE_FEE_LIMIT = 0x01; uint256 internal constant FLAG_ACCRUE_REWARD = 0x02; // Job owner uses CFG_* flags to configure a job options uint256 internal constant CFG_ACTIVE = 0x01; uint256 internal constant CFG_USE_JOB_OWNER_CREDITS = 0x02; uint256 internal constant CFG_ASSERT_RESOLVER_SELECTOR = 0x04; uint256 internal constant CFG_CHECK_KEEPER_MIN_CVP_DEPOSIT = 0x08; uint256 internal constant BM_CLEAR_CONFIG = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00; uint256 internal constant BM_CLEAR_CREDITS = 0xffffffffffffffffffffffffffffffff0000000000000000000000ffffffffff; uint256 internal constant BM_CLEAR_LAST_UPDATE_AT = 0x00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
{ "viaIR": false, "optimizer": { "enabled": true, "runs": 200000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"cvp_","type":"address"},{"internalType":"uint256","name":"minKeeperCvp_","type":"uint256"},{"internalType":"uint256","name":"pendingWithdrawalTimeoutSeconds_","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"wanted","type":"uint256"},{"internalType":"uint256","name":"actualStake","type":"uint256"},{"internalType":"uint256","name":"actualSlashedStake","type":"uint256"}],"name":"AmountGtStake","type":"error"},{"inputs":[{"internalType":"uint256","name":"baseFee","type":"uint256"},{"internalType":"uint256","name":"jobMaxBaseFeeGwei","type":"uint256"}],"name":"BaseFeeGtGasPrice","type":"error"},{"inputs":[],"name":"CreditsDepositOverflow","type":"error"},{"inputs":[],"name":"CreditsWithdrawalUnderflow","type":"error"},{"inputs":[],"name":"FeeTooBig","type":"error"},{"inputs":[{"internalType":"bytes32","name":"jobKey","type":"bytes32"}],"name":"InactiveJob","type":"error"},{"inputs":[],"name":"InsufficientAmount","type":"error"},{"inputs":[{"internalType":"uint256","name":"wanted","type":"uint256"},{"internalType":"uint256","name":"actual","type":"uint256"}],"name":"InsufficientAmountToCoverSlashedStake","type":"error"},{"inputs":[{"internalType":"uint256","name":"actual","type":"uint256"},{"internalType":"uint256","name":"wanted","type":"uint256"}],"name":"InsufficientJobCredits","type":"error"},{"inputs":[{"internalType":"uint256","name":"actual","type":"uint256"},{"internalType":"uint256","name":"wanted","type":"uint256"}],"name":"InsufficientJobOwnerCredits","type":"error"},{"inputs":[],"name":"InsufficientJobScopedKeeperStake","type":"error"},{"inputs":[],"name":"InsufficientKeeperStake","type":"error"},{"inputs":[{"internalType":"uint256","name":"lastExecutedAt","type":"uint256"},{"internalType":"uint256","name":"interval","type":"uint256"},{"internalType":"uint256","name":"_now","type":"uint256"}],"name":"IntervalNotReached","type":"error"},{"inputs":[],"name":"InvalidCalldataSource","type":"error"},{"inputs":[],"name":"InvalidJobAddress","type":"error"},{"inputs":[],"name":"JobCallRevertedWithoutDetails","type":"error"},{"inputs":[],"name":"JobIdOverflow","type":"error"},{"inputs":[],"name":"JobShouldHaveInterval","type":"error"},{"inputs":[],"name":"JobWithoutOwner","type":"error"},{"inputs":[],"name":"KeeperWorkerNotAuthorized","type":"error"},{"inputs":[],"name":"MissingAmount","type":"error"},{"inputs":[],"name":"MissingDeposit","type":"error"},{"inputs":[],"name":"MissingInputCalldata","type":"error"},{"inputs":[],"name":"MissingJobAddress","type":"error"},{"inputs":[],"name":"MissingMaxBaseFeeGwei","type":"error"},{"inputs":[],"name":"MissingResolverAddress","type":"error"},{"inputs":[],"name":"NoFixedNorPremiumPctReward","type":"error"},{"inputs":[],"name":"NoPendingWithdrawal","type":"error"},{"inputs":[],"name":"NonEOASender","type":"error"},{"inputs":[],"name":"NotSupportedByJobCalldataSource","type":"error"},{"inputs":[],"name":"OnlyJobOwner","type":"error"},{"inputs":[],"name":"OnlyKeeperAdmin","type":"error"},{"inputs":[],"name":"OnlyKeeperAdminOrWorker","type":"error"},{"inputs":[],"name":"OnlyOwner","type":"error"},{"inputs":[],"name":"OnlyPendingOwner","type":"error"},{"inputs":[],"name":"SelectorCheckFailed","type":"error"},{"inputs":[],"name":"TimeoutTooBig","type":"error"},{"inputs":[{"internalType":"uint256","name":"wanted","type":"uint256"},{"internalType":"uint256","name":"actual","type":"uint256"}],"name":"WithdrawAmountExceedsAvailable","type":"error"},{"inputs":[],"name":"WithdrawalTimoutNotReached","type":"error"},{"inputs":[],"name":"WorkerAlreadyAssigned","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"jobKey_","type":"bytes32"},{"indexed":true,"internalType":"address","name":"to_","type":"address"}],"name":"AcceptJobTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"jobKey","type":"bytes32"},{"indexed":true,"internalType":"address","name":"depositor","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"DepositJobCredits","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"jobOwner","type":"address"},{"indexed":true,"internalType":"address","name":"depositor","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"DepositJobOwnerCredits","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"jobKey","type":"bytes32"},{"indexed":true,"internalType":"address","name":"job","type":"address"},{"indexed":false,"internalType":"uint256","name":"keeperId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"gasUsed","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"baseFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"gasPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"compensation","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"binJobAfter","type":"bytes32"}],"name":"Execute","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"keeperId","type":"uint256"},{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"FinalizeRedeem","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"jobKey","type":"bytes32"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"InitiateJobTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"keeperId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"redeemAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stakeAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"slashedStakeAmount","type":"uint256"}],"name":"InitiateRedeem","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"jobKey","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"maxBaseFeeGwei","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rewardPct","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fixedReward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"jobMinCvp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"intervalSeconds","type":"uint256"}],"name":"JobUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"keeperId","type":"uint256"},{"indexed":true,"internalType":"address","name":"keeperAdmin","type":"address"},{"indexed":true,"internalType":"address","name":"keeperWorker","type":"address"}],"name":"RegisterAsKeeper","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"jobKey","type":"bytes32"},{"indexed":true,"internalType":"address","name":"jobAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"jobId","type":"uint256"},{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"components":[{"internalType":"address","name":"jobAddress","type":"address"},{"internalType":"bytes4","name":"jobSelector","type":"bytes4"},{"internalType":"bool","name":"useJobOwnerCredits","type":"bool"},{"internalType":"bool","name":"assertResolverSelector","type":"bool"},{"internalType":"uint16","name":"maxBaseFeeGwei","type":"uint16"},{"internalType":"uint16","name":"rewardPct","type":"uint16"},{"internalType":"uint32","name":"fixedReward","type":"uint32"},{"internalType":"uint256","name":"jobMinCvp","type":"uint256"},{"internalType":"uint8","name":"calldataSource","type":"uint8"},{"internalType":"uint24","name":"intervalSeconds","type":"uint24"}],"indexed":false,"internalType":"struct PPAgentV2.RegisterJobParams","name":"params","type":"tuple"}],"name":"RegisterJob","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"minKeeperCvp_","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timeoutSeconds_","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feePct_","type":"uint256"}],"name":"SetAgentParams","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"jobKey","type":"bytes32"},{"indexed":false,"internalType":"bool","name":"isActive_","type":"bool"},{"indexed":false,"internalType":"bool","name":"useJobOwnerCredits_","type":"bool"},{"indexed":false,"internalType":"bool","name":"assertResolverSelector_","type":"bool"}],"name":"SetJobConfig","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"jobKey","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"preDefinedCalldata","type":"bytes"}],"name":"SetJobPreDefinedCalldata","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"jobKey","type":"bytes32"},{"indexed":false,"internalType":"address","name":"resolverAddress","type":"address"},{"indexed":false,"internalType":"bytes","name":"resolverCalldata","type":"bytes"}],"name":"SetJobResolver","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"keeperId","type":"uint256"},{"indexed":true,"internalType":"address","name":"prev","type":"address"},{"indexed":true,"internalType":"address","name":"worker","type":"address"}],"name":"SetWorkerAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"keeperId","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"currentAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"pendingAmount","type":"uint256"}],"name":"Slash","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"keeperId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"staker","type":"address"}],"name":"Stake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"keeperId","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawCompensation","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"jobKey","type":"bytes32"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawJobCredits","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"jobOwner","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawJobOwnerCredits","type":"event"},{"inputs":[],"name":"CVP","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"jobKey_","type":"bytes32"}],"name":"acceptJobTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"rewardPct_","type":"uint256"},{"internalType":"uint256","name":"fixedReward_","type":"uint256"},{"internalType":"uint256","name":"blockBaseFee_","type":"uint256"},{"internalType":"uint256","name":"gasUsed_","type":"uint256"}],"name":"calculateCompensationPure","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"jobKey_","type":"bytes32"}],"name":"depositJobCredits","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"for_","type":"address"}],"name":"depositJobOwnerCredits","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"execute_44g58pv","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"keeperId_","type":"uint256"},{"internalType":"address","name":"to_","type":"address"}],"name":"finalizeRedeem","outputs":[{"internalType":"uint256","name":"redeemedCvp","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getConfig","outputs":[{"internalType":"uint256","name":"minKeeperCvp_","type":"uint256"},{"internalType":"uint256","name":"pendingWithdrawalTimeoutSeconds_","type":"uint256"},{"internalType":"uint256","name":"feeTotal_","type":"uint256"},{"internalType":"uint256","name":"feePpm_","type":"uint256"},{"internalType":"uint256","name":"lastKeeperId_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"jobKey_","type":"bytes32"}],"name":"getJob","outputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"pendingTransfer","type":"address"},{"internalType":"uint256","name":"jobLevelMinKeeperCvp","type":"uint256"},{"components":[{"internalType":"uint8","name":"config","type":"uint8"},{"internalType":"bytes4","name":"selector","type":"bytes4"},{"internalType":"uint88","name":"credits","type":"uint88"},{"internalType":"uint16","name":"maxBaseFeeGwei","type":"uint16"},{"internalType":"uint16","name":"rewardPct","type":"uint16"},{"internalType":"uint32","name":"fixedReward","type":"uint32"},{"internalType":"uint8","name":"calldataSource","type":"uint8"},{"internalType":"uint24","name":"intervalSeconds","type":"uint24"},{"internalType":"uint32","name":"lastExecutionAt","type":"uint32"}],"internalType":"struct IPPAgentV2Viewer.Job","name":"details","type":"tuple"},{"internalType":"bytes","name":"preDefinedCalldata","type":"bytes"},{"components":[{"internalType":"address","name":"resolverAddress","type":"address"},{"internalType":"bytes","name":"resolverCalldata","type":"bytes"}],"internalType":"struct IPPAgentV2Viewer.Resolver","name":"resolver","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"jobAddress_","type":"address"},{"internalType":"uint256","name":"jobId_","type":"uint256"}],"name":"getJobKey","outputs":[{"internalType":"bytes32","name":"jobKey","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"jobKey_","type":"bytes32"}],"name":"getJobRaw","outputs":[{"internalType":"uint256","name":"rawJob","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"keeperId_","type":"uint256"}],"name":"getKeeper","outputs":[{"internalType":"address","name":"admin","type":"address"},{"internalType":"address","name":"worker","type":"address"},{"internalType":"uint256","name":"currentStake","type":"uint256"},{"internalType":"uint256","name":"slashedStake","type":"uint256"},{"internalType":"uint256","name":"compensation","type":"uint256"},{"internalType":"uint256","name":"pendingWithdrawalAmount","type":"uint256"},{"internalType":"uint256","name":"pendingWithdrawalEndAt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"keeperId_","type":"uint256"}],"name":"getKeeperWorkerAndStake","outputs":[{"internalType":"address","name":"worker","type":"address"},{"internalType":"uint256","name":"currentStake","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"jobKey_","type":"bytes32"},{"internalType":"address","name":"to_","type":"address"}],"name":"initiateJobTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"keeperId_","type":"uint256"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"initiateRedeem","outputs":[{"internalType":"uint256","name":"pendingWithdrawalAfter","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"jobLastIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"jobOwnerCredits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"worker_","type":"address"},{"internalType":"uint256","name":"initialDepositAmount_","type":"uint256"}],"name":"registerAsKeeper","outputs":[{"internalType":"uint256","name":"keeperId","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"jobAddress","type":"address"},{"internalType":"bytes4","name":"jobSelector","type":"bytes4"},{"internalType":"bool","name":"useJobOwnerCredits","type":"bool"},{"internalType":"bool","name":"assertResolverSelector","type":"bool"},{"internalType":"uint16","name":"maxBaseFeeGwei","type":"uint16"},{"internalType":"uint16","name":"rewardPct","type":"uint16"},{"internalType":"uint32","name":"fixedReward","type":"uint32"},{"internalType":"uint256","name":"jobMinCvp","type":"uint256"},{"internalType":"uint8","name":"calldataSource","type":"uint8"},{"internalType":"uint24","name":"intervalSeconds","type":"uint24"}],"internalType":"struct PPAgentV2.RegisterJobParams","name":"params_","type":"tuple"},{"components":[{"internalType":"address","name":"resolverAddress","type":"address"},{"internalType":"bytes","name":"resolverCalldata","type":"bytes"}],"internalType":"struct IPPAgentV2Viewer.Resolver","name":"resolver_","type":"tuple"},{"internalType":"bytes","name":"preDefinedCalldata_","type":"bytes"}],"name":"registerJob","outputs":[{"internalType":"bytes32","name":"jobKey","type":"bytes32"},{"internalType":"uint256","name":"jobId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"minKeeperCvp_","type":"uint256"},{"internalType":"uint256","name":"timeoutSeconds_","type":"uint256"},{"internalType":"uint256","name":"feePpm_","type":"uint256"}],"name":"setAgentParams","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"jobKey_","type":"bytes32"},{"internalType":"bool","name":"isActive_","type":"bool"},{"internalType":"bool","name":"useJobOwnerCredits_","type":"bool"},{"internalType":"bool","name":"assertResolverSelector_","type":"bool"}],"name":"setJobConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"jobKey_","type":"bytes32"},{"internalType":"bytes","name":"preDefinedCalldata_","type":"bytes"}],"name":"setJobPreDefinedCalldata","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"jobKey_","type":"bytes32"},{"components":[{"internalType":"address","name":"resolverAddress","type":"address"},{"internalType":"bytes","name":"resolverCalldata","type":"bytes"}],"internalType":"struct IPPAgentV2Viewer.Resolver","name":"resolver_","type":"tuple"}],"name":"setJobResolver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"keeperId_","type":"uint256"},{"internalType":"address","name":"worker_","type":"address"}],"name":"setWorkerAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"keeperId_","type":"uint256"},{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"currentAmount_","type":"uint256"},{"internalType":"uint256","name":"pendingAmount_","type":"uint256"}],"name":"slash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"keeperId_","type":"uint256"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"jobKey_","type":"bytes32"},{"internalType":"uint16","name":"maxBaseFeeGwei_","type":"uint16"},{"internalType":"uint16","name":"rewardPct_","type":"uint16"},{"internalType":"uint32","name":"fixedReward_","type":"uint32"},{"internalType":"uint256","name":"jobMinCvp_","type":"uint256"},{"internalType":"uint24","name":"intervalSeconds_","type":"uint24"}],"name":"updateJob","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"keeperId_","type":"uint256"},{"internalType":"address payable","name":"to_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"withdrawCompensation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"to_","type":"address"}],"name":"withdrawFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"jobKey_","type":"bytes32"},{"internalType":"address payable","name":"to_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"withdrawJobCredits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"to_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"withdrawJobOwnerCredits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"workerKeeperIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60a06040523480156200001157600080fd5b5060405162004a9938038062004a998339810160408190526200003491620000d8565b6200003f336200006b565b60018290556001600160a01b038316608052600281905562000061846200006b565b5050505062000120565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b0381168114620000d357600080fd5b919050565b60008060008060808587031215620000ef57600080fd5b620000fa85620000bb565b93506200010a60208601620000bb565b6040860151606090960151949790965092505050565b608051614941620001586000396000818161052301528181611c0d01528181611fb00152818161245b015261315201526149416000f3fe60806040526004361061024a5760003560e01c80638f245cc511610138578063c44a7130116100b0578063f729cf0d1161007f578063f8f6318811610064578063f8f63188146107fc578063fa713f40146108a9578063ffa1ad74146108d657600080fd5b8063f729cf0d14610792578063f83c1700146107c457600080fd5b8063c44a713014610644578063d217a89514610732578063efcdd7aa14610752578063f2fde38b1461077257600080fd5b80639da867d511610107578063b882eda6116100ec578063b882eda6146105c5578063c1484807146105d8578063c3f909d41461060057600080fd5b80639da867d514610585578063a34f8e14146105a557600080fd5b80638f245cc5146104f15780639230f2c0146105115780639af83df0146105455780639caec1d81461056557600080fd5b806329956b22116101cb578063572d417b1161019a578063715018a61161017f578063715018a6146104705780637b0472f0146104855780638da5cb5b146104a557600080fd5b8063572d417b146104305780636b5dd8551461045057600080fd5b806329956b22146103a35780633a1b9942146103c357806346e89169146103e3578063499925561461041057600080fd5b8063164e68de116102225780631c1ad03d116102075780631c1ad03d14610329578063293ac1bf14610356578063298a16131461037657600080fd5b8063164e68de146102cc57806317d11280146102ec57600080fd5b801561024f57806304d0fbdf146102665780630c4a06d014610299578063146cc168146102ac575b600080fd5b34801561025b57600080fd5b5061026461092c565b005b34801561027257600080fd5b50610286610281366004613a3e565b61116c565b6040519081526020015b60405180910390f35b6102646102a7366004613a6a565b6112b4565b3480156102b857600080fd5b506102646102c7366004613a83565b611323565b3480156102d857600080fd5b506102646102e7366004613aaf565b6113f9565b3480156102f857600080fd5b50610286610307366004613ad3565b600066038d7ea4c6800084026064619c40840185028702040195945050505050565b34801561033557600080fd5b50610286610344366004613aaf565b60146020526000908152604090205481565b34801561036257600080fd5b50610286610371366004613b05565b6114a4565b34801561038257600080fd5b50610286610391366004613aaf565b600c6020526000908152604090205481565b3480156103af57600080fd5b506102646103be366004613b27565b61167a565b3480156103cf57600080fd5b506102646103de366004613b98565b611796565b3480156103ef57600080fd5b506102866103fe366004613a6a565b60009081526006602052604090205490565b34801561041c57600080fd5b5061028661042b366004613bfe565b611b13565b34801561043c57600080fd5b5061026461044b366004613c77565b611cd2565b34801561045c57600080fd5b5061026461046b366004613cdc565b611cf6565b34801561047c57600080fd5b50610264611da6565b34801561049157600080fd5b506102646104a0366004613b05565b611dba565b3480156104b157600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610290565b3480156104fd57600080fd5b5061026461050c366004613d47565b611dd1565b34801561051d57600080fd5b506104cc7f000000000000000000000000000000000000000000000000000000000000000081565b34801561055157600080fd5b50610264610560366004613bfe565b611def565b34801561057157600080fd5b50610264610580366004613d8e565b611e77565b34801561059157600080fd5b506102646105a0366004613bfe565b612078565b3480156105b157600080fd5b506102646105c0366004613b27565b61212c565b6102646105d3366004613aaf565b6122bf565b6105eb6105e6366004613dcb565b6122d0565b60408051928352602083019190915201610290565b34801561060c57600080fd5b50600154600254600354600454600554604080519586526020860194909452928401919091526060830152608082015260a001610290565b34801561065057600080fd5b506106e561065f366004613a6a565b6000908152600e6020908152604080832054600d835281842054600f845282852054601085528386205460118652848720546012909652939095205473ffffffffffffffffffffffffffffffffffffffff9283169692821695740100000000000000000000000000000000000000009092046bffffffffffffffffffffffff1694919392565b6040805173ffffffffffffffffffffffffffffffffffffffff9889168152979096166020880152948601939093526060850191909152608084015260a083015260c082015260e001610290565b34801561073e57600080fd5b5061026461074d366004613a3e565b612a1e565b34801561075e57600080fd5b5061026461076d366004613a6a565b612b25565b34801561077e57600080fd5b5061026461078d366004613aaf565b612bfb565b34801561079e57600080fd5b506107b26107ad366004613a6a565b612caf565b60405161029096959493929190613ef8565b3480156107d057600080fd5b506102866107df366004613a3e565b60008260601b6000528160e81b6014526017600020905092915050565b34801561080857600080fd5b5061087d610817366004613a6a565b6000908152600d602090815260409182902082518084019093525473ffffffffffffffffffffffffffffffffffffffff8116808452740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff169290910182905291565b6040805173ffffffffffffffffffffffffffffffffffffffff9093168352602083019190915201610290565b3480156108b557600080fd5b506102866108c4366004613aaf565b60136020526000908152604090205481565b3480156108e257600080fd5b5061091f6040518060400160405280600581526020017f322e322e3000000000000000000000000000000000000000000000000000000081525081565b6040516102909190614010565b60005a9050600060178060046000376000908120601c3560e81c808352600d602090815260409384902084518086019095525473ffffffffffffffffffffffffffffffffffffffff8116808652740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff169185019190915291935060043560601c929091601b3560f81c919033146109f3576040517f4e2c6c2600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60015481602001516bffffffffffffffffffffffff161015610a41576040517fa42f03de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060008481526006602052604090205460018116610a93576040517f2cd4cf48000000000000000000000000000000000000000000000000000000008152600481018690526024015b60405180910390fd5b6008811615158015610ae65750600085815260086020908152604080832054868452600d909252909120547401000000000000000000000000000000000000000090046bffffffffffffffffffffffff16105b15610b1d576040517f6bb3355200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b62ffffff60c882901c168015610b895760e082901c8015610b875780820142811115610b85576040517fe096085e0000000000000000000000000000000000000000000000000000000081526004810183905260248101849052426044820152606401610a8a565b505b505b50633b9aca0061ffff608083901c16024881108015610ba9575060018316155b15610be9576040517f725450b300000000000000000000000000000000000000000000000000000000815248600482015260248101829052604401610a8a565b333214610c22576040517fa397a6e500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008061c3505a610c339190614052565b9050600060ff60c086901c166002811115610c5057610c50614065565b90506000816002811115610c6657610c66614065565b03610d4057604080517fffffffff0000000000000000000000000000000000000000000000000000000060d888901b16602082018190529173ffffffffffffffffffffffffffffffffffffffff8b1691859101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052610cf191614094565b60006040518083038160008787f1925050503d8060008114610d2f576040519150601f19603f3d011682016040523d82523d6000602084013e610d34565b606091505b50508094505050610ec9565b6001816002811115610d5457610d54614065565b03610ddf578773ffffffffffffffffffffffffffffffffffffffff1682600760008c8152602001908152602001600020604051610d9191906140fd565b60006040518083038160008787f1925050503d8060008114610dcf576040519150601f19603f3d011682016040523d82523d6000602084013e610dd4565b606091505b505080935050610ec9565b6002816002811115610df357610df3614065565b03610e975736601f60405181831015610e2e577f47a0bafb000000000000000000000000000000000000000000000000000000008152600481fd5b8183039250828101604052828282376004881615610e83578760081c60e01b601f3560e01c60e01b14610e83577f84fb8275000000000000000000000000000000000000000000000000000000008152600481fd5b600080848360008f8af19550505050610ec9565b6040517fe49b9c9500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82156111185760008981526006602052604081205495505a8b03905060004880871015610ef35750855b66038d7ea4c6800063ffffffff60a08a901c16026064619c408501830261ffff60908c901c160204019150506000610f2d88600216151590565b15610f4157610f3c8c8361300c565b610fcb565b6affffffffffffffffffffff602889901c1682811015610f97576040517f208118ad0000000000000000000000000000000000000000000000000000000081526004810182905260248101849052604401610a8a565b82900360281b7fffffffffffffffffffffffffffffffff0000000000000000000000ffffffffff9890981697909717965060015b6002891615610ffd5760008a81526010602052604081208054849290610ff2908490614191565b9091555061102c9050565b604051339083156108fc029084906000818181858888f1935050505015801561102a573d6000803e3d6000fd5b505b62ffffff60c889901c16801561108a577bffffffffffffffffffffffffffffffffffffffffffffffffffffffff989098167fffffffff000000000000000000000000000000000000000000000000000000004260e01b161797600191505b5080156110a35760008c81526006602052604090208890555b50604080518a81526020810184905248818301523a60608201526080810183905260a08101899052905173ffffffffffffffffffffffffffffffffffffffff8c16918d917f59200007defbdd8d2c9e53dd05f81091fe977b424f38f2562df9ee8725d584699181900360c00190a35050611160565b3d6000819003611154576040517f81953a7e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604051816000823e8181fd5b50505050505050505050565b6000611177836130ba565b6001548210156111b3576040517f5945ea5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005600081546111c2906141a4565b91829055506000818152600e6020908152604080832080547fffffffffffffffffffffffff000000000000000000000000000000000000000016339081179091558151808301835273ffffffffffffffffffffffffffffffffffffffff898116808352828601878152888852600d8752858820935190516bffffffffffffffffffffffff167401000000000000000000000000000000000000000002921691909117909155808552601490935281842085905590519394509092909184917f28e52185bb539dddafff5a07d4d7a65b6d44c6be0460f18b77ad1b5d7c7b6d7d9190a46112ae8183613117565b92915050565b6112bc61329b565b60008181526009602052604090205473ffffffffffffffffffffffffffffffffffffffff16611317576040517fa614bda700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611320816132d5565b50565b61132b6133ec565b62278d00821115611368576040517fde2180ee00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61c3508111156113a4576040517ff6f3292b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018390556002829055600481905560408051848152602081018490529081018290527f0c9773495c97952f53e7c7c23fc4ac36bc8d0e5c9ff4b5ffc8edd7b000931ea29060600160405180910390a1505050565b6114016133ec565b60038054600091829055604051909173ffffffffffffffffffffffffffffffffffffffff84169183156108fc0291849190818181858888f1935050505015801561144f573d6000803e3d6000fd5b508173ffffffffffffffffffffffffffffffffffffffff167f9bba815921f12cb7b1408e14b5ade745234397d39623ae5e7c82d693cb45815f8260405161149891815260200190565b60405180910390a25050565b60006114af8361343d565b6114b88261349a565b6000838152600d6020908152604080832054600f909252822054740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff16916115048284614191565b90508185101561154a576040517f85348f7c0000000000000000000000000000000000000000000000000000000081526004810186905260248101839052604401610a8a565b80851115611595576040517fb3a6f108000000000000000000000000000000000000000000000000000000008152600481018690526024810184905260448101839052606401610a8a565b6000868152600f60209081526040808320839055600d8252808320805473ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000878b03808a036bffffffffffffffffffffffff16919091029190911790915560119092529091208054820190556002546116189042614191565b600088815260126020908152604091829020839055815189815290810184905290810185905290955087907f2f344f62e88371893ede3b3ea3af1bbba704965ff1a7acc83ce2e367dcc4720d9060600160405180910390a25050505092915050565b60008381526010602052604090205460018201611695578091505b61169e8261349a565b6116a7846134d4565b808211156116eb576040517fa20926670000000000000000000000000000000000000000000000000000000081526004810183905260248101829052604401610a8a565b60008481526010602052604080822084840390555173ffffffffffffffffffffffffffffffffffffffff85169184156108fc02918591818181858888f1935050505015801561173e573d6000803e3d6000fd5b508273ffffffffffffffffffffffffffffffffffffffff16847f540b25d0ce24763795ee97abcbde8b65caecb84c08851dc1e31b5616deb86fb78460405161178891815260200190565b60405180910390a350505050565b61179f86613563565b6117b88561ffff168463ffffffff168661ffff166135c0565b600086815260066020908152604091829020825161012081018452905460ff808216835261010080830460e090811b7fffffffff0000000000000000000000000000000000000000000000000000000016958501959095526501000000000083046affffffffffffffffffffff1695840195909552700100000000000000000000000000000000820461ffff90811660608501527201000000000000000000000000000000000000830416608084015274010000000000000000000000000000000000000000820463ffffffff90811660a08501527801000000000000000000000000000000000000000000000000830490911660c08401819052790100000000000000000000000000000000000000000000000000830462ffffff908116958501959095527c010000000000000000000000000000000000000000000000000000000090920416938201939093529161192591841690600281111561192057611920614065565b61363d565b805160ff16831580159061193b57508151600816155b15611944576008175b831580156119555750815160081615155b1561195e576008185b600088815260066020818152604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff8716178155600883529381902088905591815282547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff1670010000000000000000000000000000000061ffff8c81169182027fffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffff16929092177201000000000000000000000000000000000000928c16928302177fffffffff000000ff00000000ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000063ffffffff8c169081027fffffffff000000ffffffffffffffffffffffffffffffffffffffffffffffffff169190911779010000000000000000000000000000000000000000000000000062ffffff8b16908102919091179096558451918252928101919091529182015260608101869052608081019190915288907f36530212a24c816d4e494215a8c9e70aa89ee2c827cdaa6454c49a1b9c1f51709060a00160405180910390a25050505050505050565b6000611b1e8361343d565b600083815260126020526040902054421015611b66576040517fd364d89200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060008281526011602052604081205490819003611bb0576040517f9121b84f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526011602052604080822091909155517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af1158015611c56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c7a91906141dc565b508173ffffffffffffffffffffffffffffffffffffffff16837f5e205b6e480b30b73f149f1e859cba98faf02d507680260f8626f19e640abdd283604051611cc491815260200190565b60405180910390a392915050565b611cdb83613563565b611ce68360016136ae565b611cf1838383613747565b505050565b611cff84613563565b60008315611d0b576001175b8215611d15576002175b8115611d1f576004175b600085815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016821790819055604080518615158152851515602082015284151581830152905187917f654d2f54a1effa88d8b821bb9edce7ee03d265c6796c42b5fe8b7d5d55fa48c8919081900360600190a2505050505050565b611dae6137a0565b611db86000613821565b565b611dc38161349a565b611dcd8282613117565b5050565b611dda82613563565b611de58260026136ae565b611dcd8282613896565b611df882613563565b6000828152600b602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff851690811790915590519091339185917f40b48a3ccb089339d160145168f44ff509c18d032508f53097f0dc6b829065a691a45050565b611e7f6133ec565b6000611e8b8284614191565b9050611e968161349a565b8215611f3a576000858152600d602052604090208054849190601490611ee39084907401000000000000000000000000000000000000000090046bffffffffffffffffffffffff166141f9565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555082600f60008781526020019081526020016000206000828254611f349190614191565b90915550505b8115611f645760008581526011602052604081208054849290611f5e908490614052565b90915550505b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af1158015611ff9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061201d91906141dc565b50604080518481526020810184905273ffffffffffffffffffffffffffffffffffffffff86169187917fa0a4bc88df8261867a0171209f23c36f265d479f8d378e57eaddd804fa5a6d4c910160405180910390a35050505050565b6120818261343d565b61208a816130ba565b6000828152600d60208181526040808420805473ffffffffffffffffffffffffffffffffffffffff908116808752601485528387208790559087168087528387208990558887529490935280547fffffffffffffffffffffffff00000000000000000000000000000000000000001684179055519092839186917f803f1e6c69bc471f5a71c877bbb0b42287843a87118166f8b4a6701e75a9ae6a91a4505050565b6000838152600660205260409020546501000000000090046affffffffffffffffffffff166001820161216a57806affffffffffffffffffffff1691505b61217384613563565b61217c8261349a565b81816affffffffffffffffffffff1610156121c3576040517f3166cb3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008481526006602052604080822080547fffffffffffffffffffffffffffffffff0000000000000000000000ffffffffff16650100000000008686036affffffffffffffffffffff16021790555173ffffffffffffffffffffffffffffffffffffffff8516916108fc851502918591818181858888f19350505050158015612250573d6000803e3d6000fd5b508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16857f50ee63b3e6b23156354ac5126b37abf7adccada099df4c9c70205f887d76e8ca856040516122b191815260200190565b60405180910390a450505050565b6122c761329b565b6113208161395a565b600080600c816122e36020890189613aaf565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002054612315906001614191565b905062ffffff811115612354576040517f3965512700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6affffffffffffffffffffff341115612399576040517f279f9e9000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006123a86020880188613aaf565b73ffffffffffffffffffffffffffffffffffffffff16036123f5576040517f717833df00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600261240961012088016101008901614236565b60ff161115612444576040517fe49b9c9500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166124886020880188613aaf565b73ffffffffffffffffffffffffffffffffffffffff16036124d5576040517f798943b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6125156124ea61014088016101208901614251565b62ffffff1661250161012089016101008a01614236565b60ff16600281111561192057611920614065565b61255b61252860a088016080890161426c565b61ffff1661253c60e0890160c08a01614287565b63ffffffff1661255260c08a0160a08b0161426c565b61ffff166135c0565b61258261256b6020880188613aaf565b60601b600090815260e883901b6014526017902090565b9150806125926020880188613aaf565b73ffffffffffffffffffffffffffffffffffffffff16837fb9b4668f2492830c54dc2fa7c8e28d9184882690fbedea4abeb03f016663d212338a6040516125da9291906142d2565b60405180910390a460016125f661012088016101008901614236565b60ff16600281111561260a5761260a614065565b600281111561261b5761261b614065565b036126305761262b828585613747565b612678565b600261264461012088016101008901614236565b60ff16600281111561265857612658614065565b600281111561266957612669614065565b03612678576126788286613896565b6000600161268e61012089016101008a01614236565b60ff1660028111156126a2576126a2614065565b60028111156126b3576126b3614065565b146126cb576126c86040880160208901614412565b90505b60016126dd6060890160408a0161442d565b156126e6576002175b6126f66080890160608a0161442d565b156126ff576004175b60e08801351561270d576008175b604080516101208101825260ff831681527fffffffff00000000000000000000000000000000000000000000000000000000841660208201526000918101919091526060810161276360a08b0160808c0161426c565b61ffff16815260200161277c60c08b0160a08c0161426c565b61ffff16815260200161279560e08b0160c08c01614287565b63ffffffff1681526020016127b26101208b016101008c01614236565b60ff1681526020016127cc6101408b016101208c01614251565b62ffffff168152602001600063ffffffff168152506006600086815260200190815260200160002060008201518160000160006101000a81548160ff021916908360ff16021790555060208201518160000160016101000a81548163ffffffff021916908360e01c021790555060408201518160000160056101000a8154816affffffffffffffffffffff02191690836affffffffffffffffffffff16021790555060608201518160000160106101000a81548161ffff021916908361ffff16021790555060808201518160000160126101000a81548161ffff021916908361ffff16021790555060a08201518160000160146101000a81548163ffffffff021916908363ffffffff16021790555060c08201518160000160186101000a81548160ff021916908360ff16021790555060e08201518160000160196101000a81548162ffffff021916908362ffffff16021790555061010082015181600001601c6101000a81548163ffffffff021916908363ffffffff1602179055509050508760e001356008600086815260200190815260200160002081905550505080600c60008860000160208101906129829190613aaf565b73ffffffffffffffffffffffffffffffffffffffff16815260208082019290925260409081016000908120939093558483526009909152902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790553415612a15576129f9606087016040880161442d565b15612a0c57612a073361395a565b612a15565b612a15826132d5565b94509492505050565b3360009081526013602052604090205460018201612a3a578091505b612a438261349a565b81811015612a7d576040517f3166cb3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526013602052604080822084840390555173ffffffffffffffffffffffffffffffffffffffff85169184156108fc02918591818181858888f19350505050158015612ad1573d6000803e3d6000fd5b5060405182815273ffffffffffffffffffffffffffffffffffffffff84169033907f307ba9008c2eb2a77892b84866e728ce368061fe4e72e27221a4f63dfe50c085906020015b60405180910390a3505050565b6000818152600b602052604090205473ffffffffffffffffffffffffffffffffffffffff163314612b82576040517ff097464000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526009602090815260408083208054337fffffffffffffffffffffffff00000000000000000000000000000000000000009182168117909255600b909352818420805490931690925551909183917f1f436fd25d350ec220955f7c1fadbae0d1e695cf8135a25ef9c0eab577223b9f9190a350565b612c036137a0565b73ffffffffffffffffffffffffffffffffffffffff8116612ca6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610a8a565b61132081613821565b6040805161012081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905281908190604080518082019091526000815260606020820181905290600087815260096020908152604080832054600b83528184205460088452828520546006855283862060078652848720600a875296859020855161012081018752915460ff808216845261010080830460e090811b7fffffffff00000000000000000000000000000000000000000000000000000000169a86019a909a526501000000000083046affffffffffffffffffffff1698850198909852700100000000000000000000000000000000820461ffff90811660608601527201000000000000000000000000000000000000830416608085015274010000000000000000000000000000000000000000820463ffffffff90811660a08601527801000000000000000000000000000000000000000000000000830490911660c0850152790100000000000000000000000000000000000000000000000000820462ffffff16988401989098527c0100000000000000000000000000000000000000000000000000000000900490961694810194909452855473ffffffffffffffffffffffffffffffffffffffff938416969390921694909392918290612eb4906140b0565b80601f0160208091040260200160405190810160405280929190818152602001828054612ee0906140b0565b8015612f2d5780601f10612f0257610100808354040283529160200191612f2d565b820191906000526020600020905b815481529060010190602001808311612f1057829003601f168201915b505060408051808201909152855473ffffffffffffffffffffffffffffffffffffffff1681526001860180549597509094869450602086019350909150612f73906140b0565b80601f0160208091040260200160405190810160405280929190818152602001828054612f9f906140b0565b8015612fec5780601f10612fc157610100808354040283529160200191612fec565b820191906000526020600020905b815481529060010190602001808311612fcf57829003601f168201915b505050505081525050905095509550955095509550955091939550919395565b60008281526009602090815260408083205473ffffffffffffffffffffffffffffffffffffffff168352601390915290205481811015613082576040517f5a27597b0000000000000000000000000000000000000000000000000000000081526004810182905260248101839052604401610a8a565b60009283526009602090815260408085205473ffffffffffffffffffffffffffffffffffffffff168552601390915290922091039055565b73ffffffffffffffffffffffffffffffffffffffff811660009081526014602052604090205415611320576040517f81f9afb300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906323b872dd906064016020604051808303816000875af11580156131b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131d491906141dc565b506000828152600d60205260409020805482919060149061321c9084907401000000000000000000000000000000000000000090046bffffffffffffffffffffffff1661444a565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550817fb1ab6be18e00655e8a052f6565edf39309c0038d15c0be04c4f2beadbb65f924823360405161149892919091825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b34600003611db8576040517f50e620e200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806132e06139db565b600085815260066020526040812054929450909250906133179083906501000000000090046affffffffffffffffffffff16614191565b90506affffffffffffffffffffff81111561335e576040517f279f9e9000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600380548401905560008481526006602090815260409182902080547fffffffffffffffffffffffffffffffff0000000000000000000000ffffffffff16650100000000006affffffffffffffffffffff8616021790558151848152908101859052339186917fcde4bbac54ccbe285df37dd4861ba498967f700c80555187ce308b499d8980f89101611788565b60005473ffffffffffffffffffffffffffffffffffffffff163314611db8576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818152600e602052604090205473ffffffffffffffffffffffffffffffffffffffff163314611320576040517fd6b3e94e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003611320576040517f06551f4d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818152600e602052604090205473ffffffffffffffffffffffffffffffffffffffff16331480159061352c57506000818152600d602052604090205473ffffffffffffffffffffffffffffffffffffffff163314155b15611320576040517f3377c89900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526009602052604090205473ffffffffffffffffffffffffffffffffffffffff163314611320576040517fddf69e8200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826000036135fa576040517f2f61889e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81158015613606575080155b15611cf1576040517f896ce9f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b811580156136775750600081600281111561365a5761365a614065565b14806136775750600181600281111561367557613675614065565b145b15611dcd576040517f732dc01400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060028111156136c0576136c0614065565b6000838152600660205260409020547801000000000000000000000000000000000000000000000000900460ff1660028111156136ff576136ff614065565b600281111561371057613710614065565b14611dcd576040517fcaa30c5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526007602052604090206137608284836144ec565b50827fd22231b382b21cb9521ddd32d9acb2f6ee7720c09de2cfba0fbadabd15932a948383604051613793929190614650565b60405180910390a2505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611db8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a8a565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006138a56020830183613aaf565b73ffffffffffffffffffffffffffffffffffffffff16036138f2576040517fa7220e5800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600a60205260409020819061390c82826146c9565b508290507f259cf3286fb257c644397539ce6a98f9c054f66d90577d69e02503a85a5e99ce61393e6020840184613aaf565b61394b6020850185614664565b60405161149893929190614880565b6000806139656139db565b600380548301905573ffffffffffffffffffffffffffffffffffffffff8516600081815260136020526040908190208054840190555192945090925033917f37d2d0ab5d3d834b49345443201eb89ca4ac72dc66ca316e761fd1bb3d667d1d90612b189085908790918252602082015260400190565b600080620f4240600454346139f091906148b9565b6139fa91906148d0565b9150613a068234614052565b90509091565b73ffffffffffffffffffffffffffffffffffffffff8116811461132057600080fd5b8035613a3981613a0c565b919050565b60008060408385031215613a5157600080fd5b8235613a5c81613a0c565b946020939093013593505050565b600060208284031215613a7c57600080fd5b5035919050565b600080600060608486031215613a9857600080fd5b505081359360208301359350604090920135919050565b600060208284031215613ac157600080fd5b8135613acc81613a0c565b9392505050565b60008060008060808587031215613ae957600080fd5b5050823594602084013594506040840135936060013592509050565b60008060408385031215613b1857600080fd5b50508035926020909101359150565b600080600060608486031215613b3c57600080fd5b833592506020840135613b4e81613a0c565b929592945050506040919091013590565b803561ffff81168114613a3957600080fd5b803563ffffffff81168114613a3957600080fd5b803562ffffff81168114613a3957600080fd5b60008060008060008060c08789031215613bb157600080fd5b86359550613bc160208801613b5f565b9450613bcf60408801613b5f565b9350613bdd60608801613b71565b925060808701359150613bf260a08801613b85565b90509295509295509295565b60008060408385031215613c1157600080fd5b823591506020830135613c2381613a0c565b809150509250929050565b60008083601f840112613c4057600080fd5b50813567ffffffffffffffff811115613c5857600080fd5b602083019150836020828501011115613c7057600080fd5b9250929050565b600080600060408486031215613c8c57600080fd5b83359250602084013567ffffffffffffffff811115613caa57600080fd5b613cb686828701613c2e565b9497909650939450505050565b801515811461132057600080fd5b8035613a3981613cc3565b60008060008060808587031215613cf257600080fd5b843593506020850135613d0481613cc3565b92506040850135613d1481613cc3565b91506060850135613d2481613cc3565b939692955090935050565b600060408284031215613d4157600080fd5b50919050565b60008060408385031215613d5a57600080fd5b82359150602083013567ffffffffffffffff811115613d7857600080fd5b613d8485828601613d2f565b9150509250929050565b60008060008060808587031215613da457600080fd5b843593506020850135613db681613a0c565b93969395505050506040820135916060013590565b600080600080848603610180811215613de357600080fd5b61014080821215613df357600080fd5b869550850135905067ffffffffffffffff80821115613e1157600080fd5b613e1d88838901613d2f565b9450610160870135915080821115613e3457600080fd5b50613e4187828801613c2e565b95989497509550505050565b60005b83811015613e68578181015183820152602001613e50565b50506000910152565b60008151808452613e89816020860160208601613e4d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff81511682526000602082015160406020850152613ef06040850182613e71565b949350505050565b60006101c073ffffffffffffffffffffffffffffffffffffffff808a16845280891660208501525086604084015260ff86511660608401527fffffffff0000000000000000000000000000000000000000000000000000000060208701511660808401526040860151613f7a60a08501826affffffffffffffffffffff169052565b50606086015161ffff90811660c085015260808701511660e084015260a086015163ffffffff81166101008086019190915260c088015160ff1661012086015260e088015162ffffff1661014086015287015163ffffffff16610160850152506101808301819052613fee81840186613e71565b90508281036101a08401526140038185613ebb565b9998505050505050505050565b602081526000613acc6020830184613e71565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156112ae576112ae614023565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600082516140a6818460208701613e4d565b9190910192915050565b600181811c908216806140c457607f821691505b602082108103613d41577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600080835461410b816140b0565b60018281168015614123576001811461415657614185565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0084168752821515830287019450614185565b8760005260208060002060005b8581101561417c5781548a820152908401908201614163565b50505082870194505b50929695505050505050565b808201808211156112ae576112ae614023565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036141d5576141d5614023565b5060010190565b6000602082840312156141ee57600080fd5b8151613acc81613cc3565b6bffffffffffffffffffffffff82811682821603908082111561421e5761421e614023565b5092915050565b803560ff81168114613a3957600080fd5b60006020828403121561424857600080fd5b613acc82614225565b60006020828403121561426357600080fd5b613acc82613b85565b60006020828403121561427e57600080fd5b613acc82613b5f565b60006020828403121561429957600080fd5b613acc82613b71565b80357fffffffff0000000000000000000000000000000000000000000000000000000081168114613a3957600080fd5b73ffffffffffffffffffffffffffffffffffffffff83168152610160810161431a6020830161430085613a2e565b73ffffffffffffffffffffffffffffffffffffffff169052565b614326602084016142a2565b7fffffffff00000000000000000000000000000000000000000000000000000000811660408401525061435b60408401613cd1565b80151560608401525061437060608401613cd1565b80151560808401525061438560808401613b5f565b61ffff811660a08401525061439c60a08401613b5f565b61ffff811660c0840152506143b360c08401613b71565b63ffffffff811660e08401525061010060e0840135818401526143d7818501614225565b90506101206143ea8185018360ff169052565b6143f5818601613b85565b91505061440a61014084018262ffffff169052565b509392505050565b60006020828403121561442457600080fd5b613acc826142a2565b60006020828403121561443f57600080fd5b8135613acc81613cc3565b6bffffffffffffffffffffffff81811683821601908082111561421e5761421e614023565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b601f821115611cf157600081815260208120601f850160051c810160208610156144c55750805b601f850160051c820191505b818110156144e4578281556001016144d1565b505050505050565b67ffffffffffffffff8311156145045761450461446f565b6145188361451283546140b0565b8361449e565b6000601f84116001811461456a57600085156145345750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355614600565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156145b95786850135825560209485019460019092019101614599565b50868210156145f4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526000613ef0602083018486614607565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261469957600080fd5b83018035915067ffffffffffffffff8211156146b457600080fd5b602001915036819003821315613c7057600080fd5b81356146d481613a0c565b73ffffffffffffffffffffffffffffffffffffffff81167fffffffffffffffffffffffff00000000000000000000000000000000000000008354161782555060018082016020808501357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe186360301811261474e57600080fd5b8501803567ffffffffffffffff81111561476757600080fd5b803603838301131561477857600080fd5b61478c8161478686546140b0565b8661449e565b6000601f8211600181146147e057600083156147aa57508382018501355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600385901b1c1916600184901b178655614875565b6000868152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0841690835b8281101561482e5786850188013582559387019390890190870161480f565b508482101561486b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88660031b161c198785880101351681555b50508683881b0186555b505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526040602082015260006148b0604083018486614607565b95945050505050565b80820281158282048414176112ae576112ae614023565b600082614906577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea26469706673582212202f00e773eb3ece6ace307971e0278b49b0ef5cb356a963d590a3af39eeb3d1cb64736f6c63430008110033000000000000000000000000b258302c3f209491d604165549079680708581cc00000000000000000000000038e4adb44ef08f22f5b5b76a8f0c2d0dcbe7dca100000000000000000000000000000000000000000000003635c9adc5dea000000000000000000000000000000000000000000000000000000000000000069780
Deployed Bytecode
0x60806040526004361061024a5760003560e01c80638f245cc511610138578063c44a7130116100b0578063f729cf0d1161007f578063f8f6318811610064578063f8f63188146107fc578063fa713f40146108a9578063ffa1ad74146108d657600080fd5b8063f729cf0d14610792578063f83c1700146107c457600080fd5b8063c44a713014610644578063d217a89514610732578063efcdd7aa14610752578063f2fde38b1461077257600080fd5b80639da867d511610107578063b882eda6116100ec578063b882eda6146105c5578063c1484807146105d8578063c3f909d41461060057600080fd5b80639da867d514610585578063a34f8e14146105a557600080fd5b80638f245cc5146104f15780639230f2c0146105115780639af83df0146105455780639caec1d81461056557600080fd5b806329956b22116101cb578063572d417b1161019a578063715018a61161017f578063715018a6146104705780637b0472f0146104855780638da5cb5b146104a557600080fd5b8063572d417b146104305780636b5dd8551461045057600080fd5b806329956b22146103a35780633a1b9942146103c357806346e89169146103e3578063499925561461041057600080fd5b8063164e68de116102225780631c1ad03d116102075780631c1ad03d14610329578063293ac1bf14610356578063298a16131461037657600080fd5b8063164e68de146102cc57806317d11280146102ec57600080fd5b801561024f57806304d0fbdf146102665780630c4a06d014610299578063146cc168146102ac575b600080fd5b34801561025b57600080fd5b5061026461092c565b005b34801561027257600080fd5b50610286610281366004613a3e565b61116c565b6040519081526020015b60405180910390f35b6102646102a7366004613a6a565b6112b4565b3480156102b857600080fd5b506102646102c7366004613a83565b611323565b3480156102d857600080fd5b506102646102e7366004613aaf565b6113f9565b3480156102f857600080fd5b50610286610307366004613ad3565b600066038d7ea4c6800084026064619c40840185028702040195945050505050565b34801561033557600080fd5b50610286610344366004613aaf565b60146020526000908152604090205481565b34801561036257600080fd5b50610286610371366004613b05565b6114a4565b34801561038257600080fd5b50610286610391366004613aaf565b600c6020526000908152604090205481565b3480156103af57600080fd5b506102646103be366004613b27565b61167a565b3480156103cf57600080fd5b506102646103de366004613b98565b611796565b3480156103ef57600080fd5b506102866103fe366004613a6a565b60009081526006602052604090205490565b34801561041c57600080fd5b5061028661042b366004613bfe565b611b13565b34801561043c57600080fd5b5061026461044b366004613c77565b611cd2565b34801561045c57600080fd5b5061026461046b366004613cdc565b611cf6565b34801561047c57600080fd5b50610264611da6565b34801561049157600080fd5b506102646104a0366004613b05565b611dba565b3480156104b157600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610290565b3480156104fd57600080fd5b5061026461050c366004613d47565b611dd1565b34801561051d57600080fd5b506104cc7f00000000000000000000000038e4adb44ef08f22f5b5b76a8f0c2d0dcbe7dca181565b34801561055157600080fd5b50610264610560366004613bfe565b611def565b34801561057157600080fd5b50610264610580366004613d8e565b611e77565b34801561059157600080fd5b506102646105a0366004613bfe565b612078565b3480156105b157600080fd5b506102646105c0366004613b27565b61212c565b6102646105d3366004613aaf565b6122bf565b6105eb6105e6366004613dcb565b6122d0565b60408051928352602083019190915201610290565b34801561060c57600080fd5b50600154600254600354600454600554604080519586526020860194909452928401919091526060830152608082015260a001610290565b34801561065057600080fd5b506106e561065f366004613a6a565b6000908152600e6020908152604080832054600d835281842054600f845282852054601085528386205460118652848720546012909652939095205473ffffffffffffffffffffffffffffffffffffffff9283169692821695740100000000000000000000000000000000000000009092046bffffffffffffffffffffffff1694919392565b6040805173ffffffffffffffffffffffffffffffffffffffff9889168152979096166020880152948601939093526060850191909152608084015260a083015260c082015260e001610290565b34801561073e57600080fd5b5061026461074d366004613a3e565b612a1e565b34801561075e57600080fd5b5061026461076d366004613a6a565b612b25565b34801561077e57600080fd5b5061026461078d366004613aaf565b612bfb565b34801561079e57600080fd5b506107b26107ad366004613a6a565b612caf565b60405161029096959493929190613ef8565b3480156107d057600080fd5b506102866107df366004613a3e565b60008260601b6000528160e81b6014526017600020905092915050565b34801561080857600080fd5b5061087d610817366004613a6a565b6000908152600d602090815260409182902082518084019093525473ffffffffffffffffffffffffffffffffffffffff8116808452740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff169290910182905291565b6040805173ffffffffffffffffffffffffffffffffffffffff9093168352602083019190915201610290565b3480156108b557600080fd5b506102866108c4366004613aaf565b60136020526000908152604090205481565b3480156108e257600080fd5b5061091f6040518060400160405280600581526020017f322e322e3000000000000000000000000000000000000000000000000000000081525081565b6040516102909190614010565b60005a9050600060178060046000376000908120601c3560e81c808352600d602090815260409384902084518086019095525473ffffffffffffffffffffffffffffffffffffffff8116808652740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff169185019190915291935060043560601c929091601b3560f81c919033146109f3576040517f4e2c6c2600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60015481602001516bffffffffffffffffffffffff161015610a41576040517fa42f03de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060008481526006602052604090205460018116610a93576040517f2cd4cf48000000000000000000000000000000000000000000000000000000008152600481018690526024015b60405180910390fd5b6008811615158015610ae65750600085815260086020908152604080832054868452600d909252909120547401000000000000000000000000000000000000000090046bffffffffffffffffffffffff16105b15610b1d576040517f6bb3355200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b62ffffff60c882901c168015610b895760e082901c8015610b875780820142811115610b85576040517fe096085e0000000000000000000000000000000000000000000000000000000081526004810183905260248101849052426044820152606401610a8a565b505b505b50633b9aca0061ffff608083901c16024881108015610ba9575060018316155b15610be9576040517f725450b300000000000000000000000000000000000000000000000000000000815248600482015260248101829052604401610a8a565b333214610c22576040517fa397a6e500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008061c3505a610c339190614052565b9050600060ff60c086901c166002811115610c5057610c50614065565b90506000816002811115610c6657610c66614065565b03610d4057604080517fffffffff0000000000000000000000000000000000000000000000000000000060d888901b16602082018190529173ffffffffffffffffffffffffffffffffffffffff8b1691859101604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052610cf191614094565b60006040518083038160008787f1925050503d8060008114610d2f576040519150601f19603f3d011682016040523d82523d6000602084013e610d34565b606091505b50508094505050610ec9565b6001816002811115610d5457610d54614065565b03610ddf578773ffffffffffffffffffffffffffffffffffffffff1682600760008c8152602001908152602001600020604051610d9191906140fd565b60006040518083038160008787f1925050503d8060008114610dcf576040519150601f19603f3d011682016040523d82523d6000602084013e610dd4565b606091505b505080935050610ec9565b6002816002811115610df357610df3614065565b03610e975736601f60405181831015610e2e577f47a0bafb000000000000000000000000000000000000000000000000000000008152600481fd5b8183039250828101604052828282376004881615610e83578760081c60e01b601f3560e01c60e01b14610e83577f84fb8275000000000000000000000000000000000000000000000000000000008152600481fd5b600080848360008f8af19550505050610ec9565b6040517fe49b9c9500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82156111185760008981526006602052604081205495505a8b03905060004880871015610ef35750855b66038d7ea4c6800063ffffffff60a08a901c16026064619c408501830261ffff60908c901c160204019150506000610f2d88600216151590565b15610f4157610f3c8c8361300c565b610fcb565b6affffffffffffffffffffff602889901c1682811015610f97576040517f208118ad0000000000000000000000000000000000000000000000000000000081526004810182905260248101849052604401610a8a565b82900360281b7fffffffffffffffffffffffffffffffff0000000000000000000000ffffffffff9890981697909717965060015b6002891615610ffd5760008a81526010602052604081208054849290610ff2908490614191565b9091555061102c9050565b604051339083156108fc029084906000818181858888f1935050505015801561102a573d6000803e3d6000fd5b505b62ffffff60c889901c16801561108a577bffffffffffffffffffffffffffffffffffffffffffffffffffffffff989098167fffffffff000000000000000000000000000000000000000000000000000000004260e01b161797600191505b5080156110a35760008c81526006602052604090208890555b50604080518a81526020810184905248818301523a60608201526080810183905260a08101899052905173ffffffffffffffffffffffffffffffffffffffff8c16918d917f59200007defbdd8d2c9e53dd05f81091fe977b424f38f2562df9ee8725d584699181900360c00190a35050611160565b3d6000819003611154576040517f81953a7e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604051816000823e8181fd5b50505050505050505050565b6000611177836130ba565b6001548210156111b3576040517f5945ea5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005600081546111c2906141a4565b91829055506000818152600e6020908152604080832080547fffffffffffffffffffffffff000000000000000000000000000000000000000016339081179091558151808301835273ffffffffffffffffffffffffffffffffffffffff898116808352828601878152888852600d8752858820935190516bffffffffffffffffffffffff167401000000000000000000000000000000000000000002921691909117909155808552601490935281842085905590519394509092909184917f28e52185bb539dddafff5a07d4d7a65b6d44c6be0460f18b77ad1b5d7c7b6d7d9190a46112ae8183613117565b92915050565b6112bc61329b565b60008181526009602052604090205473ffffffffffffffffffffffffffffffffffffffff16611317576040517fa614bda700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611320816132d5565b50565b61132b6133ec565b62278d00821115611368576040517fde2180ee00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61c3508111156113a4576040517ff6f3292b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018390556002829055600481905560408051848152602081018490529081018290527f0c9773495c97952f53e7c7c23fc4ac36bc8d0e5c9ff4b5ffc8edd7b000931ea29060600160405180910390a1505050565b6114016133ec565b60038054600091829055604051909173ffffffffffffffffffffffffffffffffffffffff84169183156108fc0291849190818181858888f1935050505015801561144f573d6000803e3d6000fd5b508173ffffffffffffffffffffffffffffffffffffffff167f9bba815921f12cb7b1408e14b5ade745234397d39623ae5e7c82d693cb45815f8260405161149891815260200190565b60405180910390a25050565b60006114af8361343d565b6114b88261349a565b6000838152600d6020908152604080832054600f909252822054740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff16916115048284614191565b90508185101561154a576040517f85348f7c0000000000000000000000000000000000000000000000000000000081526004810186905260248101839052604401610a8a565b80851115611595576040517fb3a6f108000000000000000000000000000000000000000000000000000000008152600481018690526024810184905260448101839052606401610a8a565b6000868152600f60209081526040808320839055600d8252808320805473ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000878b03808a036bffffffffffffffffffffffff16919091029190911790915560119092529091208054820190556002546116189042614191565b600088815260126020908152604091829020839055815189815290810184905290810185905290955087907f2f344f62e88371893ede3b3ea3af1bbba704965ff1a7acc83ce2e367dcc4720d9060600160405180910390a25050505092915050565b60008381526010602052604090205460018201611695578091505b61169e8261349a565b6116a7846134d4565b808211156116eb576040517fa20926670000000000000000000000000000000000000000000000000000000081526004810183905260248101829052604401610a8a565b60008481526010602052604080822084840390555173ffffffffffffffffffffffffffffffffffffffff85169184156108fc02918591818181858888f1935050505015801561173e573d6000803e3d6000fd5b508273ffffffffffffffffffffffffffffffffffffffff16847f540b25d0ce24763795ee97abcbde8b65caecb84c08851dc1e31b5616deb86fb78460405161178891815260200190565b60405180910390a350505050565b61179f86613563565b6117b88561ffff168463ffffffff168661ffff166135c0565b600086815260066020908152604091829020825161012081018452905460ff808216835261010080830460e090811b7fffffffff0000000000000000000000000000000000000000000000000000000016958501959095526501000000000083046affffffffffffffffffffff1695840195909552700100000000000000000000000000000000820461ffff90811660608501527201000000000000000000000000000000000000830416608084015274010000000000000000000000000000000000000000820463ffffffff90811660a08501527801000000000000000000000000000000000000000000000000830490911660c08401819052790100000000000000000000000000000000000000000000000000830462ffffff908116958501959095527c010000000000000000000000000000000000000000000000000000000090920416938201939093529161192591841690600281111561192057611920614065565b61363d565b805160ff16831580159061193b57508151600816155b15611944576008175b831580156119555750815160081615155b1561195e576008185b600088815260066020818152604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff8716178155600883529381902088905591815282547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff1670010000000000000000000000000000000061ffff8c81169182027fffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffff16929092177201000000000000000000000000000000000000928c16928302177fffffffff000000ff00000000ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000063ffffffff8c169081027fffffffff000000ffffffffffffffffffffffffffffffffffffffffffffffffff169190911779010000000000000000000000000000000000000000000000000062ffffff8b16908102919091179096558451918252928101919091529182015260608101869052608081019190915288907f36530212a24c816d4e494215a8c9e70aa89ee2c827cdaa6454c49a1b9c1f51709060a00160405180910390a25050505050505050565b6000611b1e8361343d565b600083815260126020526040902054421015611b66576040517fd364d89200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060008281526011602052604081205490819003611bb0576040517f9121b84f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526011602052604080822091909155517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f00000000000000000000000038e4adb44ef08f22f5b5b76a8f0c2d0dcbe7dca1169063a9059cbb906044016020604051808303816000875af1158015611c56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c7a91906141dc565b508173ffffffffffffffffffffffffffffffffffffffff16837f5e205b6e480b30b73f149f1e859cba98faf02d507680260f8626f19e640abdd283604051611cc491815260200190565b60405180910390a392915050565b611cdb83613563565b611ce68360016136ae565b611cf1838383613747565b505050565b611cff84613563565b60008315611d0b576001175b8215611d15576002175b8115611d1f576004175b600085815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016821790819055604080518615158152851515602082015284151581830152905187917f654d2f54a1effa88d8b821bb9edce7ee03d265c6796c42b5fe8b7d5d55fa48c8919081900360600190a2505050505050565b611dae6137a0565b611db86000613821565b565b611dc38161349a565b611dcd8282613117565b5050565b611dda82613563565b611de58260026136ae565b611dcd8282613896565b611df882613563565b6000828152600b602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff851690811790915590519091339185917f40b48a3ccb089339d160145168f44ff509c18d032508f53097f0dc6b829065a691a45050565b611e7f6133ec565b6000611e8b8284614191565b9050611e968161349a565b8215611f3a576000858152600d602052604090208054849190601490611ee39084907401000000000000000000000000000000000000000090046bffffffffffffffffffffffff166141f9565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555082600f60008781526020019081526020016000206000828254611f349190614191565b90915550505b8115611f645760008581526011602052604081208054849290611f5e908490614052565b90915550505b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018390527f00000000000000000000000038e4adb44ef08f22f5b5b76a8f0c2d0dcbe7dca1169063a9059cbb906044016020604051808303816000875af1158015611ff9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061201d91906141dc565b50604080518481526020810184905273ffffffffffffffffffffffffffffffffffffffff86169187917fa0a4bc88df8261867a0171209f23c36f265d479f8d378e57eaddd804fa5a6d4c910160405180910390a35050505050565b6120818261343d565b61208a816130ba565b6000828152600d60208181526040808420805473ffffffffffffffffffffffffffffffffffffffff908116808752601485528387208790559087168087528387208990558887529490935280547fffffffffffffffffffffffff00000000000000000000000000000000000000001684179055519092839186917f803f1e6c69bc471f5a71c877bbb0b42287843a87118166f8b4a6701e75a9ae6a91a4505050565b6000838152600660205260409020546501000000000090046affffffffffffffffffffff166001820161216a57806affffffffffffffffffffff1691505b61217384613563565b61217c8261349a565b81816affffffffffffffffffffff1610156121c3576040517f3166cb3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008481526006602052604080822080547fffffffffffffffffffffffffffffffff0000000000000000000000ffffffffff16650100000000008686036affffffffffffffffffffff16021790555173ffffffffffffffffffffffffffffffffffffffff8516916108fc851502918591818181858888f19350505050158015612250573d6000803e3d6000fd5b508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16857f50ee63b3e6b23156354ac5126b37abf7adccada099df4c9c70205f887d76e8ca856040516122b191815260200190565b60405180910390a450505050565b6122c761329b565b6113208161395a565b600080600c816122e36020890189613aaf565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002054612315906001614191565b905062ffffff811115612354576040517f3965512700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6affffffffffffffffffffff341115612399576040517f279f9e9000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006123a86020880188613aaf565b73ffffffffffffffffffffffffffffffffffffffff16036123f5576040517f717833df00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600261240961012088016101008901614236565b60ff161115612444576040517fe49b9c9500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000038e4adb44ef08f22f5b5b76a8f0c2d0dcbe7dca1166124886020880188613aaf565b73ffffffffffffffffffffffffffffffffffffffff16036124d5576040517f798943b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6125156124ea61014088016101208901614251565b62ffffff1661250161012089016101008a01614236565b60ff16600281111561192057611920614065565b61255b61252860a088016080890161426c565b61ffff1661253c60e0890160c08a01614287565b63ffffffff1661255260c08a0160a08b0161426c565b61ffff166135c0565b61258261256b6020880188613aaf565b60601b600090815260e883901b6014526017902090565b9150806125926020880188613aaf565b73ffffffffffffffffffffffffffffffffffffffff16837fb9b4668f2492830c54dc2fa7c8e28d9184882690fbedea4abeb03f016663d212338a6040516125da9291906142d2565b60405180910390a460016125f661012088016101008901614236565b60ff16600281111561260a5761260a614065565b600281111561261b5761261b614065565b036126305761262b828585613747565b612678565b600261264461012088016101008901614236565b60ff16600281111561265857612658614065565b600281111561266957612669614065565b03612678576126788286613896565b6000600161268e61012089016101008a01614236565b60ff1660028111156126a2576126a2614065565b60028111156126b3576126b3614065565b146126cb576126c86040880160208901614412565b90505b60016126dd6060890160408a0161442d565b156126e6576002175b6126f66080890160608a0161442d565b156126ff576004175b60e08801351561270d576008175b604080516101208101825260ff831681527fffffffff00000000000000000000000000000000000000000000000000000000841660208201526000918101919091526060810161276360a08b0160808c0161426c565b61ffff16815260200161277c60c08b0160a08c0161426c565b61ffff16815260200161279560e08b0160c08c01614287565b63ffffffff1681526020016127b26101208b016101008c01614236565b60ff1681526020016127cc6101408b016101208c01614251565b62ffffff168152602001600063ffffffff168152506006600086815260200190815260200160002060008201518160000160006101000a81548160ff021916908360ff16021790555060208201518160000160016101000a81548163ffffffff021916908360e01c021790555060408201518160000160056101000a8154816affffffffffffffffffffff02191690836affffffffffffffffffffff16021790555060608201518160000160106101000a81548161ffff021916908361ffff16021790555060808201518160000160126101000a81548161ffff021916908361ffff16021790555060a08201518160000160146101000a81548163ffffffff021916908363ffffffff16021790555060c08201518160000160186101000a81548160ff021916908360ff16021790555060e08201518160000160196101000a81548162ffffff021916908362ffffff16021790555061010082015181600001601c6101000a81548163ffffffff021916908363ffffffff1602179055509050508760e001356008600086815260200190815260200160002081905550505080600c60008860000160208101906129829190613aaf565b73ffffffffffffffffffffffffffffffffffffffff16815260208082019290925260409081016000908120939093558483526009909152902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790553415612a15576129f9606087016040880161442d565b15612a0c57612a073361395a565b612a15565b612a15826132d5565b94509492505050565b3360009081526013602052604090205460018201612a3a578091505b612a438261349a565b81811015612a7d576040517f3166cb3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526013602052604080822084840390555173ffffffffffffffffffffffffffffffffffffffff85169184156108fc02918591818181858888f19350505050158015612ad1573d6000803e3d6000fd5b5060405182815273ffffffffffffffffffffffffffffffffffffffff84169033907f307ba9008c2eb2a77892b84866e728ce368061fe4e72e27221a4f63dfe50c085906020015b60405180910390a3505050565b6000818152600b602052604090205473ffffffffffffffffffffffffffffffffffffffff163314612b82576040517ff097464000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526009602090815260408083208054337fffffffffffffffffffffffff00000000000000000000000000000000000000009182168117909255600b909352818420805490931690925551909183917f1f436fd25d350ec220955f7c1fadbae0d1e695cf8135a25ef9c0eab577223b9f9190a350565b612c036137a0565b73ffffffffffffffffffffffffffffffffffffffff8116612ca6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610a8a565b61132081613821565b6040805161012081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905281908190604080518082019091526000815260606020820181905290600087815260096020908152604080832054600b83528184205460088452828520546006855283862060078652848720600a875296859020855161012081018752915460ff808216845261010080830460e090811b7fffffffff00000000000000000000000000000000000000000000000000000000169a86019a909a526501000000000083046affffffffffffffffffffff1698850198909852700100000000000000000000000000000000820461ffff90811660608601527201000000000000000000000000000000000000830416608085015274010000000000000000000000000000000000000000820463ffffffff90811660a08601527801000000000000000000000000000000000000000000000000830490911660c0850152790100000000000000000000000000000000000000000000000000820462ffffff16988401989098527c0100000000000000000000000000000000000000000000000000000000900490961694810194909452855473ffffffffffffffffffffffffffffffffffffffff938416969390921694909392918290612eb4906140b0565b80601f0160208091040260200160405190810160405280929190818152602001828054612ee0906140b0565b8015612f2d5780601f10612f0257610100808354040283529160200191612f2d565b820191906000526020600020905b815481529060010190602001808311612f1057829003601f168201915b505060408051808201909152855473ffffffffffffffffffffffffffffffffffffffff1681526001860180549597509094869450602086019350909150612f73906140b0565b80601f0160208091040260200160405190810160405280929190818152602001828054612f9f906140b0565b8015612fec5780601f10612fc157610100808354040283529160200191612fec565b820191906000526020600020905b815481529060010190602001808311612fcf57829003601f168201915b505050505081525050905095509550955095509550955091939550919395565b60008281526009602090815260408083205473ffffffffffffffffffffffffffffffffffffffff168352601390915290205481811015613082576040517f5a27597b0000000000000000000000000000000000000000000000000000000081526004810182905260248101839052604401610a8a565b60009283526009602090815260408085205473ffffffffffffffffffffffffffffffffffffffff168552601390915290922091039055565b73ffffffffffffffffffffffffffffffffffffffff811660009081526014602052604090205415611320576040517f81f9afb300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018290527f00000000000000000000000038e4adb44ef08f22f5b5b76a8f0c2d0dcbe7dca173ffffffffffffffffffffffffffffffffffffffff16906323b872dd906064016020604051808303816000875af11580156131b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131d491906141dc565b506000828152600d60205260409020805482919060149061321c9084907401000000000000000000000000000000000000000090046bffffffffffffffffffffffff1661444a565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550817fb1ab6be18e00655e8a052f6565edf39309c0038d15c0be04c4f2beadbb65f924823360405161149892919091825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b34600003611db8576040517f50e620e200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806132e06139db565b600085815260066020526040812054929450909250906133179083906501000000000090046affffffffffffffffffffff16614191565b90506affffffffffffffffffffff81111561335e576040517f279f9e9000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600380548401905560008481526006602090815260409182902080547fffffffffffffffffffffffffffffffff0000000000000000000000ffffffffff16650100000000006affffffffffffffffffffff8616021790558151848152908101859052339186917fcde4bbac54ccbe285df37dd4861ba498967f700c80555187ce308b499d8980f89101611788565b60005473ffffffffffffffffffffffffffffffffffffffff163314611db8576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818152600e602052604090205473ffffffffffffffffffffffffffffffffffffffff163314611320576040517fd6b3e94e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003611320576040517f06551f4d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000818152600e602052604090205473ffffffffffffffffffffffffffffffffffffffff16331480159061352c57506000818152600d602052604090205473ffffffffffffffffffffffffffffffffffffffff163314155b15611320576040517f3377c89900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526009602052604090205473ffffffffffffffffffffffffffffffffffffffff163314611320576040517fddf69e8200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826000036135fa576040517f2f61889e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81158015613606575080155b15611cf1576040517f896ce9f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b811580156136775750600081600281111561365a5761365a614065565b14806136775750600181600281111561367557613675614065565b145b15611dcd576040517f732dc01400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060028111156136c0576136c0614065565b6000838152600660205260409020547801000000000000000000000000000000000000000000000000900460ff1660028111156136ff576136ff614065565b600281111561371057613710614065565b14611dcd576040517fcaa30c5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526007602052604090206137608284836144ec565b50827fd22231b382b21cb9521ddd32d9acb2f6ee7720c09de2cfba0fbadabd15932a948383604051613793929190614650565b60405180910390a2505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611db8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a8a565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006138a56020830183613aaf565b73ffffffffffffffffffffffffffffffffffffffff16036138f2576040517fa7220e5800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600a60205260409020819061390c82826146c9565b508290507f259cf3286fb257c644397539ce6a98f9c054f66d90577d69e02503a85a5e99ce61393e6020840184613aaf565b61394b6020850185614664565b60405161149893929190614880565b6000806139656139db565b600380548301905573ffffffffffffffffffffffffffffffffffffffff8516600081815260136020526040908190208054840190555192945090925033917f37d2d0ab5d3d834b49345443201eb89ca4ac72dc66ca316e761fd1bb3d667d1d90612b189085908790918252602082015260400190565b600080620f4240600454346139f091906148b9565b6139fa91906148d0565b9150613a068234614052565b90509091565b73ffffffffffffffffffffffffffffffffffffffff8116811461132057600080fd5b8035613a3981613a0c565b919050565b60008060408385031215613a5157600080fd5b8235613a5c81613a0c565b946020939093013593505050565b600060208284031215613a7c57600080fd5b5035919050565b600080600060608486031215613a9857600080fd5b505081359360208301359350604090920135919050565b600060208284031215613ac157600080fd5b8135613acc81613a0c565b9392505050565b60008060008060808587031215613ae957600080fd5b5050823594602084013594506040840135936060013592509050565b60008060408385031215613b1857600080fd5b50508035926020909101359150565b600080600060608486031215613b3c57600080fd5b833592506020840135613b4e81613a0c565b929592945050506040919091013590565b803561ffff81168114613a3957600080fd5b803563ffffffff81168114613a3957600080fd5b803562ffffff81168114613a3957600080fd5b60008060008060008060c08789031215613bb157600080fd5b86359550613bc160208801613b5f565b9450613bcf60408801613b5f565b9350613bdd60608801613b71565b925060808701359150613bf260a08801613b85565b90509295509295509295565b60008060408385031215613c1157600080fd5b823591506020830135613c2381613a0c565b809150509250929050565b60008083601f840112613c4057600080fd5b50813567ffffffffffffffff811115613c5857600080fd5b602083019150836020828501011115613c7057600080fd5b9250929050565b600080600060408486031215613c8c57600080fd5b83359250602084013567ffffffffffffffff811115613caa57600080fd5b613cb686828701613c2e565b9497909650939450505050565b801515811461132057600080fd5b8035613a3981613cc3565b60008060008060808587031215613cf257600080fd5b843593506020850135613d0481613cc3565b92506040850135613d1481613cc3565b91506060850135613d2481613cc3565b939692955090935050565b600060408284031215613d4157600080fd5b50919050565b60008060408385031215613d5a57600080fd5b82359150602083013567ffffffffffffffff811115613d7857600080fd5b613d8485828601613d2f565b9150509250929050565b60008060008060808587031215613da457600080fd5b843593506020850135613db681613a0c565b93969395505050506040820135916060013590565b600080600080848603610180811215613de357600080fd5b61014080821215613df357600080fd5b869550850135905067ffffffffffffffff80821115613e1157600080fd5b613e1d88838901613d2f565b9450610160870135915080821115613e3457600080fd5b50613e4187828801613c2e565b95989497509550505050565b60005b83811015613e68578181015183820152602001613e50565b50506000910152565b60008151808452613e89816020860160208601613e4d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff81511682526000602082015160406020850152613ef06040850182613e71565b949350505050565b60006101c073ffffffffffffffffffffffffffffffffffffffff808a16845280891660208501525086604084015260ff86511660608401527fffffffff0000000000000000000000000000000000000000000000000000000060208701511660808401526040860151613f7a60a08501826affffffffffffffffffffff169052565b50606086015161ffff90811660c085015260808701511660e084015260a086015163ffffffff81166101008086019190915260c088015160ff1661012086015260e088015162ffffff1661014086015287015163ffffffff16610160850152506101808301819052613fee81840186613e71565b90508281036101a08401526140038185613ebb565b9998505050505050505050565b602081526000613acc6020830184613e71565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156112ae576112ae614023565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600082516140a6818460208701613e4d565b9190910192915050565b600181811c908216806140c457607f821691505b602082108103613d41577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600080835461410b816140b0565b60018281168015614123576001811461415657614185565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0084168752821515830287019450614185565b8760005260208060002060005b8581101561417c5781548a820152908401908201614163565b50505082870194505b50929695505050505050565b808201808211156112ae576112ae614023565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036141d5576141d5614023565b5060010190565b6000602082840312156141ee57600080fd5b8151613acc81613cc3565b6bffffffffffffffffffffffff82811682821603908082111561421e5761421e614023565b5092915050565b803560ff81168114613a3957600080fd5b60006020828403121561424857600080fd5b613acc82614225565b60006020828403121561426357600080fd5b613acc82613b85565b60006020828403121561427e57600080fd5b613acc82613b5f565b60006020828403121561429957600080fd5b613acc82613b71565b80357fffffffff0000000000000000000000000000000000000000000000000000000081168114613a3957600080fd5b73ffffffffffffffffffffffffffffffffffffffff83168152610160810161431a6020830161430085613a2e565b73ffffffffffffffffffffffffffffffffffffffff169052565b614326602084016142a2565b7fffffffff00000000000000000000000000000000000000000000000000000000811660408401525061435b60408401613cd1565b80151560608401525061437060608401613cd1565b80151560808401525061438560808401613b5f565b61ffff811660a08401525061439c60a08401613b5f565b61ffff811660c0840152506143b360c08401613b71565b63ffffffff811660e08401525061010060e0840135818401526143d7818501614225565b90506101206143ea8185018360ff169052565b6143f5818601613b85565b91505061440a61014084018262ffffff169052565b509392505050565b60006020828403121561442457600080fd5b613acc826142a2565b60006020828403121561443f57600080fd5b8135613acc81613cc3565b6bffffffffffffffffffffffff81811683821601908082111561421e5761421e614023565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b601f821115611cf157600081815260208120601f850160051c810160208610156144c55750805b601f850160051c820191505b818110156144e4578281556001016144d1565b505050505050565b67ffffffffffffffff8311156145045761450461446f565b6145188361451283546140b0565b8361449e565b6000601f84116001811461456a57600085156145345750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355614600565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156145b95786850135825560209485019460019092019101614599565b50868210156145f4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526000613ef0602083018486614607565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261469957600080fd5b83018035915067ffffffffffffffff8211156146b457600080fd5b602001915036819003821315613c7057600080fd5b81356146d481613a0c565b73ffffffffffffffffffffffffffffffffffffffff81167fffffffffffffffffffffffff00000000000000000000000000000000000000008354161782555060018082016020808501357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe186360301811261474e57600080fd5b8501803567ffffffffffffffff81111561476757600080fd5b803603838301131561477857600080fd5b61478c8161478686546140b0565b8661449e565b6000601f8211600181146147e057600083156147aa57508382018501355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600385901b1c1916600184901b178655614875565b6000868152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0841690835b8281101561482e5786850188013582559387019390890190870161480f565b508482101561486b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88660031b161c198785880101351681555b50508683881b0186555b505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681526040602082015260006148b0604083018486614607565b95945050505050565b80820281158282048414176112ae576112ae614023565b600082614906577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea26469706673582212202f00e773eb3ece6ace307971e0278b49b0ef5cb356a963d590a3af39eeb3d1cb64736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000b258302c3f209491d604165549079680708581cc00000000000000000000000038e4adb44ef08f22f5b5b76a8f0c2d0dcbe7dca100000000000000000000000000000000000000000000003635c9adc5dea000000000000000000000000000000000000000000000000000000000000000069780
-----Decoded View---------------
Arg [0] : owner_ (address): 0xB258302C3f209491d604165549079680708581Cc
Arg [1] : cvp_ (address): 0x38e4adB44ef08F22F5B5b76A8f0c2d0dCbE7DcA1
Arg [2] : minKeeperCvp_ (uint256): 1000000000000000000000
Arg [3] : pendingWithdrawalTimeoutSeconds_ (uint256): 432000
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000b258302c3f209491d604165549079680708581cc
Arg [1] : 00000000000000000000000038e4adb44ef08f22f5b5b76a8f0c2d0dcbe7dca1
Arg [2] : 00000000000000000000000000000000000000000000003635c9adc5dea00000
Arg [3] : 0000000000000000000000000000000000000000000000000000000000069780
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $0.063407 | 1,000 | $63.41 |
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.