More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 143 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Collect ETH | 6563794 | 10 hrs ago | IN | 0 ETH | 0.00000412 | ||||
Collect ETH | 6030037 | 6 days ago | IN | 0 ETH | 0.00000395 | ||||
Collect ETH | 6030007 | 6 days ago | IN | 0 ETH | 0.00000604 | ||||
Collect ETH | 6012053 | 7 days ago | IN | 0 ETH | 0.00000395 | ||||
Collect ETH | 6012022 | 7 days ago | IN | 0 ETH | 0.00000604 | ||||
Collect ETH | 5565307 | 12 days ago | IN | 0 ETH | 0.00000412 | ||||
Collect ETH | 5337526 | 15 days ago | IN | 0 ETH | 0.0000048 | ||||
Collect ETH | 5325261 | 15 days ago | IN | 0 ETH | 0.00000412 | ||||
Collect ETH | 4999725 | 19 days ago | IN | 0 ETH | 0.00000419 | ||||
Collect ETH | 4661569 | 23 days ago | IN | 0 ETH | 0.00000402 | ||||
Collect ETH | 4661543 | 23 days ago | IN | 0 ETH | 0.00000487 | ||||
Collect ETH | 4558585 | 24 days ago | IN | 0 ETH | 0.00000488 | ||||
Collect ETH | 4217411 | 28 days ago | IN | 0 ETH | 0.00000619 | ||||
Collect ETH | 3979668 | 31 days ago | IN | 0 ETH | 0.00000419 | ||||
Collect ETH | 3774865 | 33 days ago | IN | 0 ETH | 0.00000419 | ||||
Collect ETH | 3362129 | 38 days ago | IN | 0 ETH | 0.00000614 | ||||
Collect ETH | 3093366 | 41 days ago | IN | 0 ETH | 0.00000613 | ||||
Collect ETH | 3049641 | 42 days ago | IN | 0 ETH | 0.00000419 | ||||
Collect ETH | 2683997 | 46 days ago | IN | 0 ETH | 0.00000648 | ||||
Collect ETH | 2667434 | 46 days ago | IN | 0 ETH | 0.00000419 | ||||
Collect ETH | 2451107 | 49 days ago | IN | 0 ETH | 0.00000577 | ||||
Collect ETH | 2332731 | 50 days ago | IN | 0 ETH | 0.00000592 | ||||
Collect ETH | 2332718 | 50 days ago | IN | 0 ETH | 0.00000592 | ||||
Collect ETH | 2332713 | 50 days ago | IN | 0 ETH | 0.00000647 | ||||
Collect ETH | 2301053 | 51 days ago | IN | 0 ETH | 0.00000616 |
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
6599365 | 12 mins ago | 0.0000594 ETH | ||||
6573492 | 7 hrs ago | 0.000004 ETH | ||||
6569075 | 8 hrs ago | 0.000001 ETH | ||||
6568903 | 8 hrs ago | 0.000001 ETH | ||||
6567168 | 9 hrs ago | 0 ETH | ||||
6563794 | 10 hrs ago | 0.00021461 ETH | ||||
6563764 | 10 hrs ago | 0.00006 ETH | ||||
6563600 | 10 hrs ago | 0.00009899 ETH | ||||
6563581 | 10 hrs ago | 0.00006929 ETH | ||||
6560725 | 11 hrs ago | 0.00001979 ETH | ||||
6560704 | 11 hrs ago | 0.00002 ETH | ||||
6560670 | 11 hrs ago | 0.00000742 ETH | ||||
6560650 | 11 hrs ago | 0.00001 ETH | ||||
6560607 | 11 hrs ago | 0.0005 ETH | ||||
6559226 | 11 hrs ago | 0.0005 ETH | ||||
6553817 | 13 hrs ago | 0.00007 ETH | ||||
6553793 | 13 hrs ago | 0.0001 ETH | ||||
6552154 | 13 hrs ago | 0.0000004 ETH | ||||
6552094 | 13 hrs ago | 0.000001 ETH | ||||
6552071 | 13 hrs ago | 0.000001 ETH | ||||
6544141 | 16 hrs ago | 0.00004949 ETH | ||||
6544121 | 16 hrs ago | 0.00010889 ETH | ||||
6542299 | 16 hrs ago | 0.00001286 ETH | ||||
6542277 | 16 hrs ago | 0.000013 ETH | ||||
6542204 | 16 hrs ago | 0.0005 ETH |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Source Code Verified (Exact Match)
Contract Name:
FeeHandler
Compiler Version
v0.8.24-1.0.1
ZkSolc Version
v1.5.7
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.24; import {IFeeHandler} from "./interfaces/IFeeHandler.sol"; import {FixedPointMathLib} from "@solmate/utils/FixedPointMathLib.sol"; import {FactoryOwned} from "./FactoryOwned.sol"; contract FeeHandler is IFeeHandler, FactoryOwned { using FixedPointMathLib for uint256; uint256 public constant MAX_JACKPOT_PROBABILITY = 0.05e18; // 5% uint256 public constant MAX_FORCE_AWARD_JACKPOT_BUFFER = 1 days; // Configuration for jackpot JackpotConfig public jackpotConfig; // Configuration for % of fees that are added to the pot FeeConfig public feeConfig; // Block number at which rollJackpot() was last called uint256 public lastRolledBlockNumber; // ID of jackpot that hasn't been locked (ie. fees accrue to its pot) uint256 public nextJackpotId; // Mapping of jackpot ID to jackpot state mapping(uint256 => JackpotState) public jackpotStateById; // Amount of ETH accrued to users mapping(address => uint256) public accruedETH; // ======================================== CONSTRUCTOR ======================================== constructor( address _factory, JackpotConfig memory _jackpotConfig, FeeConfig memory _feeConfig ) FactoryOwned(_factory) { _setJackpotConfig(_jackpotConfig); _setFeeConfig(_feeConfig); } // ======================================== ADMIN FUNCTIONS ======================================== function setJackpotConfig(JackpotConfig memory config) external onlyFactoryOwner { _setJackpotConfig(config); } function setFeeConfig(FeeConfig memory config) external onlyFactoryOwner { _setFeeConfig(config); } function _setJackpotConfig(JackpotConfig memory config) internal { if (!config.lotteryEnabled) { if (config.jackpotProbability != 0 || config.minimumJackpotAmount != 0 || config.feeTicketPrice != 0 || config.directTicketPrice != 0 || config.forceAwardJackpotBuffer != 0 ) revert InvalidJackpotConfig(); } else { if (config.jackpotProbability == 0 || config.minimumJackpotAmount == 0 || config.feeTicketPrice == 0 || config.forceAwardJackpotBuffer == 0 ) revert InvalidJackpotConfig(); if (config.jackpotProbability > MAX_JACKPOT_PROBABILITY) revert JackpotProbabilityTooHigh(); if (config.forceAwardJackpotBuffer > MAX_FORCE_AWARD_JACKPOT_BUFFER) revert AwardJackpotBufferTooLarge(); if (config.directTicketPrice < config.feeTicketPrice) revert DirectTicketPriceTooLow(); } jackpotConfig = config; } function _setFeeConfig(FeeConfig memory config) internal { if ( config.tradingFeeToCreator + config.tradingFeeToPot > FixedPointMathLib.WAD || config.createFeeToPot > FixedPointMathLib.WAD || config.launchFeeToPot > FixedPointMathLib.WAD || config.buyTicketToPot > FixedPointMathLib.WAD ) revert FeeTooHigh(); feeConfig = config; } function commitAdminEntropy(uint256 jackpotId, bytes32 adminEntropyHash) external onlyFactoryOwner { JackpotState storage jackpotState = jackpotStateById[jackpotId]; if (jackpotState.lockedBlockNumber != 0) revert JackpotLocked(); jackpotState.adminEntropyHash = adminEntropyHash; } // ======================================== FACTORY FUNCTIONS ======================================== function handleCreateFee(address user) external payable onlyFactory { uint256 amount = msg.value; if (jackpotConfig.lotteryEnabled) { uint256 noOfTickets = amount / jackpotConfig.feeTicketPrice; _addTickets(user, noOfTickets == 0 ? 1 : noOfTickets); amount = _subtractFeeToPot(amount, feeConfig.createFeeToPot); } accruedETH[treasury()] += amount; } function handleTradingFee(address user, address tokenCreator) external payable onlyFactory { uint256 amount = msg.value; uint256 amountToCreator = amount.mulWadDown(feeConfig.tradingFeeToCreator); accruedETH[tokenCreator] += amountToCreator; if (jackpotConfig.lotteryEnabled) { uint256 noOfTickets = amount / jackpotConfig.feeTicketPrice; if (noOfTickets != 0) _addTickets(user, noOfTickets); amount = _subtractFeeToPot(amount, feeConfig.tradingFeeToPot); } accruedETH[treasury()] += amount - amountToCreator; } function handleLaunchFee() external payable onlyFactory { uint256 amount = msg.value; if (jackpotConfig.lotteryEnabled) { amount = _subtractFeeToPot(amount, feeConfig.launchFeeToPot); } accruedETH[treasury()] += amount; } function rollJackpot() external onlyFactory { if (!jackpotConfig.lotteryEnabled) return; if (block.number == lastRolledBlockNumber) return; lastRolledBlockNumber = block.number; uint256 _nextJackpotId = nextJackpotId; JackpotState storage jackpotState = jackpotStateById[_nextJackpotId]; if ( jackpotState.nextTicketId == 0 || jackpotState.pot < jackpotConfig.minimumJackpotAmount || jackpotState.adminEntropyHash == bytes32(0) ) return; uint256 entropy = uint256(_getEntropy(_nextJackpotId, block.number - 1)); if (entropy % FixedPointMathLib.WAD >= jackpotConfig.jackpotProbability) return; jackpotState.lockedBlockNumber = block.number; jackpotState.lockedTimestamp = block.timestamp; nextJackpotId++; } // ======================================== USER FUNCTIONS ======================================== function collectETH() external returns (uint256 ethReceived) { ethReceived = accruedETH[msg.sender]; accruedETH[msg.sender] = 0; _transferETH(msg.sender, ethReceived); } function buyTickets() external payable { if (!jackpotConfig.lotteryEnabled) revert LotteryDisabled(); uint256 ethAmount = msg.value; uint256 noOfTickets = ethAmount / jackpotConfig.directTicketPrice; if (noOfTickets == 0) revert ValueBelowTicketPrice(); _addTickets(msg.sender, noOfTickets); ethAmount = _subtractFeeToPot(ethAmount, feeConfig.buyTicketToPot); accruedETH[treasury()] += ethAmount; } function donateToPot() external payable { if (!jackpotConfig.lotteryEnabled) revert LotteryDisabled(); uint256 _nextJackpotId = nextJackpotId; jackpotStateById[_nextJackpotId].pot += msg.value; emit JackpotDonated(_nextJackpotId, msg.value); } function commitCrowdEntropy(uint256 jackpotId) external { if (jackpotId >= nextJackpotId) revert JackpotNotLocked(); JackpotState storage jackpotState = jackpotStateById[jackpotId]; if (jackpotState.crowdEntropy != bytes32(0)) revert AlreadyCommited(); jackpotState.crowdEntropy = _getCrowdEntropy(jackpotId); } function awardJackpot(uint256 jackpotId, bytes32 adminEntropy) external { if (jackpotId >= nextJackpotId) revert JackpotNotLocked(); JackpotState storage jackpotState = jackpotStateById[jackpotId]; if (keccak256(abi.encodePacked(adminEntropy)) != jackpotState.adminEntropyHash) { revert AdminRandomnessMismatch(); } bytes32 _crowdEntropy = _getCrowdEntropy(jackpotId); jackpotState.crowdEntropy = _crowdEntropy; bytes32 entropy = keccak256(abi.encodePacked(_crowdEntropy, adminEntropy)); _awardJackpot(jackpotId, entropy); } function forceAwardJackpot(uint256 jackpotId) external { if (jackpotId >= nextJackpotId) revert JackpotNotLocked(); JackpotState storage jackpotState = jackpotStateById[jackpotId]; if (block.timestamp < jackpotState.lockedTimestamp + jackpotConfig.forceAwardJackpotBuffer) { revert TooEarly(); } bytes32 _crowdEntropy = _getCrowdEntropy(jackpotId); jackpotState.crowdEntropy = _crowdEntropy; _awardJackpot(jackpotId, _crowdEntropy); } // ======================================== VIEW FUNCTIONS ======================================== function currentJackpotSize() external view returns (uint256) { return jackpotStateById[nextJackpotId].pot; } function ticketFromIndex(uint256 jackpotId, uint256 index) external view returns (Ticket memory) { return jackpotStateById[jackpotId].tickets[index]; } function ticketQueueLength(uint256 jackpotId) external view returns (uint256) { return jackpotStateById[jackpotId].tickets.length; } // ======================================== HELPER FUNCTIONS ======================================== function _subtractFeeToPot(uint256 amount, uint256 feeToPot) internal returns (uint256) { uint256 amountToPot = amount.mulWadDown(feeToPot); jackpotStateById[nextJackpotId].pot += amountToPot; return amount - amountToPot; } function _addTickets(address user, uint256 noOfTickets) internal { uint256 _nextJackpotId = nextJackpotId; JackpotState storage jackpotState = jackpotStateById[_nextJackpotId]; Ticket memory ticket = Ticket({user: user, firstTicketId: jackpotState.nextTicketId}); jackpotState.tickets.push(ticket); jackpotState.nextTicketId += noOfTickets; emit TicketAdded(_nextJackpotId, user, noOfTickets); } // From https://github.com/OpenZeppelin/openzeppelin-contracts/blob/932fddf69a699a9a80fd2396fd1a2ab91cdda123/contracts/utils/structs/Checkpoints.sol#L247-L255 function _findTicketId(Ticket[] storage tickets, uint256 ticketId) internal view returns (address) { uint256 low = 0; uint256 high = tickets.length; while (low < high) { uint256 mid = (high + low) / 2; if (tickets[mid].firstTicketId > ticketId) { high = mid; } else { low = mid + 1; } } // high should always be non-zero, _findTicketId() is always called with ticketId in range return tickets[high - 1].user; } function _awardJackpot(uint256 jackpotId, bytes32 entropy) internal { JackpotState storage jackpotState = jackpotStateById[jackpotId]; uint256 _pot = jackpotState.pot; if (_pot == 0) revert JackpotAlreadyAwarded(); uint256 winningTicketId = uint256(entropy) % jackpotState.nextTicketId; address winner = _findTicketId(jackpotState.tickets, winningTicketId); jackpotState.pot = 0; accruedETH[winner] += _pot; emit JackpotWon(jackpotId, winner, _pot); } function _getCrowdEntropy(uint256 jackpotId) internal view returns (bytes32) { JackpotState storage jackpotState = jackpotStateById[jackpotId]; bytes32 entropy = jackpotState.crowdEntropy; if (entropy != bytes32(0)) return entropy; uint256 lockedBlockNumber = jackpotState.lockedBlockNumber; if (lockedBlockNumber == 0) revert JackpotNotLocked(); /* Crowd entropy is sourced from the 5th block after the block at which the jackpot was locked. If 256 blocks have passed since the 5th block, use the earliest blockhash available. */ uint256 earliestBlockNumber = block.number - 255; uint256 selectedBlockNumber = lockedBlockNumber + 5; if (block.number <= selectedBlockNumber) revert TooEarly(); return _getEntropy( jackpotId, selectedBlockNumber > earliestBlockNumber ? selectedBlockNumber : earliestBlockNumber ); } // Include jackpot ID to get different entropy for multiple jackpots in the same block function _getEntropy(uint256 jackpotId, uint256 blockNumber) internal view returns (bytes32) { return keccak256(abi.encodePacked(jackpotId, blockhash(blockNumber))); } }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.24; import {Owned} from "@solmate/auth/Owned.sol"; import {FixedPointMathLib} from "@solmate/utils/FixedPointMathLib.sol"; import {IFactory} from "./interfaces/IFactory.sol"; import {IUniswapV2Factory} from "./interfaces/IUniswapV2Factory.sol"; import {IUniswapV2Pair} from "./interfaces/IUniswapV2Pair.sol"; import {IWETH} from "./interfaces/IWETH.sol"; import {FeeHandler} from "./FeeHandler.sol"; import {LPTokenHolder} from "./LPTokenHolder.sol"; import {Token} from "./Token.sol"; contract Factory is IFactory, Owned { using FixedPointMathLib for uint256; uint256 public constant MAX_TRADING_FEE = 0.05e18; // 5% uint256 public constant MAX_LAUNCH_FEE = 0.05e18; // 5% uint256 public constant MINIMUM_VIRTUAL_LIQUIDITY = 0.01 ether; IWETH public immutable weth; IUniswapV2Factory public immutable uniswapV2Factory; FeeHandler public feeHandler; LPTokenHolder public lpTokenHolder; // Protocol treasury address address public treasury; // Amount of "fake" ETH liquidity each pair starts with uint256 public virtualLiquidity; // Amount of ETH to be raised for bonding to end uint256 public targetETHRaised; // Fee (in ETH) for creating tokens uint256 public createFee; // Fee (%) for buying and selling tokens uint256 public tradingFee; // Fee (%) for launching tokens to DEX uint256 public launchFee; // Reserves and additional info for each token mapping(address => Pair) public pairs; // ======================================== CONSTRUCTOR ======================================== struct FactoryParams { address owner; address treasury; address weth; address uniswapV2Factory; uint256 virtualLiquidity; uint256 targetETHRaised; uint256 createFee; uint256 tradingFee; uint256 launchFee; } constructor(FactoryParams memory factoryParams) Owned(factoryParams.owner) { if (factoryParams.virtualLiquidity < MINIMUM_VIRTUAL_LIQUIDITY) revert MinimumLiquidityTooSmall(); weth = IWETH(factoryParams.weth); uniswapV2Factory = IUniswapV2Factory(factoryParams.uniswapV2Factory); treasury = factoryParams.treasury; virtualLiquidity = factoryParams.virtualLiquidity; targetETHRaised = factoryParams.targetETHRaised; _setFees(factoryParams.createFee, factoryParams.tradingFee, factoryParams.launchFee); } // ======================================== ADMIN FUNCTIONS ======================================== function setFeeHandler(address _feeHandler) external onlyOwner { feeHandler = FeeHandler(_feeHandler); } function setLpTokenHolder(address _lpTokenHolder) external onlyOwner { lpTokenHolder = LPTokenHolder(_lpTokenHolder); } function setTreasury(address _treasury) external onlyOwner { treasury = _treasury; } function setVirtualLiquidity(uint256 _virtualLiquidity) external onlyOwner { if (_virtualLiquidity < MINIMUM_VIRTUAL_LIQUIDITY) revert MinimumLiquidityTooSmall(); virtualLiquidity = _virtualLiquidity; } function setTargetETHRaised(uint256 _targetETHRaised) external onlyOwner { targetETHRaised = _targetETHRaised; } function setFees(uint256 _createFee, uint256 _tradingFee, uint256 _launchFee) external onlyOwner { _setFees(_createFee, _tradingFee, _launchFee); } function _setFees(uint256 _createFee, uint256 _tradingFee, uint256 _launchFee) internal { if (_tradingFee > MAX_TRADING_FEE || _launchFee > MAX_LAUNCH_FEE) revert FeeTooLarge(); createFee = _createFee; tradingFee = _tradingFee; launchFee = _launchFee; } // ======================================== USER FUNCTIONS ======================================== function createToken(string memory name, string memory symbol, string memory metadata, bytes32 salt) external payable returns (address tokenAddress, uint256 amountOut) { uint256 _createFee = createFee; if (msg.value < _createFee) revert InsufficientETHForCreateFee(); Token token = new Token{salt: salt}(name, symbol, metadata, msg.sender); tokenAddress = address(token); pairs[tokenAddress] = Pair({ virtualLiquidity: virtualLiquidity, reserveETH: virtualLiquidity, reserveToken: token.INITIAL_AMOUNT() }); feeHandler.rollJackpot(); // minAmountOut not needed here as token was just created uint256 amountIn = msg.value - _createFee; if (amountIn != 0) amountOut = _buyTokens(tokenAddress, amountIn, 0); feeHandler.handleCreateFee{value: _createFee}(msg.sender); emit TokenCreated(tokenAddress, msg.sender); } function buyTokens(address token, uint256 minAmountOut) external payable returns (uint256 amountOut) { Pair memory pair = pairs[token]; if (pair.virtualLiquidity == 0) revert InvalidToken(); uint256 actualLiquidity = pair.reserveETH - pair.virtualLiquidity; if (actualLiquidity >= targetETHRaised) revert TargetETHRaisedReached(); feeHandler.rollJackpot(); amountOut = _buyTokens(token, msg.value, minAmountOut); } function sellTokens(address token, uint256 amountIn, uint256 minAmountOut) external returns (uint256 amountOut) { Pair storage pair = pairs[token]; if (pair.virtualLiquidity == 0) revert InvalidToken(); uint256 actualLiquidity = pair.reserveETH - pair.virtualLiquidity; if (actualLiquidity >= targetETHRaised) revert TargetETHRaisedReached(); amountOut = _getAmountOut(amountIn, pair.reserveToken, pair.reserveETH); // In theory, this check should never fail if (amountOut > actualLiquidity) revert InsufficientETHLiquidity(); pair.reserveToken += amountIn; pair.reserveETH -= amountOut; uint256 feeAmount; (feeAmount, amountOut) = _subtractFee(amountOut, tradingFee); if (amountOut < minAmountOut) revert InsufficientAmountOut(); feeHandler.rollJackpot(); feeHandler.handleTradingFee{value: feeAmount}(msg.sender, Token(token).creator()); Token(token).transferFrom(msg.sender, address(this), amountIn); _transferETH(msg.sender, amountOut); emit TokenSold(msg.sender, token, amountOut, amountIn); } function launchToken(address token) external returns (address uniswapV2Pair) { Pair memory pair = pairs[token]; if (pair.virtualLiquidity == 0) revert InvalidToken(); uint256 actualLiquidity = pair.reserveETH - pair.virtualLiquidity; if (actualLiquidity < targetETHRaised) revert TargetETHRaisedNotReached(); delete pairs[token]; (uint256 feeAmount, uint256 ethAmount) = _subtractFee(actualLiquidity, launchFee); uint256 tokenAmount = pair.reserveToken; // Burn tokens equal to ratio of reserveETH removed to maintain constant price uint256 burnAmount = (pair.virtualLiquidity + feeAmount) * tokenAmount / pair.reserveETH; tokenAmount -= burnAmount; Token(token).burn(burnAmount); uniswapV2Pair = uniswapV2Factory.getPair(address(weth), address(token)); if (uniswapV2Pair == address(0)) { uniswapV2Pair = uniswapV2Factory.createPair(address(weth), address(token)); } weth.deposit{value: ethAmount}(); weth.transfer(uniswapV2Pair, ethAmount); Token(token).transfer(uniswapV2Pair, tokenAmount); /* This is guaranteed to be the first mint as: - Token is non-transferable before launch - UniswapV2Pair.mint() cannot be called without providing both WETH and token liquidity */ IUniswapV2Pair(uniswapV2Pair).mint(address(lpTokenHolder)); lpTokenHolder.addLaunchedToken(token, uniswapV2Pair); Token(token).enableTransfers(); feeHandler.rollJackpot(); feeHandler.handleLaunchFee{value: feeAmount}(); emit TokenLaunched(token, uniswapV2Pair); } // ======================================== VIEW FUNCTIONS ======================================== function previewBuyTokens(address token, uint256 amountIn) external view returns (uint256 amountOut) { Pair memory pair = pairs[token]; amountIn -= amountIn.mulWadDown(tradingFee); amountOut = _getAmountOut(amountIn, pair.reserveETH, pair.reserveToken); } function previewSellTokens(address token, uint256 amountIn) external view returns (uint256 amountOut) { Pair memory pair = pairs[token]; amountOut = _getAmountOut(amountIn, pair.reserveToken, pair.reserveETH); uint256 actualLiquidity = pair.reserveETH - pair.virtualLiquidity; if (amountOut > actualLiquidity) revert InsufficientETHLiquidity(); amountOut -= amountOut.mulWadDown(tradingFee); } function tokenPrice(address token) external view returns (uint256 price) { Pair memory pair = pairs[token]; price = pair.reserveETH.divWadDown(pair.reserveToken); } function bondingCurveProgress(address token) external view returns (uint256 progress) { Pair memory pair = pairs[token]; uint256 actualLiquidity = pair.reserveETH - pair.virtualLiquidity; progress = actualLiquidity.divWadDown(targetETHRaised); } // ======================================== HELPER FUNCTIONS ======================================== function _buyTokens(address token, uint256 ethAmount, uint256 minAmountOut) internal returns (uint256 amountOut) { Pair storage pair = pairs[token]; (uint256 feeAmount, uint256 amountIn) = _subtractFee(ethAmount, tradingFee); amountOut = _getAmountOut(amountIn, pair.reserveETH, pair.reserveToken); pair.reserveETH += amountIn; pair.reserveToken -= amountOut; if (amountOut < minAmountOut) revert InsufficientAmountOut(); Token(token).transfer(msg.sender, amountOut); feeHandler.handleTradingFee{value: feeAmount}(msg.sender, Token(token).creator()); emit TokenBought(msg.sender, token, amountIn, amountOut); } function _subtractFee(uint256 amount, uint256 fee) internal pure returns (uint256 feeAmount, uint256 remainingAmount) { feeAmount = amount.mulWadDown(fee); remainingAmount = amount - feeAmount; } function _getAmountOut(uint256 amountIn, uint256 reserveIn, uint256 reserveOut) internal pure returns (uint256) { if (amountIn == 0) revert InsufficientAmountIn(); if (reserveIn == 0 || reserveOut == 0) revert InsufficientLiquidity(); return (amountIn * reserveOut) / (reserveIn + amountIn); } function _transferETH(address to, uint256 amount) internal { (bool success,) = payable(to).call{value: amount}(""); if (!success) revert ETHTransferFailed(); } receive() external payable {} }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Simple single owner authorization mixin. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Owned.sol) abstract contract Owned { /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event OwnershipTransferred(address indexed user, address indexed newOwner); /*////////////////////////////////////////////////////////////// OWNERSHIP STORAGE //////////////////////////////////////////////////////////////*/ address public owner; modifier onlyOwner() virtual { require(msg.sender == owner, "UNAUTHORIZED"); _; } /*////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor(address _owner) { owner = _owner; emit OwnershipTransferred(address(0), _owner); } /*////////////////////////////////////////////////////////////// OWNERSHIP LOGIC //////////////////////////////////////////////////////////////*/ function transferOwnership(address newOwner) public virtual onlyOwner { owner = newOwner; emit OwnershipTransferred(msg.sender, newOwner); } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Arithmetic library with operations for fixed-point numbers. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol) /// @author Inspired by USM (https://github.com/usmfum/USM/blob/master/contracts/WadMath.sol) library FixedPointMathLib { /*////////////////////////////////////////////////////////////// SIMPLIFIED FIXED POINT OPERATIONS //////////////////////////////////////////////////////////////*/ uint256 internal constant MAX_UINT256 = 2**256 - 1; uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s. function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down. } function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up. } function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down. } function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up. } /*////////////////////////////////////////////////////////////// LOW LEVEL FIXED POINT OPERATIONS //////////////////////////////////////////////////////////////*/ function mulDivDown( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y)) if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) { revert(0, 0) } // Divide x * y by the denominator. z := div(mul(x, y), denominator) } } function mulDivUp( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y)) if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) { revert(0, 0) } // If x * y modulo the denominator is strictly greater than 0, // 1 is added to round up the division of x * y by the denominator. z := add(gt(mod(mul(x, y), denominator), 0), div(mul(x, y), denominator)) } } function rpow( uint256 x, uint256 n, uint256 scalar ) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { switch x case 0 { switch n case 0 { // 0 ** 0 = 1 z := scalar } default { // 0 ** n = 0 z := 0 } } default { switch mod(n, 2) case 0 { // If n is even, store scalar in z for now. z := scalar } default { // If n is odd, store x in z for now. z := x } // Shifting right by 1 is like dividing by 2. let half := shr(1, scalar) for { // Shift n right by 1 before looping to halve it. n := shr(1, n) } n { // Shift n right by 1 each iteration to halve it. n := shr(1, n) } { // Revert immediately if x ** 2 would overflow. // Equivalent to iszero(eq(div(xx, x), x)) here. if shr(128, x) { revert(0, 0) } // Store x squared. let xx := mul(x, x) // Round to the nearest number. let xxRound := add(xx, half) // Revert if xx + half overflowed. if lt(xxRound, xx) { revert(0, 0) } // Set x to scaled xxRound. x := div(xxRound, scalar) // If n is even: if mod(n, 2) { // Compute z * x. let zx := mul(z, x) // If z * x overflowed: if iszero(eq(div(zx, x), z)) { // Revert if x is non-zero. if iszero(iszero(x)) { revert(0, 0) } } // Round to the nearest number. let zxRound := add(zx, half) // Revert if zx + half overflowed. if lt(zxRound, zx) { revert(0, 0) } // Return properly scaled zxRound. z := div(zxRound, scalar) } } } } } /*////////////////////////////////////////////////////////////// GENERAL NUMBER UTILITIES //////////////////////////////////////////////////////////////*/ function sqrt(uint256 x) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { let y := x // We start y at x, which will help us make our initial estimate. z := 181 // The "correct" value is 1, but this saves a multiplication later. // This segment is to get a reasonable initial estimate for the Babylonian method. With a bad // start, the correct # of bits increases ~linearly each iteration instead of ~quadratically. // We check y >= 2^(k + 8) but shift right by k bits // each branch to ensure that if x >= 256, then y >= 256. if iszero(lt(y, 0x10000000000000000000000000000000000)) { y := shr(128, y) z := shl(64, z) } if iszero(lt(y, 0x1000000000000000000)) { y := shr(64, y) z := shl(32, z) } if iszero(lt(y, 0x10000000000)) { y := shr(32, y) z := shl(16, z) } if iszero(lt(y, 0x1000000)) { y := shr(16, y) z := shl(8, z) } // Goal was to get z*z*y within a small factor of x. More iterations could // get y in a tighter range. Currently, we will have y in [256, 256*2^16). // We ensured y >= 256 so that the relative difference between y and y+1 is small. // That's not possible if x < 256 but we can just verify those cases exhaustively. // Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), and either y >= 256, or x < 256. // Correctness can be checked exhaustively for x < 256, so we assume y >= 256. // Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps. // For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) is in the range // (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s = 1 and when s = 256 or 1/256. // Since y is in [256, 256*2^16), let a = y/65536, so that a is in [1/256, 256). Then we can estimate // sqrt(y) using sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18. // There is no overflow risk here since y < 2^136 after the first branch above. z := shr(18, mul(z, add(y, 65536))) // A mul() is saved from starting z at 181. // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough. z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) // If x+1 is a perfect square, the Babylonian method cycles between // floor(sqrt(x)) and ceil(sqrt(x)). This statement ensures we return floor. // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division // Since the ceil is rare, we save gas on the assignment and repeat division in the rare case. // If you don't care whether the floor or ceil square root is returned, you can remove this statement. z := sub(z, lt(div(x, z), z)) } } function unsafeMod(uint256 x, uint256 y) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { // Mod x by y. Note this will return // 0 instead of reverting if y is zero. z := mod(x, y) } } function unsafeDiv(uint256 x, uint256 y) internal pure returns (uint256 r) { /// @solidity memory-safe-assembly assembly { // Divide x by y. Note this will return // 0 instead of reverting if y is zero. r := div(x, y) } } function unsafeDivUp(uint256 x, uint256 y) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { // Add 1 to x * y if x % y > 0. Note this will // return 0 instead of reverting if y is zero. z := add(gt(mod(x, y), 0), div(x, y)) } } }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.24; import {IWETH} from "./IWETH.sol"; interface IFactory { error MinimumLiquidityTooSmall(); error FeeTooLarge(); error InsufficientETHForCreateFee(); error TargetETHRaisedTooLarge(); error TargetETHRaisedReached(); error TargetETHRaisedNotReached(); error InsufficientAmountIn(); error InsufficientAmountOut(); error InsufficientLiquidity(); error InsufficientETHLiquidity(); error InvalidToken(); error ETHTransferFailed(); event TokenCreated(address indexed token, address indexed creator); event TokenBought(address indexed user, address indexed token, uint256 indexed ethAmount, uint256 tokenAmount); event TokenSold(address indexed user, address indexed token, uint256 indexed ethAmount, uint256 tokenAmount); event TokenLaunched(address indexed token, address indexed uniswapV2Pair); struct Pair { uint256 virtualLiquidity; uint256 reserveETH; uint256 reserveToken; } function treasury() external view returns (address); function virtualLiquidity() external view returns (uint256); function targetETHRaised() external view returns (uint256); function createFee() external view returns (uint256); function tradingFee() external view returns (uint256); function launchFee() external view returns (uint256); function pairs(address) external view returns (uint256 virtualLiquidity, uint256 reserveETH, uint256 reserveToken); function setTreasury(address _treasury) external; function setVirtualLiquidity(uint256 _virtualLiquidity) external; function setTargetETHRaised(uint256 _targetETHRaised) external; function setFees(uint256 _createFee, uint256 _tradingFee, uint256 _launchFee) external; function createToken(string memory name, string memory symbol, string memory metadata, bytes32 salt) external payable returns (address tokenAddress, uint256 amountOut); function buyTokens(address token, uint256 minAmountOut) external payable returns (uint256); function sellTokens(address token, uint256 amountIn, uint256 minAmountOut) external returns (uint256 amountOut); function launchToken(address token) external returns (address uniswapV2Pair); function previewBuyTokens(address token, uint256 amountIn) external view returns (uint256 amountOut); function previewSellTokens(address token, uint256 amountIn) external view returns (uint256 amountOut); function tokenPrice(address token) external view returns (uint256 price); function bondingCurveProgress(address token) external view returns (uint256 progress); }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.24; interface IUniswapV2Factory { function getPair(address tokenA, address tokenB) external view returns (address pair); function createPair(address tokenA, address tokenB) external returns (address pair); }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.24; interface IUniswapV2Pair { function token0() external view returns (address); function getReserves() external view returns (uint112 _reserve0, uint112 _reserve1, uint32); function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); function transfer(address to, uint256 value) external returns (bool); function mint(address to) external returns (uint256 liquidity); function burn(address to) external returns (uint256 amount0, uint256 amount1); }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.24; interface IWETH { function balanceOf(address account) external view returns (uint256); function deposit() external payable; function withdraw(uint256 wad) external; function transfer(address dst, uint256 wad) external returns (bool); }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.24; import {FixedPointMathLib} from "@solmate/utils/FixedPointMathLib.sol"; import {IFactory} from "./interfaces/IFactory.sol"; import {IOwned} from "./interfaces/IOwned.sol"; import {IToken} from "./interfaces/IToken.sol"; import {IUniswapV2Pair} from "./interfaces/IUniswapV2Pair.sol"; import {FactoryOwned} from "./FactoryOwned.sol"; contract LPTokenHolder is FactoryOwned { using FixedPointMathLib for uint256; struct LaunchInfo { address pairAddress; uint256 initialLiquidity; } mapping(address => LaunchInfo) public launchInfo; // ======================================== CONSTRUCTOR ======================================== constructor(address _factory) FactoryOwned(_factory) {} // ======================================== ADMIN FUNCTIONS ======================================== function collectFeesFromAMM(address token) external onlyFactoryOwner { (IUniswapV2Pair pair, uint256 lpToBurn) = _lpTokensToBurn(token); pair.transfer(address(pair), lpToBurn); pair.burn(treasury()); } // ======================================== FACTORY FUNCTIONS ======================================== function addLaunchedToken(address token, address pairAddress) external onlyFactory { (,, uint256 ownedLiquidity) = _lpTokensAndLiquidityOwned(pairAddress); launchInfo[token] = LaunchInfo({pairAddress: pairAddress, initialLiquidity: ownedLiquidity}); } // ======================================== VIEW FUNCTIONS ======================================== function previewCollectFeesFromAMM(address token) external view returns (uint256 wethReceived, uint256 tokenReceived) { (IUniswapV2Pair pair, uint256 lpToBurn) = _lpTokensToBurn(token); uint256 lpTotalSupply = pair.totalSupply(); (uint256 reserve0, uint256 reserve1,) = pair.getReserves(); wethReceived = reserve0.mulDivDown(lpToBurn, lpTotalSupply); tokenReceived = reserve1.mulDivDown(lpToBurn, lpTotalSupply); if (pair.token0() == token) { (tokenReceived, wethReceived) = (wethReceived, tokenReceived); } } // ======================================== HELPER FUNCTIONS ======================================== function _lpTokensToBurn(address token) internal view returns (IUniswapV2Pair pair, uint256 lpToBurn) { LaunchInfo memory info = launchInfo[token]; uint256 lpOwned; uint256 ownedLiquidity; (pair, lpOwned, ownedLiquidity) = _lpTokensAndLiquidityOwned(info.pairAddress); lpToBurn = lpOwned.mulDivDown(ownedLiquidity - info.initialLiquidity, ownedLiquidity); } function _lpTokensAndLiquidityOwned(address pairAddress) internal view returns (IUniswapV2Pair pair, uint256 lpOwned, uint256 ownedLiquidity) { pair = IUniswapV2Pair(pairAddress); lpOwned = pair.balanceOf(address(this)); (uint256 reserve0, uint256 reserve1,) = pair.getReserves(); uint256 currentLiquidity = (reserve0 * reserve1).sqrt(); ownedLiquidity = currentLiquidity.mulDivDown(lpOwned, pair.totalSupply()); } }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.24; import {ERC20} from "@solmate/tokens/ERC20.sol"; contract Token is ERC20 { error NotFactory(); uint256 public constant INITIAL_AMOUNT = 1000_000_000e18; address public immutable factory; address public immutable creator; string public metadata; bool public transfersEnabled; constructor(string memory _name, string memory _symbol, string memory _metadata, address _creator) ERC20(_name, _symbol, 18) { factory = msg.sender; metadata = _metadata; creator = _creator; _mint(factory, INITIAL_AMOUNT); } function enableTransfers() external { if (msg.sender != factory) revert NotFactory(); transfersEnabled = true; } function burn(uint256 amount) external { if (msg.sender != factory) revert NotFactory(); _burn(msg.sender, amount); } function transfer(address to, uint256 amount) public override returns (bool) { if (!transfersEnabled && msg.sender != factory) revert NotFactory(); return super.transfer(to, amount); } function transferFrom(address from, address to, uint256 amount) public override returns (bool) { if (!transfersEnabled && msg.sender != factory) revert NotFactory(); return super.transferFrom(from, to, amount); } }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.24; interface IFeeHandler { error InvalidJackpotConfig(); error JackpotProbabilityTooHigh(); error FeeTooHigh(); error DirectTicketPriceTooLow(); error AwardJackpotBufferTooLarge(); error LotteryDisabled(); error ValueBelowTicketPrice(); error JackpotLocked(); error JackpotNotLocked(); error AlreadyCommited(); error TooEarly(); error AdminRandomnessMismatch(); error JackpotAlreadyAwarded(); event TicketAdded(uint256 indexed jackpotId, address indexed user, uint256 indexed noOfTicketsAdded); event JackpotWon(uint256 indexed jackpotId, address indexed user, uint256 indexed ethAmount); event JackpotDonated(uint256 indexed jackpotId, uint256 indexed ethAmount); struct Ticket { address user; uint256 firstTicketId; } struct JackpotState { // The next ticketId to assign. Also represents the total number of tickets uint256 nextTicketId; // Cumulative ticket queue Ticket[] tickets; // Amount of ETH in the pot uint256 pot; // Hash of random bytes32 from the admin bytes32 adminEntropyHash; // Random bytes32 from blockhash bytes32 crowdEntropy; // Block number at which the jackpot was locked uint256 lockedBlockNumber; // TImestamp as which the jackpot was locked uint256 lockedTimestamp; } struct JackpotConfig { // Switch to enable/disable the lottery bool lotteryEnabled; // Probability of activating the jackpot, out of 1e18 uint256 jackpotProbability; // Minimum ETH in the pot for someone to win uint256 minimumJackpotAmount; // Minimum fee amount for a ticket uint256 feeTicketPrice; // Price to buy one ticket uint256 directTicketPrice; // Number of seconds passed before forceAwardJackpot() can be called uint256 forceAwardJackpotBuffer; } struct FeeConfig { // % of fees added to the pot uint256 createFeeToPot; uint256 tradingFeeToPot; uint256 launchFeeToPot; // % added to the pot when a ticket is bought uint256 buyTicketToPot; // % of trading fee sent to token creator uint256 tradingFeeToCreator; } function lastRolledBlockNumber() external view returns (uint256); function nextJackpotId() external view returns (uint256); function accruedETH(address user) external view returns (uint256); function currentJackpotSize() external view returns (uint256); function ticketFromIndex(uint256 jackpotId, uint256 index) external view returns (Ticket memory); function ticketQueueLength(uint256 jackpotId) external view returns (uint256); function setJackpotConfig(JackpotConfig memory config) external; function setFeeConfig(FeeConfig memory config) external; function commitAdminEntropy(uint256 jackpotId, bytes32 adminEntropyHash) external; function handleCreateFee(address user) external payable; function handleTradingFee(address user, address tokenCreator) external payable; function handleLaunchFee() external payable; function rollJackpot() external; function collectETH() external returns (uint256 ethReceived); function buyTickets() external payable; function donateToPot() external payable; function commitCrowdEntropy(uint256 jackpotId) external; function awardJackpot(uint256 jackpotId, bytes32 adminEntropy) external; function forceAwardJackpot(uint256 jackpotId) external; }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.24; import {IOwned} from "./interfaces/IOwned.sol"; import {IFactory} from "./interfaces/IFactory.sol"; abstract contract FactoryOwned { error NotFactory(); error NotFactoryOwner(); error ETHTransferFailed(); address public immutable factory; // ======================================== MODIFIERS ======================================== modifier onlyFactory() { if (msg.sender != factory) revert NotFactory(); _; } modifier onlyFactoryOwner() { if (msg.sender != factoryOwner()) revert NotFactoryOwner(); _; } // ======================================== CONSTRUCTOR ======================================== constructor(address _factory) { factory = _factory; } // ======================================== VIEW FUNCTIONS ======================================== function factoryOwner() public view returns (address) { return IOwned(factory).owner(); } function treasury() public view returns (address) { return IFactory(factory).treasury(); } // ======================================== HELPER FUNCTIONS ======================================== function _transferETH(address to, uint256 amount) internal { (bool success,) = payable(to).call{value: amount}(""); if (!success) revert ETHTransferFailed(); } }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.24; interface IOwned { function owner() external view returns (address); }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.24; interface IToken { function transfer(address to, uint256 value) external returns (bool); }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Modern and gas efficient ERC20 + EIP-2612 implementation. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol) /// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol) /// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it. abstract contract ERC20 { /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event Transfer(address indexed from, address indexed to, uint256 amount); event Approval(address indexed owner, address indexed spender, uint256 amount); /*////////////////////////////////////////////////////////////// METADATA STORAGE //////////////////////////////////////////////////////////////*/ string public name; string public symbol; uint8 public immutable decimals; /*////////////////////////////////////////////////////////////// ERC20 STORAGE //////////////////////////////////////////////////////////////*/ uint256 public totalSupply; mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256)) public allowance; /*////////////////////////////////////////////////////////////// EIP-2612 STORAGE //////////////////////////////////////////////////////////////*/ uint256 internal immutable INITIAL_CHAIN_ID; bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR; mapping(address => uint256) public nonces; /*////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor( string memory _name, string memory _symbol, uint8 _decimals ) { name = _name; symbol = _symbol; decimals = _decimals; INITIAL_CHAIN_ID = block.chainid; INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator(); } /*////////////////////////////////////////////////////////////// ERC20 LOGIC //////////////////////////////////////////////////////////////*/ function approve(address spender, uint256 amount) public virtual returns (bool) { allowance[msg.sender][spender] = amount; emit Approval(msg.sender, spender, amount); return true; } function transfer(address to, uint256 amount) public virtual returns (bool) { balanceOf[msg.sender] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(msg.sender, to, amount); return true; } function transferFrom( address from, address to, uint256 amount ) public virtual returns (bool) { uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals. if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount; balanceOf[from] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(from, to, amount); return true; } /*////////////////////////////////////////////////////////////// EIP-2612 LOGIC //////////////////////////////////////////////////////////////*/ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual { require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED"); // Unchecked because the only math done is incrementing // the owner's nonce which cannot realistically overflow. unchecked { address recoveredAddress = ecrecover( keccak256( abi.encodePacked( "\x19\x01", DOMAIN_SEPARATOR(), keccak256( abi.encode( keccak256( "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)" ), owner, spender, value, nonces[owner]++, deadline ) ) ) ), v, r, s ); require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER"); allowance[recoveredAddress][spender] = value; } emit Approval(owner, spender, value); } function DOMAIN_SEPARATOR() public view virtual returns (bytes32) { return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator(); } function computeDomainSeparator() internal view virtual returns (bytes32) { return keccak256( abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes(name)), keccak256("1"), block.chainid, address(this) ) ); } /*////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ function _mint(address to, uint256 amount) internal virtual { totalSupply += amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(address(0), to, amount); } function _burn(address from, uint256 amount) internal virtual { balanceOf[from] -= amount; // Cannot underflow because a user's balance // will never be larger than the total supply. unchecked { totalSupply -= amount; } emit Transfer(from, address(0), amount); } }
{ "viaIR": false, "codegen": "yul", "remappings": [ "@solmate/=lib/solmate/src/", "ds-test/=lib/solmate/lib/ds-test/src/", "forge-std/=lib/forge-std/src/", "solmate/=lib/solmate/src/" ], "evmVersion": "cancun", "outputSelection": { "*": { "*": [ "abi", "metadata" ], "": [ "ast" ] } }, "optimizer": { "enabled": true, "mode": "3", "fallback_to_optimizing_for_size": false, "disable_system_request_memoization": true }, "metadata": {}, "libraries": {}, "enableEraVMExtensions": false, "forceEVMLA": false }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"components":[{"internalType":"bool","name":"lotteryEnabled","type":"bool"},{"internalType":"uint256","name":"jackpotProbability","type":"uint256"},{"internalType":"uint256","name":"minimumJackpotAmount","type":"uint256"},{"internalType":"uint256","name":"feeTicketPrice","type":"uint256"},{"internalType":"uint256","name":"directTicketPrice","type":"uint256"},{"internalType":"uint256","name":"forceAwardJackpotBuffer","type":"uint256"}],"internalType":"struct IFeeHandler.JackpotConfig","name":"_jackpotConfig","type":"tuple"},{"components":[{"internalType":"uint256","name":"createFeeToPot","type":"uint256"},{"internalType":"uint256","name":"tradingFeeToPot","type":"uint256"},{"internalType":"uint256","name":"launchFeeToPot","type":"uint256"},{"internalType":"uint256","name":"buyTicketToPot","type":"uint256"},{"internalType":"uint256","name":"tradingFeeToCreator","type":"uint256"}],"internalType":"struct IFeeHandler.FeeConfig","name":"_feeConfig","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AdminRandomnessMismatch","type":"error"},{"inputs":[],"name":"AlreadyCommited","type":"error"},{"inputs":[],"name":"AwardJackpotBufferTooLarge","type":"error"},{"inputs":[],"name":"DirectTicketPriceTooLow","type":"error"},{"inputs":[],"name":"ETHTransferFailed","type":"error"},{"inputs":[],"name":"FeeTooHigh","type":"error"},{"inputs":[],"name":"InvalidJackpotConfig","type":"error"},{"inputs":[],"name":"JackpotAlreadyAwarded","type":"error"},{"inputs":[],"name":"JackpotLocked","type":"error"},{"inputs":[],"name":"JackpotNotLocked","type":"error"},{"inputs":[],"name":"JackpotProbabilityTooHigh","type":"error"},{"inputs":[],"name":"LotteryDisabled","type":"error"},{"inputs":[],"name":"NotFactory","type":"error"},{"inputs":[],"name":"NotFactoryOwner","type":"error"},{"inputs":[],"name":"TooEarly","type":"error"},{"inputs":[],"name":"ValueBelowTicketPrice","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"jackpotId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"ethAmount","type":"uint256"}],"name":"JackpotDonated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"jackpotId","type":"uint256"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"ethAmount","type":"uint256"}],"name":"JackpotWon","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"jackpotId","type":"uint256"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"noOfTicketsAdded","type":"uint256"}],"name":"TicketAdded","type":"event"},{"inputs":[],"name":"MAX_FORCE_AWARD_JACKPOT_BUFFER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_JACKPOT_PROBABILITY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"accruedETH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"jackpotId","type":"uint256"},{"internalType":"bytes32","name":"adminEntropy","type":"bytes32"}],"name":"awardJackpot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"buyTickets","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"collectETH","outputs":[{"internalType":"uint256","name":"ethReceived","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"jackpotId","type":"uint256"},{"internalType":"bytes32","name":"adminEntropyHash","type":"bytes32"}],"name":"commitAdminEntropy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"jackpotId","type":"uint256"}],"name":"commitCrowdEntropy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentJackpotSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"donateToPot","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factoryOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeConfig","outputs":[{"internalType":"uint256","name":"createFeeToPot","type":"uint256"},{"internalType":"uint256","name":"tradingFeeToPot","type":"uint256"},{"internalType":"uint256","name":"launchFeeToPot","type":"uint256"},{"internalType":"uint256","name":"buyTicketToPot","type":"uint256"},{"internalType":"uint256","name":"tradingFeeToCreator","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"jackpotId","type":"uint256"}],"name":"forceAwardJackpot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"handleCreateFee","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"handleLaunchFee","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"tokenCreator","type":"address"}],"name":"handleTradingFee","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"jackpotConfig","outputs":[{"internalType":"bool","name":"lotteryEnabled","type":"bool"},{"internalType":"uint256","name":"jackpotProbability","type":"uint256"},{"internalType":"uint256","name":"minimumJackpotAmount","type":"uint256"},{"internalType":"uint256","name":"feeTicketPrice","type":"uint256"},{"internalType":"uint256","name":"directTicketPrice","type":"uint256"},{"internalType":"uint256","name":"forceAwardJackpotBuffer","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"jackpotStateById","outputs":[{"internalType":"uint256","name":"nextTicketId","type":"uint256"},{"internalType":"uint256","name":"pot","type":"uint256"},{"internalType":"bytes32","name":"adminEntropyHash","type":"bytes32"},{"internalType":"bytes32","name":"crowdEntropy","type":"bytes32"},{"internalType":"uint256","name":"lockedBlockNumber","type":"uint256"},{"internalType":"uint256","name":"lockedTimestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastRolledBlockNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextJackpotId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rollJackpot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"createFeeToPot","type":"uint256"},{"internalType":"uint256","name":"tradingFeeToPot","type":"uint256"},{"internalType":"uint256","name":"launchFeeToPot","type":"uint256"},{"internalType":"uint256","name":"buyTicketToPot","type":"uint256"},{"internalType":"uint256","name":"tradingFeeToCreator","type":"uint256"}],"internalType":"struct IFeeHandler.FeeConfig","name":"config","type":"tuple"}],"name":"setFeeConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"bool","name":"lotteryEnabled","type":"bool"},{"internalType":"uint256","name":"jackpotProbability","type":"uint256"},{"internalType":"uint256","name":"minimumJackpotAmount","type":"uint256"},{"internalType":"uint256","name":"feeTicketPrice","type":"uint256"},{"internalType":"uint256","name":"directTicketPrice","type":"uint256"},{"internalType":"uint256","name":"forceAwardJackpotBuffer","type":"uint256"}],"internalType":"struct IFeeHandler.JackpotConfig","name":"config","type":"tuple"}],"name":"setJackpotConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"jackpotId","type":"uint256"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"ticketFromIndex","outputs":[{"components":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"firstTicketId","type":"uint256"}],"internalType":"struct IFeeHandler.Ticket","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"jackpotId","type":"uint256"}],"name":"ticketQueueLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
9c4d535b000000000000000000000000000000000000000000000000000000000000000001000359f332a2bb24caefb91ccd99ff2cc02c72ddc303c61080994e0be417d3000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001800000000000000000000000005606cd69b61bd6ed0fd9adacd56188d9d6f576450000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000003a4965bf58a400000000000000000000000000000000000000000000000000000011c37937e08000000000000000000000000000000000000000000000000000001550f7dca70000000000000000000000000000000000000000000000000000000000000000025800000000000000000000000000000000000000000000000002c68af0bb140000000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000b1a2bc2ec500000000000000000000000000000000000000000000000000000214e8348c4f00000000000000000000000000000000000000000000000000000058d15e17628000
Deployed Bytecode
0x000200000000000200070000000000020000006003100270000002f10330019700010000003103550000000100200190000000200000c13d0000008002000039000000400020043f000000040030008c000000430000413d000000000201043b000000e002200270000003020020009c000000450000a13d000003030020009c0000005c0000213d0000030d0020009c0000018e0000a13d0000030e0020009c0000024a0000213d000003110020009c000002860000613d000003120020009c000000430000c13d0000000001000416000000000001004b000000430000c13d0000033c01000041000000800010043f0000032c0100004100000bc10001042e0000000002000416000000000002004b000000430000c13d0000001f02300039000002f202200197000000a002200039000000400020043f0000001f0430018f000002f305300198000000a002500039000000310000613d000000a006000039000000000701034f000000007807043c0000000006860436000000000026004b0000002d0000c13d000000000004004b0000003e0000613d000000000151034f0000000304400210000000000502043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f0000000000120435000001800030008c000000430000413d000000a00100043d000002f40010009c000001070000a13d000000000100001900000bc200010430000003160020009c000001100000a13d000003170020009c000001c40000a13d000003180020009c0000025f0000213d0000031b0020009c000002eb0000613d0000031c0020009c000000430000c13d0000000001000416000000000001004b000000430000c13d0000000c01000039000000000101041a000000000010043f0000000d01000039000000200010043f000000400200003900000000010000190bc00b830000040f0000000201100039000004070000013d000003040020009c000001f20000a13d000003050020009c000002680000213d000003080020009c0000030f0000613d000003090020009c000000430000c13d0000000001000416000000000001004b000000430000c13d0000032d0100004100000000001004430000000001000412000000040010044300000024000004430000000001000414000002f10010009c000002f101008041000000c0011002100000032e011001c700008005020000390bc00bbb0000040f00000001002001900000075d0000613d000000000101043b000002f4011001970000000002000411000000000012004b000004e30000c13d000000000100041a000000ff00100190000001f00000613d0000000b01000039000000000101041a000500000001001d0000032f0100004100000000001004430000000001000414000002f10010009c000002f101008041000000c00110021000000330011001c70000800b020000390bc00bbb0000040f00000001002001900000075d0000613d000000000101043b000400000001001d000000050010006c000001f00000613d00000004010000290000000b02000039000000000012041b0000000c01000039000000000101041a000500000001001d000000000010043f0000000d01000039000000200010043f0000000001000414000002f10010009c000002f101008041000000c00110021000000327011001c700008010020000390bc00bbb0000040f0000000100200190000000430000613d000000000101043b000300000001001d000000000101041a000000000001004b000001f00000613d0000000201000039000000000101041a00000003020000290000000202200039000000000202041a000000000012004b000001f00000413d00000003010000290000000301100039000000000101041a000000000001004b000001f00000613d000000040000006b000005ea0000613d000000400100043d000200000001001d00000020021000390000000501000029000100000002001d0000000000120435000003310100004100000000001004430000000401000029000000010110008a00000004001004430000000001000414000002f10010009c000002f101008041000000c00110021000000332011001c70000800b020000390bc00bbb0000040f00000001002001900000075d0000613d000000000101043b00000002030000290000004002300039000000000012043500000040010000390000000000130435000003330030009c0000010a0000213d00000002020000290000006001200039000000400010043f0000000101000029000002f10010009c000002f10100804100000040011002100000000002020433000002f10020009c000002f1020080410000006002200210000000000112019f0000000002000414000002f10020009c000002f102008041000000c002200210000000000112019f00000328011001c700008010020000390bc00bbb0000040f0000000100200190000000430000613d0000000102000039000000000202041a000000000101043b000002fe1010012a000000000021004b000001f00000813d000000030100002900000005011000390000000402000029000000000021041b000003340100004100000000001004430000000001000414000002f10010009c000002f101008041000000c00110021000000330011001c70000800b020000390bc00bbb0000040f00000001002001900000075d0000613d000000000101043b00000003020000290000000602200039000000000012041b0000000c01000039000000000101041a000000010110003a000005ea0000613d0000000c02000039000000000012041b000000000100001900000bc10001042e000000400700043d000002f50070009c0000011d0000a13d0000034901000041000000000010043f0000004101000039000000040010043f0000034a0100004100000bc200010430000003200020009c000002180000213d000003240020009c000003440000613d000003250020009c000003690000613d000003260020009c000000430000c13d0000000001000416000000000001004b000000430000c13d0000000b01000039000004070000013d000000c002700039000000400020043f000000c00200043d000000000002004b0000000003000039000000010300c039000000000032004b000000430000c13d000000000a270436000000e00200043d00000000002a0435000000400c700039000001000200043d00000000002c0435000000600b700039000001200200043d00000000002b04350000008008700039000001400200043d0000000000280435000000a009700039000001600200043d0000000000290435000000400200043d000002f60020009c0000010a0000213d000000a003200039000000400030043f000001800300043d0000000005320436000001a00300043d00000000003504350000004004200039000001c00300043d00000000003404350000006003200039000001e00600043d00000000006304350000008006200039000002000d00043d0000000000d60435000000800010043f000000000a0a04330000000007070433000000000007004b000004e60000c13d00000000000a004b000004f10000c13d000000000a0c043300000000000a004b000004f10000c13d000000000a0b043300000000000a004b000004f10000c13d0000000008080433000000000008004b000004f10000c13d0000000008090433000000000008004b00000000090000190000000008000019000000000b000019000000000c000019000000000a000019000004f10000c13d000000000e00041a0000034c0de00197000000000007004b000000010dd0c1bf0000000000d0041b00000001070000390000000000a7041b000000020a0000390000000000ca041b000000030a0000390000000000ba041b000000040a00003900000000008a041b0000000508000039000000000098041b00000000060604330000000005050433000000000065001a000005ea0000413d0000000008650019000002fe0080009c0000077e0000213d0000000002020433000002fe0020009c0000077e0000213d0000000004040433000002fe0040009c0000077e0000213d0000000003030433000002ff0030009c0000077e0000813d0000000608000039000000000028041b0000000702000039000000000052041b0000000802000039000000000042041b0000000902000039000000000032041b0000000a02000039000000000062041b00000140000004430000016000100443000000200100003900000100001004430000012000700443000003000100004100000bc10001042e000003130020009c000003f90000613d000003140020009c0000040b0000613d000003150020009c000000430000c13d000000a40030008c000000430000413d0000000002000416000000000002004b000000430000c13d0000012002000039000000400020043f0000000402100370000000000202043b000000800020043f0000002402100370000000000202043b000000a00020043f0000004402100370000000000202043b000000c00020043f0000006402100370000000000202043b000000e00020043f0000008401100370000000000101043b000001000010043f0000033d01000041000001200010043f0000032d0100004100000000001004430000000001000412000000040010044300000024000004430000000001000414000002f10010009c000002f101008041000000c0011002100000032e011001c700008005020000390bc00bbb0000040f00000001002001900000075d0000613d000000000201043b0000000001000414000002f402200197000000040020008c000005000000c13d0000000003000031000000200030008c00000020040000390000000004034019000005250000013d0000031d0020009c0000043f0000613d0000031e0020009c000003a40000613d0000031f0020009c000000430000c13d000000000100041a000000ff001001900000047a0000613d0000000c01000039000000000101041a000500000001001d000000000010043f0000000d01000039000000200010043f0000000001000414000002f10010009c000002f101008041000000c00110021000000327011001c700008010020000390bc00bbb0000040f0000000100200190000000430000613d000000000101043b0000000201100039000000000201041a0000000006000416000000000062001a000005ea0000413d0000000002620019000000000021041b0000000001000414000002f10010009c000002f101008041000000c00110021000000328011001c70000800d020000390000000303000039000003420400004100000005050000290bc00bb60000040f0000000100200190000000430000613d000000000100001900000bc10001042e0000030a0020009c000004770000613d0000030b0020009c0000047e0000613d0000030c0020009c000000430000c13d000000240030008c000000430000413d0000000002000416000000000002004b000000430000c13d0000000401100370000000000101043b000000000010043f0000000d01000039000000200010043f000000400200003900000000010000190bc00b830000040f0000000602100039000000000202041a0000000503100039000000000303041a0000000404100039000000000404041a0000000305100039000000000505041a0000000206100039000000000606041a000000000101041a000000800010043f000000a00060043f000000c00050043f000000e00040043f000001000030043f000001200020043f000003360100004100000bc10001042e000003210020009c000003a90000613d000003220020009c000003b00000613d000003230020009c000000430000c13d000000440030008c000000430000413d0000000002000416000000000002004b000000430000c13d000000c002000039000000400020043f000000800000043f000000a00000043f0000000402100370000000000202043b000000000020043f0000000d02000039000000200020043f0000002401100370000000000101043b000500000001001d000000400200003900000000010000190bc00b830000040f000000010110003900000005020000290bc008e60000040f000500000001001d000000400100043d000400000001001d0bc008d00000040f0000000503000029000000000103041a000002f401100197000000040200002900000000021204360000000103300039000000000303041a0000000000320435000000400300043d000000000113043600000000020204330000000000210435000002f10030009c000002f103008041000000400130021000000345011001c700000bc10001042e0000030f0020009c000003c40000613d000003100020009c000000430000c13d0000000001000416000000000001004b000000430000c13d0000000001000412000700000001001d000600000000003d000080050100003900000044030000390000000004000415000000070440008a00000005044002100000032d020000410bc00b980000040f000002f401100197000000800010043f0000032c0100004100000bc10001042e000003190020009c000003dd0000613d0000031a0020009c000000430000c13d0000000001000416000000000001004b000000430000c13d0000000c01000039000004070000013d000003060020009c000003e90000613d000003070020009c000000430000c13d0000000001000416000000000001004b000000430000c13d0000000001000411000000000010043f0000000e01000039000000200010043f0000000001000414000002f10010009c000002f101008041000000c00110021000000327011001c700008010020000390bc00bbb0000040f0000000100200190000000430000613d000000000101043b000000000301041a000000000001041b00000000010004140000000004000411000000040040008c000005950000c13d000000010200003900000000010000310000066d0000013d000000440030008c000000430000413d0000000402100370000000000202043b000500000002001d000002f40020009c000000430000213d0000002401100370000000000101043b000400000001001d000002f40010009c000000430000213d0000032d0100004100000000001004430000000001000412000000040010044300000024000004430000000001000414000002f10010009c000002f101008041000000c0011002100000032e011001c700008005020000390bc00bbb0000040f00000001002001900000075d0000613d000000000101043b000002f4011001970000000002000411000000000012004b000004e30000c13d0000000001000416000200000001001d0000000a01000039000000000101041a000300000001001d000000000001004b000002b10000613d000000010100008a00000003011000fa0000000002000416000000000012004b000000430000213d0000000401000029000002f401100197000000000010043f0000000e01000039000000200010043f0000000001000414000002f10010009c000002f101008041000000c00110021000000327011001c700008010020000390bc00bbb0000040f0000000100200190000000430000613d000000000200041600000003022000b9000002fe0320012a000000000101043b000000000201041a000000000032001a000005ea0000413d000400000003001d0000000002320019000000000021041b000000000100041a000000ff00100190000007d20000c13d00000004020000290004000200200073000005ea0000413d000000400200043d0000033901000041000500000002001d00000000001204350000032d0100004100000000001004430000000001000412000000040010044300000024000004430000000001000414000002f10010009c000002f101008041000000c0011002100000032e011001c700008005020000390bc00bbb0000040f00000001002001900000075d0000613d000000000201043b0000000001000414000002f402200197000000040020008c0000086a0000c13d0000000003000031000000200030008c00000020040000390000000004034019000008940000013d000000240030008c000000430000413d0000000002000416000000000002004b000000430000c13d0000000401100370000000000201043b0000000c01000039000000000101041a000000000012004b000004d50000813d000500000002001d000000000020043f0000000d01000039000000200010043f0000000001000414000002f10010009c000002f101008041000000c00110021000000327011001c700008010020000390bc00bbb0000040f0000000100200190000000430000613d000000000101043b0000000402100039000000000102041a000000000001004b000005f00000c13d0000000501000029000500000002001d0bc00a690000040f0000000502000029000000000012041b000000000100001900000bc10001042e000000240030008c000000430000413d0000000002000416000000000002004b000000430000c13d0000000401100370000000000201043b0000000c01000039000000000101041a000000000012004b000004d50000813d000500000002001d000000000020043f0000000d01000039000000200010043f0000000001000414000002f10010009c000002f101008041000000c00110021000000327011001c700008010020000390bc00bbb0000040f0000000100200190000000430000613d0000000502000039000000000202041a000000000101043b000200000001001d0000000601100039000000000101041a000400000002001d000300000001001d000000000012001a000005ea0000413d000003340100004100000000001004430000000001000414000002f10010009c000002f101008041000000c00110021000000330011001c70000800b020000390bc00bbb0000040f00000001002001900000075d0000613d00000003030000290000000402300029000000000101043b000000000021004b000007250000813d000000400100043d0000033502000041000004f30000013d000000440030008c000000430000413d0000000002000416000000000002004b000000430000c13d0000002402100370000000000202043b000400000002001d0000000401100370000000000101043b000500000001001d0000033d01000041000000800010043f0000032d0100004100000000001004430000000001000412000000040010044300000024000004430000000001000414000002f10010009c000002f101008041000000c0011002100000032e011001c700008005020000390bc00bbb0000040f00000001002001900000075d0000613d000000000201043b0000000001000414000002f402200197000000040020008c0000054d0000c13d0000000003000031000000200030008c00000020040000390000000004034019000005720000013d000000240030008c000000430000413d0000000401100370000000000101043b000500000001001d000002f40010009c000000430000213d0000032d0100004100000000001004430000000001000412000000040010044300000024000004430000000001000414000002f10010009c000002f101008041000000c0011002100000032e011001c700008005020000390bc00bbb0000040f00000001002001900000075d0000613d000000000101043b000002f4011001970000000002000411000000000012004b000004e30000c13d0000000003000416000000000100041a000000ff00100190000006f60000c13d000400000003001d000000400200043d0000033901000041000500000002001d00000000001204350000032d0100004100000000001004430000000001000412000000040010044300000024000004430000000001000414000002f10010009c000002f101008041000000c0011002100000032e011001c700008005020000390bc00bbb0000040f00000001002001900000075d0000613d000000000201043b0000000001000414000002f402200197000000040020008c000007890000c13d0000000003000031000000200030008c00000020040000390000000004034019000007b30000013d0000000001000416000000000001004b000000430000c13d0bc009020000040f000003e10000013d0000000001000416000000000001004b000000430000c13d0000034701000041000000800010043f0000032c0100004100000bc10001042e0000000001000416000000000001004b000000430000c13d0000000a01000039000000000101041a0000000902000039000000000202041a0000000803000039000000000303041a0000000704000039000000000404041a0000000605000039000000000505041a000000800050043f000000a00040043f000000c00030043f000000e00020043f000001000010043f000003460100004100000bc10001042e0000000001000416000000000001004b000000430000c13d0000000501000039000000000101041a0000000402000039000000000202041a0000000303000039000000000303041a0000000204000039000000000404041a0000000105000039000000000505041a000000000600041a000000ff006001900000000006000039000000010600c039000000800060043f000000a00050043f000000c00040043f000000e00030043f000001000020043f000001200010043f000003360100004100000bc10001042e0000000001000416000000000001004b000000430000c13d0bc009830000040f000002f401100197000000400200043d0000000000120435000002f10020009c000002f10200804100000040012002100000032b011001c700000bc10001042e000000240030008c000000430000413d0000000002000416000000000002004b000000430000c13d0000000401100370000000000101043b000002f40010009c000000430000213d000000000010043f0000000e01000039000000200010043f000000400200003900000000010000190bc00b830000040f000004070000013d000000240030008c000000430000413d0000000002000416000000000002004b000000430000c13d0000000401100370000000000101043b000000000010043f0000000d01000039000000200010043f000000400200003900000000010000190bc00b830000040f0000000101100039000000000101041a000000800010043f0000032c0100004100000bc10001042e0000032d0100004100000000001004430000000001000412000000040010044300000024000004430000000001000414000002f10010009c000002f101008041000000c0011002100000032e011001c700008005020000390bc00bbb0000040f00000001002001900000075d0000613d000000000101043b000002f4011001970000000002000411000000000012004b000004e30000c13d0000000002000416000000000100041a000000ff001001900000059d0000c13d000400000002001d0000000003000412000000400200043d0000033901000041000500000002001d00000000001204350000032d010000410000000000100443000000040030044300000024000004430000000001000414000002f10010009c000002f101008041000000c0011002100000032e011001c700008005020000390bc00bbb0000040f00000001002001900000075d0000613d000000000201043b0000000001000414000002f402200197000000040020008c000006a60000c13d0000000003000031000000200030008c00000020040000390000000004034019000006d00000013d000000c40030008c000000430000413d0000000002000416000000000002004b000000430000c13d0000014002000039000000400020043f0000000402100370000000000202043b000000000002004b0000000003000039000000010300c039000000000032004b000000430000c13d000000800020043f0000002402100370000000000202043b000000a00020043f0000004402100370000000000202043b000000c00020043f0000006402100370000000000202043b000000e00020043f0000008402100370000000000202043b000001000020043f000000a401100370000000000101043b000001200010043f0000033d01000041000001400010043f0000032d0100004100000000001004430000000001000412000000040010044300000024000004430000000001000414000002f10010009c000002f101008041000000c0011002100000032e011001c700008005020000390bc00bbb0000040f00000001002001900000075d0000613d000000000201043b0000000001000414000002f402200197000000040020008c0000060b0000c13d0000000003000031000000200030008c00000020040000390000000004034019000006300000013d000000000100041a000000ff00100190000004d90000c13d0000034301000041000000800010043f0000033b0100004100000bc200010430000000440030008c000000430000413d0000000002000416000000000002004b000000430000c13d0000002402100370000000000302043b0000000401100370000000000201043b0000000c01000039000000000101041a000000000012004b000004d50000813d000500000003001d000400000002001d000000000020043f0000000d01000039000000200010043f0000000001000414000002f10010009c000002f101008041000000c00110021000000327011001c700008010020000390bc00bbb0000040f0000000100200190000000430000613d000000000401043b000000400100043d0000002002000039000000000221043600000005030000290000000000320435000003370010009c0000010a0000213d000300000004001d0000004003100039000000400030043f000002f10020009c000002f10200804100000040022002100000000001010433000002f10010009c000002f1010080410000006001100210000000000121019f0000000002000414000002f10020009c000002f102008041000000c002200210000000000112019f00000328011001c700008010020000390bc00bbb0000040f0000000100200190000000430000613d000000000101043b00000003030000290000000302300039000000000202041a000000000021004b000007810000c13d00000004010000290bc00a690000040f00000003020000290000000402200039000000000012041b000000400400043d000300000004001d00000040024000390000000503000029000000000032043500000040020000390000000002240436000500000002001d000000000012043500000000010400190bc008db0000040f0000000301000029000000000201043300000005010000290bc00b830000040f000000000201001900000004010000290bc00ae70000040f000000000100001900000bc10001042e0000034001000041000000800010043f0000033b0100004100000bc2000104300000000401000039000000000101041a000000000001004b000004f90000c13d0000034901000041000000000010043f0000001201000039000000040010043f0000034a0100004100000bc200010430000000400100043d0000034802000041000004f30000013d00000000000a004b000004f10000613d000000000c0c043300000000000c004b000004f10000613d000000000b0b043300000000000b004b000004f10000613d0000000009090433000000000009004b0000073b0000c13d000000400100043d000002fd020000410000000000210435000002f10010009c000002f1010080410000004001100210000002fa011001c700000bc2000104300000000002000416000000000021004b000005c30000a13d0000033a01000041000000800010043f0000033b0100004100000bc200010430000002f10010009c000002f101008041000000c0011002100000033e011001c70bc00bbb0000040f0000006003100270000002f103300197000000200030008c000000200400003900000000040340190000001f0640018f00000020074001900000012005700039000001200a000039000005140000613d000000000801034f000000008908043c000000000a9a043600000000005a004b000005100000c13d000000000006004b000005210000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000000000003001f00010000000103550000000100200190000005f30000613d0000001f01400039000000600110018f0000012001100039000000400010043f000000200030008c000000430000413d000001200200043d000002f40020009c000000430000213d0000000003000411000000000023004b000006a40000c13d000001000200043d000000a00300043d000000000023001a000005ea0000413d0000000004230019000002fe0040009c0000075e0000213d000000800400043d000002fe0040009c0000075e0000213d000000c00500043d000002fe0050009c0000075e0000213d000000e00600043d000002ff0060009c0000075e0000813d0000000601000039000000000041041b0000000701000039000000000031041b0000000801000039000000000051041b0000000901000039000000000061041b0000000a01000039000000000021041b000000000100001900000bc10001042e000002f10010009c000002f101008041000000c0011002100000033b011001c70bc00bbb0000040f0000006003100270000002f103300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000080057001bf000000800a000039000005610000613d000000000801034f000000008908043c000000000a9a043600000000005a004b0000055d0000c13d000000000006004b0000056e0000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000000000003001f00010000000103550000000100200190000005ff0000613d0000001f01400039000000600110018f00000080011001bf000000400010043f000000200030008c000000430000413d000000800200043d000002f40020009c000000430000213d0000000003000411000000000023004b000006a40000c13d0000000501000029000000000010043f0000000d01000039000000200010043f0000000001000414000002f10010009c000002f101008041000000c00110021000000327011001c700008010020000390bc00bbb0000040f0000000100200190000000430000613d000000000101043b0000000502100039000000000202041a000000000002004b000007cf0000c13d00000003011000390000000402000029000000000021041b000000000100001900000bc10001042e000002f10010009c000002f101008041000000c001100210000000000003004b000500000003001d000006640000c13d0000000002040019000006670000013d0000000801000039000000000101041a000500000001001d000000000001004b000005a70000613d000000010100008a00000005011000fa0000000002000416000000000021004b000000430000413d0000000c01000039000000000101041a000000000010043f0000000d01000039000000200010043f0000000001000414000002f10010009c000002f101008041000000c00110021000000327011001c700008010020000390bc00bbb0000040f0000000100200190000000430000613d000000000400041600000005024000b9000002fe0220012a000000000101043b0000000201100039000000000301041a000000000023001a000005ea0000413d0000000003230019000000000031041b000000000424004b000005ea0000413d000400000004001d000004230000013d00000000021200d900000000010004110bc00a040000040f0000000901000039000000000101041a000500000001001d000000000001004b000005d00000613d000000010100008a00000005011000fa0000000002000416000000000021004b000000430000413d0000000c01000039000000000101041a000000000010043f0000000d01000039000000200010043f0000000001000414000002f10010009c000002f101008041000000c00110021000000327011001c700008010020000390bc00bbb0000040f0000000100200190000000430000613d000000000400041600000005024000b9000002fe0220012a000000000101043b0000000201100039000000000301041a000000000023001a000005ea0000413d0000000003230019000000000031041b000000000124004b000007400000813d0000034901000041000000000010043f0000001101000039000000040010043f0000034a0100004100000bc200010430000000400100043d0000034102000041000004f30000013d0000001f0530018f000002f306300198000000400200043d00000000046200190000076b0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000005fa0000c13d0000076b0000013d0000001f0530018f000002f306300198000000400200043d00000000046200190000076b0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000006060000c13d0000076b0000013d000002f10010009c000002f101008041000000c00110021000000344011001c70bc00bbb0000040f0000006003100270000002f103300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000140057001bf000001400a0000390000061f0000613d000000000801034f000000008908043c000000000a9a043600000000005a004b0000061b0000c13d000000000006004b0000062c0000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000000000003001f000100000001035500000001002001900000072f0000613d0000001f01400039000000600110018f0000014001100039000000400010043f000000200030008c000000430000413d000001400200043d000002f40020009c000000430000213d0000000003000411000000000023004b000006a40000c13d000000a00300043d000000800200043d000000000002004b000008020000c13d000000000003004b0000080d0000c13d000000c00300043d000000000003004b0000080d0000c13d000000e00300043d000000000003004b0000080d0000c13d000001000300043d000000000003004b0000080d0000c13d000001200300043d000000000003004b000000000500001900000000070000190000000006000019000000000400001900000000030000190000080d0000c13d000000000800041a0000034c01800197000000000002004b000000010110c1bf000000000010041b0000000101000039000000000031041b0000000201000039000000000041041b0000000301000039000000000061041b0000000401000039000000000071041b0000000501000039000000000051041b000000000100001900000bc10001042e00000328011001c7000080090200003900000000050000190bc00bb60000040f000000050300002900010000000103550000006001100270000002f10010019d000002f101100197000000000001004b000006790000c13d000000400100043d000002f10010009c000002f104000041000000000401401900000040044002100000000100200190000006a00000613d00000000003104350000032b014001c700000bc10001042e0000001f041000390000034d044001970000003f044000390000034d05400197000000400400043d0000000005540019000000000045004b00000000060000390000000106004039000003290050009c0000010a0000213d00000001006001900000010a0000c13d000000400050043f00000000061404360000034d091001980000001f0410018f00000000019600190000000105000367000006920000613d000000000705034f000000007807043c0000000006860436000000000016004b0000068e0000c13d000000000004004b0000066f0000613d000000000695034f0000000304400210000000000501043300000000054501cf000000000545022f000000000606043b0000010004400089000000000646022f00000000044601cf000000000454019f00000000004104350000066f0000013d0000032a020000410000000000210435000002fa014001c700000bc2000104300000033f020000410000080e0000013d0000000503000029000002f10030009c000002f1030080410000004003300210000002f10010009c000002f101008041000000c001100210000000000131019f000002fa011001c70bc00bbb0000040f0000006003100270000002f103300197000000200030008c000000200400003900000000040340190000001f0640018f00000020074001900000000505700029000006bf0000613d000000000801034f0000000509000029000000008a08043c0000000009a90436000000000059004b000006bb0000c13d000000000006004b000006cc0000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000000000003001f00010000000103550000000100200190000007600000613d0000001f01400039000000600210018f0000000501200029000000000021004b00000000020000390000000102004039000003290010009c0000010a0000213d00000001002001900000010a0000c13d000000400010043f000000200030008c000000430000413d00000005010000290000000001010433000002f40010009c000000430000213d000000000010043f0000000e01000039000000200010043f0000000001000414000002f10010009c000002f101008041000000c00110021000000327011001c700008010020000390bc00bbb0000040f0000000100200190000000430000613d000000000101043b000000000201041a0000000403000029000000000032001a000005ea0000413d0000000002320019000000000021041b000000000100001900000bc10001042e0000000301000039000000000101041a000000000001004b000004dd0000613d00000000021300d9000000000031004b000000010200203900000005010000290bc00a040000040f0000000601000039000000000101041a000500000001001d000000000001004b000007090000613d000000010100008a00000005011000fa0000000002000416000000000021004b000000430000413d0000000c01000039000000000101041a000000000010043f0000000d01000039000000200010043f0000000001000414000002f10010009c000002f101008041000000c00110021000000327011001c700008010020000390bc00bbb0000040f0000000100200190000000430000613d000000000400041600000005024000b9000002fe0220012a000000000101043b0000000201100039000000000301041a000000000023001a000005ea0000413d0000000003230019000000000031041b000000000424004b000005ea0000413d000400000004001d000003880000013d00000005010000290bc00a690000040f000000020200002900000004032000390000000002010019000000000013041b00000005010000290bc00ae70000040f000000000100001900000bc10001042e0000001f0530018f000002f306300198000000400200043d00000000046200190000076b0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000007360000c13d0000076b0000013d000002f700a0009c000007840000413d000000400100043d000002fc02000041000004f30000013d000400000001001d000000400200043d0000033901000041000500000002001d00000000001204350000032d0100004100000000001004430000000001000412000000040010044300000024000004430000000001000414000002f10010009c000002f101008041000000c0011002100000032e011001c700008005020000390bc00bbb0000040f00000001002001900000075d0000613d000000000201043b0000000001000414000002f402200197000000040020008c000008120000c13d0000000003000031000000200030008c000000200400003900000000040340190000083c0000013d000000000001042f00000301020000410000080e0000013d0000001f0530018f000002f306300198000000400200043d00000000046200190000076b0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000007670000c13d000000000005004b000007780000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f00000000001404350000006001300210000002f10020009c000002f1020080410000004002200210000000000112019f00000bc200010430000000400100043d0000030102000041000004f30000013d000000400100043d0000033802000041000004f30000013d000002f80090009c000007c90000413d000000400100043d000002fb02000041000004f30000013d0000000503000029000002f10030009c000002f1030080410000004003300210000002f10010009c000002f101008041000000c001100210000000000131019f000002fa011001c70bc00bbb0000040f0000006003100270000002f103300197000000200030008c000000200400003900000000040340190000001f0640018f00000020074001900000000505700029000007a20000613d000000000801034f0000000509000029000000008a08043c0000000009a90436000000000059004b0000079e0000c13d000000000006004b000007af0000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000000000003001f00010000000103550000000100200190000008520000613d0000001f01400039000000600210018f0000000501200029000000000021004b00000000020000390000000102004039000003290010009c0000010a0000213d00000001002001900000010a0000c13d000000400010043f000000200030008c000000430000413d00000005010000290000000001010433000002f40010009c000000430000213d000000000010043f0000000e01000039000000200010043f0000000001000414000006e50000013d00000000080804330000000000b8004b0000015e0000813d000000400100043d000002f902000041000004f30000013d000000400100043d0000034b02000041000004f30000013d0000000301000039000000000101041a000000000001004b000004dd0000613d0000000002000416000000000021004b000007dc0000213d00000000021200d900000005010000290bc00a040000040f0000000701000039000000000101041a000500000001001d000000000001004b000007e60000613d000000010100008a00000005011000fa0000000002000416000000000021004b000000430000413d0000000c01000039000000000101041a000000000010043f0000000d01000039000000200010043f0000000001000414000002f10010009c000002f101008041000000c00110021000000327011001c700008010020000390bc00bbb0000040f0000000100200190000000430000613d000000000200041600000005022000b9000002fe0220012a000000000101043b0000000201100039000000000301041a000000000023001a000005ea0000413d0000000003230019000000000031041b00000000010004160002000000210053000002cc0000813d000005ea0000013d000000000003004b0000080d0000613d000000c00400043d000000000004004b0000080d0000613d000000e00600043d000000000006004b0000080d0000613d000001200500043d000000000005004b000008c30000c13d000002fd0200004100000000002104350000004001100210000002fa011001c700000bc2000104300000000503000029000002f10030009c000002f1030080410000004003300210000002f10010009c000002f101008041000000c001100210000000000131019f000002fa011001c70bc00bbb0000040f0000006003100270000002f103300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000005057000290000082b0000613d000000000801034f0000000509000029000000008a08043c0000000009a90436000000000059004b000008270000c13d000000000006004b000008380000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000000000003001f000100000001035500000001002001900000085e0000613d0000001f01400039000000600210018f0000000501200029000000000021004b00000000020000390000000102004039000003290010009c0000010a0000213d00000001002001900000010a0000c13d000000400010043f000000200030008c000000430000413d00000005010000290000000001010433000002f40010009c000000430000213d000000000010043f0000000e01000039000000200010043f0000000001000414000006e50000013d0000001f0530018f000002f306300198000000400200043d00000000046200190000076b0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000008590000c13d0000076b0000013d0000001f0530018f000002f306300198000000400200043d00000000046200190000076b0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000008650000c13d0000076b0000013d0000000503000029000002f10030009c000002f1030080410000004003300210000002f10010009c000002f101008041000000c001100210000000000131019f000002fa011001c70bc00bbb0000040f0000006003100270000002f103300197000000200030008c000000200400003900000000040340190000001f0640018f00000020074001900000000505700029000008830000613d000000000801034f0000000509000029000000008a08043c0000000009a90436000000000059004b0000087f0000c13d000000000006004b000008900000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000000000003001f00010000000103550000000100200190000008b70000613d0000001f01400039000000600210018f0000000501200029000000000021004b00000000020000390000000102004039000003290010009c0000010a0000213d00000001002001900000010a0000c13d000000400010043f000000200030008c000000430000413d00000005010000290000000001010433000002f40010009c000000430000213d000000000010043f0000000e01000039000000200010043f0000000001000414000002f10010009c000002f101008041000000c00110021000000327011001c700008010020000390bc00bbb0000040f0000000100200190000000430000613d000000000101043b000000000201041a000000040020002a000005ea0000413d0000000403000029000006f20000013d0000001f0530018f000002f306300198000000400200043d00000000046200190000076b0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000008be0000c13d0000076b0000013d000002f70030009c000008c70000413d000002fc020000410000080e0000013d000002f80050009c000008cb0000413d000002fb020000410000080e0000013d000001000700043d000000000067004b000006530000813d000002f9020000410000080e0000013d0000034e0010009c000008d50000813d0000004001100039000000400010043f000000000001042d0000034901000041000000000010043f0000004101000039000000040010043f0000034a0100004100000bc2000104300000034f0010009c000008e00000813d0000006001100039000000400010043f000000000001042d0000034901000041000000000010043f0000004101000039000000040010043f0000034a0100004100000bc2000104300001000000000002000000000301041a000100000002001d000000000023004b000008fa0000a13d000000000010043f0000000001000414000002f10010009c000002f101008041000000c00110021000000350011001c700008010020000390bc00bbb0000040f0000000100200190000009000000613d00000001020000290000000102200210000000000101043b0000000001210019000000000001042d0000034901000041000000000010043f0000003201000039000000040010043f0000034a0100004100000bc200010430000000000100001900000bc2000104300001000000000002000000400200043d0000033d01000041000100000002001d00000000001204350000032d0100004100000000001004430000000001000412000000040010044300000024000004430000000001000414000002f10010009c000002f101008041000000c0011002100000032e011001c700008005020000390bc00bbb0000040f00000001002001900000095e0000613d000000000201043b0000000001000414000002f402200197000000040020008c000009200000c13d0000000003000031000000200030008c00000020040000390000000004034019000000010b0000290000094b0000013d0000000103000029000002f10030009c000002f1030080410000004003300210000002f10010009c000002f101008041000000c001100210000000000131019f000002fa011001c70bc00bbb0000040f000000010b0000290000006003100270000002f103300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000000057b00190000093a0000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b000009360000c13d000000000006004b000009470000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000000000003001f00010000000103550000000100200190000009650000613d0000001f01400039000000600210018f0000000001b20019000000000021004b00000000020000390000000102004039000003290010009c0000095f0000213d00000001002001900000095f0000c13d000000400010043f0000001f0030008c0000095c0000a13d00000000010b0433000002f40010009c0000095c0000213d000000000001042d000000000100001900000bc200010430000000000001042f0000034901000041000000000010043f0000004101000039000000040010043f0000034a0100004100000bc2000104300000001f0530018f000002f306300198000000400200043d0000000004620019000009700000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b0000096c0000c13d000000000005004b0000097d0000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f00000000001404350000006001300210000002f10020009c000002f1020080410000004002200210000000000112019f00000bc2000104300001000000000002000000400200043d0000033901000041000100000002001d00000000001204350000032d0100004100000000001004430000000001000412000000040010044300000024000004430000000001000414000002f10010009c000002f101008041000000c0011002100000032e011001c700008005020000390bc00bbb0000040f0000000100200190000009df0000613d000000000201043b0000000001000414000002f402200197000000040020008c000009a10000c13d0000000003000031000000200030008c00000020040000390000000004034019000000010b000029000009cc0000013d0000000103000029000002f10030009c000002f1030080410000004003300210000002f10010009c000002f101008041000000c001100210000000000131019f000002fa011001c70bc00bbb0000040f000000010b0000290000006003100270000002f103300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000000057b0019000009bb0000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b000009b70000c13d000000000006004b000009c80000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000000000003001f00010000000103550000000100200190000009e60000613d0000001f01400039000000600210018f0000000001b20019000000000021004b00000000020000390000000102004039000003290010009c000009e00000213d0000000100200190000009e00000c13d000000400010043f0000001f0030008c000009dd0000a13d00000000010b0433000002f40010009c000009dd0000213d000000000001042d000000000100001900000bc200010430000000000001042f0000034901000041000000000010043f0000004101000039000000040010043f0000034a0100004100000bc2000104300000001f0530018f000002f306300198000000400200043d0000000004620019000009f10000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000009ed0000c13d000000000005004b000009fe0000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f00000000001404350000006001300210000002f10020009c000002f1020080410000004002200210000000000112019f00000bc2000104300007000000000002000600000002001d000700000001001d0000000c01000039000000000101041a000500000001001d000000000010043f0000000d01000039000000200010043f0000000001000414000002f10010009c000002f101008041000000c00110021000000327011001c700008010020000390bc00bbb0000040f000000010020019000000a5b0000613d000000000301043b000000400400043d0000034e0040009c00000a5d0000813d000000000103041a0000004002400039000000400020043f0000002002400039000400000002001d00000000001204350000000701000029000002f401100197000700000001001d00000000001404350000000101300039000000000201041a000003290020009c00000a5d0000213d000200000004001d000300000003001d000100000002001d0000000102200039000000000021041b000000000010043f0000000001000414000002f10010009c000002f101008041000000c00110021000000350011001c700008010020000390bc00bbb0000040f000000010020019000000a5b0000613d00000001020000290000000102200210000000000101043b0000000001210019000000000201041a000003510220019700000002030000290000000003030433000002f403300197000000000232019f000000000021041b000000010110003900000004020000290000000002020433000000000021041b0000000302000029000000000102041a0000000607000029000000000071001a00000a630000413d0000000001710019000000000012041b0000000001000414000002f10010009c000002f101008041000000c00110021000000328011001c70000800d0200003900000004030000390000035204000041000000050500002900000007060000290bc00bb60000040f000000010020019000000a5b0000613d000000000001042d000000000100001900000bc2000104300000034901000041000000000010043f0000004101000039000000040010043f0000034a0100004100000bc2000104300000034901000041000000000010043f0000001101000039000000040010043f0000034a0100004100000bc2000104300003000000000002000300000001001d000000000010043f0000000d01000039000000200010043f0000000001000414000002f10010009c000002f101008041000000c00110021000000327011001c700008010020000390bc00bbb0000040f000000010020019000000ac90000613d000000000201043b0000000401200039000000000101041a000000000001004b00000a7d0000613d000000000001042d0000000501200039000000000101041a000200000001001d000000000001004b00000ad20000613d0000032f0100004100000000001004430000000001000414000002f10010009c000002f101008041000000c00110021000000330011001c70000800b020000390bc00bbb0000040f000000010020019000000ad10000613d000000000301043b000000ff0130008c000000020400002900000acb0000413d000003530040009c00000acb0000213d0000000502400039000000400400043d000000000023004b00000ada0000a13d000200000004001d00000020044000390000000303000029000100000004001d000000000034043500000331030000410000000000300443000000000012004b000000000201a01900000004002004430000000001000414000002f10010009c000002f101008041000000c00110021000000332011001c70000800b020000390bc00bbb0000040f000000010020019000000ad10000613d000000000101043b000000020300002900000040023000390000000000120435000000400100003900000000001304350000034f0030009c00000ae10000813d0000006001300039000000400010043f0000000101000029000002f10010009c000002f10100804100000040011002100000000002030433000002f10020009c000002f1020080410000006002200210000000000112019f0000000002000414000002f10020009c000002f102008041000000c002200210000000000112019f00000328011001c700008010020000390bc00bbb0000040f000000010020019000000ac90000613d000000000101043b000000000001042d000000000100001900000bc2000104300000034901000041000000000010043f0000001101000039000000040010043f0000034a0100004100000bc200010430000000000001042f000000400100043d00000340020000410000000000210435000002f10010009c000002f1010080410000004001100210000002fa011001c700000bc20001043000000335010000410000000000140435000002f10040009c000002f1040080410000004001400210000002fa011001c700000bc2000104300000034901000041000000000010043f0000004101000039000000040010043f0000034a0100004100000bc2000104300009000000000002000900000002001d000200000001001d000000000010043f0000000d01000039000000200010043f0000000001000414000002f10010009c000002f101008041000000c00110021000000327011001c700008010020000390bc00bbb0000040f000000010020019000000b660000613d000000000101043b0000000202100039000100000002001d000000000202041a000300000002001d000000000002004b00000b740000613d000000000201041a000000000002004b00000b7c0000613d00000009202000f9000400000002001d0000000102100039000000000302041a000000000003004b00000b6e0000613d0000000001000019000500000002001d000000000031001a00000b6e0000413d000900000003001d000800000001001d0000000001310019000600000001001d0007000100100278000000000102041a000000070010006c00000b680000a13d000000000020043f0000000001000414000002f10010009c000002f101008041000000c00110021000000350011001c700008010020000390bc00bbb0000040f000000010020019000000b660000613d000000000101043b000000060200002900000001022001bf0000000001120019000000000101041a000000040010006c0000000701000029000000090300002900000000030120190000000101100039000000000201001900000008020020290000000001020019000000000032004b000000050200002900000b080000413d000000000003004b00000b6e0000613d0009000100300092000000000102041a000000090010006c00000b680000a13d000000000020043f0000000001000414000002f10010009c000002f101008041000000c00110021000000350011001c700008010020000390bc00bbb0000040f000000010020019000000b660000613d00000009020000290000000102200210000000000101043b0000000001210019000000000101041a0000000102000029000000000002041b000002f401100197000900000001001d000000000010043f0000000e01000039000000200010043f0000000001000414000002f10010009c000002f101008041000000c00110021000000327011001c700008010020000390bc00bbb0000040f000000010020019000000b660000613d000000000101043b000000000201041a000000030020002a00000b6e0000413d00000003070000290000000002720019000000000021041b0000000001000414000002f10010009c000002f101008041000000c00110021000000328011001c70000800d0200003900000004030000390000035404000041000000020500002900000009060000290bc00bb60000040f000000010020019000000b660000613d000000000001042d000000000100001900000bc2000104300000034901000041000000000010043f0000003201000039000000040010043f0000034a0100004100000bc2000104300000034901000041000000000010043f0000001101000039000000040010043f0000034a0100004100000bc200010430000000400100043d00000355020000410000000000210435000002f10010009c000002f1010080410000004001100210000002fa011001c700000bc2000104300000034901000041000000000010043f0000001201000039000000040010043f0000034a0100004100000bc200010430000000000001042f000002f10010009c000002f1010080410000004001100210000002f10020009c000002f1020080410000006002200210000000000112019f0000000002000414000002f10020009c000002f102008041000000c002200210000000000112019f00000328011001c700008010020000390bc00bbb0000040f000000010020019000000b960000613d000000000101043b000000000001042d000000000100001900000bc20001043000000000050100190000000000200443000000050030008c00000ba60000413d000000040100003900000000020000190000000506200210000000000664001900000005066002700000000006060031000000000161043a0000000102200039000000000031004b00000b9e0000413d000002f10030009c000002f10300804100000060013002100000000002000414000002f10020009c000002f102008041000000c002200210000000000112019f00000356011001c700000000020500190bc00bbb0000040f000000010020019000000bb50000613d000000000101043b000000000001042d000000000001042f00000bb9002104210000000102000039000000000001042d0000000002000019000000000001042d00000bbe002104230000000102000039000000000001042d0000000002000019000000000001042d00000bc00000043200000bc10001042e00000bc200010430000000000000000000000000000000000000000000000000000000000000000000000000ffffffff00000000000000000000000000000000000000000000000000000001ffffffe000000000000000000000000000000000000000000000000000000000ffffffe0000000000000000000000000ffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000ffffffffffffff3f000000000000000000000000000000000000000000000000ffffffffffffff5f00000000000000000000000000000000000000000000000000b1a2bc2ec500010000000000000000000000000000000000000000000000000000000000015181cb10b7c2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000c4edc2a80000000000000000000000000000000000000000000000000000000036f8856f000000000000000000000000000000000000000000000000000000003e2e95c5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000de0b6b3a76400010000000200000000000000000000000000000080000001000000000000000000cd4e6167000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000070e2ca3200000000000000000000000000000000000000000000000000000000c819982500000000000000000000000000000000000000000000000000000000d27f9b7e00000000000000000000000000000000000000000000000000000000f185f20c00000000000000000000000000000000000000000000000000000000f185f20d00000000000000000000000000000000000000000000000000000000fdff9b8100000000000000000000000000000000000000000000000000000000d27f9b7f00000000000000000000000000000000000000000000000000000000e2e9336200000000000000000000000000000000000000000000000000000000c819982600000000000000000000000000000000000000000000000000000000cafe543500000000000000000000000000000000000000000000000000000000cc4c3bf300000000000000000000000000000000000000000000000000000000a512aee700000000000000000000000000000000000000000000000000000000abbe7fe900000000000000000000000000000000000000000000000000000000abbe7fea00000000000000000000000000000000000000000000000000000000c45a015500000000000000000000000000000000000000000000000000000000a512aee800000000000000000000000000000000000000000000000000000000a7a4d00a0000000000000000000000000000000000000000000000000000000070e2ca33000000000000000000000000000000000000000000000000000000008e8772850000000000000000000000000000000000000000000000000000000094726c56000000000000000000000000000000000000000000000000000000003042ec49000000000000000000000000000000000000000000000000000000004e1415330000000000000000000000000000000000000000000000000000000061d027b20000000000000000000000000000000000000000000000000000000061d027b30000000000000000000000000000000000000000000000000000000068b29241000000000000000000000000000000000000000000000000000000004e14153400000000000000000000000000000000000000000000000000000000585fbb6b000000000000000000000000000000000000000000000000000000003042ec4a000000000000000000000000000000000000000000000000000000004273601c0000000000000000000000000000000000000000000000000000000049e1432c000000000000000000000000000000000000000000000000000000001624e9db000000000000000000000000000000000000000000000000000000001624e9dc000000000000000000000000000000000000000000000000000000001e5eb1d0000000000000000000000000000000000000000000000000000000002793433b0000000000000000000000000000000000000000000000000000000001739f760000000000000000000000000000000000000000000000000000000005bc25a800000000000000000000000000000000000000000000000000000000105e60d702000000000000000000000000000000000000400000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffb12d13eb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000800000000000000000310ab089e4439a4c15d089f94afb7896ff553aecb10793d0ab882de59d99a32e020000020000000000000000000000000000004400000000000000000000000042cbb15ccdc3cad6266b0e7a08c0454b23bf29dc2df74b6f3c209e9336465bd1020000020000000000000000000000000000000400000000000000000000000080b41246c05cbb406f874e82aa2faf7db11bba9792fe09929e56ef1eee2c2da30200000200000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff9f796b89b91644bc98cd93958e4c9038275d622183e25ac5af08cc6b5d95539132085de6250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000800000000000000000000000000000000000000000000000000000000000000000ffffffffffffffbfa10ef97c0000000000000000000000000000000000000000000000000000000061d027b3000000000000000000000000000000000000000000000000000000003b5a417e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000080000000000000000000000000000000000000000000000000000000000000000000000000000151808da5cb5b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000001200000000000000000428e0b92000000000000000000000000000000000000000000000000000000001f2b976300000000000000000000000000000000000000000000000000000000fc507a31000000000000000000000000000000000000000000000000000000005f1df6b8213d4bbee1273aa2563c83b786eb036f6a018bb88207cd6ef0dfec71c389e7ff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000001400000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a000000080000000000000000000000000000000000000000000000000000000000000000000b1a2bc2ec5000032cc7236000000000000000000000000000000000000000000000000000000004e487b7100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000032e5c6fd00000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0000000000000000000000000000000000000000000000000ffffffffffffffc0000000000000000000000000000000000000000000000000ffffffffffffffa00200000000000000000000000000000000000020000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000d01d70b8d75d0910a4baec7ccd74d96a9df9d19bd539a8ecb156aee1c8aa621afffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaf75adeadf04a8ca4130d3774f98bdb151c71b80eb8ee92a224bced1c538e9408e42b123f000000000000000000000000000000000000000000000000000000000200000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000073ee958f75270946a22983820952bcdb9dd0a6ba77520b10dda8da8a0fcd0253
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000005606cd69b61bd6ed0fd9adacd56188d9d6f576450000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000003a4965bf58a400000000000000000000000000000000000000000000000000000011c37937e08000000000000000000000000000000000000000000000000000001550f7dca70000000000000000000000000000000000000000000000000000000000000000025800000000000000000000000000000000000000000000000002c68af0bb140000000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000b1a2bc2ec500000000000000000000000000000000000000000000000000000214e8348c4f00000000000000000000000000000000000000000000000000000058d15e17628000
-----Decoded View---------------
Arg [0] : _factory (address): 0x5606Cd69B61bD6Ed0Fd9aDACD56188D9D6F57645
Arg [1] : _jackpotConfig (tuple): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]
Arg [2] : _feeConfig (tuple): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]
-----Encoded View---------------
12 Constructor Arguments found :
Arg [0] : 0000000000000000000000005606cd69b61bd6ed0fd9adacd56188d9d6f57645
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [2] : 000000000000000000000000000000000000000000000000002386f26fc10000
Arg [3] : 0000000000000000000000000000000000000000000000003a4965bf58a40000
Arg [4] : 0000000000000000000000000000000000000000000000000011c37937e08000
Arg [5] : 000000000000000000000000000000000000000000000000001550f7dca70000
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000258
Arg [7] : 00000000000000000000000000000000000000000000000002c68af0bb140000
Arg [8] : 000000000000000000000000000000000000000000000000016345785d8a0000
Arg [9] : 00000000000000000000000000000000000000000000000000b1a2bc2ec50000
Arg [10] : 0000000000000000000000000000000000000000000000000214e8348c4f0000
Arg [11] : 0000000000000000000000000000000000000000000000000058d15e17628000
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.