More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 1,665 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Buy | 2462918 | 1 hr ago | IN | 45 S | 0.00014131 | ||||
Buy | 2462151 | 2 hrs ago | IN | 300 S | 0.00014133 | ||||
Buy | 2460781 | 2 hrs ago | IN | 430 S | 0.0001458 | ||||
Buy | 2460695 | 2 hrs ago | IN | 290 S | 0.00014498 | ||||
Buy | 2458945 | 3 hrs ago | IN | 50 S | 0.00011135 | ||||
Buy | 2458680 | 3 hrs ago | IN | 7 S | 0.00012483 | ||||
Buy | 2457426 | 3 hrs ago | IN | 60 S | 0.00014999 | ||||
Buy | 2456134 | 3 hrs ago | IN | 30 S | 0.0001413 | ||||
Sell | 2455740 | 3 hrs ago | IN | 0 S | 0.00029187 | ||||
Buy | 2455672 | 3 hrs ago | IN | 5 S | 0.0003265 | ||||
Buy | 2455520 | 4 hrs ago | IN | 450 S | 0.00034635 | ||||
Buy | 2455252 | 4 hrs ago | IN | 680 S | 0.0001458 | ||||
Buy | 2441832 | 7 hrs ago | IN | 50 S | 0.00011138 | ||||
Sell | 2431697 | 10 hrs ago | IN | 0 S | 0.00005164 | ||||
Sell | 2431696 | 10 hrs ago | IN | 0 S | 0.00013899 | ||||
Buy | 2431631 | 10 hrs ago | IN | 10 S | 0.00014367 | ||||
Sell | 2431581 | 10 hrs ago | IN | 0 S | 0.00013899 | ||||
Create Token | 2431551 | 10 hrs ago | IN | 11 S | 0.00092068 | ||||
Sell | 2431476 | 10 hrs ago | IN | 0 S | 0.00013899 | ||||
Buy | 2431449 | 10 hrs ago | IN | 10 S | 0.00014367 | ||||
Sell | 2431424 | 10 hrs ago | IN | 0 S | 0.00005165 | ||||
Sell | 2431420 | 10 hrs ago | IN | 0 S | 0.00013901 | ||||
Create Token | 2431372 | 10 hrs ago | IN | 11 S | 0.00092071 | ||||
Sell | 2428708 | 11 hrs ago | IN | 0 S | 0.00013899 | ||||
Buy | 2428645 | 11 hrs ago | IN | 10 S | 0.00014368 |
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
2455740 | 3 hrs ago | 4.9005 S | ||||
2431696 | 10 hrs ago | 9.79199422 S | ||||
2431581 | 10 hrs ago | 9.79993582 S | ||||
2431551 | 10 hrs ago | Contract Creation | 0 S | |||
2431476 | 10 hrs ago | 9.77770014 S | ||||
2431420 | 10 hrs ago | 9.79960492 S | ||||
2431372 | 10 hrs ago | Contract Creation | 0 S | |||
2428708 | 11 hrs ago | 9.78405262 S | ||||
2428611 | 11 hrs ago | 9.80075034 S | ||||
2428558 | 11 hrs ago | Contract Creation | 0 S | |||
2428026 | 11 hrs ago | 9.79199422 S | ||||
2427814 | 11 hrs ago | 9.79993582 S | ||||
2427764 | 11 hrs ago | Contract Creation | 0 S | |||
2397480 | 17 hrs ago | 9.801 S | ||||
2379316 | 20 hrs ago | 4.9005 S | ||||
2375749 | 21 hrs ago | 14.7015 S | ||||
2336020 | 29 hrs ago | 9.77770014 S | ||||
2335915 | 29 hrs ago | 9.79842313 S | ||||
2335836 | 29 hrs ago | Contract Creation | 0 S | |||
2335456 | 29 hrs ago | 9.79993582 S | ||||
2335358 | 29 hrs ago | 9.79993582 S | ||||
2335271 | 29 hrs ago | Contract Creation | 0 S | |||
2334854 | 29 hrs ago | 9.80099335 S | ||||
2334544 | 29 hrs ago | 9.76816942 S | ||||
2334320 | 29 hrs ago | Contract Creation | 0 S |
Loading...
Loading
Contract Name:
BellumFactory
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; import "@openzeppelin/contracts/utils/Address.sol"; import "contracts/BellumToken.sol"; import "contracts/BellumNursery.sol"; import "contracts/interfaces/IOwnable.sol"; import "contracts/metropolis/interfaces/IMetropolisRouter.sol"; import "contracts/metropolis/interfaces/IMetropolisFactory.sol"; pragma solidity ^0.8.17; contract BellumFactory is Ownable, ReentrancyGuard { using Address for address payable; using SafeERC20 for IERC20; // Ecosystem Info bool private isPaused; address payable public feeReceiver; uint256 public migrationFee; uint256 public pendingFees; uint256 public tradingFee; uint256 public createFee; uint256 public percentPerEpoch; // Addresses address payable public immutable METROPOLIS_ROUTER; // Constants uint256 private constant ETHER = 1 ether; uint256 private constant BIN_WIDTH = 2000; uint256 private constant BASIS = 10000; uint256 private constant COEF = 2; uint256 private constant MIN_IN = 1 ether; uint256 private constant MIN_OUT = 0.2 ether; struct Curve { uint256[] distribution; uint256 percentOfLP; // 5000 = 50% uint256 avaxAtLaunch; } struct Token { address creator; uint8 curveIndex; uint256 currentIndex; uint256 currentValue; uint256 initialSupply; bool hasLaunched; Dex dex; } enum Dex { METROPOLIS } address[] public allTokens; mapping(address => Token) public tokens; mapping(uint8 => Curve) public curves; mapping(address => address) public tokenToNursery; event TokenCreated( address indexed token, address indexed creator, uint curveIndex, uint dex ); event CurveCreated( uint indexed curveIndex ); event BellumSwap( address indexed token, address indexed sender, uint amount0In, uint amount0Out, uint amount1In, uint amount1Out ); event CurveCompleted( address indexed token, address indexed nursery, address indexed pair ); constructor(address owner_, address metropolisRouter_) Ownable(owner_) { require(owner_ != address(0), "Zero address not allowed for owner"); require(metropolisRouter_ != address(0), "Zero address not allowed for router"); tradingFee = 100; // 1% migrationFee = 400; createFee = 1 ether; METROPOLIS_ROUTER = payable(metropolisRouter_); feeReceiver = payable(owner_); percentPerEpoch = 25; } function createToken( string memory name_, string memory symbol_, uint112 totalSupply_, uint8 curveIndex_, Dex dex ) external payable nonReentrant { Curve memory curve = curves[curveIndex_]; uint256 percent = curve.percentOfLP; uint256[] memory arr = curve.distribution; uint256 createFee_ = createFee; require(!isPaused, "Bellum: TOKEN_CREATION_IS_PAUSED"); require(percent != 0, "Bellum: CURVE_DOES_NOT_EXIST"); require(totalSupply_ >= 1 ether, "Bellum: TOTAL_SUPPLY_TOO_LOW"); require(msg.value <= 500 ether + createFee_, "Bellum: TOO_MUCH_ETH"); require(msg.value >= createFee_, "Bellum: TOO_LITTLE_ETH"); BellumToken token = new BellumToken(name_, symbol_, totalSupply_); address t = address(token); allTokens.push(t); uint256 supply = uint256(totalSupply_ * percent / BASIS); tokens[t].initialSupply = supply; tokens[t].currentValue = supply * arr[0] / BASIS; tokens[t].curveIndex = curveIndex_; tokens[t].creator = msg.sender; tokens[t].dex = dex; emit TokenCreated(t, msg.sender, curveIndex_, uint256(dex)); pendingFees += createFee_; if (msg.value != createFee_) { _buy(t, msg.sender, msg.value - createFee_, 0); } } function createCurve(uint8 index, uint256[] memory lists) external onlyOwner { require(curves[index].percentOfLP == 0, "Bellum: CURVE_ALREADY_IN_USE"); uint256 totalDistribution = 0; // Amount of AVAX uint256 cumulativeValue = 0; uint256 length = lists.length; // Calculate the cumulative value and track the last non-zero bin for (uint256 i = 0; i < length; ++i) { require(lists[i] != 0, "Bellum: INVALID_BIN"); totalDistribution += lists[i]; uint256 price = ETHER * (BASIS + (i * BIN_WIDTH)) / BASIS; cumulativeValue += lists[i] * price; } // Ensure the total distribution equals 10,000 (in basis points) require(totalDistribution == BASIS, "Bellum: INVALID_TOTAL_DISTRIBUTION"); // Calculate the price for the last non-zero bin uint256 lastNonZeroPrice = ETHER * (((length - 1) * BIN_WIDTH) + BASIS) / BASIS; // Calculate the required market cap based on the last non-zero bin value and total tokens uint256 requiredMarketCap = BASIS * lastNonZeroPrice; uint256 fraction = BASIS * requiredMarketCap / (requiredMarketCap + cumulativeValue); curves[index] = Curve(lists, fraction, cumulativeValue / COEF); emit CurveCreated(index); } function sell(address token, uint256 amount0In, uint256 amount1OutMin) external nonReentrant{ Token storage t = tokens[token]; require(t.initialSupply != 0, "Bellum: TOKEN_DOES_NOT_EXIST"); require(!t.hasLaunched, "Bellum: INSUFFICIENT_LIQUIDITY"); IERC20(token).safeTransferFrom(msg.sender, address(this), amount0In); uint256[] memory arr = curves[t.curveIndex].distribution; uint256 amount1Out; uint256 amount0Used; uint256 i = t.currentIndex; uint256 currentValue = t.currentValue; uint256 initialSupply = t.initialSupply; while (amount0Used < amount0In) { uint256 amountPerAVAX = initialSupply * COEF / (BASIS + (BIN_WIDTH * i)); uint256 amount0Remaining = amount0In - amount0Used; uint256 amount0InBin = currentValue; uint256 amount0InBinMax = arr[i] * initialSupply / BASIS; if (amount0InBin + amount0Remaining <= amount0InBinMax) { amount1Out += amount0Remaining * ETHER / amountPerAVAX; currentValue += amount0Remaining; break; } else { uint256 fillBin = amount0InBinMax - amount0InBin; amount0Used += fillBin; amount1Out += fillBin * ETHER / amountPerAVAX; i--; currentValue = 0; } } require(amount1OutMin <= amount1Out, "Bellum: SLIPPAGE_LIMIT"); require(amount1Out >= MIN_OUT, "Bellum: INSUFFICIENT_ETH_OUT"); t.currentIndex = i; t.currentValue = currentValue; uint256 fee = amount1Out * tradingFee / BASIS; pendingFees += fee; payable(msg.sender).sendValue(amount1Out - fee); emit BellumSwap(token, msg.sender, amount0In, 0, 0, amount1Out); } function buy(address token, uint256 amount0OutMin) external payable nonReentrant { require(msg.value >= MIN_IN, "Bellum: TOO_LOW"); _buy(token, msg.sender, msg.value, amount0OutMin); } function _buy(address token, address sender, uint256 amount1In, uint256 amount0OutMin) internal { Token storage t = tokens[token]; require(t.initialSupply != 0, "Bellum: TOKEN_DOES_NOT_EXIST"); require(!t.hasLaunched, "Bellum: ALREADY_LAUNCHED"); uint256[] memory arr = curves[t.curveIndex].distribution; uint256 fee = amount1In * tradingFee / BASIS; uint256 value = amount1In - fee; uint256 amount0Out; uint256 amount1Used; uint256 i = t.currentIndex; uint256 currentValue = t.currentValue; uint256 initialSupply = t.initialSupply; while (amount1Used < value) { uint256 amountPerAVAX = initialSupply * COEF / (BASIS + (BIN_WIDTH * i)); uint256 valueLeft = value - amount1Used; uint256 amount0InBin = currentValue; if (amount0InBin > valueLeft * amountPerAVAX / ETHER) { uint256 outputAmount = amountPerAVAX * valueLeft / ETHER; amount1Used += valueLeft; amount0Out += outputAmount; currentValue = amount0InBin - outputAmount; break; } else { amount1Used += amount0InBin * ETHER / amountPerAVAX; amount0Out += amount0InBin; ++i; if (i < arr.length) { currentValue = arr[i] * initialSupply / BASIS; } else { break; } } } require(amount0OutMin <= amount0Out, "Bellum: SLIPPAGE_LIMIT"); t.currentIndex = i; t.currentValue = currentValue; pendingFees += fee; IERC20(token).safeTransfer(sender, amount0Out); emit BellumSwap(token, sender, 0, amount0Out, amount1In, 0); if (i >= arr.length) { payable(sender).sendValue(value - amount1Used); _launchToken(token); } } function _launchToken(address token) internal { require(!tokens[token].hasLaunched, "Bellum: ALREADY_LAUNCHED"); // Allow Transfers IOwnable(token).renounceOwnership(); uint256 balance = IERC20(token).balanceOf(address(this)); uint256 avaxToLP = curves[tokens[token].curveIndex].avaxAtLaunch; uint256 fee = avaxToLP * migrationFee / BASIS; if (fee != 0) { pendingFees += fee; } address pair; address nursery; IERC20(token).safeIncreaseAllowance(METROPOLIS_ROUTER, balance); // Create pair IMetropolisRouter MetropolisRouter = IMetropolisRouter(METROPOLIS_ROUTER); address metropolisFactory = MetropolisRouter.factory(); address weth = MetropolisRouter.WETH(); pair = IMetropolisFactory(metropolisFactory).getPair(token, weth); if (pair == address(0)) { pair = IMetropolisFactory(metropolisFactory).createPair(token, weth); } BellumNursery Nursery = new BellumNursery(token, pair, percentPerEpoch); nursery = address(Nursery); MetropolisRouter.addLiquidityETH{value: avaxToLP - fee}( token, balance, 0, // slippage is unavoidable 0, // slippage is unavoidable nursery, block.timestamp ); tokenToNursery[token] = nursery; tokens[token].hasLaunched = true; emit CurveCompleted(token, nursery, pair); } function allTokensLength() external view returns (uint) { return allTokens.length; } // Owner function changeFeeReceiver(address payable feeReceiver_) external onlyOwner { feeReceiver = feeReceiver_; } function changeFee(uint256 newFee_) external onlyOwner { require(newFee_ <= 250, "Bellum: FEE_TOO_HIGH"); tradingFee = newFee_; } function setIsPaused(bool isPaused_) external onlyOwner { isPaused = isPaused_; } function setMigrationFee(uint256 migrationFee_) external onlyOwner { require(migrationFee_ <= 1000, "Bellum: MIGRATION_FEE_TOO_HIGH"); migrationFee = migrationFee_; } function setPercentPerEpoch(uint256 percentPerEpoch_) external onlyOwner { require(percentPerEpoch_ <= 50, "Bellum: PERCENT_TOO_HIGH"); require(percentPerEpoch_ >= 10, "Bellum: PERCENT_TOO_LOW"); percentPerEpoch = percentPerEpoch_; } function setCreateFee(uint256 createFee_) external onlyOwner { require(createFee_ <= 50 ether, "Bellum: FEE_TOO_HIGH"); createFee = createFee_; } // Separate fee collection function function collectFees() external { uint256 amount = pendingFees; require(amount != 0, "No fees to collect"); pendingFees = 0; feeReceiver.sendValue(amount); } }
// 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.1.0) (interfaces/draft-IERC6093.sol) pragma solidity ^0.8.20; /** * @dev Standard ERC-20 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens. */ interface IERC20Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC20InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC20InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers. * @param spender Address that may be allowed to operate on tokens without being their owner. * @param allowance Amount of tokens a `spender` is allowed to operate with. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC20InvalidApprover(address approver); /** * @dev Indicates a failure with the `spender` to be approved. Used in approvals. * @param spender Address that may be allowed to operate on tokens without being their owner. */ error ERC20InvalidSpender(address spender); } /** * @dev Standard ERC-721 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens. */ interface IERC721Errors { /** * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20. * Used in balance queries. * @param owner Address of the current owner of a token. */ error ERC721InvalidOwner(address owner); /** * @dev Indicates a `tokenId` whose `owner` is the zero address. * @param tokenId Identifier number of a token. */ error ERC721NonexistentToken(uint256 tokenId); /** * @dev Indicates an error related to the ownership over a particular token. Used in transfers. * @param sender Address whose tokens are being transferred. * @param tokenId Identifier number of a token. * @param owner Address of the current owner of a token. */ error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC721InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC721InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param tokenId Identifier number of a token. */ error ERC721InsufficientApproval(address operator, uint256 tokenId); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC721InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC721InvalidOperator(address operator); } /** * @dev Standard ERC-1155 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens. */ interface IERC1155Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. * @param tokenId Identifier number of a token. */ error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC1155InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC1155InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param owner Address of the current owner of a token. */ error ERC1155MissingApprovalForAll(address operator, address owner); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC1155InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC1155InvalidOperator(address operator); /** * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation. * Used in batch transfers. * @param idsLength Length of the array of token identifiers * @param valuesLength Length of the array of token amounts */ error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength); }
// 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.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.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.1.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "./IERC20.sol"; import {IERC20Metadata} from "./extensions/IERC20Metadata.sol"; import {Context} from "../../utils/Context.sol"; import {IERC20Errors} from "../../interfaces/draft-IERC6093.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * * TIP: For a detailed writeup see our guide * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * The default value of {decimals} is 18. To change this, you should override * this function so it returns a different value. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC-20 * applications. */ abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors { mapping(address account => uint256) private _balances; mapping(address account => mapping(address spender => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the default value returned by this function, unless * it's overridden. * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `value`. */ function transfer(address to, uint256 value) public virtual returns (bool) { address owner = _msgSender(); _transfer(owner, to, value); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 value) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, value); return true; } /** * @dev See {IERC20-transferFrom}. * * Skips emitting an {Approval} event indicating an allowance update. This is not * required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve]. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `value`. * - the caller must have allowance for ``from``'s tokens of at least * `value`. */ function transferFrom(address from, address to, uint256 value) public virtual returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, value); _transfer(from, to, value); return true; } /** * @dev Moves a `value` amount of tokens from `from` to `to`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * NOTE: This function is not virtual, {_update} should be overridden instead. */ function _transfer(address from, address to, uint256 value) internal { if (from == address(0)) { revert ERC20InvalidSender(address(0)); } if (to == address(0)) { revert ERC20InvalidReceiver(address(0)); } _update(from, to, value); } /** * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from` * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding * this function. * * Emits a {Transfer} event. */ function _update(address from, address to, uint256 value) internal virtual { if (from == address(0)) { // Overflow check required: The rest of the code assumes that totalSupply never overflows _totalSupply += value; } else { uint256 fromBalance = _balances[from]; if (fromBalance < value) { revert ERC20InsufficientBalance(from, fromBalance, value); } unchecked { // Overflow not possible: value <= fromBalance <= totalSupply. _balances[from] = fromBalance - value; } } if (to == address(0)) { unchecked { // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply. _totalSupply -= value; } } else { unchecked { // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256. _balances[to] += value; } } emit Transfer(from, to, value); } /** * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0). * Relies on the `_update` mechanism * * Emits a {Transfer} event with `from` set to the zero address. * * NOTE: This function is not virtual, {_update} should be overridden instead. */ function _mint(address account, uint256 value) internal { if (account == address(0)) { revert ERC20InvalidReceiver(address(0)); } _update(address(0), account, value); } /** * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply. * Relies on the `_update` mechanism. * * Emits a {Transfer} event with `to` set to the zero address. * * NOTE: This function is not virtual, {_update} should be overridden instead */ function _burn(address account, uint256 value) internal { if (account == address(0)) { revert ERC20InvalidSender(address(0)); } _update(account, address(0), value); } /** * @dev Sets `value` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. * * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument. */ function _approve(address owner, address spender, uint256 value) internal { _approve(owner, spender, value, true); } /** * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event. * * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any * `Approval` event during `transferFrom` operations. * * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to * true using the following override: * * ```solidity * function _approve(address owner, address spender, uint256 value, bool) internal virtual override { * super._approve(owner, spender, value, true); * } * ``` * * Requirements are the same as {_approve}. */ function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual { if (owner == address(0)) { revert ERC20InvalidApprover(address(0)); } if (spender == address(0)) { revert ERC20InvalidSpender(address(0)); } _allowances[owner][spender] = value; if (emitEvent) { emit Approval(owner, spender, value); } } /** * @dev Updates `owner` s allowance for `spender` based on spent `value`. * * Does not update the allowance value in case of infinite allowance. * Revert if not enough allowance is available. * * Does not emit an {Approval} event. */ function _spendAllowance(address owner, address spender, uint256 value) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { if (currentAllowance < value) { revert ERC20InsufficientAllowance(spender, currentAllowance, value); } unchecked { _approve(owner, spender, currentAllowance - value, false); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC-20 standard. */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// 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.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.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.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) (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); }
// 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 import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; import "./interfaces/IBellumNursery.sol"; pragma solidity ^0.8.0; contract BellumNursery is IBellumNursery, ReentrancyGuard { using SafeERC20 for IERC20; address public immutable token; address public immutable pair; uint256 public immutable startTime; uint256 public immutable PERCENT_PER_EPOCH; // 25 = 0.25% uint256 private constant BASIS = 10000; struct Share { uint256 amount; uint256 lastClaimedEpoch; } uint256 public totalShares; mapping(address => Share) public shares; event Deposit ( address indexed sender, uint256 amount ); event Withdrawal ( address indexed sender, uint256 amount ); event EmergencyWithdrawal( address indexed sender, uint256 amount ); event ClaimRewards ( address indexed sender, uint256 lpAmount ); constructor(address token_, address pair_, uint256 percentPerEpoch_) { // Factory contract handles this PERCENT_PER_EPOCH = percentPerEpoch_; token = token_; pair = pair_; startTime = block.timestamp; } function deposit(uint256 amount) external nonReentrant { IERC20(token).safeTransferFrom(msg.sender, address(this), amount); _claimRewards(msg.sender); shares[msg.sender].amount += amount; totalShares += amount; emit Deposit(msg.sender, amount); } function withdraw(uint256 amount) external nonReentrant { require(amount <= shares[msg.sender].amount, "Bellum: NOT_ENOUGH_BALANCE"); _claimRewards(msg.sender); shares[msg.sender].amount -= amount; totalShares -= amount; IERC20(token).safeTransfer(msg.sender, amount); emit Withdrawal(msg.sender, amount); } function claimRewards() external nonReentrant{ _claimRewards(msg.sender); } // In case of emergency. WILL NOT CLAIM REWARDS. function emergencyWithdrawal() external nonReentrant { uint256 amount = shares[msg.sender].amount; totalShares -= amount; shares[msg.sender].amount = 0; IERC20(token).safeTransfer(msg.sender, amount); emit EmergencyWithdrawal(msg.sender, amount); } function _claimRewards(address shareholder) internal { uint256 amount = getUnpaidEarnings(shareholder); shares[shareholder].lastClaimedEpoch = getCurrentEpoch(); IERC20(pair).safeTransfer(shareholder, amount); emit ClaimRewards(shareholder, amount); } function getUnpaidEarnings(address shareholder) public view returns (uint256) { uint256 epoch = getCurrentEpoch(); Share memory share = shares[shareholder]; uint256 totalShares_ = totalShares; if (totalShares_ == 0) { return 0; } if (share.lastClaimedEpoch < epoch) { if (epoch - share.lastClaimedEpoch >= BASIS / PERCENT_PER_EPOCH) { return IERC20(pair).balanceOf(address(this)) * share.amount / totalShares_; } else { return IERC20(pair).balanceOf(address(this)) * share.amount * PERCENT_PER_EPOCH * (epoch - share.lastClaimedEpoch) / totalShares_ / BASIS; } } return 0; } function getCurrentEpoch() public view returns (uint256) { return (block.timestamp - startTime) / 6 hours; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; contract BellumToken is ERC20, Ownable { // mint to Bellum constructor(string memory _name, string memory _symbol, uint112 _totalSupply) ERC20(_name, _symbol) Ownable(msg.sender) { _mint(msg.sender, _totalSupply); } // To prevent LP pricing manipulations function _update(address from, address to, uint256 amount) internal virtual override { super._update(from, to, amount); address bellum = owner(); if (bellum != address(0)) { require(from == bellum || to == bellum || from == address(0), "Bellum: CANNOT_TRANSFER_YET"); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; interface IBellumNursery { function withdraw(uint256 amount) external; function deposit(uint256 amount) external; function claimRewards() external; function emergencyWithdrawal() external; function getCurrentEpoch() external view returns (uint256); function getUnpaidEarnings(address owner) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; interface IOwnable { function renounceOwnership() external; }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.17; interface IMetropolisFactory { function getPair(address tokenA, address tokenB) external view returns (address pair); function allPairs(uint256) external view returns (address pair); function allPairsLength() external view returns (uint256); function createPair(address tokenA, address tokenB) external returns (address pair); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.17; interface IMetropolisRouter { function factory() external pure returns (address); function WETH() external pure returns (address); function addLiquidity( address tokenA, address tokenB, uint amountADesired, uint amountBDesired, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB, uint liquidity); function addLiquidityETH( address token, uint amountTokenDesired, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external payable returns (uint amountToken, uint amountETH, uint liquidity); }
{ "optimizer": { "enabled": true, "runs": 200 }, "evmVersion": "paris", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"metropolisRouter_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"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":"token","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0In","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount0Out","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1In","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1Out","type":"uint256"}],"name":"BellumSwap","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"nursery","type":"address"},{"indexed":true,"internalType":"address","name":"pair","type":"address"}],"name":"CurveCompleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"curveIndex","type":"uint256"}],"name":"CurveCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"creator","type":"address"},{"indexed":false,"internalType":"uint256","name":"curveIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"dex","type":"uint256"}],"name":"TokenCreated","type":"event"},{"inputs":[],"name":"METROPOLIS_ROUTER","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allTokensLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount0OutMin","type":"uint256"}],"name":"buy","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFee_","type":"uint256"}],"name":"changeFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"feeReceiver_","type":"address"}],"name":"changeFeeReceiver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"collectFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"index","type":"uint8"},{"internalType":"uint256[]","name":"lists","type":"uint256[]"}],"name":"createCurve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"createFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"uint112","name":"totalSupply_","type":"uint112"},{"internalType":"uint8","name":"curveIndex_","type":"uint8"},{"internalType":"enum BellumFactory.Dex","name":"dex","type":"uint8"}],"name":"createToken","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint8","name":"","type":"uint8"}],"name":"curves","outputs":[{"internalType":"uint256","name":"percentOfLP","type":"uint256"},{"internalType":"uint256","name":"avaxAtLaunch","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeReceiver","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"migrationFee","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":"pendingFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"percentPerEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount0In","type":"uint256"},{"internalType":"uint256","name":"amount1OutMin","type":"uint256"}],"name":"sell","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"createFee_","type":"uint256"}],"name":"setCreateFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"isPaused_","type":"bool"}],"name":"setIsPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"migrationFee_","type":"uint256"}],"name":"setMigrationFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"percentPerEpoch_","type":"uint256"}],"name":"setPercentPerEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tokenToNursery","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tokens","outputs":[{"internalType":"address","name":"creator","type":"address"},{"internalType":"uint8","name":"curveIndex","type":"uint8"},{"internalType":"uint256","name":"currentIndex","type":"uint256"},{"internalType":"uint256","name":"currentValue","type":"uint256"},{"internalType":"uint256","name":"initialSupply","type":"uint256"},{"internalType":"bool","name":"hasLaunched","type":"bool"},{"internalType":"enum BellumFactory.Dex","name":"dex","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tradingFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60a06040523480156200001157600080fd5b50604051620045bb380380620045bb8339810160408190526200003491620001f6565b816001600160a01b0381166200006557604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b620000708162000189565b50600180556001600160a01b038216620000d85760405162461bcd60e51b815260206004820152602260248201527f5a65726f2061646472657373206e6f7420616c6c6f77656420666f72206f776e60448201526132b960f11b60648201526084016200005c565b6001600160a01b0381166200013c5760405162461bcd60e51b815260206004820152602360248201527f5a65726f2061646472657373206e6f7420616c6c6f77656420666f7220726f756044820152623a32b960e91b60648201526084016200005c565b6064600555610190600355670de0b6b3a76400006006556001600160a01b0390811660805260028054610100600160a81b031916610100939092169290920217905560196007556200022e565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b0381168114620001f157600080fd5b919050565b600080604083850312156200020a57600080fd5b6200021583620001d9565b91506200022560208401620001d9565b90509250929050565b60805161436362000258600039600081816102c701528181611cf90152611d2301526143636000f3fe608060405260043610620001a15760003560e01c80636a27246211620000e2578063b3f006741162000095578063dbb80e42116200006c578063dbb80e4214620004e7578063e486033914620004fe578063f08875b7146200057f578063f2fde38b146200059757600080fd5b8063b3f006741462000491578063c879657214620004b8578063cce7ec1314620004d057600080fd5b80636a27246214620003d2578063715018a614620003f75780637c08b964146200040f5780638da5cb5b1462000434578063a3400a661462000454578063b2db919b146200047957600080fd5b806346dcab551162000158578063634282af116200012f578063634282af146200033e5780636622e65e146200036357806366f20b4f14620003885780636a1db1bf14620003ad57600080fd5b806346dcab5514620002e957806356f43352146200030157806362914849146200031957600080fd5b806320e1fc8c14620001a6578063224438d114620001fb578063240976bf1462000222578063317e778514620002495780633d4ac80a14620002605780633f23704614620002b3575b600080fd5b348015620001b357600080fd5b50620001e1620001c53660046200231f565b600a602052600090815260409020600181015460029091015482565b604080519283526020830191909152015b60405180910390f35b3480156200020857600080fd5b506200021360045481565b604051908152602001620001f2565b3480156200022f57600080fd5b50620002476200024136600462002344565b620005bc565b005b620002476200025a36600462002429565b620005d9565b3480156200026d57600080fd5b506200029a6200027f366004620024f6565b600b602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001620001f2565b348015620002c057600080fd5b506200029a7f000000000000000000000000000000000000000000000000000000000000000081565b348015620002f657600080fd5b506200021360035481565b3480156200030e57600080fd5b506200021360055481565b3480156200032657600080fd5b50620002476200033836600462002516565b62000a5b565b3480156200034b57600080fd5b506200029a6200035d36600462002516565b62000abc565b3480156200037057600080fd5b50620002476200038236600462002516565b62000ae7565b3480156200039557600080fd5b5062000247620003a736600462002516565b62000b9c565b348015620003ba57600080fd5b5062000247620003cc36600462002516565b62000bff565b348015620003df57600080fd5b5062000247620003f136600462002530565b62000c58565b3480156200040457600080fd5b50620002476200108c565b3480156200041c57600080fd5b50620002476200042e366004620024f6565b620010a4565b3480156200044157600080fd5b506000546001600160a01b03166200029a565b3480156200046157600080fd5b50620002476200047336600462002568565b620010d6565b3480156200048657600080fd5b506200021360065481565b3480156200049e57600080fd5b506002546200029a9061010090046001600160a01b031681565b348015620004c557600080fd5b506200024762001403565b62000247620004e13660046200262e565b62001473565b348015620004f457600080fd5b5060085462000213565b3480156200050b57600080fd5b506200056a6200051d366004620024f6565b600960205260009081526040902080546001820154600283015460038401546004909401546001600160a01b0384169460ff600160a01b9095048516949091808216916101009091041687565b604051620001f2979695949392919062002673565b3480156200058c57600080fd5b506200021360075481565b348015620005a457600080fd5b5062000247620005b6366004620024f6565b620014e5565b620005c662001526565b6002805460ff1916911515919091179055565b620005e362001555565b60ff82166000908152600a6020908152604080832081518154608094810282018501909352606081018381529093919284928491908401828280156200064957602002820191906000526020600020905b81548152602001906001019080831162000634575b5050509183525050600182015460208083019190915260029283015460409092019190915282015182516006549254939450909290919060ff1615620006d65760405162461bcd60e51b815260206004820181905260248201527f42656c6c756d3a20544f4b454e5f4352454154494f4e5f49535f50415553454460448201526064015b60405180910390fd5b82600003620007285760405162461bcd60e51b815260206004820152601c60248201527f42656c6c756d3a2043555256455f444f45535f4e4f545f4558495354000000006044820152606401620006cd565b670de0b6b3a7640000876001600160701b031610156200078b5760405162461bcd60e51b815260206004820152601c60248201527f42656c6c756d3a20544f54414c5f535550504c595f544f4f5f4c4f57000000006044820152606401620006cd565b620007a081681b1ae4d6e2ef500000620026f0565b341115620007e85760405162461bcd60e51b8152602060048201526014602482015273084cad8d8eada7440a89e9ebe9aaa8690be8aa8960631b6044820152606401620006cd565b80341015620008335760405162461bcd60e51b8152602060048201526016602482015275084cad8d8eada7440a89e9ebe9892a8a8988abe8aa8960531b6044820152606401620006cd565b6000898989604051620008469062002285565b62000854939291906200274e565b604051809103906000f08015801562000871573d6000803e3d6000fd5b506008805460018101825560009182527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30180546001600160a01b0319166001600160a01b0384161790559091508190612710620008d9876001600160701b038d1662002791565b620008e59190620027ab565b6001600160a01b03831660009081526009602052604081206003018290558651919250612710918791906200091e576200091e620027ce565b60200260200101518262000933919062002791565b6200093f9190620027ab565b6001600160a01b0383166000908152600960205260409020600281019190915580546001600160a01b031960ff8c16600160a01b02166001600160a81b03199091161733178155600401805489919061ff001916610100838015620009a857620009a86200265d565b0217905550336001600160a01b0383167fc53fd35d147910e8b0428fe8d1bc5aaef0bc4af4d778ba5d10c55de9ad1349728b8b8015620009ec57620009ec6200265d565b6040805160ff909316835260208301919091520160405180910390a3836004600082825462000a1c9190620026f0565b909155505034841462000a435762000a43823362000a3b8734620027e4565b600062001580565b5050505050505062000a5460018055565b5050505050565b62000a6562001526565b6802b5e3af16b188000081111562000ab75760405162461bcd60e51b8152602060048201526014602482015273084cad8d8eada74408c8a8abea89e9ebe90928e960631b6044820152606401620006cd565b600655565b6008818154811062000acd57600080fd5b6000918252602090912001546001600160a01b0316905081565b62000af162001526565b603281111562000b445760405162461bcd60e51b815260206004820152601860248201527f42656c6c756d3a2050455243454e545f544f4f5f4849474800000000000000006044820152606401620006cd565b600a81101562000b975760405162461bcd60e51b815260206004820152601760248201527f42656c6c756d3a2050455243454e545f544f4f5f4c4f570000000000000000006044820152606401620006cd565b600755565b62000ba662001526565b6103e881111562000bfa5760405162461bcd60e51b815260206004820152601e60248201527f42656c6c756d3a204d4947524154494f4e5f4645455f544f4f5f4849474800006044820152606401620006cd565b600355565b62000c0962001526565b60fa81111562000c535760405162461bcd60e51b8152602060048201526014602482015273084cad8d8eada74408c8a8abea89e9ebe90928e960631b6044820152606401620006cd565b600555565b62000c6262001555565b6001600160a01b0383166000908152600960205260408120600381015490910362000cd05760405162461bcd60e51b815260206004820152601c60248201527f42656c6c756d3a20544f4b454e5f444f45535f4e4f545f4558495354000000006044820152606401620006cd565b600481015460ff161562000d275760405162461bcd60e51b815260206004820152601e60248201527f42656c6c756d3a20494e53554646494349454e545f4c495155494449545900006044820152606401620006cd565b62000d3e6001600160a01b038516333086620019ac565b8054600160a01b900460ff166000908152600a602090815260408083208054825181850281018501909352808352919290919083018282801562000da257602002820191906000526020600020905b81548152602001906001019080831162000d8d575b505050506001840154600285015460038601549394506000938493505b8884101562000f1857600062000dd8846107d062002791565b62000de690612710620026f0565b62000df360028462002791565b62000dff9190620027ab565b9050600062000e0f868c620027e4565b905060008490506000612710858b898151811062000e315762000e31620027ce565b602002602001015162000e45919062002791565b62000e519190620027ab565b90508062000e608484620026f0565b1162000ead578362000e7b670de0b6b3a76400008562002791565b62000e879190620027ab565b62000e93908a620026f0565b985062000ea18387620026f0565b95505050505062000f18565b600062000ebb8383620027e4565b905062000ec9818a620026f0565b98508462000ee0670de0b6b3a76400008362002791565b62000eec9190620027ab565b62000ef8908b620026f0565b99508762000f0681620027fa565b98505060009650505050505062000dbf565b8488111562000f635760405162461bcd60e51b815260206004820152601660248201527510995b1b1d5b4e8814d31254141051d157d31253525560521b6044820152606401620006cd565b6702c68af0bb14000085101562000fbd5760405162461bcd60e51b815260206004820152601c60248201527f42656c6c756d3a20494e53554646494349454e545f4554485f4f5554000000006044820152606401620006cd565b60018701839055600287018290556005546000906127109062000fe1908862002791565b62000fed9190620027ab565b90508060046000828254620010039190620026f0565b90915550620010219050620010198288620027e4565b339062001a1b565b604080518b81526000602082018190528183015260608101889052905133916001600160a01b038e16917feae13466a4e0ed2b9f8778664bef183cecabb5006850f4b17cc094d54ce3a3e89181900360800190a350505050505050506200108760018055565b505050565b6200109662001526565b620010a2600062001abe565b565b620010ae62001526565b600280546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b620010e062001526565b60ff82166000908152600a602052604090206001015415620011455760405162461bcd60e51b815260206004820152601c60248201527f42656c6c756d3a2043555256455f414c52454144595f494e5f555345000000006044820152606401620006cd565b80516000908190815b8181101562001277578481815181106200116c576200116c620027ce565b6020026020010151600003620011bb5760405162461bcd60e51b81526020600482015260136024820152722132b6363ab69d1024a72b20a624a22fa124a760691b6044820152606401620006cd565b848181518110620011d057620011d0620027ce565b602002602001015184620011e59190620026f0565b93506000612710620011fa6107d08462002791565b6200120890612710620026f0565b6200121c90670de0b6b3a764000062002791565b620012289190620027ab565b905080868381518110620012405762001240620027ce565b602002602001015162001254919062002791565b620012609085620026f0565b935050806200126f9062002814565b90506200114e565b506127108314620012d65760405162461bcd60e51b815260206004820152602260248201527f42656c6c756d3a20494e56414c49445f544f54414c5f4449535452494255544960448201526127a760f11b6064820152608401620006cd565b6000612710806107d0620012ec600186620027e4565b620012f8919062002791565b620013049190620026f0565b6200131890670de0b6b3a764000062002791565b620013249190620027ab565b90506000620013368261271062002791565b90506000620013468583620026f0565b620013548361271062002791565b620013609190620027ab565b90506040518060600160405280888152602001828152602001600287620013889190620027ab565b905260ff89166000908152600a60209081526040909120825180519192620013b69284929091019062002293565b50602082015160018201556040918201516002909101555160ff8916907f692761be1e34ff0280587cdf866deb367e85f7b32ff1d5ac3bbfdd944e5e567490600090a25050505050505050565b60045460008190036200144e5760405162461bcd60e51b8152602060048201526012602482015271139bc81999595cc81d1bc818dbdb1b1958dd60721b6044820152606401620006cd565b6000600455600254620014709061010090046001600160a01b03168262001a1b565b50565b6200147d62001555565b670de0b6b3a7640000341015620014c95760405162461bcd60e51b815260206004820152600f60248201526e42656c6c756d3a20544f4f5f4c4f5760881b6044820152606401620006cd565b620014d78233348462001580565b620014e160018055565b5050565b620014ef62001526565b6001600160a01b0381166200151b57604051631e4fbdf760e01b815260006004820152602401620006cd565b620014708162001abe565b6000546001600160a01b03163314620010a25760405163118cdaa760e01b8152336004820152602401620006cd565b6002600154036200157957604051633ee5aeb560e01b815260040160405180910390fd5b6002600155565b6001600160a01b03841660009081526009602052604081206003810154909103620015ee5760405162461bcd60e51b815260206004820152601c60248201527f42656c6c756d3a20544f4b454e5f444f45535f4e4f545f4558495354000000006044820152606401620006cd565b600481015460ff1615620016405760405162461bcd60e51b815260206004820152601860248201527710995b1b1d5b4e881053149150511657d310555390d2115160421b6044820152606401620006cd565b8054600160a01b900460ff166000908152600a6020908152604080832080548251818502810185019093528083529192909190830182828015620016a457602002820191906000526020600020905b8154815260200190600101908083116200168f575b50505050509050600061271060055486620016c0919062002791565b620016cc9190620027ab565b90506000620016dc8287620027e4565b600185015460028601546003870154929350600092839291905b85841015620018725760006200170f846107d062002791565b6200171d90612710620026f0565b6200172a60028462002791565b620017369190620027ab565b90506000620017468689620027e4565b905083670de0b6b3a76400006200175e848462002791565b6200176a9190620027ab565b811115620017cb576000670de0b6b3a764000062001789848662002791565b620017959190620027ab565b9050620017a38389620026f0565b9750620017b1818a620026f0565b9850620017bf8183620027e4565b95505050505062001872565b82620017e0670de0b6b3a76400008362002791565b620017ec9190620027ab565b620017f89088620026f0565b9650620018068189620026f0565b9750620018138662002814565b95508a518610156200186057612710848c8881518110620018385762001838620027ce565b60200260200101516200184c919062002791565b620018589190620027ab565b945062001869565b50505062001872565b505050620016f6565b848a1115620018bd5760405162461bcd60e51b815260206004820152601660248201527510995b1b1d5b4e8814d31254141051d157d31253525560521b6044820152606401620006cd565b600189018390556002890182905560048054889190600090620018e2908490620026f0565b90915550620018fe90506001600160a01b038e168d8762001b0e565b8b6001600160a01b03168d6001600160a01b03167feae13466a4e0ed2b9f8778664bef183cecabb5006850f4b17cc094d54ce3a3e86000888f600060405162001960949392919093845260208401929092526040830152606082015260800190565b60405180910390a3875183106200199d5762001992620019818588620027e4565b6001600160a01b038e169062001a1b565b6200199d8d62001b41565b50505050505050505050505050565b6040516001600160a01b03848116602483015283811660448301526064820183905262001a159186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b03838183161783525050505062002099565b50505050565b8047101562001a475760405163cf47918160e01b815247600482015260248101829052604401620006cd565b6000826001600160a01b03168260405160006040518083038185875af1925050503d806000811462001a96576040519150601f19603f3d011682016040523d82523d6000602084013e62001a9b565b606091505b5050905080620010875760405163d6bda27560e01b815260040160405180910390fd5b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6040516001600160a01b038381166024830152604482018390526200108791859182169063a9059cbb90606401620019e2565b6001600160a01b03811660009081526009602052604090206004015460ff161562001baa5760405162461bcd60e51b815260206004820152601860248201527710995b1b1d5b4e881053149150511657d310555390d2115160421b6044820152606401620006cd565b806001600160a01b031663715018a66040518163ffffffff1660e01b8152600401600060405180830381600087803b15801562001be657600080fd5b505af115801562001bfb573d6000803e3d6000fd5b50506040516370a0823160e01b8152306004820152600092506001600160a01b03841691506370a0823190602401602060405180830381865afa15801562001c47573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001c6d919062002830565b6001600160a01b038316600090815260096020908152604080832054600160a01b900460ff168352600a909152812060020154600354929350916127109062001cb7908462002791565b62001cc39190620027ab565b9050801562001ce657806004600082825462001ce09190620026f0565b90915550505b60008062001d1f6001600160a01b0387167f0000000000000000000000000000000000000000000000000000000000000000876200210f565b60007f000000000000000000000000000000000000000000000000000000000000000090506000816001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa15801562001d85573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001dab91906200284a565b90506000826001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa15801562001dee573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001e1491906200284a565b60405163e6a4390560e01b81526001600160a01b038b8116600483015280831660248301529192509083169063e6a4390590604401602060405180830381865afa15801562001e67573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001e8d91906200284a565b94506001600160a01b03851662001f18576040516364e329cb60e11b81526001600160a01b038a81166004830152828116602483015283169063c9c65396906044016020604051808303816000875af115801562001eef573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001f1591906200284a565b94505b6000898660075460405162001f2d90620022e3565b6001600160a01b0393841681529290911660208301526040820152606001604051809103906000f08015801562001f68573d6000803e3d6000fd5b5094508490506001600160a01b03841663f305d71962001f89898b620027e4565b6040516001600160e01b031960e084901b1681526001600160a01b03808f166004830152602482018e90526000604483018190526064830152891660848201524260a482015260c40160606040518083038185885af115801562001ff1573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906200201891906200286a565b5050506001600160a01b038a81166000818152600b6020908152604080832080546001600160a01b0319168b87169081179091556009909252808320600401805460ff1916600117905551938a16939092917f937f456c07a61f36132d04df1c2826dd375336feecdd370ddaf00f25342e893c91a450505050505050505050565b600080602060008451602086016000885af180620020bd576040513d6000823e3d81fd5b50506000513d91508115620020d7578060011415620020e4565b6001600160a01b0384163b155b1562001a1557604051635274afe760e01b81526001600160a01b0385166004820152602401620006cd565b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301526000919085169063dd62ed3e90604401602060405180830381865afa15801562002160573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002186919062002830565b905062001a1584846200219a8585620026f0565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052620021ed848262002231565b62001a15576040516001600160a01b038481166024830152600060448301526200222591869182169063095ea7b390606401620019e2565b62001a15848262002099565b6000806000806020600086516020880160008a5af192503d9150600051905082801562002279575081156200226a578060011462002279565b6000866001600160a01b03163b115b93505050505b92915050565b610f2f806200289a83390190565b828054828255906000526020600020908101928215620022d1579160200282015b82811115620022d1578251825591602001919060010190620022b4565b50620022df929150620022f1565b5090565b610b6580620037c983390190565b5b80821115620022df5760008155600101620022f2565b803560ff811681146200231a57600080fd5b919050565b6000602082840312156200233257600080fd5b6200233d8262002308565b9392505050565b6000602082840312156200235757600080fd5b813580151581146200233d57600080fd5b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715620023aa57620023aa62002368565b604052919050565b600082601f830112620023c457600080fd5b813567ffffffffffffffff811115620023e157620023e162002368565b620023f6601f8201601f19166020016200237e565b8181528460208386010111156200240c57600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a086880312156200244257600080fd5b853567ffffffffffffffff808211156200245b57600080fd5b6200246989838a01620023b2565b965060208801359150808211156200248057600080fd5b506200248f88828901620023b2565b94505060408601356001600160701b0381168114620024ad57600080fd5b9250620024bd6060870162002308565b9150608086013560018110620024d257600080fd5b809150509295509295909350565b6001600160a01b03811681146200147057600080fd5b6000602082840312156200250957600080fd5b81356200233d81620024e0565b6000602082840312156200252957600080fd5b5035919050565b6000806000606084860312156200254657600080fd5b83356200255381620024e0565b95602085013595506040909401359392505050565b600080604083850312156200257c57600080fd5b620025878362002308565b915060208084013567ffffffffffffffff80821115620025a657600080fd5b818601915086601f830112620025bb57600080fd5b813581811115620025d057620025d062002368565b8060051b9150620025e38483016200237e565b8181529183018401918481019089841115620025fe57600080fd5b938501935b838510156200261e5784358252938501939085019062002603565b8096505050505050509250929050565b600080604083850312156200264257600080fd5b82356200264f81620024e0565b946020939093013593505050565b634e487b7160e01b600052602160045260246000fd5b6001600160a01b038816815260ff8716602082015260408101869052606081018590526080810184905282151560a082015260e0810160018310620026c857634e487b7160e01b600052602160045260246000fd5b8260c083015298975050505050505050565b634e487b7160e01b600052601160045260246000fd5b808201808211156200227f576200227f620026da565b6000815180845260005b818110156200272e5760208185018101518683018201520162002710565b506000602082860101526020601f19601f83011685010191505092915050565b60608152600062002763606083018662002706565b828103602084015262002777818662002706565b9150506001600160701b0383166040830152949350505050565b80820281158282048414176200227f576200227f620026da565b600082620027c957634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b818103818111156200227f576200227f620026da565b6000816200280c576200280c620026da565b506000190190565b600060018201620028295762002829620026da565b5060010190565b6000602082840312156200284357600080fd5b5051919050565b6000602082840312156200285d57600080fd5b81516200233d81620024e0565b6000806000606084860312156200288057600080fd5b835192506020840151915060408401519050925092509256fe60806040523480156200001157600080fd5b5060405162000f2f38038062000f2f833981016040819052620000349162000406565b338383600362000045838262000522565b50600462000054828262000522565b5050506001600160a01b0381166200008757604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b6200009281620000b1565b50620000a8336001600160701b03831662000103565b50505062000616565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0382166200012f5760405163ec442f0560e01b8152600060048201526024016200007e565b6200013d6000838362000141565b5050565b6200014e8383836200020e565b6000620001636005546001600160a01b031690565b90506001600160a01b038116156200020857806001600160a01b0316846001600160a01b03161480620001a75750806001600160a01b0316836001600160a01b0316145b80620001ba57506001600160a01b038416155b620002085760405162461bcd60e51b815260206004820152601b60248201527f42656c6c756d3a2043414e4e4f545f5452414e534645525f594554000000000060448201526064016200007e565b50505050565b6001600160a01b0383166200023d578060026000828254620002319190620005ee565b90915550620002b19050565b6001600160a01b03831660009081526020819052604090205481811015620002925760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016200007e565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b038216620002cf57600280548290039055620002ee565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516200033491815260200190565b60405180910390a3505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200036957600080fd5b81516001600160401b038082111562000386576200038662000341565b604051601f8301601f19908116603f01168101908282118183101715620003b157620003b162000341565b81604052838152602092508683858801011115620003ce57600080fd5b600091505b83821015620003f25785820183015181830184015290820190620003d3565b600093810190920192909252949350505050565b6000806000606084860312156200041c57600080fd5b83516001600160401b03808211156200043457600080fd5b620004428783880162000357565b945060208601519150808211156200045957600080fd5b50620004688682870162000357565b604086015190935090506001600160701b03811681146200048857600080fd5b809150509250925092565b600181811c90821680620004a857607f821691505b602082108103620004c957634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200051d57600081815260208120601f850160051c81016020861015620004f85750805b601f850160051c820191505b81811015620005195782815560010162000504565b5050505b505050565b81516001600160401b038111156200053e576200053e62000341565b62000556816200054f845462000493565b84620004cf565b602080601f8311600181146200058e5760008415620005755750858301515b600019600386901b1c1916600185901b17855562000519565b600085815260208120601f198616915b82811015620005bf578886015182559484019460019091019084016200059e565b5085821015620005de5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b808201808211156200061057634e487b7160e01b600052601160045260246000fd5b92915050565b61090980620006266000396000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c8063715018a611610071578063715018a6146101575780638da5cb5b1461016157806395d89b411461017c578063a9059cbb14610184578063dd62ed3e14610197578063f2fde38b146101d057600080fd5b806306fdde03146100b9578063095ea7b3146100d757806318160ddd146100fa57806323b872dd1461010c578063313ce5671461011f57806370a082311461012e575b600080fd5b6100c16101e3565b6040516100ce9190610753565b60405180910390f35b6100ea6100e53660046107bd565b610275565b60405190151581526020016100ce565b6002545b6040519081526020016100ce565b6100ea61011a3660046107e7565b61028f565b604051601281526020016100ce565b6100fe61013c366004610823565b6001600160a01b031660009081526020819052604090205490565b61015f6102b3565b005b6005546040516001600160a01b0390911681526020016100ce565b6100c16102c7565b6100ea6101923660046107bd565b6102d6565b6100fe6101a5366004610845565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b61015f6101de366004610823565b6102e4565b6060600380546101f290610878565b80601f016020809104026020016040519081016040528092919081815260200182805461021e90610878565b801561026b5780601f106102405761010080835404028352916020019161026b565b820191906000526020600020905b81548152906001019060200180831161024e57829003601f168201915b5050505050905090565b600033610283818585610327565b60019150505b92915050565b60003361029d858285610339565b6102a88585856103b7565b506001949350505050565b6102bb610416565b6102c56000610443565b565b6060600480546101f290610878565b6000336102838185856103b7565b6102ec610416565b6001600160a01b03811661031b57604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b61032481610443565b50565b6103348383836001610495565b505050565b6001600160a01b0383811660009081526001602090815260408083209386168352929052205460001981146103b157818110156103a257604051637dc7a0d960e11b81526001600160a01b03841660048201526024810182905260448101839052606401610312565b6103b184848484036000610495565b50505050565b6001600160a01b0383166103e157604051634b637e8f60e11b815260006004820152602401610312565b6001600160a01b03821661040b5760405163ec442f0560e01b815260006004820152602401610312565b61033483838361056a565b6005546001600160a01b031633146102c55760405163118cdaa760e01b8152336004820152602401610312565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0384166104bf5760405163e602df0560e01b815260006004820152602401610312565b6001600160a01b0383166104e957604051634a1406b160e11b815260006004820152602401610312565b6001600160a01b03808516600090815260016020908152604080832093871683529290522082905580156103b157826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161055c91815260200190565b60405180910390a350505050565b610575838383610629565b60006105896005546001600160a01b031690565b90506001600160a01b038116156103b157806001600160a01b0316846001600160a01b031614806105cb5750806001600160a01b0316836001600160a01b0316145b806105dd57506001600160a01b038416155b6103b15760405162461bcd60e51b815260206004820152601b60248201527f42656c6c756d3a2043414e4e4f545f5452414e534645525f59455400000000006044820152606401610312565b6001600160a01b03831661065457806002600082825461064991906108b2565b909155506106c69050565b6001600160a01b038316600090815260208190526040902054818110156106a75760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401610312565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b0382166106e257600280548290039055610701565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161074691815260200190565b60405180910390a3505050565b600060208083528351808285015260005b8181101561078057858101830151858201604001528201610764565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b03811681146107b857600080fd5b919050565b600080604083850312156107d057600080fd5b6107d9836107a1565b946020939093013593505050565b6000806000606084860312156107fc57600080fd5b610805846107a1565b9250610813602085016107a1565b9150604084013590509250925092565b60006020828403121561083557600080fd5b61083e826107a1565b9392505050565b6000806040838503121561085857600080fd5b610861836107a1565b915061086f602084016107a1565b90509250929050565b600181811c9082168061088c57607f821691505b6020821081036108ac57634e487b7160e01b600052602260045260246000fd5b50919050565b8082018082111561028957634e487b7160e01b600052601160045260246000fdfea26469706673582212202004a68e9b68f912633e70d3d1000aa6fd800e6fbd5831c9ea08498a638d4b7d64736f6c6343000814003361010060405234801561001157600080fd5b50604051610b65380380610b658339810160408190526100309161006f565b600160005560e0526001600160a01b039182166080521660a0524260c0526100ab565b80516001600160a01b038116811461006a57600080fd5b919050565b60008060006060848603121561008457600080fd5b61008d84610053565b925061009b60208501610053565b9150604084015190509250925092565b60805160a05160c05160e051610a436101226000396000818160be0152818161028101526103910152600081816101390152610715015260008181610160015281816102d6015281816103b401526107ae0152600081816101f60152818161051a015281816105e7015261066b0152610a436000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c806378e979251161007157806378e9792514610134578063a8aa1b311461015b578063b6b55f251461019a578063b97dd9e2146101ad578063ce7c2ac2146101b5578063fc0c546a146101f157600080fd5b80632172ecc7146100b957806328fd3198146100f35780632e1a7d4d14610106578063372500ab1461011b5780633a98ef39146101235780635b0a38431461012c575b600080fd5b6100e07f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b6100e0610101366004610930565b610218565b610119610114366004610960565b61045a565b005b610119610584565b6100e060015481565b6101196105a1565b6100e07f000000000000000000000000000000000000000000000000000000000000000081565b6101827f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016100ea565b6101196101a8366004610960565b610656565b6100e061070b565b6101dc6101c3366004610930565b6002602052600090815260409020805460019091015482565b604080519283526020830191909152016100ea565b6101827f000000000000000000000000000000000000000000000000000000000000000081565b60008061022361070b565b6001600160a01b0384166000908152600260209081526040808320815180830190925280548252600190810154928201929092529054929350919081900361027057506000949350505050565b828260200151101561044f576102a87f000000000000000000000000000000000000000000000000000000000000000061271061098f565b60208301516102b790856109b1565b106103665781516040516370a0823160e01b81523060048201528291907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610325573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061034991906109ca565b61035391906109e3565b61035d919061098f565b95945050505050565b6127108183602001518561037a91906109b1565b84516040516370a0823160e01b81523060048201527f000000000000000000000000000000000000000000000000000000000000000091907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610403573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042791906109ca565b61043191906109e3565b61043b91906109e3565b61044591906109e3565b610353919061098f565b506000949350505050565b610462610749565b336000908152600260205260409020548111156104c65760405162461bcd60e51b815260206004820152601a60248201527f42656c6c756d3a204e4f545f454e4f5547485f42414c414e434500000000000060448201526064015b60405180910390fd5b6104cf33610773565b33600090815260026020526040812080548392906104ee9084906109b1565b92505081905550806001600082825461050791906109b1565b9091555061054190506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016338361081c565b60405181815233907f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65906020015b60405180910390a26105816001600055565b50565b61058c610749565b61059533610773565b61059f6001600055565b565b6105a9610749565b3360009081526002602052604081205460018054919283926105cc9084906109b1565b909155505033600081815260026020526040812055610616907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316908361081c565b60405181815233907f23d6711a1d031134a36921253c75aa59e967d38e369ac625992824315e204f209060200160405180910390a25061059f6001600055565b61065e610749565b6106936001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016333084610880565b61069c33610773565b33600090815260026020526040812080548392906106bb9084906109fa565b9250508190555080600160008282546106d491906109fa565b909155505060405181815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9060200161056f565b600061546061073a7f0000000000000000000000000000000000000000000000000000000000000000426109b1565b610744919061098f565b905090565b60026000540361076c57604051633ee5aeb560e01b815260040160405180910390fd5b6002600055565b600061077e82610218565b905061078861070b565b6001600160a01b038084166000908152600260205260409020600101919091556107d5907f000000000000000000000000000000000000000000000000000000000000000016838361081c565b816001600160a01b03167f1f89f96333d3133000ee447473151fa9606543368f02271c9d95ae14f13bcc678260405161081091815260200190565b60405180910390a25050565b6040516001600160a01b0383811660248301526044820183905261087b91859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506108bf565b505050565b6040516001600160a01b0384811660248301528381166044830152606482018390526108b99186918216906323b872dd90608401610849565b50505050565b600080602060008451602086016000885af1806108e2576040513d6000823e3d81fd5b50506000513d915081156108fa578060011415610907565b6001600160a01b0384163b155b156108b957604051635274afe760e01b81526001600160a01b03851660048201526024016104bd565b60006020828403121561094257600080fd5b81356001600160a01b038116811461095957600080fd5b9392505050565b60006020828403121561097257600080fd5b5035919050565b634e487b7160e01b600052601160045260246000fd5b6000826109ac57634e487b7160e01b600052601260045260246000fd5b500490565b818103818111156109c4576109c4610979565b92915050565b6000602082840312156109dc57600080fd5b5051919050565b80820281158282048414176109c4576109c4610979565b808201808211156109c4576109c461097956fea2646970667358221220955bc6c8d8c2763e1fc29ac56e899c2edf8a7b541ab4692218922a9d608208e664736f6c63430008140033a26469706673582212205c67fe3337fb2af1e194d684891b71be67dc9656f90a0d39f7910182c85c1b0564736f6c634300081400330000000000000000000000003a7a1f256b6180d59f58efc080321a09d456ee9b00000000000000000000000095a7e403d7cf20f675ff9273d66e94d35ba49fa3
Deployed Bytecode
0x608060405260043610620001a15760003560e01c80636a27246211620000e2578063b3f006741162000095578063dbb80e42116200006c578063dbb80e4214620004e7578063e486033914620004fe578063f08875b7146200057f578063f2fde38b146200059757600080fd5b8063b3f006741462000491578063c879657214620004b8578063cce7ec1314620004d057600080fd5b80636a27246214620003d2578063715018a614620003f75780637c08b964146200040f5780638da5cb5b1462000434578063a3400a661462000454578063b2db919b146200047957600080fd5b806346dcab551162000158578063634282af116200012f578063634282af146200033e5780636622e65e146200036357806366f20b4f14620003885780636a1db1bf14620003ad57600080fd5b806346dcab5514620002e957806356f43352146200030157806362914849146200031957600080fd5b806320e1fc8c14620001a6578063224438d114620001fb578063240976bf1462000222578063317e778514620002495780633d4ac80a14620002605780633f23704614620002b3575b600080fd5b348015620001b357600080fd5b50620001e1620001c53660046200231f565b600a602052600090815260409020600181015460029091015482565b604080519283526020830191909152015b60405180910390f35b3480156200020857600080fd5b506200021360045481565b604051908152602001620001f2565b3480156200022f57600080fd5b50620002476200024136600462002344565b620005bc565b005b620002476200025a36600462002429565b620005d9565b3480156200026d57600080fd5b506200029a6200027f366004620024f6565b600b602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001620001f2565b348015620002c057600080fd5b506200029a7f00000000000000000000000095a7e403d7cf20f675ff9273d66e94d35ba49fa381565b348015620002f657600080fd5b506200021360035481565b3480156200030e57600080fd5b506200021360055481565b3480156200032657600080fd5b50620002476200033836600462002516565b62000a5b565b3480156200034b57600080fd5b506200029a6200035d36600462002516565b62000abc565b3480156200037057600080fd5b50620002476200038236600462002516565b62000ae7565b3480156200039557600080fd5b5062000247620003a736600462002516565b62000b9c565b348015620003ba57600080fd5b5062000247620003cc36600462002516565b62000bff565b348015620003df57600080fd5b5062000247620003f136600462002530565b62000c58565b3480156200040457600080fd5b50620002476200108c565b3480156200041c57600080fd5b50620002476200042e366004620024f6565b620010a4565b3480156200044157600080fd5b506000546001600160a01b03166200029a565b3480156200046157600080fd5b50620002476200047336600462002568565b620010d6565b3480156200048657600080fd5b506200021360065481565b3480156200049e57600080fd5b506002546200029a9061010090046001600160a01b031681565b348015620004c557600080fd5b506200024762001403565b62000247620004e13660046200262e565b62001473565b348015620004f457600080fd5b5060085462000213565b3480156200050b57600080fd5b506200056a6200051d366004620024f6565b600960205260009081526040902080546001820154600283015460038401546004909401546001600160a01b0384169460ff600160a01b9095048516949091808216916101009091041687565b604051620001f2979695949392919062002673565b3480156200058c57600080fd5b506200021360075481565b348015620005a457600080fd5b5062000247620005b6366004620024f6565b620014e5565b620005c662001526565b6002805460ff1916911515919091179055565b620005e362001555565b60ff82166000908152600a6020908152604080832081518154608094810282018501909352606081018381529093919284928491908401828280156200064957602002820191906000526020600020905b81548152602001906001019080831162000634575b5050509183525050600182015460208083019190915260029283015460409092019190915282015182516006549254939450909290919060ff1615620006d65760405162461bcd60e51b815260206004820181905260248201527f42656c6c756d3a20544f4b454e5f4352454154494f4e5f49535f50415553454460448201526064015b60405180910390fd5b82600003620007285760405162461bcd60e51b815260206004820152601c60248201527f42656c6c756d3a2043555256455f444f45535f4e4f545f4558495354000000006044820152606401620006cd565b670de0b6b3a7640000876001600160701b031610156200078b5760405162461bcd60e51b815260206004820152601c60248201527f42656c6c756d3a20544f54414c5f535550504c595f544f4f5f4c4f57000000006044820152606401620006cd565b620007a081681b1ae4d6e2ef500000620026f0565b341115620007e85760405162461bcd60e51b8152602060048201526014602482015273084cad8d8eada7440a89e9ebe9aaa8690be8aa8960631b6044820152606401620006cd565b80341015620008335760405162461bcd60e51b8152602060048201526016602482015275084cad8d8eada7440a89e9ebe9892a8a8988abe8aa8960531b6044820152606401620006cd565b6000898989604051620008469062002285565b62000854939291906200274e565b604051809103906000f08015801562000871573d6000803e3d6000fd5b506008805460018101825560009182527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30180546001600160a01b0319166001600160a01b0384161790559091508190612710620008d9876001600160701b038d1662002791565b620008e59190620027ab565b6001600160a01b03831660009081526009602052604081206003018290558651919250612710918791906200091e576200091e620027ce565b60200260200101518262000933919062002791565b6200093f9190620027ab565b6001600160a01b0383166000908152600960205260409020600281019190915580546001600160a01b031960ff8c16600160a01b02166001600160a81b03199091161733178155600401805489919061ff001916610100838015620009a857620009a86200265d565b0217905550336001600160a01b0383167fc53fd35d147910e8b0428fe8d1bc5aaef0bc4af4d778ba5d10c55de9ad1349728b8b8015620009ec57620009ec6200265d565b6040805160ff909316835260208301919091520160405180910390a3836004600082825462000a1c9190620026f0565b909155505034841462000a435762000a43823362000a3b8734620027e4565b600062001580565b5050505050505062000a5460018055565b5050505050565b62000a6562001526565b6802b5e3af16b188000081111562000ab75760405162461bcd60e51b8152602060048201526014602482015273084cad8d8eada74408c8a8abea89e9ebe90928e960631b6044820152606401620006cd565b600655565b6008818154811062000acd57600080fd5b6000918252602090912001546001600160a01b0316905081565b62000af162001526565b603281111562000b445760405162461bcd60e51b815260206004820152601860248201527f42656c6c756d3a2050455243454e545f544f4f5f4849474800000000000000006044820152606401620006cd565b600a81101562000b975760405162461bcd60e51b815260206004820152601760248201527f42656c6c756d3a2050455243454e545f544f4f5f4c4f570000000000000000006044820152606401620006cd565b600755565b62000ba662001526565b6103e881111562000bfa5760405162461bcd60e51b815260206004820152601e60248201527f42656c6c756d3a204d4947524154494f4e5f4645455f544f4f5f4849474800006044820152606401620006cd565b600355565b62000c0962001526565b60fa81111562000c535760405162461bcd60e51b8152602060048201526014602482015273084cad8d8eada74408c8a8abea89e9ebe90928e960631b6044820152606401620006cd565b600555565b62000c6262001555565b6001600160a01b0383166000908152600960205260408120600381015490910362000cd05760405162461bcd60e51b815260206004820152601c60248201527f42656c6c756d3a20544f4b454e5f444f45535f4e4f545f4558495354000000006044820152606401620006cd565b600481015460ff161562000d275760405162461bcd60e51b815260206004820152601e60248201527f42656c6c756d3a20494e53554646494349454e545f4c495155494449545900006044820152606401620006cd565b62000d3e6001600160a01b038516333086620019ac565b8054600160a01b900460ff166000908152600a602090815260408083208054825181850281018501909352808352919290919083018282801562000da257602002820191906000526020600020905b81548152602001906001019080831162000d8d575b505050506001840154600285015460038601549394506000938493505b8884101562000f1857600062000dd8846107d062002791565b62000de690612710620026f0565b62000df360028462002791565b62000dff9190620027ab565b9050600062000e0f868c620027e4565b905060008490506000612710858b898151811062000e315762000e31620027ce565b602002602001015162000e45919062002791565b62000e519190620027ab565b90508062000e608484620026f0565b1162000ead578362000e7b670de0b6b3a76400008562002791565b62000e879190620027ab565b62000e93908a620026f0565b985062000ea18387620026f0565b95505050505062000f18565b600062000ebb8383620027e4565b905062000ec9818a620026f0565b98508462000ee0670de0b6b3a76400008362002791565b62000eec9190620027ab565b62000ef8908b620026f0565b99508762000f0681620027fa565b98505060009650505050505062000dbf565b8488111562000f635760405162461bcd60e51b815260206004820152601660248201527510995b1b1d5b4e8814d31254141051d157d31253525560521b6044820152606401620006cd565b6702c68af0bb14000085101562000fbd5760405162461bcd60e51b815260206004820152601c60248201527f42656c6c756d3a20494e53554646494349454e545f4554485f4f5554000000006044820152606401620006cd565b60018701839055600287018290556005546000906127109062000fe1908862002791565b62000fed9190620027ab565b90508060046000828254620010039190620026f0565b90915550620010219050620010198288620027e4565b339062001a1b565b604080518b81526000602082018190528183015260608101889052905133916001600160a01b038e16917feae13466a4e0ed2b9f8778664bef183cecabb5006850f4b17cc094d54ce3a3e89181900360800190a350505050505050506200108760018055565b505050565b6200109662001526565b620010a2600062001abe565b565b620010ae62001526565b600280546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b620010e062001526565b60ff82166000908152600a602052604090206001015415620011455760405162461bcd60e51b815260206004820152601c60248201527f42656c6c756d3a2043555256455f414c52454144595f494e5f555345000000006044820152606401620006cd565b80516000908190815b8181101562001277578481815181106200116c576200116c620027ce565b6020026020010151600003620011bb5760405162461bcd60e51b81526020600482015260136024820152722132b6363ab69d1024a72b20a624a22fa124a760691b6044820152606401620006cd565b848181518110620011d057620011d0620027ce565b602002602001015184620011e59190620026f0565b93506000612710620011fa6107d08462002791565b6200120890612710620026f0565b6200121c90670de0b6b3a764000062002791565b620012289190620027ab565b905080868381518110620012405762001240620027ce565b602002602001015162001254919062002791565b620012609085620026f0565b935050806200126f9062002814565b90506200114e565b506127108314620012d65760405162461bcd60e51b815260206004820152602260248201527f42656c6c756d3a20494e56414c49445f544f54414c5f4449535452494255544960448201526127a760f11b6064820152608401620006cd565b6000612710806107d0620012ec600186620027e4565b620012f8919062002791565b620013049190620026f0565b6200131890670de0b6b3a764000062002791565b620013249190620027ab565b90506000620013368261271062002791565b90506000620013468583620026f0565b620013548361271062002791565b620013609190620027ab565b90506040518060600160405280888152602001828152602001600287620013889190620027ab565b905260ff89166000908152600a60209081526040909120825180519192620013b69284929091019062002293565b50602082015160018201556040918201516002909101555160ff8916907f692761be1e34ff0280587cdf866deb367e85f7b32ff1d5ac3bbfdd944e5e567490600090a25050505050505050565b60045460008190036200144e5760405162461bcd60e51b8152602060048201526012602482015271139bc81999595cc81d1bc818dbdb1b1958dd60721b6044820152606401620006cd565b6000600455600254620014709061010090046001600160a01b03168262001a1b565b50565b6200147d62001555565b670de0b6b3a7640000341015620014c95760405162461bcd60e51b815260206004820152600f60248201526e42656c6c756d3a20544f4f5f4c4f5760881b6044820152606401620006cd565b620014d78233348462001580565b620014e160018055565b5050565b620014ef62001526565b6001600160a01b0381166200151b57604051631e4fbdf760e01b815260006004820152602401620006cd565b620014708162001abe565b6000546001600160a01b03163314620010a25760405163118cdaa760e01b8152336004820152602401620006cd565b6002600154036200157957604051633ee5aeb560e01b815260040160405180910390fd5b6002600155565b6001600160a01b03841660009081526009602052604081206003810154909103620015ee5760405162461bcd60e51b815260206004820152601c60248201527f42656c6c756d3a20544f4b454e5f444f45535f4e4f545f4558495354000000006044820152606401620006cd565b600481015460ff1615620016405760405162461bcd60e51b815260206004820152601860248201527710995b1b1d5b4e881053149150511657d310555390d2115160421b6044820152606401620006cd565b8054600160a01b900460ff166000908152600a6020908152604080832080548251818502810185019093528083529192909190830182828015620016a457602002820191906000526020600020905b8154815260200190600101908083116200168f575b50505050509050600061271060055486620016c0919062002791565b620016cc9190620027ab565b90506000620016dc8287620027e4565b600185015460028601546003870154929350600092839291905b85841015620018725760006200170f846107d062002791565b6200171d90612710620026f0565b6200172a60028462002791565b620017369190620027ab565b90506000620017468689620027e4565b905083670de0b6b3a76400006200175e848462002791565b6200176a9190620027ab565b811115620017cb576000670de0b6b3a764000062001789848662002791565b620017959190620027ab565b9050620017a38389620026f0565b9750620017b1818a620026f0565b9850620017bf8183620027e4565b95505050505062001872565b82620017e0670de0b6b3a76400008362002791565b620017ec9190620027ab565b620017f89088620026f0565b9650620018068189620026f0565b9750620018138662002814565b95508a518610156200186057612710848c8881518110620018385762001838620027ce565b60200260200101516200184c919062002791565b620018589190620027ab565b945062001869565b50505062001872565b505050620016f6565b848a1115620018bd5760405162461bcd60e51b815260206004820152601660248201527510995b1b1d5b4e8814d31254141051d157d31253525560521b6044820152606401620006cd565b600189018390556002890182905560048054889190600090620018e2908490620026f0565b90915550620018fe90506001600160a01b038e168d8762001b0e565b8b6001600160a01b03168d6001600160a01b03167feae13466a4e0ed2b9f8778664bef183cecabb5006850f4b17cc094d54ce3a3e86000888f600060405162001960949392919093845260208401929092526040830152606082015260800190565b60405180910390a3875183106200199d5762001992620019818588620027e4565b6001600160a01b038e169062001a1b565b6200199d8d62001b41565b50505050505050505050505050565b6040516001600160a01b03848116602483015283811660448301526064820183905262001a159186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b03838183161783525050505062002099565b50505050565b8047101562001a475760405163cf47918160e01b815247600482015260248101829052604401620006cd565b6000826001600160a01b03168260405160006040518083038185875af1925050503d806000811462001a96576040519150601f19603f3d011682016040523d82523d6000602084013e62001a9b565b606091505b5050905080620010875760405163d6bda27560e01b815260040160405180910390fd5b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6040516001600160a01b038381166024830152604482018390526200108791859182169063a9059cbb90606401620019e2565b6001600160a01b03811660009081526009602052604090206004015460ff161562001baa5760405162461bcd60e51b815260206004820152601860248201527710995b1b1d5b4e881053149150511657d310555390d2115160421b6044820152606401620006cd565b806001600160a01b031663715018a66040518163ffffffff1660e01b8152600401600060405180830381600087803b15801562001be657600080fd5b505af115801562001bfb573d6000803e3d6000fd5b50506040516370a0823160e01b8152306004820152600092506001600160a01b03841691506370a0823190602401602060405180830381865afa15801562001c47573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001c6d919062002830565b6001600160a01b038316600090815260096020908152604080832054600160a01b900460ff168352600a909152812060020154600354929350916127109062001cb7908462002791565b62001cc39190620027ab565b9050801562001ce657806004600082825462001ce09190620026f0565b90915550505b60008062001d1f6001600160a01b0387167f00000000000000000000000095a7e403d7cf20f675ff9273d66e94d35ba49fa3876200210f565b60007f00000000000000000000000095a7e403d7cf20f675ff9273d66e94d35ba49fa390506000816001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa15801562001d85573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001dab91906200284a565b90506000826001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa15801562001dee573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001e1491906200284a565b60405163e6a4390560e01b81526001600160a01b038b8116600483015280831660248301529192509083169063e6a4390590604401602060405180830381865afa15801562001e67573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001e8d91906200284a565b94506001600160a01b03851662001f18576040516364e329cb60e11b81526001600160a01b038a81166004830152828116602483015283169063c9c65396906044016020604051808303816000875af115801562001eef573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001f1591906200284a565b94505b6000898660075460405162001f2d90620022e3565b6001600160a01b0393841681529290911660208301526040820152606001604051809103906000f08015801562001f68573d6000803e3d6000fd5b5094508490506001600160a01b03841663f305d71962001f89898b620027e4565b6040516001600160e01b031960e084901b1681526001600160a01b03808f166004830152602482018e90526000604483018190526064830152891660848201524260a482015260c40160606040518083038185885af115801562001ff1573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906200201891906200286a565b5050506001600160a01b038a81166000818152600b6020908152604080832080546001600160a01b0319168b87169081179091556009909252808320600401805460ff1916600117905551938a16939092917f937f456c07a61f36132d04df1c2826dd375336feecdd370ddaf00f25342e893c91a450505050505050505050565b600080602060008451602086016000885af180620020bd576040513d6000823e3d81fd5b50506000513d91508115620020d7578060011415620020e4565b6001600160a01b0384163b155b1562001a1557604051635274afe760e01b81526001600160a01b0385166004820152602401620006cd565b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301526000919085169063dd62ed3e90604401602060405180830381865afa15801562002160573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002186919062002830565b905062001a1584846200219a8585620026f0565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052620021ed848262002231565b62001a15576040516001600160a01b038481166024830152600060448301526200222591869182169063095ea7b390606401620019e2565b62001a15848262002099565b6000806000806020600086516020880160008a5af192503d9150600051905082801562002279575081156200226a578060011462002279565b6000866001600160a01b03163b115b93505050505b92915050565b610f2f806200289a83390190565b828054828255906000526020600020908101928215620022d1579160200282015b82811115620022d1578251825591602001919060010190620022b4565b50620022df929150620022f1565b5090565b610b6580620037c983390190565b5b80821115620022df5760008155600101620022f2565b803560ff811681146200231a57600080fd5b919050565b6000602082840312156200233257600080fd5b6200233d8262002308565b9392505050565b6000602082840312156200235757600080fd5b813580151581146200233d57600080fd5b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715620023aa57620023aa62002368565b604052919050565b600082601f830112620023c457600080fd5b813567ffffffffffffffff811115620023e157620023e162002368565b620023f6601f8201601f19166020016200237e565b8181528460208386010111156200240c57600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a086880312156200244257600080fd5b853567ffffffffffffffff808211156200245b57600080fd5b6200246989838a01620023b2565b965060208801359150808211156200248057600080fd5b506200248f88828901620023b2565b94505060408601356001600160701b0381168114620024ad57600080fd5b9250620024bd6060870162002308565b9150608086013560018110620024d257600080fd5b809150509295509295909350565b6001600160a01b03811681146200147057600080fd5b6000602082840312156200250957600080fd5b81356200233d81620024e0565b6000602082840312156200252957600080fd5b5035919050565b6000806000606084860312156200254657600080fd5b83356200255381620024e0565b95602085013595506040909401359392505050565b600080604083850312156200257c57600080fd5b620025878362002308565b915060208084013567ffffffffffffffff80821115620025a657600080fd5b818601915086601f830112620025bb57600080fd5b813581811115620025d057620025d062002368565b8060051b9150620025e38483016200237e565b8181529183018401918481019089841115620025fe57600080fd5b938501935b838510156200261e5784358252938501939085019062002603565b8096505050505050509250929050565b600080604083850312156200264257600080fd5b82356200264f81620024e0565b946020939093013593505050565b634e487b7160e01b600052602160045260246000fd5b6001600160a01b038816815260ff8716602082015260408101869052606081018590526080810184905282151560a082015260e0810160018310620026c857634e487b7160e01b600052602160045260246000fd5b8260c083015298975050505050505050565b634e487b7160e01b600052601160045260246000fd5b808201808211156200227f576200227f620026da565b6000815180845260005b818110156200272e5760208185018101518683018201520162002710565b506000602082860101526020601f19601f83011685010191505092915050565b60608152600062002763606083018662002706565b828103602084015262002777818662002706565b9150506001600160701b0383166040830152949350505050565b80820281158282048414176200227f576200227f620026da565b600082620027c957634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b818103818111156200227f576200227f620026da565b6000816200280c576200280c620026da565b506000190190565b600060018201620028295762002829620026da565b5060010190565b6000602082840312156200284357600080fd5b5051919050565b6000602082840312156200285d57600080fd5b81516200233d81620024e0565b6000806000606084860312156200288057600080fd5b835192506020840151915060408401519050925092509256fe60806040523480156200001157600080fd5b5060405162000f2f38038062000f2f833981016040819052620000349162000406565b338383600362000045838262000522565b50600462000054828262000522565b5050506001600160a01b0381166200008757604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b6200009281620000b1565b50620000a8336001600160701b03831662000103565b50505062000616565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0382166200012f5760405163ec442f0560e01b8152600060048201526024016200007e565b6200013d6000838362000141565b5050565b6200014e8383836200020e565b6000620001636005546001600160a01b031690565b90506001600160a01b038116156200020857806001600160a01b0316846001600160a01b03161480620001a75750806001600160a01b0316836001600160a01b0316145b80620001ba57506001600160a01b038416155b620002085760405162461bcd60e51b815260206004820152601b60248201527f42656c6c756d3a2043414e4e4f545f5452414e534645525f594554000000000060448201526064016200007e565b50505050565b6001600160a01b0383166200023d578060026000828254620002319190620005ee565b90915550620002b19050565b6001600160a01b03831660009081526020819052604090205481811015620002925760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016200007e565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b038216620002cf57600280548290039055620002ee565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516200033491815260200190565b60405180910390a3505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200036957600080fd5b81516001600160401b038082111562000386576200038662000341565b604051601f8301601f19908116603f01168101908282118183101715620003b157620003b162000341565b81604052838152602092508683858801011115620003ce57600080fd5b600091505b83821015620003f25785820183015181830184015290820190620003d3565b600093810190920192909252949350505050565b6000806000606084860312156200041c57600080fd5b83516001600160401b03808211156200043457600080fd5b620004428783880162000357565b945060208601519150808211156200045957600080fd5b50620004688682870162000357565b604086015190935090506001600160701b03811681146200048857600080fd5b809150509250925092565b600181811c90821680620004a857607f821691505b602082108103620004c957634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200051d57600081815260208120601f850160051c81016020861015620004f85750805b601f850160051c820191505b81811015620005195782815560010162000504565b5050505b505050565b81516001600160401b038111156200053e576200053e62000341565b62000556816200054f845462000493565b84620004cf565b602080601f8311600181146200058e5760008415620005755750858301515b600019600386901b1c1916600185901b17855562000519565b600085815260208120601f198616915b82811015620005bf578886015182559484019460019091019084016200059e565b5085821015620005de5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b808201808211156200061057634e487b7160e01b600052601160045260246000fd5b92915050565b61090980620006266000396000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c8063715018a611610071578063715018a6146101575780638da5cb5b1461016157806395d89b411461017c578063a9059cbb14610184578063dd62ed3e14610197578063f2fde38b146101d057600080fd5b806306fdde03146100b9578063095ea7b3146100d757806318160ddd146100fa57806323b872dd1461010c578063313ce5671461011f57806370a082311461012e575b600080fd5b6100c16101e3565b6040516100ce9190610753565b60405180910390f35b6100ea6100e53660046107bd565b610275565b60405190151581526020016100ce565b6002545b6040519081526020016100ce565b6100ea61011a3660046107e7565b61028f565b604051601281526020016100ce565b6100fe61013c366004610823565b6001600160a01b031660009081526020819052604090205490565b61015f6102b3565b005b6005546040516001600160a01b0390911681526020016100ce565b6100c16102c7565b6100ea6101923660046107bd565b6102d6565b6100fe6101a5366004610845565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b61015f6101de366004610823565b6102e4565b6060600380546101f290610878565b80601f016020809104026020016040519081016040528092919081815260200182805461021e90610878565b801561026b5780601f106102405761010080835404028352916020019161026b565b820191906000526020600020905b81548152906001019060200180831161024e57829003601f168201915b5050505050905090565b600033610283818585610327565b60019150505b92915050565b60003361029d858285610339565b6102a88585856103b7565b506001949350505050565b6102bb610416565b6102c56000610443565b565b6060600480546101f290610878565b6000336102838185856103b7565b6102ec610416565b6001600160a01b03811661031b57604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b61032481610443565b50565b6103348383836001610495565b505050565b6001600160a01b0383811660009081526001602090815260408083209386168352929052205460001981146103b157818110156103a257604051637dc7a0d960e11b81526001600160a01b03841660048201526024810182905260448101839052606401610312565b6103b184848484036000610495565b50505050565b6001600160a01b0383166103e157604051634b637e8f60e11b815260006004820152602401610312565b6001600160a01b03821661040b5760405163ec442f0560e01b815260006004820152602401610312565b61033483838361056a565b6005546001600160a01b031633146102c55760405163118cdaa760e01b8152336004820152602401610312565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0384166104bf5760405163e602df0560e01b815260006004820152602401610312565b6001600160a01b0383166104e957604051634a1406b160e11b815260006004820152602401610312565b6001600160a01b03808516600090815260016020908152604080832093871683529290522082905580156103b157826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161055c91815260200190565b60405180910390a350505050565b610575838383610629565b60006105896005546001600160a01b031690565b90506001600160a01b038116156103b157806001600160a01b0316846001600160a01b031614806105cb5750806001600160a01b0316836001600160a01b0316145b806105dd57506001600160a01b038416155b6103b15760405162461bcd60e51b815260206004820152601b60248201527f42656c6c756d3a2043414e4e4f545f5452414e534645525f59455400000000006044820152606401610312565b6001600160a01b03831661065457806002600082825461064991906108b2565b909155506106c69050565b6001600160a01b038316600090815260208190526040902054818110156106a75760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401610312565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b0382166106e257600280548290039055610701565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161074691815260200190565b60405180910390a3505050565b600060208083528351808285015260005b8181101561078057858101830151858201604001528201610764565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b03811681146107b857600080fd5b919050565b600080604083850312156107d057600080fd5b6107d9836107a1565b946020939093013593505050565b6000806000606084860312156107fc57600080fd5b610805846107a1565b9250610813602085016107a1565b9150604084013590509250925092565b60006020828403121561083557600080fd5b61083e826107a1565b9392505050565b6000806040838503121561085857600080fd5b610861836107a1565b915061086f602084016107a1565b90509250929050565b600181811c9082168061088c57607f821691505b6020821081036108ac57634e487b7160e01b600052602260045260246000fd5b50919050565b8082018082111561028957634e487b7160e01b600052601160045260246000fdfea26469706673582212202004a68e9b68f912633e70d3d1000aa6fd800e6fbd5831c9ea08498a638d4b7d64736f6c6343000814003361010060405234801561001157600080fd5b50604051610b65380380610b658339810160408190526100309161006f565b600160005560e0526001600160a01b039182166080521660a0524260c0526100ab565b80516001600160a01b038116811461006a57600080fd5b919050565b60008060006060848603121561008457600080fd5b61008d84610053565b925061009b60208501610053565b9150604084015190509250925092565b60805160a05160c05160e051610a436101226000396000818160be0152818161028101526103910152600081816101390152610715015260008181610160015281816102d6015281816103b401526107ae0152600081816101f60152818161051a015281816105e7015261066b0152610a436000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c806378e979251161007157806378e9792514610134578063a8aa1b311461015b578063b6b55f251461019a578063b97dd9e2146101ad578063ce7c2ac2146101b5578063fc0c546a146101f157600080fd5b80632172ecc7146100b957806328fd3198146100f35780632e1a7d4d14610106578063372500ab1461011b5780633a98ef39146101235780635b0a38431461012c575b600080fd5b6100e07f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b6100e0610101366004610930565b610218565b610119610114366004610960565b61045a565b005b610119610584565b6100e060015481565b6101196105a1565b6100e07f000000000000000000000000000000000000000000000000000000000000000081565b6101827f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016100ea565b6101196101a8366004610960565b610656565b6100e061070b565b6101dc6101c3366004610930565b6002602052600090815260409020805460019091015482565b604080519283526020830191909152016100ea565b6101827f000000000000000000000000000000000000000000000000000000000000000081565b60008061022361070b565b6001600160a01b0384166000908152600260209081526040808320815180830190925280548252600190810154928201929092529054929350919081900361027057506000949350505050565b828260200151101561044f576102a87f000000000000000000000000000000000000000000000000000000000000000061271061098f565b60208301516102b790856109b1565b106103665781516040516370a0823160e01b81523060048201528291907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610325573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061034991906109ca565b61035391906109e3565b61035d919061098f565b95945050505050565b6127108183602001518561037a91906109b1565b84516040516370a0823160e01b81523060048201527f000000000000000000000000000000000000000000000000000000000000000091907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610403573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042791906109ca565b61043191906109e3565b61043b91906109e3565b61044591906109e3565b610353919061098f565b506000949350505050565b610462610749565b336000908152600260205260409020548111156104c65760405162461bcd60e51b815260206004820152601a60248201527f42656c6c756d3a204e4f545f454e4f5547485f42414c414e434500000000000060448201526064015b60405180910390fd5b6104cf33610773565b33600090815260026020526040812080548392906104ee9084906109b1565b92505081905550806001600082825461050791906109b1565b9091555061054190506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016338361081c565b60405181815233907f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65906020015b60405180910390a26105816001600055565b50565b61058c610749565b61059533610773565b61059f6001600055565b565b6105a9610749565b3360009081526002602052604081205460018054919283926105cc9084906109b1565b909155505033600081815260026020526040812055610616907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316908361081c565b60405181815233907f23d6711a1d031134a36921253c75aa59e967d38e369ac625992824315e204f209060200160405180910390a25061059f6001600055565b61065e610749565b6106936001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016333084610880565b61069c33610773565b33600090815260026020526040812080548392906106bb9084906109fa565b9250508190555080600160008282546106d491906109fa565b909155505060405181815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9060200161056f565b600061546061073a7f0000000000000000000000000000000000000000000000000000000000000000426109b1565b610744919061098f565b905090565b60026000540361076c57604051633ee5aeb560e01b815260040160405180910390fd5b6002600055565b600061077e82610218565b905061078861070b565b6001600160a01b038084166000908152600260205260409020600101919091556107d5907f000000000000000000000000000000000000000000000000000000000000000016838361081c565b816001600160a01b03167f1f89f96333d3133000ee447473151fa9606543368f02271c9d95ae14f13bcc678260405161081091815260200190565b60405180910390a25050565b6040516001600160a01b0383811660248301526044820183905261087b91859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506108bf565b505050565b6040516001600160a01b0384811660248301528381166044830152606482018390526108b99186918216906323b872dd90608401610849565b50505050565b600080602060008451602086016000885af1806108e2576040513d6000823e3d81fd5b50506000513d915081156108fa578060011415610907565b6001600160a01b0384163b155b156108b957604051635274afe760e01b81526001600160a01b03851660048201526024016104bd565b60006020828403121561094257600080fd5b81356001600160a01b038116811461095957600080fd5b9392505050565b60006020828403121561097257600080fd5b5035919050565b634e487b7160e01b600052601160045260246000fd5b6000826109ac57634e487b7160e01b600052601260045260246000fd5b500490565b818103818111156109c4576109c4610979565b92915050565b6000602082840312156109dc57600080fd5b5051919050565b80820281158282048414176109c4576109c4610979565b808201808211156109c4576109c461097956fea2646970667358221220955bc6c8d8c2763e1fc29ac56e899c2edf8a7b541ab4692218922a9d608208e664736f6c63430008140033a26469706673582212205c67fe3337fb2af1e194d684891b71be67dc9656f90a0d39f7910182c85c1b0564736f6c63430008140033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000003a7a1f256b6180d59f58efc080321a09d456ee9b00000000000000000000000095a7e403d7cf20f675ff9273d66e94d35ba49fa3
-----Decoded View---------------
Arg [0] : owner_ (address): 0x3A7A1f256b6180d59f58eFc080321A09D456Ee9b
Arg [1] : metropolisRouter_ (address): 0x95a7e403d7cF20F675fF9273D66e94d35ba49fA3
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000003a7a1f256b6180d59f58efc080321a09d456ee9b
Arg [1] : 00000000000000000000000095a7e403d7cf20f675ff9273d66e94d35ba49fa3
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.