Description:
Smart contract deployed on Ethereum.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
interface IERC20 {
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
function balanceOf(address account) external view returns (uint256);
function allowance(address owner, address spender) external view returns (uint256);
}
contract SprotoPaywall {
IERC20 public immutable sprotoToken;
address public owner;
// 10,000 $SPROTOSTORIES tokens (10,000 * 10^18)
uint256 public constant SCENE_PRICE = 10000000000000000000000; // 10^22 wei
event ScenePaid(address indexed user, uint256 indexed sceneIndex, uint256 amount, uint256 timestamp);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor(address _tokenAddress) {
require(_tokenAddress != address(0), "Invalid token address");
sprotoToken = IERC20(_tokenAddress);
owner = msg.sender;
}
modifier onlyOwner() {
require(msg.sender == owner, "Only owner can call this function");
_;
}
function payForScene(uint256 sceneIndex) external {
// Check balance first (prevents failed transfers)
uint256 balance = sprotoToken.balanceOf(msg.sender);
require(balance >= SCENE_PRICE, "Insufficient token balance");
// Check allowance
uint256 allowance = sprotoToken.allowance(msg.sender, address(this));
require(allowance >= SCENE_PRICE, "Insufficient allowance. Approve tokens first.");
// Transfer tokens from user to contract/owner
bool success = sprotoToken.transferFrom(msg.sender, owner, SCENE_PRICE);
require(success, "Token transfer failed");
// Emit payment event for verification
emit ScenePaid(msg.sender, sceneIndex, SCENE_PRICE, block.timestamp);
}
function withdrawTokens(uint256 amount) external onlyOwner {
require(amount > 0, "Amount must be greater than 0");
uint256 contractBalance = sprotoToken.balanceOf(address(this));
require(contractBalance >= amount, "Insufficient contract balance");
bool success = sprotoToken.transferFrom(address(this), owner, amount);
require(success, "Withdrawal failed");
}
function transferOwnership(address newOwner) external onlyOwner {
require(newOwner != address(0), "Invalid new owner");
require(newOwner != owner, "New owner must be different");
// Check-effects-interactions: Update state before emitting event
address oldOwner = owner;
owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
// View function to check if user can afford payment
function canAffordPayment(address user) external view returns (bool) {
uint256 balance = sprotoToken.balanceOf(user);
uint256 allowance = sprotoToken.allowance(user, address(this));
return balance >= SCENE_PRICE && allowance >= SCENE_PRICE;
}
}
Submitted on: 2025-11-06 09:56:34
Comments
Log in to comment.
No comments yet.