Source Code
Latest 25 from a total of 817 transactions
| Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Claim | 23370995 | 161 days ago | IN | 0 ETH | 0.00012373 | ||||
| Claim | 23319025 | 168 days ago | IN | 0 ETH | 0.00024091 | ||||
| Stake | 23231101 | 180 days ago | IN | 0 ETH | 0.0000849 | ||||
| Claim | 23183661 | 187 days ago | IN | 0 ETH | 0.0001092 | ||||
| Stake | 23045572 | 206 days ago | IN | 0 ETH | 0.00017871 | ||||
| Claim | 23004644 | 212 days ago | IN | 0 ETH | 0.00021227 | ||||
| Stake | 22995137 | 213 days ago | IN | 0 ETH | 0.00023045 | ||||
| Claim | 22935969 | 221 days ago | IN | 0 ETH | 0.00032463 | ||||
| Stake | 22933742 | 222 days ago | IN | 0 ETH | 0.00170482 | ||||
| Claim | 22788262 | 242 days ago | IN | 0 ETH | 0.00031516 | ||||
| Claim | 22779300 | 243 days ago | IN | 0 ETH | 0.00063105 | ||||
| Claim | 22733932 | 250 days ago | IN | 0 ETH | 0.00015942 | ||||
| Claim | 22722837 | 251 days ago | IN | 0 ETH | 0.00007919 | ||||
| Claim | 22718196 | 252 days ago | IN | 0 ETH | 0.00060724 | ||||
| Claim | 22713164 | 253 days ago | IN | 0 ETH | 0.00007896 | ||||
| Claim | 22708263 | 253 days ago | IN | 0 ETH | 0.00007494 | ||||
| Claim | 22678463 | 257 days ago | IN | 0 ETH | 0.00019297 | ||||
| Claim | 22672174 | 258 days ago | IN | 0 ETH | 0.00015175 | ||||
| Claim | 22670460 | 258 days ago | IN | 0 ETH | 0.00015741 | ||||
| Claim | 22669946 | 259 days ago | IN | 0 ETH | 0.00025517 | ||||
| Claim | 22668207 | 259 days ago | IN | 0 ETH | 0.00052293 | ||||
| Claim | 22666401 | 259 days ago | IN | 0 ETH | 0.00058566 | ||||
| Claim | 22666345 | 259 days ago | IN | 0 ETH | 0.0006725 | ||||
| Claim | 22666112 | 259 days ago | IN | 0 ETH | 0.00026716 | ||||
| Claim | 22658027 | 260 days ago | IN | 0 ETH | 0.00005133 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
To
|
|||
|---|---|---|---|---|---|---|---|
| Transfer | 22486117 | 284 days ago | 0.00107387 ETH | ||||
| Transfer | 22486117 | 284 days ago | 0.03492612 ETH | ||||
| Transfer | 22486092 | 284 days ago | 0.03706941 ETH | ||||
| Transfer | 22486092 | 284 days ago | 1.19892027 ETH | ||||
| Transfer | 22482007 | 285 days ago | 0.00088876 ETH | ||||
| Transfer | 22482007 | 285 days ago | 0.02911123 ETH | ||||
| Transfer | 22480770 | 285 days ago | 0.00156643 ETH | ||||
| Transfer | 22480770 | 285 days ago | 0.06536718 ETH | ||||
| Transfer | 22474518 | 286 days ago | 0.00140832 ETH | ||||
| Transfer | 22474518 | 286 days ago | 0.04649066 ETH | ||||
| Transfer | 22466183 | 287 days ago | 0.00002751 ETH | ||||
| Transfer | 22466183 | 287 days ago | 0.00120424 ETH | ||||
| Transfer | 22462524 | 288 days ago | 0.00082946 ETH | ||||
| Transfer | 22462524 | 288 days ago | 0.02731002 ETH | ||||
| Transfer | 22452452 | 289 days ago | 0.00008009 ETH | ||||
| Transfer | 22452452 | 289 days ago | 0.00233677 ETH | ||||
| Transfer | 22451278 | 289 days ago | 0.00058013 ETH | ||||
| Transfer | 22451278 | 289 days ago | 0.01941986 ETH | ||||
| Transfer | 22451102 | 289 days ago | 0.00719111 ETH | ||||
| Transfer | 22451102 | 289 days ago | 0.23280888 ETH | ||||
| Transfer | 22449735 | 289 days ago | 0.00008077 ETH | ||||
| Transfer | 22449735 | 289 days ago | 0.0035231 ETH | ||||
| Transfer | 22443521 | 290 days ago | 0.00024094 ETH | ||||
| Transfer | 22443521 | 290 days ago | 0.00712524 ETH | ||||
| Transfer | 22421080 | 293 days ago | 0.00088797 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
Presale
Compiler Version
v0.8.26+commit.8a97fa7a
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.26;
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {Pausable} from "@openzeppelin/contracts/utils/Pausable.sol";
import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
interface Aggregator {
function decimals() external view returns (uint8);
function latestRoundData() external view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);
}
interface StakingManager {
function deposit(address user, uint256 amount) external;
function depositByPresale(address user, uint256 amount) external;
}
contract Presale is ReentrancyGuard, Ownable, Pausable {
using SafeERC20 for IERC20;
// Digest
string private constant DIGEST = "2025-01-30"; // Compile version
// Main
bool public isMainNetwork; // Set true if its the main network where the coin will be deployed
address public saleToken;
address public admin;
StakingManager public stakingManager;
Aggregator public priceFeed;
IERC20 public usdt;
IERC20 public usdc;
bool public usdtFound;
bool public usdcFound;
uint256 public usdtDecimals;
uint256 public usdcDecimals;
uint256 public tokenDecimals;
uint256 private tokenPrecision;
// Constants
uint256 private constant DAY_SECONDS = 86400;
// Controls
uint256 public daysPerRound;
bool public updateRoundTimeAutomaticallyFlag;
uint256 public minBuyInDolar;
uint256 public maxTokensToBuy;
uint256 public claimStartTime;
uint256 public presaleStartTime;
uint256 public presaleEndTime;
uint256 public currentRound;
uint256[][3] public rounds;
uint256 public checkpoint;
address[] public addressPayment;
uint256[] public addressPercentage;
uint256[] public remainingTokensTracker;
bool public claimAvailableForWhitelistOnlyFlag;
bool public stakeAvailableForWhitelistOnlyFlag;
// History
uint256 public totalTokensSold;
uint256 public totalTokensSoldAndStaked;
uint256 public usdRaised;
uint256[] public checkpointHistory;
bool public isImportDone;
// Maps
mapping(address => uint256) public userDeposits;
mapping(address => bool) public hasClaimed;
mapping(address => bool) public isBlacklisted;
mapping(address => bool) public isWhitelisted;
mapping(address => bool) public isWertWhitelisted;
mapping(address => bool) public imported;
address[] private addressUserDeposits;
// Enums
enum CoinSymbol {
NETWORK,
USDC, // USD Coin
USDT // USD Tether
}
// Events
event PresaleTimeSet(uint256 _start, uint256 _end, uint256 _timestamp);
event PresaleTimeUpdated(bytes32 indexed _key, uint256 _oldTime, uint256 _newTime, uint256 _timestamp);
event TokensBought(address indexed _address, uint256 indexed _tokensBought, address indexed _paymentTokenAddress, uint256 _amountPaid, uint256 _amountPaidUSD, uint256 _timestamp, string _id);
event TokensBoughtAndStaked(
address indexed _address,
uint256 indexed _tokensBought,
address indexed _paymentTokenAddress,
uint256 _amountPaid,
uint256 _amountPaidUSD,
uint256 _timestamp,
string _id
);
event TokensAdded(address indexed _tokenAddress, uint256 _tokenAmount, uint256 _timestamp);
event TokensClaimed(address indexed _address, uint256 _amount, uint256 _timestamp); //After presale, only main network
event TokensStaked(address indexed _address, uint256 _amount, uint256 _timestamp); //During presale, all networks
event ClaimStartTimeUpdated(uint256 _startTimeOld, uint256 _startTimeNew, uint256 _timestamp);
event MinBuyInDolarUpdated(uint256 _minBuyInDolarOld, uint256 _minBuyInDolarNew, uint256 _timestamp);
event MaxTokensToBuyUpdated(uint256 _maxTokensToBuyOld, uint256 _maxTokensToBuyNew, uint256 _timestamp);
event RoundUpdated(uint256 _amount, uint256 _timestamp);
event AdminUpdated(address indexed _admin);
event UsdtUpdated(bool _usdtFound, address _usdt, uint256 _usdtDecimals);
event UsdcUpdated(bool _usdcFound, address _usdc, uint256 _usdcDecimals);
event CurrentRoundUpdated(uint256 _round, uint256 _checkpointAmount);
event DaysPerRoundUpdated(uint256 _daysPerRound);
event TokenDecimalsUpdated(uint256 _tokenDecimals);
event BlacklistImported(address[] addresses);
event UserDepositsImported(address[] addresses, uint256[] deposits);
// Modifiers
modifier onlyOwnerOrAdmin() {
require(msg.sender == admin || msg.sender == owner(), "Only owner or admin");
_;
}
// Constructor
struct ConstructorStruct {
bool cIsMainNetwork; // True if this is the network where the presale token will be deployed
address cAdmin; // Address of admin
address cPriceFeed; // The aggregator contract address
address cUsdt; // USDT contract address
address cUsdc; // USDC contract address
bool cUsdtFound; // If this network have USDT
bool cUsdcFound; // If this network have USDC
uint256 cUsdtDecimals; // USDT decimals
uint256 cUsdcDecimals; // USDC decimals
uint256 cDaysPerRound; // Number of days rounds will last (Default: 7 days)
bool cUpdateRoundTimeAutomaticallyFlag; // If flag is true the round end time will be updated, if its false the next round will add the remaining time (Default: true)
uint256 cMinBuyInDolar; // Minimum amount in dolars that users will be able to purchase
uint256 cMaxTokensToBuy; // Maximum amount of tokens that users will be able to purchase (Default: 1.000.000.000 Less than a full round)
uint256 cPresaleStartTime; // Timestamp to set presale start date
uint256 cPresaleEndTime; // Timestamp to set presale end date
uint256 cTokenDecimals; // Number of decimals of the Token
uint256[][3] cRounds; // Array of round details ([0] -> ROUND_TOTAL, [1] -> ROUND_PRICE, [2] -> ROUND_FINAL_TIMESTAMP)
address[] cAddressPayment; // Array of addresses that will receive payments
uint256[] cAddressPercentage; // Array of percentage of each payment address
}
/**
* @dev Initializes the contract and sets initial parameters
*
* @param _constructor The constructor tuple
*/
constructor(ConstructorStruct memory _constructor) Ownable(msg.sender) {
require(_constructor.cAdmin != address(0), "Admin contract is required");
require(_constructor.cPriceFeed != address(0), "Price feed contract is required");
if (_constructor.cUsdtFound) require(_constructor.cUsdt != address(0), "USDT contract is required");
if (_constructor.cUsdcFound) require(_constructor.cUsdc != address(0), "USDC contract is required");
require(_constructor.cDaysPerRound > 0, "Days per round must be greater than zero");
require(_constructor.cMaxTokensToBuy > 0, "Max tokens to buy must be greater than zero");
require(_constructor.cPresaleStartTime < _constructor.cPresaleEndTime, "Presale end time must be greater than start time");
require(_constructor.cPresaleEndTime > block.timestamp, "Presale end time must be in the future");
require(_constructor.cRounds[0].length > 0, "At least one round is required");
require(_constructor.cAddressPayment.length > 0, "At least one payment address is required");
require(_constructor.cAddressPayment.length == _constructor.cAddressPercentage.length, "Payment addresses and addresses percentages arrays must have same size");
isMainNetwork = _constructor.cIsMainNetwork;
admin = _constructor.cAdmin;
daysPerRound = _constructor.cDaysPerRound;
updateRoundTimeAutomaticallyFlag = _constructor.cUpdateRoundTimeAutomaticallyFlag;
minBuyInDolar = _constructor.cMinBuyInDolar;
maxTokensToBuy = _constructor.cMaxTokensToBuy;
presaleStartTime = _constructor.cPresaleStartTime;
presaleEndTime = _constructor.cPresaleEndTime;
currentRound = 0;
rounds = _constructor.cRounds;
tokenDecimals = _constructor.cTokenDecimals;
tokenPrecision = 10 ** tokenDecimals;
//Fill token information
require(_constructor.cUsdtFound || _constructor.cUsdcFound, "No USDT/USDC found on this network");
usdtFound = _constructor.cUsdtFound;
usdcFound = _constructor.cUsdcFound;
if (usdtFound) {
usdt = IERC20(_constructor.cUsdt);
usdtDecimals = _constructor.cUsdtDecimals;
}
if (usdcFound) {
usdc = IERC20(_constructor.cUsdc);
usdcDecimals = _constructor.cUsdcDecimals;
}
//Get network aggregator
require(_constructor.cPriceFeed != address(0), "Aggregator contract is required");
priceFeed = Aggregator(_constructor.cPriceFeed);
addressPayment = _constructor.cAddressPayment;
addressPercentage = _constructor.cAddressPercentage;
emit PresaleTimeSet(presaleStartTime, presaleEndTime, block.timestamp);
}
/**
* @dev Pause the presale
*/
function pause() external onlyOwner {
_pause();
}
/**
* @dev Unpause the presale
*/
function unpause() external onlyOwner {
_unpause();
}
/**
* @dev Calculate price in USD for given amount of tokens
*
* @param pAmount Amount in tokens the user wants to receive
*
* @return Amount in dolars the user will pay for this amount of tokens
*/
function calculatePrice(uint256 pAmount) public view returns (uint256) {
require(pAmount <= maxTokensToBuy, "Amount exceeds max tokens to buy");
//Check if amount is enough to advance to next round
if (pAmount + checkpoint > rounds[0][currentRound] || block.timestamp >= rounds[2][currentRound]) {
//Must be in a round before the last
require(currentRound < (rounds[0].length - 1), "Last round, it is not possible to buy this quantity");
//Must purchase fewer tokens than the available amount of a full round
require(rounds[0][currentRound] + pAmount <= rounds[0][currentRound + 1], "Can not buy this amount in a single tx");
if (block.timestamp > rounds[2][currentRound]) {
return rounds[1][currentRound + 1] * pAmount;
} else {
uint256 _amountCurrentPrice = rounds[0][currentRound] - checkpoint;
return rounds[1][currentRound] * _amountCurrentPrice + rounds[1][currentRound + 1] * (pAmount - _amountCurrentPrice);
}
} else {
return rounds[1][currentRound] * pAmount;
}
}
/**
* @dev Calculate amount of tokens for given amount in USD
*
* @param pAmountUsd amount in USD (Need to add the decimals equivalent to the TOKEN_DECIMALS)
*
* @return array with [0] -> amountToken amount of tokens, [1] -> amountInMain amount in main network symbol
*/
function calculateAmountTokens(uint256 pAmountUsd) external view returns (uint256[2] memory) {
//Amount should be bigger than one unit of token
require(pAmountUsd > rounds[1][currentRound == rounds[0].length - 1 ? currentRound : currentRound + 1], "Invalid amount");
//Calculate tokens available in current round
uint256 _amountAvailableCurrentRound = rounds[0][currentRound] - checkpoint;
//Calculate amount of tokens for given usd amount
uint256 _amountToken = pAmountUsd / rounds[1][currentRound];
//If round will increase by time
if (block.timestamp >= rounds[2][currentRound]) {
//Must be in a round before the last
require(currentRound < (rounds[0].length - 1), "The presale timestamp have ended");
_amountToken = pAmountUsd / rounds[1][currentRound + 1];
}
//If amount of tokens exceeds amount available, calculate with next round
else if (_amountToken > _amountAvailableCurrentRound) {
//Must be in a round before the last
require(currentRound < (rounds[0].length - 1), "Last round, it is not possible to buy this quantity");
uint256 _rest = pAmountUsd - _amountAvailableCurrentRound * rounds[1][currentRound];
_amountToken = _amountAvailableCurrentRound + (_rest / rounds[1][currentRound + 1]);
require(rounds[0][currentRound] + _amountToken <= rounds[0][currentRound + 1], "Can not buy this amount in a single tx");
}
require(_amountToken <= maxTokensToBuy, "Amount exceeds max tokens to buy");
return [_amountToken, mainBuyHelper(_amountToken)];
}
/**
* @dev Get latest Main Network Symbol price to x decimals places
*/
function getLatestPrice() public view returns (uint256) {
uint256 aggregatorDecimals = priceFeed.decimals();
require(aggregatorDecimals <= tokenDecimals, "Invalid aggregator decimals");
(, int256 price, , , ) = priceFeed.latestRoundData();
require(price > 0, "Error getting price");
//Normalize price to x decimals
return uint256(price) * 10 ** (tokenDecimals - aggregatorDecimals);
}
/**
* @dev Buy with Main Network Symbol
*
* @param pAmount amount of tokens to buy
* @param pStake flag to stake purchased tokens
* @param pId identficator
*/
function buyWithMain(uint256 pAmount, bool pStake, string calldata pId) external payable nonReentrant whenNotPaused returns (bool) {
require(block.timestamp >= presaleStartTime && block.timestamp <= presaleEndTime, "Out of presale period");
require(pAmount > 0, "Amount must be greater than zero");
require(pAmount <= maxTokensToBuy, "Amount exceeds max tokens to buy");
buyWithNetwork(msg.sender, pAmount, pStake, pId);
return true;
}
/**
* @dev Buy with Main Network Symbol from Wert
* Wert address must be whitelisted
*
* @param pUser address who made the purchase
* @param pAmount amount of tokens to buy
* @param pStake flag to stake purchased tokens
* @param pCoinSymbol the coin symbol
*/
function buyWithWert(address pUser, uint256 pAmount, bool pStake, CoinSymbol pCoinSymbol, string calldata pId) external payable nonReentrant whenNotPaused returns (bool) {
require(block.timestamp >= presaleStartTime && block.timestamp <= presaleEndTime, "Out of presale period");
require(pAmount > 0, "Amount must be greater than zero");
require(pAmount <= maxTokensToBuy, "Amount exceeds max tokens to buy");
require(isWertWhitelisted[msg.sender], "Address not whitelisted for this transaction");
require(pCoinSymbol == CoinSymbol.NETWORK || pCoinSymbol == CoinSymbol.USDT || pCoinSymbol == CoinSymbol.USDC, "Symbol not found");
if (pCoinSymbol == CoinSymbol.NETWORK) {
buyWithNetwork(pUser, pAmount, pStake, pId);
} else {
buyWithToken(pUser, pAmount, pStake, pCoinSymbol, pId);
}
return true;
}
/**
* @dev Buy with Main Network Symbol
*
* @param pUser address who made the purchase
* @param pAmount amount of tokens to buy
* @param pStake flag to stake purchased tokens
*/
function buyWithNetwork(address pUser, uint256 pAmount, bool pStake, string calldata pId) internal {
uint256 _usdPrice = calculatePrice(pAmount);
uint256 _mainAmount = (_usdPrice * tokenPrecision) / getLatestPrice();
require(msg.value >= _mainAmount, "Insufficient payment");
require(_usdPrice >= minBuyInDolar, "Payment lower than minimum");
uint256 _excess = msg.value - _mainAmount;
totalTokensSold += pAmount;
checkpoint += pAmount;
usdRaised += _usdPrice;
if (checkpoint > rounds[0][currentRound] || block.timestamp >= rounds[2][currentRound]) {
incrementCurrentRound(pAmount, block.timestamp);
}
if (pStake) {
require(address(stakingManager) != address(0), "Staking manager not configured");
if (stakeAvailableForWhitelistOnlyFlag) {
require(isWhitelisted[pUser], "User not whitelisted for stake");
}
totalTokensSoldAndStaked += pAmount;
stakingManager.depositByPresale(pUser, pAmount * tokenPrecision);
emit TokensBoughtAndStaked(pUser, pAmount, address(0), _mainAmount, _usdPrice, block.timestamp, pId);
} else {
if (userDeposits[pUser] == 0) addressUserDeposits.push(pUser);
userDeposits[pUser] += (pAmount * tokenPrecision);
emit TokensBought(pUser, pAmount, address(0), _mainAmount, _usdPrice, block.timestamp, pId);
}
splitCoin(_mainAmount, CoinSymbol.NETWORK);
if (_excess > 0) sendCoin(pUser, _excess, CoinSymbol.NETWORK);
}
/**
* @dev Buy with USDT
*
* @param pAmount amount of tokens to buy
* @param pStake flag to stake purchased tokens
*/
function buyWithUSDT(uint256 pAmount, bool pStake, string calldata pId) external nonReentrant whenNotPaused returns (bool) {
require(usdtFound, "USDT contract found on this network");
require(block.timestamp >= presaleStartTime && block.timestamp <= presaleEndTime, "Out of presale period");
require(pAmount > 0, "Amount must be greater than zero");
require(pAmount <= maxTokensToBuy, "Amount exceeds max tokens to buy");
buyWithToken(msg.sender, pAmount, pStake, CoinSymbol.USDT, pId);
return true;
}
/**
* @dev Buy with USDC
*
* @param pAmount amount of tokens to buy
* @param pStake flag to stake purchased tokens
*/
function buyWithUSDC(uint256 pAmount, bool pStake, string calldata pId) external nonReentrant whenNotPaused returns (bool) {
require(usdcFound, "USDC contract found on this network");
require(block.timestamp >= presaleStartTime && block.timestamp <= presaleEndTime, "Out of presale period");
require(pAmount > 0, "Amount must be greater than zero");
require(pAmount <= maxTokensToBuy, "Amount exceeds max tokens to buy");
buyWithToken(msg.sender, pAmount, pStake, CoinSymbol.USDC, pId);
return true;
}
/**
* @dev Buy with USDT/USDC
*
* @param pUser address who made the purchase
* @param pAmount amount received
* @param pStake flag to stake purchased tokens
* @param pCoinSymbol the coin symbol
*/
function buyWithToken(address pUser, uint256 pAmount, bool pStake, CoinSymbol pCoinSymbol, string calldata pId) internal {
IERC20 _token = pCoinSymbol == CoinSymbol.USDT ? usdt : usdc;
uint256 _usdPrice = calculatePrice(pAmount);
require(_usdPrice >= minBuyInDolar, "Payment lower than minimum");
totalTokensSold += pAmount;
checkpoint += pAmount;
usdRaised += _usdPrice;
if (checkpoint > rounds[0][currentRound] || block.timestamp >= rounds[2][currentRound]) {
incrementCurrentRound(pAmount, block.timestamp);
}
if (pStake) {
require(address(stakingManager) != address(0), "Staking manager not configured");
if (stakeAvailableForWhitelistOnlyFlag) {
require(isWhitelisted[pUser], "User not whitelisted for stake");
}
totalTokensSoldAndStaked += pAmount;
stakingManager.depositByPresale(pUser, pAmount * tokenPrecision);
emit TokensBoughtAndStaked(pUser, pAmount, address(_token), _usdPrice, _usdPrice, block.timestamp, pId);
} else {
if (userDeposits[pUser] == 0) addressUserDeposits.push(pUser);
userDeposits[pUser] += (pAmount * tokenPrecision);
emit TokensBought(pUser, pAmount, address(_token), _usdPrice, _usdPrice, block.timestamp, pId);
}
uint256 _usdPriceNormalized = _usdPrice / (10 ** (tokenDecimals - usdtDecimals));
uint256 _ourAllowance = _token.allowance(pUser, address(this));
require(_usdPriceNormalized <= _ourAllowance, "Not enough allowance");
splitCoin(_usdPriceNormalized, pCoinSymbol);
}
/**
* @dev Transfer to given recipient
*
* @param pRecipient payable address of transaction recipient
* @param pAmount amount received
* @param pCoinSymbol the coin symbol
*/
function sendCoin(address pRecipient, uint256 pAmount, CoinSymbol pCoinSymbol) internal {
if (pCoinSymbol == CoinSymbol.NETWORK) {
require(address(this).balance >= pAmount, "Main network symbol balance not enough");
Address.sendValue(payable(pRecipient), pAmount);
} else if (pCoinSymbol == CoinSymbol.USDT) {
require(usdt.balanceOf(msg.sender) >= pAmount, "USDT balance not enough");
usdt.safeTransferFrom(msg.sender, pRecipient, pAmount);
} else if (pCoinSymbol == CoinSymbol.USDC) {
require(usdc.balanceOf(msg.sender) >= pAmount, "USDC balance not enough");
usdc.safeTransferFrom(msg.sender, pRecipient, pAmount);
}
}
/**
* @dev Divides the amount received in between the configured wallets
*
* @param pAmount amount received
* @param pCoinSymbol the coin symbol
*/
function splitCoin(uint256 pAmount, CoinSymbol pCoinSymbol) internal {
require(addressPayment.length > 0, "Payment address not configured");
require(addressPayment.length == addressPercentage.length, "Wrong configuration payment addresses and percentages");
uint256 _totalTransferred;
uint256 size = addressPayment.length;
for (uint256 i = 0; i < size; i++) {
uint256 _amountToTransfer = (pAmount * addressPercentage[i]) / 100;
sendCoin(addressPayment[i], _amountToTransfer, pCoinSymbol);
_totalTransferred += _amountToTransfer;
}
if (_totalTransferred < pAmount) {
sendCoin(addressPayment[addressPayment.length - 1], pAmount - _totalTransferred, pCoinSymbol);
}
}
/**
* @dev Helper function to get Main Network Symbol price for given amount
*
* @param pAmount Amount in tokens the user wants to receive
*
* @return Amount in dolars the user will pay for this amount of tokens
*/
function mainBuyHelper(uint256 pAmount) public view returns (uint256) {
return (calculatePrice(pAmount) * tokenPrecision) / getLatestPrice();
}
/**
* @dev Helper function to get USD price for given amount
*
* @param pAmount Amount in tokens the user wants to receive
*
* @return Amount in dolars the user will pay for this amount of tokens
*/
function usdBuyHelper(uint256 pAmount) external view returns (uint256) {
return calculatePrice(pAmount);
}
/**
* @dev Stake tokens purchased during presale
*/
function stake() external nonReentrant whenNotPaused returns (bool) {
require(address(stakingManager) != address(0), "Staking manager not configured");
require(!isBlacklisted[msg.sender], "This address is blacklisted");
if (stakeAvailableForWhitelistOnlyFlag) {
require(isWhitelisted[msg.sender], "User not whitelisted for stake");
}
uint256 _amount = userDeposits[msg.sender];
require(_amount > 0, "Nothing to stake");
delete userDeposits[msg.sender];
//If claim the presale is still live call the deposit by presale
if (block.timestamp < claimStartTime) {
stakingManager.depositByPresale(msg.sender, _amount);
} else {
//If the presale is over make a stake
stakingManager.deposit(msg.sender, _amount);
}
emit TokensStaked(msg.sender, _amount, block.timestamp);
return true;
}
/**
* @dev Claim tokens after presale ends and claiming starts
*/
function claim() external nonReentrant whenNotPaused returns (bool) {
require(isMainNetwork, "This is not the main network");
require(saleToken != address(0), "Sale token is not configured");
require(!isBlacklisted[msg.sender], "This address is blacklisted");
require(block.timestamp >= claimStartTime, "Claim has not started yet");
require(!hasClaimed[msg.sender], "Already claimed");
if (claimAvailableForWhitelistOnlyFlag) {
require(isWhitelisted[msg.sender], "User not whitelisted for claim");
}
hasClaimed[msg.sender] = true;
uint256 _amount = userDeposits[msg.sender];
require(_amount > 0, "Nothing to claim");
delete userDeposits[msg.sender];
IERC20(saleToken).safeTransfer(msg.sender, _amount);
emit TokensClaimed(msg.sender, _amount, block.timestamp);
return true;
}
/**
* @dev Increment current round
*
* @param pAmount Amount of tokens purchased when round was incremented
*/
function incrementCurrentRound(uint256 pAmount, uint256 pTimestamp) internal {
require(currentRound < rounds[0].length - 1, "Last round reached, it is not possible to increment");
require(checkpoint > rounds[0][currentRound] || pTimestamp >= rounds[2][currentRound] || pAmount == 0, "Round limits not reached");
require(pTimestamp < presaleEndTime, "Cannot increment round after presale end time");
if (updateRoundTimeAutomaticallyFlag) {
//Update the end time of each round after the current one
uint256 size = rounds[2].length;
for (uint256 i; i < size - currentRound; i++) {
rounds[2][currentRound + i] = pTimestamp + (i * daysPerRound * DAY_SECONDS);
}
//Update the presaleEndTime according the last round end timestamp
presaleEndTime = rounds[2][size - 1];
}
//If round is being incremented but there are remaining tokens
if (checkpoint < rounds[0][currentRound]) {
remainingTokensTracker.push(rounds[0][currentRound] - checkpoint + pAmount);
checkpointHistory.push(checkpoint - pAmount);
checkpoint = rounds[0][currentRound] + pAmount;
} else {
remainingTokensTracker.push(0);
checkpointHistory.push(rounds[0][currentRound]);
}
currentRound++;
emit RoundUpdated(pAmount, pTimestamp);
}
/**
* @dev Increment current round from backend
*/
function incrementCurrentRound(uint256 pTimestamp) external onlyOwnerOrAdmin {
incrementCurrentRound(0, pTimestamp);
}
/**
* @dev Set payment addresses and percentages of each one
*
* @param pAddresses array of payment addresses
* @param pPercentages array of percentage of each payment address
*/
function setAddressPayment(address[] memory pAddresses, uint256[] memory pPercentages) external onlyOwner {
require(pAddresses.length > 0, "Must configure at least one address");
require(pAddresses.length == pPercentages.length, "Arrays sizes are mismatched");
delete addressPayment;
delete addressPercentage;
uint256 _totalPercentage;
uint256 size = pAddresses.length;
for (uint256 i = 0; i < size; i++) {
require(pPercentages[i] > 0, "Percentages must be greater than zero");
_totalPercentage += pPercentages[i];
addressPayment.push(pAddresses[i]);
addressPercentage.push(pPercentages[i]);
}
require(_totalPercentage == 100, "Total percentage must be equal 100");
}
/**
* @dev Set minimum amount in dolars users will be able to purchase
*
* @param pMinBuyInDolar minimum amount in dolars to buy
*/
function setMinBuyInDolar(uint256 pMinBuyInDolar) external onlyOwner {
uint256 _minBuyInDolarOld = minBuyInDolar;
minBuyInDolar = pMinBuyInDolar;
emit MinBuyInDolarUpdated(_minBuyInDolarOld, minBuyInDolar, block.timestamp);
}
/**
* @dev Set maximum amount of tokens users will be able to purchase
*
* @param pMaxTokensToBuy maximum amount of tokens to buy
*/
function setMaxTokensToBuy(uint256 pMaxTokensToBuy) external onlyOwner {
require(pMaxTokensToBuy > 0, "Max tokens to buy must be greater than zero");
uint256 _maxTokensToBuyOld = maxTokensToBuy;
maxTokensToBuy = pMaxTokensToBuy;
emit MaxTokensToBuyUpdated(_maxTokensToBuyOld, maxTokensToBuy, block.timestamp);
}
/**
* @dev Set new price feed contract
*
* @param pPriceFeed price feed contract address
*/
function setPriceFeed(address pPriceFeed) external onlyOwner {
require(pPriceFeed != address(0), "Invalid address");
priceFeed = Aggregator(pPriceFeed);
}
/**
* @dev Set is main network on/off
*
* @param pIsMainNetwork boolean is main network
*/
function setIsMainNetwork(bool pIsMainNetwork) external onlyOwner {
isMainNetwork = pIsMainNetwork;
}
/**
* @dev Set token decimals
*
* @param pTokenDecimals number of token decimals
*/
function setTokenDecimals(uint256 pTokenDecimals) external onlyOwner {
tokenDecimals = pTokenDecimals;
tokenPrecision = 10 ** tokenDecimals;
emit TokenDecimalsUpdated(pTokenDecimals);
}
/**
* @dev Set usdt info
*
* @param pUsdtFound usdt exists or not
* @param pUsdt usdt contract address
* @param pUsdtDecimals usdt exists or not
*/
function setUsdt(bool pUsdtFound, address pUsdt, uint256 pUsdtDecimals) external onlyOwner {
require((pUsdtFound && pUsdt != address(0)) || !pUsdtFound, "Invalid address");
usdt = IERC20(pUsdt);
usdtFound = pUsdtFound;
usdtDecimals = pUsdtDecimals;
emit UsdtUpdated(pUsdtFound, pUsdt, pUsdtDecimals);
}
/**
* @dev Set usdc info
*
* @param pUsdcFound usdc exists or not
* @param pUsdc usdc contract address
* @param pUsdcDecimals usdc exists or not
*/
function setUsdc(bool pUsdcFound, address pUsdc, uint256 pUsdcDecimals) external onlyOwner {
require((pUsdcFound && pUsdc != address(0)) || !pUsdcFound, "Invalid address");
usdc = IERC20(pUsdc);
usdcFound = pUsdcFound;
usdcDecimals = pUsdcDecimals;
emit UsdcUpdated(pUsdcFound, pUsdc, pUsdcDecimals);
}
/**
* @dev Set admin
* @param pAdmin new admin address
*/
function setAdmin(address pAdmin) external onlyOwner {
require(pAdmin != address(0), "Invalid address");
admin = pAdmin;
emit AdminUpdated(pAdmin);
}
/**
* @dev Configure Staking Manager with the contract address
*
* @param pStakingManager address of staking manager contract
*/
function setStakingManager(address pStakingManager) external onlyOwner {
stakingManager = StakingManager(pStakingManager);
if (isMainNetwork && pStakingManager != address(0)) {
require(saleToken != address(0), "Sale token not configured yet");
IERC20(saleToken).safeIncreaseAllowance(pStakingManager, type(uint256).max);
}
}
/**
* @dev Update presale start and end timestamp
*
* @param pPresaleStartTime Presale start time
* @param pPresaleEndTime Presale end time
*/
function setPresaleTimes(uint256 pPresaleStartTime, uint256 pPresaleEndTime) external onlyOwner {
require(pPresaleStartTime > 0 || pPresaleEndTime > 0, "Invalid parameters");
if (pPresaleStartTime > 0) {
require(block.timestamp < presaleStartTime, "Presale already started");
require(block.timestamp < pPresaleStartTime, "Presale start must be in future");
uint256 _presaleStartTimeOld = presaleStartTime;
presaleStartTime = pPresaleStartTime;
emit PresaleTimeUpdated(bytes32("START"), _presaleStartTimeOld, pPresaleStartTime, block.timestamp);
}
if (pPresaleEndTime > 0) {
require(block.timestamp <= presaleEndTime, "Presale already finished");
require(pPresaleEndTime > presaleStartTime, "Presale end must be after presale start");
uint256 _presaleEndTimeOld = presaleEndTime;
presaleEndTime = pPresaleEndTime;
emit PresaleTimeUpdated(bytes32("END"), _presaleEndTimeOld, pPresaleEndTime, block.timestamp);
}
}
/**
* @dev Get specifc details of all rounds
*
* @param pIndex index detail ([0] -> ROUND_TOTAL, [1] -> ROUND_PRICE, [2] -> ROUND_FINAL_TIMESTAMP)
*/
function getRoundDetails(uint256 pIndex) external view returns (uint256[] memory) {
return rounds[pIndex];
}
/**
* @dev Get current round details
// Array of round details
[0] -> ROUND_TOTAL,
[1] -> ROUND_PRICE,
[2] -> ROUND_FINAL_TIMESTAMP,
[3] -> TOTAL_TOKENS_SOLD,
[4] -> CURRENT_ROUND,
[5] -> LAST_ROUND
[6] -> LAST_ROUND_TOTAL,
[7] -> LAST_ROUND_FINAL_TIMESTAMP,
[8] -> PRESALE_END_TIME,
[9] -> USER_DEPOSIT_LENGTH,
[10] -> IS_IMPORT_DONE
*/
function getCurrentRoundDetails() external view returns (uint256[11] memory) {
uint256 _lastRoundFinalTimestamp = currentRound == 0 ? 0 : rounds[2][currentRound - 1];
uint256 _lastRoundTotalTokens = currentRound == 0 ? 0 : rounds[0][currentRound - 1];
return [
rounds[0][currentRound],
rounds[1][currentRound],
rounds[2][currentRound],
checkpoint - _lastRoundTotalTokens,
currentRound,
rounds[0].length,
_lastRoundTotalTokens,
_lastRoundFinalTimestamp,
presaleEndTime,
addressUserDeposits.length,
isImportDone ? 1 : 0
];
}
/**
* @dev Get usd raised target for current round
*/
function getUsdRaisedTarget() external view returns (uint256) {
if (currentRound == 0) return rounds[0][currentRound] * rounds[1][currentRound];
uint256 _usdRaisedTarget;
for (uint256 i; i < currentRound; i++) {
_usdRaisedTarget += (rounds[0][i] - remainingTokensTracker[i]) * rounds[1][i];
}
return _usdRaisedTarget + rounds[0][currentRound] * rounds[1][currentRound];
}
/**
* @dev Change rounds details
* Can only be called by the current owner.
*
* @param pRounds array of round details ([0] -> ROUND_TOTAL, [1] -> ROUND_PRICE, [2] -> ROUND_FINAL_TIMESTAMP)
*/
function setRounds(uint256[][3] memory pRounds) external onlyOwner {
rounds = pRounds;
//Update the presaleEndTime according the last round end timestamp
presaleEndTime = rounds[2][rounds[2].length - 1];
}
/**
* @dev Change details of the current round
* @param pRound round for which you want to change
* @param pCheckpointAmount token tracker amount
*/
function setCurrentRound(uint256 pRound, uint256 pCheckpointAmount) external onlyOwner {
require(pRound < rounds[0].length, "Invalid round");
require(rounds[0][pRound] > pCheckpointAmount, "Checkpoint cannot be greater than round total");
currentRound = pRound;
checkpoint = pCheckpointAmount;
emit CurrentRoundUpdated(pRound, pCheckpointAmount);
}
/**
* @dev Set how many days each round will last
* - It will take effect from the moment the current round ends
*
* @param pDaysPerRound number of days
*/
function setDaysPerRound(uint256 pDaysPerRound) external onlyOwner {
require(pDaysPerRound > 0, "Number of days per round must be greater than zero");
daysPerRound = pDaysPerRound;
emit DaysPerRoundUpdated(pDaysPerRound);
}
/**
* @dev Set flag to control if round time will be updated automatically
*
* @param pFlag boolean flag
*/
function setUpdateRoundTimeAutomaticallyFlag(bool pFlag) external onlyOwner {
updateRoundTimeAutomaticallyFlag = pFlag;
}
/**
* @dev Add address to whitelist
*
* @param pAddresses list of addresses to add in whitelist
*/
function addToWhitelist(address[] calldata pAddresses) external onlyOwner {
uint256 size = pAddresses.length;
for (uint256 i = 0; i < size; i++) {
isWhitelisted[pAddresses[i]] = true;
}
}
/**
* @dev Remove address from whitelist
*
* @param pAddresses list of addresses to remove from whitelist
*/
function removeFromWhitelist(address[] calldata pAddresses) external onlyOwner {
uint256 size = pAddresses.length;
for (uint256 i = 0; i < size; i++) {
isWhitelisted[pAddresses[i]] = false;
}
}
/**
* @dev Add address to blacklist
*
* @param pAddresses list of addresses to add in blacklist
*/
function addToBlacklist(address[] calldata pAddresses) external onlyOwner {
uint256 size = pAddresses.length;
for (uint256 i = 0; i < size; i++) {
isBlacklisted[pAddresses[i]] = true;
}
emit BlacklistImported(pAddresses);
}
/**
* @dev Remove address from blacklist
*
* @param pAddresses list of addresses to remove from blacklist
*/
function removeFromBlacklist(address[] calldata pAddresses) external onlyOwner {
uint256 size = pAddresses.length;
for (uint256 i = 0; i < size; i++) {
isBlacklisted[pAddresses[i]] = false;
}
}
/**
* @dev Add address to Wert whitelist
*
* @param pAddresses list of addresses to add in Wert whitelist
*/
function addToWertWhitelist(address[] calldata pAddresses) external onlyOwner {
uint256 size = pAddresses.length;
for (uint256 i = 0; i < size; i++) {
isWertWhitelisted[pAddresses[i]] = true;
}
}
/**
* @dev Remove address from Wert whitelist
*
* @param pAddresses list of addresses to remove from Wert whitelist
*/
function removeFromWertWhitelist(address[] calldata pAddresses) external onlyOwner {
uint256 size = pAddresses.length;
for (uint256 i = 0; i < size; i++) {
isWertWhitelisted[pAddresses[i]] = false;
}
}
/**
* @dev Set flag to control if stake is available only for whitelisted aaddresses
*
* @param pFlag boolean flag
*/
function setStakeAvailableForWhitelistOnlyFlag(bool pFlag) external onlyOwner {
stakeAvailableForWhitelistOnlyFlag = pFlag;
}
/**
* @dev Set flag to control if claim is available only for whitelisted addresses
*
* @param pFlag boolean flag
*/
function setClaimAvailableForWhitelistOnlyFlag(bool pFlag) external onlyOwner {
claimAvailableForWhitelistOnlyFlag = pFlag;
}
/**
* @dev Set saleToken address
*
* @param pSaleToken boolean flag
*/
function setSaleToken(address pSaleToken) external onlyOwner {
saleToken = pSaleToken;
}
/**
* @dev Set configurations of claim
*
* @param pStakingManager Address of stake contract
* @param pSaleToken Address of sale token
* @param pTokenAmount Amount of tokens available to claim
* @param pClaimStartTime Claim start timestamp
*/
function setupClaim(address pStakingManager, address pSaleToken, uint256 pTokenAmount, uint256 pClaimStartTime) external onlyOwner returns (bool) {
require(isMainNetwork, "This is not the main network");
require(pSaleToken != address(0), "Invalid sale token address");
require(pTokenAmount > 0, "Token amount must be greater than zero");
require(pClaimStartTime >= presaleEndTime, "Claim must start after presale ends");
//Initilize sale token and staking manager instances
IERC20 _token = IERC20(pSaleToken);
stakingManager = StakingManager(pStakingManager); //Initilize sale token
claimStartTime = pClaimStartTime;
saleToken = pSaleToken;
emit TokensAdded(pSaleToken, pTokenAmount, block.timestamp);
if (pStakingManager != address(0)) {
_token.safeIncreaseAllowance(pStakingManager, type(uint256).max); //Set allowance to staking manager contract spend sale tokens
}
//Check if presale contract has enough allowance to transfer tokens
uint256 _presaleAllowance = _token.allowance(msg.sender, address(this));
require(_presaleAllowance >= pTokenAmount, "Not enough allowance");
//Transfer sale tokens to presale contract
require(_token.balanceOf(msg.sender) >= pTokenAmount, "Balance not enough");
_token.safeTransferFrom(msg.sender, address(this), pTokenAmount);
return true;
}
/**
* @dev To change the claim start time
*
* @param pClaimStartTime New claim start timestamp
*/
function setClaimStartTime(uint256 pClaimStartTime) external onlyOwner returns (bool) {
require(pClaimStartTime >= presaleEndTime, "Claim must start after presale ends");
uint256 _claimStartTimeOld = claimStartTime;
claimStartTime = pClaimStartTime;
emit ClaimStartTimeUpdated(_claimStartTimeOld, claimStartTime, block.timestamp);
return true;
}
/**
* @dev Return array of remaining tokens per round
*/
function getRemainingTokensTracker() external view returns (uint256[] memory) {
return remainingTokensTracker;
}
/**
* @dev Update remaining tokens tracker per round array
*
* @param pRemainingTokensTracker new array of remaining tokens tracker
*/
function setRemainingTokensTracker(uint256[] calldata pRemainingTokensTracker) external onlyOwnerOrAdmin {
require(pRemainingTokensTracker.length > 0, "Invalid parameter");
delete remainingTokensTracker;
uint256 size = pRemainingTokensTracker.length;
for (uint256 i; i < size; i++) {
remainingTokensTracker.push(pRemainingTokensTracker[i]);
}
}
/**
* @dev This function allows the contract owner or admin to retrieve the address of a staker from the list of stakers that joined during the presale
*
* @param pIndex The index of the staker's address in the array
*
* Requirements:
* - Only the contract owner or admin can call this function
*
* @return The address of the staker at the specified index
*
*/
function getAddressUserDeposits(uint256 pIndex) external view returns (address) {
return addressUserDeposits[pIndex];
}
/**
* @dev Set imported value for a given address
*
* @param pAddresses address
* @param pValues flag to indicate if address was imported or not
*/
function setImported(address[] calldata pAddresses, bool[] calldata pValues) external onlyOwner {
require(pAddresses.length == pValues.length, "Parameters length mismatch");
uint256 size = pAddresses.length;
for (uint256 i = 0; i < size; i++) {
imported[pAddresses[i]] = pValues[i];
}
}
/**
* @dev Set is import done
*/
function setIsImportDone(bool pIsImportDone) external onlyOwner {
isImportDone = pIsImportDone;
}
/**
* @dev Import userDeposits for purchases on other networks
*
* @param pAddresses array of users addresses
* @param pDeposits array of userDeposits associated with users addresses
*/
function importUserDeposits(address[] calldata pAddresses, uint256[] calldata pDeposits) external onlyOwner {
require(isMainNetwork, "This is not the main network");
require(pAddresses.length == pDeposits.length, "Parameters length mismatch");
uint256 size = pAddresses.length;
for (uint256 i = 0; i < size; i++) {
require(!imported[pAddresses[i]], "Deposits already imported for this address");
userDeposits[pAddresses[i]] += pDeposits[i];
imported[pAddresses[i]] = true;
}
isImportDone = true;
emit UserDepositsImported(pAddresses, pDeposits);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/Address.sol)
pragma solidity ^0.8.20;
import {Errors} from "./Errors.sol";
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev There's no code at `target` (it is not a contract).
*/
error AddressEmptyCode(address target);
/**
* @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.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
if (address(this).balance < amount) {
revert Errors.InsufficientBalance(address(this).balance, amount);
}
(bool success, ) = recipient.call{value: amount}("");
if (!success) {
revert Errors.FailedCall();
}
}
/**
* @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 or custom error, it is bubbled
* up by this function (like regular Solidity function calls). However, if
* the call reverted with no returned reason, this function reverts with a
* {Errors.FailedCall} error.
*
* 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.
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0);
}
/**
* @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`.
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
if (address(this).balance < value) {
revert Errors.InsufficientBalance(address(this).balance, value);
}
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
* was not a contract or bubbling up the revert reason (falling back to {Errors.FailedCall}) in case
* of an unsuccessful call.
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata
) internal view returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
// only check if target is a contract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
if (returndata.length == 0 && target.code.length == 0) {
revert AddressEmptyCode(target);
}
return returndata;
}
}
/**
* @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
* revert reason or with a default {Errors.FailedCall} error.
*/
function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
return returndata;
}
}
/**
* @dev Reverts with returndata if present. Otherwise reverts with {Errors.FailedCall}.
*/
function _revert(bytes memory returndata) 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
assembly ("memory-safe") {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert Errors.FailedCall();
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC-20 standard as defined in the ERC.
*/
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 value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens 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 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` 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 value) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
import {IERC1363} from "../../../interfaces/IERC1363.sol";
import {Address} from "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC-20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
/**
* @dev An operation with an ERC-20 token failed.
*/
error SafeERC20FailedOperation(address token);
/**
* @dev Indicates a failed `decreaseAllowance` request.
*/
error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*
* IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
* smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
* this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
* that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
forceApprove(token, spender, oldAllowance + value);
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
* value, non-reverting calls are assumed to be successful.
*
* IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
* smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
* this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
* that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
unchecked {
uint256 currentAllowance = token.allowance(address(this), spender);
if (currentAllowance < requestedDecrease) {
revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
}
forceApprove(token, spender, currentAllowance - requestedDecrease);
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*
* NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function
* only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being
* set here.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
safeTransfer(token, to, value);
} else if (!token.transferAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target
* has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferFromAndCallRelaxed(
IERC1363 token,
address from,
address to,
uint256 value,
bytes memory data
) internal {
if (to.code.length == 0) {
safeTransferFrom(token, from, to, value);
} else if (!token.transferFromAndCall(from, to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.
* Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}
* once without retrying, and relies on the returned value to be true.
*
* Reverts if the returned value is other than `true`.
*/
function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
forceApprove(token, to, value);
} else if (!token.approveAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements.
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
uint256 returnSize;
uint256 returnValue;
assembly ("memory-safe") {
let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
// bubble errors
if iszero(success) {
let ptr := mload(0x40)
returndatacopy(ptr, 0, returndatasize())
revert(ptr, returndatasize())
}
returnSize := returndatasize()
returnValue := mload(0)
}
if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
bool success;
uint256 returnSize;
uint256 returnValue;
assembly ("memory-safe") {
success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
returnSize := returndatasize()
returnValue := mload(0)
}
return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {Context} from "../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.
*
* The initial owner is set to the address provided by the deployer. 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;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @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 {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @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 {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_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 v5.0.0) (utils/Pausable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract Pausable is Context {
bool private _paused;
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
/**
* @dev The operation failed because the contract is paused.
*/
error EnforcedPause();
/**
* @dev The operation failed because the contract is not paused.
*/
error ExpectedPause();
/**
* @dev Initializes the contract in unpaused state.
*/
constructor() {
_paused = false;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
_requireNotPaused();
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
_requirePaused();
_;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
return _paused;
}
/**
* @dev Throws if the contract is paused.
*/
function _requireNotPaused() internal view virtual {
if (paused()) {
revert EnforcedPause();
}
}
/**
* @dev Throws if the contract is not paused.
*/
function _requirePaused() internal view virtual {
if (!paused()) {
revert ExpectedPause();
}
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol)
pragma solidity ^0.8.20;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at,
* consider using {ReentrancyGuardTransient} instead.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant NOT_ENTERED = 1;
uint256 private constant ENTERED = 2;
uint256 private _status;
/**
* @dev Unauthorized reentrant call.
*/
error ReentrancyGuardReentrantCall();
constructor() {
_status = NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be NOT_ENTERED
if (_status == ENTERED) {
revert ReentrancyGuardReentrantCall();
}
// Any calls to nonReentrant after this point will fail
_status = ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = NOT_ENTERED;
}
/**
* @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
* `nonReentrant` function in the call stack.
*/
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == ENTERED;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/Errors.sol)
pragma solidity ^0.8.20;
/**
* @dev Collection of common custom errors used in multiple contracts
*
* IMPORTANT: Backwards compatibility is not guaranteed in future versions of the library.
* It is recommended to avoid relying on the error API for critical functionality.
*
* _Available since v5.1._
*/
library Errors {
/**
* @dev The ETH balance of the account is not enough to perform the operation.
*/
error InsufficientBalance(uint256 balance, uint256 needed);
/**
* @dev A call to an address target failed. The target may have reverted.
*/
error FailedCall();
/**
* @dev The deployment failed.
*/
error FailedDeployment();
/**
* @dev A necessary precompile is missing.
*/
error MissingPrecompile(address);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC1363.sol)
pragma solidity ^0.8.20;
import {IERC20} from "./IERC20.sol";
import {IERC165} from "./IERC165.sol";
/**
* @title IERC1363
* @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].
*
* Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract
* after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.
*/
interface IERC1363 is IERC20, IERC165 {
/*
* Note: the ERC-165 identifier for this interface is 0xb0202a11.
* 0xb0202a11 ===
* bytes4(keccak256('transferAndCall(address,uint256)')) ^
* bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^
* bytes4(keccak256('approveAndCall(address,uint256)')) ^
* bytes4(keccak256('approveAndCall(address,uint256,bytes)'))
*/
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferAndCall(address to, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @param data Additional data with no specified format, sent in call to `to`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param from The address which you want to send tokens from.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferFromAndCall(address from, address to, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param from The address which you want to send tokens from.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @param data Additional data with no specified format, sent in call to `to`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function approveAndCall(address spender, uint256 value) external returns (bool);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
* @param data Additional data with no specified format, sent in call to `spender`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @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 v5.0.0) (interfaces/IERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../token/ERC20/IERC20.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol)
pragma solidity ^0.8.20;
import {IERC165} from "../utils/introspection/IERC165.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC-165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[ERC].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}{
"remappings": [
"forge-std/=lib/forge-std/src/",
"@openzeppelin/=lib/openzeppelin-contracts/",
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"ds-test/=lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/",
"erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
"halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/"
],
"optimizer": {
"enabled": true,
"runs": 200,
"details": {
"constantOptimizer": true,
"yul": true
}
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "paris",
"viaIR": true,
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"components":[{"internalType":"bool","name":"cIsMainNetwork","type":"bool"},{"internalType":"address","name":"cAdmin","type":"address"},{"internalType":"address","name":"cPriceFeed","type":"address"},{"internalType":"address","name":"cUsdt","type":"address"},{"internalType":"address","name":"cUsdc","type":"address"},{"internalType":"bool","name":"cUsdtFound","type":"bool"},{"internalType":"bool","name":"cUsdcFound","type":"bool"},{"internalType":"uint256","name":"cUsdtDecimals","type":"uint256"},{"internalType":"uint256","name":"cUsdcDecimals","type":"uint256"},{"internalType":"uint256","name":"cDaysPerRound","type":"uint256"},{"internalType":"bool","name":"cUpdateRoundTimeAutomaticallyFlag","type":"bool"},{"internalType":"uint256","name":"cMinBuyInDolar","type":"uint256"},{"internalType":"uint256","name":"cMaxTokensToBuy","type":"uint256"},{"internalType":"uint256","name":"cPresaleStartTime","type":"uint256"},{"internalType":"uint256","name":"cPresaleEndTime","type":"uint256"},{"internalType":"uint256","name":"cTokenDecimals","type":"uint256"},{"internalType":"uint256[][3]","name":"cRounds","type":"uint256[][3]"},{"internalType":"address[]","name":"cAddressPayment","type":"address[]"},{"internalType":"uint256[]","name":"cAddressPercentage","type":"uint256[]"}],"internalType":"struct Presale.ConstructorStruct","name":"_constructor","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"EnforcedPause","type":"error"},{"inputs":[],"name":"ExpectedPause","type":"error"},{"inputs":[],"name":"FailedCall","type":"error"},{"inputs":[{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_admin","type":"address"}],"name":"AdminUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"addresses","type":"address[]"}],"name":"BlacklistImported","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_startTimeOld","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_startTimeNew","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"ClaimStartTimeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_round","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_checkpointAmount","type":"uint256"}],"name":"CurrentRoundUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_daysPerRound","type":"uint256"}],"name":"DaysPerRoundUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_maxTokensToBuyOld","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_maxTokensToBuyNew","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"MaxTokensToBuyUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_minBuyInDolarOld","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_minBuyInDolarNew","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"MinBuyInDolarUpdated","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":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_start","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_end","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"PresaleTimeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_key","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"_oldTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"PresaleTimeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"RoundUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_tokenDecimals","type":"uint256"}],"name":"TokenDecimalsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_tokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"_tokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"TokensAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_address","type":"address"},{"indexed":true,"internalType":"uint256","name":"_tokensBought","type":"uint256"},{"indexed":true,"internalType":"address","name":"_paymentTokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amountPaid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_amountPaidUSD","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_timestamp","type":"uint256"},{"indexed":false,"internalType":"string","name":"_id","type":"string"}],"name":"TokensBought","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_address","type":"address"},{"indexed":true,"internalType":"uint256","name":"_tokensBought","type":"uint256"},{"indexed":true,"internalType":"address","name":"_paymentTokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amountPaid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_amountPaidUSD","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_timestamp","type":"uint256"},{"indexed":false,"internalType":"string","name":"_id","type":"string"}],"name":"TokensBoughtAndStaked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_address","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"TokensClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_address","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"TokensStaked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"_usdcFound","type":"bool"},{"indexed":false,"internalType":"address","name":"_usdc","type":"address"},{"indexed":false,"internalType":"uint256","name":"_usdcDecimals","type":"uint256"}],"name":"UsdcUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"_usdtFound","type":"bool"},{"indexed":false,"internalType":"address","name":"_usdt","type":"address"},{"indexed":false,"internalType":"uint256","name":"_usdtDecimals","type":"uint256"}],"name":"UsdtUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"addresses","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"deposits","type":"uint256[]"}],"name":"UserDepositsImported","type":"event"},{"inputs":[{"internalType":"address[]","name":"pAddresses","type":"address[]"}],"name":"addToBlacklist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"pAddresses","type":"address[]"}],"name":"addToWertWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"pAddresses","type":"address[]"}],"name":"addToWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"addressPayment","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"addressPercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pAmount","type":"uint256"},{"internalType":"bool","name":"pStake","type":"bool"},{"internalType":"string","name":"pId","type":"string"}],"name":"buyWithMain","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pAmount","type":"uint256"},{"internalType":"bool","name":"pStake","type":"bool"},{"internalType":"string","name":"pId","type":"string"}],"name":"buyWithUSDC","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pAmount","type":"uint256"},{"internalType":"bool","name":"pStake","type":"bool"},{"internalType":"string","name":"pId","type":"string"}],"name":"buyWithUSDT","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pUser","type":"address"},{"internalType":"uint256","name":"pAmount","type":"uint256"},{"internalType":"bool","name":"pStake","type":"bool"},{"internalType":"enum Presale.CoinSymbol","name":"pCoinSymbol","type":"uint8"},{"internalType":"string","name":"pId","type":"string"}],"name":"buyWithWert","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pAmountUsd","type":"uint256"}],"name":"calculateAmountTokens","outputs":[{"internalType":"uint256[2]","name":"","type":"uint256[2]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pAmount","type":"uint256"}],"name":"calculatePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"checkpoint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"checkpointHistory","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claim","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimAvailableForWhitelistOnlyFlag","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentRound","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"daysPerRound","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pIndex","type":"uint256"}],"name":"getAddressUserDeposits","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentRoundDetails","outputs":[{"internalType":"uint256[11]","name":"","type":"uint256[11]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLatestPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRemainingTokensTracker","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pIndex","type":"uint256"}],"name":"getRoundDetails","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getUsdRaisedTarget","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"hasClaimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"pAddresses","type":"address[]"},{"internalType":"uint256[]","name":"pDeposits","type":"uint256[]"}],"name":"importUserDeposits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"imported","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pTimestamp","type":"uint256"}],"name":"incrementCurrentRound","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isBlacklisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isImportDone","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isMainNetwork","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isWertWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pAmount","type":"uint256"}],"name":"mainBuyHelper","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTokensToBuy","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minBuyInDolar","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"presaleEndTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"presaleStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"priceFeed","outputs":[{"internalType":"contract Aggregator","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"remainingTokensTracker","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"pAddresses","type":"address[]"}],"name":"removeFromBlacklist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"pAddresses","type":"address[]"}],"name":"removeFromWertWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"pAddresses","type":"address[]"}],"name":"removeFromWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"rounds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"saleToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"pAddresses","type":"address[]"},{"internalType":"uint256[]","name":"pPercentages","type":"uint256[]"}],"name":"setAddressPayment","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pAdmin","type":"address"}],"name":"setAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"pFlag","type":"bool"}],"name":"setClaimAvailableForWhitelistOnlyFlag","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pClaimStartTime","type":"uint256"}],"name":"setClaimStartTime","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pRound","type":"uint256"},{"internalType":"uint256","name":"pCheckpointAmount","type":"uint256"}],"name":"setCurrentRound","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pDaysPerRound","type":"uint256"}],"name":"setDaysPerRound","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"pAddresses","type":"address[]"},{"internalType":"bool[]","name":"pValues","type":"bool[]"}],"name":"setImported","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"pIsImportDone","type":"bool"}],"name":"setIsImportDone","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"pIsMainNetwork","type":"bool"}],"name":"setIsMainNetwork","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pMaxTokensToBuy","type":"uint256"}],"name":"setMaxTokensToBuy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pMinBuyInDolar","type":"uint256"}],"name":"setMinBuyInDolar","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pPresaleStartTime","type":"uint256"},{"internalType":"uint256","name":"pPresaleEndTime","type":"uint256"}],"name":"setPresaleTimes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pPriceFeed","type":"address"}],"name":"setPriceFeed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"pRemainingTokensTracker","type":"uint256[]"}],"name":"setRemainingTokensTracker","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[][3]","name":"pRounds","type":"uint256[][3]"}],"name":"setRounds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pSaleToken","type":"address"}],"name":"setSaleToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"pFlag","type":"bool"}],"name":"setStakeAvailableForWhitelistOnlyFlag","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pStakingManager","type":"address"}],"name":"setStakingManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pTokenDecimals","type":"uint256"}],"name":"setTokenDecimals","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"pFlag","type":"bool"}],"name":"setUpdateRoundTimeAutomaticallyFlag","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"pUsdcFound","type":"bool"},{"internalType":"address","name":"pUsdc","type":"address"},{"internalType":"uint256","name":"pUsdcDecimals","type":"uint256"}],"name":"setUsdc","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"pUsdtFound","type":"bool"},{"internalType":"address","name":"pUsdt","type":"address"},{"internalType":"uint256","name":"pUsdtDecimals","type":"uint256"}],"name":"setUsdt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pStakingManager","type":"address"},{"internalType":"address","name":"pSaleToken","type":"address"},{"internalType":"uint256","name":"pTokenAmount","type":"uint256"},{"internalType":"uint256","name":"pClaimStartTime","type":"uint256"}],"name":"setupClaim","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stake","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakeAvailableForWhitelistOnlyFlag","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakingManager","outputs":[{"internalType":"contract StakingManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenDecimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalTokensSold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalTokensSoldAndStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updateRoundTimeAutomaticallyFlag","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pAmount","type":"uint256"}],"name":"usdBuyHelper","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"usdRaised","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"usdc","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"usdcDecimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"usdcFound","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"usdt","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"usdtDecimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"usdtFound","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userDeposits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]Contract Creation Code
608060405234610b8f576164ce8038038061001981610be1565b9283396020828281010312610b8f578151916001600160401b038311610b8f576102608382018383010312610b8f576040519261026084016001600160401b038111858210176105d257604052610071818301610c06565b8452610081602082840101610c13565b6020850152610094604082840101610c13565b60408501526100a7606082840101610c13565b60608501526100ba608082840101610c13565b60808501526100cd60a082840101610c06565b60a08501526100e060c082840101610c06565b60c085015281810160e08181015190860152610100808201519086015261012080820151908601526101159061014001610c06565b610140850152818101610160818101519086015261018080820151908601526101a080820151908601526101c080820151908601526101e0808201519086015261020001516001600160401b038111610b8f57838301601f8284860101011215610b8f5760405190606082016001600160401b038111838210176105d25760405281858501606083868801010111610b8f578184860101905b60608386880101018210610baf5750505061020085015281810161022001516001600160401b038111610b8f57838301601f8284860101011215610b8f578082840101516102036101fe82610c27565b610be1565b91602083838152019086860160208460051b83888a0101010111610b8f57906020828688010101915b60208460051b82888a010101018310610b9457505050506102208501528181016102400151906001600160401b038211610b8f5761026e938301920101610c3e565b61024082015260016000553315610b7957600154604051336001600160a01b0383167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a360208301516001600160a01b031615610b37575060408201516001600160a01b031615610af25760a0820151610a9b575b60c0820151610a44575b610120820151156109ee5761018082015115610995576101a08201516101c08301511115610937576101c08201514210156108e35761020082015151511561089e576102208201515115610848576102208201515161024083015151036107ce5781516001600160b01b03199091163361ffff60a01b19161790151560a81b60ff60a81b16176001556020810151600380546001600160a01b0319166001600160a01b0392909216919091179055610120810151600c55610140810151600d805491151560ff1660ff1992909216919091179055610160810151600e55610180810151600f556101a08101516011556101c081015160125560006013819055610200820151601491905b6003821061073f57836101e081015180600a55604d811161072957600a0a600b5560a08101511580159061071c575b156106cc5760a081015115156007549060ff60a01b9060a01b1660ff60a81b60c0840151151560a81b169060ff828261ffff60a01b198616171780600755818160a01c1661069a575b60a81c16610668575b50505060408101516001600160a01b031615610623576040810151600580546001600160a01b0319166001600160a01b03929092169190911790556102208101518051906001600160401b0382116105d2576801000000000000000082116105d25760209060185483601855808410610605575b50016018600052602060002060005b8381106105e8576102408501518051906001600160401b0382116105d2576801000000000000000082116105d257602090601954836019558084106105b4575b500190601960005260206000209160005b8281106105a0577fd4ebc506b735b7002102d1487f26f7cd3f61493e35520a7b443e8124db68c37b60606011546012546040519182526020820152426040820152a16040516158259081610ca98239f35b60019060208351930192818601550161054f565b6105cc90601960005284846000209182019101610c91565b8361053e565b634e487b7160e01b600052604160045260246000fd5b82516001600160a01b0316818301556020909201916001016104fe565b61061d90601860005284846000209182019101610c91565b846104ef565b60405162461bcd60e51b815260206004820152601f60248201527f41676772656761746f7220636f6e7472616374206973207265717569726564006044820152606490fd5b60808401516001600160a01b03166001600160b01b03199390931617171760075561010081015160095581808061047b565b6060860151600680546001600160a01b0319166001600160a01b039290921691909117905560e0860151600855610472565b60405162461bcd60e51b815260206004820152602260248201527f4e6f20555344542f5553444320666f756e64206f6e2074686973206e6574776f604482015261726b60f01b6064820152608490fd5b5060c08101511515610429565b634e487b7160e01b600052601160045260246000fd5b80518051906001600160401b0382116105d2576801000000000000000082116105d25760209085548387558084106107b1575b500184600052602060002060005b83811061079d5750505050600160208192019301910190916103fa565b600190602084519401938184015501610780565b6107c8908760005284846000209182019101610c91565b38610772565b60405162461bcd60e51b815260206004820152604660248201527f5061796d656e742061646472657373657320616e64206164647265737365732060448201527f70657263656e746167657320617272617973206d75737420686176652073616d606482015265652073697a6560d01b608482015260a490fd5b60405162461bcd60e51b815260206004820152602860248201527f4174206c65617374206f6e65207061796d656e742061646472657373206973206044820152671c995c5d5a5c995960c21b6064820152608490fd5b60405162461bcd60e51b815260206004820152601e60248201527f4174206c65617374206f6e6520726f756e6420697320726571756972656400006044820152606490fd5b60405162461bcd60e51b815260206004820152602660248201527f50726573616c6520656e642074696d65206d75737420626520696e207468652060448201526566757475726560d01b6064820152608490fd5b60405162461bcd60e51b815260206004820152603060248201527f50726573616c6520656e642074696d65206d757374206265206772656174657260448201526f207468616e2073746172742074696d6560801b6064820152608490fd5b60405162461bcd60e51b815260206004820152602b60248201527f4d617820746f6b656e7320746f20627579206d7573742062652067726561746560448201526a72207468616e207a65726f60a81b6064820152608490fd5b60405162461bcd60e51b815260206004820152602860248201527f446179732070657220726f756e64206d7573742062652067726561746572207460448201526768616e207a65726f60c01b6064820152608490fd5b60808201516001600160a01b03166102f05760405162461bcd60e51b815260206004820152601960248201527f5553444320636f6e7472616374206973207265717569726564000000000000006044820152606490fd5b60608201516001600160a01b03166102e65760405162461bcd60e51b815260206004820152601960248201527f5553445420636f6e7472616374206973207265717569726564000000000000006044820152606490fd5b60405162461bcd60e51b815260206004820152601f60248201527f5072696365206665656420636f6e7472616374206973207265717569726564006044820152606490fd5b62461bcd60e51b815260206004820152601a60248201527f41646d696e20636f6e74726163742069732072657175697265640000000000006044820152606490fd5b631e4fbdf760e01b600052600060045260246000fd5b600080fd5b6020808093610ba286610c13565b815201930192915061022c565b81516001600160401b038111610b8f57602091610bd683928a8a0190878a8c010101610c3e565b8152019101906101ae565b6040519190601f01601f191682016001600160401b038111838210176105d257604052565b51908115158203610b8f57565b51906001600160a01b0382168203610b8f57565b6001600160401b0381116105d25760051b60200190565b9080601f83011215610b8f578151610c586101fe82610c27565b9260208085848152019260051b820101928311610b8f57602001905b828210610c815750505090565b8151815260209182019101610c74565b818110610c9c575050565b60008155600101610c9156fe6080604052600436101561001257600080fd5b6000803560e01c80630188a4fd14613e6b57806302ab3b79146139865780630b94ec44146138835780630ba36dcd1461384a578063119507a014613806578063123425891461350257806322828cc2146134d957806322b2074b1461322457806323494c4714613206578063249b7c19146131e857806325105ea8146131bd5780632533a5f61461313957806325ea750f14613117578063285c9dd5146130f15780632f48ab7d146130c857806333aac1d414613093578063343637031461302b578063344f8d9614612fb157806336f1631a14612c2e5780633a4b66f114612a3e5780633af32abf146129ff5780633b97e856146129e15780633c297db0146127395780633e413bee146127105780633f4ba83a146126a057806341e191ab146125425780634351c6b21461250d57806345516581146124915780634e71d92d146121f7578063548db1741461217d5780635783d469146121485780635c975abb146121225780635d776fc014611df15780635ee2fcf214611d2b5780636195544d14611d1057806362c0067d14611cd457806363b2011714611cb65780636ec4ec23146110a2578063704b6c0214611c47578063715018a614611bea578063724e78da14611b9e57806373b2e80e14611b5f578063741bef1a14611b365780637bf4216514611b185780637d04926a14611a635780637f649783146119e757806382543b32146119c95780638456cb591461196657806386dd75101461194057806389daf799146118c65780638a19c8bc146118a85780638da5cb5b1461187f5780638e15f47314611864578063935eb35f146117b0578063952bd0741461154c57806398a7c5e6146114e957806398b7e3c3146114925780639bb6eb701461130f5780639cfa0f7c146112f15780639d4571f6146112cb578063a039c0f414611256578063a29f481c14611216578063a43ef6dd146111f0578063a6a11bb1146111d2578063a82524b2146111b4578063aa12267b14611191578063aa9c641b146110c9578063ae104265146110a2578063b00bba6a14610fdb578063b6b12e6114610f53578063b97af2c814610ef9578063bc5e00bc14610e21578063be76f98614610d9c578063c23326f314610d71578063c2c4c5c114610d53578063c754cc0314610bac578063c8b26f5e14610b89578063c95c16af14610b4a578063c9d8caee14610b2c578063ce2fafbc14610b0e578063d7cdc3e2146109fc578063dfca41c81461098d578063e0b8f99414610951578063e5b002f814610912578063e6da9213146108d0578063e985e367146108a7578063eadd94ec14610889578063ee8bfd13146104f9578063f2fde38b14610470578063f851a440146104475763fe575a871461040657600080fd5b346104445760203660031901126104445760209060ff906040906001600160a01b03610430613ebc565b168152602384522054166040519015158152f35b80fd5b50346104445780600319360112610444576003546040516001600160a01b039091168152602090f35b50346104445760203660031901126104445761048a613ebc565b610492614b41565b6001600160a01b031680156104e557600180546001600160a01b0319811683179091556001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b631e4fbdf760e01b82526004829052602482fd5b5034610444576040366003190112610444576004356001600160401b0381116108855736602382011215610885578060040135906105368261409f565b916105446040519384614068565b8083526024602084019160051b8301019136831161088157602401905b828210610869575050506024356001600160401b0381116108655761058a9036906004016140b6565b610592614b41565b8151156108145781518151036107cf576018548360185580610797575b50601954836019558061075f575b50815191839182915b8483106106295785606485036105d95780f35b60405162461bcd60e51b815260206004820152602260248201527f546f74616c2070657263656e74616765206d75737420626520657175616c2031604482015261030360f41b6064820152608490fd5b9091926106368484614ae8565b511561070c576106519061064a8585614ae8565b51906144b8565b926001600160a01b036106648284614ae8565b5116601854600160401b8110156106f85780600161068792016018556018613fe1565b81546001600160a01b0360039290921b91821b191692901b9190911790556106af8184614ae8565b51601954600160401b8110156106f857600192916106d782856106f094016019556019613fe1565b90919082549060031b91821b91600019901b1916179055565b0191906105c6565b634e487b7160e01b88526041600452602488fd5b60405162461bcd60e51b815260206004820152602560248201527f50657263656e7461676573206d7573742062652067726561746572207468616e604482015264207a65726f60d81b6064820152608490fd5b60198452610791907f944998273e477b495144fb8794c914197f3ccb46be2900f4698fd0ef743c9695908101906145bb565b386105bd565b601884526107c9907fb13d2d76d1f4b7be834882e410b3e3a8afaf69f83600ae24db354391d2378d2e908101906145bb565b386105af565b60405162461bcd60e51b815260206004820152601b60248201527f4172726179732073697a657320617265206d69736d61746368656400000000006044820152606490fd5b60405162461bcd60e51b815260206004820152602360248201527f4d75737420636f6e666967757265206174206c65617374206f6e65206164647260448201526265737360e81b6064820152608490fd5b8280fd5b6020809161087684613ed2565b815201910190610561565b8480fd5b5080fd5b50346104445780600319360112610444576020601e54604051908152f35b50346104445780600319360112610444576002546040516001600160a01b039091168152602090f35b5034610444576108df36613f13565b91906003811015610885576014019081548310156104445760206109038484613fe1565b90549060031b1c604051908152f35b50346104445760203660031901126104445760209060ff906040906001600160a01b0361093d613ebc565b168152602584522054166040519015158152f35b50346104445760203660031901126104445761096b613ead565b610973614b41565b61ff00601b5491151560081b169061ff00191617601b5580f35b6001826109e461099c36613ff9565b926109a8929192614b6a565b6109b0614b8c565b601154421015806109f0575b6109c5906141cc565b6109d0811515614210565b6109de600f5482111561425b565b33614c33565b55602060405160018152f35b506012544211156109bc565b5034610444576020366003190112610444576004356001600160401b03811161088557610a2d903690600401614038565b6003546001600160a01b031633148015610afa575b610a4b906145d2565b8015610ac157601a5483601a5580610a89575b50825b818110610a6c578380f35b80610a83610a7d600193858761438d565b35614a6a565b01610a61565b601a8452610abb907f057c384a7d1c54f3a1b2e5e67b2617b8224fdfd1ea7234eea573a6ff665ff63e908101906145bb565b38610a5e565b60405162461bcd60e51b815260206004820152601160248201527024b73b30b634b2103830b930b6b2ba32b960791b6044820152606490fd5b506001546001600160a01b03163314610a42565b50346104445780600319360112610444576020600e54604051908152f35b50346104445780600319360112610444576020601d54604051908152f35b50346104445760203660031901126104445760209060ff906040906001600160a01b03610b75613ebc565b168152602684522054166040519015158152f35b5034610444578060031936011261044457602060ff601b54166040519015158152f35b503461044457610bbb36614180565b9092610bc5614b41565b610bd660ff60015460a81c166142a6565b610be1828414614a1e565b845b838110610c605750610c0e90600160ff196020541617602055604051936040855260408501916148b5565b8281036020840152818152906001600160fb1b038111610881577f4053c3111bf4f54ff49c4fd2319edc66e2c70481c8aace4237e657bbe4f99eba93602092849260051b80928583013701030190a180f35b6001600160a01b03610c7b610c7683878661438d565b61439d565b168652602660205260ff604087205416610cfb5780610c9d600192858861438d565b35828060a01b03610cb2610c7684898861438d565b1688526021602052610cc9604089209182546144b8565b9055818060a01b03610cdf610c7683888761438d565b168752602660205260408720805460ff19168317905501610be3565b60405162461bcd60e51b815260206004820152602a60248201527f4465706f7369747320616c726561647920696d706f7274656420666f722074686044820152696973206164647265737360b01b6064820152608490fd5b50346104445780600319360112610444576020601754604051908152f35b50346104445760203660031901126104445760043590601a5482101561044457602061090383613fc6565b503461044457610dab36614180565b610db6939193614b41565b610dc1818414614a1e565b845b838110610dce578580f35b610dd981838761438d565b3590811515809203610e1d576001916001600160a01b03610dfe610c7684898961438d565b1688526026602052604088209060ff8019835416911617905501610dc3565b8680fd5b5034610444577f051425e088ef75da1d8905d9f9d688e5eb2e4102ffccb6466db812a4109ef3fc610ed9610e5436614113565b610e5f939193614b41565b8280610ee7575b8015610edf575b610e7690614614565b600680546001600160a01b0319166001600160a01b039590951694851790556007805460ff60a01b191693151560a081901b60ff60a01b169490941790556008819055604080519384526020840194909452928201929092529081906060820190565b0390a180f35b508215610e6d565b506001600160a01b0384161515610e66565b5034610444576020366003190112610444577f03843ff361861286e264d715d7e39e4f0d8babbee80357c8467b29fd6225a0c56020600435610f39614b41565b80600a55610f4681614704565b600b55604051908152a180f35b5034610444576020366003190112610444576004356003811015610fc7576014016040519181548084526020840192825260208220915b818110610fb157610fad85610fa181870382614068565b60405191829182614146565b0390f35b8254845260209093019260019283019201610f8a565b634e487b7160e01b82526032600452602482fd5b503461044457602036600319011261044457610ff5613ebc565b610ffd614b41565b600480546001600160a01b0319166001600160a01b03831690811790915560015460a81c60ff169081611098575b50611034575080f35b6002546001600160a01b0316908115611053576110509161512f565b80f35b60405162461bcd60e51b815260206004820152601d60248201527f53616c6520746f6b656e206e6f7420636f6e66696775726564207965740000006044820152606490fd5b905015153861102b565b50346104445760203660031901126104445760206110c16004356148f5565b604051908152f35b5034610444576020366003190112610444576004356110e6614b41565b8015611138577f836edba84bfb1c311fd21566a6d3adee8c90e9eb6aab4a862c54073d4c29191790600f549080600f55610ed96040519283924291846040919493926060820195825260208201520152565b60405162461bcd60e51b815260206004820152602b60248201527f4d617820746f6b656e7320746f20627579206d7573742062652067726561746560448201526a72207468616e207a65726f60a81b6064820152608490fd5b5034610444578060031936011261044457602060ff600d54166040519015158152f35b50346104445780600319360112610444576020601154604051908152f35b50346104445780600319360112610444576020601054604051908152f35b5034610444578060031936011261044457602060ff60075460a81c166040519015158152f35b503461044457602036600319011261044457611230613ebc565b611238614b41565b60018060a01b03166001600160601b0360a01b600254161760025580f35b5034610444578060031936011261044457604051601a8054808352908352909160208301917f057c384a7d1c54f3a1b2e5e67b2617b8224fdfd1ea7234eea573a6ff665ff63e915b8181106112b557610fad85610fa181870382614068565b825484526020909301926001928301920161129e565b5034610444578060031936011261044457602060ff601b5460081c166040519015158152f35b50346104445780600319360112610444576020600f54604051908152f35b503461044457806003193601126104445761016090816040516113328282614068565b369037601354801580156114705782905b1561143b57825b604051928584018481106001600160401b038211176114275760405261136f81613f29565b90549060031b1c845261138181613f90565b90549060031b1c602085015261139681613fab565b90549060031b1c60408501526113ae82601754614495565b6060850152608084015260145460a084015260c083015260e082015260125461010082015260275461012082015260205460ff161561141e579060ff60015b166101408301526040519190825b600b821061140857505050f35b60208060019285518152019301910190916113fb565b9060ff816113ed565b634e487b7160e01b86526041600452602486fd5b600019820182811161145c5761145090613f29565b90549060031b1c61134a565b634e487b7160e01b84526011600452602484fd5b600019820182811161145c5761148590613fab565b90549060031b1c90611343565b50346104445760203660031901126104445760043590601f5482101561044457601f548210156114d557602091601f825282822001549060031b1c604051908152f35b634e487b7160e01b81526032600452602490fd5b503461044457602036600319011261044457600435906027548210156114d557602781527f98a476f1687bc3d60a2da2adbcba2c46958e61fa2fb4042cd7bc5816a710195b9091015460405160039290921b1c6001600160a01b03168152602090f35b50346104445761155b36613f13565b90611564614b41565b8015801580916117a7575b1561176d5761167e575b5080611583575080f35b601254804211611639576011548211156115e457601282905560408051918252602082019290925242918101919091526211539160ea1b907f251662bca07d8017c5337e9e812f654ec6cbcca77df4aaac6211514eb35ceb4c90606090a280f35b60405162461bcd60e51b815260206004820152602760248201527f50726573616c6520656e64206d7573742062652061667465722070726573616c60448201526619481cdd185c9d60ca1b6064820152608490fd5b60405162461bcd60e51b815260206004820152601860248201527f50726573616c6520616c72656164792066696e697368656400000000000000006044820152606490fd5b6011548042101561172857814210156116e357601182905560408051918252602082019290925242918101919091526414d510549560da1b907f251662bca07d8017c5337e9e812f654ec6cbcca77df4aaac6211514eb35ceb4c90606090a238611579565b60405162461bcd60e51b815260206004820152601f60248201527f50726573616c65207374617274206d75737420626520696e20667574757265006044820152606490fd5b60405162461bcd60e51b815260206004820152601760248201527f50726573616c6520616c726561647920737461727465640000000000000000006044820152606490fd5b60405162461bcd60e51b8152602060048201526012602482015271496e76616c696420706172616d657465727360701b6044820152606490fd5b5082151561156f565b5034610444576020366003190112610444576004356001600160401b038111610885576117e1903690600401614038565b91906117eb614b41565b815b83811061182f57507f2e0232d6af885035fd9e51c8a3394424686b7064556dc33fefb82c976d0d4eae9192610ed96040519283926020845260208401916148b5565b6001906001600160a01b03611848610c7683888761438d565b168452602360205260408420805460ff191683179055016117ed565b503461044457806003193601126104445760206110c1614712565b50346104445780600319360112610444576001546040516001600160a01b039091168152602090f35b50346104445780600319360112610444576020601354604051908152f35b5034610444576020366003190112610444576004356001600160401b038111610885576118f7903690600401614038565b90611900614b41565b825b82811061190d578380f35b6001906001600160a01b03611926610c7683878761438d565b168552602360205260408520805460ff1916905501611902565b5034610444578060031936011261044457602060ff60075460a01c166040519015158152f35b503461044457806003193601126104445761197f614b41565b611987614b8c565b6001805460ff60a01b1916600160a01b1790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602090a180f35b50346104445780600319360112610444576020600854604051908152f35b5034610444576020366003190112610444576004356001600160401b03811161088557611a18903690600401614038565b90611a21614b41565b825b828110611a2e578380f35b6001906001600160a01b03611a47610c7683878761438d565b168552602460205260408520805460ff19168317905501611a23565b503461044457602036600319011261044457600435611a80614b41565b8015611ab8576020817fbd0fa37abdec0d9fb0895e44615fc5461e23843b08239fd36615e0a3dc3a856592600c55604051908152a180f35b60405162461bcd60e51b815260206004820152603260248201527f4e756d626572206f6620646179732070657220726f756e64206d7573742062656044820152712067726561746572207468616e207a65726f60701b6064820152608490fd5b50346104445780600319360112610444576020600954604051908152f35b50346104445780600319360112610444576005546040516001600160a01b039091168152602090f35b50346104445760203660031901126104445760209060ff906040906001600160a01b03611b8a613ebc565b168152602284522054166040519015158152f35b503461044457602036600319011261044457611bb8613ebc565b611bc0614b41565b6001600160a01b0316611bd4811515614614565b6001600160601b0360a01b600554161760055580f35b5034610444578060031936011261044457611c03614b41565b600180546001600160a01b0319811690915581906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b503461044457602036600319011261044457611c61613ebc565b611c69614b41565b6001600160a01b0316611c7d811515614614565b600380546001600160a01b031916821790557f54e4612788f90384e6843298d7854436f3a585b2c3831ab66abf1de63bfa6c2d8280a280f35b50346104445780600319360112610444576020601c54604051908152f35b50346104445760203660031901126104445760206110c1611d02611cf96004356148f5565b600b549061454d565b611d0a614712565b906144c5565b503461044457806003193601126104445760206110c1614652565b5034610444577f2f2f5c262547cb1fffcd5fd0bde6a83df558b3ba431dd4998d172de22fd15f96610ed9611d5e36614113565b611d69939193614b41565b8280611ddf575b8015611dd7575b611d8090614614565b60078054600161ff0160a01b0319166001600160a01b039590951694851793151560a881901b60ff60a81b169490941790556009819055604080519384526020840194909452928201929092529081906060820190565b508215611d77565b506001600160a01b0384161515611d70565b50346104445760203660031901126104445760043560018060a01b03600354163314801561210e575b611e23906145d2565b601354601454600019810190811161145c578110156120ad57601754611e4882613f29565b90549060031b1c10908115612093575b50801561208b575b1561204657601254811015611feb5760ff600d5416611f5e575b601754611e88601354613f29565b90549060031b1c11600014611f3757611ebc611eb7611ea8601354613f29565b90546017549160031b1c614495565b614a6a565b611ec7601754614ac3565b611ed2601354613f29565b90549060031b1c6017555b6013546000198114611f23577f1d41d2db921fa91b9381a24cedb839376c0f5e82c7822a79c6695666133b24dc916001604092016013558151908482526020820152a180f35b634e487b7160e01b83526011600452602483fd5b611f3f614a91565b611f59611f4d601354613f29565b90549060031b1c614ac3565b611edd565b60165491805b601354611f718186614495565b821015611fc457611f84600c548361454d565b6201518081029080820462015180149015171561145c5782916106d7611fb9600195611fb3611fbe958a6144b8565b936144b8565b613fab565b01611f64565b5050916000198101908111611f2357611fdc90613fab565b90549060031b1c601255611e7a565b60405162461bcd60e51b815260206004820152602d60248201527f43616e6e6f7420696e6372656d656e7420726f756e642061667465722070726560448201526c73616c6520656e642074696d6560981b6064820152608490fd5b60405162461bcd60e51b815260206004820152601860248201527f526f756e64206c696d697473206e6f74207265616368656400000000000000006044820152606490fd5b506001611e60565b61209d9150613fab565b90549060031b1c81101538611e58565b60405162461bcd60e51b815260206004820152603360248201527f4c61737420726f756e6420726561636865642c206974206973206e6f7420706f6044820152721cdcda589b19481d1bc81a5b98dc995b595b9d606a1b6064820152608490fd5b506001546001600160a01b03163314611e1a565b5034610444578060031936011261044457602060ff60015460a01c166040519015158152f35b503461044457602036600319011261044457612162613ead565b61216a614b41565b60ff8019601b54169115151617601b5580f35b5034610444576020366003190112610444576004356001600160401b038111610885576121ae903690600401614038565b906121b7614b41565b825b8281106121c4578380f35b6001906001600160a01b036121dd610c7683878761438d565b168552602460205260408520805460ff19169055016121b9565b5034610444578060031936011261044457612210614b6a565b612218614b8c565b61222960ff60015460a81c166142a6565b6002546001600160a01b03161561244c57338152602360205261225360ff604083205416156143fd565b601054421061240757338152602260205260ff6040822054166123d05760ff601b5416612377575b338152602260205260408120600160ff198254161790553381526021602052604081205490811561233f5733808252602160209081526040808420849055600254905163a9059cbb60e01b928101929092526024820192909252604480820185905281526001939161230191906001600160a01b03166122fc606483614068565b615754565b6040519081524260208201527f9923b4306c6c030f2bdfbf156517d5983b87e15b96176da122cd4f2effa4ba7b60403392a255602060405160018152f35b60405162461bcd60e51b815260206004820152601060248201526f4e6f7468696e6720746f20636c61696d60801b6044820152606490fd5b338152602460205260ff60408220541661227b5760405162461bcd60e51b815260206004820152601e60248201527f55736572206e6f742077686974656c697374656420666f7220636c61696d00006044820152606490fd5b60405162461bcd60e51b815260206004820152600f60248201526e105b1c9958591e4818db185a5b5959608a1b6044820152606490fd5b60405162461bcd60e51b815260206004820152601960248201527f436c61696d20686173206e6f74207374617274656420796574000000000000006044820152606490fd5b60405162461bcd60e51b815260206004820152601c60248201527f53616c6520746f6b656e206973206e6f7420636f6e66696775726564000000006044820152606490fd5b5034610444576020366003190112610444576004356001600160401b038111610885576124c2903690600401614038565b906124cb614b41565b825b8281106124d8578380f35b6001906001600160a01b036124f1610c7683878761438d565b168552602560205260408520805460ff191683179055016124cd565b503461044457602036600319011261044457612527613ead565b61252f614b41565b60ff8019600d54169115151617600d5580f35b5034610444576020366003190112610444576004356001600160401b0381116108855736602382011215610885576040519061257f606083614068565b60648101823682116108815782600401905b8282106126715785856125a2614b41565b60149082905b600382106125ea578360165460001981019081116125d6576125c990613fab565b90549060031b1c60125580f35b634e487b7160e01b82526011600452602482fd5b80518051906001600160401b03821161142757600160401b8211611427576020908554838755808410612654575b500184865260208620865b8381106126405750505050600160208192019301910190916125a8565b600190602084519401938184015501612623565b61266b9087600052848460002091820191016145bb565b87612618565b81356001600160401b038111610e1d576020916126958392600436918901016140b6565b815201910190612591565b50346104445780600319360112610444576126b9614b41565b60015460ff8160a01c16156127015760ff60a01b19166001556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa90602090a180f35b638dfc202b60e01b8252600482fd5b50346104445780600319360112610444576007546040516001600160a01b039091168152602090f35b5034610444576020366003190112610444576004359060409182805161275f8282614068565b369037601354601454600019810190811180612970578282036129b95761278583613f90565b90549060031b1c8411156129845761279f611ea884613f29565b6127b86127ab85613f90565b90549060031b1c866144c5565b906127c285613fab565b905460039190911b1c42106128c557505061145c578110156128825760018101809111611f2357906127f661280392613f90565b90549060031b1c906144c5565b612811600f5482111561425b565b8251908382018281106001600160401b0382111761286e57611d02611cf98695936128409387528086526148f5565b602083015282519190825b6002821061285857505050f35b602080600192855181520193019101909161284b565b634e487b7160e01b84526041600452602484fd5b6064845162461bcd60e51b815260206004820152602060248201527f5468652070726573616c652074696d657374616d70206861766520656e6465646044820152fd5b8181959492969350116128dc575b50505050612803565b61290d929394506128ee9084106144e5565b6129076128fa84613f90565b90549060031b1c8561454d565b90614495565b916001820192838311612970576129536129679361293f8694612939612959956127f66129479a613f90565b906144b8565b958691613f29565b90549060031b1c6144b8565b91613f29565b90549060031b1c1015614560565b388080806128d3565b634e487b7160e01b85526011600452602485fd5b855162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b6044820152606490fd5b600183018084116129cd5761278590613f90565b634e487b7160e01b86526011600452602486fd5b50346104445780600319360112610444576020600a54604051908152f35b50346104445760203660031901126104445760209060ff906040906001600160a01b03612a2a613ebc565b168152602484522054166040519015158152f35b5034610444578060031936011261044457612a57614b6a565b612a5f614b8c565b600454612a76906001600160a01b031615156143b1565b3381526023602052612a8f60ff604083205416156143fd565b60ff601b5460081c16612c11575b338152602160205260408120548015612bd95733825260216020528160408120556010544210600014612b74576004546001600160a01b0316803b15610865576040516348e30cb360e11b8152336004820152602481018390529083908290604490829084905af18015612b6957612b54575b50906001915b6040519081524260208201527fdd2a19c3bdd089cbe77c04f5655f83de0504d6140d12c8667646f55d0557c4dc60403392a255602060405160018152f35b612b5f838092614068565b6108855738612b10565b6040513d85823e3d90fd5b6004546001600160a01b0316803b15610865576040516311f9fbc960e21b8152336004820152602481018390529083908290604490829084905af18015612b6957612bc4575b5090600191612b16565b612bcf838092614068565b6108855738612bba565b60405162461bcd60e51b815260206004820152601060248201526f4e6f7468696e6720746f207374616b6560801b6044820152606490fd5b3381526024602052612c2960ff604083205416614449565b612a9d565b503461044457612c3d36613ff9565b93919092612c49614b6a565b612c51614b8c565b60ff60075460a81c1615612f605760115442101580612f54575b612c74906141cc565b612c7f811515614210565b612c8d600f5482111561425b565b6007546001600160a01b031693612ca3826148f5565b92612cb2600e54851015614bac565b612cbe83601c546144b8565b601c55612ccd836017546144b8565b80601755612cdd85601e546144b8565b601e5560135490612ced82613f29565b90549060031b1c10908115612f3a575b50612f2b575b15612eb0576004546001600160a01b031695612d208715156143b1565b60ff601b5460081c16612e93575b612d3a83601d546144b8565b601d55612d49600b548461454d565b873b15612e8f576040516348e30cb360e11b81523360048201526024810191909152959694959486908690604490829084905af18015612e8457908688949392612e65575b50612dd39550612db86000805160206157d0833981519152916040519182913395428a8086614bf8565b0390a45b611d0a612dce600a5460085490614495565b614704565b604051636eb1769f60e11b815233600482015230602482015292602090849060449082905afa928315612e5a578293612e20575b50600181612e1b82956109e494111561434a565b615471565b92506020833d602011612e52575b81612e3b60209383614068565b81010312612e4d579151916001612e07565b600080fd5b3d9150612e2e565b6040513d84823e3d90fd5b80929450612e7591939596614068565b61088157918591849386612d8e565b6040513d88823e3d90fd5b8580fd5b3385526024602052612eab60ff604087205416614449565b612d2e565b908495916000805160206157b0833981519152612f15612dd39697943389526021602052604089205415612f1d575b612eeb600b548661454d565b338a526021602052612f0260408b209182546144b8565b90556040519182913395428a8086614bf8565b0390a4612dbc565b612f2633614afc565b612edf565b612f3542846152b8565b612d03565b612f449150613fab565b90549060031b1c42101538612cfd565b50601254421115612c6b565b60405162461bcd60e51b815260206004820152602360248201527f5553444320636f6e747261637420666f756e64206f6e2074686973206e6574776044820152626f726b60e81b6064820152608490fd5b5034610444576020366003190112610444576004356001600160401b03811161088557612fe2903690600401614038565b90612feb614b41565b825b828110612ff8578380f35b6001906001600160a01b03613011610c7683878761438d565b168552602560205260408520805460ff1916905501612fed565b5034610444576020366003190112610444577f51cf07e612d83da8f12bd68a61b160a4a100189a4c3c8c0b1e859d8738739d15600435613069614b41565b600e549080600e55610ed96040519283924291846040919493926060820195825260208201520152565b5034610444576020366003190112610444576130ad613ead565b6130b5614b41565b60ff801960205416911515161760205580f35b50346104445780600319360112610444576006546040516001600160a01b039091168152602090f35b5034610444578060031936011261044457602060ff60015460a81c166040519015158152f35b5034610444578060031936011261044457602060ff8154166040519015158152f35b5034610444576020366003190112610444577f137c2e88b808cc3889ff5cc4e6f6c813f879579a4afe7573d003c67ebf6431f7600435613177614b41565b6131856012548210156142f2565b60105490806010556131af6040519283924291846040919493926060820195825260208201520152565b0390a1602060405160018152f35b5034610444576020366003190112610444576004359060195482101561044457602061090383613f75565b50346104445780600319360112610444576020601254604051908152f35b50346104445780600319360112610444576020600c54604051908152f35b50346104445760803660031901126104445761323e613ebc565b6024356001600160a01b03811691908290036108655760443590606435613263614b41565b61327460ff60015460a81c166142a6565b83156134945782156134405761328e6012548210156142f2565b60018060a01b03821690816001600160601b0360a01b6004541617600455601055836001600160601b0360a01b6002541617600255837fdc9670dbabdd488b372eb16ebe49a39b3124a12cdffdcefbc89834a408bf8ff860408051868152426020820152a2613430575b50604051636eb1769f60e11b8152336004820152306024820152602081604481865afa80156133ef57829085906133fa575b6133369250101561434a565b6040516370a0823160e01b8152336004820152602081602481865afa9081156133ef57829394916133ba575b5010613380576133759130903390615274565b602060405160018152f35b60405162461bcd60e51b8152602060048201526012602482015271084c2d8c2dcc6ca40dcdee840cadcdeeaced60731b6044820152606490fd5b9150506020813d6020116133e7575b816133d660209383614068565b81010312612e4d5781905138613362565b3d91506133c9565b6040513d86823e3d90fd5b50506020813d602011613428575b8161341560209383614068565b81010312612e4d5781613336915161332a565b3d9150613408565b61343a908361512f565b386132f8565b60405162461bcd60e51b815260206004820152602660248201527f546f6b656e20616d6f756e74206d7573742062652067726561746572207468616044820152656e207a65726f60d01b6064820152608490fd5b60405162461bcd60e51b815260206004820152601a60248201527f496e76616c69642073616c6520746f6b656e20616464726573730000000000006044820152606490fd5b50346104445780600319360112610444576004546040516001600160a01b039091168152602090f35b50346104445761351136613ff9565b9391909261351d614b6a565b613525614b8c565b60ff60075460a01c16156137b557601154421015806137a9575b613548906141cc565b613553811515614210565b613561600f5482111561425b565b6006546001600160a01b031693613577826148f5565b92613586600e54851015614bac565b61359283601c546144b8565b601c556135a1836017546144b8565b806017556135b185601e546144b8565b601e55601354906135c182613f29565b90549060031b1c1090811561378f575b50613780575b15613746576004546001600160a01b0316956135f48715156143b1565b60ff601b5460081c16613729575b61360e83601d546144b8565b601d5561361d600b548461454d565b873b15612e8f576040516348e30cb360e11b81523360048201526024810191909152959694959486908690604490829084905af18015612e845790868894939261370a575b5061368c9550612db86000805160206157d0833981519152916040519182913395428a8086614bf8565b604051636eb1769f60e11b815233600482015230602482015292602090849060449082905afa928315612e5a5782936136d5575b50600281612e1b6001956109e494111561434a565b92506020833d602011613702575b816136f060209383614068565b81010312612e4d5791519160026136c0565b3d91506136e3565b8092945061371a91939596614068565b61088157918591849386613662565b338552602460205261374160ff604087205416614449565b613602565b908495916000805160206157b0833981519152612f1561368c9697943389526021602052604089205415612f1d57612eeb600b548661454d565b61378a42846152b8565b6135d7565b6137999150613fab565b90549060031b1c421015386135d1565b5060125442111561353f565b60405162461bcd60e51b815260206004820152602360248201527f5553445420636f6e747261637420666f756e64206f6e2074686973206e6574776044820152626f726b60e81b6064820152608490fd5b5034610444576020366003190112610444576004359060185482101561044457602061383183613f5a565b905460405160039290921b1c6001600160a01b03168152f35b5034610444576020366003190112610444576020906040906001600160a01b03613872613ebc565b168152602183522054604051908152f35b50346104445761389236613f13565b61389a614b41565b60145482101561395157806138ae83613f29565b90549060031b1c11156138f657816040917f1c8f1847dfc445804fec63332d23742b97dd76eee45cc4212cc8f7534d59ddfa936013558060175582519182526020820152a180f35b60405162461bcd60e51b815260206004820152602d60248201527f436865636b706f696e742063616e6e6f7420626520677265617465722074686160448201526c1b881c9bdd5b99081d1bdd185b609a1b6064820152608490fd5b60405162461bcd60e51b815260206004820152600d60248201526c125b9d985b1a59081c9bdd5b99609a1b6044820152606490fd5b5060a03660031901126104445761399b613ebc565b906024356044358015158103610865576064359160038310948515610881576084356001600160401b038111612e8f576139d9903690600401613ee6565b9490966139e4614b6a565b6139ec614b8c565b60115442101580613e5f575b613a01906141cc565b613a0c841515614210565b613a1a600f5485111561425b565b338752602560205260ff60408820541615613e0557811587818015613df9575b818115613dd5575b5015613d9d57613d895715613a6257505091600195916109e49493614c33565b94919392909415613d755760028503613d63576006546001600160a01b0316965b613a8c826148f5565b93613a9b600e54861015614bac565b613aa783601c546144b8565b601c55613ab6836017546144b8565b80601755613ac686601e546144b8565b601e5560135490613ad682613f29565b90549060031b1c10908115613d49575b50613d3a575b15613caf576004546001600160a01b0316613b088115156143b1565b60ff601b5460081c16613c88575b613b2283601d546144b8565b601d55613b31600b548461454d565b813b15613c84576040516348e30cb360e11b81526001600160a01b038816600482015260248101919091529088908290604490829084905af18015613c7957613c54575b50604051613beb956020959094613bb79491936001600160a01b03808d1694908816926000805160206157d0833981519152928291612db891428a8086614bf8565b604051636eb1769f60e11b81526001600160a01b039092166004830152306024830152959092839190829081906044820190565b03916001600160a01b03165afa908115612b69578391613c1f575b509083612e1b613c1a93600196111561434a565b6109e4565b9190506020823d602011613c4c575b81613c3b60209383614068565b81010312612e4d5790516001613c06565b3d9150613c2e565b92613bb79288613c6c602097949a613beb9997614068565b9892955092509294613b75565b6040513d8a823e3d90fd5b8880fd5b6001600160a01b038616885260246020526040882054613caa9060ff16614449565b613b16565b92602093613bb792613beb96946000805160206157b083398151915260018060a01b03871691828c526021895260408c205415613d2c575b8b613d0a6040613cf9600b548861454d565b9286815260218d52209182546144b8565b90556040516001600160a01b038e169590918291612f159190428a8086614bf8565b613d3588614afc565b613ce7565b613d4442846152b8565b613aec565b613d539150613fab565b90549060031b1c42101538613ae6565b6007546001600160a01b031696613a83565b634e487b7160e01b86526021600452602486fd5b634e487b7160e01b88526021600452602488fd5b60405162461bcd60e51b815260206004820152601060248201526f14de5b589bdb081b9bdd08199bdd5b9960821b6044820152606490fd5b9050613de5576001841481613a42565b634e487b7160e01b89526021600452602489fd5b50508760028414613a3a565b60405162461bcd60e51b815260206004820152602c60248201527f41646472657373206e6f742077686974656c697374656420666f72207468697360448201526b103a3930b739b0b1ba34b7b760a11b6064820152608490fd5b506012544211156139f8565b503461044457602036600319011261044457613e85613ead565b613e8d614b41565b6001805460ff60a81b191691151560a81b60ff60a81b1691909117905580f35b600435908115158203612e4d57565b600435906001600160a01b0382168203612e4d57565b35906001600160a01b0382168203612e4d57565b9181601f84011215612e4d578235916001600160401b038311612e4d5760208381860195010111612e4d57565b6040906003190112612e4d576004359060243590565b601454811015613f4457601460005260206000200190600090565b634e487b7160e01b600052603260045260246000fd5b601854811015613f4457601860005260206000200190600090565b601954811015613f4457601960005260206000200190600090565b601554811015613f4457601560005260206000200190600090565b601654811015613f4457601660005260206000200190600090565b601a54811015613f4457601a60005260206000200190600090565b8054821015613f445760005260206000200190600090565b6060600319820112612e4d57600435916024358015158103612e4d5791604435906001600160401b038211612e4d5761403491600401613ee6565b9091565b9181601f84011215612e4d578235916001600160401b038311612e4d576020808501948460051b010111612e4d57565b90601f801991011681019081106001600160401b0382111761408957604052565b634e487b7160e01b600052604160045260246000fd5b6001600160401b0381116140895760051b60200190565b9080601f83011215612e4d5781356140cd8161409f565b926140db6040519485614068565b81845260208085019260051b820101928311612e4d57602001905b8282106141035750505090565b81358152602091820191016140f6565b6060906003190112612e4d576004358015158103612e4d57906024356001600160a01b0381168103612e4d579060443590565b602060408183019282815284518094520192019060005b81811061416a5750505090565b825184526020938401939092019160010161415d565b6040600319820112612e4d576004356001600160401b038111612e4d57816141aa91600401614038565b92909291602435906001600160401b038211612e4d5761403491600401614038565b156141d357565b60405162461bcd60e51b815260206004820152601560248201527413dd5d081bd9881c1c995cd85b19481c195c9a5bd9605a1b6044820152606490fd5b1561421757565b606460405162461bcd60e51b815260206004820152602060248201527f416d6f756e74206d7573742062652067726561746572207468616e207a65726f6044820152fd5b1561426257565b606460405162461bcd60e51b815260206004820152602060248201527f416d6f756e742065786365656473206d617820746f6b656e7320746f206275796044820152fd5b156142ad57565b60405162461bcd60e51b815260206004820152601c60248201527f54686973206973206e6f7420746865206d61696e206e6574776f726b000000006044820152606490fd5b156142f957565b60405162461bcd60e51b815260206004820152602360248201527f436c61696d206d7573742073746172742061667465722070726573616c6520656044820152626e647360e81b6064820152608490fd5b1561435157565b60405162461bcd60e51b81526020600482015260146024820152734e6f7420656e6f75676820616c6c6f77616e636560601b6044820152606490fd5b9190811015613f445760051b0190565b356001600160a01b0381168103612e4d5790565b156143b857565b60405162461bcd60e51b815260206004820152601e60248201527f5374616b696e67206d616e61676572206e6f7420636f6e6669677572656400006044820152606490fd5b1561440457565b60405162461bcd60e51b815260206004820152601b60248201527f54686973206164647265737320697320626c61636b6c697374656400000000006044820152606490fd5b1561445057565b60405162461bcd60e51b815260206004820152601e60248201527f55736572206e6f742077686974656c697374656420666f72207374616b6500006044820152606490fd5b919082039182116144a257565b634e487b7160e01b600052601160045260246000fd5b919082018092116144a257565b81156144cf570490565b634e487b7160e01b600052601260045260246000fd5b156144ec57565b60405162461bcd60e51b815260206004820152603360248201527f4c61737420726f756e642c206974206973206e6f7420706f737369626c6520746044820152726f206275792074686973207175616e7469747960681b6064820152608490fd5b818102929181159184041417156144a257565b1561456757565b60405162461bcd60e51b815260206004820152602660248201527f43616e206e6f7420627579207468697320616d6f756e7420696e20612073696e6044820152650ced8ca40e8f60d31b6064820152608490fd5b8181106145c6575050565b600081556001016145bb565b156145d957565b60405162461bcd60e51b815260206004820152601360248201527227b7363c9037bbb732b91037b91030b236b4b760691b6044820152606490fd5b1561461b57565b60405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b6044820152606490fd5b60135480156146dd5760009060005b81811061469a5750906129398261468a61467d61469795613f29565b90549060031b1c91613f90565b90549060031b1c9061454d565b90565b916146d66001916129396146cd6146b087613f29565b90549060031b1c6146c088613fc6565b90549060031b1c90614495565b61468a87613f90565b9201614661565b8061468a61467d61469793613f29565b519069ffffffffffffffffffff82168203612e4d57565b604d81116144a257600a0a90565b60055460405163313ce56760e01b81526001600160a01b0390911690602081600481855afa90811561482757600091614878575b5060ff1690600a54918281116148335760a060049260405193848092633fabe5a360e21b82525afa918215614827576000926147d8575b50600082131561479d57612dce6147979161469794614495565b9061454d565b60405162461bcd60e51b81526020600482015260136024820152724572726f722067657474696e6720707269636560681b6044820152606490fd5b90915060a0813d60a01161481f575b816147f460a09383614068565b81010312612e4d57614805816146ed565b506148176080602083015192016146ed565b50903861477d565b3d91506147e7565b6040513d6000823e3d90fd5b60405162461bcd60e51b815260206004820152601b60248201527f496e76616c69642061676772656761746f7220646563696d616c7300000000006044820152606490fd5b6020813d6020116148ad575b8161489160209383614068565b8101031261088557519060ff82168203610444575060ff614746565b3d9150614884565b9160209082815201919060005b8181106148cf5750505090565b909192602080600192838060a01b036148e788613ed2565b1681520194019291016148c2565b614903600f5482111561425b565b6017549061491182826144b8565b6013549061491e82613f29565b90549060031b1c108015614a05575b156149f75760145460001981019081116144a25761494c9082106144e5565b6149598261294783613f29565b90600181019384821192836144a2576149759061295987613f29565b61497e82613fab565b90549060031b1c42116000146149ac5750506144a2576149a061469792613f90565b90549060031b1c61454d565b61293992506149a06149ea6149e4846149dc614797956149d06146979b9a98613f29565b90549060031b1c614495565b938491613f90565b95613f90565b90549060031b1c92614495565b61469792506149a090613f90565b50614a0f81613fab565b90549060031b1c42101561492d565b15614a2557565b60405162461bcd60e51b815260206004820152601a60248201527f506172616d6574657273206c656e677468206d69736d617463680000000000006044820152606490fd5b601a5490600160401b821015614089576106d7826001614a8f9401601a55601a613fe1565b565b601a54600160401b81101561408957806001614ab29201601a55601a613fe1565b8154906000199060031b1b19169055565b601f5490600160401b821015614089576106d7826001614a8f9401601f55601f613fe1565b8051821015613f445760209160051b010190565b602754600160401b81101561408957806001614b1d92016027556027613fe1565b81546001600160a01b0393841660039290921b91821b9390911b1916919091179055565b6001546001600160a01b03163303614b5557565b63118cdaa760e01b6000523360045260246000fd5b600260005414614b7b576002600055565b633ee5aeb560e01b60005260046000fd5b60ff60015460a01c16614b9b57565b63d93c066560e01b60005260046000fd5b15614bb357565b60405162461bcd60e51b815260206004820152601a60248201527f5061796d656e74206c6f776572207468616e206d696e696d756d0000000000006044820152606490fd5b93909285939260a0969386526020860152604085015260806060850152816080850152848401376000828201840152601f01601f1916010190565b919290614c3f816148f5565b600b5495614c52611d026000988461454d565b938434106150f357614c68600e54841015614bac565b87614c738634614495565b97614c8086601c546144b8565b601c55614c8f866017546144b8565b80601755614c9f86601e546144b8565b601e5560135490614caf82613f29565b90549060031b1c109081156150d9575b506150ca575b1561504d57506004546001600160a01b0316614ce28115156143b1565b60ff601b5460081c16615026575b614cfc85601d546144b8565b601d55614d0b600b548661454d565b90803b15615022576040516348e30cb360e11b81526001600160a01b0389166004820152602481019290925289908290604490829084905af1801561501757614fef575b506040518894936001600160a01b038816936000805160206157d0833981519152938392614d8292919042908b86614bf8565b0390a45b6018548015614faa576019548103614f4757849085905b808210614ef4575050818110614eae575b505081614dba57505050565b814710614e5a57814710614e425782918291829182916001600160a01b03165af13d15614e3d573d6001600160401b038111614e295760405190614e08601f8201601f191660200183614068565b81528260203d92013e5b15614e1a5750565b63d6bda27560e01b8152600490fd5b634e487b7160e01b83526041600452602483fd5b614e12565b63cf47918160e01b8352476004526024829052604483fd5b60405162461bcd60e51b815260206004820152602660248201527f4d61696e206e6574776f726b2073796d626f6c2062616c616e6365206e6f74206044820152650cadcdeeaced60d31b6064820152608490fd5b60185460001981019081116129cd5791614ee78692614ecf614eed95613f5a565b905460039190911b1c6001600160a01b031692614495565b906154fb565b3880614dae565b9091614f3f6001916064614f17614f0a87613f75565b90549060031b1c8861454d565b0490614f3a8a83614f2789613f5a565b888060a01b0391549060031b1c166154fb565b6144b8565b920190614d9d565b60405162461bcd60e51b815260206004820152603560248201527f57726f6e6720636f6e66696775726174696f6e207061796d656e742061646472604482015274657373657320616e642070657263656e746167657360581b6064820152608490fd5b60405162461bcd60e51b815260206004820152601e60248201527f5061796d656e742061646472657373206e6f7420636f6e6669677572656400006044820152606490fd5b9761500d816000805160206157d0833981519152939695949a614068565b9791929390614d4f565b6040513d8b823e3d90fd5b8980fd5b6001600160a01b0387168952602460205260408920546150489060ff16614449565b614cf0565b9392906000805160206157b0833981519152916150b460018060a01b0389169485885260216020526040882054156150bc575b61508c600b548861454d565b86895260216020526150a360408a209182546144b8565b905560405193849342908b86614bf8565b0390a4614d86565b6150c58a614afc565b615080565b6150d442876152b8565b614cc5565b6150e39150613fab565b90549060031b1c42101538614cbf565b60405162461bcd60e51b8152602060048201526014602482015273125b9cdd59999a58da595b9d081c185e5b595b9d60621b6044820152606490fd5b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301529091908116602083604481845afa92831561482757600093615240575b5060001983018093116144a25760405163095ea7b360e01b60208083019182526001600160a01b03871660248401526044808401969096529482529093906000906151bb606487614068565b85519082865af1903d6000519083615221575b505050156151db57505050565b60405163095ea7b360e01b60208201526001600160a01b03909316602484015260006044808501919091528352614a8f926122fc9061521b606482614068565b82615754565b9192509061523657503b15155b3880806151ce565b600191501461522e565b90926020823d60201161526c575b8161525b60209383614068565b81010312610444575051913861516f565b3d915061524e565b6040516323b872dd60e01b60208201526001600160a01b039283166024820152929091166044830152606480830193909352918152614a8f916122fc608483614068565b60135460145460001981019081116144a2578110156120ad576017546152dd82613f29565b90549060031b1c10908115615457575b50801561544f575b1561204657601254821015611feb5760ff600d54166153c8575b60175461531d601354613f29565b90549060031b1c116000146153ad57615341611eb782614f3a611ea8601354613f29565b61535561535082601754614495565b614ac3565b61536481612947601354613f29565b6017555b6013549060001982146144a2577f1d41d2db921fa91b9381a24cedb839376c0f5e82c7822a79c6695666133b24dc9260016040930160135582519182526020820152a1565b6153b5614a91565b6153c3611f4d601354613f29565b615368565b906016549260005b601354906153de8287614495565b811015615425576153f1600c548261454d565b620151808102908082046201518014901517156144a2576001926106d7611fb984611fb361541f958a6144b8565b016153d0565b50509291909160001981019081116144a25761544090613fab565b90549060031b1c60125561530f565b5080156152f5565b6154619150613fab565b90549060031b1c821015386152ed565b90601854918215614faa576019548303614f47576000926000905b8082106154c05750508083106154a157505050565b60185460001981019081116144a257614a8f93614ecf614ee792613f5a565b90936154f360019160646154e36154d689613f75565b90549060031b1c8761454d565b0490614f3a8783614f278b613f5a565b94019061548c565b91600381101561573e578061559c575090814710614e5a57814710615583576000918291829182916001600160a01b03165af13d1561557e573d6001600160401b038111614089576040519061555b601f8201601f191660200183614068565b8152600060203d92013e5b1561556d57565b63d6bda27560e01b60005260046000fd5b615566565b504763cf47918160e01b60005260045260245260446000fd5b6002810361566c57506006546040516370a0823160e01b81523360048201526001600160a01b039091169290602081602481875afa8015614827578391600091615637575b50106155f257614a8f923390615274565b60405162461bcd60e51b815260206004820152601760248201527f555344542062616c616e6365206e6f7420656e6f7567680000000000000000006044820152606490fd5b9150506020813d602011615664575b8161565360209383614068565b81010312612e4d57829051386155e1565b3d9150615646565b600114615677575050565b6007546040516370a0823160e01b81523360048201526001600160a01b039091169290602081602481875afa8015614827578391600091615709575b50106156c457614a8f923390615274565b60405162461bcd60e51b815260206004820152601760248201527f555344432062616c616e6365206e6f7420656e6f7567680000000000000000006044820152606490fd5b9150506020813d602011615736575b8161572560209383614068565b81010312612e4d57829051386156b3565b3d9150615718565b634e487b7160e01b600052602160045260246000fd5b906000602091828151910182855af115614827576000513d6157a657506001600160a01b0381163b155b6157855750565b635274afe760e01b60009081526001600160a01b0391909116600452602490fd5b6001141561577e56fe669f5b3ea5a6185ec3bb56d247002f736893c205f65ece2330c4f7ca599e52574c56565e3fd9d98d897a1354c44260050e5ed40878076114deae8e6330a88c34a2646970667358221220a66cbd215ed508831e938fab946bdf8d9a3e2330197c722a871f98217e8a4b3f64736f6c634300081a0033000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000001ebd3797f82155710cbd8267a4bf485658f183d00000000000000000000000005f4ec3df9cbd43714fe2740f5e3616155c5b8419000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000004c4b400000000000000000000000000000000000000000000000000000000067a0afc000000000000000000000000000000000000000000000000000000000682b1d40000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000aa00000000000000000000000000000000000000000000000000000000000000ae00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000005a0000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000009896800000000000000000000000000000000000000000000000000000000001312d000000000000000000000000000000000000000000000000000000000001c9c3800000000000000000000000000000000000000000000000000000000002625a000000000000000000000000000000000000000000000000000000000002faf080000000000000000000000000000000000000000000000000000000000393870000000000000000000000000000000000000000000000000000000000042c1d800000000000000000000000000000000000000000000000000000000004c4b40000000000000000000000000000000000000000000000000000000000055d4a800000000000000000000000000000000000000000000000000000000005f5e10000000000000000000000000000000000000000000000000000000000068e77800000000000000000000000000000000000000000000000000000000007270e000000000000000000000000000000000000000000000000000000000007bfa4800000000000000000000000000000000000000000000000000000000008583b000000000000000000000000000000000000000000000000000000000008f0d1800000000000000000000000000000000000000000000000000000000009896800000000000000000000000000000000000000000000000000000000000a21fe80000000000000000000000000000000000000000000000000000000000aba9500000000000000000000000000000000000000000000000000000000000b532b80000000000000000000000000000000000000000000000000000000000bebc200000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000b6139a7cbd200000000000000000000000000000000000000000000000000000ba8478cab5400000000000000000000000000000000000000000000000000000bef55718ad600000000000000000000000000000000000000000000000000000c3663566a5800000000000000000000000000000000000000000000000000000c7d713b49da00000000000000000000000000000000000000000000000000000cc47f20295c00000000000000000000000000000000000000000000000000000d0b8d0508de00000000000000000000000000000000000000000000000000000d529ae9e86000000000000000000000000000000000000000000000000000000d99a8cec7e200000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000e27c49886e600000000000000000000000000000000000000000000000000000e6ed27d666800000000000000000000000000000000000000000000000000000eb5e06245ea00000000000000000000000000000000000000000000000000000efcee47256c00000000000000000000000000000000000000000000000000000f43fc2c04ee00000000000000000000000000000000000000000000000000000f8b0a10e47000000000000000000000000000000000000000000000000000000fd217f5c3f20000000000000000000000000000000000000000000000000000101925daa3740000000000000000000000000000000000000000000000000000106033bf82f600000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000067ae08f00000000000000000000000000000000000000000000000000000000067b4a0700000000000000000000000000000000000000000000000000000000067bb37f00000000000000000000000000000000000000000000000000000000067c1cf700000000000000000000000000000000000000000000000000000000067c866f00000000000000000000000000000000000000000000000000000000067cefe700000000000000000000000000000000000000000000000000000000067d595f00000000000000000000000000000000000000000000000000000000067dc2d700000000000000000000000000000000000000000000000000000000067e2c4f00000000000000000000000000000000000000000000000000000000067e95c700000000000000000000000000000000000000000000000000000000067eff3f00000000000000000000000000000000000000000000000000000000067f68b700000000000000000000000000000000000000000000000000000000067fd22f0000000000000000000000000000000000000000000000000000000006803ba7000000000000000000000000000000000000000000000000000000000680a51f0000000000000000000000000000000000000000000000000000000006810e97000000000000000000000000000000000000000000000000000000000681780f000000000000000000000000000000000000000000000000000000000681e1870000000000000000000000000000000000000000000000000000000006824aff000000000000000000000000000000000000000000000000000000000682b47700000000000000000000000000000000000000000000000000000000000000001000000000000000000000000c94f39ecb6af81560bc431df6592683a4e793f2100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000064
Deployed Bytecode
0x6080604052600436101561001257600080fd5b6000803560e01c80630188a4fd14613e6b57806302ab3b79146139865780630b94ec44146138835780630ba36dcd1461384a578063119507a014613806578063123425891461350257806322828cc2146134d957806322b2074b1461322457806323494c4714613206578063249b7c19146131e857806325105ea8146131bd5780632533a5f61461313957806325ea750f14613117578063285c9dd5146130f15780632f48ab7d146130c857806333aac1d414613093578063343637031461302b578063344f8d9614612fb157806336f1631a14612c2e5780633a4b66f114612a3e5780633af32abf146129ff5780633b97e856146129e15780633c297db0146127395780633e413bee146127105780633f4ba83a146126a057806341e191ab146125425780634351c6b21461250d57806345516581146124915780634e71d92d146121f7578063548db1741461217d5780635783d469146121485780635c975abb146121225780635d776fc014611df15780635ee2fcf214611d2b5780636195544d14611d1057806362c0067d14611cd457806363b2011714611cb65780636ec4ec23146110a2578063704b6c0214611c47578063715018a614611bea578063724e78da14611b9e57806373b2e80e14611b5f578063741bef1a14611b365780637bf4216514611b185780637d04926a14611a635780637f649783146119e757806382543b32146119c95780638456cb591461196657806386dd75101461194057806389daf799146118c65780638a19c8bc146118a85780638da5cb5b1461187f5780638e15f47314611864578063935eb35f146117b0578063952bd0741461154c57806398a7c5e6146114e957806398b7e3c3146114925780639bb6eb701461130f5780639cfa0f7c146112f15780639d4571f6146112cb578063a039c0f414611256578063a29f481c14611216578063a43ef6dd146111f0578063a6a11bb1146111d2578063a82524b2146111b4578063aa12267b14611191578063aa9c641b146110c9578063ae104265146110a2578063b00bba6a14610fdb578063b6b12e6114610f53578063b97af2c814610ef9578063bc5e00bc14610e21578063be76f98614610d9c578063c23326f314610d71578063c2c4c5c114610d53578063c754cc0314610bac578063c8b26f5e14610b89578063c95c16af14610b4a578063c9d8caee14610b2c578063ce2fafbc14610b0e578063d7cdc3e2146109fc578063dfca41c81461098d578063e0b8f99414610951578063e5b002f814610912578063e6da9213146108d0578063e985e367146108a7578063eadd94ec14610889578063ee8bfd13146104f9578063f2fde38b14610470578063f851a440146104475763fe575a871461040657600080fd5b346104445760203660031901126104445760209060ff906040906001600160a01b03610430613ebc565b168152602384522054166040519015158152f35b80fd5b50346104445780600319360112610444576003546040516001600160a01b039091168152602090f35b50346104445760203660031901126104445761048a613ebc565b610492614b41565b6001600160a01b031680156104e557600180546001600160a01b0319811683179091556001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b631e4fbdf760e01b82526004829052602482fd5b5034610444576040366003190112610444576004356001600160401b0381116108855736602382011215610885578060040135906105368261409f565b916105446040519384614068565b8083526024602084019160051b8301019136831161088157602401905b828210610869575050506024356001600160401b0381116108655761058a9036906004016140b6565b610592614b41565b8151156108145781518151036107cf576018548360185580610797575b50601954836019558061075f575b50815191839182915b8483106106295785606485036105d95780f35b60405162461bcd60e51b815260206004820152602260248201527f546f74616c2070657263656e74616765206d75737420626520657175616c2031604482015261030360f41b6064820152608490fd5b9091926106368484614ae8565b511561070c576106519061064a8585614ae8565b51906144b8565b926001600160a01b036106648284614ae8565b5116601854600160401b8110156106f85780600161068792016018556018613fe1565b81546001600160a01b0360039290921b91821b191692901b9190911790556106af8184614ae8565b51601954600160401b8110156106f857600192916106d782856106f094016019556019613fe1565b90919082549060031b91821b91600019901b1916179055565b0191906105c6565b634e487b7160e01b88526041600452602488fd5b60405162461bcd60e51b815260206004820152602560248201527f50657263656e7461676573206d7573742062652067726561746572207468616e604482015264207a65726f60d81b6064820152608490fd5b60198452610791907f944998273e477b495144fb8794c914197f3ccb46be2900f4698fd0ef743c9695908101906145bb565b386105bd565b601884526107c9907fb13d2d76d1f4b7be834882e410b3e3a8afaf69f83600ae24db354391d2378d2e908101906145bb565b386105af565b60405162461bcd60e51b815260206004820152601b60248201527f4172726179732073697a657320617265206d69736d61746368656400000000006044820152606490fd5b60405162461bcd60e51b815260206004820152602360248201527f4d75737420636f6e666967757265206174206c65617374206f6e65206164647260448201526265737360e81b6064820152608490fd5b8280fd5b6020809161087684613ed2565b815201910190610561565b8480fd5b5080fd5b50346104445780600319360112610444576020601e54604051908152f35b50346104445780600319360112610444576002546040516001600160a01b039091168152602090f35b5034610444576108df36613f13565b91906003811015610885576014019081548310156104445760206109038484613fe1565b90549060031b1c604051908152f35b50346104445760203660031901126104445760209060ff906040906001600160a01b0361093d613ebc565b168152602584522054166040519015158152f35b50346104445760203660031901126104445761096b613ead565b610973614b41565b61ff00601b5491151560081b169061ff00191617601b5580f35b6001826109e461099c36613ff9565b926109a8929192614b6a565b6109b0614b8c565b601154421015806109f0575b6109c5906141cc565b6109d0811515614210565b6109de600f5482111561425b565b33614c33565b55602060405160018152f35b506012544211156109bc565b5034610444576020366003190112610444576004356001600160401b03811161088557610a2d903690600401614038565b6003546001600160a01b031633148015610afa575b610a4b906145d2565b8015610ac157601a5483601a5580610a89575b50825b818110610a6c578380f35b80610a83610a7d600193858761438d565b35614a6a565b01610a61565b601a8452610abb907f057c384a7d1c54f3a1b2e5e67b2617b8224fdfd1ea7234eea573a6ff665ff63e908101906145bb565b38610a5e565b60405162461bcd60e51b815260206004820152601160248201527024b73b30b634b2103830b930b6b2ba32b960791b6044820152606490fd5b506001546001600160a01b03163314610a42565b50346104445780600319360112610444576020600e54604051908152f35b50346104445780600319360112610444576020601d54604051908152f35b50346104445760203660031901126104445760209060ff906040906001600160a01b03610b75613ebc565b168152602684522054166040519015158152f35b5034610444578060031936011261044457602060ff601b54166040519015158152f35b503461044457610bbb36614180565b9092610bc5614b41565b610bd660ff60015460a81c166142a6565b610be1828414614a1e565b845b838110610c605750610c0e90600160ff196020541617602055604051936040855260408501916148b5565b8281036020840152818152906001600160fb1b038111610881577f4053c3111bf4f54ff49c4fd2319edc66e2c70481c8aace4237e657bbe4f99eba93602092849260051b80928583013701030190a180f35b6001600160a01b03610c7b610c7683878661438d565b61439d565b168652602660205260ff604087205416610cfb5780610c9d600192858861438d565b35828060a01b03610cb2610c7684898861438d565b1688526021602052610cc9604089209182546144b8565b9055818060a01b03610cdf610c7683888761438d565b168752602660205260408720805460ff19168317905501610be3565b60405162461bcd60e51b815260206004820152602a60248201527f4465706f7369747320616c726561647920696d706f7274656420666f722074686044820152696973206164647265737360b01b6064820152608490fd5b50346104445780600319360112610444576020601754604051908152f35b50346104445760203660031901126104445760043590601a5482101561044457602061090383613fc6565b503461044457610dab36614180565b610db6939193614b41565b610dc1818414614a1e565b845b838110610dce578580f35b610dd981838761438d565b3590811515809203610e1d576001916001600160a01b03610dfe610c7684898961438d565b1688526026602052604088209060ff8019835416911617905501610dc3565b8680fd5b5034610444577f051425e088ef75da1d8905d9f9d688e5eb2e4102ffccb6466db812a4109ef3fc610ed9610e5436614113565b610e5f939193614b41565b8280610ee7575b8015610edf575b610e7690614614565b600680546001600160a01b0319166001600160a01b039590951694851790556007805460ff60a01b191693151560a081901b60ff60a01b169490941790556008819055604080519384526020840194909452928201929092529081906060820190565b0390a180f35b508215610e6d565b506001600160a01b0384161515610e66565b5034610444576020366003190112610444577f03843ff361861286e264d715d7e39e4f0d8babbee80357c8467b29fd6225a0c56020600435610f39614b41565b80600a55610f4681614704565b600b55604051908152a180f35b5034610444576020366003190112610444576004356003811015610fc7576014016040519181548084526020840192825260208220915b818110610fb157610fad85610fa181870382614068565b60405191829182614146565b0390f35b8254845260209093019260019283019201610f8a565b634e487b7160e01b82526032600452602482fd5b503461044457602036600319011261044457610ff5613ebc565b610ffd614b41565b600480546001600160a01b0319166001600160a01b03831690811790915560015460a81c60ff169081611098575b50611034575080f35b6002546001600160a01b0316908115611053576110509161512f565b80f35b60405162461bcd60e51b815260206004820152601d60248201527f53616c6520746f6b656e206e6f7420636f6e66696775726564207965740000006044820152606490fd5b905015153861102b565b50346104445760203660031901126104445760206110c16004356148f5565b604051908152f35b5034610444576020366003190112610444576004356110e6614b41565b8015611138577f836edba84bfb1c311fd21566a6d3adee8c90e9eb6aab4a862c54073d4c29191790600f549080600f55610ed96040519283924291846040919493926060820195825260208201520152565b60405162461bcd60e51b815260206004820152602b60248201527f4d617820746f6b656e7320746f20627579206d7573742062652067726561746560448201526a72207468616e207a65726f60a81b6064820152608490fd5b5034610444578060031936011261044457602060ff600d54166040519015158152f35b50346104445780600319360112610444576020601154604051908152f35b50346104445780600319360112610444576020601054604051908152f35b5034610444578060031936011261044457602060ff60075460a81c166040519015158152f35b503461044457602036600319011261044457611230613ebc565b611238614b41565b60018060a01b03166001600160601b0360a01b600254161760025580f35b5034610444578060031936011261044457604051601a8054808352908352909160208301917f057c384a7d1c54f3a1b2e5e67b2617b8224fdfd1ea7234eea573a6ff665ff63e915b8181106112b557610fad85610fa181870382614068565b825484526020909301926001928301920161129e565b5034610444578060031936011261044457602060ff601b5460081c166040519015158152f35b50346104445780600319360112610444576020600f54604051908152f35b503461044457806003193601126104445761016090816040516113328282614068565b369037601354801580156114705782905b1561143b57825b604051928584018481106001600160401b038211176114275760405261136f81613f29565b90549060031b1c845261138181613f90565b90549060031b1c602085015261139681613fab565b90549060031b1c60408501526113ae82601754614495565b6060850152608084015260145460a084015260c083015260e082015260125461010082015260275461012082015260205460ff161561141e579060ff60015b166101408301526040519190825b600b821061140857505050f35b60208060019285518152019301910190916113fb565b9060ff816113ed565b634e487b7160e01b86526041600452602486fd5b600019820182811161145c5761145090613f29565b90549060031b1c61134a565b634e487b7160e01b84526011600452602484fd5b600019820182811161145c5761148590613fab565b90549060031b1c90611343565b50346104445760203660031901126104445760043590601f5482101561044457601f548210156114d557602091601f825282822001549060031b1c604051908152f35b634e487b7160e01b81526032600452602490fd5b503461044457602036600319011261044457600435906027548210156114d557602781527f98a476f1687bc3d60a2da2adbcba2c46958e61fa2fb4042cd7bc5816a710195b9091015460405160039290921b1c6001600160a01b03168152602090f35b50346104445761155b36613f13565b90611564614b41565b8015801580916117a7575b1561176d5761167e575b5080611583575080f35b601254804211611639576011548211156115e457601282905560408051918252602082019290925242918101919091526211539160ea1b907f251662bca07d8017c5337e9e812f654ec6cbcca77df4aaac6211514eb35ceb4c90606090a280f35b60405162461bcd60e51b815260206004820152602760248201527f50726573616c6520656e64206d7573742062652061667465722070726573616c60448201526619481cdd185c9d60ca1b6064820152608490fd5b60405162461bcd60e51b815260206004820152601860248201527f50726573616c6520616c72656164792066696e697368656400000000000000006044820152606490fd5b6011548042101561172857814210156116e357601182905560408051918252602082019290925242918101919091526414d510549560da1b907f251662bca07d8017c5337e9e812f654ec6cbcca77df4aaac6211514eb35ceb4c90606090a238611579565b60405162461bcd60e51b815260206004820152601f60248201527f50726573616c65207374617274206d75737420626520696e20667574757265006044820152606490fd5b60405162461bcd60e51b815260206004820152601760248201527f50726573616c6520616c726561647920737461727465640000000000000000006044820152606490fd5b60405162461bcd60e51b8152602060048201526012602482015271496e76616c696420706172616d657465727360701b6044820152606490fd5b5082151561156f565b5034610444576020366003190112610444576004356001600160401b038111610885576117e1903690600401614038565b91906117eb614b41565b815b83811061182f57507f2e0232d6af885035fd9e51c8a3394424686b7064556dc33fefb82c976d0d4eae9192610ed96040519283926020845260208401916148b5565b6001906001600160a01b03611848610c7683888761438d565b168452602360205260408420805460ff191683179055016117ed565b503461044457806003193601126104445760206110c1614712565b50346104445780600319360112610444576001546040516001600160a01b039091168152602090f35b50346104445780600319360112610444576020601354604051908152f35b5034610444576020366003190112610444576004356001600160401b038111610885576118f7903690600401614038565b90611900614b41565b825b82811061190d578380f35b6001906001600160a01b03611926610c7683878761438d565b168552602360205260408520805460ff1916905501611902565b5034610444578060031936011261044457602060ff60075460a01c166040519015158152f35b503461044457806003193601126104445761197f614b41565b611987614b8c565b6001805460ff60a01b1916600160a01b1790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602090a180f35b50346104445780600319360112610444576020600854604051908152f35b5034610444576020366003190112610444576004356001600160401b03811161088557611a18903690600401614038565b90611a21614b41565b825b828110611a2e578380f35b6001906001600160a01b03611a47610c7683878761438d565b168552602460205260408520805460ff19168317905501611a23565b503461044457602036600319011261044457600435611a80614b41565b8015611ab8576020817fbd0fa37abdec0d9fb0895e44615fc5461e23843b08239fd36615e0a3dc3a856592600c55604051908152a180f35b60405162461bcd60e51b815260206004820152603260248201527f4e756d626572206f6620646179732070657220726f756e64206d7573742062656044820152712067726561746572207468616e207a65726f60701b6064820152608490fd5b50346104445780600319360112610444576020600954604051908152f35b50346104445780600319360112610444576005546040516001600160a01b039091168152602090f35b50346104445760203660031901126104445760209060ff906040906001600160a01b03611b8a613ebc565b168152602284522054166040519015158152f35b503461044457602036600319011261044457611bb8613ebc565b611bc0614b41565b6001600160a01b0316611bd4811515614614565b6001600160601b0360a01b600554161760055580f35b5034610444578060031936011261044457611c03614b41565b600180546001600160a01b0319811690915581906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b503461044457602036600319011261044457611c61613ebc565b611c69614b41565b6001600160a01b0316611c7d811515614614565b600380546001600160a01b031916821790557f54e4612788f90384e6843298d7854436f3a585b2c3831ab66abf1de63bfa6c2d8280a280f35b50346104445780600319360112610444576020601c54604051908152f35b50346104445760203660031901126104445760206110c1611d02611cf96004356148f5565b600b549061454d565b611d0a614712565b906144c5565b503461044457806003193601126104445760206110c1614652565b5034610444577f2f2f5c262547cb1fffcd5fd0bde6a83df558b3ba431dd4998d172de22fd15f96610ed9611d5e36614113565b611d69939193614b41565b8280611ddf575b8015611dd7575b611d8090614614565b60078054600161ff0160a01b0319166001600160a01b039590951694851793151560a881901b60ff60a81b169490941790556009819055604080519384526020840194909452928201929092529081906060820190565b508215611d77565b506001600160a01b0384161515611d70565b50346104445760203660031901126104445760043560018060a01b03600354163314801561210e575b611e23906145d2565b601354601454600019810190811161145c578110156120ad57601754611e4882613f29565b90549060031b1c10908115612093575b50801561208b575b1561204657601254811015611feb5760ff600d5416611f5e575b601754611e88601354613f29565b90549060031b1c11600014611f3757611ebc611eb7611ea8601354613f29565b90546017549160031b1c614495565b614a6a565b611ec7601754614ac3565b611ed2601354613f29565b90549060031b1c6017555b6013546000198114611f23577f1d41d2db921fa91b9381a24cedb839376c0f5e82c7822a79c6695666133b24dc916001604092016013558151908482526020820152a180f35b634e487b7160e01b83526011600452602483fd5b611f3f614a91565b611f59611f4d601354613f29565b90549060031b1c614ac3565b611edd565b60165491805b601354611f718186614495565b821015611fc457611f84600c548361454d565b6201518081029080820462015180149015171561145c5782916106d7611fb9600195611fb3611fbe958a6144b8565b936144b8565b613fab565b01611f64565b5050916000198101908111611f2357611fdc90613fab565b90549060031b1c601255611e7a565b60405162461bcd60e51b815260206004820152602d60248201527f43616e6e6f7420696e6372656d656e7420726f756e642061667465722070726560448201526c73616c6520656e642074696d6560981b6064820152608490fd5b60405162461bcd60e51b815260206004820152601860248201527f526f756e64206c696d697473206e6f74207265616368656400000000000000006044820152606490fd5b506001611e60565b61209d9150613fab565b90549060031b1c81101538611e58565b60405162461bcd60e51b815260206004820152603360248201527f4c61737420726f756e6420726561636865642c206974206973206e6f7420706f6044820152721cdcda589b19481d1bc81a5b98dc995b595b9d606a1b6064820152608490fd5b506001546001600160a01b03163314611e1a565b5034610444578060031936011261044457602060ff60015460a01c166040519015158152f35b503461044457602036600319011261044457612162613ead565b61216a614b41565b60ff8019601b54169115151617601b5580f35b5034610444576020366003190112610444576004356001600160401b038111610885576121ae903690600401614038565b906121b7614b41565b825b8281106121c4578380f35b6001906001600160a01b036121dd610c7683878761438d565b168552602460205260408520805460ff19169055016121b9565b5034610444578060031936011261044457612210614b6a565b612218614b8c565b61222960ff60015460a81c166142a6565b6002546001600160a01b03161561244c57338152602360205261225360ff604083205416156143fd565b601054421061240757338152602260205260ff6040822054166123d05760ff601b5416612377575b338152602260205260408120600160ff198254161790553381526021602052604081205490811561233f5733808252602160209081526040808420849055600254905163a9059cbb60e01b928101929092526024820192909252604480820185905281526001939161230191906001600160a01b03166122fc606483614068565b615754565b6040519081524260208201527f9923b4306c6c030f2bdfbf156517d5983b87e15b96176da122cd4f2effa4ba7b60403392a255602060405160018152f35b60405162461bcd60e51b815260206004820152601060248201526f4e6f7468696e6720746f20636c61696d60801b6044820152606490fd5b338152602460205260ff60408220541661227b5760405162461bcd60e51b815260206004820152601e60248201527f55736572206e6f742077686974656c697374656420666f7220636c61696d00006044820152606490fd5b60405162461bcd60e51b815260206004820152600f60248201526e105b1c9958591e4818db185a5b5959608a1b6044820152606490fd5b60405162461bcd60e51b815260206004820152601960248201527f436c61696d20686173206e6f74207374617274656420796574000000000000006044820152606490fd5b60405162461bcd60e51b815260206004820152601c60248201527f53616c6520746f6b656e206973206e6f7420636f6e66696775726564000000006044820152606490fd5b5034610444576020366003190112610444576004356001600160401b038111610885576124c2903690600401614038565b906124cb614b41565b825b8281106124d8578380f35b6001906001600160a01b036124f1610c7683878761438d565b168552602560205260408520805460ff191683179055016124cd565b503461044457602036600319011261044457612527613ead565b61252f614b41565b60ff8019600d54169115151617600d5580f35b5034610444576020366003190112610444576004356001600160401b0381116108855736602382011215610885576040519061257f606083614068565b60648101823682116108815782600401905b8282106126715785856125a2614b41565b60149082905b600382106125ea578360165460001981019081116125d6576125c990613fab565b90549060031b1c60125580f35b634e487b7160e01b82526011600452602482fd5b80518051906001600160401b03821161142757600160401b8211611427576020908554838755808410612654575b500184865260208620865b8381106126405750505050600160208192019301910190916125a8565b600190602084519401938184015501612623565b61266b9087600052848460002091820191016145bb565b87612618565b81356001600160401b038111610e1d576020916126958392600436918901016140b6565b815201910190612591565b50346104445780600319360112610444576126b9614b41565b60015460ff8160a01c16156127015760ff60a01b19166001556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa90602090a180f35b638dfc202b60e01b8252600482fd5b50346104445780600319360112610444576007546040516001600160a01b039091168152602090f35b5034610444576020366003190112610444576004359060409182805161275f8282614068565b369037601354601454600019810190811180612970578282036129b95761278583613f90565b90549060031b1c8411156129845761279f611ea884613f29565b6127b86127ab85613f90565b90549060031b1c866144c5565b906127c285613fab565b905460039190911b1c42106128c557505061145c578110156128825760018101809111611f2357906127f661280392613f90565b90549060031b1c906144c5565b612811600f5482111561425b565b8251908382018281106001600160401b0382111761286e57611d02611cf98695936128409387528086526148f5565b602083015282519190825b6002821061285857505050f35b602080600192855181520193019101909161284b565b634e487b7160e01b84526041600452602484fd5b6064845162461bcd60e51b815260206004820152602060248201527f5468652070726573616c652074696d657374616d70206861766520656e6465646044820152fd5b8181959492969350116128dc575b50505050612803565b61290d929394506128ee9084106144e5565b6129076128fa84613f90565b90549060031b1c8561454d565b90614495565b916001820192838311612970576129536129679361293f8694612939612959956127f66129479a613f90565b906144b8565b958691613f29565b90549060031b1c6144b8565b91613f29565b90549060031b1c1015614560565b388080806128d3565b634e487b7160e01b85526011600452602485fd5b855162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b6044820152606490fd5b600183018084116129cd5761278590613f90565b634e487b7160e01b86526011600452602486fd5b50346104445780600319360112610444576020600a54604051908152f35b50346104445760203660031901126104445760209060ff906040906001600160a01b03612a2a613ebc565b168152602484522054166040519015158152f35b5034610444578060031936011261044457612a57614b6a565b612a5f614b8c565b600454612a76906001600160a01b031615156143b1565b3381526023602052612a8f60ff604083205416156143fd565b60ff601b5460081c16612c11575b338152602160205260408120548015612bd95733825260216020528160408120556010544210600014612b74576004546001600160a01b0316803b15610865576040516348e30cb360e11b8152336004820152602481018390529083908290604490829084905af18015612b6957612b54575b50906001915b6040519081524260208201527fdd2a19c3bdd089cbe77c04f5655f83de0504d6140d12c8667646f55d0557c4dc60403392a255602060405160018152f35b612b5f838092614068565b6108855738612b10565b6040513d85823e3d90fd5b6004546001600160a01b0316803b15610865576040516311f9fbc960e21b8152336004820152602481018390529083908290604490829084905af18015612b6957612bc4575b5090600191612b16565b612bcf838092614068565b6108855738612bba565b60405162461bcd60e51b815260206004820152601060248201526f4e6f7468696e6720746f207374616b6560801b6044820152606490fd5b3381526024602052612c2960ff604083205416614449565b612a9d565b503461044457612c3d36613ff9565b93919092612c49614b6a565b612c51614b8c565b60ff60075460a81c1615612f605760115442101580612f54575b612c74906141cc565b612c7f811515614210565b612c8d600f5482111561425b565b6007546001600160a01b031693612ca3826148f5565b92612cb2600e54851015614bac565b612cbe83601c546144b8565b601c55612ccd836017546144b8565b80601755612cdd85601e546144b8565b601e5560135490612ced82613f29565b90549060031b1c10908115612f3a575b50612f2b575b15612eb0576004546001600160a01b031695612d208715156143b1565b60ff601b5460081c16612e93575b612d3a83601d546144b8565b601d55612d49600b548461454d565b873b15612e8f576040516348e30cb360e11b81523360048201526024810191909152959694959486908690604490829084905af18015612e8457908688949392612e65575b50612dd39550612db86000805160206157d0833981519152916040519182913395428a8086614bf8565b0390a45b611d0a612dce600a5460085490614495565b614704565b604051636eb1769f60e11b815233600482015230602482015292602090849060449082905afa928315612e5a578293612e20575b50600181612e1b82956109e494111561434a565b615471565b92506020833d602011612e52575b81612e3b60209383614068565b81010312612e4d579151916001612e07565b600080fd5b3d9150612e2e565b6040513d84823e3d90fd5b80929450612e7591939596614068565b61088157918591849386612d8e565b6040513d88823e3d90fd5b8580fd5b3385526024602052612eab60ff604087205416614449565b612d2e565b908495916000805160206157b0833981519152612f15612dd39697943389526021602052604089205415612f1d575b612eeb600b548661454d565b338a526021602052612f0260408b209182546144b8565b90556040519182913395428a8086614bf8565b0390a4612dbc565b612f2633614afc565b612edf565b612f3542846152b8565b612d03565b612f449150613fab565b90549060031b1c42101538612cfd565b50601254421115612c6b565b60405162461bcd60e51b815260206004820152602360248201527f5553444320636f6e747261637420666f756e64206f6e2074686973206e6574776044820152626f726b60e81b6064820152608490fd5b5034610444576020366003190112610444576004356001600160401b03811161088557612fe2903690600401614038565b90612feb614b41565b825b828110612ff8578380f35b6001906001600160a01b03613011610c7683878761438d565b168552602560205260408520805460ff1916905501612fed565b5034610444576020366003190112610444577f51cf07e612d83da8f12bd68a61b160a4a100189a4c3c8c0b1e859d8738739d15600435613069614b41565b600e549080600e55610ed96040519283924291846040919493926060820195825260208201520152565b5034610444576020366003190112610444576130ad613ead565b6130b5614b41565b60ff801960205416911515161760205580f35b50346104445780600319360112610444576006546040516001600160a01b039091168152602090f35b5034610444578060031936011261044457602060ff60015460a81c166040519015158152f35b5034610444578060031936011261044457602060ff8154166040519015158152f35b5034610444576020366003190112610444577f137c2e88b808cc3889ff5cc4e6f6c813f879579a4afe7573d003c67ebf6431f7600435613177614b41565b6131856012548210156142f2565b60105490806010556131af6040519283924291846040919493926060820195825260208201520152565b0390a1602060405160018152f35b5034610444576020366003190112610444576004359060195482101561044457602061090383613f75565b50346104445780600319360112610444576020601254604051908152f35b50346104445780600319360112610444576020600c54604051908152f35b50346104445760803660031901126104445761323e613ebc565b6024356001600160a01b03811691908290036108655760443590606435613263614b41565b61327460ff60015460a81c166142a6565b83156134945782156134405761328e6012548210156142f2565b60018060a01b03821690816001600160601b0360a01b6004541617600455601055836001600160601b0360a01b6002541617600255837fdc9670dbabdd488b372eb16ebe49a39b3124a12cdffdcefbc89834a408bf8ff860408051868152426020820152a2613430575b50604051636eb1769f60e11b8152336004820152306024820152602081604481865afa80156133ef57829085906133fa575b6133369250101561434a565b6040516370a0823160e01b8152336004820152602081602481865afa9081156133ef57829394916133ba575b5010613380576133759130903390615274565b602060405160018152f35b60405162461bcd60e51b8152602060048201526012602482015271084c2d8c2dcc6ca40dcdee840cadcdeeaced60731b6044820152606490fd5b9150506020813d6020116133e7575b816133d660209383614068565b81010312612e4d5781905138613362565b3d91506133c9565b6040513d86823e3d90fd5b50506020813d602011613428575b8161341560209383614068565b81010312612e4d5781613336915161332a565b3d9150613408565b61343a908361512f565b386132f8565b60405162461bcd60e51b815260206004820152602660248201527f546f6b656e20616d6f756e74206d7573742062652067726561746572207468616044820152656e207a65726f60d01b6064820152608490fd5b60405162461bcd60e51b815260206004820152601a60248201527f496e76616c69642073616c6520746f6b656e20616464726573730000000000006044820152606490fd5b50346104445780600319360112610444576004546040516001600160a01b039091168152602090f35b50346104445761351136613ff9565b9391909261351d614b6a565b613525614b8c565b60ff60075460a01c16156137b557601154421015806137a9575b613548906141cc565b613553811515614210565b613561600f5482111561425b565b6006546001600160a01b031693613577826148f5565b92613586600e54851015614bac565b61359283601c546144b8565b601c556135a1836017546144b8565b806017556135b185601e546144b8565b601e55601354906135c182613f29565b90549060031b1c1090811561378f575b50613780575b15613746576004546001600160a01b0316956135f48715156143b1565b60ff601b5460081c16613729575b61360e83601d546144b8565b601d5561361d600b548461454d565b873b15612e8f576040516348e30cb360e11b81523360048201526024810191909152959694959486908690604490829084905af18015612e845790868894939261370a575b5061368c9550612db86000805160206157d0833981519152916040519182913395428a8086614bf8565b604051636eb1769f60e11b815233600482015230602482015292602090849060449082905afa928315612e5a5782936136d5575b50600281612e1b6001956109e494111561434a565b92506020833d602011613702575b816136f060209383614068565b81010312612e4d5791519160026136c0565b3d91506136e3565b8092945061371a91939596614068565b61088157918591849386613662565b338552602460205261374160ff604087205416614449565b613602565b908495916000805160206157b0833981519152612f1561368c9697943389526021602052604089205415612f1d57612eeb600b548661454d565b61378a42846152b8565b6135d7565b6137999150613fab565b90549060031b1c421015386135d1565b5060125442111561353f565b60405162461bcd60e51b815260206004820152602360248201527f5553445420636f6e747261637420666f756e64206f6e2074686973206e6574776044820152626f726b60e81b6064820152608490fd5b5034610444576020366003190112610444576004359060185482101561044457602061383183613f5a565b905460405160039290921b1c6001600160a01b03168152f35b5034610444576020366003190112610444576020906040906001600160a01b03613872613ebc565b168152602183522054604051908152f35b50346104445761389236613f13565b61389a614b41565b60145482101561395157806138ae83613f29565b90549060031b1c11156138f657816040917f1c8f1847dfc445804fec63332d23742b97dd76eee45cc4212cc8f7534d59ddfa936013558060175582519182526020820152a180f35b60405162461bcd60e51b815260206004820152602d60248201527f436865636b706f696e742063616e6e6f7420626520677265617465722074686160448201526c1b881c9bdd5b99081d1bdd185b609a1b6064820152608490fd5b60405162461bcd60e51b815260206004820152600d60248201526c125b9d985b1a59081c9bdd5b99609a1b6044820152606490fd5b5060a03660031901126104445761399b613ebc565b906024356044358015158103610865576064359160038310948515610881576084356001600160401b038111612e8f576139d9903690600401613ee6565b9490966139e4614b6a565b6139ec614b8c565b60115442101580613e5f575b613a01906141cc565b613a0c841515614210565b613a1a600f5485111561425b565b338752602560205260ff60408820541615613e0557811587818015613df9575b818115613dd5575b5015613d9d57613d895715613a6257505091600195916109e49493614c33565b94919392909415613d755760028503613d63576006546001600160a01b0316965b613a8c826148f5565b93613a9b600e54861015614bac565b613aa783601c546144b8565b601c55613ab6836017546144b8565b80601755613ac686601e546144b8565b601e5560135490613ad682613f29565b90549060031b1c10908115613d49575b50613d3a575b15613caf576004546001600160a01b0316613b088115156143b1565b60ff601b5460081c16613c88575b613b2283601d546144b8565b601d55613b31600b548461454d565b813b15613c84576040516348e30cb360e11b81526001600160a01b038816600482015260248101919091529088908290604490829084905af18015613c7957613c54575b50604051613beb956020959094613bb79491936001600160a01b03808d1694908816926000805160206157d0833981519152928291612db891428a8086614bf8565b604051636eb1769f60e11b81526001600160a01b039092166004830152306024830152959092839190829081906044820190565b03916001600160a01b03165afa908115612b69578391613c1f575b509083612e1b613c1a93600196111561434a565b6109e4565b9190506020823d602011613c4c575b81613c3b60209383614068565b81010312612e4d5790516001613c06565b3d9150613c2e565b92613bb79288613c6c602097949a613beb9997614068565b9892955092509294613b75565b6040513d8a823e3d90fd5b8880fd5b6001600160a01b038616885260246020526040882054613caa9060ff16614449565b613b16565b92602093613bb792613beb96946000805160206157b083398151915260018060a01b03871691828c526021895260408c205415613d2c575b8b613d0a6040613cf9600b548861454d565b9286815260218d52209182546144b8565b90556040516001600160a01b038e169590918291612f159190428a8086614bf8565b613d3588614afc565b613ce7565b613d4442846152b8565b613aec565b613d539150613fab565b90549060031b1c42101538613ae6565b6007546001600160a01b031696613a83565b634e487b7160e01b86526021600452602486fd5b634e487b7160e01b88526021600452602488fd5b60405162461bcd60e51b815260206004820152601060248201526f14de5b589bdb081b9bdd08199bdd5b9960821b6044820152606490fd5b9050613de5576001841481613a42565b634e487b7160e01b89526021600452602489fd5b50508760028414613a3a565b60405162461bcd60e51b815260206004820152602c60248201527f41646472657373206e6f742077686974656c697374656420666f72207468697360448201526b103a3930b739b0b1ba34b7b760a11b6064820152608490fd5b506012544211156139f8565b503461044457602036600319011261044457613e85613ead565b613e8d614b41565b6001805460ff60a81b191691151560a81b60ff60a81b1691909117905580f35b600435908115158203612e4d57565b600435906001600160a01b0382168203612e4d57565b35906001600160a01b0382168203612e4d57565b9181601f84011215612e4d578235916001600160401b038311612e4d5760208381860195010111612e4d57565b6040906003190112612e4d576004359060243590565b601454811015613f4457601460005260206000200190600090565b634e487b7160e01b600052603260045260246000fd5b601854811015613f4457601860005260206000200190600090565b601954811015613f4457601960005260206000200190600090565b601554811015613f4457601560005260206000200190600090565b601654811015613f4457601660005260206000200190600090565b601a54811015613f4457601a60005260206000200190600090565b8054821015613f445760005260206000200190600090565b6060600319820112612e4d57600435916024358015158103612e4d5791604435906001600160401b038211612e4d5761403491600401613ee6565b9091565b9181601f84011215612e4d578235916001600160401b038311612e4d576020808501948460051b010111612e4d57565b90601f801991011681019081106001600160401b0382111761408957604052565b634e487b7160e01b600052604160045260246000fd5b6001600160401b0381116140895760051b60200190565b9080601f83011215612e4d5781356140cd8161409f565b926140db6040519485614068565b81845260208085019260051b820101928311612e4d57602001905b8282106141035750505090565b81358152602091820191016140f6565b6060906003190112612e4d576004358015158103612e4d57906024356001600160a01b0381168103612e4d579060443590565b602060408183019282815284518094520192019060005b81811061416a5750505090565b825184526020938401939092019160010161415d565b6040600319820112612e4d576004356001600160401b038111612e4d57816141aa91600401614038565b92909291602435906001600160401b038211612e4d5761403491600401614038565b156141d357565b60405162461bcd60e51b815260206004820152601560248201527413dd5d081bd9881c1c995cd85b19481c195c9a5bd9605a1b6044820152606490fd5b1561421757565b606460405162461bcd60e51b815260206004820152602060248201527f416d6f756e74206d7573742062652067726561746572207468616e207a65726f6044820152fd5b1561426257565b606460405162461bcd60e51b815260206004820152602060248201527f416d6f756e742065786365656473206d617820746f6b656e7320746f206275796044820152fd5b156142ad57565b60405162461bcd60e51b815260206004820152601c60248201527f54686973206973206e6f7420746865206d61696e206e6574776f726b000000006044820152606490fd5b156142f957565b60405162461bcd60e51b815260206004820152602360248201527f436c61696d206d7573742073746172742061667465722070726573616c6520656044820152626e647360e81b6064820152608490fd5b1561435157565b60405162461bcd60e51b81526020600482015260146024820152734e6f7420656e6f75676820616c6c6f77616e636560601b6044820152606490fd5b9190811015613f445760051b0190565b356001600160a01b0381168103612e4d5790565b156143b857565b60405162461bcd60e51b815260206004820152601e60248201527f5374616b696e67206d616e61676572206e6f7420636f6e6669677572656400006044820152606490fd5b1561440457565b60405162461bcd60e51b815260206004820152601b60248201527f54686973206164647265737320697320626c61636b6c697374656400000000006044820152606490fd5b1561445057565b60405162461bcd60e51b815260206004820152601e60248201527f55736572206e6f742077686974656c697374656420666f72207374616b6500006044820152606490fd5b919082039182116144a257565b634e487b7160e01b600052601160045260246000fd5b919082018092116144a257565b81156144cf570490565b634e487b7160e01b600052601260045260246000fd5b156144ec57565b60405162461bcd60e51b815260206004820152603360248201527f4c61737420726f756e642c206974206973206e6f7420706f737369626c6520746044820152726f206275792074686973207175616e7469747960681b6064820152608490fd5b818102929181159184041417156144a257565b1561456757565b60405162461bcd60e51b815260206004820152602660248201527f43616e206e6f7420627579207468697320616d6f756e7420696e20612073696e6044820152650ced8ca40e8f60d31b6064820152608490fd5b8181106145c6575050565b600081556001016145bb565b156145d957565b60405162461bcd60e51b815260206004820152601360248201527227b7363c9037bbb732b91037b91030b236b4b760691b6044820152606490fd5b1561461b57565b60405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b6044820152606490fd5b60135480156146dd5760009060005b81811061469a5750906129398261468a61467d61469795613f29565b90549060031b1c91613f90565b90549060031b1c9061454d565b90565b916146d66001916129396146cd6146b087613f29565b90549060031b1c6146c088613fc6565b90549060031b1c90614495565b61468a87613f90565b9201614661565b8061468a61467d61469793613f29565b519069ffffffffffffffffffff82168203612e4d57565b604d81116144a257600a0a90565b60055460405163313ce56760e01b81526001600160a01b0390911690602081600481855afa90811561482757600091614878575b5060ff1690600a54918281116148335760a060049260405193848092633fabe5a360e21b82525afa918215614827576000926147d8575b50600082131561479d57612dce6147979161469794614495565b9061454d565b60405162461bcd60e51b81526020600482015260136024820152724572726f722067657474696e6720707269636560681b6044820152606490fd5b90915060a0813d60a01161481f575b816147f460a09383614068565b81010312612e4d57614805816146ed565b506148176080602083015192016146ed565b50903861477d565b3d91506147e7565b6040513d6000823e3d90fd5b60405162461bcd60e51b815260206004820152601b60248201527f496e76616c69642061676772656761746f7220646563696d616c7300000000006044820152606490fd5b6020813d6020116148ad575b8161489160209383614068565b8101031261088557519060ff82168203610444575060ff614746565b3d9150614884565b9160209082815201919060005b8181106148cf5750505090565b909192602080600192838060a01b036148e788613ed2565b1681520194019291016148c2565b614903600f5482111561425b565b6017549061491182826144b8565b6013549061491e82613f29565b90549060031b1c108015614a05575b156149f75760145460001981019081116144a25761494c9082106144e5565b6149598261294783613f29565b90600181019384821192836144a2576149759061295987613f29565b61497e82613fab565b90549060031b1c42116000146149ac5750506144a2576149a061469792613f90565b90549060031b1c61454d565b61293992506149a06149ea6149e4846149dc614797956149d06146979b9a98613f29565b90549060031b1c614495565b938491613f90565b95613f90565b90549060031b1c92614495565b61469792506149a090613f90565b50614a0f81613fab565b90549060031b1c42101561492d565b15614a2557565b60405162461bcd60e51b815260206004820152601a60248201527f506172616d6574657273206c656e677468206d69736d617463680000000000006044820152606490fd5b601a5490600160401b821015614089576106d7826001614a8f9401601a55601a613fe1565b565b601a54600160401b81101561408957806001614ab29201601a55601a613fe1565b8154906000199060031b1b19169055565b601f5490600160401b821015614089576106d7826001614a8f9401601f55601f613fe1565b8051821015613f445760209160051b010190565b602754600160401b81101561408957806001614b1d92016027556027613fe1565b81546001600160a01b0393841660039290921b91821b9390911b1916919091179055565b6001546001600160a01b03163303614b5557565b63118cdaa760e01b6000523360045260246000fd5b600260005414614b7b576002600055565b633ee5aeb560e01b60005260046000fd5b60ff60015460a01c16614b9b57565b63d93c066560e01b60005260046000fd5b15614bb357565b60405162461bcd60e51b815260206004820152601a60248201527f5061796d656e74206c6f776572207468616e206d696e696d756d0000000000006044820152606490fd5b93909285939260a0969386526020860152604085015260806060850152816080850152848401376000828201840152601f01601f1916010190565b919290614c3f816148f5565b600b5495614c52611d026000988461454d565b938434106150f357614c68600e54841015614bac565b87614c738634614495565b97614c8086601c546144b8565b601c55614c8f866017546144b8565b80601755614c9f86601e546144b8565b601e5560135490614caf82613f29565b90549060031b1c109081156150d9575b506150ca575b1561504d57506004546001600160a01b0316614ce28115156143b1565b60ff601b5460081c16615026575b614cfc85601d546144b8565b601d55614d0b600b548661454d565b90803b15615022576040516348e30cb360e11b81526001600160a01b0389166004820152602481019290925289908290604490829084905af1801561501757614fef575b506040518894936001600160a01b038816936000805160206157d0833981519152938392614d8292919042908b86614bf8565b0390a45b6018548015614faa576019548103614f4757849085905b808210614ef4575050818110614eae575b505081614dba57505050565b814710614e5a57814710614e425782918291829182916001600160a01b03165af13d15614e3d573d6001600160401b038111614e295760405190614e08601f8201601f191660200183614068565b81528260203d92013e5b15614e1a5750565b63d6bda27560e01b8152600490fd5b634e487b7160e01b83526041600452602483fd5b614e12565b63cf47918160e01b8352476004526024829052604483fd5b60405162461bcd60e51b815260206004820152602660248201527f4d61696e206e6574776f726b2073796d626f6c2062616c616e6365206e6f74206044820152650cadcdeeaced60d31b6064820152608490fd5b60185460001981019081116129cd5791614ee78692614ecf614eed95613f5a565b905460039190911b1c6001600160a01b031692614495565b906154fb565b3880614dae565b9091614f3f6001916064614f17614f0a87613f75565b90549060031b1c8861454d565b0490614f3a8a83614f2789613f5a565b888060a01b0391549060031b1c166154fb565b6144b8565b920190614d9d565b60405162461bcd60e51b815260206004820152603560248201527f57726f6e6720636f6e66696775726174696f6e207061796d656e742061646472604482015274657373657320616e642070657263656e746167657360581b6064820152608490fd5b60405162461bcd60e51b815260206004820152601e60248201527f5061796d656e742061646472657373206e6f7420636f6e6669677572656400006044820152606490fd5b9761500d816000805160206157d0833981519152939695949a614068565b9791929390614d4f565b6040513d8b823e3d90fd5b8980fd5b6001600160a01b0387168952602460205260408920546150489060ff16614449565b614cf0565b9392906000805160206157b0833981519152916150b460018060a01b0389169485885260216020526040882054156150bc575b61508c600b548861454d565b86895260216020526150a360408a209182546144b8565b905560405193849342908b86614bf8565b0390a4614d86565b6150c58a614afc565b615080565b6150d442876152b8565b614cc5565b6150e39150613fab565b90549060031b1c42101538614cbf565b60405162461bcd60e51b8152602060048201526014602482015273125b9cdd59999a58da595b9d081c185e5b595b9d60621b6044820152606490fd5b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301529091908116602083604481845afa92831561482757600093615240575b5060001983018093116144a25760405163095ea7b360e01b60208083019182526001600160a01b03871660248401526044808401969096529482529093906000906151bb606487614068565b85519082865af1903d6000519083615221575b505050156151db57505050565b60405163095ea7b360e01b60208201526001600160a01b03909316602484015260006044808501919091528352614a8f926122fc9061521b606482614068565b82615754565b9192509061523657503b15155b3880806151ce565b600191501461522e565b90926020823d60201161526c575b8161525b60209383614068565b81010312610444575051913861516f565b3d915061524e565b6040516323b872dd60e01b60208201526001600160a01b039283166024820152929091166044830152606480830193909352918152614a8f916122fc608483614068565b60135460145460001981019081116144a2578110156120ad576017546152dd82613f29565b90549060031b1c10908115615457575b50801561544f575b1561204657601254821015611feb5760ff600d54166153c8575b60175461531d601354613f29565b90549060031b1c116000146153ad57615341611eb782614f3a611ea8601354613f29565b61535561535082601754614495565b614ac3565b61536481612947601354613f29565b6017555b6013549060001982146144a2577f1d41d2db921fa91b9381a24cedb839376c0f5e82c7822a79c6695666133b24dc9260016040930160135582519182526020820152a1565b6153b5614a91565b6153c3611f4d601354613f29565b615368565b906016549260005b601354906153de8287614495565b811015615425576153f1600c548261454d565b620151808102908082046201518014901517156144a2576001926106d7611fb984611fb361541f958a6144b8565b016153d0565b50509291909160001981019081116144a25761544090613fab565b90549060031b1c60125561530f565b5080156152f5565b6154619150613fab565b90549060031b1c821015386152ed565b90601854918215614faa576019548303614f47576000926000905b8082106154c05750508083106154a157505050565b60185460001981019081116144a257614a8f93614ecf614ee792613f5a565b90936154f360019160646154e36154d689613f75565b90549060031b1c8761454d565b0490614f3a8783614f278b613f5a565b94019061548c565b91600381101561573e578061559c575090814710614e5a57814710615583576000918291829182916001600160a01b03165af13d1561557e573d6001600160401b038111614089576040519061555b601f8201601f191660200183614068565b8152600060203d92013e5b1561556d57565b63d6bda27560e01b60005260046000fd5b615566565b504763cf47918160e01b60005260045260245260446000fd5b6002810361566c57506006546040516370a0823160e01b81523360048201526001600160a01b039091169290602081602481875afa8015614827578391600091615637575b50106155f257614a8f923390615274565b60405162461bcd60e51b815260206004820152601760248201527f555344542062616c616e6365206e6f7420656e6f7567680000000000000000006044820152606490fd5b9150506020813d602011615664575b8161565360209383614068565b81010312612e4d57829051386155e1565b3d9150615646565b600114615677575050565b6007546040516370a0823160e01b81523360048201526001600160a01b039091169290602081602481875afa8015614827578391600091615709575b50106156c457614a8f923390615274565b60405162461bcd60e51b815260206004820152601760248201527f555344432062616c616e6365206e6f7420656e6f7567680000000000000000006044820152606490fd5b9150506020813d602011615736575b8161572560209383614068565b81010312612e4d57829051386156b3565b3d9150615718565b634e487b7160e01b600052602160045260246000fd5b906000602091828151910182855af115614827576000513d6157a657506001600160a01b0381163b155b6157855750565b635274afe760e01b60009081526001600160a01b0391909116600452602490fd5b6001141561577e56fe669f5b3ea5a6185ec3bb56d247002f736893c205f65ece2330c4f7ca599e52574c56565e3fd9d98d897a1354c44260050e5ed40878076114deae8e6330a88c34a2646970667358221220a66cbd215ed508831e938fab946bdf8d9a3e2330197c722a871f98217e8a4b3f64736f6c634300081a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000001ebd3797f82155710cbd8267a4bf485658f183d00000000000000000000000005f4ec3df9cbd43714fe2740f5e3616155c5b8419000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000004c4b400000000000000000000000000000000000000000000000000000000067a0afc000000000000000000000000000000000000000000000000000000000682b1d40000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000aa00000000000000000000000000000000000000000000000000000000000000ae00000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000005a0000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000009896800000000000000000000000000000000000000000000000000000000001312d000000000000000000000000000000000000000000000000000000000001c9c3800000000000000000000000000000000000000000000000000000000002625a000000000000000000000000000000000000000000000000000000000002faf080000000000000000000000000000000000000000000000000000000000393870000000000000000000000000000000000000000000000000000000000042c1d800000000000000000000000000000000000000000000000000000000004c4b40000000000000000000000000000000000000000000000000000000000055d4a800000000000000000000000000000000000000000000000000000000005f5e10000000000000000000000000000000000000000000000000000000000068e77800000000000000000000000000000000000000000000000000000000007270e000000000000000000000000000000000000000000000000000000000007bfa4800000000000000000000000000000000000000000000000000000000008583b000000000000000000000000000000000000000000000000000000000008f0d1800000000000000000000000000000000000000000000000000000000009896800000000000000000000000000000000000000000000000000000000000a21fe80000000000000000000000000000000000000000000000000000000000aba9500000000000000000000000000000000000000000000000000000000000b532b80000000000000000000000000000000000000000000000000000000000bebc200000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000b1a2bc2ec5000000000000000000000000000000000000000000000000000000b6139a7cbd200000000000000000000000000000000000000000000000000000ba8478cab5400000000000000000000000000000000000000000000000000000bef55718ad600000000000000000000000000000000000000000000000000000c3663566a5800000000000000000000000000000000000000000000000000000c7d713b49da00000000000000000000000000000000000000000000000000000cc47f20295c00000000000000000000000000000000000000000000000000000d0b8d0508de00000000000000000000000000000000000000000000000000000d529ae9e86000000000000000000000000000000000000000000000000000000d99a8cec7e200000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000e27c49886e600000000000000000000000000000000000000000000000000000e6ed27d666800000000000000000000000000000000000000000000000000000eb5e06245ea00000000000000000000000000000000000000000000000000000efcee47256c00000000000000000000000000000000000000000000000000000f43fc2c04ee00000000000000000000000000000000000000000000000000000f8b0a10e47000000000000000000000000000000000000000000000000000000fd217f5c3f20000000000000000000000000000000000000000000000000000101925daa3740000000000000000000000000000000000000000000000000000106033bf82f600000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000067ae08f00000000000000000000000000000000000000000000000000000000067b4a0700000000000000000000000000000000000000000000000000000000067bb37f00000000000000000000000000000000000000000000000000000000067c1cf700000000000000000000000000000000000000000000000000000000067c866f00000000000000000000000000000000000000000000000000000000067cefe700000000000000000000000000000000000000000000000000000000067d595f00000000000000000000000000000000000000000000000000000000067dc2d700000000000000000000000000000000000000000000000000000000067e2c4f00000000000000000000000000000000000000000000000000000000067e95c700000000000000000000000000000000000000000000000000000000067eff3f00000000000000000000000000000000000000000000000000000000067f68b700000000000000000000000000000000000000000000000000000000067fd22f0000000000000000000000000000000000000000000000000000000006803ba7000000000000000000000000000000000000000000000000000000000680a51f0000000000000000000000000000000000000000000000000000000006810e97000000000000000000000000000000000000000000000000000000000681780f000000000000000000000000000000000000000000000000000000000681e1870000000000000000000000000000000000000000000000000000000006824aff000000000000000000000000000000000000000000000000000000000682b47700000000000000000000000000000000000000000000000000000000000000001000000000000000000000000c94f39ecb6af81560bc431df6592683a4e793f2100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000064
-----Decoded View---------------
Arg [0] : _constructor (tuple):
Arg [1] : cIsMainNetwork (bool): True
Arg [2] : cAdmin (address): 0x1ebd3797f82155710cBd8267A4Bf485658f183d0
Arg [3] : cPriceFeed (address): 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419
Arg [4] : cUsdt (address): 0xdAC17F958D2ee523a2206206994597C13D831ec7
Arg [5] : cUsdc (address): 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
Arg [6] : cUsdtFound (bool): True
Arg [7] : cUsdcFound (bool): True
Arg [8] : cUsdtDecimals (uint256): 6
Arg [9] : cUsdcDecimals (uint256): 6
Arg [10] : cDaysPerRound (uint256): 5
Arg [11] : cUpdateRoundTimeAutomaticallyFlag (bool): True
Arg [12] : cMinBuyInDolar (uint256): 1
Arg [13] : cMaxTokensToBuy (uint256): 5000000
Arg [14] : cPresaleStartTime (uint256): 1738584000
Arg [15] : cPresaleEndTime (uint256): 1747656000
Arg [16] : cTokenDecimals (uint256): 18
Arg [17] : cRounds (uint256[][3]): System.Collections.Generic.List`1[System.Numerics.BigInteger],System.Collections.Generic.List`1[System.Numerics.BigInteger],System.Collections.Generic.List`1[System.Numerics.BigInteger]
Arg [18] : cAddressPayment (address[]): 0xC94f39eCb6AF81560bC431DF6592683A4E793f21
Arg [19] : cAddressPercentage (uint256[]): 100
-----Encoded View---------------
90 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000020
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [2] : 0000000000000000000000001ebd3797f82155710cbd8267a4bf485658f183d0
Arg [3] : 0000000000000000000000005f4ec3df9cbd43714fe2740f5e3616155c5b8419
Arg [4] : 000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7
Arg [5] : 000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [10] : 0000000000000000000000000000000000000000000000000000000000000005
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [12] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [13] : 00000000000000000000000000000000000000000000000000000000004c4b40
Arg [14] : 0000000000000000000000000000000000000000000000000000000067a0afc0
Arg [15] : 00000000000000000000000000000000000000000000000000000000682b1d40
Arg [16] : 0000000000000000000000000000000000000000000000000000000000000012
Arg [17] : 0000000000000000000000000000000000000000000000000000000000000260
Arg [18] : 0000000000000000000000000000000000000000000000000000000000000aa0
Arg [19] : 0000000000000000000000000000000000000000000000000000000000000ae0
Arg [20] : 0000000000000000000000000000000000000000000000000000000000000060
Arg [21] : 0000000000000000000000000000000000000000000000000000000000000300
Arg [22] : 00000000000000000000000000000000000000000000000000000000000005a0
Arg [23] : 0000000000000000000000000000000000000000000000000000000000000014
Arg [24] : 0000000000000000000000000000000000000000000000000000000000989680
Arg [25] : 0000000000000000000000000000000000000000000000000000000001312d00
Arg [26] : 0000000000000000000000000000000000000000000000000000000001c9c380
Arg [27] : 0000000000000000000000000000000000000000000000000000000002625a00
Arg [28] : 0000000000000000000000000000000000000000000000000000000002faf080
Arg [29] : 0000000000000000000000000000000000000000000000000000000003938700
Arg [30] : 00000000000000000000000000000000000000000000000000000000042c1d80
Arg [31] : 0000000000000000000000000000000000000000000000000000000004c4b400
Arg [32] : 00000000000000000000000000000000000000000000000000000000055d4a80
Arg [33] : 0000000000000000000000000000000000000000000000000000000005f5e100
Arg [34] : 00000000000000000000000000000000000000000000000000000000068e7780
Arg [35] : 0000000000000000000000000000000000000000000000000000000007270e00
Arg [36] : 0000000000000000000000000000000000000000000000000000000007bfa480
Arg [37] : 0000000000000000000000000000000000000000000000000000000008583b00
Arg [38] : 0000000000000000000000000000000000000000000000000000000008f0d180
Arg [39] : 0000000000000000000000000000000000000000000000000000000009896800
Arg [40] : 000000000000000000000000000000000000000000000000000000000a21fe80
Arg [41] : 000000000000000000000000000000000000000000000000000000000aba9500
Arg [42] : 000000000000000000000000000000000000000000000000000000000b532b80
Arg [43] : 000000000000000000000000000000000000000000000000000000000bebc200
Arg [44] : 0000000000000000000000000000000000000000000000000000000000000014
Arg [45] : 00000000000000000000000000000000000000000000000000b1a2bc2ec50000
Arg [46] : 00000000000000000000000000000000000000000000000000b6139a7cbd2000
Arg [47] : 00000000000000000000000000000000000000000000000000ba8478cab54000
Arg [48] : 00000000000000000000000000000000000000000000000000bef55718ad6000
Arg [49] : 00000000000000000000000000000000000000000000000000c3663566a58000
Arg [50] : 00000000000000000000000000000000000000000000000000c7d713b49da000
Arg [51] : 00000000000000000000000000000000000000000000000000cc47f20295c000
Arg [52] : 00000000000000000000000000000000000000000000000000d0b8d0508de000
Arg [53] : 00000000000000000000000000000000000000000000000000d529ae9e860000
Arg [54] : 00000000000000000000000000000000000000000000000000d99a8cec7e2000
Arg [55] : 00000000000000000000000000000000000000000000000000de0b6b3a764000
Arg [56] : 00000000000000000000000000000000000000000000000000e27c49886e6000
Arg [57] : 00000000000000000000000000000000000000000000000000e6ed27d6668000
Arg [58] : 00000000000000000000000000000000000000000000000000eb5e06245ea000
Arg [59] : 00000000000000000000000000000000000000000000000000efcee47256c000
Arg [60] : 00000000000000000000000000000000000000000000000000f43fc2c04ee000
Arg [61] : 00000000000000000000000000000000000000000000000000f8b0a10e470000
Arg [62] : 00000000000000000000000000000000000000000000000000fd217f5c3f2000
Arg [63] : 0000000000000000000000000000000000000000000000000101925daa374000
Arg [64] : 0000000000000000000000000000000000000000000000000106033bf82f6000
Arg [65] : 0000000000000000000000000000000000000000000000000000000000000014
Arg [66] : 0000000000000000000000000000000000000000000000000000000067ae08f0
Arg [67] : 0000000000000000000000000000000000000000000000000000000067b4a070
Arg [68] : 0000000000000000000000000000000000000000000000000000000067bb37f0
Arg [69] : 0000000000000000000000000000000000000000000000000000000067c1cf70
Arg [70] : 0000000000000000000000000000000000000000000000000000000067c866f0
Arg [71] : 0000000000000000000000000000000000000000000000000000000067cefe70
Arg [72] : 0000000000000000000000000000000000000000000000000000000067d595f0
Arg [73] : 0000000000000000000000000000000000000000000000000000000067dc2d70
Arg [74] : 0000000000000000000000000000000000000000000000000000000067e2c4f0
Arg [75] : 0000000000000000000000000000000000000000000000000000000067e95c70
Arg [76] : 0000000000000000000000000000000000000000000000000000000067eff3f0
Arg [77] : 0000000000000000000000000000000000000000000000000000000067f68b70
Arg [78] : 0000000000000000000000000000000000000000000000000000000067fd22f0
Arg [79] : 000000000000000000000000000000000000000000000000000000006803ba70
Arg [80] : 00000000000000000000000000000000000000000000000000000000680a51f0
Arg [81] : 000000000000000000000000000000000000000000000000000000006810e970
Arg [82] : 00000000000000000000000000000000000000000000000000000000681780f0
Arg [83] : 00000000000000000000000000000000000000000000000000000000681e1870
Arg [84] : 000000000000000000000000000000000000000000000000000000006824aff0
Arg [85] : 00000000000000000000000000000000000000000000000000000000682b4770
Arg [86] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [87] : 000000000000000000000000c94f39ecb6af81560bc431df6592683a4e793f21
Arg [88] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [89] : 0000000000000000000000000000000000000000000000000000000000000064
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 34 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.