// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract RevShareContract {
uint256 public immutable REVENUE_AMOUNT;
address public owner;
uint256 public totalSnapshotTokens;
uint256 public snapshotTime;
bool public isSnapshotLocked;
uint256 public constant TOTAL_TOKENS = 10 ** 6 * 10 ** 18; // 1 Million Tokens
mapping(address => uint256) public snapshotBalances;
mapping(address => bool) public hasClaimed;
event AxeSnapshotLock();
event AxeSnapshotUnlock();
event EthClaim(address indexed claimer, uint256 amount);
event AdminWithdraw(uint256 amount);
constructor() payable {
owner = msg.sender;
REVENUE_AMOUNT = msg.value;
}
modifier onlyOwner() {
require(msg.sender == owner, "Caller is not the owner");
_;
}
modifier after2Days() {
require(
block.timestamp > snapshotTime + 2 days,
"Can only call after 2 days of snapshot"
);
_;
}
function uploadSnapshot(
address[] calldata users,
uint256[] calldata balances
) external onlyOwner {
require(
users.length == balances.length,
"Arrays must be of equal length"
);
require(
users.length <= 125,
"Can only upload up to 125 addresses at a time"
);
// note: should not have more than one user value
for (uint256 i = 0; i < users.length; i++) {
snapshotBalances[users[i]] += balances[i];
totalSnapshotTokens += balances[i];
}
}
function lockSnapshot() external onlyOwner {
require(!isSnapshotLocked, "snapshot already locked");
snapshotTime = block.timestamp;
isSnapshotLocked = true;
emit AxeSnapshotLock();
}
function unlockSnapshot() external onlyOwner {
require(isSnapshotLocked, "snapshot already unlocked");
snapshotTime = 0;
isSnapshotLocked = false;
emit AxeSnapshotUnlock();
}
function claimETH() external {
require(isSnapshotLocked, "Snapshot not yet locked");
require(!hasClaimed[msg.sender], "You have already claimed your ETH");
require(
snapshotBalances[msg.sender] > 0,
"You do not have any AXE tokens in the snapshot"
);
uint256 claimableAmount = (REVENUE_AMOUNT *
snapshotBalances[msg.sender]) / TOTAL_TOKENS;
// prevent reentrancy
hasClaimed[msg.sender] = true;
// see https://ethereum.stackexchange.com/questions/78124/is-transfer-still-safe-after-the-istanbul-update
(bool isSuccess, ) = msg.sender.call{value: claimableAmount}("");
require(isSuccess, "Claim amount tranfer failed");
emit EthClaim(msg.sender, claimableAmount);
}
// Function to withdraw unclaimed ETH after 7 days
function withdrawUnclaimedETH() public onlyOwner after2Days {
uint256 amount = address(this).balance;
msg.sender.call{value: amount}("");
emit AdminWithdraw(amount);
}
receive() external payable {}
}
{
"compilationTarget": {
"contracts/RevShareContract.sol": "RevShareContract"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 300
},
"remappings": []
}
[{"inputs":[],"stateMutability":"payable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"AdminWithdraw","type":"event"},{"anonymous":false,"inputs":[],"name":"AxeSnapshotLock","type":"event"},{"anonymous":false,"inputs":[],"name":"AxeSnapshotUnlock","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"claimer","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EthClaim","type":"event"},{"inputs":[],"name":"REVENUE_AMOUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TOTAL_TOKENS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"hasClaimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isSnapshotLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockSnapshot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"snapshotBalances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"snapshotTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSnapshotTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unlockSnapshot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"users","type":"address[]"},{"internalType":"uint256[]","name":"balances","type":"uint256[]"}],"name":"uploadSnapshot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawUnclaimedETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]