More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 131 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Buy | 12046291 | 2 hrs ago | IN | 35 S | 0.00650014 | ||||
Buy | 12024388 | 5 hrs ago | IN | 11 S | 0.00617633 | ||||
Buy | 12010006 | 6 hrs ago | IN | 50 S | 0.0067358 | ||||
Buy | 12009964 | 6 hrs ago | IN | 50 S | 0.00650086 | ||||
Buy | 12009924 | 6 hrs ago | IN | 100 S | 0.00748856 | ||||
Buy | 12009838 | 6 hrs ago | IN | 150 S | 0.00772351 | ||||
Sell | 11982300 | 9 hrs ago | IN | 0 S | 0.00644358 | ||||
Sell | 11936057 | 14 hrs ago | IN | 0 S | 0.04541724 | ||||
Buy | 11926476 | 15 hrs ago | IN | 100 S | 0.05990105 | ||||
Buy | 11926475 | 15 hrs ago | IN | 30 S | 0.3562377 | ||||
Create Token | 11926473 | 15 hrs ago | IN | 6 S | 0.23746441 | ||||
Buy | 11926473 | 15 hrs ago | IN | 30 S | 0.3242526 | ||||
Sell | 11903962 | 18 hrs ago | IN | 0 S | 0.00636487 | ||||
Buy | 11894143 | 19 hrs ago | IN | 94 S | 0.00711749 | ||||
Buy | 11893538 | 19 hrs ago | IN | 245 S | 0.00748785 | ||||
Sell | 11889430 | 19 hrs ago | IN | 0 S | 0.00636487 | ||||
Buy | 11887505 | 19 hrs ago | IN | 5 S | 0.00629409 | ||||
Buy | 11882044 | 20 hrs ago | IN | 250 S | 0.00711749 | ||||
Buy | 11881734 | 20 hrs ago | IN | 100 S | 0.00711749 | ||||
Sell | 11865289 | 22 hrs ago | IN | 0 S | 0.04541724 | ||||
Buy | 11855379 | 23 hrs ago | IN | 100 S | 0.05990105 | ||||
Buy | 11855376 | 23 hrs ago | IN | 8 S | 0.3562377 | ||||
Create Token | 11855376 | 23 hrs ago | IN | 11 S | 0.16710974 | ||||
Buy | 11848375 | 23 hrs ago | IN | 100 S | 0.00734321 | ||||
Sell | 11848317 | 23 hrs ago | IN | 0 S | 0.00670692 |
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
11982300 | 9 hrs ago | 294.03 S | ||||
11936057 | 14 hrs ago | 98.01 S | ||||
11926473 | 15 hrs ago | Contract Creation | 0 S | |||
11903962 | 18 hrs ago | 92.1294 S | ||||
11889430 | 19 hrs ago | 245.025 S | ||||
11865289 | 22 hrs ago | 98.01 S | ||||
11855376 | 23 hrs ago | Contract Creation | 0 S | |||
11848317 | 23 hrs ago | 97.1025 S | ||||
11834066 | 25 hrs ago | 98.01 S | ||||
11834029 | 25 hrs ago | 19.11195 S | ||||
11833444 | 25 hrs ago | 247.6452 S | ||||
11833379 | 25 hrs ago | 29.403 S | ||||
11832047 | 25 hrs ago | 493.4237 S | ||||
11831940 | 25 hrs ago | 98.01 S | ||||
11831940 | 25 hrs ago | 246.11227142 S | ||||
11831823 | 25 hrs ago | 559.54037857 S | ||||
11825079 | 26 hrs ago | 550.69245 S | ||||
11820982 | 26 hrs ago | Contract Creation | 0 S | |||
11815342 | 27 hrs ago | 93.8487 S | ||||
11815339 | 27 hrs ago | 61.49714999 S | ||||
11810827 | 28 hrs ago | Contract Creation | 0 S | |||
11781602 | 31 hrs ago | 68.607 S | ||||
11781578 | 31 hrs ago | 49.005 S | ||||
11781549 | 31 hrs ago | 39.35021538 S | ||||
11774108 | 32 hrs ago | 114.59630769 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/Ownable2Step.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"; import "contracts/pharaoh/interfaces/IPharaohRouter.sol"; import "contracts/pharaoh/interfaces/IPharaohFactory.sol"; pragma solidity ^0.8.17; contract BellumFactory is Ownable2Step, 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 creatorRewards; // Addresses address payable public immutable METROPOLIS_ROUTER; address payable public immutable SHADOW_ROUTER; address private constant DEAD_ADDRESS = address(0xdead); // 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; address pair; uint8 curveIndex; uint256 currentIndex; uint256 currentValue; uint256 initialSupply; bool hasLaunched; Dex dex; } enum Dex { METROPOLIS, SHADOW } address[] public allTokens; mapping(address => Token) public tokens; mapping(uint8 => Curve) public curves; 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 msig, address metropolisRouter_, address shadowRouter_) Ownable(msig) { require(msig != address(0), "Zero address not allowed for owner"); require(metropolisRouter_ != address(0), "Zero address not allowed for router"); require(shadowRouter_ != address(0), "Zero address not allowed for router"); METROPOLIS_ROUTER = payable(metropolisRouter_); SHADOW_ROUTER = payable(shadowRouter_); feeReceiver = payable(msig); tradingFee = 100; // 1% migrationFee = 400; createFee = 1 ether; creatorRewards = 300; // 3% } 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; // Create pair initially address pair; if (dex == Dex.SHADOW) { address factory = IPharaohRouter(SHADOW_ROUTER).factory(); address weth = IPharaohRouter(SHADOW_ROUTER).WETH(); pair = IPharaohFactory(factory).createPair(t, weth, false); } else { address factory = IMetropolisRouter(METROPOLIS_ROUTER).factory(); address weth = IMetropolisRouter(METROPOLIS_ROUTER).WETH(); pair = IMetropolisFactory(factory).createPair(t, weth); } tokens[t].pair = pair; 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; } // Add liquidity Dex dex = tokens[token].dex; address pair = tokens[token].pair; if (dex == Dex.METROPOLIS) { IERC20(token).safeIncreaseAllowance(METROPOLIS_ROUTER, balance); (,, uint256 liquidity) = IMetropolisRouter(METROPOLIS_ROUTER).addLiquidityETH{value: avaxToLP - fee}( token, balance, 0, // slippage is unavoidable 0, // slippage is unavoidable address(this), block.timestamp ); uint256 toCreator = liquidity * creatorRewards / BASIS; IERC20(pair).safeTransfer(tokens[token].creator, toCreator); IERC20(pair).safeTransfer(DEAD_ADDRESS, liquidity - toCreator); } else if (dex == Dex.SHADOW) { IERC20(token).safeIncreaseAllowance(SHADOW_ROUTER, balance); IPharaohRouter(SHADOW_ROUTER).addLiquidityETH{value: avaxToLP - fee}( token, false, balance, 0, // slippage is unavoidable 0, // slippage is unavoidable DEAD_ADDRESS, block.timestamp ); } // Update Launch Status tokens[token].hasLaunched = true; emit CurveCompleted(token, address(0), 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 setCreateFee(uint256 createFee_) external onlyOwner { require(createFee_ <= 50 ether, "Bellum: FEE_TOO_HIGH"); createFee = createFee_; } function setCreatorRewards(uint256 creatorRewards_) external onlyOwner { require(creatorRewards_ <= 1000, "Bellum: CREATOR_REWARDS_TOO_HIGH"); creatorRewards = creatorRewards_; } // 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.0.0) (access/Ownable2Step.sol) pragma solidity ^0.8.20; import {Ownable} from "./Ownable.sol"; /** * @dev Contract module which provides access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is specified at deployment time in the constructor for `Ownable`. This * can later be changed with {transferOwnership} and {acceptOwnership}. * * This module is used through inheritance. It will make available all functions * from parent (Ownable). */ abstract contract Ownable2Step is Ownable { address private _pendingOwner; event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner); /** * @dev Returns the address of the pending owner. */ function pendingOwner() public view virtual returns (address) { return _pendingOwner; } /** * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual override onlyOwner { _pendingOwner = newOwner; emit OwnershipTransferStarted(owner(), newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner. * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual override { delete _pendingOwner; super._transferOwnership(newOwner); } /** * @dev The new owner accepts the ownership transfer. */ function acceptOwnership() public virtual { address sender = _msgSender(); if (pendingOwner() != sender) { revert OwnableUnauthorizedAccount(sender); } _transferOwnership(sender); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol) pragma solidity ^0.8.20; /** * @dev Standard ERC20 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 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 ERC721 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens. */ interface IERC721Errors { /** * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-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 ERC1155 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 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.0.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 ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. */ 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}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * 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: * ``` * 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.0.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 ERC20 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.0.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * ==== Security Considerations * * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be * considered as an intention to spend the allowance in any specific way. The second is that because permits have * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be * generally recommended is: * * ```solidity * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public { * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {} * doThing(..., value); * } * * function doThing(..., uint256 value) public { * token.safeTransferFrom(msg.sender, address(this), value); * ... * } * ``` * * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also * {SafeERC20-safeTransferFrom}). * * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so * contracts should have entry points that don't rely on permit. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. * * CAUTION: See Security Considerations above. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the 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.0.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; import {IERC20Permit} from "../extensions/IERC20Permit.sol"; import {Address} from "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 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 { using Address for address; /** * @dev An operation with an ERC20 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. */ 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. */ 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. */ 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 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). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data); if (returndata.length != 0 && !abi.decode(returndata, (bool))) { 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 silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol) pragma solidity ^0.8.20; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev The ETH balance of the account is not enough to perform the operation. */ error AddressInsufficientBalance(address account); /** * @dev There's no code at `target` (it is not a contract). */ error AddressEmptyCode(address target); /** * @dev A call to an address target failed. The target may have reverted. */ error FailedInnerCall(); /** * @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 AddressInsufficientBalance(address(this)); } (bool success, ) = recipient.call{value: amount}(""); if (!success) { revert FailedInnerCall(); } } /** * @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 * {FailedInnerCall} 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 AddressInsufficientBalance(address(this)); } (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 {FailedInnerCall}) 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 {FailedInnerCall} 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 {FailedInnerCall}. */ 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 /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert FailedInnerCall(); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (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 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); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; interface IPharaohFactory { function params() external view returns (address token0, address token1, bool stable, address voter); function allPairsLength() external view returns (uint256); function isPair(address pair) external view returns (bool); function pairCodeHash() external view returns (bytes32); function getPair( address tokenA, address token, bool stable ) external view returns (address); function createPair( address tokenA, address tokenB, bool stable ) external returns (address pair); function voter() external view returns (address); function allPairs(uint256) external view returns (address); function pairFee(address) external view returns (uint256); function getFee(bool) external view returns (uint256); function isPaused() external view returns (bool); function acceptFeeManager() external; function setFeeManager(address _feeManager) external; function setPairFee(address _pair, uint256 _fee) external; function setFee(bool _stable, uint256 _fee) external; }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.17; interface IPharaohRouter { function pairFor( address tokenA, address tokenB, bool stable ) external view returns (address pair); function factory() external pure returns (address); function WETH() external pure returns (address); function addLiquidityETH( address token, bool stable, uint256 amountTokenDesired, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline ) external payable returns ( uint256 amountToken, uint256 amountETH, uint256 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
Contract ABI
API[{"inputs":[{"internalType":"address","name":"msig","type":"address"},{"internalType":"address","name":"metropolisRouter_","type":"address"},{"internalType":"address","name":"shadowRouter_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[],"name":"FailedInnerCall","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":"OwnershipTransferStarted","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":[],"name":"SHADOW_ROUTER","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","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":[],"name":"creatorRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"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":"uint256","name":"creatorRewards_","type":"uint256"}],"name":"setCreatorRewards","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":"address","name":"","type":"address"}],"name":"tokens","outputs":[{"internalType":"address","name":"creator","type":"address"},{"internalType":"address","name":"pair","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
60c06040523480156200001157600080fd5b50604051620040f2380380620040f283398101604081905262000034916200025d565b826001600160a01b0381166200006557604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b6200007081620001d2565b5060016002556001600160a01b038316620000d95760405162461bcd60e51b815260206004820152602260248201527f5a65726f2061646472657373206e6f7420616c6c6f77656420666f72206f776e60448201526132b960f11b60648201526084016200005c565b6001600160a01b0382166200012c5760405162461bcd60e51b81526020600482015260236024820152600080516020620040d28339815191526044820152623a32b960e91b60648201526084016200005c565b6001600160a01b0381166200017f5760405162461bcd60e51b81526020600482015260236024820152600080516020620040d28339815191526044820152623a32b960e91b60648201526084016200005c565b6001600160a01b03918216608052811660a05260038054610100600160a81b03191661010093909216929092021790556064600655610190600455670de0b6b3a764000060075561012c600855620002a7565b600180546001600160a01b0319169055620001ed81620001f0565b50565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b03811681146200025857600080fd5b919050565b6000806000606084860312156200027357600080fd5b6200027e8462000240565b92506200028e6020850162000240565b91506200029e6040850162000240565b90509250925092565b60805160a051613dcd620003056000396000818161035201528181610ab701528181610b40015281816122d101526123010152600081816102d301528181610c5301528181610cdc0152818161213401526121660152613dcd6000f3fe608060405260043610620001db5760003560e01c8063715018a611620000ff578063b3f006741162000095578063dbb80e42116200006c578063dbb80e42146200054d578063e30c39781462000564578063e48603391462000584578063f2fde38b146200061057600080fd5b8063b3f0067414620004f7578063c8796572146200051e578063cce7ec13146200053657600080fd5b80638da5cb5b11620000d65780638da5cb5b146200048257806397506cd214620004a2578063a3400a6614620004ba578063b2db919b14620004df57600080fd5b8063715018a6146200042d57806379ba509714620004455780637c08b964146200045d57600080fd5b806356f433521162000175578063634282af116200014c578063634282af146200039957806366f20b4f14620003be5780636a1db1bf14620003e35780636a272462146200040857600080fd5b806356f4335214620003265780635b7ff11e146200033e57806362914849146200037457600080fd5b8063240976bf11620001b6578063240976bf1462000283578063317e778514620002a85780633f23704614620002bf57806346dcab55146200030e57600080fd5b80631d08c0e114620001e057806320e1fc8c1462000207578063224438d1146200025c575b600080fd5b348015620001ed57600080fd5b5062000205620001ff3660046200287f565b62000635565b005b3480156200021457600080fd5b506200024262000226366004620028b0565b600b602052600090815260409020600181015460029091015482565b604080519283526020830191909152015b60405180910390f35b3480156200026957600080fd5b506200027460055481565b60405190815260200162000253565b3480156200029057600080fd5b5062000205620002a2366004620028dd565b6200069c565b62000205620002b9366004620029be565b620006b9565b348015620002cc57600080fd5b50620002f57f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200162000253565b3480156200031b57600080fd5b506200027460045481565b3480156200033357600080fd5b506200027460065481565b3480156200034b57600080fd5b50620002f57f000000000000000000000000000000000000000000000000000000000000000081565b3480156200038157600080fd5b5062000205620003933660046200287f565b62000ebe565b348015620003a657600080fd5b50620002f5620003b83660046200287f565b62000f1f565b348015620003cb57600080fd5b5062000205620003dd3660046200287f565b62000f4a565b348015620003f057600080fd5b5062000205620004023660046200287f565b62000fad565b3480156200041557600080fd5b50620002056200042736600462002a8b565b62001006565b3480156200043a57600080fd5b50620002056200143e565b3480156200045257600080fd5b506200020562001456565b3480156200046a57600080fd5b50620002056200047c36600462002ac3565b6200149e565b3480156200048f57600080fd5b506000546001600160a01b0316620002f5565b348015620004af57600080fd5b506200027460085481565b348015620004c757600080fd5b5062000205620004d936600462002ae3565b620014d0565b348015620004ec57600080fd5b506200027460075481565b3480156200050457600080fd5b50600354620002f59061010090046001600160a01b031681565b3480156200052b57600080fd5b5062000205620017fd565b620002056200054736600462002ba9565b6200186a565b3480156200055a57600080fd5b5060095462000274565b3480156200057157600080fd5b506001546001600160a01b0316620002f5565b3480156200059157600080fd5b50620005fa620005a336600462002ac3565b600a602052600090815260409020805460018201546002830154600384015460048501546005909501546001600160a01b03948516959484169460ff600160a01b9095048516949091808216916101009091041688565b6040516200025398979695949392919062002bee565b3480156200061d57600080fd5b50620002056200062f36600462002ac3565b620018dd565b6200063f62001951565b6103e8811115620006975760405162461bcd60e51b815260206004820181905260248201527f42656c6c756d3a2043524541544f525f524557415244535f544f4f5f4849474860448201526064015b60405180910390fd5b600855565b620006a662001951565b6003805460ff1916911515919091179055565b620006c362001980565b60ff82166000908152600b6020908152604080832081518154608094810282018501909352606081018381529093919284928491908401828280156200072957602002820191906000526020600020905b81548152602001906001019080831162000714575b505050918352505060018201546020808301919091526002909201546040909101528101518151600754600354939450919290919060ff1615620007b05760405162461bcd60e51b815260206004820181905260248201527f42656c6c756d3a20544f4b454e5f4352454154494f4e5f49535f50415553454460448201526064016200068e565b82600003620008025760405162461bcd60e51b815260206004820152601c60248201527f42656c6c756d3a2043555256455f444f45535f4e4f545f45584953540000000060448201526064016200068e565b670de0b6b3a7640000876001600160701b03161015620008655760405162461bcd60e51b815260206004820152601c60248201527f42656c6c756d3a20544f54414c5f535550504c595f544f4f5f4c4f570000000060448201526064016200068e565b6200087a81681b1ae4d6e2ef50000062002c75565b341115620008c25760405162461bcd60e51b8152602060048201526014602482015273084cad8d8eada7440a89e9ebe9aaa8690be8aa8960631b60448201526064016200068e565b803410156200090d5760405162461bcd60e51b8152602060048201526016602482015275084cad8d8eada7440a89e9ebe9892a8a8988abe8aa8960531b60448201526064016200068e565b600089898960405162000920906200280a565b6200092e9392919062002cdf565b604051809103906000f0801580156200094b573d6000803e3d6000fd5b506009805460018101825560009182527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0180546001600160a01b0319166001600160a01b0384161790559091508190612710620009b3876001600160701b038d1662002d22565b620009bf919062002d3c565b6001600160a01b0383166000908152600a60205260408120600401829055865191925061271091879190620009f857620009f862002d5f565b60200260200101518262000a0d919062002d22565b62000a19919062002d3c565b6001600160a01b0383166000908152600a6020526040902060038101919091556001808201805460ff8d16600160a01b0260ff60a01b1990911617905581546001600160a01b03191633178255600590910180548a9261ff00199091169061010090849081111562000a8f5762000a8f62002bd8565b02179055506000600189600181111562000aad5762000aad62002bd8565b0362000c4f5760007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000b14573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000b3a919062002d75565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000b9d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000bc3919062002d75565b6040516320b7f73960e21b81526001600160a01b038781166004830152808316602483015260006044830152919250908316906382dfdce4906064016020604051808303816000875af115801562000c1f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000c45919062002d75565b9250505062000ddf565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000cb0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000cd6919062002d75565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000d39573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d5f919062002d75565b6040516364e329cb60e11b81526001600160a01b03878116600483015280831660248301529192509083169063c9c65396906044016020604051808303816000875af115801562000db4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000dda919062002d75565b925050505b6001600160a01b038381166000818152600a60205260409020600190810180546001600160a01b0319169385169390931790925533917fc53fd35d147910e8b0428fe8d1bc5aaef0bc4af4d778ba5d10c55de9ad134972908d908d9081111562000e4d5762000e4d62002bd8565b6040805160ff909316835260208301919091520160405180910390a3846005600082825462000e7d919062002c75565b909155505034851462000ea45762000ea4833362000e9c883462002d95565b6000620019a9565b505050505050505062000eb76001600255565b5050505050565b62000ec862001951565b6802b5e3af16b188000081111562000f1a5760405162461bcd60e51b8152602060048201526014602482015273084cad8d8eada74408c8a8abea89e9ebe90928e960631b60448201526064016200068e565b600755565b6009818154811062000f3057600080fd5b6000918252602090912001546001600160a01b0316905081565b62000f5462001951565b6103e881111562000fa85760405162461bcd60e51b815260206004820152601e60248201527f42656c6c756d3a204d4947524154494f4e5f4645455f544f4f5f48494748000060448201526064016200068e565b600455565b62000fb762001951565b60fa811115620010015760405162461bcd60e51b8152602060048201526014602482015273084cad8d8eada74408c8a8abea89e9ebe90928e960631b60448201526064016200068e565b600655565b6200101062001980565b6001600160a01b0383166000908152600a6020526040812060048101549091036200107e5760405162461bcd60e51b815260206004820152601c60248201527f42656c6c756d3a20544f4b454e5f444f45535f4e4f545f45584953540000000060448201526064016200068e565b600581015460ff1615620010d55760405162461bcd60e51b815260206004820152601e60248201527f42656c6c756d3a20494e53554646494349454e545f4c4951554944495459000060448201526064016200068e565b620010ec6001600160a01b03851633308662001dd8565b6001810154600160a01b900460ff166000908152600b60209081526040808320805482518185028101850190935280835291929091908301828280156200115357602002820191906000526020600020905b8154815260200190600101908083116200113e575b505050506002840154600385015460048601549394506000938493505b88841015620012c957600062001189846107d062002d22565b620011979061271062002c75565b620011a460028462002d22565b620011b0919062002d3c565b90506000620011c0868c62002d95565b905060008490506000612710858b8981518110620011e257620011e262002d5f565b6020026020010151620011f6919062002d22565b62001202919062002d3c565b90508062001211848462002c75565b116200125e57836200122c670de0b6b3a76400008562002d22565b62001238919062002d3c565b62001244908a62002c75565b985062001252838762002c75565b955050505050620012c9565b60006200126c838362002d95565b90506200127a818a62002c75565b98508462001291670de0b6b3a76400008362002d22565b6200129d919062002d3c565b620012a9908b62002c75565b995087620012b78162002dab565b98505060009650505050505062001170565b84881115620013145760405162461bcd60e51b815260206004820152601660248201527510995b1b1d5b4e8814d31254141051d157d31253525560521b60448201526064016200068e565b6702c68af0bb1400008510156200136e5760405162461bcd60e51b815260206004820152601c60248201527f42656c6c756d3a20494e53554646494349454e545f4554485f4f55540000000060448201526064016200068e565b60028701839055600387018290556006546000906127109062001392908862002d22565b6200139e919062002d3c565b90508060056000828254620013b4919062002c75565b90915550620013d29050620013ca828862002d95565b339062001e47565b604080518b81526000602082018190528183015260608101889052905133916001600160a01b038e16917feae13466a4e0ed2b9f8778664bef183cecabb5006850f4b17cc094d54ce3a3e89181900360800190a35050505050505050620014396001600255565b505050565b6200144862001951565b62001454600062001ee3565b565b60015433906001600160a01b03168114620014905760405163118cdaa760e01b81526001600160a01b03821660048201526024016200068e565b6200149b8162001ee3565b50565b620014a862001951565b600380546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b620014da62001951565b60ff82166000908152600b6020526040902060010154156200153f5760405162461bcd60e51b815260206004820152601c60248201527f42656c6c756d3a2043555256455f414c52454144595f494e5f5553450000000060448201526064016200068e565b80516000908190815b81811015620016715784818151811062001566576200156662002d5f565b6020026020010151600003620015b55760405162461bcd60e51b81526020600482015260136024820152722132b6363ab69d1024a72b20a624a22fa124a760691b60448201526064016200068e565b848181518110620015ca57620015ca62002d5f565b602002602001015184620015df919062002c75565b93506000612710620015f46107d08462002d22565b620016029061271062002c75565b6200161690670de0b6b3a764000062002d22565b62001622919062002d3c565b9050808683815181106200163a576200163a62002d5f565b60200260200101516200164e919062002d22565b6200165a908562002c75565b93505080620016699062002dc5565b905062001548565b506127108314620016d05760405162461bcd60e51b815260206004820152602260248201527f42656c6c756d3a20494e56414c49445f544f54414c5f4449535452494255544960448201526127a760f11b60648201526084016200068e565b6000612710806107d0620016e660018662002d95565b620016f2919062002d22565b620016fe919062002c75565b6200171290670de0b6b3a764000062002d22565b6200171e919062002d3c565b90506000620017308261271062002d22565b9050600062001740858362002c75565b6200174e8361271062002d22565b6200175a919062002d3c565b9050604051806060016040528088815260200182815260200160028762001782919062002d3c565b905260ff89166000908152600b60209081526040909120825180519192620017b09284929091019062002818565b50602082015160018201556040918201516002909101555160ff8916907f692761be1e34ff0280587cdf866deb367e85f7b32ff1d5ac3bbfdd944e5e567490600090a25050505050505050565b6005546000819003620018485760405162461bcd60e51b8152602060048201526012602482015271139bc81999595cc81d1bc818dbdb1b1958dd60721b60448201526064016200068e565b60006005556003546200149b9061010090046001600160a01b03168262001e47565b6200187462001980565b670de0b6b3a7640000341015620018c05760405162461bcd60e51b815260206004820152600f60248201526e42656c6c756d3a20544f4f5f4c4f5760881b60448201526064016200068e565b620018ce82333484620019a9565b620018d96001600255565b5050565b620018e762001951565b600180546001600160a01b0383166001600160a01b03199091168117909155620019196000546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6000546001600160a01b03163314620014545760405163118cdaa760e01b81523360048201526024016200068e565b6002805403620019a357604051633ee5aeb560e01b815260040160405180910390fd5b60028055565b6001600160a01b0384166000908152600a60205260408120600481015490910362001a175760405162461bcd60e51b815260206004820152601c60248201527f42656c6c756d3a20544f4b454e5f444f45535f4e4f545f45584953540000000060448201526064016200068e565b600581015460ff161562001a695760405162461bcd60e51b815260206004820152601860248201527710995b1b1d5b4e881053149150511657d310555390d2115160421b60448201526064016200068e565b6001810154600160a01b900460ff166000908152600b602090815260408083208054825181850281018501909352808352919290919083018282801562001ad057602002820191906000526020600020905b81548152602001906001019080831162001abb575b5050505050905060006127106006548662001aec919062002d22565b62001af8919062002d3c565b9050600062001b08828762002d95565b600285015460038601546004870154929350600092839291905b8584101562001c9e57600062001b3b846107d062002d22565b62001b499061271062002c75565b62001b5660028462002d22565b62001b62919062002d3c565b9050600062001b72868962002d95565b905083670de0b6b3a764000062001b8a848462002d22565b62001b96919062002d3c565b81111562001bf7576000670de0b6b3a764000062001bb5848662002d22565b62001bc1919062002d3c565b905062001bcf838962002c75565b975062001bdd818a62002c75565b985062001beb818362002d95565b95505050505062001c9e565b8262001c0c670de0b6b3a76400008362002d22565b62001c18919062002d3c565b62001c24908862002c75565b965062001c32818962002c75565b975062001c3f8662002dc5565b95508a5186101562001c8c57612710848c888151811062001c645762001c6462002d5f565b602002602001015162001c78919062002d22565b62001c84919062002d3c565b945062001c95565b50505062001c9e565b50505062001b22565b848a111562001ce95760405162461bcd60e51b815260206004820152601660248201527510995b1b1d5b4e8814d31254141051d157d31253525560521b60448201526064016200068e565b60028901839055600389018290556005805488919060009062001d0e90849062002c75565b9091555062001d2a90506001600160a01b038e168d8762001efe565b8b6001600160a01b03168d6001600160a01b03167feae13466a4e0ed2b9f8778664bef183cecabb5006850f4b17cc094d54ce3a3e86000888f600060405162001d8c949392919093845260208401929092526040830152606082015260800190565b60405180910390a38751831062001dc95762001dbe62001dad858862002d95565b6001600160a01b038e169062001e47565b62001dc98d62001f31565b50505050505050505050505050565b6040516001600160a01b03848116602483015283811660448301526064820183905262001e419186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b03838183161783525050505062002429565b50505050565b8047101562001e6c5760405163cd78605960e01b81523060048201526024016200068e565b6000826001600160a01b03168260405160006040518083038185875af1925050503d806000811462001ebb576040519150601f19603f3d011682016040523d82523d6000602084013e62001ec0565b606091505b50509050806200143957604051630a12f52160e11b815260040160405180910390fd5b600180546001600160a01b03191690556200149b8162002493565b6040516001600160a01b038381166024830152604482018390526200143991859182169063a9059cbb9060640162001e0e565b6001600160a01b0381166000908152600a602052604090206005015460ff161562001f9a5760405162461bcd60e51b815260206004820152601860248201527710995b1b1d5b4e881053149150511657d310555390d2115160421b60448201526064016200068e565b806001600160a01b031663715018a66040518163ffffffff1660e01b8152600401600060405180830381600087803b15801562001fd657600080fd5b505af115801562001feb573d6000803e3d6000fd5b50506040516370a0823160e01b8152306004820152600092506001600160a01b03841691506370a0823190602401602060405180830381865afa15801562002037573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200205d919062002de1565b6001600160a01b0383166000908152600a6020908152604080832060010154600160a01b900460ff168352600b9091528120600201546004549293509161271090620020aa908462002d22565b620020b6919062002d3c565b90508015620020d9578060056000828254620020d3919062002c75565b90915550505b6001600160a01b038481166000908152600a60205260408120600581015460019091015461010090910460ff169216908260018111156200211e576200211e62002bd8565b03620022a4576200215a6001600160a01b0387167f000000000000000000000000000000000000000000000000000000000000000087620024e3565b60006001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663f305d71962002197868862002d95565b6040516001600160e01b031960e084901b1681526001600160a01b038b166004820152602481018a905260006044820181905260648201523060848201524260a482015260c40160606040518083038185885af1158015620021fd573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019062002224919062002dfb565b925050506000612710600854836200223d919062002d22565b62002249919062002d3c565b6001600160a01b03808a166000908152600a6020526040902054919250620022779185821691168362001efe565b6200229c61dead6200228a838562002d95565b6001600160a01b038616919062001efe565b5050620023cc565b6001826001811115620022bb57620022bb62002bd8565b03620023cc57620022f76001600160a01b0387167f000000000000000000000000000000000000000000000000000000000000000087620024e3565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663b7e0d4c062002332858762002d95565b6040516001600160e01b031960e084901b1681526001600160a01b038a166004820152600060248201819052604482018a905260648201819052608482015261dead60a48201524260c482015260e40160606040518083038185885af1158015620023a1573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190620023c8919062002dfb565b5050505b6001600160a01b038087166000818152600a6020526040808220600501805460ff1916600117905551928416929091907f937f456c07a61f36132d04df1c2826dd375336feecdd370ddaf00f25342e893c908390a4505050505050565b6000620024406001600160a01b0384168362002574565b905080516000141580156200246857508080602001905181019062002466919062002e2a565b155b156200143957604051635274afe760e01b81526001600160a01b03841660048201526024016200068e565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301526000919085169063dd62ed3e90604401602060405180830381865afa15801562002534573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200255a919062002de1565b905062001e4184846200256e858562002c75565b6200258d565b6060620025848383600062002624565b90505b92915050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052620025e08482620026cb565b62001e41576040516001600160a01b038481166024830152600060448301526200261891869182169063095ea7b39060640162001e0e565b62001e41848262002429565b6060814710156200264b5760405163cd78605960e01b81523060048201526024016200068e565b600080856001600160a01b0316848660405162002669919062002e4a565b60006040518083038185875af1925050503d8060008114620026a8576040519150601f19603f3d011682016040523d82523d6000602084013e620026ad565b606091505b5091509150620026bf8683836200277c565b925050505b9392505050565b6000806000846001600160a01b031684604051620026ea919062002e4a565b6000604051808303816000865af19150503d806000811462002729576040519150601f19603f3d011682016040523d82523d6000602084013e6200272e565b606091505b50915091508180156200275c5750805115806200275c5750808060200190518101906200275c919062002e2a565b80156200277357506000856001600160a01b03163b115b95945050505050565b60608262002795576200278f82620027e0565b620026c4565b8151158015620027ad57506001600160a01b0384163b155b15620027d857604051639996b31560e01b81526001600160a01b03851660048201526024016200068e565b5080620026c4565b805115620027f15780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b610f2f8062002e6983390190565b82805482825590600052602060002090810192821562002856579160200282015b828111156200285657825182559160200191906001019062002839565b506200286492915062002868565b5090565b5b8082111562002864576000815560010162002869565b6000602082840312156200289257600080fd5b5035919050565b803560ff81168114620028ab57600080fd5b919050565b600060208284031215620028c357600080fd5b620025848262002899565b80151581146200149b57600080fd5b600060208284031215620028f057600080fd5b8135620026c481620028ce565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156200293f576200293f620028fd565b604052919050565b600082601f8301126200295957600080fd5b813567ffffffffffffffff811115620029765762002976620028fd565b6200298b601f8201601f191660200162002913565b818152846020838601011115620029a157600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a08688031215620029d757600080fd5b853567ffffffffffffffff80821115620029f057600080fd5b620029fe89838a0162002947565b9650602088013591508082111562002a1557600080fd5b5062002a248882890162002947565b94505060408601356001600160701b038116811462002a4257600080fd5b925062002a526060870162002899565b915060808601356002811062002a6757600080fd5b809150509295509295909350565b6001600160a01b03811681146200149b57600080fd5b60008060006060848603121562002aa157600080fd5b833562002aae8162002a75565b95602085013595506040909401359392505050565b60006020828403121562002ad657600080fd5b8135620026c48162002a75565b6000806040838503121562002af757600080fd5b62002b028362002899565b915060208084013567ffffffffffffffff8082111562002b2157600080fd5b818601915086601f83011262002b3657600080fd5b81358181111562002b4b5762002b4b620028fd565b8060051b915062002b5e84830162002913565b818152918301840191848101908984111562002b7957600080fd5b938501935b8385101562002b995784358252938501939085019062002b7e565b8096505050505050509250929050565b6000806040838503121562002bbd57600080fd5b823562002bca8162002a75565b946020939093013593505050565b634e487b7160e01b600052602160045260246000fd5b6001600160a01b0389811682528816602082015260ff87166040820152606081018690526080810185905260a0810184905282151560c082015261010081016002831062002c4c57634e487b7160e01b600052602160045260246000fd5b8260e08301529998505050505050505050565b634e487b7160e01b600052601160045260246000fd5b8082018082111562002587576200258762002c5f565b60005b8381101562002ca857818101518382015260200162002c8e565b50506000910152565b6000815180845262002ccb81602086016020860162002c8b565b601f01601f19169290920160200192915050565b60608152600062002cf4606083018662002cb1565b828103602084015262002d08818662002cb1565b9150506001600160701b0383166040830152949350505050565b808202811582820484141762002587576200258762002c5f565b60008262002d5a57634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b60006020828403121562002d8857600080fd5b8151620026c48162002a75565b8181038181111562002587576200258762002c5f565b60008162002dbd5762002dbd62002c5f565b506000190190565b60006001820162002dda5762002dda62002c5f565b5060010190565b60006020828403121562002df457600080fd5b5051919050565b60008060006060848603121562002e1157600080fd5b8351925060208401519150604084015190509250925092565b60006020828403121562002e3d57600080fd5b8151620026c481620028ce565b6000825162002e5e81846020870162002c8b565b919091019291505056fe60806040523480156200001157600080fd5b5060405162000f2f38038062000f2f833981016040819052620000349162000406565b338383600362000045838262000522565b50600462000054828262000522565b5050506001600160a01b0381166200008757604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b6200009281620000b1565b50620000a8336001600160701b03831662000103565b50505062000616565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0382166200012f5760405163ec442f0560e01b8152600060048201526024016200007e565b6200013d6000838362000141565b5050565b6200014e8383836200020e565b6000620001636005546001600160a01b031690565b90506001600160a01b038116156200020857806001600160a01b0316846001600160a01b03161480620001a75750806001600160a01b0316836001600160a01b0316145b80620001ba57506001600160a01b038416155b620002085760405162461bcd60e51b815260206004820152601b60248201527f42656c6c756d3a2043414e4e4f545f5452414e534645525f594554000000000060448201526064016200007e565b50505050565b6001600160a01b0383166200023d578060026000828254620002319190620005ee565b90915550620002b19050565b6001600160a01b03831660009081526020819052604090205481811015620002925760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016200007e565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b038216620002cf57600280548290039055620002ee565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516200033491815260200190565b60405180910390a3505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200036957600080fd5b81516001600160401b038082111562000386576200038662000341565b604051601f8301601f19908116603f01168101908282118183101715620003b157620003b162000341565b81604052838152602092508683858801011115620003ce57600080fd5b600091505b83821015620003f25785820183015181830184015290820190620003d3565b600093810190920192909252949350505050565b6000806000606084860312156200041c57600080fd5b83516001600160401b03808211156200043457600080fd5b620004428783880162000357565b945060208601519150808211156200045957600080fd5b50620004688682870162000357565b604086015190935090506001600160701b03811681146200048857600080fd5b809150509250925092565b600181811c90821680620004a857607f821691505b602082108103620004c957634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200051d57600081815260208120601f850160051c81016020861015620004f85750805b601f850160051c820191505b81811015620005195782815560010162000504565b5050505b505050565b81516001600160401b038111156200053e576200053e62000341565b62000556816200054f845462000493565b84620004cf565b602080601f8311600181146200058e5760008415620005755750858301515b600019600386901b1c1916600185901b17855562000519565b600085815260208120601f198616915b82811015620005bf578886015182559484019460019091019084016200059e565b5085821015620005de5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b808201808211156200061057634e487b7160e01b600052601160045260246000fd5b92915050565b61090980620006266000396000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c8063715018a611610071578063715018a6146101575780638da5cb5b1461016157806395d89b411461017c578063a9059cbb14610184578063dd62ed3e14610197578063f2fde38b146101d057600080fd5b806306fdde03146100b9578063095ea7b3146100d757806318160ddd146100fa57806323b872dd1461010c578063313ce5671461011f57806370a082311461012e575b600080fd5b6100c16101e3565b6040516100ce9190610753565b60405180910390f35b6100ea6100e53660046107bd565b610275565b60405190151581526020016100ce565b6002545b6040519081526020016100ce565b6100ea61011a3660046107e7565b61028f565b604051601281526020016100ce565b6100fe61013c366004610823565b6001600160a01b031660009081526020819052604090205490565b61015f6102b3565b005b6005546040516001600160a01b0390911681526020016100ce565b6100c16102c7565b6100ea6101923660046107bd565b6102d6565b6100fe6101a5366004610845565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b61015f6101de366004610823565b6102e4565b6060600380546101f290610878565b80601f016020809104026020016040519081016040528092919081815260200182805461021e90610878565b801561026b5780601f106102405761010080835404028352916020019161026b565b820191906000526020600020905b81548152906001019060200180831161024e57829003601f168201915b5050505050905090565b600033610283818585610327565b60019150505b92915050565b60003361029d858285610339565b6102a88585856103b7565b506001949350505050565b6102bb610416565b6102c56000610443565b565b6060600480546101f290610878565b6000336102838185856103b7565b6102ec610416565b6001600160a01b03811661031b57604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b61032481610443565b50565b6103348383836001610495565b505050565b6001600160a01b0383811660009081526001602090815260408083209386168352929052205460001981146103b157818110156103a257604051637dc7a0d960e11b81526001600160a01b03841660048201526024810182905260448101839052606401610312565b6103b184848484036000610495565b50505050565b6001600160a01b0383166103e157604051634b637e8f60e11b815260006004820152602401610312565b6001600160a01b03821661040b5760405163ec442f0560e01b815260006004820152602401610312565b61033483838361056a565b6005546001600160a01b031633146102c55760405163118cdaa760e01b8152336004820152602401610312565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0384166104bf5760405163e602df0560e01b815260006004820152602401610312565b6001600160a01b0383166104e957604051634a1406b160e11b815260006004820152602401610312565b6001600160a01b03808516600090815260016020908152604080832093871683529290522082905580156103b157826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161055c91815260200190565b60405180910390a350505050565b610575838383610629565b60006105896005546001600160a01b031690565b90506001600160a01b038116156103b157806001600160a01b0316846001600160a01b031614806105cb5750806001600160a01b0316836001600160a01b0316145b806105dd57506001600160a01b038416155b6103b15760405162461bcd60e51b815260206004820152601b60248201527f42656c6c756d3a2043414e4e4f545f5452414e534645525f59455400000000006044820152606401610312565b6001600160a01b03831661065457806002600082825461064991906108b2565b909155506106c69050565b6001600160a01b038316600090815260208190526040902054818110156106a75760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401610312565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b0382166106e257600280548290039055610701565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161074691815260200190565b60405180910390a3505050565b600060208083528351808285015260005b8181101561078057858101830151858201604001528201610764565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b03811681146107b857600080fd5b919050565b600080604083850312156107d057600080fd5b6107d9836107a1565b946020939093013593505050565b6000806000606084860312156107fc57600080fd5b610805846107a1565b9250610813602085016107a1565b9150604084013590509250925092565b60006020828403121561083557600080fd5b61083e826107a1565b9392505050565b6000806040838503121561085857600080fd5b610861836107a1565b915061086f602084016107a1565b90509250929050565b600181811c9082168061088c57607f821691505b6020821081036108ac57634e487b7160e01b600052602260045260246000fd5b50919050565b8082018082111561028957634e487b7160e01b600052601160045260246000fdfea26469706673582212209fd5ea3d869bae12a381f0e829925dd684325f6d3322b51596c4432d24e4925364736f6c63430008140033a264697066735822122019769a3f98dfb864f1e3a03295cf8a76721ac21f478548cbec6ac488569b7c7b64736f6c634300081400335a65726f2061646472657373206e6f7420616c6c6f77656420666f7220726f750000000000000000000000003a7a1f256b6180d59f58efc080321a09d456ee9b00000000000000000000000095a7e403d7cf20f675ff9273d66e94d35ba49fa30000000000000000000000001d368773735ee1e678950b7a97bca2cafb330cdc
Deployed Bytecode
0x608060405260043610620001db5760003560e01c8063715018a611620000ff578063b3f006741162000095578063dbb80e42116200006c578063dbb80e42146200054d578063e30c39781462000564578063e48603391462000584578063f2fde38b146200061057600080fd5b8063b3f0067414620004f7578063c8796572146200051e578063cce7ec13146200053657600080fd5b80638da5cb5b11620000d65780638da5cb5b146200048257806397506cd214620004a2578063a3400a6614620004ba578063b2db919b14620004df57600080fd5b8063715018a6146200042d57806379ba509714620004455780637c08b964146200045d57600080fd5b806356f433521162000175578063634282af116200014c578063634282af146200039957806366f20b4f14620003be5780636a1db1bf14620003e35780636a272462146200040857600080fd5b806356f4335214620003265780635b7ff11e146200033e57806362914849146200037457600080fd5b8063240976bf11620001b6578063240976bf1462000283578063317e778514620002a85780633f23704614620002bf57806346dcab55146200030e57600080fd5b80631d08c0e114620001e057806320e1fc8c1462000207578063224438d1146200025c575b600080fd5b348015620001ed57600080fd5b5062000205620001ff3660046200287f565b62000635565b005b3480156200021457600080fd5b506200024262000226366004620028b0565b600b602052600090815260409020600181015460029091015482565b604080519283526020830191909152015b60405180910390f35b3480156200026957600080fd5b506200027460055481565b60405190815260200162000253565b3480156200029057600080fd5b5062000205620002a2366004620028dd565b6200069c565b62000205620002b9366004620029be565b620006b9565b348015620002cc57600080fd5b50620002f57f00000000000000000000000095a7e403d7cf20f675ff9273d66e94d35ba49fa381565b6040516001600160a01b03909116815260200162000253565b3480156200031b57600080fd5b506200027460045481565b3480156200033357600080fd5b506200027460065481565b3480156200034b57600080fd5b50620002f57f0000000000000000000000001d368773735ee1e678950b7a97bca2cafb330cdc81565b3480156200038157600080fd5b5062000205620003933660046200287f565b62000ebe565b348015620003a657600080fd5b50620002f5620003b83660046200287f565b62000f1f565b348015620003cb57600080fd5b5062000205620003dd3660046200287f565b62000f4a565b348015620003f057600080fd5b5062000205620004023660046200287f565b62000fad565b3480156200041557600080fd5b50620002056200042736600462002a8b565b62001006565b3480156200043a57600080fd5b50620002056200143e565b3480156200045257600080fd5b506200020562001456565b3480156200046a57600080fd5b50620002056200047c36600462002ac3565b6200149e565b3480156200048f57600080fd5b506000546001600160a01b0316620002f5565b348015620004af57600080fd5b506200027460085481565b348015620004c757600080fd5b5062000205620004d936600462002ae3565b620014d0565b348015620004ec57600080fd5b506200027460075481565b3480156200050457600080fd5b50600354620002f59061010090046001600160a01b031681565b3480156200052b57600080fd5b5062000205620017fd565b620002056200054736600462002ba9565b6200186a565b3480156200055a57600080fd5b5060095462000274565b3480156200057157600080fd5b506001546001600160a01b0316620002f5565b3480156200059157600080fd5b50620005fa620005a336600462002ac3565b600a602052600090815260409020805460018201546002830154600384015460048501546005909501546001600160a01b03948516959484169460ff600160a01b9095048516949091808216916101009091041688565b6040516200025398979695949392919062002bee565b3480156200061d57600080fd5b50620002056200062f36600462002ac3565b620018dd565b6200063f62001951565b6103e8811115620006975760405162461bcd60e51b815260206004820181905260248201527f42656c6c756d3a2043524541544f525f524557415244535f544f4f5f4849474860448201526064015b60405180910390fd5b600855565b620006a662001951565b6003805460ff1916911515919091179055565b620006c362001980565b60ff82166000908152600b6020908152604080832081518154608094810282018501909352606081018381529093919284928491908401828280156200072957602002820191906000526020600020905b81548152602001906001019080831162000714575b505050918352505060018201546020808301919091526002909201546040909101528101518151600754600354939450919290919060ff1615620007b05760405162461bcd60e51b815260206004820181905260248201527f42656c6c756d3a20544f4b454e5f4352454154494f4e5f49535f50415553454460448201526064016200068e565b82600003620008025760405162461bcd60e51b815260206004820152601c60248201527f42656c6c756d3a2043555256455f444f45535f4e4f545f45584953540000000060448201526064016200068e565b670de0b6b3a7640000876001600160701b03161015620008655760405162461bcd60e51b815260206004820152601c60248201527f42656c6c756d3a20544f54414c5f535550504c595f544f4f5f4c4f570000000060448201526064016200068e565b6200087a81681b1ae4d6e2ef50000062002c75565b341115620008c25760405162461bcd60e51b8152602060048201526014602482015273084cad8d8eada7440a89e9ebe9aaa8690be8aa8960631b60448201526064016200068e565b803410156200090d5760405162461bcd60e51b8152602060048201526016602482015275084cad8d8eada7440a89e9ebe9892a8a8988abe8aa8960531b60448201526064016200068e565b600089898960405162000920906200280a565b6200092e9392919062002cdf565b604051809103906000f0801580156200094b573d6000803e3d6000fd5b506009805460018101825560009182527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0180546001600160a01b0319166001600160a01b0384161790559091508190612710620009b3876001600160701b038d1662002d22565b620009bf919062002d3c565b6001600160a01b0383166000908152600a60205260408120600401829055865191925061271091879190620009f857620009f862002d5f565b60200260200101518262000a0d919062002d22565b62000a19919062002d3c565b6001600160a01b0383166000908152600a6020526040902060038101919091556001808201805460ff8d16600160a01b0260ff60a01b1990911617905581546001600160a01b03191633178255600590910180548a9261ff00199091169061010090849081111562000a8f5762000a8f62002bd8565b02179055506000600189600181111562000aad5762000aad62002bd8565b0362000c4f5760007f0000000000000000000000001d368773735ee1e678950b7a97bca2cafb330cdc6001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000b14573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000b3a919062002d75565b905060007f0000000000000000000000001d368773735ee1e678950b7a97bca2cafb330cdc6001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000b9d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000bc3919062002d75565b6040516320b7f73960e21b81526001600160a01b038781166004830152808316602483015260006044830152919250908316906382dfdce4906064016020604051808303816000875af115801562000c1f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000c45919062002d75565b9250505062000ddf565b60007f00000000000000000000000095a7e403d7cf20f675ff9273d66e94d35ba49fa36001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000cb0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000cd6919062002d75565b905060007f00000000000000000000000095a7e403d7cf20f675ff9273d66e94d35ba49fa36001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000d39573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d5f919062002d75565b6040516364e329cb60e11b81526001600160a01b03878116600483015280831660248301529192509083169063c9c65396906044016020604051808303816000875af115801562000db4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000dda919062002d75565b925050505b6001600160a01b038381166000818152600a60205260409020600190810180546001600160a01b0319169385169390931790925533917fc53fd35d147910e8b0428fe8d1bc5aaef0bc4af4d778ba5d10c55de9ad134972908d908d9081111562000e4d5762000e4d62002bd8565b6040805160ff909316835260208301919091520160405180910390a3846005600082825462000e7d919062002c75565b909155505034851462000ea45762000ea4833362000e9c883462002d95565b6000620019a9565b505050505050505062000eb76001600255565b5050505050565b62000ec862001951565b6802b5e3af16b188000081111562000f1a5760405162461bcd60e51b8152602060048201526014602482015273084cad8d8eada74408c8a8abea89e9ebe90928e960631b60448201526064016200068e565b600755565b6009818154811062000f3057600080fd5b6000918252602090912001546001600160a01b0316905081565b62000f5462001951565b6103e881111562000fa85760405162461bcd60e51b815260206004820152601e60248201527f42656c6c756d3a204d4947524154494f4e5f4645455f544f4f5f48494748000060448201526064016200068e565b600455565b62000fb762001951565b60fa811115620010015760405162461bcd60e51b8152602060048201526014602482015273084cad8d8eada74408c8a8abea89e9ebe90928e960631b60448201526064016200068e565b600655565b6200101062001980565b6001600160a01b0383166000908152600a6020526040812060048101549091036200107e5760405162461bcd60e51b815260206004820152601c60248201527f42656c6c756d3a20544f4b454e5f444f45535f4e4f545f45584953540000000060448201526064016200068e565b600581015460ff1615620010d55760405162461bcd60e51b815260206004820152601e60248201527f42656c6c756d3a20494e53554646494349454e545f4c4951554944495459000060448201526064016200068e565b620010ec6001600160a01b03851633308662001dd8565b6001810154600160a01b900460ff166000908152600b60209081526040808320805482518185028101850190935280835291929091908301828280156200115357602002820191906000526020600020905b8154815260200190600101908083116200113e575b505050506002840154600385015460048601549394506000938493505b88841015620012c957600062001189846107d062002d22565b620011979061271062002c75565b620011a460028462002d22565b620011b0919062002d3c565b90506000620011c0868c62002d95565b905060008490506000612710858b8981518110620011e257620011e262002d5f565b6020026020010151620011f6919062002d22565b62001202919062002d3c565b90508062001211848462002c75565b116200125e57836200122c670de0b6b3a76400008562002d22565b62001238919062002d3c565b62001244908a62002c75565b985062001252838762002c75565b955050505050620012c9565b60006200126c838362002d95565b90506200127a818a62002c75565b98508462001291670de0b6b3a76400008362002d22565b6200129d919062002d3c565b620012a9908b62002c75565b995087620012b78162002dab565b98505060009650505050505062001170565b84881115620013145760405162461bcd60e51b815260206004820152601660248201527510995b1b1d5b4e8814d31254141051d157d31253525560521b60448201526064016200068e565b6702c68af0bb1400008510156200136e5760405162461bcd60e51b815260206004820152601c60248201527f42656c6c756d3a20494e53554646494349454e545f4554485f4f55540000000060448201526064016200068e565b60028701839055600387018290556006546000906127109062001392908862002d22565b6200139e919062002d3c565b90508060056000828254620013b4919062002c75565b90915550620013d29050620013ca828862002d95565b339062001e47565b604080518b81526000602082018190528183015260608101889052905133916001600160a01b038e16917feae13466a4e0ed2b9f8778664bef183cecabb5006850f4b17cc094d54ce3a3e89181900360800190a35050505050505050620014396001600255565b505050565b6200144862001951565b62001454600062001ee3565b565b60015433906001600160a01b03168114620014905760405163118cdaa760e01b81526001600160a01b03821660048201526024016200068e565b6200149b8162001ee3565b50565b620014a862001951565b600380546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b620014da62001951565b60ff82166000908152600b6020526040902060010154156200153f5760405162461bcd60e51b815260206004820152601c60248201527f42656c6c756d3a2043555256455f414c52454144595f494e5f5553450000000060448201526064016200068e565b80516000908190815b81811015620016715784818151811062001566576200156662002d5f565b6020026020010151600003620015b55760405162461bcd60e51b81526020600482015260136024820152722132b6363ab69d1024a72b20a624a22fa124a760691b60448201526064016200068e565b848181518110620015ca57620015ca62002d5f565b602002602001015184620015df919062002c75565b93506000612710620015f46107d08462002d22565b620016029061271062002c75565b6200161690670de0b6b3a764000062002d22565b62001622919062002d3c565b9050808683815181106200163a576200163a62002d5f565b60200260200101516200164e919062002d22565b6200165a908562002c75565b93505080620016699062002dc5565b905062001548565b506127108314620016d05760405162461bcd60e51b815260206004820152602260248201527f42656c6c756d3a20494e56414c49445f544f54414c5f4449535452494255544960448201526127a760f11b60648201526084016200068e565b6000612710806107d0620016e660018662002d95565b620016f2919062002d22565b620016fe919062002c75565b6200171290670de0b6b3a764000062002d22565b6200171e919062002d3c565b90506000620017308261271062002d22565b9050600062001740858362002c75565b6200174e8361271062002d22565b6200175a919062002d3c565b9050604051806060016040528088815260200182815260200160028762001782919062002d3c565b905260ff89166000908152600b60209081526040909120825180519192620017b09284929091019062002818565b50602082015160018201556040918201516002909101555160ff8916907f692761be1e34ff0280587cdf866deb367e85f7b32ff1d5ac3bbfdd944e5e567490600090a25050505050505050565b6005546000819003620018485760405162461bcd60e51b8152602060048201526012602482015271139bc81999595cc81d1bc818dbdb1b1958dd60721b60448201526064016200068e565b60006005556003546200149b9061010090046001600160a01b03168262001e47565b6200187462001980565b670de0b6b3a7640000341015620018c05760405162461bcd60e51b815260206004820152600f60248201526e42656c6c756d3a20544f4f5f4c4f5760881b60448201526064016200068e565b620018ce82333484620019a9565b620018d96001600255565b5050565b620018e762001951565b600180546001600160a01b0383166001600160a01b03199091168117909155620019196000546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6000546001600160a01b03163314620014545760405163118cdaa760e01b81523360048201526024016200068e565b6002805403620019a357604051633ee5aeb560e01b815260040160405180910390fd5b60028055565b6001600160a01b0384166000908152600a60205260408120600481015490910362001a175760405162461bcd60e51b815260206004820152601c60248201527f42656c6c756d3a20544f4b454e5f444f45535f4e4f545f45584953540000000060448201526064016200068e565b600581015460ff161562001a695760405162461bcd60e51b815260206004820152601860248201527710995b1b1d5b4e881053149150511657d310555390d2115160421b60448201526064016200068e565b6001810154600160a01b900460ff166000908152600b602090815260408083208054825181850281018501909352808352919290919083018282801562001ad057602002820191906000526020600020905b81548152602001906001019080831162001abb575b5050505050905060006127106006548662001aec919062002d22565b62001af8919062002d3c565b9050600062001b08828762002d95565b600285015460038601546004870154929350600092839291905b8584101562001c9e57600062001b3b846107d062002d22565b62001b499061271062002c75565b62001b5660028462002d22565b62001b62919062002d3c565b9050600062001b72868962002d95565b905083670de0b6b3a764000062001b8a848462002d22565b62001b96919062002d3c565b81111562001bf7576000670de0b6b3a764000062001bb5848662002d22565b62001bc1919062002d3c565b905062001bcf838962002c75565b975062001bdd818a62002c75565b985062001beb818362002d95565b95505050505062001c9e565b8262001c0c670de0b6b3a76400008362002d22565b62001c18919062002d3c565b62001c24908862002c75565b965062001c32818962002c75565b975062001c3f8662002dc5565b95508a5186101562001c8c57612710848c888151811062001c645762001c6462002d5f565b602002602001015162001c78919062002d22565b62001c84919062002d3c565b945062001c95565b50505062001c9e565b50505062001b22565b848a111562001ce95760405162461bcd60e51b815260206004820152601660248201527510995b1b1d5b4e8814d31254141051d157d31253525560521b60448201526064016200068e565b60028901839055600389018290556005805488919060009062001d0e90849062002c75565b9091555062001d2a90506001600160a01b038e168d8762001efe565b8b6001600160a01b03168d6001600160a01b03167feae13466a4e0ed2b9f8778664bef183cecabb5006850f4b17cc094d54ce3a3e86000888f600060405162001d8c949392919093845260208401929092526040830152606082015260800190565b60405180910390a38751831062001dc95762001dbe62001dad858862002d95565b6001600160a01b038e169062001e47565b62001dc98d62001f31565b50505050505050505050505050565b6040516001600160a01b03848116602483015283811660448301526064820183905262001e419186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b03838183161783525050505062002429565b50505050565b8047101562001e6c5760405163cd78605960e01b81523060048201526024016200068e565b6000826001600160a01b03168260405160006040518083038185875af1925050503d806000811462001ebb576040519150601f19603f3d011682016040523d82523d6000602084013e62001ec0565b606091505b50509050806200143957604051630a12f52160e11b815260040160405180910390fd5b600180546001600160a01b03191690556200149b8162002493565b6040516001600160a01b038381166024830152604482018390526200143991859182169063a9059cbb9060640162001e0e565b6001600160a01b0381166000908152600a602052604090206005015460ff161562001f9a5760405162461bcd60e51b815260206004820152601860248201527710995b1b1d5b4e881053149150511657d310555390d2115160421b60448201526064016200068e565b806001600160a01b031663715018a66040518163ffffffff1660e01b8152600401600060405180830381600087803b15801562001fd657600080fd5b505af115801562001feb573d6000803e3d6000fd5b50506040516370a0823160e01b8152306004820152600092506001600160a01b03841691506370a0823190602401602060405180830381865afa15801562002037573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200205d919062002de1565b6001600160a01b0383166000908152600a6020908152604080832060010154600160a01b900460ff168352600b9091528120600201546004549293509161271090620020aa908462002d22565b620020b6919062002d3c565b90508015620020d9578060056000828254620020d3919062002c75565b90915550505b6001600160a01b038481166000908152600a60205260408120600581015460019091015461010090910460ff169216908260018111156200211e576200211e62002bd8565b03620022a4576200215a6001600160a01b0387167f00000000000000000000000095a7e403d7cf20f675ff9273d66e94d35ba49fa387620024e3565b60006001600160a01b037f00000000000000000000000095a7e403d7cf20f675ff9273d66e94d35ba49fa31663f305d71962002197868862002d95565b6040516001600160e01b031960e084901b1681526001600160a01b038b166004820152602481018a905260006044820181905260648201523060848201524260a482015260c40160606040518083038185885af1158015620021fd573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019062002224919062002dfb565b925050506000612710600854836200223d919062002d22565b62002249919062002d3c565b6001600160a01b03808a166000908152600a6020526040902054919250620022779185821691168362001efe565b6200229c61dead6200228a838562002d95565b6001600160a01b038616919062001efe565b5050620023cc565b6001826001811115620022bb57620022bb62002bd8565b03620023cc57620022f76001600160a01b0387167f0000000000000000000000001d368773735ee1e678950b7a97bca2cafb330cdc87620024e3565b6001600160a01b037f0000000000000000000000001d368773735ee1e678950b7a97bca2cafb330cdc1663b7e0d4c062002332858762002d95565b6040516001600160e01b031960e084901b1681526001600160a01b038a166004820152600060248201819052604482018a905260648201819052608482015261dead60a48201524260c482015260e40160606040518083038185885af1158015620023a1573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190620023c8919062002dfb565b5050505b6001600160a01b038087166000818152600a6020526040808220600501805460ff1916600117905551928416929091907f937f456c07a61f36132d04df1c2826dd375336feecdd370ddaf00f25342e893c908390a4505050505050565b6000620024406001600160a01b0384168362002574565b905080516000141580156200246857508080602001905181019062002466919062002e2a565b155b156200143957604051635274afe760e01b81526001600160a01b03841660048201526024016200068e565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301526000919085169063dd62ed3e90604401602060405180830381865afa15801562002534573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200255a919062002de1565b905062001e4184846200256e858562002c75565b6200258d565b6060620025848383600062002624565b90505b92915050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052620025e08482620026cb565b62001e41576040516001600160a01b038481166024830152600060448301526200261891869182169063095ea7b39060640162001e0e565b62001e41848262002429565b6060814710156200264b5760405163cd78605960e01b81523060048201526024016200068e565b600080856001600160a01b0316848660405162002669919062002e4a565b60006040518083038185875af1925050503d8060008114620026a8576040519150601f19603f3d011682016040523d82523d6000602084013e620026ad565b606091505b5091509150620026bf8683836200277c565b925050505b9392505050565b6000806000846001600160a01b031684604051620026ea919062002e4a565b6000604051808303816000865af19150503d806000811462002729576040519150601f19603f3d011682016040523d82523d6000602084013e6200272e565b606091505b50915091508180156200275c5750805115806200275c5750808060200190518101906200275c919062002e2a565b80156200277357506000856001600160a01b03163b115b95945050505050565b60608262002795576200278f82620027e0565b620026c4565b8151158015620027ad57506001600160a01b0384163b155b15620027d857604051639996b31560e01b81526001600160a01b03851660048201526024016200068e565b5080620026c4565b805115620027f15780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b610f2f8062002e6983390190565b82805482825590600052602060002090810192821562002856579160200282015b828111156200285657825182559160200191906001019062002839565b506200286492915062002868565b5090565b5b8082111562002864576000815560010162002869565b6000602082840312156200289257600080fd5b5035919050565b803560ff81168114620028ab57600080fd5b919050565b600060208284031215620028c357600080fd5b620025848262002899565b80151581146200149b57600080fd5b600060208284031215620028f057600080fd5b8135620026c481620028ce565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156200293f576200293f620028fd565b604052919050565b600082601f8301126200295957600080fd5b813567ffffffffffffffff811115620029765762002976620028fd565b6200298b601f8201601f191660200162002913565b818152846020838601011115620029a157600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a08688031215620029d757600080fd5b853567ffffffffffffffff80821115620029f057600080fd5b620029fe89838a0162002947565b9650602088013591508082111562002a1557600080fd5b5062002a248882890162002947565b94505060408601356001600160701b038116811462002a4257600080fd5b925062002a526060870162002899565b915060808601356002811062002a6757600080fd5b809150509295509295909350565b6001600160a01b03811681146200149b57600080fd5b60008060006060848603121562002aa157600080fd5b833562002aae8162002a75565b95602085013595506040909401359392505050565b60006020828403121562002ad657600080fd5b8135620026c48162002a75565b6000806040838503121562002af757600080fd5b62002b028362002899565b915060208084013567ffffffffffffffff8082111562002b2157600080fd5b818601915086601f83011262002b3657600080fd5b81358181111562002b4b5762002b4b620028fd565b8060051b915062002b5e84830162002913565b818152918301840191848101908984111562002b7957600080fd5b938501935b8385101562002b995784358252938501939085019062002b7e565b8096505050505050509250929050565b6000806040838503121562002bbd57600080fd5b823562002bca8162002a75565b946020939093013593505050565b634e487b7160e01b600052602160045260246000fd5b6001600160a01b0389811682528816602082015260ff87166040820152606081018690526080810185905260a0810184905282151560c082015261010081016002831062002c4c57634e487b7160e01b600052602160045260246000fd5b8260e08301529998505050505050505050565b634e487b7160e01b600052601160045260246000fd5b8082018082111562002587576200258762002c5f565b60005b8381101562002ca857818101518382015260200162002c8e565b50506000910152565b6000815180845262002ccb81602086016020860162002c8b565b601f01601f19169290920160200192915050565b60608152600062002cf4606083018662002cb1565b828103602084015262002d08818662002cb1565b9150506001600160701b0383166040830152949350505050565b808202811582820484141762002587576200258762002c5f565b60008262002d5a57634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b60006020828403121562002d8857600080fd5b8151620026c48162002a75565b8181038181111562002587576200258762002c5f565b60008162002dbd5762002dbd62002c5f565b506000190190565b60006001820162002dda5762002dda62002c5f565b5060010190565b60006020828403121562002df457600080fd5b5051919050565b60008060006060848603121562002e1157600080fd5b8351925060208401519150604084015190509250925092565b60006020828403121562002e3d57600080fd5b8151620026c481620028ce565b6000825162002e5e81846020870162002c8b565b919091019291505056fe60806040523480156200001157600080fd5b5060405162000f2f38038062000f2f833981016040819052620000349162000406565b338383600362000045838262000522565b50600462000054828262000522565b5050506001600160a01b0381166200008757604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b6200009281620000b1565b50620000a8336001600160701b03831662000103565b50505062000616565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0382166200012f5760405163ec442f0560e01b8152600060048201526024016200007e565b6200013d6000838362000141565b5050565b6200014e8383836200020e565b6000620001636005546001600160a01b031690565b90506001600160a01b038116156200020857806001600160a01b0316846001600160a01b03161480620001a75750806001600160a01b0316836001600160a01b0316145b80620001ba57506001600160a01b038416155b620002085760405162461bcd60e51b815260206004820152601b60248201527f42656c6c756d3a2043414e4e4f545f5452414e534645525f594554000000000060448201526064016200007e565b50505050565b6001600160a01b0383166200023d578060026000828254620002319190620005ee565b90915550620002b19050565b6001600160a01b03831660009081526020819052604090205481811015620002925760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016200007e565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b038216620002cf57600280548290039055620002ee565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516200033491815260200190565b60405180910390a3505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200036957600080fd5b81516001600160401b038082111562000386576200038662000341565b604051601f8301601f19908116603f01168101908282118183101715620003b157620003b162000341565b81604052838152602092508683858801011115620003ce57600080fd5b600091505b83821015620003f25785820183015181830184015290820190620003d3565b600093810190920192909252949350505050565b6000806000606084860312156200041c57600080fd5b83516001600160401b03808211156200043457600080fd5b620004428783880162000357565b945060208601519150808211156200045957600080fd5b50620004688682870162000357565b604086015190935090506001600160701b03811681146200048857600080fd5b809150509250925092565b600181811c90821680620004a857607f821691505b602082108103620004c957634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200051d57600081815260208120601f850160051c81016020861015620004f85750805b601f850160051c820191505b81811015620005195782815560010162000504565b5050505b505050565b81516001600160401b038111156200053e576200053e62000341565b62000556816200054f845462000493565b84620004cf565b602080601f8311600181146200058e5760008415620005755750858301515b600019600386901b1c1916600185901b17855562000519565b600085815260208120601f198616915b82811015620005bf578886015182559484019460019091019084016200059e565b5085821015620005de5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b808201808211156200061057634e487b7160e01b600052601160045260246000fd5b92915050565b61090980620006266000396000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c8063715018a611610071578063715018a6146101575780638da5cb5b1461016157806395d89b411461017c578063a9059cbb14610184578063dd62ed3e14610197578063f2fde38b146101d057600080fd5b806306fdde03146100b9578063095ea7b3146100d757806318160ddd146100fa57806323b872dd1461010c578063313ce5671461011f57806370a082311461012e575b600080fd5b6100c16101e3565b6040516100ce9190610753565b60405180910390f35b6100ea6100e53660046107bd565b610275565b60405190151581526020016100ce565b6002545b6040519081526020016100ce565b6100ea61011a3660046107e7565b61028f565b604051601281526020016100ce565b6100fe61013c366004610823565b6001600160a01b031660009081526020819052604090205490565b61015f6102b3565b005b6005546040516001600160a01b0390911681526020016100ce565b6100c16102c7565b6100ea6101923660046107bd565b6102d6565b6100fe6101a5366004610845565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b61015f6101de366004610823565b6102e4565b6060600380546101f290610878565b80601f016020809104026020016040519081016040528092919081815260200182805461021e90610878565b801561026b5780601f106102405761010080835404028352916020019161026b565b820191906000526020600020905b81548152906001019060200180831161024e57829003601f168201915b5050505050905090565b600033610283818585610327565b60019150505b92915050565b60003361029d858285610339565b6102a88585856103b7565b506001949350505050565b6102bb610416565b6102c56000610443565b565b6060600480546101f290610878565b6000336102838185856103b7565b6102ec610416565b6001600160a01b03811661031b57604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b61032481610443565b50565b6103348383836001610495565b505050565b6001600160a01b0383811660009081526001602090815260408083209386168352929052205460001981146103b157818110156103a257604051637dc7a0d960e11b81526001600160a01b03841660048201526024810182905260448101839052606401610312565b6103b184848484036000610495565b50505050565b6001600160a01b0383166103e157604051634b637e8f60e11b815260006004820152602401610312565b6001600160a01b03821661040b5760405163ec442f0560e01b815260006004820152602401610312565b61033483838361056a565b6005546001600160a01b031633146102c55760405163118cdaa760e01b8152336004820152602401610312565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0384166104bf5760405163e602df0560e01b815260006004820152602401610312565b6001600160a01b0383166104e957604051634a1406b160e11b815260006004820152602401610312565b6001600160a01b03808516600090815260016020908152604080832093871683529290522082905580156103b157826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161055c91815260200190565b60405180910390a350505050565b610575838383610629565b60006105896005546001600160a01b031690565b90506001600160a01b038116156103b157806001600160a01b0316846001600160a01b031614806105cb5750806001600160a01b0316836001600160a01b0316145b806105dd57506001600160a01b038416155b6103b15760405162461bcd60e51b815260206004820152601b60248201527f42656c6c756d3a2043414e4e4f545f5452414e534645525f59455400000000006044820152606401610312565b6001600160a01b03831661065457806002600082825461064991906108b2565b909155506106c69050565b6001600160a01b038316600090815260208190526040902054818110156106a75760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401610312565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b0382166106e257600280548290039055610701565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161074691815260200190565b60405180910390a3505050565b600060208083528351808285015260005b8181101561078057858101830151858201604001528201610764565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b03811681146107b857600080fd5b919050565b600080604083850312156107d057600080fd5b6107d9836107a1565b946020939093013593505050565b6000806000606084860312156107fc57600080fd5b610805846107a1565b9250610813602085016107a1565b9150604084013590509250925092565b60006020828403121561083557600080fd5b61083e826107a1565b9392505050565b6000806040838503121561085857600080fd5b610861836107a1565b915061086f602084016107a1565b90509250929050565b600181811c9082168061088c57607f821691505b6020821081036108ac57634e487b7160e01b600052602260045260246000fd5b50919050565b8082018082111561028957634e487b7160e01b600052601160045260246000fdfea26469706673582212209fd5ea3d869bae12a381f0e829925dd684325f6d3322b51596c4432d24e4925364736f6c63430008140033a264697066735822122019769a3f98dfb864f1e3a03295cf8a76721ac21f478548cbec6ac488569b7c7b64736f6c63430008140033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000003a7a1f256b6180d59f58efc080321a09d456ee9b00000000000000000000000095a7e403d7cf20f675ff9273d66e94d35ba49fa30000000000000000000000001d368773735ee1e678950b7a97bca2cafb330cdc
-----Decoded View---------------
Arg [0] : msig (address): 0x3A7A1f256b6180d59f58eFc080321A09D456Ee9b
Arg [1] : metropolisRouter_ (address): 0x95a7e403d7cF20F675fF9273D66e94d35ba49fA3
Arg [2] : shadowRouter_ (address): 0x1D368773735ee1E678950B7A97bcA2CafB330CDc
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000003a7a1f256b6180d59f58efc080321a09d456ee9b
Arg [1] : 00000000000000000000000095a7e403d7cf20f675ff9273d66e94d35ba49fa3
Arg [2] : 0000000000000000000000001d368773735ee1e678950b7a97bca2cafb330cdc
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 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.