More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 28,479 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Harvest | 19958099 | 16 hrs ago | IN | 1.62985397 S | 0.01544035 | ||||
Withdraw | 19956146 | 16 hrs ago | IN | 0 S | 0.01000825 | ||||
Harvest | 19006574 | 5 days ago | IN | 0.85208993 S | 0.01366624 | ||||
Harvest | 19006530 | 5 days ago | IN | 5.97696606 S | 0.01380993 | ||||
Withdraw | 19006379 | 5 days ago | IN | 0 S | 0.0091525 | ||||
Withdraw | 19006199 | 5 days ago | IN | 0 S | 0.0081648 | ||||
Harvest All | 18689831 | 6 days ago | IN | 0.89269716 S | 0.02902844 | ||||
Withdraw | 18689737 | 6 days ago | IN | 0 S | 0.0081648 | ||||
Deposit | 18435586 | 7 days ago | IN | 0 S | 0.01026228 | ||||
Harvest All | 18391092 | 8 days ago | IN | 0.6823813 S | 0.01692923 | ||||
Harvest All | 18391080 | 8 days ago | IN | 0.6823813 S | 0.01692923 | ||||
Harvest All | 18391073 | 8 days ago | IN | 0.6823813 S | 0.02510555 | ||||
Withdraw | 18391025 | 8 days ago | IN | 0 S | 0.00783516 | ||||
Collect Sonic | 18324013 | 8 days ago | IN | 0 S | 0.00191467 | ||||
Withdraw | 18010868 | 10 days ago | IN | 0 S | 0.00915084 | ||||
Withdraw | 18010822 | 10 days ago | IN | 0 S | 0.00914947 | ||||
Withdraw | 17157789 | 13 days ago | IN | 0 S | 0.00816562 | ||||
Harvest All | 16736269 | 15 days ago | IN | 3.46650308 S | 0.02903372 | ||||
Harvest All | 16536400 | 16 days ago | IN | 0.00049337 S | 0.02803564 | ||||
Withdraw | 16337423 | 17 days ago | IN | 0 S | 0.0081648 | ||||
Withdraw | 16131784 | 18 days ago | IN | 0 S | 0.00677111 | ||||
Harvest | 16032234 | 18 days ago | IN | 0.69377053 S | 0.01479763 | ||||
Withdraw | 16032111 | 18 days ago | IN | 0 S | 0.00915322 | ||||
Withdraw | 15978551 | 19 days ago | IN | 0 S | 0.0087461 | ||||
Harvest All | 15962274 | 19 days ago | IN | 0.10094774 S | 0.02902844 |
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
19958099 | 16 hrs ago | 0.15152837 S | ||||
19006574 | 5 days ago | 0.07921924 S | ||||
19006530 | 5 days ago | 0.55568165 S | ||||
18689831 | 6 days ago | 0.08299452 S | ||||
18391073 | 8 days ago | 0.06344134 S | ||||
18324013 | 8 days ago | 33.02656411 S | ||||
16736269 | 15 days ago | 0.32228259 S | ||||
16536400 | 16 days ago | 0.00004586 S | ||||
16032234 | 18 days ago | 0.0645002 S | ||||
15962274 | 19 days ago | 0.00938516 S | ||||
15935756 | 19 days ago | 0.21739722 S | ||||
15894241 | 19 days ago | 0.06811078 S | ||||
15732260 | 20 days ago | 0.43713575 S | ||||
15693382 | 20 days ago | 2.26663608 S | ||||
15628253 | 20 days ago | 194.81830042 S | ||||
15623373 | 20 days ago | 14.43932781 S | ||||
15559003 | 20 days ago | 0.03690758 S | ||||
15405778 | 21 days ago | 0.27720674 S | ||||
15277629 | 22 days ago | 1.21365835 S | ||||
15186329 | 22 days ago | 0.09882668 S | ||||
15135982 | 23 days ago | 3.90756521 S | ||||
14815249 | 24 days ago | 331.9467275 S | ||||
14747869 | 25 days ago | 0.01640645 S | ||||
14708342 | 25 days ago | 0.01141886 S | ||||
14646609 | 25 days ago | 0.02536378 S |
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:
GSnakeRewardPoolV2
Compiler Version
v0.8.26+commit.8a97fa7a
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 // GSnakeRewardPool --> visit https://snake.finance/ for full experience // Made by Kell pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/utils/math/SafeMath.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "../interfaces/IBasisAsset.sol"; import "../interfaces/IOracle.sol"; import "../interfaces/farming/IERC4626.sol"; import "../interfaces/farming/IShadowGauge.sol"; import "../interfaces/farming/ISwapxGauge.sol"; import "../interfaces/farming/IShadowVoter.sol"; import "../interfaces/farming/ISwapxVoter.sol"; import "../interfaces/farming/IX33.sol"; contract GSnakeRewardPoolV2 is ReentrancyGuard { using SafeMath for uint256; using SafeERC20 for IERC20; enum GaugeDex { NONE, SHADOW, SWAPX } // governance address public operator; // Info of each user. struct UserInfo { uint256 amount; // How many LP tokens the user has provided. uint256 rewardDebt; // Reward debt. See explanation below. } struct GaugeInfo { bool isGauge; // If this is a gauge address gauge; // The gauge GaugeDex gaugeDex; // Dex of the gauge } // Info of each pool. struct PoolInfo { IERC20 token; // Address of LP token contract. uint256 depFee; // deposit fee that is applied to created pool. uint256 allocPoint; // How many allocation points assigned to this pool. GSNAKEs to distribute per block. uint256 lastRewardTime; // Last time that GSNAKEs distribution occurs. uint256 accGsnakePerShare; // Accumulated GSNAKEs per share, times 1e18. See below. bool isStarted; // if lastRewardTime has passed GaugeInfo gaugeInfo; // Gauge info (does this pool have a gauge and where is it) uint256 poolGsnakePerSec; // rewards per second for pool (acts as allocPoint) } IERC20 public gsnake; IOracle public gsnakeOracle; bool public claimGaugeRewardsOnUpdatePool = true; bool public pegStabilityModuleFeeEnabled = true; uint256 public pegStabilityModuleFee = 150; // 15% uint256 public minClaimThreshold = 1e12; // 0.000001 GSNAKE IShadowVoter public shadowVoter; ISwapxVoter public swapxVoter; address public constant XSHADOW_TOKEN = 0x5050bc082FF4A74Fb6B0B04385dEfdDB114b2424; address public constant X33_TOKEN = 0x3333111A391cC08fa51353E9195526A70b333333; address public constant SWAPX_TOKEN = 0xA04BC7140c26fc9BB1F36B1A604C7A5a88fb0E70; address public bribesSafe; // Info of each pool. PoolInfo[] public poolInfo; // Info of each user that stakes LP tokens. mapping(uint256 => mapping(address => UserInfo)) public userInfo; // Pending rewards for each user in each pool (pending rewards accrued since last deposit/withdrawal) mapping(uint256 => mapping(address => uint256)) public pendingRewards; // Total allocation points. Must be the sum of all allocation points in all pools. uint256 public totalAllocPoint = 0; // The time when GSNAKE mining starts. uint256 public poolStartTime; // The time when GSNAKE mining ends. uint256 public poolEndTime; uint256 public sharePerSecond = 0 ether; uint256 public runningTime = 730 days; 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); constructor( address _gsnake, address _bribesSafe, uint256 _poolStartTime, address _shadowVoter, address _swapxVoter ) { require(block.timestamp < _poolStartTime, "pool cant be started in the past"); if (_gsnake != address(0)) gsnake = IERC20(_gsnake); if(_bribesSafe != address(0)) bribesSafe = _bribesSafe; poolStartTime = _poolStartTime; poolEndTime = _poolStartTime + runningTime; operator = msg.sender; shadowVoter = IShadowVoter(_shadowVoter); swapxVoter = ISwapxVoter(_swapxVoter); bribesSafe = _bribesSafe; // create all the pools add(0, 0, IERC20(0x287c6882dE298665977787e268f3dba052A6e251), false, 0); // Snake-S add(0, 0, IERC20(0xb901D7316447C84f4417b8a8268E2822095051E6), false, 0); // GSnake-S } modifier onlyOperator() { require(operator == msg.sender, "GSnakeRewardPool: caller is not the operator"); _; } function poolLength() external view returns (uint256) { return poolInfo.length; } function checkPoolDuplicate(IERC20 _token) internal view { uint256 length = poolInfo.length; for (uint256 pid = 0; pid < length; ++pid) { require(poolInfo[pid].token != _token, "GSnakeRewardPool: existing pool?"); } } // Add new lp to the pool. Can only be called by operator. function add( uint256 _allocPoint, uint256 _depFee, IERC20 _token, bool _withUpdate, uint256 _lastRewardTime ) public onlyOperator { checkPoolDuplicate(_token); if (_withUpdate) { massUpdatePools(); } if (block.timestamp < poolStartTime) { // chef is sleeping if (_lastRewardTime == 0) { _lastRewardTime = poolStartTime; } else { if (_lastRewardTime < poolStartTime) { _lastRewardTime = poolStartTime; } } } else { // chef is cooking if (_lastRewardTime == 0 || _lastRewardTime < block.timestamp) { _lastRewardTime = block.timestamp; } } bool _isStarted = (_lastRewardTime <= poolStartTime) || (_lastRewardTime <= block.timestamp); poolInfo.push(PoolInfo({ token: _token, depFee: _depFee, allocPoint: _allocPoint, poolGsnakePerSec: _allocPoint, lastRewardTime: _lastRewardTime, accGsnakePerShare: 0, isStarted: _isStarted, gaugeInfo: GaugeInfo(false, address(0), GaugeDex.NONE) })); // enableGauge(poolInfo.length - 1); if (_isStarted) { totalAllocPoint = totalAllocPoint.add(_allocPoint); sharePerSecond = sharePerSecond.add(_allocPoint); } } // Update the given pool's GSNAKE allocation point. Can only be called by the operator. function set(uint256 _pid, uint256 _allocPoint, uint256 _depFee) public onlyOperator { massUpdatePools(); PoolInfo storage pool = poolInfo[_pid]; require(_depFee < 200); // deposit fee cant be more than 2%; pool.depFee = _depFee; if (pool.isStarted) { totalAllocPoint = totalAllocPoint.sub(pool.allocPoint).add(_allocPoint); sharePerSecond = sharePerSecond.sub(pool.poolGsnakePerSec).add(_allocPoint); } pool.allocPoint = _allocPoint; pool.poolGsnakePerSec = _allocPoint; } function bulkSet(uint256[] calldata _pids, uint256[] calldata _allocPoints, uint256[] calldata _depFees) external onlyOperator { require(_pids.length == _allocPoints.length && _pids.length == _depFees.length, "GSnakeRewardPool: invalid length"); for (uint256 i = 0; i < _pids.length; i++) { set(_pids[i], _allocPoints[i], _depFees[i]); } } // Return accumulate rewards over the given _from to _to block. function getGeneratedReward(uint256 _fromTime, uint256 _toTime) public view returns (uint256) { if (_fromTime >= _toTime) return 0; if (_toTime >= poolEndTime) { if (_fromTime >= poolEndTime) return 0; if (_fromTime <= poolStartTime) return poolEndTime.sub(poolStartTime).mul(sharePerSecond); return poolEndTime.sub(_fromTime).mul(sharePerSecond); } else { if (_toTime <= poolStartTime) return 0; if (_fromTime <= poolStartTime) return _toTime.sub(poolStartTime).mul(sharePerSecond); return _toTime.sub(_fromTime).mul(sharePerSecond); } } // View function to see pending GSNAKEs on frontend. function pendingShare(uint256 _pid, address _user) public view returns (uint256) { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][_user]; uint256 accGsnakePerShare = pool.accGsnakePerShare; uint256 tokenSupply = pool.gaugeInfo.isGauge ? IShadowGauge(pool.gaugeInfo.gauge).balanceOf(address(this)) : pool.token.balanceOf(address(this)); if (block.timestamp > pool.lastRewardTime && tokenSupply != 0) { uint256 _generatedReward = getGeneratedReward(pool.lastRewardTime, block.timestamp); uint256 _gsnakeReward = _generatedReward.mul(pool.allocPoint).div(totalAllocPoint); accGsnakePerShare = accGsnakePerShare.add(_gsnakeReward.mul(1e18).div(tokenSupply)); } return user.amount.mul(accGsnakePerShare).div(1e18).sub(user.rewardDebt); } // View function to see pending GSNAKEs on frontend and any other pending rewards accumulated. function pendingShareAndPendingRewards(uint256 _pid, address _user) external view returns (uint256) { uint256 _pendingShare = pendingShare(_pid, _user); return _pendingShare.add(pendingRewards[_pid][_user]); } function massUpdatePools() public { uint256 length = poolInfo.length; for (uint256 pid = 0; pid < length; ++pid) { updatePool(pid); updatePoolWithGaugeDeposit(pid); } } // massUpdatePoolsInRange function massUpdatePoolsInRange(uint256 _fromPid, uint256 _toPid) public { require(_fromPid <= _toPid, "GSnakeRewardPool: invalid range"); for (uint256 pid = _fromPid; pid <= _toPid; ++pid) { updatePool(pid); updatePoolWithGaugeDeposit(pid); } } // Update reward variables of the given pool to be up-to-date. function updatePool(uint256 _pid) private { updatePoolWithGaugeDeposit(_pid); PoolInfo storage pool = poolInfo[_pid]; if (block.timestamp <= pool.lastRewardTime) { return; } uint256 tokenSupply = pool.gaugeInfo.isGauge ? IShadowGauge(pool.gaugeInfo.gauge).balanceOf(address(this)) : pool.token.balanceOf(address(this)); if (tokenSupply == 0) { pool.lastRewardTime = block.timestamp; return; } if (!pool.isStarted) { pool.isStarted = true; totalAllocPoint = totalAllocPoint.add(pool.allocPoint); sharePerSecond = sharePerSecond.add(pool.poolGsnakePerSec); } if (totalAllocPoint > 0) { uint256 _generatedReward = getGeneratedReward(pool.lastRewardTime, block.timestamp); uint256 _gsnakeReward = _generatedReward.mul(pool.allocPoint).div(totalAllocPoint); pool.accGsnakePerShare = pool.accGsnakePerShare.add(_gsnakeReward.mul(1e18).div(tokenSupply)); } pool.lastRewardTime = block.timestamp; if (claimGaugeRewardsOnUpdatePool) {claimAllRewards(_pid);} } // Deposit LP tokens to earn rewards function updatePoolWithGaugeDeposit(uint256 _pid) public { PoolInfo storage pool = poolInfo[_pid]; address gauge = pool.gaugeInfo.gauge; uint256 balance = pool.token.balanceOf(address(this)); // Do nothing if this pool doesn't have a gauge if (pool.gaugeInfo.isGauge) { // Do nothing if the LP token in the MC is empty if (balance > 0) { // Approve to the gauge if (pool.token.allowance(address(this), gauge) < balance ){ pool.token.approve(gauge, type(uint256).max); } // Deposit the LP in the gauge IShadowGauge(pool.gaugeInfo.gauge).deposit(balance); // NOTE: no need to check if gauge is shadow or swapx, because both have the same function } } } // Claim rewards to treasury function claimAllRewards(uint256 _pid) public { PoolInfo storage pool = poolInfo[_pid]; if (pool.gaugeInfo.isGauge) { if (pool.gaugeInfo.gaugeDex == GaugeDex.SHADOW) { _claimShadowRewards(_pid); } if (pool.gaugeInfo.gaugeDex == GaugeDex.SWAPX) { _claimSwapxRewards(_pid); } } } function _claimShadowRewards(uint256 _pid) internal { PoolInfo storage pool = poolInfo[_pid]; address[] memory gaugeRewardTokens = IShadowGauge(pool.gaugeInfo.gauge).rewardsList(); IShadowGauge(pool.gaugeInfo.gauge).getReward(address(this), gaugeRewardTokens); for (uint256 i = 0; i < gaugeRewardTokens.length; i++) { IERC20 rewardToken = IERC20(gaugeRewardTokens[i]); uint256 rewardAmount = rewardToken.balanceOf(address(this)); if (rewardAmount > 0) { if (address(rewardToken) == XSHADOW_TOKEN) { _convertXShadow(rewardAmount); } else { rewardToken.safeTransfer(bribesSafe, rewardAmount); } } } } function convertXShadow(uint256 _amount) public onlyOperator { _convertXShadow(_amount); } function _convertXShadow(uint256 _amount) internal { IERC20(XSHADOW_TOKEN).approve(address(X33_TOKEN), _amount); // approve xshadow to x33 bool canMint = IX33(X33_TOKEN).isUnlocked(); if (canMint) { IERC4626(X33_TOKEN).deposit(_amount, address(this)); // mint x33 IERC20(X33_TOKEN).safeTransfer(bribesSafe, _amount); // send x33 to bribesSafe } } function _claimSwapxRewards(uint256 _pid) internal { PoolInfo storage pool = poolInfo[_pid]; ISwapxGauge(pool.gaugeInfo.gauge).getReward(); // claim the swapx rewards IERC20 rewardToken = IERC20(SWAPX_TOKEN); uint256 rewardAmount = rewardToken.balanceOf(address(this)); if (rewardAmount > 0) { rewardToken.safeTransfer(bribesSafe, rewardAmount); } } // Add a gauge to a pool function enableGauge(uint256 _pid, GaugeDex _gaugeDex) public onlyOperator { if (_gaugeDex == GaugeDex.SHADOW) { _enableGaugeShadow(_pid); } if (_gaugeDex == GaugeDex.SWAPX) { _enableGaugeSwapX(_pid); } } function _enableGaugeShadow(uint256 _pid) internal { address gauge = shadowVoter.gaugeForPool(address(poolInfo[_pid].token)); if (gauge != address(0)) { poolInfo[_pid].gaugeInfo = GaugeInfo(true, gauge, GaugeDex.SHADOW); } } function _enableGaugeSwapX(uint256 _pid) internal { // Add the logic for swapx address gauge = swapxVoter.gauges(address(poolInfo[_pid].token)); if (gauge != address(0)) { poolInfo[_pid].gaugeInfo = GaugeInfo(true, gauge, GaugeDex.SWAPX); } } // Withdraw LP from the gauge function withdrawFromGauge(uint256 _pid, uint256 _amount) internal { PoolInfo storage pool = poolInfo[_pid]; // Do nothing if this pool doesn't have a gauge if (pool.gaugeInfo.isGauge) { // Withdraw from the gauge IShadowGauge(pool.gaugeInfo.gauge).withdraw(_amount); // NOTE: no need to check if gauge is shadow or swapx, because both have the same function } } // Deposit LP tokens. 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.mul(pool.accGsnakePerShare).div(1e18).sub(user.rewardDebt); if (_pending > 0) { // safeGsnakeTransfer(_sender, _pending); // emit RewardPaid(_sender, _pending); // accrue pending rewards to be claimed later pendingRewards[_pid][_sender] = pendingRewards[_pid][_sender].add(_pending); } } if (_amount > 0 ) { pool.token.safeTransferFrom(_sender, address(this), _amount); uint256 depositDebt = _amount.mul(pool.depFee).div(10000); user.amount = user.amount.add(_amount.sub(depositDebt)); pool.token.safeTransfer(bribesSafe, depositDebt); } updatePoolWithGaugeDeposit(_pid); user.rewardDebt = user.amount.mul(pool.accGsnakePerShare).div(1e18); emit Deposit(_sender, _pid, _amount); } // Withdraw LP tokens. 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: not good"); updatePool(_pid); updatePoolWithGaugeDeposit(_pid); uint256 _pending = user.amount.mul(pool.accGsnakePerShare).div(1e18).sub(user.rewardDebt); if (_pending > 0) { // safeGsnakeTransfer(_sender, _pending); // emit RewardPaid(_sender, _pending); // accrue pending rewards to be claimed later pendingRewards[_pid][_sender] = pendingRewards[_pid][_sender].add(_pending); } if (_amount > 0) { user.amount = user.amount.sub(_amount); withdrawFromGauge(_pid, _amount); pool.token.safeTransfer(_sender, _amount); } user.rewardDebt = user.amount.mul(pool.accGsnakePerShare).div(1e18); emit Withdraw(_sender, _pid, _amount); } function harvest(uint256 _pid) public payable nonReentrant { address _sender = msg.sender; PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][_sender]; // Ensure rewards are updated updatePool(_pid); updatePoolWithGaugeDeposit(_pid); // Calculate the latest pending rewards uint256 _pending = user.amount.mul(pool.accGsnakePerShare).div(1e18).sub(user.rewardDebt); uint256 _accumulatedPending = pendingRewards[_pid][_sender]; uint256 _rewardsToClaim = _pending.add(_accumulatedPending); // Ensure that the user is claiming an amount above the minimum threshold require(_rewardsToClaim >= minClaimThreshold, "Claim amount below minimum threshold"); if (_rewardsToClaim > 0) { pendingRewards[_pid][_sender] = 0; uint256 amountSonicToPay = 0; if (pegStabilityModuleFeeEnabled) { uint256 currentGSNAKEPriceInSonic = gsnakeOracle.twap(address(gsnake), 1e18); amountSonicToPay = (currentGSNAKEPriceInSonic.mul(_rewardsToClaim).div(1e18)).mul(pegStabilityModuleFee).div(1000); require(msg.value >= amountSonicToPay, "insufficient sonic for PSM cost"); } else { require(msg.value == 0, "GSnakeRewardPool: invalid msg.value"); } safeGsnakeTransfer(_sender, _rewardsToClaim); emit RewardPaid(_sender, _rewardsToClaim); // Refund any excess S if pegStabilityModuleFee is enabled if (pegStabilityModuleFeeEnabled && msg.value > amountSonicToPay) { uint256 refundAmount = msg.value - amountSonicToPay; (bool success, ) = _sender.call{value: refundAmount}(""); require(success, "Refund failed"); } } // Update the user’s reward debt user.rewardDebt = user.amount.mul(pool.accGsnakePerShare).div(1e18); } 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]; // Ensure rewards are updated updatePool(pid); updatePoolWithGaugeDeposit(pid); // Calculate the latest pending rewards uint256 _pending = user.amount.mul(pool.accGsnakePerShare).div(1e18).sub(user.rewardDebt); uint256 _accumulatedPending = pendingRewards[pid][_sender]; uint256 _rewardsToClaim = _pending.add(_accumulatedPending); if (_rewardsToClaim > 0) { pendingRewards[pid][_sender] = 0; totalUserRewardsToClaim = totalUserRewardsToClaim.add(_rewardsToClaim); } // Update the user’s reward debt user.rewardDebt = user.amount.mul(pool.accGsnakePerShare).div(1e18); } // Ensure that the user is claiming an amount above the minimum threshold require(totalUserRewardsToClaim >= minClaimThreshold, "Claim amount below minimum threshold"); if (totalUserRewardsToClaim > 0) { uint256 amountSonicToPay = 0; if (pegStabilityModuleFeeEnabled) { uint256 currentGSNAKEPriceInSonic = gsnakeOracle.twap(address(gsnake), 1e18); amountSonicToPay = (currentGSNAKEPriceInSonic.mul(totalUserRewardsToClaim).div(1e18)).mul(pegStabilityModuleFee).div(1000); require(msg.value >= amountSonicToPay, "insufficient sonic for PSM cost"); } else { require(msg.value == 0, "GSnakeRewardPool: invalid msg.value"); } safeGsnakeTransfer(_sender, totalUserRewardsToClaim); emit RewardPaid(_sender, totalUserRewardsToClaim); // Refund any excess S if pegStabilityModuleFee is enabled if (pegStabilityModuleFeeEnabled && msg.value > amountSonicToPay) { uint256 refundAmount = msg.value - amountSonicToPay; (bool success, ) = _sender.call{value: refundAmount}(""); require(success, "Refund failed"); } } } // Withdraw without caring about rewards. EMERGENCY ONLY. function emergencyWithdraw(uint256 _pid) public nonReentrant { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; uint256 _amount = user.amount; withdrawFromGauge(_pid, _amount); pendingRewards[_pid][msg.sender] = 0; user.amount = 0; user.rewardDebt = 0; pool.token.safeTransfer(msg.sender, _amount); emit EmergencyWithdraw(msg.sender, _pid, _amount); } // Safe gsnake transfer function, just in case if rounding error causes pool to not have enough GSNAKEs. function safeGsnakeTransfer(address _to, uint256 _amount) internal { uint256 _gsnakeBal = gsnake.balanceOf(address(this)); if (_gsnakeBal > 0) { if (_amount > _gsnakeBal) { gsnake.safeTransfer(_to, _gsnakeBal); } else { gsnake.safeTransfer(_to, _amount); } } } function setOperator(address _operator) external onlyOperator { operator = _operator; } function setBribesSafe(address _bribesSafe) public onlyOperator { bribesSafe = _bribesSafe; } function setPegStabilityModuleFee(uint256 _pegStabilityModuleFee) external onlyOperator { require(_pegStabilityModuleFee <= 500, "GSnakeRewardPool: invalid peg stability module fee"); // max 50% pegStabilityModuleFee = _pegStabilityModuleFee; } function setGSnakeOracle(IOracle _gsnakeOracle) external onlyOperator { gsnakeOracle = _gsnakeOracle; } function setPegStabilityModuleFeeEnabled(bool _enabled) external onlyOperator { pegStabilityModuleFeeEnabled = _enabled; } function setMinClaimThreshold(uint256 _minClaimThreshold) external onlyOperator { require(_minClaimThreshold >= 0, "GSnakeRewardPool: invalid min claim threshold"); require(_minClaimThreshold <= 1e18, "GSnakeRewardPool: invalid max claim threshold"); minClaimThreshold = _minClaimThreshold; } function setClaimGaugeRewardsOnUpdatePool(bool _claimGaugeRewardsOnUpdatePool) external onlyOperator { claimGaugeRewardsOnUpdatePool = _claimGaugeRewardsOnUpdatePool; } 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, "ShareRewardPool: Token cannot be pool token"); } _token.safeTransfer(to, amount); } /** * @notice Collects the Sonic. * @param amount The amount of Sonic to collect */ function collectSonic(uint256 amount) public onlyOperator { (bool sent,) = bribesSafe.call{value: amount}(""); require(sent, "failed to send Sonic"); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; 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 require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // 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 v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * ==== Security Considerations * * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be * considered as an intention to spend the allowance in any specific way. The second is that because permits have * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be * generally recommended is: * * ```solidity * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public { * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {} * doThing(..., value); * } * * function doThing(..., uint256 value) public { * token.safeTransferFrom(msg.sender, address(this), value); * ... * } * ``` * * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also * {SafeERC20-safeTransferFrom}). * * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so * contracts should have entry points that don't rely on permit. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. * * CAUTION: See Security Considerations above. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` 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 amount) 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 `amount` 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 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` 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 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; /** * @dev 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.encodeWithSelector(token.transfer.selector, 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.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value)); } /** * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value)); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, approvalCall); } } /** * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. * Revert on invalid signature. */ function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol) pragma solidity ^0.8.0; // CAUTION // This version of SafeMath should only be used with Solidity 0.8 or later, // because it relies on the compiler's built in overflow checks. /** * @dev Wrappers over Solidity's arithmetic operations. * * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler * now has built in overflow checking. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { return a + b; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { return a * b; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { unchecked { require(b <= a, errorMessage); return a - b; } } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a / b; } } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a % b; } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC4626.sol) pragma solidity ^0.8.20; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; /** * @dev Interface of the ERC-4626 "Tokenized Vault Standard", as defined in * https://eips.ethereum.org/EIPS/eip-4626[ERC-4626]. */ interface IERC4626 is IERC20, IERC20Metadata { event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares); event Withdraw( address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares ); /** * @dev Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing. * * - MUST be an ERC-20 token contract. * - MUST NOT revert. */ function asset() external view returns (address assetTokenAddress); /** * @dev Returns the total amount of the underlying asset that is “managed” by Vault. * * - SHOULD include any compounding that occurs from yield. * - MUST be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT revert. */ function totalAssets() external view returns (uint256 totalManagedAssets); /** * @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal * scenario where all the conditions are met. * * - MUST NOT be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT show any variations depending on the caller. * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. * - MUST NOT revert. * * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and * from. */ function convertToShares(uint256 assets) external view returns (uint256 shares); /** * @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal * scenario where all the conditions are met. * * - MUST NOT be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT show any variations depending on the caller. * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. * - MUST NOT revert. * * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and * from. */ function convertToAssets(uint256 shares) external view returns (uint256 assets); /** * @dev Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver, * through a deposit call. * * - MUST return a limited value if receiver is subject to some deposit limit. * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited. * - MUST NOT revert. */ function maxDeposit(address receiver) external view returns (uint256 maxAssets); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given * current on-chain conditions. * * - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit * call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called * in the same transaction. * - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the * deposit would be accepted, regardless if the user has enough tokens approved, etc. * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by depositing. */ function previewDeposit(uint256 assets) external view returns (uint256 shares); /** * @dev Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens. * * - MUST emit the Deposit event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * deposit execution, and are accounted for during deposit. * - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not * approving enough underlying tokens to the Vault contract, etc). * * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. */ function deposit(uint256 assets, address receiver) external returns (uint256 shares); /** * @dev Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call. * - MUST return a limited value if receiver is subject to some mint limit. * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted. * - MUST NOT revert. */ function maxMint(address receiver) external view returns (uint256 maxShares); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given * current on-chain conditions. * * - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call * in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the * same transaction. * - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint * would be accepted, regardless if the user has enough tokens approved, etc. * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by minting. */ function previewMint(uint256 shares) external view returns (uint256 assets); /** * @dev Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens. * * - MUST emit the Deposit event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint * execution, and are accounted for during mint. * - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not * approving enough underlying tokens to the Vault contract, etc). * * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. */ function mint(uint256 shares, address receiver) external returns (uint256 assets); /** * @dev Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the * Vault, through a withdraw call. * * - MUST return a limited value if owner is subject to some withdrawal limit or timelock. * - MUST NOT revert. */ function maxWithdraw(address owner) external view returns (uint256 maxAssets); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block, * given current on-chain conditions. * * - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw * call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if * called * in the same transaction. * - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though * the withdrawal would be accepted, regardless if the user has enough shares, etc. * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by depositing. */ function previewWithdraw(uint256 assets) external view returns (uint256 shares); /** * @dev Burns shares from owner and sends exactly assets of underlying tokens to receiver. * * - MUST emit the Withdraw event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * withdraw execution, and are accounted for during withdraw. * - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner * not having enough shares, etc). * * Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed. * Those methods should be performed separately. */ function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares); /** * @dev Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault, * through a redeem call. * * - MUST return a limited value if owner is subject to some withdrawal limit or timelock. * - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock. * - MUST NOT revert. */ function maxRedeem(address owner) external view returns (uint256 maxShares); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block, * given current on-chain conditions. * * - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call * in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the * same transaction. * - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the * redemption would be accepted, regardless if the user has enough shares, etc. * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by redeeming. */ function previewRedeem(uint256 shares) external view returns (uint256 assets); /** * @dev Burns exactly shares from owner and sends assets of underlying tokens to receiver. * * - MUST emit the Withdraw event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * redeem execution, and are accounted for during redeem. * - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner * not having enough shares, etc). * * NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed. * Those methods should be performed separately. */ function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.26; interface IShadowGauge { error ZERO_AMOUNT(); error CANT_NOTIFY_STAKE(); error REWARD_TOO_HIGH(); error NOT_GREATER_THAN_REMAINING(uint256 amount, uint256 remaining); error TOKEN_ERROR(address token); error NOT_WHITELISTED(); error NOT_AUTHORIZED(); event Deposit(address indexed from, uint256 amount); event Withdraw(address indexed from, uint256 amount); event NotifyReward( address indexed from, address indexed reward, uint256 amount ); event ClaimRewards( address indexed from, address indexed reward, uint256 amount ); event RewardWhitelisted(address indexed reward, bool whitelisted); /// @notice Get the amount of stakingToken deposited by an account function balanceOf(address) external view returns (uint256); /// @notice returns an array with all the addresses of the rewards /// @return _rewards array of addresses for rewards function rewardsList() external view returns (address[] memory _rewards); /// @notice number of different rewards the gauge has facilitated that are 'active' /// @return _length the number of individual rewards function rewardsListLength() external view returns (uint256 _length); /// @notice returns the last time the reward was modified or periodFinish if the reward has ended /// @param token address of the token /// @return ltra last time reward applicable function lastTimeRewardApplicable( address token ) external view returns (uint256 ltra); /// @notice displays the data struct of rewards for a token /// @param token the address of the token /// @return data rewards struct function rewardData( address token ) external view returns (Reward memory data); /// @notice calculates the amount of tokens earned for an address /// @param token address of the token to check /// @param account address to check /// @return _reward amount of token claimable function earned( address token, address account ) external view returns (uint256 _reward); /// @notice claims rewards (shadow + any external LP Incentives) /// @param account the address to claim for /// @param tokens an array of the tokens to claim function getReward(address account, address[] calldata tokens) external; /// @notice claims all rewards and instant exits xshadow into shadow function getRewardAndExit( address account, address[] calldata tokens ) external; /// @notice calculates the token amounts earned per lp token /// @param token address of the token to check /// @return rpt reward per token function rewardPerToken(address token) external view returns (uint256 rpt); /// @notice deposit all LP tokens from msg.sender's wallet to the gauge function depositAll() external; /// @param recipient the address of who to deposit on behalf of /// @param amount the amount of LP tokens to withdraw function depositFor(address recipient, uint256 amount) external; /// @notice deposit LP tokens to the gauge /// @param amount the amount of LP tokens to withdraw function deposit(uint256 amount) external; /// @notice withdraws all fungible LP tokens from legacy gauges function withdrawAll() external; /// @notice withdraws fungible LP tokens from legacy gauges /// @param amount the amount of LP tokens to withdraw function withdraw(uint256 amount) external; /// @notice calculates how many tokens are left to be distributed /// @dev reduces per second /// @param token the address of the token function left(address token) external view returns (uint256); /// @notice add a reward to the whitelist /// @param _reward address of the reward function whitelistReward(address _reward) external; /// @notice remove rewards from the whitelist /// @param _reward address of the reward function removeRewardWhitelist(address _reward) external; /** * @notice amount must be greater than left() for the token, this is to prevent griefing attacks * @notice notifying rewards is completely permissionless * @notice if nobody registers for a newly added reward for the period it will remain in the contract indefinitely */ function notifyRewardAmount(address token, uint256 amount) external; struct Reward { /// @dev tokens per second uint256 rewardRate; /// @dev 7 days after start uint256 periodFinish; uint256 lastUpdateTime; uint256 rewardPerTokenStored; } /// @notice checks if a reward is whitelisted /// @param reward the address of the reward /// @return true if the reward is whitelisted, false otherwise function isWhitelisted(address reward) external view returns (bool); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.26; pragma abicoder v2; interface IShadowVoter { error ACTIVE_GAUGE(address gauge); error GAUGE_INACTIVE(address gauge); error ALREADY_WHITELISTED(address token); error NOT_AUTHORIZED(address caller); error NOT_WHITELISTED(); error NOT_POOL(); error NOT_INIT(); error LENGTH_MISMATCH(); error NO_GAUGE(); error ALREADY_DISTRIBUTED(address gauge, uint256 period); error ZERO_VOTE(address pool); error RATIO_TOO_HIGH(uint256 _xRatio); error VOTE_UNSUCCESSFUL(); event GaugeCreated( address indexed gauge, address creator, address feeDistributor, address indexed pool ); event GaugeKilled(address indexed gauge); event GaugeRevived(address indexed gauge); event Voted(address indexed owner, uint256 weight, address indexed pool); event Abstained(address indexed owner, uint256 weight); event Deposit( address indexed lp, address indexed gauge, address indexed owner, uint256 amount ); event Withdraw( address indexed lp, address indexed gauge, address indexed owner, uint256 amount ); event NotifyReward( address indexed sender, address indexed reward, uint256 amount ); event DistributeReward( address indexed sender, address indexed gauge, uint256 amount ); event EmissionsRatio( address indexed caller, uint256 oldRatio, uint256 newRatio ); event NewGovernor(address indexed sender, address indexed governor); event Whitelisted(address indexed whitelister, address indexed token); event WhitelistRevoked( address indexed forbidder, address indexed token, bool status ); event MainTickSpacingChanged( address indexed token0, address indexed token1, int24 indexed newMainTickSpacing ); event Poke(address indexed user); function initialize( address _shadow, address _legacyFactory, address _gauges, address _feeDistributorFactory, address _minter, address _msig, address _xShadow, address _clFactory, address _clGaugeFactory, address _nfpManager, address _feeRecipientFactory, address _voteModule, address _launcherPlugin ) external; /// @notice denominator basis function BASIS() external view returns (uint256); /// @notice ratio of xShadow emissions globally function xRatio() external view returns (uint256); /// @notice xShadow contract address function xShadow() external view returns (address); /// @notice legacy factory address (uni-v2/stableswap) function legacyFactory() external view returns (address); /// @notice concentrated liquidity factory function clFactory() external view returns (address); /// @notice gauge factory for CL function clGaugeFactory() external view returns (address); /// @notice legacy fee recipient factory function feeRecipientFactory() external view returns (address); /// @notice peripheral NFPManager contract function nfpManager() external view returns (address); /// @notice returns the address of the current governor /// @return _governor address of the governor function governor() external view returns (address _governor); /// @notice the address of the vote module /// @return _voteModule the vote module contract address function voteModule() external view returns (address _voteModule); /// @notice address of the central access Hub function accessHub() external view returns (address); /// @notice the address of the shadow launcher plugin to enable third party launchers /// @return _launcherPlugin the address of the plugin function launcherPlugin() external view returns (address _launcherPlugin); /// @notice distributes emissions from the minter to the voter /// @param amount the amount of tokens to notify function notifyRewardAmount(uint256 amount) external; /// @notice distributes the emissions for a specific gauge /// @param _gauge the gauge address function distribute(address _gauge) external; /// @notice returns the address of the gauge factory /// @param _gaugeFactory gauge factory address function gaugeFactory() external view returns (address _gaugeFactory); /// @notice returns the address of the feeDistributor factory /// @return _feeDistributorFactory feeDist factory address function feeDistributorFactory() external view returns (address _feeDistributorFactory); /// @notice returns the address of the minter contract /// @return _minter address of the minter function minter() external view returns (address _minter); /// @notice check if the gauge is active for governance use /// @param _gauge address of the gauge /// @return _trueOrFalse if the gauge is alive function isAlive(address _gauge) external view returns (bool _trueOrFalse); /// @notice allows the token to be paired with other whitelisted assets to participate in governance /// @param _token the address of the token function whitelist(address _token) external; /// @notice effectively disqualifies a token from governance /// @param _token the address of the token function revokeWhitelist(address _token) external; /// @notice returns if the address is a gauge /// @param gauge address of the gauge /// @return _trueOrFalse boolean if the address is a gauge function isGauge(address gauge) external view returns (bool _trueOrFalse); /// @notice disable a gauge from governance /// @param _gauge address of the gauge function killGauge(address _gauge) external; /// @notice re-activate a dead gauge /// @param _gauge address of the gauge function reviveGauge(address _gauge) external; /// @notice re-cast a tokenID's votes /// @param owner address of the owner function poke(address owner) external; /// @notice sets the main tickspacing of a token pairing /// @param tokenA address of tokenA /// @param tokenB address of tokenB /// @param tickSpacing the main tickspacing to set to function setMainTickSpacing( address tokenA, address tokenB, int24 tickSpacing ) external; /// @notice returns if the address is a fee distributor /// @param _feeDistributor address of the feeDist /// @return _trueOrFalse if the address is a fee distributor function isFeeDistributor( address _feeDistributor ) external view returns (bool _trueOrFalse); /// @notice returns the address of the emission's token /// @return _shadow emissions token contract address function shadow() external view returns (address _shadow); /// @notice returns the address of the pool's gauge, if any /// @param _pool pool address /// @return _gauge gauge address function gaugeForPool(address _pool) external view returns (address _gauge); /// @notice returns the address of the pool's feeDistributor, if any /// @param _gauge address of the gauge /// @return _feeDistributor address of the pool's feedist function feeDistributorForGauge( address _gauge ) external view returns (address _feeDistributor); /// @notice returns the new toPool that was redirected fromPool /// @param fromPool address of the original pool /// @return toPool the address of the redirected pool function poolRedirect( address fromPool ) external view returns (address toPool); /// @notice returns the gauge address of a CL pool /// @param tokenA address of token A in the pair /// @param tokenB address of token B in the pair /// @param tickSpacing tickspacing of the pool /// @return gauge address of the gauge function gaugeForClPool( address tokenA, address tokenB, int24 tickSpacing ) external view returns (address gauge); /// @notice returns the array of all tickspacings for the tokenA/tokenB combination /// @param tokenA address of token A in the pair /// @param tokenB address of token B in the pair /// @return _ts array of all the tickspacings function tickSpacingsForPair( address tokenA, address tokenB ) external view returns (int24[] memory _ts); /// @notice returns the main tickspacing used in the gauge/governance process /// @param tokenA address of token A in the pair /// @param tokenB address of token B in the pair /// @return _ts the main tickspacing function mainTickSpacingForPair( address tokenA, address tokenB ) external view returns (int24 _ts); /// @notice returns the block.timestamp divided by 1 week in seconds /// @return period the period used for gauges function getPeriod() external view returns (uint256 period); /// @notice cast a vote to direct emissions to gauges and earn incentives /// @param owner address of the owner /// @param _pools the list of pools to vote on /// @param _weights an arbitrary weight per pool which will be normalized to 100% regardless of numerical inputs function vote( address owner, address[] calldata _pools, uint256[] calldata _weights ) external; /// @notice reset the vote of an address /// @param owner address of the owner function reset(address owner) external; /// @notice set the governor address /// @param _governor the new governor address function setGovernor(address _governor) external; /// @notice recover stuck emissions /// @param _gauge the gauge address /// @param _period the period function stuckEmissionsRecovery(address _gauge, uint256 _period) external; /// @notice whitelists extra rewards for a gauge /// @param _gauge the gauge to whitelist rewards to /// @param _reward the reward to whitelist function whitelistGaugeRewards(address _gauge, address _reward) external; /// @notice removes a reward from the gauge whitelist /// @param _gauge the gauge to remove the whitelist from /// @param _reward the reward to remove from the whitelist function removeGaugeRewardWhitelist( address _gauge, address _reward ) external; /// @notice creates a legacy gauge for the pool /// @param _pool pool's address /// @return _gauge address of the new gauge function createGauge(address _pool) external returns (address _gauge); /// @notice create a concentrated liquidity gauge /// @param tokenA the address of tokenA /// @param tokenB the address of tokenB /// @param tickSpacing the tickspacing of the pool /// @return _clGauge address of the new gauge function createCLGauge( address tokenA, address tokenB, int24 tickSpacing ) external returns (address _clGauge); /// @notice claim concentrated liquidity gauge rewards for specific NFP token ids /// @param _gauges array of gauges /// @param _tokens two dimensional array for the tokens to claim /// @param _nfpTokenIds two dimensional array for the NFPs function claimClGaugeRewards( address[] calldata _gauges, address[][] calldata _tokens, uint256[][] calldata _nfpTokenIds ) external; /// @notice claim arbitrary rewards from specific feeDists /// @param owner address of the owner /// @param _feeDistributors address of the feeDists /// @param _tokens two dimensional array for the tokens to claim function claimIncentives( address owner, address[] calldata _feeDistributors, address[][] calldata _tokens ) external; /// @notice claim arbitrary rewards from specific gauges /// @param _gauges address of the gauges /// @param _tokens two dimensional array for the tokens to claim function claimRewards( address[] calldata _gauges, address[][] calldata _tokens ) external; /// @notice claim arbitrary rewards from specific legacy gauges, and exit to shadow /// @param _gauges address of the gauges /// @param _tokens two dimensional array for the tokens to claim function claimLegacyRewardsAndExit( address[] calldata _gauges, address[][] calldata _tokens ) external; /// @notice distribute emissions to a gauge for a specific period /// @param _gauge address of the gauge /// @param _period value of the period function distributeForPeriod(address _gauge, uint256 _period) external; /// @notice attempt distribution of emissions to all gauges function distributeAll() external; /// @notice distribute emissions to gauges by index /// @param startIndex start of the loop /// @param endIndex end of the loop function batchDistributeByIndex( uint256 startIndex, uint256 endIndex ) external; /// @notice returns the votes cast for a tokenID /// @param owner address of the owner /// @return votes an array of votes casted /// @return weights an array of the weights casted per pool function getVotes( address owner, uint256 period ) external view returns (address[] memory votes, uint256[] memory weights); /// @notice returns an array of all the gauges /// @return _gauges the array of gauges function getAllGauges() external view returns (address[] memory _gauges); /// @notice returns an array of all the feeDists /// @return _feeDistributors the array of feeDists function getAllFeeDistributors() external view returns (address[] memory _feeDistributors); /// @notice sets the xShadowRatio default function setGlobalRatio(uint256 _xRatio) external; /// @notice whether the token is whitelisted in governance function isWhitelisted(address _token) external view returns (bool _tf); /// @notice function for removing malicious or stuffed tokens function removeFeeDistributorReward( address _feeDist, address _token ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; interface ISwapxGauge { function notifyRewardAmount(address token, uint amount) external; // function getReward(address account, address[] memory tokens) external; function getReward(address account) external; function getReward() external; function deposit(uint256 amount) external; function withdraw(uint256 amount) external; function claimFees() external returns (uint claimed0, uint claimed1); function left(address token) external view returns (uint); function rewardRate(address _pair) external view returns (uint); function balanceOf(address _account) external view returns (uint); function isForPair() external view returns (bool); function totalSupply() external view returns (uint); function earned(address token, address account) external view returns (uint); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.26; pragma abicoder v2; interface ISwapxVoter { function gauges(address _pool) external view returns (address); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.24; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; interface IX33 is IERC20 { /// @dev parameters passed to the aggregator swap struct AggregatorParams { address aggregator; // address of the whitelisted aggregator address tokenIn; // token to swap from uint256 amountIn; // amount of tokenIn to swap uint256 minAmountOut; // minimum amount of tokenOut to receive bytes callData; // encoded swap calldata } /** * Error strings */ error ZERO(); error NOT_ENOUGH(); error NOT_CONFORMED_TO_SCALE(uint256); error NOT_ACCESSHUB(address); error LOCKED(); error REBASE_IN_PROGRESS(); error AGGREGATOR_REVERTED(bytes); error AMOUNT_OUT_TOO_LOW(uint256); error AGGREGATOR_NOT_WHITELISTED(address); error FORBIDDEN_TOKEN(address); event Entered(address indexed user, uint256 amount, uint256 ratioAtDeposit); event Exited(address indexed user, uint256 _outAmount, uint256 ratioAtWithdrawal); event NewOperator(address _oldOperator, address _newOperator); event Compounded(uint256 oldRatio, uint256 newRatio, uint256 amount); event SwappedBribe(address indexed operator, address indexed tokenIn, uint256 amountIn, uint256 amountOut); event Rebased(uint256 oldRatio, uint256 newRatio, uint256 amount); /// @notice Event emitted when an aggregator's whitelist status changes event AggregatorWhitelistUpdated(address aggregator, bool status); event Unlocked(uint256 _ts); event UpdatedIndex(uint256 _index); event ClaimedIncentives(address[] feeDistributors, address[][] tokens); /// @notice submits the optimized votes for the epoch function submitVotes(address[] calldata _pools, uint256[] calldata _weights) external; /// @notice swap function using aggregators to process rewards into SHADOW function swapIncentiveViaAggregator(AggregatorParams calldata _params) external; /// @notice claims the rebase accrued to x33 function claimRebase() external; /// @notice compounds any existing SHADOW within the contract function compound() external; /// @notice direct claim function claimIncentives(address[] calldata _feeDistributors, address[][] calldata _tokens) external; /// @notice rescue stuck tokens function rescue(address _token, uint256 _amount) external; /// @notice allows the operator to unlock the contract for the current period function unlock() external; /// @notice add or remove an aggregator from the whitelist (timelocked) /// @param _aggregator address of the aggregator to update /// @param _status new whitelist status function whitelistAggregator(address _aggregator, bool _status) external; /// @notice transfers the operator via accesshub function transferOperator(address _newOperator) external; /// @notice simple getPeriod call function getPeriod() external view returns (uint256 period); /// @notice if the contract is unlocked for deposits function isUnlocked() external view returns (bool); /// @notice determines whether the cooldown is active function isCooldownActive() external view returns (bool); /// @notice address of the current operator function operator() external view returns (address); /// @notice accessHub address function accessHub() external view returns (address); /// @notice returns the ratio of xShadow per X33 token function ratio() external view returns (uint256 _ratio); /// @notice the most recent active period the contract has interacted in function activePeriod() external view returns (uint256); /// @notice whether the periods are unlocked function periodUnlockStatus(uint256 _period) external view returns (bool unlocked); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; 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; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IOracle { function update() external; function consult(address _token, uint256 _amountIn) external view returns (uint256 amountOut); function twap(address _token, uint256 _amountIn) external view returns (uint256 _amountOut); }
{ "optimizer": { "enabled": true, "runs": 200 }, "evmVersion": "paris", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_gsnake","type":"address"},{"internalType":"address","name":"_bribesSafe","type":"address"},{"internalType":"uint256","name":"_poolStartTime","type":"uint256"},{"internalType":"address","name":"_shadowVoter","type":"address"},{"internalType":"address","name":"_swapxVoter","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"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":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"SWAPX_TOKEN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"X33_TOKEN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"XSHADOW_TOKEN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_allocPoint","type":"uint256"},{"internalType":"uint256","name":"_depFee","type":"uint256"},{"internalType":"contract IERC20","name":"_token","type":"address"},{"internalType":"bool","name":"_withUpdate","type":"bool"},{"internalType":"uint256","name":"_lastRewardTime","type":"uint256"}],"name":"add","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"bribesSafe","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_pids","type":"uint256[]"},{"internalType":"uint256[]","name":"_allocPoints","type":"uint256[]"},{"internalType":"uint256[]","name":"_depFees","type":"uint256[]"}],"name":"bulkSet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"claimAllRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimGaugeRewardsOnUpdatePool","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"collectSonic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"convertXShadow","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":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"enum GSnakeRewardPoolV2.GaugeDex","name":"_gaugeDex","type":"uint8"}],"name":"enableGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fromTime","type":"uint256"},{"internalType":"uint256","name":"_toTime","type":"uint256"}],"name":"getGeneratedReward","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":[],"name":"gsnake","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gsnakeOracle","outputs":[{"internalType":"contract IOracle","name":"","type":"address"}],"stateMutability":"view","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":[{"internalType":"uint256","name":"_fromPid","type":"uint256"},{"internalType":"uint256","name":"_toPid","type":"uint256"}],"name":"massUpdatePoolsInRange","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":"pegStabilityModuleFeeEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"pendingRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"pendingShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"pendingShareAndPendingRewards","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":"depFee","type":"uint256"},{"internalType":"uint256","name":"allocPoint","type":"uint256"},{"internalType":"uint256","name":"lastRewardTime","type":"uint256"},{"internalType":"uint256","name":"accGsnakePerShare","type":"uint256"},{"internalType":"bool","name":"isStarted","type":"bool"},{"components":[{"internalType":"bool","name":"isGauge","type":"bool"},{"internalType":"address","name":"gauge","type":"address"},{"internalType":"enum GSnakeRewardPoolV2.GaugeDex","name":"gaugeDex","type":"uint8"}],"internalType":"struct GSnakeRewardPoolV2.GaugeInfo","name":"gaugeInfo","type":"tuple"},{"internalType":"uint256","name":"poolGsnakePerSec","type":"uint256"}],"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":"runningTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_allocPoint","type":"uint256"},{"internalType":"uint256","name":"_depFee","type":"uint256"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_bribesSafe","type":"address"}],"name":"setBribesSafe","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_claimGaugeRewardsOnUpdatePool","type":"bool"}],"name":"setClaimGaugeRewardsOnUpdatePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IOracle","name":"_gsnakeOracle","type":"address"}],"name":"setGSnakeOracle","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":"bool","name":"_enabled","type":"bool"}],"name":"setPegStabilityModuleFeeEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shadowVoter","outputs":[{"internalType":"contract IShadowVoter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sharePerSecond","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"swapxVoter","outputs":[{"internalType":"contract ISwapxVoter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAllocPoint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"updatePoolWithGaugeDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"userInfo","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"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"}]
Contract Creation Code
60806040526003805461ffff60a01b191661010160a01b179055609660045564e8d4a510006005556000600c819055600f556303c2670060105534801561004557600080fd5b50604051614f80380380614f808339810160408190526100649161127d565b60016000554283116100bd5760405162461bcd60e51b815260206004820181905260248201527f706f6f6c2063616e74206265207374617274656420696e20746865207061737460448201526064015b60405180910390fd5b6001600160a01b038516156100e857600280546001600160a01b0319166001600160a01b0387161790555b6001600160a01b0384161561011357600880546001600160a01b0319166001600160a01b0386161790555b600d83905560105461012590846112f2565b600e5560018054336001600160a01b0319918216179091556006805482166001600160a01b03858116919091179091556007805483168483161790556008805490921690861617905561019060008073287c6882de298665977787e268f3dba052a6e25181806101bc565b6101b260008073b901d7316447c84f4417b8a8268e2822095051e681806101bc565b5050505050611576565b6001546001600160a01b0316331461022b5760405162461bcd60e51b815260206004820152602c60248201527f47536e616b65526577617264506f6f6c3a2063616c6c6572206973206e6f742060448201526b3a34329037b832b930ba37b960a11b60648201526084016100b4565b61023483610446565b8115610242576102426104e5565b600d54421015610271578060000361025d5750600d54610285565b600d5481101561026c5750600d545b610285565b80158061027d57504281105b156102855750425b6000600d54821115806102985750428211155b90506009604051806101000160405280866001600160a01b03168152602001878152602001888152602001848152602001600081526020018315158152602001604051806060016040528060001515815260200160006001600160a01b031681526020016000600281111561030f5761030f611305565b905281526020908101899052825460018181018555600094855293829020835160089092020180546001600160a01b039283166001600160a01b03199091161781558383015194810194909455604080840151600280870191909155606085015160038701556080850151600487015560a085015160058701805491151560ff1990921691909117905560c085015180516006880180549683015190951661010002610100600160a81b0319911515919091166001600160a81b031990961695909517949094178084559184015194959491839160ff60a81b1990911690600160a81b90849081111561040457610404611305565b0217905550505060e082015181600701555050801561043e57600c5461042a9087610511565b600c55600f5461043a9087610511565b600f555b505050505050565b60095460005b818110156104e057826001600160a01b0316600982815481106104715761047161131b565b60009182526020909120600890910201546001600160a01b0316036104d85760405162461bcd60e51b815260206004820181905260248201527f47536e616b65526577617264506f6f6c3a206578697374696e6720706f6f6c3f60448201526064016100b4565b60010161044c565b505050565b60095460005b8181101561050d576104fc81610526565b61050581610743565b6001016104eb565b5050565b600061051d82846112f2565b90505b92915050565b61052f81610743565b6000600982815481106105445761054461131b565b9060005260206000209060080201905080600301544211610563575050565b600681015460009060ff166105e25781546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156105b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105dd9190611331565b610654565b60068201546040516370a0823160e01b81523060048201526101009091046001600160a01b0316906370a0823190602401602060405180830381865afa158015610630573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106549190611331565b90508060000361066957504260039091015550565b600582015460ff166106ad5760058201805460ff191660011790556002820154600c5461069591610511565b600c556007820154600f546106a991610511565b600f555b600c54156107205760006106cb83600301544261095860201b60201c565b905060006106f2600c546106ec866002015485610a0760201b90919060201c565b90610a13565b905061071861070d846106ec84670de0b6b3a7640000610a07565b600486015490610511565b600485015550505b4260038381019190915554600160a01b900460ff16156104e0576104e083610a1f565b6000600982815481106107585761075861131b565b60009182526020822060089190910201600681015481546040516370a0823160e01b81523060048201529294506101009091046001600160a01b0390811693929116906370a0823190602401602060405180830381865afa1580156107c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e59190611331565b600684015490915060ff1615610952578015610952578254604051636eb1769f60e11b81523060048201526001600160a01b0384811660248301528392169063dd62ed3e90604401602060405180830381865afa15801561084a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061086e9190611331565b10156108ed57825460405163095ea7b360e01b81526001600160a01b03848116600483015260001960248301529091169063095ea7b3906044016020604051808303816000875af11580156108c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108eb919061134a565b505b600683015460405163b6b55f2560e01b8152600481018390526101009091046001600160a01b03169063b6b55f2590602401600060405180830381600087803b15801561093957600080fd5b505af115801561094d573d6000803e3d6000fd5b505050505b50505050565b600081831061096957506000610520565b600e5482106109c657600e54831061098357506000610520565b600d5483116109b157600f54600d54600e546109aa92916109a49190610ab4565b90610a07565b9050610520565b600f54600e546109aa91906109a49086610ab4565b600d5482116109d757506000610520565b600d5483116109f657600f54600d546109aa91906109a4908590610ab4565b600f546109aa906109a48486610ab4565b600061051d8284611373565b600061051d828461138a565b600060098281548110610a3457610a3461131b565b60009182526020909120600890910201600681015490915060ff161561050d5760016006820154600160a81b900460ff166002811115610a7657610a76611305565b03610a8457610a8482610ac0565b60026006820154600160a81b900460ff166002811115610aa657610aa6611305565b0361050d5761050d82610ccb565b600061051d82846113ac565b600060098281548110610ad557610ad561131b565b9060005260206000209060080201905060008160060160000160019054906101000a90046001600160a01b03166001600160a01b0316638003b6146040518163ffffffff1660e01b8152600401600060405180830381865afa158015610b3f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b6791908101906113d5565b60068301546040516331279d3d60e01b815291925061010090046001600160a01b0316906331279d3d90610ba190309085906004016114a4565b600060405180830381600087803b158015610bbb57600080fd5b505af1158015610bcf573d6000803e3d6000fd5b5050505060005b8151811015610952576000828281518110610bf357610bf361131b565b60209081029190910101516040516370a0823160e01b81523060048201529091506000906001600160a01b038316906370a0823190602401602060405180830381865afa158015610c48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c6c9190611331565b90508015610cc157735050bc082ff4a74fb6b0b04385defddb114b2423196001600160a01b03831601610ca757610ca281610df7565b610cc1565b600854610cc1906001600160a01b03848116911683610fad565b5050600101610bd6565b600060098281548110610ce057610ce061131b565b906000526020600020906008020190508060060160000160019054906101000a90046001600160a01b03166001600160a01b0316633d18b9126040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610d4557600080fd5b505af1158015610d59573d6000803e3d6000fd5b50506040516370a0823160e01b815230600482015273a04bc7140c26fc9bb1f36b1a604c7a5a88fb0e7092506000915082906370a0823190602401602060405180830381865afa158015610db1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dd59190611331565b9050801561095257600854610952906001600160a01b03848116911683610fad565b60405163095ea7b360e01b8152733333111a391cc08fa51353e9195526a70b333333600482015260248101829052735050bc082ff4a74fb6b0b04385defddb114b24249063095ea7b3906044016020604051808303816000875af1158015610e63573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e87919061134a565b506000733333111a391cc08fa51353e9195526a70b3333336001600160a01b0316638380edb76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610edc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f00919061134a565b9050801561050d57604051636e553f6560e01b815260048101839052306024820152733333111a391cc08fa51353e9195526a70b33333390636e553f65906044016020604051808303816000875af1158015610f60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f849190611331565b5060085461050d90733333111a391cc08fa51353e9195526a70b333333906001600160a01b0316845b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663a9059cbb60e01b179091526104e091859161100316565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656490820152600090611050906001600160a01b0385169084906110d0565b9050805160001480611071575080806020019051810190611071919061134a565b6104e05760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016100b4565b60606110df84846000856110e7565b949350505050565b6060824710156111485760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016100b4565b600080866001600160a01b031685876040516111649190611527565b60006040518083038185875af1925050503d80600081146111a1576040519150601f19603f3d011682016040523d82523d6000602084013e6111a6565b606091505b5090925090506111b8878383876111c3565b979650505050505050565b6060831561123257825160000361122b576001600160a01b0385163b61122b5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016100b4565b50816110df565b6110df83838151156112475781518083602001fd5b8060405162461bcd60e51b81526004016100b49190611543565b80516001600160a01b038116811461127857600080fd5b919050565b600080600080600060a0868803121561129557600080fd5b61129e86611261565b94506112ac60208701611261565b604087015190945092506112c260608701611261565b91506112d060808701611261565b90509295509295909350565b634e487b7160e01b600052601160045260246000fd5b80820180821115610520576105206112dc565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b60006020828403121561134357600080fd5b5051919050565b60006020828403121561135c57600080fd5b8151801515811461136c57600080fd5b9392505050565b8082028115828204841417610520576105206112dc565b6000826113a757634e487b7160e01b600052601260045260246000fd5b500490565b81810381811115610520576105206112dc565b634e487b7160e01b600052604160045260246000fd5b6000602082840312156113e757600080fd5b81516001600160401b038111156113fd57600080fd5b8201601f8101841361140e57600080fd5b80516001600160401b03811115611427576114276113bf565b604051600582901b90603f8201601f191681016001600160401b0381118282101715611455576114556113bf565b60405291825260208184018101929081018784111561147357600080fd5b6020850194505b838510156114995761148b85611261565b81526020948501940161147a565b509695505050505050565b6001600160a01b0383168152604060208083018290528351918301829052600091908401906060840190835b818110156114f75783516001600160a01b03168352602093840193909201916001016114d0565b50909695505050505050565b60005b8381101561151e578181015183820152602001611506565b50506000910152565b60008251611539818460208701611503565b9190910192915050565b6020815260008251806020840152611562816040850160208701611503565b601f01601f19169190910160400192915050565b6139fb806115856000396000f3fe6080604052600436106102925760003560e01c80636b2681c51161015a578063ba44a45a116100c1578063d18df53c1161007a578063d18df53c146107e9578063ddc6326214610821578063de89c76c14610834578063dfbffa8c14610854578063e2bbb1581461087c578063fddc298c1461089c57600080fd5b8063ba44a45a14610733578063c69c2c0214610749578063ce862f1714610769578063cec39bd114610789578063ced8a5d7146107a9578063cf4b55cb146107c957600080fd5b80638ed955b9116101135780638ed955b91461066157806390c5ed6a1461066957806393f1a40b14610689578063943f013d146106dd578063b3ab15fb146106f3578063b947a88d1461071357600080fd5b80636b2681c5146105aa5780636e142c8e146105ca5780636e271dd5146105ea578063717478021461060057806378e39d5d146106215780637ebd739f1461064157600080fd5b8063441a3e70116101fe57806357356232116101b757806357356232146105095780635752933a146105295780635f96dc111461053f5780636057836914610555578063630b5ba11461057557806363eb04161461058a57600080fd5b8063441a3e701461044e57806351637ba9146104615780635312ea8e1461048157806354575af4146104a1578063549c278a146104c1578063570ca735146104e957600080fd5b80632760f89b116102505780632760f89b146103875780632df95ed7146103a75780633202f6c1146103c75780633695dad1146103e75780633afb24f1146103fd57806343b0e8df1461042e57600080fd5b8062c6b39114610297578063033cdb61146102dc578063081e3eda146102fe5780631526fe271461031d57806317caf6f114610351578063231f0c6a14610367575b600080fd5b3480156102a357600080fd5b506102bf735050bc082ff4a74fb6b0b04385defddb114b242481565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156102e857600080fd5b506102fc6102f73660046132f0565b6108bc565b005b34801561030a57600080fd5b506009545b6040519081526020016102d3565b34801561032957600080fd5b5061033d6103383660046132f0565b6108fb565b6040516102d398979695949392919061331f565b34801561035d57600080fd5b5061030f600c5481565b34801561037357600080fd5b5061030f6103823660046133a9565b6109ba565b34801561039357600080fd5b506003546102bf906001600160a01b031681565b3480156103b357600080fd5b506102fc6103c23660046132f0565b610a7f565b3480156103d357600080fd5b506006546102bf906001600160a01b031681565b3480156103f357600080fd5b5061030f60055481565b34801561040957600080fd5b5060035461041e90600160a01b900460ff1681565b60405190151581526020016102d3565b34801561043a57600080fd5b506102fc6104493660046133cb565b610c94565b6102fc61045c3660046133a9565b610d5f565b34801561046d57600080fd5b506102fc61047c3660046132f0565b610f49565b34801561048d57600080fd5b506102fc61049c3660046132f0565b610fe6565b3480156104ad57600080fd5b506102fc6104bc36600461340c565b6110ba565b3480156104cd57600080fd5b506102bf733333111a391cc08fa51353e9195526a70b33333381565b3480156104f557600080fd5b506001546102bf906001600160a01b031681565b34801561051557600080fd5b506102fc61052436600461344e565b6111a9565b34801561053557600080fd5b5061030f600f5481565b34801561054b57600080fd5b5061030f600d5481565b34801561056157600080fd5b506102fc6105703660046132f0565b6111f5565b34801561058157600080fd5b506102fc611291565b34801561059657600080fd5b506102fc6105a5366004613479565b6112b9565b3480156105b657600080fd5b5061030f6105c5366004613496565b611301565b3480156105d657600080fd5b506007546102bf906001600160a01b031681565b3480156105f657600080fd5b5061030f600e5481565b34801561060c57600080fd5b5060035461041e90600160a81b900460ff1681565b34801561062d57600080fd5b506102fc61063c3660046132f0565b611347565b34801561064d57600080fd5b506102fc61065c3660046132f0565b61140b565b6102fc6114a0565b34801561067557600080fd5b506102fc6106843660046134c6565b61185f565b34801561069557600080fd5b506106c86106a4366004613496565b600a6020908152600092835260408084209091529082529020805460019091015482565b604080519283526020830191909152016102d3565b3480156106e957600080fd5b5061030f60105481565b3480156106ff57600080fd5b506102fc61070e36600461344e565b611aa4565b34801561071f57600080fd5b506102fc61072e3660046133a9565b611af0565b34801561073f57600080fd5b5061030f60045481565b34801561075557600080fd5b506102fc610764366004613479565b611b70565b34801561077557600080fd5b506102fc610784366004613518565b611bb8565b34801561079557600080fd5b506002546102bf906001600160a01b031681565b3480156107b557600080fd5b506102fc6107c436600461344e565b611c26565b3480156107d557600080fd5b5061030f6107e4366004613496565b611c72565b3480156107f557600080fd5b5061030f610804366004613496565b600b60209081526000928352604080842090915290825290205481565b6102fc61082f3660046132f0565b611e57565b34801561084057600080fd5b506008546102bf906001600160a01b031681565b34801561086057600080fd5b506102bf73a04bc7140c26fc9bb1f36b1a604c7a5a88fb0e7081565b34801561088857600080fd5b506102fc6108973660046133a9565b6121e6565b3480156108a857600080fd5b506102fc6108b736600461358d565b6123c1565b6001546001600160a01b031633146108ef5760405162461bcd60e51b81526004016108e690613633565b60405180910390fd5b6108f8816124b4565b50565b6009818154811061090b57600080fd5b6000918252602091829020600890910201805460018201546002808401546003850154600486015460058701546040805160608101825260068a01805460ff8181161515845261010082046001600160a01b039081169e85019e909e529c909a169c50979a9599949893979286169694959094929391850192600160a81b909204169081111561099d5761099d613309565b60028111156109ae576109ae613309565b90525060079091015488565b60008183106109cb57506000610a79565b600e548210610a3357600e5483106109e557506000610a79565b600d548311610a1857610a11600f54610a0b600d54600e5461266e90919063ffffffff16565b90612681565b9050610a79565b610a11600f54610a0b85600e5461266e90919063ffffffff16565b600d548211610a4457506000610a79565b600d548311610a6857610a11600f54610a0b600d548561266e90919063ffffffff16565b600f54610a1190610a0b848661266e565b92915050565b600060098281548110610a9457610a9461367f565b60009182526020822060089190910201600681015481546040516370a0823160e01b81523060048201529294506101009091046001600160a01b0390811693929116906370a0823190602401602060405180830381865afa158015610afd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b219190613695565b600684015490915060ff1615610c8e578015610c8e578254604051636eb1769f60e11b81523060048201526001600160a01b0384811660248301528392169063dd62ed3e90604401602060405180830381865afa158015610b86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610baa9190613695565b1015610c2957825460405163095ea7b360e01b81526001600160a01b03848116600483015260001960248301529091169063095ea7b3906044016020604051808303816000875af1158015610c03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c2791906136ae565b505b600683015460405163b6b55f2560e01b8152600481018390526101009091046001600160a01b03169063b6b55f2590602401600060405180830381600087803b158015610c7557600080fd5b505af1158015610c89573d6000803e3d6000fd5b505050505b50505050565b6001546001600160a01b03163314610cbe5760405162461bcd60e51b81526004016108e690613633565b610cc6611291565b600060098481548110610cdb57610cdb61367f565b9060005260206000209060080201905060c88210610cf857600080fd5b60018101829055600581015460ff1615610d4d57610d2f83610d298360020154600c5461266e90919063ffffffff16565b9061268d565b600c556007810154600f54610d49918591610d299161266e565b600f555b60028101839055600701919091555050565b610d67612699565b6000339050600060098481548110610d8157610d8161367f565b60009182526020808320878452600a825260408085206001600160a01b03881686529092529220805460089092029092019250841115610df85760405162461bcd60e51b81526020600482015260126024820152711dda5d1a191c985dce881b9bdd0819dbdbd960721b60448201526064016108e6565b610e01856126f2565b610e0a85610a7f565b6000610e478260010154610e41670de0b6b3a7640000610e3b8760040154876000015461268190919063ffffffff16565b90612903565b9061266e565b90508015610ea0576000868152600b602090815260408083206001600160a01b0388168452909152902054610e7c908261268d565b6000878152600b602090815260408083206001600160a01b03891684529091529020555b8415610ed4578154610eb2908661266e565b8255610ebe868661290f565b8254610ed4906001600160a01b031685876129a4565b60048301548254610ef291670de0b6b3a764000091610e3b91612681565b600183015560405185815286906001600160a01b038616907ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b5689060200160405180910390a350505050610f456001600055565b5050565b6001546001600160a01b03163314610f735760405162461bcd60e51b81526004016108e690613633565b670de0b6b3a7640000811115610fe15760405162461bcd60e51b815260206004820152602d60248201527f47536e616b65526577617264506f6f6c3a20696e76616c6964206d617820636c60448201526c185a5b481d1a1c995cda1bdb19609a1b60648201526084016108e6565b600555565b610fee612699565b6000600982815481106110035761100361367f565b60009182526020808320858452600a825260408085203386529092529220805460089092029092019250611037848261290f565b6000848152600b60209081526040808320338085529252822082905581845560018401919091558354611076916001600160a01b0390911690836129a4565b604051818152849033907fbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae05959060200160405180910390a35050506108f86001600055565b6001546001600160a01b031633146110e45760405162461bcd60e51b81526004016108e690613633565b60095460005b81811015611194576000600982815481106111075761110761367f565b6000918252602090912060089091020180549091506001600160a01b039081169087160361118b5760405162461bcd60e51b815260206004820152602b60248201527f5368617265526577617264506f6f6c3a20546f6b656e2063616e6e6f7420626560448201526a103837b7b6103a37b5b2b760a91b60648201526084016108e6565b506001016110ea565b50610c8e6001600160a01b03851683856129a4565b6001546001600160a01b031633146111d35760405162461bcd60e51b81526004016108e690613633565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b0316331461121f5760405162461bcd60e51b81526004016108e690613633565b6101f481111561128c5760405162461bcd60e51b815260206004820152603260248201527f47536e616b65526577617264506f6f6c3a20696e76616c6964207065672073746044820152716162696c697479206d6f64756c652066656560701b60648201526084016108e6565b600455565b60095460005b81811015610f45576112a8816126f2565b6112b181610a7f565b600101611297565b6001546001600160a01b031633146112e35760405162461bcd60e51b81526004016108e690613633565b60038054911515600160a01b0260ff60a01b19909216919091179055565b60008061130e8484611c72565b6000858152600b602090815260408083206001600160a01b038816845290915290205490915061133f90829061268d565b949350505050565b6001546001600160a01b031633146113715760405162461bcd60e51b81526004016108e690613633565b6008546040516000916001600160a01b03169083908381818185875af1925050503d80600081146113be576040519150601f19603f3d011682016040523d82523d6000602084013e6113c3565b606091505b5050905080610f455760405162461bcd60e51b81526020600482015260146024820152736661696c656420746f2073656e6420536f6e696360601b60448201526064016108e6565b6000600982815481106114205761142061367f565b60009182526020909120600890910201600681015490915060ff1615610f455760016006820154600160a81b900460ff16600281111561146257611462613309565b036114705761147082612a07565b60026006820154600160a81b900460ff16600281111561149257611492613309565b03610f4557610f4582612c12565b6114a8612699565b60095433906000805b828110156115dc576000600982815481106114ce576114ce61367f565b60009182526020808320858452600a825260408085206001600160a01b038b168652909252922060089091029091019150611508836126f2565b61151183610a7f565b60006115428260010154610e41670de0b6b3a7640000610e3b8760040154876000015461268190919063ffffffff16565b6000858152600b602090815260408083206001600160a01b038c168452909152812054919250611572838361268d565b905080156115aa576000868152600b602090815260408083206001600160a01b038d1684529091528120556115a7878261268d565b96505b600485015484546115c891670de0b6b3a764000091610e3b91612681565b6001948501555050509190910190506114b1565b506005548110156115ff5760405162461bcd60e51b81526004016108e6906136cb565b801561185057600354600090600160a81b900460ff161561172257600354600254604051630d01142560e31b81526001600160a01b039182166004820152670de0b6b3a764000060248201526000929190911690636808a12890604401602060405180830381865afa158015611679573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061169d9190613695565b90506116ca6103e8610e3b600454610a0b670de0b6b3a7640000610e3b898861268190919063ffffffff16565b91508134101561171c5760405162461bcd60e51b815260206004820152601f60248201527f696e73756666696369656e7420736f6e696320666f722050534d20636f73740060448201526064016108e6565b50611740565b34156117405760405162461bcd60e51b81526004016108e69061370f565b61174a8483612d3e565b836001600160a01b03167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e04868360405161178591815260200190565b60405180910390a2600354600160a81b900460ff1680156117a557508034115b1561184e5760006117b68234613768565b90506000856001600160a01b03168260405160006040518083038185875af1925050503d8060008114611805576040519150601f19603f3d011682016040523d82523d6000602084013e61180a565b606091505b505090508061184b5760405162461bcd60e51b815260206004820152600d60248201526c1499599d5b990819985a5b1959609a1b60448201526064016108e6565b50505b505b50505061185d6001600055565b565b6001546001600160a01b031633146118895760405162461bcd60e51b81526004016108e690613633565b61189283612de9565b81156118a0576118a0611291565b600d544210156118cf57806000036118bb5750600d546118e3565b600d548110156118ca5750600d545b6118e3565b8015806118db57504281105b156118e35750425b6000600d54821115806118f65750428211155b90506009604051806101000160405280866001600160a01b03168152602001878152602001888152602001848152602001600081526020018315158152602001604051806060016040528060001515815260200160006001600160a01b031681526020016000600281111561196d5761196d613309565b905281526020908101899052825460018181018555600094855293829020835160089092020180546001600160a01b039283166001600160a01b03199091161781558383015194810194909455604080840151600280870191909155606085015160038701556080850151600487015560a085015160058701805491151560ff1990921691909117905560c085015180516006880180549683015190951661010002610100600160a81b0319911515919091166001600160a81b031990961695909517949094178084559184015194959491839160ff60a81b1990911690600160a81b908490811115611a6257611a62613309565b0217905550505060e0820151816007015550508015611a9c57600c54611a88908761268d565b600c55600f54611a98908761268d565b600f555b505050505050565b6001546001600160a01b03163314611ace5760405162461bcd60e51b81526004016108e690613633565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b80821115611b405760405162461bcd60e51b815260206004820152601f60248201527f47536e616b65526577617264506f6f6c3a20696e76616c69642072616e67650060448201526064016108e6565b815b818111611b6b57611b52816126f2565b611b5b81610a7f565b611b648161377b565b9050611b42565b505050565b6001546001600160a01b03163314611b9a5760405162461bcd60e51b81526004016108e690613633565b60038054911515600160a81b0260ff60a81b19909216919091179055565b6001546001600160a01b03163314611be25760405162461bcd60e51b81526004016108e690613633565b6001816002811115611bf657611bf6613309565b03611c0457611c0482612e83565b6002816002811115611c1857611c18613309565b03610f4557610f4582612ff5565b6001546001600160a01b03163314611c505760405162461bcd60e51b81526004016108e690613633565b600880546001600160a01b0319166001600160a01b0392909216919091179055565b60008060098481548110611c8857611c8861367f565b60009182526020808320878452600a825260408085206001600160a01b0389168652909252908320600892909202016004810154600682015491945091929060ff16611d3e5783546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015611d15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d399190613695565b611db0565b60068401546040516370a0823160e01b81523060048201526101009091046001600160a01b0316906370a0823190602401602060405180830381865afa158015611d8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611db09190613695565b9050836003015442118015611dc457508015155b15611e21576000611dd98560030154426109ba565b90506000611dfa600c54610e3b88600201548561268190919063ffffffff16565b9050611e1c611e1584610e3b84670de0b6b3a7640000612681565b859061268d565b935050505b611e4c8360010154610e41670de0b6b3a7640000610e3b86886000015461268190919063ffffffff16565b979650505050505050565b611e5f612699565b6000339050600060098381548110611e7957611e7961367f565b60009182526020808320868452600a825260408085206001600160a01b0388168652909252922060089091029091019150611eb3846126f2565b611ebc84610a7f565b6000611eed8260010154610e41670de0b6b3a7640000610e3b8760040154876000015461268190919063ffffffff16565b6000868152600b602090815260408083206001600160a01b0389168452909152812054919250611f1d838361268d565b9050600554811015611f415760405162461bcd60e51b81526004016108e6906136cb565b80156121b4576000878152600b602090815260408083206001600160a01b038a1684529091528120819055600354600160a81b900460ff161561208657600354600254604051630d01142560e31b81526001600160a01b039182166004820152670de0b6b3a764000060248201526000929190911690636808a12890604401602060405180830381865afa158015611fdd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120019190613695565b905061202e6103e8610e3b600454610a0b670de0b6b3a7640000610e3b898861268190919063ffffffff16565b9150813410156120805760405162461bcd60e51b815260206004820152601f60248201527f696e73756666696369656e7420736f6e696320666f722050534d20636f73740060448201526064016108e6565b506120a4565b34156120a45760405162461bcd60e51b81526004016108e69061370f565b6120ae8783612d3e565b866001600160a01b03167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e0486836040516120e991815260200190565b60405180910390a2600354600160a81b900460ff16801561210957508034115b156121b257600061211a8234613768565b90506000886001600160a01b03168260405160006040518083038185875af1925050503d8060008114612169576040519150601f19603f3d011682016040523d82523d6000602084013e61216e565b606091505b50509050806121af5760405162461bcd60e51b815260206004820152600d60248201526c1499599d5b990819985a5b1959609a1b60448201526064016108e6565b50505b505b600485015484546121d291670de0b6b3a764000091610e3b91612681565b600194850155505050600055506108f89050565b6121ee612699565b60003390506000600984815481106122085761220861367f565b60009182526020808320878452600a825260408085206001600160a01b0388168652909252922060089091029091019150612242856126f2565b8054156122d557600061227a8260010154610e41670de0b6b3a7640000610e3b8760040154876000015461268190919063ffffffff16565b905080156122d3576000868152600b602090815260408083206001600160a01b03881684529091529020546122af908261268d565b6000878152600b602090815260408083206001600160a01b03891684529091529020555b505b83156123485781546122f2906001600160a01b03168430876130d0565b6000612311612710610e3b85600101548861268190919063ffffffff16565b9050612328612320868361266e565b83549061268d565b82556008548354612346916001600160a01b039182169116836129a4565b505b61235185610a7f565b6004820154815461236f91670de0b6b3a764000091610e3b91612681565b600182015560405184815285906001600160a01b038516907f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a159060200160405180910390a3505050610f456001600055565b6001546001600160a01b031633146123eb5760405162461bcd60e51b81526004016108e690613633565b84831480156123f957508481145b6124455760405162461bcd60e51b815260206004820181905260248201527f47536e616b65526577617264506f6f6c3a20696e76616c6964206c656e67746860448201526064016108e6565b60005b858110156124ab576124a38787838181106124655761246561367f565b9050602002013586868481811061247e5761247e61367f565b905060200201358585858181106124975761249761367f565b90506020020135610c94565b600101612448565b50505050505050565b60405163095ea7b360e01b8152733333111a391cc08fa51353e9195526a70b333333600482015260248101829052735050bc082ff4a74fb6b0b04385defddb114b24249063095ea7b3906044016020604051808303816000875af1158015612520573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061254491906136ae565b506000733333111a391cc08fa51353e9195526a70b3333336001600160a01b0316638380edb76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612599573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125bd91906136ae565b90508015610f4557604051636e553f6560e01b815260048101839052306024820152733333111a391cc08fa51353e9195526a70b33333390636e553f65906044016020604051808303816000875af115801561261d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126419190613695565b50600854610f4590733333111a391cc08fa51353e9195526a70b333333906001600160a01b0316846129a4565b600061267a8284613768565b9392505050565b600061267a8284613794565b600061267a82846137ab565b6002600054036126eb5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016108e6565b6002600055565b6126fb81610a7f565b6000600982815481106127105761271061367f565b906000526020600020906008020190508060030154421161272f575050565b600681015460009060ff166127ae5781546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015612785573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127a99190613695565b612820565b60068201546040516370a0823160e01b81523060048201526101009091046001600160a01b0316906370a0823190602401602060405180830381865afa1580156127fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128209190613695565b90508060000361283557504260039091015550565b600582015460ff166128795760058201805460ff191660011790556002820154600c546128619161268d565b600c556007820154600f546128759161268d565b600f555b600c54156128e05760006128918360030154426109ba565b905060006128b2600c54610e3b86600201548561268190919063ffffffff16565b90506128d86128cd84610e3b84670de0b6b3a7640000612681565b60048601549061268d565b600485015550505b4260038381019190915554600160a01b900460ff1615611b6b57611b6b8361140b565b600061267a82846137be565b6000600983815481106129245761292461367f565b60009182526020909120600890910201600681015490915060ff1615611b6b576006810154604051632e1a7d4d60e01b8152600481018490526101009091046001600160a01b031690632e1a7d4d90602401600060405180830381600087803b15801561299057600080fd5b505af11580156124ab573d6000803e3d6000fd5b6040516001600160a01b038316602482015260448101829052611b6b90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613108565b600060098281548110612a1c57612a1c61367f565b9060005260206000209060080201905060008160060160000160019054906101000a90046001600160a01b03166001600160a01b0316638003b6146040518163ffffffff1660e01b8152600401600060405180830381865afa158015612a86573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612aae9190810190613806565b60068301546040516331279d3d60e01b815291925061010090046001600160a01b0316906331279d3d90612ae890309085906004016138d6565b600060405180830381600087803b158015612b0257600080fd5b505af1158015612b16573d6000803e3d6000fd5b5050505060005b8151811015610c8e576000828281518110612b3a57612b3a61367f565b60209081029190910101516040516370a0823160e01b81523060048201529091506000906001600160a01b038316906370a0823190602401602060405180830381865afa158015612b8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bb39190613695565b90508015612c0857735050bc082ff4a74fb6b0b04385defddb114b2423196001600160a01b03831601612bee57612be9816124b4565b612c08565b600854612c08906001600160a01b038481169116836129a4565b5050600101612b1d565b600060098281548110612c2757612c2761367f565b906000526020600020906008020190508060060160000160019054906101000a90046001600160a01b03166001600160a01b0316633d18b9126040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612c8c57600080fd5b505af1158015612ca0573d6000803e3d6000fd5b50506040516370a0823160e01b815230600482015273a04bc7140c26fc9bb1f36b1a604c7a5a88fb0e7092506000915082906370a0823190602401602060405180830381865afa158015612cf8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d1c9190613695565b90508015610c8e57600854610c8e906001600160a01b038481169116836129a4565b6002546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015612d87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dab9190613695565b90508015611b6b5780821115612dd257600254611b6b906001600160a01b031684836129a4565b600254611b6b906001600160a01b031684846129a4565b60095460005b81811015611b6b57826001600160a01b031660098281548110612e1457612e1461367f565b60009182526020909120600890910201546001600160a01b031603612e7b5760405162461bcd60e51b815260206004820181905260248201527f47536e616b65526577617264506f6f6c3a206578697374696e6720706f6f6c3f60448201526064016108e6565b600101612def565b600654600980546000926001600160a01b031691632045be909185908110612ead57612ead61367f565b600091825260209091206008909102015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa158015612f02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f269190613935565b90506001600160a01b03811615610f45576040805160608101825260018082526001600160a01b038416602083015290918201905b81525060098381548110612f7157612f7161367f565b6000918252602091829020835160066008909302909101919091018054928401516001600160a01b031661010002610100600160a81b0319921515929092166001600160a81b03199093169290921717808255604083015190829060ff60a81b1916600160a81b836002811115612fea57612fea613309565b021790555050505050565b600754600980546000926001600160a01b03169163b9a09fd5918590811061301f5761301f61367f565b600091825260209091206008909102015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa158015613074573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130989190613935565b90506001600160a01b03811615610f455760408051606081018252600181526001600160a01b03831660208201529081016002612f5b565b6040516001600160a01b0380851660248301528316604482015260648101829052610c8e9085906323b872dd60e01b906084016129d0565b600061315d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166131dd9092919063ffffffff16565b905080516000148061317e57508080602001905181019061317e91906136ae565b611b6b5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016108e6565b606061133f848460008585600080866001600160a01b031685876040516132049190613976565b60006040518083038185875af1925050503d8060008114613241576040519150601f19603f3d011682016040523d82523d6000602084013e613246565b606091505b5091509150611e4c87838387606083156132c15782516000036132ba576001600160a01b0385163b6132ba5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016108e6565b508161133f565b61133f83838151156132d65781518083602001fd5b8060405162461bcd60e51b81526004016108e69190613992565b60006020828403121561330257600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b6001600160a01b03898116825260208083018a905260408084018a9052606084018990526080840188905286151560a08501528551151560c08501529085015190911660e08301528301516101408201906003811061338e57634e487b7160e01b600052602160045260246000fd5b61010083015261012090910191909152979650505050505050565b600080604083850312156133bc57600080fd5b50508035926020909101359150565b6000806000606084860312156133e057600080fd5b505081359360208301359350604090920135919050565b6001600160a01b03811681146108f857600080fd5b60008060006060848603121561342157600080fd5b833561342c816133f7565b9250602084013591506040840135613443816133f7565b809150509250925092565b60006020828403121561346057600080fd5b813561267a816133f7565b80151581146108f857600080fd5b60006020828403121561348b57600080fd5b813561267a8161346b565b600080604083850312156134a957600080fd5b8235915060208301356134bb816133f7565b809150509250929050565b600080600080600060a086880312156134de57600080fd5b853594506020860135935060408601356134f7816133f7565b925060608601356135078161346b565b949793965091946080013592915050565b6000806040838503121561352b57600080fd5b823591506020830135600381106134bb57600080fd5b60008083601f84011261355357600080fd5b50813567ffffffffffffffff81111561356b57600080fd5b6020830191508360208260051b850101111561358657600080fd5b9250929050565b600080600080600080606087890312156135a657600080fd5b863567ffffffffffffffff8111156135bd57600080fd5b6135c989828a01613541565b909750955050602087013567ffffffffffffffff8111156135e957600080fd5b6135f589828a01613541565b909550935050604087013567ffffffffffffffff81111561361557600080fd5b61362189828a01613541565b979a9699509497509295939492505050565b6020808252602c908201527f47536e616b65526577617264506f6f6c3a2063616c6c6572206973206e6f742060408201526b3a34329037b832b930ba37b960a11b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156136a757600080fd5b5051919050565b6000602082840312156136c057600080fd5b815161267a8161346b565b60208082526024908201527f436c61696d20616d6f756e742062656c6f77206d696e696d756d2074687265736040820152631a1bdb1960e21b606082015260800190565b60208082526023908201527f47536e616b65526577617264506f6f6c3a20696e76616c6964206d73672e76616040820152626c756560e81b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b81810381811115610a7957610a79613752565b60006001820161378d5761378d613752565b5060010190565b8082028115828204841417610a7957610a79613752565b80820180821115610a7957610a79613752565b6000826137db57634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052604160045260246000fd5b8051613801816133f7565b919050565b60006020828403121561381857600080fd5b815167ffffffffffffffff81111561382f57600080fd5b8201601f8101841361384057600080fd5b805167ffffffffffffffff81111561385a5761385a6137e0565b8060051b604051601f19603f830116810181811067ffffffffffffffff82111715613887576138876137e0565b6040529182526020818401810192908101878411156138a557600080fd5b6020850194505b838510156138cb576138bd856137f6565b8152602094850194016138ac565b509695505050505050565b6001600160a01b0383168152604060208083018290528351918301829052600091908401906060840190835b818110156139295783516001600160a01b0316835260209384019390920191600101613902565b50909695505050505050565b60006020828403121561394757600080fd5b815161267a816133f7565b60005b8381101561396d578181015183820152602001613955565b50506000910152565b60008251613988818460208701613952565b9190910192915050565b60208152600082518060208401526139b1816040850160208701613952565b601f01601f1916919091016040019291505056fea2646970667358221220022cecc24a1aa7e12ce4a2a17d71148102eeb486ed9d4bf295e1d69cc9de185164736f6c634300081a0033000000000000000000000000674a430f531847a6f8976a900f8ace765f896a1b000000000000000000000000a906b773bf4e1f5c668eedeed06aa8917057ea7d0000000000000000000000000000000000000000000000000000000067b0d6200000000000000000000000003af1dd7a2755201f8e2d6dcda1a61d9f54838f4f000000000000000000000000c1ae2779903cfb84cb9dee5c03eceac32dc407f2
Deployed Bytecode
0x6080604052600436106102925760003560e01c80636b2681c51161015a578063ba44a45a116100c1578063d18df53c1161007a578063d18df53c146107e9578063ddc6326214610821578063de89c76c14610834578063dfbffa8c14610854578063e2bbb1581461087c578063fddc298c1461089c57600080fd5b8063ba44a45a14610733578063c69c2c0214610749578063ce862f1714610769578063cec39bd114610789578063ced8a5d7146107a9578063cf4b55cb146107c957600080fd5b80638ed955b9116101135780638ed955b91461066157806390c5ed6a1461066957806393f1a40b14610689578063943f013d146106dd578063b3ab15fb146106f3578063b947a88d1461071357600080fd5b80636b2681c5146105aa5780636e142c8e146105ca5780636e271dd5146105ea578063717478021461060057806378e39d5d146106215780637ebd739f1461064157600080fd5b8063441a3e70116101fe57806357356232116101b757806357356232146105095780635752933a146105295780635f96dc111461053f5780636057836914610555578063630b5ba11461057557806363eb04161461058a57600080fd5b8063441a3e701461044e57806351637ba9146104615780635312ea8e1461048157806354575af4146104a1578063549c278a146104c1578063570ca735146104e957600080fd5b80632760f89b116102505780632760f89b146103875780632df95ed7146103a75780633202f6c1146103c75780633695dad1146103e75780633afb24f1146103fd57806343b0e8df1461042e57600080fd5b8062c6b39114610297578063033cdb61146102dc578063081e3eda146102fe5780631526fe271461031d57806317caf6f114610351578063231f0c6a14610367575b600080fd5b3480156102a357600080fd5b506102bf735050bc082ff4a74fb6b0b04385defddb114b242481565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156102e857600080fd5b506102fc6102f73660046132f0565b6108bc565b005b34801561030a57600080fd5b506009545b6040519081526020016102d3565b34801561032957600080fd5b5061033d6103383660046132f0565b6108fb565b6040516102d398979695949392919061331f565b34801561035d57600080fd5b5061030f600c5481565b34801561037357600080fd5b5061030f6103823660046133a9565b6109ba565b34801561039357600080fd5b506003546102bf906001600160a01b031681565b3480156103b357600080fd5b506102fc6103c23660046132f0565b610a7f565b3480156103d357600080fd5b506006546102bf906001600160a01b031681565b3480156103f357600080fd5b5061030f60055481565b34801561040957600080fd5b5060035461041e90600160a01b900460ff1681565b60405190151581526020016102d3565b34801561043a57600080fd5b506102fc6104493660046133cb565b610c94565b6102fc61045c3660046133a9565b610d5f565b34801561046d57600080fd5b506102fc61047c3660046132f0565b610f49565b34801561048d57600080fd5b506102fc61049c3660046132f0565b610fe6565b3480156104ad57600080fd5b506102fc6104bc36600461340c565b6110ba565b3480156104cd57600080fd5b506102bf733333111a391cc08fa51353e9195526a70b33333381565b3480156104f557600080fd5b506001546102bf906001600160a01b031681565b34801561051557600080fd5b506102fc61052436600461344e565b6111a9565b34801561053557600080fd5b5061030f600f5481565b34801561054b57600080fd5b5061030f600d5481565b34801561056157600080fd5b506102fc6105703660046132f0565b6111f5565b34801561058157600080fd5b506102fc611291565b34801561059657600080fd5b506102fc6105a5366004613479565b6112b9565b3480156105b657600080fd5b5061030f6105c5366004613496565b611301565b3480156105d657600080fd5b506007546102bf906001600160a01b031681565b3480156105f657600080fd5b5061030f600e5481565b34801561060c57600080fd5b5060035461041e90600160a81b900460ff1681565b34801561062d57600080fd5b506102fc61063c3660046132f0565b611347565b34801561064d57600080fd5b506102fc61065c3660046132f0565b61140b565b6102fc6114a0565b34801561067557600080fd5b506102fc6106843660046134c6565b61185f565b34801561069557600080fd5b506106c86106a4366004613496565b600a6020908152600092835260408084209091529082529020805460019091015482565b604080519283526020830191909152016102d3565b3480156106e957600080fd5b5061030f60105481565b3480156106ff57600080fd5b506102fc61070e36600461344e565b611aa4565b34801561071f57600080fd5b506102fc61072e3660046133a9565b611af0565b34801561073f57600080fd5b5061030f60045481565b34801561075557600080fd5b506102fc610764366004613479565b611b70565b34801561077557600080fd5b506102fc610784366004613518565b611bb8565b34801561079557600080fd5b506002546102bf906001600160a01b031681565b3480156107b557600080fd5b506102fc6107c436600461344e565b611c26565b3480156107d557600080fd5b5061030f6107e4366004613496565b611c72565b3480156107f557600080fd5b5061030f610804366004613496565b600b60209081526000928352604080842090915290825290205481565b6102fc61082f3660046132f0565b611e57565b34801561084057600080fd5b506008546102bf906001600160a01b031681565b34801561086057600080fd5b506102bf73a04bc7140c26fc9bb1f36b1a604c7a5a88fb0e7081565b34801561088857600080fd5b506102fc6108973660046133a9565b6121e6565b3480156108a857600080fd5b506102fc6108b736600461358d565b6123c1565b6001546001600160a01b031633146108ef5760405162461bcd60e51b81526004016108e690613633565b60405180910390fd5b6108f8816124b4565b50565b6009818154811061090b57600080fd5b6000918252602091829020600890910201805460018201546002808401546003850154600486015460058701546040805160608101825260068a01805460ff8181161515845261010082046001600160a01b039081169e85019e909e529c909a169c50979a9599949893979286169694959094929391850192600160a81b909204169081111561099d5761099d613309565b60028111156109ae576109ae613309565b90525060079091015488565b60008183106109cb57506000610a79565b600e548210610a3357600e5483106109e557506000610a79565b600d548311610a1857610a11600f54610a0b600d54600e5461266e90919063ffffffff16565b90612681565b9050610a79565b610a11600f54610a0b85600e5461266e90919063ffffffff16565b600d548211610a4457506000610a79565b600d548311610a6857610a11600f54610a0b600d548561266e90919063ffffffff16565b600f54610a1190610a0b848661266e565b92915050565b600060098281548110610a9457610a9461367f565b60009182526020822060089190910201600681015481546040516370a0823160e01b81523060048201529294506101009091046001600160a01b0390811693929116906370a0823190602401602060405180830381865afa158015610afd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b219190613695565b600684015490915060ff1615610c8e578015610c8e578254604051636eb1769f60e11b81523060048201526001600160a01b0384811660248301528392169063dd62ed3e90604401602060405180830381865afa158015610b86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610baa9190613695565b1015610c2957825460405163095ea7b360e01b81526001600160a01b03848116600483015260001960248301529091169063095ea7b3906044016020604051808303816000875af1158015610c03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c2791906136ae565b505b600683015460405163b6b55f2560e01b8152600481018390526101009091046001600160a01b03169063b6b55f2590602401600060405180830381600087803b158015610c7557600080fd5b505af1158015610c89573d6000803e3d6000fd5b505050505b50505050565b6001546001600160a01b03163314610cbe5760405162461bcd60e51b81526004016108e690613633565b610cc6611291565b600060098481548110610cdb57610cdb61367f565b9060005260206000209060080201905060c88210610cf857600080fd5b60018101829055600581015460ff1615610d4d57610d2f83610d298360020154600c5461266e90919063ffffffff16565b9061268d565b600c556007810154600f54610d49918591610d299161266e565b600f555b60028101839055600701919091555050565b610d67612699565b6000339050600060098481548110610d8157610d8161367f565b60009182526020808320878452600a825260408085206001600160a01b03881686529092529220805460089092029092019250841115610df85760405162461bcd60e51b81526020600482015260126024820152711dda5d1a191c985dce881b9bdd0819dbdbd960721b60448201526064016108e6565b610e01856126f2565b610e0a85610a7f565b6000610e478260010154610e41670de0b6b3a7640000610e3b8760040154876000015461268190919063ffffffff16565b90612903565b9061266e565b90508015610ea0576000868152600b602090815260408083206001600160a01b0388168452909152902054610e7c908261268d565b6000878152600b602090815260408083206001600160a01b03891684529091529020555b8415610ed4578154610eb2908661266e565b8255610ebe868661290f565b8254610ed4906001600160a01b031685876129a4565b60048301548254610ef291670de0b6b3a764000091610e3b91612681565b600183015560405185815286906001600160a01b038616907ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b5689060200160405180910390a350505050610f456001600055565b5050565b6001546001600160a01b03163314610f735760405162461bcd60e51b81526004016108e690613633565b670de0b6b3a7640000811115610fe15760405162461bcd60e51b815260206004820152602d60248201527f47536e616b65526577617264506f6f6c3a20696e76616c6964206d617820636c60448201526c185a5b481d1a1c995cda1bdb19609a1b60648201526084016108e6565b600555565b610fee612699565b6000600982815481106110035761100361367f565b60009182526020808320858452600a825260408085203386529092529220805460089092029092019250611037848261290f565b6000848152600b60209081526040808320338085529252822082905581845560018401919091558354611076916001600160a01b0390911690836129a4565b604051818152849033907fbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae05959060200160405180910390a35050506108f86001600055565b6001546001600160a01b031633146110e45760405162461bcd60e51b81526004016108e690613633565b60095460005b81811015611194576000600982815481106111075761110761367f565b6000918252602090912060089091020180549091506001600160a01b039081169087160361118b5760405162461bcd60e51b815260206004820152602b60248201527f5368617265526577617264506f6f6c3a20546f6b656e2063616e6e6f7420626560448201526a103837b7b6103a37b5b2b760a91b60648201526084016108e6565b506001016110ea565b50610c8e6001600160a01b03851683856129a4565b6001546001600160a01b031633146111d35760405162461bcd60e51b81526004016108e690613633565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b0316331461121f5760405162461bcd60e51b81526004016108e690613633565b6101f481111561128c5760405162461bcd60e51b815260206004820152603260248201527f47536e616b65526577617264506f6f6c3a20696e76616c6964207065672073746044820152716162696c697479206d6f64756c652066656560701b60648201526084016108e6565b600455565b60095460005b81811015610f45576112a8816126f2565b6112b181610a7f565b600101611297565b6001546001600160a01b031633146112e35760405162461bcd60e51b81526004016108e690613633565b60038054911515600160a01b0260ff60a01b19909216919091179055565b60008061130e8484611c72565b6000858152600b602090815260408083206001600160a01b038816845290915290205490915061133f90829061268d565b949350505050565b6001546001600160a01b031633146113715760405162461bcd60e51b81526004016108e690613633565b6008546040516000916001600160a01b03169083908381818185875af1925050503d80600081146113be576040519150601f19603f3d011682016040523d82523d6000602084013e6113c3565b606091505b5050905080610f455760405162461bcd60e51b81526020600482015260146024820152736661696c656420746f2073656e6420536f6e696360601b60448201526064016108e6565b6000600982815481106114205761142061367f565b60009182526020909120600890910201600681015490915060ff1615610f455760016006820154600160a81b900460ff16600281111561146257611462613309565b036114705761147082612a07565b60026006820154600160a81b900460ff16600281111561149257611492613309565b03610f4557610f4582612c12565b6114a8612699565b60095433906000805b828110156115dc576000600982815481106114ce576114ce61367f565b60009182526020808320858452600a825260408085206001600160a01b038b168652909252922060089091029091019150611508836126f2565b61151183610a7f565b60006115428260010154610e41670de0b6b3a7640000610e3b8760040154876000015461268190919063ffffffff16565b6000858152600b602090815260408083206001600160a01b038c168452909152812054919250611572838361268d565b905080156115aa576000868152600b602090815260408083206001600160a01b038d1684529091528120556115a7878261268d565b96505b600485015484546115c891670de0b6b3a764000091610e3b91612681565b6001948501555050509190910190506114b1565b506005548110156115ff5760405162461bcd60e51b81526004016108e6906136cb565b801561185057600354600090600160a81b900460ff161561172257600354600254604051630d01142560e31b81526001600160a01b039182166004820152670de0b6b3a764000060248201526000929190911690636808a12890604401602060405180830381865afa158015611679573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061169d9190613695565b90506116ca6103e8610e3b600454610a0b670de0b6b3a7640000610e3b898861268190919063ffffffff16565b91508134101561171c5760405162461bcd60e51b815260206004820152601f60248201527f696e73756666696369656e7420736f6e696320666f722050534d20636f73740060448201526064016108e6565b50611740565b34156117405760405162461bcd60e51b81526004016108e69061370f565b61174a8483612d3e565b836001600160a01b03167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e04868360405161178591815260200190565b60405180910390a2600354600160a81b900460ff1680156117a557508034115b1561184e5760006117b68234613768565b90506000856001600160a01b03168260405160006040518083038185875af1925050503d8060008114611805576040519150601f19603f3d011682016040523d82523d6000602084013e61180a565b606091505b505090508061184b5760405162461bcd60e51b815260206004820152600d60248201526c1499599d5b990819985a5b1959609a1b60448201526064016108e6565b50505b505b50505061185d6001600055565b565b6001546001600160a01b031633146118895760405162461bcd60e51b81526004016108e690613633565b61189283612de9565b81156118a0576118a0611291565b600d544210156118cf57806000036118bb5750600d546118e3565b600d548110156118ca5750600d545b6118e3565b8015806118db57504281105b156118e35750425b6000600d54821115806118f65750428211155b90506009604051806101000160405280866001600160a01b03168152602001878152602001888152602001848152602001600081526020018315158152602001604051806060016040528060001515815260200160006001600160a01b031681526020016000600281111561196d5761196d613309565b905281526020908101899052825460018181018555600094855293829020835160089092020180546001600160a01b039283166001600160a01b03199091161781558383015194810194909455604080840151600280870191909155606085015160038701556080850151600487015560a085015160058701805491151560ff1990921691909117905560c085015180516006880180549683015190951661010002610100600160a81b0319911515919091166001600160a81b031990961695909517949094178084559184015194959491839160ff60a81b1990911690600160a81b908490811115611a6257611a62613309565b0217905550505060e0820151816007015550508015611a9c57600c54611a88908761268d565b600c55600f54611a98908761268d565b600f555b505050505050565b6001546001600160a01b03163314611ace5760405162461bcd60e51b81526004016108e690613633565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b80821115611b405760405162461bcd60e51b815260206004820152601f60248201527f47536e616b65526577617264506f6f6c3a20696e76616c69642072616e67650060448201526064016108e6565b815b818111611b6b57611b52816126f2565b611b5b81610a7f565b611b648161377b565b9050611b42565b505050565b6001546001600160a01b03163314611b9a5760405162461bcd60e51b81526004016108e690613633565b60038054911515600160a81b0260ff60a81b19909216919091179055565b6001546001600160a01b03163314611be25760405162461bcd60e51b81526004016108e690613633565b6001816002811115611bf657611bf6613309565b03611c0457611c0482612e83565b6002816002811115611c1857611c18613309565b03610f4557610f4582612ff5565b6001546001600160a01b03163314611c505760405162461bcd60e51b81526004016108e690613633565b600880546001600160a01b0319166001600160a01b0392909216919091179055565b60008060098481548110611c8857611c8861367f565b60009182526020808320878452600a825260408085206001600160a01b0389168652909252908320600892909202016004810154600682015491945091929060ff16611d3e5783546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015611d15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d399190613695565b611db0565b60068401546040516370a0823160e01b81523060048201526101009091046001600160a01b0316906370a0823190602401602060405180830381865afa158015611d8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611db09190613695565b9050836003015442118015611dc457508015155b15611e21576000611dd98560030154426109ba565b90506000611dfa600c54610e3b88600201548561268190919063ffffffff16565b9050611e1c611e1584610e3b84670de0b6b3a7640000612681565b859061268d565b935050505b611e4c8360010154610e41670de0b6b3a7640000610e3b86886000015461268190919063ffffffff16565b979650505050505050565b611e5f612699565b6000339050600060098381548110611e7957611e7961367f565b60009182526020808320868452600a825260408085206001600160a01b0388168652909252922060089091029091019150611eb3846126f2565b611ebc84610a7f565b6000611eed8260010154610e41670de0b6b3a7640000610e3b8760040154876000015461268190919063ffffffff16565b6000868152600b602090815260408083206001600160a01b0389168452909152812054919250611f1d838361268d565b9050600554811015611f415760405162461bcd60e51b81526004016108e6906136cb565b80156121b4576000878152600b602090815260408083206001600160a01b038a1684529091528120819055600354600160a81b900460ff161561208657600354600254604051630d01142560e31b81526001600160a01b039182166004820152670de0b6b3a764000060248201526000929190911690636808a12890604401602060405180830381865afa158015611fdd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120019190613695565b905061202e6103e8610e3b600454610a0b670de0b6b3a7640000610e3b898861268190919063ffffffff16565b9150813410156120805760405162461bcd60e51b815260206004820152601f60248201527f696e73756666696369656e7420736f6e696320666f722050534d20636f73740060448201526064016108e6565b506120a4565b34156120a45760405162461bcd60e51b81526004016108e69061370f565b6120ae8783612d3e565b866001600160a01b03167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e0486836040516120e991815260200190565b60405180910390a2600354600160a81b900460ff16801561210957508034115b156121b257600061211a8234613768565b90506000886001600160a01b03168260405160006040518083038185875af1925050503d8060008114612169576040519150601f19603f3d011682016040523d82523d6000602084013e61216e565b606091505b50509050806121af5760405162461bcd60e51b815260206004820152600d60248201526c1499599d5b990819985a5b1959609a1b60448201526064016108e6565b50505b505b600485015484546121d291670de0b6b3a764000091610e3b91612681565b600194850155505050600055506108f89050565b6121ee612699565b60003390506000600984815481106122085761220861367f565b60009182526020808320878452600a825260408085206001600160a01b0388168652909252922060089091029091019150612242856126f2565b8054156122d557600061227a8260010154610e41670de0b6b3a7640000610e3b8760040154876000015461268190919063ffffffff16565b905080156122d3576000868152600b602090815260408083206001600160a01b03881684529091529020546122af908261268d565b6000878152600b602090815260408083206001600160a01b03891684529091529020555b505b83156123485781546122f2906001600160a01b03168430876130d0565b6000612311612710610e3b85600101548861268190919063ffffffff16565b9050612328612320868361266e565b83549061268d565b82556008548354612346916001600160a01b039182169116836129a4565b505b61235185610a7f565b6004820154815461236f91670de0b6b3a764000091610e3b91612681565b600182015560405184815285906001600160a01b038516907f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a159060200160405180910390a3505050610f456001600055565b6001546001600160a01b031633146123eb5760405162461bcd60e51b81526004016108e690613633565b84831480156123f957508481145b6124455760405162461bcd60e51b815260206004820181905260248201527f47536e616b65526577617264506f6f6c3a20696e76616c6964206c656e67746860448201526064016108e6565b60005b858110156124ab576124a38787838181106124655761246561367f565b9050602002013586868481811061247e5761247e61367f565b905060200201358585858181106124975761249761367f565b90506020020135610c94565b600101612448565b50505050505050565b60405163095ea7b360e01b8152733333111a391cc08fa51353e9195526a70b333333600482015260248101829052735050bc082ff4a74fb6b0b04385defddb114b24249063095ea7b3906044016020604051808303816000875af1158015612520573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061254491906136ae565b506000733333111a391cc08fa51353e9195526a70b3333336001600160a01b0316638380edb76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612599573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125bd91906136ae565b90508015610f4557604051636e553f6560e01b815260048101839052306024820152733333111a391cc08fa51353e9195526a70b33333390636e553f65906044016020604051808303816000875af115801561261d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126419190613695565b50600854610f4590733333111a391cc08fa51353e9195526a70b333333906001600160a01b0316846129a4565b600061267a8284613768565b9392505050565b600061267a8284613794565b600061267a82846137ab565b6002600054036126eb5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016108e6565b6002600055565b6126fb81610a7f565b6000600982815481106127105761271061367f565b906000526020600020906008020190508060030154421161272f575050565b600681015460009060ff166127ae5781546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015612785573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127a99190613695565b612820565b60068201546040516370a0823160e01b81523060048201526101009091046001600160a01b0316906370a0823190602401602060405180830381865afa1580156127fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128209190613695565b90508060000361283557504260039091015550565b600582015460ff166128795760058201805460ff191660011790556002820154600c546128619161268d565b600c556007820154600f546128759161268d565b600f555b600c54156128e05760006128918360030154426109ba565b905060006128b2600c54610e3b86600201548561268190919063ffffffff16565b90506128d86128cd84610e3b84670de0b6b3a7640000612681565b60048601549061268d565b600485015550505b4260038381019190915554600160a01b900460ff1615611b6b57611b6b8361140b565b600061267a82846137be565b6000600983815481106129245761292461367f565b60009182526020909120600890910201600681015490915060ff1615611b6b576006810154604051632e1a7d4d60e01b8152600481018490526101009091046001600160a01b031690632e1a7d4d90602401600060405180830381600087803b15801561299057600080fd5b505af11580156124ab573d6000803e3d6000fd5b6040516001600160a01b038316602482015260448101829052611b6b90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613108565b600060098281548110612a1c57612a1c61367f565b9060005260206000209060080201905060008160060160000160019054906101000a90046001600160a01b03166001600160a01b0316638003b6146040518163ffffffff1660e01b8152600401600060405180830381865afa158015612a86573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612aae9190810190613806565b60068301546040516331279d3d60e01b815291925061010090046001600160a01b0316906331279d3d90612ae890309085906004016138d6565b600060405180830381600087803b158015612b0257600080fd5b505af1158015612b16573d6000803e3d6000fd5b5050505060005b8151811015610c8e576000828281518110612b3a57612b3a61367f565b60209081029190910101516040516370a0823160e01b81523060048201529091506000906001600160a01b038316906370a0823190602401602060405180830381865afa158015612b8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bb39190613695565b90508015612c0857735050bc082ff4a74fb6b0b04385defddb114b2423196001600160a01b03831601612bee57612be9816124b4565b612c08565b600854612c08906001600160a01b038481169116836129a4565b5050600101612b1d565b600060098281548110612c2757612c2761367f565b906000526020600020906008020190508060060160000160019054906101000a90046001600160a01b03166001600160a01b0316633d18b9126040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612c8c57600080fd5b505af1158015612ca0573d6000803e3d6000fd5b50506040516370a0823160e01b815230600482015273a04bc7140c26fc9bb1f36b1a604c7a5a88fb0e7092506000915082906370a0823190602401602060405180830381865afa158015612cf8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d1c9190613695565b90508015610c8e57600854610c8e906001600160a01b038481169116836129a4565b6002546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015612d87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dab9190613695565b90508015611b6b5780821115612dd257600254611b6b906001600160a01b031684836129a4565b600254611b6b906001600160a01b031684846129a4565b60095460005b81811015611b6b57826001600160a01b031660098281548110612e1457612e1461367f565b60009182526020909120600890910201546001600160a01b031603612e7b5760405162461bcd60e51b815260206004820181905260248201527f47536e616b65526577617264506f6f6c3a206578697374696e6720706f6f6c3f60448201526064016108e6565b600101612def565b600654600980546000926001600160a01b031691632045be909185908110612ead57612ead61367f565b600091825260209091206008909102015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa158015612f02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f269190613935565b90506001600160a01b03811615610f45576040805160608101825260018082526001600160a01b038416602083015290918201905b81525060098381548110612f7157612f7161367f565b6000918252602091829020835160066008909302909101919091018054928401516001600160a01b031661010002610100600160a81b0319921515929092166001600160a81b03199093169290921717808255604083015190829060ff60a81b1916600160a81b836002811115612fea57612fea613309565b021790555050505050565b600754600980546000926001600160a01b03169163b9a09fd5918590811061301f5761301f61367f565b600091825260209091206008909102015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa158015613074573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130989190613935565b90506001600160a01b03811615610f455760408051606081018252600181526001600160a01b03831660208201529081016002612f5b565b6040516001600160a01b0380851660248301528316604482015260648101829052610c8e9085906323b872dd60e01b906084016129d0565b600061315d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166131dd9092919063ffffffff16565b905080516000148061317e57508080602001905181019061317e91906136ae565b611b6b5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016108e6565b606061133f848460008585600080866001600160a01b031685876040516132049190613976565b60006040518083038185875af1925050503d8060008114613241576040519150601f19603f3d011682016040523d82523d6000602084013e613246565b606091505b5091509150611e4c87838387606083156132c15782516000036132ba576001600160a01b0385163b6132ba5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016108e6565b508161133f565b61133f83838151156132d65781518083602001fd5b8060405162461bcd60e51b81526004016108e69190613992565b60006020828403121561330257600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b6001600160a01b03898116825260208083018a905260408084018a9052606084018990526080840188905286151560a08501528551151560c08501529085015190911660e08301528301516101408201906003811061338e57634e487b7160e01b600052602160045260246000fd5b61010083015261012090910191909152979650505050505050565b600080604083850312156133bc57600080fd5b50508035926020909101359150565b6000806000606084860312156133e057600080fd5b505081359360208301359350604090920135919050565b6001600160a01b03811681146108f857600080fd5b60008060006060848603121561342157600080fd5b833561342c816133f7565b9250602084013591506040840135613443816133f7565b809150509250925092565b60006020828403121561346057600080fd5b813561267a816133f7565b80151581146108f857600080fd5b60006020828403121561348b57600080fd5b813561267a8161346b565b600080604083850312156134a957600080fd5b8235915060208301356134bb816133f7565b809150509250929050565b600080600080600060a086880312156134de57600080fd5b853594506020860135935060408601356134f7816133f7565b925060608601356135078161346b565b949793965091946080013592915050565b6000806040838503121561352b57600080fd5b823591506020830135600381106134bb57600080fd5b60008083601f84011261355357600080fd5b50813567ffffffffffffffff81111561356b57600080fd5b6020830191508360208260051b850101111561358657600080fd5b9250929050565b600080600080600080606087890312156135a657600080fd5b863567ffffffffffffffff8111156135bd57600080fd5b6135c989828a01613541565b909750955050602087013567ffffffffffffffff8111156135e957600080fd5b6135f589828a01613541565b909550935050604087013567ffffffffffffffff81111561361557600080fd5b61362189828a01613541565b979a9699509497509295939492505050565b6020808252602c908201527f47536e616b65526577617264506f6f6c3a2063616c6c6572206973206e6f742060408201526b3a34329037b832b930ba37b960a11b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156136a757600080fd5b5051919050565b6000602082840312156136c057600080fd5b815161267a8161346b565b60208082526024908201527f436c61696d20616d6f756e742062656c6f77206d696e696d756d2074687265736040820152631a1bdb1960e21b606082015260800190565b60208082526023908201527f47536e616b65526577617264506f6f6c3a20696e76616c6964206d73672e76616040820152626c756560e81b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b81810381811115610a7957610a79613752565b60006001820161378d5761378d613752565b5060010190565b8082028115828204841417610a7957610a79613752565b80820180821115610a7957610a79613752565b6000826137db57634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052604160045260246000fd5b8051613801816133f7565b919050565b60006020828403121561381857600080fd5b815167ffffffffffffffff81111561382f57600080fd5b8201601f8101841361384057600080fd5b805167ffffffffffffffff81111561385a5761385a6137e0565b8060051b604051601f19603f830116810181811067ffffffffffffffff82111715613887576138876137e0565b6040529182526020818401810192908101878411156138a557600080fd5b6020850194505b838510156138cb576138bd856137f6565b8152602094850194016138ac565b509695505050505050565b6001600160a01b0383168152604060208083018290528351918301829052600091908401906060840190835b818110156139295783516001600160a01b0316835260209384019390920191600101613902565b50909695505050505050565b60006020828403121561394757600080fd5b815161267a816133f7565b60005b8381101561396d578181015183820152602001613955565b50506000910152565b60008251613988818460208701613952565b9190910192915050565b60208152600082518060208401526139b1816040850160208701613952565b601f01601f1916919091016040019291505056fea2646970667358221220022cecc24a1aa7e12ce4a2a17d71148102eeb486ed9d4bf295e1d69cc9de185164736f6c634300081a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000674a430f531847a6f8976a900f8ace765f896a1b000000000000000000000000a906b773bf4e1f5c668eedeed06aa8917057ea7d0000000000000000000000000000000000000000000000000000000067b0d6200000000000000000000000003af1dd7a2755201f8e2d6dcda1a61d9f54838f4f000000000000000000000000c1ae2779903cfb84cb9dee5c03eceac32dc407f2
-----Decoded View---------------
Arg [0] : _gsnake (address): 0x674a430f531847a6f8976A900f8ace765f896a1b
Arg [1] : _bribesSafe (address): 0xa906B773bf4E1F5C668EeDEed06aa8917057eA7D
Arg [2] : _poolStartTime (uint256): 1739642400
Arg [3] : _shadowVoter (address): 0x3aF1dD7A2755201F8e2D6dCDA1a61d9f54838f4f
Arg [4] : _swapxVoter (address): 0xC1AE2779903cfB84CB9DEe5c03EcEAc32dc407F2
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 000000000000000000000000674a430f531847a6f8976a900f8ace765f896a1b
Arg [1] : 000000000000000000000000a906b773bf4e1f5c668eedeed06aa8917057ea7d
Arg [2] : 0000000000000000000000000000000000000000000000000000000067b0d620
Arg [3] : 0000000000000000000000003af1dd7a2755201f8e2d6dcda1a61d9f54838f4f
Arg [4] : 000000000000000000000000c1ae2779903cfb84cb9dee5c03eceac32dc407f2
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
SONIC | 100.00% | $0.499463 | 9.1011 | $4.55 |
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.