Overview
SOPH Balance
SOPH Value
-More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
5762334 | 2 days ago | Contract Creation | 0 SOPH |
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:
SophonFarmingL2
Compiler Version
v0.8.26+commit.8a97fa7a
ZkSolc Version
v1.5.6
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0-only pragma solidity 0.8.26; import "contracts/token/ERC20/utils/SafeERC20.sol"; import "contracts/token/ERC20/extensions/IERC20Metadata.sol"; import "contracts/utils/cryptography/MerkleProof.sol"; import "contracts/utils/math/Math.sol"; import "contracts/farm/interfaces/IWeth.sol"; import "contracts/farm/interfaces/IstETH.sol"; import "contracts/farm/interfaces/IwstETH.sol"; import "contracts/farm/interfaces/IsDAI.sol"; import "contracts/farm/interfaces/IeETHLiquidityPool.sol"; import "contracts/farm/interfaces/IweETH.sol"; import "contracts/farm/interfaces/IPriceFeeds.sol"; import "contracts/proxies/Upgradeable2Step.sol"; import "contracts/farm/SophonFarmingState.sol"; /** * @title Sophon Farming Contract * @author Sophon */ contract SophonFarmingL2 is Upgradeable2Step, SophonFarmingState { using SafeERC20 for IERC20; /// @notice Emitted when a new pool is added event Add(address indexed lpToken, uint256 indexed pid, uint256 allocPoint); /// @notice Emitted when a pool is updated event Set(address indexed lpToken, uint256 indexed pid, uint256 allocPoint); /// @notice Emitted when a user deposits to a pool event Deposit(address indexed user, uint256 indexed pid, uint256 depositAmount, uint256 boostAmount); /// @notice Emitted when a user withdraws from a pool event Withdraw(address indexed user, uint256 indexed pid, uint256 amount); /// @notice Emitted when a whitelisted admin transfers points from one user to another event TransferPoints(address indexed sender, address indexed receiver, uint256 indexed pid, uint256 amount); /// @notice Emitted when a user increases the boost of an existing deposit event IncreaseBoost(address indexed user, uint256 indexed pid, uint256 boostAmount); /// @notice Emitted when the the updatePool function is called event PoolUpdated(uint256 indexed pid, uint256 currentValue, uint256 newPrice); /// @notice Emitted when setPointsPerBlock is called event SetPointsPerBlock(uint256 oldValue, uint256 newValue); /// @notice Emitted when setEmissionsMultiplier is called event SetEmissionsMultiplier(uint256 oldValue, uint256 newValue); /// @notice Emitted when held proceeds are withdrawn event WithdrawHeldProceeds(uint256 indexed pid, address indexed to, uint256 amount); event LPDeployed(address indexed pool, uint256 amount); error ZeroAddress(); error PoolExists(); error PoolDoesNotExist(); error AlreadyInitialized(); error NotFound(address lpToken); error FarmingIsStarted(); error FarmingIsEnded(); error TransferNotAllowed(); error TransferTooHigh(uint256 maxAllowed); error InvalidEndBlock(); error InvalidDeposit(); error InvalidPointsPerBlock(); error InvalidTransfer(); error WithdrawNotAllowed(); error WithdrawTooHigh(uint256 maxAllowed); error WithdrawIsZero(); error NothingInPool(); error NoEthSent(); error BridgeInvalid(); error OnlyMerkle(); error CountMismatch(); address public immutable MERKLE; IPriceFeeds public immutable priceFeeds; //Blocks per day = 86,400/ 1 = 86,400 blocks (approximately). uint256 public constant MIN_WITHDRAWAL_BLOCKS = 86400; /** * @notice Construct SophonFarming */ constructor(address _MERKLE, address _priceFeeds) { if (_MERKLE == address(0)) revert ZeroAddress(); MERKLE = _MERKLE; if (_priceFeeds == address(0)) revert ZeroAddress(); priceFeeds = IPriceFeeds(_priceFeeds); } function _setBoostApprovals(bool revoke) external onlyOwner { for(uint256 pid = 0; pid < poolInfo.length; ++pid) { IERC20 token = poolInfo[pid].lpToken; if (address(token) != address(0)) { if (revoke) { token.forceApprove(0x2da10A1e27bF85cEdD8FFb1AbBe97e53391C0295, 0); } else { uint256 amount = heldProceeds[pid]; if (amount != 0) { token.forceApprove(0x2da10A1e27bF85cEdD8FFb1AbBe97e53391C0295, amount); } } } } } function _burnHeldLPs(address[] memory lps) external onlyOwner { for(uint256 i; i < lps.length; i++) { address lp = lps[i]; uint256 amount = heldProceedLPs[lp]; if (amount != 0) { IERC20(lp).transfer(0x000000000000000000000000000000000000dEaD, amount); heldProceedLPs[lp] = 0; } } } function _setLPAdmin(address _lpAdmin) external onlyOwner { lpAdmin = _lpAdmin; } function submitLP(uint256 pidA, uint256 pidB, bytes memory data) external { require(msg.sender == lpAdmin || msg.sender == owner(), "unauthorized"); IERC20 pool; assembly { pool := mload(add(data, 36)) // sig(4) + address(32) } IERC20 tokenA = poolInfo[pidA].lpToken; IERC20 tokenB = poolInfo[pidB].lpToken; uint256 balanceBeforePool = pool.balanceOf(address(this)); uint256 balanceBeforeA = tokenA.balanceOf(address(this)); uint256 balanceBeforeB = tokenB.balanceOf(address(this)); (bool success,) = 0x2da10A1e27bF85cEdD8FFb1AbBe97e53391C0295.call(data); if (!success) { assembly { returndatacopy(0, 0, returndatasize()) revert(0, returndatasize()) } } uint256 lpAmountA = balanceBeforeA - tokenA.balanceOf(address(this)); require(lpAmountA != 0 && lpAmountA <= heldProceeds[pidA], "invalid A amount"); uint256 lpAmountB = balanceBeforeB - tokenB.balanceOf(address(this)); require(lpAmountB != 0 && lpAmountB <= heldProceeds[pidB], "invalid B amount"); heldProceeds[pidA] -= lpAmountA; heldProceeds[pidB] -= lpAmountB; uint256 balanceAfterPool = pool.balanceOf(address(this)); require(balanceAfterPool > balanceBeforePool, "invalid pool amount"); heldProceedLPs[address(pool)] += balanceAfterPool - balanceBeforePool; emit LPDeployed(address(pool), balanceAfterPool - balanceBeforePool); } function updateUserInfo(address _user, uint256 _pid, UserInfo memory _userFromClaim) external { if (msg.sender != MERKLE) revert OnlyMerkle(); require(_pid < poolInfo.length, "Invalid pool id"); require(_userFromClaim.amount == _userFromClaim.boostAmount + _userFromClaim.depositAmount, "balances don't match"); massUpdatePools(); UserInfo storage user = userInfo[_pid][_user]; uint256 accPointsPerShare = poolInfo[_pid].accPointsPerShare; user.amount = user.amount + _userFromClaim.amount; // handles rewards for deposits before claims and for backdated rewards on claimed amounts user.rewardSettled = user.amount * accPointsPerShare / 1e18 + user.rewardSettled - user.rewardDebt; user.rewardSettled = user.rewardSettled + _userFromClaim.rewardSettled; user.boostAmount = user.boostAmount + _userFromClaim.boostAmount; user.depositAmount = user.depositAmount + _userFromClaim.depositAmount; user.rewardDebt = user.amount * accPointsPerShare / 1e18; } /** * @notice Adds a new pool to the farm. Can only be called by the owner. * @param _lpToken lpToken address * @param _emissionsMultiplier multiplier for emissions fine tuning; use 0 or 1e18 for 1x * @param _description description of new pool * @param _poolStartBlock block at which points start to accrue for the pool * @param _newPointsPerBlock update global points per block; 0 means no update * @return uint256 The pid of the newly created asset */ function add(address _lpToken, uint256 _emissionsMultiplier, string memory _description, uint256 _poolStartBlock, uint256 _newPointsPerBlock) public onlyOwner returns (uint256) { if (_lpToken == address(0)) { revert ZeroAddress(); } if (poolExists[_lpToken]) { revert PoolExists(); } if (isFarmingEnded()) { revert FarmingIsEnded(); } if (_newPointsPerBlock != 0) { setPointsPerBlock(_newPointsPerBlock); } else { massUpdatePools(); } uint256 lastRewardBlock = getBlockNumber() > _poolStartBlock ? getBlockNumber() : _poolStartBlock; poolExists[_lpToken] = true; uint256 pid = poolInfo.length; poolInfo.push( PoolInfo({ lpToken: IERC20(_lpToken), l2Farm: address(0), amount: 0, boostAmount: 0, depositAmount: 0, allocPoint: 0, lastRewardBlock: lastRewardBlock, accPointsPerShare: 0, totalRewards: 0, description: _description }) ); if (_emissionsMultiplier == 0) { // set multiplier to 1x _emissionsMultiplier = 1e18; } poolValue[pid].emissionsMultiplier = _emissionsMultiplier; emit Add(_lpToken, pid, 0); return pid; } /** * @notice Updates the given pool's allocation point. Can only be called by the owner. * @param _pid The pid to update * @param _emissionsMultiplier multiplier for emissions fine tuning; use 0 for no update OR 1e18 for 1x * @param _poolStartBlock block at which points start to accrue for the pool; 0 means no update * @param _newPointsPerBlock update global points per block; 0 means no update */ function set(uint256 _pid, uint256 _emissionsMultiplier, uint256 _poolStartBlock, uint256 _newPointsPerBlock) external onlyOwner { if (isFarmingEnded()) { revert FarmingIsEnded(); } if (_newPointsPerBlock != 0) { setPointsPerBlock(_newPointsPerBlock); } else { massUpdatePools(); } PoolInfo storage pool = poolInfo[_pid]; address lpToken = address(pool.lpToken); if (lpToken == address(0) || !poolExists[lpToken]) { revert PoolDoesNotExist(); } if (_emissionsMultiplier != 0) { poolValue[_pid].emissionsMultiplier = _emissionsMultiplier; } // pool starting block is updated if farming hasn't started and _poolStartBlock is non-zero if (_poolStartBlock != 0 && getBlockNumber() < pool.lastRewardBlock) { pool.lastRewardBlock = getBlockNumber() > _poolStartBlock ? getBlockNumber() : _poolStartBlock; } emit Set(lpToken, _pid, 0); } /** * @notice Returns the number of pools in the farm * @return uint256 number of pools */ function poolLength() external view returns (uint256) { return poolInfo.length; } /** * @notice Checks if farming is ended * @return bool True if farming is ended */ function isFarmingEnded() public view returns (bool) { uint256 _endBlock = endBlock; return _endBlock != 0 && getBlockNumber() > _endBlock; } /** * @notice Checks if the withdrawal period is ended * @return bool True if withdrawal period is ended */ function isWithdrawPeriodEnded() public view returns (bool) { uint256 _endBlockForWithdrawals = endBlockForWithdrawals; return _endBlockForWithdrawals != 0 && getBlockNumber() > _endBlockForWithdrawals; } /** * @notice Set the end block of the farm * @param _endBlock the end block * @param _withdrawalBlocks the last block that withdrawals are allowed */ function setEndBlock(uint256 _endBlock, uint256 _withdrawalBlocks) external onlyOwner { if (isFarmingEnded()) { revert FarmingIsEnded(); } uint256 _endBlockForWithdrawals; if (_endBlock != 0) { if (getBlockNumber() > _endBlock) { revert InvalidEndBlock(); } // Enforce the minimum withdrawal period if (_withdrawalBlocks < MIN_WITHDRAWAL_BLOCKS) { revert InvalidEndBlock(); // Use a custom error or revert message for clarity } _endBlockForWithdrawals = _endBlock + _withdrawalBlocks; } else { // withdrawal blocks needs an endBlock _endBlockForWithdrawals = 0; } massUpdatePools(); endBlock = _endBlock; endBlockForWithdrawals = _endBlockForWithdrawals; } /** * @notice Set points per block * @param _pointsPerBlock points per block to set */ function setPointsPerBlock(uint256 _pointsPerBlock) virtual public onlyOwner { if (isFarmingEnded()) { revert FarmingIsEnded(); } if (_pointsPerBlock < 1e18 || _pointsPerBlock > 1_000e18) { revert InvalidPointsPerBlock(); } massUpdatePools(); emit SetPointsPerBlock(pointsPerBlock, _pointsPerBlock); pointsPerBlock = _pointsPerBlock; } /** * @notice Returns the block multiplier * @param _from from block * @param _to to block * @return uint256 The block multiplier */ function _getBlockMultiplier(uint256 _from, uint256 _to) internal view returns (uint256) { uint256 _endBlock = endBlock; if (_endBlock != 0) { _to = Math.min(_to, _endBlock); } if (_to > _from) { return (_to - _from) * 1e18; } else { return 0; } } /** * @notice Adds or removes users from the whitelist * @param _userAdmin an admin user who can transfer points for users * @param _users list of users * @param _isInWhitelist to add or remove */ function setUsersWhitelisted(address _userAdmin, address[] memory _users, bool _isInWhitelist) external onlyOwner { mapping(address user => bool inWhitelist) storage whitelist_ = whitelist[_userAdmin]; for(uint i = 0; i < _users.length; i++) { whitelist_[_users[i]] = _isInWhitelist; } } /** * @notice Returns pending points for user in a pool * @param _pid pid of the pool * @param _user user in the pool * @return uint256 pendings points */ function _pendingPoints(uint256 _pid, address _user) internal view returns (uint256) { UserInfo storage user = userInfo[_pid][_user]; (uint256 accPointsPerShare, ) = _settlePool(_pid); return user.amount * accPointsPerShare / 1e18 + user.rewardSettled - user.rewardDebt; } /** * @notice Set emissions multiplier * @param _emissionsMultiplier emissions multiplier to set */ function setEmissionsMultiplier(uint256 _pid, uint256 _emissionsMultiplier) external onlyOwner { if (_emissionsMultiplier == 0) { // set multiplier to 1x _emissionsMultiplier = 1e18; } massUpdatePools(); PoolValue storage pv = poolValue[_pid]; emit SetEmissionsMultiplier(pv.emissionsMultiplier, _emissionsMultiplier); pv.emissionsMultiplier = _emissionsMultiplier; } /** * @notice Returns accPointsPerShare and totalRewards to date for the pool * @param _pid pid of the pool * @return accPointsPerShare * @return totalRewards */ function _settlePool(uint256 _pid) internal view returns (uint256 accPointsPerShare, uint256 totalRewards) { PoolInfo storage pool = poolInfo[_pid]; accPointsPerShare = pool.accPointsPerShare; totalRewards = pool.totalRewards; uint256 lpSupply = pool.amount; uint256 _totalValue = totalValue; if (getBlockNumber() > pool.lastRewardBlock && lpSupply != 0 && _totalValue != 0) { uint256 blockMultiplier = _getBlockMultiplier(pool.lastRewardBlock, getBlockNumber()); uint256 pointReward = blockMultiplier * pointsPerBlock * poolValue[_pid].lastValue / _totalValue; totalRewards = totalRewards + pointReward / 1e18; accPointsPerShare = pointReward / lpSupply + accPointsPerShare; } } /** * @notice Returns pending points for user in a pool * @param _pid pid of the pool * @param _user user in the pool * @return uint256 pendings points */ function pendingPoints(uint256 _pid, address _user) external view returns (uint256) { return _pendingPoints(_pid, _user); } /** * @notice Update accounting of all pools */ function massUpdatePools() public { uint256 length = poolInfo.length; uint256 totalNewValue; uint256 _pid; // [[lastRewardBlock, lastValue, lpSupply, newPrice]] uint256[4][] memory valuesArray = new uint256[4][](length); for(_pid = 0; _pid < length; ++_pid) { valuesArray[_pid] = _updatePool(_pid); totalNewValue += valuesArray[_pid][1]; } totalValue = totalNewValue; uint256 _pointsPerBlock = pointsPerBlock; for(_pid = 0; _pid < length; ++_pid) { uint256[4] memory values = valuesArray[_pid]; PoolInfo storage pool = poolInfo[_pid]; if (getBlockNumber() <= values[0]) { continue; } if (values[2] != 0 && values[1] != 0) { uint256 blockMultiplier = _getBlockMultiplier(values[0], getBlockNumber()); uint256 pointReward = blockMultiplier * _pointsPerBlock * values[1] / totalNewValue; pool.totalRewards = pool.totalRewards + pointReward / 1e18; pool.accPointsPerShare = pointReward / values[2] + pool.accPointsPerShare; } pool.lastRewardBlock = getBlockNumber(); emit PoolUpdated(_pid, values[1], values[3]); } } // returns [lastRewardBlock, lastValue, lpSupply, newPrice] function _updatePool(uint256 _pid) internal returns (uint256[4] memory values) { PoolInfo storage pool = poolInfo[_pid]; values[0] = pool.lastRewardBlock; if (getBlockNumber() < values[0]) { // pool doesn't start until a future block return values; } PoolValue storage pv = poolValue[_pid]; values[1] = pv.lastValue; if (getBlockNumber() == values[0]) { // pool was already processed this block, but we still need the value return values; } values[2] = pool.amount; if (values[2] == 0) { return values; } values[3] = priceFeeds.getPrice(address(pool.lpToken)); if (values[3] == 0) { // invalid price return values; } uint256 newValue = values[2] * values[3] / 1e18; newValue = newValue * pv.emissionsMultiplier / 1e18; if (newValue == 0) { // invalid value return values; } pv.lastValue = newValue; values[1] = newValue; return values; } /** * @notice Deposit assets to SophonFarming * @param _pid pid of the pool * @param _amount amount of the deposit * @param _boostAmount amount to boost */ function deposit(uint256 _pid, uint256 _amount, uint256 _boostAmount) external { poolInfo[_pid].lpToken.safeTransferFrom( msg.sender, address(this), _amount ); _deposit(_pid, _amount, _boostAmount); } /** * @notice Deposit an asset to SophonFarming * @param _pid pid of the deposit * @param _depositAmount amount of the deposit * @param _boostAmount amount to boost */ function _deposit(uint256 _pid, uint256 _depositAmount, uint256 _boostAmount) internal { if (isFarmingEnded()) { revert FarmingIsEnded(); } if (_depositAmount == 0) { revert InvalidDeposit(); } _boostAmount; // unused massUpdatePools(); PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; uint256 userAmount = user.amount; user.rewardSettled = userAmount * pool.accPointsPerShare / 1e18 + user.rewardSettled - user.rewardDebt; // set deposit amount user.depositAmount = user.depositAmount + _depositAmount; pool.depositAmount = pool.depositAmount + _depositAmount; userAmount = userAmount + _depositAmount; user.amount = userAmount; pool.amount = pool.amount + _depositAmount; user.rewardDebt = userAmount * pool.accPointsPerShare / 1e18; emit Deposit(msg.sender, _pid, _depositAmount, 0); } /** * @notice Returns max additional boost amount allowed to boost current deposits * @dev total allowed boost is 100% of total deposit * @param _user user in pool * @param _pid pid of pool * @return uint256 max additional boost */ function getMaxAdditionalBoost(address _user, uint256 _pid) public view returns (uint256) { return 0; } /** * @notice Withdraw an asset to SophonFarming * @param _pid pid of the withdraw * @param _withdrawAmount amount of the withdraw */ function withdraw(uint256 _pid, uint256 _withdrawAmount) external { if (isWithdrawPeriodEnded()) { revert WithdrawNotAllowed(); } if (_withdrawAmount == 0) { revert WithdrawIsZero(); } massUpdatePools(); PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; uint256 userDepositAmount = user.depositAmount; if (_withdrawAmount == type(uint256).max) { _withdrawAmount = userDepositAmount; } else if (_withdrawAmount > userDepositAmount) { revert WithdrawTooHigh(userDepositAmount); } uint256 userAmount = user.amount; user.rewardSettled = userAmount * pool.accPointsPerShare / 1e18 + user.rewardSettled - user.rewardDebt; user.depositAmount = userDepositAmount - _withdrawAmount; pool.depositAmount = pool.depositAmount - _withdrawAmount; userAmount = userAmount - _withdrawAmount; user.amount = userAmount; pool.amount = pool.amount - _withdrawAmount; user.rewardDebt = userAmount * pool.accPointsPerShare / 1e18; pool.lpToken.safeTransfer(msg.sender, _withdrawAmount); emit Withdraw(msg.sender, _pid, _withdrawAmount); } /** * @notice Called by an whitelisted admin to transfer points to another user * @param _pid pid of the pool to transfer points from * @param _sender address to send accrued points * @param _receiver address to receive accrued points * @param _transferAmount amount of points to transfer */ function transferPoints(uint256 _pid, address _sender, address _receiver, uint256 _transferAmount) external { if (!whitelist[msg.sender][_sender]) { revert TransferNotAllowed(); } if (_sender == _receiver || _receiver == address(this) || _transferAmount == 0) { revert InvalidTransfer(); } massUpdatePools(); PoolInfo storage pool = poolInfo[_pid]; if (address(pool.lpToken) == address(0)) { revert PoolDoesNotExist(); } uint256 accPointsPerShare = pool.accPointsPerShare; UserInfo storage userFrom = userInfo[_pid][_sender]; UserInfo storage userTo = userInfo[_pid][_receiver]; uint256 userFromAmount = userFrom.amount; uint256 userToAmount = userTo.amount; uint userFromRewardSettled = userFromAmount * accPointsPerShare / 1e18 + userFrom.rewardSettled - userFrom.rewardDebt; if (_transferAmount == type(uint256).max) { _transferAmount = userFromRewardSettled; } else if (_transferAmount > userFromRewardSettled) { revert TransferTooHigh(userFromRewardSettled); } userFrom.rewardSettled = userFromRewardSettled - _transferAmount; userTo.rewardSettled = userToAmount * accPointsPerShare / 1e18 + userTo.rewardSettled - userTo.rewardDebt + _transferAmount; userFrom.rewardDebt = userFromAmount * accPointsPerShare / 1e18; userTo.rewardDebt = userToAmount * accPointsPerShare / 1e18; emit TransferPoints(_sender, _receiver, _pid, _transferAmount); } function batchAwardPoints(uint256 _pid, address[] memory _receivers, uint256[] memory _quantities) external onlyOwner { if (_receivers.length != _quantities.length) { revert CountMismatch(); } PoolInfo storage pool = poolInfo[_pid]; if (address(pool.lpToken) == address(0)) { revert PoolDoesNotExist(); } uint256 _totalPoints; for (uint256 i; i < _receivers.length; i++) { UserInfo storage user = userInfo[_pid][_receivers[i]]; user.rewardSettled = user.rewardSettled + _quantities[i]; _totalPoints = _totalPoints + _quantities[i]; } pool.totalRewards = pool.totalRewards + _totalPoints; } /** * @notice Returns the current block number * @dev Included to help with testing since it can be overridden for custom functionality * @return uint256 current block number */ function getBlockNumber() virtual public view returns (uint256) { return block.number; } /** * @notice Returns info about each pool * @return poolInfos all pool info */ function getPoolInfo() external view returns (PoolInfo[] memory poolInfos) { uint256 length = poolInfo.length; poolInfos = new PoolInfo[](length); for(uint256 pid = 0; pid < length; ++pid) { poolInfos[pid] = poolInfo[pid]; (, poolInfos[pid].totalRewards) = _settlePool(pid); } } /** * @notice Returns user info for a list of users * @param _users list of users * @return userInfos optimized user info */ function getOptimizedUserInfo(address[] memory _users) external view returns (uint256[4][][] memory userInfos) { uint256 usersLen = _users.length; userInfos = new uint256[4][][](usersLen); uint256 poolLen = poolInfo.length; for(uint256 i = 0; i < usersLen; i++) { address _user = _users[i]; userInfos[i] = new uint256[4][](poolLen); for(uint256 pid = 0; pid < poolLen; ++pid) { UserInfo memory uinfo = userInfo[pid][_user]; userInfos[i][pid][0] = uinfo.amount; userInfos[i][pid][1] = uinfo.boostAmount; userInfos[i][pid][2] = uinfo.depositAmount; userInfos[i][pid][3] = _pendingPoints(pid, _user); } } } /** * @notice Returns accrued points for a list of users * @param _users list of users * @return pendings accured points for user */ function getPendingPoints(address[] memory _users) external view returns (uint256[][] memory pendings) { uint256 usersLen = _users.length; pendings = new uint256[][](usersLen); uint256 poolLen = poolInfo.length; for(uint256 i = 0; i < usersLen; i++) { address _user = _users[i]; pendings[i] = new uint256[](poolLen); for(uint256 pid = 0; pid < poolLen; ++pid) { pendings[i][pid] = _pendingPoints(pid, _user); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "contracts/token/ERC20/IERC20.sol"; import {IERC20Permit} from "contracts/token/ERC20/extensions/IERC20Permit.sol"; import {Address} from "contracts/utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; /** * @dev An operation with an ERC20 token failed. */ error SafeERC20FailedOperation(address token); /** * @dev Indicates a failed `decreaseAllowance` request. */ error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease); /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value))); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value))); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); forceApprove(token, spender, oldAllowance + value); } /** * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no * value, non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal { unchecked { uint256 currentAllowance = token.allowance(address(this), spender); if (currentAllowance < requestedDecrease) { revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease); } forceApprove(token, spender, currentAllowance - requestedDecrease); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value)); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0))); _callOptionalReturn(token, approvalCall); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data); if (returndata.length != 0 && !abi.decode(returndata, (bool))) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 value) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 value) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * ==== Security Considerations * * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be * considered as an intention to spend the allowance in any specific way. The second is that because permits have * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be * generally recommended is: * * ```solidity * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public { * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {} * doThing(..., value); * } * * function doThing(..., uint256 value) public { * token.safeTransferFrom(msg.sender, address(this), value); * ... * } * ``` * * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also * {SafeERC20-safeTransferFrom}). * * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so * contracts should have entry points that don't rely on permit. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. * * CAUTION: See Security Considerations above. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol) pragma solidity ^0.8.20; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev The ETH balance of the account is not enough to perform the operation. */ error AddressInsufficientBalance(address account); /** * @dev There's no code at `target` (it is not a contract). */ error AddressEmptyCode(address target); /** * @dev A call to an address target failed. The target may have reverted. */ error FailedInnerCall(); /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { if (address(this).balance < amount) { revert AddressInsufficientBalance(address(this)); } (bool success, ) = recipient.call{value: amount}(""); if (!success) { revert FailedInnerCall(); } } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason or custom error, it is bubbled * up by this function (like regular Solidity function calls). However, if * the call reverted with no returned reason, this function reverts with a * {FailedInnerCall} error. * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { if (address(this).balance < value) { revert AddressInsufficientBalance(address(this)); } (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an * unsuccessful call. */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata ) internal view returns (bytes memory) { if (!success) { _revert(returndata); } else { // only check if target is a contract if the call was successful and the return data is empty // otherwise we already know that it was a contract if (returndata.length == 0 && target.code.length == 0) { revert AddressEmptyCode(target); } return returndata; } } /** * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the * revert reason or with a default {FailedInnerCall} error. */ function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) { if (!success) { _revert(returndata); } else { return returndata; } } /** * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}. */ function _revert(bytes memory returndata) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert FailedInnerCall(); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.20; import {IERC20} from "contracts/token/ERC20/IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/MerkleProof.sol) pragma solidity ^0.8.20; /** * @dev These functions deal with verification of Merkle Tree proofs. * * The tree and the proofs can be generated using our * https://github.com/OpenZeppelin/merkle-tree[JavaScript library]. * You will find a quickstart guide in the readme. * * WARNING: You should avoid using leaf values that are 64 bytes long prior to * hashing, or use a hash function other than keccak256 for hashing leaves. * This is because the concatenation of a sorted pair of internal nodes in * the Merkle tree could be reinterpreted as a leaf value. * OpenZeppelin's JavaScript library generates Merkle trees that are safe * against this attack out of the box. */ library MerkleProof { /** *@dev The multiproof provided is not valid. */ error MerkleProofInvalidMultiproof(); /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. */ function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { return processProof(proof, leaf) == root; } /** * @dev Calldata version of {verify} */ function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { return processProofCalldata(proof, leaf) == root; } /** * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt * hash matches the root of the tree. When processing the proof, the pairs * of leafs & pre-images are assumed to be sorted. */ function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Calldata version of {processProof} */ function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a Merkle tree defined by * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}. * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. */ function multiProofVerify( bytes32[] memory proof, bool[] memory proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProof(proof, proofFlags, leaves) == root; } /** * @dev Calldata version of {multiProofVerify} * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. */ function multiProofVerifyCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProofCalldata(proof, proofFlags, leaves) == root; } /** * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false * respectively. * * CAUTION: Not all Merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer). */ function processMultiProof( bytes32[] memory proof, bool[] memory proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the Merkle tree. uint256 leavesLen = leaves.length; uint256 proofLen = proof.length; uint256 totalHashes = proofFlags.length; // Check proof validity. if (leavesLen + proofLen != totalHashes + 1) { revert MerkleProofInvalidMultiproof(); } // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { if (proofPos != proofLen) { revert MerkleProofInvalidMultiproof(); } unchecked { return hashes[totalHashes - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Calldata version of {processMultiProof}. * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. */ function processMultiProofCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the Merkle tree. uint256 leavesLen = leaves.length; uint256 proofLen = proof.length; uint256 totalHashes = proofFlags.length; // Check proof validity. if (leavesLen + proofLen != totalHashes + 1) { revert MerkleProofInvalidMultiproof(); } // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { if (proofPos != proofLen) { revert MerkleProofInvalidMultiproof(); } unchecked { return hashes[totalHashes - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Sorts the pair (a, b) and hashes the result. */ function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) { return a < b ? _efficientHash(a, b) : _efficientHash(b, a); } /** * @dev Implementation of keccak256(abi.encode(a, b)) that doesn't allocate or expand memory. */ function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { /// @solidity memory-safe-assembly assembly { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol) pragma solidity ^0.8.20; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Muldiv operation overflow. */ error MathOverflowedMulDiv(); enum Rounding { Floor, // Toward negative infinity Ceil, // Toward positive infinity Trunc, // Toward zero Expand // Away from zero } /** * @dev Returns the addition of two unsigned integers, with an overflow flag. */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an overflow flag. */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds towards infinity instead * of rounding towards zero. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { if (b == 0) { // Guarantee the same behavior as in a regular Solidity division. return a / b; } // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or * denominator == 0. * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by * Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0 = x * y; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. if (denominator <= prod1) { revert MathOverflowedMulDiv(); } /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. // Always >= 1. See https://cs.stackexchange.com/q/138556/92363. uint256 twos = denominator & (0 - denominator); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also // works in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded * towards zero. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256 of a positive value rounded towards zero. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0); } } /** * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers. */ function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) { return uint8(rounding) % 2 == 1; } }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity 0.8.26; interface IWeth { event Approval(address indexed src, address indexed guy, uint wad); event Transfer(address indexed src, address indexed dst, uint wad); event Deposit(address indexed dst, uint wad); event Withdrawal(address indexed src, uint wad); function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); function balanceOf(address user) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); function totalSupply() external view returns (uint); function deposit() external payable; function withdraw(uint256 wad) external; function approve(address guy, uint wad) external returns (bool); function transfer(address dst, uint wad) external returns (bool); function transferFrom(address src, address dst, uint wad) external returns (bool); }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity 0.8.26; interface IstETH { function submit(address _referral) external payable returns (uint256); function getSharesByPooledEth(uint256 _ethAmount) external view returns (uint256); function getPooledEthByShares(uint256 _sharesAmount) external view returns (uint256); }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity 0.8.26; interface IwstETH { function wrap(uint256 _stETHAmount) external returns (uint256); function unwrap(uint256 _wstETHAmount) external returns (uint256); function getWstETHByStETH(uint256 _stETHAmount) external view returns (uint256); function getStETHByWstETH(uint256 _wstETHAmount) external view returns (uint256); function stEthPerToken() external view returns (uint256); function tokensPerStEth() external view returns (uint256); }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity 0.8.26; interface IsDAI { function deposit(uint256 assets, address receiver) external returns (uint256 shares); function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets); function convertToShares(uint256 assets) external view returns (uint256); function convertToAssets(uint256 shares) external view returns (uint256); }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity 0.8.26; interface IeETHLiquidityPool { function deposit(address _referral) external payable returns (uint256); function sharesForAmount(uint256 _amount) external view returns (uint256); function amountForShare(uint256 _share) external view returns (uint256); }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity 0.8.26; interface IweETH { function wrap(uint256 _eETHAmount) external returns (uint256); }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity 0.8.26; interface IPriceFeeds { event SetPriceFeedData(address indexed poolToken, FeedType feedType, bytes32 feedHash, uint256 staleSeconds); error ZeroAddress(); error CountMismatch(); error InvalidCall(); error InvalidType(); error TypeMismatch(); error InvalidStaleSeconds(); enum FeedType { Undefined, Stork } struct StorkData { bytes32 feedHash; uint256 staleSeconds; FeedType feedType; } function getPrice(address poolToken_) external view returns (uint256); function getStorkPrice(bytes32 feedHash_, uint256 staleSeconds_) external view returns (uint256); function setStorkFeedsData(address farmContract, address[] memory poolTokens_, StorkData[] memory poolTokenDatas_) external; }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity 0.8.26; import "contracts/access/Ownable2Step.sol"; event ReplaceImplementationStarted(address indexed previousImplementation, address indexed newImplementation); event ReplaceImplementation(address indexed previousImplementation, address indexed newImplementation); error Unauthorized(); contract Upgradeable2Step is Ownable2Step { address public pendingImplementation; address public implementation; constructor() Ownable(msg.sender) {} // called on an inheriting proxy contract function replaceImplementation(address impl_) public onlyOwner { pendingImplementation = impl_; emit ReplaceImplementationStarted(implementation, impl_); } // called from an inheriting implementation contract function acceptImplementation() public { if (msg.sender != pendingImplementation) { revert OwnableUnauthorizedAccount(msg.sender); } emit ReplaceImplementation(implementation, msg.sender); delete pendingImplementation; implementation = msg.sender; } // called on an inheriting implementation contract function becomeImplementation(Upgradeable2Step proxy) public { if (msg.sender != proxy.owner()) { revert Unauthorized(); } proxy.acceptImplementation(); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable2Step.sol) pragma solidity ^0.8.20; import {Ownable} from "contracts/access/Ownable.sol"; /** * @dev Contract module which provides access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is specified at deployment time in the constructor for `Ownable`. This * can later be changed with {transferOwnership} and {acceptOwnership}. * * This module is used through inheritance. It will make available all functions * from parent (Ownable). */ abstract contract Ownable2Step is Ownable { address private _pendingOwner; event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner); /** * @dev Returns the address of the pending owner. */ function pendingOwner() public view virtual returns (address) { return _pendingOwner; } /** * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual override onlyOwner { _pendingOwner = newOwner; emit OwnershipTransferStarted(owner(), newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner. * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual override { delete _pendingOwner; super._transferOwnership(newOwner); } /** * @dev The new owner accepts the ownership transfer. */ function acceptOwnership() public virtual { address sender = _msgSender(); if (pendingOwner() != sender) { revert OwnableUnauthorizedAccount(sender); } _transferOwnership(sender); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; import {Context} from "contracts/utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is set to the address provided by the deployer. This can * later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity 0.8.26; import "contracts/token/ERC20/IERC20.sol"; import "contracts/farm/interfaces/bridge/IBridgehub.sol"; contract SophonFarmingState { // Info of each pool. struct PoolInfo { IERC20 lpToken; // Address of LP token contract. address l2Farm; // Address of the farming contract on Sophon chain uint256 amount; // total amount of LP tokens earning yield from deposits and boosts uint256 boostAmount; // total boosted value purchased by users uint256 depositAmount; // remaining deposits not applied to a boost purchases uint256 allocPoint; // How many allocation points assigned to this pool. Points to distribute per block. uint256 lastRewardBlock; // Last block number that points distribution occurs. uint256 accPointsPerShare; // Accumulated points per share. uint256 totalRewards; // Total rewards earned by the pool. string description; // Description of pool. } // Info of each user. struct UserInfo { uint256 amount; // Amount of LP tokens the user is earning yield on from deposits and boosts uint256 boostAmount; // Boosted value purchased by the user uint256 depositAmount; // remaining deposits not applied to a boost purchases uint256 rewardSettled; // rewards settled uint256 rewardDebt; // rewards debt } enum PredefinedPool { sDAI, // MakerDAO (sDAI) wstETH, // Lido (wstETH) weETH // ether.fi (weETH) } mapping(PredefinedPool => uint256) public typeToId; // held proceeds from booster sales mapping(uint256 => uint256) public heldProceeds; uint256 public boosterMultiplier; // Points created per block. uint256 public pointsPerBlock; // Info of each pool. PoolInfo[] public poolInfo; // Info of each user that stakes LP tokens. mapping(uint256 => mapping(address => UserInfo)) public userInfo; // Total allocation points. Must be the sum of all allocation points in all pools. uint256 public totalAllocPoint; // The block number when point mining ends. uint256 public endBlock; bool internal _initialized; mapping(address => bool) public poolExists; uint256 public endBlockForWithdrawals; IBridgehub public bridge; mapping(uint256 => bool) public isBridged; mapping(address userAdmin => mapping(address user => bool inWhitelist)) public whitelist; struct PoolValue { uint256 lastValue; uint256 emissionsMultiplier; } mapping(uint256 pid => PoolValue) public poolValue; // total USD value of all pools including all deposits, boosts, and emissionsMultipliers uint256 public totalValue; address internal lpAdmin; mapping(address => uint256) public heldProceedLPs; // LP_token_address => amount_held }
// SPDX-License-Identifier: MIT pragma solidity 0.8.26; import {IL1SharedBridge} from "contracts/farm/interfaces/bridge/IL1SharedBridge.sol"; import {L2Message, L2Log, TxStatus} from "contracts/farm/interfaces/bridge/Messaging.sol"; struct L2TransactionRequestDirect { uint256 chainId; uint256 mintValue; address l2Contract; uint256 l2Value; bytes l2Calldata; uint256 l2GasLimit; uint256 l2GasPerPubdataByteLimit; bytes[] factoryDeps; address refundRecipient; } struct L2TransactionRequestTwoBridgesOuter { uint256 chainId; uint256 mintValue; uint256 l2Value; uint256 l2GasLimit; uint256 l2GasPerPubdataByteLimit; address refundRecipient; address secondBridgeAddress; uint256 secondBridgeValue; bytes secondBridgeCalldata; } struct L2TransactionRequestTwoBridgesInner { bytes32 magicValue; address l2Contract; bytes l2Calldata; bytes[] factoryDeps; bytes32 txDataHash; } interface IBridgehub { /// @notice pendingAdmin is changed /// @dev Also emitted when new admin is accepted and in this case, `newPendingAdmin` would be zero address event NewPendingAdmin(address indexed oldPendingAdmin, address indexed newPendingAdmin); /// @notice Admin changed event NewAdmin(address indexed oldAdmin, address indexed newAdmin); /// @notice Starts the transfer of admin rights. Only the current admin can propose a new pending one. /// @notice New admin can accept admin rights by calling `acceptAdmin` function. /// @param _newPendingAdmin Address of the new admin function setPendingAdmin(address _newPendingAdmin) external; /// @notice Accepts transfer of admin rights. Only pending admin can accept the role. function acceptAdmin() external; /// Getters function stateTransitionManagerIsRegistered(address _stateTransitionManager) external view returns (bool); function stateTransitionManager(uint256 _chainId) external view returns (address); function tokenIsRegistered(address _baseToken) external view returns (bool); function baseToken(uint256 _chainId) external view returns (address); function sharedBridge() external view returns (IL1SharedBridge); function getHyperchain(uint256 _chainId) external view returns (address); /// Mailbox forwarder function proveL2MessageInclusion( uint256 _chainId, uint256 _batchNumber, uint256 _index, L2Message calldata _message, bytes32[] calldata _proof ) external view returns (bool); function proveL2LogInclusion( uint256 _chainId, uint256 _batchNumber, uint256 _index, L2Log memory _log, bytes32[] calldata _proof ) external view returns (bool); function proveL1ToL2TransactionStatus( uint256 _chainId, bytes32 _l2TxHash, uint256 _l2BatchNumber, uint256 _l2MessageIndex, uint16 _l2TxNumberInBatch, bytes32[] calldata _merkleProof, TxStatus _status ) external view returns (bool); function requestL2TransactionDirect( L2TransactionRequestDirect calldata _request ) external payable returns (bytes32 canonicalTxHash); function requestL2TransactionTwoBridges( L2TransactionRequestTwoBridgesOuter calldata _request ) external payable returns (bytes32 canonicalTxHash); function l2TransactionBaseCost( uint256 _chainId, uint256 _gasPrice, uint256 _l2GasLimit, uint256 _l2GasPerPubdataByteLimit ) external view returns (uint256); //// Registry function createNewChain( uint256 _chainId, address _stateTransitionManager, address _baseToken, uint256 _salt, address _admin, bytes calldata _initData ) external returns (uint256 chainId); function addStateTransitionManager(address _stateTransitionManager) external; function removeStateTransitionManager(address _stateTransitionManager) external; function addToken(address _token) external; function setSharedBridge(address _sharedBridge) external; event NewChain(uint256 indexed chainId, address stateTransitionManager, address indexed chainGovernance); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.26; /// @title L1 Bridge contract interface /// @author Matter Labs /// @custom:security-contact [email protected] interface IL1SharedBridge { event LegacyDepositInitiated( uint256 indexed chainId, bytes32 indexed l2DepositTxHash, address indexed from, address to, address l1Token, uint256 amount ); event BridgehubDepositInitiated( uint256 indexed chainId, bytes32 indexed txDataHash, address indexed from, address to, address l1Token, uint256 amount ); event BridgehubDepositBaseTokenInitiated( uint256 indexed chainId, address indexed from, address l1Token, uint256 amount ); event BridgehubDepositFinalized( uint256 indexed chainId, bytes32 indexed txDataHash, bytes32 indexed l2DepositTxHash ); event WithdrawalFinalizedSharedBridge( uint256 indexed chainId, address indexed to, address indexed l1Token, uint256 amount ); event ClaimedFailedDepositSharedBridge( uint256 indexed chainId, address indexed to, address indexed l1Token, uint256 amount ); function isWithdrawalFinalized( uint256 _chainId, uint256 _l2BatchNumber, uint256 _l2MessageIndex ) external view returns (bool); function depositLegacyErc20Bridge( address _msgSender, address _l2Receiver, address _l1Token, uint256 _amount, uint256 _l2TxGasLimit, uint256 _l2TxGasPerPubdataByte, address _refundRecipient ) external payable returns (bytes32 txHash); function claimFailedDepositLegacyErc20Bridge( address _depositSender, address _l1Token, uint256 _amount, bytes32 _l2TxHash, uint256 _l2BatchNumber, uint256 _l2MessageIndex, uint16 _l2TxNumberInBatch, bytes32[] calldata _merkleProof ) external; function claimFailedDeposit( uint256 _chainId, address _depositSender, address _l1Token, uint256 _amount, bytes32 _l2TxHash, uint256 _l2BatchNumber, uint256 _l2MessageIndex, uint16 _l2TxNumberInBatch, bytes32[] calldata _merkleProof ) external; function finalizeWithdrawalLegacyErc20Bridge( uint256 _l2BatchNumber, uint256 _l2MessageIndex, uint16 _l2TxNumberInBatch, bytes calldata _message, bytes32[] calldata _merkleProof ) external returns (address l1Receiver, address l1Token, uint256 amount); function finalizeWithdrawal( uint256 _chainId, uint256 _l2BatchNumber, uint256 _l2MessageIndex, uint16 _l2TxNumberInBatch, bytes calldata _message, bytes32[] calldata _merkleProof ) external; function setEraPostDiamondUpgradeFirstBatch(uint256 _eraPostDiamondUpgradeFirstBatch) external; function setEraPostLegacyBridgeUpgradeFirstBatch(uint256 _eraPostLegacyBridgeUpgradeFirstBatch) external; function setEraLegacyBridgeLastDepositTime( uint256 _eraLegacyBridgeLastDepositBatch, uint256 _eraLegacyBridgeLastDepositTxNumber ) external; function L1_WETH_TOKEN() external view returns (address); function BRIDGE_HUB() external view returns (address); function legacyBridge() external view returns (address); function l2BridgeAddress(uint256 _chainId) external view returns (address); function depositHappened(uint256 _chainId, bytes32 _l2TxHash) external view returns (bytes32); struct L2TransactionRequestTwoBridgesInner { bytes32 magicValue; address l2Contract; bytes l2Calldata; bytes[] factoryDeps; bytes32 txDataHash; } /// data is abi encoded : /// address _l1Token, /// uint256 _amount, /// address _l2Receiver function bridgehubDeposit( uint256 _chainId, address _prevMsgSender, uint256 _l2Value, bytes calldata _data ) external payable returns (L2TransactionRequestTwoBridgesInner memory request); function bridgehubDepositBaseToken( uint256 _chainId, address _prevMsgSender, address _l1Token, uint256 _amount ) external payable; function bridgehubConfirmL2Transaction(uint256 _chainId, bytes32 _txDataHash, bytes32 _txHash) external; function receiveEth(uint256 _chainId) external payable; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.26; /// @dev The enum that represents the transaction execution status /// @param Failure The transaction execution failed /// @param Success The transaction execution succeeded enum TxStatus { Failure, Success } /// @dev The log passed from L2 /// @param l2ShardId The shard identifier, 0 - rollup, 1 - porter /// All other values are not used but are reserved for the future /// @param isService A boolean flag that is part of the log along with `key`, `value`, and `sender` address. /// This field is required formally but does not have any special meaning /// @param txNumberInBatch The L2 transaction number in a Batch, in which the log was sent /// @param sender The L2 address which sent the log /// @param key The 32 bytes of information that was sent in the log /// @param value The 32 bytes of information that was sent in the log // Both `key` and `value` are arbitrary 32-bytes selected by the log sender struct L2Log { uint8 l2ShardId; bool isService; uint16 txNumberInBatch; address sender; bytes32 key; bytes32 value; } /// @dev An arbitrary length message passed from L2 /// @notice Under the hood it is `L2Log` sent from the special system L2 contract /// @param txNumberInBatch The L2 transaction number in a Batch, in which the message was sent /// @param sender The address of the L2 account from which the message was passed /// @param data An arbitrary length message struct L2Message { uint16 txNumberInBatch; address sender; bytes data; } /// @dev Internal structure that contains the parameters for the writePriorityOp /// internal function. /// @param txId The id of the priority transaction. /// @param l2GasPrice The gas price for the l2 priority operation. /// @param expirationTimestamp The timestamp by which the priority operation must be processed by the operator. /// @param request The external calldata request for the priority operation. struct WritePriorityOpParams { uint256 txId; uint256 l2GasPrice; uint64 expirationTimestamp; BridgehubL2TransactionRequest request; } /// @dev Structure that includes all fields of the L2 transaction /// @dev The hash of this structure is the "canonical L2 transaction hash" and can /// be used as a unique identifier of a tx /// @param txType The tx type number, depending on which the L2 transaction can be /// interpreted differently /// @param from The sender's address. `uint256` type for possible address format changes /// and maintaining backward compatibility /// @param to The recipient's address. `uint256` type for possible address format changes /// and maintaining backward compatibility /// @param gasLimit The L2 gas limit for L2 transaction. Analog to the `gasLimit` on an /// L1 transactions /// @param gasPerPubdataByteLimit Maximum number of L2 gas that will cost one byte of pubdata /// (every piece of data that will be stored on L1 as calldata) /// @param maxFeePerGas The absolute maximum sender willing to pay per unit of L2 gas to get /// the transaction included in a Batch. Analog to the EIP-1559 `maxFeePerGas` on an L1 transactions /// @param maxPriorityFeePerGas The additional fee that is paid directly to the validator /// to incentivize them to include the transaction in a Batch. Analog to the EIP-1559 /// `maxPriorityFeePerGas` on an L1 transactions /// @param paymaster The address of the EIP-4337 paymaster, that will pay fees for the /// transaction. `uint256` type for possible address format changes and maintaining backward compatibility /// @param nonce The nonce of the transaction. For L1->L2 transactions it is the priority /// operation Id /// @param value The value to pass with the transaction /// @param reserved The fixed-length fields for usage in a future extension of transaction /// formats /// @param data The calldata that is transmitted for the transaction call /// @param signature An abstract set of bytes that are used for transaction authorization /// @param factoryDeps The set of L2 bytecode hashes whose preimages were shown on L1 /// @param paymasterInput The arbitrary-length data that is used as a calldata to the paymaster pre-call /// @param reservedDynamic The arbitrary-length field for usage in a future extension of transaction formats struct L2CanonicalTransaction { uint256 txType; uint256 from; uint256 to; uint256 gasLimit; uint256 gasPerPubdataByteLimit; uint256 maxFeePerGas; uint256 maxPriorityFeePerGas; uint256 paymaster; uint256 nonce; uint256 value; // In the future, we might want to add some // new fields to the struct. The `txData` struct // is to be passed to account and any changes to its structure // would mean a breaking change to these accounts. To prevent this, // we should keep some fields as "reserved" // It is also recommended that their length is fixed, since // it would allow easier proof integration (in case we will need // some special circuit for preprocessing transactions) uint256[4] reserved; bytes data; bytes signature; uint256[] factoryDeps; bytes paymasterInput; // Reserved dynamic type for the future use-case. Using it should be avoided, // But it is still here, just in case we want to enable some additional functionality bytes reservedDynamic; } /// @param sender The sender's address. /// @param contractAddressL2 The address of the contract on L2 to call. /// @param valueToMint The amount of base token that should be minted on L2 as the result of this transaction. /// @param l2Value The msg.value of the L2 transaction. /// @param l2Calldata The calldata for the L2 transaction. /// @param l2GasLimit The limit of the L2 gas for the L2 transaction /// @param l2GasPerPubdataByteLimit The price for a single pubdata byte in L2 gas. /// @param factoryDeps The array of L2 bytecodes that the tx depends on. /// @param refundRecipient The recipient of the refund for the transaction on L2. If the transaction fails, then /// this address will receive the `l2Value`. struct BridgehubL2TransactionRequest { address sender; address contractL2; uint256 mintValue; uint256 l2Value; bytes l2Calldata; uint256 l2GasLimit; uint256 l2GasPerPubdataByteLimit; bytes[] factoryDeps; address refundRecipient; }
{ "evmVersion": "shanghai", "optimizer": { "enabled": true, "runs": 200 }, "libraries": { "SophonFarmingL2.sol": {} }, "remappings": [ "@erc721a=./node_modules/erc721a/contracts", "@chainlink=./node_modules/@chainlink/contracts/src/v0.8", "@openzeppelin=./node_modules/@openzeppelin", "OpenZeppelin=C:/Users/tomcb/.brownie/packages/OpenZeppelin", "paulrberg=C:/Users/tomcb/.brownie/packages/paulrberg" ], "metadata": { "appendCBOR": false, "bytecodeHash": "none" }, "outputSelection": { "*": { "*": [ "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_MERKLE","type":"address"},{"internalType":"address","name":"_priceFeeds","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"BridgeInvalid","type":"error"},{"inputs":[],"name":"CountMismatch","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[],"name":"FarmingIsEnded","type":"error"},{"inputs":[],"name":"FarmingIsStarted","type":"error"},{"inputs":[],"name":"InvalidDeposit","type":"error"},{"inputs":[],"name":"InvalidEndBlock","type":"error"},{"inputs":[],"name":"InvalidPointsPerBlock","type":"error"},{"inputs":[],"name":"InvalidTransfer","type":"error"},{"inputs":[],"name":"NoEthSent","type":"error"},{"inputs":[{"internalType":"address","name":"lpToken","type":"address"}],"name":"NotFound","type":"error"},{"inputs":[],"name":"NothingInPool","type":"error"},{"inputs":[],"name":"OnlyMerkle","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"PoolDoesNotExist","type":"error"},{"inputs":[],"name":"PoolExists","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[],"name":"TransferNotAllowed","type":"error"},{"inputs":[{"internalType":"uint256","name":"maxAllowed","type":"uint256"}],"name":"TransferTooHigh","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"WithdrawIsZero","type":"error"},{"inputs":[],"name":"WithdrawNotAllowed","type":"error"},{"inputs":[{"internalType":"uint256","name":"maxAllowed","type":"uint256"}],"name":"WithdrawTooHigh","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"lpToken","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"allocPoint","type":"uint256"}],"name":"Add","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"depositAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"boostAmount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"boostAmount","type":"uint256"}],"name":"IncreaseBoost","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pool","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"LPDeployed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"currentValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newPrice","type":"uint256"}],"name":"PoolUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousImplementation","type":"address"},{"indexed":true,"internalType":"address","name":"newImplementation","type":"address"}],"name":"ReplaceImplementation","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousImplementation","type":"address"},{"indexed":true,"internalType":"address","name":"newImplementation","type":"address"}],"name":"ReplaceImplementationStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"lpToken","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"allocPoint","type":"uint256"}],"name":"Set","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"SetEmissionsMultiplier","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"SetPointsPerBlock","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TransferPoints","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawHeldProceeds","type":"event"},{"inputs":[],"name":"MERKLE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_WITHDRAWAL_BLOCKS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"lps","type":"address[]"}],"name":"_burnHeldLPs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"revoke","type":"bool"}],"name":"_setBoostApprovals","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_lpAdmin","type":"address"}],"name":"_setLPAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"acceptImplementation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_lpToken","type":"address"},{"internalType":"uint256","name":"_emissionsMultiplier","type":"uint256"},{"internalType":"string","name":"_description","type":"string"},{"internalType":"uint256","name":"_poolStartBlock","type":"uint256"},{"internalType":"uint256","name":"_newPointsPerBlock","type":"uint256"}],"name":"add","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address[]","name":"_receivers","type":"address[]"},{"internalType":"uint256[]","name":"_quantities","type":"uint256[]"}],"name":"batchAwardPoints","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract Upgradeable2Step","name":"proxy","type":"address"}],"name":"becomeImplementation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"boosterMultiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bridge","outputs":[{"internalType":"contract IBridgehub","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_boostAmount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"endBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"endBlockForWithdrawals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBlockNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"getMaxAdditionalBoost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_users","type":"address[]"}],"name":"getOptimizedUserInfo","outputs":[{"internalType":"uint256[4][][]","name":"userInfos","type":"uint256[4][][]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_users","type":"address[]"}],"name":"getPendingPoints","outputs":[{"internalType":"uint256[][]","name":"pendings","type":"uint256[][]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPoolInfo","outputs":[{"components":[{"internalType":"contract IERC20","name":"lpToken","type":"address"},{"internalType":"address","name":"l2Farm","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"boostAmount","type":"uint256"},{"internalType":"uint256","name":"depositAmount","type":"uint256"},{"internalType":"uint256","name":"allocPoint","type":"uint256"},{"internalType":"uint256","name":"lastRewardBlock","type":"uint256"},{"internalType":"uint256","name":"accPointsPerShare","type":"uint256"},{"internalType":"uint256","name":"totalRewards","type":"uint256"},{"internalType":"string","name":"description","type":"string"}],"internalType":"struct SophonFarmingState.PoolInfo[]","name":"poolInfos","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"heldProceedLPs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"heldProceeds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"isBridged","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isFarmingEnded","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isWithdrawPeriodEnded","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"massUpdatePools","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"pendingPoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pointsPerBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"poolExists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"poolInfo","outputs":[{"internalType":"contract IERC20","name":"lpToken","type":"address"},{"internalType":"address","name":"l2Farm","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"boostAmount","type":"uint256"},{"internalType":"uint256","name":"depositAmount","type":"uint256"},{"internalType":"uint256","name":"allocPoint","type":"uint256"},{"internalType":"uint256","name":"lastRewardBlock","type":"uint256"},{"internalType":"uint256","name":"accPointsPerShare","type":"uint256"},{"internalType":"uint256","name":"totalRewards","type":"uint256"},{"internalType":"string","name":"description","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"}],"name":"poolValue","outputs":[{"internalType":"uint256","name":"lastValue","type":"uint256"},{"internalType":"uint256","name":"emissionsMultiplier","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"priceFeeds","outputs":[{"internalType":"contract IPriceFeeds","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"impl_","type":"address"}],"name":"replaceImplementation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_emissionsMultiplier","type":"uint256"},{"internalType":"uint256","name":"_poolStartBlock","type":"uint256"},{"internalType":"uint256","name":"_newPointsPerBlock","type":"uint256"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_emissionsMultiplier","type":"uint256"}],"name":"setEmissionsMultiplier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_endBlock","type":"uint256"},{"internalType":"uint256","name":"_withdrawalBlocks","type":"uint256"}],"name":"setEndBlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pointsPerBlock","type":"uint256"}],"name":"setPointsPerBlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_userAdmin","type":"address"},{"internalType":"address[]","name":"_users","type":"address[]"},{"internalType":"bool","name":"_isInWhitelist","type":"bool"}],"name":"setUsersWhitelisted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pidA","type":"uint256"},{"internalType":"uint256","name":"pidB","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"submitLP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalAllocPoint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_sender","type":"address"},{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"uint256","name":"_transferAmount","type":"uint256"}],"name":"transferPoints","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum SophonFarmingState.PredefinedPool","name":"","type":"uint8"}],"name":"typeToId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_pid","type":"uint256"},{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"boostAmount","type":"uint256"},{"internalType":"uint256","name":"depositAmount","type":"uint256"},{"internalType":"uint256","name":"rewardSettled","type":"uint256"},{"internalType":"uint256","name":"rewardDebt","type":"uint256"}],"internalType":"struct SophonFarmingState.UserInfo","name":"_userFromClaim","type":"tuple"}],"name":"updateUserInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"userInfo","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"boostAmount","type":"uint256"},{"internalType":"uint256","name":"depositAmount","type":"uint256"},{"internalType":"uint256","name":"rewardSettled","type":"uint256"},{"internalType":"uint256","name":"rewardDebt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAdmin","type":"address"},{"internalType":"address","name":"user","type":"address"}],"name":"whitelist","outputs":[{"internalType":"bool","name":"inWhitelist","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_withdrawAmount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
9c4d535b0000000000000000000000000000000000000000000000000000000000000000010006eb43e2123b304fd5ebce505bfe746157dfb077e65a6c9ff6d7675117fa00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000040000000000000000000000000a24f69faa295426bca2cf610bf992cdc992ceea00000000000000000000000002edf18b640a705f16947a7b95fc338fde340dd48
Deployed Bytecode
0x000400000000000200160000000000020000006004100270000006340340019700030000003103550002000000010355000006340040019d0000000100200190000000f40000c13d0000008004000039000000400040043f000000040030008c0000011b0000413d000000000201043b000000e0022002700000063e0020009c0000011d0000213d000006640020009c000001470000a13d000006650020009c000001ad0000213d0000066f0020009c000002e20000a13d000006700020009c000004740000213d000006730020009c000008790000613d000006740020009c0000011b0000c13d000000240030008c0000011b0000413d0000000002000416000000000002004b0000011b0000c13d0000000401100370000000000201043b000000000002004b0000000001000039000000010100c039000000000012004b0000011b0000c13d000000000100041a00000637031001970000000001000411000000000013004b000009bd0000c13d0000000801000039000000000101041a000000000001004b000004a40000613d000000000002004b00000c6e0000c13d0000000003000019000000530000013d000000400200043d0000002001200039000006cc0300004100000000003104350000002401200039000006aa03000041000000000031043500000044010000390000000000120435000000440120003900000000000104350000068b0020009c00000bf90000213d0000008001200039000000400010043f00000000010b001918cd17ac0000040f0000000d010000290000000b0200002918cd17ac0000040f00000000010004150000000a0110006900000000010000020000000c0300002900000001033000390000000801000039000000000101041a000000000013004b000004a40000813d0000000801000039000000000010043f0000000a013000c9000006a70110009a000000000101041a00000637041001980000004e0000613d000000000030043f0000000501000039000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c70000801002000039000c00000003001d000d00000004001d18cd18c80000040f0000000d0b0000290000000c0300002900000001002001900000011b0000613d000000000101043b000000000101041a000000000001004b0000004e0000613d0000000002000415000a00000002001d000000400400043d000000440240003900000000001204350000002001400039000006cc0200004100000000002104350000002402400039000006aa03000041000000000032043500000044020000390000000000240435000b00000004001d0000068b0040009c00000bf90000213d0000000b030000290000008002300039000000400020043f000000000303043300000000020004140000000400b0008c000000880000c13d000000010400003100000001020000390000009b0000013d000006340010009c00000634010080410000004001100210000006340030009c00000634030080410000006003300210000000000113019f000006340020009c0000063402008041000000c002200210000000000121019f00000000020b001918cd18c30000040f0000000d0b000029000000010220018f00030000000103550000006001100270000106340010019d0000063404100197000000000004004b00000080010000390000006003000039000000c70000613d000006890040009c00000bf90000213d0000001f01400039000006e1011001970000003f01100039000006e101100197000000400300043d0000000001130019000000000031004b00000000050000390000000105004039000006890010009c00000bf90000213d000000010050019000000bf90000c13d000000400010043f0000000001430436000006e10640019800000000056100190000000307000367000000ba0000613d000000000807034f0000000009010019000000008a08043c0000000009a90436000000000059004b000000b60000c13d0000001f04400190000000c70000613d000000000667034f0000000304400210000000000705043300000000074701cf000000000747022f000000000606043b0000010004400089000000000646022f00000000044601cf000000000474019f0000000000450435000000000002004b000000360000613d0000000004000415000000140440008a00000005044002100000000002030433000000000002004b000000de0000613d000006cd0020009c0000011b0000213d000000200020008c0000011b0000413d0000000001010433000000000001004b0000000002000039000000010200c039000000000021004b0000011b0000c13d0000000004000415000000150440008a0000000504400210000000000001004b000000360000613d000900000004001d000006990100004100000000001004430000000400b004430000000001000414000006340010009c0000063401008041000000c0011002100000069a011001c7000080020200003918cd18c80000040f0000000100200190000012260000613d000000000101043b000000000001004b00000009010000290000000501100270000000000100003f000000010100c03f0000000d0b0000290000004a0000c13d000000360000013d0000000002000416000000000002004b0000011b0000c13d0000001f023000390000063502200197000000c002200039000000400020043f0000001f0430018f0000063605300198000000c002500039000001050000613d000000c006000039000000000701034f000000007807043c0000000006860436000000000026004b000001010000c13d000000000004004b000001120000613d000000000151034f0000000304400210000000000502043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f0000000000120435000000400030008c0000011b0000413d000000c00100043d000006370010009c0000011b0000213d000000e00200043d000d00000002001d000006370020009c000001e50000a13d0000000001000019000018cf000104300000063f0020009c000001900000a13d000006400020009c000001c10000213d0000064a0020009c000002f40000a13d0000064b0020009c0000047d0000213d0000064e0020009c0000088d0000613d0000064f0020009c0000011b0000c13d000000240030008c0000011b0000413d0000000002000416000000000002004b0000011b0000c13d0000000401100370000000000601043b000006370060009c0000011b0000213d000000000100041a00000637021001970000000001000411000000000012004b000009bd0000c13d0000000201000039000000000201041a0000063802200197000000000262019f000000000021041b0000000303000039000000000103041a00000000020004140000063705100197000006340020009c0000063402008041000000c00120021000000639011001c70000800d02000039000006b104000041000004a10000013d000006780020009c000001ed0000a13d000006790020009c0000023a0000a13d0000067a0020009c000003230000213d0000067d0020009c000006500000613d0000067e0020009c0000011b0000c13d000000440030008c0000011b0000413d0000000002000416000000000002004b0000011b0000c13d000000000200041a00000637032001970000000002000411000000000023004b000009d30000c13d0000002402100370000000000202043b000d00000002001d0000000401100370000000000101043b000c00000001001d18cd14f10000040f0000000c01000029000000000010043f0000001201000039000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f0000000d0000006b0000000d030000290000068e03006041000d00000003001d00000001002001900000011b0000613d000000000101043b0000000101100039000c00000001001d000000000101041a000000400200043d00000020032000390000000d0400002900000000004304350000000000120435000006340020009c000006340200804100000040012002100000000002000414000006340020009c0000063402008041000000c002200210000000000112019f0000068d011001c70000800d020000390000000103000039000006d20400004118cd18c30000040f00000001002001900000011b0000613d0000000d010000290000000c02000029000000000012041b0000000001000019000018ce0001042e000006530020009c000001fa0000a13d000006540020009c0000024c0000a13d000006550020009c0000032c0000213d000006580020009c000006880000613d000006590020009c0000011b0000c13d000000240030008c0000011b0000413d0000000002000416000000000002004b0000011b0000c13d0000000401100370000000000101043b000000000010043f0000001201000039000000200010043f000000400100003918cd18940000040f0000000102100039000000000202041a000000000101041a000000800010043f000000a00020043f000006b801000041000018ce0001042e000006660020009c0000030c0000a13d000006670020009c000004860000213d0000066a0020009c000008920000613d0000066b0020009c0000011b0000c13d000000440030008c0000011b0000413d0000000002000416000000000002004b0000011b0000c13d0000000401100370000000000101043b000006370010009c0000011b0000213d000000800000043f0000069c01000041000018ce0001042e000006410020009c000003180000a13d000006420020009c000004a60000213d000006450020009c000008fb0000613d000006460020009c0000011b0000c13d000000240030008c0000011b0000413d0000000002000416000000000002004b0000011b0000c13d0000000401100370000000000601043b000006370060009c0000011b0000213d000000000100041a00000637011001970000000005000411000000000051004b000009ce0000c13d0000000101000039000000000201041a0000063802200197000000000262019f000000000021041b0000000001000414000006340010009c0000063401008041000000c00110021000000639011001c70000800d0200003900000003030000390000069404000041000004a10000013d0000000006000411000000000006004b0000021b0000c13d0000063c01000041000000000010043f000000040000043f0000063d01000041000018cf00010430000006820020009c000002ae0000213d000006860020009c000006b20000613d000006870020009c000005460000613d000006880020009c0000011b0000c13d0000000001000416000000000001004b0000011b0000c13d0000000b01000039000009890000013d0000065d0020009c000002d70000213d000006610020009c000006e10000613d000006620020009c0000054b0000613d000006630020009c0000011b0000c13d0000000001000416000000000001004b0000011b0000c13d0000000101000039000000000201041a00000637032001970000000006000411000000000063004b00000b240000c13d0000063802200197000000000021041b000000000100041a0000063802100197000000000262019f000000000020041b00000000020004140000063705100197000006340020009c0000063402008041000000c00120021000000639011001c70000800d0200003900000003030000390000063a04000041000004a10000013d000c00000001001d0000000101000039000000000201041a0000063802200197000000000021041b000000000100041a0000063802100197000000000262019f000000000020041b00000000020004140000063705100197000006340020009c0000063402008041000000c00120021000000639011001c70000800d0200003900000003030000390000063a0400004118cd18c30000040f0000000c0100002900000001002001900000011b0000613d000000000001004b000002360000613d000000800010043f0000000d0000006b000009c20000c13d000006b701000041000000000010043f0000069801000041000018cf000104300000067f0020009c000005f50000613d000006800020009c000004fb0000613d000006810020009c0000011b0000c13d000000240030008c0000011b0000413d0000000002000416000000000002004b0000011b0000c13d0000000401100370000000000101043b000006370010009c0000011b0000213d000000000010043f0000000d01000039000006030000013d0000065a0020009c000005fa0000613d0000065b0020009c0000051b0000613d0000065c0020009c0000011b0000c13d000000240030008c0000011b0000413d0000000002000416000000000002004b0000011b0000c13d0000000402100370000000000202043b000006890020009c0000011b0000213d0000002304200039000000000034004b0000011b0000813d0000000404200039000000000441034f000000000504043b000006890050009c00000bf90000213d00000005045002100000003f064000390000068a066001970000068b0060009c00000bf90000213d0000008006600039000900000006001d000000400060043f000000800050043f00000024022000390000000004240019000000000034004b0000011b0000213d000000000005004b000000000300001900000dfb0000c13d000400000003001d00000005013002100000003f021000390000068c03200197000000090c0000290000000002c30019000000000032004b00000000030000390000000103004039000006890020009c00000bf90000213d000000010030019000000bf90000c13d000000400020043f000000040200002900000000032c0436000300000003001d000000000002004b00000f120000c13d000000400100043d0000002002000039000000000221043600000000030c04330000000000320435000000400410003900000005023002100000000002420019000000000003004b000004e80000613d0000000005000019000000090d000029000002960000013d0000000105500039000000000035004b000004e80000813d0000000006120049000000400660008a0000000004640436000000200dd0003900000000060d043300000000070604330000000002720436000000000007004b000002930000613d000000000800001900000020066000390000000009060433000000000a000019000000000b020019000000009c090434000000000bcb04360000000300a0008c000000010aa00039000002a40000413d00000080022000390000000108800039000000000078004b000002a00000413d000002930000013d000006830020009c0000078e0000613d000006840020009c000005560000613d000006850020009c0000011b0000c13d0000000001000416000000000001004b0000011b0000c13d0000000201000039000000000201041a00000637012001970000000006000411000000000016004b00000b240000c13d000d00000002001d0000000303000039000000000103041a00000000020004140000063705100197000006340020009c0000063402008041000000c00120021000000639011001c70000800d02000039000006da0400004118cd18c30000040f00000001002001900000011b0000613d0000000d0100002900000638011001970000000202000039000000000012041b0000000303000039000000000103041a00000638011001970000000002000411000000000121019f000000000013041b0000000001000019000018ce0001042e0000065e0020009c0000079c0000613d0000065f0020009c000005730000613d000006600020009c0000011b0000c13d0000000001000416000000000001004b0000011b0000c13d000000000100041a000006950000013d000006750020009c000007a90000613d000006760020009c0000060d0000613d000006770020009c0000011b0000c13d000000240030008c0000011b0000413d0000000002000416000000000002004b0000011b0000c13d0000000401100370000000000101043b000006370010009c0000011b0000213d000000000010043f0000001501000039000007a50000013d000006500020009c000007ae0000613d000006510020009c0000061a0000613d000006520020009c0000011b0000c13d000000240030008c0000011b0000413d0000000002000416000000000002004b0000011b0000c13d0000000401100370000000000101043b000d00000001001d000006370010009c0000011b0000213d18cd16e40000040f0000001401000039000000000201041a00000638022001970000000d022001af000000000021041b0000000001000019000018ce0001042e0000066c0020009c000007c60000613d0000066d0020009c0000061f0000613d0000066e0020009c0000011b0000c13d0000000001000416000000000001004b0000011b0000c13d18cd14f10000040f0000000001000019000018ce0001042e000006470020009c000007e50000613d000006480020009c0000064a0000613d000006490020009c0000011b0000c13d0000000001000416000000000001004b0000011b0000c13d0000000f010000390000064e0000013d0000067b0020009c000006990000613d0000067c0020009c0000011b0000c13d0000000001000416000000000001004b0000011b0000c13d00000002010000390000064e0000013d000006560020009c000006a50000613d000006570020009c0000011b0000c13d000000a40030008c0000011b0000413d0000000002000416000000000002004b0000011b0000c13d0000000402100370000000000202043b000d00000002001d000006370020009c0000011b0000213d0000002402100370000000000202043b000c00000002001d0000004402100370000000000402043b000006890040009c0000011b0000213d0000002302400039000000000032004b0000011b0000813d0000000405400039000000000251034f000000000202043b000006890020009c00000bf90000213d0000001f06200039000006e1066001970000003f06600039000006e1066001970000068b0060009c00000bf90000213d00000024044000390000008006600039000000400060043f000000800020043f0000000004420019000000000034004b0000011b0000213d0000002003500039000000000431034f000006e1052001980000001f0620018f000000a003500039000003620000613d000000a007000039000000000804034f000000008908043c0000000007970436000000000037004b0000035e0000c13d000000000006004b0000036f0000613d000000000454034f0000000305600210000000000603043300000000065601cf000000000656022f000000000404043b0000010005500089000000000454022f00000000045401cf000000000464019f0000000000430435000000a00220003900000000000204350000008402100370000000000202043b000b00000002001d0000006401100370000000000101043b000a00000001001d000000000100041a00000637011001970000000002000411000000000021004b000012050000c13d0000000d0000006b000002360000613d0000000d01000029000000000010043f0000000d01000039000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f00000001002001900000011b0000613d000000000101043b000000000101041a000000ff00100190000011c80000c13d0000000b01000039000000000101041a000900000001001d000000000001004b000003a20000613d000006900100004100000000001004430000000001000414000006340010009c0000063401008041000000c00110021000000691011001c70000800b0200003918cd18c80000040f0000000100200190000012260000613d000000000101043b000000090010006c00000af90000213d0000000b0000006b000011dc0000c13d18cd14f10000040f000006900100004100000000001004430000000001000414000006340010009c0000063401008041000000c00110021000000691011001c70000800b0200003918cd18c80000040f0000000100200190000012260000613d000000000101043b000b00000001001d0000000d01000029000000000010043f0000000d01000039000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f0000000b060000290000000a0060006c0000000a0600a02900000001002001900000011b0000613d000000000101043b000000000201041a000006e20220019700000001022001bf000000000021041b000000400100043d000b00000001001d000006b50010009c00000bf90000213d0000000801000039000000000301041a0000000b050000290000014002500039000000400020043f00000120045000390000008002000039000900000004001d0000000000240435000000c002500039000700000002001d00000000006204350000000d0200002900000000042504360000010002500039000800000002001d0000000000020435000000e002500039000600000002001d0000000000020435000000a002500039000500000002001d00000000000204350000008002500039000400000002001d00000000000204350000006002500039000200000002001d00000000000204350000004002500039000100000002001d0000000000020435000300000004001d0000000000040435000a00000003001d000006890030009c00000bf90000213d0000000a020000290000000102200039000000000021041b000000000010043f0000000001000414000006340010009c0000063401008041000000c001100210000006ad011001c7000080100200003918cd18c80000040f00000001002001900000011b0000613d0000000a020000290000000a022000c9000000000101043b0000000001210019000000000201041a00000638022001970000000b0300002900000000030304330000063703300197000000000232019f000000000021041b0000000102100039000000000302041a0000063803300197000000030400002900000000040404330000063704400197000000000343019f000000000032041b000000010200002900000000020204330000000203100039000000000023041b000000020200002900000000020204330000000303100039000000000023041b000000040200002900000000020204330000000403100039000000000023041b000000050200002900000000020204330000000503100039000000000023041b000000070200002900000000020204330000000603100039000000000023041b000000060200002900000000020204330000000703100039000000000023041b000000080200002900000000020204330000000803100039000000000023041b00000009020000290000000002020433000800000002001d0000000032020434000900000003001d000b00000002001d000006890020009c00000bf90000213d0000000901100039000700000001001d000000000101041a000000010010019000000001021002700000007f0220618f000600000002001d0000001f0020008c00000000020000390000000102002039000000000121013f00000001001001900000056d0000c13d0000000601000029000000200010008c000004600000413d0000000701000029000000000010043f0000000001000414000006340010009c0000063401008041000000c001100210000006ad011001c7000080100200003918cd18c80000040f00000001002001900000011b0000613d0000000b030000290000001f023000390000000502200270000000200030008c0000000002004019000000000301043b00000006010000290000001f01100039000000050110027000000000011300190000000002230019000000000012004b000004600000813d000000000002041b0000000102200039000000000012004b0000045c0000413d0000000b01000029000000200010008c000013590000413d0000000701000029000000000010043f0000000001000414000006340010009c0000063401008041000000c001100210000006ad011001c7000080100200003918cd18c80000040f00000001002001900000011b0000613d000000200200008a0000000b02200180000000000101043b000013660000c13d0000002003000039000013730000013d000006710020009c000009100000613d000006720020009c0000011b0000c13d0000000001000416000000000001004b0000011b0000c13d00000003010000390000064e0000013d0000064c0020009c000009170000613d0000064d0020009c0000011b0000c13d0000000001000416000000000001004b0000011b0000c13d18cd16ca0000040f000007920000013d000006680020009c000009850000613d000006690020009c0000011b0000c13d0000000001000416000000000001004b0000011b0000c13d000000000100041a00000637021001970000000005000411000000000052004b000009ce0000c13d0000000102000039000000000302041a0000063803300197000000000032041b0000063801100197000000000010041b0000000001000414000006340010009c0000063401008041000000c00110021000000639011001c70000800d0200003900000003030000390000063a04000041000000000600001918cd18c30000040f00000001002001900000011b0000613d0000000001000019000018ce0001042e000006430020009c0000098d0000613d000006440020009c0000011b0000c13d000000240030008c0000011b0000413d0000000002000416000000000002004b0000011b0000c13d0000000402100370000000000202043b000006890020009c0000011b0000213d0000002305200039000000000035004b0000011b0000813d0000000405200039000000000551034f000000000605043b000006890060009c00000bf90000213d00000005056002100000003f075000390000068a077001970000068b0070009c00000bf90000213d0000008007700039000700000007001d000000400070043f000000800060043f00000024022000390000000005250019000000000035004b0000011b0000213d000000000006004b0000000003000019000004ea0000c13d000500000003001d00000005013002100000003f021000390000068c0320019700000007080000290000000002830019000000000032004b00000000030000390000000103004039000006890020009c00000bf90000213d000000010030019000000bf90000c13d000000400020043f00000005020000290000000003280436000400000003001d000000000002004b00000ffe0000c13d000000400100043d0000002002000039000000000221043600000000030804330000000000320435000000400410003900000005023002100000000002420019000000000003004b000010f90000c13d000000000212004900000bd00000013d000000000321034f000000000303043b000006370030009c0000011b0000213d000000200440003900000000003404350000002002200039000000000052004b000004ea0000413d000000800100043d000006890010009c00000bf90000213d0000000002010019000000400100043d000700000001001d0000000003020019000004cb0000013d000000440030008c0000011b0000413d0000000002000416000000000002004b0000011b0000c13d0000002402100370000000000402043b0000000401100370000000000301043b000000000100041a00000637021001970000000001000411000000000012004b000009bd0000c13d0000000b01000039000000000101041a000000000001004b000d00000003001d00000a220000c13d000000000003004b000000000100001900000afd0000c13d000c00000001001d18cd14f10000040f0000000b010000390000000d02000029000000000021041b0000000e010000390000000c02000029000000000021041b0000000001000019000018ce0001042e000000440030008c0000011b0000413d0000000002000416000000000002004b0000011b0000c13d0000002402100370000000000202043b000d00000002001d000006370020009c0000011b0000213d0000000401100370000000000101043b000000000010043f0000000901000039000000200010043f000000400100003918cd18940000040f0000000d0200002918cd14c70000040f0000000102100039000000000202041a0000000203100039000000000303041a0000000304100039000000000404041a000000000501041a0000000401100039000000000101041a000000400600043d000000800760003900000000001704350000006001600039000000000041043500000040016000390000000000310435000000200160003900000000002104350000000000560435000006340060009c00000634060080410000004001600210000006ba011001c7000018ce0001042e0000000001000416000000000001004b0000011b0000c13d0000000801000039000009890000013d0000000001000416000000000001004b0000011b0000c13d0000000001000412001100000001001d001000200000003d000080050100003900000044030000390000000004000415000000110440008a000006920000013d000000240030008c0000011b0000413d0000000002000416000000000002004b0000011b0000c13d0000000401100370000000000101043b0000000802000039000000000302041a000000000031004b0000011b0000813d000000000020043f0000000a041000c9000006ca0140009a000000000201041a000000010320019000000001062002700000007f0660618f0000001f0060008c00000000050000390000000105002039000000000053004b00000a350000613d000006dc01000041000000000010043f0000002201000039000000040010043f0000063d01000041000018cf00010430000000640030008c0000011b0000413d0000000002000416000000000002004b0000011b0000c13d0000000402100370000000000202043b000a00000002001d0000002402100370000000000202043b000006890020009c0000011b0000213d0000002304200039000000000034004b0000011b0000813d0000000404200039000000000441034f000000000504043b000006890050009c00000bf90000213d00000005045002100000003f064000390000068a066001970000068b0060009c00000bf90000213d0000008006600039000000400060043f000000800050043f00000024022000390000000004240019000000000034004b0000011b0000213d000000000005004b0000059f0000613d0000008005000039000000000621034f000000000606043b000006370060009c0000011b0000213d000000200550003900000000006504350000002002200039000000000042004b000005960000413d0000004402100370000000000202043b000006890020009c0000011b0000213d0000002304200039000000000034004b0000000005000019000006bb05008041000006bb04400197000000000004004b0000000006000019000006bb06004041000006bb0040009c000000000605c019000000000006004b0000011b0000c13d0000000404200039000000000441034f000000000404043b000006890040009c00000bf90000213d00000005054002100000003f065000390000068a06600197000000400700043d0000000006670019000900000007001d000000000076004b00000000070000390000000107004039000006890060009c00000bf90000213d000000010070019000000bf90000c13d000000400060043f00000009060000290000000006460436000800000006001d00000024022000390000000005250019000000000035004b0000011b0000213d000000000004004b000005d20000613d0000000803000029000000000421034f000000000404043b00000000034304360000002002200039000000000052004b000005cc0000413d000000000100041a00000637021001970000000001000411000000000012004b000009bd0000c13d00000009010000290000000002010433000000800100043d000000000021004b000011d80000c13d0000000802000039000000000302041a0000000a0030006c0000100e0000a13d000000000020043f0000000a020000290000000a022000c9000700000002001d000006a70220009a000000000202041a0000063700200198000006460000613d000000000001004b000c00000000001d000012330000c13d0000000701000029000006bd0110009a000000000201041a0000000c03000029000000000032001a000012a70000413d0000000002320019000000000021041b0000000001000019000018ce0001042e0000000001000416000000000001004b0000011b0000c13d0000000a01000039000009890000013d000000240030008c0000011b0000413d0000000002000416000000000002004b0000011b0000c13d0000000401100370000000000101043b000000000010043f0000001001000039000000200010043f000000400100003918cd18940000040f000000000101041a000000ff001001900000000001000039000000010100c039000000800010043f0000069c01000041000018ce0001042e0000000001000416000000000001004b0000011b0000c13d0000800b0100003900000004030000390000000004000415000000160440008a0000000504400210000006900200004118cd18a50000040f000000800010043f0000069c01000041000018ce0001042e0000000001000416000000000001004b0000011b0000c13d0000000e01000039000009890000013d000000840030008c0000011b0000413d0000000002000416000000000002004b0000011b0000c13d0000006402100370000000000502043b0000004402100370000000000302043b0000002402100370000000000402043b0000000401100370000000000201043b000000000100041a00000637011001970000000006000411000000000061004b00000b240000c13d0000000b07000039000000000107041a000000000001004b000d00000002001d000a00000003001d000c00000004001d00000a640000c13d000000000005004b00000b140000c13d18cd14f10000040f0000000801000039000000000101041a0000000d0010006c0000100e0000a13d0000000d010000290000000a011000c9000b00000001001d000006a70110009a000000000101041a000006370110019800000d200000c13d000006d501000041000000000010043f0000069801000041000018cf000104300000000001000416000000000001004b0000011b0000c13d0000000101000039000000000101041a000006950000013d000000840030008c0000011b0000413d0000000002000416000000000002004b0000011b0000c13d0000000402100370000000000202043b000c00000002001d0000002402100370000000000202043b000d00000002001d000006370020009c0000011b0000213d0000004402100370000000000202043b000b00000002001d000006370020009c0000011b0000213d0000006401100370000000000101043b000a00000001001d00000000010004110000063701100197000000000010043f0000001101000039000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f00000001002001900000011b0000613d000000000101043b0000000d02000029000000000020043f000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f00000001002001900000011b0000613d000000000101043b000000000101041a000000ff0010019000000e170000c13d000006d701000041000000000010043f0000069801000041000018cf000104300000000001000416000000000001004b0000011b0000c13d0000000001000412000f00000001001d000e00000000003d0000800501000039000000440300003900000000040004150000000f0440008a00000005044002100000069d0200004118cd18a50000040f0000063701100197000000800010043f0000069c01000041000018ce0001042e000000240030008c0000011b0000413d0000000002000416000000000002004b0000011b0000c13d0000000401100370000000000101043b000000020010008c0000011b0000213d000000000010043f0000000401000039000007a50000013d000000440030008c0000011b0000413d0000000002000416000000000002004b0000011b0000c13d0000002402100370000000000202043b000006370020009c0000011b0000213d0000000401100370000000000101043b18cd17700000040f000007950000013d000000640030008c0000011b0000413d0000000002000416000000000002004b0000011b0000c13d0000002402100370000000000202043b000d00000002001d0000000401100370000000000201043b0000000801000039000000000101041a000c00000002001d000000000021004b0000100e0000a13d0000000801000039000000000010043f0000000c010000290000000a011000c9000b00000001001d000006a70110009a000000000101041a000006dd02000041000000a00020043f0000000002000411000000a40020043f0000000002000410000000c40020043f0000000d02000029000000e40020043f0000006402000039000000800020043f0000012002000039000000400020043f0000063701100197000000800200003918cd17ac0000040f0000000b01000039000000000101041a000000000001004b00000a780000c13d0000000d0000006b00000b290000c13d000006e001000041000000000010043f0000069801000041000018cf00010430000000240030008c0000011b0000413d0000000002000416000000000002004b0000011b0000c13d0000000402100370000000000202043b000006890020009c0000011b0000213d0000002304200039000000000034004b0000011b0000813d0000000404200039000000000441034f000000000504043b000006890050009c00000bf90000213d00000005045002100000003f064000390000068a066001970000068b0060009c00000bf90000213d0000008006600039000000400060043f000000800050043f00000024022000390000000004240019000000000034004b0000011b0000213d000000000005004b0000070a0000613d0000008003000039000000000521034f000000000505043b000006370050009c0000011b0000213d000000200330003900000000005304350000002002200039000000000042004b000007010000413d000000000100041a00000637021001970000000001000411000000000012004b000009bd0000c13d000000800100043d000000000001004b000004a40000613d000d00000000001d000007190000013d0000000d02000029000d00010020003d000000800100043d0000000d0010006b000004a40000813d0000000d010000290000000501100210000000a00110003900000000010104330000063701100197000c00000001001d000000000010043f0000001501000039000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f00000001002001900000011b0000613d000000000101043b000000000101041a000000000001004b000007140000613d000000400a00043d0000002402a000390000000000120435000006be0100004100000000001a04350000000401a000390000dead02000039000000000021043500000000010004140000000c02000029000000040020008c000007400000c13d0000000103000031000000200030008c000000200400003900000000040340190000076b0000013d0000063400a0009c000006340300004100000000030a40190000004003300210000006340010009c0000063401008041000000c001100210000000000131019f000006bf011001c7000b0000000a001d18cd18c30000040f0000000b0a00002900000060031002700000063403300197000000200030008c00000020040000390000000004034019000000200640019000000000056a00190000075a0000613d000000000701034f00000000080a0019000000007907043c0000000008980436000000000058004b000007560000c13d0000001f07400190000007670000613d000000000661034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000011cc0000613d0000001f01400039000000600210018f0000000001a20019000000000021004b00000000020000390000000102004039000006890010009c00000bf90000213d000000010020019000000bf90000c13d000000400010043f000000200030008c0000011b0000413d00000000010a0433000000000001004b0000000002000039000000010200c039000000000021004b0000011b0000c13d0000000c01000029000000000010043f0000001501000039000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f00000001002001900000011b0000613d000000000101043b000000000001041b000007140000013d0000000001000416000000000001004b0000011b0000c13d18cd14d70000040f000000000001004b0000000001000039000000010100c039000000400200043d0000000000120435000006340020009c00000634020080410000004001200210000006a5011001c7000018ce0001042e000000240030008c0000011b0000413d0000000002000416000000000002004b0000011b0000c13d0000000401100370000000000101043b000000000010043f0000000501000039000000200010043f000000400100003918cd18940000040f000009890000013d0000000001000416000000000001004b0000011b0000c13d0000000701000039000009890000013d000000440030008c0000011b0000413d0000000002000416000000000002004b0000011b0000c13d0000000402100370000000000202043b000006370020009c0000011b0000213d0000002401100370000000000101043b000d00000001001d000006370010009c0000011b0000213d000000000020043f0000001101000039000000200010043f000000400100003918cd18940000040f0000000d0200002918cd14c70000040f000000000101041a000000ff00100190000007930000013d0000000001000416000000000001004b0000011b0000c13d0000000801000039000000000101041a000b00000001001d000006890010009c00000bf90000213d0000000b0100002900000005021002100000003f012000390000068a031001970000068b0030009c00000bf90000213d0000008001300039000000400010043f0000000b04000029000000800040043f000000000004004b00000bd80000c13d00000020020000390000000003210436000000800200043d0000000000230435000000400310003900000005042002100000000008340019000000000002004b00000c210000c13d000000000218004900000bd00000013d000000e40030008c0000011b0000413d0000000002000416000000000002004b0000011b0000c13d0000000402100370000000000202043b000d00000002001d000006370020009c0000011b0000213d0000002402100370000000000202043b000c00000002001d0000012002000039000000400020043f0000004402100370000000000202043b000000800020043f0000006402100370000000000202043b000000a00020043f0000008402100370000000000202043b000000c00020043f000000a402100370000000000202043b000000e00020043f000000c401100370000000000101043b000001000010043f0000069d0100004100000000001004430000000001000412000000040010044300000024000004430000000001000414000006340010009c0000063401008041000000c0011002100000069e011001c7000080050200003918cd18c80000040f0000000100200190000012260000613d000000000101043b00000637011001970000000002000411000000000012004b00000bff0000c13d0000000801000039000000000101041a0000000c0010006c00000c670000a13d000000a00100043d000000c00200043d000000000012001a000012a70000413d0000000001120019000000800200043d000000000012004b00000e1e0000c13d18cd14f10000040f0000000c01000029000000000010043f0000000901000039000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f00000001002001900000011b0000613d000000000101043b0000000d02000029000000000020043f000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f00000001002001900000011b0000613d000000000101043b0000000802000039000000000202041a0000000c0020006c0000100e0000a13d0000000802000039000000000020043f000000000201041a000000800300043d000000000023001a000012a70000413d000000000223001a0000000c030000290000000a033000c9000006a40330009a000000000303041a000000000021041b00000000043200a9000008530000613d00000000052400d9000000000035004b000012a70000c13d0000068e0540012a0000000307100039000000000607041a000000000056001a000012a70000413d00000000085600190000000406100039000000000906041a000000000898004b000012a70000413d000000000087041b000000e00900043d000000000089001a000012a70000413d0000000008890019000000000087041b0000000107100039000000000807041a000000a00900043d000000000089001a000012a70000413d0000000008890019000000000087041b0000000201100039000000000701041a000000c00800043d000000000078001a000012a70000413d0000000007780019000000000071041b000000000002004b000008760000613d00000000012400d9000000000031004b000012a70000c13d000000000056041b0000000001000019000018ce0001042e000000440030008c0000011b0000413d0000000002000416000000000002004b0000011b0000c13d0000002402100370000000000202043b0000000401100370000000000101043b000d00000001001d0000000e01000039000000000101041a000000000001004b000009d80000c13d000000000002004b000009ed0000c13d000006d101000041000000000010043f0000069801000041000018cf000104300000000001000416000000000001004b0000011b0000c13d0000001301000039000009890000013d000000640030008c0000011b0000413d0000000002000416000000000002004b0000011b0000c13d0000000402100370000000000202043b000006370020009c0000011b0000213d0000002404100370000000000404043b000006890040009c0000011b0000213d0000002305400039000000000035004b0000011b0000813d0000000405400039000000000551034f000000000605043b000006890060009c00000bf90000213d00000005056002100000003f075000390000068a077001970000068b0070009c00000bf90000213d0000008007700039000000400070043f000000800060043f00000024044000390000000005450019000000000035004b0000011b0000213d000000000006004b000008bf0000613d0000008003000039000000000641034f000000000606043b000006370060009c0000011b0000213d000000200330003900000000006304350000002004400039000000000054004b000008b60000413d0000004401100370000000000301043b000000000003004b0000000001000039000000010100c039000c00000003001d000000000013004b0000011b0000c13d000000000100041a00000637031001970000000001000411000000000013004b000009bd0000c13d0000063701200197000000000010043f0000001101000039000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f00000001002001900000011b0000613d000000000101043b000b00000001001d000000800100043d000000000001004b000004a40000613d0000000004000019000d00000004001d0000000501400210000000a00110003900000000010104330000063701100197000000000010043f0000000b01000029000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f0000000d0400002900000001002001900000011b0000613d000000000101043b000000000201041a000006e2022001970000000c022001af000000000021041b0000000104400039000000800100043d000000000014004b000008df0000413d000004a40000013d000000240030008c0000011b0000413d0000000002000416000000000002004b0000011b0000c13d0000000401100370000000000101043b000d00000001001d000006370010009c0000011b0000213d0000069501000041000000800010043f00000000010004140000000d02000029000000040020008c00000a880000c13d0000000103000031000000200030008c0000002004000039000000000403401900000aad0000013d0000000001000416000000000001004b0000011b0000c13d000006cb01000041000000800010043f0000069c01000041000018ce0001042e000000640030008c0000011b0000413d0000000002000416000000000002004b0000011b0000c13d0000002402100370000000000202043b000c00000002001d0000000402100370000000000202043b000d00000002001d0000004402100370000000000402043b000006890040009c0000011b0000213d0000002302400039000000000032004b0000011b0000813d0000000405400039000000000251034f000000000202043b000006890020009c00000bf90000213d0000001f07200039000006e1077001970000003f07700039000006e1077001970000068b0070009c00000bf90000213d00000024044000390000008007700039000000400070043f000000800020043f0000000004420019000000000034004b0000011b0000213d0000002003500039000000000331034f000006e1042001980000001f0520018f000000a001400039000009470000613d000000a006000039000000000703034f000000007807043c0000000006860436000000000016004b000009430000c13d000000000005004b000009540000613d000000000343034f0000000304500210000000000501043300000000054501cf000000000545022f000000000303043b0000010004400089000000000343022f00000000034301cf000000000353019f0000000000310435000000a00120003900000000000104350000001401000039000000000101041a00000637021001970000000001000411000000000021004b000009600000613d000000000200041a0000063702200197000000000021004b00000f010000c13d0000000801000039000000000201041a0000000d0020006c0000100e0000a13d0000000c0020006c0000100e0000a13d000000a40200043d0000000d030000290000000a033000c9000006a70330009a000000000303041a000700000003001d000000000010043f0000000c010000290000000a011000c9000006a70110009a000000000101041a000600000001001d000000400400043d000006a801000041000000000014043500000000010004100000063703100197000b00000004001d0000000401400039000800000003001d000000000031043500000000010004140000063702200197000900000002001d000000040020008c000010140000c13d0000000103000031000000200030008c000000200400003900000000040340190000103f0000013d0000000001000416000000000001004b0000011b0000c13d0000000601000039000000000101041a000000800010043f0000069c01000041000018ce0001042e000000240030008c0000011b0000413d0000000002000416000000000002004b0000011b0000c13d0000000401100370000000000301043b000000000100041a00000637021001970000000001000411000000000012004b000009bd0000c13d0000000b01000039000000000101041a000000000001004b00000ae80000c13d0000068e0130009a000006920010009c00000b200000213d000d00000003001d18cd14f10000040f0000000701000039000000000101041a000000400200043d00000020032000390000000d0400002900000000004304350000000000120435000006340020009c000006340200804100000040012002100000000002000414000006340020009c0000063402008041000000c002200210000000000112019f0000068d011001c70000800d020000390000000103000039000006930400004118cd18c30000040f00000001002001900000011b0000613d0000000d010000290000000702000039000000000012041b0000000001000019000018ce0001042e0000068f02000041000000000020043f000000040010043f0000063d01000041000018cf000104300000000d02000029000000a00020043f0000014000000443000001600010044300000020010000390000018000100443000001a0002004430000010000100443000000020100003900000120001004430000063b01000041000018ce0001042e0000068f01000041000000000010043f000000040050043f0000063d01000041000018cf000104300000068f01000041000000000010043f000000040020043f0000063d01000041000018cf00010430000b00000001001d000c00000002001d000006900100004100000000001004430000000001000414000006340010009c0000063401008041000000c00110021000000691011001c70000800b0200003918cd18c80000040f0000000100200190000012260000613d000000000101043b0000000b0010006c0000000c02000029000008870000a13d000006ce01000041000000000010043f0000069801000041000018cf00010430000c00000002001d18cd14f10000040f0000000801000039000000000101041a0000000d0010006c0000100e0000a13d0000000d01000029000000000010043f0000000901000039000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f00000001002001900000011b0000613d000000000101043b00000000020004110000063702200197000b00000002001d000000000020043f000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f00000001002001900000011b0000613d000000000101043b0000000204100039000000000304041a000000010200008a0000000c0020006b0000000c020000290000000008000019000000000503001900000e250000613d000000000032004b00000000080000390000000108002039000000000502001900000e250000a13d000006cf01000041000000000010043f000000040030043f0000063d01000041000018cf00010430000b00000001001d000c00000004001d000006900100004100000000001004430000000001000414000006340010009c0000063401008041000000c00110021000000691011001c70000800b0200003918cd18c80000040f0000000100200190000012260000613d000000000101043b0000000b0010006c0000000d030000290000000c040000290000050e0000a13d00000af90000013d000006bd0540009a000000000505041a000700000005001d000006a40540009a000000000505041a000800000005001d000006c20540009a000000000505041a000900000005001d000006c90540009a000000000505041a000a00000005001d000006c80540009a000000000505041a000b00000005001d000006c70540009a000000000505041a000c00000005001d000006c60540009a000000000505041a000d00000005001d000006c50540009a000000000505041a000600000005001d000006a70440009a000000000404041a000500000004001d000000800060043f000000000003004b00000b930000613d000400000006001d000000000010043f0000000001000414000006340010009c0000063401008041000000c001100210000006ad011001c7000080100200003918cd18c80000040f00000001002001900000011b0000613d0000000405000029000000000005004b00000e0d0000c13d0000002002000039000000a00100003900000b9d0000013d000900000001001d000b00000005001d000006900100004100000000001004430000000001000414000006340010009c0000063401008041000000c00110021000000691011001c70000800b0200003918cd18c80000040f0000000100200190000012260000613d000000000101043b000000090010006c0000000b0500002900000000060004110000000b07000039000006380000a13d00000af90000013d000a00000001001d000006900100004100000000001004430000000001000414000006340010009c0000063401008041000000c00110021000000691011001c70000800b0200003918cd18c80000040f0000000100200190000012260000613d000000000101043b0000000a0010006c000006db0000a13d00000af90000013d000006340010009c0000063401008041000000c00110021000000696011001c718cd18c80000040f00000060031002700000063403300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000080057001bf00000a9c0000613d0000008008000039000000000901034f000000009a09043c0000000008a80436000000000058004b00000a980000c13d000000000006004b00000aa90000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f0003000000010355000000010020019000000c030000613d0000001f01400039000000600110018f00000080011001bf000000400010043f000000200030008c0000011b0000413d000000800100043d000006370010009c0000011b0000213d0000000002000411000000000012004b00000d1c0000c13d000006990100004100000000001004430000000d0100002900000004001004430000000001000414000006340010009c0000063401008041000000c0011002100000069a011001c7000080020200003918cd18c80000040f0000000100200190000012260000613d000000000101043b000000000001004b0000011b0000613d000000400200043d0000069b01000041000c00000002001d000000000012043500000000010004140000000d02000029000000040020008c00000ae10000613d0000000c02000029000006340020009c00000634020080410000004002200210000006340010009c0000063401008041000000c001100210000000000121019f00000698011001c70000000d0200002918cd18c30000040f0000006003100270000106340030019d00030000000103550000000100200190000011af0000613d0000000c01000029000006890010009c00000bf90000213d0000000c01000029000000400010043f0000000001000019000018ce0001042e000c00000001001d000d00000003001d000006900100004100000000001004430000000001000414000006340010009c0000063401008041000000c00110021000000691011001c70000800b0200003918cd18c80000040f0000000100200190000012260000613d000000000101043b0000000c0010006c0000000d030000290000099d0000a13d000006de01000041000000000010043f0000069801000041000018cf00010430000c00000004001d000006900100004100000000001004430000000001000414000006340010009c0000063401008041000000c00110021000000691011001c70000800b0200003918cd18c80000040f0000000100200190000012260000613d000000000101043b0000000d02000029000000000021004b0000000c0100002900000d570000213d000006d80010009c00000d570000a13d000000000021001a000012a70000413d0000000001210019000005110000013d000000000100041a0000063701100197000000000061004b00000b240000c13d000000000107041a000900000001001d000000000001004b000b00000005001d00000d5b0000c13d000006b30150009a000006c00010009c00000e7b0000213d000006c101000041000000000010043f0000069801000041000018cf000104300000068f01000041000000000010043f000000040060043f0000063d01000041000018cf0001043018cd14f10000040f0000000801000039000000000101041a0000000c0010006c0000100e0000a13d0000000c01000029000000000010043f0000000901000039000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f00000001002001900000011b0000613d000000000101043b00000000020004110000063702200197000000000020043f000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f00000001002001900000011b0000613d0000000b02000029000006a40220009a000000000502041a000000000301043b000000000403041a00000000014500a9000000000004004b0000000d0800002900000b550000613d00000000064100d9000000000056004b000012a70000c13d0000068e0110012a0000000305300039000000000605041a000000000016001a000012a70000413d00000000061600190000000401300039000000000701041a000000000676004b000012a70000413d000000000065041b0000000205300039000000000605041a000000000086001a000012a70000413d0000000006860019000000000065041b0000000b05000029000006c80550009a000000000605041a000000000086001a000012a70000413d0000000006860019000000000065041b000000000084001a000012a70000413d0000000004840019000000000043041b0000000b03000029000006c60330009a000000000503041a000000000085001a000012a70000413d0000000005850019000000000053041b000000000302041a00000000024300a9000000000004004b00000b7f0000613d00000000044200d9000000000034004b000012a70000c13d0000068e0220012a000000000021041b000000400100043d00000000028104360000000000020435000006340010009c000006340100804100000040011002100000000002000414000006340020009c0000063402008041000000c002200210000000000112019f0000068d011001c70000800d020000390000000303000039000006df0400004100000000050004110000000c06000029000004a10000013d000006e201200197000000a00010043f000000000006004b000000200100003900000000010060390000003f01100039000006e102100197000006db0020009c00000bf90000813d00000080012000390000000603000029000006370330019700000005040000290000063704400197000000400010043f0000000000410435000001a0042000390000014005000039000000000054043500000180042000390000000705000029000000000054043500000160042000390000000805000029000000000054043500000140042000390000000905000029000000000054043500000120042000390000000a05000029000000000054043500000100042000390000000b050000290000000000540435000000e0042000390000000c050000290000000000540435000000c0042000390000000d050000290000000000540435000000a0042000390000000000340435000001c004200039000000800300043d0000000000340435000001e002200039000000000003004b00000bcb0000613d00000000040000190000000005240019000000a006400039000000000606043300000000006504350000002004400039000000000034004b00000bc40000413d0000001f04300039000006e104400197000000000223001900000000000204350000016002400039000006340020009c00000634020080410000006002200210000006340010009c00000634010080410000004001100210000000000112019f000018ce0001042e000006c40030009c00000bf90000213d000000600300003900000000040000190000014005100039000000400050043f0000012005100039000000000035043500000100051000390000000000050435000000e0051000390000000000050435000000c0051000390000000000050435000000a0051000390000000000050435000000800510003900000000000504350000006005100039000000000005043500000040051000390000000000050435000000200510003900000000000504350000000000010435000000a00540003900000000001504350000002004400039000000000024004b00000d6b0000813d000000400100043d000006b50010009c00000bdc0000a13d000006dc01000041000000000010043f0000004101000039000000040010043f0000063d01000041000018cf000104300000069f01000041000000000010043f0000069801000041000018cf000104300000001f0530018f0000063606300198000000400200043d000000000462001900000c0e0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00000c0a0000c13d000000000005004b00000c1b0000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f00000000001404350000006001300210000006340020009c00000634020080410000004002200210000000000112019f000018cf0001043000000080040000390000014005000039000000000700001900000c2d0000013d0000001f0a900039000006e10aa00197000000000998001900000000000904350000000008a800190000000107700039000000000027004b000007e30000813d0000000009180049000000400990008a00000000039304360000002004400039000000000904043300000000ba090434000006370aa00197000000000aa80436000000000b0b0433000006370bb001970000000000ba0435000000400a900039000000000a0a0433000000400b8000390000000000ab0435000000600a900039000000000a0a0433000000600b8000390000000000ab0435000000800a900039000000000a0a0433000000800b8000390000000000ab0435000000a00a900039000000000a0a0433000000a00b8000390000000000ab0435000000c00a900039000000000a0a0433000000c00b8000390000000000ab0435000000e00a900039000000000a0a0433000000e00b8000390000000000ab0435000001000a900039000000000a0a0433000001000b8000390000000000ab043500000120099000390000000009090433000001200a80003900000000005a0435000001400b80003900000000a909043400000000009b04350000016008800039000000000009004b00000c250000613d000000000b000019000000000c8b0019000000000dba0019000000000d0d04330000000000dc0435000000200bb0003900000000009b004b00000c5f0000413d00000c250000013d000000400100043d0000004402100039000006a003000041000000000032043500000024021000390000000f0300003900000f070000013d000000000300001900000c8d0000013d000000400200043d0000002001200039000006cc0300004100000000003104350000002401200039000006aa03000041000000000031043500000044010000390000000000120435000000440120003900000000000104350000068b0020009c00000bf90000213d0000008001200039000000400010043f00000000010b001918cd17ac0000040f0000000c010000290000000d0200002918cd17ac0000040f00000000010004150000000a0110006900000000010000020000000801000039000000000101041a0000000b030000290000000103300039000000000013004b000004a40000813d0000000802000039000000000020043f0000000a023000c9000006a70220009a000000000202041a000006370b20019800000c8a0000613d000b00000003001d0000000001000415000a00000001001d000000400400043d0000002001400039000006cc0200004100000000002104350000002402400039000006aa0300004100000000003204350000004402000039000000000024043500000044024000390000000000020435000d00000004001d0000068b0040009c00000bf90000213d0000000d030000290000008002300039000000400020043f000000000303043300000000020004140000000400b0008c000c0000000b001d00000cb00000c13d0000000104000031000000010200003900000cc30000013d000006340010009c00000634010080410000004001100210000006340030009c00000634030080410000006003300210000000000113019f000006340020009c0000063402008041000000c002200210000000000121019f00000000020b001918cd18c30000040f0000000c0b000029000000010220018f00030000000103550000006001100270000106340010019d0000063404100197000000000004004b0000008001000039000000600300003900000cef0000613d000006890040009c00000bf90000213d0000001f01400039000006e1011001970000003f01100039000006e101100197000000400300043d0000000001130019000000000031004b00000000050000390000000105004039000006890010009c00000bf90000213d000000010050019000000bf90000c13d000000400010043f0000000001430436000006e1064001980000000005610019000000030700036700000ce20000613d000000000807034f0000000009010019000000008a08043c0000000009a90436000000000059004b00000cde0000c13d0000001f0440019000000cef0000613d000000000667034f0000000304400210000000000705043300000000074701cf000000000747022f000000000606043b0000010004400089000000000646022f00000000044601cf000000000474019f0000000000450435000000000002004b00000c700000613d0000000004000415000000130440008a00000005044002100000000002030433000000000002004b00000d060000613d000006cd0020009c0000011b0000213d000000200020008c0000011b0000413d0000000001010433000000000001004b0000000002000039000000010200c039000000000021004b0000011b0000c13d0000000004000415000000120440008a0000000504400210000000000001004b00000c700000613d000900000004001d000006990100004100000000001004430000000400b004430000000001000414000006340010009c0000063401008041000000c0011002100000069a011001c7000080020200003918cd18c80000040f0000000100200190000012260000613d000000000101043b000000000001004b00000009010000290000000501100270000000000100003f000000010100c03f0000000c0b00002900000c840000c13d00000c700000013d0000069701000041000000000010043f0000069801000041000018cf00010430000900000001001d000000000010043f0000000d01000039000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f00000001002001900000011b0000613d000000000101043b000000000101041a000000ff00100190000006460000613d0000000c0000006b00000d440000613d0000000d01000029000000000010043f0000001201000039000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f00000001002001900000011b0000613d000000000101043b00000001011000390000000c02000029000000000021041b0000000a0000006b0000118b0000c13d000000400100043d0000000000010435000006340010009c000006340100804100000040011002100000000002000414000006340020009c0000063402008041000000c002200210000000000112019f000006ad011001c70000800d020000390000000303000039000006c30400004100000009050000290000000d06000029000004a10000013d000006d901000041000000000010043f0000069801000041000018cf00010430000006900100004100000000001004430000000001000414000006340010009c0000063401008041000000c00110021000000691011001c70000800b0200003918cd18c80000040f0000000100200190000012260000613d000000000101043b000000090010006c0000000b0500002900000af90000213d00000b1d0000013d00000000050000190000000801000039000000000101041a000000000051004b0000100e0000a13d0000000801000039000000000010043f000000400600043d000006b50060009c00000bf90000213d0000014001600039000000400010043f0000000a015000c9000006a70210009a000000000202041a00000637022001970000000002260436000006c50310009a000000000303041a00000637033001970000000000320435000006c60210009a000000000202041a00000040036000390000000000230435000006c70210009a000000000202041a00000060036000390000000000230435000006c80210009a000000000202041a00000080036000390000000000230435000006c90210009a000000000202041a000000a0036000390000000000230435000006c20210009a000000000202041a000000c0036000390000000000230435000006a40210009a000000000202041a000000e00360003900000000002304350000010002600039000006bd0310009a000000000303041a0000000000320435000006ca0110009a000000000201041a000000010320019000000001082002700000007f0880618f0000001f0080008c00000000040000390000000104002039000000000442013f00000001004001900000056d0000c13d000000400700043d0000000004870436000000000003004b000d00000005001d00000dcb0000613d000800000004001d000900000008001d000a00000007001d000c00000006001d000000000010043f0000000001000414000006340010009c0000063401008041000000c001100210000006ad011001c7000080100200003918cd18c80000040f00000001002001900000011b0000613d0000000908000029000000000008004b00000dd10000613d000000000201043b00000000010000190000000d050000290000000c060000290000000a0700002900000008090000290000000003190019000000000402041a000000000043043500000001022000390000002001100039000000000081004b00000dc30000413d00000dd50000013d000006e2012001970000000000140435000000000008004b0000002001000039000000000100603900000dd50000013d00000000010000190000000d050000290000000c060000290000000a070000290000003f01100039000006e1021001970000000001720019000000000021004b00000000020000390000000102004039000006890010009c00000bf90000213d000000010020019000000bf90000c13d000000400010043f00000120016000390000000000710435000000800100043d000000000051004b0000100e0000a13d0000000501500210000000a001100039000c00000001001d0000000000610435000000800100043d000000000051004b0000100e0000a13d000000000105001918cd16ef0000040f0000000d05000029000000800100043d000000000051004b0000100e0000a13d0000000c0100002900000000010104330000010001100039000000000021043500000001055000390000000b0050006c00000d6c0000413d000000400100043d000007da0000013d0000008003000039000000000521034f000000000505043b000006370050009c0000011b0000213d000000200330003900000000005304350000002002200039000000000042004b00000dfc0000413d000000800100043d000006890010009c00000bf90000213d0000000002010019000000400100043d000900000001001d0000000003020019000002730000013d000000000201043b0000000001000019000000000302041a000000a004100039000000000034043500000001022000390000002001100039000000000051004b00000e0f0000413d00000b980000013d0000000b020000290000000d0020006b00000e960000c13d000006d601000041000000000010043f0000069801000041000018cf00010430000000400100043d0000004402100039000006a30300004100000000003204350000002402100039000000140300003900000f070000013d000c00000005001d0000000d020000290000000a022000c9000006a40620009a000000000906041a000000000501041a00000000075900a9000000000005004b00000e310000613d000000000a5700d900000000009a004b000012a70000c13d0000068e0770012a0000000309100039000000000a09041a00000000007a001a000012a70000413d000000000a7a00190000000407100039000000000b07041a000000000aba004b000012a70000413d0000000000a9041b0000000100800190000012a70000c13d0000000c0330006a000000000034041b000006c80320009a000000000403041a0000000c0440006c000012a70000413d000000000043041b0000000c0350006c000012a70000413d000000000031041b000006c60120009a000000000401041a0000000c0440006c000012a70000413d000000000041041b000000000406041a00000000013400a90000000c0050006c00000e540000613d00000000033100d9000000000043004b000012a70000c13d000006a70220009a0000068e0110012a000000000017041b000000000102041a000000400200043d0000002003200039000006be04000041000000000043043500000044032000390000000c04000029000000000043043500000024032000390000000b040000290000000000430435000000440300003900000000003204350000068b0020009c00000bf90000213d0000008003200039000000400030043f000006370110019718cd17ac0000040f000000400100043d0000000c020000290000000000210435000006340010009c000006340100804100000040011002100000000002000414000006340020009c0000063402008041000000c002200210000000000112019f000006ad011001c70000800d020000390000000303000039000006d004000041000000000500041100000d550000013d18cd14f10000040f0000000701000039000000000101041a000000400200043d00000020032000390000000b0400002900000000004304350000000000120435000006340020009c000006340200804100000040012002100000000002000414000006340020009c0000063402008041000000c002200210000000000112019f0000068d011001c70000800d020000390000000103000039000006930400004118cd18c30000040f00000001002001900000011b0000613d0000000b010000290000000702000039000000000012041b0000063b0000013d0000000001000410000000000012004b00000e1a0000613d0000000a0000006b00000e1a0000613d18cd14f10000040f0000000801000039000000000101041a0000000c0010006c0000100e0000a13d0000000c010000290000000a011000c9000006a70210009a000000000202041a0000063700200198000006460000613d000006a40110009a000000000101041a000900000001001d0000000c01000029000000000010043f0000000901000039000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f00000001002001900000011b0000613d000000000101043b0000000d02000029000000000020043f000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f00000001002001900000011b0000613d000000000101043b000800000001001d0000000c01000029000000000010043f0000000901000039000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f00000001002001900000011b0000613d000000000101043b0000000b02000029000000000020043f000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f00000001002001900000011b0000613d0000000802000029000000000202041a00000009032000b9000000000701043b000000000107041a000000000002004b00000ee90000613d00000000042300d9000000090040006c000012a70000c13d0000068e0430012a00000008050000290000000308500039000000000508041a000000000045001a000012a70000413d000000000545001900000008060000290000000406600039000000000906041a000000000995004b000012a70000413d000000010500008a0000000a0050006b0000000005090019000012950000613d0000000a05000029000000000095004b000012950000a13d000006d301000041000000000010043f000000040090043f0000063d01000041000018cf00010430000000400100043d0000004402100039000006a603000041000000000032043500000024021000390000000c030000390000000000320435000006a1020000410000000000210435000000040210003900000020030000390000000000320435000006340010009c00000634010080410000004001100210000006a2011001c7000018cf00010430000000600200003900000000030000190000000305000029000000000453001900000000002404350000002003300039000000000013004b00000f150000413d0000000801000039000000000101041a000600000001001d000006890010009c0000100b0000213d00000006010000290000000501100210000500000001001d0000003f011000390002068a0010019b000080100d000039000000000e000019000000090c00002900000f2b0000013d000000010ee000390000000400e0006c000002860000813d000000800100043d0000000000e1004b0000100e0000a13d000000400100043d0000000204100029000000000014004b00000000020000390000000102004039000006890040009c00000bf90000213d000000010020019000000bf90000c13d0000000503e00210000000a0023000390000000002020433000000400040043f00000006050000290000000004510436000000000005004b00000f520000613d000000000500003100000002055003670000000006000019000000400700043d0000068b0070009c00000bf90000213d0000008008700039000000400080043f000000000905034f000000000a070019000000009b09043c000000000aba043600000000008a004b00000f490000c13d000000000864001900000000007804350000002006600039000000050060006c00000f420000413d00000000040c04330000000000e4004b0000100e0000a13d0000000304300029000000000014043500000000010c04330000000000e1004b0000100e0000a13d000000060000006b00000f280000613d000c06370020019b0000000005000019000b0000000e001d000a00000004001d000d00000005001d000000000050043f0000000901000039000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c700000000020d001918cd18c80000040f00000001002001900000011b0000613d000000000101043b0000000c02000029000000000020043f000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f00000001002001900000011b0000613d000000400400043d000006b90040009c000000090800002900008010020000390000000b0a0000290000000a0b0000290000000d0c00002900000bf90000213d000000000501043b000000a001400039000000400010043f000000000305041a00000000093404360000000101500039000000000101041a00000000001904350000000201500039000000000601041a000000400140003900000000006104350000000306500039000000000606041a0000006007400039000000000067043500000080044000390000000405500039000000000505041a000000000054043500000000040804330000000000a4004b0000100e0000a13d00000000040b043300000000050404330000000000c5004b0000100e0000a13d0000000505c00210000000200550003900000000045400190000000004040433000000000034043500000000030804330000000000a3004b0000100e0000a13d00000000030b043300000000040304330000000000c4004b0000100e0000a13d0000000004090433000000000353001900000000030304330000002003300039000000000043043500000000030804330000000000a3004b0000100e0000a13d00000000040b043300000000030404330000000000c3004b0000100e0000a13d0000000001010433000800000005001d00000000035400190000000003030433000000400330003900000000001304350000000000c0043f0000000901000039000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c718cd18c80000040f00000001002001900000011b0000613d000000000101043b0000000c02000029000000000020043f000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f00000001002001900000011b0000613d000000000101043b000700000001001d0000000d0100002918cd16ef0000040f0000000704000029000000000304041a00000000023100a9000000000003004b00000fdf0000613d00000000033200d9000000000013004b000012a70000c13d0000068e0120012a0000000302400039000000000202041a000000000012001a000012a70000413d00000000011200190000000402400039000000000202041a000000000121004b000012a70000413d000000090c00002900000000020c04330000000b0e0000290000000000e2004b000080100d0000390000000a040000290000000d0500002900000008060000290000100e0000a13d00000000020404330000000003020433000000000053004b0000100e0000a13d00000000026200190000000002020433000000600220003900000000001204350000000105500039000000060050006c00000f600000413d00000f280000013d000000600200003900000000030000190000000405000029000000000453001900000000002404350000002003300039000000000013004b000010010000413d0000000801000039000000000101041a000b00000001001d000006890010009c000011100000a13d000000800100043d000000000001004b00000bf90000c13d000006dc01000041000000000010043f0000003201000039000000040010043f0000063d01000041000018cf000104300000000b02000029000006340020009c00000634020080410000004002200210000006340010009c0000063401008041000000c001100210000000000121019f0000063d011001c7000000090200002918cd18c80000040f00000060031002700000063403300197000000200030008c000000200400003900000000040340190000001f0640018f00000020074001900000000b057000290000102e0000613d000000000801034f0000000b09000029000000008a08043c0000000009a90436000000000059004b0000102a0000c13d000000000006004b0000103b0000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000011bc0000613d0000001f01400039000000600110018f0000000b04100029000000000014004b00000000020000390000000102004039000a00000004001d000006890040009c00000bf90000213d000000010020019000000bf90000c13d0000000a02000029000000400020043f000000200030008c0000011b0000413d000000070200002900000637052001970000000b020000290000000002020433000500000002001d000006a8020000410000000a0400002900000000002404350000000402400039000000080400002900000000004204350000000002000414000700000005001d000000040050008c0000108a0000613d0000000a01000029000006340010009c00000634010080410000004001100210000006340020009c0000063402008041000000c002200210000000000112019f0000063d011001c7000000070200002918cd18c80000040f00000060031002700000063403300197000000200030008c000000200400003900000000040340190000001f0640018f00000020074001900000000a05700029000010770000613d000000000801034f0000000a09000029000000008a08043c0000000009a90436000000000059004b000010730000c13d000000000006004b000010840000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f000300000001035500000001002001900000120b0000613d0000001f01400039000000600110018f0000000a02100029000b00000002001d000006890020009c00000bf90000213d0000000b02000029000000400020043f000000200030008c0000011b0000413d000000060200002900000637052001970000000a020000290000000002020433000600000002001d000006a8020000410000000b0400002900000000002404350000000402400039000000080400002900000000004204350000000002000414000a00000005001d000000040050008c000010ce0000613d0000000b01000029000006340010009c00000634010080410000004001100210000006340020009c0000063402008041000000c002200210000000000112019f0000063d011001c70000000a0200002918cd18c80000040f00000060031002700000063403300197000000200030008c000000200400003900000000040340190000001f0640018f00000020074001900000000b05700029000010bb0000613d000000000801034f0000000b09000029000000008a08043c0000000009a90436000000000059004b000010b70000c13d000000000006004b000010c80000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000012270000613d0000001f01400039000000600110018f0000000b01100029000006890010009c00000bf90000213d000000400010043f000000200030008c0000011b0000413d0000000b010000290000000001010433000400000001001d000000800100043d000006340010009c000006340100804100000060011002100000000002000414000006340020009c0000063402008041000000c002200210000000000112019f000006a9011001c7000006aa0200004118cd18c30000040f00030000000103550000006003100270000106340030019d00000634033001980000126f0000c13d0000000100200190000012ad0000613d000000400200043d000006a8010000410000000000120435000b00000002001d00000004012000390000000802000029000000000021043500000000010004140000000702000029000000040020008c000012c50000c13d000000200030008c00000020040000390000000004034019000012f00000013d0000000005000019000000070a000029000010ff0000013d0000000105500039000000000035004b000004e80000813d0000000006120049000000400660008a0000000004640436000000200aa0003900000000060a043300000000070604330000000002720436000000000007004b000010fc0000613d00000000080000190000002006600039000000000906043300000000029204360000000108800039000000000078004b000011090000413d000010fc0000013d0000000b0100002900000005021002100000003f012000390003068a0010019b000600000002001d0002001f002001930000801009000039000000000a00001900000007080000290000111d0000013d000000010aa000390000000500a0006c000004de0000813d000000800100043d0000000000a1004b0000100e0000a13d000000400100043d0000000304100029000000000014004b00000000020000390000000102004039000006890040009c00000bf90000213d000000010020019000000bf90000c13d0000000503a00210000000a0023000390000000002020433000000400040043f0000000b040000290000000004410436000000060000006b000011380000613d000000060540002900000000060000310000000206600367000000006706043c0000000004740436000000000054004b000011340000c13d000000020000006b00000000040804330000000000a4004b0000100e0000a13d0000000403300029000a00000003001d000000000013043500000000010804330000000000a1004b0000100e0000a13d0000000b0000006b0000111a0000613d000906370020019b000000000400001900080000000a001d000d00000004001d000000000040043f0000000901000039000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000000000209001918cd18c80000040f00000001002001900000011b0000613d000000000101043b0000000902000029000000000020043f000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f00000001002001900000011b0000613d000000000101043b000c00000001001d0000000d0100002918cd16ef0000040f0000000c04000029000000000304041a00000000023100a9000000000003004b0000116d0000613d00000000033200d9000000000013004b000012a70000c13d0000068e0120012a0000000302400039000000000202041a000000000012001a000012a70000413d00000000011200190000000402400039000000000202041a000000000121004b000012a70000413d00000007080000290000000002080433000000080a0000290000000000a2004b00008010090000390000000d040000290000100e0000a13d0000000a0200002900000000020204330000000003020433000000000043004b0000100e0000a13d000000050340021000000000022300190000002002200039000000000012043500000001044000390000000b0040006c000011470000413d0000111a0000013d0000000b01000029000006c20110009a000b00000001001d000000000101041a000c00000001001d000006900100004100000000001004430000000001000414000006340010009c0000063401008041000000c00110021000000691011001c70000800b0200003918cd18c80000040f0000000100200190000012260000613d000000000101043b0000000c0010006c00000d460000813d000006900100004100000000001004430000000001000414000006340010009c0000063401008041000000c00110021000000691011001c70000800b0200003918cd18c80000040f0000000100200190000012260000613d000000000101043b0000000a0010006c0000000a0100a0290000000b02000029000000000012041b00000d460000013d00000634033001970000001f0530018f0000063606300198000000400200043d000000000462001900000c0e0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000011b70000c13d00000c0e0000013d0000001f0530018f0000063606300198000000400200043d000000000462001900000c0e0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000011c30000c13d00000c0e0000013d000006b201000041000000000010043f0000069801000041000018cf000104300000001f0530018f0000063606300198000000400200043d000000000462001900000c0e0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000011d30000c13d00000c0e0000013d000006bc01000041000000000010043f0000069801000041000018cf00010430000000000100041a00000637011001970000000002000411000000000021004b000012050000c13d0000000b01000039000000000101041a000900000001001d000000000001004b000012170000c13d0000000b01000029000006b30110009a000006b40010009c00000b200000413d18cd14f10000040f0000000701000039000000000101041a000000400200043d00000020032000390000000b0400002900000000004304350000000000120435000006340020009c000006340200804100000040012002100000000002000414000006340020009c0000063402008041000000c002200210000000000112019f0000068d011001c70000800d020000390000000103000039000006930400004118cd18c30000040f00000001002001900000011b0000613d0000000b010000290000000702000039000000000012041b000003a50000013d0000068f01000041000000000010043f0000000001000411000000040010043f0000063d01000041000018cf000104300000001f0530018f0000063606300198000000400200043d000000000462001900000c0e0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000012120000c13d00000c0e0000013d000006900100004100000000001004430000000001000414000006340010009c0000063401008041000000c00110021000000691011001c70000800b0200003918cd18c80000040f0000000100200190000012260000613d000000000101043b000000090010006c00000af90000213d000011e60000013d000000000001042f0000001f0530018f0000063606300198000000400200043d000000000462001900000c0e0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b0000122e0000c13d00000c0e0000013d000d00000000001d000c00000000001d0000000a01000029000000000010043f0000000901000039000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f00000001002001900000011b0000613d000000800200043d0000000d03000029000000000032004b0000100e0000a13d000000000101043b0000000502300210000b00000002001d000000a00220003900000000020204330000063702200197000000000020043f000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f00000001002001900000011b0000613d000000000101043b000000090200002900000000020204330000000d05000029000000000052004b0000100e0000a13d00000003021000390000000b0300002900000008013000290000000001010433000000000302041a000000000031001a0000000c04000029000012a70000413d0000000003310019000000000032041b000000000041001a000012a70000413d000c00000041001d000d00010050003d000000800100043d0000000d0010006b000012350000413d000005eb0000013d0000001f0430003900000635044001970000003f04400039000006ab05400197000000400400043d0000000005540019000000000045004b00000000060000390000000106004039000006890050009c00000bf90000213d000000010060019000000bf90000c13d000000400050043f0000001f0530018f000000000734043600000636063001980000000004670019000012870000613d000000000801034f000000008908043c0000000007970436000000000047004b000012830000c13d000000000005004b000010e80000613d000000000661034f0000000305500210000000000704043300000000075701cf000000000757022f000000000606043b0000010005500089000000000656022f00000000055601cf000000000575019f0000000000540435000010e80000013d0000000009590049000000000098041b00000009081000b9000000000001004b0000129d0000613d00000000091800d9000000090090006c000012a70000c13d0000068e0980012a000000030a700039000000000b0a041a00000000009b001a000012a70000413d000000000b9b00190000000407700039000000000c07041a000000000bcb004b000013280000813d000006dc01000041000000000010043f0000001101000039000000040010043f0000063d01000041000018cf000104300000001f0430018f0000063602300198000012b60000613d000000000501034f0000000006000019000000005705043c0000000006760436000000000026004b000012b20000c13d000000000004004b000012c30000613d000000000121034f0000000304400210000000000502043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f00000000001204350000006001300210000018cf000104300000000b02000029000006340020009c00000634020080410000004002200210000006340010009c0000063401008041000000c001100210000000000121019f0000063d011001c7000000070200002918cd18c80000040f00000060031002700000063403300197000000200030008c000000200400003900000000040340190000001f0640018f00000020074001900000000b05700029000012df0000613d000000000801034f0000000b09000029000000008a08043c0000000009a90436000000000059004b000012db0000c13d000000000006004b000012ec0000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f000300000001035500000001002001900000134d0000613d0000001f01400039000000600110018f0000000b02100029000000000012004b00000000010000390000000101004039000700000002001d000006890020009c00000bf90000213d000000010010019000000bf90000c13d0000000701000029000000400010043f000000200030008c0000011b0000413d0000000b010000290000000001010433000b000600100073000012a70000413d000013170000613d0000000d01000029000000000010043f0000000501000039000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f00000001002001900000011b0000613d000000400200043d000700000002001d000000000101043b000000000101041a0000000b0010006b000013b10000a13d00000007030000290000004401300039000006b0020000410000000000210435000000240130003900000010020000390000000000210435000006a1010000410000000000130435000000040130003900000020020000390000000000210435000006340030009c00000634030080410000004001300210000006a2011001c7000018cf0001043000000000005b001a000012a70000413d000000000b5b00190000000000ba041b000000000002004b000013310000613d00000000022300d9000000090020006c000012a70000c13d000000000046041b000000000001004b000013370000613d00000000011800d9000000090010006c000012a70000c13d000000000097041b000000400100043d0000000000510435000006340010009c000006340100804100000040011002100000000002000414000006340020009c0000063402008041000000c002200210000000000112019f000006ad011001c70000800d020000390000000403000039000006d4040000410000000d050000290000000b060000290000000c0700002918cd18c30000040f00000001002001900000011b0000613d000004a40000013d0000001f0530018f0000063606300198000000400200043d000000000462001900000c0e0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000013540000c13d00000c0e0000013d0000000b0000006b0000000001000019000013810000613d0000000b030000290000000301300210000006e30110027f000006e30110016700000009020000290000000002020433000000000112016f0000000102300210000000000121019f000013810000013d000000010320008a0000000503300270000000000431001900000020030000390000000104400039000000080600002900000000056300190000000005050433000000000051041b00000020033000390000000101100039000000000041004b0000136c0000c13d0000000b0020006c0000137e0000813d0000000b020000290000000302200210000000f80220018f000006e30220027f000006e30220016700000008033000290000000003030433000000000223016f000000000021041b0000000b01000029000000010110021000000001011001bf0000000702000029000000000012041b0000000a01000029000000000010043f0000001201000039000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f00000001002001900000011b0000613d0000000c0000006b0000000c020000290000068e02006041000000000101043b0000000101100039000000000021041b000000400100043d0000000000010435000006340010009c000006340100804100000040011002100000000002000414000006340020009c0000063402008041000000c002200210000000000112019f000006ad011001c70000800d020000390000000303000039000006b6040000410000000d050000290000000a0600002918cd18c30000040f00000001002001900000011b0000613d000000400100043d0000000a020000290000000000210435000006340010009c00000634010080410000004001100210000006a5011001c7000018ce0001042e000006a8010000410000000702000029000000000012043500000004012000390000000802000029000000000021043500000000010004140000000a02000029000000040020008c000013c00000c13d0000000103000031000000200030008c00000020040000390000000004034019000013eb0000013d0000000702000029000006340020009c00000634020080410000004002200210000006340010009c0000063401008041000000c001100210000000000121019f0000063d011001c70000000a0200002918cd18c80000040f00000060031002700000063403300197000000200030008c000000200400003900000000040340190000001f0640018f00000020074001900000000705700029000013da0000613d000000000801034f0000000709000029000000008a08043c0000000009a90436000000000059004b000013d60000c13d000000000006004b000013e70000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000014150000613d0000001f01400039000000600210018f0000000701200029000000000021004b00000000020000390000000102004039000006890010009c00000bf90000213d000000010020019000000bf90000c13d000000400010043f000000200030008c0000011b0000413d00000007020000290000000002020433000a000400200073000012a70000413d0000140f0000613d0000000c01000029000000000010043f0000000501000039000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f00000001002001900000011b0000613d000000000101043b000000000101041a0000000a0010006b000014210000a13d000000400100043d0000004402100039000006af0300004100000000003204350000002402100039000000100300003900000f070000013d0000001f0530018f0000063606300198000000400200043d000000000462001900000c0e0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b0000141c0000c13d00000c0e0000013d0000000d01000029000000000010043f0000000501000039000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f00000001002001900000011b0000613d000000000101043b000000000201041a0000000b0220006c000012a70000413d000000000021041b0000000c01000029000000000010043f0000000501000039000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f00000001002001900000011b0000613d000000000101043b000000000201041a0000000a0220006c000012a70000413d000000000021041b000006a801000041000000400200043d0000000000120435000d00000002001d00000004012000390000000802000029000000000021043500000000010004140000000902000029000000040020008c000014550000c13d0000000103000031000000200030008c00000020040000390000000004034019000014800000013d0000000d02000029000006340020009c00000634020080410000004002200210000006340010009c0000063401008041000000c001100210000000000121019f0000063d011001c7000000090200002918cd18c80000040f00000060031002700000063403300197000000200030008c000000200400003900000000040340190000001f0640018f00000020074001900000000d057000290000146f0000613d000000000801034f0000000d09000029000000008a08043c0000000009a90436000000000059004b0000146b0000c13d000000000006004b0000147c0000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000014b50000613d0000001f01400039000000600210018f0000000d01200029000000000021004b00000000020000390000000102004039000006890010009c00000bf90000213d000000010020019000000bf90000c13d000000400010043f000000200030008c0000011b0000413d0000000d020000290000000002020433000d000500200074000014c10000a13d0000000901000029000000000010043f0000001501000039000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f00000001002001900000011b0000613d000000000101043b000000000201041a0000000d0020002a000012a70000413d0000000d030000290000000002320019000000000021041b000000400100043d0000000000310435000006340010009c000006340100804100000040011002100000000002000414000006340020009c0000063402008041000000c002200210000000000112019f000006ad011001c70000800d020000390000000203000039000006ae040000410000000905000029000004a10000013d0000001f0530018f0000063606300198000000400200043d000000000462001900000c0e0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000014bc0000c13d00000c0e0000013d0000004402100039000006ac0300004100000000003204350000002402100039000000130300003900000f070000013d0000063702200197000000000020043f000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f0000000100200190000014d50000613d000000000101043b000000000001042d0000000001000019000018cf0001043000010000000000020000000e01000039000000000101041a000000000001004b000014ee0000613d000100000001001d000006900100004100000000001004430000000001000414000006340010009c0000063401008041000000c00110021000000691011001c70000800b0200003918cd18c80000040f0000000100200190000014f00000613d000000000101043b000000010010006c00000000010000390000000101002039000000010110018f000000000001042d000000010100018f000000000001042d000000000001042f000d0000000000020000000801000039000000000101041a000500000001001d000006e40010009c0000169d0000813d000000050100002900000005011002100000003f021000390000068a02200197000000400300043d0000000002230019000a00000003001d000000000032004b00000000030000390000000103004039000006890020009c0000169d0000213d00000001003001900000169d0000c13d000000400020043f00000005020000290000000a030000290000000003230436000900000003001d000000000002004b000016940000613d000000000200003100000002022003670000000003000019000000400400043d0000068b0040009c0000169d0000213d0000008005400039000000400050043f000000000602034f0000000007040019000000006806043c0000000007870436000000000057004b000015160000c13d000000090530002900000000004504350000002003300039000000000013004b0000150f0000413d00000000020000190000000005000019000b00000002001d000000400600043d0000068b0060009c0000169d0000213d0000008001600039000000400010043f000000000200003100000002022003670000000003060019000000002402043c0000000003430436000000000013004b0000152a0000c13d0000000801000039000000000101041a000000000051004b000016970000a13d0000000801000039000000000010043f000800000005001d0000000a015000c9000300000001001d000006c20110009a000000000101041a000700000006001d000400000001001d0000000001160436000600000001001d000006900100004100000000001004430000000001000414000006340010009c0000063401008041000000c00110021000000691011001c70000800b0200003918cd18c80000040f0000000100200190000016a30000613d000000000101043b000000040010006c00000008050000290000000706000029000015e80000413d000400000001001d000000000050043f0000001201000039000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f000000070600002900000008050000290000000100200190000016a40000613d000000000301043b000000000103041a000000060200002900000000001204350000000001060433000000040010006b000015e80000613d00000040026000390000000301000029000006c60110009a000000000101041a0000000000120435000000000001004b000015e80000613d000100000002001d000200000003001d0000000301000029000006a70110009a000000000101041a000000400300043d000006e50200004100000000002304350000063701100197000400000003001d000000040230003900000000001204350000069d01000041000000000010044300000000010004120000000400100443000000200100003900000024001004430000000001000414000006340010009c0000063401008041000000c0011002100000069e011001c7000080050200003918cd18c80000040f0000000100200190000016a30000613d000000000201043b00000000010004140000063702200197000000040020008c000015920000c13d0000000103000031000000200030008c0000002004000039000000000403401900000008050000290000000706000029000000040a000029000015be0000013d0000000403000029000006340030009c00000634030080410000004003300210000006340010009c0000063401008041000000c001100210000000000131019f0000063d011001c718cd18c80000040f000000040a00002900000060031002700000063403300197000000200030008c00000020040000390000000004034019000000200640019000000000056a0019000015ab0000613d000000000701034f00000000080a0019000000007907043c0000000008980436000000000058004b000015a70000c13d0000001f07400190000015b80000613d000000000661034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000016ac0000613d000000080500002900000007060000290000001f01400039000000600210018f0000000001a20019000000000021004b00000000020000390000000102004039000006890010009c0000169d0000213d00000001002001900000169d0000c13d000000400010043f000000200030008c0000000204000029000016a40000413d00000000010a043300000060026000390000000000120435000000000001004b0000000102000029000015e80000613d0000000003020433000000000003004b000015e80000613d00000000021300a900000000033200d9000000000013004b000016a60000c13d0000068e0020009c000015e80000413d0000000101400039000000000301041a0000068e0220012a00000000012300a900000000022100d9000000000032004b000016a60000c13d0000068e0010009c000015e80000413d0000068e0110012a000000000014041b000000060200002900000000001204350000000a010000290000000001010433000000000051004b000016970000a13d0000000501500210000000090110002900000000006104350000000a010000290000000001010433000000000051004b000016970000a13d000000060100002900000000010104330000000b0010002a000016a60000413d0000000b021000290000000105500039000000050050006c000015210000413d0000001301000039000b00000002001d000000000021041b0000000701000039000000000101041a000300000001001d0000000002000019000016200000013d000006c20220009a000000000012041b00000000010b04330000006002a000390000000002020433000000400300043d000000200430003900000000002404350000000000130435000006340030009c000006340300804100000040013002100000000002000414000006340020009c0000063402008041000000c002200210000000000112019f0000068d011001c70000800d020000390000000203000039000006e604000041000000000509001918cd18c30000040f0000000100200190000016a40000613d00000008020000290000000102200039000000050020006c000016930000813d0000000a010000290000000001010433000000000021004b000016970000a13d0000000801000039000000000101041a000000000021004b000016970000a13d000800000002001d0000000501200210000000090110002900000000020104330000000801000039000000000010043f000600000002001d0000000012020434000700000002001d000400000001001d000006900100004100000000001004430000000001000414000006340010009c0000063401008041000000c00110021000000691011001c70000800b0200003918cd18c80000040f0000000100200190000016a30000613d000000000101043b000000070010006c0000161c0000a13d00000008090000290000000a029000c9000000060a0000290000004003a000390000000003030433000000000003004b000000040b000029000016030000613d00000000040b0433000000000004004b000016030000613d0000000b05000039000000000505041a000000000015004b00000000060100190000000006054019000000000005004b000000000601601900000000050004150000000d0550008a000000050550021000000000070a0433000000000776004b0000000006000019000016740000a13d0000068e067000d100000000057600d90000068e0050009c000016a60000c13d00000000050004150000000d0550008a0000000505500210000000000006004b000016730000613d00000003076000b900000000056700d9000000030050006c000016a60000c13d00000000050004150000000c0550008a0000000505500210000000000007004b000016890000613d00000000050004150000000c0550008a000000050550021000000000067400a900000000077600d9000000000047004b000016740000613d000016a60000013d00000000060000190000000b04000029000000000004004b0000168d0000613d00000000044600d90000000505500270000000000504001f0000068e0640012a000006bd0520009a000000000705041a000000000067001a000016a60000413d0000000006670019000000000065041b00000000043400d9000006a40320009a000000000503041a000000000045001a000016a60000413d0000000004450019000000000043041b000016030000013d00000000060000190000000b04000029000000000004004b000016770000c13d000006dc01000041000000000010043f0000001201000039000000040010043f0000063d01000041000018cf00010430000000000001042d0000001301000039000000000001041b000000000001042d000006dc01000041000000000010043f0000003201000039000000040010043f0000063d01000041000018cf00010430000006dc01000041000000000010043f0000004101000039000000040010043f0000063d01000041000018cf00010430000000000001042f0000000001000019000018cf00010430000006dc01000041000000000010043f0000001101000039000000040010043f0000063d01000041000018cf000104300000001f0530018f0000063606300198000000400200043d0000000004620019000016b70000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000016b30000c13d000000000005004b000016c40000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f00000000001404350000006001300210000006340020009c00000634020080410000004002200210000000000112019f000018cf0001043000010000000000020000000b01000039000000000101041a000000000001004b000016e10000613d000100000001001d000006900100004100000000001004430000000001000414000006340010009c0000063401008041000000c00110021000000691011001c70000800b0200003918cd18c80000040f0000000100200190000016e30000613d000000000101043b000000010010006c00000000010000390000000101002039000000010110018f000000000001042d000000010100018f000000000001042d000000000001042f000000000100041a00000637021001970000000001000411000000000012004b000016ea0000c13d000000000001042d0000068f02000041000000000020043f000000040010043f0000063d01000041000018cf0001043000080000000000020000000803000039000000000203041a000000000012004b000017670000a13d000000000030043f000100000001001d0000000a011000c90000001302000039000000000202041a000300000002001d000006c20210009a000000000202041a000200000002001d000006c60210009a000000000202041a000400000002001d000006bd0210009a000000000202041a000600000002001d000006a40110009a000000000101041a000500000001001d000006900100004100000000001004430000000001000414000006340010009c0000063401008041000000c00110021000000691011001c70000800b0200003918cd18c80000040f00000001002001900000176d0000613d000000000401043b0000000205000029000000000054004b00000006020000290000173a0000a13d000000040000006b0000173a0000613d000000030000006b0000173a0000613d0000000b01000039000000000101041a000000000041004b00000000030400190000000003014019000000000001004b000000000403c0190000000001000415000000080110008a0000000501100210000000000354004b00000000040000190000173d0000a13d0000068e023000d100000000013200d90000068e0010009c000017610000c13d0000000001000415000000070110008a0000000501100210000000000002004b0000173c0000613d0000000001000415000000070110008a00000005011002100000000703000039000000000303041a00000000042300a900000000022400d9000000000032004b0000173d0000613d000017610000013d0000000501000029000000000001042d00000000040000190000000501100270000200000004001d000000000104001f0000000101000029000000000010043f0000001201000039000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f00000001002001900000176e0000613d000000000101043b000000000401041a000000020300002900000000013400a9000000000003004b0000000602000029000017570000613d00000000033100d9000000000043004b000017610000c13d00000003031000fa0000068e0130012a000000000021001a000017610000413d00000004033000fa000000050030002a000017610000413d00000000022100190000000501300029000000000001042d000006dc01000041000000000010043f0000001101000039000000040010043f0000063d01000041000018cf00010430000006dc01000041000000000010043f0000003201000039000000040010043f0000063d01000041000018cf00010430000000000001042f0000000001000019000018cf000104300002000000000002000200000002001d000100000001001d000000000010043f0000000901000039000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f0000000100200190000017a40000613d000000000101043b00000002020000290000063702200197000000000020043f000000200010043f0000000001000414000006340010009c0000063401008041000000c0011002100000068d011001c7000080100200003918cd18c80000040f0000000100200190000017a40000613d000000000101043b000200000001001d000000010100002918cd16ef0000040f0000000204000029000000000304041a00000000023100a9000000000003004b000017990000613d00000000033200d9000000000013004b000017a60000c13d0000068e0120012a0000000302400039000000000202041a000000000012001a000017a60000413d00000000011200190000000402400039000000000202041a000000000121004b000017a60000413d000000000001042d0000000001000019000018cf00010430000006dc01000041000000000010043f0000001101000039000000040010043f0000063d01000041000018cf00010430000400000000000200000000340204340000000002000414000006370a1001970000000400a0008c000017dd0000c13d0000000101000032000018180000613d000006e40010009c000018730000813d0000001f03100039000006e1033001970000003f03300039000006e103300197000000400b00043d00000000033b00190000000000b3004b00000000040000390000000104004039000006890030009c000018730000213d0000000100400190000018730000c13d000000400030043f00000000051b0436000006e1021001980000001f0310018f00000000012500190000000304000367000017cf0000613d000000000604034f000000006706043c0000000005750436000000000015004b000017cb0000c13d000000000003004b000018190000613d000000000224034f0000000303300210000000000401043300000000043401cf000000000434022f000000000202043b0000010003300089000000000232022f00000000023201cf000000000242019f0000000000210435000018190000013d000006340040009c00000634040080410000006001400210000006340030009c00000634030080410000004003300210000000000131019f000006340020009c0000063402008041000000c002200210000000000121019f00020000000a001d00000000020a001918cd18c30000040f00030000000103550000006003100270000106340030019d00000634043001980000183b0000613d0000001f0340003900000635033001970000003f03300039000006ab03300197000000400b00043d00000000033b00190000000000b3004b00000000050000390000000105004039000006890030009c000000020a000029000018730000213d0000000100500190000018730000c13d000000400030043f0000001f0540018f00000000034b0436000006360640019800000000046300190000180a0000613d000000000701034f0000000008030019000000007907043c0000000008980436000000000048004b000018060000c13d000000000005004b0000183e0000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f00000000001404350000183e0000013d000000600b0000390000000002000415000000040220008a000000050220021000000000010b0433000000000001004b000018460000c13d00010000000b001d00020000000a001d00000699010000410000000000100443000000040100003900000004001004430000000001000414000006340010009c0000063401008041000000c0011002100000069a011001c7000080020200003918cd18c80000040f0000000100200190000018840000613d0000000002000415000000040220008a0000000502200210000000000101043b000000000001004b000000010b0000290000185d0000c13d000006e801000041000000000010043f0000000401000039000000040010043f0000063d01000041000018cf00010430000000600b0000390000008003000039000000020a00002900000000010b043300000001002001900000187e0000613d0000000002000415000000030220008a0000000502200210000000000001004b000018490000613d000000050220027000000000020b001f000018630000013d00010000000b001d000006990100004100000000001004430000000400a004430000000001000414000006340010009c0000063401008041000000c0011002100000069a011001c7000080020200003918cd18c80000040f0000000100200190000018840000613d0000000002000415000000030220008a0000000502200210000000000101043b000000000001004b000000010b0000290000188d0000613d00000000010b0433000000050220027000000000020b001f000000000001004b000000020a000029000018700000613d000006cd0010009c000018710000213d0000001f0010008c000018710000a13d0000002001b000390000000001010433000000000001004b0000000002000039000000010200c039000000000021004b000018710000c13d000000000001004b000018790000613d000000000001042d0000000001000019000018cf00010430000006dc01000041000000000010043f0000004101000039000000040010043f0000063d01000041000018cf00010430000006e901000041000000000010043f0000000400a0043f0000063d01000041000018cf00010430000000000001004b000018850000c13d000006e701000041000000000010043f0000069801000041000018cf00010430000000000001042f000006340030009c00000634030080410000004002300210000006340010009c00000634010080410000006001100210000000000121019f000018cf00010430000006e801000041000000000010043f0000000201000029000000040010043f0000063d01000041000018cf00010430000000000001042f000006340010009c000006340100804100000060011002100000000002000414000006340020009c0000063402008041000000c002200210000000000112019f00000639011001c7000080100200003918cd18c80000040f0000000100200190000018a30000613d000000000101043b000000000001042d0000000001000019000018cf0001043000000000050100190000000000200443000000050030008c000018b30000413d000000040100003900000000020000190000000506200210000000000664001900000005066002700000000006060031000000000161043a0000000102200039000000000031004b000018ab0000413d000006340030009c000006340300804100000060013002100000000002000414000006340020009c0000063402008041000000c002200210000000000112019f000006ea011001c7000000000205001918cd18c80000040f0000000100200190000018c20000613d000000000101043b000000000001042d000000000001042f000018c6002104210000000102000039000000000001042d0000000002000019000000000001042d000018cb002104230000000102000039000000000001042d0000000002000019000000000001042d000018cd00000432000018ce0001042e000018cf0001043000000000000000000000000000000000000000000000000000000000ffffffff00000000000000000000000000000000000000000000000000000001ffffffe000000000000000000000000000000000000000000000000000000000ffffffe0000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000008be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e000000002000000000000000000000000000000c00000010000000000000000001e4fbdf70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000240000000000000000000000000000000000000000000000000000000000000000000000000000000076affe6900000000000000000000000000000000000000000000000000000000b092145d00000000000000000000000000000000000000000000000000000000e198a86200000000000000000000000000000000000000000000000000000000eaac8c3100000000000000000000000000000000000000000000000000000000fb8d81f000000000000000000000000000000000000000000000000000000000fb8d81f100000000000000000000000000000000000000000000000000000000fff52ee800000000000000000000000000000000000000000000000000000000eaac8c3200000000000000000000000000000000000000000000000000000000f2fde38b00000000000000000000000000000000000000000000000000000000e198a86300000000000000000000000000000000000000000000000000000000e30c397800000000000000000000000000000000000000000000000000000000e78cea9200000000000000000000000000000000000000000000000000000000d4c3ee9f00000000000000000000000000000000000000000000000000000000db290f2000000000000000000000000000000000000000000000000000000000db290f2100000000000000000000000000000000000000000000000000000000de26c3c600000000000000000000000000000000000000000000000000000000d4c3eea000000000000000000000000000000000000000000000000000000000d69efdc500000000000000000000000000000000000000000000000000000000b092145e00000000000000000000000000000000000000000000000000000000beece24b00000000000000000000000000000000000000000000000000000000cf54d9a900000000000000000000000000000000000000000000000000000000933f395700000000000000000000000000000000000000000000000000000000a01892a400000000000000000000000000000000000000000000000000000000a8a77a1800000000000000000000000000000000000000000000000000000000a8a77a1900000000000000000000000000000000000000000000000000000000ad88a17e00000000000000000000000000000000000000000000000000000000a01892a500000000000000000000000000000000000000000000000000000000a04a4d5300000000000000000000000000000000000000000000000000000000933f39580000000000000000000000000000000000000000000000000000000093f1a40b0000000000000000000000000000000000000000000000000000000099d8f74a000000000000000000000000000000000000000000000000000000007a94c067000000000000000000000000000000000000000000000000000000007a94c06800000000000000000000000000000000000000000000000000000000885dba1d000000000000000000000000000000000000000000000000000000008da5cb5b0000000000000000000000000000000000000000000000000000000076affe6a0000000000000000000000000000000000000000000000000000000078d849ed0000000000000000000000000000000000000000000000000000000079ba5097000000000000000000000000000000000000000000000000000000003fdb1e8e0000000000000000000000000000000000000000000000000000000060246c87000000000000000000000000000000000000000000000000000000006b1033c3000000000000000000000000000000000000000000000000000000006f52daae000000000000000000000000000000000000000000000000000000006f52daaf00000000000000000000000000000000000000000000000000000000715018a6000000000000000000000000000000000000000000000000000000006b1033c4000000000000000000000000000000000000000000000000000000006e910bfd0000000000000000000000000000000000000000000000000000000060246c8800000000000000000000000000000000000000000000000000000000606ce3bf00000000000000000000000000000000000000000000000000000000630b5ba100000000000000000000000000000000000000000000000000000000441a3e6f000000000000000000000000000000000000000000000000000000005aac4a20000000000000000000000000000000000000000000000000000000005aac4a21000000000000000000000000000000000000000000000000000000005c60da1b00000000000000000000000000000000000000000000000000000000441a3e700000000000000000000000000000000000000000000000000000000056b0f5b6000000000000000000000000000000000000000000000000000000003fdb1e8f0000000000000000000000000000000000000000000000000000000042cbb15c000000000000000000000000000000000000000000000000000000004310d4450000000000000000000000000000000000000000000000000000000017caf6f00000000000000000000000000000000000000000000000000000000026076f960000000000000000000000000000000000000000000000000000000030cdb3c50000000000000000000000000000000000000000000000000000000030cdb3c600000000000000000000000000000000000000000000000000000000396f7b230000000000000000000000000000000000000000000000000000000026076f97000000000000000000000000000000000000000000000000000000002d25a23d0000000000000000000000000000000000000000000000000000000017caf6f1000000000000000000000000000000000000000000000000000000001abbeb54000000000000000000000000000000000000000000000000000000001e1c6a070000000000000000000000000000000000000000000000000000000012863f010000000000000000000000000000000000000000000000000000000012863f02000000000000000000000000000000000000000000000000000000001526fe270000000000000000000000000000000000000000000000000000000015ba56e50000000000000000000000000000000000000000000000000000000000aeef8a00000000000000000000000000000000000000000000000000000000081e3eda00000000000000000000000000000000000000000000000000000000083c6323000000000000000000000000000000000000000000000000ffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0000000000000000000000000000000000000000000000000ffffffffffffff7f00000000000000000000000000000000000000000000003fffffffffffffffe002000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a7640000118cdaa70000000000000000000000000000000000000000000000000000000042cbb15ccdc3cad6266b0e7a08c0454b23bf29dc2df74b6f3c209e9336465bd1020000020000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000003627e8f712373c0000b48e36a0869514773506a41441177faf21ebdda362731b7363ee174f3a00772838d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e227008da5cb5b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000080000000000000000082b429000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000001806aa1896bbf26568e884a7374b41e002500962caba6a15023a8d90e8508b83020000020000000000000000000000000000002400000000000000000000000015ba56e5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000800000000000000000310ab089e4439a4c15d089f94afb7896ff553aecb10793d0ab882de59d99a32e0200000200000000000000000000000000000044000000000000000000000000f84de9bf00000000000000000000000000000000000000000000000000000000496e76616c696420706f6f6c206964000000000000000000000000000000000008c379a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006400000000000000000000000062616c616e63657320646f6e2774206d617463680000000000000000000000000c085601c9b05546c4de925af5cdebeab0dd5f5d4bea4dc57b37e961749c91160000000000000000000000000000000000000020000000000000000000000000756e617574686f72697a656400000000000000000000000000000000000000000c085601c9b05546c4de925af5cdebeab0dd5f5d4bea4dc57b37e961749c911d70a08231000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000002da10a1e27bf85cedd8ffb1abbe97e53391c029500000000000000000000000000000000000000000000000000000003ffffffe0696e76616c696420706f6f6c20616d6f756e740000000000000000000000000002000000000000000000000000000000000000200000000000000000000000002054ed6425ba3fec34091e25c5bc8099357b522ba2f4ec2d26403fa7628f4fc1696e76616c6964204220616d6f756e7400000000000000000000000000000000696e76616c6964204120616d6f756e740000000000000000000000000000000067f679e13fe9dca16f3079221965ec41838cb8881cbc0f440bc13507c6b214c2f48e3c260000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003635c9adc5dea00001ffffffffffffffffffffffffffffffffffffffffffffffc9d81708edc8c3ffff000000000000000000000000000000000000000000000000fffffffffffffebfc264f49177bdbe55a01fae0e77c3fdc75d515d242b32bc4d56c565f5b47865bad92e233d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000800000000000000000000000000000000000000000000000000000000000000000ffffffffffffff5f00000000000000000000000000000000000000a00000000000000000000000008000000000000000000000000000000000000000000000000000000000000000ea0f5562000000000000000000000000000000000000000000000000000000000c085601c9b05546c4de925af5cdebeab0dd5f5d4bea4dc57b37e961749c9115a9059cbb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffc9d81708edc8c3fffeede31886000000000000000000000000000000000000000000000000000000000c085601c9b05546c4de925af5cdebeab0dd5f5d4bea4dc57b37e961749c91179eca8f7bcfb868d72b4ed95b71c627c194ab6bcb9b83adb2280e8a0320bb8476000000000000000000000000000000000000000000000000fffffffffffffe3f0c085601c9b05546c4de925af5cdebeab0dd5f5d4bea4dc57b37e961749c911c0c085601c9b05546c4de925af5cdebeab0dd5f5d4bea4dc57b37e961749c911b0c085601c9b05546c4de925af5cdebeab0dd5f5d4bea4dc57b37e961749c911a0c085601c9b05546c4de925af5cdebeab0dd5f5d4bea4dc57b37e961749c91190c085601c9b05546c4de925af5cdebeab0dd5f5d4bea4dc57b37e961749c91180c085601c9b05546c4de925af5cdebeab0dd5f5d4bea4dc57b37e961749c91140000000000000000000000000000000000000000000000000000000000015180095ea7b3000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff15e34e0500000000000000000000000000000000000000000000000000000000bc53949c00000000000000000000000000000000000000000000000000000000f279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568214671ad000000000000000000000000000000000000000000000000000000001e110c234a3519983cc1a5dc771c3648cfb2118072924b096d56566097b2251b061008d1000000000000000000000000000000000000000000000000000000000e2d25f1d1094599e7ad7c5abf20c243dd116941d455eb79616135defbc6fb9b9c8787c0000000000000000000000000000000000000000000000000000000002f352531000000000000000000000000000000000000000000000000000000008cd22d1900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001517f7bd4747600000000000000000000000000000000000000000000000000000000eb7a7d62743daf8cf4055aea544d0a89e2011279ed4105567d010759e6fa4de2000000000000000000000000000000000000000000000000ffffffffffffff804e487b710000000000000000000000000000000000000000000000000000000023b872dd00000000000000000000000000000000000000000000000000000000442400af0000000000000000000000000000000000000000000000000000000036af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1eb2e532de00000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000001000000000000000041976e090000000000000000000000000000000000000000000000000000000017b8644f386d1c7c7138ef98b3c8035622bbe94d7be9b26f71d2654a547c29431425ea42000000000000000000000000000000000000000000000000000000009996b315000000000000000000000000000000000000000000000000000000005274afe7000000000000000000000000000000000000000000000000000000000200000200000000000000000000000000000000000000000000000000000000
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000a24f69faa295426bca2cf610bf992cdc992ceea00000000000000000000000002edf18b640a705f16947a7b95fc338fde340dd48
-----Decoded View---------------
Arg [0] : _MERKLE (address): 0xa24F69fAA295426Bca2Cf610bf992CDc992CeEa0
Arg [1] : _priceFeeds (address): 0x2eDf18b640A705F16947A7B95Fc338fde340Dd48
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000a24f69faa295426bca2cf610bf992cdc992ceea0
Arg [1] : 0000000000000000000000002edf18b640a705f16947a7b95fc338fde340dd48
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.