Contract Overview
Balance:
0 FTM
FTM Value:
$0.00
My Name Tag:
Not Available, login to update
Txn Hash | Method |
Block
|
From
|
To
|
Value | [Txn Fee] | |||
---|---|---|---|---|---|---|---|---|---|
0xc35a9d865f0cf993633120d8ae7ea37d85cbb16cfb03b0ee33c665db1eb1de5c | 0x60806040 | 57873401 | 5 days 1 min ago | 0x5c146cd18fa53914580573c9b9604588529406ca | IN | Create: GaugeFactory | 0 FTM | 0.457557675 |
[ Download CSV Export ]
Latest 13 internal transactions
[ Download CSV Export ]
Contract Name:
GaugeFactory
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity)
/** *Submitted for verification at FtmScan.com on 2023-03-18 */ /** * EQUALIZER EXCHANGE * The New Liquidity Hub of Fantom chain! * https://equalizer.exchange (Dapp) * https://discord.gg/MaMhbgHMby (Community) * * * Version: 1.5.1 * - Backwards-compatibility with version < v1.4.0 * - periodFinish(<token>) * - rewardRate(<token>) * - lastUpdateTime(<token>) * - _ve() * - "Enhanced" Taxable Fee-Claims (This is NOT deposit/withdraw fee!) * - Ability to introduce Protocol Fees * * * Version: 1.5.0 * - Remove the "checkpoint" system * - Remove "Proxy pattern" construction * - Remove Pausable contract (Removes inheritance from Owned contract) * - MultiRewards Gauge with per-token variable epoch-lengths (default: 7 days) * - Supports Rewarding with Transfer-fee tokens * - Supports Deposits/Withdraws of tokens with Transfer-fee * - Support for LP Bribes * - Voter.team() can enable a new Reward token, which can be added by anyone as a reward thereafter * - Base Equal token default with a single-token reward config over 7 days * - Taxable Fee-Claims (This is NOT deposit/withdraw fee!) * - Ability to fund multiple Bribes at once * - Ability to channel funds from 'claimFees' into some other contracts * - Support for new LP types: * - 2pool/3pool/4pool: Curve-style Stable Pools & Crypto Pools * - Upto 8-token weighted, stable, meta-boosted & meta-stable Balancer-style pools * - Wrapped Concentrated Liquidity fungible pools (ERC1155) * - "Enhanced" Griefing Protection Enabled for Unknown reward adders * - Voter & Distributor can notify rewards freely without any restrictions * - Choice of validation between best of SNX method (rewardRate not lower) or CRV method (more than left) * - Remove "Boosted" rewards * - No concept of derivedBalances * - No veNFT attachments/detachments upon deposits/withdrawals * - totalBribePayouts to replace fee0 & fees1 to support multi-token accounting of claimed fees * - Introduce the concept of `bribeTokens` to help facilitate bribes from non-standard multi-token pools * - Upgradable Reward-distribution Durations * - Remove concept of MAX_REWARD_TOKENS * - Only ve.team() can `addReward()` new tokens * * * Version: 1.4.0 * - Remove the whole concept of Internal Bribes (Trade Fees Streamer). * - Each deposit/withdraw/getReward also calls claimFees * - Allow to notifyRewards to Bribe without the fear of griefing * - Time-dilution of reward APR by extending periodFinish is not possible * - Bribes are paid as a lumpsum. Trade Fees are treated as External Bribes. * - Repurpose usage of fees0 & fees1 as indicators of net revenue of a gauge * - Allow overriding fee receipient (like ABcDeFX) by Voter.team() * - Voter.team() can siphon out unclaimed rewards. * - The deposited "stake" tokens (user funds) cannot be rescued. (No Rugs!) * - Only the Reward tokens can be rescue()'d. * - Useful in cases of non-official/external/independent gauges * - Especially in cases where "stake"d tokens have their own claimFees(). * * * * * Contributors: * - Synthetix Network * - Curve Finance * - Andre Cronje, Fantom & Solidly.Exchange * - 543 (Sam), ftm.guru & Equalizer.exchange * * * SPDX-License-Identifier: UNLICENSED */ pragma solidity 0.8.9; // File: contracts/interfaces/IGaugeFactory.sol interface IGaugeFactory { function createGauge(address, address, address, bool, address[] memory) external returns (address); } // File: contracts/interfaces/IVotingEscrow.sol interface IVotingEscrow { struct Point { int128 bias; int128 slope; // # -dweight / dt uint256 ts; uint256 blk; // block } function token() external view returns (address); function team() external returns (address); function epoch() external view returns (uint); function point_history(uint loc) external view returns (Point memory); function user_point_history(uint tokenId, uint loc) external view returns (Point memory); function user_point_epoch(uint tokenId) external view returns (uint); function ownerOf(uint) external view returns (address); function isApprovedOrOwner(address, uint) external view returns (bool); function transferFrom(address, address, uint) external; function voting(uint tokenId) external; function abstain(uint tokenId) external; function attach(uint tokenId) external; function detach(uint tokenId) external; function checkpoint() external; function deposit_for(uint tokenId, uint value) external; function create_lock_for(uint, uint, address) external returns (uint); function balanceOfNFT(uint) external view returns (uint); function totalSupply() external view returns (uint); } // File: contracts/interfaces/IVoter.sol interface IVoter { function _ve() external view returns (address); function governor() external view returns (address); function emergencyCouncil() external view returns (address); function protocolFeesTaker() external view returns (address); function attachTokenToGauge(uint _tokenId, address account) external; function attachable() external view returns (bool); function protocolFeesPerMillion() external view returns (uint); function detachTokenFromGauge(uint _tokenId, address account) external; function emitDeposit(uint _tokenId, address account, uint amount) external; function emitWithdraw(uint _tokenId, address account, uint amount) external; function isWhitelisted(address token) external view returns (bool); function notifyRewardAmount(uint amount) external; function distribute(address _gauge) external; } // File: contracts/interfaces/IPair.sol interface IPair { function metadata() external view returns (uint dec0, uint dec1, uint r0, uint r1, bool st, address t0, address t1); function claimFees() external returns (uint, uint); function tokens() external returns (address, address); function transferFrom(address src, address dst, uint amount) external returns (bool); function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external; function burn(address to) external returns (uint amount0, uint amount1); function mint(address to) external returns (uint liquidity); function getReserves() external view returns (uint _reserve0, uint _reserve1, uint _blockTimestampLast); function getAmountOut(uint, address) external view returns (uint); } // File: contracts/interfaces/IERC20.sol interface IERC20 { function totalSupply() external view returns (uint256); function transfer(address recipient, uint amount) external returns (bool); function decimals() external view returns (uint8); function symbol() external view returns (string memory); function balanceOf(address) external view returns (uint); function transferFrom(address sender, address recipient, uint amount) external returns (bool); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); event Transfer(address indexed from, address indexed to, uint value); event Approval(address indexed owner, address indexed spender, uint value); } // File: contracts/interfaces/IBribe.sol interface IBribe { function _deposit(uint amount, uint tokenId) external; function _withdraw(uint amount, uint tokenId) external; function getRewardForOwner(uint tokenId, address[] memory tokens) external; function notifyRewardAmount(address token, uint amount) external; function left(address token) external view returns (uint); function rewardsListLength() external view returns (uint); function rewards(uint) external view returns (address); } library Address { /** * @dev Returns true if `account` is a contract. * * This test is non-exhaustive, and there may be false-negatives: during the * execution of a contract's constructor, its address will be reported as * not containing a contract. * * > It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. */ function isContract(address account) internal view returns (bool) { // This method relies in extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } } library Math { /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow, so we distribute return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2); } } contract ReentrancyGuard { /// @dev counter to allow mutex lock with only one SSTORE operation uint256 private _guardCounter; constructor () { // The counter starts at one to prevent changing it from zero to a non-zero // value, which is a more expensive operation. _guardCounter = 1; } /** * @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 make it call a * `private` function that does the actual work. */ modifier nonReentrant() { _guardCounter += 1; uint256 localCounter = _guardCounter; _; require(localCounter == _guardCounter, "ReentrancyGuard: reentrant call"); } } library SafeERC20 { using SafeMath for uint256; using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } 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' // solhint-disable-next-line max-line-length 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)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value); callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } /** * @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. // A Solidity high level call has three parts: // 1. The target address is checked to verify it contains contract code // 2. The call itself is made, and success asserted // 3. The return value is decoded, which in turn checks the size of the returned data. // solhint-disable-next-line max-line-length require(address(token).isContract(), "SafeERC20: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = address(token).call(data); require(success, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } library SafeMath { /** * @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) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @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) { require(b <= a, "SafeMath: subtraction overflow"); uint256 c = a - b; return c; } /** * @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) { // 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-solidity/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts 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) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, "SafeMath: division by zero"); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts 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) { require(b != 0, "SafeMath: modulo by zero"); return a % b; } } contract GaugeEquivalent is ReentrancyGuard { using SafeMath for uint256; using SafeERC20 for IERC20; /* ========== STATE VARIABLES ========== */ struct Reward { address rewardsDistributor; uint256 rewardsDuration; uint256 periodFinish; uint256 rewardRate; uint256 lastUpdateTime; uint256 rewardPerTokenStored; } bool public paused; IERC20 public stake; mapping(address => Reward) public rewardData; address[] public rewardTokens; address[] public bribeTokens; // user -> reward token -> amount mapping(address => mapping(address => uint256)) public userRewardPerTokenPaid; mapping(address => mapping(address => uint256)) public rewards; mapping(address => bool) public isReward; mapping(address => bool) public isBribeToken; uint256 private _totalSupply; mapping(address => uint256) private _balances; IBribe public bribe; IVotingEscrow public ve; IVoter public voter; bool public isForPair; address public feeTaker; mapping(address => uint) public payouts; mapping(address => uint) public payoutsNotified; mapping(address => mapping(address => uint)) public earnings; mapping(address => uint) public totalFeesPayouts; /* ========== CONSTRUCTOR ========== */ constructor( address _stake, address _ebribe, address __ve, address _voter, bool _forPair, address[] memory _allowedRewardTokens ) { stake = IERC20(_stake); bribe = IBribe(_ebribe); ve = IVotingEscrow(__ve); voter = IVoter(_voter); isForPair = _forPair; for (uint i; i < _allowedRewardTokens.length; i++) { if (_allowedRewardTokens[i] != address(0)) { isReward[_allowedRewardTokens[i]] = true; rewardTokens.push(_allowedRewardTokens[i]); rewardData[_allowedRewardTokens[i]].rewardsDistributor = _voter; rewardData[_allowedRewardTokens[i]].rewardsDuration = 7 days; } } if(_forPair) { //claimFees : Bribe Rewards //Pre-approve to save gas, since both Bribe & Gauge are immutable (address _token0, address _token1) = IPair(_stake).tokens(); IERC20(_token0).approve(_ebribe, type(uint256).max); IERC20(_token1).approve(_ebribe, type(uint256).max); bribeTokens.push(_token0); bribeTokens.push(_token1); isBribeToken[_token0] = true; isBribeToken[_token1] = true; emit BribeTokenSet(_token0, _ebribe, true); emit BribeTokenSet(_token1, _ebribe, true); } ///else ve.team() must manually `addBribeTokens()` } /* ========== VIEWS ========== */ function totalSupply() external view returns (uint256) { return _totalSupply; } function balanceOf(address account) external view returns (uint256) { return _balances[account]; } function lastTimeRewardApplicable(address _rewardsToken) public view returns (uint256) { return Math.min(block.timestamp, rewardData[_rewardsToken].periodFinish); } function rewardPerToken(address _rewardsToken) public view returns (uint256) { if (_totalSupply == 0) { return rewardData[_rewardsToken].rewardPerTokenStored; } return rewardData[_rewardsToken].rewardPerTokenStored.add( lastTimeRewardApplicable(_rewardsToken).sub(rewardData[_rewardsToken].lastUpdateTime).mul(rewardData[_rewardsToken].rewardRate).mul(1e18).div(_totalSupply) ); } /// @param account 1 /// @param _rewardsToken 2 function earnedBy(address account, address _rewardsToken) public view returns (uint256) { return _balances[account].mul(rewardPerToken(_rewardsToken).sub(userRewardPerTokenPaid[account][_rewardsToken])).div(1e18).add(rewards[account][_rewardsToken]); } /// Backwards compatible view with 3qu471738 <= v1.3 /// @param _rewardsToken 1 /// @param account 2 function earned(address _rewardsToken, address account) public view returns (uint256) { return earnedBy(account, _rewardsToken); } function getRewardForDuration(address _rewardsToken) external view returns (uint256) { return rewardData[_rewardsToken].rewardRate.mul(rewardData[_rewardsToken].rewardsDuration); } function left(address _rewardsToken) external view returns (uint) { if (block.timestamp >= rewardData[_rewardsToken].periodFinish) return 0; uint256 remaining = rewardData[_rewardsToken].periodFinish.sub(block.timestamp); return remaining.mul(rewardData[_rewardsToken].rewardRate); } function rewardsListLength() external view returns (uint) { return rewardTokens.length; } function bribesListLength() external view returns (uint) { return bribeTokens.length; } /* ========== BACKWARDS-COMPATIBLE VIEW FUNCTIONS ========== */ function _ve() external view returns (address) { return address(ve); } function periodFinish(address _tkn) external view returns (uint) { return rewardData[_tkn].periodFinish; } function rewardRate(address _tkn) external view returns (uint) { return rewardData[_tkn].rewardRate; } function lastUpdateTime(address _tkn) external view returns (uint) { return rewardData[_tkn].lastUpdateTime; } /* ========== MUTATIVE FUNCTIONS ========== */ function setRewardsDistributor(address _rewardsToken, address _rewardsDistributor) external onlyOwner { rewardData[_rewardsToken].rewardsDistributor = _rewardsDistributor; } function deposit(uint256 amount) public nonReentrant notPaused updateReward(msg.sender) { require(amount > 0, "Cannot stake 0"); _totalSupply = _totalSupply.add(amount); _balances[msg.sender] = _balances[msg.sender].add(amount); stake.safeTransferFrom(msg.sender, address(this), amount); emit Deposit(msg.sender, amount); _claimFees(); } function depositFor(address _user, uint256 amount) public nonReentrant notPaused updateReward(_user) { require(amount > 0, "Cannot stake 0"); _totalSupply = _totalSupply.add(amount); _balances[_user] = _balances[_user].add(amount); stake.safeTransferFrom(msg.sender, address(this), amount); emit Deposit(_user, amount); _claimFees(); } function depositAll() external { deposit(stake.balanceOf(msg.sender)); } function depositAllFor(address _user) external { depositFor(_user, stake.balanceOf(msg.sender)); } function withdraw(uint256 amount) public nonReentrant updateReward(msg.sender) { require(amount > 0, "Cannot withdraw 0"); _totalSupply = _totalSupply.sub(amount); _balances[msg.sender] = _balances[msg.sender].sub(amount); stake.safeTransfer(msg.sender, amount); emit Withdrawn(msg.sender, amount); _claimFees(); } function withdrawAll() external { withdraw(_balances[msg.sender]); } function getReward() public nonReentrant updateReward(msg.sender) { for (uint i; i < rewardTokens.length; i++) { address _rewardsToken = rewardTokens[i]; uint256 _reward = rewards[msg.sender][_rewardsToken]; if (_reward > 0) { rewards[msg.sender][_rewardsToken] = 0; IERC20(_rewardsToken).safeTransfer(msg.sender, _reward); emit ClaimRewards(msg.sender, _rewardsToken, _reward); payouts[_rewardsToken] += _reward; earnings[msg.sender][_rewardsToken] += _reward; } } _claimFees(); } function _getReward(address account, address[] memory _tokens) internal nonReentrant updateReward(account) { for (uint i; i < _tokens.length; i++) { address _rewardsToken = _tokens[i]; uint256 _reward = rewards[account][_rewardsToken]; if (_reward > 0) { rewards[account][_rewardsToken] = 0; IERC20(_rewardsToken).safeTransfer(account, _reward); emit ClaimRewards(_rewardsToken, account, _reward); payouts[_rewardsToken] += _reward; earnings[account][_rewardsToken] += _reward; } } _claimFees(); } function getReward(address account, address[] memory tokens) external { require(msg.sender == account || msg.sender == address(voter), "Un-authorized claim!"); voter.distribute(address(this)); _getReward(account, tokens); } function exit() external { withdraw(_balances[msg.sender]); getReward(); } function notifyRewardAmount(address _rewardsToken, uint256 _reward) external nonReentrant updateReward(address(0)) { require(_rewardsToken != address(stake), "Can't distribute staked token as reward!"); require(isReward[_rewardsToken], "Not a reward!!" ); /// The old pattern to get force collection of fees at least once a week during emission distribution to this gauge /// & distribute it to voters over the next week via the (external) Bribe _claimFees(); /// Support feeOnTransfer tokens like ELITE etc. uint rtbb = IERC20(_rewardsToken).balanceOf(address(this)); // handle the transfer of reward tokens via `transferFrom` to reduce the number // of transactions required and ensure correctness of the reward amount IERC20(_rewardsToken).safeTransferFrom(msg.sender, address(this), _reward); uint rtba = IERC20(_rewardsToken).balanceOf(address(this)); _reward = rtba - rtbb; require(_reward > 0, "Reward amount must be greater than 0!"); if (block.timestamp >= rewardData[_rewardsToken].periodFinish) { rewardData[_rewardsToken].rewardRate = _reward.div(rewardData[_rewardsToken].rewardsDuration); } else { //Griefing Protection Enabled for Unknown reward adders uint _oldRewardRate = rewardData[_rewardsToken].rewardRate; uint256 remaining = rewardData[_rewardsToken].periodFinish.sub(block.timestamp); uint256 leftover = remaining.mul(rewardData[_rewardsToken].rewardRate); rewardData[_rewardsToken].rewardRate = _reward.add(leftover).div(rewardData[_rewardsToken].rewardsDuration); if( msg.sender!=address(voter) || msg.sender!=rewardData[_rewardsToken].rewardsDistributor ) { require( ( rewardData[_rewardsToken].rewardRate >= _oldRewardRate || _reward > leftover ), "Enhanced Griefing Protection Enabled!" ); } } rewardData[_rewardsToken].lastUpdateTime = block.timestamp; rewardData[_rewardsToken].periodFinish = block.timestamp.add(rewardData[_rewardsToken].rewardsDuration); emit RewardAdded(_rewardsToken, msg.sender, _reward); payoutsNotified[_rewardsToken] += _reward; } function claimFees() external nonReentrant returns (uint claimed0, uint claimed1) { return _claimFees(); } function _claimFees() internal returns (uint claimed0, uint claimed1) { uint _pfpm = voter.protocolFeesPerMillion(); address _pft = _pfpm > 0 ? voter.protocolFeesTaker() : address(0); /// Equa7izer v1.5: Support Custom pools to be Gaugable if (!isForPair) { /// For non-official/external/independent gauges only /// If compatible, the claimed fees should be notified to Bribe /// Else, this contract will hold the fees & ve.team() can rescue() uint _bn = bribeTokens.length; IERC20[] memory _brews = new IERC20[](_bn); uint[] memory _brewbals = new uint[](_bn); for(uint _n; _n < _bn; _n++) { _brews[_n] = IERC20( bribeTokens[_n] ); /// Record current balance to protect gauge deposits & rewards. /// Also Support feeOnTransfer tokens like ELITE etc. /// Also makes sure a bribe-reward isnt 'killed' or uninitialized. _brewbals[_n] = address(_brews[_n]) == address(0) ? 0 : _brews[_n].balanceOf(address(this)); } try IPair(address(stake)).claimFees() { /// if call succeeds, gauge will have a surplus of extra tokens which can be sent to bribes /// useful in cases of non-equa1izer lps, like conc., weighted or multi-token Liquidity pools for(uint _n = 0; _n < _bn; _n++) { /// Don't trigger bribes for 0x00 rewards uint _a = address(_brews[_n]) == address(0) ? 0 : _brews[_n].balanceOf(address(this)); /// Trigger only when a token balance increases when we try IPair(stake).claimFees() /// because there could possibly be an overlap between rewardTokens & bribeTokens if(_a > _brewbals[_n]) { ///Protocol Fees if( ( (_a - _brewbals[_n]) * _pfpm) / 1e6 > 0) { _brews[_n].transfer(_pft, ( (_a.sub(_brewbals[_n])) * _pfpm) / 1e6 ); emit ProtocolFees(msg.sender,_pft,address(_brews[_n]),((_a.sub(_brewbals[_n])) * _pfpm) / 1e6); _a = _brews[_n].balanceOf(address(this)); } ///Normal Fees -> Bribe if (feeTaker == address(0)) { bribe.notifyRewardAmount( address(_brews[_n]), (_a.sub(_brewbals[_n])) ); emit ClaimFees(msg.sender, address(bribe), address(_brews[_n]), (_a - _brewbals[_n]) ); totalFeesPayouts[ address(_brews[_n]) ] += (_a - _brewbals[_n]); } ///Re-channeled Fees -> FeesTaker else { _brews[_n].transfer(feeTaker, (_a.sub(_brewbals[_n])) ); emit ClaimFees(msg.sender, feeTaker, address(_brews[_n]), (_a - _brewbals[_n]) ); totalFeesPayouts[ address(_brews[_n]) ] += (_a - _brewbals[_n]); } } /// else: we dont have any fees here ser! } return (0, 0); } catch { /// if call fails, do nothing (much). return (0, 0); } } //else: /// For actual Protocol gauges, created by Voter, for E9ua1izer Factory Pairs (address _token0, address _token1) = IPair(address(stake)).tokens(); /// Support feeOnTransfer tokens like ELITE etc. uint t0bb = IERC20(_token0).balanceOf(address(this)); uint t1bb = IERC20(_token1).balanceOf(address(this)); //(claimed0, claimed1) = IPair(address(stake)).claimFees(); claimed0 = IERC20(_token0).balanceOf(address(this)) - t0bb; claimed1 = IERC20(_token1).balanceOf(address(this)) - t1bb; //claimed0 = t0ba - t0bb; //claimed1 = t1ba - t1bb; ///ProtocolFees if( ( claimed0 * _pfpm) / 1e6 > 0) { IERC20(_token0).transfer(_pft, (claimed0*_pfpm)/1e6 ); emit ProtocolFees(msg.sender,_token0,_pft,(claimed0*_pfpm)/1e6); claimed0 = IERC20(_token0).balanceOf(address(this)).sub(t0bb); } if( ( claimed1 * _pfpm) / 1e6 > 0) { IERC20(_token1).transfer(_pft, (claimed1*_pfpm)/1e6 ); emit ProtocolFees(msg.sender,_token1,_pft,(claimed1*_pfpm)/1e6); claimed1 = IERC20(_token1).balanceOf(address(this)).sub(t1bb); } ///Normal Fees -> Bribe if (feeTaker == address(0)) { if (claimed0 > 0) { bribe.notifyRewardAmount(_token0, claimed0); totalFeesPayouts[ _token0 ] += claimed0; // stores total token0 fees claimed since genesis emit ClaimFees(msg.sender, feeTaker, _token0, claimed0); } if (claimed1 > 0) { bribe.notifyRewardAmount(_token1, claimed1); totalFeesPayouts[ _token1 ] += claimed1; // stores total token1 fees claimed since genesis emit ClaimFees(msg.sender, feeTaker, _token1, claimed1); } } ///Re-channeled Fees -> FeesTaker else { IERC20(_token0).transfer(feeTaker, claimed0); IERC20(_token1).transfer(feeTaker, claimed1); emit ClaimFees(msg.sender, feeTaker, _token0, claimed0); emit ClaimFees(msg.sender, feeTaker, _token1, claimed1); totalFeesPayouts[ _token0 ] += claimed0; // stores total token0 fees claimed since genesis totalFeesPayouts[ _token1 ] += claimed1; // stores total token1 fees claimed since genesis } return (claimed0, claimed1); } /* ========== RESTRICTED FUNCTIONS ========== */ function addReward(address _rewardsToken, address _rewardsDistributor, uint256 _rewardsDuration) public onlyOwner { require( isReward[_rewardsToken] == false && rewardData[_rewardsToken].rewardsDuration == 0 , "Already Initialized!" ); require( _rewardsToken != address(stake), "Cannot reward staking token!"); rewardTokens.push(_rewardsToken); isReward[_rewardsToken] = true; rewardData[_rewardsToken].rewardsDistributor = _rewardsDistributor; rewardData[_rewardsToken].rewardsDuration = _rewardsDuration; } /// This can break claims of rewards! /// Useful during a platform-wide upgrade (optional) function rescue(uint _amt, address _token, address _to) external onlyOwner { if(_token == address(stake)) { /// totalSupply marks the sum of all user deposits. /// surplus checks for any additional holdings that are not user-deposits /// Helps rescue of extra rewards from single-side same-token staking. uint _surplus = (stake.balanceOf(address(this))).sub(_totalSupply); require( _amt <= _surplus, "Rescuing User Deposits Prohibited!"); } IERC20(_token).transfer(_to, _amt); emit Recovered(_token, _amt); } function setRewardsDuration(address _rewardsToken, uint256 _rewardsDuration) external onlyOwner { require( block.timestamp > rewardData[_rewardsToken].periodFinish, "Reward period still active" ); require(_rewardsDuration > 0, "Reward duration must be non-zero"); rewardData[_rewardsToken].rewardsDuration = _rewardsDuration; emit RewardsDurationUpdated(_rewardsToken, rewardData[_rewardsToken].rewardsDuration); } function addBribeToken(address _t) public onlyOwner { require(isBribeToken[_t] == false, "Bribe Token Active!"); require( _t != address(stake), "Cannot bribe staking token!"); IERC20(_t).approve(address(bribe), type(uint256).max); bribeTokens.push(_t); isBribeToken[_t] = true; emit BribeTokenSet(_t, address(bribe), true); } function removeBribeToken(address _t) public onlyOwner { require(isBribeToken[_t] == true, "Bribe Token Inactive!"); IERC20(_t).approve(address(bribe), 0); uint _bl = bribeTokens.length; if(bribeTokens[_bl-1]==_t) { bribeTokens.pop(); isBribeToken[_t] = false; } else { for(uint i; i < bribeTokens.length - 1; i++) { if(bribeTokens[i]==_t) { bribeTokens[i] = bribeTokens[_bl-1]; bribeTokens.pop(); isBribeToken[_t] = false; } } } emit BribeTokenSet(_t, address(bribe), false); } function addBribeTokens(address[] memory _tks) external onlyOwner { for(uint _j; _j < _tks.length; _j++) { addBribeToken(_tks[_j]); } } function removeBribeTokens(address[] memory _tks) external onlyOwner { for(uint _j; _j < _tks.length; _j++) { removeBribeToken(_tks[_j]); } } /// When feeTaker is set, all Fees Claims go to it instead of going to the Bribe. /// Useful during a platform-wide upgrade (optional) function setFeeTaker(address _ft) external onlyOwner { feeTaker = _ft; } function setPaused(bool _b) external onlyOwner { paused = _b; } /* ========== MODIFIERS ========== */ modifier updateReward(address account) { for (uint i; i < rewardTokens.length; i++) { address token = rewardTokens[i]; rewardData[token].rewardPerTokenStored = rewardPerToken(token); rewardData[token].lastUpdateTime = lastTimeRewardApplicable(token); if (account != address(0)) { rewards[account][token] = earnedBy(account, token); userRewardPerTokenPaid[account][token] = rewardData[token].rewardPerTokenStored; } } _; } modifier onlyOwner { require(msg.sender==ve.team(), "Only ve.team!"); _; } modifier notPaused { require(!paused, "Paused!"); _; } /* ========== EVENTS ========== */ event RewardAdded(address indexed token, address indexed notifier, uint256 reward); event Deposit(address indexed user, uint256 amount); event Withdrawn(address indexed user, uint256 amount); event ClaimRewards(address indexed token, address indexed user, uint256 reward); event RewardsDurationUpdated(address indexed token, uint256 newDuration); event Recovered(address indexed token, uint256 amount); event BribeTokenSet(address indexed token, address indexed bribe, bool indexed active); event ProtocolFees(address indexed initiator, address indexed taker, address indexed token, uint amount); event ClaimFees(address indexed initiator, address indexed bribe, address indexed token, uint amount); } // File: contracts/factories/GaugeFactory.sol contract GaugeFactory is IGaugeFactory { address public lastGauge; event GaugeCreated(address indexed maker, address indexed pool, address g, address b, address v, bool i, address[] a); function createGauge( address _pool, address _bribe, address _ve, bool isPair, address[] memory _allowedRewards ) external returns (address) { GaugeEquivalent gauge = new GaugeEquivalent( _pool, _bribe, _ve, msg.sender, isPair, _allowedRewards ); lastGauge = address(gauge); emit GaugeCreated(msg.sender, _pool, address(gauge), _bribe, _ve, isPair, _allowedRewards); return lastGauge; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"maker","type":"address"},{"indexed":true,"internalType":"address","name":"pool","type":"address"},{"indexed":false,"internalType":"address","name":"g","type":"address"},{"indexed":false,"internalType":"address","name":"b","type":"address"},{"indexed":false,"internalType":"address","name":"v","type":"address"},{"indexed":false,"internalType":"bool","name":"i","type":"bool"},{"indexed":false,"internalType":"address[]","name":"a","type":"address[]"}],"name":"GaugeCreated","type":"event"},{"inputs":[{"internalType":"address","name":"_pool","type":"address"},{"internalType":"address","name":"_bribe","type":"address"},{"internalType":"address","name":"_ve","type":"address"},{"internalType":"bool","name":"isPair","type":"bool"},{"internalType":"address[]","name":"_allowedRewards","type":"address[]"}],"name":"createGauge","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lastGauge","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50615813806100206000396000f3fe60806040523480156200001157600080fd5b50600436106200003a5760003560e01c80631ede5a8e146200003f578063b46d34651462000072575b600080fd5b62000056620000503660046200018d565b62000086565b6040516001600160a01b03909116815260200160405180910390f35b60005462000056906001600160a01b031681565b6000808686863387876040516200009d906200014c565b620000ae96959493929190620002f9565b604051809103906000f080158015620000cb573d6000803e3d6000fd5b50600080546001600160a01b0319166001600160a01b038381169190911790915560405191925088169033907eaba88e0f5bf7d92560ada0256f8eba87415938ce7b97f4f1d2fb68ee78c1d4906200012d9085908b908b908b908b906200034b565b60405180910390a350506000546001600160a01b031695945050505050565b615449806200039583390190565b80356001600160a01b03811681146200017257600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600080600080600060a08688031215620001a657600080fd5b620001b1866200015a565b94506020620001c28188016200015a565b9450620001d2604088016200015a565b935060608701358015158114620001e857600080fd5b9250608087013567ffffffffffffffff808211156200020657600080fd5b818901915089601f8301126200021b57600080fd5b81358181111562000230576200023062000177565b8060051b604051601f19603f8301168101818110858211171562000258576200025862000177565b60405291825284820192508381018501918c8311156200027757600080fd5b938501935b82851015620002a05762000290856200015a565b845293850193928501926200027c565b8096505050505050509295509295909350565b600081518084526020808501945080840160005b83811015620002ee5781516001600160a01b031687529582019590820190600101620002c7565b509495945050505050565b6001600160a01b0387811682528681166020830152858116604083015284166060820152821515608082015260c060a082018190526000906200033f90830184620002b3565b98975050505050505050565b6001600160a01b038681168252858116602083015284166040820152821515606082015260a0608082018190526000906200038990830184620002b3565b97965050505050505056fe60806040523480156200001157600080fd5b506040516200544938038062005449833981016040819052620000349162000527565b600160008181558154610100600160a81b0319166101006001600160a01b038a81169190910291909117909255600b80546001600160a01b031990811689851617909155600c8054909116878416179055600d80549286166001600160a81b031990931692909217600160a01b85151502179091555b8151811015620002655760006001600160a01b0316828281518110620000d457620000d462000658565b60200260200101516001600160a01b031614620002505760016007600084848151811062000106576200010662000658565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff02191690831515021790555060038282815181106200015c576200015c62000658565b6020908102919091018101518254600181018455600093845291832090910180546001600160a01b0319166001600160a01b0390921691909117905582518591600291859085908110620001b457620001b462000658565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555062093a806002600084848151811062000220576200022062000658565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020600101819055505b806200025c816200066e565b915050620000aa565b508115620004d757600080876001600160a01b0316639d63848a6040518163ffffffff1660e01b81526004016040805180830381600087803b158015620002ab57600080fd5b505af1158015620002c0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002e6919062000698565b60405163095ea7b360e01b81526001600160a01b038a8116600483015260001960248301529294509092509083169063095ea7b390604401602060405180830381600087803b1580156200033957600080fd5b505af11580156200034e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003749190620006d0565b5060405163095ea7b360e01b81526001600160a01b038881166004830152600019602483015282169063095ea7b390604401602060405180830381600087803b158015620003c157600080fd5b505af1158015620003d6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003fc9190620006d0565b5060048054600181810183557f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b91820180546001600160a01b038088166001600160a01b031992831681179093558554808501909655949093018054868616941684179055600081815260086020526040808220805460ff19908116861790915594825280822080549095168417909455925191938b16929091600080516020620054298339815191529190a46040516001906001600160a01b03808a1691908416906000805160206200542983398151915290600090a450505b505050505050620006f5565b80516001600160a01b0381168114620004fb57600080fd5b919050565b80518015158114620004fb57600080fd5b634e487b7160e01b600052604160045260246000fd5b60008060008060008060c087890312156200054157600080fd5b6200054c87620004e3565b955060206200055d818901620004e3565b95506200056d60408901620004e3565b94506200057d60608901620004e3565b93506200058d6080890162000500565b60a08901519093506001600160401b0380821115620005ab57600080fd5b818a0191508a601f830112620005c057600080fd5b815181811115620005d557620005d562000511565b8060051b604051601f19603f83011681018181108582111715620005fd57620005fd62000511565b60405291825284820192508381018501918d8311156200061c57600080fd5b938501935b8285101562000645576200063585620004e3565b8452938501939285019262000621565b8096505050505050509295509295509295565b634e487b7160e01b600052603260045260246000fd5b60006000198214156200069157634e487b7160e01b600052601160045260246000fd5b5060010190565b60008060408385031215620006ac57600080fd5b620006b783620004e3565b9150620006c760208401620004e3565b90509250929050565b600060208284031215620006e357600080fd5b620006ee8262000500565b9392505050565b614d2480620007056000396000f3fe608060405234801561001057600080fd5b50600436106103275760003560e01c80635a6e6eab116101b8578063b66503cf11610104578063de5f6268116100a2578063e70b9e271161007c578063e70b9e271461081e578063e9fad8ee14610849578063f122977714610851578063f5ae22401461086457600080fd5b8063de5f6268146107fa578063e574821314610802578063e68863961461081657600080fd5b8063d0ed26ae116100de578063d0ed26ae1461077a578063d294f0931461078d578063da09d19d146107aa578063dd501205146107d757600080fd5b8063b66503cf14610741578063b6b55f2514610754578063bcd110141461076757600080fd5b8063749f1044116101715780638a5011001161014b5780638a501100146107025780638dd598fb146107155780638f27f1041461072657806399bcc0521461072e57600080fd5b8063749f1044146106d45780637bb7bed1146106e7578063853828b6146106fa57600080fd5b80635a6e6eab1461062d5780635c975abb14610640578063638634ee1461064d57806365bcfbe7146106605780637035ab981461068057806370a08231146106ab57600080fd5b80632f4f21e2116102775780633f695b45116102305780634d5ce0381161020a5780634d5ce038146105c15780634ec5908d146105f457806352f18405146106075780635557cc611461061a57600080fd5b80633f695b451461051557806346c96aac1461052857806348e5d9f81461053b57600080fd5b80632f4f21e2146104a95780633010d8ef146104bc57806331279d3d146104cf57806337d0208c146104e25780633a4b66f1146104f55780633d18b9121461050d57600080fd5b80631f850716116102e45780632378bea6116102be5780632378bea61461042c5780632af2cecc1461043f5780632ce9aead1461046a5780632e1a7d4d1461049657600080fd5b80631f850716146103c2578063211dc32d146103ed578063221ca18c1461040057600080fd5b8063023df7671461032c5780630efeb2fb14610341578063102a7ad41461037457806315ae92f71461038757806316c38b3c146103a757806318160ddd146103ba575b600080fd5b61033f61033a366004614823565b610877565b005b61036161034f366004614823565b60106020526000908152604090205481565b6040519081526020015b60405180910390f35b610361610382366004614840565b610b16565b610361610395366004614823565b60126020526000908152604090205481565b61033f6103b5366004614887565b610bb1565b600954610361565b600c546103d5906001600160a01b031681565b6040516001600160a01b03909116815260200161036b565b6103616103fb366004614840565b610c7c565b61036161040e366004614823565b6001600160a01b031660009081526002602052604090206003015490565b61033f61043a3660046148a4565b610c88565b61036161044d366004614840565b601160209081526000928352604080842090915290825290205481565b610361610478366004614823565b6001600160a01b031660009081526002602052604090206004015490565b61033f6104a43660046148d0565b610e57565b61033f6104b73660046148a4565b611070565b61033f6104ca366004614823565b6112dc565b61033f6104dd3660046149a1565b611364565b600b546103d5906001600160a01b031681565b6001546103d59061010090046001600160a01b031681565b61033f61142f565b61033f610523366004614840565b6116b7565b600d546103d5906001600160a01b031681565b61058a610549366004614823565b60026020819052600091825260409091208054600182015492820154600383015460048401546005909401546001600160a01b039093169493919290919086565b604080516001600160a01b0390971687526020870195909552938501929092526060840152608083015260a082015260c00161036b565b6105e46105cf366004614823565b60076020526000908152604090205460ff1681565b604051901515815260200161036b565b61033f610602366004614823565b61179d565b61033f6106153660046149f1565b611877565b61033f610628366004614823565b61196f565b61033f61063b3660046149f1565b611d24565b6001546105e49060ff1681565b61036161065b366004614823565b611e1c565b61036161066e366004614823565b600f6020526000908152604090205481565b61036161068e366004614840565b600560209081526000928352604080842090915290825290205481565b6103616106b9366004614823565b6001600160a01b03166000908152600a602052604090205490565b600e546103d5906001600160a01b031681565b6103d56106f53660046148d0565b611e43565b61033f611e6d565b61033f610710366004614a26565b611e88565b600c546001600160a01b03166103d5565b600454610361565b61036161073c366004614823565b61210f565b61033f61074f3660046148a4565b612190565b61033f6107623660046148d0565b612793565b610361610775366004614823565b6129b2565b61033f610788366004614a68565b6129de565b610795612c00565b6040805192835260208301919091520161036b565b6103616107b8366004614823565b6001600160a01b03166000908152600260208190526040909120015490565b6105e46107e5366004614823565b60086020526000908152604090205460ff1681565b61033f612c4f565b600d546105e490600160a01b900460ff1681565b600354610361565b61036161082c366004614840565b600660209081526000928352604080842090915290825290205481565b61033f612cd1565b61036161085f366004614823565b612cf2565b6103d56108723660046148d0565b612d94565b600c60009054906101000a90046001600160a01b03166001600160a01b03166385f2aef26040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156108c757600080fd5b505af11580156108db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ff9190614aa9565b6001600160a01b0316336001600160a01b0316146109385760405162461bcd60e51b815260040161092f90614ac6565b60405180910390fd5b6001600160a01b03811660009081526008602052604090205460ff16156109975760405162461bcd60e51b8152602060048201526013602482015272427269626520546f6b656e204163746976652160681b604482015260640161092f565b6001546001600160a01b038281166101009092041614156109fa5760405162461bcd60e51b815260206004820152601b60248201527f43616e6e6f74206272696265207374616b696e6720746f6b656e210000000000604482015260640161092f565b600b5460405163095ea7b360e01b81526001600160a01b038381169263095ea7b392610a30929091169060001990600401614aed565b602060405180830381600087803b158015610a4a57600080fd5b505af1158015610a5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a829190614b06565b506004805460018082019092557f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0180546001600160a01b0319166001600160a01b03848116918217909255600081815260086020526040808220805460ff191686179055600b5490519316927f6f3d0c80b7142a8d817dfedfe293680f67ba78aacbbc59db82973fd195982d059190a450565b6001600160a01b038083166000818152600660209081526040808320948616808452948252808320549383526005825280832094835293905291822054610ba89190610ba290670de0b6b3a764000090610b9c90610b7d90610b7789612cf2565b90612da4565b6001600160a01b0389166000908152600a602052604090205490612e0a565b90612e89565b90612ee6565b90505b92915050565b600c60009054906101000a90046001600160a01b03166001600160a01b03166385f2aef26040518163ffffffff1660e01b8152600401602060405180830381600087803b158015610c0157600080fd5b505af1158015610c15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c399190614aa9565b6001600160a01b0316336001600160a01b031614610c695760405162461bcd60e51b815260040161092f90614ac6565b6001805460ff1916911515919091179055565b6000610ba88284610b16565b600c60009054906101000a90046001600160a01b03166001600160a01b03166385f2aef26040518163ffffffff1660e01b8152600401602060405180830381600087803b158015610cd857600080fd5b505af1158015610cec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d109190614aa9565b6001600160a01b0316336001600160a01b031614610d405760405162461bcd60e51b815260040161092f90614ac6565b6001600160a01b038216600090815260026020819052604090912001544211610dab5760405162461bcd60e51b815260206004820152601a60248201527f52657761726420706572696f64207374696c6c20616374697665000000000000604482015260640161092f565b60008111610dfb5760405162461bcd60e51b815260206004820181905260248201527f526577617264206475726174696f6e206d757374206265206e6f6e2d7a65726f604482015260640161092f565b6001600160a01b03821660008181526002602052604090819020600101839055517fad2f86b01ed93b4b3a150d448c61a4f5d8d38075d3c0c64cc0a26fd6e1f4954590610e4b9084815260200190565b60405180910390a25050565b6001600080828254610e699190614b39565b9091555050600080549033905b600354811015610f6b57600060038281548110610e9557610e95614b51565b6000918252602090912001546001600160a01b03169050610eb581612cf2565b6001600160a01b038216600090815260026020526040902060050155610eda81611e1c565b6001600160a01b03808316600090815260026020526040902060040191909155831615610f5857610f0b8382610b16565b6001600160a01b0380851660008181526006602090815260408083209487168084529482528083209590955560028152848220600590810154938352815284822093825292909252919020555b5080610f6381614b67565b915050610e76565b5060008311610fb05760405162461bcd60e51b8152602060048201526011602482015270043616e6e6f74207769746864726177203607c1b604482015260640161092f565b600954610fbd9084612da4565b600955336000908152600a6020526040902054610fda9084612da4565b336000818152600a602052604090209190915560015461100a916101009091046001600160a01b03169085612f45565b60405183815233907f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5906020015b60405180910390a2611048612f9b565b505050600054811461106c5760405162461bcd60e51b815260040161092f90614b82565b5050565b60016000808282546110829190614b39565b909155505060005460015460ff16156110c75760405162461bcd60e51b81526020600482015260076024820152665061757365642160c81b604482015260640161092f565b8260005b6003548110156111c0576000600382815481106110ea576110ea614b51565b6000918252602090912001546001600160a01b0316905061110a81612cf2565b6001600160a01b03821660009081526002602052604090206005015561112f81611e1c565b6001600160a01b038083166000908152600260205260409020600401919091558316156111ad576111608382610b16565b6001600160a01b0380851660008181526006602090815260408083209487168084529482528083209590955560028152848220600590810154938352815284822093825292909252919020555b50806111b881614b67565b9150506110cb565b50600083116112025760405162461bcd60e51b815260206004820152600e60248201526d043616e6e6f74207374616b6520360941b604482015260640161092f565b60095461120f9084612ee6565b6009556001600160a01b0384166000908152600a60205260409020546112359084612ee6565b6001600160a01b038086166000908152600a602052604090209190915560015461126891610100909104163330866143b1565b836001600160a01b03167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c846040516112a391815260200190565b60405180910390a26112b3612f9b565b50505060005481146112d75760405162461bcd60e51b815260040161092f90614b82565b505050565b6001546040516370a0823160e01b81523360048201526113619183916101009091046001600160a01b0316906370a082319060240160206040518083038186803b15801561132957600080fd5b505afa15801561133d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b79190614bb9565b50565b336001600160a01b03831614806113855750600d546001600160a01b031633145b6113c85760405162461bcd60e51b8152602060048201526014602482015273556e2d617574686f72697a656420636c61696d2160601b604482015260640161092f565b600d546040516363453ae160e01b81523060048201526001600160a01b03909116906363453ae190602401600060405180830381600087803b15801561140d57600080fd5b505af1158015611421573d6000803e3d6000fd5b5050505061106c82826143ef565b60016000808282546114419190614b39565b9091555050600080549033905b6003548110156115435760006003828154811061146d5761146d614b51565b6000918252602090912001546001600160a01b0316905061148d81612cf2565b6001600160a01b0382166000908152600260205260409020600501556114b281611e1c565b6001600160a01b03808316600090815260026020526040902060040191909155831615611530576114e38382610b16565b6001600160a01b0380851660008181526006602090815260408083209487168084529482528083209590955560028152848220600590810154938352815284822093825292909252919020555b508061153b81614b67565b91505061144e565b5060005b60035481101561168a5760006003828154811061156657611566614b51565b60009182526020808320909101543383526006825260408084206001600160a01b03909216808552919092529120549091508015611675573360008181526006602090815260408083206001600160a01b03871680855292528220919091556115cf9183612f45565b6040518181526001600160a01b0383169033907f9aa05b3d70a9e3e2f004f039648839560576334fb45c81f91b6db03ad9e2efc99060200160405180910390a36001600160a01b0382166000908152600f602052604081208054839290611637908490614b39565b90915550503360009081526011602090815260408083206001600160a01b03861684529091528120805483929061166f908490614b39565b90915550505b5050808061168290614b67565b915050611547565b50611693612f9b565b50505060005481146113615760405162461bcd60e51b815260040161092f90614b82565b600c60009054906101000a90046001600160a01b03166001600160a01b03166385f2aef26040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561170757600080fd5b505af115801561171b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061173f9190614aa9565b6001600160a01b0316336001600160a01b03161461176f5760405162461bcd60e51b815260040161092f90614ac6565b6001600160a01b03918216600090815260026020526040902080546001600160a01b03191691909216179055565b600c60009054906101000a90046001600160a01b03166001600160a01b03166385f2aef26040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156117ed57600080fd5b505af1158015611801573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118259190614aa9565b6001600160a01b0316336001600160a01b0316146118555760405162461bcd60e51b815260040161092f90614ac6565b600e80546001600160a01b0319166001600160a01b0392909216919091179055565b600c60009054906101000a90046001600160a01b03166001600160a01b03166385f2aef26040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156118c757600080fd5b505af11580156118db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118ff9190614aa9565b6001600160a01b0316336001600160a01b03161461192f5760405162461bcd60e51b815260040161092f90614ac6565b60005b815181101561106c5761195d82828151811061195057611950614b51565b6020026020010151610877565b8061196781614b67565b915050611932565b600c60009054906101000a90046001600160a01b03166001600160a01b03166385f2aef26040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156119bf57600080fd5b505af11580156119d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119f79190614aa9565b6001600160a01b0316336001600160a01b031614611a275760405162461bcd60e51b815260040161092f90614ac6565b6001600160a01b03811660009081526008602052604090205460ff161515600114611a8c5760405162461bcd60e51b8152602060048201526015602482015274427269626520546f6b656e20496e6163746976652160581b604482015260640161092f565b600b5460405163095ea7b360e01b81526001600160a01b038381169263095ea7b392611ac19290911690600090600401614aed565b602060405180830381600087803b158015611adb57600080fd5b505af1158015611aef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b139190614b06565b5060048054906001600160a01b03831690611b2f600184614bd2565b81548110611b3f57611b3f614b51565b6000918252602090912001546001600160a01b03161415611bb2576004805480611b6b57611b6b614be9565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b03841682526008905260409020805460ff19169055611ce2565b60005b600454611bc490600190614bd2565b811015611ce057826001600160a01b031660048281548110611be857611be8614b51565b6000918252602090912001546001600160a01b03161415611cce576004611c10600184614bd2565b81548110611c2057611c20614b51565b600091825260209091200154600480546001600160a01b039092169183908110611c4c57611c4c614b51565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506004805480611c8b57611c8b614be9565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b03851682526008905260409020805460ff191690555b80611cd881614b67565b915050611bb5565b505b600b546040516000916001600160a01b0390811691908516907f6f3d0c80b7142a8d817dfedfe293680f67ba78aacbbc59db82973fd195982d05908490a45050565b600c60009054906101000a90046001600160a01b03166001600160a01b03166385f2aef26040518163ffffffff1660e01b8152600401602060405180830381600087803b158015611d7457600080fd5b505af1158015611d88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dac9190614aa9565b6001600160a01b0316336001600160a01b031614611ddc5760405162461bcd60e51b815260040161092f90614ac6565b60005b815181101561106c57611e0a828281518110611dfd57611dfd614b51565b602002602001015161196f565b80611e1481614b67565b915050611ddf565b6001600160a01b038116600090815260026020819052604082200154610bab904290614668565b60038181548110611e5357600080fd5b6000918252602090912001546001600160a01b0316905081565b336000908152600a6020526040902054611e8690610e57565b565b600c60009054906101000a90046001600160a01b03166001600160a01b03166385f2aef26040518163ffffffff1660e01b8152600401602060405180830381600087803b158015611ed857600080fd5b505af1158015611eec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f109190614aa9565b6001600160a01b0316336001600160a01b031614611f405760405162461bcd60e51b815260040161092f90614ac6565b6001546001600160a01b03838116610100909204161415612046576009546001546040516370a0823160e01b8152306004820152600092611fe79290916101009091046001600160a01b0316906370a08231906024015b60206040518083038186803b158015611faf57600080fd5b505afa158015611fc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b779190614bb9565b9050808411156120445760405162461bcd60e51b815260206004820152602260248201527f5265736375696e672055736572204465706f736974732050726f686962697465604482015261642160f01b606482015260840161092f565b505b60405163a9059cbb60e01b81526001600160a01b0383169063a9059cbb906120749084908790600401614aed565b602060405180830381600087803b15801561208e57600080fd5b505af11580156120a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120c69190614b06565b50816001600160a01b03167f8c1256b8896378cd5044f80c202f9772b9d77dc85c8a6eb51967210b09bfaa288460405161210291815260200190565b60405180910390a2505050565b6001600160a01b038116600090815260026020819052604082200154421061213957506000919050565b6001600160a01b03821660009081526002602081905260408220015461215f9042612da4565b6001600160a01b038416600090815260026020526040902060030154909150612189908290612e0a565b9392505050565b60016000808282546121a29190614b39565b90915550506000805490805b6003548110156122a3576000600382815481106121cd576121cd614b51565b6000918252602090912001546001600160a01b031690506121ed81612cf2565b6001600160a01b03821660009081526002602052604090206005015561221281611e1c565b6001600160a01b03808316600090815260026020526040902060040191909155831615612290576122438382610b16565b6001600160a01b0380851660008181526006602090815260408083209487168084529482528083209590955560028152848220600590810154938352815284822093825292909252919020555b508061229b81614b67565b9150506121ae565b506001546001600160a01b038581166101009092041614156123185760405162461bcd60e51b815260206004820152602860248201527f43616e27742064697374726962757465207374616b656420746f6b656e206173604482015267207265776172642160c01b606482015260840161092f565b6001600160a01b03841660009081526007602052604090205460ff166123715760405162461bcd60e51b815260206004820152600e60248201526d4e6f74206120726577617264212160901b604482015260640161092f565b612379612f9b565b50506040516370a0823160e01b81523060048201526000906001600160a01b038616906370a082319060240160206040518083038186803b1580156123bd57600080fd5b505afa1580156123d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123f59190614bb9565b905061240c6001600160a01b0386163330876143b1565b6040516370a0823160e01b81523060048201526000906001600160a01b038716906370a082319060240160206040518083038186803b15801561244e57600080fd5b505afa158015612462573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124869190614bb9565b90506124928282614bd2565b9450600085116124f25760405162461bcd60e51b815260206004820152602560248201527f52657761726420616d6f756e74206d7573742062652067726561746572207468604482015264616e20302160d81b606482015260840161092f565b6001600160a01b03861660009081526002602081905260409091200154421061255d576001600160a01b03861660009081526002602052604090206001015461253c908690612e89565b6001600160a01b0387166000908152600260205260409020600301556126bc565b6001600160a01b03861660009081526002602081905260408220600381015491015490919061258c9042612da4565b6001600160a01b038916600090815260026020526040812060030154919250906125b7908390612e0a565b6001600160a01b038a166000908152600260205260409020600101549091506125e490610b9c8a84612ee6565b6001600160a01b038a8116600090815260026020526040902060030191909155600d54163314158061263057506001600160a01b03898116600090815260026020526040902054163314155b156126b8576001600160a01b0389166000908152600260205260409020600301548311158061265e57508088115b6126b85760405162461bcd60e51b815260206004820152602560248201527f456e68616e636564204772696566696e672050726f74656374696f6e20456e61604482015264626c65642160d81b606482015260840161092f565b5050505b6001600160a01b038616600090815260026020526040902042600482018190556001909101546126ec9190612ee6565b6001600160a01b038716600081815260026020818152604092839020909101939093555187815233927f0f7cde3c0518e1cc590491be5861d70a2e333f7e65af2e1ebd91a3c9a3cc638d910160405180910390a36001600160a01b03861660009081526010602052604081208054879290612768908490614b39565b9250508190555050505060005481146112d75760405162461bcd60e51b815260040161092f90614b82565b60016000808282546127a59190614b39565b909155505060005460015460ff16156127ea5760405162461bcd60e51b81526020600482015260076024820152665061757365642160c81b604482015260640161092f565b3360005b6003548110156128e35760006003828154811061280d5761280d614b51565b6000918252602090912001546001600160a01b0316905061282d81612cf2565b6001600160a01b03821660009081526002602052604090206005015561285281611e1c565b6001600160a01b038083166000908152600260205260409020600401919091558316156128d0576128838382610b16565b6001600160a01b0380851660008181526006602090815260408083209487168084529482528083209590955560028152848220600590810154938352815284822093825292909252919020555b50806128db81614b67565b9150506127ee565b50600083116129255760405162461bcd60e51b815260206004820152600e60248201526d043616e6e6f74207374616b6520360941b604482015260640161092f565b6009546129329084612ee6565b600955336000908152600a602052604090205461294f9084612ee6565b336000818152600a6020526040902091909155600154612980916101009091046001600160a01b03169030866143b1565b60405183815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c90602001611038565b6001600160a01b03811660009081526002602052604081206001810154600390910154610bab91612e0a565b600c60009054906101000a90046001600160a01b03166001600160a01b03166385f2aef26040518163ffffffff1660e01b8152600401602060405180830381600087803b158015612a2e57600080fd5b505af1158015612a42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a669190614aa9565b6001600160a01b0316336001600160a01b031614612a965760405162461bcd60e51b815260040161092f90614ac6565b6001600160a01b03831660009081526007602052604090205460ff16158015612ad857506001600160a01b038316600090815260026020526040902060010154155b612b1b5760405162461bcd60e51b8152602060048201526014602482015273416c726561647920496e697469616c697a65642160601b604482015260640161092f565b6001546001600160a01b03848116610100909204161415612b7e5760405162461bcd60e51b815260206004820152601c60248201527f43616e6e6f7420726577617264207374616b696e6720746f6b656e2100000000604482015260640161092f565b6003805460018181019092557fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b039586166001600160a01b031991821681179092556000918252600760209081526040808420805460ff19168617905560029091529091208054949095169316929092178355910155565b6000806001600080828254612c159190614b39565b9091555050600054612c25612f9b565b925092506000548114612c4a5760405162461bcd60e51b815260040161092f90614b82565b509091565b6001546040516370a0823160e01b8152336004820152611e869161010090046001600160a01b0316906370a082319060240160206040518083038186803b158015612c9957600080fd5b505afa158015612cad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107629190614bb9565b336000908152600a6020526040902054612cea90610e57565b611e8661142f565b600060095460001415612d1e57506001600160a01b031660009081526002602052604090206005015490565b6009546001600160a01b03831660009081526002602052604090206003810154600490910154610bab92612d72929091610b9c91670de0b6b3a764000091612d6c91908290610b778b611e1c565b90612e0a565b6001600160a01b03841660009081526002602052604090206005015490612ee6565b60048181548110611e5357600080fd5b600082821115612df65760405162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015260640161092f565b6000612e028385614bd2565b949350505050565b600082612e1957506000610bab565b6000612e258385614bff565b905082612e328583614c1e565b14610ba85760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b606482015260840161092f565b6000808211612eda5760405162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015260640161092f565b6000612e028385614c1e565b600080612ef38385614b39565b905083811015610ba85760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015260640161092f565b6112d78363a9059cbb60e01b8484604051602401612f64929190614aed565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261467e565b6000806000600d60009054906101000a90046001600160a01b03166001600160a01b0316633f6678256040518163ffffffff1660e01b815260040160206040518083038186803b158015612fee57600080fd5b505afa158015613002573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130269190614bb9565b905060008082116130385760006130be565b600d60009054906101000a90046001600160a01b03166001600160a01b03166313416d996040518163ffffffff1660e01b815260040160206040518083038186803b15801561308657600080fd5b505afa15801561309a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130be9190614aa9565b600d54909150600160a01b900460ff16613a855760045460008167ffffffffffffffff8111156130f0576130f06148e9565b604051908082528060200260200182016040528015613119578160200160208202803683370190505b50905060008267ffffffffffffffff811115613137576131376148e9565b604051908082528060200260200182016040528015613160578160200160208202803683370190505b50905060005b838110156132d0576004818154811061318157613181614b51565b9060005260206000200160009054906101000a90046001600160a01b03168382815181106131b1576131b1614b51565b60200260200101906001600160a01b031690816001600160a01b03168152505060006001600160a01b03168382815181106131ee576131ee614b51565b60200260200101516001600160a01b03161461329e5782818151811061321657613216614b51565b60209081029190910101516040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b15801561326157600080fd5b505afa158015613275573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132999190614bb9565b6132a1565b60005b8282815181106132b3576132b3614b51565b6020908102919091010152806132c881614b67565b915050613166565b5060018054906101000a90046001600160a01b03166001600160a01b031663d294f0936040518163ffffffff1660e01b81526004016040805180830381600087803b15801561331e57600080fd5b505af192505050801561334e575060408051601f3d908101601f1916820190925261334b91810190614c40565b60015b6133615750600096879650945050505050565b505060005b83811015613a75576000806001600160a01b031684838151811061338c5761338c614b51565b60200260200101516001600160a01b03161461343c578382815181106133b4576133b4614b51565b60209081029190910101516040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b1580156133ff57600080fd5b505afa158015613413573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134379190614bb9565b61343f565b60005b905082828151811061345357613453614b51565b6020026020010151811115613a62576000620f42408885858151811061347b5761347b614b51565b60200260200101518461348e9190614bd2565b6134989190614bff565b6134a29190614c1e565b11156136cc578382815181106134ba576134ba614b51565b60200260200101516001600160a01b031663a9059cbb87620f42408a6135028888815181106134eb576134eb614b51565b602002602001015187612da490919063ffffffff16565b61350c9190614bff565b6135169190614c1e565b6040518363ffffffff1660e01b8152600401613533929190614aed565b602060405180830381600087803b15801561354d57600080fd5b505af1158015613561573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135859190614b06565b5083828151811061359857613598614b51565b60200260200101516001600160a01b0316866001600160a01b0316336001600160a01b03167f78c0b7f8dc279098cd35e7f6ed62faef6b268eb5f31ece1326f32e1bc1d5a048620f42408b61360f8989815181106135f8576135f8614b51565b602002602001015188612da490919063ffffffff16565b6136199190614bff565b6136239190614c1e565b60405190815260200160405180910390a483828151811061364657613646614b51565b60209081029190910101516040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b15801561369157600080fd5b505afa1580156136a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136c99190614bb9565b90505b600e546001600160a01b031661389657600b5484516001600160a01b039091169063b66503cf9086908590811061370557613705614b51565b602002602001015161373986868151811061372257613722614b51565b602002602001015185612da490919063ffffffff16565b6040518363ffffffff1660e01b8152600401613756929190614aed565b600060405180830381600087803b15801561377057600080fd5b505af1158015613784573d6000803e3d6000fd5b5050505083828151811061379a5761379a614b51565b60200260200101516001600160a01b0316600b60009054906101000a90046001600160a01b03166001600160a01b0316336001600160a01b0316600080516020614ccf8339815191528686815181106137f5576137f5614b51565b6020026020010151856138089190614bd2565b60405190815260200160405180910390a482828151811061382b5761382b614b51565b60200260200101518161383e9190614bd2565b6012600086858151811061385457613854614b51565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020600082825461388b9190614b39565b90915550613a629050565b8382815181106138a8576138a8614b51565b60200260200101516001600160a01b031663a9059cbb600e60009054906101000a90046001600160a01b03166138e986868151811061372257613722614b51565b6040518363ffffffff1660e01b8152600401613906929190614aed565b602060405180830381600087803b15801561392057600080fd5b505af1158015613934573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139589190614b06565b5083828151811061396b5761396b614b51565b60200260200101516001600160a01b0316600e60009054906101000a90046001600160a01b03166001600160a01b0316336001600160a01b0316600080516020614ccf8339815191528686815181106139c6576139c6614b51565b6020026020010151856139d99190614bd2565b60405190815260200160405180910390a48282815181106139fc576139fc614b51565b602002602001015181613a0f9190614bd2565b60126000868581518110613a2557613a25614b51565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000206000828254613a5c9190614b39565b90915550505b5080613a6d81614b67565b915050613366565b5060009788975095505050505050565b60008060018054906101000a90046001600160a01b03166001600160a01b0316639d63848a6040518163ffffffff1660e01b81526004016040805180830381600087803b158015613ad557600080fd5b505af1158015613ae9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b0d9190614c64565b6040516370a0823160e01b815230600482015291935091506000906001600160a01b038416906370a082319060240160206040518083038186803b158015613b5457600080fd5b505afa158015613b68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b8c9190614bb9565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038416906370a082319060240160206040518083038186803b158015613bd157600080fd5b505afa158015613be5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c099190614bb9565b905060018054906101000a90046001600160a01b03166001600160a01b031663d294f0936040518163ffffffff1660e01b81526004016040805180830381600087803b158015613c5857600080fd5b505af1158015613c6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c909190614c40565b50506040516370a0823160e01b815230600482015282906001600160a01b038616906370a082319060240160206040518083038186803b158015613cd357600080fd5b505afa158015613ce7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d0b9190614bb9565b613d159190614bd2565b6040516370a0823160e01b815230600482015290985081906001600160a01b038516906370a082319060240160206040518083038186803b158015613d5957600080fd5b505afa158015613d6d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d919190614bb9565b613d9b9190614bd2565b96506000620f4240613dad888b614bff565b613db79190614c1e565b1115613ee3576001600160a01b03841663a9059cbb86620f4240613ddb8a8d614bff565b613de59190614c1e565b6040518363ffffffff1660e01b8152600401613e02929190614aed565b602060405180830381600087803b158015613e1c57600080fd5b505af1158015613e30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e549190614b06565b506001600160a01b03808616908516337f78c0b7f8dc279098cd35e7f6ed62faef6b268eb5f31ece1326f32e1bc1d5a048620f4240613e938b8e614bff565b613e9d9190614c1e565b60405190815260200160405180910390a46040516370a0823160e01b8152306004820152613ee09083906001600160a01b038716906370a0823190602401611f97565b97505b6000620f4240613ef3888a614bff565b613efd9190614c1e565b1115614029576001600160a01b03831663a9059cbb86620f4240613f218a8c614bff565b613f2b9190614c1e565b6040518363ffffffff1660e01b8152600401613f48929190614aed565b602060405180830381600087803b158015613f6257600080fd5b505af1158015613f76573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f9a9190614b06565b506001600160a01b03808616908416337f78c0b7f8dc279098cd35e7f6ed62faef6b268eb5f31ece1326f32e1bc1d5a048620f4240613fd98b8d614bff565b613fe39190614c1e565b60405190815260200160405180910390a46040516370a0823160e01b81523060048201526140269082906001600160a01b038616906370a0823190602401611f97565b96505b600e546001600160a01b03166141d657871561410557600b5460405163b66503cf60e01b81526001600160a01b039091169063b66503cf906140719087908c90600401614aed565b600060405180830381600087803b15801561408b57600080fd5b505af115801561409f573d6000803e3d6000fd5b505050506001600160a01b038416600090815260126020526040812080548a92906140cb908490614b39565b9091555050600e546040518981526001600160a01b038681169216903390600080516020614ccf8339815191529060200160405180910390a45b86156141d157600b5460405163b66503cf60e01b81526001600160a01b039091169063b66503cf9061413d9086908b90600401614aed565b600060405180830381600087803b15801561415757600080fd5b505af115801561416b573d6000803e3d6000fd5b505050506001600160a01b03831660009081526012602052604081208054899290614197908490614b39565b9091555050600e546040518881526001600160a01b038581169216903390600080516020614ccf8339815191529060200160405180910390a45b6143a7565b600e5460405163a9059cbb60e01b81526001600160a01b038681169263a9059cbb9261420a92909116908c90600401614aed565b602060405180830381600087803b15801561422457600080fd5b505af1158015614238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061425c9190614b06565b50600e5460405163a9059cbb60e01b81526001600160a01b038581169263a9059cbb9261429192909116908b90600401614aed565b602060405180830381600087803b1580156142ab57600080fd5b505af11580156142bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142e39190614b06565b50600e546040518981526001600160a01b038681169216903390600080516020614ccf8339815191529060200160405180910390a4600e546040518881526001600160a01b038581169216903390600080516020614ccf8339815191529060200160405180910390a46001600160a01b038416600090815260126020526040812080548a9290614374908490614b39565b90915550506001600160a01b038316600090815260126020526040812080548992906143a1908490614b39565b90915550505b5050505050509091565b6040516001600160a01b03808516602483015283166044820152606481018290526143e99085906323b872dd60e01b90608401612f64565b50505050565b60016000808282546144019190614b39565b9091555050600080549083905b6003548110156145035760006003828154811061442d5761442d614b51565b6000918252602090912001546001600160a01b0316905061444d81612cf2565b6001600160a01b03821660009081526002602052604090206005015561447281611e1c565b6001600160a01b038083166000908152600260205260409020600401919091558316156144f0576144a38382610b16565b6001600160a01b0380851660008181526006602090815260408083209487168084529482528083209590955560028152848220600590810154938352815284822093825292909252919020555b50806144fb81614b67565b91505061440e565b5060005b835181101561465f57600084828151811061452457614524614b51565b6020908102919091018101516001600160a01b03808916600090815260068452604080822092841682529190935290912054909150801561464a576001600160a01b03808816600090815260066020908152604080832093861680845293909152812055614593908883612f45565b866001600160a01b0316826001600160a01b03167f9aa05b3d70a9e3e2f004f039648839560576334fb45c81f91b6db03ad9e2efc9836040516145d891815260200190565b60405180910390a36001600160a01b0382166000908152600f602052604081208054839290614608908490614b39565b90915550506001600160a01b03808816600090815260116020908152604080832093861683529290529081208054839290614644908490614b39565b90915550505b5050808061465790614b67565b915050614507565b506112b3612f9b565b60008183106146775781610ba8565b5090919050565b6001600160a01b0382163b6146d55760405162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015260640161092f565b600080836001600160a01b0316836040516146f09190614c93565b6000604051808303816000865af19150503d806000811461472d576040519150601f19603f3d011682016040523d82523d6000602084013e614732565b606091505b5091509150816147845760405162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015260640161092f565b8051156143e9578080602001905181019061479f9190614b06565b6143e95760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161092f565b6001600160a01b038116811461136157600080fd5b803561481e816147fe565b919050565b60006020828403121561483557600080fd5b8135610ba8816147fe565b6000806040838503121561485357600080fd5b823561485e816147fe565b9150602083013561486e816147fe565b809150509250929050565b801515811461136157600080fd5b60006020828403121561489957600080fd5b8135610ba881614879565b600080604083850312156148b757600080fd5b82356148c2816147fe565b946020939093013593505050565b6000602082840312156148e257600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b600082601f83011261491057600080fd5b8135602067ffffffffffffffff8083111561492d5761492d6148e9565b8260051b604051601f19603f83011681018181108482111715614952576149526148e9565b60405293845285810183019383810192508785111561497057600080fd5b83870191505b848210156149965761498782614813565b83529183019190830190614976565b979650505050505050565b600080604083850312156149b457600080fd5b82356149bf816147fe565b9150602083013567ffffffffffffffff8111156149db57600080fd5b6149e7858286016148ff565b9150509250929050565b600060208284031215614a0357600080fd5b813567ffffffffffffffff811115614a1a57600080fd5b612e02848285016148ff565b600080600060608486031215614a3b57600080fd5b833592506020840135614a4d816147fe565b91506040840135614a5d816147fe565b809150509250925092565b600080600060608486031215614a7d57600080fd5b8335614a88816147fe565b92506020840135614a98816147fe565b929592945050506040919091013590565b600060208284031215614abb57600080fd5b8151610ba8816147fe565b6020808252600d908201526c4f6e6c792076652e7465616d2160981b604082015260600190565b6001600160a01b03929092168252602082015260400190565b600060208284031215614b1857600080fd5b8151610ba881614879565b634e487b7160e01b600052601160045260246000fd5b60008219821115614b4c57614b4c614b23565b500190565b634e487b7160e01b600052603260045260246000fd5b6000600019821415614b7b57614b7b614b23565b5060010190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b600060208284031215614bcb57600080fd5b5051919050565b600082821015614be457614be4614b23565b500390565b634e487b7160e01b600052603160045260246000fd5b6000816000190483118215151615614c1957614c19614b23565b500290565b600082614c3b57634e487b7160e01b600052601260045260246000fd5b500490565b60008060408385031215614c5357600080fd5b505080516020909101519092909150565b60008060408385031215614c7757600080fd5b8251614c82816147fe565b602084015190925061486e816147fe565b6000825160005b81811015614cb45760208186018101518583015201614c9a565b81811115614cc3576000828501525b50919091019291505056feee447878094bcc87bd81b55e4831b5e9e3d095866fce10f4f7e4caa64ea7a558a2646970667358221220cebd89c532c39dff28e605d8662ea3f1a93b28f80d12ac1731898220bf59bbd664736f6c634300080900336f3d0c80b7142a8d817dfedfe293680f67ba78aacbbc59db82973fd195982d05a2646970667358221220039fc786cf5482341dd9c1bf214979e7f2827e37b56f2c58d277fc0106a8134364736f6c63430008090033
Deployed ByteCode Sourcemap
39981:768:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40182:564;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1999:32:1;;;1981:51;;1969:2;1954:18;40182:564:0;;;;;;;40027:24;;;;;-1:-1:-1;;;;;40027:24:0;;;40182:564;40364:7;40384:21;40442:5;40462:6;40483:3;40501:10;40526:6;40547:15;40408:165;;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;40584:9:0;:26;;-1:-1:-1;;;;;;40584:26:0;-1:-1:-1;;;;;40584:26:0;;;;;;;;;;40626:85;;40584:26;;-1:-1:-1;40626:85:0;;;40639:10;;40626:85;;;;40584:26;;40674:6;;40682:3;;40687:6;;40695:15;;40626:85;:::i;:::-;;;;;;;;-1:-1:-1;;40729:9:0;;-1:-1:-1;;;;;40729:9:0;40182:564;;;;;;;:::o;-1:-1:-1:-;;;;;;;;:::o;14:173:1:-;82:20;;-1:-1:-1;;;;;131:31:1;;121:42;;111:70;;177:1;174;167:12;111:70;14:173;;;:::o;192:127::-;253:10;248:3;244:20;241:1;234:31;284:4;281:1;274:15;308:4;305:1;298:15;324:1506;441:6;449;457;465;473;526:3;514:9;505:7;501:23;497:33;494:53;;;543:1;540;533:12;494:53;566:29;585:9;566:29;:::i;:::-;556:39;;614:2;635:38;669:2;658:9;654:18;635:38;:::i;:::-;625:48;;692:38;726:2;715:9;711:18;692:38;:::i;:::-;682:48;;780:2;769:9;765:18;752:32;827:5;820:13;813:21;806:5;803:32;793:60;;849:1;846;839:12;793:60;872:5;-1:-1:-1;928:3:1;913:19;;900:33;952:18;982:14;;;979:34;;;1009:1;1006;999:12;979:34;1047:6;1036:9;1032:22;1022:32;;1092:7;1085:4;1081:2;1077:13;1073:27;1063:55;;1114:1;1111;1104:12;1063:55;1150:2;1137:16;1172:2;1168;1165:10;1162:36;;;1178:18;;:::i;:::-;1224:2;1221:1;1217:10;1256:2;1250:9;1319:2;1315:7;1310:2;1306;1302:11;1298:25;1290:6;1286:38;1374:6;1362:10;1359:22;1354:2;1342:10;1339:18;1336:46;1333:72;;;1385:18;;:::i;:::-;1421:2;1414:22;1471:18;;;1505:15;;;;-1:-1:-1;1547:11:1;;;1543:20;;;1575:19;;;1572:39;;;1607:1;1604;1597:12;1572:39;1631:11;;;;1651:148;1667:6;1662:3;1659:15;1651:148;;;1733:23;1752:3;1733:23;:::i;:::-;1721:36;;1684:12;;;;1777;;;;1651:148;;;1818:6;1808:16;;;;;;;;324:1506;;;;;;;;:::o;2043:461::-;2096:3;2134:5;2128:12;2161:6;2156:3;2149:19;2187:4;2216:2;2211:3;2207:12;2200:19;;2253:2;2246:5;2242:14;2274:1;2284:195;2298:6;2295:1;2292:13;2284:195;;;2363:13;;-1:-1:-1;;;;;2359:39:1;2347:52;;2419:12;;;;2454:15;;;;2395:1;2313:9;2284:195;;;-1:-1:-1;2495:3:1;;2043:461;-1:-1:-1;;;;;2043:461:1:o;2509:704::-;-1:-1:-1;;;;;2860:15:1;;;2842:34;;2912:15;;;2907:2;2892:18;;2885:43;2964:15;;;2959:2;2944:18;;2937:43;3016:15;;3011:2;2996:18;;2989:43;3076:14;;3069:22;3063:3;3048:19;;3041:51;3129:3;2822;3108:19;;3101:32;;;2785:4;;3150:57;;3187:19;;3179:6;3150:57;:::i;:::-;3142:65;2509:704;-1:-1:-1;;;;;;;;2509:704:1:o;3218:623::-;-1:-1:-1;;;;;3541:15:1;;;3523:34;;3593:15;;;3588:2;3573:18;;3566:43;3645:15;;3640:2;3625:18;;3618:43;3704:14;;3697:22;3692:2;3677:18;;3670:50;3503:3;3751;3736:19;;3729:32;;;3466:4;;3778:57;;3815:19;;3807:6;3778:57;:::i;:::-;3770:65;3218:623;-1:-1:-1;;;;;;;3218:623:1:o
Swarm Source
ipfs://039fc786cf5482341dd9c1bf214979e7f2827e37b56f2c58d277fc0106a81343
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Validator ID :
0 FTM
Amount Staked
0
Amount Delegated
0
Staking Total
0
Staking Start Epoch
0
Staking Start Time
0
Proof of Importance
0
Origination Score
0
Validation Score
0
Active
0
Online
0
Downtime
0 s
Address | Amount | claimed Rewards | Created On Epoch | Created On |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.