Contract detail
FastTrackFactory
FastTrackFactory is a verified Robinhood Chain smart contract at 0x2e2b018e…aa6eb206 with 3 indexed transactions.
- Address type
- Smart contract
- Transactions
- 3
- First indexed block
- #26520982
- Latest indexed block
- #26665521
- Emitted events
- 8
- Verification
- Verified
- Compiler
- 0.8.34+commit.80d5c536
- Verification match
- exact
- Creation transaction
- 0x066ad8d9…b20f4a94
- Created at block
- #26520982
- Language
- Solidity
- License
- MIT
- Compiler optimization
- Disabled
- Deployed bytecode hash
- 0x2e915ce032cefbc63048063954bf8c17ab9a1d36aa6f4d863f1314aeef5b53e5
Related activity
Transactions
Verified contract
Contract source code
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
/*
╔══════════════════════════════════════════════════════════════════════╗
║ ║
║ H O O D S C O P E . I O ║
║ ║
║ FASTTRACK PAYMENT SYSTEM ║
║ ROBINHOOD CHAIN ║
║ ║
║ Stay Alert • Find Alpha • Move Early ║
║ ║
╚══════════════════════════════════════════════════════════════════════╝
Official Website : https://hoodscope.io
Telegram : https://t.me/HoodScopeHQ
Trends : https://t.me/HoodScopeTrends
X : https://x.com/HoodScopeHQ
*/
import "./FastTrackInvoice.sol";
import "./FastTrackInvoice.sol";
/// @notice Creates a unique payment contract for every HoodScope FastTrack order.
contract FastTrackFactory {
struct Package { uint64 duration; uint192 price; bool enabled; }
struct Order {
address invoice;
address token;
address payer;
uint96 amount;
uint64 duration;
uint64 createdAt;
uint64 paidAt;
}
address public owner;
address public pendingOwner;
address public operator;
address payable public treasury;
bool public paused;
mapping(uint8 => Package) public packages;
mapping(bytes32 => Order) public orders;
mapping(address => bytes32) public invoiceOrder;
event InvoiceCreated(bytes32 indexed orderId, address indexed invoice, address indexed token, uint8 packageId, uint256 amount, uint256 duration);
event InvoicePaid(bytes32 indexed orderId, address indexed invoice, address indexed payer, uint256 amount, uint256 paidAt);
event PackageUpdated(uint8 indexed packageId, uint256 duration, uint256 price, bool enabled);
event OperatorUpdated(address indexed operator);
event TreasuryUpdated(address indexed treasury);
event OwnershipTransferStarted(address indexed currentOwner, address indexed pendingOwner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
event Paused(bool paused);
error Unauthorized();
error InvalidOrder();
error InvalidPackage();
error DuplicateOrder();
error InvalidAddress();
modifier onlyOwner() { if (msg.sender != owner) revert Unauthorized(); _; }
modifier onlyOperator() { if (msg.sender != operator) revert Unauthorized(); _; }
modifier whenActive() { if (paused) revert Unauthorized(); _; }
constructor(address owner_, address operator_, address payable treasury_) {
if (owner_ == address(0) || operator_ == address(0) || treasury_ == address(0)) revert InvalidAddress();
owner = owner_;
operator = operator_;
treasury = treasury_;
_setPackage(1, 3 hours, 0.01 ether, true);
_setPackage(2, 6 hours, 0.018 ether, true);
_setPackage(3, 12 hours, 0.032 ether, true);
_setPackage(4, 24 hours, 0.055 ether, true);
}
function createInvoice(bytes32 orderId, address token, uint8 packageId) external onlyOperator whenActive returns (address invoice) {
if (orderId == bytes32(0) || token == address(0)) revert InvalidOrder();
if (orders[orderId].invoice != address(0)) revert DuplicateOrder();
Package memory selected = packages[packageId];
if (!selected.enabled || selected.price == 0 || selected.duration == 0) revert InvalidPackage();
bytes32 salt = keccak256(abi.encode(orderId, token, packageId));
invoice = address(new FastTrackInvoice{salt: salt}(treasury, orderId, selected.price));
orders[orderId] = Order(invoice, token, address(0), uint96(selected.price), selected.duration, uint64(block.timestamp), 0);
invoiceOrder[invoice] = orderId;
emit InvoiceCreated(orderId, invoice, token, packageId, selected.price, selected.duration);
}
function markPaid(bytes32 orderId, address payer, uint256 amount) external {
Order storage order = orders[orderId];
if (msg.sender != order.invoice || order.paidAt != 0 || amount != order.amount) revert InvalidOrder();
order.payer = payer;
order.paidAt = uint64(block.timestamp);
emit InvoicePaid(orderId, msg.sender, payer, amount, block.timestamp);
}
function setPackage(uint8 packageId, uint64 duration, uint192 price, bool enabled) external onlyOwner {
_setPackage(packageId, duration, price, enabled);
}
function _setPackage(uint8 packageId, uint64 duration, uint192 price, bool enabled) internal {
if (packageId == 0 || duration == 0 || price == 0) revert InvalidPackage();
packages[packageId] = Package(duration, price, enabled);
emit PackageUpdated(packageId, duration, price, enabled);
}
function setOperator(address next) external onlyOwner {
if (next == address(0)) revert InvalidAddress();
operator = next;
emit OperatorUpdated(next);
}
function setTreasury(address payable next) external onlyOwner {
if (next == address(0)) revert InvalidAddress();
treasury = next;
emit TreasuryUpdated(next);
}
function setPaused(bool value) external onlyOwner { paused = value; emit Paused(value); }
function transferOwnership(address next) external onlyOwner {
if (next == address(0)) revert InvalidAddress();
pendingOwner = next;
emit OwnershipTransferStarted(owner, next);
}
function acceptOwnership() external {
if (msg.sender != pendingOwner) revert Unauthorized();
address previous = owner;
owner = msg.sender;
pendingOwner = address(0);
emit OwnershipTransferred(previous, msg.sender);
}
}