Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 1 from a total of 1 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| New Recurring Bi... | 7042391 | 2571 days ago | IN | 0 ETH | 0.00336394 |
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| - | 7042391 | 2571 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
RecurringBillingContractFactory
Compiler Version
v0.5.2+commit.1df8f40c
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity)
/**
*Submitted for verification at Etherscan.io on 2019-01-10
*/
/**
* Token recurring billing smart contracts, which enable recurring billing feature for ERC20-compatible tokens.
* Developed by DreamTeam.GG contributors. Visit dreamteam.gg and github.com/dreamteam-gg/smart-contracts for more info.
* Copyright © 2019 DREAMTEAM.
* Licensed under the Apache License, Version 2.0 (the "License").
*/
pragma solidity 0.5.2;
interface ERC20CompatibleToken {
function balanceOf(address tokenOwner) external view returns (uint balance);
function allowance(address tokenOwner, address spender) external view returns (uint remaining);
function transfer (address to, uint tokens) external returns (bool success);
function transferFrom (address from, address to, uint tokens) external returns (bool success);
}
/**
* Math operations with safety checks that throw on overflows.
*/
library SafeMath {
function mul (uint256 a, uint256 b) internal pure returns (uint256 c) {
if (a == 0) {
return 0;
}
c = a * b;
require(c / a == b);
return c;
}
function div (uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
function sub (uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a);
return a - b;
}
function add (uint256 a, uint256 b) internal pure returns (uint256 c) {
c = a + b;
require(c >= a);
return c;
}
}
/**
* Factory that creates recurring billing smart contracts for specified token.
* You can enable recurring billing for your own ERC20-compatible tokens!
* Find the documentation here: https://github.com/dreamteam-gg/smart-contracts#smart-contracts-documentation
*/
contract RecurringBillingContractFactory {
event NewRecurringBillingContractCreated(address token, address recurringBillingContract);
function newRecurringBillingContract (address tokenAddress) public returns (address recurringBillingContractAddress) {
TokenRecurringBilling rb = new TokenRecurringBilling(tokenAddress);
emit NewRecurringBillingContractCreated(tokenAddress, address(rb));
return address(rb);
}
}
/**
* Smart contract for recurring billing in ERC20-compatible tokens. This smart contract defines workflow between
* a merchant and a customer. Workflow:
* 1. Merchant registers theirselves in this smart contract using `registerNewMerchant`.
* 1.1. Merchant specifies `beneficiary` address, which receives tokens.
* 1.2. Merchant specifies `merchant` address, which is able to change `merchant` and `beneficiary` addresses.
* 1.3. Merchant specified an address that is authorized to call `charge` related to this merchant.
* 1.3.1. Later, merchant can (de)authorize another addresses to call `charge` using `changeMerchantChargingAccount`.
* 1.4. As a result, merchant gets `merchantId`, which is used to initialize recurring billing by customers.
* 1.5. Merchant account can change their `beneficiary`, `merchant` and authorized charging addresses by calling:
* 1.4.1. Function `changeMerchantAccount`, which changes account that can control this merchant (`merchantId`).
* 1.4.2. Function `changeMerchantBeneficiaryAddress`, which changes merchant's `beneficiary`.
* 1.4.3. Function `changeMerchantChargingAccount`, which (de)authorizes addresses to call `charge` on behalf of this merchant.
* 2. According to an off-chain agreement with merchant, customer calls `allowRecurringBilling` and:
* 2.1. Specifies `billingId`, which is given off-chain by merchant (merchant will listen blockchain Event on this ID).
* 2.2. Specifies `merchantId`, the merchant which will receive tokens.
* 2.3. Specifies `period` in seconds, during which only one charge can occur.
* 2.4. Specifies `value`, amount in tokens which can be charged each `period`.
* 2.4.1. If the customer doesn't have at least `value` tokens, `allowRecurringBilling` errors.
* 2.4.2. If the customer haven't approved at least `value` tokens for a smart contract, `allowRecurringBilling` errors.
* 2.5. `billingId` is then used by merchant to charge customer each `period`.
* 3. Merchant use authorized accounts (1.3) to call the `charge` function each `period` to charge agreed amount from a customer.
* 3.1. It is impossible to call `charge` if the date of the last charge is less than `period`.
* 3.2. Calling `charge` cancels billing when called after 2 `period`s from the last charge.
* 3.3. Thus, to successfully charge an account, `charge` must be strictly called within 1 and 2 `period`s after the last charge.
* 3.4. Calling `charge` errors if any of the following occur:
* 3.4.1. Customer canceled recurring billing with `cancelRecurringBilling`.
* 3.4.2. Customer's balance is lower than the chargeable amount.
* 3.4.3. Customer's allowance to the smart contract is less than the chargable amount.
* 3.4.4. Specified `billingId` does not exists.
* 3.4.5. There's no `period` passed since the last charge.
* 3.5. Next charge date increments strictly by `period` each charge, thus, there's no need to exec `charge` strictly on time.
* 4. Customer can cancel further billing by calling `cancelRecurringBilling` and passing `billingId`.
* 5. TokenRecurringBilling smart contract implements `receiveApproval` function for allowing/cancelling billing within one call from
* the token smart contract. Parameter `data` is encoded as tightly-packed (uint256 metadata, uint256 billingId).
* 5.1. `metadata` is encoded using `encodeBillingMetadata`.
* 5.2. As for `receiveApproval`, `lastChargeAt` in `metadata` is used as an action identifier.
* 5.2.1. `lastChargeAt=0` specifies that customer wants to allow new recurring billing.
* 5.2.2. `lastChargeAt=1` specifies that customer wants to cancel existing recurring billing.
* 5.3. Make sure that passed `bytes` parameter is exactly 64 bytes in length.
*/
contract TokenRecurringBilling {
using SafeMath for uint256;
event BillingAllowed(uint256 indexed billingId, address customer, uint256 merchantId, uint256 timestamp, uint256 period, uint256 value);
event BillingCharged(uint256 indexed billingId, uint256 timestamp, uint256 nextChargeTimestamp);
event BillingCanceled(uint256 indexed billingId);
event MerchantRegistered(uint256 indexed merchantId, address merchantAccount, address beneficiaryAddress);
event MerchantAccountChanged(uint256 indexed merchantId, address merchantAccount);
event MerchantBeneficiaryAddressChanged(uint256 indexed merchantId, address beneficiaryAddress);
event MerchantChargingAccountAllowed(uint256 indexed merchantId, address chargingAccount, bool allowed);
struct BillingRecord {
address customer; // Billing address (those who pay).
uint256 metadata; // Metadata packs 5 values to save on storage. Metadata spec (from first to last byte):
// + uint32 period; // Billing period in seconds; configurable period of up to 136 years.
// + uint32 merchantId; // Merchant ID; up to ~4.2 Milliard IDs.
// + uint48 lastChargeAt; // When the last charge occurred; up to year 999999+.
// + uint144 value; // Billing value charrged each period; up to ~22 septillion tokens with 18 decimals
}
struct Merchant {
address merchant; // Merchant admin address that can change all merchant struct properties.
address beneficiary; // Address receiving tokens.
}
enum receiveApprovalAction { // In receiveApproval, `lastChargeAt` in passed `metadata` specifies an action to execute.
allowRecurringBilling, // == 0
cancelRecurringBilling // == 1
}
uint256 public lastMerchantId; // This variable increments on each new merchant registered, generating unique ids for merchant.
ERC20CompatibleToken public token; // Token address.
mapping(uint256 => BillingRecord) public billingRegistry; // List of all billings registered by ID.
mapping(uint256 => Merchant) public merchantRegistry; // List of all merchants registered by ID.
mapping(uint256 => mapping(address => bool)) public merchantChargingAccountAllowed; // Accounts that are allowed to charge customers.
// Checks whether {merchant} owns {merchantId}
modifier isMerchant (uint256 merchantId) {
require(merchantRegistry[merchantId].merchant == msg.sender, "Sender is not a merchant");
_;
}
// Checks whether {customer} owns {billingId}
modifier isCustomer (uint256 billingId) {
require(billingRegistry[billingId].customer == msg.sender, "Sender is not a customer");
_;
}
// Guarantees that the transaction is sent by token smart contract only.
modifier tokenOnly () {
require(msg.sender == address(token), "Sender is not a token");
_;
}
/// ======================================================== Constructor ========================================================= \\\
// Creates a recurring billing smart contract for particular token.
constructor (address tokenAddress) public {
token = ERC20CompatibleToken(tokenAddress);
}
/// ====================================================== Public Functions ====================================================== \\\
// Enables merchant with {merchantId} to charge transaction signer's account according to specified {value} and {period}.
function allowRecurringBilling (uint256 billingId, uint256 merchantId, uint256 value, uint256 period) public {
allowRecurringBillingInternal(msg.sender, merchantId, billingId, value, period);
}
// Enables anyone to become a merchant, charging tokens for their services.
function registerNewMerchant (address beneficiary, address chargingAccount) public returns (uint256 merchantId) {
merchantId = ++lastMerchantId;
Merchant storage record = merchantRegistry[merchantId];
record.merchant = msg.sender;
record.beneficiary = beneficiary;
emit MerchantRegistered(merchantId, msg.sender, beneficiary);
changeMerchantChargingAccount(merchantId, chargingAccount, true);
}
/// =========================================== Public Functions with Restricted Access =========================================== \\\
// Calcels recurring billing with id {billingId} if it is owned by a transaction signer.
function cancelRecurringBilling (uint256 billingId) public isCustomer(billingId) {
cancelRecurringBillingInternal(billingId);
}
// Charges customer's account according to defined {billingId} billing rules. Only merchant's authorized accounts can charge the customer.
function charge (uint256 billingId) public {
BillingRecord storage billingRecord = billingRegistry[billingId];
(uint256 value, uint256 lastChargeAt, uint256 merchantId, uint256 period) = decodeBillingMetadata(billingRecord.metadata);
require(merchantChargingAccountAllowed[merchantId][msg.sender], "Sender is not allowed to charge");
require(merchantId != 0, "Billing does not exist");
require(lastChargeAt.add(period) <= now, "Charged too early");
// If 2 periods have already passed since the last charge (or beginning), no further charges are possible
// and recurring billing is canceled in case of a charge.
if (now > lastChargeAt.add(period.mul(2))) {
cancelRecurringBillingInternal(billingId);
return;
}
require(
token.transferFrom(billingRecord.customer, merchantRegistry[merchantId].beneficiary, value),
"Unable to charge customer"
);
billingRecord.metadata = encodeBillingMetadata(value, lastChargeAt.add(period), merchantId, period);
emit BillingCharged(billingId, now, lastChargeAt.add(period.mul(2)));
}
/**
* Invoked by a token smart contract on approveAndCall. Allows or cancels recurring billing.
* @param sender - Address that approved some tokens for this smart contract.
* @param data - Tightly-packed (uint256,uint256) values of (metadata, billingId). Metadata's `lastChargeAt`
* specifies an action to perform (see `receiveApprovalAction` enum).
*/
function receiveApproval (address sender, uint, address, bytes calldata data) external tokenOnly {
// The token contract MUST guarantee that "sender" is actually the token owner, and metadata is signed by a token owner.
require(data.length == 64, "Invalid data length");
// `action` is used instead of `lastCahrgeAt` to save some space.
(uint256 value, uint256 action, uint256 merchantId, uint256 period) = decodeBillingMetadata(bytesToUint256(data, 0));
uint256 billingId = bytesToUint256(data, 32);
if (action == uint256(receiveApprovalAction.allowRecurringBilling)) {
allowRecurringBillingInternal(sender, merchantId, billingId, value, period);
} else if (action == uint256(receiveApprovalAction.cancelRecurringBilling)) {
require(billingRegistry[billingId].customer == sender, "Unable to cancel recurring billing of another customer");
cancelRecurringBillingInternal(billingId);
} else {
revert("Unknown action provided");
}
}
// Changes merchant account with id {merchantId} to {newMerchantAccount}.
function changeMerchantAccount (uint256 merchantId, address newMerchantAccount) public isMerchant(merchantId) {
merchantRegistry[merchantId].merchant = newMerchantAccount;
emit MerchantAccountChanged(merchantId, newMerchantAccount);
}
// Changes merchant's beneficiary address (address that receives charged tokens) to {newBeneficiaryAddress}.
function changeMerchantBeneficiaryAddress (uint256 merchantId, address newBeneficiaryAddress) public isMerchant(merchantId) {
merchantRegistry[merchantId].beneficiary = newBeneficiaryAddress;
emit MerchantBeneficiaryAddressChanged(merchantId, newBeneficiaryAddress);
}
// Allows or disallows particular {account} to charge customers related to this merchant.
function changeMerchantChargingAccount (uint256 merchantId, address account, bool allowed) public isMerchant(merchantId) {
merchantChargingAccountAllowed[merchantId][account] = allowed;
emit MerchantChargingAccountAllowed(merchantId, account, allowed);
}
/// ================================================== Public Utility Functions ================================================== \\\
// Used to encode 5 values into one uint256 value. This is primarily made for cheaper storage.
function encodeBillingMetadata (
uint256 value,
uint256 lastChargeAt,
uint256 merchantId,
uint256 period
) public pure returns (uint256 result) {
require(
value < 2 ** 144
&& lastChargeAt < 2 ** 48
&& merchantId < 2 ** 32
&& period < 2 ** 32,
"Invalid input sizes to encode"
);
result = value;
result |= lastChargeAt << (144);
result |= merchantId << (144 + 48);
result |= period << (144 + 48 + 32);
return result;
}
// Used to decode 5 values from one uint256 value encoded by `encodeBillingMetadata` function.
function decodeBillingMetadata (uint256 encodedData) public pure returns (
uint256 value,
uint256 lastChargeAt,
uint256 merchantId,
uint256 period
) {
value = uint144(encodedData);
lastChargeAt = uint48(encodedData >> (144));
merchantId = uint32(encodedData >> (144 + 48));
period = uint32(encodedData >> (144 + 48 + 32));
}
/// ================================================ Internal (Private) Functions ================================================ \\\
// Allows recurring billing. Noone but this contract can call this function.
function allowRecurringBillingInternal (
address customer,
uint256 merchantId,
uint256 billingId,
uint256 value,
uint256 period
) internal {
require(merchantId <= lastMerchantId && merchantId != 0, "Invalid merchant specified");
require(period < now, "Invalid period specified");
require(token.balanceOf(customer) >= value, "Not enough tokens for the first charge");
require(token.allowance(customer, address(this)) >= value, "Tokens are not approved for this smart contract");
require(billingRegistry[billingId].customer == address(0x0), "Recurring billing with this ID is already registered");
BillingRecord storage newRecurringBilling = billingRegistry[billingId];
newRecurringBilling.metadata = encodeBillingMetadata(value, now.sub(period), merchantId, period);
newRecurringBilling.customer = customer;
emit BillingAllowed(billingId, customer, merchantId, now, period, value);
}
// Cancels recurring billing. Noone but this contract can call this function.
function cancelRecurringBillingInternal (uint256 billingId) internal {
delete billingRegistry[billingId];
emit BillingCanceled(billingId);
}
// Utility function to convert bytes type to uint256. Noone but this contract can call this function.
function bytesToUint256(bytes memory input, uint offset) internal pure returns (uint256 output) {
assembly { output := mload(add(add(input, 32), offset)) }
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"constant":false,"inputs":[{"name":"tokenAddress","type":"address"}],"name":"newRecurringBillingContract","outputs":[{"name":"recurringBillingContractAddress","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"token","type":"address"},{"indexed":false,"name":"recurringBillingContract","type":"address"}],"name":"NewRecurringBillingContractCreated","type":"event"}]Contract Creation Code
608060405234801561001057600080fd5b5061162f806100206000396000f3fe608060405234801561001057600080fd5b5060043610610047577c01000000000000000000000000000000000000000000000000000000006000350463ddcfa217811461004c575b600080fd5b61007f6004803603602081101561006257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166100a8565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b600080826100b461014a565b73ffffffffffffffffffffffffffffffffffffffff909116815260405190819003602001906000f0801580156100ee573d6000803e3d6000fd5b506040805173ffffffffffffffffffffffffffffffffffffffff80871682528316602082015281519293507f9f6cf7ccb2e4f68c7ce568594283c8d89ee6a64266981b12086ae803e7e75500929081900390910190a192915050565b6040516114a98061015b8339019056fe608060405234801561001057600080fd5b506040516020806114a98339810180604052602081101561003057600080fd5b505160018054600160a060020a031916600160a060020a03909216919091179055611449806100606000396000f3fe608060405234801561001057600080fd5b50600436106100f95760003560e060020a9004806382ef2ad01161009b578063e457e1e51161006a578063e457e1e514610373578063ee95a9de14610390578063f1e8ace7146103be578063fc0c546a14610401576100f9565b806382ef2ad01461027f5780638f4ffcb1146102875780639cd106a814610316578063c446ae7014610333576100f9565b8063440b2355116100d7578063440b2355146101a15780634c18e960146101e45780636e2f10bd146102135780637fb339d61461023f576100f9565b806317c3925f146100fe5780632faa5e3c1461013f5780633913848e1461016d575b600080fd5b61012d6004803603608081101561011457600080fd5b5080359060208101359060408101359060600135610425565b60408051918252519081900360200190f35b61016b6004803603604081101561015557600080fd5b5080359060200135600160a060020a031661050b565b005b61016b6004803603606081101561018357600080fd5b50803590600160a060020a03602082013516906040013515156105ed565b6101be600480360360208110156101b757600080fd5b50356106d0565b60408051600160a060020a03938416815291909216602082015281519081900390910190f35b61016b600480360360808110156101fa57600080fd5b50803590602081013590604081013590606001356106f6565b61016b6004803603604081101561022957600080fd5b5080359060200135600160a060020a0316610709565b61025c6004803603602081101561025557600080fd5b50356107ee565b60408051600160a060020a03909316835260208301919091528051918290030190f35b61012d610813565b61016b6004803603608081101561029d57600080fd5b600160a060020a0382358116926020810135926040820135909216918101906080810160608201356401000000008111156102d757600080fd5b8201836020820111156102e957600080fd5b8035906020019184600183028401116401000000008311171561030b57600080fd5b509092509050610819565b61016b6004803603602081101561032c57600080fd5b5035610a50565b61035f6004803603604081101561034957600080fd5b5080359060200135600160a060020a0316610acd565b604080519115158252519081900360200190f35b61016b6004803603602081101561038957600080fd5b5035610aed565b61012d600480360360408110156103a657600080fd5b50600160a060020a0381358116916020013516610e1b565b6103db600480360360208110156103d457600080fd5b5035610ebf565b604080519485526020850193909352838301919091526060830152519081900360800190f35b610409610f24565b60408051600160a060020a039092168252519081900360200190f35b600072010000000000000000000000000000000000008510801561044f5750660100000000000084105b801561045f575064010000000083105b801561046f575064010000000082105b15156104c5576040805160e560020a62461bcd02815260206004820152601d60248201527f496e76616c696420696e7075742073697a657320746f20656e636f6465000000604482015290519081900360640190fd5b5060e060020a8102780100000000000000000000000000000000000000000000000083027201000000000000000000000000000000000000850286171717949350505050565b6000828152600360205260409020548290600160a060020a0316331461057b576040805160e560020a62461bcd02815260206004820152601860248201527f53656e646572206973206e6f742061206d65726368616e740000000000000000604482015290519081900360640190fd5b600083815260036020908152604091829020805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0386169081179091558251908152915185927fd35b408ba3571fabd440ceb0aec76b70ca0bc9f3e3ba8fff9d29f04bfff304dd92908290030190a2505050565b6000838152600360205260409020548390600160a060020a0316331461065d576040805160e560020a62461bcd02815260206004820152601860248201527f53656e646572206973206e6f742061206d65726368616e740000000000000000604482015290519081900360640190fd5b6000848152600460209081526040808320600160a060020a03871680855290835292819020805460ff1916861515908117909155815193845291830191909152805186927fc338630af7fbf9aa0a16bb027ac14ebd17333b7e4bc624bcc26e43a3044ba32292908290030190a250505050565b60036020526000908152604090208054600190910154600160a060020a03918216911682565b6107033384868585610f33565b50505050565b6000828152600360205260409020548290600160a060020a03163314610779576040805160e560020a62461bcd02815260206004820152601860248201527f53656e646572206973206e6f742061206d65726368616e740000000000000000604482015290519081900360640190fd5b600083815260036020908152604091829020600101805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0386169081179091558251908152915185927f9d83cbe44450c5e9f8b8adcff3a1812cfdfdb4b73ad00696c06712779805541f92908290030190a2505050565b60026020526000908152604090208054600190910154600160a060020a039091169082565b60005481565b600154600160a060020a0316331461087b576040805160e560020a62461bcd02815260206004820152601560248201527f53656e646572206973206e6f74206120746f6b656e0000000000000000000000604482015290519081900360640190fd5b604081146108d3576040805160e560020a62461bcd02815260206004820152601360248201527f496e76616c69642064617461206c656e67746800000000000000000000000000604482015290519081900360640190fd5b60008060008061092061091b87878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525092506112a6915050565b610ebf565b9350935093509350600061096c87878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250602092506112a6915050565b9050831515610987576109828a84838886610f33565b610a44565b60018414156109f457600081815260026020526040902054600160a060020a038b81169116146109eb5760405160e560020a62461bcd02815260040180806020018281038252603681526020018061135f6036913960400191505060405180910390fd5b610982816112ae565b6040805160e560020a62461bcd02815260206004820152601760248201527f556e6b6e6f776e20616374696f6e2070726f7669646564000000000000000000604482015290519081900360640190fd5b50505050505050505050565b6000818152600260205260409020548190600160a060020a03163314610ac0576040805160e560020a62461bcd02815260206004820152601860248201527f53656e646572206973206e6f74206120637573746f6d65720000000000000000604482015290519081900360640190fd5b610ac9826112ae565b5050565b600460209081526000928352604080842090915290825290205460ff1681565b60008181526002602052604081206001810154909190819081908190610b1290610ebf565b60008281526004602090815260408083203384529091529020549397509195509350915060ff161515610b8f576040805160e560020a62461bcd02815260206004820152601f60248201527f53656e646572206973206e6f7420616c6c6f77656420746f2063686172676500604482015290519081900360640190fd5b811515610be6576040805160e560020a62461bcd02815260206004820152601660248201527f42696c6c696e6720646f6573206e6f7420657869737400000000000000000000604482015290519081900360640190fd5b42610bf7848363ffffffff61130716565b1115610c4d576040805160e560020a62461bcd02815260206004820152601160248201527f4368617267656420746f6f206561726c79000000000000000000000000000000604482015290519081900360640190fd5b610c6e610c6182600263ffffffff61131d16565b849063ffffffff61130716565b421115610c8857610c7e866112ae565b5050505050610e18565b60018054865460008581526003602090815260408083209095015485517f23b872dd000000000000000000000000000000000000000000000000000000008152600160a060020a0394851660048201529084166024820152604481018a9052945192909316936323b872dd93606480830194919391928390030190829087803b158015610d1457600080fd5b505af1158015610d28573d6000803e3d6000fd5b505050506040513d6020811015610d3e57600080fd5b50511515610d96576040805160e560020a62461bcd02815260206004820152601960248201527f556e61626c6520746f2063686172676520637573746f6d657200000000000000604482015290519081900360640190fd5b610db184610daa858463ffffffff61130716565b8484610425565b6001860155857ff0e249d47d0ac6e79422d646c38f31c1b93dc56cc3ca0202a9f0c8a5879f96ef42610dfa610ded85600263ffffffff61131d16565b879063ffffffff61130716565b6040805192835260208301919091528051918290030190a250505050505b50565b60008054600190810180835580835260036020908152604093849020805473ffffffffffffffffffffffffffffffffffffffff199081163390811783559482018054600160a060020a038a1692168217905585519485529184019190915283519193909284927f817e18163b81cf9c490b9d9e647dae7d192c4907c18acf578ec4e3de57202023929181900390910190a2610eb8828460016105ed565b5092915050565b71ffffffffffffffffffffffffffffffffffff81169165ffffffffffff72010000000000000000000000000000000000008304169163ffffffff7801000000000000000000000000000000000000000000000000820481169260e060020a9092041690565b600154600160a060020a031681565b6000548411158015610f4457508315155b1515610f9a576040805160e560020a62461bcd02815260206004820152601a60248201527f496e76616c6964206d65726368616e7420737065636966696564000000000000604482015290519081900360640190fd5b428110610ff1576040805160e560020a62461bcd02815260206004820152601860248201527f496e76616c696420706572696f64207370656369666965640000000000000000604482015290519081900360640190fd5b600154604080517f70a08231000000000000000000000000000000000000000000000000000000008152600160a060020a0388811660048301529151859392909216916370a0823191602480820192602092909190829003018186803b15801561105a57600080fd5b505afa15801561106e573d6000803e3d6000fd5b505050506040513d602081101561108457600080fd5b505110156110c65760405160e560020a62461bcd0281526004018080602001828103825260268152602001806113f86026913960400191505060405180910390fd5b600154604080517fdd62ed3e000000000000000000000000000000000000000000000000000000008152600160a060020a03888116600483015230602483015291518593929092169163dd62ed3e91604480820192602092909190829003018186803b15801561113557600080fd5b505afa158015611149573d6000803e3d6000fd5b505050506040513d602081101561115f57600080fd5b505110156111a15760405160e560020a62461bcd02815260040180806020018281038252602f8152602001806113c9602f913960400191505060405180910390fd5b600083815260026020526040902054600160a060020a0316156111f85760405160e560020a62461bcd0281526004018080602001828103825260348152602001806113956034913960400191505060405180910390fd5b60008381526002602052604090206112218361121a428563ffffffff61134916565b8785610425565b60018201558054600160a060020a03871673ffffffffffffffffffffffffffffffffffffffff19909116811782556040805191825260208201879052428282015260608201849052608082018590525185917feb239a79a50d36f19427f1b96bc211ab9fa7e493e250417e593b28b872a6fa94919081900360a00190a2505050505050565b016020015190565b600081815260026020526040808220805473ffffffffffffffffffffffffffffffffffffffff191681556001018290555182917f2b5753dbaf3a6af5535e40a61f019aad8c4e909e178a42b4b8f680a76bef3c3891a250565b8181018281101561131757600080fd5b92915050565b600082151561132e57506000611317565b5081810281838281151561133e57fe5b041461131757600080fd5b60008282111561135857600080fd5b5090039056fe556e61626c6520746f2063616e63656c20726563757272696e672062696c6c696e67206f6620616e6f7468657220637573746f6d6572526563757272696e672062696c6c696e672077697468207468697320494420697320616c72656164792072656769737465726564546f6b656e7320617265206e6f7420617070726f76656420666f72207468697320736d61727420636f6e74726163744e6f7420656e6f75676820746f6b656e7320666f722074686520666972737420636861726765a165627a7a72305820b1d9df70b2769f1c0a6dc1994e80fd22c9704ad6f275775307b10c94113d58ad0029a165627a7a723058201cc1efc1eef791dcb151481223309dfaca0402a9e7b5bd47ac54f227daee50440029
Deployed Bytecode
0x608060405234801561001057600080fd5b5060043610610047577c01000000000000000000000000000000000000000000000000000000006000350463ddcfa217811461004c575b600080fd5b61007f6004803603602081101561006257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166100a8565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b600080826100b461014a565b73ffffffffffffffffffffffffffffffffffffffff909116815260405190819003602001906000f0801580156100ee573d6000803e3d6000fd5b506040805173ffffffffffffffffffffffffffffffffffffffff80871682528316602082015281519293507f9f6cf7ccb2e4f68c7ce568594283c8d89ee6a64266981b12086ae803e7e75500929081900390910190a192915050565b6040516114a98061015b8339019056fe608060405234801561001057600080fd5b506040516020806114a98339810180604052602081101561003057600080fd5b505160018054600160a060020a031916600160a060020a03909216919091179055611449806100606000396000f3fe608060405234801561001057600080fd5b50600436106100f95760003560e060020a9004806382ef2ad01161009b578063e457e1e51161006a578063e457e1e514610373578063ee95a9de14610390578063f1e8ace7146103be578063fc0c546a14610401576100f9565b806382ef2ad01461027f5780638f4ffcb1146102875780639cd106a814610316578063c446ae7014610333576100f9565b8063440b2355116100d7578063440b2355146101a15780634c18e960146101e45780636e2f10bd146102135780637fb339d61461023f576100f9565b806317c3925f146100fe5780632faa5e3c1461013f5780633913848e1461016d575b600080fd5b61012d6004803603608081101561011457600080fd5b5080359060208101359060408101359060600135610425565b60408051918252519081900360200190f35b61016b6004803603604081101561015557600080fd5b5080359060200135600160a060020a031661050b565b005b61016b6004803603606081101561018357600080fd5b50803590600160a060020a03602082013516906040013515156105ed565b6101be600480360360208110156101b757600080fd5b50356106d0565b60408051600160a060020a03938416815291909216602082015281519081900390910190f35b61016b600480360360808110156101fa57600080fd5b50803590602081013590604081013590606001356106f6565b61016b6004803603604081101561022957600080fd5b5080359060200135600160a060020a0316610709565b61025c6004803603602081101561025557600080fd5b50356107ee565b60408051600160a060020a03909316835260208301919091528051918290030190f35b61012d610813565b61016b6004803603608081101561029d57600080fd5b600160a060020a0382358116926020810135926040820135909216918101906080810160608201356401000000008111156102d757600080fd5b8201836020820111156102e957600080fd5b8035906020019184600183028401116401000000008311171561030b57600080fd5b509092509050610819565b61016b6004803603602081101561032c57600080fd5b5035610a50565b61035f6004803603604081101561034957600080fd5b5080359060200135600160a060020a0316610acd565b604080519115158252519081900360200190f35b61016b6004803603602081101561038957600080fd5b5035610aed565b61012d600480360360408110156103a657600080fd5b50600160a060020a0381358116916020013516610e1b565b6103db600480360360208110156103d457600080fd5b5035610ebf565b604080519485526020850193909352838301919091526060830152519081900360800190f35b610409610f24565b60408051600160a060020a039092168252519081900360200190f35b600072010000000000000000000000000000000000008510801561044f5750660100000000000084105b801561045f575064010000000083105b801561046f575064010000000082105b15156104c5576040805160e560020a62461bcd02815260206004820152601d60248201527f496e76616c696420696e7075742073697a657320746f20656e636f6465000000604482015290519081900360640190fd5b5060e060020a8102780100000000000000000000000000000000000000000000000083027201000000000000000000000000000000000000850286171717949350505050565b6000828152600360205260409020548290600160a060020a0316331461057b576040805160e560020a62461bcd02815260206004820152601860248201527f53656e646572206973206e6f742061206d65726368616e740000000000000000604482015290519081900360640190fd5b600083815260036020908152604091829020805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0386169081179091558251908152915185927fd35b408ba3571fabd440ceb0aec76b70ca0bc9f3e3ba8fff9d29f04bfff304dd92908290030190a2505050565b6000838152600360205260409020548390600160a060020a0316331461065d576040805160e560020a62461bcd02815260206004820152601860248201527f53656e646572206973206e6f742061206d65726368616e740000000000000000604482015290519081900360640190fd5b6000848152600460209081526040808320600160a060020a03871680855290835292819020805460ff1916861515908117909155815193845291830191909152805186927fc338630af7fbf9aa0a16bb027ac14ebd17333b7e4bc624bcc26e43a3044ba32292908290030190a250505050565b60036020526000908152604090208054600190910154600160a060020a03918216911682565b6107033384868585610f33565b50505050565b6000828152600360205260409020548290600160a060020a03163314610779576040805160e560020a62461bcd02815260206004820152601860248201527f53656e646572206973206e6f742061206d65726368616e740000000000000000604482015290519081900360640190fd5b600083815260036020908152604091829020600101805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0386169081179091558251908152915185927f9d83cbe44450c5e9f8b8adcff3a1812cfdfdb4b73ad00696c06712779805541f92908290030190a2505050565b60026020526000908152604090208054600190910154600160a060020a039091169082565b60005481565b600154600160a060020a0316331461087b576040805160e560020a62461bcd02815260206004820152601560248201527f53656e646572206973206e6f74206120746f6b656e0000000000000000000000604482015290519081900360640190fd5b604081146108d3576040805160e560020a62461bcd02815260206004820152601360248201527f496e76616c69642064617461206c656e67746800000000000000000000000000604482015290519081900360640190fd5b60008060008061092061091b87878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525092506112a6915050565b610ebf565b9350935093509350600061096c87878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250602092506112a6915050565b9050831515610987576109828a84838886610f33565b610a44565b60018414156109f457600081815260026020526040902054600160a060020a038b81169116146109eb5760405160e560020a62461bcd02815260040180806020018281038252603681526020018061135f6036913960400191505060405180910390fd5b610982816112ae565b6040805160e560020a62461bcd02815260206004820152601760248201527f556e6b6e6f776e20616374696f6e2070726f7669646564000000000000000000604482015290519081900360640190fd5b50505050505050505050565b6000818152600260205260409020548190600160a060020a03163314610ac0576040805160e560020a62461bcd02815260206004820152601860248201527f53656e646572206973206e6f74206120637573746f6d65720000000000000000604482015290519081900360640190fd5b610ac9826112ae565b5050565b600460209081526000928352604080842090915290825290205460ff1681565b60008181526002602052604081206001810154909190819081908190610b1290610ebf565b60008281526004602090815260408083203384529091529020549397509195509350915060ff161515610b8f576040805160e560020a62461bcd02815260206004820152601f60248201527f53656e646572206973206e6f7420616c6c6f77656420746f2063686172676500604482015290519081900360640190fd5b811515610be6576040805160e560020a62461bcd02815260206004820152601660248201527f42696c6c696e6720646f6573206e6f7420657869737400000000000000000000604482015290519081900360640190fd5b42610bf7848363ffffffff61130716565b1115610c4d576040805160e560020a62461bcd02815260206004820152601160248201527f4368617267656420746f6f206561726c79000000000000000000000000000000604482015290519081900360640190fd5b610c6e610c6182600263ffffffff61131d16565b849063ffffffff61130716565b421115610c8857610c7e866112ae565b5050505050610e18565b60018054865460008581526003602090815260408083209095015485517f23b872dd000000000000000000000000000000000000000000000000000000008152600160a060020a0394851660048201529084166024820152604481018a9052945192909316936323b872dd93606480830194919391928390030190829087803b158015610d1457600080fd5b505af1158015610d28573d6000803e3d6000fd5b505050506040513d6020811015610d3e57600080fd5b50511515610d96576040805160e560020a62461bcd02815260206004820152601960248201527f556e61626c6520746f2063686172676520637573746f6d657200000000000000604482015290519081900360640190fd5b610db184610daa858463ffffffff61130716565b8484610425565b6001860155857ff0e249d47d0ac6e79422d646c38f31c1b93dc56cc3ca0202a9f0c8a5879f96ef42610dfa610ded85600263ffffffff61131d16565b879063ffffffff61130716565b6040805192835260208301919091528051918290030190a250505050505b50565b60008054600190810180835580835260036020908152604093849020805473ffffffffffffffffffffffffffffffffffffffff199081163390811783559482018054600160a060020a038a1692168217905585519485529184019190915283519193909284927f817e18163b81cf9c490b9d9e647dae7d192c4907c18acf578ec4e3de57202023929181900390910190a2610eb8828460016105ed565b5092915050565b71ffffffffffffffffffffffffffffffffffff81169165ffffffffffff72010000000000000000000000000000000000008304169163ffffffff7801000000000000000000000000000000000000000000000000820481169260e060020a9092041690565b600154600160a060020a031681565b6000548411158015610f4457508315155b1515610f9a576040805160e560020a62461bcd02815260206004820152601a60248201527f496e76616c6964206d65726368616e7420737065636966696564000000000000604482015290519081900360640190fd5b428110610ff1576040805160e560020a62461bcd02815260206004820152601860248201527f496e76616c696420706572696f64207370656369666965640000000000000000604482015290519081900360640190fd5b600154604080517f70a08231000000000000000000000000000000000000000000000000000000008152600160a060020a0388811660048301529151859392909216916370a0823191602480820192602092909190829003018186803b15801561105a57600080fd5b505afa15801561106e573d6000803e3d6000fd5b505050506040513d602081101561108457600080fd5b505110156110c65760405160e560020a62461bcd0281526004018080602001828103825260268152602001806113f86026913960400191505060405180910390fd5b600154604080517fdd62ed3e000000000000000000000000000000000000000000000000000000008152600160a060020a03888116600483015230602483015291518593929092169163dd62ed3e91604480820192602092909190829003018186803b15801561113557600080fd5b505afa158015611149573d6000803e3d6000fd5b505050506040513d602081101561115f57600080fd5b505110156111a15760405160e560020a62461bcd02815260040180806020018281038252602f8152602001806113c9602f913960400191505060405180910390fd5b600083815260026020526040902054600160a060020a0316156111f85760405160e560020a62461bcd0281526004018080602001828103825260348152602001806113956034913960400191505060405180910390fd5b60008381526002602052604090206112218361121a428563ffffffff61134916565b8785610425565b60018201558054600160a060020a03871673ffffffffffffffffffffffffffffffffffffffff19909116811782556040805191825260208201879052428282015260608201849052608082018590525185917feb239a79a50d36f19427f1b96bc211ab9fa7e493e250417e593b28b872a6fa94919081900360a00190a2505050505050565b016020015190565b600081815260026020526040808220805473ffffffffffffffffffffffffffffffffffffffff191681556001018290555182917f2b5753dbaf3a6af5535e40a61f019aad8c4e909e178a42b4b8f680a76bef3c3891a250565b8181018281101561131757600080fd5b92915050565b600082151561132e57506000611317565b5081810281838281151561133e57fe5b041461131757600080fd5b60008282111561135857600080fd5b5090039056fe556e61626c6520746f2063616e63656c20726563757272696e672062696c6c696e67206f6620616e6f7468657220637573746f6d6572526563757272696e672062696c6c696e672077697468207468697320494420697320616c72656164792072656769737465726564546f6b656e7320617265206e6f7420617070726f76656420666f72207468697320736d61727420636f6e74726163744e6f7420656e6f75676820746f6b656e7320666f722074686520666972737420636861726765a165627a7a72305820b1d9df70b2769f1c0a6dc1994e80fd22c9704ad6f275775307b10c94113d58ad0029a165627a7a723058201cc1efc1eef791dcb151481223309dfaca0402a9e7b5bd47ac54f227daee50440029
Swarm Source
bzzr://1cc1efc1eef791dcb151481223309dfaca0402a9e7b5bd47ac54f227daee5044
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.