Latest 25 from a total of 23,877 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Emergency Withdr... | 44340873 | 239 days ago | IN | 0 S | 0.002599 | ||||
| Claim Legacy Rew... | 44340849 | 239 days ago | IN | 0 S | 0.001291 | ||||
| Emergency Withdr... | 44191430 | 240 days ago | IN | 0 S | 0.00302868 | ||||
| Emergency Withdr... | 42768311 | 250 days ago | IN | 0 S | 0.0027159 | ||||
| Emergency Withdr... | 42730504 | 251 days ago | IN | 0 S | 0.0027159 | ||||
| Emergency Withdr... | 42576576 | 252 days ago | IN | 0 S | 0.00346857 | ||||
| Emergency Withdr... | 25472476 | 346 days ago | IN | 0 S | 0.00417467 | ||||
| Emergency Withdr... | 16615266 | 388 days ago | IN | 0 S | 0.00407825 | ||||
| Emergency Withdr... | 16615172 | 388 days ago | IN | 0 S | 0.0030303 | ||||
| Emergency Withdr... | 16615110 | 388 days ago | IN | 0 S | 0.00250765 | ||||
| Emergency Withdr... | 16119694 | 390 days ago | IN | 0 S | 0.00353947 | ||||
| Withdraw | 15664614 | 392 days ago | IN | 0 S | 0.0016709 | ||||
| Withdraw | 14709656 | 397 days ago | IN | 0 S | 0.00500508 | ||||
| Deposit | 14709617 | 397 days ago | IN | 0 S | 0.00972945 | ||||
| Deposit | 14697645 | 397 days ago | IN | 0 S | 0.00637421 | ||||
| Deposit | 14697592 | 397 days ago | IN | 0 S | 0.00550882 | ||||
| Withdraw | 14690918 | 397 days ago | IN | 0 S | 0.00513024 | ||||
| Deposit | 14690160 | 397 days ago | IN | 0 S | 0.00786989 | ||||
| Withdraw | 14690095 | 397 days ago | IN | 0 S | 0.00427598 | ||||
| Deposit | 14689535 | 397 days ago | IN | 0 S | 0.00966108 | ||||
| Withdraw | 11858704 | 411 days ago | IN | 0 S | 0.00408281 | ||||
| Withdraw | 11858676 | 411 days ago | IN | 0 S | 0.0049038 | ||||
| Withdraw | 11817154 | 411 days ago | IN | 0 S | 0.00497541 | ||||
| Withdraw | 11817110 | 411 days ago | IN | 0 S | 0.00486123 | ||||
| Withdraw | 11066939 | 415 days ago | IN | 0 S | 0.00599141 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
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 Name:
SnakeGenesisRewardPool
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
// SnakeGenesisRewardPool --> 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 "../shadow/interfaces/IGauge.sol";
import "../shadow/interfaces/IVoter.sol";
contract SnakeGenesisRewardPool is ReentrancyGuard {
using SafeMath for uint256;
using SafeERC20 for IERC20;
// 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
IGauge gauge; // The gauge
address[] rewardTokens; // tokens that are used in 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. SNAKEs to distribute per block.
uint256 lastRewardTime; // Last time that SNAKEs distribution occurs.
uint256 accSnakePerShare; // Accumulated SNAKEs 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 poolSnakePerSec; // rewards per second for pool (acts as allocPoint)
}
IERC20 public snake;
IVoter public voter;
address public xSHADOW = 0x5050bc082FF4A74Fb6B0B04385dEfdDB114b2424;
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;
// Total allocation points. Must be the sum of all allocation points in all pools.
uint256 public totalAllocPoint = 0;
// The time when SNAKE mining starts.
uint256 public poolStartTime;
// The time when SNAKE mining ends.
uint256 public poolEndTime;
uint256 public snakePerSecond = 0 ether;
uint256 public runningTime = 7 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 _snake,
address _bribesSafe,
uint256 _poolStartTime,
address _voter
) {
require(block.timestamp < _poolStartTime, "pool cant be started in the past");
if (_snake != address(0)) snake = IERC20(_snake);
if(_bribesSafe != address(0)) bribesSafe = _bribesSafe;
poolStartTime = _poolStartTime;
poolEndTime = _poolStartTime + runningTime;
operator = msg.sender;
voter = IVoter(_voter);
bribesSafe = _bribesSafe;
// create all the pools
add(0.231481481481481000 ether, 0, IERC20(0x287c6882dE298665977787e268f3dba052A6e251), false, 0); // Snake-S
add(0.173611111111111000 ether, 100, IERC20(0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38), false, 0); // S
add(0.115740740740741000 ether, 100, IERC20(0x29219dd400f2Bf60E5a23d13Be72B486D4038894), false, 0); // USDC.e
add(0.115740740740741000 ether, 100, IERC20(0x50c42dEAcD8Fc9773493ED674b675bE577f2634b), false, 0); // WETH
add(0.023148148148148100 ether, 100, IERC20(0x3333b97138D4b086720b5aE8A7844b1345a33333), false, 0); // SHADOW
add(0.023148148148148100 ether, 100, IERC20(0x79bbF4508B1391af3A0F4B30bb5FC4aa9ab0E07C), false, 0); // ANON
add(0.092592592592592600 ether, 100, IERC20(0xd3DCe716f3eF535C5Ff8d041c1A41C3bd89b97aE), false, 0); // scUSD
}
modifier onlyOperator() {
require(operator == msg.sender, "SnakeGenesisRewardPool: 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, "SnakeGenesisRewardPool: existing pool?");
}
}
// bulk add pools
function addBulk(uint256[] calldata _allocPoints, uint256[] calldata _depFees, IERC20[] calldata _tokens, bool _withUpdate, uint256 _lastRewardTime) external onlyOperator {
require(_allocPoints.length == _depFees.length && _allocPoints.length == _tokens.length, "SnakeGenesisRewardPool: invalid length");
for (uint256 i = 0; i < _allocPoints.length; i++) {
add(_allocPoints[i], _depFees[i], _tokens[i], _withUpdate, _lastRewardTime);
}
}
// 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);
address[] memory rewardTokensGauge = new address[](1);
rewardTokensGauge[0] = xSHADOW;
poolInfo.push(PoolInfo({
token: _token,
depFee: _depFee,
allocPoint: _allocPoint,
poolSnakePerSec: _allocPoint,
lastRewardTime: _lastRewardTime,
accSnakePerShare: 0,
isStarted: _isStarted,
gaugeInfo: GaugeInfo(false, IGauge(address(0)), rewardTokensGauge)
}));
enableGauge(poolInfo.length - 1);
if (_isStarted) {
totalAllocPoint = totalAllocPoint.add(_allocPoint);
snakePerSecond = snakePerSecond.add(_allocPoint);
}
}
// Update the given pool's SNAKE 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);
snakePerSecond = snakePerSecond.sub(pool.poolSnakePerSec).add(_allocPoint);
}
pool.allocPoint = _allocPoint;
pool.poolSnakePerSec = _allocPoint;
}
function bulkSet(uint256[] calldata _pids, uint256[] calldata _allocPoints, uint256[] calldata _depFees) external onlyOperator {
require(_pids.length == _allocPoints.length && _pids.length == _depFees.length, "SnakeGenesisRewardPool: 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(snakePerSecond);
return poolEndTime.sub(_fromTime).mul(snakePerSecond);
} else {
if (_toTime <= poolStartTime) return 0;
if (_fromTime <= poolStartTime) return _toTime.sub(poolStartTime).mul(snakePerSecond);
return _toTime.sub(_fromTime).mul(snakePerSecond);
}
}
// View function to see pending SNAKEs on frontend.
function pendingSNAKE(uint256 _pid, address _user) external view returns (uint256) {
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][_user];
uint256 accSnakePerShare = pool.accSnakePerShare;
uint256 tokenSupply = pool.gaugeInfo.isGauge ? 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 _snakeReward = _generatedReward.mul(pool.allocPoint).div(totalAllocPoint);
accSnakePerShare = accSnakePerShare.add(_snakeReward.mul(1e18).div(tokenSupply));
}
return user.amount.mul(accSnakePerShare).div(1e18).sub(user.rewardDebt);
}
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, "SnakeGenesisRewardPool: 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 ? 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);
snakePerSecond = snakePerSecond.add(pool.poolSnakePerSec);
}
if (totalAllocPoint > 0) {
uint256 _generatedReward = getGeneratedReward(pool.lastRewardTime, block.timestamp);
uint256 _snakeReward = _generatedReward.mul(pool.allocPoint).div(totalAllocPoint);
pool.accSnakePerShare = pool.accSnakePerShare.add(_snakeReward.mul(1e18).div(tokenSupply));
}
pool.lastRewardTime = block.timestamp;
claimLegacyRewards(_pid);
}
// Deposit LP tokens to earn rewards
function updatePoolWithGaugeDeposit(uint256 _pid) public {
PoolInfo storage pool = poolInfo[_pid];
address gauge = address(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
pool.gaugeInfo.gauge.depositFor(address(this), balance);
}
}
}
// Claim rewards to treasury
function claimLegacyRewards(uint256 _pid) public {
PoolInfo storage pool = poolInfo[_pid];
if (pool.gaugeInfo.isGauge) {
if (pool.gaugeInfo.rewardTokens.length > 0) {
uint256[] memory beforeBalances = new uint256[](pool.gaugeInfo.rewardTokens.length);
// Store balances before claim
for (uint256 i = 0; i < pool.gaugeInfo.rewardTokens.length; i++) {
beforeBalances[i] = IERC20(pool.gaugeInfo.rewardTokens[i]).balanceOf(address(this));
}
address[] memory gaugesToCheck = new address[](1);
gaugesToCheck[0] = address(pool.gaugeInfo.gauge);
address[][] memory gaugeRewardTokens = new address[][](1);
gaugeRewardTokens[0] = pool.gaugeInfo.rewardTokens;
voter.claimRewards(gaugesToCheck, gaugeRewardTokens);
for (uint256 i = 0; i < pool.gaugeInfo.rewardTokens.length; i++) {
IERC20 rewardToken = IERC20(pool.gaugeInfo.rewardTokens[i]);
uint256 afterBalance = rewardToken.balanceOf(address(this));
uint256 rewardAmount = afterBalance - beforeBalances[i];
if (rewardAmount > 0) {
rewardToken.safeTransfer(bribesSafe, rewardAmount);
}
}
}
}
}
// Add a gauge to a pool
function enableGauge(uint256 _pid) public onlyOperator {
address gauge = voter.gaugeForPool(address(poolInfo[_pid].token));
if (gauge != address(0)) {
address[] memory rewardTokensGauge = new address[](1);
rewardTokensGauge[0] = xSHADOW;
poolInfo[_pid].gaugeInfo = GaugeInfo(true, IGauge(gauge), rewardTokensGauge);
}
}
function setGaugeRewardTokens(uint256 _pid, address[] calldata _rewardTokens) public onlyOperator {
PoolInfo storage pool = poolInfo[_pid];
require(pool.gaugeInfo.isGauge, "SnakeGenesisRewardPool: not a gauge pool");
pool.gaugeInfo.rewardTokens = _rewardTokens;
}
function setBribesSafe(address _bribesSafe) public onlyOperator {
bribesSafe = _bribesSafe;
}
// 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
pool.gaugeInfo.gauge.withdraw(_amount);
}
}
// 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.accSnakePerShare).div(1e18).sub(user.rewardDebt);
if (_pending > 0) {
safeSnakeTransfer(_sender, _pending);
emit RewardPaid(_sender, _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.accSnakePerShare).div(1e18);
emit Deposit(_sender, _pid, _amount);
}
// Withdraw LP tokens.
function withdraw(uint256 _pid, uint256 _amount) public 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.accSnakePerShare).div(1e18).sub(user.rewardDebt);
if (_pending > 0) {
safeSnakeTransfer(_sender, _pending);
emit RewardPaid(_sender, _pending);
}
if (_amount > 0) {
user.amount = user.amount.sub(_amount);
withdrawFromGauge(_pid, _amount);
pool.token.safeTransfer(_sender, _amount);
}
user.rewardDebt = user.amount.mul(pool.accSnakePerShare).div(1e18);
emit Withdraw(_sender, _pid, _amount);
}
// 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);
user.amount = 0;
user.rewardDebt = 0;
pool.token.safeTransfer(msg.sender, _amount);
emit EmergencyWithdraw(msg.sender, _pid, _amount);
}
// Safe snake transfer function, just in case if rounding error causes pool to not have enough SNAKEs.
function safeSnakeTransfer(address _to, uint256 _amount) internal {
uint256 _snakeBal = snake.balanceOf(address(this));
if (_snakeBal > 0) {
if (_amount > _snakeBal) {
snake.safeTransfer(_to, _snakeBal);
} else {
snake.safeTransfer(_to, _amount);
}
}
}
function setOperator(address _operator) external onlyOperator {
operator = _operator;
}
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);
}
}// 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 (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
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: GPL-2.0-or-later
pragma solidity ^0.8.26;
interface IGauge {
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 IVoter {
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;
}{
"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":"_snake","type":"address"},{"internalType":"address","name":"_bribesSafe","type":"address"},{"internalType":"uint256","name":"_poolStartTime","type":"uint256"},{"internalType":"address","name":"_voter","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":[{"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":[{"internalType":"uint256[]","name":"_allocPoints","type":"uint256[]"},{"internalType":"uint256[]","name":"_depFees","type":"uint256[]"},{"internalType":"contract IERC20[]","name":"_tokens","type":"address[]"},{"internalType":"bool","name":"_withUpdate","type":"bool"},{"internalType":"uint256","name":"_lastRewardTime","type":"uint256"}],"name":"addBulk","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":"claimLegacyRewards","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"}],"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":"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":"operator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"pendingSNAKE","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":"accSnakePerShare","type":"uint256"},{"internalType":"bool","name":"isStarted","type":"bool"},{"components":[{"internalType":"bool","name":"isGauge","type":"bool"},{"internalType":"contract IGauge","name":"gauge","type":"address"},{"internalType":"address[]","name":"rewardTokens","type":"address[]"}],"internalType":"struct SnakeGenesisRewardPool.GaugeInfo","name":"gaugeInfo","type":"tuple"},{"internalType":"uint256","name":"poolSnakePerSec","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":"uint256","name":"_pid","type":"uint256"},{"internalType":"address[]","name":"_rewardTokens","type":"address[]"}],"name":"setGaugeRewardTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"}],"name":"setOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"snake","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"snakePerSecond","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":[],"name":"voter","outputs":[{"internalType":"contract IVoter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"xSHADOW","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]Contract Creation Code
6080604052600480546001600160a01b031916735050bc082ff4a74fb6b0b04385defddb114b242417905560006008819055600b5562093a80600c5534801561004757600080fd5b50604051614369380380614369833981016040819052610066916114a3565b60016000554282116100bf5760405162461bcd60e51b815260206004820181905260248201527f706f6f6c2063616e74206265207374617274656420696e20746865207061737460448201526064015b60405180910390fd5b6001600160a01b038416156100ea57600280546001600160a01b0319166001600160a01b0386161790555b6001600160a01b0383161561011557600580546001600160a01b0319166001600160a01b0385161790555b6009829055600c546101279083611507565b600a5560018054336001600160a01b0319918216179091556003805482166001600160a01b03848116919091179091556005805490921690851617905561018e670336632e53c8eb28600073287c6882de298665977787e268f3dba052a6e2518180610297565b6101b9670268ca62bed6b158606473039e2fb66102314ce7b64ce5ce3e5183bc94ad38600080610297565b6101e467019b319729e4778860647329219dd400f2bf60e5a23d13be72b486d4038894600080610297565b61020f67019b319729e4778860647350c42deacd8fc9773493ed674b675be577f2634b600080610297565b61023966523d1e3b9417846064733333b97138d4b086720b5ae8a7844b1345a33333600080610297565b61026366523d1e3b94178460647379bbf4508b1391af3a0f4b30bb5fc4aa9ab0e07c600080610297565b61028e670148f478ee505ed8606473d3dce716f3ef535c5ff8d041c1a41c3bd89b97ae600080610297565b5050505061173f565b6001546001600160a01b031633146102fa5760405162461bcd60e51b8152602060048201526032602482015260008051602061434983398151915260448201527139903737ba103a34329037b832b930ba37b960711b60648201526084016100b6565b610303836105a4565b811561031157610311610652565b600954421015610340578060000361032c5750600954610354565b60095481101561033b57506009545b610354565b80158061034c57504281105b156103545750425b6000600954821115806103675750428211155b6040805160018082528183019092529192506000919060208083019080368337505060045482519293506001600160a01b0316918391506000906103ad576103ad611530565b60200260200101906001600160a01b031690816001600160a01b0316815250506006604051806101000160405280876001600160a01b03168152602001888152602001898152602001858152602001600081526020018415158152602001604051806060016040528060001515815260200160006001600160a01b0316815260200185815250815260200189815250908060018154018082558091505060019003906000526020600020906009020160009091909190915060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506020820151816001015560408201518160020155606082015181600301556080820151816004015560a08201518160050160006101000a81548160ff02191690831515021790555060c08201518160060160008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a8154816001600160a01b0302191690836001600160a01b03160217905550604082015181600101908051906020019061054c92919061140d565b50505060e091909101516008909101556006546105749061056f90600190611546565b61067e565b811561059b5760085461058790886108a3565b600855600b5461059790886108a3565b600b555b50505050505050565b60065460005b8181101561064d57826001600160a01b0316600682815481106105cf576105cf611530565b60009182526020909120600990910201546001600160a01b0316036106455760405162461bcd60e51b815260206004820152602660248201527f536e616b6547656e65736973526577617264506f6f6c3a206578697374696e6760448201526520706f6f6c3f60d01b60648201526084016100b6565b6001016105aa565b505050565b60065460005b8181101561067a57610669816108b8565b61067281610ac1565b600101610658565b5050565b6001546001600160a01b031633146106e15760405162461bcd60e51b8152602060048201526032602482015260008051602061434983398151915260448201527139903737ba103a34329037b832b930ba37b960711b60648201526084016100b6565b600354600680546000926001600160a01b031691632045be90918590811061070b5761070b611530565b600091825260209091206009909102015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa158015610760573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107849190611559565b90506001600160a01b0381161561067a5760408051600180825281830190925260009160208083019080368337505060045482519293506001600160a01b0316918391506000906107d7576107d7611530565b60200260200101906001600160a01b031690816001600160a01b0316815250506040518060600160405280600115158152602001836001600160a01b03168152602001828152506006848154811061083157610831611530565b60009182526020918290208351600660099093029091019182018054858501516001600160a01b031661010002610100600160a81b0319931515939093166001600160a81b03199091161791909117815560408401518051919361089b936007019291019061140d565b505050505050565b60006108af8284611507565b90505b92915050565b6108c181610ac1565b6000600682815481106108d6576108d6611530565b90600052602060002090600902019050806003015442116108f5575050565b600681015460009060ff166109745781546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa15801561094b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061096f9190611574565b6109e6565b60068201546040516370a0823160e01b81523060048201526101009091046001600160a01b0316906370a0823190602401602060405180830381865afa1580156109c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109e69190611574565b9050806000036109fb57504260039091015550565b600582015460ff16610a3f5760058201805460ff191660011790556002820154600854610a27916108a3565b6008908155820154600b54610a3b916108a3565b600b555b60085415610ab2576000610a5d836003015442610cdc60201b60201c565b90506000610a84600854610a7e866002015485610d8b60201b90919060201c565b90610d97565b9050610aaa610a9f84610a7e84670de0b6b3a7640000610d8b565b6004860154906108a3565b600485015550505b42600383015561064d83610da3565b600060068281548110610ad657610ad6611530565b60009182526020822060099190910201600681015481546040516370a0823160e01b81523060048201529294506101009091046001600160a01b0390811693929116906370a0823190602401602060405180830381865afa158015610b3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b639190611574565b600684015490915060ff1615610cd6578015610cd6578254604051636eb1769f60e11b81523060048201526001600160a01b0384811660248301528392169063dd62ed3e90604401602060405180830381865afa158015610bc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bec9190611574565b1015610c6b57825460405163095ea7b360e01b81526001600160a01b03848116600483015260001960248301529091169063095ea7b3906044016020604051808303816000875af1158015610c45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c69919061158d565b505b60068301546040516317a790f160e11b8152306004820152602481018390526101009091046001600160a01b031690632f4f21e290604401600060405180830381600087803b158015610cbd57600080fd5b505af1158015610cd1573d6000803e3d6000fd5b505050505b50505050565b6000818310610ced575060006108b2565b600a548210610d4a57600a548310610d07575060006108b2565b6009548311610d3557600b54600954600a54610d2e9291610d28919061114d565b90610d8b565b90506108b2565b600b54600a54610d2e9190610d28908661114d565b6009548211610d5b575060006108b2565b6009548311610d7a57600b54600954610d2e9190610d2890859061114d565b600b54610d2e90610d28848661114d565b60006108af82846115b6565b60006108af82846115cd565b600060068281548110610db857610db8611530565b60009182526020909120600990910201600681015490915060ff161561067a5760078101541561067a5760078101546000906001600160401b03811115610e0157610e0161151a565b604051908082528060200260200182016040528015610e2a578160200160208202803683370190505b50905060005b6007830154811015610eec5760078301805482908110610e5257610e52611530565b6000918252602090912001546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015610ea3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ec79190611574565b828281518110610ed957610ed9611530565b6020908102919091010152600101610e30565b5060408051600180825281830190925260009160208083019080368337019050506006840154815191925061010090046001600160a01b0316908290600090610f3757610f37611530565b6001600160a01b039290921660209283029190910190910152604080516001808252818301909252600091816020015b6060815260200190600190039081610f6757505060078501805460408051602080840282018101909252828152939450830182828015610fd057602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610fb2575b505050505081600081518110610fe857610fe8611530565b60209081029190910101526003546040516320b1cb6f60e01b81526001600160a01b03909116906320b1cb6f9061102590859085906004016115ef565b600060405180830381600087803b15801561103f57600080fd5b505af1158015611053573d6000803e3d6000fd5b5050505060005b600785015481101561089b57600085600601600101828154811061108057611080611530565b60009182526020822001546040516370a0823160e01b81523060048201526001600160a01b03909116925082906370a0823190602401602060405180830381865afa1580156110d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110f79190611574565b9050600086848151811061110d5761110d611530565b6020026020010151826111209190611546565b9050801561114257600554611142906001600160a01b03858116911683611159565b50505060010161105a565b60006108af8284611546565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663a9059cbb60e01b1790915261064d9185916111af16565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564908201526000906111fc906001600160a01b03851690849061127c565b905080516000148061121d57508080602001905181019061121d919061158d565b61064d5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016100b6565b606061128b8484600085611293565b949350505050565b6060824710156112f45760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016100b6565b600080866001600160a01b0316858760405161131091906116f0565b60006040518083038185875af1925050503d806000811461134d576040519150601f19603f3d011682016040523d82523d6000602084013e611352565b606091505b5090925090506113648783838761136f565b979650505050505050565b606083156113de5782516000036113d7576001600160a01b0385163b6113d75760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016100b6565b508161128b565b61128b83838151156113f35781518083602001fd5b8060405162461bcd60e51b81526004016100b6919061170c565b828054828255906000526020600020908101928215611462579160200282015b8281111561146257825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019061142d565b5061146e929150611472565b5090565b5b8082111561146e5760008155600101611473565b80516001600160a01b038116811461149e57600080fd5b919050565b600080600080608085870312156114b957600080fd5b6114c285611487565b93506114d060208601611487565b604086015190935091506114e660608601611487565b905092959194509250565b634e487b7160e01b600052601160045260246000fd5b808201808211156108b2576108b26114f1565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b818103818111156108b2576108b26114f1565b60006020828403121561156b57600080fd5b6108af82611487565b60006020828403121561158657600080fd5b5051919050565b60006020828403121561159f57600080fd5b815180151581146115af57600080fd5b9392505050565b80820281158282048414176108b2576108b26114f1565b6000826115ea57634e487b7160e01b600052601260045260246000fd5b500490565b6040808252835190820181905260009060208501906060840190835b818110156116325783516001600160a01b031683526020938401939092019160010161160b565b50508381036020850152809150845180825260208201925060208160051b8301016020870160005b838110156116be57848303601f190186528151805180855260209182019185019060005b818110156116a55783516001600160a01b031683526020938401939092019160010161167e565b505060209788019790945092909201915060010161165a565b509098975050505050505050565b60005b838110156116e75781810151838201526020016116cf565b50506000910152565b600082516117028184602087016116cc565b9190910192915050565b602081526000825180602084015261172b8160408501602087016116cc565b601f01601f19169190910160400192915050565b612bfb8061174e6000396000f3fe608060405234801561001057600080fd5b50600436106101e55760003560e01c806362d303681161010f578063b2c75f8c116100a2578063ced8a5d711610071578063ced8a5d714610414578063de89c76c14610427578063e2bbb1581461043a578063fddc298c1461044d57600080fd5b8063b2c75f8c146103d2578063b3ab15fb146103e5578063b7bb600d146103f8578063b947a88d1461040157600080fd5b80636ef3c44c116100de5780636ef3c44c1461035c57806390c5ed6a1461036f57806393f1a40b14610382578063943f013d146103c957600080fd5b806362d3036814610325578063630b5ba1146103385780636a6adeb3146103405780636e271dd51461035357600080fd5b806343b0e8df116101875780635312ea8e116101565780635312ea8e146102e357806354575af4146102f6578063570ca735146103095780635f96dc111461031c57600080fd5b806343b0e8df14610297578063441a3e70146102aa57806346c96aac146102bd5780634e2768ca146102d057600080fd5b806317caf6f1116101c357806317caf6f114610253578063231f0c6a1461025c5780632df95ed71461026f5780633de2c6de1461028457600080fd5b8063081e3eda146101ea57806311284b42146102015780631526fe271461022c575b600080fd5b6006545b6040519081526020015b60405180910390f35b600454610214906001600160a01b031681565b6040516001600160a01b0390911681526020016101f8565b61023f61023a3660046124ce565b610460565b6040516101f898979695949392919061252c565b6101ee60085481565b6101ee61026a3660046125af565b61058d565b61028261027d3660046124ce565b610652565b005b6101ee6102923660046125e6565b61086d565b6102826102a5366004612616565b610a5e565b6102826102b83660046125af565b610b32565b600354610214906001600160a01b031681565b6102826102de3660046124ce565b610d0d565b6102826102f13660046124ce565b610ef9565b610282610304366004612642565b610fb1565b600154610214906001600160a01b031681565b6101ee60095481565b6102826103333660046126de565b6110a0565b610282611175565b600254610214906001600160a01b031681565b6101ee600a5481565b61028261036a3660046127a1565b61119d565b61028261037d3660046127ed565b611269565b6103b46103903660046125e6565b60076020908152600092835260408084209091529082529020805460019091015482565b604080519283526020830191909152016101f8565b6101ee600c5481565b6102826103e03660046124ce565b611538565b6102826103f336600461283f565b6118e3565b6101ee600b5481565b61028261040f3660046125af565b61192f565b61028261042236600461283f565b6119bd565b600554610214906001600160a01b031681565b6102826104483660046125af565b611a09565b61028261045b36600461285c565b611be1565b6006818154811061047057600080fd5b90600052602060002090600902016000915090508060000160009054906101000a90046001600160a01b0316908060010154908060020154908060030154908060040154908060050160009054906101000a900460ff1690806006016040518060600160405290816000820160009054906101000a900460ff161515151581526020016000820160019054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016001820180548060200260200160405190810160405280929190818152602001828054801561057a57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161055c575b5050509190925250505060089091015488565b600081831061059e5750600061064c565b600a54821061060657600a5483106105b85750600061064c565b60095483116105eb576105e4600b546105de600954600a54611c9b90919063ffffffff16565b90611cae565b905061064c565b6105e4600b546105de85600a54611c9b90919063ffffffff16565b60095482116106175750600061064c565b600954831161063b576105e4600b546105de60095485611c9b90919063ffffffff16565b600b546105e4906105de8486611c9b565b92915050565b60006006828154811061066757610667612902565b60009182526020822060099190910201600681015481546040516370a0823160e01b81523060048201529294506101009091046001600160a01b0390811693929116906370a0823190602401602060405180830381865afa1580156106d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106f49190612918565b600684015490915060ff1615610867578015610867578254604051636eb1769f60e11b81523060048201526001600160a01b0384811660248301528392169063dd62ed3e90604401602060405180830381865afa158015610759573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061077d9190612918565b10156107fc57825460405163095ea7b360e01b81526001600160a01b03848116600483015260001960248301529091169063095ea7b3906044016020604051808303816000875af11580156107d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107fa9190612931565b505b60068301546040516317a790f160e11b8152306004820152602481018390526101009091046001600160a01b031690632f4f21e290604401600060405180830381600087803b15801561084e57600080fd5b505af1158015610862573d6000803e3d6000fd5b505050505b50505050565b6000806006848154811061088357610883612902565b600091825260208083208784526007825260408085206001600160a01b0389168652909252908320600992909202016004810154600682015491945091929060ff166109395783546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015610910573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109349190612918565b6109ab565b60068401546040516370a0823160e01b81523060048201526101009091046001600160a01b0316906370a0823190602401602060405180830381865afa158015610987573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ab9190612918565b90508360030154421180156109bf57508015155b15610a225760006109d485600301544261058d565b905060006109fb6008546109f5886002015485611cae90919063ffffffff16565b90611cba565b9050610a1d610a16846109f584670de0b6b3a7640000611cae565b8590611cc6565b935050505b610a538360010154610a4d670de0b6b3a76400006109f5868860000154611cae90919063ffffffff16565b90611c9b565b979650505050505050565b6001546001600160a01b03163314610a915760405162461bcd60e51b8152600401610a889061294e565b60405180910390fd5b610a99611175565b600060068481548110610aae57610aae612902565b9060005260206000209060090201905060c88210610acb57600080fd5b60018101829055600581015460ff1615610b2057610b0283610afc8360020154600854611c9b90919063ffffffff16565b90611cc6565b6008908155810154600b54610b1c918591610afc91611c9b565b600b555b60028101839055600801919091555050565b610b3a611cd2565b6000339050600060068481548110610b5457610b54612902565b600091825260208083208784526007825260408085206001600160a01b03881686529092529220805460099092029092019250841115610bcb5760405162461bcd60e51b81526020600482015260126024820152711dda5d1a191c985dce881b9bdd0819dbdbd960721b6044820152606401610a88565b610bd485611d2b565b610bdd85610652565b6000610c0e8260010154610a4d670de0b6b3a76400006109f587600401548760000154611cae90919063ffffffff16565b90508015610c6457610c208482611f28565b836001600160a01b03167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e048682604051610c5b91815260200190565b60405180910390a25b8415610c98578154610c769086611c9b565b8255610c828686611fd3565b8254610c98906001600160a01b03168587612068565b60048301548254610cb691670de0b6b3a7640000916109f591611cae565b600183015560405185815286906001600160a01b038616907ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b5689060200160405180910390a350505050610d096001600055565b5050565b6001546001600160a01b03163314610d375760405162461bcd60e51b8152600401610a889061294e565b600354600680546000926001600160a01b031691632045be909185908110610d6157610d61612902565b600091825260209091206009909102015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa158015610db6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dda91906129a0565b90506001600160a01b03811615610d095760408051600180825281830190925260009160208083019080368337505060045482519293506001600160a01b031691839150600090610e2d57610e2d612902565b60200260200101906001600160a01b031690816001600160a01b0316815250506040518060600160405280600115158152602001836001600160a01b031681526020018281525060068481548110610e8757610e87612902565b60009182526020918290208351600660099093029091019182018054858501516001600160a01b031661010002610100600160a81b0319931515939093166001600160a81b031990911617919091178155604084015180519193610ef19360070192910190612401565b505050505050565b610f01611cd2565b600060068281548110610f1657610f16612902565b600091825260208083208584526007825260408085203386529092529220805460099092029092019250610f4a8482611fd3565b600080835560018301558254610f6a906001600160a01b03163383612068565b604051818152849033907fbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae05959060200160405180910390a3505050610fae6001600055565b50565b6001546001600160a01b03163314610fdb5760405162461bcd60e51b8152600401610a889061294e565b60065460005b8181101561108b57600060068281548110610ffe57610ffe612902565b6000918252602090912060099091020180549091506001600160a01b03908116908716036110825760405162461bcd60e51b815260206004820152602b60248201527f5368617265526577617264506f6f6c3a20546f6b656e2063616e6e6f7420626560448201526a103837b7b6103a37b5b2b760a91b6064820152608401610a88565b50600101610fe1565b506108676001600160a01b0385168385612068565b6001546001600160a01b031633146110ca5760405162461bcd60e51b8152600401610a889061294e565b86851480156110d857508683145b6110f45760405162461bcd60e51b8152600401610a88906129d3565b60005b8781101561116a5761116289898381811061111457611114612902565b9050602002013588888481811061112d5761112d612902565b9050602002013587878581811061114657611146612902565b905060200201602081019061115b919061283f565b8686611269565b6001016110f7565b505050505050505050565b60065460005b81811015610d095761118c81611d2b565b61119581610652565b60010161117b565b6001546001600160a01b031633146111c75760405162461bcd60e51b8152600401610a889061294e565b6000600684815481106111dc576111dc612902565b60009182526020909120600990910201600681015490915060ff166112545760405162461bcd60e51b815260206004820152602860248201527f536e616b6547656e65736973526577617264506f6f6c3a206e6f7420612067616044820152671d59d9481c1bdbdb60c21b6064820152608401610a88565b611262600782018484612466565b5050505050565b6001546001600160a01b031633146112935760405162461bcd60e51b8152600401610a889061294e565b61129c836120cb565b81156112aa576112aa611175565b6009544210156112d957806000036112c557506009546112ed565b6009548110156112d457506009545b6112ed565b8015806112e557504281105b156112ed5750425b6000600954821115806113005750428211155b6040805160018082528183019092529192506000919060208083019080368337505060045482519293506001600160a01b03169183915060009061134657611346612902565b60200260200101906001600160a01b031690816001600160a01b0316815250506006604051806101000160405280876001600160a01b03168152602001888152602001898152602001858152602001600081526020018415158152602001604051806060016040528060001515815260200160006001600160a01b0316815260200185815250815260200189815250908060018154018082558091505060019003906000526020600020906009020160009091909190915060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506020820151816001015560408201518160020155606082015181600301556080820151816004015560a08201518160050160006101000a81548160ff02191690831515021790555060c08201518160060160008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a8154816001600160a01b0302191690836001600160a01b0316021790555060408201518160010190805190602001906114e5929190612401565b50505060e09190910151600890910155600654611508906102de90600190612a2f565b811561152f5760085461151b9088611cc6565b600855600b5461152b9088611cc6565b600b555b50505050505050565b60006006828154811061154d5761154d612902565b60009182526020909120600990910201600681015490915060ff1615610d0957600781015415610d0957600781015460009067ffffffffffffffff811115611597576115976129bd565b6040519080825280602002602001820160405280156115c0578160200160208202803683370190505b50905060005b600783015481101561168257600783018054829081106115e8576115e8612902565b6000918252602090912001546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015611639573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061165d9190612918565b82828151811061166f5761166f612902565b60209081029190910101526001016115c6565b5060408051600180825281830190925260009160208083019080368337019050506006840154815191925061010090046001600160a01b03169082906000906116cd576116cd612902565b6001600160a01b039290921660209283029190910190910152604080516001808252818301909252600091816020015b60608152602001906001900390816116fd5750506007850180546040805160208084028201810190925282815293945083018282801561176657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611748575b50505050508160008151811061177e5761177e612902565b60209081029190910101526003546040516320b1cb6f60e01b81526001600160a01b03909116906320b1cb6f906117bb9085908590600401612a42565b600060405180830381600087803b1580156117d557600080fd5b505af11580156117e9573d6000803e3d6000fd5b5050505060005b6007850154811015610ef157600085600601600101828154811061181657611816612902565b60009182526020822001546040516370a0823160e01b81523060048201526001600160a01b03909116925082906370a0823190602401602060405180830381865afa158015611869573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061188d9190612918565b905060008684815181106118a3576118a3612902565b6020026020010151826118b69190612a2f565b905080156118d8576005546118d8906001600160a01b03858116911683612068565b5050506001016117f0565b6001546001600160a01b0316331461190d5760405162461bcd60e51b8152600401610a889061294e565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b8082111561198d5760405162461bcd60e51b815260206004820152602560248201527f536e616b6547656e65736973526577617264506f6f6c3a20696e76616c69642060448201526472616e676560d81b6064820152608401610a88565b815b8181116119b85761199f81611d2b565b6119a881610652565b6119b181612aed565b905061198f565b505050565b6001546001600160a01b031633146119e75760405162461bcd60e51b8152600401610a889061294e565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b611a11611cd2565b6000339050600060068481548110611a2b57611a2b612902565b600091825260208083208784526007825260408085206001600160a01b0388168652909252922060099091029091019150611a6585611d2b565b805415611af5576000611a9d8260010154610a4d670de0b6b3a76400006109f587600401548760000154611cae90919063ffffffff16565b90508015611af357611aaf8482611f28565b836001600160a01b03167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e048682604051611aea91815260200190565b60405180910390a25b505b8315611b68578154611b12906001600160a01b0316843087612174565b6000611b316127106109f5856001015488611cae90919063ffffffff16565b9050611b48611b408683611c9b565b835490611cc6565b82556005548354611b66916001600160a01b03918216911683612068565b505b611b7185610652565b60048201548154611b8f91670de0b6b3a7640000916109f591611cae565b600182015560405184815285906001600160a01b038516907f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a159060200160405180910390a3505050610d096001600055565b6001546001600160a01b03163314611c0b5760405162461bcd60e51b8152600401610a889061294e565b8483148015611c1957508481145b611c355760405162461bcd60e51b8152600401610a88906129d3565b60005b8581101561152f57611c93878783818110611c5557611c55612902565b90506020020135868684818110611c6e57611c6e612902565b90506020020135858585818110611c8757611c87612902565b90506020020135610a5e565b600101611c38565b6000611ca78284612a2f565b9392505050565b6000611ca78284612b06565b6000611ca78284612b1d565b6000611ca78284612b3f565b600260005403611d245760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610a88565b6002600055565b611d3481610652565b600060068281548110611d4957611d49612902565b9060005260206000209060090201905080600301544211611d68575050565b600681015460009060ff16611de75781546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015611dbe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611de29190612918565b611e59565b60068201546040516370a0823160e01b81523060048201526101009091046001600160a01b0316906370a0823190602401602060405180830381865afa158015611e35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e599190612918565b905080600003611e6e57504260039091015550565b600582015460ff16611eb25760058201805460ff191660011790556002820154600854611e9a91611cc6565b6008908155820154600b54611eae91611cc6565b600b555b60085415611f19576000611eca83600301544261058d565b90506000611eeb6008546109f5866002015485611cae90919063ffffffff16565b9050611f11611f06846109f584670de0b6b3a7640000611cae565b600486015490611cc6565b600485015550505b4260038301556119b883611538565b6002546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015611f71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f959190612918565b905080156119b85780821115611fbc576002546119b8906001600160a01b03168483612068565b6002546119b8906001600160a01b03168484612068565b600060068381548110611fe857611fe8612902565b60009182526020909120600990910201600681015490915060ff16156119b8576006810154604051632e1a7d4d60e01b8152600481018490526101009091046001600160a01b031690632e1a7d4d90602401600060405180830381600087803b15801561205457600080fd5b505af115801561152f573d6000803e3d6000fd5b6040516001600160a01b0383166024820152604481018290526119b890849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526121ac565b60065460005b818110156119b857826001600160a01b0316600682815481106120f6576120f6612902565b60009182526020909120600990910201546001600160a01b03160361216c5760405162461bcd60e51b815260206004820152602660248201527f536e616b6547656e65736973526577617264506f6f6c3a206578697374696e6760448201526520706f6f6c3f60d01b6064820152608401610a88565b6001016120d1565b6040516001600160a01b03808516602483015283166044820152606481018290526108679085906323b872dd60e01b90608401612094565b6000612201826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166122819092919063ffffffff16565b90508051600014806122225750808060200190518101906122229190612931565b6119b85760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610a88565b60606122908484600085612298565b949350505050565b6060824710156122f95760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610a88565b600080866001600160a01b031685876040516123159190612b76565b60006040518083038185875af1925050503d8060008114612352576040519150601f19603f3d011682016040523d82523d6000602084013e612357565b606091505b5091509150610a5387838387606083156123d25782516000036123cb576001600160a01b0385163b6123cb5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610a88565b5081612290565b61229083838151156123e75781518083602001fd5b8060405162461bcd60e51b8152600401610a889190612b92565b828054828255906000526020600020908101928215612456579160200282015b8281111561245657825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190612421565b506124629291506124b9565b5090565b828054828255906000526020600020908101928215612456579160200282015b828111156124565781546001600160a01b0319166001600160a01b03843516178255602090920191600190910190612486565b5b8082111561246257600081556001016124ba565b6000602082840312156124e057600080fd5b5035919050565b600081518084526020840193506020830160005b828110156125225781516001600160a01b03168652602095860195909101906001016124fb565b5093949350505050565b60018060a01b038916815287602082015286604082015285606082015284608082015283151560a082015261010060c08201528251151561010082015260018060a01b036020840151166101208201526000604084015160606101408401526125996101608401826124e7565b9150508260e08301529998505050505050505050565b600080604083850312156125c257600080fd5b50508035926020909101359150565b6001600160a01b0381168114610fae57600080fd5b600080604083850312156125f957600080fd5b82359150602083013561260b816125d1565b809150509250929050565b60008060006060848603121561262b57600080fd5b505081359360208301359350604090920135919050565b60008060006060848603121561265757600080fd5b8335612662816125d1565b9250602084013591506040840135612679816125d1565b809150509250925092565b60008083601f84011261269657600080fd5b50813567ffffffffffffffff8111156126ae57600080fd5b6020830191508360208260051b85010111156126c957600080fd5b9250929050565b8015158114610fae57600080fd5b60008060008060008060008060a0898b0312156126fa57600080fd5b883567ffffffffffffffff81111561271157600080fd5b61271d8b828c01612684565b909950975050602089013567ffffffffffffffff81111561273d57600080fd5b6127498b828c01612684565b909750955050604089013567ffffffffffffffff81111561276957600080fd5b6127758b828c01612684565b9095509350506060890135612789816126d0565b979a9699509497939692959194509192608001359150565b6000806000604084860312156127b657600080fd5b83359250602084013567ffffffffffffffff8111156127d457600080fd5b6127e086828701612684565b9497909650939450505050565b600080600080600060a0868803121561280557600080fd5b8535945060208601359350604086013561281e816125d1565b9250606086013561282e816126d0565b949793965091946080013592915050565b60006020828403121561285157600080fd5b8135611ca7816125d1565b6000806000806000806060878903121561287557600080fd5b863567ffffffffffffffff81111561288c57600080fd5b61289889828a01612684565b909750955050602087013567ffffffffffffffff8111156128b857600080fd5b6128c489828a01612684565b909550935050604087013567ffffffffffffffff8111156128e457600080fd5b6128f089828a01612684565b979a9699509497509295939492505050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561292a57600080fd5b5051919050565b60006020828403121561294357600080fd5b8151611ca7816126d0565b60208082526032908201527f536e616b6547656e65736973526577617264506f6f6c3a2063616c6c6572206960408201527139903737ba103a34329037b832b930ba37b960711b606082015260800190565b6000602082840312156129b257600080fd5b8151611ca7816125d1565b634e487b7160e01b600052604160045260246000fd5b60208082526026908201527f536e616b6547656e65736973526577617264506f6f6c3a20696e76616c6964206040820152650d8cadccee8d60d31b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b8181038181111561064c5761064c612a19565b6040808252835190820181905260009060208501906060840190835b81811015612a855783516001600160a01b0316835260209384019390920191600101612a5e565b50508381036020850152809150845180825260208201925060208160051b8301016020870160005b83811015612adf57601f19858403018652612ac98383516124e7565b6020968701969093509190910190600101612aad565b509098975050505050505050565b600060018201612aff57612aff612a19565b5060010190565b808202811582820484141761064c5761064c612a19565b600082612b3a57634e487b7160e01b600052601260045260246000fd5b500490565b8082018082111561064c5761064c612a19565b60005b83811015612b6d578181015183820152602001612b55565b50506000910152565b60008251612b88818460208701612b52565b9190910192915050565b6020815260008251806020840152612bb1816040850160208701612b52565b601f01601f1916919091016040019291505056fea2646970667358221220adb4bd64e4c708ecaafb583fa43987b5fc06c7f41563e494d0092997a18fd48564736f6c634300081a0033536e616b6547656e65736973526577617264506f6f6c3a2063616c6c657220690000000000000000000000003a516e01f82c1e18916ed69a81dd498ef64bb157000000000000000000000000a906b773bf4e1f5c668eedeed06aa8917057ea7d0000000000000000000000000000000000000000000000000000000067a79ba00000000000000000000000003af1dd7a2755201f8e2d6dcda1a61d9f54838f4f
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101e55760003560e01c806362d303681161010f578063b2c75f8c116100a2578063ced8a5d711610071578063ced8a5d714610414578063de89c76c14610427578063e2bbb1581461043a578063fddc298c1461044d57600080fd5b8063b2c75f8c146103d2578063b3ab15fb146103e5578063b7bb600d146103f8578063b947a88d1461040157600080fd5b80636ef3c44c116100de5780636ef3c44c1461035c57806390c5ed6a1461036f57806393f1a40b14610382578063943f013d146103c957600080fd5b806362d3036814610325578063630b5ba1146103385780636a6adeb3146103405780636e271dd51461035357600080fd5b806343b0e8df116101875780635312ea8e116101565780635312ea8e146102e357806354575af4146102f6578063570ca735146103095780635f96dc111461031c57600080fd5b806343b0e8df14610297578063441a3e70146102aa57806346c96aac146102bd5780634e2768ca146102d057600080fd5b806317caf6f1116101c357806317caf6f114610253578063231f0c6a1461025c5780632df95ed71461026f5780633de2c6de1461028457600080fd5b8063081e3eda146101ea57806311284b42146102015780631526fe271461022c575b600080fd5b6006545b6040519081526020015b60405180910390f35b600454610214906001600160a01b031681565b6040516001600160a01b0390911681526020016101f8565b61023f61023a3660046124ce565b610460565b6040516101f898979695949392919061252c565b6101ee60085481565b6101ee61026a3660046125af565b61058d565b61028261027d3660046124ce565b610652565b005b6101ee6102923660046125e6565b61086d565b6102826102a5366004612616565b610a5e565b6102826102b83660046125af565b610b32565b600354610214906001600160a01b031681565b6102826102de3660046124ce565b610d0d565b6102826102f13660046124ce565b610ef9565b610282610304366004612642565b610fb1565b600154610214906001600160a01b031681565b6101ee60095481565b6102826103333660046126de565b6110a0565b610282611175565b600254610214906001600160a01b031681565b6101ee600a5481565b61028261036a3660046127a1565b61119d565b61028261037d3660046127ed565b611269565b6103b46103903660046125e6565b60076020908152600092835260408084209091529082529020805460019091015482565b604080519283526020830191909152016101f8565b6101ee600c5481565b6102826103e03660046124ce565b611538565b6102826103f336600461283f565b6118e3565b6101ee600b5481565b61028261040f3660046125af565b61192f565b61028261042236600461283f565b6119bd565b600554610214906001600160a01b031681565b6102826104483660046125af565b611a09565b61028261045b36600461285c565b611be1565b6006818154811061047057600080fd5b90600052602060002090600902016000915090508060000160009054906101000a90046001600160a01b0316908060010154908060020154908060030154908060040154908060050160009054906101000a900460ff1690806006016040518060600160405290816000820160009054906101000a900460ff161515151581526020016000820160019054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016001820180548060200260200160405190810160405280929190818152602001828054801561057a57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161055c575b5050509190925250505060089091015488565b600081831061059e5750600061064c565b600a54821061060657600a5483106105b85750600061064c565b60095483116105eb576105e4600b546105de600954600a54611c9b90919063ffffffff16565b90611cae565b905061064c565b6105e4600b546105de85600a54611c9b90919063ffffffff16565b60095482116106175750600061064c565b600954831161063b576105e4600b546105de60095485611c9b90919063ffffffff16565b600b546105e4906105de8486611c9b565b92915050565b60006006828154811061066757610667612902565b60009182526020822060099190910201600681015481546040516370a0823160e01b81523060048201529294506101009091046001600160a01b0390811693929116906370a0823190602401602060405180830381865afa1580156106d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106f49190612918565b600684015490915060ff1615610867578015610867578254604051636eb1769f60e11b81523060048201526001600160a01b0384811660248301528392169063dd62ed3e90604401602060405180830381865afa158015610759573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061077d9190612918565b10156107fc57825460405163095ea7b360e01b81526001600160a01b03848116600483015260001960248301529091169063095ea7b3906044016020604051808303816000875af11580156107d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107fa9190612931565b505b60068301546040516317a790f160e11b8152306004820152602481018390526101009091046001600160a01b031690632f4f21e290604401600060405180830381600087803b15801561084e57600080fd5b505af1158015610862573d6000803e3d6000fd5b505050505b50505050565b6000806006848154811061088357610883612902565b600091825260208083208784526007825260408085206001600160a01b0389168652909252908320600992909202016004810154600682015491945091929060ff166109395783546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015610910573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109349190612918565b6109ab565b60068401546040516370a0823160e01b81523060048201526101009091046001600160a01b0316906370a0823190602401602060405180830381865afa158015610987573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ab9190612918565b90508360030154421180156109bf57508015155b15610a225760006109d485600301544261058d565b905060006109fb6008546109f5886002015485611cae90919063ffffffff16565b90611cba565b9050610a1d610a16846109f584670de0b6b3a7640000611cae565b8590611cc6565b935050505b610a538360010154610a4d670de0b6b3a76400006109f5868860000154611cae90919063ffffffff16565b90611c9b565b979650505050505050565b6001546001600160a01b03163314610a915760405162461bcd60e51b8152600401610a889061294e565b60405180910390fd5b610a99611175565b600060068481548110610aae57610aae612902565b9060005260206000209060090201905060c88210610acb57600080fd5b60018101829055600581015460ff1615610b2057610b0283610afc8360020154600854611c9b90919063ffffffff16565b90611cc6565b6008908155810154600b54610b1c918591610afc91611c9b565b600b555b60028101839055600801919091555050565b610b3a611cd2565b6000339050600060068481548110610b5457610b54612902565b600091825260208083208784526007825260408085206001600160a01b03881686529092529220805460099092029092019250841115610bcb5760405162461bcd60e51b81526020600482015260126024820152711dda5d1a191c985dce881b9bdd0819dbdbd960721b6044820152606401610a88565b610bd485611d2b565b610bdd85610652565b6000610c0e8260010154610a4d670de0b6b3a76400006109f587600401548760000154611cae90919063ffffffff16565b90508015610c6457610c208482611f28565b836001600160a01b03167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e048682604051610c5b91815260200190565b60405180910390a25b8415610c98578154610c769086611c9b565b8255610c828686611fd3565b8254610c98906001600160a01b03168587612068565b60048301548254610cb691670de0b6b3a7640000916109f591611cae565b600183015560405185815286906001600160a01b038616907ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b5689060200160405180910390a350505050610d096001600055565b5050565b6001546001600160a01b03163314610d375760405162461bcd60e51b8152600401610a889061294e565b600354600680546000926001600160a01b031691632045be909185908110610d6157610d61612902565b600091825260209091206009909102015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602401602060405180830381865afa158015610db6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dda91906129a0565b90506001600160a01b03811615610d095760408051600180825281830190925260009160208083019080368337505060045482519293506001600160a01b031691839150600090610e2d57610e2d612902565b60200260200101906001600160a01b031690816001600160a01b0316815250506040518060600160405280600115158152602001836001600160a01b031681526020018281525060068481548110610e8757610e87612902565b60009182526020918290208351600660099093029091019182018054858501516001600160a01b031661010002610100600160a81b0319931515939093166001600160a81b031990911617919091178155604084015180519193610ef19360070192910190612401565b505050505050565b610f01611cd2565b600060068281548110610f1657610f16612902565b600091825260208083208584526007825260408085203386529092529220805460099092029092019250610f4a8482611fd3565b600080835560018301558254610f6a906001600160a01b03163383612068565b604051818152849033907fbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae05959060200160405180910390a3505050610fae6001600055565b50565b6001546001600160a01b03163314610fdb5760405162461bcd60e51b8152600401610a889061294e565b60065460005b8181101561108b57600060068281548110610ffe57610ffe612902565b6000918252602090912060099091020180549091506001600160a01b03908116908716036110825760405162461bcd60e51b815260206004820152602b60248201527f5368617265526577617264506f6f6c3a20546f6b656e2063616e6e6f7420626560448201526a103837b7b6103a37b5b2b760a91b6064820152608401610a88565b50600101610fe1565b506108676001600160a01b0385168385612068565b6001546001600160a01b031633146110ca5760405162461bcd60e51b8152600401610a889061294e565b86851480156110d857508683145b6110f45760405162461bcd60e51b8152600401610a88906129d3565b60005b8781101561116a5761116289898381811061111457611114612902565b9050602002013588888481811061112d5761112d612902565b9050602002013587878581811061114657611146612902565b905060200201602081019061115b919061283f565b8686611269565b6001016110f7565b505050505050505050565b60065460005b81811015610d095761118c81611d2b565b61119581610652565b60010161117b565b6001546001600160a01b031633146111c75760405162461bcd60e51b8152600401610a889061294e565b6000600684815481106111dc576111dc612902565b60009182526020909120600990910201600681015490915060ff166112545760405162461bcd60e51b815260206004820152602860248201527f536e616b6547656e65736973526577617264506f6f6c3a206e6f7420612067616044820152671d59d9481c1bdbdb60c21b6064820152608401610a88565b611262600782018484612466565b5050505050565b6001546001600160a01b031633146112935760405162461bcd60e51b8152600401610a889061294e565b61129c836120cb565b81156112aa576112aa611175565b6009544210156112d957806000036112c557506009546112ed565b6009548110156112d457506009545b6112ed565b8015806112e557504281105b156112ed5750425b6000600954821115806113005750428211155b6040805160018082528183019092529192506000919060208083019080368337505060045482519293506001600160a01b03169183915060009061134657611346612902565b60200260200101906001600160a01b031690816001600160a01b0316815250506006604051806101000160405280876001600160a01b03168152602001888152602001898152602001858152602001600081526020018415158152602001604051806060016040528060001515815260200160006001600160a01b0316815260200185815250815260200189815250908060018154018082558091505060019003906000526020600020906009020160009091909190915060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506020820151816001015560408201518160020155606082015181600301556080820151816004015560a08201518160050160006101000a81548160ff02191690831515021790555060c08201518160060160008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a8154816001600160a01b0302191690836001600160a01b0316021790555060408201518160010190805190602001906114e5929190612401565b50505060e09190910151600890910155600654611508906102de90600190612a2f565b811561152f5760085461151b9088611cc6565b600855600b5461152b9088611cc6565b600b555b50505050505050565b60006006828154811061154d5761154d612902565b60009182526020909120600990910201600681015490915060ff1615610d0957600781015415610d0957600781015460009067ffffffffffffffff811115611597576115976129bd565b6040519080825280602002602001820160405280156115c0578160200160208202803683370190505b50905060005b600783015481101561168257600783018054829081106115e8576115e8612902565b6000918252602090912001546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015611639573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061165d9190612918565b82828151811061166f5761166f612902565b60209081029190910101526001016115c6565b5060408051600180825281830190925260009160208083019080368337019050506006840154815191925061010090046001600160a01b03169082906000906116cd576116cd612902565b6001600160a01b039290921660209283029190910190910152604080516001808252818301909252600091816020015b60608152602001906001900390816116fd5750506007850180546040805160208084028201810190925282815293945083018282801561176657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611748575b50505050508160008151811061177e5761177e612902565b60209081029190910101526003546040516320b1cb6f60e01b81526001600160a01b03909116906320b1cb6f906117bb9085908590600401612a42565b600060405180830381600087803b1580156117d557600080fd5b505af11580156117e9573d6000803e3d6000fd5b5050505060005b6007850154811015610ef157600085600601600101828154811061181657611816612902565b60009182526020822001546040516370a0823160e01b81523060048201526001600160a01b03909116925082906370a0823190602401602060405180830381865afa158015611869573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061188d9190612918565b905060008684815181106118a3576118a3612902565b6020026020010151826118b69190612a2f565b905080156118d8576005546118d8906001600160a01b03858116911683612068565b5050506001016117f0565b6001546001600160a01b0316331461190d5760405162461bcd60e51b8152600401610a889061294e565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b8082111561198d5760405162461bcd60e51b815260206004820152602560248201527f536e616b6547656e65736973526577617264506f6f6c3a20696e76616c69642060448201526472616e676560d81b6064820152608401610a88565b815b8181116119b85761199f81611d2b565b6119a881610652565b6119b181612aed565b905061198f565b505050565b6001546001600160a01b031633146119e75760405162461bcd60e51b8152600401610a889061294e565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b611a11611cd2565b6000339050600060068481548110611a2b57611a2b612902565b600091825260208083208784526007825260408085206001600160a01b0388168652909252922060099091029091019150611a6585611d2b565b805415611af5576000611a9d8260010154610a4d670de0b6b3a76400006109f587600401548760000154611cae90919063ffffffff16565b90508015611af357611aaf8482611f28565b836001600160a01b03167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e048682604051611aea91815260200190565b60405180910390a25b505b8315611b68578154611b12906001600160a01b0316843087612174565b6000611b316127106109f5856001015488611cae90919063ffffffff16565b9050611b48611b408683611c9b565b835490611cc6565b82556005548354611b66916001600160a01b03918216911683612068565b505b611b7185610652565b60048201548154611b8f91670de0b6b3a7640000916109f591611cae565b600182015560405184815285906001600160a01b038516907f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a159060200160405180910390a3505050610d096001600055565b6001546001600160a01b03163314611c0b5760405162461bcd60e51b8152600401610a889061294e565b8483148015611c1957508481145b611c355760405162461bcd60e51b8152600401610a88906129d3565b60005b8581101561152f57611c93878783818110611c5557611c55612902565b90506020020135868684818110611c6e57611c6e612902565b90506020020135858585818110611c8757611c87612902565b90506020020135610a5e565b600101611c38565b6000611ca78284612a2f565b9392505050565b6000611ca78284612b06565b6000611ca78284612b1d565b6000611ca78284612b3f565b600260005403611d245760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610a88565b6002600055565b611d3481610652565b600060068281548110611d4957611d49612902565b9060005260206000209060090201905080600301544211611d68575050565b600681015460009060ff16611de75781546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015611dbe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611de29190612918565b611e59565b60068201546040516370a0823160e01b81523060048201526101009091046001600160a01b0316906370a0823190602401602060405180830381865afa158015611e35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e599190612918565b905080600003611e6e57504260039091015550565b600582015460ff16611eb25760058201805460ff191660011790556002820154600854611e9a91611cc6565b6008908155820154600b54611eae91611cc6565b600b555b60085415611f19576000611eca83600301544261058d565b90506000611eeb6008546109f5866002015485611cae90919063ffffffff16565b9050611f11611f06846109f584670de0b6b3a7640000611cae565b600486015490611cc6565b600485015550505b4260038301556119b883611538565b6002546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015611f71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f959190612918565b905080156119b85780821115611fbc576002546119b8906001600160a01b03168483612068565b6002546119b8906001600160a01b03168484612068565b600060068381548110611fe857611fe8612902565b60009182526020909120600990910201600681015490915060ff16156119b8576006810154604051632e1a7d4d60e01b8152600481018490526101009091046001600160a01b031690632e1a7d4d90602401600060405180830381600087803b15801561205457600080fd5b505af115801561152f573d6000803e3d6000fd5b6040516001600160a01b0383166024820152604481018290526119b890849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526121ac565b60065460005b818110156119b857826001600160a01b0316600682815481106120f6576120f6612902565b60009182526020909120600990910201546001600160a01b03160361216c5760405162461bcd60e51b815260206004820152602660248201527f536e616b6547656e65736973526577617264506f6f6c3a206578697374696e6760448201526520706f6f6c3f60d01b6064820152608401610a88565b6001016120d1565b6040516001600160a01b03808516602483015283166044820152606481018290526108679085906323b872dd60e01b90608401612094565b6000612201826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166122819092919063ffffffff16565b90508051600014806122225750808060200190518101906122229190612931565b6119b85760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610a88565b60606122908484600085612298565b949350505050565b6060824710156122f95760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610a88565b600080866001600160a01b031685876040516123159190612b76565b60006040518083038185875af1925050503d8060008114612352576040519150601f19603f3d011682016040523d82523d6000602084013e612357565b606091505b5091509150610a5387838387606083156123d25782516000036123cb576001600160a01b0385163b6123cb5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610a88565b5081612290565b61229083838151156123e75781518083602001fd5b8060405162461bcd60e51b8152600401610a889190612b92565b828054828255906000526020600020908101928215612456579160200282015b8281111561245657825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190612421565b506124629291506124b9565b5090565b828054828255906000526020600020908101928215612456579160200282015b828111156124565781546001600160a01b0319166001600160a01b03843516178255602090920191600190910190612486565b5b8082111561246257600081556001016124ba565b6000602082840312156124e057600080fd5b5035919050565b600081518084526020840193506020830160005b828110156125225781516001600160a01b03168652602095860195909101906001016124fb565b5093949350505050565b60018060a01b038916815287602082015286604082015285606082015284608082015283151560a082015261010060c08201528251151561010082015260018060a01b036020840151166101208201526000604084015160606101408401526125996101608401826124e7565b9150508260e08301529998505050505050505050565b600080604083850312156125c257600080fd5b50508035926020909101359150565b6001600160a01b0381168114610fae57600080fd5b600080604083850312156125f957600080fd5b82359150602083013561260b816125d1565b809150509250929050565b60008060006060848603121561262b57600080fd5b505081359360208301359350604090920135919050565b60008060006060848603121561265757600080fd5b8335612662816125d1565b9250602084013591506040840135612679816125d1565b809150509250925092565b60008083601f84011261269657600080fd5b50813567ffffffffffffffff8111156126ae57600080fd5b6020830191508360208260051b85010111156126c957600080fd5b9250929050565b8015158114610fae57600080fd5b60008060008060008060008060a0898b0312156126fa57600080fd5b883567ffffffffffffffff81111561271157600080fd5b61271d8b828c01612684565b909950975050602089013567ffffffffffffffff81111561273d57600080fd5b6127498b828c01612684565b909750955050604089013567ffffffffffffffff81111561276957600080fd5b6127758b828c01612684565b9095509350506060890135612789816126d0565b979a9699509497939692959194509192608001359150565b6000806000604084860312156127b657600080fd5b83359250602084013567ffffffffffffffff8111156127d457600080fd5b6127e086828701612684565b9497909650939450505050565b600080600080600060a0868803121561280557600080fd5b8535945060208601359350604086013561281e816125d1565b9250606086013561282e816126d0565b949793965091946080013592915050565b60006020828403121561285157600080fd5b8135611ca7816125d1565b6000806000806000806060878903121561287557600080fd5b863567ffffffffffffffff81111561288c57600080fd5b61289889828a01612684565b909750955050602087013567ffffffffffffffff8111156128b857600080fd5b6128c489828a01612684565b909550935050604087013567ffffffffffffffff8111156128e457600080fd5b6128f089828a01612684565b979a9699509497509295939492505050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561292a57600080fd5b5051919050565b60006020828403121561294357600080fd5b8151611ca7816126d0565b60208082526032908201527f536e616b6547656e65736973526577617264506f6f6c3a2063616c6c6572206960408201527139903737ba103a34329037b832b930ba37b960711b606082015260800190565b6000602082840312156129b257600080fd5b8151611ca7816125d1565b634e487b7160e01b600052604160045260246000fd5b60208082526026908201527f536e616b6547656e65736973526577617264506f6f6c3a20696e76616c6964206040820152650d8cadccee8d60d31b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b8181038181111561064c5761064c612a19565b6040808252835190820181905260009060208501906060840190835b81811015612a855783516001600160a01b0316835260209384019390920191600101612a5e565b50508381036020850152809150845180825260208201925060208160051b8301016020870160005b83811015612adf57601f19858403018652612ac98383516124e7565b6020968701969093509190910190600101612aad565b509098975050505050505050565b600060018201612aff57612aff612a19565b5060010190565b808202811582820484141761064c5761064c612a19565b600082612b3a57634e487b7160e01b600052601260045260246000fd5b500490565b8082018082111561064c5761064c612a19565b60005b83811015612b6d578181015183820152602001612b55565b50506000910152565b60008251612b88818460208701612b52565b9190910192915050565b6020815260008251806020840152612bb1816040850160208701612b52565b601f01601f1916919091016040019291505056fea2646970667358221220adb4bd64e4c708ecaafb583fa43987b5fc06c7f41563e494d0092997a18fd48564736f6c634300081a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000003a516e01f82c1e18916ed69a81dd498ef64bb157000000000000000000000000a906b773bf4e1f5c668eedeed06aa8917057ea7d0000000000000000000000000000000000000000000000000000000067a79ba00000000000000000000000003af1dd7a2755201f8e2d6dcda1a61d9f54838f4f
-----Decoded View---------------
Arg [0] : _snake (address): 0x3a516e01f82c1e18916ED69a81Dd498eF64bB157
Arg [1] : _bribesSafe (address): 0xa906B773bf4E1F5C668EeDEed06aa8917057eA7D
Arg [2] : _poolStartTime (uint256): 1739037600
Arg [3] : _voter (address): 0x3aF1dD7A2755201F8e2D6dCDA1a61d9f54838f4f
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000003a516e01f82c1e18916ed69a81dd498ef64bb157
Arg [1] : 000000000000000000000000a906b773bf4e1f5c668eedeed06aa8917057ea7d
Arg [2] : 0000000000000000000000000000000000000000000000000000000067a79ba0
Arg [3] : 0000000000000000000000003af1dd7a2755201f8e2d6dcda1a61d9f54838f4f
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$16.13
Net Worth in S
Token Allocations
WETH
36.76%
USDC
32.18%
STS
16.87%
Others
14.18%
Multichain Portfolio | 32 Chains
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ 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.