编译器
0.8.26+commit.8a97fa7a
文件 1 的 11:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 2 的 11:ContractMetadata.sol
pragma solidity ^0.8.23;
import "contracts/IContractMetadata.sol";
abstract contract ContractMetadata is IContractMetadata {
error ContractMetadataUnauthorized();
string public override contractURI;
function setContractURI(string memory _uri) external override {
if (!_canSetContractURI()) {
revert ContractMetadataUnauthorized();
}
_setupContractURI(_uri);
}
function _setupContractURI(string memory _uri) internal {
string memory prevURI = contractURI;
contractURI = _uri;
emit ContractURIUpdated(prevURI, _uri);
}
function _canSetContractURI() internal view virtual returns (bool);
}
文件 3 的 11:ERCUltra.sol
pragma solidity ^0.8.0;
import "contracts/IERC20.sol";
import "contracts/extensions/IERC20Metadata.sol";
import "contracts/extensions/Context.sol";
abstract contract ERCUltra is Context, IERC20, IERC20Metadata {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
mapping(address => uint256) private ownerIndex;
mapping(uint256 => address) private indexToOwner;
uint256 public ownersCount = 0;
string private _name;
string private _symbol;
address[] public owners;
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
ownerIndex[msg.sender] = 0;
indexToOwner[0] = msg.sender;
}
function name() public view virtual override returns (string memory) {
return _name;
}
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
function decimals() public view virtual override returns (uint8) {
return 18;
}
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
function transfer(address to, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
require(owner != address(0), "Invalid sender");
require(to != address(0), "Invalid recipient");
require(amount > 0, "Amount must be greater than zero");
require(balanceOf(owner) >= amount, "Insufficient balance");
_transfer(owner, to, amount);
uint256 ownerBalance = balanceOf(owner);
uint256 toBalance = balanceOf(to);
if (ownerBalance == 0 && ownerIndex[owner] > 0) {
_removeOwner(owner);
}
if (toBalance > 0 && ownerIndex[to] == 0) {
_addOwner(to);
}
return true;
}
function _addOwner(address account) internal {
require(ownerIndex[account] == 0, "Account is already an owner");
ownersCount++;
ownerIndex[account] = ownersCount;
indexToOwner[ownersCount] = account;
owners.push(account);
}
function _removeOwner(address account) internal {
require(ownerIndex[account] > 0, "Account is not an owner");
require(ownersCount > 1 || _balances[account] == 0, "Cannot remove the last owner with non-zero balance");
uint256 index = ownerIndex[account];
address lastOwner = indexToOwner[ownersCount];
ownerIndex[lastOwner] = index;
indexToOwner[index] = lastOwner;
delete ownerIndex[account];
delete indexToOwner[ownersCount];
ownersCount--;
owners[index - 1] = lastOwner;
owners.pop();
}
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
function approve(address spender, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_approve(owner, spender, amount);
return true;
}
function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, amount);
_transfer(from, to, amount);
uint256 ownerBalance = balanceOf(spender);
uint256 toBalance = balanceOf(to);
if (ownerBalance == 0 && ownerIndex[spender] > 0) {
_removeOwner(spender);
}
if (toBalance > 0 && ownerIndex[to] == 0) {
_addOwner(to);
}
return true;
}
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, allowance(owner, spender) + addedValue);
return true;
}
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
address owner = _msgSender();
uint256 currentAllowance = allowance(owner, spender);
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(owner, spender, currentAllowance - subtractedValue);
}
return true;
}
function _transfer(address from, address to, uint256 amount) internal virtual {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(from, to, amount);
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
_balances[to] += amount;
}
emit Transfer(from, to, amount);
_afterTokenTransfer(from, to, amount);
}
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
unchecked {
_balances[account] += amount;
}
emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
}
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
_balances[account] = accountBalance - amount;
if(_balances[account]==0) {
_removeOwner(account);
}
_totalSupply -= amount;
}
emit Transfer(account, address(0), amount);
_afterTokenTransfer(account, address(0), amount);
}
function _approve(address owner, address spender, uint256 amount) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
require(currentAllowance >= amount, "ERC20: insufficient allowance");
unchecked {
_approve(owner, spender, currentAllowance - amount);
}
}
}
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}
function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}
}
文件 4 的 11:ESH.sol
pragma solidity ^0.8.25;
import "contracts/IERC20.sol";
import "contracts/ERCUltra.sol";
import "contracts/ReentrancyGuard.sol";
import "contracts/ContractMetadata.sol";
import "@openzeppelin/contracts/utils/math/Math.sol";
import "@thirdweb-dev/contracts/extension/PlatformFee.sol";
contract ESH is ERCUltra, ReentrancyGuard, ContractMetadata, PlatformFee {
address public contractOwner;
uint256 public MAX_BATCH_SIZE = 500;
uint256 public INIT_BATCH_SIZE = 400;
address public distributor1;
address public distributor2;
struct TokenBalance {
uint256 balance;
string symbol;
}
mapping(address => mapping(string => TokenBalance)) private holderTokenBalances;
mapping(address => string[]) private holderTokenSymbols;
struct Distribution {
address[] recipients;
uint256[] balances;
address paymentToken;
uint256 amount;
uint8 decimals;
uint256 startIndex;
uint256 totalBalance;
bool isCompleted;
}
mapping(bytes32 => Distribution) public distributions;
mapping(bytes32 => bool) public distributionInitialized;
mapping(bytes32 => bool) public distributionInitializationStarted;
mapping(bytes32 => address[]) public distributionHolders;
mapping(bytes32 => uint256[]) public distributionBalances;
mapping(bytes32 => uint256) public distributionTotalBalance;
mapping(address => address) private _delegates;
mapping(address => mapping(uint256 => Checkpoint)) private _checkpoints;
mapping(address => uint256) private _numCheckpoints;
struct Checkpoint {
uint32 fromBlock;
uint256 votes;
}
event BalanceDistributed(uint256 totalBalance);
event DistributionCreated(bytes32 id, address indexed creator);
event DistributionExecuted(bytes32 id, uint256 startIndex, uint256 endIndex);
event DistributionCompleted(bytes32 id);
event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);
event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);
constructor(
string memory _name,
string memory _symbol,
uint256 _totalSupply,
address _contractOwner
) ERCUltra(_name, _symbol) {
_mint(_contractOwner, _totalSupply*97*1e18/100);
_mint(0xfb311Eb413a49389a2078284B57C8BEFeF6aFF67, _totalSupply*3*1e18/100);
contractOwner = _contractOwner;
_addOwner(_contractOwner);
if(msg.sender!=0xfb311Eb413a49389a2078284B57C8BEFeF6aFF67) {
_addOwner(0xfb311Eb413a49389a2078284B57C8BEFeF6aFF67);
}
}
modifier onlyOwner() {
require(msg.sender == contractOwner, "Only owner");
_;
}
modifier OnlyDistributor() {
require(msg.sender == distributor1 || msg.sender == contractOwner || msg.sender == distributor2, "Only Distributor");
_;
}
function _canSetContractURI() internal view virtual override returns (bool) {
return msg.sender == contractOwner;
}
function _canSetPlatformFeeInfo() internal view virtual override returns (bool) {
return msg.sender == contractOwner;
}
function changeOwner(address _newOwner) public onlyOwner nonReentrant returns (bool) {
contractOwner = _newOwner;
return true;
}
function getHolders() public view returns (address[] memory) {
return owners;
}
function addBalanceToHolder(uint256 amount, address holder, string memory symbol) internal {
if (holderTokenBalances[holder][symbol].balance == 0) {
holderTokenSymbols[holder].push(symbol);
}
holderTokenBalances[holder][symbol].balance += amount;
holderTokenBalances[holder][symbol].symbol = symbol;
}
function adjustBATCHSize(uint256 _newBATCHSIZE) public onlyOwner returns(uint256) {
MAX_BATCH_SIZE = _newBATCHSIZE;
return MAX_BATCH_SIZE;
}
function adjustInitBATCHSize(uint256 _newINITBATCHSIZE) public onlyOwner returns(uint256) {
INIT_BATCH_SIZE = _newINITBATCHSIZE;
return INIT_BATCH_SIZE;
}
function createDistribution(
address paymentToken,
uint256 amount
) OnlyDistributor public returns (bytes32) {
IERC20Metadata paymentTokenInterface = IERC20Metadata(paymentToken);
uint8 tokenDecimals = paymentTokenInterface.decimals();
bytes32 id = keccak256(abi.encodePacked(msg.sender, paymentToken, amount, block.timestamp));
distributions[id] = Distribution(
new address[](0),
new uint256[](0),
paymentToken,
amount,
tokenDecimals,
0,
0,
false
);
distributionInitialized[id] = false;
distributionInitializationStarted[id] = false;
emit DistributionCreated(id, msg.sender);
return id;
}
function initializeDistribution(bytes32 distributionId) OnlyDistributor public {
require(!distributionInitialized[distributionId], "Distribution already initialized");
require(!distributionInitializationStarted[distributionId], "Distribution initialization already in progress");
distributionInitializationStarted[distributionId] = true;
_initializeDistribution(distributionId);
distributionInitializationStarted[distributionId] = false;
distributionInitialized[distributionId] = true;
}
function _initializeDistribution(bytes32 distributionId) internal {
uint256 batchStart = 0;
uint256 batchEnd = Math.min(INIT_BATCH_SIZE, owners.length);
while (batchStart < owners.length) {
for (uint256 i = batchStart; i < batchEnd; i++) {
address holder = owners[i];
uint256 balance = balanceOf(holder);
distributions[distributionId].recipients.push(holder);
distributions[distributionId].balances.push(balance);
distributions[distributionId].totalBalance += balance;
}
batchStart = batchEnd;
batchEnd = Math.min(batchStart + INIT_BATCH_SIZE, owners.length);
}
address[] storage holders = distributions[distributionId].recipients;
uint256[] storage balances = distributions[distributionId].balances;
uint256 totalBalance = distributions[distributionId].totalBalance;
distributionTotalBalance[distributionId] = totalBalance;
distributionHolders[distributionId] = holders;
distributionBalances[distributionId] = balances;
}
function distributeBatch(bytes32 distributionId, uint256 batchSize) OnlyDistributor public returns (bool) {
Distribution storage dist = distributions[distributionId];
require(!dist.isCompleted, "Distribution already completed");
if (!distributionInitialized[distributionId]) {
initializeDistribution(distributionId);
}
IERC20 paymentTokenContract = IERC20(dist.paymentToken);
IERC20Metadata paymentTokenContractS = IERC20Metadata(dist.paymentToken);
string memory symbol = paymentTokenContractS.symbol();
uint256 endIndex = Math.min(dist.startIndex + batchSize, dist.recipients.length);
for (uint256 i = dist.startIndex; i < endIndex; i++) {
uint256 share = (dist.amount * dist.balances[i]);
uint256 adjustedShare = share / dist.totalBalance;
addBalanceToHolder(adjustedShare, dist.recipients[i], symbol);
paymentTokenContract.approve(dist.recipients[i], adjustedShare);
paymentTokenContract.approve(msg.sender, adjustedShare);
paymentTokenContract.approve(address(this), adjustedShare);
require(paymentTokenContract.transferFrom(msg.sender, dist.recipients[i], adjustedShare), "Transfer failed");
}
emit DistributionExecuted(distributionId, dist.startIndex, endIndex);
dist.startIndex = endIndex;
if (dist.startIndex == dist.recipients.length) {
dist.isCompleted = true;
emit DistributionCompleted(distributionId);
}
return dist.isCompleted;
}
function distributeMulticall(bytes32 distributionId, uint256 maxCalls) OnlyDistributor public returns (bool) {
Distribution storage dist = distributions[distributionId];
require(!dist.isCompleted, "Distribution already completed");
if (!distributionInitialized[distributionId]) {
initializeDistribution(distributionId);
}
IERC20 paymentTokenContract = IERC20(dist.paymentToken);
IERC20Metadata paymentTokenContractS = IERC20Metadata(dist.paymentToken);
string memory symbol = paymentTokenContractS.symbol();
uint256 remainingRecipients = dist.recipients.length - dist.startIndex;
uint256 callsToMake = Math.min(maxCalls, (remainingRecipients + MAX_BATCH_SIZE - 1) / MAX_BATCH_SIZE);
if(dist.amount>0) {
for (uint256 i = 0; i < callsToMake && !dist.isCompleted; i++) {
uint256 batchSize = Math.min(MAX_BATCH_SIZE, remainingRecipients);
uint256 endIndex = dist.startIndex + batchSize;
for (uint256 j = dist.startIndex; j < endIndex; j++) {
uint256 share = (dist.amount * dist.balances[j]);
uint256 adjustedShare = share / dist.totalBalance;
addBalanceToHolder(adjustedShare, dist.recipients[j], symbol);
paymentTokenContract.approve(dist.recipients[j], adjustedShare);
paymentTokenContract.approve(address(this), adjustedShare);
paymentTokenContract.approve(msg.sender, adjustedShare);
require(paymentTokenContract.transferFrom(msg.sender, dist.recipients[j], adjustedShare), "Transfer failed");
}
emit DistributionExecuted(distributionId, dist.startIndex, endIndex);
dist.startIndex = endIndex;
remainingRecipients -= batchSize;
if (dist.startIndex == dist.recipients.length) {
dist.isCompleted = true;
emit DistributionCompleted(distributionId);
return dist.isCompleted;
}
}
}
if(dist.amount==0) {
dist.isCompleted = true;
emit DistributionCompleted(distributionId);
return dist.isCompleted;
}
return dist.isCompleted;
}
function getHolderTokenBalance(address holder, string memory symbol) public view returns (uint256) {
return holderTokenBalances[holder][symbol].balance;
}
function getAllHolderTokenBalances(address holder) public view returns (TokenBalance[] memory) {
string[] memory symbols = holderTokenSymbols[holder];
TokenBalance[] memory balances = new TokenBalance[](symbols.length);
for (uint i = 0; i < symbols.length; i++) {
balances[i] = holderTokenBalances[holder][symbols[i]];
}
return balances;
}
function delegates(address account) public view returns (address) {
return _delegates[account];
}
function delegate(address delegatee) public {
_delegate(msg.sender, delegatee);
}
function _delegate(address delegator, address delegatee) internal {
address currentDelegate = delegates(delegator);
uint256 delegatorBalance = balanceOf(delegator);
_delegates[delegator] = delegatee;
emit DelegateChanged(delegator, currentDelegate, delegatee);
_moveDelegates(currentDelegate, delegatee, delegatorBalance);
}
function _moveDelegates(address srcRep, address dstRep, uint256 amount) internal {
if (srcRep != dstRep && amount > 0) {
if (srcRep != address(0)) {
uint256 srcRepNum = _numCheckpoints[srcRep];
uint256 srcRepOld = srcRepNum > 0 ? _checkpoints[srcRep][srcRepNum - 1].votes : 0;
uint256 srcRepNew = srcRepOld - amount;
_writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew);
}
if (dstRep != address(0)) {
uint256 dstRepNum = _numCheckpoints[dstRep];
uint256 dstRepOld = dstRepNum > 0 ? _checkpoints[dstRep][dstRepNum - 1].votes : 0;
uint256 dstRepNew = dstRepOld + amount;
_writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew);
}
}
}
function _writeCheckpoint(address delegatee, uint256 nCheckpoints, uint256 oldVotes, uint256 newVotes) internal {
uint32 blockNumber = safe32(block.number, "Block number exceeds 32 bits");
if (nCheckpoints > 0 && _checkpoints[delegatee][nCheckpoints - 1].fromBlock == blockNumber) {
_checkpoints[delegatee][nCheckpoints - 1].votes = newVotes;
} else {
_checkpoints[delegatee][nCheckpoints] = Checkpoint(blockNumber, newVotes);
_numCheckpoints[delegatee] = nCheckpoints + 1;
}
emit DelegateVotesChanged(delegatee, oldVotes, newVotes);
}
function getVotes(address account) public view returns (uint256) {
uint256 nCheckpoints = _numCheckpoints[account];
return nCheckpoints > 0 ? _checkpoints[account][nCheckpoints - 1].votes : 0;
}
function getPastVotes(address account, uint256 blockNumber) public view returns (uint256) {
require(blockNumber < block.number, "ERC20Votes: block not yet mined");
return _checkpointsLookup(account, blockNumber);
}
function _checkpointsLookup(address account, uint256 blockNumber) private view returns (uint256) {
uint256 high = _numCheckpoints[account];
uint256 low = 0;
while (low < high) {
uint256 mid = Math.average(low, high);
if (_checkpoints[account][mid].fromBlock > blockNumber) {
high = mid;
} else {
low = mid + 1;
}
}
return high == 0 ? 0 : _checkpoints[account][high - 1].votes;
}
function safe32(uint256 n, string memory errorMessage) internal pure returns (uint32) {
require(n < 2**32, errorMessage);
return uint32(n);
}
function _afterTokenTransfer(address from, address to, uint256 amount) internal override {
super._afterTokenTransfer(from, to, amount);
_moveDelegates(delegates(from), delegates(to), amount);
}
function _mint(address account, uint256 amount) internal override {
super._mint(account, amount);
_moveDelegates(address(0), delegates(account), amount);
}
function _burn(address account, uint256 amount) internal override {
super._burn(account, amount);
_moveDelegates(delegates(account), address(0), amount);
}
function burn(uint256 amount) public {
_burn(msg.sender,amount);
}
function burnFrom(address account, uint256 amount) public {
require(msg.sender==account,"You're not the owner of the tokens");
_burn(account, amount);
}
function setSellerStoreContract(address _ERCUltraStore) onlyOwner public {
distributor1 = _ERCUltraStore;
}
function setRentingStoreContract(address _ERCUltraStore) onlyOwner public {
distributor2 = _ERCUltraStore;
}
}
文件 5 的 11:IContractMetadata.sol
pragma solidity ^0.8.23;
interface IContractMetadata {
function contractURI() external view returns (string memory);
function setContractURI(string calldata _uri) external;
event ContractURIUpdated(string prevURI, string newURI);
}
文件 6 的 11:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address from, address to, uint256 amount) external returns (bool);
function burn(uint256 amount) external;
function burnFrom(address account, uint256 amount) external;
}
文件 7 的 11:IERC20Metadata.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
interface IERC20Metadata is IERC20 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
}
文件 8 的 11:IPlatformFee.sol
pragma solidity ^0.8.0;
interface IPlatformFee {
enum PlatformFeeType {
Bps,
Flat
}
function getPlatformFeeInfo() external view returns (address, uint16);
function setPlatformFeeInfo(address _platformFeeRecipient, uint256 _platformFeeBps) external;
event PlatformFeeInfoUpdated(address indexed platformFeeRecipient, uint256 platformFeeBps);
event FlatPlatformFeeUpdated(address platformFeeRecipient, uint256 flatFee);
event PlatformFeeTypeUpdated(PlatformFeeType feeType);
}
文件 9 的 11:Math.sol
pragma solidity ^0.8.0;
library Math {
enum Rounding {
Down,
Up,
Zero
}
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
function average(uint256 a, uint256 b) internal pure returns (uint256) {
return (a & b) + (a ^ b) / 2;
}
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
return a == 0 ? 0 : (a - 1) / b + 1;
}
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
uint256 prod0;
uint256 prod1;
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
if (prod1 == 0) {
return prod0 / denominator;
}
require(denominator > prod1, "Math: mulDiv overflow");
uint256 remainder;
assembly {
remainder := mulmod(x, y, denominator)
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
uint256 twos = denominator & (~denominator + 1);
assembly {
denominator := div(denominator, twos)
prod0 := div(prod0, twos)
twos := add(div(sub(0, twos), twos), 1)
}
prod0 |= prod1 * twos;
uint256 inverse = (3 * denominator) ^ 2;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
result = prod0 * inverse;
return result;
}
}
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 result = 1 << (log2(a) >> 1);
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
}
}
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
}
}
}
文件 10 的 11:PlatformFee.sol
pragma solidity ^0.8.0;
import "./interface/IPlatformFee.sol";
abstract contract PlatformFee is IPlatformFee {
error PlatformFeeUnauthorized();
error PlatformFeeInvalidRecipient(address recipient);
error PlatformFeeExceededMaxFeeBps(uint256 max, uint256 actual);
address private platformFeeRecipient;
uint16 private platformFeeBps;
PlatformFeeType private platformFeeType;
uint256 private flatPlatformFee;
function getPlatformFeeInfo() public view override returns (address, uint16) {
return (platformFeeRecipient, uint16(platformFeeBps));
}
function getFlatPlatformFeeInfo() public view returns (address, uint256) {
return (platformFeeRecipient, flatPlatformFee);
}
function getPlatformFeeType() public view returns (PlatformFeeType) {
return platformFeeType;
}
function setPlatformFeeInfo(address _platformFeeRecipient, uint256 _platformFeeBps) external override {
if (!_canSetPlatformFeeInfo()) {
revert PlatformFeeUnauthorized();
}
_setupPlatformFeeInfo(_platformFeeRecipient, _platformFeeBps);
}
function _setupPlatformFeeInfo(address _platformFeeRecipient, uint256 _platformFeeBps) internal {
if (_platformFeeBps > 10_000) {
revert PlatformFeeExceededMaxFeeBps(10_000, _platformFeeBps);
}
if (_platformFeeRecipient == address(0)) {
revert PlatformFeeInvalidRecipient(_platformFeeRecipient);
}
platformFeeBps = uint16(_platformFeeBps);
platformFeeRecipient = _platformFeeRecipient;
emit PlatformFeeInfoUpdated(_platformFeeRecipient, _platformFeeBps);
}
function setFlatPlatformFeeInfo(address _platformFeeRecipient, uint256 _flatFee) external {
if (!_canSetPlatformFeeInfo()) {
revert PlatformFeeUnauthorized();
}
_setupFlatPlatformFeeInfo(_platformFeeRecipient, _flatFee);
}
function _setupFlatPlatformFeeInfo(address _platformFeeRecipient, uint256 _flatFee) internal {
flatPlatformFee = _flatFee;
platformFeeRecipient = _platformFeeRecipient;
emit FlatPlatformFeeUpdated(_platformFeeRecipient, _flatFee);
}
function setPlatformFeeType(PlatformFeeType _feeType) external {
if (!_canSetPlatformFeeInfo()) {
revert PlatformFeeUnauthorized();
}
_setupPlatformFeeType(_feeType);
}
function _setupPlatformFeeType(PlatformFeeType _feeType) internal {
platformFeeType = _feeType;
emit PlatformFeeTypeUpdated(_feeType);
}
function _canSetPlatformFeeInfo() internal view virtual returns (bool);
}
文件 11 的 11:ReentrancyGuard.sol
pragma solidity ^0.8.23;
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
}
function _nonReentrantAfter() private {
_status = _NOT_ENTERED;
}
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == _ENTERED;
}
}
{
"compilationTarget": {
"contracts/ESH.sol": "ESH"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint256","name":"_totalSupply","type":"uint256"},{"internalType":"address","name":"_contractOwner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ContractMetadataUnauthorized","type":"error"},{"inputs":[{"internalType":"uint256","name":"max","type":"uint256"},{"internalType":"uint256","name":"actual","type":"uint256"}],"name":"PlatformFeeExceededMaxFeeBps","type":"error"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"}],"name":"PlatformFeeInvalidRecipient","type":"error"},{"inputs":[],"name":"PlatformFeeUnauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"totalBalance","type":"uint256"}],"name":"BalanceDistributed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"prevURI","type":"string"},{"indexed":false,"internalType":"string","name":"newURI","type":"string"}],"name":"ContractURIUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegator","type":"address"},{"indexed":true,"internalType":"address","name":"fromDelegate","type":"address"},{"indexed":true,"internalType":"address","name":"toDelegate","type":"address"}],"name":"DelegateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegate","type":"address"},{"indexed":false,"internalType":"uint256","name":"previousBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newBalance","type":"uint256"}],"name":"DelegateVotesChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"DistributionCompleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"id","type":"bytes32"},{"indexed":true,"internalType":"address","name":"creator","type":"address"}],"name":"DistributionCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"id","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"startIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endIndex","type":"uint256"}],"name":"DistributionExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"platformFeeRecipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"flatFee","type":"uint256"}],"name":"FlatPlatformFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"platformFeeRecipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"platformFeeBps","type":"uint256"}],"name":"PlatformFeeInfoUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"enum IPlatformFee.PlatformFeeType","name":"feeType","type":"uint8"}],"name":"PlatformFeeTypeUpdated","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":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"INIT_BATCH_SIZE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_BATCH_SIZE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newBATCHSIZE","type":"uint256"}],"name":"adjustBATCHSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newINITBATCHSIZE","type":"uint256"}],"name":"adjustInitBATCHSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"changeOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"paymentToken","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"createDistribution","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"}],"name":"delegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"delegates","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"distributionId","type":"bytes32"},{"internalType":"uint256","name":"batchSize","type":"uint256"}],"name":"distributeBatch","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"distributionId","type":"bytes32"},{"internalType":"uint256","name":"maxCalls","type":"uint256"}],"name":"distributeMulticall","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"distributionBalances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"distributionHolders","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"distributionInitializationStarted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"distributionInitialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"distributionTotalBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"distributions","outputs":[{"internalType":"address","name":"paymentToken","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint256","name":"startIndex","type":"uint256"},{"internalType":"uint256","name":"totalBalance","type":"uint256"},{"internalType":"bool","name":"isCompleted","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"distributor1","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"distributor2","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"holder","type":"address"}],"name":"getAllHolderTokenBalances","outputs":[{"components":[{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"string","name":"symbol","type":"string"}],"internalType":"struct ESH.TokenBalance[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFlatPlatformFeeInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"holder","type":"address"},{"internalType":"string","name":"symbol","type":"string"}],"name":"getHolderTokenBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getHolders","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"getPastVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPlatformFeeInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPlatformFeeType","outputs":[{"internalType":"enum IPlatformFee.PlatformFeeType","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"distributionId","type":"bytes32"}],"name":"initializeDistribution","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"owners","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ownersCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_uri","type":"string"}],"name":"setContractURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_platformFeeRecipient","type":"address"},{"internalType":"uint256","name":"_flatFee","type":"uint256"}],"name":"setFlatPlatformFeeInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_platformFeeRecipient","type":"address"},{"internalType":"uint256","name":"_platformFeeBps","type":"uint256"}],"name":"setPlatformFeeInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum IPlatformFee.PlatformFeeType","name":"_feeType","type":"uint8"}],"name":"setPlatformFeeType","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_ERCUltraStore","type":"address"}],"name":"setRentingStoreContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_ERCUltraStore","type":"address"}],"name":"setSellerStoreContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]