Source Code
More Info
Private Name Tags
ContractCreator
TokenTracker
Multichain Info
Latest 25 from a total of 302 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Run Interval | 21638436 | 851 days ago | IN | 0 CELO | 0.00062039 | ||||
| Run Interval | 21638360 | 851 days ago | IN | 0 CELO | 0.00062039 | ||||
| Create Travel Pa... | 21112855 | 881 days ago | IN | 0 CELO | 0.00843587 | ||||
| Create Travel Pa... | 21112779 | 881 days ago | IN | 0 CELO | 0.00843587 | ||||
| Run Interval | 20865227 | 895 days ago | IN | 0 CELO | 0.00097847 | ||||
| Claim Travel Pla... | 20614953 | 910 days ago | IN | 0 CELO | 0.00180275 | ||||
| Contribute To Tr... | 20614548 | 910 days ago | IN | 0 CELO | 0.00201942 | ||||
| Claim Travel Pla... | 20614476 | 910 days ago | IN | 0 CELO | 0.00165025 | ||||
| Claim Travel Pla... | 20614206 | 910 days ago | IN | 0 CELO | 0.00180275 | ||||
| Run Interval | 20467518 | 918 days ago | IN | 0 CELO | 0.00097847 | ||||
| Contribute To Tr... | 20442246 | 920 days ago | IN | 0 CELO | 0.00201972 | ||||
| Create Travel Pa... | 20339661 | 926 days ago | IN | 0 CELO | 0.00843617 | ||||
| Run Interval | 20269086 | 930 days ago | IN | 0 CELO | 0.00097847 | ||||
| Contribute To Tr... | 20263740 | 930 days ago | IN | 0 CELO | 0.00162442 | ||||
| Contribute To Tr... | 20263724 | 930 days ago | IN | 0 CELO | 0.00201942 | ||||
| Contribute To Tr... | 20251821 | 931 days ago | IN | 0 CELO | 0.00201942 | ||||
| Create Travel Pa... | 20251805 | 931 days ago | IN | 0 CELO | 0.00843617 | ||||
| Run Interval | 19975618 | 947 days ago | IN | 0 CELO | 0.00097847 | ||||
| Run Interval | 19958337 | 948 days ago | IN | 0 CELO | 0.00262267 | ||||
| Create Payment P... | 19941933 | 949 days ago | IN | 0 CELO | 0.00556987 | ||||
| Run Interval | 19941056 | 949 days ago | IN | 0 CELO | 0.00262267 | ||||
| Run Interval | 19923775 | 950 days ago | IN | 0 CELO | 0.00262267 | ||||
| Run Interval | 19906494 | 951 days ago | IN | 0 CELO | 0.00262267 | ||||
| Cancel Payment P... | 19906369 | 951 days ago | IN | 0 CELO | 0.0012265 | ||||
| Run Interval | 19889214 | 952 days ago | IN | 0 CELO | 0.00341267 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
Contract Name:
TravelSaver
Compiler Version
v0.8.17+commit.8df45f5f
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.17;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
/**
* @title Travel Saving Vault with Recurring Payments Scheduler
*/
contract TravelSaver {
// ***** ***** EVENTS ***** *****
/**
* @notice Emitted when a TravelPlan is created
*
* @param ID uniqe plan's ID
* @param owner user who created it
* @param travelPlan a plan's details
*/
event CreatedTravelPlan(
uint256 indexed ID,
address indexed owner,
TravelPlan travelPlan
);
/**
* @notice Emitted when a token transfer is made to each TravelPlan
*
* @param ID uniqe plan's ID
* @param contributor address that made a transfer
* @param amount an ERC20 unit as per its decimals
*/
event ContributeToTravelPlan(
uint256 indexed ID,
address indexed contributor,
uint256 amount
);
/**
* @notice Emitted when a user makes a withdrawl towards a booking
*
* @param ID uniqe plan's ID
* @param owner address that received a transfer
* @param amount an ERC20 unit as per its decimals
*/
event ClaimTravelPlan(uint256 indexed ID, address owner, uint256 amount);
/**
* @notice Emitted when a user makes a withdrawl towards a booking
*
* @param from address that made a transfer
* @param to address that received a transfer
* @param amount an ERC20 unit as per its decimals
*/
event Transfer(address indexed from, address indexed to, uint256 amount);
/**
* @notice Emitted when a PaymentPlan is created
*
* @param ID uniqe plan's ID
* @param owner user who created it
* @param paymentPlan a plan's details
*/
event CreatedPaymentPlan(
uint256 indexed ID,
address indexed owner,
PaymentPlan paymentPlan
);
/**
* @notice Emitted when a PaymentPlan is cancelled before scheduled payments are made
*
* @param ID uniqe plan's ID
* @param owner user who created it
* @param paymentPlan a plan's details
*/
event CancelPaymentPlan(
uint256 indexed ID,
address indexed owner,
PaymentPlan paymentPlan
);
/**
* @notice Emitted when a PaymentPlan scheduled payment has been sucessfully made
*
* @param ID uniqe plan's ID
* @param callableOn unix TS of next scheduled payment
* @param amount an ERC20 unit as per its decimals
* @param intervalNo sequential scheduled payment count
*/
event StartPaymentPlanInterval(
uint256 indexed ID,
uint256 indexed callableOn,
uint256 indexed amount,
uint256 intervalNo
);
/**
* @notice Emitted when a PaymentPlan scheduled payment has been sucessfully made
*
* @param ID uniqe plan's ID
* @param intervalNo sequential scheduled payment count
*/
event PaymentPlanIntervalEnded(
uint256 indexed ID,
uint256 indexed intervalNo
);
/**
* @notice Emitted when a PaymentPlan has ended as scheduled, after last payment
*
* @param ID uniqe plan's ID
* @param owner user who created it
* @param paymentPlan a plan's details
*/
event EndPaymentPlan(
uint256 indexed ID,
address indexed owner,
PaymentPlan paymentPlan
);
// ***** ***** STRUCTS ***** *****
/**
* @notice TravelPlan is a vault where users funds are retained until the booking
*
* @param owner user's wallet address, plan creator, who can transfer money out to operators wallet -> make a booking
* @param ID unique identifier within the contract generated sequencially
* @param operatorPlanID operator's reference booking identifier
* @param operatorUserID operator's reference user identifier
* @param contributedAmount current ammount available for a whithdrawal
* @param createdAt the creation date
* @param claimedAt last clamied date
* @param claimed true if it has been clamimed in the past
*/
struct TravelPlan {
address owner;
uint256 ID;
uint256 operatorPlanID;
uint256 operatorUserID;
uint256 contributedAmount;
uint256 createdAt;
uint256 claimedAt;
bool claimed;
}
/**
* @notice PaymentPlan is a recurring payments scheduler that must target specific TravelPlan
*
* @param travelPlanID id reference to a vault id where funds will be sent to
* @param ID unique identifier within the contract generated sequencially
* @param totalAmount the planned value of a total savings to be scheduled
* @param amountSent the current state of all payments made
* @param amountPerInterval unit value of a specific ERC-20 token to be sent per each scheduled payment
* @param totalIntervals total number of scheduled payments
* @param intervalsProcessed cuurent number of processed payments
* @param nextTransferOn unix secs TS of a next scheduled payment due at
* @param interval current interval count
* @param sender the owner of the plan - might be different to the TravelPlan
* @param alive determined whether plan is active or cancelled
*/
struct PaymentPlan {
uint256 travelPlanID;
uint256 ID;
uint256 totalAmount;
uint256 amountSent;
uint256 amountPerInterval;
uint256 totalIntervals;
uint256 intervalsProcessed;
uint256 nextTransferOn;
uint256 interval;
address sender;
bool alive;
}
// ***** ***** STATE-VARIABLES ***** *****
address public immutable operatorWallet; // hardcoded address of the operator wallet where funds are send from travel-plan as external multisg wallet that is opearated and solely responsible for by the ticket issuer
using SafeERC20 for IERC20;
IERC20 public immutable token; // hardcoded address of the ERC20 EUR/USD PEGGED and NON DEFLACTIONARY token that serves a currency of the contract
uint256 travelPlanCount; // current number of contract's created travel-plans
uint256 paymentPlanCount; // current number of contract's created payment-plans
mapping(uint256 => TravelPlan) public travelPlans; // TravelPlan reference by ID, returns Plans state
mapping(uint256 => PaymentPlan) public paymentPlans; // PaymentPlan referenced by ID, returns Plans state
// mapping(uint256 => mapping(address => uint256)) public contributedAmount; // ID
/**
* @param ERC20_ EUR or USD PEGGED, STABLE and NON DEFLACTIONARY tokens ONLY
*
* @param operatorWallet_ an external multisg wallet that is opearated and solely responsible for by the ticket issuer,
* user is to be guaranteed that once claimed funds to that address -> off chain purchase or refund must be processed by contract issuing party
*/
constructor(address ERC20_, address operatorWallet_) {
token = IERC20(ERC20_);
operatorWallet = operatorWallet_;
}
/**
***** ***** STATE-CHANGING-EXTERNAL-FUNCTIONS ***** *****
*/
/**
* @dev create Travel Plan and New Payment Plan attached to it in one go
*
* @param operatorPlanID_ The plan id provided by the operator.
* @param operatorUserID_ The user id provided by the operator.
* @param amountPerInterval unit value of a specific ERC-20 token to be sent per each scheduled payment
* @param totalIntervals total number of payments to be scheduled
* @param intervalLength time distance between each payments in seconds
*
* @return travelPlanID paymentPlanID new sequential count based UUIDs
*
* Emits a {CreatedTravelPlan, CreatedPaymentPlan} event.
*/
function createTravelPaymentPlan(
uint256 operatorPlanID_,
uint256 operatorUserID_,
uint256 amountPerInterval,
uint256 totalIntervals,
uint256 intervalLength
) external returns (uint256 travelPlanID, uint256 paymentPlanID) {
travelPlanID = createTravelPlan(operatorPlanID_, operatorUserID_);
paymentPlanID = createPaymentPlan(
travelPlanID,
amountPerInterval,
totalIntervals,
intervalLength
);
return (travelPlanID, paymentPlanID);
}
/**
* @dev create Travel Plan where user will store his/hers savings until the booking date
*
* @param operatorPlanID_ The plan id provided by the operator.
* @param operatorUserID_ The user id provided by the operator.
*
* @return travelPlanCount a new sequential count based UUID
*
* Emits a {CreatedTravelPlan} event.
*/
function createTravelPlan(
uint256 operatorPlanID_,
uint256 operatorUserID_
) public returns (uint256) {
travelPlanCount += 1;
travelPlans[travelPlanCount] = TravelPlan({
owner: msg.sender,
ID: travelPlanCount,
operatorPlanID: operatorPlanID_,
operatorUserID: operatorUserID_,
contributedAmount: 0,
createdAt: block.timestamp,
claimedAt: 0,
claimed: false
});
emit CreatedTravelPlan(
travelPlanCount,
msg.sender,
travelPlans[travelPlanCount]
);
return travelPlanCount;
}
/**
* @dev allows to transfer ERC20 token to specific TravelPlan by anyone
*
* @param ID TravelPlan existing UUID
* @param amount ERC20 token value defined by its decimals
*
* Emits a {ContributeToTravelPlan, Transfer} event.
*/
function contributeToTravelPlan(uint256 ID, uint256 amount) external {
TravelPlan storage plan = travelPlans[ID];
require(plan.ID == ID, "doesn't exist");
plan.contributedAmount += amount;
token.safeTransferFrom(msg.sender, address(this), amount);
emit ContributeToTravelPlan(ID, msg.sender, amount);
emit Transfer(msg.sender, address(this), amount);
}
/**
* @dev allows to transfer ERC20 token from specific TravelPlan to operators wallet to make a booking only by the user/owner
*
* @param ID TravelPlan existing UUID
* @param value ERC20 token value defined by its decimals
*
* Emits a {ClaimTravelPlan, Transfer} event.
*/
function claimTravelPlan(uint256 ID, uint256 value) external {
TravelPlan storage plan = travelPlans[ID];
require(plan.ID == ID, "doesn't exist");
require(plan.owner == msg.sender, "not owner");
require(plan.contributedAmount >= value, "insufficient funds");
plan.contributedAmount -= value;
token.safeTransfer(operatorWallet, value);
plan.claimed = true;
plan.claimedAt = block.timestamp;
emit ClaimTravelPlan(ID, msg.sender, value);
emit Transfer(address(this), operatorWallet, value);
}
/**
* @dev creates a new payment plan targeting existing travel-plan along with its sheduled payments details
*
* @param _travelPlanID The plan id provided by the operator.
* @param amountPerInterval unit value of a specific ERC-20 token to be sent per each scheduled payment
* @param totalIntervals total number of payments to be scheduled
* @param intervalLength time distance between each payments in seconds
*
* @return id a new sequential count based UUID
*
* Emits a {CreatedPaymentPlan} event.
*/
function createPaymentPlan(
uint256 _travelPlanID,
uint256 amountPerInterval,
uint256 totalIntervals,
uint256 intervalLength
) public returns (uint256) {
uint256 totalToTransfer = amountPerInterval * totalIntervals;
require(
IERC20(token).allowance(msg.sender, address(this)) >=
totalToTransfer,
"ERC20: insufficient allowance"
);
TravelPlan memory plan = travelPlans[_travelPlanID];
require(plan.ID == _travelPlanID, "doesn't exist");
uint256 id = ++paymentPlanCount;
paymentPlans[id] = PaymentPlan({
travelPlanID: _travelPlanID,
ID: id,
totalAmount: totalToTransfer,
amountSent: 0,
amountPerInterval: amountPerInterval,
totalIntervals: totalIntervals,
intervalsProcessed: 0,
nextTransferOn: 0,
interval: intervalLength,
sender: msg.sender,
alive: true
});
_startInterval(id);
emit CreatedPaymentPlan(id, msg.sender, paymentPlans[id]);
return id;
}
/**
* @dev cancelPaymentPlan cancels existing payment schedule before its plannned due date
*
* @param ID TravelPlan existing UUID
*
* Emits a {CancelPaymentPlan} event.
*/
function cancelPaymentPlan(uint256 ID) external {
require(msg.sender == paymentPlans[ID].sender, "only plan owner");
_endPaymentPlan(ID);
emit CancelPaymentPlan(ID, msg.sender, paymentPlans[ID]);
}
/**
* @dev runInterval executes scheduled payment
*
* @param ID PaymentPlan existing UUID
*/
function runInterval(uint256 ID) external {
_fulfillPaymentPlanInterval(ID);
}
/**
***** ***** STATE-CHANGING-PRIVATE-FUNCTIONS ***** *****
*/
/**
* @dev _startInterval sets new payment schedule
*
* @param ID PaymentPlan existing UUIDs
*
* Emits a {StartPaymentPlanInterval} event.
*/
function _startInterval(uint256 ID) internal {
PaymentPlan memory plan = paymentPlans[ID];
uint256 callableOn = paymentPlans[ID].interval + block.timestamp;
uint256 intervalNumber = plan.intervalsProcessed + 1;
paymentPlans[ID].nextTransferOn = callableOn;
emit StartPaymentPlanInterval(
ID,
callableOn,
plan.amountPerInterval,
intervalNumber
);
}
/**
* @dev _endPaymentPlan ends payment plan
*
* @param ID PaymentPlan existing UUIDs
*
* Emits a {EndPaymentPlan} event.
*/
function _endPaymentPlan(uint256 ID) internal {
PaymentPlan memory plan = paymentPlans[ID];
paymentPlans[ID].alive = false;
emit EndPaymentPlan(ID, plan.sender, plan);
}
/**
* @dev _contributeToTravelPlan executes scheduled payments internaly by transfering tokens from user to the vault - used by a off chain worker
*
* @param ID PaymentPlan existing UUIDs
* @param amount ERC20 token value defined by its decimals
* @param caller address of a contract that executes transaction on behalf of the user
*
* Emits a {ContributeToTravelPlan, Transfer} event.
*/
function _contributeToTravelPlan(
uint256 ID,
uint256 amount,
address caller
) internal {
TravelPlan storage plan = travelPlans[ID];
// require(block.timestamp >= plan.createdAt, "doesn't exist");
require(plan.ID == ID, "doesn't exist");
plan.contributedAmount += amount;
// contributedAmount[ID][caller] += amount;
token.safeTransferFrom(caller, address(this), amount);
emit ContributeToTravelPlan(ID, caller, amount);
emit Transfer(caller, address(this), amount);
}
/**
* @dev _fulfillPaymentPlanInterval executes scheduled payments internaly
*
* @param ID PaymentPlan existing UUIDs
*
* Emits a {PaymentPlanIntervalEnded} event.
*/
function _fulfillPaymentPlanInterval(uint256 ID) internal {
PaymentPlan memory plan = paymentPlans[ID];
uint256 amountToTransfer = plan.amountPerInterval;
address sender = plan.sender;
uint256 interval = plan.intervalsProcessed + 1;
require(plan.nextTransferOn <= block.timestamp, "too early");
require(plan.alive, "plan ended");
// Check conditions here with an if clause instead of require, so that integrators dont have to keep track of balances
if (
token.balanceOf(sender) >= amountToTransfer &&
token.allowance(sender, address(this)) >= amountToTransfer
) {
_contributeToTravelPlan(
plan.travelPlanID,
amountToTransfer,
sender
);
paymentPlans[ID].amountSent += amountToTransfer;
paymentPlans[ID].intervalsProcessed = interval;
emit PaymentPlanIntervalEnded(ID, interval);
if (interval < plan.totalIntervals) {
_startInterval(ID);
} else {
_endPaymentPlan(ID);
}
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/draft-IERC20Permit.sol";
import "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
// Return data is optional
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @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
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "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");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, 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) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, 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) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// 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
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}{
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": false,
"runs": 200
},
"remappings": [],
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"ERC20_","type":"address"},{"internalType":"address","name":"operatorWallet_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"ID","type":"uint256"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"components":[{"internalType":"uint256","name":"travelPlanID","type":"uint256"},{"internalType":"uint256","name":"ID","type":"uint256"},{"internalType":"uint256","name":"totalAmount","type":"uint256"},{"internalType":"uint256","name":"amountSent","type":"uint256"},{"internalType":"uint256","name":"amountPerInterval","type":"uint256"},{"internalType":"uint256","name":"totalIntervals","type":"uint256"},{"internalType":"uint256","name":"intervalsProcessed","type":"uint256"},{"internalType":"uint256","name":"nextTransferOn","type":"uint256"},{"internalType":"uint256","name":"interval","type":"uint256"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"bool","name":"alive","type":"bool"}],"indexed":false,"internalType":"struct TravelSaver.PaymentPlan","name":"paymentPlan","type":"tuple"}],"name":"CancelPaymentPlan","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"ID","type":"uint256"},{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ClaimTravelPlan","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"ID","type":"uint256"},{"indexed":true,"internalType":"address","name":"contributor","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ContributeToTravelPlan","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"ID","type":"uint256"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"components":[{"internalType":"uint256","name":"travelPlanID","type":"uint256"},{"internalType":"uint256","name":"ID","type":"uint256"},{"internalType":"uint256","name":"totalAmount","type":"uint256"},{"internalType":"uint256","name":"amountSent","type":"uint256"},{"internalType":"uint256","name":"amountPerInterval","type":"uint256"},{"internalType":"uint256","name":"totalIntervals","type":"uint256"},{"internalType":"uint256","name":"intervalsProcessed","type":"uint256"},{"internalType":"uint256","name":"nextTransferOn","type":"uint256"},{"internalType":"uint256","name":"interval","type":"uint256"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"bool","name":"alive","type":"bool"}],"indexed":false,"internalType":"struct TravelSaver.PaymentPlan","name":"paymentPlan","type":"tuple"}],"name":"CreatedPaymentPlan","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"ID","type":"uint256"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"ID","type":"uint256"},{"internalType":"uint256","name":"operatorPlanID","type":"uint256"},{"internalType":"uint256","name":"operatorUserID","type":"uint256"},{"internalType":"uint256","name":"contributedAmount","type":"uint256"},{"internalType":"uint256","name":"createdAt","type":"uint256"},{"internalType":"uint256","name":"claimedAt","type":"uint256"},{"internalType":"bool","name":"claimed","type":"bool"}],"indexed":false,"internalType":"struct TravelSaver.TravelPlan","name":"travelPlan","type":"tuple"}],"name":"CreatedTravelPlan","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"ID","type":"uint256"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"components":[{"internalType":"uint256","name":"travelPlanID","type":"uint256"},{"internalType":"uint256","name":"ID","type":"uint256"},{"internalType":"uint256","name":"totalAmount","type":"uint256"},{"internalType":"uint256","name":"amountSent","type":"uint256"},{"internalType":"uint256","name":"amountPerInterval","type":"uint256"},{"internalType":"uint256","name":"totalIntervals","type":"uint256"},{"internalType":"uint256","name":"intervalsProcessed","type":"uint256"},{"internalType":"uint256","name":"nextTransferOn","type":"uint256"},{"internalType":"uint256","name":"interval","type":"uint256"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"bool","name":"alive","type":"bool"}],"indexed":false,"internalType":"struct TravelSaver.PaymentPlan","name":"paymentPlan","type":"tuple"}],"name":"EndPaymentPlan","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"ID","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"intervalNo","type":"uint256"}],"name":"PaymentPlanIntervalEnded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"ID","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"callableOn","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"intervalNo","type":"uint256"}],"name":"StartPaymentPlanInterval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"uint256","name":"ID","type":"uint256"}],"name":"cancelPaymentPlan","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"ID","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"claimTravelPlan","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"ID","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"contributeToTravelPlan","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_travelPlanID","type":"uint256"},{"internalType":"uint256","name":"amountPerInterval","type":"uint256"},{"internalType":"uint256","name":"totalIntervals","type":"uint256"},{"internalType":"uint256","name":"intervalLength","type":"uint256"}],"name":"createPaymentPlan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"operatorPlanID_","type":"uint256"},{"internalType":"uint256","name":"operatorUserID_","type":"uint256"},{"internalType":"uint256","name":"amountPerInterval","type":"uint256"},{"internalType":"uint256","name":"totalIntervals","type":"uint256"},{"internalType":"uint256","name":"intervalLength","type":"uint256"}],"name":"createTravelPaymentPlan","outputs":[{"internalType":"uint256","name":"travelPlanID","type":"uint256"},{"internalType":"uint256","name":"paymentPlanID","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"operatorPlanID_","type":"uint256"},{"internalType":"uint256","name":"operatorUserID_","type":"uint256"}],"name":"createTravelPlan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"operatorWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"paymentPlans","outputs":[{"internalType":"uint256","name":"travelPlanID","type":"uint256"},{"internalType":"uint256","name":"ID","type":"uint256"},{"internalType":"uint256","name":"totalAmount","type":"uint256"},{"internalType":"uint256","name":"amountSent","type":"uint256"},{"internalType":"uint256","name":"amountPerInterval","type":"uint256"},{"internalType":"uint256","name":"totalIntervals","type":"uint256"},{"internalType":"uint256","name":"intervalsProcessed","type":"uint256"},{"internalType":"uint256","name":"nextTransferOn","type":"uint256"},{"internalType":"uint256","name":"interval","type":"uint256"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"bool","name":"alive","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"ID","type":"uint256"}],"name":"runInterval","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"travelPlans","outputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"ID","type":"uint256"},{"internalType":"uint256","name":"operatorPlanID","type":"uint256"},{"internalType":"uint256","name":"operatorUserID","type":"uint256"},{"internalType":"uint256","name":"contributedAmount","type":"uint256"},{"internalType":"uint256","name":"createdAt","type":"uint256"},{"internalType":"uint256","name":"claimedAt","type":"uint256"},{"internalType":"bool","name":"claimed","type":"bool"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60c06040523480156200001157600080fd5b5060405162002c5b38038062002c5b833981810160405281019062000037919062000111565b8173ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff16815250508073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1681525050505062000158565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620000d982620000ac565b9050919050565b620000eb81620000cc565b8114620000f757600080fd5b50565b6000815190506200010b81620000e0565b92915050565b600080604083850312156200012b576200012a620000a7565b5b60006200013b85828601620000fa565b92505060206200014e85828601620000fa565b9150509250929050565b60805160a051612aa5620001b66000396000818161027c015281816106c001528181610cde01528181610e5901528181611020015281816110c401526116a3015260008181610cbc01528181610d840152610e350152612aa56000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c806390513e1a1161007157806390513e1a1461017d5780639d92068814610199578063a601c2c6146101d3578063aaec77e5146101ef578063f90ef4ac14610220578063fc0c546a1461023e576100a9565b80630cf9e555146100ae578063223f83e2146100ca5780632b06fa74146100fa57806385fcc9a2146101165780638818e16514610146575b600080fd5b6100c860048036038101906100c39190611a71565b61025c565b005b6100e460048036038101906100df9190611a9e565b610268565b6040516100f19190611b14565b60405180910390f35b610114600480360381019061010f9190611b2f565b610640565b005b610130600480360381019061012b9190611b2f565b6107be565b60405161013d9190611b14565b60405180910390f35b610160600480360381019061015b9190611a71565b610959565b604051610174989796959493929190611bcb565b60405180910390f35b61019760048036038101906101929190611a71565b6109ce565b005b6101b360048036038101906101ae9190611a71565b610adf565b6040516101ca9b9a99989796959493929190611c49565b60405180910390f35b6101ed60048036038101906101e89190611b2f565b610b66565b005b61020960048036038101906102049190611cf4565b610e0c565b604051610217929190611d6f565b60405180910390f35b610228610e33565b6040516102359190611d98565b60405180910390f35b610246610e57565b6040516102539190611e12565b60405180910390f35b61026581610e7b565b50565b60008083856102779190611e5c565b9050807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e33306040518363ffffffff1660e01b81526004016102d5929190611e9e565b602060405180830381865afa1580156102f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103169190611edc565b1015610357576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161034e90611f66565b60405180910390fd5b600060026000888152602001908152602001600020604051806101000160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820154815260200160028201548152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820160009054906101000a900460ff16151515158152505090508681602001511461046d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046490611fd2565b60405180910390fd5b600060016000815461047e90611ff2565b91905081905590506040518061016001604052808981526020018281526020018481526020016000815260200188815260200187815260200160008152602001600081526020018681526020013373ffffffffffffffffffffffffffffffffffffffff1681526020016001151581525060036000838152602001908152602001600020600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e0820151816007015561010082015181600801556101208201518160090160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506101408201518160090160146101000a81548160ff0219169083151502179055509050506105d181611217565b3373ffffffffffffffffffffffffffffffffffffffff16817ffd671f7182c83d1e07d1bd1748354402aa8a9193629cad7a0fbaac5c8ffe28186003600085815260200190815260200160002060405161062a9190612258565b60405180910390a3809350505050949350505050565b60006002600084815260200190815260200160002090508281600101541461069d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161069490611fd2565b60405180910390fd5b818160040160008282546106b19190612274565b925050819055506107053330847f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1661139f909392919063ffffffff16565b3373ffffffffffffffffffffffffffffffffffffffff16837f20c5b66cd5e4a4148323852541307bd30d5674f62e2247aefbd3dbae8be5e9188460405161074c9190611b14565b60405180910390a33073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516107b19190611b14565b60405180910390a3505050565b600060016000808282546107d29190612274565b925050819055506040518061010001604052803373ffffffffffffffffffffffffffffffffffffffff1681526020016000548152602001848152602001838152602001600081526020014281526020016000815260200160001515815250600260008054815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e08201518160070160006101000a81548160ff0219169083151502179055509050503373ffffffffffffffffffffffffffffffffffffffff166000547f71acf40162e8307c5fd5ec4e08cd622f5e5d29c2b1982af5421d95c0b1d117cf600260008054815260200190815260200160002060405161094691906123be565b60405180910390a3600054905092915050565b60026020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010154908060020154908060030154908060040154908060050154908060060154908060070160009054906101000a900460ff16905088565b6003600082815260200190815260200160002060090160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a72576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a6990612426565b60405180910390fd5b610a7b81611428565b3373ffffffffffffffffffffffffffffffffffffffff16817f1508b4f1d043dd53494e9f162026083edd68e32aa1e6e2d8818021c384fe080a60036000858152602001908152602001600020604051610ad49190612258565b60405180910390a350565b60036020528060005260406000206000915090508060000154908060010154908060020154908060030154908060040154908060050154908060060154908060070154908060080154908060090160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060090160149054906101000a900460ff1690508b565b600060026000848152602001908152602001600020905082816001015414610bc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bba90611fd2565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610c55576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c4c90612492565b60405180910390fd5b8181600401541015610c9c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c93906124fe565b60405180910390fd5b81816004016000828254610cb0919061251e565b92505081905550610d227f0000000000000000000000000000000000000000000000000000000000000000837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1661159d9092919063ffffffff16565b60018160070160006101000a81548160ff021916908315150217905550428160060181905550827f486095ee3674fb24bd0a2fcf31db414056448c4f6e206484eae4bcbb17fea35a3384604051610d7a929190612552565b60405180910390a27f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610dff9190611b14565b60405180910390a3505050565b600080610e1987876107be565b9150610e2782868686610268565b90509550959350505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600060036000838152602001908152602001600020604051806101600160405290816000820154815260200160018201548152602001600282015481526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016009820160149054906101000a900460ff161515151581525050905060008160800151905060008261012001519050600060018460c00151610f8f9190612274565b9050428460e001511115610fd8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fcf906125c7565b60405180910390fd5b83610140015161101d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161101490612633565b60405180910390fd5b827f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231846040518263ffffffff1660e01b81526004016110779190611d98565b602060405180830381865afa158015611094573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110b89190611edc565b101580156111615750827f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e84306040518363ffffffff1660e01b815260040161111d929190611e9e565b602060405180830381865afa15801561113a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061115e9190611edc565b10155b156112105761117584600001518484611623565b8260036000878152602001908152602001600020600301600082825461119b9190612274565b9250508190555080600360008781526020019081526020016000206006018190555080857fbec3f63cb2d17ab9edd65a1a7ab167efd9802d37681c490ed1b215c6995bb3cb60405160405180910390a38360a001518110156112055761120085611217565b61120f565b61120e85611428565b5b5b5050505050565b600060036000838152602001908152602001600020604051806101600160405290816000820154815260200160018201548152602001600282015481526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016009820160149054906101000a900460ff161515151581525050905060004260036000858152602001908152602001600020600801546113299190612274565b9050600060018360c0015161133e9190612274565b9050816003600086815260200190815260200160002060070181905550826080015182857f7191b4f9ba2ec111b9ae2a916ba78702dfbfe79ca993c2ce4321ff79a52a4c9c846040516113919190611b14565b60405180910390a450505050565b611422846323b872dd60e01b8585856040516024016113c093929190612653565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506117a2565b50505050565b600060036000838152602001908152602001600020604051806101600160405290816000820154815260200160018201548152602001600282015481526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016009820160149054906101000a900460ff161515151581525050905060006003600084815260200190815260200160002060090160146101000a81548160ff02191690831515021790555080610120015173ffffffffffffffffffffffffffffffffffffffff16827f5e2829107023b345d1e5d6a90c0485ea550de003591f622a48dd48034b80486b83604051611591919061276b565b60405180910390a35050565b61161e8363a9059cbb60e01b84846040516024016115bc929190612552565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506117a2565b505050565b600060026000858152602001908152602001600020905083816001015414611680576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167790611fd2565b60405180910390fd5b828160040160008282546116949190612274565b925050819055506116e88230857f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1661139f909392919063ffffffff16565b8173ffffffffffffffffffffffffffffffffffffffff16847f20c5b66cd5e4a4148323852541307bd30d5674f62e2247aefbd3dbae8be5e9188560405161172f9190611b14565b60405180910390a33073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040516117949190611b14565b60405180910390a350505050565b6000611804826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166118699092919063ffffffff16565b9050600081511115611864578080602001905181019061182491906127b3565b611863576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161185a90612852565b60405180910390fd5b5b505050565b60606118788484600085611881565b90509392505050565b6060824710156118c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118bd906128e4565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516118ef9190612975565b60006040518083038185875af1925050503d806000811461192c576040519150601f19603f3d011682016040523d82523d6000602084013e611931565b606091505b50915091506119428783838761194e565b92505050949350505050565b606083156119b05760008351036119a857611968856119c3565b6119a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161199e906129d8565b60405180910390fd5b5b8290506119bb565b6119ba83836119e6565b5b949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6000825111156119f95781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a2d9190612a4d565b60405180910390fd5b600080fd5b6000819050919050565b611a4e81611a3b565b8114611a5957600080fd5b50565b600081359050611a6b81611a45565b92915050565b600060208284031215611a8757611a86611a36565b5b6000611a9584828501611a5c565b91505092915050565b60008060008060808587031215611ab857611ab7611a36565b5b6000611ac687828801611a5c565b9450506020611ad787828801611a5c565b9350506040611ae887828801611a5c565b9250506060611af987828801611a5c565b91505092959194509250565b611b0e81611a3b565b82525050565b6000602082019050611b296000830184611b05565b92915050565b60008060408385031215611b4657611b45611a36565b5b6000611b5485828601611a5c565b9250506020611b6585828601611a5c565b9150509250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611b9a82611b6f565b9050919050565b611baa81611b8f565b82525050565b60008115159050919050565b611bc581611bb0565b82525050565b600061010082019050611be1600083018b611ba1565b611bee602083018a611b05565b611bfb6040830189611b05565b611c086060830188611b05565b611c156080830187611b05565b611c2260a0830186611b05565b611c2f60c0830185611b05565b611c3c60e0830184611bbc565b9998505050505050505050565b600061016082019050611c5f600083018e611b05565b611c6c602083018d611b05565b611c79604083018c611b05565b611c86606083018b611b05565b611c93608083018a611b05565b611ca060a0830189611b05565b611cad60c0830188611b05565b611cba60e0830187611b05565b611cc8610100830186611b05565b611cd6610120830185611ba1565b611ce4610140830184611bbc565b9c9b505050505050505050505050565b600080600080600060a08688031215611d1057611d0f611a36565b5b6000611d1e88828901611a5c565b9550506020611d2f88828901611a5c565b9450506040611d4088828901611a5c565b9350506060611d5188828901611a5c565b9250506080611d6288828901611a5c565b9150509295509295909350565b6000604082019050611d846000830185611b05565b611d916020830184611b05565b9392505050565b6000602082019050611dad6000830184611ba1565b92915050565b6000819050919050565b6000611dd8611dd3611dce84611b6f565b611db3565b611b6f565b9050919050565b6000611dea82611dbd565b9050919050565b6000611dfc82611ddf565b9050919050565b611e0c81611df1565b82525050565b6000602082019050611e276000830184611e03565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611e6782611a3b565b9150611e7283611a3b565b9250828202611e8081611a3b565b91508282048414831517611e9757611e96611e2d565b5b5092915050565b6000604082019050611eb36000830185611ba1565b611ec06020830184611ba1565b9392505050565b600081519050611ed681611a45565b92915050565b600060208284031215611ef257611ef1611a36565b5b6000611f0084828501611ec7565b91505092915050565b600082825260208201905092915050565b7f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000600082015250565b6000611f50601d83611f09565b9150611f5b82611f1a565b602082019050919050565b60006020820190508181036000830152611f7f81611f43565b9050919050565b7f646f65736e277420657869737400000000000000000000000000000000000000600082015250565b6000611fbc600d83611f09565b9150611fc782611f86565b602082019050919050565b60006020820190508181036000830152611feb81611faf565b9050919050565b6000611ffd82611a3b565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361202f5761202e611e2d565b5b600182019050919050565b60008160001c9050919050565b6000819050919050565b600061206461205f8361203a565b612047565b9050919050565b61207481611a3b565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006120ad6120a88361203a565b61207a565b9050919050565b6120bd81611b8f565b82525050565b60008160a01c9050919050565b600060ff82169050919050565b60006120f06120eb836120c3565b6120d0565b9050919050565b61210081611bb0565b82525050565b6101608201600080830154905061211c81612051565b612129600086018261206b565b506001830154905061213a81612051565b612147602086018261206b565b506002830154905061215881612051565b612165604086018261206b565b506003830154905061217681612051565b612183606086018261206b565b506004830154905061219481612051565b6121a1608086018261206b565b50600583015490506121b281612051565b6121bf60a086018261206b565b50600683015490506121d081612051565b6121dd60c086018261206b565b50600783015490506121ee81612051565b6121fb60e086018261206b565b506008830154905061220c81612051565b61221a61010086018261206b565b506009830154905061222b8161209a565b6122396101208601826120b4565b50612243816120dd565b6122516101408601826120f7565b5050505050565b60006101608201905061226e6000830184612106565b92915050565b600061227f82611a3b565b915061228a83611a3b565b92508282019050808211156122a2576122a1611e2d565b5b92915050565b60006122bb6122b68361203a565b6120d0565b9050919050565b610100820160008083015490506122d88161209a565b6122e560008601826120b4565b50600183015490506122f681612051565b612303602086018261206b565b506002830154905061231481612051565b612321604086018261206b565b506003830154905061233281612051565b61233f606086018261206b565b506004830154905061235081612051565b61235d608086018261206b565b506005830154905061236e81612051565b61237b60a086018261206b565b506006830154905061238c81612051565b61239960c086018261206b565b50600783015490506123aa816122a8565b6123b760e08601826120f7565b5050505050565b6000610100820190506123d460008301846122c2565b92915050565b7f6f6e6c7920706c616e206f776e65720000000000000000000000000000000000600082015250565b6000612410600f83611f09565b915061241b826123da565b602082019050919050565b6000602082019050818103600083015261243f81612403565b9050919050565b7f6e6f74206f776e65720000000000000000000000000000000000000000000000600082015250565b600061247c600983611f09565b915061248782612446565b602082019050919050565b600060208201905081810360008301526124ab8161246f565b9050919050565b7f696e73756666696369656e742066756e64730000000000000000000000000000600082015250565b60006124e8601283611f09565b91506124f3826124b2565b602082019050919050565b60006020820190508181036000830152612517816124db565b9050919050565b600061252982611a3b565b915061253483611a3b565b925082820390508181111561254c5761254b611e2d565b5b92915050565b60006040820190506125676000830185611ba1565b6125746020830184611b05565b9392505050565b7f746f6f206561726c790000000000000000000000000000000000000000000000600082015250565b60006125b1600983611f09565b91506125bc8261257b565b602082019050919050565b600060208201905081810360008301526125e0816125a4565b9050919050565b7f706c616e20656e64656400000000000000000000000000000000000000000000600082015250565b600061261d600a83611f09565b9150612628826125e7565b602082019050919050565b6000602082019050818103600083015261264c81612610565b9050919050565b60006060820190506126686000830186611ba1565b6126756020830185611ba1565b6126826040830184611b05565b949350505050565b610160820160008201516126a1600085018261206b565b5060208201516126b4602085018261206b565b5060408201516126c7604085018261206b565b5060608201516126da606085018261206b565b5060808201516126ed608085018261206b565b5060a082015161270060a085018261206b565b5060c082015161271360c085018261206b565b5060e082015161272660e085018261206b565b5061010082015161273b61010085018261206b565b506101208201516127506101208501826120b4565b506101408201516127656101408501826120f7565b50505050565b600061016082019050612781600083018461268a565b92915050565b61279081611bb0565b811461279b57600080fd5b50565b6000815190506127ad81612787565b92915050565b6000602082840312156127c9576127c8611a36565b5b60006127d78482850161279e565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b600061283c602a83611f09565b9150612847826127e0565b604082019050919050565b6000602082019050818103600083015261286b8161282f565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b60006128ce602683611f09565b91506128d982612872565b604082019050919050565b600060208201905081810360008301526128fd816128c1565b9050919050565b600081519050919050565b600081905092915050565b60005b8381101561293857808201518184015260208101905061291d565b60008484015250505050565b600061294f82612904565b612959818561290f565b935061296981856020860161291a565b80840191505092915050565b60006129818284612944565b915081905092915050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b60006129c2601d83611f09565b91506129cd8261298c565b602082019050919050565b600060208201905081810360008301526129f1816129b5565b9050919050565b600081519050919050565b6000601f19601f8301169050919050565b6000612a1f826129f8565b612a298185611f09565b9350612a3981856020860161291a565b612a4281612a03565b840191505092915050565b60006020820190508181036000830152612a678184612a14565b90509291505056fea2646970667358221220e1d77d29467eef7ad05e606f8aba04b6c2980c4a42a8a2981baf7f5e8848b61964736f6c63430008110033000000000000000000000000765de816845861e75a25fca122bb6898b8b1282a0000000000000000000000002e7997baf30435d70b5a2ec3ea334975b16c5204
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100a95760003560e01c806390513e1a1161007157806390513e1a1461017d5780639d92068814610199578063a601c2c6146101d3578063aaec77e5146101ef578063f90ef4ac14610220578063fc0c546a1461023e576100a9565b80630cf9e555146100ae578063223f83e2146100ca5780632b06fa74146100fa57806385fcc9a2146101165780638818e16514610146575b600080fd5b6100c860048036038101906100c39190611a71565b61025c565b005b6100e460048036038101906100df9190611a9e565b610268565b6040516100f19190611b14565b60405180910390f35b610114600480360381019061010f9190611b2f565b610640565b005b610130600480360381019061012b9190611b2f565b6107be565b60405161013d9190611b14565b60405180910390f35b610160600480360381019061015b9190611a71565b610959565b604051610174989796959493929190611bcb565b60405180910390f35b61019760048036038101906101929190611a71565b6109ce565b005b6101b360048036038101906101ae9190611a71565b610adf565b6040516101ca9b9a99989796959493929190611c49565b60405180910390f35b6101ed60048036038101906101e89190611b2f565b610b66565b005b61020960048036038101906102049190611cf4565b610e0c565b604051610217929190611d6f565b60405180910390f35b610228610e33565b6040516102359190611d98565b60405180910390f35b610246610e57565b6040516102539190611e12565b60405180910390f35b61026581610e7b565b50565b60008083856102779190611e5c565b9050807f000000000000000000000000765de816845861e75a25fca122bb6898b8b1282a73ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e33306040518363ffffffff1660e01b81526004016102d5929190611e9e565b602060405180830381865afa1580156102f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103169190611edc565b1015610357576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161034e90611f66565b60405180910390fd5b600060026000888152602001908152602001600020604051806101000160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820154815260200160028201548152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820160009054906101000a900460ff16151515158152505090508681602001511461046d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046490611fd2565b60405180910390fd5b600060016000815461047e90611ff2565b91905081905590506040518061016001604052808981526020018281526020018481526020016000815260200188815260200187815260200160008152602001600081526020018681526020013373ffffffffffffffffffffffffffffffffffffffff1681526020016001151581525060036000838152602001908152602001600020600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e0820151816007015561010082015181600801556101208201518160090160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506101408201518160090160146101000a81548160ff0219169083151502179055509050506105d181611217565b3373ffffffffffffffffffffffffffffffffffffffff16817ffd671f7182c83d1e07d1bd1748354402aa8a9193629cad7a0fbaac5c8ffe28186003600085815260200190815260200160002060405161062a9190612258565b60405180910390a3809350505050949350505050565b60006002600084815260200190815260200160002090508281600101541461069d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161069490611fd2565b60405180910390fd5b818160040160008282546106b19190612274565b925050819055506107053330847f000000000000000000000000765de816845861e75a25fca122bb6898b8b1282a73ffffffffffffffffffffffffffffffffffffffff1661139f909392919063ffffffff16565b3373ffffffffffffffffffffffffffffffffffffffff16837f20c5b66cd5e4a4148323852541307bd30d5674f62e2247aefbd3dbae8be5e9188460405161074c9190611b14565b60405180910390a33073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516107b19190611b14565b60405180910390a3505050565b600060016000808282546107d29190612274565b925050819055506040518061010001604052803373ffffffffffffffffffffffffffffffffffffffff1681526020016000548152602001848152602001838152602001600081526020014281526020016000815260200160001515815250600260008054815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e08201518160070160006101000a81548160ff0219169083151502179055509050503373ffffffffffffffffffffffffffffffffffffffff166000547f71acf40162e8307c5fd5ec4e08cd622f5e5d29c2b1982af5421d95c0b1d117cf600260008054815260200190815260200160002060405161094691906123be565b60405180910390a3600054905092915050565b60026020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010154908060020154908060030154908060040154908060050154908060060154908060070160009054906101000a900460ff16905088565b6003600082815260200190815260200160002060090160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a72576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a6990612426565b60405180910390fd5b610a7b81611428565b3373ffffffffffffffffffffffffffffffffffffffff16817f1508b4f1d043dd53494e9f162026083edd68e32aa1e6e2d8818021c384fe080a60036000858152602001908152602001600020604051610ad49190612258565b60405180910390a350565b60036020528060005260406000206000915090508060000154908060010154908060020154908060030154908060040154908060050154908060060154908060070154908060080154908060090160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060090160149054906101000a900460ff1690508b565b600060026000848152602001908152602001600020905082816001015414610bc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bba90611fd2565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610c55576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c4c90612492565b60405180910390fd5b8181600401541015610c9c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c93906124fe565b60405180910390fd5b81816004016000828254610cb0919061251e565b92505081905550610d227f0000000000000000000000002e7997baf30435d70b5a2ec3ea334975b16c5204837f000000000000000000000000765de816845861e75a25fca122bb6898b8b1282a73ffffffffffffffffffffffffffffffffffffffff1661159d9092919063ffffffff16565b60018160070160006101000a81548160ff021916908315150217905550428160060181905550827f486095ee3674fb24bd0a2fcf31db414056448c4f6e206484eae4bcbb17fea35a3384604051610d7a929190612552565b60405180910390a27f0000000000000000000000002e7997baf30435d70b5a2ec3ea334975b16c520473ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610dff9190611b14565b60405180910390a3505050565b600080610e1987876107be565b9150610e2782868686610268565b90509550959350505050565b7f0000000000000000000000002e7997baf30435d70b5a2ec3ea334975b16c520481565b7f000000000000000000000000765de816845861e75a25fca122bb6898b8b1282a81565b600060036000838152602001908152602001600020604051806101600160405290816000820154815260200160018201548152602001600282015481526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016009820160149054906101000a900460ff161515151581525050905060008160800151905060008261012001519050600060018460c00151610f8f9190612274565b9050428460e001511115610fd8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fcf906125c7565b60405180910390fd5b83610140015161101d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161101490612633565b60405180910390fd5b827f000000000000000000000000765de816845861e75a25fca122bb6898b8b1282a73ffffffffffffffffffffffffffffffffffffffff166370a08231846040518263ffffffff1660e01b81526004016110779190611d98565b602060405180830381865afa158015611094573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110b89190611edc565b101580156111615750827f000000000000000000000000765de816845861e75a25fca122bb6898b8b1282a73ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e84306040518363ffffffff1660e01b815260040161111d929190611e9e565b602060405180830381865afa15801561113a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061115e9190611edc565b10155b156112105761117584600001518484611623565b8260036000878152602001908152602001600020600301600082825461119b9190612274565b9250508190555080600360008781526020019081526020016000206006018190555080857fbec3f63cb2d17ab9edd65a1a7ab167efd9802d37681c490ed1b215c6995bb3cb60405160405180910390a38360a001518110156112055761120085611217565b61120f565b61120e85611428565b5b5b5050505050565b600060036000838152602001908152602001600020604051806101600160405290816000820154815260200160018201548152602001600282015481526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016009820160149054906101000a900460ff161515151581525050905060004260036000858152602001908152602001600020600801546113299190612274565b9050600060018360c0015161133e9190612274565b9050816003600086815260200190815260200160002060070181905550826080015182857f7191b4f9ba2ec111b9ae2a916ba78702dfbfe79ca993c2ce4321ff79a52a4c9c846040516113919190611b14565b60405180910390a450505050565b611422846323b872dd60e01b8585856040516024016113c093929190612653565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506117a2565b50505050565b600060036000838152602001908152602001600020604051806101600160405290816000820154815260200160018201548152602001600282015481526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016009820160149054906101000a900460ff161515151581525050905060006003600084815260200190815260200160002060090160146101000a81548160ff02191690831515021790555080610120015173ffffffffffffffffffffffffffffffffffffffff16827f5e2829107023b345d1e5d6a90c0485ea550de003591f622a48dd48034b80486b83604051611591919061276b565b60405180910390a35050565b61161e8363a9059cbb60e01b84846040516024016115bc929190612552565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506117a2565b505050565b600060026000858152602001908152602001600020905083816001015414611680576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167790611fd2565b60405180910390fd5b828160040160008282546116949190612274565b925050819055506116e88230857f000000000000000000000000765de816845861e75a25fca122bb6898b8b1282a73ffffffffffffffffffffffffffffffffffffffff1661139f909392919063ffffffff16565b8173ffffffffffffffffffffffffffffffffffffffff16847f20c5b66cd5e4a4148323852541307bd30d5674f62e2247aefbd3dbae8be5e9188560405161172f9190611b14565b60405180910390a33073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040516117949190611b14565b60405180910390a350505050565b6000611804826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166118699092919063ffffffff16565b9050600081511115611864578080602001905181019061182491906127b3565b611863576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161185a90612852565b60405180910390fd5b5b505050565b60606118788484600085611881565b90509392505050565b6060824710156118c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118bd906128e4565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516118ef9190612975565b60006040518083038185875af1925050503d806000811461192c576040519150601f19603f3d011682016040523d82523d6000602084013e611931565b606091505b50915091506119428783838761194e565b92505050949350505050565b606083156119b05760008351036119a857611968856119c3565b6119a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161199e906129d8565b60405180910390fd5b5b8290506119bb565b6119ba83836119e6565b5b949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6000825111156119f95781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a2d9190612a4d565b60405180910390fd5b600080fd5b6000819050919050565b611a4e81611a3b565b8114611a5957600080fd5b50565b600081359050611a6b81611a45565b92915050565b600060208284031215611a8757611a86611a36565b5b6000611a9584828501611a5c565b91505092915050565b60008060008060808587031215611ab857611ab7611a36565b5b6000611ac687828801611a5c565b9450506020611ad787828801611a5c565b9350506040611ae887828801611a5c565b9250506060611af987828801611a5c565b91505092959194509250565b611b0e81611a3b565b82525050565b6000602082019050611b296000830184611b05565b92915050565b60008060408385031215611b4657611b45611a36565b5b6000611b5485828601611a5c565b9250506020611b6585828601611a5c565b9150509250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611b9a82611b6f565b9050919050565b611baa81611b8f565b82525050565b60008115159050919050565b611bc581611bb0565b82525050565b600061010082019050611be1600083018b611ba1565b611bee602083018a611b05565b611bfb6040830189611b05565b611c086060830188611b05565b611c156080830187611b05565b611c2260a0830186611b05565b611c2f60c0830185611b05565b611c3c60e0830184611bbc565b9998505050505050505050565b600061016082019050611c5f600083018e611b05565b611c6c602083018d611b05565b611c79604083018c611b05565b611c86606083018b611b05565b611c93608083018a611b05565b611ca060a0830189611b05565b611cad60c0830188611b05565b611cba60e0830187611b05565b611cc8610100830186611b05565b611cd6610120830185611ba1565b611ce4610140830184611bbc565b9c9b505050505050505050505050565b600080600080600060a08688031215611d1057611d0f611a36565b5b6000611d1e88828901611a5c565b9550506020611d2f88828901611a5c565b9450506040611d4088828901611a5c565b9350506060611d5188828901611a5c565b9250506080611d6288828901611a5c565b9150509295509295909350565b6000604082019050611d846000830185611b05565b611d916020830184611b05565b9392505050565b6000602082019050611dad6000830184611ba1565b92915050565b6000819050919050565b6000611dd8611dd3611dce84611b6f565b611db3565b611b6f565b9050919050565b6000611dea82611dbd565b9050919050565b6000611dfc82611ddf565b9050919050565b611e0c81611df1565b82525050565b6000602082019050611e276000830184611e03565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611e6782611a3b565b9150611e7283611a3b565b9250828202611e8081611a3b565b91508282048414831517611e9757611e96611e2d565b5b5092915050565b6000604082019050611eb36000830185611ba1565b611ec06020830184611ba1565b9392505050565b600081519050611ed681611a45565b92915050565b600060208284031215611ef257611ef1611a36565b5b6000611f0084828501611ec7565b91505092915050565b600082825260208201905092915050565b7f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000600082015250565b6000611f50601d83611f09565b9150611f5b82611f1a565b602082019050919050565b60006020820190508181036000830152611f7f81611f43565b9050919050565b7f646f65736e277420657869737400000000000000000000000000000000000000600082015250565b6000611fbc600d83611f09565b9150611fc782611f86565b602082019050919050565b60006020820190508181036000830152611feb81611faf565b9050919050565b6000611ffd82611a3b565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361202f5761202e611e2d565b5b600182019050919050565b60008160001c9050919050565b6000819050919050565b600061206461205f8361203a565b612047565b9050919050565b61207481611a3b565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006120ad6120a88361203a565b61207a565b9050919050565b6120bd81611b8f565b82525050565b60008160a01c9050919050565b600060ff82169050919050565b60006120f06120eb836120c3565b6120d0565b9050919050565b61210081611bb0565b82525050565b6101608201600080830154905061211c81612051565b612129600086018261206b565b506001830154905061213a81612051565b612147602086018261206b565b506002830154905061215881612051565b612165604086018261206b565b506003830154905061217681612051565b612183606086018261206b565b506004830154905061219481612051565b6121a1608086018261206b565b50600583015490506121b281612051565b6121bf60a086018261206b565b50600683015490506121d081612051565b6121dd60c086018261206b565b50600783015490506121ee81612051565b6121fb60e086018261206b565b506008830154905061220c81612051565b61221a61010086018261206b565b506009830154905061222b8161209a565b6122396101208601826120b4565b50612243816120dd565b6122516101408601826120f7565b5050505050565b60006101608201905061226e6000830184612106565b92915050565b600061227f82611a3b565b915061228a83611a3b565b92508282019050808211156122a2576122a1611e2d565b5b92915050565b60006122bb6122b68361203a565b6120d0565b9050919050565b610100820160008083015490506122d88161209a565b6122e560008601826120b4565b50600183015490506122f681612051565b612303602086018261206b565b506002830154905061231481612051565b612321604086018261206b565b506003830154905061233281612051565b61233f606086018261206b565b506004830154905061235081612051565b61235d608086018261206b565b506005830154905061236e81612051565b61237b60a086018261206b565b506006830154905061238c81612051565b61239960c086018261206b565b50600783015490506123aa816122a8565b6123b760e08601826120f7565b5050505050565b6000610100820190506123d460008301846122c2565b92915050565b7f6f6e6c7920706c616e206f776e65720000000000000000000000000000000000600082015250565b6000612410600f83611f09565b915061241b826123da565b602082019050919050565b6000602082019050818103600083015261243f81612403565b9050919050565b7f6e6f74206f776e65720000000000000000000000000000000000000000000000600082015250565b600061247c600983611f09565b915061248782612446565b602082019050919050565b600060208201905081810360008301526124ab8161246f565b9050919050565b7f696e73756666696369656e742066756e64730000000000000000000000000000600082015250565b60006124e8601283611f09565b91506124f3826124b2565b602082019050919050565b60006020820190508181036000830152612517816124db565b9050919050565b600061252982611a3b565b915061253483611a3b565b925082820390508181111561254c5761254b611e2d565b5b92915050565b60006040820190506125676000830185611ba1565b6125746020830184611b05565b9392505050565b7f746f6f206561726c790000000000000000000000000000000000000000000000600082015250565b60006125b1600983611f09565b91506125bc8261257b565b602082019050919050565b600060208201905081810360008301526125e0816125a4565b9050919050565b7f706c616e20656e64656400000000000000000000000000000000000000000000600082015250565b600061261d600a83611f09565b9150612628826125e7565b602082019050919050565b6000602082019050818103600083015261264c81612610565b9050919050565b60006060820190506126686000830186611ba1565b6126756020830185611ba1565b6126826040830184611b05565b949350505050565b610160820160008201516126a1600085018261206b565b5060208201516126b4602085018261206b565b5060408201516126c7604085018261206b565b5060608201516126da606085018261206b565b5060808201516126ed608085018261206b565b5060a082015161270060a085018261206b565b5060c082015161271360c085018261206b565b5060e082015161272660e085018261206b565b5061010082015161273b61010085018261206b565b506101208201516127506101208501826120b4565b506101408201516127656101408501826120f7565b50505050565b600061016082019050612781600083018461268a565b92915050565b61279081611bb0565b811461279b57600080fd5b50565b6000815190506127ad81612787565b92915050565b6000602082840312156127c9576127c8611a36565b5b60006127d78482850161279e565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b600061283c602a83611f09565b9150612847826127e0565b604082019050919050565b6000602082019050818103600083015261286b8161282f565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b60006128ce602683611f09565b91506128d982612872565b604082019050919050565b600060208201905081810360008301526128fd816128c1565b9050919050565b600081519050919050565b600081905092915050565b60005b8381101561293857808201518184015260208101905061291d565b60008484015250505050565b600061294f82612904565b612959818561290f565b935061296981856020860161291a565b80840191505092915050565b60006129818284612944565b915081905092915050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b60006129c2601d83611f09565b91506129cd8261298c565b602082019050919050565b600060208201905081810360008301526129f1816129b5565b9050919050565b600081519050919050565b6000601f19601f8301169050919050565b6000612a1f826129f8565b612a298185611f09565b9350612a3981856020860161291a565b612a4281612a03565b840191505092915050565b60006020820190508181036000830152612a678184612a14565b90509291505056fea2646970667358221220e1d77d29467eef7ad05e606f8aba04b6c2980c4a42a8a2981baf7f5e8848b61964736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000765de816845861e75a25fca122bb6898b8b1282a0000000000000000000000002e7997baf30435d70b5a2ec3ea334975b16c5204
-----Decoded View---------------
Arg [0] : ERC20_ (address): 0x765DE816845861e75A25fCA122bb6898B8B1282a
Arg [1] : operatorWallet_ (address): 0x2e7997BaF30435d70b5a2EC3eA334975b16C5204
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000765de816845861e75a25fca122bb6898b8b1282a
Arg [1] : 0000000000000000000000002e7997baf30435d70b5a2ec3ea334975b16c5204
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.