Contract Overview
My Name Tag:
Not Available, login to update
[ Download CSV Export ]
Contract Name:
DystVoter
Compiler Version
v0.8.13+commit.abaa5c0e
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import "../../interface/IVe.sol"; import "../../interface/IVoter.sol"; import "../../interface/IERC20.sol"; import "../../interface/IERC721.sol"; import "../../interface/IGauge.sol"; import "../../interface/IFactory.sol"; import "../../interface/IPair.sol"; import "../../interface/IBribeFactory.sol"; import "../../interface/IGaugeFactory.sol"; import "../../interface/IMinter.sol"; import "../../interface/IBribe.sol"; import "../../interface/IMultiRewardsPool.sol"; import "../Reentrancy.sol"; import "../../lib/SafeERC20.sol"; contract DystVoter is IVoter, Reentrancy { using SafeERC20 for IERC20; /// @dev The ve token that governs these contracts address public immutable override ve; /// @dev DystFactory address public immutable factory; address public immutable token; address public immutable gaugeFactory; address public immutable bribeFactory; /// @dev Rewards are released over 7 days uint internal constant DURATION = 7 days; address public minter; /// @dev Total voting weight uint public totalWeight; /// @dev All pools viable for incentives address[] public pools; /// @dev pool => gauge mapping(address => address) public gauges; /// @dev gauge => pool mapping(address => address) public poolForGauge; /// @dev gauge => bribe mapping(address => address) public bribes; /// @dev pool => weight mapping(address => int256) public weights; /// @dev nft => pool => votes mapping(uint => mapping(address => int256)) public votes; /// @dev nft => pools mapping(uint => address[]) public poolVote; /// @dev nft => total voting weight of user mapping(uint => uint) public usedWeights; mapping(address => bool) public isGauge; mapping(address => bool) public isWhitelisted; uint public index; mapping(address => uint) public supplyIndex; mapping(address => uint) public claimable; event GaugeCreated(address indexed gauge, address creator, address indexed bribe, address indexed pool); event Voted(address indexed voter, uint tokenId, int256 weight); event Abstained(uint tokenId, int256 weight); event Deposit(address indexed lp, address indexed gauge, uint tokenId, uint amount); event Withdraw(address indexed lp, address indexed gauge, uint tokenId, uint amount); event NotifyReward(address indexed sender, address indexed reward, uint amount); event DistributeReward(address indexed sender, address indexed gauge, uint amount); event Attach(address indexed owner, address indexed gauge, uint tokenId); event Detach(address indexed owner, address indexed gauge, uint tokenId); event Whitelisted(address indexed whitelister, address indexed token); constructor(address _ve, address _factory, address _gaugeFactory, address _bribeFactory) { ve = _ve; factory = _factory; token = IVe(_ve).token(); gaugeFactory = _gaugeFactory; bribeFactory = _bribeFactory; minter = msg.sender; } function initialize(address[] memory _tokens, address _minter) external { require(msg.sender == minter, "!minter"); for (uint i = 0; i < _tokens.length; i++) { _whitelist(_tokens[i]); } minter = _minter; } /// @dev Amount of tokens required to be hold for whitelisting. function listingFee() external view returns (uint) { return _listingFee(); } /// @dev 20% of circulation supply. function _listingFee() internal view returns (uint) { return (IERC20(token).totalSupply() - IERC20(ve).totalSupply()) / 5; } /// @dev Remove all votes for given tokenId. function reset(uint _tokenId) external { require(IVe(ve).isApprovedOrOwner(msg.sender, _tokenId), "!owner"); _reset(_tokenId); IVe(ve).abstain(_tokenId); } function _reset(uint _tokenId) internal { address[] storage _poolVote = poolVote[_tokenId]; uint _poolVoteCnt = _poolVote.length; int256 _totalWeight = 0; for (uint i = 0; i < _poolVoteCnt; i ++) { address _pool = _poolVote[i]; int256 _votes = votes[_tokenId][_pool]; _updateFor(gauges[_pool]); weights[_pool] -= _votes; votes[_tokenId][_pool] -= _votes; if (_votes > 0) { IBribe(bribes[gauges[_pool]])._withdraw(uint(_votes), _tokenId); _totalWeight += _votes; } else { _totalWeight -= _votes; } emit Abstained(_tokenId, _votes); } totalWeight -= uint(_totalWeight); usedWeights[_tokenId] = 0; delete poolVote[_tokenId]; } /// @dev Resubmit exist votes for given token. For internal purposes. function poke(uint _tokenId) external { address[] memory _poolVote = poolVote[_tokenId]; uint _poolCnt = _poolVote.length; int256[] memory _weights = new int256[](_poolCnt); for (uint i = 0; i < _poolCnt; i ++) { _weights[i] = votes[_tokenId][_poolVote[i]]; } _vote(_tokenId, _poolVote, _weights); } function _vote(uint _tokenId, address[] memory _poolVote, int256[] memory _weights) internal { _reset(_tokenId); uint _poolCnt = _poolVote.length; int256 _weight = int256(IVe(ve).balanceOfNFT(_tokenId)); int256 _totalVoteWeight = 0; int256 _totalWeight = 0; int256 _usedWeight = 0; for (uint i = 0; i < _poolCnt; i++) { _totalVoteWeight += _weights[i] > 0 ? _weights[i] : - _weights[i]; } for (uint i = 0; i < _poolCnt; i++) { address _pool = _poolVote[i]; address _gauge = gauges[_pool]; int256 _poolWeight = _weights[i] * _weight / _totalVoteWeight; require(votes[_tokenId][_pool] == 0, "duplicate pool"); require(_poolWeight != 0, "zero power"); _updateFor(_gauge); poolVote[_tokenId].push(_pool); weights[_pool] += _poolWeight; votes[_tokenId][_pool] += _poolWeight; if (_poolWeight > 0) { IBribe(bribes[_gauge])._deposit(uint(_poolWeight), _tokenId); } else { _poolWeight = - _poolWeight; } _usedWeight += _poolWeight; _totalWeight += _poolWeight; emit Voted(msg.sender, _tokenId, _poolWeight); } if (_usedWeight > 0) IVe(ve).voting(_tokenId); totalWeight += uint(_totalWeight); usedWeights[_tokenId] = uint(_usedWeight); } /// @dev Vote for given pools using a vote power of given tokenId. Reset previous votes. function vote(uint tokenId, address[] calldata _poolVote, int256[] calldata _weights) external { require(IVe(ve).isApprovedOrOwner(msg.sender, tokenId), "!owner"); require(_poolVote.length == _weights.length, "!arrays"); _vote(tokenId, _poolVote, _weights); } /// @dev Add token to whitelist. Only pools with whitelisted tokens can be added to gauge. function whitelist(address _token, uint _tokenId) external { require(_tokenId > 0, "!token"); require(msg.sender == IERC721(ve).ownerOf(_tokenId), "!owner"); require(IVe(ve).balanceOfNFT(_tokenId) > _listingFee(), "!power"); _whitelist(_token); } function _whitelist(address _token) internal { require(!isWhitelisted[_token], "already whitelisted"); isWhitelisted[_token] = true; emit Whitelisted(msg.sender, _token); } /// @dev Add a token to a gauge/bribe as possible reward. function registerRewardToken(address _token, address _gaugeOrBribe, uint _tokenId) external { require(_tokenId > 0, "!token"); require(msg.sender == IERC721(ve).ownerOf(_tokenId), "!owner"); require(IVe(ve).balanceOfNFT(_tokenId) > _listingFee(), "!power"); IMultiRewardsPool(_gaugeOrBribe).registerRewardToken(_token); } /// @dev Remove a token from a gauge/bribe allowed rewards list. function removeRewardToken(address _token, address _gaugeOrBribe, uint _tokenId) external { require(_tokenId > 0, "!token"); require(msg.sender == IERC721(ve).ownerOf(_tokenId), "!owner"); require(IVe(ve).balanceOfNFT(_tokenId) > _listingFee(), "!power"); IMultiRewardsPool(_gaugeOrBribe).removeRewardToken(_token); } /// @dev Create gauge for given pool. Only for a pool with whitelisted tokens. function createGauge(address _pool) external returns (address) { require(gauges[_pool] == address(0x0), "exists"); require(IFactory(factory).isPair(_pool), "!pool"); (address tokenA, address tokenB) = IPair(_pool).tokens(); require(isWhitelisted[tokenA] && isWhitelisted[tokenB], "!whitelisted"); address[] memory allowedRewards = new address[](3); allowedRewards[0] = tokenA; allowedRewards[1] = tokenB; if (token != tokenA && token != tokenB) { allowedRewards[2] = token; } address _bribe = IBribeFactory(bribeFactory).createBribe(allowedRewards); address _gauge = IGaugeFactory(gaugeFactory).createGauge(_pool, _bribe, ve, allowedRewards); IERC20(token).safeIncreaseAllowance(_gauge, type(uint).max); bribes[_gauge] = _bribe; gauges[_pool] = _gauge; poolForGauge[_gauge] = _pool; isGauge[_gauge] = true; _updateFor(_gauge); pools.push(_pool); emit GaugeCreated(_gauge, msg.sender, _bribe, _pool); return _gauge; } /// @dev A gauge should be able to attach a token for preventing transfers/withdraws. function attachTokenToGauge(uint tokenId, address account) external override { require(isGauge[msg.sender], "!gauge"); if (tokenId > 0) { IVe(ve).attachToken(tokenId); } emit Attach(account, msg.sender, tokenId); } /// @dev Emit deposit event for easily handling external actions. function emitDeposit(uint tokenId, address account, uint amount) external override { require(isGauge[msg.sender], "!gauge"); emit Deposit(account, msg.sender, tokenId, amount); } /// @dev Detach given token. function detachTokenFromGauge(uint tokenId, address account) external override { require(isGauge[msg.sender], "!gauge"); if (tokenId > 0) { IVe(ve).detachToken(tokenId); } emit Detach(account, msg.sender, tokenId); } /// @dev Emit withdraw event for easily handling external actions. function emitWithdraw(uint tokenId, address account, uint amount) external override { require(isGauge[msg.sender], "!gauge"); emit Withdraw(account, msg.sender, tokenId, amount); } /// @dev Length of pools function poolsLength() external view returns (uint) { return pools.length; } /// @dev Add rewards to this contract. Usually it is DystMinter. function notifyRewardAmount(uint amount) external override { require(amount != 0, "zero amount"); uint _totalWeight = totalWeight; // without votes rewards can not be added require(_totalWeight != 0, "!weights"); // transfer the distro in IERC20(token).safeTransferFrom(msg.sender, address(this), amount); // 1e18 adjustment is removed during claim uint _ratio = amount * 1e18 / _totalWeight; if (_ratio > 0) { index += _ratio; } emit NotifyReward(msg.sender, token, amount); } /// @dev Update given gauges. function updateFor(address[] memory _gauges) external { for (uint i = 0; i < _gauges.length; i++) { _updateFor(_gauges[i]); } } /// @dev Update gauges by indexes in a range. function updateForRange(uint start, uint end) public { for (uint i = start; i < end; i++) { _updateFor(gauges[pools[i]]); } } /// @dev Update all gauges. function updateAll() external { updateForRange(0, pools.length); } /// @dev Update reward info for given gauge. function updateGauge(address _gauge) external { _updateFor(_gauge); } function _updateFor(address _gauge) internal { address _pool = poolForGauge[_gauge]; int256 _supplied = weights[_pool]; if (_supplied > 0) { uint _supplyIndex = supplyIndex[_gauge]; // get global index for accumulated distro uint _index = index; // update _gauge current position to global position supplyIndex[_gauge] = _index; // see if there is any difference that need to be accrued uint _delta = _index - _supplyIndex; if (_delta > 0) { // add accrued difference for each supplied token uint _share = uint(_supplied) * _delta / 1e18; claimable[_gauge] += _share; } } else { // new users are set to the default global state supplyIndex[_gauge] = index; } } /// @dev Batch claim rewards from given gauges. function claimRewards(address[] memory _gauges, address[][] memory _tokens) external { for (uint i = 0; i < _gauges.length; i++) { IGauge(_gauges[i]).getReward(msg.sender, _tokens[i]); } } /// @dev Batch claim rewards from given bribe contracts for given tokenId. function claimBribes(address[] memory _bribes, address[][] memory _tokens, uint _tokenId) external { require(IVe(ve).isApprovedOrOwner(msg.sender, _tokenId), "!owner"); for (uint i = 0; i < _bribes.length; i++) { IBribe(_bribes[i]).getRewardForOwner(_tokenId, _tokens[i]); } } /// @dev Claim fees from given bribes. function claimFees(address[] memory _bribes, address[][] memory _tokens, uint _tokenId) external { require(IVe(ve).isApprovedOrOwner(msg.sender, _tokenId), "!owner"); for (uint i = 0; i < _bribes.length; i++) { IBribe(_bribes[i]).getRewardForOwner(_tokenId, _tokens[i]); } } /// @dev Move fees from deposited pools to bribes for given gauges. function distributeFees(address[] memory _gauges) external { for (uint i = 0; i < _gauges.length; i++) { IGauge(_gauges[i]).claimFees(); } } /// @dev Get emission from minter and notify rewards for given gauge. function distribute(address _gauge) external override { _distribute(_gauge); } function _distribute(address _gauge) internal lock { IMinter(minter).updatePeriod(); _updateFor(_gauge); uint _claimable = claimable[_gauge]; if (_claimable > IMultiRewardsPool(_gauge).left(token) && _claimable / DURATION > 0) { claimable[_gauge] = 0; IGauge(_gauge).notifyRewardAmount(token, _claimable); emit DistributeReward(msg.sender, _gauge, _claimable); } } /// @dev Distribute rewards for all pools. function distributeAll() external { uint length = pools.length; for (uint x; x < length; x++) { _distribute(gauges[pools[x]]); } } function distributeForPoolsInRange(uint start, uint finish) external { for (uint x = start; x < finish; x++) { _distribute(gauges[pools[x]]); } } function distributeForGauges(address[] memory _gauges) external { for (uint x = 0; x < _gauges.length; x++) { _distribute(_gauges[x]); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; interface IVe { enum DepositType { DEPOSIT_FOR_TYPE, CREATE_LOCK_TYPE, INCREASE_LOCK_AMOUNT, INCREASE_UNLOCK_TIME, MERGE_TYPE } struct Point { int128 bias; int128 slope; // # -dweight / dt uint ts; uint blk; // block } /* We cannot really do block numbers per se b/c slope is per time, not per block * and per block could be fairly bad b/c Ethereum changes blocktimes. * What we can do is to extrapolate ***At functions */ struct LockedBalance { int128 amount; uint end; } function token() external view returns (address); function balanceOfNFT(uint) external view returns (uint); function isApprovedOrOwner(address, uint) external view returns (bool); function createLockFor(uint, uint, address) external returns (uint); function userPointEpoch(uint tokenId) external view returns (uint); function epoch() external view returns (uint); function userPointHistory(uint tokenId, uint loc) external view returns (Point memory); function pointHistory(uint loc) external view returns (Point memory); function checkpoint() external; function depositFor(uint tokenId, uint value) external; function attachToken(uint tokenId) external; function detachToken(uint tokenId) external; function voting(uint tokenId) external; function abstain(uint tokenId) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; interface IVoter { function ve() external view returns (address); function attachTokenToGauge(uint _tokenId, address account) external; 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 distribute(address _gauge) external; function notifyRewardAmount(uint amount) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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 `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, 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 `sender` to `recipient` 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 sender, address recipient, uint256 amount ) external returns (bool); /** * @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); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import "./IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; interface IGauge { function notifyRewardAmount(address token, uint amount) external; function getReward(address account, address[] memory tokens) external; function claimFees() external returns (uint claimed0, uint claimed1); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; interface IFactory { function treasury() external view returns (address); function isPair(address pair) external view returns (bool); function getInitializable() external view returns (address, address, bool); function isPaused() external view returns (bool); function pairCodeHash() external pure returns (bytes32); function getPair(address tokenA, address token, bool stable) external view returns (address); function createPair(address tokenA, address tokenB, bool stable) external returns (address pair); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; interface IPair { // Structure to capture time period obervations every 30 minutes, used for local oracles struct Observation { uint timestamp; uint reserve0Cumulative; uint reserve1Cumulative; } 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 (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast); function getAmountOut(uint, address) external view returns (uint); function claimFees() external returns (uint, uint); function tokens() external returns (address, address); function token0() external returns (address); function token1() external returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; interface IBribeFactory { function createBribe(address[] memory _allowedRewardTokens) external returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; interface IGaugeFactory { function createGauge( address _pool, address _bribe, address _ve, address[] memory _allowedRewardTokens ) external returns (address); function createGaugeSingle( address _pool, address _bribe, address _ve, address _voter, address[] memory _allowedRewardTokens ) external returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; interface IMinter { function updatePeriod() external returns (uint); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; interface IBribe { function notifyRewardAmount(address token, uint amount) external; function _deposit(uint amount, uint tokenId) external; function _withdraw(uint amount, uint tokenId) external; function getRewardForOwner(uint tokenId, address[] memory tokens) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; interface IMultiRewardsPool { function underlying() external view returns (address); function derivedSupply() external view returns (uint); function derivedBalances(address account) external view returns (uint); function totalSupply() external view returns (uint); function balanceOf(address account) external view returns (uint); function rewardTokens(uint id) external view returns (address); function isRewardToken(address token) external view returns (bool); function rewardTokensLength() external view returns (uint); function derivedBalance(address account) external view returns (uint); function left(address token) external view returns (uint); function earned(address token, address account) external view returns (uint); function registerRewardToken(address token) external; function removeRewardToken(address token) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; abstract contract Reentrancy { /// @dev simple re-entrancy check uint internal _unlocked = 1; modifier lock() { require(_unlocked == 1, "Reentrant call"); _unlocked = 2; _; _unlocked = 1; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.13; import "../interface/IERC20.sol"; import "./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; function safeTransfer( IERC20 token, address to, uint value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint value ) internal { uint newAllowance = token.allowance(address(this), spender) + 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. 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"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol) pragma solidity ^0.8.13; /** * @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 * ==== * * [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; } function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason 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 { // 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 assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_ve","type":"address"},{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_gaugeFactory","type":"address"},{"internalType":"address","name":"_bribeFactory","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"int256","name":"weight","type":"int256"}],"name":"Abstained","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"gauge","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Attach","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"lp","type":"address"},{"indexed":true,"internalType":"address","name":"gauge","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"gauge","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Detach","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"gauge","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"DistributeReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"gauge","type":"address"},{"indexed":false,"internalType":"address","name":"creator","type":"address"},{"indexed":true,"internalType":"address","name":"bribe","type":"address"},{"indexed":true,"internalType":"address","name":"pool","type":"address"}],"name":"GaugeCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"reward","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"NotifyReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"voter","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"int256","name":"weight","type":"int256"}],"name":"Voted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"whitelister","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"}],"name":"Whitelisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"lp","type":"address"},{"indexed":true,"internalType":"address","name":"gauge","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"account","type":"address"}],"name":"attachTokenToGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"bribeFactory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"bribes","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_bribes","type":"address[]"},{"internalType":"address[][]","name":"_tokens","type":"address[][]"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"claimBribes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_bribes","type":"address[]"},{"internalType":"address[][]","name":"_tokens","type":"address[][]"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"claimFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_gauges","type":"address[]"},{"internalType":"address[][]","name":"_tokens","type":"address[][]"}],"name":"claimRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"claimable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_pool","type":"address"}],"name":"createGauge","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"account","type":"address"}],"name":"detachTokenFromGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gauge","type":"address"}],"name":"distribute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"distributeAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_gauges","type":"address[]"}],"name":"distributeFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_gauges","type":"address[]"}],"name":"distributeForGauges","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"finish","type":"uint256"}],"name":"distributeForPoolsInRange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"emitDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"emitWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gaugeFactory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"gauges","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"index","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_tokens","type":"address[]"},{"internalType":"address","name":"_minter","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isGauge","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"listingFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"notifyRewardAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"poke","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"poolForGauge","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"poolVote","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"pools","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_gaugeOrBribe","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"registerRewardToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_gaugeOrBribe","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"removeRewardToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"reset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"supplyIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalWeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"updateAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_gauges","type":"address[]"}],"name":"updateFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"end","type":"uint256"}],"name":"updateForRange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gauge","type":"address"}],"name":"updateGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"usedWeights","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ve","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address[]","name":"_poolVote","type":"address[]"},{"internalType":"int256[]","name":"_weights","type":"int256[]"}],"name":"vote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"votes","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"weights","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"whitelist","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
61012060405260016000553480156200001757600080fd5b5060405162003bbe38038062003bbe8339810160408190526200003a9162000102565b6001600160a01b03808516608081905290841660a05260408051637e062a3560e11b8152905163fc0c546a916004808201926020929091908290030181865afa1580156200008c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000b291906200015f565b6001600160a01b0390811660c05291821660e05216610100525050600180546001600160a01b0319163317905562000184565b80516001600160a01b0381168114620000fd57600080fd5b919050565b600080600080608085870312156200011957600080fd5b6200012485620000e5565b93506200013460208601620000e5565b92506200014460408601620000e5565b91506200015460608601620000e5565b905092959194509250565b6000602082840312156200017257600080fd5b6200017d82620000e5565b9392505050565b60805160a05160c05160e0516101005161392a62000294600039600081816106c601526119430152600081816102f801526119c10152600081816106ed01528181610b3001528181610ba70152818161186b015281816118a4015281816118d601528181611a83015281816121da015281816122960152612b8c015260008181610608015261166301526000818161031f01528181610838015281816108ef01528181610c4801528181610e3a01528181610efb0152818161105b015281816111e5015281816112bb01528181611431015281816114f2015281816119f201528181611d9f01528181611e6001528181611fac0152818161257d015281816129560152612b0a015261392a6000f3fe608060405234801561001057600080fd5b50600436106102955760003560e01c80636ecbe38a11610167578063ac4afa38116100ce578063ddbe883c11610087578063ddbe883c1461067b578063e380fcad1461068e578063ea94ee44146106ae578063eb4a78e0146106c1578063fc0c546a146106e8578063fecdad601461070f57600080fd5b8063ac4afa38146105c7578063b9a09fd5146105da578063c45a015514610603578063c527ee1f1461062a578063d23254b41461063d578063d560b0d71461066857600080fd5b8063a5f4301e11610120578063a5f4301e14610522578063a61c713a14610535578063a7cac84614610548578063a86a366d14610568578063a8c5d95a1461057b578063aa79979b146105a457600080fd5b80636ecbe38a146104ad5780637715ee75146104c057806379e93824146104d357806396c82e57146104f357806398fc55d8146104fc5780639b6a9d721461050f57600080fd5b80633c6b16ab1161020b57806353d78693116101c457806353d786931461045157806353f38e6b1461045957806363453ae11461046c578063666256aa1461047f578063698473e3146104925780636a1b7ecc146104a557600080fd5b80633c6b16ab146103dd578063402914f5146103f0578063411b1f7714610410578063436596c414610423578063462d0b2e1461042b5780634c6e62b61461043e57600080fd5b806320b1cb6f1161025d57806320b1cb6f146103565780632716ae66146103695780632986c0e51461037b578063310bd74b1461038457806332145f90146103975780633af32abf146103aa57600080fd5b806306d6a1b21461029a57806307546172146102e05780630d52333c146102f35780631f8507161461031a5780632025e9b814610341575b600080fd5b6102c36102a8366004612fda565b6005602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6001546102c3906001600160a01b031681565b6102c37f000000000000000000000000000000000000000000000000000000000000000081565b6102c37f000000000000000000000000000000000000000000000000000000000000000081565b61035461034f3660046130d6565b610722565b005b610354610364366004613193565b610766565b6003545b6040519081526020016102d7565b61036d600d5481565b6103546103923660046131f7565b61081c565b6103546103a53660046131f7565b610956565b6103cd6103b8366004612fda565b600c6020526000908152604090205460ff1681565b60405190151581526020016102d7565b6103546103eb3660046131f7565b610aa6565b61036d6103fe366004612fda565b600f6020526000908152604090205481565b61035461041e366004613210565b610bfd565b610354610cf2565b610354610439366004613240565b610d5c565b61035461044c366004613287565b610e04565b610354610fec565b6103546104673660046132c8565b610ffd565b61035461047a366004612fda565b611033565b61035461048d3660046132ea565b61103f565b6103546104a0366004613210565b61119b565b61036d611287565b6103546104bb366004612fda565b611296565b6103546104ce3660046132ea565b61129f565b61036d6104e13660046131f7565b600a6020526000908152604090205481565b61036d60025481565b61035461050a366004613357565b6113fb565b61035461051d3660046132c8565b61158b565b6102c3610530366004612fda565b6115f1565b610354610543366004613383565b611bb8565b61036d610556366004612fda565b60076020526000908152604090205481565b6102c36105763660046132c8565b611c2a565b6102c3610589366004612fda565b6006602052600090815260409020546001600160a01b031681565b6103cd6105b2366004612fda565b600b6020526000908152604090205460ff1681565b6102c36105d53660046131f7565b611c62565b6102c36105e8366004612fda565b6004602052600090815260409020546001600160a01b031681565b6102c37f000000000000000000000000000000000000000000000000000000000000000081565b6103546106383660046130d6565b611c8c565b61036d61064b366004613210565b600860209081526000928352604080842090915290825290205481565b6103546106763660046130d6565b611d29565b610354610689366004613287565b611d69565b61036d61069c366004612fda565b600e6020526000908152604090205481565b6103546106bc366004613383565b611f1e565b6102c37f000000000000000000000000000000000000000000000000000000000000000081565b6102c37f000000000000000000000000000000000000000000000000000000000000000081565b61035461071d3660046133f6565b611f90565b60005b81518110156107625761075082828151811061074357610743613470565b60200260200101516120e2565b8061075a8161349c565b915050610725565b5050565b60005b82518110156108175782818151811061078457610784613470565b60200260200101516001600160a01b03166331279d3d338484815181106107ad576107ad613470565b60200260200101516040518363ffffffff1660e01b81526004016107d29291906134f9565b600060405180830381600087803b1580156107ec57600080fd5b505af1158015610800573d6000803e3d6000fd5b50505050808061080f9061349c565b915050610769565b505050565b60405163430c208160e01b8152336004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063430c208190604401602060405180830381865afa158015610887573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ab919061351d565b6108d05760405162461bcd60e51b81526004016108c79061353f565b60405180910390fd5b6108d98161234a565b60405163c1f0fb9f60e01b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063c1f0fb9f90602401600060405180830381600087803b15801561093b57600080fd5b505af115801561094f573d6000803e3d6000fd5b5050505050565b6000818152600960209081526040808320805482518185028101850190935280835291929091908301828280156109b657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610998575b5050505050905060008151905060008167ffffffffffffffff8111156109de576109de612ff7565b604051908082528060200260200182016040528015610a07578160200160208202803683370190505b50905060005b82811015610a9457600860008681526020019081526020016000206000858381518110610a3c57610a3c613470565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002054828281518110610a7757610a77613470565b602090810291909101015280610a8c8161349c565b915050610a0d565b50610aa0848483612559565b50505050565b80600003610ae45760405162461bcd60e51b815260206004820152600b60248201526a1e995c9bc8185b5bdd5b9d60aa1b60448201526064016108c7565b6002546000819003610b235760405162461bcd60e51b8152602060048201526008602482015267217765696768747360c01b60448201526064016108c7565b610b586001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163330856129ed565b600081610b6d84670de0b6b3a764000061355f565b610b779190613594565b90508015610b975780600d6000828254610b9191906135a8565b90915550505b6040518381526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169033907ff70d5c697de7ea828df48e5c4573cb2194c659f1901f70110c52b066dcf50826906020015b60405180910390a3505050565b336000908152600b602052604090205460ff16610c2c5760405162461bcd60e51b81526004016108c7906135c0565b8115610cad57604051634c3c15a760e11b8152600481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906398782b4e90602401600060405180830381600087803b158015610c9457600080fd5b505af1158015610ca8573d6000803e3d6000fd5b505050505b60405182815233906001600160a01b038316907fae268d9aab12f3605f58efd74fd3801fa812b03fdb44317eb70f46dff0e19e22906020015b60405180910390a35050565b60035460005b8181101561076257610d4a6004600060038481548110610d1a57610d1a613470565b60009182526020808320909101546001600160a01b039081168452908301939093526040909101902054166120e2565b80610d548161349c565b915050610cf8565b6001546001600160a01b03163314610da05760405162461bcd60e51b815260206004820152600760248201526610b6b4b73a32b960c91b60448201526064016108c7565b60005b8251811015610de057610dce838281518110610dc157610dc1613470565b6020026020010151612a58565b80610dd88161349c565b915050610da3565b50600180546001600160a01b0319166001600160a01b039290921691909117905550565b60008111610e245760405162461bcd60e51b81526004016108c7906135e0565b6040516331a9108f60e11b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690636352211e90602401602060405180830381865afa158015610e89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ead9190613600565b6001600160a01b0316336001600160a01b031614610edd5760405162461bcd60e51b81526004016108c79061353f565b610ee5612b04565b6040516339f890b560e21b8152600481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e7e242d490602401602060405180830381865afa158015610f4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6e919061361d565b11610f8b5760405162461bcd60e51b81526004016108c790613636565b604051631c8db79360e31b81526001600160a01b03848116600483015283169063e46dbc98906024015b600060405180830381600087803b158015610fcf57600080fd5b505af1158015610fe3573d6000803e3d6000fd5b50505050505050565b600354610ffb9060009061158b565b565b815b81811015610817576110216004600060038481548110610d1a57610d1a613470565b8061102b8161349c565b915050610fff565b61103c816120e2565b50565b60405163430c208160e01b8152336004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063430c208190604401602060405180830381865afa1580156110aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ce919061351d565b6110ea5760405162461bcd60e51b81526004016108c79061353f565b60005b8351811015610aa05783818151811061110857611108613470565b60200260200101516001600160a01b031663a7852afa8385848151811061113157611131613470565b60200260200101516040518363ffffffff1660e01b8152600401611156929190613656565b600060405180830381600087803b15801561117057600080fd5b505af1158015611184573d6000803e3d6000fd5b5050505080806111939061349c565b9150506110ed565b336000908152600b602052604090205460ff166111ca5760405162461bcd60e51b81526004016108c7906135c0565b811561124a576040516246b3bd60e81b8152600481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906346b3bd0090602401600060405180830381600087803b15801561123157600080fd5b505af1158015611245573d6000803e3d6000fd5b505050505b60405182815233906001600160a01b038316907f60940192810a6fb3bce3fd3e2e3a13fd6ccc7605e963fb87ee971aba829989bd90602001610ce6565b6000611291612b04565b905090565b61103c81612c20565b60405163430c208160e01b8152336004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063430c208190604401602060405180830381865afa15801561130a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061132e919061351d565b61134a5760405162461bcd60e51b81526004016108c79061353f565b60005b8351811015610aa05783818151811061136857611368613470565b60200260200101516001600160a01b031663a7852afa8385848151811061139157611391613470565b60200260200101516040518363ffffffff1660e01b81526004016113b6929190613656565b600060405180830381600087803b1580156113d057600080fd5b505af11580156113e4573d6000803e3d6000fd5b5050505080806113f39061349c565b91505061134d565b6000811161141b5760405162461bcd60e51b81526004016108c7906135e0565b6040516331a9108f60e11b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690636352211e90602401602060405180830381865afa158015611480573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114a49190613600565b6001600160a01b0316336001600160a01b0316146114d45760405162461bcd60e51b81526004016108c79061353f565b6114dc612b04565b6040516339f890b560e21b8152600481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e7e242d490602401602060405180830381865afa158015611541573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611565919061361d565b116115825760405162461bcd60e51b81526004016108c790613636565b61076282612a58565b815b81811015610817576115df60046000600384815481106115af576115af613470565b60009182526020808320909101546001600160a01b03908116845290830193909352604090910190205416612c20565b806115e98161349c565b91505061158d565b6001600160a01b03818116600090815260046020526040812054909116156116445760405162461bcd60e51b815260206004820152600660248201526565786973747360d01b60448201526064016108c7565b60405163e5e31b1360e01b81526001600160a01b0383811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063e5e31b1390602401602060405180830381865afa1580156116aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116ce919061351d565b6117025760405162461bcd60e51b8152602060048201526005602482015264085c1bdbdb60da1b60448201526064016108c7565b600080836001600160a01b0316639d63848a6040518163ffffffff1660e01b815260040160408051808303816000875af1158015611744573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611768919061366f565b6001600160a01b0382166000908152600c6020526040902054919350915060ff1680156117ad57506001600160a01b0381166000908152600c602052604090205460ff165b6117e85760405162461bcd60e51b815260206004820152600c60248201526b085dda1a5d195b1a5cdd195960a21b60448201526064016108c7565b6040805160038082526080820190925260009160208201606080368337019050509050828160008151811061181f5761181f613470565b60200260200101906001600160a01b031690816001600160a01b031681525050818160018151811061185357611853613470565b6001600160a01b0392831660209182029290920101527f00000000000000000000000000000000000000000000000000000000000000008116908416148015906118cf5750816001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614155b15611929577f00000000000000000000000000000000000000000000000000000000000000008160028151811061190857611908613470565b60200260200101906001600160a01b031690816001600160a01b0316815250505b60405163897cd6b360e01b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063897cd6b39061197890859060040161369e565b6020604051808303816000875af1158015611997573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119bb9190613600565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166358c14b6588847f0000000000000000000000000000000000000000000000000000000000000000876040518563ffffffff1660e01b8152600401611a3194939291906136b1565b6020604051808303816000875af1158015611a50573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a749190613600565b9050611aac6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001682600019612d04565b6001600160a01b03808216600081815260066020908152604080832080548689166001600160a01b031991821617909155948c16808452600483528184208054871686179055938352600582528083208054909516909317909355600b9092529020805460ff19166001179055611b2281612c20565b600380546001810182556000919091527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b0319166001600160a01b03898116918217909255604051338152909184811691908416907f48d3c521fd0d5541640f58c6d6381eed7cb2e8c9df421ae165a4f4c2d221ee0d9060200160405180910390a49695505050505050565b336000908152600b602052604090205460ff16611be75760405162461bcd60e51b81526004016108c7906135c0565b604080518481526020810183905233916001600160a01b038516917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d79101610bf0565b60096020528160005260406000208181548110611c4657600080fd5b6000918252602090912001546001600160a01b03169150829050565b60038181548110611c7257600080fd5b6000918252602090912001546001600160a01b0316905081565b60005b815181101561076257818181518110611caa57611caa613470565b60200260200101516001600160a01b031663d294f0936040518163ffffffff1660e01b815260040160408051808303816000875af1158015611cf0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d1491906136ef565b50508080611d219061349c565b915050611c8f565b60005b815181101561076257611d57828281518110611d4a57611d4a613470565b6020026020010151612c20565b80611d618161349c565b915050611d2c565b60008111611d895760405162461bcd60e51b81526004016108c7906135e0565b6040516331a9108f60e11b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690636352211e90602401602060405180830381865afa158015611dee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e129190613600565b6001600160a01b0316336001600160a01b031614611e425760405162461bcd60e51b81526004016108c79061353f565b611e4a612b04565b6040516339f890b560e21b8152600481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e7e242d490602401602060405180830381865afa158015611eaf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ed3919061361d565b11611ef05760405162461bcd60e51b81526004016108c790613636565b604051633d509c9760e01b81526001600160a01b038481166004830152831690633d509c9790602401610fb5565b336000908152600b602052604090205460ff16611f4d5760405162461bcd60e51b81526004016108c7906135c0565b604080518481526020810183905233916001600160a01b038516917ff341246adaac6f497bc2a656f546ab9e182111d630394f0c57c710a59a2cb5679101610bf0565b60405163430c208160e01b8152336004820152602481018690527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063430c208190604401602060405180830381865afa158015611ffb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061201f919061351d565b61203b5760405162461bcd60e51b81526004016108c79061353f565b8281146120745760405162461bcd60e51b81526020600482015260076024820152662161727261797360c81b60448201526064016108c7565b61094f858585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080890282810182019093528882529093508892508791829185019084908082843760009201919091525061255992505050565b6000546001146121255760405162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b60448201526064016108c7565b6002600081905550600160009054906101000a90046001600160a01b03166001600160a01b031663a83627de6040518163ffffffff1660e01b81526004016020604051808303816000875af1158015612182573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121a6919061361d565b506121b081612c20565b6001600160a01b038181166000818152600f602052604090819020549051634cde602960e11b81527f00000000000000000000000000000000000000000000000000000000000000009093166004840152916399bcc05290602401602060405180830381865afa158015612228573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061224c919061361d565b811180156122665750600061226462093a8083613594565b115b15612341576001600160a01b038281166000818152600f6020526040808220919091555163b66503cf60e01b81527f00000000000000000000000000000000000000000000000000000000000000009092166004830152602482018390529063b66503cf90604401600060405180830381600087803b1580156122e857600080fd5b505af11580156122fc573d6000803e3d6000fd5b50506040518381526001600160a01b03851692503391507f4fa9693cae526341d334e2862ca2413b2e503f1266255f9e0869fb36e6d89b179060200160405180910390a35b50506001600055565b600081815260096020526040812080549091805b8281101561251d57600084828154811061237a5761237a613470565b60009182526020808320909101548883526008825260408084206001600160a01b0392831680865290845281852054600490945293205492935090916123c09116612c20565b6001600160a01b038216600090815260076020526040812080548392906123e8908490613713565b909155505060008781526008602090815260408083206001600160a01b03861684529091528120805483929061241f908490613713565b909155505060008113156124c2576001600160a01b038281166000908152600460208181526040808420548516845260069091529182902054915163278afc8b60e21b8152908101849052602481018a9052911690639e2bf22c90604401600060405180830381600087803b15801561249757600080fd5b505af11580156124ab573d6000803e3d6000fd5b5050505080846124bb9190613752565b93506124cf565b6124cc8185613713565b93505b60408051888152602081018390527f6b3894ce60b9bbe9d93f1a4e6fc25b6b93cd8222e73ab6348d79c596f5b51de9910160405180910390a1505080806125159061349c565b91505061235e565b5080600260008282546125309190613793565b90915550506000848152600a6020908152604080832083905560099091528120610aa091612f93565b6125628361234a565b81516040516339f890b560e21b8152600481018590526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e7e242d490602401602060405180830381865afa1580156125cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125f0919061361d565b90506000806000805b8581101561268357600087828151811061261557612615613470565b60200260200101511361264a5786818151811061263457612634613470565b6020026020010151612645906137aa565b612665565b86818151811061265c5761265c613470565b60200260200101515b61266f9085613752565b93508061267b8161349c565b9150506125f9565b5060005b858110156129365760008882815181106126a3576126a3613470565b6020908102919091018101516001600160a01b038082166000908152600490935260408320548b51929450169190879089908c90879081106126e7576126e7613470565b60200260200101516126f991906137c6565b612703919061384b565b60008d81526008602090815260408083206001600160a01b0388168452909152902054909150156127675760405162461bcd60e51b815260206004820152600e60248201526d191d5c1b1a58d85d19481c1bdbdb60921b60448201526064016108c7565b806000036127a45760405162461bcd60e51b815260206004820152600a6024820152693d32b937903837bbb2b960b11b60448201526064016108c7565b6127ad82612c20565b60008c815260096020908152604080832080546001810182559084528284200180546001600160a01b0319166001600160a01b0388169081179091558352600790915281208054839290612802908490613752565b909155505060008c81526008602090815260408083206001600160a01b038716845290915281208054839290612839908490613752565b909155505060008113156128c0576001600160a01b038083166000908152600660205260409081902054905163f320772360e01b815260048101849052602481018f905291169063f320772390604401600060405180830381600087803b1580156128a357600080fd5b505af11580156128b7573d6000803e3d6000fd5b505050506128cc565b6128c9816137aa565b90505b6128d68186613752565b94506128e28187613752565b604080518e81526020810184905291975033917f1263a2295e53acd6ef8f655b8afc11fa0f2cf11925be7aa1757d741ef32a926c910160405180910390a2505050808061292e9061349c565b915050612687565b5060008113156129bb5760405163fd4a77f160e01b8152600481018990527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063fd4a77f190602401600060405180830381600087803b1580156129a257600080fd5b505af11580156129b6573d6000803e3d6000fd5b505050505b81600260008282546129cd91906135a8565b90915550506000978852600a602052604090972096909655505050505050565b6040516001600160a01b0380851660248301528316604482015260648101829052610aa09085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612db6565b6001600160a01b0381166000908152600c602052604090205460ff1615612ab75760405162461bcd60e51b8152602060048201526013602482015272185b1c9958591e481dda1a5d195b1a5cdd1959606a1b60448201526064016108c7565b6001600160a01b0381166000818152600c6020526040808220805460ff191660011790555133917f6661a7108aecd07864384529117d96c319c1163e3010c01390f6b704726e07de91a350565b600060057f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b8a919061361d565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612be8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c0c919061361d565b612c169190613793565b6112919190613594565b6001600160a01b0380821660009081526005602090815260408083205490931680835260079091529181205490811315612ce3576001600160a01b0383166000908152600e602052604081208054600d549182905591612c808383613793565b90508015612cdb576000670de0b6b3a7640000612c9d838761355f565b612ca79190613594565b6001600160a01b0388166000908152600f6020526040812080549293508392909190612cd49084906135a8565b9091555050505b505050505050565b600d546001600160a01b0384166000908152600e6020526040902055505050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa158015612d55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d79919061361d565b612d8391906135a8565b6040516001600160a01b038516602482015260448101829052909150610aa090859063095ea7b360e01b90606401612a21565b6000612e0b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612e889092919063ffffffff16565b8051909150156108175780806020019051810190612e29919061351d565b6108175760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016108c7565b60606001600160a01b0384163b612ee15760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016108c7565b600080856001600160a01b031685604051612efc91906138a5565b6000604051808303816000865af19150503d8060008114612f39576040519150601f19603f3d011682016040523d82523d6000602084013e612f3e565b606091505b5091509150612f4e828286612f5a565b925050505b9392505050565b60608315612f69575081612f53565b825115612f795782518084602001fd5b8160405162461bcd60e51b81526004016108c791906138c1565b508054600082559060005260206000209081019061103c91905b80821115612fc15760008155600101612fad565b5090565b6001600160a01b038116811461103c57600080fd5b600060208284031215612fec57600080fd5b8135612f5381612fc5565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561303657613036612ff7565b604052919050565b600067ffffffffffffffff82111561305857613058612ff7565b5060051b60200190565b600082601f83011261307357600080fd5b813560206130886130838361303e565b61300d565b82815260059290921b840181019181810190868411156130a757600080fd5b8286015b848110156130cb5780356130be81612fc5565b83529183019183016130ab565b509695505050505050565b6000602082840312156130e857600080fd5b813567ffffffffffffffff8111156130ff57600080fd5b61310b84828501613062565b949350505050565b600082601f83011261312457600080fd5b813560206131346130838361303e565b82815260059290921b8401810191818101908684111561315357600080fd5b8286015b848110156130cb57803567ffffffffffffffff8111156131775760008081fd5b6131858986838b0101613062565b845250918301918301613157565b600080604083850312156131a657600080fd5b823567ffffffffffffffff808211156131be57600080fd5b6131ca86838701613062565b935060208501359150808211156131e057600080fd5b506131ed85828601613113565b9150509250929050565b60006020828403121561320957600080fd5b5035919050565b6000806040838503121561322357600080fd5b82359150602083013561323581612fc5565b809150509250929050565b6000806040838503121561325357600080fd5b823567ffffffffffffffff81111561326a57600080fd5b61327685828601613062565b925050602083013561323581612fc5565b60008060006060848603121561329c57600080fd5b83356132a781612fc5565b925060208401356132b781612fc5565b929592945050506040919091013590565b600080604083850312156132db57600080fd5b50508035926020909101359150565b6000806000606084860312156132ff57600080fd5b833567ffffffffffffffff8082111561331757600080fd5b61332387838801613062565b9450602086013591508082111561333957600080fd5b5061334686828701613113565b925050604084013590509250925092565b6000806040838503121561336a57600080fd5b823561337581612fc5565b946020939093013593505050565b60008060006060848603121561339857600080fd5b8335925060208401356132b781612fc5565b60008083601f8401126133bc57600080fd5b50813567ffffffffffffffff8111156133d457600080fd5b6020830191508360208260051b85010111156133ef57600080fd5b9250929050565b60008060008060006060868803121561340e57600080fd5b85359450602086013567ffffffffffffffff8082111561342d57600080fd5b61343989838a016133aa565b9096509450604088013591508082111561345257600080fd5b5061345f888289016133aa565b969995985093965092949392505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016134ae576134ae613486565b5060010190565b600081518084526020808501945080840160005b838110156134ee5781516001600160a01b0316875295820195908201906001016134c9565b509495945050505050565b6001600160a01b038316815260406020820181905260009061310b908301846134b5565b60006020828403121561352f57600080fd5b81518015158114612f5357600080fd5b60208082526006908201526510b7bbb732b960d11b604082015260600190565b600081600019048311821515161561357957613579613486565b500290565b634e487b7160e01b600052601260045260246000fd5b6000826135a3576135a361357e565b500490565b600082198211156135bb576135bb613486565b500190565b60208082526006908201526521676175676560d01b604082015260600190565b60208082526006908201526510ba37b5b2b760d11b604082015260600190565b60006020828403121561361257600080fd5b8151612f5381612fc5565b60006020828403121561362f57600080fd5b5051919050565b60208082526006908201526510b837bbb2b960d11b604082015260600190565b82815260406020820152600061310b60408301846134b5565b6000806040838503121561368257600080fd5b825161368d81612fc5565b602084015190925061323581612fc5565b602081526000612f5360208301846134b5565b6001600160a01b0385811682528481166020830152831660408201526080606082018190526000906136e5908301846134b5565b9695505050505050565b6000806040838503121561370257600080fd5b505080516020909101519092909150565b60008083128015600160ff1b85018412161561373157613731613486565b6001600160ff1b038401831381161561374c5761374c613486565b50500390565b600080821280156001600160ff1b038490038513161561377457613774613486565b600160ff1b839003841281161561378d5761378d613486565b50500190565b6000828210156137a5576137a5613486565b500390565b6000600160ff1b82016137bf576137bf613486565b5060000390565b60006001600160ff1b03818413828413808216868404861116156137ec576137ec613486565b600160ff1b600087128281168783058912161561380b5761380b613486565b6000871292508782058712848416161561382757613827613486565b8785058712818416161561383d5761383d613486565b505050929093029392505050565b60008261385a5761385a61357e565b600160ff1b82146000198414161561387457613874613486565b500590565b60005b8381101561389457818101518382015260200161387c565b83811115610aa05750506000910152565b600082516138b7818460208701613879565b9190910192915050565b60208152600082518060208401526138e0816040850160208701613879565b601f01601f1916919091016040019291505056fea2646970667358221220b985fb2e298c45cc59b5ef3e4545428a44e1ac75ef2eb3b3748089622242580b64736f6c634300080d0033000000000000000000000000060fa7ad32c510f12550c7a967999810dafc56970000000000000000000000001d21db6cde1b18c7e47b0f7f42f4b3f68b9beec9000000000000000000000000719bfe5213af9c2523e9f46b86cc70eb8b7f530f0000000000000000000000007add42d9c53df14c1bc2507034f63b0ac924345f
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000060fa7ad32c510f12550c7a967999810dafc56970000000000000000000000001d21db6cde1b18c7e47b0f7f42f4b3f68b9beec9000000000000000000000000719bfe5213af9c2523e9f46b86cc70eb8b7f530f0000000000000000000000007add42d9c53df14c1bc2507034f63b0ac924345f
-----Decoded View---------------
Arg [0] : _ve (address): 0x060fa7ad32c510f12550c7a967999810dafc5697
Arg [1] : _factory (address): 0x1d21db6cde1b18c7e47b0f7f42f4b3f68b9beec9
Arg [2] : _gaugeFactory (address): 0x719bfe5213af9c2523e9f46b86cc70eb8b7f530f
Arg [3] : _bribeFactory (address): 0x7add42d9c53df14c1bc2507034f63b0ac924345f
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000060fa7ad32c510f12550c7a967999810dafc5697
Arg [1] : 0000000000000000000000001d21db6cde1b18c7e47b0f7f42f4b3f68b9beec9
Arg [2] : 000000000000000000000000719bfe5213af9c2523e9f46b86cc70eb8b7f530f
Arg [3] : 0000000000000000000000007add42d9c53df14c1bc2507034f63b0ac924345f
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.