More Info
Private Name Tags
ContractCreator:
Latest 25 from a total of 28,534 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
Accept Payeeship | 72190602 | 111 days ago | IN | 0 FTM | 0.04200173 | ||||
Transfer Payeesh... | 72190436 | 111 days ago | IN | 0 FTM | 0.06914128 | ||||
Withdraw Payment | 72190417 | 111 days ago | IN | 0 FTM | 0.05985625 | ||||
Withdraw Payment | 69725563 | 155 days ago | IN | 0 FTM | 0.00438602 | ||||
Withdraw Payment | 54668394 | 423 days ago | IN | 0 FTM | 0.0018155 | ||||
Withdraw Funds | 51016002 | 497 days ago | IN | 0 FTM | 0.04108897 | ||||
Withdraw Funds | 51015954 | 497 days ago | IN | 0 FTM | 0.04108897 | ||||
Cancel Upkeep | 51015800 | 497 days ago | IN | 0 FTM | 0.01667776 | ||||
Perform Upkeep | 51015776 | 497 days ago | IN | 0 FTM | 0.35498625 | ||||
Perform Upkeep | 51015768 | 497 days ago | IN | 0 FTM | 0.39225989 | ||||
Perform Upkeep | 51015753 | 497 days ago | IN | 0 FTM | 9.67985464 | ||||
Perform Upkeep | 51015245 | 497 days ago | IN | 0 FTM | 0.07657038 | ||||
Perform Upkeep | 51014744 | 497 days ago | IN | 0 FTM | 0.08175805 | ||||
Perform Upkeep | 51014268 | 497 days ago | IN | 0 FTM | 0.08066354 | ||||
Perform Upkeep | 51013898 | 497 days ago | IN | 0 FTM | 1.04970681 | ||||
Perform Upkeep | 51013394 | 497 days ago | IN | 0 FTM | 0.29635043 | ||||
Perform Upkeep | 51012843 | 497 days ago | IN | 0 FTM | 0.09810967 | ||||
Perform Upkeep | 51012351 | 497 days ago | IN | 0 FTM | 0.05677643 | ||||
Perform Upkeep | 51011694 | 497 days ago | IN | 0 FTM | 0.07655219 | ||||
Perform Upkeep | 51011154 | 497 days ago | IN | 0 FTM | 0.07249942 | ||||
Perform Upkeep | 51010616 | 497 days ago | IN | 0 FTM | 0.09885152 | ||||
Perform Upkeep | 51010060 | 497 days ago | IN | 0 FTM | 0.07655219 | ||||
Perform Upkeep | 51009490 | 497 days ago | IN | 0 FTM | 0.07657038 | ||||
Perform Upkeep | 51009050 | 497 days ago | IN | 0 FTM | 25.26899029 | ||||
Perform Upkeep | 51008491 | 497 days ago | IN | 0 FTM | 0.07655219 |
Latest 1 internal transaction
Parent Txn Hash | Block | From | To | Value | ||
---|---|---|---|---|---|---|
36950845 | 702 days ago | Contract Creation | 0 FTM |
Loading...
Loading
Contract Name:
KeeperRegistry
Compiler Version
v0.7.6+commit.7338295f
Optimization Enabled:
Yes with 1000000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; import "./interfaces/AggregatorV3Interface.sol"; import "./interfaces/LinkTokenInterface.sol"; import "./interfaces/KeeperCompatibleInterface.sol"; import "./interfaces/KeeperRegistryInterface.sol"; import "./interfaces/TypeAndVersionInterface.sol"; import "./vendor/SafeMathChainlink.sol"; import "./vendor/Address.sol"; import "./vendor/Pausable.sol"; import "./vendor/ReentrancyGuard.sol"; import "./vendor/SignedSafeMath.sol"; import "./vendor/SafeMath96.sol"; import "./KeeperBase.sol"; import "./ConfirmedOwner.sol"; /** * @notice Registry for adding work for Chainlink Keepers to perform on client * contracts. Clients must support the Upkeep interface. */ contract KeeperRegistry is TypeAndVersionInterface, ConfirmedOwner, KeeperBase, ReentrancyGuard, Pausable, KeeperRegistryExecutableInterface { using Address for address; using SafeMathChainlink for uint256; using SafeMath96 for uint96; using SignedSafeMath for int256; address private constant ZERO_ADDRESS = address(0); address private constant IGNORE_ADDRESS = 0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF; bytes4 private constant CHECK_SELECTOR = KeeperCompatibleInterface.checkUpkeep.selector; bytes4 private constant PERFORM_SELECTOR = KeeperCompatibleInterface.performUpkeep.selector; uint256 private constant CALL_GAS_MAX = 5_000_000; uint256 private constant CALL_GAS_MIN = 2_300; uint256 private constant CANCELATION_DELAY = 50; uint256 private constant CUSHION = 5_000; uint256 private constant REGISTRY_GAS_OVERHEAD = 80_000; uint256 private constant PPB_BASE = 1_000_000_000; uint64 private constant UINT64_MAX = 2**64 - 1; uint96 private constant LINK_TOTAL_SUPPLY = 1e27; uint256 private s_upkeepCount; uint256[] private s_canceledUpkeepList; address[] private s_keeperList; mapping(uint256 => Upkeep) private s_upkeep; mapping(address => KeeperInfo) private s_keeperInfo; mapping(address => address) private s_proposedPayee; mapping(uint256 => bytes) private s_checkData; Config private s_config; uint256 private s_fallbackGasPrice; // not in config object for gas savings uint256 private s_fallbackLinkPrice; // not in config object for gas savings uint256 private s_expectedLinkBalance; LinkTokenInterface public immutable LINK; AggregatorV3Interface public immutable LINK_ETH_FEED; AggregatorV3Interface public immutable FAST_GAS_FEED; address private s_registrar; /** * @notice versions: * - KeeperRegistry 1.2.0: allow funding within performUpkeep * - KeeperRegistry 1.1.0: added flatFeeMicroLink * - KeeperRegistry 1.0.0: initial release */ string public constant override typeAndVersion = "KeeperRegistry 1.1.0"; struct Upkeep { address target; uint32 executeGas; uint96 balance; address admin; uint64 maxValidBlocknumber; address lastKeeper; } struct KeeperInfo { address payee; uint96 balance; bool active; } struct Config { uint32 paymentPremiumPPB; uint32 flatFeeMicroLink; // min 0.000001 LINK, max 4294 LINK uint24 blockCountPerTurn; uint32 checkGasLimit; uint24 stalenessSeconds; uint16 gasCeilingMultiplier; } struct PerformParams { address from; uint256 id; bytes performData; uint256 maxLinkPayment; uint256 gasLimit; uint256 adjustedGasWei; uint256 linkEth; } event UpkeepRegistered(uint256 indexed id, uint32 executeGas, address admin); event UpkeepPerformed( uint256 indexed id, bool indexed success, address indexed from, uint96 payment, bytes performData ); event UpkeepCanceled(uint256 indexed id, uint64 indexed atBlockHeight); event FundsAdded(uint256 indexed id, address indexed from, uint96 amount); event FundsWithdrawn(uint256 indexed id, uint256 amount, address to); event ConfigSet( uint32 paymentPremiumPPB, uint24 blockCountPerTurn, uint32 checkGasLimit, uint24 stalenessSeconds, uint16 gasCeilingMultiplier, uint256 fallbackGasPrice, uint256 fallbackLinkPrice ); event FlatFeeSet(uint32 flatFeeMicroLink); event KeepersUpdated(address[] keepers, address[] payees); event PaymentWithdrawn(address indexed keeper, uint256 indexed amount, address indexed to, address payee); event PayeeshipTransferRequested(address indexed keeper, address indexed from, address indexed to); event PayeeshipTransferred(address indexed keeper, address indexed from, address indexed to); event RegistrarChanged(address indexed from, address indexed to); /** * @param link address of the LINK Token * @param linkEthFeed address of the LINK/ETH price feed * @param fastGasFeed address of the Fast Gas price feed * @param paymentPremiumPPB payment premium rate oracles receive on top of * being reimbursed for gas, measured in parts per billion * @param flatFeeMicroLink flat fee paid to oracles for performing upkeeps, * priced in MicroLink; can be used in conjunction with or independently of * paymentPremiumPPB * @param blockCountPerTurn number of blocks each oracle has during their turn to * perform upkeep before it will be the next keeper's turn to submit * @param checkGasLimit gas limit when checking for upkeep * @param stalenessSeconds number of seconds that is allowed for feed data to * be stale before switching to the fallback pricing * @param gasCeilingMultiplier multiplier to apply to the fast gas feed price * when calculating the payment ceiling for keepers * @param fallbackGasPrice gas price used if the gas price feed is stale * @param fallbackLinkPrice LINK price used if the LINK price feed is stale */ constructor( address link, address linkEthFeed, address fastGasFeed, uint32 paymentPremiumPPB, uint32 flatFeeMicroLink, uint24 blockCountPerTurn, uint32 checkGasLimit, uint24 stalenessSeconds, uint16 gasCeilingMultiplier, uint256 fallbackGasPrice, uint256 fallbackLinkPrice ) ConfirmedOwner(msg.sender) { LINK = LinkTokenInterface(link); LINK_ETH_FEED = AggregatorV3Interface(linkEthFeed); FAST_GAS_FEED = AggregatorV3Interface(fastGasFeed); setConfig( paymentPremiumPPB, flatFeeMicroLink, blockCountPerTurn, checkGasLimit, stalenessSeconds, gasCeilingMultiplier, fallbackGasPrice, fallbackLinkPrice ); } // ACTIONS /** * @notice adds a new upkeep * @param target address to perform upkeep on * @param gasLimit amount of gas to provide the target contract when * performing upkeep * @param admin address to cancel upkeep and withdraw remaining funds * @param checkData data passed to the contract when checking for upkeep */ function registerUpkeep( address target, uint32 gasLimit, address admin, bytes calldata checkData ) external override onlyOwnerOrRegistrar returns (uint256 id) { require(target.isContract(), "target is not a contract"); require(gasLimit >= CALL_GAS_MIN, "min gas is 2300"); require(gasLimit <= CALL_GAS_MAX, "max gas is 5000000"); id = s_upkeepCount; s_upkeep[id] = Upkeep({ target: target, executeGas: gasLimit, balance: 0, admin: admin, maxValidBlocknumber: UINT64_MAX, lastKeeper: address(0) }); s_checkData[id] = checkData; s_upkeepCount++; emit UpkeepRegistered(id, gasLimit, admin); return id; } /** * @notice simulated by keepers via eth_call to see if the upkeep needs to be * performed. If upkeep is needed, the call then simulates performUpkeep * to make sure it succeeds. Finally, it returns the success status along with * payment information and the perform data payload. * @param id identifier of the upkeep to check * @param from the address to simulate performing the upkeep from */ function checkUpkeep(uint256 id, address from) external override whenNotPaused cannotExecute returns ( bytes memory performData, uint256 maxLinkPayment, uint256 gasLimit, uint256 adjustedGasWei, uint256 linkEth ) { Upkeep memory upkeep = s_upkeep[id]; bytes memory callData = abi.encodeWithSelector(CHECK_SELECTOR, s_checkData[id]); (bool success, bytes memory result) = upkeep.target.call{gas: s_config.checkGasLimit}(callData); if (!success) { string memory upkeepRevertReason = getRevertMsg(result); string memory reason = string(abi.encodePacked("call to check target failed: ", upkeepRevertReason)); revert(reason); } (success, performData) = abi.decode(result, (bool, bytes)); require(success, "upkeep not needed"); PerformParams memory params = generatePerformParams(from, id, performData, false); prePerformUpkeep(upkeep, params.from, params.maxLinkPayment); return (performData, params.maxLinkPayment, params.gasLimit, params.adjustedGasWei, params.linkEth); } /** * @notice executes the upkeep with the perform data returned from * checkUpkeep, validates the keeper's permissions, and pays the keeper. * @param id identifier of the upkeep to execute the data with. * @param performData calldata parameter to be passed to the target upkeep. */ function performUpkeep(uint256 id, bytes calldata performData) external override returns (bool success) { return performUpkeepWithParams(generatePerformParams(msg.sender, id, performData, true)); } /** * @notice prevent an upkeep from being performed in the future * @param id upkeep to be canceled */ function cancelUpkeep(uint256 id) external override { uint64 maxValid = s_upkeep[id].maxValidBlocknumber; bool notCanceled = maxValid == UINT64_MAX; bool isOwner = msg.sender == owner(); require(notCanceled || (isOwner && maxValid > block.number), "too late to cancel upkeep"); require(isOwner || msg.sender == s_upkeep[id].admin, "only owner or admin"); uint256 height = block.number; if (!isOwner) { height = height.add(CANCELATION_DELAY); } s_upkeep[id].maxValidBlocknumber = uint64(height); if (notCanceled) { s_canceledUpkeepList.push(id); } emit UpkeepCanceled(id, uint64(height)); } /** * @notice adds LINK funding for an upkeep by transferring from the sender's * LINK balance * @param id upkeep to fund * @param amount number of LINK to transfer */ function addFunds(uint256 id, uint96 amount) external override { require(s_upkeep[id].maxValidBlocknumber == UINT64_MAX, "upkeep must be active"); s_upkeep[id].balance = s_upkeep[id].balance.add(amount); s_expectedLinkBalance = s_expectedLinkBalance.add(amount); LINK.transferFrom(msg.sender, address(this), amount); emit FundsAdded(id, msg.sender, amount); } /** * @notice uses LINK's transferAndCall to LINK and add funding to an upkeep * @dev safe to cast uint256 to uint96 as total LINK supply is under UINT96MAX * @param sender the account which transferred the funds * @param amount number of LINK transfer */ function onTokenTransfer( address sender, uint256 amount, bytes calldata data ) external { require(msg.sender == address(LINK), "only callable through LINK"); require(data.length == 32, "data must be 32 bytes"); uint256 id = abi.decode(data, (uint256)); require(s_upkeep[id].maxValidBlocknumber == UINT64_MAX, "upkeep must be active"); s_upkeep[id].balance = s_upkeep[id].balance.add(uint96(amount)); s_expectedLinkBalance = s_expectedLinkBalance.add(amount); emit FundsAdded(id, sender, uint96(amount)); } /** * @notice removes funding from a canceled upkeep * @param id upkeep to withdraw funds from * @param to destination address for sending remaining funds */ function withdrawFunds(uint256 id, address to) external validateRecipient(to) { require(s_upkeep[id].admin == msg.sender, "only callable by admin"); require(s_upkeep[id].maxValidBlocknumber <= block.number, "upkeep must be canceled"); uint256 amount = s_upkeep[id].balance; s_upkeep[id].balance = 0; s_expectedLinkBalance = s_expectedLinkBalance.sub(amount); emit FundsWithdrawn(id, amount, to); LINK.transfer(to, amount); } /** * @notice recovers LINK funds improperly transferred to the registry * @dev In principle this function’s execution cost could exceed block * gas limit. However, in our anticipated deployment, the number of upkeeps and * keepers will be low enough to avoid this problem. */ function recoverFunds() external onlyOwner { uint256 total = LINK.balanceOf(address(this)); LINK.transfer(msg.sender, total.sub(s_expectedLinkBalance)); } /** * @notice withdraws a keeper's payment, callable only by the keeper's payee * @param from keeper address * @param to address to send the payment to */ function withdrawPayment(address from, address to) external validateRecipient(to) { KeeperInfo memory keeper = s_keeperInfo[from]; require(keeper.payee == msg.sender, "only callable by payee"); s_keeperInfo[from].balance = 0; s_expectedLinkBalance = s_expectedLinkBalance.sub(keeper.balance); emit PaymentWithdrawn(from, keeper.balance, to, msg.sender); LINK.transfer(to, keeper.balance); } /** * @notice proposes the safe transfer of a keeper's payee to another address * @param keeper address of the keeper to transfer payee role * @param proposed address to nominate for next payeeship */ function transferPayeeship(address keeper, address proposed) external { require(s_keeperInfo[keeper].payee == msg.sender, "only callable by payee"); require(proposed != msg.sender, "cannot transfer to self"); if (s_proposedPayee[keeper] != proposed) { s_proposedPayee[keeper] = proposed; emit PayeeshipTransferRequested(keeper, msg.sender, proposed); } } /** * @notice accepts the safe transfer of payee role for a keeper * @param keeper address to accept the payee role for */ function acceptPayeeship(address keeper) external { require(s_proposedPayee[keeper] == msg.sender, "only callable by proposed payee"); address past = s_keeperInfo[keeper].payee; s_keeperInfo[keeper].payee = msg.sender; s_proposedPayee[keeper] = ZERO_ADDRESS; emit PayeeshipTransferred(keeper, past, msg.sender); } /** * @notice signals to keepers that they should not perform upkeeps until the * contract has been unpaused */ function pause() external onlyOwner { _pause(); } /** * @notice signals to keepers that they can perform upkeeps once again after * having been paused */ function unpause() external onlyOwner { _unpause(); } // SETTERS /** * @notice updates the configuration of the registry * @param paymentPremiumPPB payment premium rate oracles receive on top of * being reimbursed for gas, measured in parts per billion * @param flatFeeMicroLink flat fee paid to oracles for performing upkeeps * @param blockCountPerTurn number of blocks an oracle should wait before * checking for upkeep * @param checkGasLimit gas limit when checking for upkeep * @param stalenessSeconds number of seconds that is allowed for feed data to * be stale before switching to the fallback pricing * @param fallbackGasPrice gas price used if the gas price feed is stale * @param fallbackLinkPrice LINK price used if the LINK price feed is stale */ function setConfig( uint32 paymentPremiumPPB, uint32 flatFeeMicroLink, uint24 blockCountPerTurn, uint32 checkGasLimit, uint24 stalenessSeconds, uint16 gasCeilingMultiplier, uint256 fallbackGasPrice, uint256 fallbackLinkPrice ) public onlyOwner { s_config = Config({ paymentPremiumPPB: paymentPremiumPPB, flatFeeMicroLink: flatFeeMicroLink, blockCountPerTurn: blockCountPerTurn, checkGasLimit: checkGasLimit, stalenessSeconds: stalenessSeconds, gasCeilingMultiplier: gasCeilingMultiplier }); s_fallbackGasPrice = fallbackGasPrice; s_fallbackLinkPrice = fallbackLinkPrice; emit ConfigSet( paymentPremiumPPB, blockCountPerTurn, checkGasLimit, stalenessSeconds, gasCeilingMultiplier, fallbackGasPrice, fallbackLinkPrice ); emit FlatFeeSet(flatFeeMicroLink); } /** * @notice update the list of keepers allowed to perform upkeep * @param keepers list of addresses allowed to perform upkeep * @param payees addresses corresponding to keepers who are allowed to * move payments which have been accrued */ function setKeepers(address[] calldata keepers, address[] calldata payees) external onlyOwner { require(keepers.length == payees.length, "address lists not the same length"); require(keepers.length >= 2, "not enough keepers"); for (uint256 i = 0; i < s_keeperList.length; i++) { address keeper = s_keeperList[i]; s_keeperInfo[keeper].active = false; } for (uint256 i = 0; i < keepers.length; i++) { address keeper = keepers[i]; KeeperInfo storage s_keeper = s_keeperInfo[keeper]; address oldPayee = s_keeper.payee; address newPayee = payees[i]; require(newPayee != address(0), "cannot set payee to the zero address"); require(oldPayee == ZERO_ADDRESS || oldPayee == newPayee || newPayee == IGNORE_ADDRESS, "cannot change payee"); require(!s_keeper.active, "cannot add keeper twice"); s_keeper.active = true; if (newPayee != IGNORE_ADDRESS) { s_keeper.payee = newPayee; } } s_keeperList = keepers; emit KeepersUpdated(keepers, payees); } /** * @notice update registrar * @param registrar new registrar */ function setRegistrar(address registrar) external onlyOwnerOrRegistrar { address previous = s_registrar; require(registrar != previous, "Same registrar"); s_registrar = registrar; emit RegistrarChanged(previous, registrar); } // GETTERS /** * @notice read all of the details about an upkeep */ function getUpkeep(uint256 id) external view override returns ( address target, uint32 executeGas, bytes memory checkData, uint96 balance, address lastKeeper, address admin, uint64 maxValidBlocknumber ) { Upkeep memory reg = s_upkeep[id]; return ( reg.target, reg.executeGas, s_checkData[id], reg.balance, reg.lastKeeper, reg.admin, reg.maxValidBlocknumber ); } /** * @notice read the total number of upkeep's registered */ function getUpkeepCount() external view override returns (uint256) { return s_upkeepCount; } /** * @notice read the current list canceled upkeep IDs */ function getCanceledUpkeepList() external view override returns (uint256[] memory) { return s_canceledUpkeepList; } /** * @notice read the current list of addresses allowed to perform upkeep */ function getKeeperList() external view override returns (address[] memory) { return s_keeperList; } /** * @notice read the current registrar */ function getRegistrar() external view returns (address) { return s_registrar; } /** * @notice read the current info about any keeper address */ function getKeeperInfo(address query) external view override returns ( address payee, bool active, uint96 balance ) { KeeperInfo memory keeper = s_keeperInfo[query]; return (keeper.payee, keeper.active, keeper.balance); } /** * @notice read the current configuration of the registry */ function getConfig() external view override returns ( uint32 paymentPremiumPPB, uint24 blockCountPerTurn, uint32 checkGasLimit, uint24 stalenessSeconds, uint16 gasCeilingMultiplier, uint256 fallbackGasPrice, uint256 fallbackLinkPrice ) { Config memory config = s_config; return ( config.paymentPremiumPPB, config.blockCountPerTurn, config.checkGasLimit, config.stalenessSeconds, config.gasCeilingMultiplier, s_fallbackGasPrice, s_fallbackLinkPrice ); } /** * @notice getFlatFee gets the flat rate fee charged to customers when performing upkeep, * in units of of micro LINK */ function getFlatFee() external view returns (uint32) { return s_config.flatFeeMicroLink; } /** * @notice calculates the minimum balance required for an upkeep to remain eligible */ function getMinBalanceForUpkeep(uint256 id) external view returns (uint96 minBalance) { return getMaxPaymentForGas(s_upkeep[id].executeGas); } /** * @notice calculates the maximum payment for a given gas limit */ function getMaxPaymentForGas(uint256 gasLimit) public view returns (uint96 maxPayment) { (uint256 gasWei, uint256 linkEth) = getFeedData(); uint256 adjustedGasWei = adjustGasPrice(gasWei, false); return calculatePaymentAmount(gasLimit, adjustedGasWei, linkEth); } // PRIVATE /** * @dev retrieves feed data for fast gas/eth and link/eth prices. if the feed * data is stale it uses the configured fallback price. Once a price is picked * for gas it takes the min of gas price in the transaction or the fast gas * price in order to reduce costs for the upkeep clients. */ function getFeedData() private view returns (uint256 gasWei, uint256 linkEth) { uint32 stalenessSeconds = s_config.stalenessSeconds; bool staleFallback = stalenessSeconds > 0; uint256 timestamp; int256 feedValue; (, feedValue, , timestamp, ) = FAST_GAS_FEED.latestRoundData(); if ((staleFallback && stalenessSeconds < block.timestamp - timestamp) || feedValue <= 0) { gasWei = s_fallbackGasPrice; } else { gasWei = uint256(feedValue); } (, feedValue, , timestamp, ) = LINK_ETH_FEED.latestRoundData(); if ((staleFallback && stalenessSeconds < block.timestamp - timestamp) || feedValue <= 0) { linkEth = s_fallbackLinkPrice; } else { linkEth = uint256(feedValue); } return (gasWei, linkEth); } /** * @dev calculates LINK paid for gas spent plus a configure premium percentage */ function calculatePaymentAmount( uint256 gasLimit, uint256 gasWei, uint256 linkEth ) private view returns (uint96 payment) { Config memory config = s_config; uint256 weiForGas = gasWei.mul(gasLimit.add(REGISTRY_GAS_OVERHEAD)); uint256 premium = PPB_BASE.add(config.paymentPremiumPPB); uint256 total = weiForGas.mul(1e9).mul(premium).div(linkEth).add(uint256(config.flatFeeMicroLink).mul(1e12)); require(total <= LINK_TOTAL_SUPPLY, "payment greater than all LINK"); return uint96(total); // LINK_TOTAL_SUPPLY < UINT96_MAX } /** * @dev calls target address with exactly gasAmount gas and data as calldata * or reverts if at least gasAmount gas is not available */ function callWithExactGas( uint256 gasAmount, address target, bytes memory data ) private returns (bool success) { assembly { let g := gas() // Compute g -= CUSHION and check for underflow if lt(g, CUSHION) { revert(0, 0) } g := sub(g, CUSHION) // if g - g//64 <= gasAmount, revert // (we subtract g//64 because of EIP-150) if iszero(gt(sub(g, div(g, 64)), gasAmount)) { revert(0, 0) } // solidity calls check that a contract actually exists at the destination, so we do the same if iszero(extcodesize(target)) { revert(0, 0) } // call and return whether we succeeded. ignore return data success := call(gasAmount, target, 0, add(data, 0x20), mload(data), 0, 0) } return success; } /** * @dev calls the Upkeep target with the performData param passed in by the * keeper and the exact gas required by the Upkeep */ function performUpkeepWithParams(PerformParams memory params) private nonReentrant validUpkeep(params.id) returns (bool success) { Upkeep memory upkeep = s_upkeep[params.id]; prePerformUpkeep(upkeep, params.from, params.maxLinkPayment); uint256 gasUsed = gasleft(); bytes memory callData = abi.encodeWithSelector(PERFORM_SELECTOR, params.performData); success = callWithExactGas(params.gasLimit, upkeep.target, callData); gasUsed = gasUsed - gasleft(); uint96 payment = calculatePaymentAmount(gasUsed, params.adjustedGasWei, params.linkEth); uint96 newUpkeepBalance = s_upkeep[params.id].balance.sub(payment); s_upkeep[params.id].balance = newUpkeepBalance; s_upkeep[params.id].lastKeeper = params.from; uint96 newKeeperBalance = s_keeperInfo[params.from].balance.add(payment); s_keeperInfo[params.from].balance = newKeeperBalance; emit UpkeepPerformed(params.id, success, params.from, payment, params.performData); return success; } /** * @dev ensures a upkeep is valid */ function validateUpkeep(uint256 id) private view { require(s_upkeep[id].maxValidBlocknumber > block.number, "invalid upkeep id"); } /** * @dev ensures all required checks are passed before an upkeep is performed */ function prePerformUpkeep( Upkeep memory upkeep, address from, uint256 maxLinkPayment ) private view { require(s_keeperInfo[from].active, "only active keepers"); require(upkeep.balance >= maxLinkPayment, "insufficient funds"); require(upkeep.lastKeeper != from, "keepers must take turns"); } /** * @dev adjusts the gas price to min(ceiling, tx.gasprice) or just uses the ceiling if tx.gasprice is disabled */ function adjustGasPrice(uint256 gasWei, bool useTxGasPrice) private view returns (uint256 adjustedPrice) { adjustedPrice = gasWei.mul(s_config.gasCeilingMultiplier); if (useTxGasPrice && tx.gasprice < adjustedPrice) { adjustedPrice = tx.gasprice; } } /** * @dev generates a PerformParams struct for use in performUpkeepWithParams() */ function generatePerformParams( address from, uint256 id, bytes memory performData, bool useTxGasPrice ) private view returns (PerformParams memory) { uint256 gasLimit = s_upkeep[id].executeGas; (uint256 gasWei, uint256 linkEth) = getFeedData(); uint256 adjustedGasWei = adjustGasPrice(gasWei, useTxGasPrice); uint96 maxLinkPayment = calculatePaymentAmount(gasLimit, adjustedGasWei, linkEth); return PerformParams({ from: from, id: id, performData: performData, maxLinkPayment: maxLinkPayment, gasLimit: gasLimit, adjustedGasWei: adjustedGasWei, linkEth: linkEth }); } /** * @dev extracts a revert reason from a call result payload */ function getRevertMsg(bytes memory _payload) private pure returns (string memory) { if (_payload.length < 68) return "transaction reverted silently"; assembly { _payload := add(_payload, 0x04) } return abi.decode(_payload, (string)); } // MODIFIERS /** * @dev ensures a upkeep is valid */ modifier validUpkeep(uint256 id) { validateUpkeep(id); _; } /** * @dev ensures that burns don't accidentally happen by sending to the zero * address */ modifier validateRecipient(address to) { require(to != address(0), "cannot send to zero address"); _; } /** * @dev Reverts if called by anyone other than the contract owner or registrar. */ modifier onlyOwnerOrRegistrar() { require(msg.sender == owner() || msg.sender == s_registrar, "Only callable by owner or registrar"); _; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; interface AggregatorV3Interface { function decimals() external view returns (uint8); function description() external view returns (string memory); function version() external view returns (uint256); // getRoundData and latestRoundData should both raise "No data present" // if they do not have data to report, instead of returning unset values // which could be misinterpreted as actual reported values. function getRoundData(uint80 _roundId) external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); function latestRoundData() external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; interface LinkTokenInterface { function allowance(address owner, address spender) external view returns (uint256 remaining); function approve(address spender, uint256 value) external returns (bool success); function balanceOf(address owner) external view returns (uint256 balance); function decimals() external view returns (uint8 decimalPlaces); function decreaseApproval(address spender, uint256 addedValue) external returns (bool success); function increaseApproval(address spender, uint256 subtractedValue) external; function name() external view returns (string memory tokenName); function symbol() external view returns (string memory tokenSymbol); function totalSupply() external view returns (uint256 totalTokensIssued); function transfer(address to, uint256 value) external returns (bool success); function transferAndCall( address to, uint256 value, bytes calldata data ) external returns (bool success); function transferFrom( address from, address to, uint256 value ) external returns (bool success); }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; interface KeeperCompatibleInterface { /** * @notice method that is simulated by the keepers to see if any work actually * needs to be performed. This method does does not actually need to be * executable, and since it is only ever simulated it can consume lots of gas. * @dev To ensure that it is never called, you may want to add the * cannotExecute modifier from KeeperBase to your implementation of this * method. * @param checkData specified in the upkeep registration so it is always the * same for a registered upkeep. This can easily be broken down into specific * arguments using `abi.decode`, so multiple upkeeps can be registered on the * same contract and easily differentiated by the contract. * @return upkeepNeeded boolean to indicate whether the keeper should call * performUpkeep or not. * @return performData bytes that the keeper should call performUpkeep with, if * upkeep is needed. If you would like to encode data to decode later, try * `abi.encode`. */ function checkUpkeep(bytes calldata checkData) external returns (bool upkeepNeeded, bytes memory performData); /** * @notice method that is actually executed by the keepers, via the registry. * The data returned by the checkUpkeep simulation will be passed into * this method to actually be executed. * @dev The input to this method should not be trusted, and the caller of the * method should not even be restricted to any single registry. Anyone should * be able call it, and the input should be validated, there is no guarantee * that the data passed in is the performData returned from checkUpkeep. This * could happen due to malicious keepers, racing keepers, or simply a state * change while the performUpkeep transaction is waiting for confirmation. * Always validate the data passed in. * @param performData is the data which was passed back from the checkData * simulation. If it is encoded, it can easily be decoded into other types by * calling `abi.decode`. This data should not be trusted, and should be * validated against the contract's current state. */ function performUpkeep(bytes calldata performData) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; interface KeeperRegistryBaseInterface { function registerUpkeep( address target, uint32 gasLimit, address admin, bytes calldata checkData ) external returns (uint256 id); function performUpkeep(uint256 id, bytes calldata performData) external returns (bool success); function cancelUpkeep(uint256 id) external; function addFunds(uint256 id, uint96 amount) external; function getUpkeep(uint256 id) external view returns ( address target, uint32 executeGas, bytes memory checkData, uint96 balance, address lastKeeper, address admin, uint64 maxValidBlocknumber ); function getUpkeepCount() external view returns (uint256); function getCanceledUpkeepList() external view returns (uint256[] memory); function getKeeperList() external view returns (address[] memory); function getKeeperInfo(address query) external view returns ( address payee, bool active, uint96 balance ); function getConfig() external view returns ( uint32 paymentPremiumPPB, uint24 checkFrequencyBlocks, uint32 checkGasLimit, uint24 stalenessSeconds, uint16 gasCeilingMultiplier, uint256 fallbackGasPrice, uint256 fallbackLinkPrice ); } /** * @dev The view methods are not actually marked as view in the implementation * but we want them to be easily queried off-chain. Solidity will not compile * if we actually inherit from this interface, so we document it here. */ interface KeeperRegistryInterface is KeeperRegistryBaseInterface { function checkUpkeep(uint256 upkeepId, address from) external view returns ( bytes memory performData, uint256 maxLinkPayment, uint256 gasLimit, int256 gasWei, int256 linkEth ); } interface KeeperRegistryExecutableInterface is KeeperRegistryBaseInterface { function checkUpkeep(uint256 upkeepId, address from) external returns ( bytes memory performData, uint256 maxLinkPayment, uint256 gasLimit, uint256 adjustedGasWei, uint256 linkEth ); }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; abstract contract TypeAndVersionInterface { function typeAndVersion() external pure virtual returns (string memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMathChainlink { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, "SafeMath: division by zero"); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0, "SafeMath: modulo by zero"); return a % b; } }
// SPDX-License-Identifier: MIT // From https://github.com/OpenZeppelin/openzeppelin-contracts v3.4.0(fa64a1ced0b70ab89073d5d0b6e01b0778f7e7d6) pragma solidity >=0.6.2 <0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{value: value}(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) private pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT // github.com/OpenZeppelin/openzeppelin-contracts@fa64a1ced0b70ab89073d5d0b6e01b0778f7e7d6 pragma solidity ^0.7.0; import "./Context.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { require(!paused(), "Pausable: paused"); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { require(paused(), "Pausable: not paused"); _; } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } }
// SPDX-License-Identifier: MIT // github.com/OpenZeppelin/openzeppelin-contracts@fa64a1ced0b70ab89073d5d0b6e01b0778f7e7d6 pragma solidity ^0.7.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; /** * @title SignedSafeMath * @dev Signed math operations with safety checks that revert on error. */ library SignedSafeMath { int256 private constant _INT256_MIN = -2**255; /** * @dev Returns the multiplication of two signed integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(int256 a, int256 b) internal pure returns (int256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } require(!(a == -1 && b == _INT256_MIN), "SignedSafeMath: multiplication overflow"); int256 c = a * b; require(c / a == b, "SignedSafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two signed integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(int256 a, int256 b) internal pure returns (int256) { require(b != 0, "SignedSafeMath: division by zero"); require(!(b == -1 && a == _INT256_MIN), "SignedSafeMath: division overflow"); int256 c = a / b; return c; } /** * @dev Returns the subtraction of two signed integers, reverting on * overflow. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(int256 a, int256 b) internal pure returns (int256) { int256 c = a - b; require((b >= 0 && c <= a) || (b < 0 && c > a), "SignedSafeMath: subtraction overflow"); return c; } /** * @dev Returns the addition of two signed integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(int256 a, int256 b) internal pure returns (int256) { int256 c = a + b; require((b >= 0 && c >= a) || (b < 0 && c < a), "SignedSafeMath: addition overflow"); return c; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. * * This library is a version of Open Zeppelin's SafeMath, modified to support * unsigned 96 bit integers. */ library SafeMath96 { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint96 a, uint96 b) internal pure returns (uint96) { uint96 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint96 a, uint96 b) internal pure returns (uint96) { require(b <= a, "SafeMath: subtraction overflow"); uint96 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * - Multiplication cannot overflow. */ function mul(uint96 a, uint96 b) internal pure returns (uint96) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 if (a == 0) { return 0; } uint96 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint96 a, uint96 b) internal pure returns (uint96) { // Solidity only automatically asserts when dividing by 0 require(b > 0, "SafeMath: division by zero"); uint96 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod(uint96 a, uint96 b) internal pure returns (uint96) { require(b != 0, "SafeMath: modulo by zero"); return a % b; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; contract KeeperBase { /** * @notice method that allows it to be simulated via eth_call by checking that * the sender is the zero address. */ function preventExecution() internal view { require(tx.origin == address(0), "only for simulated backend"); } /** * @notice modifier that allows it to be simulated via eth_call by checking * that the sender is the zero address. */ modifier cannotExecute() { preventExecution(); _; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; import "./ConfirmedOwnerWithProposal.sol"; /** * @title The ConfirmedOwner contract * @notice A contract with helpers for basic contract ownership. */ contract ConfirmedOwner is ConfirmedOwnerWithProposal { constructor(address newOwner) ConfirmedOwnerWithProposal(newOwner, address(0)) {} }
// SPDX-License-Identifier: MIT // github.com/OpenZeppelin/openzeppelin-contracts@fa64a1ced0b70ab89073d5d0b6e01b0778f7e7d6 pragma solidity ^0.7.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 GSN 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 payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; import "./interfaces/OwnableInterface.sol"; /** * @title The ConfirmedOwner contract * @notice A contract with helpers for basic contract ownership. */ contract ConfirmedOwnerWithProposal is OwnableInterface { address private s_owner; address private s_pendingOwner; event OwnershipTransferRequested(address indexed from, address indexed to); event OwnershipTransferred(address indexed from, address indexed to); constructor(address newOwner, address pendingOwner) { require(newOwner != address(0), "Cannot set owner to zero"); s_owner = newOwner; if (pendingOwner != address(0)) { _transferOwnership(pendingOwner); } } /** * @notice Allows an owner to begin transferring ownership to a new address, * pending. */ function transferOwnership(address to) public override onlyOwner { _transferOwnership(to); } /** * @notice Allows an ownership transfer to be completed by the recipient. */ function acceptOwnership() external override { require(msg.sender == s_pendingOwner, "Must be proposed owner"); address oldOwner = s_owner; s_owner = msg.sender; s_pendingOwner = address(0); emit OwnershipTransferred(oldOwner, msg.sender); } /** * @notice Get the current owner */ function owner() public view override returns (address) { return s_owner; } /** * @notice validate, transfer ownership, and emit relevant events */ function _transferOwnership(address to) private { require(to != msg.sender, "Cannot transfer to self"); s_pendingOwner = to; emit OwnershipTransferRequested(s_owner, to); } /** * @notice validate access */ function _validateOwnership() internal view { require(msg.sender == s_owner, "Only callable by owner"); } /** * @notice Reverts if called by anyone other than the contract owner. */ modifier onlyOwner() { _validateOwnership(); _; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0; interface OwnableInterface { function owner() external returns (address); function transferOwnership(address recipient) external; function acceptOwnership() external; }
{ "optimizer": { "enabled": true, "runs": 1000000 }, "metadata": { "bytecodeHash": "none", "useLiteralContent": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"link","type":"address"},{"internalType":"address","name":"linkEthFeed","type":"address"},{"internalType":"address","name":"fastGasFeed","type":"address"},{"internalType":"uint32","name":"paymentPremiumPPB","type":"uint32"},{"internalType":"uint32","name":"flatFeeMicroLink","type":"uint32"},{"internalType":"uint24","name":"blockCountPerTurn","type":"uint24"},{"internalType":"uint32","name":"checkGasLimit","type":"uint32"},{"internalType":"uint24","name":"stalenessSeconds","type":"uint24"},{"internalType":"uint16","name":"gasCeilingMultiplier","type":"uint16"},{"internalType":"uint256","name":"fallbackGasPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackLinkPrice","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"paymentPremiumPPB","type":"uint32"},{"indexed":false,"internalType":"uint24","name":"blockCountPerTurn","type":"uint24"},{"indexed":false,"internalType":"uint32","name":"checkGasLimit","type":"uint32"},{"indexed":false,"internalType":"uint24","name":"stalenessSeconds","type":"uint24"},{"indexed":false,"internalType":"uint16","name":"gasCeilingMultiplier","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"fallbackGasPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fallbackLinkPrice","type":"uint256"}],"name":"ConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"flatFeeMicroLink","type":"uint32"}],"name":"FlatFeeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint96","name":"amount","type":"uint96"}],"name":"FundsAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"to","type":"address"}],"name":"FundsWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"keepers","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"payees","type":"address[]"}],"name":"KeepersUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"OwnershipTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"keeper","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"PayeeshipTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"keeper","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"PayeeshipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"keeper","type":"address"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"address","name":"payee","type":"address"}],"name":"PaymentWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"RegistrarChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"uint64","name":"atBlockHeight","type":"uint64"}],"name":"UpkeepCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"bool","name":"success","type":"bool"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint96","name":"payment","type":"uint96"},{"indexed":false,"internalType":"bytes","name":"performData","type":"bytes"}],"name":"UpkeepPerformed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint32","name":"executeGas","type":"uint32"},{"indexed":false,"internalType":"address","name":"admin","type":"address"}],"name":"UpkeepRegistered","type":"event"},{"inputs":[],"name":"FAST_GAS_FEED","outputs":[{"internalType":"contract AggregatorV3Interface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LINK","outputs":[{"internalType":"contract LinkTokenInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LINK_ETH_FEED","outputs":[{"internalType":"contract AggregatorV3Interface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"keeper","type":"address"}],"name":"acceptPayeeship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint96","name":"amount","type":"uint96"}],"name":"addFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"cancelUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"from","type":"address"}],"name":"checkUpkeep","outputs":[{"internalType":"bytes","name":"performData","type":"bytes"},{"internalType":"uint256","name":"maxLinkPayment","type":"uint256"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"uint256","name":"adjustedGasWei","type":"uint256"},{"internalType":"uint256","name":"linkEth","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getCanceledUpkeepList","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getConfig","outputs":[{"internalType":"uint32","name":"paymentPremiumPPB","type":"uint32"},{"internalType":"uint24","name":"blockCountPerTurn","type":"uint24"},{"internalType":"uint32","name":"checkGasLimit","type":"uint32"},{"internalType":"uint24","name":"stalenessSeconds","type":"uint24"},{"internalType":"uint16","name":"gasCeilingMultiplier","type":"uint16"},{"internalType":"uint256","name":"fallbackGasPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackLinkPrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFlatFee","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"query","type":"address"}],"name":"getKeeperInfo","outputs":[{"internalType":"address","name":"payee","type":"address"},{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint96","name":"balance","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getKeeperList","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"gasLimit","type":"uint256"}],"name":"getMaxPaymentForGas","outputs":[{"internalType":"uint96","name":"maxPayment","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getMinBalanceForUpkeep","outputs":[{"internalType":"uint96","name":"minBalance","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRegistrar","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getUpkeep","outputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint32","name":"executeGas","type":"uint32"},{"internalType":"bytes","name":"checkData","type":"bytes"},{"internalType":"uint96","name":"balance","type":"uint96"},{"internalType":"address","name":"lastKeeper","type":"address"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"uint64","name":"maxValidBlocknumber","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getUpkeepCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onTokenTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"performData","type":"bytes"}],"name":"performUpkeep","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"recoverFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint32","name":"gasLimit","type":"uint32"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"bytes","name":"checkData","type":"bytes"}],"name":"registerUpkeep","outputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"paymentPremiumPPB","type":"uint32"},{"internalType":"uint32","name":"flatFeeMicroLink","type":"uint32"},{"internalType":"uint24","name":"blockCountPerTurn","type":"uint24"},{"internalType":"uint32","name":"checkGasLimit","type":"uint32"},{"internalType":"uint24","name":"stalenessSeconds","type":"uint24"},{"internalType":"uint16","name":"gasCeilingMultiplier","type":"uint16"},{"internalType":"uint256","name":"fallbackGasPrice","type":"uint256"},{"internalType":"uint256","name":"fallbackLinkPrice","type":"uint256"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"keepers","type":"address[]"},{"internalType":"address[]","name":"payees","type":"address[]"}],"name":"setKeepers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"registrar","type":"address"}],"name":"setRegistrar","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"keeper","type":"address"},{"internalType":"address","name":"proposed","type":"address"}],"name":"transferPayeeship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"typeAndVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"withdrawFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"withdrawPayment","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60e06040523480156200001157600080fd5b50604051620052493803806200524983398181016040526101608110156200003857600080fd5b508051602082015160408301516060840151608085015160a086015160c087015160e08801516101008901516101208a0151610140909a0151989997989697959694959394929391929091903380600081620000db576040805162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f0000000000000000604482015290519081900360640190fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156200010e576200010e8162000165565b50506001600255506003805460ff191690556001600160601b031960608c811b82166080528b811b821660a0528a901b1660c05262000154888888888888888862000215565b505050505050505050505062000487565b6001600160a01b038116331415620001c4576040805162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015290519081900360640190fd5b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6200021f62000425565b6040518060c001604052808963ffffffff1681526020018863ffffffff1681526020018762ffffff1681526020018663ffffffff1681526020018562ffffff1681526020018461ffff16815250600b60008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160086101000a81548162ffffff021916908362ffffff160217905550606082015181600001600b6101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600f6101000a81548162ffffff021916908362ffffff16021790555060a08201518160000160126101000a81548161ffff021916908361ffff16021790555090505081600c8190555080600d819055507feb3c06937e6595fd80ec1add18a195026d5cf65f122cc3ffedbfb18a9ed80b3988878787878787604051808863ffffffff1681526020018762ffffff1681526020018663ffffffff1681526020018562ffffff1681526020018461ffff16815260200183815260200182815260200197505050505050505060405180910390a16040805163ffffffff8916815290517f17b46a44a823646eef686b7824df2962de896bc9a012a60b67694c5cbf184d8b9181900360200190a15050505050505050565b6000546001600160a01b0316331462000485576040805162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b565b60805160601c60a05160601c60c05160601c614d64620004e560003980610d0052806140085250806119eb52806140db525080610bf55280610fa652806113a2528061147752806119485280611b825280611c505250614d646000f3fe608060405234801561001057600080fd5b50600436106102265760003560e01c8063a4c0ed361161012a578063c41b813a116100bd578063db30a3861161008c578063f2fde38b11610071578063f2fde38b14610add578063faab9d3914610b10578063fecf27c914610b4357610226565b8063db30a38614610a41578063eb5dcd6c14610aa257610226565b8063c41b813a14610784578063c7c3a19a14610851578063c804802214610970578063da5c67411461098d57610226565b8063b657bc9c116100f9578063b657bc9c14610645578063b79550be14610662578063b7fdb4361461066a578063c3f909d41461072c57610226565b8063a4c0ed361461053d578063a710b221146105cf578063ad1783611461060a578063b121e1471461061257610226565b80635c975abb116101bd5780638456cb591161018c5780638da5cb5b116101715780638da5cb5b146104c657806393f0c1fc146104ce578063948108f71461050c57610226565b80638456cb591461049d5780638a601fc8146104a557610226565b80635c975abb146103c9578063744bfe61146103e557806379ba50971461041e5780637bbaf1ea1461042657610226565b80632cb6864d116101f95780632cb6864d146103a75780633f4ba83a146103af5780634584a419146103b95780634d3f7334146103c157610226565b806315a126ea1461022b578063181f5a77146102835780631b6b6d23146103005780631e12b8a514610331575b600080fd5b610233610b4b565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561026f578181015183820152602001610257565b505050509050019250505060405180910390f35b61028b610bba565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102c55781810151838201526020016102ad565b50505050905090810190601f1680156102f25780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610308610bf3565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6103646004803603602081101561034757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610c17565b6040805173ffffffffffffffffffffffffffffffffffffffff909416845291151560208401526bffffffffffffffffffffffff1682820152519081900360600190f35b610233610c95565b6103b7610cec565b005b610308610cfe565b610308610d22565b6103d1610d3e565b604080519115158252519081900360200190f35b6103b7600480360360408110156103fb57600080fd5b508035906020013573ffffffffffffffffffffffffffffffffffffffff16610d47565b6103b7611067565b6103d16004803603604081101561043c57600080fd5b8135919081019060408101602082013564010000000081111561045e57600080fd5b82018360208201111561047057600080fd5b8035906020019184600183028401116401000000008311171561049257600080fd5b509092509050611169565b6103b76111bf565b6104ad6111cf565b6040805163ffffffff9092168252519081900360200190f35b6103086111e3565b6104eb600480360360208110156104e457600080fd5b50356111ff565b604080516bffffffffffffffffffffffff9092168252519081900360200190f35b6103b76004803603604081101561052257600080fd5b50803590602001356bffffffffffffffffffffffff16611235565b6103b76004803603606081101561055357600080fd5b73ffffffffffffffffffffffffffffffffffffffff8235169160208101359181019060608101604082013564010000000081111561059057600080fd5b8201836020820111156105a257600080fd5b803590602001918460018302840111640100000000831117156105c457600080fd5b50909250905061145f565b6103b7600480360360408110156105e557600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166116fb565b6103086119e9565b6103b76004803603602081101561062857600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611a0d565b6104eb6004803603602081101561065b57600080fd5b5035611b3a565b6103b7611b76565b6103b76004803603604081101561068057600080fd5b81019060208101813564010000000081111561069b57600080fd5b8201836020820111156106ad57600080fd5b803590602001918460208302840111640100000000831117156106cf57600080fd5b9193909290916020810190356401000000008111156106ed57600080fd5b8201836020820111156106ff57600080fd5b8035906020019184602083028401116401000000008311171561072157600080fd5b509092509050611d06565b610734612223565b6040805163ffffffff988916815262ffffff9788166020820152959097168588015292909416606084015261ffff16608083015260a082019290925260c081019190915290519081900360e00190f35b6107bd6004803603604081101561079a57600080fd5b508035906020013573ffffffffffffffffffffffffffffffffffffffff166122cc565b6040518080602001868152602001858152602001848152602001838152602001828103825287818151815260200191508051906020019080838360005b838110156108125781810151838201526020016107fa565b50505050905090810190601f16801561083f5780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390f35b61086e6004803603602081101561086757600080fd5b503561296b565b604051808873ffffffffffffffffffffffffffffffffffffffff1681526020018763ffffffff16815260200180602001866bffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018367ffffffffffffffff168152602001828103825287818151815260200191508051906020019080838360005b8381101561092f578181015183820152602001610917565b50505050905090810190601f16801561095c5780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390f35b6103b76004803603602081101561098657600080fd5b5035612b14565b610a2f600480360360808110156109a357600080fd5b73ffffffffffffffffffffffffffffffffffffffff823581169263ffffffff602082013516926040820135909216918101906080810160608201356401000000008111156109f057600080fd5b820183602082011115610a0257600080fd5b80359060200191846001830284011164010000000083111715610a2457600080fd5b509092509050612d75565b60408051918252519081900360200190f35b6103b76004803603610100811015610a5857600080fd5b5063ffffffff8135811691602081013582169162ffffff604083013581169260608101359092169160808101359091169061ffff60a0820135169060c08101359060e001356131c1565b6103b760048036036040811015610ab857600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166133cf565b6103b760048036036020811015610af357600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16613599565b6103b760048036036020811015610b2657600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166135ad565b610a2f61375c565b60606006805480602002602001604051908101604052809291908181526020018280548015610bb057602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610b85575b5050505050905090565b6040518060400160405280601481526020017f4b6565706572526567697374727920312e312e3000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b73ffffffffffffffffffffffffffffffffffffffff90811660009081526008602090815260409182902082516060810184528154948516808252740100000000000000000000000000000000000000009095046bffffffffffffffffffffffff1692810183905260019091015460ff16151592018290529192909190565b60606005805480602002602001604051908101604052809291908181526020018280548015610bb057602002820191906000526020600020905b815481526020019060010190808311610ccf575050505050905090565b610cf4613762565b610cfc6137e8565b565b7f000000000000000000000000000000000000000000000000000000000000000081565b600f5473ffffffffffffffffffffffffffffffffffffffff1690565b60035460ff1690565b8073ffffffffffffffffffffffffffffffffffffffff8116610dca57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f63616e6e6f742073656e6420746f207a65726f20616464726573730000000000604482015290519081900360640190fd5b6000838152600760205260409020600101546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff163314610e6f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f6f6e6c792063616c6c61626c652062792061646d696e00000000000000000000604482015290519081900360640190fd5b6000838152600760205260409020600201544367ffffffffffffffff9091161115610efb57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f75706b656570206d7573742062652063616e63656c6564000000000000000000604482015290519081900360640190fd5b600083815260076020526040902060010180547fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008116909155600e546bffffffffffffffffffffffff90911690610f5290826138d6565b600e556040805182815273ffffffffffffffffffffffffffffffffffffffff85166020820152815186927ff3b5906e5672f3e524854103bcafbbdba80dbdfeca2c35e116127b1060a68318928290030190a27f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561103557600080fd5b505af1158015611049573d6000803e3d6000fd5b505050506040513d602081101561105f57600080fd5b505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146110ed57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015290519081900360640190fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60006111b76111b2338686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506001925061394d915050565b613a0e565b949350505050565b6111c7613762565b610cfc613f0d565b600b54640100000000900463ffffffff1690565b60005473ffffffffffffffffffffffffffffffffffffffff1690565b600080600061120c613fd5565b91509150600061121d8360006141b4565b905061122a8582846141fa565b93505050505b919050565b60008281526007602052604090206002015467ffffffffffffffff908116146112bf57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f75706b656570206d757374206265206163746976650000000000000000000000604482015290519081900360640190fd5b6000828152600760205260409020600101546112e9906bffffffffffffffffffffffff16826143a9565b600083815260076020526040902060010180547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff928316179055600e5461133f918316614435565b600e55604080517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201523060248201526bffffffffffffffffffffffff83166044820152905173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016916323b872dd9160648083019260209291908290030181600087803b1580156113ea57600080fd5b505af11580156113fe573d6000803e3d6000fd5b505050506040513d602081101561141457600080fd5b5050604080516bffffffffffffffffffffffff831681529051339184917fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa7348915062039181900360200190a35050565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461150357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f6f6e6c792063616c6c61626c65207468726f756768204c494e4b000000000000604482015290519081900360640190fd5b6020811461157257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f64617461206d7573742062652033322062797465730000000000000000000000604482015290519081900360640190fd5b60008282602081101561158457600080fd5b503560008181526007602052604090206002015490915067ffffffffffffffff9081161461161357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f75706b656570206d757374206265206163746976650000000000000000000000604482015290519081900360640190fd5b60008181526007602052604090206001015461163d906bffffffffffffffffffffffff16856143a9565b600082815260076020526040902060010180547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff92909216919091179055600e546116969085614435565b600e55604080516bffffffffffffffffffffffff86168152905173ffffffffffffffffffffffffffffffffffffffff87169183917fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa7348915062039181900360200190a35050505050565b8073ffffffffffffffffffffffffffffffffffffffff811661177e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f63616e6e6f742073656e6420746f207a65726f20616464726573730000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff83811660009081526008602090815260409182902082516060810184528154948516808252740100000000000000000000000000000000000000009095046bffffffffffffffffffffffff16928101929092526001015460ff1615159181019190915290331461186457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f6f6e6c792063616c6c61626c6520627920706179656500000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff80851660009081526008602090815260409091208054909216909155810151600e546118b2916bffffffffffffffffffffffff166138d6565b600e819055508273ffffffffffffffffffffffffffffffffffffffff1681602001516bffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f9819093176a1851202c7bcfa46845809b4e47c261866550e94ed3775d2f4069833604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a47f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8483602001516040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff168152602001826bffffffffffffffffffffffff16815260200192505050602060405180830381600087803b15801561103557600080fd5b7f000000000000000000000000000000000000000000000000000000000000000081565b73ffffffffffffffffffffffffffffffffffffffff818116600090815260096020526040902054163314611aa257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f6f6e6c792063616c6c61626c652062792070726f706f73656420706179656500604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff81811660008181526008602090815260408083208054337fffffffffffffffffffffffff000000000000000000000000000000000000000080831682179093556009909452828520805490921690915590519416939092849290917f78af32efdcad432315431e9b03d27e6cd98fb79c405fdc5af7c1714d9c0f75b39190a45050565b600081815260076020526040812054611b709074010000000000000000000000000000000000000000900463ffffffff166111ff565b92915050565b611b7e613762565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611c0757600080fd5b505afa158015611c1b573d6000803e3d6000fd5b505050506040513d6020811015611c3157600080fd5b5051600e5490915073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb903390611c849085906138d6565b6040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015611cd757600080fd5b505af1158015611ceb573d6000803e3d6000fd5b505050506040513d6020811015611d0157600080fd5b505050565b611d0e613762565b828114611d66576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180614d376021913960400191505060405180910390fd5b6002831015611dd657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6e6f7420656e6f756768206b6565706572730000000000000000000000000000604482015290519081900360640190fd5b60005b600654811015611e5657600060068281548110611df257fe5b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff1682526008905260409020600190810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055919091019050611dd9565b5060005b83811015612140576000858583818110611e7057fe5b73ffffffffffffffffffffffffffffffffffffffff6020918202939093013583166000818152600890925260408220805491955093169150868686818110611eb457fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611f59576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180614ccf6024913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82161580611fa757508073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b80611fc7575073ffffffffffffffffffffffffffffffffffffffff818116145b61203257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f63616e6e6f74206368616e676520706179656500000000000000000000000000604482015290519081900360640190fd5b600183015460ff16156120a657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f63616e6e6f7420616464206b6565706572207477696365000000000000000000604482015290519081900360640190fd5b600183810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016909117905573ffffffffffffffffffffffffffffffffffffffff818116146121305782547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff82161783555b505060019092019150611e5a9050565b5061214d60068585614b44565b507f056264c94f28bb06c99d13f0446eb96c67c215d8d707bce2655a98ddf1c0b71f848484846040518080602001806020018381038352878782818152602001925060200280828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169091018481038352858152602090810191508690860280828437600083820152604051601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018290039850909650505050505050a150505050565b6040805160c081018252600b5463ffffffff80821680845264010000000083048216602085015268010000000000000000830462ffffff9081169585018690526b0100000000000000000000008404909216606085018190526f01000000000000000000000000000000840490921660808501819052720100000000000000000000000000000000000090930461ffff1660a0909401849052600c54600d549196929492909190565b60606000806000806122dc610d3e565b1561234857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015290519081900360640190fd5b6123506144a9565b6000878152600760209081526040808320815160c081018352815473ffffffffffffffffffffffffffffffffffffffff80821683527401000000000000000000000000000000000000000090910463ffffffff16828601526001808401546bffffffffffffffffffffffff8116848701526c0100000000000000000000000090048216606084015260029384015467ffffffffffffffff8116608085015268010000000000000000900490911660a08301528c8652600a8552838620935160248101958652845461010092811615929092027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190911692909204604483018190529094937f6e04ff0d0000000000000000000000000000000000000000000000000000000093929091829160640190849080156124cf5780601f106124a4576101008083540402835291602001916124cf565b820191906000526020600020905b8154815290600101906020018083116124b257829003601f168201915b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009097169690961786528751600b549151835193985060009788975073ffffffffffffffffffffffffffffffffffffffff909216955063ffffffff6b01000000000000000000000090930492909216935087928291908083835b602083106125da57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161259d565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038160008787f1925050503d806000811461263d576040519150601f19603f3d011682016040523d82523d6000602084013e612642565b606091505b5091509150816127dd57600061265782614516565b905060008160405160200180807f63616c6c20746f20636865636b20746172676574206661696c65643a20000000815250601d0182805190602001908083835b602083106126d457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101612697565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905260408051929094018281037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018352938490527f08c379a00000000000000000000000000000000000000000000000000000000084526004840181815282516024860152825192975087965094508493604401925085019080838360005b838110156127a257818101518382015260200161278a565b50505050905090810190601f1680156127cf5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b8080602001905160408110156127f257600080fd5b81516020830180516040519294929383019291908464010000000082111561281957600080fd5b90830190602082018581111561282e57600080fd5b825164010000000081118282018810171561284857600080fd5b82525081516020918201929091019080838360005b8381101561287557818101518382015260200161285d565b50505050905090810190601f1680156128a25780820380516001836020036101000a031916815260200191505b50604052505050809a5081935050508161291d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f75706b656570206e6f74206e6565646564000000000000000000000000000000604482015290519081900360640190fd5b600061292c8b8d8c600061394d565b9050612941858260000151836060015161462d565b6060810151608082015160a083015160c0909301519b9e919d509b50909998509650505050505050565b6000818152600760209081526040808320815160c081018352815473ffffffffffffffffffffffffffffffffffffffff8082168084527401000000000000000000000000000000000000000090920463ffffffff168387018190526001808601546bffffffffffffffffffffffff81168689019081526c010000000000000000000000009091048416606080880191825260029889015467ffffffffffffffff811660808a019081526801000000000000000090910490961660a089019081528d8d52600a8c528a8d20935190519251965184548c5161010097821615979097027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01169a909a04601f81018d90048d0286018d01909b528a85528c9b919a8c9a8b9a8b9a8b9a91999098909796949591939091879190830182828015612af35780601f10612ac857610100808354040283529160200191612af3565b820191906000526020600020905b815481529060010190602001808311612ad657829003601f168201915b50505050509450975097509750975097509750975050919395979092949650565b60008181526007602052604081206002015467ffffffffffffffff9081169190821490612b3f6111e3565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161490508180612b8c5750808015612b8c5750438367ffffffffffffffff16115b612bf757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f746f6f206c61746520746f2063616e63656c2075706b65657000000000000000604482015290519081900360640190fd5b8080612c3957506000848152600760205260409020600101546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1633145b612ca457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f6f6e6c79206f776e6572206f722061646d696e00000000000000000000000000604482015290519081900360640190fd5b4381612cb857612cb5816032614435565b90505b600085815260076020526040902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83161790558215612d3757600580546001810182556000919091527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0018590555b60405167ffffffffffffffff82169086907f91cb3bb75cfbd718bbfccc56b7f53d92d7048ef4ca39a3b7b7c6d4af1f79118190600090a35050505050565b6000612d7f6111e3565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480612dcf5750600f5473ffffffffffffffffffffffffffffffffffffffff1633145b612e24576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180614cf36023913960400191505060405180910390fd5b612e438673ffffffffffffffffffffffffffffffffffffffff166147e4565b612eae57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f746172676574206973206e6f74206120636f6e74726163740000000000000000604482015290519081900360640190fd5b6108fc8563ffffffff161015612f2557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f6d696e2067617320697320323330300000000000000000000000000000000000604482015290519081900360640190fd5b624c4b408563ffffffff161115612f9d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6d61782067617320697320353030303030300000000000000000000000000000604482015290519081900360640190fd5b506004546040805160c08101825273ffffffffffffffffffffffffffffffffffffffff808916825263ffffffff808916602080850191825260008587018181528b86166060880190815267ffffffffffffffff6080890181815260a08a018581528c8652600787528b86209a518b54985190991674010000000000000000000000000000000000000000027fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff998b167fffffffffffffffffffffffff000000000000000000000000000000000000000090991698909817989098169690961789559151600189018054925189166c01000000000000000000000000026bffffffffffffffffffffffff9283167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000090941693909317909116919091179055925160029096018054945190951668010000000000000000027fffffffff0000000000000000000000000000000000000000ffffffffffffffff969093167fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909416939093179490941617909155600a90915220613159908484614bcc565b506004805460010190556040805163ffffffff8716815273ffffffffffffffffffffffffffffffffffffffff86166020820152815183927fbae366358c023f887e791d7a62f2e4316f1026bd77f6fb49501a917b3bc5d012928290030190a295945050505050565b6131c9613762565b6040518060c001604052808963ffffffff1681526020018863ffffffff1681526020018762ffffff1681526020018663ffffffff1681526020018562ffffff1681526020018461ffff16815250600b60008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160086101000a81548162ffffff021916908362ffffff160217905550606082015181600001600b6101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600f6101000a81548162ffffff021916908362ffffff16021790555060a08201518160000160126101000a81548161ffff021916908361ffff16021790555090505081600c8190555080600d819055507feb3c06937e6595fd80ec1add18a195026d5cf65f122cc3ffedbfb18a9ed80b3988878787878787604051808863ffffffff1681526020018762ffffff1681526020018663ffffffff1681526020018562ffffff1681526020018461ffff16815260200183815260200182815260200197505050505050505060405180910390a16040805163ffffffff8916815290517f17b46a44a823646eef686b7824df2962de896bc9a012a60b67694c5cbf184d8b9181900360200190a15050505050505050565b73ffffffffffffffffffffffffffffffffffffffff82811660009081526008602052604090205416331461346457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f6f6e6c792063616c6c61626c6520627920706179656500000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff81163314156134e957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f63616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8281166000908152600960205260409020548116908216146135955773ffffffffffffffffffffffffffffffffffffffff82811660008181526009602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169486169485179055513392917f84f7c7c80bb8ed2279b4aab5f61cd05e6374073d38f46d7f32de8c30e9e3836791a45b5050565b6135a1613762565b6135aa816147ea565b50565b6135b56111e3565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806136055750600f5473ffffffffffffffffffffffffffffffffffffffff1633145b61365a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180614cf36023913960400191505060405180910390fd5b600f5473ffffffffffffffffffffffffffffffffffffffff9081169082168114156136e657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f53616d6520726567697374726172000000000000000000000000000000000000604482015290519081900360640190fd5b600f80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84811691821790925560405190918316907f9bf4a5b30267728df68663e14adb47e559863967c419dc6030638883408bed2e90600090a35050565b60045490565b60005473ffffffffffffffffffffffffffffffffffffffff163314610cfc57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b6137f0610d3e565b61385b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f7420706175736564000000000000000000000000604482015290519081900360640190fd5b600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6138ac6148e5565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190a1565b60008282111561394757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b613955614c66565b60008481526007602052604081205474010000000000000000000000000000000000000000900463ffffffff16908061398c613fd5565b91509150600061399c83876141b4565b905060006139ab8583856141fa565b6040805160e08101825273ffffffffffffffffffffffffffffffffffffffff8d168152602081018c90529081018a90526bffffffffffffffffffffffff909116606082015260808101959095525060a084015260c0830152509050949350505050565b6000600280541415613a8157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600280556020820151613a93816148e9565b602083810151600090815260078252604090819020815160c081018352815473ffffffffffffffffffffffffffffffffffffffff80821683527401000000000000000000000000000000000000000090910463ffffffff169482019490945260018201546bffffffffffffffffffffffff8116938201939093526c01000000000000000000000000909204831660608084019190915260029091015467ffffffffffffffff8116608084015268010000000000000000900490921660a08201528451918501519091613b679183919061462d565b60005a90506000634585e33b60e01b86604001516040516024018080602001828103825283818151815260200191508051906020019080838360005b83811015613bbb578181015183820152602001613ba3565b50505050905090810190601f168015613be85780820380516001836020036101000a031916815260200191505b50604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009096169590951790945250505060808701518451919250613c7d9183614974565b94505a820391506000613c99838860a001518960c001516141fa565b60208089015160009081526007909152604081206001015491925090613ccd906bffffffffffffffffffffffff16836149c0565b60208981018051600090815260078352604080822060010180547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff878116919091179091558d519351835281832060020180547fffffffff0000000000000000000000000000000000000000ffffffffffffffff166801000000000000000073ffffffffffffffffffffffffffffffffffffffff968716021790558d5190931682526008909352918220549293509091613daf917401000000000000000000000000000000000000000090910416846143a9565b905080600860008b6000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550886000015173ffffffffffffffffffffffffffffffffffffffff168815158a602001517fcaacad83e47cc45c280d487ec84184eee2fa3b54ebaa393bda7549f13da228f6868d6040015160405180836bffffffffffffffffffffffff16815260200180602001828103825283818151815260200191508051906020019080838360005b83811015613ec1578181015183820152602001613ea9565b50505050905090810190601f168015613eee5780820380516001836020036101000a031916815260200191505b50935050505060405180910390a4505050505050506001600255919050565b613f15610d3e565b15613f8157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015290519081900360640190fd5b600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586138ac6148e5565b6000806000600b600001600f9054906101000a900462ffffff1662ffffff1690506000808263ffffffff161190506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a06040518083038186803b15801561406c57600080fd5b505afa158015614080573d6000803e3d6000fd5b505050506040513d60a081101561409657600080fd5b506020810151606090910151925090508280156140ba57508142038463ffffffff16105b806140c6575060008113155b156140d557600c5495506140d9565b8095505b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a06040518083038186803b15801561413f57600080fd5b505afa158015614153573d6000803e3d6000fd5b505050506040513d60a081101561416957600080fd5b5060208101516060909101519250905082801561418d57508142038463ffffffff16105b80614199575060008113155b156141a857600d5494506141ac565b8094505b505050509091565b600b546000906141df9084907201000000000000000000000000000000000000900461ffff16614a4d565b90508180156141ed5750803a105b15611b7057503a92915050565b6040805160c081018252600b5463ffffffff808216835264010000000082048116602084015262ffffff6801000000000000000083048116948401949094526b0100000000000000000000008204811660608401526f010000000000000000000000000000008204909316608083015261ffff72010000000000000000000000000000000000009091041660a082015260009182906142ab906142a4908890620138809061443516565b8690614a4d565b905060006142d0836000015163ffffffff16633b9aca0061443590919063ffffffff16565b905060006143216142f964e8d4a51000866020015163ffffffff16614a4d90919063ffffffff16565b61431b886143158661430f89633b9aca00614a4d565b90614a4d565b90614ac0565b90614435565b90506b033b2e3c9fd0803ce800000081111561439e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f7061796d656e742067726561746572207468616e20616c6c204c494e4b000000604482015290519081900360640190fd5b979650505050505050565b60008282016bffffffffffffffffffffffff808516908216101561442e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b60008282018381101561442e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b3215610cfc57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f6f6e6c7920666f722073696d756c61746564206261636b656e64000000000000604482015290519081900360640190fd5b606060448251101561455c575060408051808201909152601d81527f7472616e73616374696f6e2072657665727465642073696c656e746c790000006020820152611230565b600482018051909260240190602081101561457657600080fd5b810190808051604051939291908464010000000082111561459657600080fd5b9083019060208201858111156145ab57600080fd5b82516401000000008111828201881017156145c557600080fd5b82525081516020918201929091019080838360005b838110156145f25781810151838201526020016145da565b50505050905090810190601f16801561461f5780820380516001836020036101000a031916815260200191505b506040525050509050919050565b73ffffffffffffffffffffffffffffffffffffffff821660009081526008602052604090206001015460ff166146c457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f6f6e6c7920616374697665206b65657065727300000000000000000000000000604482015290519081900360640190fd5b8083604001516bffffffffffffffffffffffff16101561474557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f696e73756666696369656e742066756e64730000000000000000000000000000604482015290519081900360640190fd5b8173ffffffffffffffffffffffffffffffffffffffff168360a0015173ffffffffffffffffffffffffffffffffffffffff161415611d0157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f6b656570657273206d7573742074616b65207475726e73000000000000000000604482015290519081900360640190fd5b3b151590565b73ffffffffffffffffffffffffffffffffffffffff811633141561486f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015290519081900360640190fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b3390565b6000818152600760205260409020600201544367ffffffffffffffff909116116135aa57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f696e76616c69642075706b656570206964000000000000000000000000000000604482015290519081900360640190fd5b60005a61138881101561498657600080fd5b61138881039050846040820482031161499e57600080fd5b50823b6149aa57600080fd5b60008083516020850160008789f1949350505050565b6000826bffffffffffffffffffffffff16826bffffffffffffffffffffffff16111561394757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b600082614a5c57506000611b70565b82820282848281614a6957fe5b041461442e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180614d166021913960400191505060405180910390fd5b6000808211614b3057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b6000828481614b3b57fe5b04949350505050565b828054828255906000526020600020908101928215614bbc579160200282015b82811115614bbc5781547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff843516178255602090920191600190910190614b64565b50614bc8929150614cb9565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282614c025760008555614bbc565b82601f10614c39578280017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00823516178555614bbc565b82800160010185558215614bbc579182015b82811115614bbc578235825591602001919060010190614c4b565b6040518060e00160405280600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160608152602001600081526020016000815260200160008152602001600081525090565b5b80821115614bc85760008155600101614cba56fe63616e6e6f742073657420706179656520746f20746865207a65726f20616464726573734f6e6c792063616c6c61626c65206279206f776e6572206f7220726567697374726172536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7761646472657373206c69737473206e6f74207468652073616d65206c656e677468a164736f6c6343000706000a0000000000000000000000006f43ff82cca38001b6699a8ac47a2d0e669394070000000000000000000000003ffe75e8eda86f48e454e6bfb5f74d95c20744f4000000000000000000000000b71eb5cabce02d55d1fac0e26c5745e704b610210000000000000000000000000000000000000000000000000000000029b92700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000632ea00000000000000000000000000000000000000000000000000000000000015f9000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000015d3ef798000000000000000000000000000000000000000000000000008ac7230489e80000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102265760003560e01c8063a4c0ed361161012a578063c41b813a116100bd578063db30a3861161008c578063f2fde38b11610071578063f2fde38b14610add578063faab9d3914610b10578063fecf27c914610b4357610226565b8063db30a38614610a41578063eb5dcd6c14610aa257610226565b8063c41b813a14610784578063c7c3a19a14610851578063c804802214610970578063da5c67411461098d57610226565b8063b657bc9c116100f9578063b657bc9c14610645578063b79550be14610662578063b7fdb4361461066a578063c3f909d41461072c57610226565b8063a4c0ed361461053d578063a710b221146105cf578063ad1783611461060a578063b121e1471461061257610226565b80635c975abb116101bd5780638456cb591161018c5780638da5cb5b116101715780638da5cb5b146104c657806393f0c1fc146104ce578063948108f71461050c57610226565b80638456cb591461049d5780638a601fc8146104a557610226565b80635c975abb146103c9578063744bfe61146103e557806379ba50971461041e5780637bbaf1ea1461042657610226565b80632cb6864d116101f95780632cb6864d146103a75780633f4ba83a146103af5780634584a419146103b95780634d3f7334146103c157610226565b806315a126ea1461022b578063181f5a77146102835780631b6b6d23146103005780631e12b8a514610331575b600080fd5b610233610b4b565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561026f578181015183820152602001610257565b505050509050019250505060405180910390f35b61028b610bba565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102c55781810151838201526020016102ad565b50505050905090810190601f1680156102f25780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610308610bf3565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6103646004803603602081101561034757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610c17565b6040805173ffffffffffffffffffffffffffffffffffffffff909416845291151560208401526bffffffffffffffffffffffff1682820152519081900360600190f35b610233610c95565b6103b7610cec565b005b610308610cfe565b610308610d22565b6103d1610d3e565b604080519115158252519081900360200190f35b6103b7600480360360408110156103fb57600080fd5b508035906020013573ffffffffffffffffffffffffffffffffffffffff16610d47565b6103b7611067565b6103d16004803603604081101561043c57600080fd5b8135919081019060408101602082013564010000000081111561045e57600080fd5b82018360208201111561047057600080fd5b8035906020019184600183028401116401000000008311171561049257600080fd5b509092509050611169565b6103b76111bf565b6104ad6111cf565b6040805163ffffffff9092168252519081900360200190f35b6103086111e3565b6104eb600480360360208110156104e457600080fd5b50356111ff565b604080516bffffffffffffffffffffffff9092168252519081900360200190f35b6103b76004803603604081101561052257600080fd5b50803590602001356bffffffffffffffffffffffff16611235565b6103b76004803603606081101561055357600080fd5b73ffffffffffffffffffffffffffffffffffffffff8235169160208101359181019060608101604082013564010000000081111561059057600080fd5b8201836020820111156105a257600080fd5b803590602001918460018302840111640100000000831117156105c457600080fd5b50909250905061145f565b6103b7600480360360408110156105e557600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166116fb565b6103086119e9565b6103b76004803603602081101561062857600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611a0d565b6104eb6004803603602081101561065b57600080fd5b5035611b3a565b6103b7611b76565b6103b76004803603604081101561068057600080fd5b81019060208101813564010000000081111561069b57600080fd5b8201836020820111156106ad57600080fd5b803590602001918460208302840111640100000000831117156106cf57600080fd5b9193909290916020810190356401000000008111156106ed57600080fd5b8201836020820111156106ff57600080fd5b8035906020019184602083028401116401000000008311171561072157600080fd5b509092509050611d06565b610734612223565b6040805163ffffffff988916815262ffffff9788166020820152959097168588015292909416606084015261ffff16608083015260a082019290925260c081019190915290519081900360e00190f35b6107bd6004803603604081101561079a57600080fd5b508035906020013573ffffffffffffffffffffffffffffffffffffffff166122cc565b6040518080602001868152602001858152602001848152602001838152602001828103825287818151815260200191508051906020019080838360005b838110156108125781810151838201526020016107fa565b50505050905090810190601f16801561083f5780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390f35b61086e6004803603602081101561086757600080fd5b503561296b565b604051808873ffffffffffffffffffffffffffffffffffffffff1681526020018763ffffffff16815260200180602001866bffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018367ffffffffffffffff168152602001828103825287818151815260200191508051906020019080838360005b8381101561092f578181015183820152602001610917565b50505050905090810190601f16801561095c5780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390f35b6103b76004803603602081101561098657600080fd5b5035612b14565b610a2f600480360360808110156109a357600080fd5b73ffffffffffffffffffffffffffffffffffffffff823581169263ffffffff602082013516926040820135909216918101906080810160608201356401000000008111156109f057600080fd5b820183602082011115610a0257600080fd5b80359060200191846001830284011164010000000083111715610a2457600080fd5b509092509050612d75565b60408051918252519081900360200190f35b6103b76004803603610100811015610a5857600080fd5b5063ffffffff8135811691602081013582169162ffffff604083013581169260608101359092169160808101359091169061ffff60a0820135169060c08101359060e001356131c1565b6103b760048036036040811015610ab857600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166133cf565b6103b760048036036020811015610af357600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16613599565b6103b760048036036020811015610b2657600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166135ad565b610a2f61375c565b60606006805480602002602001604051908101604052809291908181526020018280548015610bb057602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610b85575b5050505050905090565b6040518060400160405280601481526020017f4b6565706572526567697374727920312e312e3000000000000000000000000081525081565b7f0000000000000000000000006f43ff82cca38001b6699a8ac47a2d0e6693940781565b73ffffffffffffffffffffffffffffffffffffffff90811660009081526008602090815260409182902082516060810184528154948516808252740100000000000000000000000000000000000000009095046bffffffffffffffffffffffff1692810183905260019091015460ff16151592018290529192909190565b60606005805480602002602001604051908101604052809291908181526020018280548015610bb057602002820191906000526020600020905b815481526020019060010190808311610ccf575050505050905090565b610cf4613762565b610cfc6137e8565b565b7f000000000000000000000000b71eb5cabce02d55d1fac0e26c5745e704b6102181565b600f5473ffffffffffffffffffffffffffffffffffffffff1690565b60035460ff1690565b8073ffffffffffffffffffffffffffffffffffffffff8116610dca57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f63616e6e6f742073656e6420746f207a65726f20616464726573730000000000604482015290519081900360640190fd5b6000838152600760205260409020600101546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff163314610e6f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f6f6e6c792063616c6c61626c652062792061646d696e00000000000000000000604482015290519081900360640190fd5b6000838152600760205260409020600201544367ffffffffffffffff9091161115610efb57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f75706b656570206d7573742062652063616e63656c6564000000000000000000604482015290519081900360640190fd5b600083815260076020526040902060010180547fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008116909155600e546bffffffffffffffffffffffff90911690610f5290826138d6565b600e556040805182815273ffffffffffffffffffffffffffffffffffffffff85166020820152815186927ff3b5906e5672f3e524854103bcafbbdba80dbdfeca2c35e116127b1060a68318928290030190a27f0000000000000000000000006f43ff82cca38001b6699a8ac47a2d0e6693940773ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561103557600080fd5b505af1158015611049573d6000803e3d6000fd5b505050506040513d602081101561105f57600080fd5b505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146110ed57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015290519081900360640190fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60006111b76111b2338686868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506001925061394d915050565b613a0e565b949350505050565b6111c7613762565b610cfc613f0d565b600b54640100000000900463ffffffff1690565b60005473ffffffffffffffffffffffffffffffffffffffff1690565b600080600061120c613fd5565b91509150600061121d8360006141b4565b905061122a8582846141fa565b93505050505b919050565b60008281526007602052604090206002015467ffffffffffffffff908116146112bf57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f75706b656570206d757374206265206163746976650000000000000000000000604482015290519081900360640190fd5b6000828152600760205260409020600101546112e9906bffffffffffffffffffffffff16826143a9565b600083815260076020526040902060010180547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff928316179055600e5461133f918316614435565b600e55604080517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201523060248201526bffffffffffffffffffffffff83166044820152905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000006f43ff82cca38001b6699a8ac47a2d0e6693940716916323b872dd9160648083019260209291908290030181600087803b1580156113ea57600080fd5b505af11580156113fe573d6000803e3d6000fd5b505050506040513d602081101561141457600080fd5b5050604080516bffffffffffffffffffffffff831681529051339184917fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa7348915062039181900360200190a35050565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000006f43ff82cca38001b6699a8ac47a2d0e66939407161461150357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f6f6e6c792063616c6c61626c65207468726f756768204c494e4b000000000000604482015290519081900360640190fd5b6020811461157257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f64617461206d7573742062652033322062797465730000000000000000000000604482015290519081900360640190fd5b60008282602081101561158457600080fd5b503560008181526007602052604090206002015490915067ffffffffffffffff9081161461161357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f75706b656570206d757374206265206163746976650000000000000000000000604482015290519081900360640190fd5b60008181526007602052604090206001015461163d906bffffffffffffffffffffffff16856143a9565b600082815260076020526040902060010180547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff92909216919091179055600e546116969085614435565b600e55604080516bffffffffffffffffffffffff86168152905173ffffffffffffffffffffffffffffffffffffffff87169183917fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa7348915062039181900360200190a35050505050565b8073ffffffffffffffffffffffffffffffffffffffff811661177e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f63616e6e6f742073656e6420746f207a65726f20616464726573730000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff83811660009081526008602090815260409182902082516060810184528154948516808252740100000000000000000000000000000000000000009095046bffffffffffffffffffffffff16928101929092526001015460ff1615159181019190915290331461186457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f6f6e6c792063616c6c61626c6520627920706179656500000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff80851660009081526008602090815260409091208054909216909155810151600e546118b2916bffffffffffffffffffffffff166138d6565b600e819055508273ffffffffffffffffffffffffffffffffffffffff1681602001516bffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f9819093176a1851202c7bcfa46845809b4e47c261866550e94ed3775d2f4069833604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a47f0000000000000000000000006f43ff82cca38001b6699a8ac47a2d0e6693940773ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8483602001516040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff168152602001826bffffffffffffffffffffffff16815260200192505050602060405180830381600087803b15801561103557600080fd5b7f0000000000000000000000003ffe75e8eda86f48e454e6bfb5f74d95c20744f481565b73ffffffffffffffffffffffffffffffffffffffff818116600090815260096020526040902054163314611aa257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f6f6e6c792063616c6c61626c652062792070726f706f73656420706179656500604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff81811660008181526008602090815260408083208054337fffffffffffffffffffffffff000000000000000000000000000000000000000080831682179093556009909452828520805490921690915590519416939092849290917f78af32efdcad432315431e9b03d27e6cd98fb79c405fdc5af7c1714d9c0f75b39190a45050565b600081815260076020526040812054611b709074010000000000000000000000000000000000000000900463ffffffff166111ff565b92915050565b611b7e613762565b60007f0000000000000000000000006f43ff82cca38001b6699a8ac47a2d0e6693940773ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611c0757600080fd5b505afa158015611c1b573d6000803e3d6000fd5b505050506040513d6020811015611c3157600080fd5b5051600e5490915073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000006f43ff82cca38001b6699a8ac47a2d0e66939407169063a9059cbb903390611c849085906138d6565b6040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015611cd757600080fd5b505af1158015611ceb573d6000803e3d6000fd5b505050506040513d6020811015611d0157600080fd5b505050565b611d0e613762565b828114611d66576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180614d376021913960400191505060405180910390fd5b6002831015611dd657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6e6f7420656e6f756768206b6565706572730000000000000000000000000000604482015290519081900360640190fd5b60005b600654811015611e5657600060068281548110611df257fe5b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff1682526008905260409020600190810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055919091019050611dd9565b5060005b83811015612140576000858583818110611e7057fe5b73ffffffffffffffffffffffffffffffffffffffff6020918202939093013583166000818152600890925260408220805491955093169150868686818110611eb457fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611f59576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180614ccf6024913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82161580611fa757508073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b80611fc7575073ffffffffffffffffffffffffffffffffffffffff818116145b61203257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f63616e6e6f74206368616e676520706179656500000000000000000000000000604482015290519081900360640190fd5b600183015460ff16156120a657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f63616e6e6f7420616464206b6565706572207477696365000000000000000000604482015290519081900360640190fd5b600183810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016909117905573ffffffffffffffffffffffffffffffffffffffff818116146121305782547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff82161783555b505060019092019150611e5a9050565b5061214d60068585614b44565b507f056264c94f28bb06c99d13f0446eb96c67c215d8d707bce2655a98ddf1c0b71f848484846040518080602001806020018381038352878782818152602001925060200280828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169091018481038352858152602090810191508690860280828437600083820152604051601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018290039850909650505050505050a150505050565b6040805160c081018252600b5463ffffffff80821680845264010000000083048216602085015268010000000000000000830462ffffff9081169585018690526b0100000000000000000000008404909216606085018190526f01000000000000000000000000000000840490921660808501819052720100000000000000000000000000000000000090930461ffff1660a0909401849052600c54600d549196929492909190565b60606000806000806122dc610d3e565b1561234857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015290519081900360640190fd5b6123506144a9565b6000878152600760209081526040808320815160c081018352815473ffffffffffffffffffffffffffffffffffffffff80821683527401000000000000000000000000000000000000000090910463ffffffff16828601526001808401546bffffffffffffffffffffffff8116848701526c0100000000000000000000000090048216606084015260029384015467ffffffffffffffff8116608085015268010000000000000000900490911660a08301528c8652600a8552838620935160248101958652845461010092811615929092027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190911692909204604483018190529094937f6e04ff0d0000000000000000000000000000000000000000000000000000000093929091829160640190849080156124cf5780601f106124a4576101008083540402835291602001916124cf565b820191906000526020600020905b8154815290600101906020018083116124b257829003601f168201915b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009097169690961786528751600b549151835193985060009788975073ffffffffffffffffffffffffffffffffffffffff909216955063ffffffff6b01000000000000000000000090930492909216935087928291908083835b602083106125da57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161259d565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038160008787f1925050503d806000811461263d576040519150601f19603f3d011682016040523d82523d6000602084013e612642565b606091505b5091509150816127dd57600061265782614516565b905060008160405160200180807f63616c6c20746f20636865636b20746172676574206661696c65643a20000000815250601d0182805190602001908083835b602083106126d457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101612697565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905260408051929094018281037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018352938490527f08c379a00000000000000000000000000000000000000000000000000000000084526004840181815282516024860152825192975087965094508493604401925085019080838360005b838110156127a257818101518382015260200161278a565b50505050905090810190601f1680156127cf5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b8080602001905160408110156127f257600080fd5b81516020830180516040519294929383019291908464010000000082111561281957600080fd5b90830190602082018581111561282e57600080fd5b825164010000000081118282018810171561284857600080fd5b82525081516020918201929091019080838360005b8381101561287557818101518382015260200161285d565b50505050905090810190601f1680156128a25780820380516001836020036101000a031916815260200191505b50604052505050809a5081935050508161291d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f75706b656570206e6f74206e6565646564000000000000000000000000000000604482015290519081900360640190fd5b600061292c8b8d8c600061394d565b9050612941858260000151836060015161462d565b6060810151608082015160a083015160c0909301519b9e919d509b50909998509650505050505050565b6000818152600760209081526040808320815160c081018352815473ffffffffffffffffffffffffffffffffffffffff8082168084527401000000000000000000000000000000000000000090920463ffffffff168387018190526001808601546bffffffffffffffffffffffff81168689019081526c010000000000000000000000009091048416606080880191825260029889015467ffffffffffffffff811660808a019081526801000000000000000090910490961660a089019081528d8d52600a8c528a8d20935190519251965184548c5161010097821615979097027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01169a909a04601f81018d90048d0286018d01909b528a85528c9b919a8c9a8b9a8b9a8b9a91999098909796949591939091879190830182828015612af35780601f10612ac857610100808354040283529160200191612af3565b820191906000526020600020905b815481529060010190602001808311612ad657829003601f168201915b50505050509450975097509750975097509750975050919395979092949650565b60008181526007602052604081206002015467ffffffffffffffff9081169190821490612b3f6111e3565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161490508180612b8c5750808015612b8c5750438367ffffffffffffffff16115b612bf757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f746f6f206c61746520746f2063616e63656c2075706b65657000000000000000604482015290519081900360640190fd5b8080612c3957506000848152600760205260409020600101546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1633145b612ca457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f6f6e6c79206f776e6572206f722061646d696e00000000000000000000000000604482015290519081900360640190fd5b4381612cb857612cb5816032614435565b90505b600085815260076020526040902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83161790558215612d3757600580546001810182556000919091527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0018590555b60405167ffffffffffffffff82169086907f91cb3bb75cfbd718bbfccc56b7f53d92d7048ef4ca39a3b7b7c6d4af1f79118190600090a35050505050565b6000612d7f6111e3565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480612dcf5750600f5473ffffffffffffffffffffffffffffffffffffffff1633145b612e24576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180614cf36023913960400191505060405180910390fd5b612e438673ffffffffffffffffffffffffffffffffffffffff166147e4565b612eae57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f746172676574206973206e6f74206120636f6e74726163740000000000000000604482015290519081900360640190fd5b6108fc8563ffffffff161015612f2557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f6d696e2067617320697320323330300000000000000000000000000000000000604482015290519081900360640190fd5b624c4b408563ffffffff161115612f9d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6d61782067617320697320353030303030300000000000000000000000000000604482015290519081900360640190fd5b506004546040805160c08101825273ffffffffffffffffffffffffffffffffffffffff808916825263ffffffff808916602080850191825260008587018181528b86166060880190815267ffffffffffffffff6080890181815260a08a018581528c8652600787528b86209a518b54985190991674010000000000000000000000000000000000000000027fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff998b167fffffffffffffffffffffffff000000000000000000000000000000000000000090991698909817989098169690961789559151600189018054925189166c01000000000000000000000000026bffffffffffffffffffffffff9283167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000090941693909317909116919091179055925160029096018054945190951668010000000000000000027fffffffff0000000000000000000000000000000000000000ffffffffffffffff969093167fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909416939093179490941617909155600a90915220613159908484614bcc565b506004805460010190556040805163ffffffff8716815273ffffffffffffffffffffffffffffffffffffffff86166020820152815183927fbae366358c023f887e791d7a62f2e4316f1026bd77f6fb49501a917b3bc5d012928290030190a295945050505050565b6131c9613762565b6040518060c001604052808963ffffffff1681526020018863ffffffff1681526020018762ffffff1681526020018663ffffffff1681526020018562ffffff1681526020018461ffff16815250600b60008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160086101000a81548162ffffff021916908362ffffff160217905550606082015181600001600b6101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600f6101000a81548162ffffff021916908362ffffff16021790555060a08201518160000160126101000a81548161ffff021916908361ffff16021790555090505081600c8190555080600d819055507feb3c06937e6595fd80ec1add18a195026d5cf65f122cc3ffedbfb18a9ed80b3988878787878787604051808863ffffffff1681526020018762ffffff1681526020018663ffffffff1681526020018562ffffff1681526020018461ffff16815260200183815260200182815260200197505050505050505060405180910390a16040805163ffffffff8916815290517f17b46a44a823646eef686b7824df2962de896bc9a012a60b67694c5cbf184d8b9181900360200190a15050505050505050565b73ffffffffffffffffffffffffffffffffffffffff82811660009081526008602052604090205416331461346457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f6f6e6c792063616c6c61626c6520627920706179656500000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff81163314156134e957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f63616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8281166000908152600960205260409020548116908216146135955773ffffffffffffffffffffffffffffffffffffffff82811660008181526009602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169486169485179055513392917f84f7c7c80bb8ed2279b4aab5f61cd05e6374073d38f46d7f32de8c30e9e3836791a45b5050565b6135a1613762565b6135aa816147ea565b50565b6135b56111e3565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806136055750600f5473ffffffffffffffffffffffffffffffffffffffff1633145b61365a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180614cf36023913960400191505060405180910390fd5b600f5473ffffffffffffffffffffffffffffffffffffffff9081169082168114156136e657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f53616d6520726567697374726172000000000000000000000000000000000000604482015290519081900360640190fd5b600f80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84811691821790925560405190918316907f9bf4a5b30267728df68663e14adb47e559863967c419dc6030638883408bed2e90600090a35050565b60045490565b60005473ffffffffffffffffffffffffffffffffffffffff163314610cfc57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015290519081900360640190fd5b6137f0610d3e565b61385b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f7420706175736564000000000000000000000000604482015290519081900360640190fd5b600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6138ac6148e5565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190a1565b60008282111561394757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b613955614c66565b60008481526007602052604081205474010000000000000000000000000000000000000000900463ffffffff16908061398c613fd5565b91509150600061399c83876141b4565b905060006139ab8583856141fa565b6040805160e08101825273ffffffffffffffffffffffffffffffffffffffff8d168152602081018c90529081018a90526bffffffffffffffffffffffff909116606082015260808101959095525060a084015260c0830152509050949350505050565b6000600280541415613a8157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600280556020820151613a93816148e9565b602083810151600090815260078252604090819020815160c081018352815473ffffffffffffffffffffffffffffffffffffffff80821683527401000000000000000000000000000000000000000090910463ffffffff169482019490945260018201546bffffffffffffffffffffffff8116938201939093526c01000000000000000000000000909204831660608084019190915260029091015467ffffffffffffffff8116608084015268010000000000000000900490921660a08201528451918501519091613b679183919061462d565b60005a90506000634585e33b60e01b86604001516040516024018080602001828103825283818151815260200191508051906020019080838360005b83811015613bbb578181015183820152602001613ba3565b50505050905090810190601f168015613be85780820380516001836020036101000a031916815260200191505b50604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009096169590951790945250505060808701518451919250613c7d9183614974565b94505a820391506000613c99838860a001518960c001516141fa565b60208089015160009081526007909152604081206001015491925090613ccd906bffffffffffffffffffffffff16836149c0565b60208981018051600090815260078352604080822060010180547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff878116919091179091558d519351835281832060020180547fffffffff0000000000000000000000000000000000000000ffffffffffffffff166801000000000000000073ffffffffffffffffffffffffffffffffffffffff968716021790558d5190931682526008909352918220549293509091613daf917401000000000000000000000000000000000000000090910416846143a9565b905080600860008b6000015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550886000015173ffffffffffffffffffffffffffffffffffffffff168815158a602001517fcaacad83e47cc45c280d487ec84184eee2fa3b54ebaa393bda7549f13da228f6868d6040015160405180836bffffffffffffffffffffffff16815260200180602001828103825283818151815260200191508051906020019080838360005b83811015613ec1578181015183820152602001613ea9565b50505050905090810190601f168015613eee5780820380516001836020036101000a031916815260200191505b50935050505060405180910390a4505050505050506001600255919050565b613f15610d3e565b15613f8157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015290519081900360640190fd5b600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586138ac6148e5565b6000806000600b600001600f9054906101000a900462ffffff1662ffffff1690506000808263ffffffff161190506000807f000000000000000000000000b71eb5cabce02d55d1fac0e26c5745e704b6102173ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a06040518083038186803b15801561406c57600080fd5b505afa158015614080573d6000803e3d6000fd5b505050506040513d60a081101561409657600080fd5b506020810151606090910151925090508280156140ba57508142038463ffffffff16105b806140c6575060008113155b156140d557600c5495506140d9565b8095505b7f0000000000000000000000003ffe75e8eda86f48e454e6bfb5f74d95c20744f473ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a06040518083038186803b15801561413f57600080fd5b505afa158015614153573d6000803e3d6000fd5b505050506040513d60a081101561416957600080fd5b5060208101516060909101519250905082801561418d57508142038463ffffffff16105b80614199575060008113155b156141a857600d5494506141ac565b8094505b505050509091565b600b546000906141df9084907201000000000000000000000000000000000000900461ffff16614a4d565b90508180156141ed5750803a105b15611b7057503a92915050565b6040805160c081018252600b5463ffffffff808216835264010000000082048116602084015262ffffff6801000000000000000083048116948401949094526b0100000000000000000000008204811660608401526f010000000000000000000000000000008204909316608083015261ffff72010000000000000000000000000000000000009091041660a082015260009182906142ab906142a4908890620138809061443516565b8690614a4d565b905060006142d0836000015163ffffffff16633b9aca0061443590919063ffffffff16565b905060006143216142f964e8d4a51000866020015163ffffffff16614a4d90919063ffffffff16565b61431b886143158661430f89633b9aca00614a4d565b90614a4d565b90614ac0565b90614435565b90506b033b2e3c9fd0803ce800000081111561439e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f7061796d656e742067726561746572207468616e20616c6c204c494e4b000000604482015290519081900360640190fd5b979650505050505050565b60008282016bffffffffffffffffffffffff808516908216101561442e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b60008282018381101561442e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b3215610cfc57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f6f6e6c7920666f722073696d756c61746564206261636b656e64000000000000604482015290519081900360640190fd5b606060448251101561455c575060408051808201909152601d81527f7472616e73616374696f6e2072657665727465642073696c656e746c790000006020820152611230565b600482018051909260240190602081101561457657600080fd5b810190808051604051939291908464010000000082111561459657600080fd5b9083019060208201858111156145ab57600080fd5b82516401000000008111828201881017156145c557600080fd5b82525081516020918201929091019080838360005b838110156145f25781810151838201526020016145da565b50505050905090810190601f16801561461f5780820380516001836020036101000a031916815260200191505b506040525050509050919050565b73ffffffffffffffffffffffffffffffffffffffff821660009081526008602052604090206001015460ff166146c457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f6f6e6c7920616374697665206b65657065727300000000000000000000000000604482015290519081900360640190fd5b8083604001516bffffffffffffffffffffffff16101561474557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f696e73756666696369656e742066756e64730000000000000000000000000000604482015290519081900360640190fd5b8173ffffffffffffffffffffffffffffffffffffffff168360a0015173ffffffffffffffffffffffffffffffffffffffff161415611d0157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f6b656570657273206d7573742074616b65207475726e73000000000000000000604482015290519081900360640190fd5b3b151590565b73ffffffffffffffffffffffffffffffffffffffff811633141561486f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015290519081900360640190fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b3390565b6000818152600760205260409020600201544367ffffffffffffffff909116116135aa57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f696e76616c69642075706b656570206964000000000000000000000000000000604482015290519081900360640190fd5b60005a61138881101561498657600080fd5b61138881039050846040820482031161499e57600080fd5b50823b6149aa57600080fd5b60008083516020850160008789f1949350505050565b6000826bffffffffffffffffffffffff16826bffffffffffffffffffffffff16111561394757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b600082614a5c57506000611b70565b82820282848281614a6957fe5b041461442e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180614d166021913960400191505060405180910390fd5b6000808211614b3057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b6000828481614b3b57fe5b04949350505050565b828054828255906000526020600020908101928215614bbc579160200282015b82811115614bbc5781547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff843516178255602090920191600190910190614b64565b50614bc8929150614cb9565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282614c025760008555614bbc565b82601f10614c39578280017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00823516178555614bbc565b82800160010185558215614bbc579182015b82811115614bbc578235825591602001919060010190614c4b565b6040518060e00160405280600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160608152602001600081526020016000815260200160008152602001600081525090565b5b80821115614bc85760008155600101614cba56fe63616e6e6f742073657420706179656520746f20746865207a65726f20616464726573734f6e6c792063616c6c61626c65206279206f776e6572206f7220726567697374726172536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7761646472657373206c69737473206e6f74207468652073616d65206c656e677468a164736f6c6343000706000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000006f43ff82cca38001b6699a8ac47a2d0e669394070000000000000000000000003ffe75e8eda86f48e454e6bfb5f74d95c20744f4000000000000000000000000b71eb5cabce02d55d1fac0e26c5745e704b610210000000000000000000000000000000000000000000000000000000029b92700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000632ea00000000000000000000000000000000000000000000000000000000000015f9000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000015d3ef798000000000000000000000000000000000000000000000000008ac7230489e80000
-----Decoded View---------------
Arg [0] : link (address): 0x6F43FF82CCA38001B6699a8AC47A2d0E66939407
Arg [1] : linkEthFeed (address): 0x3FFe75E8EDA86F48e454e6bfb5F74d95C20744f4
Arg [2] : fastGasFeed (address): 0xB71eB5CABCE02d55d1Fac0e26c5745E704b61021
Arg [3] : paymentPremiumPPB (uint32): 700000000
Arg [4] : flatFeeMicroLink (uint32): 0
Arg [5] : blockCountPerTurn (uint24): 20
Arg [6] : checkGasLimit (uint32): 6500000
Arg [7] : stalenessSeconds (uint24): 90000
Arg [8] : gasCeilingMultiplier (uint16): 2
Arg [9] : fallbackGasPrice (uint256): 1500000000000
Arg [10] : fallbackLinkPrice (uint256): 10000000000000000000
-----Encoded View---------------
11 Constructor Arguments found :
Arg [0] : 0000000000000000000000006f43ff82cca38001b6699a8ac47a2d0e66939407
Arg [1] : 0000000000000000000000003ffe75e8eda86f48e454e6bfb5f74d95c20744f4
Arg [2] : 000000000000000000000000b71eb5cabce02d55d1fac0e26c5745e704b61021
Arg [3] : 0000000000000000000000000000000000000000000000000000000029b92700
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000014
Arg [6] : 0000000000000000000000000000000000000000000000000000000000632ea0
Arg [7] : 0000000000000000000000000000000000000000000000000000000000015f90
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [9] : 0000000000000000000000000000000000000000000000000000015d3ef79800
Arg [10] : 0000000000000000000000000000000000000000000000008ac7230489e80000
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.