Overview
SOPH Balance
0 SOPH
SOPH Value
-More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Become Implement... | 814886 | 4 days ago | IN | 0 SOPH | 0.38319095 |
Latest 1 internal transaction
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
814793 | 4 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); 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 InvalidBooster(); error InvalidPointsPerBlock(); error InvalidTransfer(); error WithdrawNotAllowed(); error WithdrawTooHigh(uint256 maxAllowed); error WithdrawIsZero(); error NothingInPool(); error NoEthSent(); error BoostTooHigh(uint256 maxAllowed); error BoostIsZero(); error BridgeInvalid(); error OnlyMerkle(); address public immutable MERKLE; IPriceFeeds public immutable priceFeeds; /** * @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); } // Order is important function addPool( uint256 _pid, IERC20 _lpToken, address _l2Farm, uint256 _amount, uint256 _boostAmount, uint256 _depositAmount, uint256 _allocPoint, uint256 _lastRewardBlock, uint256 _accPointsPerShare, uint256 _totalRewards, string memory _description, uint256 _heldProceeds ) public onlyOwner { require(_amount == _boostAmount + _depositAmount, "balances don't match"); PoolInfo memory newPool = PoolInfo({ lpToken: _lpToken, l2Farm: _l2Farm, amount: _amount, boostAmount: _boostAmount, depositAmount: _depositAmount, allocPoint: 0, lastRewardBlock: _lastRewardBlock, accPointsPerShare: 0, totalRewards: _totalRewards, description: _description }); if (_pid < poolInfo.length) { PoolInfo storage existingPool = poolInfo[_pid]; require(existingPool.lpToken == _lpToken, "Pool LP token mismatch"); // Update the pool poolInfo[_pid] = newPool; } else if (_pid == poolInfo.length) { // Add new pool poolInfo.push(newPool); } else { revert("wrong pid"); } heldProceeds[_pid] = _heldProceeds; poolExists[address(_lpToken)] = true; } /** * @notice Withdraw heldProceeds for a given pool * @param _pid The pool ID to withdraw from * @param _to The address that will receive the tokens */ function withdrawHeldProceeds(uint256 _pid, address _to) external onlyOwner { if (_to == address(0)) revert ZeroAddress(); uint256 amount = heldProceeds[_pid]; if (amount == 0) revert NothingInPool(); // Transfer the tokens to the specified address poolInfo[_pid].lpToken.safeTransfer(_to, amount); // Reset the mapping for that pid heldProceeds[_pid] = 0; emit WithdrawHeldProceeds(_pid, _to, amount); } function updateUserInfo(address _user, uint256 _pid, UserInfo memory _userFromClaim) public { if (msg.sender != MERKLE) revert OnlyMerkle(); require(_pid < poolInfo.length, "Invalid pool id"); require(_userFromClaim.amount == _userFromClaim.boostAmount + _userFromClaim.depositAmount, "balances don't match"); PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][_user]; massUpdatePools(); uint256 userAmount = user.amount; user.rewardSettled = user.amount * pool.accPointsPerShare / 1e18 + user.rewardSettled - user.rewardDebt; user.rewardSettled = user.rewardSettled + _userFromClaim.rewardSettled; user.boostAmount = user.boostAmount + _userFromClaim.boostAmount; pool.boostAmount = pool.boostAmount + _userFromClaim.boostAmount; user.depositAmount = user.depositAmount + _userFromClaim.depositAmount; pool.depositAmount = pool.depositAmount + _userFromClaim.depositAmount; user.amount = user.amount + _userFromClaim.amount; pool.amount = pool.amount + _userFromClaim.amount; user.rewardDebt = user.amount * pool.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(); } _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 Set booster multiplier * @param _boosterMultiplier booster multiplier to set */ function setBoosterMultiplier(uint256 _boosterMultiplier) virtual external onlyOwner { if (_boosterMultiplier < 1e18 || _boosterMultiplier > 10e18) { revert InvalidBooster(); } if (isFarmingEnded()) { revert FarmingIsEnded(); } massUpdatePools(); boosterMultiplier = _boosterMultiplier; } /** * @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(); } if (_boostAmount > _depositAmount) { revert BoostTooHigh(_depositAmount); } PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; massUpdatePools(); uint256 userAmount = user.amount; user.rewardSettled = userAmount * pool.accPointsPerShare / 1e18 + user.rewardSettled - user.rewardDebt; // booster purchase proceeds heldProceeds[_pid] = heldProceeds[_pid] + _boostAmount; // deposit amount is reduced by amount of the deposit to boost _depositAmount = _depositAmount - _boostAmount; // set deposit amount user.depositAmount = user.depositAmount + _depositAmount; pool.depositAmount = pool.depositAmount + _depositAmount; // apply the boost multiplier _boostAmount = _boostAmount * boosterMultiplier / 1e18; user.boostAmount = user.boostAmount + _boostAmount; pool.boostAmount = pool.boostAmount + _boostAmount; // userAmount is increased by remaining deposit amount + full boosted amount userAmount = userAmount + _depositAmount + _boostAmount; user.amount = userAmount; pool.amount = pool.amount + _depositAmount + _boostAmount; user.rewardDebt = userAmount * pool.accPointsPerShare / 1e18; emit Deposit(msg.sender, _pid, _depositAmount, _boostAmount); } /** * @notice Increase boost from existing deposits * @param _pid pid to pool * @param _boostAmount amount to boost */ function increaseBoost(uint256 _pid, uint256 _boostAmount) external { if (isFarmingEnded()) { revert FarmingIsEnded(); } if (_boostAmount == 0) { revert BoostIsZero(); } uint256 maxAdditionalBoost = getMaxAdditionalBoost(msg.sender, _pid); if (_boostAmount > maxAdditionalBoost) { revert BoostTooHigh(maxAdditionalBoost); } PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; massUpdatePools(); uint256 userAmount = user.amount; user.rewardSettled = userAmount * pool.accPointsPerShare / 1e18 + user.rewardSettled - user.rewardDebt; // booster purchase proceeds heldProceeds[_pid] = heldProceeds[_pid] + _boostAmount; // user's remaining deposit is reduced by amount of the deposit to boost user.depositAmount = user.depositAmount - _boostAmount; pool.depositAmount = pool.depositAmount - _boostAmount; // apply the multiplier uint256 finalBoostAmount = _boostAmount * boosterMultiplier / 1e18; user.boostAmount = user.boostAmount + finalBoostAmount; pool.boostAmount = pool.boostAmount + finalBoostAmount; // user amount is increased by the full boosted amount - deposit amount used to boost userAmount = userAmount + finalBoostAmount - _boostAmount; user.amount = userAmount; pool.amount = pool.amount + finalBoostAmount - _boostAmount; user.rewardDebt = userAmount * pool.accPointsPerShare / 1e18; emit IncreaseBoost(msg.sender, _pid, finalBoostAmount); } /** * @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 userInfo[_pid][_user].depositAmount; } /** * @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(); } PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; massUpdatePools(); 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(); } PoolInfo storage pool = poolInfo[_pid]; if (address(pool.lpToken) == address(0)) { revert PoolDoesNotExist(); } massUpdatePools(); 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); } /** * @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(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; }
// 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":"BoostIsZero","type":"error"},{"inputs":[{"internalType":"uint256","name":"maxAllowed","type":"uint256"}],"name":"BoostTooHigh","type":"error"},{"inputs":[],"name":"BridgeInvalid","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[],"name":"FarmingIsEnded","type":"error"},{"inputs":[],"name":"FarmingIsStarted","type":"error"},{"inputs":[],"name":"InvalidBooster","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":"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":"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":"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":"uint256","name":"_heldProceeds","type":"uint256"}],"name":"addPool","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":"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":"_pid","type":"uint256"},{"internalType":"uint256","name":"_boostAmount","type":"uint256"}],"name":"increaseBoost","outputs":[],"stateMutability":"nonpayable","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":"_boosterMultiplier","type":"uint256"}],"name":"setBoosterMultiplier","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":[],"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"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_to","type":"address"}],"name":"withdrawHeldProceeds","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
9c4d535b000000000000000000000000000000000000000000000000000000000000000001000683a4677180b4bbc6029b5522118cd499ec03c97340828ee0273c5e01db00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000040000000000000000000000000a24f69faa295426bca2cf610bf992cdc992ceea00000000000000000000000002edf18b640a705f16947a7b95fc338fde340dd48
Deployed Bytecode
0x000400000000000200160000000000020000006004100270000005da0340019700030000003103550002000000010355000005da0040019d0000000100200190000000300000c13d0000008004000039000000400040043f000000040030008c000008ea0000413d000000000201043b000000e002200270000005e40020009c0000005f0000a13d000005e50020009c000000d40000213d000005f70020009c000001090000a13d000005f80020009c000001690000a13d000005f90020009c000002cb0000213d000005fc0020009c000004100000613d000005fd0020009c000008ea0000c13d000000240030008c000008ea0000413d0000000002000416000000000002004b000008ea0000c13d0000000401100370000000000101043b000000000010043f0000001201000039000000200010043f0000004001000039176217290000040f0000000102100039000000000202041a000000000101041a000000800010043f000000a00020043f0000065401000041000017630001042e0000000002000416000000000002004b000008ea0000c13d0000001f02300039000005db02200197000000c002200039000000400020043f0000001f0430018f000005dc05300198000000c002500039000000410000613d000000c006000039000000000701034f000000007807043c0000000006860436000000000026004b0000003d0000c13d000000000004004b0000004e0000613d000000000151034f0000000304400210000000000502043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f0000000000120435000000400030008c000008ea0000413d000000c00100043d000005dd0010009c000008ea0000213d000000e00200043d001100000002001d000005dd0020009c000008ea0000213d0000000006000411000000000006004b0000014a0000c13d000005e201000041000000000010043f000000040000043f000005e3010000410000176400010430000006080020009c000000fa0000a13d000006090020009c0000011c0000a13d0000060a0020009c000001cb0000a13d0000060b0020009c000003b10000213d0000060e0020009c0000041e0000613d0000060f0020009c000008ea0000c13d000000640030008c000008ea0000413d0000000002000416000000000002004b000008ea0000c13d0000000402100370000000000202043b000005dd0020009c000008ea0000213d0000002404100370000000000404043b000006290040009c000008ea0000213d0000002305400039000000000035004b000008ea0000813d0000000405400039000000000551034f000000000605043b000006290060009c000009550000213d00000005056002100000003f075000390000062a077001970000062b0070009c000009550000213d0000008007700039000000400070043f000000800060043f00000024044000390000000005450019000000000035004b000008ea0000213d000000000006004b000000980000613d0000008003000039000000000641034f000000000606043b000005dd0060009c000008ea0000213d000000200330003900000000006304350000002004400039000000000054004b0000008f0000413d0000004401100370000000000301043b000000000003004b0000000001000039000000010100c039001000000003001d000000000013004b000008ea0000c13d000000000100041a000005dd031001970000000001000411000000000013004b000008440000c13d000005dd01200197000000000010043f0000001101000039000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000008ea0000613d000000000101043b000f00000001001d000000800100043d000000000001004b0000078f0000613d0000000004000019001100000004001d0000000501400210000000a0011000390000000001010433000005dd01100197000000000010043f0000000f01000029000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f00000011040000290000000100200190000008ea0000613d000000000101043b000000000201041a000006770220019700000010022001af000000000021041b0000000104400039000000800100043d000000000014004b000000b80000413d0000078f0000013d000005e60020009c000001290000a13d000005e70020009c0000020f0000a13d000005e80020009c000003ba0000213d000005eb0020009c000004240000613d000005ec0020009c000008ea0000c13d000000240030008c000008ea0000413d0000000002000416000000000002004b000008ea0000c13d0000000401100370000000000601043b000005dd0060009c000008ea0000213d000000000100041a000005dd011001970000000005000411000000000051004b000008550000c13d0000000101000039000000000201041a000005de02200197000000000262019f000000000021041b0000000001000414000005da0010009c000005da01008041000000c001100210000005df011001c70000800d02000039000000030300003900000638040000410000078c0000013d0000061a0020009c000001360000213d000006220020009c0000021a0000213d000006260020009c000004390000613d000006270020009c000004790000613d000006280020009c000008ea0000c13d0000000001000416000000000001004b000008ea0000c13d0000000b010000390000076b0000013d000006010020009c000002440000213d000006050020009c0000047e0000613d000006060020009c000004960000613d000006070020009c000008ea0000c13d0000000001000416000000000001004b000008ea0000c13d0000000001000412001500000001001d001400200000003d000080050100003900000044030000390000000004000415000000150440008a0000041a0000013d000006130020009c0000024f0000213d000006170020009c000005180000613d000006180020009c000005240000613d000006190020009c000008ea0000c13d0000000001000416000000000001004b000008ea0000c13d00000007010000390000076b0000013d000005f00020009c0000027b0000213d000005f40020009c000005290000613d000005f50020009c0000053f0000613d000005f60020009c000008ea0000c13d0000000001000416000000000001004b000008ea0000c13d0000000e010000390000076b0000013d0000061b0020009c000002860000213d0000061f0020009c000005680000613d000006200020009c0000056d0000613d000006210020009c000008ea0000c13d000000240030008c000008ea0000413d0000000002000416000000000002004b000008ea0000c13d0000000401100370000000000101043b000005dd0010009c000008ea0000213d000000000010043f0000000d01000039000005a80000013d001000000001001d0000000101000039000000000201041a000005de02200197000000000021041b000000000100041a000005de02100197000000000262019f000000000020041b0000000002000414000005dd05100197000005da0020009c000005da02008041000000c001200210000005df011001c70000800d020000390000000303000039000005e004000041176217580000040f00000010010000290000000100200190000008ea0000613d000000000001004b000001650000613d000000800010043f000000110000006b000008490000c13d0000065301000041000000000010043f0000063c010000410000176400010430000005fe0020009c0000059f0000613d000005ff0020009c000005b20000613d000006000020009c000008ea0000c13d000000240030008c000008ea0000413d0000000002000416000000000002004b000008ea0000c13d0000000402100370000000000202043b000006290020009c000008ea0000213d0000002304200039000000000034004b000008ea0000813d0000000404200039000000000441034f000000000504043b000006290050009c000009550000213d00000005045002100000003f064000390000062a066001970000062b0060009c000009550000213d0000008006600039001000000006001d000000400060043f000000800050043f00000024022000390000000004240019000000000034004b000008ea0000213d000000000005004b000000000300001900000bc00000c13d000200000003001d00000005013002100000003f021000390000062c032001970000001002300029000000000032004b00000000030000390000000103004039000006290020009c000009550000213d0000000100300190000009550000c13d000000400020043f000000100200002900000002030000290000000005320436000000000003004b000600000005001d00000dc50000c13d000000400100043d00000020020000390000000002210436000000100300002900000000030304330000000000320435000000400410003900000005023002100000000002420019000000000003004b000003fd0000613d0000000005000019000000060d000029000001b40000013d0000000105500039000000000035004b000003fd0000813d0000000006120049000000400660008a000000000464043600000000d60d043400000000070604330000000002720436000000000007004b000001b10000613d000000000800001900000020066000390000000009060433000000000a000019000000000b020019000000009c090434000000000bcb04360000000300a0008c000000010aa00039000001c10000413d00000080022000390000000108800039000000000078004b000001bd0000413d000001b10000013d000006100020009c000005d80000613d000006110020009c000005dd0000613d000006120020009c000008ea0000c13d000000840030008c000008ea0000413d0000000002000416000000000002004b000008ea0000c13d0000006402100370000000000502043b0000004402100370000000000302043b0000002402100370000000000402043b0000000401100370000000000201043b000000000100041a000005dd011001970000000006000411000000000061004b000009170000c13d0000000b07000039000000000107041a000000000001004b001100000002001d000e00000003001d001000000004001d000001fd0000613d000d00000001001d000f00000005001d000006320100004100000000001004430000000001000414000005da0010009c000005da01008041000000c00110021000000633011001c70000800b020000391762175d0000040f0000000100200190000010cf0000613d000000000101043b0000000d0010006c0000000f0500002900000000060004110000000b0700003900000bb70000213d000000000005004b000008f00000c13d176211cc0000040f0000000801000039000000000101041a0000001102000029000000000021004b00000f2c0000a13d0000000a012000c9000f00000001001d0000064c0110009a000000000101041a000005dd0110019800000ac60000c13d0000066e01000041000000000010043f0000063c010000410000176400010430000005ed0020009c000006030000613d000005ee0020009c000006aa0000613d000005ef0020009c000008ea0000c13d0000000001000416000000000001004b000008ea0000c13d0000000f01000039000006ae0000013d000006230020009c000006b30000613d000006240020009c000006bb0000613d000006250020009c000008ea0000c13d0000000001000416000000000001004b000008ea0000c13d0000000201000039000000000201041a000005dd012001970000000006000411000000000016004b000009170000c13d001100000002001d0000000303000039000000000203041a0000000001000414000005da0010009c000005da01008041000000c001100210000005df011001c7001000000002001d000005dd052001970000800d020000390000067204000041176217580000040f0000000100200190000008ea0000613d0000001101000029000005de011001970000000202000039000000000012041b0000001001000029000005de011001970000000002000411000000000121019f0000000302000039000000000012041b0000000001000019000017630001042e000006020020009c000007100000613d000006030020009c000007290000613d000006040020009c000008ea0000c13d0000000001000416000000000001004b000008ea0000c13d000000000100041a000006af0000013d000006140020009c000007360000613d000006150020009c000007430000613d000006160020009c000008ea0000c13d000000440030008c000008ea0000413d0000000002000416000000000002004b000008ea0000c13d0000002402100370000000000302043b0000000401100370000000000201043b0000000b01000039000000000101041a000000000001004b000002750000613d000f00000001001d001100000003001d001000000002001d000006320100004100000000001004430000000001000414000005da0010009c000005da01008041000000c00110021000000633011001c70000800b020000391762175d0000040f0000000100200190000010cf0000613d000000000101043b0000000f0010006c0000001002000029000000110300002900000bb70000213d000000000003004b000008650000c13d0000066401000041000000000010043f0000063c010000410000176400010430000005f10020009c000007670000613d000005f20020009c0000076f0000613d000005f30020009c000008ea0000c13d0000000001000416000000000001004b000008ea0000c13d176215290000040f000006b70000013d0000061c0020009c000007910000613d0000061d0020009c000007c80000613d0000061e0020009c000008ea0000c13d000000440030008c000008ea0000413d0000000002000416000000000002004b000008ea0000c13d000000000200041a000005dd032001970000000002000411000000000023004b000008600000c13d0000002402100370000000000202043b001100000002001d0000000401100370000000000101043b001000000001001d176211cc0000040f0000001001000029000000000010043f0000001201000039000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f000000110000006b00000011030000290000063403006041001100000003001d0000000100200190000008ea0000613d000000000101043b0000000101100039001000000001001d000000000101041a000000400200043d0000002003200039000000110400002900000000004304350000000000120435000005da0020009c000005da0200804100000040012002100000000002000414000005da0020009c000005da02008041000000c002200210000000000112019f0000062d011001c70000800d0200003900000001030000390000066904000041176217580000040f0000000100200190000008ea0000613d00000011010000290000001002000029000000000012041b0000000001000019000017630001042e000005fa0020009c000007e20000613d000005fb0020009c000008ea0000c13d000000a40030008c000008ea0000413d0000000002000416000000000002004b000008ea0000c13d0000000402100370000000000202043b001100000002001d000005dd0020009c000008ea0000213d0000002402100370000000000202043b001000000002001d0000004402100370000000000402043b000006290040009c000008ea0000213d0000002302400039000000000032004b000008ea0000813d0000000405400039000000000251034f000000000202043b000006290020009c000009550000213d0000001f0720003900000678077001970000003f0770003900000678077001970000062b0070009c000009550000213d0000008007700039000000400070043f000000800020043f00000000042400190000002404400039000000000034004b000008ea0000213d0000002003500039000000000431034f00000678052001980000001f0620018f000000a003500039000003010000613d000000a007000039000000000804034f000000008908043c0000000007970436000000000037004b000002fd0000c13d000000000006004b0000030e0000613d000000000454034f0000000305600210000000000603043300000000065601cf000000000656022f000000000404043b0000010005500089000000000454022f00000000045401cf000000000464019f0000000000430435000000a00220003900000000000204350000008402100370000000000202043b000f00000002001d0000006401100370000000000101043b000e00000001001d000000000100041a000005dd011001970000000002000411000000000021004b000010d40000c13d000000110000006b000001650000613d0000001101000029000000000010043f0000000d01000039000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000008ea0000613d000000000101043b000000000101041a000000ff00100190000010790000c13d0000000b01000039000000000101041a000d00000001001d000000000001004b000003410000613d000006320100004100000000001004430000000001000414000005da0010009c000005da01008041000000c00110021000000633011001c70000800b020000391762175d0000040f0000000100200190000010cf0000613d000000000101043b0000000d0010006c00000bb70000213d0000000f0000006b000010980000c13d176211cc0000040f000006320100004100000000001004430000000001000414000005da0010009c000005da01008041000000c00110021000000633011001c70000800b020000391762175d0000040f0000000100200190000010cf0000613d000000000101043b000f00000001001d0000001101000029000000000010043f0000000d01000039000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000f040000290000000e0040006c0000000e0400a0290000000100200190000008ea0000613d000000000101043b000000000201041a000006770220019700000001022001bf000000000021041b000000400100043d000006510010009c000009550000213d0000000802000039000000000202041a000f00000002001d0000014002100039000000400020043f000001200210003900000080030000390000000000320435000000c00210003900000000004204350000001102000029000000000221043600000100031000390000000000030435000000e0031000390000000000030435000000a00310003900000000000304350000008003100039000000000003043500000060031000390000000000030435000000400310003900000000000304350000000000020435176214770000040f0000000f01000029000000000010043f0000001201000039000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000008ea0000613d000000100000006b00000010020000290000063402006041000000000101043b0000000101100039000000000021041b000000400100043d0000000000010435000005da0010009c000005da0100804100000040011002100000000002000414000005da0020009c000005da02008041000000c002200210000000000112019f0000064d011001c70000800d020000390000000303000039000006520400004100000011050000290000000f06000029176217580000040f0000000100200190000008ea0000613d000000400100043d0000000f020000290000000000210435000005da0010009c000005da0100804100000040011002100000064a011001c7000017630001042e0000060c0020009c000007ef0000613d0000060d0020009c000008ea0000c13d0000000001000416000000000001004b000008ea0000c13d00000006010000390000076b0000013d000005e90020009c000008030000613d000005ea0020009c000008ea0000c13d000000240030008c000008ea0000413d0000000002000416000000000002004b000008ea0000c13d0000000402100370000000000202043b000006290020009c000008ea0000213d0000002305200039000000000035004b000008ea0000813d0000000405200039000000000551034f000000000605043b000006290060009c000009550000213d00000005056002100000003f075000390000062a077001970000062b0070009c000009550000213d0000008007700039000800000007001d000000400070043f000000800060043f00000024022000390000000005250019000000000035004b000008ea0000213d000000000006004b0000000003000019000003ff0000c13d000300000003001d00000005013002100000003f021000390000062c032001970000000802300029000000000032004b00000000030000390000000103004039000006290020009c000009550000213d0000000100300190000009550000c13d000000400020043f000000080200002900000003030000290000000005320436000000000003004b000b00000005001d00000f1d0000c13d000000400100043d00000020020000390000000002210436000000080300002900000000030304330000000000320435000000400410003900000005023002100000000002420019000000000003004b00000f370000c13d0000000002120049000005fb0000013d000000000321034f000000000303043b000005dd0030009c000008ea0000213d000000200440003900000000003404350000002002200039000000000052004b000003ff0000413d000000800100043d000006290010009c000009550000213d0000000002010019000000400100043d000800000001001d0000000003020019000003df0000013d0000000001000416000000000001004b000008ea0000c13d0000000001000412001300000001001d001200000000003d000080050100003900000044030000390000000004000415000000130440008a000000050440021000000641020000411762173a0000040f000006af0000013d0000000001000416000000000001004b000008ea0000c13d176211cc0000040f0000000001000019000017630001042e000000240030008c000008ea0000413d0000000002000416000000000002004b000008ea0000c13d0000000401100370000000000101043b000005dd0010009c000008ea0000213d000005dd021001970000063901000041000000800010043f0000000001000414000000040020008c001100000002001d000008bc0000c13d0000000103000031000000200030008c00000020040000390000000004034019000008e10000013d000000640030008c000008ea0000413d0000000002000416000000000002004b000008ea0000c13d0000004402100370000000000302043b0000002402100370000000000402043b0000000401100370000000000201043b0000000805000039000000000105041a000000000021004b00000f2c0000a13d001000000003001d000000000050043f000f00000002001d0000000a012000c9000e00000001001d0000064c0110009a000000000101041a0000067302000041000000a00020043f0000000002000411000000a40020043f0000000002000410000000c40020043f000000e40040043f0000006402000039000000800020043f0000012002000039000000400020043f000005dd011001970000008002000039001100000004001d176216900000040f00000011020000290000000b01000039000000000101041a000000000001004b000004730000613d000d00000001001d000006320100004100000000001004430000000001000414000005da0010009c000005da01008041000000c00110021000000633011001c70000800b020000391762175d0000040f0000000100200190000010cf0000613d000000000101043b0000000d0010006c000000110200002900000bb70000213d000000000002004b0000091c0000c13d0000067601000041000000000010043f0000063c0100004100001764000104300000000001000416000000000001004b000008ea0000c13d00000008010000390000076b0000013d0000000001000416000000000001004b000008ea0000c13d000000000100041a000005dd021001970000000005000411000000000052004b000008550000c13d0000000102000039000000000302041a000005de03300197000000000032041b000005de01100197000000000010041b0000000001000414000005da0010009c000005da01008041000000c001100210000005df011001c70000800d020000390000000303000039000005e00400004100000000060000190000078c0000013d000001840030008c000008ea0000413d0000000002000416000000000002004b000008ea0000c13d0000000402100370000000000202043b001100000002001d0000002402100370000000000402043b000005dd0040009c000008ea0000213d0000004402100370000000000202043b000005dd0020009c000008ea0000213d000000a405100370000000000705043b0000008405100370000000000605043b0000006405100370000000000505043b0000014408100370000000000908043b000006290090009c000008ea0000213d0000002308900039000000000038004b000008ea0000813d000000040a9000390000000008a1034f000000000808043b000006290080009c000009550000213d0000001f0c800039000006780cc001970000003f0cc00039000006780cc001970000062b00c0009c000009550000213d000000800cc000390000004000c0043f000000800080043f00000000098900190000002409900039000000000039004b000008ea0000213d0000002003a00039000000000931034f000006780a8001980000001f0b80018f000000a003a00039000004d10000613d000000a00c000039000000000d09034f00000000de0d043c000000000cec043600000000003c004b000004cd0000c13d00000000000b004b000004de0000613d0000000009a9034f000000030ab00210000000000b030433000000000bab01cf000000000bab022f000000000909043b000001000aa000890000000009a9022f0000000009a901cf0000000009b9019f0000000000930435000000a0038000390000000000030435000000000300041a000005dd083001970000000003000411000000000038004b00000f320000c13d000000000067001a000010fa0000413d0000000008670019000000400300043d000000000085004b000010560000c13d000006510030009c000009550000213d000005dd084001970000014004300039000000400040043f00000080043000390000000000740435000000600430003900000000006404350000004004300039000000000054043500000020043000390000000000240435001000000008001d0000000000830435000000a0023000390000000000020435000000e402100370000000000202043b000000c0043000390000000000240435000000e00230003900000000000204350000012401100370000000000101043b000001200230003900000080040000390000000000420435000001000230003900000000001204350000000801000039000000000201041a000000110020006b0000107d0000813d000000000010043f00000011010000290000000a011000c90000064c0110009a000000000201041a000005dd02200197000000100020006c000010da0000c13d0000000002000019176213c70000040f000010800000013d000000240030008c000008ea0000413d0000000002000416000000000002004b000008ea0000c13d0000000401100370000000000101043b000000020010008c000008ea0000213d000000000010043f0000000401000039000007320000013d0000000001000416000000000001004b000008ea0000c13d0000000201000039000006ae0000013d000000440030008c000008ea0000413d0000000002000416000000000002004b000008ea0000c13d0000000402100370000000000202043b000005dd0020009c000008ea0000213d0000002401100370000000000101043b001100000001001d000005dd0010009c000008ea0000213d000000000020043f0000001101000039000000200010043f0000004001000039176217290000040f0000001102000029000000000020043f000005a80000013d000000440030008c000008ea0000413d0000000002000416000000000002004b000008ea0000c13d0000000402100370000000000202043b001000000002001d0000002401100370000000000101043b001100000001001d000005dd0010009c000008ea0000213d000000000100041a000005dd021001970000000001000411000000000012004b000008440000c13d000000110000006b000001650000613d0000001001000029000000000010043f0000000501000039000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000008ea0000613d000000000101043b000000000101041a000000000001004b00000bd20000c13d0000064f01000041000000000010043f0000063c0100004100001764000104300000000001000416000000000001004b000008ea0000c13d0000000a010000390000076b0000013d000000440030008c000008ea0000413d0000000002000416000000000002004b000008ea0000c13d0000002402100370000000000402043b0000000401100370000000000301043b000000000100041a000005dd021001970000000001000411000000000012004b000008440000c13d0000000b01000039000000000101041a000000000001004b001100000003001d000005920000613d000f00000001001d001000000004001d000006320100004100000000001004430000000001000414000005da0010009c000005da01008041000000c00110021000000633011001c70000800b020000391762175d0000040f0000000100200190000010cf0000613d000000000101043b0000000f0010006c0000001103000029000000100400002900000bb70000213d000000000003004b0000000001000019000009200000c13d001000000001001d176211cc0000040f0000000b010000390000001102000029000000000021041b0000000e010000390000001002000029000000000021041b0000000001000019000017630001042e000000240030008c000008ea0000413d0000000002000416000000000002004b000008ea0000c13d0000000401100370000000000101043b000000000010043f0000001001000039000000200010043f0000004001000039176217290000040f000000000101041a000000ff001001900000000001000039000000010100c039000000800010043f0000064001000041000017630001042e000000440030008c000008ea0000413d0000000002000416000000000002004b000008ea0000c13d0000002402100370000000000202043b001100000002001d000005dd0020009c000008ea0000213d0000000401100370000000000101043b000000000010043f0000000901000039000000200010043f0000004001000039176217290000040f0000001102000029000000000020043f000000200010043f0000004001000039176217290000040f0000000402100039000000000202041a0000000303100039000000000303041a0000000204100039000000000404041a0000000105100039000000000505041a000000000101041a000000800010043f000000a00050043f000000c00040043f000000e00030043f000001000020043f0000065601000041000017630001042e0000000001000416000000000001004b000008ea0000c13d0000000301000039000006ae0000013d0000000001000416000000000001004b000008ea0000c13d0000000801000039000000000101041a000a00000001001d0000065c0010009c000009550000813d0000000a0100002900000005021002100000003f012000390000062a031001970000062b0030009c000009550000213d0000008001300039000000400010043f0000000a04000029000000800040043f000000000004004b000009340000c13d00000020020000390000000003210436000000800200043d0000000000230435000000400310003900000005042002100000000008340019000000000002004b00000a760000c13d0000000002180049000005da0020009c000005da020080410000006002200210000005da0010009c000005da010080410000004001100210000000000112019f000017630001042e000000e40030008c000008ea0000413d0000000002000416000000000002004b000008ea0000c13d0000000402100370000000000202043b001100000002001d000005dd0020009c000008ea0000213d0000002402100370000000000202043b001000000002001d0000012002000039000000400020043f0000004402100370000000000202043b000000800020043f0000006402100370000000000202043b000000a00020043f0000008402100370000000000202043b000000c00020043f000000a402100370000000000202043b000000e00020043f000000c401100370000000000101043b000001000010043f000006410100004100000000001004430000000001000412000000040010044300000024000004430000000001000414000005da0010009c000005da01008041000000c00110021000000642011001c700008005020000391762175d0000040f0000000100200190000010cf0000613d000000000101043b000005dd011001970000000002000411000000000012004b0000095b0000c13d0000000801000039000000000101041a000000100010006b00000abb0000813d000000a00100043d000000c00200043d000000000012001a000010fa0000413d0000000001120019000000800200043d000000000012004b00000c010000c13d0000001001000029000000000010043f0000000901000039000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000008ea0000613d000000000101043b0000001102000029000000000020043f000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000008ea0000613d00000010020000290010000a002000cd000000000101043b001100000001001d176211cc0000040f00000010010000290000000006010019000006310110009a000000000301041a00000011020000290000000005020019000000000402041a00000000024300a9000000000004004b0000066c0000613d00000000044200d9000000000034004b000010fa0000c13d000006340320012a0000000302500039000000000402041a000000000034001a000010fa0000413d00000000033400190000000404500039000f00000004001d000000000404041a000000000343004b000010fa0000413d000000e00400043d000000000034001a000010fa0000413d0000000003340019000000000032041b0000000103500039000000000403041a000000a00200043d000000000042001a000010fa0000413d0000000004420019000000000043041b000006480360009a000000000403041a000000000024001a000010fa0000413d0000000002240019000000000023041b0000000203500039000000000403041a000000c00200043d000000000042001a000010fa0000413d0000000004420019000000000043041b000006490360009a000000000403041a000000000024001a000010fa0000413d0000000002240019000000000023041b000000000305041a000000800200043d000000000032001a000010fa0000413d0000000003320019000000000035041b0000062f0360009a000000000403041a000000000024001a000010fa0000413d0000000002240019000000000023041b000000000201041a000000000105041a176211be0000040f000006340110012a0000000f02000029000000000012041b0000000001000019000017630001042e0000000001000416000000000001004b000008ea0000c13d0000000101000039000000000101041a000005dd01100197000000800010043f0000064001000041000017630001042e0000000001000416000000000001004b000008ea0000c13d176211a40000040f000000000001004b0000000001000039000000010100c039000007fc0000013d000000240030008c000008ea0000413d0000000002000416000000000002004b000008ea0000c13d0000000401100370000000000101043b0000000802000039000000000202041a000000000021004b000008ea0000813d176211250000040f0000000802100039000000000202041a001100000002001d0000000702100039000000000202041a001000000002001d0000000602100039000000000202041a000f00000002001d0000000502100039000000000202041a000d00000002001d0000000402100039000000000202041a000c00000002001d0000000302100039000000000202041a000b00000002001d0000000202100039000000000202041a000a00000002001d0000000102100039000000000202041a000900000002001d000000000201041a000e00000002001d0000000901100039176211450000040f0000000902000029000005dd02200197000000400400043d000900000004001d0000002003400039000000000023043500000040024000390000000a03000029000000000032043500000060024000390000000b03000029000000000032043500000080024000390000000c030000290000000000320435000000a0024000390000000d030000290000000000320435000000c0024000390000000f030000290000000000320435000000e002400039000000100300002900000000003204350000010002400039000000110300002900000000003204350000014002000039000001200340003900000000002304350000000e02000029000005dd0220019700000000002404350000014002400039176211920000040f00000009020000290000000001210049000005da0010009c000005da01008041000005da0020009c000005da0200804100000060011002100000004002200210000000000121019f000017630001042e0000000001000416000000000001004b000008ea0000c13d0000000101000039000000000201041a000005dd032001970000000006000411000000000063004b000009170000c13d000005de02200197000000000021041b000000000100041a000005de02100197000000000262019f000000000020041b0000000002000414000005dd05100197000005da0020009c000005da02008041000000c001200210000005df011001c70000800d020000390000000303000039000005e0040000410000078c0000013d000000240030008c000008ea0000413d0000000002000416000000000002004b000008ea0000c13d0000000401100370000000000101043b000000000010043f0000000501000039000000200010043f0000004001000039176217290000040f0000076b0000013d0000000001000416000000000001004b000008ea0000c13d0000800b0100003900000004030000390000000004000415000000160440008a000000050440021000000632020000411762173a0000040f000000800010043f0000064001000041000017630001042e000000440030008c000008ea0000413d0000000002000416000000000002004b000008ea0000c13d0000002402100370000000000302043b0000000401100370000000000201043b0000000e01000039000000000101041a000000000001004b0000085a0000613d000f00000001001d001100000003001d001000000002001d000006320100004100000000001004430000000001000414000005da0010009c000005da01008041000000c00110021000000633011001c70000800b020000391762175d0000040f0000000100200190000010cf0000613d000000000101043b0000000f0010006c000000100200002900000011030000290000085a0000a13d0000066501000041000000000010043f0000063c0100004100001764000104300000000001000416000000000001004b000008ea0000c13d0000001301000039000000000101041a000000800010043f0000064001000041000017630001042e000000240030008c000008ea0000413d0000000002000416000000000002004b000008ea0000c13d0000000401100370000000000601043b000005dd0060009c000008ea0000213d000000000100041a000005dd021001970000000001000411000000000012004b000008440000c13d0000000201000039000000000201041a000005de02200197000000000262019f000000000021041b0000000303000039000000000103041a0000000002000414000005dd05100197000005da0020009c000005da02008041000000c001200210000005df011001c70000800d020000390000064b04000041176217580000040f0000000100200190000008ea0000613d0000000001000019000017630001042e000000840030008c000008ea0000413d0000000002000416000000000002004b000008ea0000c13d0000000402100370000000000202043b001000000002001d0000002402100370000000000202043b001100000002001d000005dd0020009c000008ea0000213d0000004402100370000000000202043b000f00000002001d000005dd0020009c000008ea0000213d0000006401100370000000000101043b000e00000001001d0000000001000411000000000010043f0000001101000039000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000008ea0000613d000000000101043b0000001102000029000000000020043f000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000008ea0000613d000000000101043b000000000101041a000000ff0010019000000c120000c13d0000067001000041000000000010043f0000063c010000410000176400010430000000240030008c000008ea0000413d0000000002000416000000000002004b000008ea0000c13d0000000401100370000000000301043b000000000100041a000005dd021001970000000001000411000000000012004b000008440000c13d000006340130009a0000066a0010009c000008ec0000813d001100000003001d0000000b01000039000000000101041a000000000001004b0000095f0000c13d176211cc0000040f00000006010000390000001102000029000000000021041b0000000001000019000017630001042e000000440030008c000008ea0000413d0000000002000416000000000002004b000008ea0000c13d0000002402100370000000000202043b000005dd0020009c000008ea0000213d0000000401100370000000000101043b176215ea0000040f000007fc0000013d000000440030008c000008ea0000413d0000000002000416000000000002004b000008ea0000c13d0000000402100370000000000302043b000005dd0030009c000008ea0000213d0000002401100370000000000201043b0000000001030019176213a50000040f000000400200043d0000000000120435000005da0020009c000005da0200804100000040012002100000064a011001c7000017630001042e000000240030008c000008ea0000413d0000000002000416000000000002004b000008ea0000c13d0000000401100370000000000301043b000000000100041a000005dd021001970000000001000411000000000012004b000008440000c13d0000000b01000039000000000101041a000000000001004b000008240000613d001000000001001d001100000003001d000006320100004100000000001004430000000001000414000005da0010009c000005da01008041000000c00110021000000633011001c70000800b020000391762175d0000040f0000000100200190000010cf0000613d000000000101043b000000100010006c000000110300002900000bb70000213d000006340130009a000006360010009c000010d00000213d001100000003001d176211cc0000040f0000000701000039000000000101041a000000400200043d0000002003200039000000110400002900000000004304350000000000120435000005da0020009c000005da0200804100000040012002100000000002000414000005da0020009c000005da02008041000000c002200210000000000112019f0000062d011001c70000800d0200003900000001030000390000063704000041176217580000040f0000000100200190000008ea0000613d00000011010000290000000702000039000000000012041b0000000001000019000017630001042e0000063502000041000000000020043f000000040010043f000005e30100004100001764000104300000001102000029000000a00020043f0000014000000443000001600010044300000020010000390000018000100443000001a000200443000001000010044300000002010000390000012000100443000005e101000041000017630001042e0000063501000041000000000010043f000000040050043f000005e3010000410000176400010430000000000003004b000008890000c13d0000066801000041000000000010043f0000063c0100004100001764000104300000063501000041000000000010043f000000040020043f000005e3010000410000176400010430001100000003001d001000000002001d000000000020043f0000000901000039000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000008ea0000613d0000000002000411000000000101043b000005dd02200197000f00000002001d000000000020043f000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000008ea0000613d000000000101043b0000000201100039000000000101041a000000110010006b00000afc0000a13d0000066302000041000008450000013d0000000801000039000000000101041a000000000021004b00000f2c0000a13d001100000003001d001000000002001d000000000020043f0000000901000039000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000008ea0000613d000000000101043b0000000002000411000005dd02200197000000000020043f000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000008ea0000613d000000000101043b000f00000001001d176211cc0000040f0000000f01000029000000000c0100190000000203100039000000000203041a0000001104000029000006790040009c0000000007000019000000000b02001900000d0e0000613d000000000024004b00000000070000390000000107002039000000000b04001900000d0e0000a13d0000066601000041000008610000013d000005da0010009c000005da01008041000000c0011002100000063a011001c71762175d0000040f0000006003100270000005da03300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000080057001bf000008d00000613d0000008008000039000000000901034f000000009a09043c0000000008a80436000000000058004b000008cc0000c13d000000000006004b000008dd0000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f000300000001035500000001002001900000096f0000613d0000001f01400039000000600110018f00000080011001bf000000400010043f000000200030008c000008ea0000413d000000800100043d000005dd0010009c0000098d0000a13d000000000100001900001764000104300000066b01000041000000000010043f0000063c010000410000176400010430000000000100041a000005dd01100197000000000061004b000009170000c13d000000000107041a000d00000001001d000000000001004b000f00000005001d00000ba80000c13d000006340150009a000006590010009c000010d00000813d176211cc0000040f0000000701000039000000000101041a000000400200043d00000020032000390000000f0400002900000000004304350000000000120435000005da0020009c000005da0200804100000040012002100000000002000414000005da0020009c000005da02008041000000c002200210000000000112019f0000062d011001c70000800d0200003900000001030000390000063704000041176217580000040f0000000100200190000008ea0000613d0000000f010000290000000702000039000000000012041b000002000000013d0000063501000041000000000010043f000000040060043f000005e3010000410000176400010430000000100120006c000009bd0000813d0000066301000041000008610000013d001000000004001d000006320100004100000000001004430000000001000414000005da0010009c000005da01008041000000c00110021000000633011001c70000800b020000391762175d0000040f0000000100200190000010cf0000613d000000000101043b0000001102000029000000000021004b00000bbb0000a13d0000067101000041000000000010043f0000063c0100004100001764000104300000065d0030009c000009550000213d000000600300003900000000040000190000014005100039000000400050043f0000012005100039000000000035043500000100051000390000000000050435000000e0051000390000000000050435000000c0051000390000000000050435000000a0051000390000000000050435000000800510003900000000000504350000006005100039000000000005043500000040051000390000000000050435000000200510003900000000000504350000000000010435000000a00540003900000000001504350000002004400039000000000024004b00000c190000813d000000400100043d000006510010009c000009380000a13d0000066101000041000000000010043f0000004101000039000000040010043f000005e30100004100001764000104300000064301000041000000000010043f0000063c010000410000176400010430001000000001001d000006320100004100000000001004430000000001000414000005da0010009c000005da01008041000000c00110021000000633011001c70000800b020000391762175d0000040f0000000100200190000010cf0000613d000000000101043b000000100010006c000007dc0000a13d00000bb70000013d0000001f0530018f000005dc06300198000000400200043d00000000046200190000097a0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000009760000c13d000000000005004b000009870000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f00000000001404350000006001300210000005da0020009c000005da020080410000004002200210000000000112019f00001764000104300000000002000411000000000012004b00000ac20000c13d0000063d010000410000000000100443000000110100002900000004001004430000000001000414000005da0010009c000005da01008041000000c0011002100000063e011001c700008002020000391762175d0000040f0000000100200190000010cf0000613d000000000101043b000000000001004b000008ea0000613d000000400200043d0000063f01000041001000000002001d000000000012043500000000010004140000001102000029000000040020008c000009b80000613d0000001002000029000005da0020009c000005da020080410000004002200210000005da0010009c000005da01008041000000c001100210000000000121019f0000063c011001c70000001102000029176217580000040f0000006003100270000105da0030019d00030000000103550000000100200190000010660000613d00000010010000290000000002000019176211330000040f0000000001000019000017630001042e001100000001001d0000000801000039000000000101041a0000000f02000029000000000021004b00000f2c0000a13d000000000020043f0000000901000039000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000008ea0000613d000000000101043b0000000002000411000005dd02200197000000000020043f000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000008ea0000613d000000000101043b000d00000001001d176211cc0000040f0000000e01000029000006310110009a000b00000001001d000000000201041a0000000d01000029000000000301041a00000000013200a9000c00000003001d000000000003004b000009ed0000613d0000000c031000fa000000000023004b000010fa0000c13d000006340210012a0000000d010000290000000301100039000000000301041a000000000023001a000010fa0000413d00000000022300190000000d030000290000000403300039000a00000003001d000000000303041a000000000232004b000010fa0000413d000000000021041b0000000f01000029000000000010043f0000000501000039000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000008ea0000613d000000000101043b000000000201041a000900000002001d000000100020002a000010fa0000413d0000000f01000029000000000010043f0000000501000039000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000008ea0000613d00000009030000290000001002300029000000000101043b000000000021041b0000000d010000290000000201100039000000000201041a000000110020002a000010fa0000413d0000001102200029000000000021041b0000000e01000029000006490110009a000000000201041a000000110020002a000010fa0000413d0000001102200029000000000021041b0000000601000039000000000201041a00000010012000b9000000100000006b00000a340000613d00000010031000fa000000000023004b000010fa0000c13d000006340110012a0000000d020000290000000102200039000000000302041a000000000013001a000010fa0000413d0000000003130019000000000032041b0000000e02000029000006480220009a000000000302041a000000000013001a000010fa0000413d0000000003130019000000000032041b0000000c03000029000000110030002a000010fa0000413d0000000c030000290000001102300029000000000021001a000010fa0000413d00000000022100190000000d03000029000000000023041b0000000e030000290000062f0330009a000000000403041a000000110040002a000010fa0000413d0000001104400029000000000014001a000010fa0000413d0000000004140019000000000043041b0000000b03000029000000000403041a00000000032400a9000000000002004b00000a5f0000613d00000000022300d9000000000042004b000010fa0000c13d000006340230012a0000000a03000029000000000023041b000000400200043d0000002003200039000000000013043500000011010000290000000000120435000005da0020009c000005da0200804100000040012002100000000002000414000005da0020009c000005da02008041000000c002200210000000000112019f0000062d011001c70000800d020000390000000303000039000006750400004100000000050004110000000f060000290000078c0000013d000000a0040000390000014005000039000000000700001900000a820000013d0000001f0a900039000006780aa00197000000000998001900000000000904350000000008a800190000000107700039000000000027004b000005fa0000813d0000000009180049000000400990008a0000000003930436000000004904043400000000ba090434000005dd0aa00197000000000aa80436000000000b0b0433000005dd0bb001970000000000ba0435000000400a900039000000000a0a0433000000400b8000390000000000ab0435000000600a900039000000000a0a0433000000600b8000390000000000ab0435000000800a900039000000000a0a0433000000800b8000390000000000ab0435000000a00a900039000000000a0a0433000000a00b8000390000000000ab0435000000c00a900039000000000a0a0433000000c00b8000390000000000ab0435000000e00a900039000000000a0a0433000000e00b8000390000000000ab0435000001000a900039000000000a0a0433000001000b8000390000000000ab043500000120099000390000000009090433000001200a80003900000000005a0435000001400b80003900000000a909043400000000009b04350000016008800039000000000009004b00000a7a0000613d000000000b000019000000000c8b0019000000000dba0019000000000d0d04330000000000dc0435000000200bb0003900000000009b004b00000ab30000413d00000a7a0000013d000000400100043d00000044021000390000064403000041000000000032043500000024021000390000000f0300003900000c070000013d0000063b01000041000000000010043f0000063c010000410000176400010430000d00000001001d000000000010043f0000000d01000039000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000008ea0000613d000000000101043b000000000101041a000000ff001001900000020b0000613d000000100000006b00000aea0000613d0000001101000029000000000010043f0000001201000039000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000008ea0000613d000000000101043b00000001011000390000001002000029000000000021041b0000000e0000006b000010320000c13d000000400100043d0000000000010435000005da0010009c000005da0100804100000040011002100000000002000414000005da0020009c000005da02008041000000c002200210000000000112019f0000064d011001c70000800d0200003900000003030000390000065b040000410000000d0500002900000bff0000013d0000000801000039000000000101041a0000001002000029000000000021004b00000f2c0000a13d000000000020043f0000000901000039000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000008ea0000613d000000000101043b0000000f02000029000000000020043f000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000008ea0000613d0000001002000029000e000a002000cd000000000101043b000f00000001001d176211cc0000040f0000000e01000029000006310110009a000c00000001001d000000000201041a0000000f01000029000000000301041a00000000013200a9000d00000003001d000000000003004b00000b2c0000613d0000000d031000fa000000000023004b000010fa0000c13d000006340210012a0000000f010000290000000301100039000000000301041a000000000023001a000010fa0000413d00000000022300190000000f030000290000000403300039000b00000003001d000000000303041a000000000232004b000010fa0000413d000000000021041b0000001001000029000000000010043f0000000501000039000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000008ea0000613d000000000101043b000000000201041a000a00000002001d000000110020002a000010fa0000413d0000001001000029000000000010043f0000000501000039000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000008ea0000613d0000000a020000290000001102200029000000000101043b000000000021041b0000000f010000290000000201100039000000000201041a000000110220006c000010fa0000413d000000000021041b0000000e01000029000006490110009a000000000201041a000000110220006c000010fa0000413d000000000021041b0000000601000039000000000201041a00000011012000b900000011031000fa000000000023004b000010fa0000c13d000006340110012a0000000f020000290000000102200039000000000302041a000000000013001a000010fa0000413d0000000003130019000000000032041b0000000e02000029000006480220009a000000000302041a000000000013001a000010fa0000413d0000000003130019000000000032041b0000000d0010002a000010fa0000413d0000000d03100029000000110230006c000010fa0000413d0000000f04000029000000000024041b0000000e040000290000062f0440009a000000000504041a000000000015001a000010fa0000413d0000000005150019000000110550006c000010fa0000413d000000000054041b0000000c04000029000000000504041a00000000042500a9000000110030006c00000b960000613d00000000022400d9000000000052004b000010fa0000c13d000006340240012a0000000b03000029000000000023041b000000400200043d0000000000120435000005da0020009c000005da0200804100000040012002100000000002000414000005da0020009c000005da02008041000000c002200210000000000112019f0000064d011001c70000800d020000390000000303000039000006620400004100000d540000013d000006320100004100000000001004430000000001000414000005da0010009c000005da01008041000000c00110021000000633011001c70000800b020000391762175d0000040f0000000100200190000010cf0000613d000000000101043b0000000d0010006c0000000f05000029000008f90000a13d0000067401000041000000000010043f0000063c010000410000176400010430000000100020002a000010fa0000413d00000010010000290000001101100029000005950000013d0000008003000039000000000521034f000000000505043b000005dd0050009c000008ea0000213d000000200330003900000000005304350000002002200039000000000042004b00000bc10000413d000000800100043d000006290010009c000009550000213d0000000002010019000000400100043d001000000001001d0000000003020019000001900000013d000f00000001001d0000000801000039000000000201041a000000100020006c00000f2c0000a13d000000000010043f00000010010000290000000a011000c90000064c0110009a000000000101041a000005dd0110019700000011020000290000000f03000029176215430000040f0000001001000029000000000010043f0000000501000039000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000008ea0000613d000000000101043b000000000001041b000000400100043d0000000f020000290000000000210435000005da0010009c000005da0100804100000040011002100000000002000414000005da0020009c000005da02008041000000c002200210000000000112019f0000064d011001c70000800d0200003900000003030000390000064e04000041000000100500002900000011060000290000078c0000013d000000400100043d00000044021000390000064703000041000000000032043500000024021000390000001403000039000000000032043500000645020000410000000000210435000000040210003900000020030000390000000000320435000005da0010009c000005da01008041000000400110021000000646011001c700001764000104300000000f02000029000000110020006b00000d570000c13d0000066f01000041000000000010043f0000063c01000041000017640001043000000000050000190000000801000039000000000101041a000000000051004b00000f2c0000a13d000000400600043d000006510060009c000009550000213d0000014001600039000000400010043f0000000a015000c90000064c0210009a000000000202041a000005dd0220019700000000022604360000065e0310009a000000000303041a000005dd03300197000000000032043500000040026000390000062f0710009a000000000307041a0000000000320435000006480210009a000000000202041a00000060036000390000000000230435000006490210009a000000000202041a000000800360003900000000002304350000065f0210009a000000000202041a000000a0036000390000000000230435000000c0026000390000062e0810009a000000000308041a0000000000320435000000e002600039000006310910009a000000000309041a00000000003204350000010002600039000006300a10009a00000000030a041a0000000000320435000006600110009a000000000201041a0000000103200190000000010c2002700000007f0cc0618f0000001f00c0008c00000000040000390000000104002039000000000043004b000010730000c13d000000400b00043d0000000004cb0436000000000003004b001100000005001d00000c7e0000613d000800000004001d00100000000c001d00090000000b001d000b0000000a001d000c00000009001d000d00000008001d000e00000007001d000f00000006001d000000000010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000064d011001c700008010020000391762175d0000040f0000000100200190000008ea0000613d000000100c00002900000000000c004b00000c840000613d000000000201043b000000000100001900000011050000290000000f060000290000000e070000290000000d080000290000000c090000290000000b0a000029000000090b000029000000080d00002900000000031d0019000000000402041a0000000000430435000000010220003900000020011000390000000000c1004b00000c760000413d00000c8c0000013d0000067701200197000000000014043500000000000c004b0000002001000039000000000100603900000c8c0000013d000000000100001900000011050000290000000f060000290000000e070000290000000d080000290000000c090000290000000b0a000029000000090b0000290000003f0110003900000678021001970000000001b20019000000000021004b00000000020000390000000102004039000006290010009c000009550000213d0000000100200190000009550000c13d000000400010043f00000120016000390000000000b10435000000800100043d000000000051004b00000f2c0000a13d0000000501500210000000a001100039000c00000001001d0000000000610435000000800100043d000000000051004b00000f2c0000a13d0000000801000039000000000101041a000000000051004b00000f2c0000a13d0000000801000039000000000010043f000000000108041a000d00000001001d0000001301000039000000000101041a000e00000001001d000000000107041a000f00000001001d00000000010a041a001000000001001d000000000109041a000b00000001001d000006320100004100000000001004430000000001000414000005da0010009c000005da01008041000000c00110021000000633011001c70000800b020000391762175d0000040f0000000100200190000010cf0000613d000000000101043b0000000d06000029000000000061004b0000001105000029000000100400002900000d020000a13d0000000f0000006b00000d020000613d0000000e0000006b00000d020000613d0000000b02000039000000000202041a000000000012004b00000000030100190000000003024019000000000002004b000000000103c019000000000261004b000000000300001900000ce10000a13d00000634012000d100000000022100d9000006340020009c000010fa0000c13d000000000001004b00000ce00000613d0000000702000039000000000202041a00000000031200a900000000011300d9000000000021004b00000ce10000613d000010fa0000013d0000000003000019000d00000003001d000000000050043f0000001201000039000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000008ea0000613d000000000101043b000000000201041a0000000d0300002900000000013200a9000000000003004b0000001105000029000000100400002900000cf90000613d00000000033100d9000000000023004b000010fa0000c13d0000000e021000fa000006340120012a000000000041001a000010fa0000413d0000000f022000fa00000679022001670000000b0020006b000010fa0000213d0000000004410019000000800100043d000000000051004b00000f2c0000a13d0000000c0100002900000000010104330000010001100039000000000041043500000001055000390000000a0050006c00000c1a0000413d000000400100043d000005f10000013d00000010010000290000000a011000c9000006310510009a000000000805041a00000000040c041a00000000064800a9000000000004004b00000d190000613d00000000094600d9000000000089004b000010fa0000c13d000006340660012a0000000308c00039000000000908041a000000000069001a000010fa0000413d00000000096900190000000406c00039000000000a06041a0000000009a9004b000010fa0000413d000000000098041b0000000100700190000010fa0000c13d0000000002b20049000000000023041b000006490210009a000000000302041a0000000003b3004b000010fa0000413d000000000032041b0000000002b4004b000010fa0000413d00000000002c041b0000062f0310009a000000000703041a0000000007b7004b000010fa0000413d000000000073041b000000000505041a00000000032500a90000000000b4004b00000d3c0000613d00000000022300d9000000000052004b000010fa0000c13d0000064c0110009a000006340230012a000000000026041b000000000101041a000005dd01100197000000000200041100000000030b001900110000000b001d176215430000040f000000400100043d00000011020000290000000000210435000005da0010009c000005da0100804100000040011002100000000002000414000005da0020009c000005da02008041000000c002200210000000000112019f0000064d011001c70000800d0200003900000003030000390000066704000041000000000500041100000010060000290000078c0000013d0000000001000410000000000012004b00000c150000613d0000000e0000006b00000c150000613d0000000801000039000000000201041a000000100020006c00000f2c0000a13d000000000010043f00000010010000290000000a011000c9000d00000001001d0000064c0110009a000000000101041a000005dd001001980000020b0000613d176211cc0000040f0000000d01000029000006310110009a000000000101041a000d00000001001d0000001001000029000000000010043f0000000901000039000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000008ea0000613d000000000101043b0000001102000029000000000020043f000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000008ea0000613d000000000101043b000c00000001001d0000001001000029000000000010043f0000000901000039000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000008ea0000613d000000000101043b0000000f02000029000000000020043f000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000008ea0000613d0000000c02000029000000000202041a0000000d032000b9000000000701043b000000000107041a000000000002004b00000dad0000613d00000000042300d90000000d0040006c000010fa0000c13d000006340430012a0000000c050000290000000308500039000000000508041a000000000045001a000010fa0000413d00000000054500190000000c060000290000000406600039000000000906041a000000000995004b000010fa0000413d000000010500008a0000000e0050006b0000000005090019000010e80000613d0000000e05000029000000000095004b000010e80000a13d0000066c01000041000000000010043f000000040090043f000005e301000041000017640001043000000060020000390000000003000019000000000453001900000000002404350000002003300039000000000013004b00000dc70000413d0000000801000039000000000101041a000400000001001d000006290010009c00000f290000213d00000004010000290000000501100210000300000001001d0000003f011000390001062a0010019b000080100d000039000000000e000019000000060c00002900000ddd0000013d000000010ee000390000000200e0006c000001a30000813d000000800100043d0000000000e1004b00000f2c0000a13d000000400100043d0000000104100029000000000014004b00000000020000390000000102004039000006290040009c000009550000213d0000000100200190000009550000c13d0000000503e00210000000a0023000390000000002020433000000400040043f00000004050000290000000004510436000000000005004b00000e040000613d000000000500003100000002055003670000000006000019000000400700043d0000062b0070009c000009550000213d0000008008700039000000400080043f000000000905034f000000000a070019000000009b09043c000000000aba043600000000008a004b00000dfb0000c13d000000000864001900000000007804350000002006600039000000030060006c00000df40000413d000000100400002900000000040404330000000000e4004b00000f2c0000a13d0000000003c30019000f00000003001d0000000000130435000000100100002900000000010104330000000000e1004b00000f2c0000a13d000000040000006b00000dda0000613d000805dd0020019b0000000004000019000d0000000e001d001100000004001d000000000040043f0000000901000039000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700000000020d00191762175d0000040f0000000100200190000008ea0000613d000000000101043b0000000802000029000000000020043f000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000008ea0000613d000000400400043d000006550040009c00008010080000390000000d09000029000000110a000029000009550000213d000000000501043b000000a001400039000000400010043f000000000305041a00000000023404360000000101500039000000000101041a00000000001204350000000201500039000000000601041a000000400140003900000000006104350000000306500039000000000606041a0000006007400039000000000067043500000080044000390000000405500039000000000505041a000000000054043500000010040000290000000004040433000000000094004b00000f2c0000a13d0000000f04000029000000000404043300000000050404330000000000a5004b00000f2c0000a13d0000000505a00210000e00200050003d0000000e044000290000000004040433000000000034043500000010030000290000000003030433000000000093004b00000f2c0000a13d0000000f03000029000000000303043300000000040304330000000000a4004b00000f2c0000a13d00000000020204330000000e0330002900000000030304330000002003300039000000000023043500000010020000290000000002020433000000000092004b00000f2c0000a13d0000000f02000029000000000202043300000000030204330000000000a3004b00000f2c0000a13d00000000010104330000000e022000290000000002020433000000400220003900000000001204350000000000a0043f0000000901000039000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700000000020800191762175d0000040f0000000100200190000008ea0000613d000000000101043b0000000802000029000000000020043f000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000008ea0000613d000000000101043b000c00000001001d0000000801000039000000000101041a0000001102000029000000000021004b00000f2c0000a13d0000000801000039000000000010043f0000000a012000c90000001302000039000000000202041a000900000002001d0000062e0210009a000000000202041a000700000002001d0000062f0210009a000000000202041a000a00000002001d000006300210009a000000000202041a000500000002001d000006310110009a000000000101041a000b00000001001d000006320100004100000000001004430000000001000414000005da0010009c000005da01008041000000c00110021000000633011001c70000800b020000391762175d0000040f0000000100200190000010cf0000613d000000000101043b0000000707000029000000000071004b000000060c000029000080100d0000390000000d0e00002900000011040000290000000c050000290000000b0600002900000efb0000a13d0000000a0000006b00000efb0000613d000000090000006b00000efb0000613d0000000b02000039000000000202041a000000000012004b00000000030100190000000003024019000000000002004b000000000103c019000000000271004b000000000300001900000ed50000a13d00000634012000d100000000022100d9000006340020009c000010fa0000c13d000000000001004b00000ed40000613d0000000702000039000000000202041a00000000031200a900000000011300d9000000000021004b00000ed50000613d000010fa0000013d0000000003000019000700000003001d000000000040043f0000001201000039000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700000000020d00191762175d0000040f0000000100200190000008ea0000613d000000000101043b000000000201041a000000070300002900000000013200a9000000000003004b000000060c000029000080100d0000390000000d0e00002900000011040000290000000c050000290000000b0600002900000ef10000613d00000000033100d9000000000023004b000010fa0000c13d000000010200008a000000050220014f00000009011000fa000006340310012a000000000023004b000010fa0000213d0000000a011000fa000000000061001a000010fa0000413d0000000006610019000000000205041a00000000016200a9000000000002004b00000f020000613d00000000022100d9000000000062004b000010fa0000c13d000006340110012a0000000302500039000000000202041a000000000012001a000010fa0000413d00000000011200190000000402500039000000000202041a000000000121004b000010fa0000413d000000100200002900000000020204330000000000e2004b00000f2c0000a13d0000000f0200002900000000020204330000000003020433000000000043004b00000f2c0000a13d0000000e022000290000000002020433000000600220003900000000001204350000000104400039000000040040006c00000e140000413d00000dda0000013d00000060020000390000000003000019000000000453001900000000002404350000002003300039000000000013004b00000f1f0000413d0000000801000039000000000101041a000700000001001d000006290010009c00000f4d0000a13d000000800100043d000000000001004b000009550000c13d0000066101000041000000000010043f0000003201000039000000040010043f000005e30100004100001764000104300000063501000041000000000010043f000000040030043f000005e301000041000017640001043000000000050000190000000b0a00002900000f3d0000013d0000000105500039000000000035004b000003fd0000813d0000000006120049000000400660008a000000000464043600000000a60a043400000000070604330000000002720436000000000007004b00000f3a0000613d00000000080000190000002006600039000000000906043300000000029204360000000108800039000000000078004b00000f460000413d00000f3a0000013d000000070100002900000005021002100000003f012000390002062a0010019b000400000002001d0001001f00200193000080100900003900000000020000190000000b0800002900000f5b0000013d00000009020000290000000102200039000000030020006c000003f20000813d000000800100043d000900000002001d000000000021004b00000f2c0000a13d000000400100043d0000000204100029000000000014004b00000000020000390000000102004039000006290040009c000009550000213d0000000100200190000009550000c13d00000009020000290000000503200210000000a0023000390000000002020433000000400040043f00000007040000290000000004410436000000040000006b00000f780000613d000000040540002900000000060000310000000206600367000000006706043c0000000004740436000000000054004b00000f740000c13d000000010000006b00000008040000290000000004040433000000090040006c00000f2c0000a13d0000000003830019000600000003001d000000000013043500000008010000290000000001010433000000090010006c00000f2c0000a13d000000070000006b00000f570000613d000505dd0020019b0000000004000019001100000004001d000000000040043f0000000901000039000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700000000020900191762175d0000040f0000000100200190000008ea0000613d000000000101043b0000000502000029000000000020043f000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000008ea0000613d000000000101043b001000000001001d0000000801000039000000000101041a0000001102000029000000000021004b00000f2c0000a13d0000000801000039000000000010043f0000000a012000c90000001302000039000000000202041a000d00000002001d0000062e0210009a000000000202041a000c00000002001d0000062f0210009a000000000202041a000e00000002001d000006300210009a000000000202041a000a00000002001d000006310110009a000000000101041a000f00000001001d000006320100004100000000001004430000000001000414000005da0010009c000005da01008041000000c00110021000000633011001c70000800b020000391762175d0000040f0000000100200190000010cf0000613d000000000101043b0000000c07000029000000000071004b0000000b080000290000801009000039000000110400002900000010050000290000000f06000029000010100000a13d0000000e0000006b000010100000613d0000000d0000006b000010100000613d0000000b02000039000000000202041a000000000012004b00000000030100190000000003024019000000000002004b000000000103c019000000000271004b000000000300001900000feb0000a13d00000634012000d100000000022100d9000006340020009c000010fa0000c13d000000000001004b00000fea0000613d0000000702000039000000000202041a00000000031200a900000000011300d9000000000021004b00000feb0000613d000010fa0000013d0000000003000019000c00000003001d000000000040043f0000001201000039000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700000000020900191762175d0000040f0000000100200190000008ea0000613d000000000101043b000000000201041a0000000c0300002900000000013200a9000000000003004b0000000b080000290000801009000039000000110400002900000010050000290000000f06000029000010060000613d00000000033100d9000000000023004b000010fa0000c13d000000010200008a0000000a0220014f0000000d011000fa000006340310012a000000000023004b000010fa0000213d0000000e011000fa000000000061001a000010fa0000413d0000000006610019000000000205041a00000000016200a9000000000002004b000010170000613d00000000022100d9000000000062004b000010fa0000c13d000006340110012a0000000302500039000000000202041a000000000012001a000010fa0000413d00000000011200190000000402500039000000000202041a000000000121004b000010fa0000413d00000008020000290000000002020433000000090020006c00000f2c0000a13d000000060200002900000000020204330000000003020433000000000043004b00000f2c0000a13d00000005034002100000000002230019000000200220003900000000001204350000000104400039000000070040006c00000f880000413d00000f570000013d0000000f010000290000062e0110009a000f00000001001d000000000101041a001000000001001d000006320100004100000000001004430000000001000414000005da0010009c000005da01008041000000c00110021000000633011001c70000800b020000391762175d0000040f0000000100200190000010cf0000613d000000000101043b000000100010006c00000aec0000813d000006320100004100000000001004430000000001000414000005da0010009c000005da01008041000000c00110021000000633011001c70000800b020000391762175d0000040f0000000100200190000010cf0000613d000000000101043b0000000e0010006c0000000e0100a0290000000f02000029000000000012041b00000aec0000013d00000044013000390000064702000041000000000021043500000024013000390000001402000039000000000021043500000645010000410000000000130435000000040130003900000020020000390000000000210435000005da0030009c000005da03008041000000400130021000000646011001c70000176400010430000005da033001970000001f0530018f000005dc06300198000000400200043d00000000046200190000097a0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b0000106e0000c13d0000097a0000013d0000066101000041000000000010043f0000002201000039000000040010043f000005e30100004100001764000104300000065001000041000000000010043f0000063c010000410000176400010430000010e10000c13d0000000001030019176214770000040f0000001101000029000000000010043f0000000501000039000000200010043f00000164010000390000000201100367000000000101043b001100000001001d0000004001000039176217290000040f0000001102000029000000000021041b0000001001000029000000000010043f0000000d01000039000000200010043f0000004001000039176217290000040f000000000301041a000006770230019700000001022001bf000000000021041b0000000001000019000017630001042e000000000100041a000005dd011001970000000002000411000000000021004b000010d40000c13d0000000b01000039000000000101041a000d00000001001d000000000001004b000010b00000613d000006320100004100000000001004430000000001000414000005da0010009c000005da01008041000000c00110021000000633011001c70000800b020000391762175d0000040f0000000100200190000010cf0000613d000000000101043b0000000d0010006c00000bb70000213d0000000f01000029000006340110009a000006360010009c000010d00000213d176211cc0000040f0000000701000039000000000101041a000000400200043d00000020032000390000000f0400002900000000004304350000000000120435000005da0020009c000005da0200804100000040012002100000000002000414000005da0020009c000005da02008041000000c002200210000000000112019f0000062d011001c70000800d0200003900000001030000390000063704000041176217580000040f0000000100200190000008ea0000613d0000000f010000290000000702000039000000000012041b000003440000013d000000000001042f0000065a01000041000000000010043f0000063c0100004100001764000104300000063501000041000000000010043f0000000001000411000000040010043f000005e3010000410000176400010430000000400100043d0000004402100039000006580300004100000000003204350000002402100039000000160300003900000c070000013d000000400100043d0000004402100039000006570300004100000000003204350000002402100039000000090300003900000c070000013d0000000009590049000000000098041b0000000d081000b9000000000001004b000010f00000613d00000000091800d90000000d0090006c000010fa0000c13d000006340980012a000000030a700039000000000b0a041a00000000009b001a000010fa0000413d000000000b9b00190000000407700039000000000c07041a000000000bcb004b000011000000813d0000066101000041000000000010043f0000001101000039000000040010043f000005e301000041000017640001043000000000005b001a000010fa0000413d000000000b5b00190000000000ba041b000000000002004b000011090000613d00000000022300d90000000d0020006c000010fa0000c13d000000000046041b000000000001004b0000110f0000613d00000000011800d90000000d0010006c000010fa0000c13d000000000097041b000000400100043d0000000000510435000005da0010009c000005da0100804100000040011002100000000002000414000005da0020009c000005da02008041000000c002200210000000000112019f0000064d011001c70000800d0200003900000004030000390000066d0400004100000011050000290000000f060000290000001007000029176217580000040f0000000100200190000008ea0000613d0000078f0000013d0000000802000039000000000302041a000000000013004b0000112d0000a13d000000000020043f0000000a011000c90000064c0110009a000000000001042d0000066101000041000000000010043f0000003201000039000000040010043f000005e30100004100001764000104300000001f0220003900000678022001970000000001120019000000000021004b00000000020000390000000102004039000006290010009c0000113f0000213d00000001002001900000113f0000c13d000000400010043f000000000001042d0000066101000041000000000010043f0000004101000039000000040010043f000005e30100004100001764000104300003000000000002000000000201041a000000010320019000000001062002700000007f0660618f0000001f0060008c00000000040000390000000104002039000000000043004b000011840000c13d000000400500043d0000000004650436000000000003004b0000116f0000613d000100000004001d000300000006001d000200000005001d000000000010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000064d011001c700008010020000391762175d0000040f0000000100200190000011900000613d0000000306000029000000000006004b000011750000613d000000000201043b0000000001000019000000020500002900000001070000290000000003170019000000000402041a000000000043043500000001022000390000002001100039000000000061004b000011670000413d000011770000013d00000677012001970000000000140435000000000006004b00000020010000390000000001006039000011770000013d000000000100001900000002050000290000003f0110003900000678021001970000000001520019000000000021004b00000000020000390000000102004039000006290010009c0000118a0000213d00000001002001900000118a0000c13d000000400010043f0000000001050019000000000001042d0000066101000041000000000010043f0000002201000039000000040010043f000005e30100004100001764000104300000066101000041000000000010043f0000004101000039000000040010043f000005e30100004100001764000104300000000001000019000017640001043000000000430104340000000001320436000000000003004b0000119e0000613d000000000200001900000000052100190000000006240019000000000606043300000000006504350000002002200039000000000032004b000011970000413d000000000231001900000000000204350000001f0230003900000678022001970000000001210019000000000001042d00010000000000020000000e01000039000000000101041a000000000001004b000011bb0000613d000100000001001d000006320100004100000000001004430000000001000414000005da0010009c000005da01008041000000c00110021000000633011001c70000800b020000391762175d0000040f0000000100200190000011bd0000613d000000000101043b000000010010006c00000000010000390000000101002039000000010110018f000000000001042d000000010100018f000000000001042d000000000001042f000000000301001900000000011200a9000000000003004b000011c50000613d00000000033100d9000000000023004b000011c60000c13d000000000001042d0000066101000041000000000010043f0000001101000039000000040010043f000005e3010000410000176400010430000d0000000000020000000801000039000000000101041a000500000001001d0000065c0010009c000013780000813d000000050100002900000005011002100000003f021000390000062a02200197000000400300043d0000000002230019000a00000003001d000000000032004b00000000030000390000000103004039000006290020009c000013780000213d0000000100300190000013780000c13d000000400020043f00000005020000290000000a030000290000000003230436000900000003001d000000000002004b0000136f0000613d000000000200003100000002022003670000000003000019000000400400043d0000062b0040009c000013780000213d0000008005400039000000400050043f000000000602034f0000000007040019000000006806043c0000000007870436000000000057004b000011f10000c13d000000090530002900000000004504350000002003300039000000000013004b000011ea0000413d00000000020000190000000005000019000b00000002001d000000400600043d0000062b0060009c000013780000213d0000008001600039000000400010043f000000000200003100000002022003670000000003060019000000002402043c0000000003430436000000000013004b000012050000c13d0000000801000039000000000101041a000000000051004b000013720000a13d0000000801000039000000000010043f000800000005001d0000000a015000c9000300000001001d0000062e0110009a000000000101041a000700000006001d000400000001001d0000000001160436000600000001001d000006320100004100000000001004430000000001000414000005da0010009c000005da01008041000000c00110021000000633011001c70000800b020000391762175d0000040f00000001002001900000137e0000613d000000000101043b000000040010006c00000008050000290000000706000029000012c30000413d000400000001001d000000000050043f0000001201000039000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000706000029000000080500002900000001002001900000137f0000613d000000000301043b000000000103041a000000060200002900000000001204350000000001060433000000040010006b000012c30000613d000000400260003900000003010000290000062f0110009a000000000101041a0000000000120435000000000001004b000012c30000613d000100000002001d000200000003001d00000003010000290000064c0110009a000000000101041a000000400300043d0000067a020000410000000000230435000005dd01100197000400000003001d000000040230003900000000001204350000064101000041000000000010044300000000010004120000000400100443000000200100003900000024001004430000000001000414000005da0010009c000005da01008041000000c00110021000000642011001c700008005020000391762175d0000040f00000001002001900000137e0000613d000000000201043b0000000001000414000005dd02200197000000040020008c0000126d0000c13d0000000103000031000000200030008c0000002004000039000000000403401900000008050000290000000706000029000000040a000029000012990000013d0000000403000029000005da0030009c000005da030080410000004003300210000005da0010009c000005da01008041000000c001100210000000000131019f000005e3011001c71762175d0000040f000000040a0000290000006003100270000005da03300197000000200030008c00000020040000390000000004034019000000200640019000000000056a0019000012860000613d000000000701034f00000000080a0019000000007907043c0000000008980436000000000058004b000012820000c13d0000001f07400190000012930000613d000000000661034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000013870000613d000000080500002900000007060000290000001f01400039000000600210018f0000000001a20019000000000021004b00000000020000390000000102004039000006290010009c000013780000213d0000000100200190000013780000c13d000000400010043f000000200030008c00000002040000290000137f0000413d00000000010a043300000060026000390000000000120435000000000001004b0000000102000029000012c30000613d0000000003020433000000000003004b000012c30000613d00000000021300a900000000033200d9000000000013004b000013810000c13d000006340020009c000012c30000413d0000000101400039000000000301041a000006340220012a00000000012300a900000000022100d9000000000032004b000013810000c13d000006340010009c000012c30000413d000006340110012a000000000014041b000000060200002900000000001204350000000a010000290000000001010433000000000051004b000013720000a13d0000000501500210000000090110002900000000006104350000000a010000290000000001010433000000000051004b000013720000a13d000000060100002900000000010104330000000b0010002a000013810000413d0000000b021000290000000105500039000000050050006c000011fc0000413d0000001301000039000b00000002001d000000000021041b0000000701000039000000000101041a000300000001001d0000000002000019000012fb0000013d0000062e0220009a000000000012041b00000000010b04330000006002a000390000000002020433000000400300043d000000200430003900000000002404350000000000130435000005da0030009c000005da0300804100000040013002100000000002000414000005da0020009c000005da02008041000000c002200210000000000112019f0000062d011001c70000800d0200003900000002030000390000067b040000410000000005090019176217580000040f00000001002001900000137f0000613d00000008020000290000000102200039000000050020006c0000136e0000813d0000000a010000290000000001010433000000000021004b000013720000a13d0000000801000039000000000101041a000000000021004b000013720000a13d000800000002001d0000000501200210000000090110002900000000020104330000000801000039000000000010043f000600000002001d0000000012020434000700000002001d000400000001001d000006320100004100000000001004430000000001000414000005da0010009c000005da01008041000000c00110021000000633011001c70000800b020000391762175d0000040f00000001002001900000137e0000613d000000000101043b000000070010006c000012f70000a13d00000008090000290000000a029000c9000000060a0000290000004003a000390000000003030433000000000003004b000000040b000029000012de0000613d00000000040b0433000000000004004b000012de0000613d0000000b05000039000000000505041a000000000015004b00000000060100190000000006054019000000000005004b000000000601601900000000050004150000000d0550008a000000050550021000000000070a0433000000000776004b00000000060000190000134f0000a13d00000634067000d100000000057600d9000006340050009c000013810000c13d00000000050004150000000d0550008a0000000505500210000000000006004b0000134e0000613d00000003076000b900000000056700d9000000030050006c000013810000c13d00000000050004150000000c0550008a0000000505500210000000000007004b000013640000613d00000000050004150000000c0550008a000000050550021000000000067400a900000000077600d9000000000047004b0000134f0000613d000013810000013d00000000060000190000000b04000029000000000004004b000013680000613d00000000044600d90000000505500270000000000504001f000006340640012a000006300520009a000000000705041a000000000067001a000013810000413d0000000006670019000000000065041b00000000043400d9000006310320009a000000000503041a000000000045001a000013810000413d0000000004450019000000000043041b000012de0000013d00000000060000190000000b04000029000000000004004b000013520000c13d0000066101000041000000000010043f0000001201000039000000040010043f000005e3010000410000176400010430000000000001042d0000001301000039000000000001041b000000000001042d0000066101000041000000000010043f0000003201000039000000040010043f000005e30100004100001764000104300000066101000041000000000010043f0000004101000039000000040010043f000005e3010000410000176400010430000000000001042f000000000100001900001764000104300000066101000041000000000010043f0000001101000039000000040010043f000005e30100004100001764000104300000001f0530018f000005dc06300198000000400200043d0000000004620019000013920000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b0000138e0000c13d000000000005004b0000139f0000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f00000000001404350000006001300210000005da0020009c000005da020080410000004002200210000000000112019f00001764000104300001000000000002000100000001001d000000000020043f0000000901000039000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000013c50000613d000000000101043b0000000102000029000005dd02200197000000000020043f000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000013c50000613d000000000101043b0000000201100039000000000101041a000000000001042d000000000100001900001764000104300005000000000002000000000002004b000014640000c13d0000000042030434000005dd02200197000000000501041a000005de05500197000000000225019f000000000021041b0000000002040433000005dd022001970000000104100039000000000504041a000005de05500197000000000225019f000000000024041b000000400230003900000000020204330000000204100039000000000024041b000000600230003900000000020204330000000304100039000000000024041b000000800230003900000000020204330000000404100039000000000024041b000000a00230003900000000020204330000000504100039000000000024041b000000c00230003900000000020204330000000604100039000000000024041b000000e00230003900000000020204330000000704100039000000000024041b000001000230003900000000020204330000000804100039000000000024041b0000012002300039000000000302043300000000540304340000065c0040009c000014690000813d0000000906100039000000000106041a000000010210019000000001071002700000007f0770618f0000001f0070008c00000000010000390000000101002039000000000012004b0000146f0000c13d000000200070008c000400000006001d000500000004001d000300000003001d000014260000413d000100000007001d000200000005001d000000000060043f0000000001000414000005da0010009c000005da01008041000000c0011002100000064d011001c700008010020000391762175d0000040f0000000100200190000014750000613d00000005040000290000001f024000390000000502200270000000200040008c0000000002004019000000000301043b00000001010000290000001f01100039000000050110027000000000011300190000000002230019000000000012004b00000004060000290000000205000029000014260000813d000000000002041b0000000102200039000000000012004b000014220000413d0000001f0040008c000014520000a13d000000000060043f0000000001000414000005da0010009c000005da01008041000000c0011002100000064d011001c700008010020000391762175d0000040f0000000100200190000014750000613d00000005070000290000067802700198000000000101043b00000003080000290000145f0000613d000000010320008a0000000503300270000000000431001900000020030000390000000104400039000000040600002900000000058300190000000005050433000000000051041b00000020033000390000000101100039000000000041004b0000143d0000c13d000000000072004b0000144e0000813d0000000302700210000000f80220018f000006790220027f000006790220016700000000038300190000000003030433000000000223016f000000000021041b000000010170021000000001011001bf000000000016041b000000000001042d000000000004004b000014560000613d0000000001050433000014570000013d00000000010000190000000302400210000006790220027f0000067902200167000000000121016f0000000102400210000000000121019f000000000016041b000000000001042d00000020030000390000000406000029000000000072004b000014460000413d0000144e0000013d0000066101000041000000000010043f000000040000043f000005e30100004100001764000104300000066101000041000000000010043f0000004101000039000000040010043f000005e30100004100001764000104300000066101000041000000000010043f0000002201000039000000040010043f000005e30100004100001764000104300000000001000019000017640001043000050000000000020000000803000039000000000203041a0000065c0020009c0000151b0000813d0000000104200039000000000043041b000000000030043f0000000043010434000005dd033001970000000a022000c90000064c0520009a000000000605041a000005de06600197000000000336019f000000000035041b0000000003040433000005dd033001970000065e0420009a000000000504041a000005de05500197000000000335019f000000000034041b000000400310003900000000030304330000062f0420009a000000000034041b00000060031000390000000003030433000006480420009a000000000034041b00000080031000390000000003030433000006490420009a000000000034041b000000a00310003900000000030304330000065f0420009a000000000034041b000000c00310003900000000030304330000062e0420009a000000000034041b000000e0031000390000000003030433000006310420009a000000000034041b00000100031000390000000003030433000006300420009a000000000034041b000001200110003900000000030104330000000054030434000006290040009c0000151b0000213d000006600620009a000000000106041a000000010210019000000001071002700000007f0770618f0000001f0070008c00000000010000390000000101002039000000000012004b000015210000c13d000000200070008c000400000006001d000500000004001d000300000003001d000014dd0000413d000100000007001d000200000005001d000000000060043f0000000001000414000005da0010009c000005da01008041000000c0011002100000064d011001c700008010020000391762175d0000040f0000000100200190000015270000613d00000005040000290000001f024000390000000502200270000000200040008c0000000002004019000000000301043b00000001010000290000001f01100039000000050110027000000000011300190000000002230019000000000012004b00000004060000290000000205000029000014dd0000813d000000000002041b0000000102200039000000000012004b000014d90000413d0000001f0040008c000015090000a13d000000000060043f0000000001000414000005da0010009c000005da01008041000000c0011002100000064d011001c700008010020000391762175d0000040f0000000100200190000015270000613d00000005070000290000067802700198000000000101043b0000000308000029000015160000613d000000010320008a0000000503300270000000000431001900000020030000390000000104400039000000040600002900000000058300190000000005050433000000000051041b00000020033000390000000101100039000000000041004b000014f40000c13d000000000072004b000015050000813d0000000302700210000000f80220018f000006790220027f000006790220016700000000038300190000000003030433000000000223016f000000000021041b000000010170021000000001011001bf000000000016041b000000000001042d000000000004004b0000150d0000613d00000000010504330000150e0000013d00000000010000190000000302400210000006790220027f0000067902200167000000000121016f0000000102400210000000000121019f000000000016041b000000000001042d00000020030000390000000406000029000000000072004b000014fd0000413d000015050000013d0000066101000041000000000010043f0000004101000039000000040010043f000005e30100004100001764000104300000066101000041000000000010043f0000002201000039000000040010043f000005e30100004100001764000104300000000001000019000017640001043000010000000000020000000b01000039000000000101041a000000000001004b000015400000613d000100000001001d000006320100004100000000001004430000000001000414000005da0010009c000005da01008041000000c00110021000000633011001c70000800b020000391762175d0000040f0000000100200190000015420000613d000000000101043b000000010010006c00000000010000390000000101002039000000010110018f000000000001042d000000010100018f000000000001042d000000000001042f0003000000000002000000400400043d0000004405400039000000000035043500000020034000390000067c050000410000000000530435000005dd0220019700000024054000390000000000250435000000440200003900000000002404350000067d0040009c000015c80000813d0000008002400039000000400020043f00000000040404330000000002000414000005dd09100197000000040090008c000015860000c13d00000001020000390000000101000031000000000001004b0000159c0000613d000006290010009c000015c80000213d0000001f0410003900000678044001970000003f044000390000067804400197000000400b00043d00000000044b00190000000000b4004b00000000050000390000000105004039000006290040009c000015c80000213d0000000100500190000015c80000c13d000000400040043f000000000a1b043600000678031001980000001f0410018f00000000013a00190000000305000367000015780000613d000000000605034f00000000070a0019000000006806043c0000000007870436000000000017004b000015740000c13d000000000004004b0000159e0000613d000000000335034f0000000304400210000000000501043300000000054501cf000000000545022f000000000303043b0000010004400089000000000343022f00000000034301cf000000000353019f00000000003104350000159e0000013d000005da0030009c000005da030080410000004001300210000005da0040009c000005da040080410000006003400210000000000113019f000005da0020009c000005da02008041000000c002200210000000000121019f0000000002090019000300000009001d176217580000040f0000000309000029000000010220018f00030000000103550000006001100270000105da0010019d000005da01100197000000000001004b0000155c0000c13d000000600b000039000000800a00003900000000010b0433000000000002004b000015d00000613d000000000001004b000015bb0000c13d00020000000b001d00010000000a001d0000063d010000410000000000100443000300000009001d00000004009004430000000001000414000005da0010009c000005da01008041000000c0011002100000063e011001c700008002020000391762175d0000040f0000000100200190000015e30000613d000000000101043b000000000001004b0000000201000029000015e40000613d0000000001010433000000000001004b0000000309000029000000010a000029000015c70000613d0000067e0010009c000015ce0000213d000000200010008c000015ce0000413d00000000010a0433000000000001004b0000000002000039000000010200c039000000000021004b000015ce0000c13d000000000001004b000015d60000613d000000000001042d0000066101000041000000000010043f0000004101000039000000040010043f000005e301000041000017640001043000000000010000190000176400010430000000000001004b000015db0000c13d0000068101000041000000000010043f0000063c0100004100001764000104300000067f01000041000000000010043f000000040090043f000005e3010000410000176400010430000005da00a0009c000005da0a0080410000004002a00210000005da0010009c000005da010080410000006001100210000000000121019f0000176400010430000000000001042f0000068001000041000000000010043f0000000301000029000000040010043f000005e30100004100001764000104300007000000000002000600000002001d000700000001001d000000000010043f0000000901000039000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000016870000613d000000000101043b0000000602000029000005dd02200197000000000020043f000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000016870000613d000000000101043b000600000001001d0000000801000039000000000201041a0000000703000029000000000032004b000016890000a13d000000000010043f0000000a013000c90000001302000039000000000202041a000300000002001d0000062e0210009a000000000202041a000200000002001d0000062f0210009a000000000202041a000400000002001d000006300210009a000000000202041a000100000002001d000006310110009a000000000101041a000500000001001d000006320100004100000000001004430000000001000414000005da0010009c000005da01008041000000c00110021000000633011001c70000800b020000391762175d0000040f00000001002001900000168f0000613d000000000101043b0000000206000029000000000061004b000000060400002900000005050000290000166f0000a13d000000040000006b0000166f0000613d000000030000006b0000166f0000613d0000000b02000039000000000202041a000000000012004b00000000030100190000000003024019000000000002004b000000000103c019000000000261004b00000000030000190000164c0000a13d00000634012000d100000000022100d9000006340020009c000016810000c13d000000000001004b0000164b0000613d0000000702000039000000000202041a00000000031200a900000000011300d9000000000021004b0000164c0000613d000016810000013d0000000003000019000200000003001d0000000701000029000000000010043f0000001201000039000000200010043f0000000001000414000005da0010009c000005da01008041000000c0011002100000062d011001c700008010020000391762175d0000040f0000000100200190000016870000613d000000000101043b000000000201041a000000020300002900000000013200a9000000000003004b00000006040000290000000505000029000016650000613d00000000033100d9000000000023004b000016810000c13d000000010200008a000000010220014f00000003011000fa000006340310012a000000000023004b000016810000213d00000004011000fa000000000051001a000016810000413d0000000005510019000000000204041a00000000015200a9000000000002004b000016760000613d00000000022100d9000000000052004b000016810000c13d000006340110012a0000000302400039000000000202041a000000000012001a000016810000413d00000000011200190000000402400039000000000202041a000000000121004b000016810000413d000000000001042d0000066101000041000000000010043f0000001101000039000000040010043f000005e3010000410000176400010430000000000100001900001764000104300000066101000041000000000010043f0000003201000039000000040010043f000005e3010000410000176400010430000000000001042f000300000000000200000000340204340000000002000414000005dd09100197000000040090008c000016c40000c13d00000001020000390000000101000031000000000001004b000016da0000613d0000065c0010009c000017080000813d0000001f0410003900000678044001970000003f044000390000067804400197000000400b00043d00000000044b00190000000000b4004b00000000050000390000000105004039000006290040009c000017080000213d0000000100500190000017080000c13d000000400040043f000000000a1b043600000678031001980000001f0410018f00000000013a00190000000305000367000016b60000613d000000000605034f00000000070a0019000000006806043c0000000007870436000000000017004b000016b20000c13d000000000004004b000016dc0000613d000000000335034f0000000304400210000000000501043300000000054501cf000000000545022f000000000303043b0000010004400089000000000343022f00000000034301cf000000000353019f0000000000310435000016dc0000013d000005da0040009c000005da040080410000006001400210000005da0030009c000005da030080410000004003300210000000000131019f000005da0020009c000005da02008041000000c002200210000000000121019f0000000002090019000300000009001d176217580000040f0000000309000029000000010220018f00030000000103550000006001100270000105da0010019d000005da01100197000000000001004b0000169a0000c13d000000600b000039000000800a00003900000000010b0433000000000002004b0000170e0000613d000000000001004b000016f90000c13d00020000000b001d00010000000a001d0000063d010000410000000000100443000300000009001d00000004009004430000000001000414000005da0010009c000005da01008041000000c0011002100000063e011001c700008002020000391762175d0000040f0000000100200190000017210000613d000000000101043b000000000001004b0000000201000029000017220000613d0000000001010433000000000001004b0000000309000029000000010a000029000017050000613d0000067e0010009c000017060000213d000000200010008c000017060000413d00000000010a0433000000000001004b0000000002000039000000010200c039000000000021004b000017060000c13d000000000001004b000017140000613d000000000001042d000000000100001900001764000104300000066101000041000000000010043f0000004101000039000000040010043f000005e3010000410000176400010430000000000001004b000017190000c13d0000068101000041000000000010043f0000063c0100004100001764000104300000067f01000041000000000010043f000000040090043f000005e3010000410000176400010430000005da00a0009c000005da0a0080410000004002a00210000005da0010009c000005da010080410000006001100210000000000121019f0000176400010430000000000001042f0000068001000041000000000010043f0000000301000029000000040010043f000005e3010000410000176400010430000000000001042f000005da0010009c000005da0100804100000060011002100000000002000414000005da0020009c000005da02008041000000c002200210000000000112019f000005df011001c700008010020000391762175d0000040f0000000100200190000017380000613d000000000101043b000000000001042d0000000001000019000017640001043000000000050100190000000000200443000000050030008c000017480000413d000000040100003900000000020000190000000506200210000000000664001900000005066002700000000006060031000000000161043a0000000102200039000000000031004b000017400000413d000005da0030009c000005da0300804100000060013002100000000002000414000005da0020009c000005da02008041000000c002200210000000000112019f00000682011001c700000000020500191762175d0000040f0000000100200190000017570000613d000000000101043b000000000001042d000000000001042f0000175b002104210000000102000039000000000001042d0000000002000019000000000001042d00001760002104230000000102000039000000000001042d0000000002000019000000000001042d0000176200000432000017630001042e000017640001043000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffff00000000000000000000000000000000000000000000000000000001ffffffe000000000000000000000000000000000000000000000000000000000ffffffe0000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000008be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e000000002000000000000000000000000000000c00000010000000000000000001e4fbdf700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000000000000000000000715018a500000000000000000000000000000000000000000000000000000000b092145d00000000000000000000000000000000000000000000000000000000e198a86200000000000000000000000000000000000000000000000000000000eaac8c3100000000000000000000000000000000000000000000000000000000fb8d81f000000000000000000000000000000000000000000000000000000000fb8d81f100000000000000000000000000000000000000000000000000000000fff52ee800000000000000000000000000000000000000000000000000000000eaac8c3200000000000000000000000000000000000000000000000000000000f2fde38b00000000000000000000000000000000000000000000000000000000e198a86300000000000000000000000000000000000000000000000000000000e30c397800000000000000000000000000000000000000000000000000000000e78cea9200000000000000000000000000000000000000000000000000000000d4c3ee9f00000000000000000000000000000000000000000000000000000000d4c3eea000000000000000000000000000000000000000000000000000000000d69efdc500000000000000000000000000000000000000000000000000000000de26c3c600000000000000000000000000000000000000000000000000000000b092145e00000000000000000000000000000000000000000000000000000000bd35dd9200000000000000000000000000000000000000000000000000000000beece24b00000000000000000000000000000000000000000000000000000000933f395700000000000000000000000000000000000000000000000000000000a01892a400000000000000000000000000000000000000000000000000000000a8a77a1800000000000000000000000000000000000000000000000000000000a8a77a1900000000000000000000000000000000000000000000000000000000ad88a17e00000000000000000000000000000000000000000000000000000000a01892a500000000000000000000000000000000000000000000000000000000a04a4d5300000000000000000000000000000000000000000000000000000000933f39580000000000000000000000000000000000000000000000000000000093f1a40b0000000000000000000000000000000000000000000000000000000099d8f74a0000000000000000000000000000000000000000000000000000000079ba50960000000000000000000000000000000000000000000000000000000079ba5097000000000000000000000000000000000000000000000000000000007a94c068000000000000000000000000000000000000000000000000000000008da5cb5b00000000000000000000000000000000000000000000000000000000715018a6000000000000000000000000000000000000000000000000000000007761fc700000000000000000000000000000000000000000000000000000000078d849ed0000000000000000000000000000000000000000000000000000000030cdb3c5000000000000000000000000000000000000000000000000000000005c60da1a00000000000000000000000000000000000000000000000000000000630b5ba0000000000000000000000000000000000000000000000000000000006e910bfc000000000000000000000000000000000000000000000000000000006e910bfd000000000000000000000000000000000000000000000000000000006f52daaf00000000000000000000000000000000000000000000000000000000630b5ba1000000000000000000000000000000000000000000000000000000006b1033c4000000000000000000000000000000000000000000000000000000005c60da1b0000000000000000000000000000000000000000000000000000000060246c8800000000000000000000000000000000000000000000000000000000606ce3bf0000000000000000000000000000000000000000000000000000000042cbb15b0000000000000000000000000000000000000000000000000000000042cbb15c00000000000000000000000000000000000000000000000000000000441a3e700000000000000000000000000000000000000000000000000000000047c8b1a90000000000000000000000000000000000000000000000000000000030cdb3c600000000000000000000000000000000000000000000000000000000396f7b23000000000000000000000000000000000000000000000000000000003fdb1e8f0000000000000000000000000000000000000000000000000000000017caf6f00000000000000000000000000000000000000000000000000000000026076f960000000000000000000000000000000000000000000000000000000026076f97000000000000000000000000000000000000000000000000000000002c8e418a000000000000000000000000000000000000000000000000000000002d25a23d0000000000000000000000000000000000000000000000000000000017caf6f1000000000000000000000000000000000000000000000000000000001abbeb54000000000000000000000000000000000000000000000000000000001e1c6a070000000000000000000000000000000000000000000000000000000012863f010000000000000000000000000000000000000000000000000000000012863f02000000000000000000000000000000000000000000000000000000001526fe270000000000000000000000000000000000000000000000000000000015ba56e50000000000000000000000000000000000000000000000000000000000aeef8a00000000000000000000000000000000000000000000000000000000081e3eda00000000000000000000000000000000000000000000000000000000083c6323000000000000000000000000000000000000000000000000ffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0000000000000000000000000000000000000000000000000ffffffffffffff7f00000000000000000000000000000000000000000000003fffffffffffffffe002000000000000000000000000000000000000400000000000000000000000000c085601c9b05546c4de925af5cdebeab0dd5f5d4bea4dc57b37e961749c91170c085601c9b05546c4de925af5cdebeab0dd5f5d4bea4dc57b37e961749c911b0c085601c9b05546c4de925af5cdebeab0dd5f5d4bea4dc57b37e961749c91150c085601c9b05546c4de925af5cdebeab0dd5f5d4bea4dc57b37e961749c911642cbb15ccdc3cad6266b0e7a08c0454b23bf29dc2df74b6f3c209e9336465bd102000002000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a7640000118cdaa70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003627e8f712373c0000b48e36a0869514773506a41441177faf21ebdda362731b7363ee174f3a00772838d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e227008da5cb5b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000080000000000000000082b429000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000001806aa1896bbf26568e884a7374b41e002500962caba6a15023a8d90e8508b83020000020000000000000000000000000000002400000000000000000000000015ba56e5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000800000000000000000310ab089e4439a4c15d089f94afb7896ff553aecb10793d0ab882de59d99a32e0200000200000000000000000000000000000044000000000000000000000000f84de9bf00000000000000000000000000000000000000000000000000000000496e76616c696420706f6f6c206964000000000000000000000000000000000008c379a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006400000000000000000000000062616c616e63657320646f6e2774206d617463680000000000000000000000000c085601c9b05546c4de925af5cdebeab0dd5f5d4bea4dc57b37e961749c911a0c085601c9b05546c4de925af5cdebeab0dd5f5d4bea4dc57b37e961749c9119000000000000000000000000000000000000002000000000000000000000000067f679e13fe9dca16f3079221965ec41838cb8881cbc0f440bc13507c6b214c20c085601c9b05546c4de925af5cdebeab0dd5f5d4bea4dc57b37e961749c911d0200000000000000000000000000000000000020000000000000000000000000845324a5e5310b4f56edb5ef034fb84a1a21fb9248f15eb3ad2d205f7f8f2d60af5e9d9d00000000000000000000000000000000000000000000000000000000f48e3c2600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fffffffffffffebfc264f49177bdbe55a01fae0e77c3fdc75d515d242b32bc4d56c565f5b47865bad92e233d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000800000000000000000000000000000000000000000000000000000000000000000ffffffffffffff5f00000000000000000000000000000000000000a000000080000000000000000077726f6e67207069640000000000000000000000000000000000000000000000506f6f6c204c5020746f6b656e206d69736d617463680000000000000000000000000000000000000000000000000000000000000000003627e8f712373c0001ede31886000000000000000000000000000000000000000000000000000000009eca8f7bcfb868d72b4ed95b71c627c194ab6bcb9b83adb2280e8a0320bb84760000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000fffffffffffffe3f0c085601c9b05546c4de925af5cdebeab0dd5f5d4bea4dc57b37e961749c911c0c085601c9b05546c4de925af5cdebeab0dd5f5d4bea4dc57b37e961749c91180c085601c9b05546c4de925af5cdebeab0dd5f5d4bea4dc57b37e961749c91144e487b7100000000000000000000000000000000000000000000000000000000c0314854fdea1f413e5498dd58aa7953bae1e4e5d587ea2f4e3dacceaa244dea06f743c4000000000000000000000000000000000000000000000000000000003ff721530000000000000000000000000000000000000000000000000000000015e34e0500000000000000000000000000000000000000000000000000000000bc53949c00000000000000000000000000000000000000000000000000000000f279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568214671ad000000000000000000000000000000000000000000000000000000001e110c234a3519983cc1a5dc771c3648cfb2118072924b096d56566097b2251b0000000000000000000000000000000000000000000000007ce66c50e28400014d495f1c00000000000000000000000000000000000000000000000000000000061008d1000000000000000000000000000000000000000000000000000000000e2d25f1d1094599e7ad7c5abf20c243dd116941d455eb79616135defbc6fb9b9c8787c0000000000000000000000000000000000000000000000000000000002f352531000000000000000000000000000000000000000000000000000000008cd22d19000000000000000000000000000000000000000000000000000000007bd4747600000000000000000000000000000000000000000000000000000000eb7a7d62743daf8cf4055aea544d0a89e2011279ed4105567d010759e6fa4de223b872dd00000000000000000000000000000000000000000000000000000000442400af0000000000000000000000000000000000000000000000000000000036af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1eb2e532de00000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff41976e090000000000000000000000000000000000000000000000000000000017b8644f386d1c7c7138ef98b3c8035622bbe94d7be9b26f71d2654a547c2943a9059cbb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5274afe7000000000000000000000000000000000000000000000000000000009996b315000000000000000000000000000000000000000000000000000000001425ea42000000000000000000000000000000000000000000000000000000000200000200000000000000000000000000000000000000000000000000000000
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 | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.