More Info
Private Name Tags
ContractCreator
Latest 21 from a total of 21 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Deposit | 13216649 | 10 hrs ago | IN | 0 S | 0.0131593 | ||||
Withdraw | 13203292 | 12 hrs ago | IN | 0 S | 0.00428055 | ||||
Deposit | 13203277 | 12 hrs ago | IN | 0 S | 0.00650015 | ||||
Withdraw | 13202671 | 12 hrs ago | IN | 0 S | 0.00428055 | ||||
Deposit | 13198952 | 13 hrs ago | IN | 0 S | 0.00517405 | ||||
Deposit | 13169969 | 16 hrs ago | IN | 0 S | 0.00387145 | ||||
Withdraw | 13169719 | 16 hrs ago | IN | 0 S | 0.00732466 | ||||
Deposit | 13168970 | 17 hrs ago | IN | 0 S | 0.00426002 | ||||
Withdraw | 13168473 | 17 hrs ago | IN | 0 S | 0.00425854 | ||||
Deposit | 13166952 | 17 hrs ago | IN | 0 S | 0.00742266 | ||||
Deposit | 13165133 | 17 hrs ago | IN | 0 S | 0.01266313 | ||||
Deposit | 13028949 | 33 hrs ago | IN | 0 S | 0.00563106 | ||||
Withdraw | 13028789 | 33 hrs ago | IN | 0 S | 0.00403995 | ||||
Deposit | 13028598 | 33 hrs ago | IN | 0 S | 0.0038727 | ||||
Deposit | 13028262 | 33 hrs ago | IN | 0 S | 0.00795991 | ||||
Withdraw | 13028080 | 33 hrs ago | IN | 0 S | 0.00451875 | ||||
Deposit | 13027813 | 33 hrs ago | IN | 0 S | 0.00667516 | ||||
Set Fog Oracle | 12989740 | 38 hrs ago | IN | 0 S | 0.00230485 | ||||
Add | 12981728 | 39 hrs ago | IN | 0 S | 0.00687941 | ||||
Add | 12981672 | 39 hrs ago | IN | 0 S | 0.00749556 | ||||
Add | 12981570 | 39 hrs ago | IN | 0 S | 0.00602171 |
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:
FogRewardPool
Compiler Version
v0.8.28+commit.7893614a
Optimization Enabled:
Yes with 999999 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.28; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; import "../interfaces/IWETH.sol"; import "../interfaces/IBasisAsset.sol"; import "../interfaces/IOracle.sol"; /** * @title FogRewardPool * @notice A staking reward pool where users deposit LP tokens to earn FOG. * @dev FOG rewards are distributed over time (rewardPerSecond) to stakers. When harvesting, users must pay a fee in native Sonic, * which is used for peg stabilization. In addition, this contract supports emergency withdrawal. */ contract FogRewardPool is ReentrancyGuard { using SafeERC20 for IERC20; /* ========== STATE VARIABLES ========== */ // Governance address public operator; // User info for stakers. struct UserInfo { uint256 amount; // LP tokens provided by the user. uint256 rewardDebt; // Reward debt; used for reward calculations. } // Pool info for each LP token. struct PoolInfo { IERC20 token; // LP token contract. uint256 allocPoint; // Allocation points for FOG distribution. uint256 lastRewardTime; // Last timestamp FOG distribution occurred. uint256 accFogPerShare; // Accumulated FOG per share (scaled by 1e18). bool isStarted; // True if pool reward distribution has started. } // FOG token and price oracle. address public fog; IOracle public fogOracle; uint256 public pegStabilityModuleFee = 2500; // 25% fee; set to 0 to disable. uint256 public minClaimThreshold = 1e16; // Minimum claim threshold: 0.01 FOG. address public pegStabilizationReserves; // Address to receive part of minted rewards (Collateral Pool). // Wrapped Sonic instance for native Sonic conversion. IWETH public wrappedSonic = IWETH(0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38); // Pool and user accounting. PoolInfo[] public poolInfo; mapping(uint256 => mapping(address => UserInfo)) public userInfo; mapping(uint256 => mapping(address => uint256)) public unclaimedRewards; // Total allocation points across all pools. uint256 public totalAllocPoint = 0; // Mining schedule. uint256 public poolStartTime; uint256 public poolEndTime; uint256 public rewardPerSecond = 0.00009512938 ether; uint256 public runningTime = 730 days; /* ========== EVENTS ========== */ event Deposit(address indexed user, uint256 indexed pid, uint256 amount); event Withdraw(address indexed user, uint256 indexed pid, uint256 amount); event EmergencyWithdraw(address indexed user, uint256 indexed pid, uint256 amount); event RewardPaid(address indexed user, uint256 amount); event SonicPaid(address indexed user, uint256 amount); event UpdateRewardPerSecond(uint256 rewardPerSecond); /* ========== CONSTRUCTOR ========== */ /** * @notice Constructs the FogRewardPool. * @param _fog Address of the FOG token. * @param _pegStabilizationReserves Address for the Peg Stabilization Reserves. * @param _poolStartTime Timestamp for when FOG mining begins. */ constructor(address _fog, address _pegStabilizationReserves, uint256 _poolStartTime) { require(block.timestamp < _poolStartTime, "Pool cannot start in the past"); require(_fog != address(0), "Invalid FOG address"); require(_pegStabilizationReserves != address(0), "Invalid pegStabilizationReserves address"); fog = _fog; pegStabilizationReserves = _pegStabilizationReserves; poolStartTime = _poolStartTime; poolEndTime = _poolStartTime + runningTime; operator = msg.sender; } /** * @notice Allow the contract to receive native Sonic. */ receive() external payable {} /* ========== MODIFIERS ========== */ /** * @dev Throws if called by any account other than the operator. */ modifier onlyOperator() { require(operator == msg.sender, "FogRewardPool: caller is not the operator"); _; } /* ========== POOL MANAGEMENT ========== */ /** * @notice Returns the number of pools. * @return Number of pools. */ function poolLength() external view returns (uint256) { return poolInfo.length; } /** * @dev Ensures no duplicate pool exists for the same LP token. * @param _token LP token address. */ function checkPoolDuplicate(IERC20 _token) internal view { uint256 length = poolInfo.length; for (uint256 pid = 0; pid < length; ++pid) { require(poolInfo[pid].token != _token, "FogRewardPool: existing pool?"); } } /** * @notice Adds a new LP pool. * @param _allocPoint Allocation points for FOG distribution. * @param _token LP token address. * @param _lastRewardTime Custom last reward timestamp; if zero, it defaults to poolStartTime or current time. */ function add(uint256 _allocPoint, IERC20 _token, uint256 _lastRewardTime) public onlyOperator { checkPoolDuplicate(_token); massUpdatePools(); if (block.timestamp < poolStartTime) { _lastRewardTime = (_lastRewardTime == 0 || _lastRewardTime < poolStartTime) ? poolStartTime : _lastRewardTime; } else { _lastRewardTime = (_lastRewardTime == 0 || _lastRewardTime < block.timestamp) ? block.timestamp : _lastRewardTime; } bool _isStarted = (_lastRewardTime <= poolStartTime) || (_lastRewardTime <= block.timestamp); poolInfo.push(PoolInfo({token: _token, allocPoint: _allocPoint, lastRewardTime: _lastRewardTime, accFogPerShare: 0, isStarted: _isStarted})); if (_isStarted) { totalAllocPoint += _allocPoint; } } /** * @notice Updates allocation points for an existing pool. * @param _pid Pool id. * @param _allocPoint New allocation points. */ function set(uint256 _pid, uint256 _allocPoint) public onlyOperator { massUpdatePools(); PoolInfo storage pool = poolInfo[_pid]; if (pool.isStarted) { totalAllocPoint = totalAllocPoint - pool.allocPoint + _allocPoint; } pool.allocPoint = _allocPoint; } /** * @notice Bulk updates allocation points for multiple pools. * @param _pids Array of pool ids. * @param _allocPoints Array of new allocation points. */ function bulkSet(uint256[] calldata _pids, uint256[] calldata _allocPoints) external onlyOperator { require(_pids.length == _allocPoints.length, "FogRewardPool: invalid length"); for (uint256 i = 0; i < _pids.length; i++) { set(_pids[i], _allocPoints[i]); } } /* ========== VIEW FUNCTIONS ========== */ /** * @notice Returns the pending FOG rewards for a user in a pool. * @param _pid Pool id. * @param _user User address. * @return Pending FOG reward. */ function pendingReward(uint256 _pid, address _user) public view returns (uint256) { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][_user]; uint256 accFogPerShare = pool.accFogPerShare; uint256 tokenSupply = pool.token.balanceOf(address(this)); if (block.timestamp > pool.lastRewardTime && tokenSupply != 0) { uint256 elapsed = block.timestamp - pool.lastRewardTime; uint256 _fogReward = (elapsed * rewardPerSecond * pool.allocPoint) / totalAllocPoint; accFogPerShare += (_fogReward * 1e18) / tokenSupply; } return unclaimedRewards[_pid][_user] + ((user.amount * accFogPerShare) / 1e18) - user.rewardDebt; } /** * @notice Returns the total pending FOG rewards for a user across all pools. * @param _user User address. * @return Total pending rewards. */ function pendingAllRewards(address _user) public view returns (uint256) { uint256 length = poolInfo.length; uint256 totalPending; for (uint256 pid = 0; pid < length; ++pid) { totalPending += pendingReward(pid, _user); } return totalPending; } /** * @notice Gets the FOG price in Sonic by querying the fogOracle. * @return FOG price in Sonic. */ function getFogPriceInSonic() public view returns (uint256) { return fogOracle.twap(address(fog), 1e18); } /** * @notice Returns the native Sonic fee required to harvest pending rewards for a pool. * @param _pid Pool id. * @param _user User address. * @return Fee in native Sonic. */ function getBribingSonicToHarvest(uint256 _pid, address _user) external view returns (uint256) { uint256 pending = pendingReward(_pid, _user); return (getFogPriceInSonic() * pending * pegStabilityModuleFee) / 1e22; } /** * @notice Returns the total native Sonic fee to harvest all pending rewards for a user. * @param _user User address. * @return Total fee in native Sonic. */ function getBribingSonicToHarvestAll(address _user) external view returns (uint256) { uint256 pending = pendingAllRewards(_user); return (getFogPriceInSonic() * pending * pegStabilityModuleFee) / 1e22; } /* ========== UPDATE FUNCTIONS ========== */ /** * @notice Updates reward variables for all pools. */ function massUpdatePools() public { uint256 length = poolInfo.length; for (uint256 pid = 0; pid < length; ++pid) { updatePool(pid); } } /** * @notice Updates reward variables for a specific pool. * @param _pid Pool id. */ function updatePool(uint256 _pid) private { PoolInfo storage pool = poolInfo[_pid]; if (block.timestamp <= pool.lastRewardTime) { return; } uint256 tokenSupply = pool.token.balanceOf(address(this)); if (tokenSupply == 0) { pool.lastRewardTime = block.timestamp; return; } if (!pool.isStarted) { pool.isStarted = true; totalAllocPoint += pool.allocPoint; } if (totalAllocPoint > 0) { uint256 elapsed = block.timestamp - pool.lastRewardTime; uint256 _fogReward = (elapsed * rewardPerSecond * pool.allocPoint) / totalAllocPoint; pool.accFogPerShare += (_fogReward * 1e18) / tokenSupply; } pool.lastRewardTime = block.timestamp; } /* ========== USER FUNCTIONS ========== */ /** * @notice Deposits LP tokens into a pool. * @param _pid Pool id. * @param _amount Amount of LP tokens to deposit. */ function deposit(uint256 _pid, uint256 _amount) public nonReentrant { address _sender = msg.sender; PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][_sender]; updatePool(_pid); if (user.amount > 0) { uint256 _pending = (user.amount * pool.accFogPerShare) / 1e18 - user.rewardDebt; if (_pending > 0) { unclaimedRewards[_pid][_sender] += _pending; } } if (_amount > 0) { IERC20 _lpToken = IERC20(pool.token); uint256 _before = _lpToken.balanceOf(address(this)); _lpToken.safeTransferFrom(_sender, address(this), _amount); _amount = _lpToken.balanceOf(address(this)) - _before; // adjust for deflationary tokens if (_amount > 0) { user.amount += _amount; } } user.rewardDebt = (user.amount * pool.accFogPerShare) / 1e18; emit Deposit(_sender, _pid, _amount); } /** * @notice Withdraws LP tokens from a pool. * @param _pid Pool id. * @param _amount Amount of LP tokens to withdraw. */ function withdraw(uint256 _pid, uint256 _amount) public payable nonReentrant { address _sender = msg.sender; PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][_sender]; require(user.amount >= _amount, "withdraw: insufficient balance"); updatePool(_pid); uint256 pending = (user.amount * pool.accFogPerShare) / 1e18 - user.rewardDebt; if (pending > 0) { unclaimedRewards[_pid][_sender] += pending; } if (_amount > 0) { user.amount -= _amount; pool.token.safeTransfer(_sender, _amount); } user.rewardDebt = (user.amount * pool.accFogPerShare) / 1e18; emit Withdraw(_sender, _pid, _amount); } /** * @notice Harvests pending FOG rewards for a specific pool. * Users must pay a bribe fee in native Sonic, converted to Wrapped Sonic. * @param _pid Pool id. */ function harvest(uint256 _pid) public payable nonReentrant { address _sender = msg.sender; PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][_sender]; updatePool(_pid); uint256 _pending = (user.amount * pool.accFogPerShare) / 1e18 - user.rewardDebt; uint256 _rewardsToClaim = _pending + unclaimedRewards[_pid][_sender]; require(_rewardsToClaim >= minClaimThreshold, "Claim amount below minimum threshold"); if (_rewardsToClaim > 0) { unclaimedRewards[_pid][_sender] = 0; uint256 amountSonicToPay = 0; if (pegStabilityModuleFee > 0) { amountSonicToPay = (getFogPriceInSonic() * _rewardsToClaim * pegStabilityModuleFee) / 1e22; require(msg.value >= amountSonicToPay, "insufficient sonic for PSM cost"); emit SonicPaid(_sender, amountSonicToPay); } else { require(msg.value == 0, "Invalid msg.value"); } safeFogTransfer(_sender, _rewardsToClaim); emit RewardPaid(_sender, _rewardsToClaim); if (pegStabilityModuleFee > 0 && msg.value > amountSonicToPay) { uint256 refundAmount = msg.value - amountSonicToPay; (bool success, ) = _sender.call{value: refundAmount}(""); require(success, "Refund failed"); } } user.rewardDebt = (user.amount * pool.accFogPerShare) / 1e18; } /** * @notice Harvests pending FOG rewards from all pools. */ function harvestAll() public payable nonReentrant { address _sender = msg.sender; uint256 length = poolInfo.length; uint256 totalUserRewardsToClaim = 0; for (uint256 pid = 0; pid < length; ++pid) { PoolInfo storage pool = poolInfo[pid]; UserInfo storage user = userInfo[pid][_sender]; updatePool(pid); uint256 _pending = (user.amount * pool.accFogPerShare) / 1e18 - user.rewardDebt; uint256 _rewardsToClaim = _pending + unclaimedRewards[pid][_sender]; if (_rewardsToClaim > 0) { unclaimedRewards[pid][_sender] = 0; totalUserRewardsToClaim += _rewardsToClaim; } user.rewardDebt = (user.amount * pool.accFogPerShare) / 1e18; } require(totalUserRewardsToClaim >= minClaimThreshold, "Claim amount below minimum threshold"); if (totalUserRewardsToClaim > 0) { uint256 amountSonicToPay = 0; if (pegStabilityModuleFee > 0) { amountSonicToPay = (getFogPriceInSonic() * totalUserRewardsToClaim * pegStabilityModuleFee) / 1e22; require(msg.value >= amountSonicToPay, "insufficient sonic for PSM cost"); emit SonicPaid(_sender, amountSonicToPay); } else { require(msg.value == 0, "Invalid msg.value"); } safeFogTransfer(_sender, totalUserRewardsToClaim); emit RewardPaid(_sender, totalUserRewardsToClaim); if (pegStabilityModuleFee > 0 && msg.value > amountSonicToPay) { uint256 refundAmount = msg.value - amountSonicToPay; (bool success, ) = _sender.call{value: refundAmount}(""); require(success, "Refund failed"); } } } /** * @notice Emergency withdrawal of LP tokens. * @param _pid Pool id. */ function emergencyWithdraw(uint256 _pid) public nonReentrant { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; uint256 _amount = user.amount; unclaimedRewards[_pid][msg.sender] = 0; user.amount = 0; user.rewardDebt = 0; pool.token.safeTransfer(msg.sender, _amount); emit EmergencyWithdraw(msg.sender, _pid, _amount); } /* ========== INTERNAL FUNCTIONS ========== */ /** * @notice Safely transfers FOG tokens to a recipient. Mints additional tokens if the contract balance is insufficient. * @param _to The recipient address. * @param _amount The amount of FOG to transfer. */ function safeFogTransfer(address _to, uint256 _amount) internal { uint256 _fogBal = IERC20(fog).balanceOf(address(this)); if (_fogBal < _amount) { IBasisAsset(fog).mint(address(this), _amount - _fogBal); } _fogBal = IERC20(fog).balanceOf(address(this)); if (_fogBal > 0) { if (_amount > _fogBal) { IERC20(fog).safeTransfer(_to, _fogBal); } else { IERC20(fog).safeTransfer(_to, _amount); } } } /* ========== GOVERNANCE & ADMIN FUNCTIONS ========== */ function setOperator(address _operator) external onlyOperator { require(_operator != address(0), "Invalid address"); operator = _operator; } function setPegStabilizationReserves(address _pegStabilizationReserves) public onlyOperator { require(_pegStabilizationReserves != address(0), "Invalid address"); pegStabilizationReserves = _pegStabilizationReserves; } function setPegStabilityModuleFee(uint256 _pegStabilityModuleFee) external onlyOperator { require(_pegStabilityModuleFee <= 5000, "Invalid fee"); // max 50% pegStabilityModuleFee = _pegStabilityModuleFee; } function setFogOracle(address _fogOracle) external onlyOperator { require(_fogOracle != address(0), "Invalid address"); fogOracle = IOracle(_fogOracle); } function setMinClaimThreshold(uint256 _minClaimThreshold) external onlyOperator { require(_minClaimThreshold <= 1e18, "Invalid min claim threshold"); minClaimThreshold = _minClaimThreshold; } function setWSonic(IWETH _wrappedSonic) external onlyOperator { require(address(_wrappedSonic) != address(0), "Invalid Wrapped Sonic address"); wrappedSonic = _wrappedSonic; } function setRewardPerSecond(uint256 _rewardPerSecond) external onlyOperator { require(_rewardPerSecond <= 0.00019 ether, "Rate too high"); massUpdatePools(); rewardPerSecond = _rewardPerSecond; emit UpdateRewardPerSecond(_rewardPerSecond); } /** * @notice Allows the operator to recover unsupported tokens. * @param _token The token to recover. * @param amount The amount to recover. * @param _to The recipient address. */ function governanceRecoverUnsupported(IERC20 _token, uint256 amount, address _to) external onlyOperator { uint256 length = poolInfo.length; for (uint256 pid = 0; pid < length; ++pid) { PoolInfo storage pool = poolInfo[pid]; require(_token != pool.token, "Token cannot be pool token"); } _token.safeTransfer(_to, amount); } /** * @notice Collects all native Sonic held by this contract, wraps it into Wrapped Sonic, and transfers it to pegStabilizationReserves. */ function collectSonic() external { require(address(wrappedSonic) != address(0), "wrappedSonic not set"); uint256 amount = address(this).balance; require(amount > 0, "No Sonic balance to collect"); wrappedSonic.deposit{value: amount}(); IERC20(wrappedSonic).safeTransfer(pegStabilizationReserves, amount); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.28; interface IOracle { function update() external; function consult(address _token, uint256 _amountIn) external view returns (uint144 amountOut); function twap(address _token, uint256 _amountIn) external view returns (uint144 _amountOut); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.28; interface IBasisAsset { function mint(address recipient, uint256 amount) external returns (bool); function burn(uint256 amount) external; function burnFrom(address from, uint256 amount) external; function isOperator() external returns (bool); function operator() external view returns (address); function transferOperator(address newOperator_) external; function transferOwnership(address newOwner_) external; function totalBurned() external view returns (uint256); }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.28; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; interface IWETH is IERC20 { function deposit() external payable; function withdraw(uint256 wad) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol) pragma solidity ^0.8.20; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at, * consider using {ReentrancyGuardTransient} instead. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant NOT_ENTERED = 1; uint256 private constant ENTERED = 2; uint256 private _status; /** * @dev Unauthorized reentrant call. */ error ReentrancyGuardReentrantCall(); constructor() { _status = NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be NOT_ENTERED if (_status == ENTERED) { revert ReentrancyGuardReentrantCall(); } // Any calls to nonReentrant after this point will fail _status = ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.2.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; import {IERC1363} from "../../../interfaces/IERC1363.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC-20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { /** * @dev An operation with an ERC-20 token failed. */ error SafeERC20FailedOperation(address token); /** * @dev Indicates a failed `decreaseAllowance` request. */ error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease); /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value))); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value))); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. * * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client" * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); forceApprove(token, spender, oldAllowance + value); } /** * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no * value, non-reverting calls are assumed to be successful. * * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client" * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal { unchecked { uint256 currentAllowance = token.allowance(address(this), spender); if (currentAllowance < requestedDecrease) { revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease); } forceApprove(token, spender, currentAllowance - requestedDecrease); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. * * NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function * only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being * set here. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value)); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0))); _callOptionalReturn(token, approvalCall); } } /** * @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * Reverts if the returned value is other than `true`. */ function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal { if (to.code.length == 0) { safeTransfer(token, to, value); } else if (!token.transferAndCall(to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target * has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * Reverts if the returned value is other than `true`. */ function transferFromAndCallRelaxed( IERC1363 token, address from, address to, uint256 value, bytes memory data ) internal { if (to.code.length == 0) { safeTransferFrom(token, from, to, value); } else if (!token.transferFromAndCall(from, to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}. * Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall} * once without retrying, and relies on the returned value to be true. * * Reverts if the returned value is other than `true`. */ function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal { if (to.code.length == 0) { forceApprove(token, to, value); } else if (!token.approveAndCall(to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements. */ function _callOptionalReturn(IERC20 token, bytes memory data) private { uint256 returnSize; uint256 returnValue; assembly ("memory-safe") { let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20) // bubble errors if iszero(success) { let ptr := mload(0x40) returndatacopy(ptr, 0, returndatasize()) revert(ptr, returndatasize()) } returnSize := returndatasize() returnValue := mload(0) } if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { bool success; uint256 returnSize; uint256 returnValue; assembly ("memory-safe") { success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20) returnSize := returndatasize() returnValue := mload(0) } return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-20 standard as defined in the ERC. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 value) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 value) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC1363.sol) pragma solidity ^0.8.20; import {IERC20} from "./IERC20.sol"; import {IERC165} from "./IERC165.sol"; /** * @title IERC1363 * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363]. * * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction. */ interface IERC1363 is IERC20, IERC165 { /* * Note: the ERC-165 identifier for this interface is 0xb0202a11. * 0xb0202a11 === * bytes4(keccak256('transferAndCall(address,uint256)')) ^ * bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^ * bytes4(keccak256('approveAndCall(address,uint256)')) ^ * bytes4(keccak256('approveAndCall(address,uint256,bytes)')) */ /** * @dev Moves a `value` amount of tokens from the caller's account to `to` * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferAndCall(address to, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from the caller's account to `to` * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @param data Additional data with no specified format, sent in call to `to`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param from The address which you want to send tokens from. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferFromAndCall(address from, address to, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param from The address which you want to send tokens from. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @param data Additional data with no specified format, sent in call to `to`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`. * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function approveAndCall(address spender, uint256 value) external returns (bool); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`. * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. * @param data Additional data with no specified format, sent in call to `spender`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol) pragma solidity ^0.8.20; import {IERC165} from "../utils/introspection/IERC165.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "../token/ERC20/IERC20.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[ERC]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
{ "optimizer": { "enabled": true, "runs": 999999 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "remappings": [] }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_fog","type":"address"},{"internalType":"address","name":"_pegStabilizationReserves","type":"address"},{"internalType":"uint256","name":"_poolStartTime","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"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":"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":"amount","type":"uint256"}],"name":"EmergencyWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RewardPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"SonicPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"rewardPerSecond","type":"uint256"}],"name":"UpdateRewardPerSecond","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"},{"inputs":[{"internalType":"uint256","name":"_allocPoint","type":"uint256"},{"internalType":"contract IERC20","name":"_token","type":"address"},{"internalType":"uint256","name":"_lastRewardTime","type":"uint256"}],"name":"add","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_pids","type":"uint256[]"},{"internalType":"uint256[]","name":"_allocPoints","type":"uint256[]"}],"name":"bulkSet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"collectSonic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"fog","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fogOracle","outputs":[{"internalType":"contract IOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"getBribingSonicToHarvest","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getBribingSonicToHarvestAll","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFogPriceInSonic","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"_to","type":"address"}],"name":"governanceRecoverUnsupported","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"harvest","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"harvestAll","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"massUpdatePools","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"minClaimThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pegStabilityModuleFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pegStabilizationReserves","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"pendingAllRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"pendingReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolEndTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"poolInfo","outputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"uint256","name":"allocPoint","type":"uint256"},{"internalType":"uint256","name":"lastRewardTime","type":"uint256"},{"internalType":"uint256","name":"accFogPerShare","type":"uint256"},{"internalType":"bool","name":"isStarted","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardPerSecond","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"runningTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_allocPoint","type":"uint256"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_fogOracle","type":"address"}],"name":"setFogOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minClaimThreshold","type":"uint256"}],"name":"setMinClaimThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"}],"name":"setOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pegStabilityModuleFee","type":"uint256"}],"name":"setPegStabilityModuleFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pegStabilizationReserves","type":"address"}],"name":"setPegStabilizationReserves","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rewardPerSecond","type":"uint256"}],"name":"setRewardPerSecond","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IWETH","name":"_wrappedSonic","type":"address"}],"name":"setWSonic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalAllocPoint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"unclaimedRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"rewardDebt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"wrappedSonic","outputs":[{"internalType":"contract IWETH","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60806040526109c4600455662386f26fc10000600555600780546001600160a01b03191673039e2fb66102314ce7b64ce5ce3e5183bc94ad381790555f600b5565568508e71100600e556303c26700600f5534801561005c575f5ffd5b5060405161382538038061382583398101604081905261007b9161020a565b60015f554281116100d35760405162461bcd60e51b815260206004820152601d60248201527f506f6f6c2063616e6e6f7420737461727420696e20746865207061737400000060448201526064015b60405180910390fd5b6001600160a01b0383166101295760405162461bcd60e51b815260206004820152601360248201527f496e76616c696420464f4720616464726573730000000000000000000000000060448201526064016100ca565b6001600160a01b0382166101905760405162461bcd60e51b815260206004820152602860248201527f496e76616c69642070656753746162696c697a6174696f6e5265736572766573604482015267206164647265737360c01b60648201526084016100ca565b600280546001600160a01b038086166001600160a01b0319928316179092556006805492851692909116919091179055600c819055600f546101d29082610243565b600d555050600180546001600160a01b0319163317905550610268565b80516001600160a01b0381168114610205575f5ffd5b919050565b5f5f5f6060848603121561021c575f5ffd5b610225846101ef565b9250610233602085016101ef565b9150604084015190509250925092565b8082018082111561026257634e487b7160e01b5f52601160045260245ffd5b92915050565b6135b0806102755f395ff3fe608060405260043610610294575f3560e01c806366da581511610165578063b3ab15fb116100c6578063bd61ea791161007c578063d63abf3b11610062578063d63abf3b14610768578063ddc6326214610787578063e2bbb1581461079a575f5ffd5b8063bd61ea7914610710578063ce75d5651461073c575f5ffd5b8063b9955e39116100ac578063b9955e39146106c8578063ba44a45a146106e7578063bb264dcb146106fc575f5ffd5b8063b3ab15fb1461068a578063b86d2481146106a9575f5ffd5b80638ed955b91161011b57806393f1a40b1161010157806393f1a40b14610604578063943f013d1461065657806398969e821461066b575f5ffd5b80638ed955b9146105e75780638f10369a146105ef575f5ffd5b80637296359a1161014b5780637296359a1461057d5780638941a937146105a95780638e09136f146105c8575f5ffd5b806366da5815146105495780636e271dd514610568575f5ffd5b80634b96f52a1161020f5780635f96dc11116101c557806360578369116101ab57806360578369146104ea5780636246645614610509578063630b5ba114610535575f5ffd5b80635f96dc11146104b65780636038fc75146104cb575f5ffd5b80635312ea8e116101f55780635312ea8e1461042757806354575af414610446578063570ca73514610465575f5ffd5b80634b96f52a146103e957806351637ba914610408575f5ffd5b80631ab06ee5116102645780633695dad11161024a5780633695dad11461038b578063441a3e70146103a057806346f90748146103b3575f5ffd5b80631ab06ee51461034d5780632521a1aa1461036c575f5ffd5b8063031514461461029f578063081e3eda146102b55780631526fe27146102d857806317caf6f114610338575f5ffd5b3661029b57005b5f5ffd5b3480156102aa575f5ffd5b506102b36107b9565b005b3480156102c0575f5ffd5b506008545b6040519081526020015b60405180910390f35b3480156102e3575f5ffd5b506102f76102f236600461327b565b610951565b6040805173ffffffffffffffffffffffffffffffffffffffff909616865260208601949094529284019190915260608301521515608082015260a0016102cf565b348015610343575f5ffd5b506102c5600b5481565b348015610358575f5ffd5b506102b3610367366004613292565b6109aa565b348015610377575f5ffd5b506102c56103863660046132d3565b610ab4565b348015610396575f5ffd5b506102c560055481565b6102b36103ae366004613292565b610afd565b3480156103be575f5ffd5b506102c56103cd3660046132ee565b600a60209081525f928352604080842090915290825290205481565b3480156103f4575f5ffd5b506102b36104033660046132d3565b610d17565b348015610413575f5ffd5b506102b361042236600461327b565b610e82565b348015610432575f5ffd5b506102b361044136600461327b565b610fa0565b348015610451575f5ffd5b506102b361046036600461331c565b611074565b348015610470575f5ffd5b506001546104919073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102cf565b3480156104c1575f5ffd5b506102c5600c5481565b3480156104d6575f5ffd5b506102c56104e53660046132ee565b611203565b3480156104f5575f5ffd5b506102b361050436600461327b565b611250565b348015610514575f5ffd5b506003546104919073ffffffffffffffffffffffffffffffffffffffff1681565b348015610540575f5ffd5b506102b3611368565b348015610554575f5ffd5b506102b361056336600461327b565b611386565b348015610573575f5ffd5b506102c5600d5481565b348015610588575f5ffd5b506002546104919073ffffffffffffffffffffffffffffffffffffffff1681565b3480156105b4575f5ffd5b506102b36105c33660046132d3565b6114e0565b3480156105d3575f5ffd5b506102c56105e23660046132d3565b61164b565b6102b3611681565b3480156105fa575f5ffd5b506102c5600e5481565b34801561060f575f5ffd5b5061064161061e3660046132ee565b600960209081525f92835260408084209091529082529020805460019091015482565b604080519283526020830191909152016102cf565b348015610661575f5ffd5b506102c5600f5481565b348015610676575f5ffd5b506102c56106853660046132ee565b611b36565b348015610695575f5ffd5b506102b36106a43660046132d3565b611d06565b3480156106b4575f5ffd5b506102b36106c33660046133a3565b611e71565b3480156106d3575f5ffd5b506102b36106e236600461340f565b611fd4565b3480156106f2575f5ffd5b506102c560045481565b348015610707575f5ffd5b506102c5612276565b34801561071b575f5ffd5b506006546104919073ffffffffffffffffffffffffffffffffffffffff1681565b348015610747575f5ffd5b506007546104919073ffffffffffffffffffffffffffffffffffffffff1681565b348015610773575f5ffd5b506102b36107823660046132d3565b612335565b6102b361079536600461327b565b6124a0565b3480156107a5575f5ffd5b506102b36107b4366004613292565b612926565b60075473ffffffffffffffffffffffffffffffffffffffff1661083d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f77726170706564536f6e6963206e6f742073657400000000000000000000000060448201526064015b60405180910390fd5b47806108a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4e6f20536f6e69632062616c616e636520746f20636f6c6c65637400000000006044820152606401610834565b60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004015f604051808303818588803b15801561090c575f5ffd5b505af115801561091e573d5f5f3e3d5ffd5b505060065460075461094e945073ffffffffffffffffffffffffffffffffffffffff908116935016905083612c11565b50565b60088181548110610960575f80fd5b5f9182526020909120600590910201805460018201546002830154600384015460049094015473ffffffffffffffffffffffffffffffffffffffff90931694509092909160ff1685565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a51576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f466f67526577617264506f6f6c3a2063616c6c6572206973206e6f742074686560448201527f206f70657261746f7200000000000000000000000000000000000000000000006064820152608401610834565b610a59611368565b5f60088381548110610a6d57610a6d613444565b5f9182526020909120600590910201600481015490915060ff1615610aad57818160010154600b54610a9f919061349e565b610aa991906134b1565b600b555b6001015550565b5f5f610abf8361164b565b905069021e19e0c9bab240000060045482610ad8612276565b610ae291906134c4565b610aec91906134c4565b610af691906134db565b9392505050565b610b05612c97565b5f3390505f60088481548110610b1d57610b1d613444565b5f918252602080832087845260098252604080852073ffffffffffffffffffffffffffffffffffffffff881686529092529220805460059092029092019250841115610bc5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f77697468647261773a20696e73756666696369656e742062616c616e636500006044820152606401610834565b610bce85612cd8565b5f8160010154670de0b6b3a76400008460030154845f0154610bf091906134c4565b610bfa91906134db565b610c04919061349e565b90508015610c50575f868152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8816845290915281208054839290610c4a9084906134b1565b90915550505b8415610c905784825f015f828254610c68919061349e565b90915550508254610c909073ffffffffffffffffffffffffffffffffffffffff168587612c11565b60038301548254670de0b6b3a764000091610caa916134c4565b610cb491906134db565b6001830155604051858152869073ffffffffffffffffffffffffffffffffffffffff8616907ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b5689060200160405180910390a350505050610d1360015f55565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610dbe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f466f67526577617264506f6f6c3a2063616c6c6572206973206e6f742074686560448201527f206f70657261746f7200000000000000000000000000000000000000000000006064820152608401610834565b73ffffffffffffffffffffffffffffffffffffffff8116610e3b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f496e76616c6964206164647265737300000000000000000000000000000000006044820152606401610834565b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60015473ffffffffffffffffffffffffffffffffffffffff163314610f29576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f466f67526577617264506f6f6c3a2063616c6c6572206973206e6f742074686560448201527f206f70657261746f7200000000000000000000000000000000000000000000006064820152608401610834565b670de0b6b3a7640000811115610f9b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f496e76616c6964206d696e20636c61696d207468726573686f6c6400000000006044820152606401610834565b600555565b610fa8612c97565b5f60088281548110610fbc57610fbc613444565b5f9182526020808320858452600982526040808520338087529084528186208054898852600a865283882083895290955291862086905585825560018201959095556005909302018054909450919290916110319173ffffffffffffffffffffffffffffffffffffffff919091169083612c11565b604051818152849033907fbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae05959060200160405180910390a350505061094e60015f55565b60015473ffffffffffffffffffffffffffffffffffffffff16331461111b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f466f67526577617264506f6f6c3a2063616c6c6572206973206e6f742074686560448201527f206f70657261746f7200000000000000000000000000000000000000000000006064820152608401610834565b6008545f5b818110156111db575f6008828154811061113c5761113c613444565b5f9182526020909120600590910201805490915073ffffffffffffffffffffffffffffffffffffffff908116908716036111d2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f546f6b656e2063616e6e6f7420626520706f6f6c20746f6b656e0000000000006044820152606401610834565b50600101611120565b506111fd73ffffffffffffffffffffffffffffffffffffffff85168385612c11565b50505050565b5f5f61120f8484611b36565b905069021e19e0c9bab240000060045482611228612276565b61123291906134c4565b61123c91906134c4565b61124691906134db565b9150505b92915050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146112f7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f466f67526577617264506f6f6c3a2063616c6c6572206973206e6f742074686560448201527f206f70657261746f7200000000000000000000000000000000000000000000006064820152608401610834565b611388811115611363576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f496e76616c6964206665650000000000000000000000000000000000000000006044820152606401610834565b600455565b6008545f5b81811015610d135761137e81612cd8565b60010161136d565b60015473ffffffffffffffffffffffffffffffffffffffff16331461142d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f466f67526577617264506f6f6c3a2063616c6c6572206973206e6f742074686560448201527f206f70657261746f7200000000000000000000000000000000000000000000006064820152608401610834565b65accdd281e00081111561149d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f5261746520746f6f2068696768000000000000000000000000000000000000006044820152606401610834565b6114a5611368565b600e8190556040518181527fee73bca933ff988cd418cad94a06871f02a18d517a0967540b66a8c7b0bc092b9060200160405180910390a150565b60015473ffffffffffffffffffffffffffffffffffffffff163314611587576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f466f67526577617264506f6f6c3a2063616c6c6572206973206e6f742074686560448201527f206f70657261746f7200000000000000000000000000000000000000000000006064820152608401610834565b73ffffffffffffffffffffffffffffffffffffffff8116611604576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f496e76616c6964206164647265737300000000000000000000000000000000006044820152606401610834565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6008545f9081805b82811015611679576116658186611b36565b61166f90836134b1565b9150600101611653565b509392505050565b611689612c97565b60085433905f805b828110156117e1575f600882815481106116ad576116ad613444565b5f918252602080832085845260098252604080852073ffffffffffffffffffffffffffffffffffffffff8b1686529092529220600590910290910191506116f383612cd8565b5f8160010154670de0b6b3a76400008460030154845f015461171591906134c4565b61171f91906134db565b611729919061349e565b5f858152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8c1684529091528120549192509061176690836134b1565b905080156117aa575f858152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8c1684529091528120556117a781876134b1565b95505b60038401548354670de0b6b3a7640000916117c4916134c4565b6117ce91906134db565b6001938401555050919091019050611691565b50600554811015611873576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f436c61696d20616d6f756e742062656c6f77206d696e696d756d20746872657360448201527f686f6c64000000000000000000000000000000000000000000000000000000006064820152608401610834565b8015611b28576004545f90156119795769021e19e0c9bab24000006004548361189a612276565b6118a491906134c4565b6118ae91906134c4565b6118b891906134db565b905080341015611924576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f696e73756666696369656e7420736f6e696320666f722050534d20636f7374006044820152606401610834565b8373ffffffffffffffffffffffffffffffffffffffff167f929ae8f8bdb7264c3cba18f28abffbd6ee68b646a28b22c320a682e50b279fd68260405161196c91815260200190565b60405180910390a26119e1565b34156119e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f496e76616c6964206d73672e76616c75650000000000000000000000000000006044820152606401610834565b6119eb8483612e8c565b8373ffffffffffffffffffffffffffffffffffffffff167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e048683604051611a3391815260200190565b60405180910390a25f600454118015611a4b57508034115b15611b26575f611a5b823461349e565b90505f8573ffffffffffffffffffffffffffffffffffffffff16826040515f6040518083038185875af1925050503d805f8114611ab3576040519150601f19603f3d011682016040523d82523d5f602084013e611ab8565b606091505b5050905080611b23576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f526566756e64206661696c6564000000000000000000000000000000000000006044820152606401610834565b50505b505b505050611b3460015f55565b565b5f5f60088481548110611b4b57611b4b613444565b5f918252602080832087845260098252604080852073ffffffffffffffffffffffffffffffffffffffff898116875293528085206005949094029091016003810154815492517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015291965093949291909116906370a0823190602401602060405180830381865afa158015611be9573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c0d9190613513565b9050836002015442118015611c2157508015155b15611c92575f846002015442611c37919061349e565b90505f600b548660010154600e5484611c5091906134c4565b611c5a91906134c4565b611c6491906134db565b905082611c7982670de0b6b3a76400006134c4565b611c8391906134db565b611c8d90856134b1565b935050505b60018301548354670de0b6b3a764000090611cae9085906134c4565b611cb891906134db565b5f898152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8c168452909152902054611cf191906134b1565b611cfb919061349e565b979650505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611dad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f466f67526577617264506f6f6c3a2063616c6c6572206973206e6f742074686560448201527f206f70657261746f7200000000000000000000000000000000000000000000006064820152608401610834565b73ffffffffffffffffffffffffffffffffffffffff8116611e2a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f496e76616c6964206164647265737300000000000000000000000000000000006044820152606401610834565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60015473ffffffffffffffffffffffffffffffffffffffff163314611f18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f466f67526577617264506f6f6c3a2063616c6c6572206973206e6f742074686560448201527f206f70657261746f7200000000000000000000000000000000000000000000006064820152608401610834565b828114611f81576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f466f67526577617264506f6f6c3a20696e76616c6964206c656e6774680000006044820152606401610834565b5f5b83811015611fcd57611fc5858583818110611fa057611fa0613444565b90506020020135848484818110611fb957611fb9613444565b905060200201356109aa565b600101611f83565b5050505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461207b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f466f67526577617264506f6f6c3a2063616c6c6572206973206e6f742074686560448201527f206f70657261746f7200000000000000000000000000000000000000000000006064820152608401610834565b612084826130ca565b61208c611368565b600c544210156120b9578015806120a45750600c5481105b6120ae57806120b2565b600c545b90506120d4565b8015806120c557504281105b6120cf57806120d1565b425b90505b5f600c54821115806120e65750428211155b6040805160a08101825273ffffffffffffffffffffffffffffffffffffffff8681168252602082018881529282018681525f60608401818152861580156080870190815260088054600181018255945295517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3600590940293840180547fffffffffffffffffffffffff000000000000000000000000000000000000000016919096161790945594517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee482015590517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee582015592517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee684015590517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee790920180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016921515929092179091559091506111fd5783600b5f82825461226b91906134b1565b909155505050505050565b6003546002546040517f6808a12800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152670de0b6b3a764000060248201525f929190911690636808a12890604401602060405180830381865afa1580156122f8573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061231c919061352a565b71ffffffffffffffffffffffffffffffffffff16905090565b60015473ffffffffffffffffffffffffffffffffffffffff1633146123dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f466f67526577617264506f6f6c3a2063616c6c6572206973206e6f742074686560448201527f206f70657261746f7200000000000000000000000000000000000000000000006064820152608401610834565b73ffffffffffffffffffffffffffffffffffffffff8116612459576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f496e76616c6964205772617070656420536f6e696320616464726573730000006044820152606401610834565b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6124a8612c97565b5f3390505f600883815481106124c0576124c0613444565b5f918252602080832086845260098252604080852073ffffffffffffffffffffffffffffffffffffffff8816865290925292206005909102909101915061250684612cd8565b5f8160010154670de0b6b3a76400008460030154845f015461252891906134c4565b61253291906134db565b61253c919061349e565b5f868152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff891684529091528120549192509061257990836134b1565b905060055481101561260c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f436c61696d20616d6f756e742062656c6f77206d696e696d756d20746872657360448201527f686f6c64000000000000000000000000000000000000000000000000000000006064820152608401610834565b80156128f0575f868152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff891684529091528120819055600454156127415769021e19e0c9bab240000060045483612662612276565b61266c91906134c4565b61267691906134c4565b61268091906134db565b9050803410156126ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f696e73756666696369656e7420736f6e696320666f722050534d20636f7374006044820152606401610834565b8573ffffffffffffffffffffffffffffffffffffffff167f929ae8f8bdb7264c3cba18f28abffbd6ee68b646a28b22c320a682e50b279fd68260405161273491815260200190565b60405180910390a26127a9565b34156127a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f496e76616c6964206d73672e76616c75650000000000000000000000000000006044820152606401610834565b6127b38683612e8c565b8573ffffffffffffffffffffffffffffffffffffffff167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e0486836040516127fb91815260200190565b60405180910390a25f60045411801561281357508034115b156128ee575f612823823461349e565b90505f8773ffffffffffffffffffffffffffffffffffffffff16826040515f6040518083038185875af1925050503d805f811461287b576040519150601f19603f3d011682016040523d82523d5f602084013e612880565b606091505b50509050806128eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f526566756e64206661696c6564000000000000000000000000000000000000006044820152606401610834565b50505b505b60038401548354670de0b6b3a76400009161290a916134c4565b61291491906134db565b60019384015550505f555061094e9050565b61292e612c97565b5f3390505f6008848154811061294657612946613444565b5f918252602080832087845260098252604080852073ffffffffffffffffffffffffffffffffffffffff8816865290925292206005909102909101915061298c85612cd8565b805415612a17575f8160010154670de0b6b3a76400008460030154845f01546129b591906134c4565b6129bf91906134db565b6129c9919061349e565b90508015612a15575f868152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8816845290915281208054839290612a0f9084906134b1565b90915550505b505b8315612b8f5781546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116905f9082906370a0823190602401602060405180830381865afa158015612a8c573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612ab09190613513565b9050612ad473ffffffffffffffffffffffffffffffffffffffff8316863089613196565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152819073ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015612b3e573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612b629190613513565b612b6c919061349e565b95508515612b8c5785835f015f828254612b8691906134b1565b90915550505b50505b60038201548154670de0b6b3a764000091612ba9916134c4565b612bb391906134db565b6001820155604051848152859073ffffffffffffffffffffffffffffffffffffffff8516907f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a159060200160405180910390a3505050610d1360015f55565b60405173ffffffffffffffffffffffffffffffffffffffff838116602483015260448201839052612c9291859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506131dc565b505050565b60025f5403612cd2576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025f55565b5f60088281548110612cec57612cec613444565b905f5260205f209060050201905080600201544211612d09575050565b80546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f9173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612d74573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612d989190613513565b9050805f03612dac57504260029091015550565b600482015460ff16612e02576004820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155820154600b80545f90612dfc9084906134b1565b90915550505b600b5415612e81575f826002015442612e1b919061349e565b90505f600b548460010154600e5484612e3491906134c4565b612e3e91906134c4565b612e4891906134db565b905082612e5d82670de0b6b3a76400006134c4565b612e6791906134db565b846003015f828254612e7991906134b1565b909155505050505b504260029091015550565b6002546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f9173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612ef8573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612f1c9190613513565b905081811015612fe25760025473ffffffffffffffffffffffffffffffffffffffff166340c10f1930612f4f848661349e565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff909216600483015260248201526044016020604051808303815f875af1158015612fbc573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612fe0919061355b565b505b6002546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561304e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130729190613513565b90508015612c9257808211156130a657600254612c929073ffffffffffffffffffffffffffffffffffffffff168483612c11565b600254612c929073ffffffffffffffffffffffffffffffffffffffff168484612c11565b6008545f5b81811015612c92578273ffffffffffffffffffffffffffffffffffffffff166008828154811061310157613101613444565b5f91825260209091206005909102015473ffffffffffffffffffffffffffffffffffffffff160361318e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f466f67526577617264506f6f6c3a206578697374696e6720706f6f6c3f0000006044820152606401610834565b6001016130cf565b60405173ffffffffffffffffffffffffffffffffffffffff84811660248301528381166044830152606482018390526111fd9186918216906323b872dd90608401612c4b565b5f5f60205f8451602086015f885af1806131fb576040513d5f823e3d81fd5b50505f513d9150811561321257806001141561322c565b73ffffffffffffffffffffffffffffffffffffffff84163b155b156111fd576040517f5274afe700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85166004820152602401610834565b5f6020828403121561328b575f5ffd5b5035919050565b5f5f604083850312156132a3575f5ffd5b50508035926020909101359150565b73ffffffffffffffffffffffffffffffffffffffff8116811461094e575f5ffd5b5f602082840312156132e3575f5ffd5b8135610af6816132b2565b5f5f604083850312156132ff575f5ffd5b823591506020830135613311816132b2565b809150509250929050565b5f5f5f6060848603121561332e575f5ffd5b8335613339816132b2565b9250602084013591506040840135613350816132b2565b809150509250925092565b5f5f83601f84011261336b575f5ffd5b50813567ffffffffffffffff811115613382575f5ffd5b6020830191508360208260051b850101111561339c575f5ffd5b9250929050565b5f5f5f5f604085870312156133b6575f5ffd5b843567ffffffffffffffff8111156133cc575f5ffd5b6133d88782880161335b565b909550935050602085013567ffffffffffffffff8111156133f7575f5ffd5b6134038782880161335b565b95989497509550505050565b5f5f5f60608486031215613421575f5ffd5b833592506020840135613433816132b2565b929592945050506040919091013590565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b8181038181111561124a5761124a613471565b8082018082111561124a5761124a613471565b808202811582820484141761124a5761124a613471565b5f8261350e577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b500490565b5f60208284031215613523575f5ffd5b5051919050565b5f6020828403121561353a575f5ffd5b815171ffffffffffffffffffffffffffffffffffff81168114610af6575f5ffd5b5f6020828403121561356b575f5ffd5b81518015158114610af6575f5ffdfea2646970667358221220bfe718dd7d1057350ef0eb26001722834345de9b26f6a91fd9b4f891379aade464736f6c634300081c0033000000000000000000000000b144e5f84bba5b2b4ea2fba9d7364e8990fc7216000000000000000000000000f9f9382908add14ae5e00c496a0eed43fc55a01f0000000000000000000000000000000000000000000000000000000067d2c8c0
Deployed Bytecode
0x608060405260043610610294575f3560e01c806366da581511610165578063b3ab15fb116100c6578063bd61ea791161007c578063d63abf3b11610062578063d63abf3b14610768578063ddc6326214610787578063e2bbb1581461079a575f5ffd5b8063bd61ea7914610710578063ce75d5651461073c575f5ffd5b8063b9955e39116100ac578063b9955e39146106c8578063ba44a45a146106e7578063bb264dcb146106fc575f5ffd5b8063b3ab15fb1461068a578063b86d2481146106a9575f5ffd5b80638ed955b91161011b57806393f1a40b1161010157806393f1a40b14610604578063943f013d1461065657806398969e821461066b575f5ffd5b80638ed955b9146105e75780638f10369a146105ef575f5ffd5b80637296359a1161014b5780637296359a1461057d5780638941a937146105a95780638e09136f146105c8575f5ffd5b806366da5815146105495780636e271dd514610568575f5ffd5b80634b96f52a1161020f5780635f96dc11116101c557806360578369116101ab57806360578369146104ea5780636246645614610509578063630b5ba114610535575f5ffd5b80635f96dc11146104b65780636038fc75146104cb575f5ffd5b80635312ea8e116101f55780635312ea8e1461042757806354575af414610446578063570ca73514610465575f5ffd5b80634b96f52a146103e957806351637ba914610408575f5ffd5b80631ab06ee5116102645780633695dad11161024a5780633695dad11461038b578063441a3e70146103a057806346f90748146103b3575f5ffd5b80631ab06ee51461034d5780632521a1aa1461036c575f5ffd5b8063031514461461029f578063081e3eda146102b55780631526fe27146102d857806317caf6f114610338575f5ffd5b3661029b57005b5f5ffd5b3480156102aa575f5ffd5b506102b36107b9565b005b3480156102c0575f5ffd5b506008545b6040519081526020015b60405180910390f35b3480156102e3575f5ffd5b506102f76102f236600461327b565b610951565b6040805173ffffffffffffffffffffffffffffffffffffffff909616865260208601949094529284019190915260608301521515608082015260a0016102cf565b348015610343575f5ffd5b506102c5600b5481565b348015610358575f5ffd5b506102b3610367366004613292565b6109aa565b348015610377575f5ffd5b506102c56103863660046132d3565b610ab4565b348015610396575f5ffd5b506102c560055481565b6102b36103ae366004613292565b610afd565b3480156103be575f5ffd5b506102c56103cd3660046132ee565b600a60209081525f928352604080842090915290825290205481565b3480156103f4575f5ffd5b506102b36104033660046132d3565b610d17565b348015610413575f5ffd5b506102b361042236600461327b565b610e82565b348015610432575f5ffd5b506102b361044136600461327b565b610fa0565b348015610451575f5ffd5b506102b361046036600461331c565b611074565b348015610470575f5ffd5b506001546104919073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102cf565b3480156104c1575f5ffd5b506102c5600c5481565b3480156104d6575f5ffd5b506102c56104e53660046132ee565b611203565b3480156104f5575f5ffd5b506102b361050436600461327b565b611250565b348015610514575f5ffd5b506003546104919073ffffffffffffffffffffffffffffffffffffffff1681565b348015610540575f5ffd5b506102b3611368565b348015610554575f5ffd5b506102b361056336600461327b565b611386565b348015610573575f5ffd5b506102c5600d5481565b348015610588575f5ffd5b506002546104919073ffffffffffffffffffffffffffffffffffffffff1681565b3480156105b4575f5ffd5b506102b36105c33660046132d3565b6114e0565b3480156105d3575f5ffd5b506102c56105e23660046132d3565b61164b565b6102b3611681565b3480156105fa575f5ffd5b506102c5600e5481565b34801561060f575f5ffd5b5061064161061e3660046132ee565b600960209081525f92835260408084209091529082529020805460019091015482565b604080519283526020830191909152016102cf565b348015610661575f5ffd5b506102c5600f5481565b348015610676575f5ffd5b506102c56106853660046132ee565b611b36565b348015610695575f5ffd5b506102b36106a43660046132d3565b611d06565b3480156106b4575f5ffd5b506102b36106c33660046133a3565b611e71565b3480156106d3575f5ffd5b506102b36106e236600461340f565b611fd4565b3480156106f2575f5ffd5b506102c560045481565b348015610707575f5ffd5b506102c5612276565b34801561071b575f5ffd5b506006546104919073ffffffffffffffffffffffffffffffffffffffff1681565b348015610747575f5ffd5b506007546104919073ffffffffffffffffffffffffffffffffffffffff1681565b348015610773575f5ffd5b506102b36107823660046132d3565b612335565b6102b361079536600461327b565b6124a0565b3480156107a5575f5ffd5b506102b36107b4366004613292565b612926565b60075473ffffffffffffffffffffffffffffffffffffffff1661083d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f77726170706564536f6e6963206e6f742073657400000000000000000000000060448201526064015b60405180910390fd5b47806108a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4e6f20536f6e69632062616c616e636520746f20636f6c6c65637400000000006044820152606401610834565b60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004015f604051808303818588803b15801561090c575f5ffd5b505af115801561091e573d5f5f3e3d5ffd5b505060065460075461094e945073ffffffffffffffffffffffffffffffffffffffff908116935016905083612c11565b50565b60088181548110610960575f80fd5b5f9182526020909120600590910201805460018201546002830154600384015460049094015473ffffffffffffffffffffffffffffffffffffffff90931694509092909160ff1685565b60015473ffffffffffffffffffffffffffffffffffffffff163314610a51576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f466f67526577617264506f6f6c3a2063616c6c6572206973206e6f742074686560448201527f206f70657261746f7200000000000000000000000000000000000000000000006064820152608401610834565b610a59611368565b5f60088381548110610a6d57610a6d613444565b5f9182526020909120600590910201600481015490915060ff1615610aad57818160010154600b54610a9f919061349e565b610aa991906134b1565b600b555b6001015550565b5f5f610abf8361164b565b905069021e19e0c9bab240000060045482610ad8612276565b610ae291906134c4565b610aec91906134c4565b610af691906134db565b9392505050565b610b05612c97565b5f3390505f60088481548110610b1d57610b1d613444565b5f918252602080832087845260098252604080852073ffffffffffffffffffffffffffffffffffffffff881686529092529220805460059092029092019250841115610bc5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f77697468647261773a20696e73756666696369656e742062616c616e636500006044820152606401610834565b610bce85612cd8565b5f8160010154670de0b6b3a76400008460030154845f0154610bf091906134c4565b610bfa91906134db565b610c04919061349e565b90508015610c50575f868152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8816845290915281208054839290610c4a9084906134b1565b90915550505b8415610c905784825f015f828254610c68919061349e565b90915550508254610c909073ffffffffffffffffffffffffffffffffffffffff168587612c11565b60038301548254670de0b6b3a764000091610caa916134c4565b610cb491906134db565b6001830155604051858152869073ffffffffffffffffffffffffffffffffffffffff8616907ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b5689060200160405180910390a350505050610d1360015f55565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610dbe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f466f67526577617264506f6f6c3a2063616c6c6572206973206e6f742074686560448201527f206f70657261746f7200000000000000000000000000000000000000000000006064820152608401610834565b73ffffffffffffffffffffffffffffffffffffffff8116610e3b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f496e76616c6964206164647265737300000000000000000000000000000000006044820152606401610834565b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60015473ffffffffffffffffffffffffffffffffffffffff163314610f29576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f466f67526577617264506f6f6c3a2063616c6c6572206973206e6f742074686560448201527f206f70657261746f7200000000000000000000000000000000000000000000006064820152608401610834565b670de0b6b3a7640000811115610f9b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f496e76616c6964206d696e20636c61696d207468726573686f6c6400000000006044820152606401610834565b600555565b610fa8612c97565b5f60088281548110610fbc57610fbc613444565b5f9182526020808320858452600982526040808520338087529084528186208054898852600a865283882083895290955291862086905585825560018201959095556005909302018054909450919290916110319173ffffffffffffffffffffffffffffffffffffffff919091169083612c11565b604051818152849033907fbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae05959060200160405180910390a350505061094e60015f55565b60015473ffffffffffffffffffffffffffffffffffffffff16331461111b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f466f67526577617264506f6f6c3a2063616c6c6572206973206e6f742074686560448201527f206f70657261746f7200000000000000000000000000000000000000000000006064820152608401610834565b6008545f5b818110156111db575f6008828154811061113c5761113c613444565b5f9182526020909120600590910201805490915073ffffffffffffffffffffffffffffffffffffffff908116908716036111d2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f546f6b656e2063616e6e6f7420626520706f6f6c20746f6b656e0000000000006044820152606401610834565b50600101611120565b506111fd73ffffffffffffffffffffffffffffffffffffffff85168385612c11565b50505050565b5f5f61120f8484611b36565b905069021e19e0c9bab240000060045482611228612276565b61123291906134c4565b61123c91906134c4565b61124691906134db565b9150505b92915050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146112f7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f466f67526577617264506f6f6c3a2063616c6c6572206973206e6f742074686560448201527f206f70657261746f7200000000000000000000000000000000000000000000006064820152608401610834565b611388811115611363576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f496e76616c6964206665650000000000000000000000000000000000000000006044820152606401610834565b600455565b6008545f5b81811015610d135761137e81612cd8565b60010161136d565b60015473ffffffffffffffffffffffffffffffffffffffff16331461142d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f466f67526577617264506f6f6c3a2063616c6c6572206973206e6f742074686560448201527f206f70657261746f7200000000000000000000000000000000000000000000006064820152608401610834565b65accdd281e00081111561149d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f5261746520746f6f2068696768000000000000000000000000000000000000006044820152606401610834565b6114a5611368565b600e8190556040518181527fee73bca933ff988cd418cad94a06871f02a18d517a0967540b66a8c7b0bc092b9060200160405180910390a150565b60015473ffffffffffffffffffffffffffffffffffffffff163314611587576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f466f67526577617264506f6f6c3a2063616c6c6572206973206e6f742074686560448201527f206f70657261746f7200000000000000000000000000000000000000000000006064820152608401610834565b73ffffffffffffffffffffffffffffffffffffffff8116611604576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f496e76616c6964206164647265737300000000000000000000000000000000006044820152606401610834565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6008545f9081805b82811015611679576116658186611b36565b61166f90836134b1565b9150600101611653565b509392505050565b611689612c97565b60085433905f805b828110156117e1575f600882815481106116ad576116ad613444565b5f918252602080832085845260098252604080852073ffffffffffffffffffffffffffffffffffffffff8b1686529092529220600590910290910191506116f383612cd8565b5f8160010154670de0b6b3a76400008460030154845f015461171591906134c4565b61171f91906134db565b611729919061349e565b5f858152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8c1684529091528120549192509061176690836134b1565b905080156117aa575f858152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8c1684529091528120556117a781876134b1565b95505b60038401548354670de0b6b3a7640000916117c4916134c4565b6117ce91906134db565b6001938401555050919091019050611691565b50600554811015611873576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f436c61696d20616d6f756e742062656c6f77206d696e696d756d20746872657360448201527f686f6c64000000000000000000000000000000000000000000000000000000006064820152608401610834565b8015611b28576004545f90156119795769021e19e0c9bab24000006004548361189a612276565b6118a491906134c4565b6118ae91906134c4565b6118b891906134db565b905080341015611924576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f696e73756666696369656e7420736f6e696320666f722050534d20636f7374006044820152606401610834565b8373ffffffffffffffffffffffffffffffffffffffff167f929ae8f8bdb7264c3cba18f28abffbd6ee68b646a28b22c320a682e50b279fd68260405161196c91815260200190565b60405180910390a26119e1565b34156119e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f496e76616c6964206d73672e76616c75650000000000000000000000000000006044820152606401610834565b6119eb8483612e8c565b8373ffffffffffffffffffffffffffffffffffffffff167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e048683604051611a3391815260200190565b60405180910390a25f600454118015611a4b57508034115b15611b26575f611a5b823461349e565b90505f8573ffffffffffffffffffffffffffffffffffffffff16826040515f6040518083038185875af1925050503d805f8114611ab3576040519150601f19603f3d011682016040523d82523d5f602084013e611ab8565b606091505b5050905080611b23576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f526566756e64206661696c6564000000000000000000000000000000000000006044820152606401610834565b50505b505b505050611b3460015f55565b565b5f5f60088481548110611b4b57611b4b613444565b5f918252602080832087845260098252604080852073ffffffffffffffffffffffffffffffffffffffff898116875293528085206005949094029091016003810154815492517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015291965093949291909116906370a0823190602401602060405180830381865afa158015611be9573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c0d9190613513565b9050836002015442118015611c2157508015155b15611c92575f846002015442611c37919061349e565b90505f600b548660010154600e5484611c5091906134c4565b611c5a91906134c4565b611c6491906134db565b905082611c7982670de0b6b3a76400006134c4565b611c8391906134db565b611c8d90856134b1565b935050505b60018301548354670de0b6b3a764000090611cae9085906134c4565b611cb891906134db565b5f898152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8c168452909152902054611cf191906134b1565b611cfb919061349e565b979650505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611dad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f466f67526577617264506f6f6c3a2063616c6c6572206973206e6f742074686560448201527f206f70657261746f7200000000000000000000000000000000000000000000006064820152608401610834565b73ffffffffffffffffffffffffffffffffffffffff8116611e2a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f496e76616c6964206164647265737300000000000000000000000000000000006044820152606401610834565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60015473ffffffffffffffffffffffffffffffffffffffff163314611f18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f466f67526577617264506f6f6c3a2063616c6c6572206973206e6f742074686560448201527f206f70657261746f7200000000000000000000000000000000000000000000006064820152608401610834565b828114611f81576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f466f67526577617264506f6f6c3a20696e76616c6964206c656e6774680000006044820152606401610834565b5f5b83811015611fcd57611fc5858583818110611fa057611fa0613444565b90506020020135848484818110611fb957611fb9613444565b905060200201356109aa565b600101611f83565b5050505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461207b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f466f67526577617264506f6f6c3a2063616c6c6572206973206e6f742074686560448201527f206f70657261746f7200000000000000000000000000000000000000000000006064820152608401610834565b612084826130ca565b61208c611368565b600c544210156120b9578015806120a45750600c5481105b6120ae57806120b2565b600c545b90506120d4565b8015806120c557504281105b6120cf57806120d1565b425b90505b5f600c54821115806120e65750428211155b6040805160a08101825273ffffffffffffffffffffffffffffffffffffffff8681168252602082018881529282018681525f60608401818152861580156080870190815260088054600181018255945295517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3600590940293840180547fffffffffffffffffffffffff000000000000000000000000000000000000000016919096161790945594517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee482015590517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee582015592517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee684015590517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee790920180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016921515929092179091559091506111fd5783600b5f82825461226b91906134b1565b909155505050505050565b6003546002546040517f6808a12800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152670de0b6b3a764000060248201525f929190911690636808a12890604401602060405180830381865afa1580156122f8573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061231c919061352a565b71ffffffffffffffffffffffffffffffffffff16905090565b60015473ffffffffffffffffffffffffffffffffffffffff1633146123dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f466f67526577617264506f6f6c3a2063616c6c6572206973206e6f742074686560448201527f206f70657261746f7200000000000000000000000000000000000000000000006064820152608401610834565b73ffffffffffffffffffffffffffffffffffffffff8116612459576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f496e76616c6964205772617070656420536f6e696320616464726573730000006044820152606401610834565b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6124a8612c97565b5f3390505f600883815481106124c0576124c0613444565b5f918252602080832086845260098252604080852073ffffffffffffffffffffffffffffffffffffffff8816865290925292206005909102909101915061250684612cd8565b5f8160010154670de0b6b3a76400008460030154845f015461252891906134c4565b61253291906134db565b61253c919061349e565b5f868152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff891684529091528120549192509061257990836134b1565b905060055481101561260c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f436c61696d20616d6f756e742062656c6f77206d696e696d756d20746872657360448201527f686f6c64000000000000000000000000000000000000000000000000000000006064820152608401610834565b80156128f0575f868152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff891684529091528120819055600454156127415769021e19e0c9bab240000060045483612662612276565b61266c91906134c4565b61267691906134c4565b61268091906134db565b9050803410156126ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f696e73756666696369656e7420736f6e696320666f722050534d20636f7374006044820152606401610834565b8573ffffffffffffffffffffffffffffffffffffffff167f929ae8f8bdb7264c3cba18f28abffbd6ee68b646a28b22c320a682e50b279fd68260405161273491815260200190565b60405180910390a26127a9565b34156127a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f496e76616c6964206d73672e76616c75650000000000000000000000000000006044820152606401610834565b6127b38683612e8c565b8573ffffffffffffffffffffffffffffffffffffffff167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e0486836040516127fb91815260200190565b60405180910390a25f60045411801561281357508034115b156128ee575f612823823461349e565b90505f8773ffffffffffffffffffffffffffffffffffffffff16826040515f6040518083038185875af1925050503d805f811461287b576040519150601f19603f3d011682016040523d82523d5f602084013e612880565b606091505b50509050806128eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f526566756e64206661696c6564000000000000000000000000000000000000006044820152606401610834565b50505b505b60038401548354670de0b6b3a76400009161290a916134c4565b61291491906134db565b60019384015550505f555061094e9050565b61292e612c97565b5f3390505f6008848154811061294657612946613444565b5f918252602080832087845260098252604080852073ffffffffffffffffffffffffffffffffffffffff8816865290925292206005909102909101915061298c85612cd8565b805415612a17575f8160010154670de0b6b3a76400008460030154845f01546129b591906134c4565b6129bf91906134db565b6129c9919061349e565b90508015612a15575f868152600a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8816845290915281208054839290612a0f9084906134b1565b90915550505b505b8315612b8f5781546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116905f9082906370a0823190602401602060405180830381865afa158015612a8c573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612ab09190613513565b9050612ad473ffffffffffffffffffffffffffffffffffffffff8316863089613196565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152819073ffffffffffffffffffffffffffffffffffffffff8416906370a0823190602401602060405180830381865afa158015612b3e573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612b629190613513565b612b6c919061349e565b95508515612b8c5785835f015f828254612b8691906134b1565b90915550505b50505b60038201548154670de0b6b3a764000091612ba9916134c4565b612bb391906134db565b6001820155604051848152859073ffffffffffffffffffffffffffffffffffffffff8516907f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a159060200160405180910390a3505050610d1360015f55565b60405173ffffffffffffffffffffffffffffffffffffffff838116602483015260448201839052612c9291859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506131dc565b505050565b60025f5403612cd2576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025f55565b5f60088281548110612cec57612cec613444565b905f5260205f209060050201905080600201544211612d09575050565b80546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f9173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612d74573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612d989190613513565b9050805f03612dac57504260029091015550565b600482015460ff16612e02576004820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155820154600b80545f90612dfc9084906134b1565b90915550505b600b5415612e81575f826002015442612e1b919061349e565b90505f600b548460010154600e5484612e3491906134c4565b612e3e91906134c4565b612e4891906134db565b905082612e5d82670de0b6b3a76400006134c4565b612e6791906134db565b846003015f828254612e7991906134b1565b909155505050505b504260029091015550565b6002546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f9173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612ef8573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612f1c9190613513565b905081811015612fe25760025473ffffffffffffffffffffffffffffffffffffffff166340c10f1930612f4f848661349e565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff909216600483015260248201526044016020604051808303815f875af1158015612fbc573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612fe0919061355b565b505b6002546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa15801561304e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130729190613513565b90508015612c9257808211156130a657600254612c929073ffffffffffffffffffffffffffffffffffffffff168483612c11565b600254612c929073ffffffffffffffffffffffffffffffffffffffff168484612c11565b6008545f5b81811015612c92578273ffffffffffffffffffffffffffffffffffffffff166008828154811061310157613101613444565b5f91825260209091206005909102015473ffffffffffffffffffffffffffffffffffffffff160361318e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f466f67526577617264506f6f6c3a206578697374696e6720706f6f6c3f0000006044820152606401610834565b6001016130cf565b60405173ffffffffffffffffffffffffffffffffffffffff84811660248301528381166044830152606482018390526111fd9186918216906323b872dd90608401612c4b565b5f5f60205f8451602086015f885af1806131fb576040513d5f823e3d81fd5b50505f513d9150811561321257806001141561322c565b73ffffffffffffffffffffffffffffffffffffffff84163b155b156111fd576040517f5274afe700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85166004820152602401610834565b5f6020828403121561328b575f5ffd5b5035919050565b5f5f604083850312156132a3575f5ffd5b50508035926020909101359150565b73ffffffffffffffffffffffffffffffffffffffff8116811461094e575f5ffd5b5f602082840312156132e3575f5ffd5b8135610af6816132b2565b5f5f604083850312156132ff575f5ffd5b823591506020830135613311816132b2565b809150509250929050565b5f5f5f6060848603121561332e575f5ffd5b8335613339816132b2565b9250602084013591506040840135613350816132b2565b809150509250925092565b5f5f83601f84011261336b575f5ffd5b50813567ffffffffffffffff811115613382575f5ffd5b6020830191508360208260051b850101111561339c575f5ffd5b9250929050565b5f5f5f5f604085870312156133b6575f5ffd5b843567ffffffffffffffff8111156133cc575f5ffd5b6133d88782880161335b565b909550935050602085013567ffffffffffffffff8111156133f7575f5ffd5b6134038782880161335b565b95989497509550505050565b5f5f5f60608486031215613421575f5ffd5b833592506020840135613433816132b2565b929592945050506040919091013590565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b8181038181111561124a5761124a613471565b8082018082111561124a5761124a613471565b808202811582820484141761124a5761124a613471565b5f8261350e577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b500490565b5f60208284031215613523575f5ffd5b5051919050565b5f6020828403121561353a575f5ffd5b815171ffffffffffffffffffffffffffffffffffff81168114610af6575f5ffd5b5f6020828403121561356b575f5ffd5b81518015158114610af6575f5ffdfea2646970667358221220bfe718dd7d1057350ef0eb26001722834345de9b26f6a91fd9b4f891379aade464736f6c634300081c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000b144e5f84bba5b2b4ea2fba9d7364e8990fc7216000000000000000000000000f9f9382908add14ae5e00c496a0eed43fc55a01f0000000000000000000000000000000000000000000000000000000067d2c8c0
-----Decoded View---------------
Arg [0] : _fog (address): 0xB144E5f84BbA5b2b4Ea2fBa9d7364E8990FC7216
Arg [1] : _pegStabilizationReserves (address): 0xF9f9382908ADD14Ae5e00c496a0eed43fC55A01F
Arg [2] : _poolStartTime (uint256): 1741867200
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000b144e5f84bba5b2b4ea2fba9d7364e8990fc7216
Arg [1] : 000000000000000000000000f9f9382908add14ae5e00c496a0eed43fc55a01f
Arg [2] : 0000000000000000000000000000000000000000000000000000000067d2c8c0
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 35 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.