Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 149 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Approve | 23302696 | 181 days ago | IN | 0 ETH | 0.000028 | ||||
| Approve | 22675946 | 269 days ago | IN | 0 ETH | 0.00026856 | ||||
| Remove Limits | 22675935 | 269 days ago | IN | 0 ETH | 0.00011503 | ||||
| Approve | 22675933 | 269 days ago | IN | 0 ETH | 0.00025361 | ||||
| Approve | 22675927 | 269 days ago | IN | 0 ETH | 0.00025185 | ||||
| Manual Swap | 22675843 | 269 days ago | IN | 0 ETH | 0.0006892 | ||||
| Approve | 22675703 | 269 days ago | IN | 0 ETH | 0.00031794 | ||||
| Approve | 22675695 | 269 days ago | IN | 0 ETH | 0.00018398 | ||||
| Approve | 22675678 | 269 days ago | IN | 0 ETH | 0.00025907 | ||||
| Approve | 22675674 | 269 days ago | IN | 0 ETH | 0.00023963 | ||||
| Approve | 22675670 | 269 days ago | IN | 0 ETH | 0.00030604 | ||||
| Approve | 22675661 | 269 days ago | IN | 0 ETH | 0.00026899 | ||||
| Approve | 22675661 | 269 days ago | IN | 0 ETH | 0.00031533 | ||||
| Approve | 22675660 | 269 days ago | IN | 0 ETH | 0.00033557 | ||||
| Approve | 22675656 | 269 days ago | IN | 0 ETH | 0.00033003 | ||||
| Approve | 22675640 | 269 days ago | IN | 0 ETH | 0.00033931 | ||||
| Approve | 22675626 | 269 days ago | IN | 0 ETH | 0.00035825 | ||||
| Approve | 22675622 | 269 days ago | IN | 0 ETH | 0.00034698 | ||||
| Approve | 22675622 | 269 days ago | IN | 0 ETH | 0.00034698 | ||||
| Approve | 22675618 | 269 days ago | IN | 0 ETH | 0.00035205 | ||||
| Approve | 22675618 | 269 days ago | IN | 0 ETH | 0.00046326 | ||||
| Approve | 22675615 | 269 days ago | IN | 0 ETH | 0.00038537 | ||||
| Set Taxes | 22675610 | 269 days ago | IN | 0 ETH | 0.00020755 | ||||
| Approve | 22675606 | 269 days ago | IN | 0 ETH | 0.00040259 | ||||
| Approve | 22675602 | 269 days ago | IN | 0 ETH | 0.00041609 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| Transfer | 22676124 | 268 days ago | 0.00277461 ETH | ||||
| Transfer | 22676124 | 268 days ago | 0.00277461 ETH | ||||
| Transfer | 22676124 | 268 days ago | 0.00310493 ETH | ||||
| Transfer | 22676124 | 268 days ago | 0.00310493 ETH | ||||
| Transfer | 22675908 | 269 days ago | 0.00236795 ETH | ||||
| Transfer | 22675908 | 269 days ago | 0.00236795 ETH | ||||
| Transfer | 22675843 | 269 days ago | 0.68847207 ETH | ||||
| Transfer | 22675843 | 269 days ago | 0.68847207 ETH | ||||
| Transfer | 22675834 | 269 days ago | 0.004571 ETH | ||||
| Transfer | 22675834 | 269 days ago | 0.004571 ETH | ||||
| Transfer | 22675829 | 269 days ago | 0.00017787 ETH | ||||
| Transfer | 22675829 | 269 days ago | 0.00017787 ETH | ||||
| Transfer | 22675821 | 269 days ago | 0.00464904 ETH | ||||
| Transfer | 22675821 | 269 days ago | 0.00464904 ETH | ||||
| Transfer | 22675820 | 269 days ago | 0.0046955 ETH | ||||
| Transfer | 22675820 | 269 days ago | 0.0046955 ETH | ||||
| Transfer | 22675800 | 269 days ago | 0.0047283 ETH | ||||
| Transfer | 22675800 | 269 days ago | 0.0047283 ETH | ||||
| Transfer | 22675799 | 269 days ago | 0.00028682 ETH | ||||
| Transfer | 22675799 | 269 days ago | 0.00028682 ETH | ||||
| Transfer | 22675798 | 269 days ago | 0.00482232 ETH | ||||
| Transfer | 22675798 | 269 days ago | 0.00482232 ETH | ||||
| Transfer | 22675765 | 269 days ago | 0.00496129 ETH | ||||
| Transfer | 22675765 | 269 days ago | 0.00496129 ETH | ||||
| Transfer | 22675731 | 269 days ago | 0.00516071 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
LuckyOrRekt
Compiler Version
v0.8.24+commit.e11b9ed9
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity =0.8.24;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Address.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "./interfaces/IUniswapV2Factory.sol";
import "./interfaces/IUniswapV2Router02.sol";
import "./interfaces/ITaxContract.sol";
import "./RandomnessProvider.sol";
/*
Lucky or Rekt ($YOLO)
*/
contract LuckyOrRekt is Context, IERC20, Ownable {
using Address for address payable;
using SafeMath for uint;
mapping(address => uint) private _balances;
mapping(address => mapping(address => uint)) private _allowances;
mapping(address => bool) private _isExcludedFromFee;
address payable public taxContractAddress;
RandomnessProvider public randomnessProvider;
uint private _buyTax = 30;
uint private _sellTax = 30;
uint private _preventSwapBefore = 30;
// Lucky or Rekt Configuration Parameters
uint public lossChance = 60; // 60% chance of loss (rekt)
uint public winChance = 40; // 40% chance of win (lucky)
// Range configuration struct
struct Range {
uint percent; // Percentage of this range within the scenario
uint multiplier; // Penalty percentage (for loss) or bonus percentage (for win)
}
// Loss (Rekt) Configuration - 5 ranges
Range[5] public lossRanges;
// Win (Lucky) Configuration - 5 ranges
Range[5] public winRanges;
// Burn configuration for losses
uint public burnPercentageOnLoss = 30; // 30% of penalty tokens are burned, rest to tax contract
// Minimum balance protection (percentage of bought amount that must remain)
uint public minBalancePercentage = 50; // 50% of bought amount must remain
// Maximum bonus cap (percentage of total supply that can be minted as bonus)
uint public maxBonusPercentage = 10; // 10% of total supply max per bonus
uint8 private constant _decimals = 8;
uint private _totalSupply = 1_000_000_000 * 10 ** _decimals;
string private constant _name = unicode"Lucky or Rekt";
string private constant _symbol = unicode"YOLO";
uint public _maxTxAmount = (_totalSupply * 135) / 10000; // 1.35%
uint public _maxWalletSize = (_totalSupply * 135) / 10000; // 1.35%
uint public _swapThreshold = _totalSupply / 1000;
IUniswapV2Router02 private uniswapV2Router;
address private uniswapV2Pair;
address public routerAddress;
bool private tradingOpen;
uint public launchBlock;
bool private inSwap = false;
bool private swapEnabled = false;
bool private inLuckyOrRekt = false; // Reentrancy protection for Lucky or Rekt
// Emergency controls - starts disabled by default
bool public luckyOrRektPaused = true;
address public lastBuyer;
uint public lastBoughtAmount;
// Track minimum balance required for pending lucky or rekt effects
mapping(address => uint) public pendingMinBalance;
// Track total tokens burned and minted from Lucky or Rekt effects
uint public totalBurned = 0; // Total tokens burned from Rekt effects
uint public totalMinted = 0; // Total tokens minted from Lucky effects
event MaxTxAmountUpdated(uint _maxTxAmount);
event LuckyOrRekted(
address indexed buyer,
uint boughtAmount,
int256 percentageModifier,
uint modifiedAmount,
bool isLucky
);
event TaxContractCallFailed(address indexed buyer, uint amount);
modifier lockTheSwap() {
inSwap = true;
_;
inSwap = false;
}
constructor(address _taxContractAddress, address _randomnessProvider) {
taxContractAddress = payable(_taxContractAddress);
randomnessProvider = RandomnessProvider(_randomnessProvider);
_balances[_msgSender()] = _totalSupply;
// Set default router address for Ethereum Sepolia
// Update this for different networks:
// BASE: 0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24
// ETHEREUM MAINNET: 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D
routerAddress = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
_isExcludedFromFee[_msgSender()] = true;
_isExcludedFromFee[address(this)] = true;
_isExcludedFromFee[_taxContractAddress] = true;
// Initialize loss ranges with default values (more likely to lose big)
lossRanges[0] = Range(10, 5); // 10% chance, -5% penalty (small loss, rare)
lossRanges[1] = Range(20, 15); // 20% chance, -15% penalty
lossRanges[2] = Range(30, 25); // 30% chance, -25% penalty
lossRanges[3] = Range(25, 35); // 25% chance, -35% penalty
lossRanges[4] = Range(15, 50); // 15% chance, -50% penalty (big loss, more common)
// Initialize win ranges with default values (less likely to win big)
winRanges[0] = Range(40, 5); // 40% chance, +5% bonus (small win, common)
winRanges[1] = Range(30, 10); // 30% chance, +10% bonus
winRanges[2] = Range(20, 20); // 20% chance, +20% bonus
winRanges[3] = Range(8, 50); // 8% chance, +50% bonus (rare)
winRanges[4] = Range(2, 100); // 2% chance, +100% bonus (very rare jackpot)
// Validate that ranges add up to 100%
uint totalLossPercent = 0;
uint totalWinPercent = 0;
for (uint i = 0; i < 5; i++) {
totalLossPercent += lossRanges[i].percent;
totalWinPercent += winRanges[i].percent;
}
require(totalLossPercent == 100, "Loss ranges must add up to 100%");
require(totalWinPercent == 100, "Win ranges must add up to 100%");
emit Transfer(address(0), _msgSender(), _totalSupply);
}
function name() public pure returns (string memory) {
return _name;
}
function symbol() public pure returns (string memory) {
return _symbol;
}
function decimals() public pure returns (uint8) {
return _decimals;
}
function totalSupply() public view override returns (uint) {
return _totalSupply;
}
function balanceOf(address account) public view override returns (uint) {
return _balances[account];
}
function transfer(
address recipient,
uint amount
) public override returns (bool) {
_transfer(_msgSender(), recipient, amount);
return true;
}
function allowance(
address owner,
address spender
) public view override returns (uint) {
return _allowances[owner][spender];
}
function approve(
address spender,
uint amount
) public override returns (bool) {
_approve(_msgSender(), spender, amount);
return true;
}
function transferFrom(
address sender,
address recipient,
uint amount
) public override returns (bool) {
_transfer(sender, recipient, amount);
_approve(
sender,
_msgSender(),
_allowances[sender][_msgSender()].sub(
amount,
"ERC20: transfer amount exceeds allowance"
)
);
return true;
}
function _approve(address owner, address spender, uint amount) private {
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 _transfer(address from, address to, uint amount) private {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
require(amount > 0, "Transfer amount must be greater than zero");
// Determine if current transaction is a buy to check against lastBuyer
// Note: This detection works for Uniswap V2 direct swaps, may need adjustment for V3 or aggregators
address currentBuyer;
bool isSell = (to == uniswapV2Pair && from != address(this));
// Improved buy detection with additional safety checks
if (
from == uniswapV2Pair &&
to != address(uniswapV2Router) &&
to != address(this) &&
to != uniswapV2Pair &&
to != taxContractAddress &&
!Address.isContract(to) &&
to != address(0) // Additional safety check
) {
// this is a buy - from pair to EOA (not router or other contract)
currentBuyer = to;
}
// Check if sender has pending lucky or rekt effect and prevent draining below minimum
// Exception: Allow sells - they will clear the pending status
if (
pendingMinBalance[from] > 0 && !_isExcludedFromFee[from] && !isSell
) {
uint balanceAfterTransfer = _balances[from].sub(amount);
require(
balanceAfterTransfer >= pendingMinBalance[from],
"Cannot transfer below minimum balance while pending lucky or rekt effect"
);
}
// If user is selling and has pending status, clear them as lastBuyer
if (isSell && pendingMinBalance[from] > 0) {
if (lastBuyer == from) {
lastBuyer = address(0);
lastBoughtAmount = 0;
}
pendingMinBalance[from] = 0;
}
// Apply Lucky or Rekt to previous buyer (if exists) on EVERY transaction
// But prevent users from triggering their own effect via sells (transfers are allowed)
if (
lastBuyer != address(0) &&
lastBoughtAmount > 0 &&
lastBuyer != address(this) &&
lastBuyer != address(uniswapV2Router) &&
lastBuyer != address(uniswapV2Pair) &&
lastBuyer != address(taxContractAddress) &&
!Address.isContract(lastBuyer) &&
!(isSell && lastBuyer == from) &&
!inLuckyOrRekt // Reentrancy protection
) {
// Store the values before clearing to ensure randomness provider gets correct data
address buyerToProcess = lastBuyer;
uint amountToProcess = lastBoughtAmount;
// Clear the lastBuyer immediately to prevent reentrancy issues
lastBuyer = address(0);
lastBoughtAmount = 0;
// Process lucky/rekt with internal error handling using stored values
bool success = _processLuckyOrRektInternal(
buyerToProcess,
amountToProcess,
from, // Current transaction sender
amount // Current transaction amount
);
if (!success) {
// Failed - emit event but don't revert transaction
emit TaxContractCallFailed(buyerToProcess, amountToProcess);
}
}
uint taxAmount;
if (!_isExcludedFromFee[from] && !_isExcludedFromFee[to]) {
// Only apply tax on buys and sells, not normal transfers
if (currentBuyer != address(0)) {
// This is a buy transaction
if (!_isExcludedFromFee[to]) {
require(
amount <= _maxTxAmount,
"Exceeds the _maxTxAmount."
);
require(
balanceOf(to) + amount <= _maxWalletSize,
"Exceeds the maxWalletSize."
);
}
taxAmount = amount.mul(_buyTax).div(100);
} else if (to == uniswapV2Pair && from != address(this)) {
// This is a sell transaction
require(amount <= _maxTxAmount, "Exceeds the _maxTxAmount.");
taxAmount = amount.mul(_sellTax).div(100);
}
// Normal transfers between users have no tax (taxAmount remains 0)
// Auto-swap logic for sells only
if (to == uniswapV2Pair && from != address(this)) {
uint contractTokenBalance = balanceOf(address(this));
if (
!inSwap &&
swapEnabled &&
contractTokenBalance > _swapThreshold &&
block.number > launchBlock + _preventSwapBefore
) {
swapTokensForEth(
min(amount, min(contractTokenBalance, _swapThreshold))
);
uint contractETHBalance = address(this).balance;
if (contractETHBalance > 0) {
sendETHToTaxContract(contractETHBalance);
ITaxContract(taxContractAddress).distribute(
contractETHBalance
);
}
}
}
}
if (taxAmount > 0) {
_balances[address(this)] = _balances[address(this)].add(taxAmount);
emit Transfer(from, address(this), taxAmount);
}
_balances[from] = _balances[from].sub(amount);
_balances[to] = _balances[to].add(amount.sub(taxAmount));
// Set new buyer for next transaction (if this is a buy)
if (
currentBuyer != address(0) &&
currentBuyer != address(this) &&
currentBuyer != address(uniswapV2Router) &&
currentBuyer != address(uniswapV2Pair) &&
currentBuyer != address(taxContractAddress) &&
!Address.isContract(currentBuyer)
) {
uint boughtAmount = amount.sub(taxAmount);
if (boughtAmount > 0) {
// Clear previous buyer's minimum balance requirement if they're buying again
if (pendingMinBalance[currentBuyer] > 0) {
pendingMinBalance[currentBuyer] = 0;
}
lastBuyer = currentBuyer;
lastBoughtAmount = boughtAmount;
// Set minimum balance requirement (configurable percentage of bought amount)
pendingMinBalance[currentBuyer] = boughtAmount
.mul(minBalancePercentage)
.div(100);
}
}
emit Transfer(from, to, amount.sub(taxAmount));
}
function min(uint a, uint b) private pure returns (uint) {
return (a > b) ? b : a;
}
/**
* @dev Determines lucky or rekt outcome for a buyer
* @param buyer The address of the buyer (previous buyer being processed)
* @param amount The amount being bought (previous buyer's amount)
* @param currentSender Current transaction sender (for additional entropy)
* @param currentAmount Current transaction amount (for additional entropy)
* @return percentageModifier The percentage modifier (positive for bonus, negative for penalty)
* @return isLucky True if the outcome is lucky (bonus), false if rekt (penalty)
*/
function luckyOrRekt(
address buyer,
uint amount,
address currentSender,
uint currentAmount
) private returns (int256 percentageModifier, bool isLucky) {
// Safety checks to prevent division by zero
require(
lossChance > 0 && winChance > 0,
"Invalid chance configuration"
);
require(lossChance + winChance == 100, "Chances must equal 100");
// Get random number from external provider (0-99)
// Pass current transaction info (msg.sender, current amount) for additional entropy
// while processing the effect for the previous buyer
uint256 randomNum = randomnessProvider.requestRandomness(
buyer, // Previous buyer being processed
amount, // Previous buyer's amount
currentSender, // Current transaction sender (for additional entropy)
currentAmount // Current transaction amount (for additional entropy)
);
// Determine win/loss based on configured split
if (randomNum < lossChance) {
// REKT - Apply penalty
isLucky = false;
// Map randomNum (0 to lossChance-1) to loss ranges with proper scaling
// Ensure full 0-99 coverage for range positions
uint256 lossPosition = (randomNum * 100) / lossChance;
// Cap at 99 to ensure we don't exceed range bounds
if (lossPosition >= 100) lossPosition = 99;
// Calculate cumulative range boundaries
uint256 range1End = lossRanges[0].percent;
uint256 range2End = range1End + lossRanges[1].percent;
uint256 range3End = range2End + lossRanges[2].percent;
uint256 range4End = range3End + lossRanges[3].percent;
if (lossPosition < range1End) {
percentageModifier = -int256(lossRanges[0].multiplier);
} else if (lossPosition < range2End) {
percentageModifier = -int256(lossRanges[1].multiplier);
} else if (lossPosition < range3End) {
percentageModifier = -int256(lossRanges[2].multiplier);
} else if (lossPosition < range4End) {
percentageModifier = -int256(lossRanges[3].multiplier);
} else {
percentageModifier = -int256(lossRanges[4].multiplier);
}
} else {
// LUCKY - Apply bonus
isLucky = true;
// Map randomNum (lossChance to 99) to win ranges with proper scaling
// Ensure full 0-99 coverage for range positions
uint256 winPosition = ((randomNum - lossChance) * 100) / winChance;
// Cap at 99 to ensure we don't exceed range bounds
if (winPosition >= 100) winPosition = 99;
// Calculate cumulative range boundaries
uint256 range1End = winRanges[0].percent;
uint256 range2End = range1End + winRanges[1].percent;
uint256 range3End = range2End + winRanges[2].percent;
uint256 range4End = range3End + winRanges[3].percent;
if (winPosition < range1End) {
percentageModifier = int256(winRanges[0].multiplier);
} else if (winPosition < range2End) {
percentageModifier = int256(winRanges[1].multiplier);
} else if (winPosition < range3End) {
percentageModifier = int256(winRanges[2].multiplier);
} else if (winPosition < range4End) {
percentageModifier = int256(winRanges[3].multiplier);
} else {
percentageModifier = int256(winRanges[4].multiplier);
}
}
return (percentageModifier, isLucky);
}
function swapTokensForEth(uint tokenAmount) private lockTheSwap {
if (tokenAmount == 0) return;
if (!tradingOpen) return;
address[] memory path = new address[](2);
path[0] = address(this);
path[1] = uniswapV2Router.WETH();
_approve(address(this), address(uniswapV2Router), tokenAmount);
uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(
tokenAmount,
0,
path,
address(this),
block.timestamp
);
}
function removeLimits() external onlyOwner {
_maxTxAmount = type(uint256).max;
_maxWalletSize = type(uint256).max;
emit MaxTxAmountUpdated(type(uint256).max);
}
function sendETHToTaxContract(uint amount) private {
Address.sendValue(taxContractAddress, amount);
}
function openTrading() external onlyOwner {
require(!tradingOpen, "Trading is already open");
require(balanceOf(address(this)) > 0, "No token balance");
require(address(this).balance > 0, "No eth balance");
require(routerAddress != address(0), "Router address not set");
uniswapV2Router = IUniswapV2Router02(routerAddress);
_approve(address(this), address(uniswapV2Router), _totalSupply);
uniswapV2Pair = IUniswapV2Factory(uniswapV2Router.factory()).createPair(
address(this),
uniswapV2Router.WETH()
);
uniswapV2Router.addLiquidityETH{value: address(this).balance}(
address(this),
balanceOf(address(this)),
0,
0,
owner(),
block.timestamp
);
IERC20(uniswapV2Pair).approve(address(uniswapV2Router), type(uint).max);
swapEnabled = true;
tradingOpen = true;
launchBlock = block.number;
}
function manualSwap(uint amount) external onlyOwner {
uint tokenBalance = balanceOf(address(this));
require(amount <= tokenBalance, "!amount");
if (amount > 0) {
swapTokensForEth(amount);
}
uint ethBalance = address(this).balance;
if (ethBalance > 0) {
sendETHToTaxContract(ethBalance);
ITaxContract(taxContractAddress).distribute(ethBalance);
}
}
function setExcluded(address account, bool isExcluded) external onlyOwner {
_isExcludedFromFee[account] = isExcluded;
}
function setTaxContract(address _taxContractAddress) external onlyOwner {
taxContractAddress = payable(_taxContractAddress);
}
function setTaxes(uint _buyTaxRate, uint _sellTaxRate) external onlyOwner {
require(_buyTaxRate <= 30, "Buy tax cannot exceed 30%");
require(_sellTaxRate <= 30, "Sell tax cannot exceed 30%");
_buyTax = _buyTaxRate;
_sellTax = _sellTaxRate;
}
function getBuyTax() external view returns (uint) {
return _buyTax;
}
function getSellTax() external view returns (uint) {
return _sellTax;
}
function setRouterAddress(address _routerAddress) external onlyOwner {
require(!tradingOpen, "Cannot change router after trading opens");
require(_routerAddress != address(0), "Router address cannot be zero");
routerAddress = _routerAddress;
}
function rescueETH() external onlyOwner {
payable(_msgSender()).transfer(address(this).balance);
}
function rescueTokens(address _token) external onlyOwner {
require(_token != address(this), "Can not rescue own token!");
IERC20(_token).transfer(
_msgSender(),
IERC20(_token).balanceOf(address(this))
);
}
// Lucky or Rekt Configuration Functions
function setLuckyOrRektChances(
uint _lossChance,
uint _winChance
) external onlyOwner {
require(_lossChance + _winChance == 100, "Chances must add up to 100");
lossChance = _lossChance;
winChance = _winChance;
}
function setLossRange(
uint rangeNumber,
uint rangePercent,
uint penaltyPercent
) external onlyOwner {
require(rangeNumber >= 1 && rangeNumber <= 5, "Invalid range number");
require(penaltyPercent <= 100, "Penalty cannot exceed 100%");
lossRanges[rangeNumber - 1] = Range(rangePercent, penaltyPercent);
// Validate that all loss ranges add up to 100%
uint totalPercent = 0;
for (uint i = 0; i < 5; i++) {
totalPercent += lossRanges[i].percent;
}
require(totalPercent == 100, "Loss ranges must add up to 100%");
}
function setWinRange(
uint rangeNumber,
uint rangePercent,
uint bonusPercent
) external onlyOwner {
require(rangeNumber >= 1 && rangeNumber <= 5, "Invalid range number");
require(bonusPercent <= 1000, "Bonus cannot exceed 1000%"); // Allow up to 10x bonus
winRanges[rangeNumber - 1] = Range(rangePercent, bonusPercent);
// Validate that all win ranges add up to 100%
uint totalPercent = 0;
for (uint i = 0; i < 5; i++) {
totalPercent += winRanges[i].percent;
}
require(totalPercent == 100, "Win ranges must add up to 100%");
}
function setBurnPercentage(uint _burnPercentage) external onlyOwner {
require(_burnPercentage <= 100, "Burn percentage cannot exceed 100%");
burnPercentageOnLoss = _burnPercentage;
}
function setMinBalancePercentage(
uint _minBalancePercentage
) external onlyOwner {
require(
_minBalancePercentage <= 100,
"Min balance percentage cannot exceed 100%"
);
minBalancePercentage = _minBalancePercentage;
}
function setMaxBonusPercentage(
uint _maxBonusPercentage
) external onlyOwner {
require(
_maxBonusPercentage <= 50,
"Max bonus percentage cannot exceed 50% of supply"
);
maxBonusPercentage = _maxBonusPercentage;
}
// View functions for lucky or rekt status
function getPendingMinBalance(address user) external view returns (uint) {
return pendingMinBalance[user];
}
function isUserPendingLuckyOrRekt(
address user
) external view returns (bool) {
return pendingMinBalance[user] > 0;
}
// Getter functions for ranges
function getLossRange(
uint index
) external view returns (uint percent, uint multiplier) {
require(index < 5, "Invalid range index");
return (lossRanges[index].percent, lossRanges[index].multiplier);
}
function getWinRange(
uint index
) external view returns (uint percent, uint multiplier) {
require(index < 5, "Invalid range index");
return (winRanges[index].percent, winRanges[index].multiplier);
}
function getAllLossRanges() external view returns (Range[5] memory) {
return lossRanges;
}
function getAllWinRanges() external view returns (Range[5] memory) {
return winRanges;
}
// Analytics functions for Lucky or Rekt effects
function getTotalBurned() external view returns (uint) {
return totalBurned;
}
function getTotalMinted() external view returns (uint) {
return totalMinted;
}
function getNetSupplyChange() external view returns (int256) {
return int256(totalMinted) - int256(totalBurned);
}
function getBurnMintRatio() external view returns (uint256) {
if (totalMinted == 0) return 0;
return (totalBurned * 100) / totalMinted; // Returns percentage (burned/minted * 100)
}
receive() external payable {}
/**
* @dev Internal function to process lucky or rekt logic for a buyer
* Returns true on success, false on failure (to prevent transaction revert)
*/
function _processLuckyOrRektInternal(
address buyer,
uint boughtAmount,
address from, // Current transaction sender
uint amount // Current transaction amount
) private returns (bool) {
require(!inLuckyOrRekt, "Already processing lucky or rekt");
// Check if lucky or rekt system is paused
if (luckyOrRektPaused) {
return true; // Skip processing but don't fail the transaction
}
inLuckyOrRekt = true; // Set reentrancy lock
try this._executeLuckyOrRekt(buyer, boughtAmount, from, amount) {
inLuckyOrRekt = false; // Release reentrancy lock
return true;
} catch {
inLuckyOrRekt = false; // Release reentrancy lock
return false;
}
}
/**
* @dev External function to execute lucky or rekt logic (for try-catch)
*/
function _executeLuckyOrRekt(
address buyer,
uint boughtAmount,
address from,
uint amount
) external {
require(msg.sender == address(this), "Only self-call allowed");
// Apply lucky or rekt logic to the buyer
(int256 percentageModifier, bool isLucky) = luckyOrRekt(
buyer,
boughtAmount,
from, // Current transaction sender for additional entropy
amount // Current transaction amount for additional entropy
);
if (percentageModifier != 0) {
uint modificationAmount = boughtAmount
.mul(
uint256(
percentageModifier > 0
? percentageModifier
: -percentageModifier
)
)
.div(100);
if (isLucky) {
// LUCKY - Mint new tokens as bonus (with safety cap)
if (modificationAmount > 0) {
// Cap bonus to prevent massive supply inflation (max configurable % of current supply)
uint maxBonus = _totalSupply.mul(maxBonusPercentage).div(
100
);
if (modificationAmount > maxBonus) {
modificationAmount = maxBonus;
}
_totalSupply = _totalSupply.add(modificationAmount);
_balances[buyer] = _balances[buyer].add(modificationAmount);
totalMinted = totalMinted.add(modificationAmount); // Track total minted
emit Transfer(address(0), buyer, modificationAmount);
}
} else {
// REKT - Apply penalty by burning some tokens and sending rest to tax contract
if (modificationAmount > 0) {
uint availableBalance = _balances[buyer];
uint minBalance = pendingMinBalance[buyer];
// Calculate maximum penalty that can be applied without going below minimum balance
uint maxPenalty = availableBalance > minBalance
? availableBalance - minBalance
: 0;
uint actualPenalty = modificationAmount <= maxPenalty
? modificationAmount
: maxPenalty;
if (actualPenalty > 0) {
// Calculate burn amount and tax contract amount based on actual penalty
uint burnAmount = actualPenalty
.mul(burnPercentageOnLoss)
.div(100);
uint taxContractAmount = actualPenalty.sub(burnAmount);
// Remove penalty tokens from buyer
_balances[buyer] = _balances[buyer].sub(actualPenalty);
// Burn tokens (decrease total supply)
if (burnAmount > 0) {
_totalSupply = _totalSupply.sub(burnAmount);
totalBurned = totalBurned.add(burnAmount); // Track total burned
emit Transfer(buyer, address(0), burnAmount);
}
// Transfer remaining penalty to tax contract
if (taxContractAmount > 0) {
_balances[taxContractAddress] = _balances[
taxContractAddress
].add(taxContractAmount);
emit Transfer(
buyer,
taxContractAddress,
taxContractAmount
);
// Safe external call - will revert if it fails
ITaxContract(taxContractAddress).gather(
taxContractAmount
);
}
// Update modification amount for event emission
modificationAmount = actualPenalty;
}
}
}
emit LuckyOrRekted(
buyer,
boughtAmount,
percentageModifier,
modificationAmount,
isLucky
);
}
// Clear the pending minimum balance requirement for the processed buyer
if (pendingMinBalance[buyer] > 0) {
pendingMinBalance[buyer] = 0;
}
}
function setRandomnessProvider(
address _randomnessProvider
) external onlyOwner {
randomnessProvider = RandomnessProvider(_randomnessProvider);
}
function enableLuckyOrRekt() external onlyOwner {
luckyOrRektPaused = false;
}
function disableLuckyOrRekt() external onlyOwner {
luckyOrRektPaused = true;
}
function isLuckyOrRektEnabled() external view returns (bool) {
return !luckyOrRektPaused;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
*
* Furthermore, `isContract` will also return true if the target contract within
* the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
* which only has an effect at the end of a transaction.
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol)
pragma solidity ^0.8.0;
// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.
/**
* @dev Wrappers over Solidity's arithmetic operations.
*
* NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
* now has built in overflow checking.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the subtraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
return a + b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
return a * b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator.
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a / b;
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
interface ITaxContract {
function distribute(uint amount) external;
function gather(uint amount) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IUniswapV2Factory {
event PairCreated(
address indexed token0,
address indexed token1,
address pair,
uint
);
function feeTo() external view returns (address);
function feeToSetter() external view returns (address);
function getPair(address tokenA, address tokenB)
external
view
returns (address pair);
function allPairs(uint) external view returns (address pair);
function allPairsLength() external view returns (uint);
function createPair(address tokenA, address tokenB)
external
returns (address pair);
function setFeeTo(address) external;
function setFeeToSetter(address) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IUniswapV2Router02 {
function factory() external pure returns (address);
function WETH() external pure returns (address);
function addLiquidity(
address tokenA,
address tokenB,
uint amountADesired,
uint amountBDesired,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
)
external
returns (
uint amountA,
uint amountB,
uint liquidity
);
function addLiquidityETH(
address token,
uint amountTokenDesired,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
)
external
payable
returns (
uint amountToken,
uint amountETH,
uint liquidity
);
function removeLiquidityETH(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external returns (uint amountToken, uint amountETH);
function removeLiquidityETHSupportingFeeOnTransferTokens(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external returns (uint amountETH);
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
function swapExactETHForTokensSupportingFeeOnTransferTokens(
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external payable;
function swapExactTokensForETHSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
}// SPDX-License-Identifier: MIT
pragma solidity =0.8.24;
import "@openzeppelin/contracts/access/Ownable.sol";
/**
* @title RandomnessProvider
* @dev Enhanced pseudo-random number generator with multiple entropy sources
* Designed to be unpredictable while remaining synchronous
*/
contract RandomnessProvider is Ownable {
// Historical entropy accumulation
bytes32 private entropyPool;
uint256 private entropyNonce;
uint256 private lastBlockUsed;
// Historical block hashes for additional entropy
mapping(uint256 => bytes32) private historicalHashes;
uint256 private hashHistorySize = 10;
uint256 private currentHashIndex;
// Request tracking for additional entropy
mapping(address => uint256) private requestCounts;
uint256 private totalRequests;
// Gas accumulation for entropy
uint256 private accumulatedGasUsed;
// Events
event EntropyUpdated(bytes32 indexed newEntropy, uint256 blockNumber);
event RandomnessRequested(
address indexed requester,
uint256 result,
uint256 entropy
);
constructor() {
// Initialize entropy pool with deployment data
entropyPool = keccak256(
abi.encodePacked(
block.timestamp,
block.prevrandao,
block.number,
msg.sender,
address(this),
block.coinbase
)
);
lastBlockUsed = block.number;
entropyNonce = 1;
}
/**
* @dev Request enhanced pseudo-random number (0-99)
* Uses multiple entropy sources for unpredictability
*/
function requestRandomness(
address buyer,
uint256 amount,
address lastBuyer,
uint256 lastBoughtAmount
) external returns (uint256) {
// Update entropy pool before generating randomness
_updateEntropyPool();
// Generate randomness with multiple entropy sources
uint256 randomness = _generateEnhancedRandom(
buyer,
amount,
lastBuyer,
lastBoughtAmount
);
// Update request tracking
requestCounts[tx.origin]++;
totalRequests++;
// Update accumulated gas for additional entropy
accumulatedGasUsed += gasleft();
emit RandomnessRequested(tx.origin, randomness, uint256(entropyPool));
return randomness;
}
/**
* @dev Generate enhanced pseudo-random number with multiple entropy sources
*/
function _generateEnhancedRandom(
address buyer,
uint256 amount,
address lastBuyer,
uint256 lastBoughtAmount
) private returns (uint256) {
// Increment nonce for each request
entropyNonce++;
// Gather multiple entropy sources
bytes32 entropy1 = keccak256(
abi.encodePacked(
entropyPool,
block.timestamp,
block.prevrandao,
block.number,
entropyNonce
)
);
bytes32 entropy2 = keccak256(
abi.encodePacked(
buyer,
amount,
lastBuyer,
lastBoughtAmount,
msg.sender,
tx.origin
)
);
bytes32 entropy3 = keccak256(
abi.encodePacked(
block.coinbase,
block.gaslimit,
accumulatedGasUsed,
totalRequests,
requestCounts[tx.origin]
)
);
// Use historical block data if available
bytes32 historicalEntropy = _getHistoricalEntropy();
// Combine all entropy sources with multiple hash rounds
bytes32 combinedEntropy = entropy1;
for (uint i = 0; i < 3; i++) {
combinedEntropy = keccak256(
abi.encodePacked(
combinedEntropy,
entropy2,
entropy3,
historicalEntropy,
i
)
);
}
// Final randomness extraction with modular reduction
uint256 randomValue = uint256(combinedEntropy);
// Use multiple modular operations to avoid patterns
randomValue =
(randomValue ^ uint256(entropy2) ^ uint256(entropy3)) %
100;
// Store this round's entropy for future use
_storeHistoricalHash(combinedEntropy);
return randomValue;
}
/**
* @dev Update the entropy pool with current block data
*/
function _updateEntropyPool() private {
if (block.number > lastBlockUsed) {
entropyPool = keccak256(
abi.encodePacked(
entropyPool,
blockhash(block.number - 1),
block.timestamp,
block.prevrandao,
block.number,
totalRequests
)
);
lastBlockUsed = block.number;
emit EntropyUpdated(entropyPool, block.number);
}
}
/**
* @dev Get historical entropy from stored block hashes
*/
function _getHistoricalEntropy() private view returns (bytes32) {
bytes32 historical = bytes32(0);
// Combine several historical hashes if available
for (uint i = 0; i < hashHistorySize && i < currentHashIndex; i++) {
uint256 index = (currentHashIndex - 1 - i) % hashHistorySize;
historical = keccak256(
abi.encodePacked(historical, historicalHashes[index])
);
}
return historical;
}
/**
* @dev Store hash for historical entropy
*/
function _storeHistoricalHash(bytes32 hash) private {
historicalHashes[currentHashIndex % hashHistorySize] = hash;
currentHashIndex++;
}
/**
* @dev Admin function to add external entropy (e.g., from off-chain sources)
*/
function addExternalEntropy(bytes32 externalEntropy) external onlyOwner {
entropyPool = keccak256(
abi.encodePacked(
entropyPool,
externalEntropy,
block.timestamp,
block.number
)
);
emit EntropyUpdated(entropyPool, block.number);
}
/**
* @dev Emergency function to reset entropy pool
*/
function resetEntropyPool() external onlyOwner {
entropyPool = keccak256(
abi.encodePacked(
block.timestamp,
block.prevrandao,
block.number,
totalRequests,
address(this).balance
)
);
entropyNonce = 1;
emit EntropyUpdated(entropyPool, block.number);
}
/**
* @dev View function to check entropy pool state (for debugging)
*/
function getEntropyInfo()
external
view
returns (
bytes32 currentEntropy,
uint256 currentNonce,
uint256 totalRequestCount,
uint256 historySize
)
{
return (entropyPool, entropyNonce, totalRequests, currentHashIndex);
}
/**
* @dev Get user's request statistics
*/
function getUserStats(
address user
) external view returns (uint256 requestCount) {
return requestCounts[user];
}
}{
"optimizer": {
"enabled": true,
"runs": 200
},
"viaIR": true,
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_taxContractAddress","type":"address"},{"internalType":"address","name":"_randomnessProvider","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"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":true,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint256","name":"boughtAmount","type":"uint256"},{"indexed":false,"internalType":"int256","name":"percentageModifier","type":"int256"},{"indexed":false,"internalType":"uint256","name":"modifiedAmount","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isLucky","type":"bool"}],"name":"LuckyOrRekted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_maxTxAmount","type":"uint256"}],"name":"MaxTxAmountUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TaxContractCallFailed","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":[{"internalType":"address","name":"buyer","type":"address"},{"internalType":"uint256","name":"boughtAmount","type":"uint256"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"_executeLuckyOrRekt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"_maxTxAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_maxWalletSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_swapThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":[],"name":"burnPercentageOnLoss","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"disableLuckyOrRekt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enableLuckyOrRekt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAllLossRanges","outputs":[{"components":[{"internalType":"uint256","name":"percent","type":"uint256"},{"internalType":"uint256","name":"multiplier","type":"uint256"}],"internalType":"struct LuckyOrRekt.Range[5]","name":"","type":"tuple[5]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllWinRanges","outputs":[{"components":[{"internalType":"uint256","name":"percent","type":"uint256"},{"internalType":"uint256","name":"multiplier","type":"uint256"}],"internalType":"struct LuckyOrRekt.Range[5]","name":"","type":"tuple[5]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBurnMintRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBuyTax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getLossRange","outputs":[{"internalType":"uint256","name":"percent","type":"uint256"},{"internalType":"uint256","name":"multiplier","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNetSupplyChange","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getPendingMinBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSellTax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalBurned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getWinRange","outputs":[{"internalType":"uint256","name":"percent","type":"uint256"},{"internalType":"uint256","name":"multiplier","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isLuckyOrRektEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"isUserPendingLuckyOrRekt","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastBoughtAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastBuyer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"launchBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lossChance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"lossRanges","outputs":[{"internalType":"uint256","name":"percent","type":"uint256"},{"internalType":"uint256","name":"multiplier","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"luckyOrRektPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"manualSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maxBonusPercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minBalancePercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"openTrading","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":"pendingMinBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"randomnessProvider","outputs":[{"internalType":"contract RandomnessProvider","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"removeLimits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rescueETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"rescueTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"routerAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_burnPercentage","type":"uint256"}],"name":"setBurnPercentage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"isExcluded","type":"bool"}],"name":"setExcluded","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"rangeNumber","type":"uint256"},{"internalType":"uint256","name":"rangePercent","type":"uint256"},{"internalType":"uint256","name":"penaltyPercent","type":"uint256"}],"name":"setLossRange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lossChance","type":"uint256"},{"internalType":"uint256","name":"_winChance","type":"uint256"}],"name":"setLuckyOrRektChances","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxBonusPercentage","type":"uint256"}],"name":"setMaxBonusPercentage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minBalancePercentage","type":"uint256"}],"name":"setMinBalancePercentage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_randomnessProvider","type":"address"}],"name":"setRandomnessProvider","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_routerAddress","type":"address"}],"name":"setRouterAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_taxContractAddress","type":"address"}],"name":"setTaxContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_buyTaxRate","type":"uint256"},{"internalType":"uint256","name":"_sellTaxRate","type":"uint256"}],"name":"setTaxes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"rangeNumber","type":"uint256"},{"internalType":"uint256","name":"rangePercent","type":"uint256"},{"internalType":"uint256","name":"bonusPercent","type":"uint256"}],"name":"setWinRange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"taxContractAddress","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalBurned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"winChance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"winRanges","outputs":[{"internalType":"uint256","name":"percent","type":"uint256"},{"internalType":"uint256","name":"multiplier","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
608034620003bb576200354790601f38839003908101601f19168201906001600160401b03821183831017620003c05780839160409586948552833981010312620003bb5780620000546200006292620003f6565b9060209283809201620003f6565b600080546001600160a01b031980821633908117845592956001600160a01b03949193909285167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08880a3601e93846006558460075584600855603c600955737a250d5630b4cf539739df2c5dacb4c659f2488d600a946028865586601f5560328855856021558267016345785d8a000095866022556604cbd15e72600080602355602455655af3107a4000602555630100000063ffffffff19602a541617602a558a602d558a602e5516928382600454161760045560059416818554161784553389526001948589528b8a20556028541617602855600386528887209060ff19918483825416179055308852898820848382541617905587528289882091825416179055808562000193620003d6565b8581520152600b9280600b5581600c55620001ad620003d6565b600f87601492838152015280600d55600f600e55601987620001ce620003d6565b888152015285600f556019601055602387620001e9620003d6565b6019815201526019601155602360125560328762000206620003d6565b600f81520152600f60135560328155828762000221620003d6565b60288152015260159160286015558360165580886200023f620003d6565b898152015286601755601855808762000257620003d6565b828152015280601955601a5560328662000270620003d6565b6008815201526008601b556032601c556200028a620003d6565b926002845260648097819501526002601d558386558792889589935b82851062000380575050505050036200033d578203620002fd5750507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6022549284519384523393a3516131179081620004308239f35b915092519162461bcd60e51b8352600483015260248201527f57696e2072616e676573206d7573742061646420757020746f203130302500006044820152fd5b855162461bcd60e51b815260048101869052601f60248201527f4c6f73732072616e676573206d7573742061646420757020746f20313030250060448201528390fd5b91939683959650620003ac90620003a1898694961b9889870154906200040b565b97840154906200040b565b960192909188959492620002a6565b600080fd5b634e487b7160e01b600052604160045260246000fd5b60408051919082016001600160401b03811183821017620003c057604052565b51906001600160a01b0382168203620003bb57565b919082018092116200041957565b634e487b7160e01b600052601160045260246000fdfe60406080815260049081361015610020575b5050361561001e57600080fd5b005b600091823560e01c908162ae3bf814611f0257816306fdde0314611ebd578163095ea7b314611e935781630ca1c5c9146113015781630e5a923114611e7457816313ecfbfa14611e4b57816317cb51e614611e2257816318160ddd14611e0357816318b6157b14611de4578163191ec56b14611da357816320800a0014611d5d5781632090b83014611d2357816322557c0014611cfb57816323b872dd14611c30578163252d723a14611c115781632836be2414611bbb578163313ce56714611b9f5781633268cc5614611b76578163355ca75414611b525781633a21911814611b3357816341cb87fc14611a4657816347b73bab146118f55781634802c4c8146118b15781635bac3c2b1461173b5781635d897501146116e457816361251a891461166157816361e1bead146115f15781636dbeffbe146115d257816370a082311461159a578163715018a614611540578163751039fc146114ee5781637cc74f3c146114645781637d1db4a5146114455781638da5cb5b1461141d5781638f9a55c0146113fe5781639555211b146113c557816395d89b411461138857816398cc0613146113595781639f27822d14611320578163a2309ff814611301578163a8c205461461042a578163a9059cbb146112d0578163ab225d951461125c578163ab63fa41146111e1578163abbba41b146111c2578163b0bc85de146111a3578163b15fbc1414611160578163b55cd04b146104b0578163b70143c91461106e578163c14c0f8814611050578163c3f0d32714610fd4578163c4d9352414610fae578163c647b20e14610ef1578163c9567bf914610b50578163ce9bf5ac14610b27578163d00efb2f14610b08578163d4cce96914610ae9578163d603c36d146104cf578163d89135cd146104b0578163dd62ed3e14610462578163e87968611461042a578163f1f1fb2d146103dd578163f2fde38b14610311575063fe50718c03610011573461030d578160031936011261030d5760209060ff602a5460181c1690519015158152f35b5080fd5b9050346103d95760203660031901126103d95761032c61202a565b9061033561234e565b6001600160a01b03918216928315610387575050600054826001600160601b0360a01b821617600055167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a380f35b906020608492519162461bcd60e51b8352820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152fd5b8280fd5b83833461030d578160031936011261030d57602e5491602d5492818482039412818512811691851390151617610417576020838351908152f35b634e487b7160e01b815260118452602490fd5b50503461030d57602036600319011261030d5760209181906001600160a01b0361045261202a565b168152602c845220549051908152f35b50503461030d578060031936011261030d5760209161047f61202a565b82610488612040565b6001600160a01b03928316845260028652922091166000908152908352819020549051908152f35b50503461030d578160031936011261030d57602090602d549051908152f35b83833461030d57608036600319011261030d576104ea61202a565b60443593906001600160a01b036024358187168703610a125760648097303303610aaf5760095480151580610aa4575b15610a625761052d8391600a549061228c565b03610a285760055487516372e5b9ef60e01b81526001600160a01b0387811689830190815260208082018890529490911660408201529335606085015291959392869183918290036080019082908c9089165af1908115610a1e5788916109ec575b5060095498898210156109255788918181029080820483149015171561091257899a6105ba916121ea565b8181101561090a575b600b54906105d3600d548361228c565b6105df600f548261228c565b906105ec6011548361228c565b938310156108c05750505050610603600c5461233d565b80610624575b50505050602c935016845252812080546106205750f35b5580f35b898113156108ae5781610638825b866121c1565b0491831561071057602c985082610691575b505b88519384528684015287830152151560608201527f99a6274a1a1725e8a90fb49c35e71855a9bc4f06b0eb5813dc2dc8f93f3f8a88608084841692a287808080610609565b602254906106a1602154836121c1565b04808411610706575b50826106b59161228c565b602255858516808b52600188526106cf838b8d205461228c565b818c52600189528a8c20556106e683602e5461228c565b602e558a6000805160206130c2833981519152898c51868152a38b61064a565b92506106b56106aa565b82610720575b50602c975061064c565b86861698898c52600189528a8c2054602c8a528b8d20548082116000146108a65761074a9161227f565b8085116108a0575083915b82610762575b5050610716565b9091929350610773601f54846121c1565b048b8a8c8b610782858861227f565b9483855260018252610797888487205461227f565b848652600183528386205580610863575b5050915050816107c3575b505050602c9750908b808061075b565b89939a8d828b86541691828152600188526107e1868383205461228c565b9281526001885220556000805160206130c28339815191528a85541695869351858152a3823b1561085f5760248c92838d51958694859363a62cf65d60e01b85528401525af1801561085557908a9161083d575b88918a6107b3565b6108469061213b565b61085157888b610835565b8880fd5b89513d8c823e3d90fd5b8b80fd5b6000805160206130c28339815191529261087f8260225461227f565b60225561088e82602d5461228c565b602d5551908152a38b8a8c8b386107a8565b91610755565b50508b61074a565b816106386108bb8361233d565b610632565b8210156108da575050506108d5600e5461233d565b610603565b8110156108ee5750506108d560105461233d565b10156108ff576108d560125461233d565b6108d560145461233d565b5060636105c3565b634e487b7160e01b8a526011885260248afd5b986109329060019261227f565b98808a0299808b048214901517156109d957610952899a600a54906121ea565b818110156109d1575b6015549061096b6017548361228c565b6109776019548261228c565b90610984601b548361228c565b938310156109985750505050601654610603565b8210156109aa57505050601854610603565b8110156109bb575050601a54610603565b10156109c957601c54610603565b601e54610603565b50606361095b565b634e487b7160e01b895260118752602489fd5b90508481813d8311610a17575b610a038183612187565b81010312610a1257518961058f565b600080fd5b503d6109f9565b87513d8a823e3d90fd5b50855162461bcd60e51b8152602081870152601660248201527504368616e636573206d75737420657175616c203130360541b6044820152fd5b875162461bcd60e51b8152602081890152601c60248201527f496e76616c6964206368616e636520636f6e66696775726174696f6e0000000060448201528390fd5b50600a54151561051a565b50855162461bcd60e51b8152602081870152601660248201527513db9b1e481cd95b198b58d85b1b08185b1b1bddd95960521b6044820152fd5b50503461030d578160031936011261030d576020906021549051908152f35b50503461030d578160031936011261030d576020906029549051908152f35b50503461030d578160031936011261030d5760055490516001600160a01b039091168152602090f35b919050346103d957826003193601126103d957610b6b61234e565b6028549060ff8260a01c16610eaf57308452602092600184528185205415610e7b574715610e49576001600160a01b039283168015610e0e57610bcb6026546001600160601b0360a01b92808483161760265588602254921617306123a6565b602654835163c45a015560e01b815290851686828581845afa918215610de557849188918a94610def575b5086516315ab88c960e31b815292839182905afa908115610de5576044889288928b91610dc8575b508a83895196879586946364e329cb60e11b8652308c870152166024850152165af1908115610dbe579085918891610d91575b501690602754161760275582602654166060473088526001875260c485892054878a5416928751958694859363f305d71960e01b8552308a86015260248501528c60448501528c606485015260848401524260a48401525af18015610d875790859291610d54575b5060448460275416946026541691878551968794859363095ea7b360e01b855284015260001960248401525af1908115610d4b5750610d1d575b602a805461ff0019166101001790556028805460ff60a01b1916600160a01b179055436029558280f35b81610d3c92903d10610d44575b610d348183612187565b8101906121a9565b503880610cf3565b503d610d2a565b513d85823e3d90fd5b6060809293503d8311610d80575b610d6c8183612187565b81010312610d7c57839038610cb9565b8480fd5b503d610d62565b83513d88823e3d90fd5b610db19150873d8911610db7575b610da98183612187565b81019061231e565b38610c51565b503d610d9f565b84513d89823e3d90fd5b610ddf9150843d8611610db757610da98183612187565b38610c1e565b85513d8a823e3d90fd5b610e07919450823d8411610db757610da98183612187565b9238610bf6565b5083606492519162461bcd60e51b83528201526016602482015275149bdd5d195c881859191c995cdcc81b9bdd081cd95d60521b6044820152fd5b83606492519162461bcd60e51b8352820152600e60248201526d4e6f206574682062616c616e636560901b6044820152fd5b83606492519162461bcd60e51b8352820152601060248201526f4e6f20746f6b656e2062616c616e636560801b6044820152fd5b5162461bcd60e51b8152602081840152601760248201527f54726164696e6720697320616c7265616479206f70656e0000000000000000006044820152606490fd5b919050346103d957610f02366120f3565b929091610f0d61234e565b601e8311610f6b57601e8411610f2857505060065560075580f35b906020606492519162461bcd60e51b8352820152601a60248201527f53656c6c207461782063616e6e6f7420657863656564203330250000000000006044820152fd5b906020606492519162461bcd60e51b8352820152601960248201527f427579207461782063616e6e6f742065786365656420333025000000000000006044820152fd5b50503461030d578160031936011261030d5760209060ff602a5460181c16159051908152f35b9050346103d95760203660031901126103d957803591610ff261234e565b60648311611002575050601f5580f35b906020608492519162461bcd60e51b8352820152602260248201527f4275726e2070657263656e746167652063616e6e6f7420657863656564203130604482015261302560f01b6064820152fd5b50503461030d578160031936011261030d5760209081549051908152f35b919050346103d95760203660031901126103d957813561108c61234e565b3084526001602052818420548111611133578061110f575b508247806110b0575080f35b6110b981612ea0565b83546001600160a01b031693843b156103d95760249083855196879485936391c05b0b60e01b85528401525af190811561110657506110f757808280f35b6111009061213b565b38808280f35b513d84823e3d90fd5b61112660ff1991600183602a541617602a55612d23565b602a5416602a55386110a4565b815162461bcd60e51b8152602081850152600760248201526608585b5bdd5b9d60ca1b6044820152606490fd5b83346111a05760203660031901126111a05761117a61202a565b61118261234e565b60018060a01b03166001600160601b0360a01b600554161760055580f35b80fd5b50503461030d578160031936011261030d576020906007549051908152f35b50503461030d578160031936011261030d576020906009549051908152f35b919050346103d9576111f2366120f3565b9290916111fd61234e565b6064611209858561228c565b03611219575050600955600a5580f35b906020606492519162461bcd60e51b8352820152601a60248201527f4368616e636573206d7573742061646420757020746f203130300000000000006044820152fd5b8284346111a057806003193601126111a0576112766122db565b508151906112838261214f565b600b90825b600582106112a15784518061129d86826120b9565b0390f35b60026001918651906112b282612109565b85548252838601549160209283820152815201930191019091611288565b50503461030d578060031936011261030d576020906112fa6112f061202a565b60243590336124f4565b5160018152f35b50503461030d578160031936011261030d57602090602e549051908152f35b8391503461030d57602036600319011261030d57359060058210156111a0575060011b600c81600b015491015482519182526020820152f35b83346111a057806003193601126111a05761137261234e565b630100000063ff00000019602a541617602a5580f35b919050346103d957826003193601126103d95761129d92508051916113ac83612109565b825263594f4c4f60e01b60208301525191829182612056565b8391503461030d57602036600319011261030d57359060058210156111a0575060011b6016816015015491015482519182526020820152f35b50503461030d578160031936011261030d576020906024549051908152f35b50503461030d578160031936011261030d57905490516001600160a01b039091168152602090f35b50503461030d578160031936011261030d576020906023549051908152f35b9050346103d95760203660031901126103d95780359161148261234e565b6032831161149257505060215580f35b906020608492519162461bcd60e51b8352820152603060248201527f4d617820626f6e75732070657263656e746167652063616e6e6f74206578636560448201526f656420353025206f6620737570706c7960801b6064820152fd5b50503461030d578160031936011261030d5760207f947f344d56e1e8c70dc492fb94c4ddddd490c016aab685f5e7e47b2e85cb44cf9161152c61234e565b60001990816023558160245551908152a180f35b83346111a057806003193601126111a05761155961234e565b80546001600160a01b03198116825581906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b50503461030d57602036600319011261030d5760209181906001600160a01b036115c261202a565b1681526001845220549051908152f35b50503461030d578160031936011261030d57602090600a549051908152f35b8284346111a057806003193601126111a05761160b6122db565b508151906116188261214f565b601590825b600582106116325784518061129d86826120b9565b600260019186519061164382612109565b8554825283860154916020928382015281520193019101909161161d565b9050346103d95760203660031901126103d95780359161167f61234e565b6064831161168f57505060205580f35b906020608492519162461bcd60e51b8352820152602960248201527f4d696e2062616c616e63652070657263656e746167652063616e6e6f7420657860448201526863656564203130302560b81b6064820152fd5b905082346111a05760203660031901126111a0578135916005831061170881612299565b1561172857505060011b600c81600b015491015482519182526020820152f35b634e487b7160e01b825260329052602490fd5b919050346103d95761174c3661209f565b9061175561234e565b6001916001841015806118a6575b61176c9061223c565b606481116118635784519161178083612109565b82526020820152600019830192831161185057600590600584101561183d576117c090600b9392939460011b600b01906020600191805184550151910155565b859186935b81851061181f5750505060649150036117dc578280f35b906020606492519162461bcd60e51b8352820152601f60248201527f4c6f73732072616e676573206d7573742061646420757020746f2031303025006044820152fd5b9091611832819486831b8401549061228c565b9401939291906117c5565b634e487b7160e01b875260328652602487fd5b634e487b7160e01b865260118552602486fd5b845162461bcd60e51b8152602081880152601a60248201527f50656e616c74792063616e6e6f742065786365656420313030250000000000006044820152606490fd5b506005841115611763565b905082346111a05760203660031901126111a057813591600583106118d581612299565b1561172857505060011b6016816015015491015482519182526020820152f35b919050346103d9576119063661209f565b9061190f61234e565b600191600184101580611a3b575b6119269061223c565b6103e881116119f85784519161193b83612109565b82526020820152600019830192831161185057600590600584101561183d5761197b9060159392939460011b601501906020600191805184550151910155565b859186935b8185106119da575050506064915003611997578280f35b906020606492519162461bcd60e51b8352820152601e60248201527f57696e2072616e676573206d7573742061646420757020746f203130302500006044820152fd5b90916119ed819486831b8401549061228c565b940193929190611980565b845162461bcd60e51b8152602081880152601960248201527f426f6e75732063616e6e6f7420657863656564203130303025000000000000006044820152606490fd5b50600584111561191d565b9050346103d95760203660031901126103d957611a6161202a565b90611a6a61234e565b6028549160ff8360a01c16611adf576001600160a01b0316928315611a9c5750506001600160a01b0319161760285580f35b906020606492519162461bcd60e51b8352820152601d60248201527f526f7574657220616464726573732063616e6e6f74206265207a65726f0000006044820152fd5b835162461bcd60e51b8152602081840152602860248201527f43616e6e6f74206368616e676520726f757465722061667465722074726164696044820152676e67206f70656e7360c01b6064820152608490fd5b50503461030d578160031936011261030d57602090602b549051908152f35b50503461030d578160031936011261030d57602090611b6f61220a565b9051908152f35b50503461030d578160031936011261030d5760285490516001600160a01b039091168152602090f35b50503461030d578160031936011261030d576020905160088152f35b50503461030d578060031936011261030d57611bd561202a565b9060243591821515809303611c0d57611bec61234e565b60018060a01b03168352600360205282209060ff8019835416911617905580f35b8380fd5b50503461030d578160031936011261030d576020906006549051908152f35b8284346111a05760603660031901126111a057611c4b61202a565b9282611c55612040565b92611c646044358095886124f4565b6001600160a01b0386168152600260209081528282203383529052205483519091611c8e8261216b565b602882527f45524332303a207472616e7366657220616d6f756e74206578636565647320616020830152676c6c6f77616e636560c01b85830152828411611cdf576020856112fa868603338a6123a6565b611cf7855192839262461bcd60e51b84528301612056565b0390fd5b9050346103d957826003193601126103d9575490516001600160a01b03909116815260209150f35b50503461030d57602036600319011261030d5760209181906001600160a01b03611d4b61202a565b168152602c8452205415159051908152f35b50503461030d578160031936011261030d57611d7761234e565b8180808047818115611d9a575b3390f115611d90575080f35b51903d90823e3d90fd5b506108fc611d84565b83903461030d57602036600319011261030d57611dbe61202a565b611dc661234e565b81546001600160a01b0319166001600160a01b039190911617905580f35b50503461030d578160031936011261030d57602090601f549051908152f35b50503461030d578160031936011261030d576020906022549051908152f35b83346111a057806003193601126111a057611e3b61234e565b63ff00000019602a5416602a5580f35b50503461030d578160031936011261030d57602a549051602091821c6001600160a01b03168152f35b50503461030d578160031936011261030d576020906025549051908152f35b50503461030d578060031936011261030d576020906112fa611eb361202a565b60243590336123a6565b50503461030d578160031936011261030d57805161129d91611ede82612109565b600d82526c131d58dade481bdc8814995add609a1b60208301525191829182612056565b9050346103d95760209182600319360112611c0d57611f1f61202a565b611f2761234e565b6001600160a01b031691308314611fe95781516370a0823160e01b81523082820152908482602481875afa918215610d8757908592918792611fb3575b50604490878551968794859363a9059cbb60e01b8552339085015260248401525af1908115610d4b5750611f96578280f35b81611fac92903d10610d4457610d348183612187565b5038808280f35b8381949293503d8311611fe2575b611fcb8183612187565b81010312611fde57905184916044611f64565b8580fd5b503d611fc1565b83606492519162461bcd60e51b8352820152601960248201527f43616e206e6f7420726573637565206f776e20746f6b656e21000000000000006044820152fd5b600435906001600160a01b0382168203610a1257565b602435906001600160a01b0382168203610a1257565b6020808252825181830181905290939260005b82811061208b57505060409293506000838284010152601f8019910116010190565b818101860151848201604001528501612069565b6060906003190112610a1257600435906024359060443590565b610140810192916000915b600583106120d157505050565b60019060408351918251815260208093015183820152019201920191906120c4565b6040906003190112610a12576004359060243590565b6040810190811067ffffffffffffffff82111761212557604052565b634e487b7160e01b600052604160045260246000fd5b67ffffffffffffffff811161212557604052565b60a0810190811067ffffffffffffffff82111761212557604052565b6060810190811067ffffffffffffffff82111761212557604052565b90601f8019910116810190811067ffffffffffffffff82111761212557604052565b90816020910312610a1257518015158103610a125790565b818102929181159184041417156121d457565b634e487b7160e01b600052601160045260246000fd5b81156121f4570490565b634e487b7160e01b600052601260045260246000fd5b602e54801561223657602d54906064820291808304606414901517156121d457612233916121ea565b90565b50600090565b1561224357565b60405162461bcd60e51b815260206004820152601460248201527324b73b30b634b2103930b733b290373ab6b132b960611b6044820152606490fd5b919082039182116121d457565b919082018092116121d457565b156122a057565b60405162461bcd60e51b8152602060048201526013602482015272092dcecc2d8d2c840e4c2dcceca40d2dcc8caf606b1b6044820152606490fd5b604090604051916122eb8361214f565b600083815b60a081106122fe5750505050565b602090845161230c81612109565b848152848382015281840152016122f0565b90816020910312610a1257516001600160a01b0381168103610a125790565b600160ff1b81146121d45760000390565b6000546001600160a01b0316330361236257565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b6001600160a01b0390811691821561245757169182156124075760207f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925918360005260028252604060002085600052825280604060002055604051908152a3565b60405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608490fd5b60405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608490fd5b156124af57565b60405162461bcd60e51b815260206004820152601960248201527f4578636565647320746865205f6d61785478416d6f756e742e000000000000006044820152606490fd5b6001600160a01b039283821692916000918415612cd0578584169586159384612c7f578215612c285780958260275416808a1496879182612c1d575b8a149182612c0e575b82612c03575b82612bfa575b5081612beb575b81612be1575b81612bd8575b50612bd0575b50868152602c60209681885260409687842054151580612bbe575b80612bb6575b612b1a575b8080612b08575b612acc575b602a9689885491888884841c16948515159081612ac0575b81612ab5575b81612aa6575b81612a97575b81612a88575b81612a7e575b81612a66575b5080612a58575b6129f7575b50505050508295898452600389528a8a60ff8a8720541615806129e4575b612793575b928a61269d9896938a9896938c9b966000805160206130c28339815191529e9d97612763575b808752600184526126358a8989205461227f565b908752600184528787205580865261265a878720546126548c8c61227f565b9061228c565b9086526001835286862055868316968715159081612758575b81612749575b8161273a575b8161272b575b5080612722575b6126a5575b5050505050505061227f565b9051908152a3565b6126af898961227f565b90816126bc575b50612691565b60649385612705948a89525286888120805461271a575b50508154640100000000600160c01b031916908e1b640100000000600160c01b0316179055602b8190558b54906121c1565b049382528852205538848180808981806126b6565b5586386126d3565b50823b1561268c565b90506004541687141538612685565b6027548116891415915061267f565b60265481168914159150612679565b308914159150612673565b308752600184526127778b8989205461228c565b308852600185528888205587518b81528f8290863093a3612621565b5090969050818516156129a257508983526003885260ff878420541615612933575b60646127c3600654876121c1565b04955b8a8a8660275416821480612929575b156125fb575050308452600189528a8a8986205483549060ff8216158061291c575b80612911575b806128fa575b61280f575b50506125fb565b91509150602554908181116000146128f357505b808811156128e957612840905b60ff199283166001178455612d23565b81541681558a8a4780612854575b80612808565b8092506128619150612ea0565b856004541690813b15611fde578591602483928c5194859384926391c05b0b60e01b845260048401525af180156128df57928a61269d9896938e8e8d9c9a98956000805160206130c28339815191529f9e986128cc575b509396509396989a9b9c509396985061284e565b6128d89097919761213b565b95386128b8565b89513d87823e3d90fd5b5061284087612830565b9050612823565b5061290a6029546008549061228c565b4311612803565b5060255481116127fd565b5060ff8260081c166127f7565b50308114156127d5565b6129416023548611156124a8565b89835260018852612955858885205461228c565b60245410156127b557865162461bcd60e51b815260048101899052601a60248201527f4578636565647320746865206d617857616c6c657453697a652e0000000000006044820152606490fd5b9584602754168b14806129da575b156127c65795506129c56023548611156124a8565b60646129d3600754876121c1565b04956127c6565b50308a14156129b0565b505084528a8a60ff8a87205416156125f6565b602b8054640100000000600160c01b03199095168c55889055612a1b918486612fc7565b15612a28575b81886125d8565b7fc051183f44b74d752a72eae2c131fcdd0304d418814e6951448a72a3012753dd918a51908152a2388089612a21565b5060ff8460101c16156125d3565b905080612a75575b15386125cc565b508d8514612a6e565b863b1591506125c6565b6004548b1687141591506125c0565b6027548b1687141591506125ba565b6026548b1687141591506125b4565b3087141591506125ae565b602b54151591506125a8565b602a548a86828c1c1614612aec575b508984528289528388812055612590565b640100000000600160c01b031916602a55602b84905538612adb565b5089845282895287842054151561258b565b60018952612b2b868986205461227f565b8a8552838a5288852054111561258457875162461bcd60e51b8152600481018a9052604860248201527f43616e6e6f74207472616e736665722062656c6f77206d696e696d756d20626160448201527f6c616e6365207768696c652070656e64696e67206c75636b79206f722072656b6064820152671d081959999958dd60c21b608482015260a490fd5b50801561257f565b506003895260ff888520541615612579565b95503861255e565b90501538612558565b823b159150612552565b60045485168b1415915061254c565b15915038612545565b308c1415925061253f565b60265486168c14159250612539565b308b14159850612530565b60405162461bcd60e51b815260206004820152602960248201527f5472616e7366657220616d6f756e74206d7573742062652067726561746572206044820152687468616e207a65726f60b81b6064820152608490fd5b60405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608490fd5b60405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608490fd5b8015612e9d5760ff60285460a01c1615612e9d576040805191612d458361216b565b6002835260208084019083368337845115612e5d5730825260265484516315ab88c960e31b81526001600160a01b03949092909185168184600481845afa938415612e9257600094612e73575b5087519360019460011015612e5d57612db39187859216898b0152306123a6565b846026541694853b15610a1257918697949391975197889563791ac94760e01b875260a487019260048801526000602488015260a060448801525180925260c4860194936000905b838210612e43575050505050509181600081819530606483015242608483015203925af1908115612e395750612e2e5750565b612e379061213b565b565b513d6000823e3d90fd5b8551811687528a9750958201959482019490840190612dfb565b634e487b7160e01b600052603260045260246000fd5b612e8b919450823d8411610db757610da98183612187565b9238612d92565b87513d6000823e3d90fd5b50565b6004546001600160a01b0316478211612f825760008080809481945af1903d15612f7c573d9067ffffffffffffffff8211612f685760405191612eed601f8201601f191660200184612187565b825260203d92013e5b15612efd57565b60405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608490fd5b634e487b7160e01b81526041600452602490fd5b50612ef6565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606490fd5b9091602a9283549260009560ff8560101c1661307d5760ff8560181c166130715762ff00001994851662010000178655303b1561306d5760405163d603c36d60e01b81526001600160a01b0392831660048201526024810193909352921660448201526064810191909152838160848183305af1908161305a575b5061304f57815416905590565b815416905550600190565b6130669094919461213b565b9238613042565b8680fd5b50505050505050600190565b606460405162461bcd60e51b815260206004820152602060248201527f416c72656164792070726f63657373696e67206c75636b79206f722072656b746044820152fdfeddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa26469706673582212207ff9f4bbf2c94e27a177aa6e28a96d6f3ed6ab4fc433147a3d70cf79aa29641264736f6c6343000818003300000000000000000000000044ef9b0db29ed5e7fbcf5e0d21e897917065e07a000000000000000000000000a688965eef354372e9b73719a9f7fec4e5984e7a
Deployed Bytecode
0x60406080815260049081361015610020575b5050361561001e57600080fd5b005b600091823560e01c908162ae3bf814611f0257816306fdde0314611ebd578163095ea7b314611e935781630ca1c5c9146113015781630e5a923114611e7457816313ecfbfa14611e4b57816317cb51e614611e2257816318160ddd14611e0357816318b6157b14611de4578163191ec56b14611da357816320800a0014611d5d5781632090b83014611d2357816322557c0014611cfb57816323b872dd14611c30578163252d723a14611c115781632836be2414611bbb578163313ce56714611b9f5781633268cc5614611b76578163355ca75414611b525781633a21911814611b3357816341cb87fc14611a4657816347b73bab146118f55781634802c4c8146118b15781635bac3c2b1461173b5781635d897501146116e457816361251a891461166157816361e1bead146115f15781636dbeffbe146115d257816370a082311461159a578163715018a614611540578163751039fc146114ee5781637cc74f3c146114645781637d1db4a5146114455781638da5cb5b1461141d5781638f9a55c0146113fe5781639555211b146113c557816395d89b411461138857816398cc0613146113595781639f27822d14611320578163a2309ff814611301578163a8c205461461042a578163a9059cbb146112d0578163ab225d951461125c578163ab63fa41146111e1578163abbba41b146111c2578163b0bc85de146111a3578163b15fbc1414611160578163b55cd04b146104b0578163b70143c91461106e578163c14c0f8814611050578163c3f0d32714610fd4578163c4d9352414610fae578163c647b20e14610ef1578163c9567bf914610b50578163ce9bf5ac14610b27578163d00efb2f14610b08578163d4cce96914610ae9578163d603c36d146104cf578163d89135cd146104b0578163dd62ed3e14610462578163e87968611461042a578163f1f1fb2d146103dd578163f2fde38b14610311575063fe50718c03610011573461030d578160031936011261030d5760209060ff602a5460181c1690519015158152f35b5080fd5b9050346103d95760203660031901126103d95761032c61202a565b9061033561234e565b6001600160a01b03918216928315610387575050600054826001600160601b0360a01b821617600055167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a380f35b906020608492519162461bcd60e51b8352820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152fd5b8280fd5b83833461030d578160031936011261030d57602e5491602d5492818482039412818512811691851390151617610417576020838351908152f35b634e487b7160e01b815260118452602490fd5b50503461030d57602036600319011261030d5760209181906001600160a01b0361045261202a565b168152602c845220549051908152f35b50503461030d578060031936011261030d5760209161047f61202a565b82610488612040565b6001600160a01b03928316845260028652922091166000908152908352819020549051908152f35b50503461030d578160031936011261030d57602090602d549051908152f35b83833461030d57608036600319011261030d576104ea61202a565b60443593906001600160a01b036024358187168703610a125760648097303303610aaf5760095480151580610aa4575b15610a625761052d8391600a549061228c565b03610a285760055487516372e5b9ef60e01b81526001600160a01b0387811689830190815260208082018890529490911660408201529335606085015291959392869183918290036080019082908c9089165af1908115610a1e5788916109ec575b5060095498898210156109255788918181029080820483149015171561091257899a6105ba916121ea565b8181101561090a575b600b54906105d3600d548361228c565b6105df600f548261228c565b906105ec6011548361228c565b938310156108c05750505050610603600c5461233d565b80610624575b50505050602c935016845252812080546106205750f35b5580f35b898113156108ae5781610638825b866121c1565b0491831561071057602c985082610691575b505b88519384528684015287830152151560608201527f99a6274a1a1725e8a90fb49c35e71855a9bc4f06b0eb5813dc2dc8f93f3f8a88608084841692a287808080610609565b602254906106a1602154836121c1565b04808411610706575b50826106b59161228c565b602255858516808b52600188526106cf838b8d205461228c565b818c52600189528a8c20556106e683602e5461228c565b602e558a6000805160206130c2833981519152898c51868152a38b61064a565b92506106b56106aa565b82610720575b50602c975061064c565b86861698898c52600189528a8c2054602c8a528b8d20548082116000146108a65761074a9161227f565b8085116108a0575083915b82610762575b5050610716565b9091929350610773601f54846121c1565b048b8a8c8b610782858861227f565b9483855260018252610797888487205461227f565b848652600183528386205580610863575b5050915050816107c3575b505050602c9750908b808061075b565b89939a8d828b86541691828152600188526107e1868383205461228c565b9281526001885220556000805160206130c28339815191528a85541695869351858152a3823b1561085f5760248c92838d51958694859363a62cf65d60e01b85528401525af1801561085557908a9161083d575b88918a6107b3565b6108469061213b565b61085157888b610835565b8880fd5b89513d8c823e3d90fd5b8b80fd5b6000805160206130c28339815191529261087f8260225461227f565b60225561088e82602d5461228c565b602d5551908152a38b8a8c8b386107a8565b91610755565b50508b61074a565b816106386108bb8361233d565b610632565b8210156108da575050506108d5600e5461233d565b610603565b8110156108ee5750506108d560105461233d565b10156108ff576108d560125461233d565b6108d560145461233d565b5060636105c3565b634e487b7160e01b8a526011885260248afd5b986109329060019261227f565b98808a0299808b048214901517156109d957610952899a600a54906121ea565b818110156109d1575b6015549061096b6017548361228c565b6109776019548261228c565b90610984601b548361228c565b938310156109985750505050601654610603565b8210156109aa57505050601854610603565b8110156109bb575050601a54610603565b10156109c957601c54610603565b601e54610603565b50606361095b565b634e487b7160e01b895260118752602489fd5b90508481813d8311610a17575b610a038183612187565b81010312610a1257518961058f565b600080fd5b503d6109f9565b87513d8a823e3d90fd5b50855162461bcd60e51b8152602081870152601660248201527504368616e636573206d75737420657175616c203130360541b6044820152fd5b875162461bcd60e51b8152602081890152601c60248201527f496e76616c6964206368616e636520636f6e66696775726174696f6e0000000060448201528390fd5b50600a54151561051a565b50855162461bcd60e51b8152602081870152601660248201527513db9b1e481cd95b198b58d85b1b08185b1b1bddd95960521b6044820152fd5b50503461030d578160031936011261030d576020906021549051908152f35b50503461030d578160031936011261030d576020906029549051908152f35b50503461030d578160031936011261030d5760055490516001600160a01b039091168152602090f35b919050346103d957826003193601126103d957610b6b61234e565b6028549060ff8260a01c16610eaf57308452602092600184528185205415610e7b574715610e49576001600160a01b039283168015610e0e57610bcb6026546001600160601b0360a01b92808483161760265588602254921617306123a6565b602654835163c45a015560e01b815290851686828581845afa918215610de557849188918a94610def575b5086516315ab88c960e31b815292839182905afa908115610de5576044889288928b91610dc8575b508a83895196879586946364e329cb60e11b8652308c870152166024850152165af1908115610dbe579085918891610d91575b501690602754161760275582602654166060473088526001875260c485892054878a5416928751958694859363f305d71960e01b8552308a86015260248501528c60448501528c606485015260848401524260a48401525af18015610d875790859291610d54575b5060448460275416946026541691878551968794859363095ea7b360e01b855284015260001960248401525af1908115610d4b5750610d1d575b602a805461ff0019166101001790556028805460ff60a01b1916600160a01b179055436029558280f35b81610d3c92903d10610d44575b610d348183612187565b8101906121a9565b503880610cf3565b503d610d2a565b513d85823e3d90fd5b6060809293503d8311610d80575b610d6c8183612187565b81010312610d7c57839038610cb9565b8480fd5b503d610d62565b83513d88823e3d90fd5b610db19150873d8911610db7575b610da98183612187565b81019061231e565b38610c51565b503d610d9f565b84513d89823e3d90fd5b610ddf9150843d8611610db757610da98183612187565b38610c1e565b85513d8a823e3d90fd5b610e07919450823d8411610db757610da98183612187565b9238610bf6565b5083606492519162461bcd60e51b83528201526016602482015275149bdd5d195c881859191c995cdcc81b9bdd081cd95d60521b6044820152fd5b83606492519162461bcd60e51b8352820152600e60248201526d4e6f206574682062616c616e636560901b6044820152fd5b83606492519162461bcd60e51b8352820152601060248201526f4e6f20746f6b656e2062616c616e636560801b6044820152fd5b5162461bcd60e51b8152602081840152601760248201527f54726164696e6720697320616c7265616479206f70656e0000000000000000006044820152606490fd5b919050346103d957610f02366120f3565b929091610f0d61234e565b601e8311610f6b57601e8411610f2857505060065560075580f35b906020606492519162461bcd60e51b8352820152601a60248201527f53656c6c207461782063616e6e6f7420657863656564203330250000000000006044820152fd5b906020606492519162461bcd60e51b8352820152601960248201527f427579207461782063616e6e6f742065786365656420333025000000000000006044820152fd5b50503461030d578160031936011261030d5760209060ff602a5460181c16159051908152f35b9050346103d95760203660031901126103d957803591610ff261234e565b60648311611002575050601f5580f35b906020608492519162461bcd60e51b8352820152602260248201527f4275726e2070657263656e746167652063616e6e6f7420657863656564203130604482015261302560f01b6064820152fd5b50503461030d578160031936011261030d5760209081549051908152f35b919050346103d95760203660031901126103d957813561108c61234e565b3084526001602052818420548111611133578061110f575b508247806110b0575080f35b6110b981612ea0565b83546001600160a01b031693843b156103d95760249083855196879485936391c05b0b60e01b85528401525af190811561110657506110f757808280f35b6111009061213b565b38808280f35b513d84823e3d90fd5b61112660ff1991600183602a541617602a55612d23565b602a5416602a55386110a4565b815162461bcd60e51b8152602081850152600760248201526608585b5bdd5b9d60ca1b6044820152606490fd5b83346111a05760203660031901126111a05761117a61202a565b61118261234e565b60018060a01b03166001600160601b0360a01b600554161760055580f35b80fd5b50503461030d578160031936011261030d576020906007549051908152f35b50503461030d578160031936011261030d576020906009549051908152f35b919050346103d9576111f2366120f3565b9290916111fd61234e565b6064611209858561228c565b03611219575050600955600a5580f35b906020606492519162461bcd60e51b8352820152601a60248201527f4368616e636573206d7573742061646420757020746f203130300000000000006044820152fd5b8284346111a057806003193601126111a0576112766122db565b508151906112838261214f565b600b90825b600582106112a15784518061129d86826120b9565b0390f35b60026001918651906112b282612109565b85548252838601549160209283820152815201930191019091611288565b50503461030d578060031936011261030d576020906112fa6112f061202a565b60243590336124f4565b5160018152f35b50503461030d578160031936011261030d57602090602e549051908152f35b8391503461030d57602036600319011261030d57359060058210156111a0575060011b600c81600b015491015482519182526020820152f35b83346111a057806003193601126111a05761137261234e565b630100000063ff00000019602a541617602a5580f35b919050346103d957826003193601126103d95761129d92508051916113ac83612109565b825263594f4c4f60e01b60208301525191829182612056565b8391503461030d57602036600319011261030d57359060058210156111a0575060011b6016816015015491015482519182526020820152f35b50503461030d578160031936011261030d576020906024549051908152f35b50503461030d578160031936011261030d57905490516001600160a01b039091168152602090f35b50503461030d578160031936011261030d576020906023549051908152f35b9050346103d95760203660031901126103d95780359161148261234e565b6032831161149257505060215580f35b906020608492519162461bcd60e51b8352820152603060248201527f4d617820626f6e75732070657263656e746167652063616e6e6f74206578636560448201526f656420353025206f6620737570706c7960801b6064820152fd5b50503461030d578160031936011261030d5760207f947f344d56e1e8c70dc492fb94c4ddddd490c016aab685f5e7e47b2e85cb44cf9161152c61234e565b60001990816023558160245551908152a180f35b83346111a057806003193601126111a05761155961234e565b80546001600160a01b03198116825581906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b50503461030d57602036600319011261030d5760209181906001600160a01b036115c261202a565b1681526001845220549051908152f35b50503461030d578160031936011261030d57602090600a549051908152f35b8284346111a057806003193601126111a05761160b6122db565b508151906116188261214f565b601590825b600582106116325784518061129d86826120b9565b600260019186519061164382612109565b8554825283860154916020928382015281520193019101909161161d565b9050346103d95760203660031901126103d95780359161167f61234e565b6064831161168f57505060205580f35b906020608492519162461bcd60e51b8352820152602960248201527f4d696e2062616c616e63652070657263656e746167652063616e6e6f7420657860448201526863656564203130302560b81b6064820152fd5b905082346111a05760203660031901126111a0578135916005831061170881612299565b1561172857505060011b600c81600b015491015482519182526020820152f35b634e487b7160e01b825260329052602490fd5b919050346103d95761174c3661209f565b9061175561234e565b6001916001841015806118a6575b61176c9061223c565b606481116118635784519161178083612109565b82526020820152600019830192831161185057600590600584101561183d576117c090600b9392939460011b600b01906020600191805184550151910155565b859186935b81851061181f5750505060649150036117dc578280f35b906020606492519162461bcd60e51b8352820152601f60248201527f4c6f73732072616e676573206d7573742061646420757020746f2031303025006044820152fd5b9091611832819486831b8401549061228c565b9401939291906117c5565b634e487b7160e01b875260328652602487fd5b634e487b7160e01b865260118552602486fd5b845162461bcd60e51b8152602081880152601a60248201527f50656e616c74792063616e6e6f742065786365656420313030250000000000006044820152606490fd5b506005841115611763565b905082346111a05760203660031901126111a057813591600583106118d581612299565b1561172857505060011b6016816015015491015482519182526020820152f35b919050346103d9576119063661209f565b9061190f61234e565b600191600184101580611a3b575b6119269061223c565b6103e881116119f85784519161193b83612109565b82526020820152600019830192831161185057600590600584101561183d5761197b9060159392939460011b601501906020600191805184550151910155565b859186935b8185106119da575050506064915003611997578280f35b906020606492519162461bcd60e51b8352820152601e60248201527f57696e2072616e676573206d7573742061646420757020746f203130302500006044820152fd5b90916119ed819486831b8401549061228c565b940193929190611980565b845162461bcd60e51b8152602081880152601960248201527f426f6e75732063616e6e6f7420657863656564203130303025000000000000006044820152606490fd5b50600584111561191d565b9050346103d95760203660031901126103d957611a6161202a565b90611a6a61234e565b6028549160ff8360a01c16611adf576001600160a01b0316928315611a9c5750506001600160a01b0319161760285580f35b906020606492519162461bcd60e51b8352820152601d60248201527f526f7574657220616464726573732063616e6e6f74206265207a65726f0000006044820152fd5b835162461bcd60e51b8152602081840152602860248201527f43616e6e6f74206368616e676520726f757465722061667465722074726164696044820152676e67206f70656e7360c01b6064820152608490fd5b50503461030d578160031936011261030d57602090602b549051908152f35b50503461030d578160031936011261030d57602090611b6f61220a565b9051908152f35b50503461030d578160031936011261030d5760285490516001600160a01b039091168152602090f35b50503461030d578160031936011261030d576020905160088152f35b50503461030d578060031936011261030d57611bd561202a565b9060243591821515809303611c0d57611bec61234e565b60018060a01b03168352600360205282209060ff8019835416911617905580f35b8380fd5b50503461030d578160031936011261030d576020906006549051908152f35b8284346111a05760603660031901126111a057611c4b61202a565b9282611c55612040565b92611c646044358095886124f4565b6001600160a01b0386168152600260209081528282203383529052205483519091611c8e8261216b565b602882527f45524332303a207472616e7366657220616d6f756e74206578636565647320616020830152676c6c6f77616e636560c01b85830152828411611cdf576020856112fa868603338a6123a6565b611cf7855192839262461bcd60e51b84528301612056565b0390fd5b9050346103d957826003193601126103d9575490516001600160a01b03909116815260209150f35b50503461030d57602036600319011261030d5760209181906001600160a01b03611d4b61202a565b168152602c8452205415159051908152f35b50503461030d578160031936011261030d57611d7761234e565b8180808047818115611d9a575b3390f115611d90575080f35b51903d90823e3d90fd5b506108fc611d84565b83903461030d57602036600319011261030d57611dbe61202a565b611dc661234e565b81546001600160a01b0319166001600160a01b039190911617905580f35b50503461030d578160031936011261030d57602090601f549051908152f35b50503461030d578160031936011261030d576020906022549051908152f35b83346111a057806003193601126111a057611e3b61234e565b63ff00000019602a5416602a5580f35b50503461030d578160031936011261030d57602a549051602091821c6001600160a01b03168152f35b50503461030d578160031936011261030d576020906025549051908152f35b50503461030d578060031936011261030d576020906112fa611eb361202a565b60243590336123a6565b50503461030d578160031936011261030d57805161129d91611ede82612109565b600d82526c131d58dade481bdc8814995add609a1b60208301525191829182612056565b9050346103d95760209182600319360112611c0d57611f1f61202a565b611f2761234e565b6001600160a01b031691308314611fe95781516370a0823160e01b81523082820152908482602481875afa918215610d8757908592918792611fb3575b50604490878551968794859363a9059cbb60e01b8552339085015260248401525af1908115610d4b5750611f96578280f35b81611fac92903d10610d4457610d348183612187565b5038808280f35b8381949293503d8311611fe2575b611fcb8183612187565b81010312611fde57905184916044611f64565b8580fd5b503d611fc1565b83606492519162461bcd60e51b8352820152601960248201527f43616e206e6f7420726573637565206f776e20746f6b656e21000000000000006044820152fd5b600435906001600160a01b0382168203610a1257565b602435906001600160a01b0382168203610a1257565b6020808252825181830181905290939260005b82811061208b57505060409293506000838284010152601f8019910116010190565b818101860151848201604001528501612069565b6060906003190112610a1257600435906024359060443590565b610140810192916000915b600583106120d157505050565b60019060408351918251815260208093015183820152019201920191906120c4565b6040906003190112610a12576004359060243590565b6040810190811067ffffffffffffffff82111761212557604052565b634e487b7160e01b600052604160045260246000fd5b67ffffffffffffffff811161212557604052565b60a0810190811067ffffffffffffffff82111761212557604052565b6060810190811067ffffffffffffffff82111761212557604052565b90601f8019910116810190811067ffffffffffffffff82111761212557604052565b90816020910312610a1257518015158103610a125790565b818102929181159184041417156121d457565b634e487b7160e01b600052601160045260246000fd5b81156121f4570490565b634e487b7160e01b600052601260045260246000fd5b602e54801561223657602d54906064820291808304606414901517156121d457612233916121ea565b90565b50600090565b1561224357565b60405162461bcd60e51b815260206004820152601460248201527324b73b30b634b2103930b733b290373ab6b132b960611b6044820152606490fd5b919082039182116121d457565b919082018092116121d457565b156122a057565b60405162461bcd60e51b8152602060048201526013602482015272092dcecc2d8d2c840e4c2dcceca40d2dcc8caf606b1b6044820152606490fd5b604090604051916122eb8361214f565b600083815b60a081106122fe5750505050565b602090845161230c81612109565b848152848382015281840152016122f0565b90816020910312610a1257516001600160a01b0381168103610a125790565b600160ff1b81146121d45760000390565b6000546001600160a01b0316330361236257565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b6001600160a01b0390811691821561245757169182156124075760207f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925918360005260028252604060002085600052825280604060002055604051908152a3565b60405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608490fd5b60405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608490fd5b156124af57565b60405162461bcd60e51b815260206004820152601960248201527f4578636565647320746865205f6d61785478416d6f756e742e000000000000006044820152606490fd5b6001600160a01b039283821692916000918415612cd0578584169586159384612c7f578215612c285780958260275416808a1496879182612c1d575b8a149182612c0e575b82612c03575b82612bfa575b5081612beb575b81612be1575b81612bd8575b50612bd0575b50868152602c60209681885260409687842054151580612bbe575b80612bb6575b612b1a575b8080612b08575b612acc575b602a9689885491888884841c16948515159081612ac0575b81612ab5575b81612aa6575b81612a97575b81612a88575b81612a7e575b81612a66575b5080612a58575b6129f7575b50505050508295898452600389528a8a60ff8a8720541615806129e4575b612793575b928a61269d9896938a9896938c9b966000805160206130c28339815191529e9d97612763575b808752600184526126358a8989205461227f565b908752600184528787205580865261265a878720546126548c8c61227f565b9061228c565b9086526001835286862055868316968715159081612758575b81612749575b8161273a575b8161272b575b5080612722575b6126a5575b5050505050505061227f565b9051908152a3565b6126af898961227f565b90816126bc575b50612691565b60649385612705948a89525286888120805461271a575b50508154640100000000600160c01b031916908e1b640100000000600160c01b0316179055602b8190558b54906121c1565b049382528852205538848180808981806126b6565b5586386126d3565b50823b1561268c565b90506004541687141538612685565b6027548116891415915061267f565b60265481168914159150612679565b308914159150612673565b308752600184526127778b8989205461228c565b308852600185528888205587518b81528f8290863093a3612621565b5090969050818516156129a257508983526003885260ff878420541615612933575b60646127c3600654876121c1565b04955b8a8a8660275416821480612929575b156125fb575050308452600189528a8a8986205483549060ff8216158061291c575b80612911575b806128fa575b61280f575b50506125fb565b91509150602554908181116000146128f357505b808811156128e957612840905b60ff199283166001178455612d23565b81541681558a8a4780612854575b80612808565b8092506128619150612ea0565b856004541690813b15611fde578591602483928c5194859384926391c05b0b60e01b845260048401525af180156128df57928a61269d9896938e8e8d9c9a98956000805160206130c28339815191529f9e986128cc575b509396509396989a9b9c509396985061284e565b6128d89097919761213b565b95386128b8565b89513d87823e3d90fd5b5061284087612830565b9050612823565b5061290a6029546008549061228c565b4311612803565b5060255481116127fd565b5060ff8260081c166127f7565b50308114156127d5565b6129416023548611156124a8565b89835260018852612955858885205461228c565b60245410156127b557865162461bcd60e51b815260048101899052601a60248201527f4578636565647320746865206d617857616c6c657453697a652e0000000000006044820152606490fd5b9584602754168b14806129da575b156127c65795506129c56023548611156124a8565b60646129d3600754876121c1565b04956127c6565b50308a14156129b0565b505084528a8a60ff8a87205416156125f6565b602b8054640100000000600160c01b03199095168c55889055612a1b918486612fc7565b15612a28575b81886125d8565b7fc051183f44b74d752a72eae2c131fcdd0304d418814e6951448a72a3012753dd918a51908152a2388089612a21565b5060ff8460101c16156125d3565b905080612a75575b15386125cc565b508d8514612a6e565b863b1591506125c6565b6004548b1687141591506125c0565b6027548b1687141591506125ba565b6026548b1687141591506125b4565b3087141591506125ae565b602b54151591506125a8565b602a548a86828c1c1614612aec575b508984528289528388812055612590565b640100000000600160c01b031916602a55602b84905538612adb565b5089845282895287842054151561258b565b60018952612b2b868986205461227f565b8a8552838a5288852054111561258457875162461bcd60e51b8152600481018a9052604860248201527f43616e6e6f74207472616e736665722062656c6f77206d696e696d756d20626160448201527f6c616e6365207768696c652070656e64696e67206c75636b79206f722072656b6064820152671d081959999958dd60c21b608482015260a490fd5b50801561257f565b506003895260ff888520541615612579565b95503861255e565b90501538612558565b823b159150612552565b60045485168b1415915061254c565b15915038612545565b308c1415925061253f565b60265486168c14159250612539565b308b14159850612530565b60405162461bcd60e51b815260206004820152602960248201527f5472616e7366657220616d6f756e74206d7573742062652067726561746572206044820152687468616e207a65726f60b81b6064820152608490fd5b60405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608490fd5b60405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608490fd5b8015612e9d5760ff60285460a01c1615612e9d576040805191612d458361216b565b6002835260208084019083368337845115612e5d5730825260265484516315ab88c960e31b81526001600160a01b03949092909185168184600481845afa938415612e9257600094612e73575b5087519360019460011015612e5d57612db39187859216898b0152306123a6565b846026541694853b15610a1257918697949391975197889563791ac94760e01b875260a487019260048801526000602488015260a060448801525180925260c4860194936000905b838210612e43575050505050509181600081819530606483015242608483015203925af1908115612e395750612e2e5750565b612e379061213b565b565b513d6000823e3d90fd5b8551811687528a9750958201959482019490840190612dfb565b634e487b7160e01b600052603260045260246000fd5b612e8b919450823d8411610db757610da98183612187565b9238612d92565b87513d6000823e3d90fd5b50565b6004546001600160a01b0316478211612f825760008080809481945af1903d15612f7c573d9067ffffffffffffffff8211612f685760405191612eed601f8201601f191660200184612187565b825260203d92013e5b15612efd57565b60405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608490fd5b634e487b7160e01b81526041600452602490fd5b50612ef6565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606490fd5b9091602a9283549260009560ff8560101c1661307d5760ff8560181c166130715762ff00001994851662010000178655303b1561306d5760405163d603c36d60e01b81526001600160a01b0392831660048201526024810193909352921660448201526064810191909152838160848183305af1908161305a575b5061304f57815416905590565b815416905550600190565b6130669094919461213b565b9238613042565b8680fd5b50505050505050600190565b606460405162461bcd60e51b815260206004820152602060248201527f416c72656164792070726f63657373696e67206c75636b79206f722072656b746044820152fdfeddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa26469706673582212207ff9f4bbf2c94e27a177aa6e28a96d6f3ed6ab4fc433147a3d70cf79aa29641264736f6c63430008180033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000044ef9b0db29ed5e7fbcf5e0d21e897917065e07a000000000000000000000000a688965eef354372e9b73719a9f7fec4e5984e7a
-----Decoded View---------------
Arg [0] : _taxContractAddress (address): 0x44ef9b0db29Ed5E7fbcf5E0d21e897917065E07A
Arg [1] : _randomnessProvider (address): 0xA688965EeF354372e9b73719A9F7fEc4E5984E7a
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 00000000000000000000000044ef9b0db29ed5e7fbcf5e0d21e897917065e07a
Arg [1] : 000000000000000000000000a688965eef354372e9b73719a9f7fec4e5984e7a
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 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.