Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x61016060 | 18072391 | 405 days ago | IN | 0 ETH | 0.03813004 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
StakingExtension
Compiler Version
v0.7.6+commit.7338295f
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.7.6; pragma abicoder v2; import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol"; import { StakingV4Storage } from "./StakingStorage.sol"; import { IStakingExtension } from "./IStakingExtension.sol"; import { TokenUtils } from "../utils/TokenUtils.sol"; import { IGraphToken } from "../token/IGraphToken.sol"; import { GraphUpgradeable } from "../upgrades/GraphUpgradeable.sol"; import { Stakes } from "./libs/Stakes.sol"; import { IStakingData } from "./IStakingData.sol"; import { MathUtils } from "./libs/MathUtils.sol"; /** * @title StakingExtension contract * @dev This contract provides the logic to manage delegations and other Staking * extension features (e.g. storage getters). It is meant to be called through delegatecall from the * Staking contract, and is only kept separate to keep the Staking contract size * within limits. */ contract StakingExtension is StakingV4Storage, GraphUpgradeable, IStakingExtension { using SafeMath for uint256; using Stakes for Stakes.Indexer; /// @dev 100% in parts per million uint32 private constant MAX_PPM = 1000000; /** * @dev Check if the caller is the slasher. */ modifier onlySlasher() { require(__slashers[msg.sender] == true, "!slasher"); _; } /** * @notice Initialize the StakingExtension contract * @dev This function is meant to be delegatecalled from the Staking contract's * initialize() function, so it uses the same access control check to ensure it is * being called by the Staking implementation as part of the proxy upgrade process. * @param _delegationUnbondingPeriod Delegation unbonding period in blocks * @param _cooldownBlocks Minimum time between changes to delegation parameters, in blocks * @param _delegationRatio Delegation capacity multiplier (e.g. 10 means 10x the indexer stake) * @param _delegationTaxPercentage Percentage of delegated tokens to burn as delegation tax, expressed in parts per million */ function initialize( uint32 _delegationUnbondingPeriod, uint32 _cooldownBlocks, uint32 _delegationRatio, uint32 _delegationTaxPercentage ) external onlyImpl { _setDelegationUnbondingPeriod(_delegationUnbondingPeriod); _setDelegationParametersCooldown(_cooldownBlocks); _setDelegationRatio(_delegationRatio); _setDelegationTaxPercentage(_delegationTaxPercentage); } /** * @notice Set a delegation tax percentage to burn when delegated funds are deposited. * @dev This function is only callable by the governor * @param _percentage Percentage of delegated tokens to burn as delegation tax, expressed in parts per million */ function setDelegationTaxPercentage(uint32 _percentage) external override onlyGovernor { _setDelegationTaxPercentage(_percentage); } /** * @notice Set the delegation ratio. * If set to 10 it means the indexer can use up to 10x the indexer staked amount * from their delegated tokens * @dev This function is only callable by the governor * @param _delegationRatio Delegation capacity multiplier */ function setDelegationRatio(uint32 _delegationRatio) external override onlyGovernor { _setDelegationRatio(_delegationRatio); } /** * @notice Set the minimum time in blocks an indexer needs to wait to change delegation parameters. * Indexers can set a custom amount time for their own cooldown, but it must be greater than this. * @dev This function is only callable by the governor * @param _blocks Number of blocks to set the delegation parameters cooldown period */ function setDelegationParametersCooldown(uint32 _blocks) external override onlyGovernor { _setDelegationParametersCooldown(_blocks); } /** * @notice Set the time, in epochs, a Delegator needs to wait to withdraw tokens after undelegating. * @dev This function is only callable by the governor * @param _delegationUnbondingPeriod Period in epochs to wait for token withdrawals after undelegating */ function setDelegationUnbondingPeriod(uint32 _delegationUnbondingPeriod) external override onlyGovernor { _setDelegationUnbondingPeriod(_delegationUnbondingPeriod); } /** * @notice Set or unset an address as allowed slasher. * @param _slasher Address of the party allowed to slash indexers * @param _allowed True if slasher is allowed */ function setSlasher(address _slasher, bool _allowed) external override onlyGovernor { require(_slasher != address(0), "!slasher"); __slashers[_slasher] = _allowed; emit SlasherUpdate(msg.sender, _slasher, _allowed); } /** * @notice Delegate tokens to an indexer. * @param _indexer Address of the indexer to which tokens are delegated * @param _tokens Amount of tokens to delegate * @return Amount of shares issued from the delegation pool */ function delegate(address _indexer, uint256 _tokens) external override notPartialPaused returns (uint256) { address delegator = msg.sender; // Transfer tokens to delegate to this contract TokenUtils.pullTokens(graphToken(), delegator, _tokens); // Update state return _delegate(delegator, _indexer, _tokens); } /** * @notice Undelegate tokens from an indexer. Tokens will be locked for the unbonding period. * @param _indexer Address of the indexer to which tokens had been delegated * @param _shares Amount of shares to return and undelegate tokens * @return Amount of tokens returned for the shares of the delegation pool */ function undelegate(address _indexer, uint256 _shares) external override notPartialPaused returns (uint256) { return _undelegate(msg.sender, _indexer, _shares); } /** * @notice Withdraw undelegated tokens once the unbonding period has passed, and optionally * re-delegate to a new indexer. * @param _indexer Withdraw available tokens delegated to indexer * @param _newIndexer Re-delegate to indexer address if non-zero, withdraw if zero address */ function withdrawDelegated(address _indexer, address _newIndexer) external override notPaused returns (uint256) { return _withdrawDelegated(msg.sender, _indexer, _newIndexer); } /** * @notice Slash the indexer stake. Delegated tokens are not subject to slashing. * @dev Can only be called by the slasher role. * @param _indexer Address of indexer to slash * @param _tokens Amount of tokens to slash from the indexer stake * @param _reward Amount of reward tokens to send to a beneficiary * @param _beneficiary Address of a beneficiary to receive a reward for the slashing */ function slash( address _indexer, uint256 _tokens, uint256 _reward, address _beneficiary ) external override onlySlasher notPartialPaused { Stakes.Indexer storage indexerStake = __stakes[_indexer]; // Only able to slash a non-zero number of tokens require(_tokens > 0, "!tokens"); // Rewards comes from tokens slashed balance require(_tokens >= _reward, "rewards>slash"); // Cannot slash stake of an indexer without any or enough stake require(indexerStake.tokensStaked > 0, "!stake"); require(_tokens <= indexerStake.tokensStaked, "slash>stake"); // Validate beneficiary of slashed tokens require(_beneficiary != address(0), "!beneficiary"); // Slashing more tokens than freely available (over allocation condition) // Unlock locked tokens to avoid the indexer to withdraw them if (_tokens > indexerStake.tokensAvailable() && indexerStake.tokensLocked > 0) { uint256 tokensOverAllocated = _tokens.sub(indexerStake.tokensAvailable()); uint256 tokensToUnlock = MathUtils.min(tokensOverAllocated, indexerStake.tokensLocked); indexerStake.unlockTokens(tokensToUnlock); } // Remove tokens to slash from the stake indexerStake.release(_tokens); // -- Interactions -- IGraphToken graphToken = graphToken(); // Set apart the reward for the beneficiary and burn remaining slashed stake TokenUtils.burnTokens(graphToken, _tokens.sub(_reward)); // Give the beneficiary a reward for slashing TokenUtils.pushTokens(graphToken, _beneficiary, _reward); emit StakeSlashed(_indexer, _tokens, _reward, _beneficiary); } /** * @notice Return the delegation from a delegator to an indexer. * @param _indexer Address of the indexer where funds have been delegated * @param _delegator Address of the delegator * @return Delegation data */ function getDelegation(address _indexer, address _delegator) external view override returns (Delegation memory) { return __delegationPools[_indexer].delegators[_delegator]; } /** * @notice Getter for the delegationRatio, i.e. the delegation capacity multiplier: * If delegation ratio is 100, and an Indexer has staked 5 GRT, * then they can use up to 500 GRT from the delegated stake * @return Delegation ratio */ function delegationRatio() external view override returns (uint32) { return __delegationRatio; } /** * @notice Getter for delegationParametersCooldown: * Minimum time in blocks an indexer needs to wait to change delegation parameters * @return Delegation parameters cooldown in blocks */ function delegationParametersCooldown() external view override returns (uint32) { return __delegationParametersCooldown; } /** * @notice Getter for delegationUnbondingPeriod: * Time in epochs a delegator needs to wait to withdraw delegated stake * @return Delegation unbonding period in epochs */ function delegationUnbondingPeriod() external view override returns (uint32) { return __delegationUnbondingPeriod; } /** * @notice Getter for delegationTaxPercentage: * Percentage of tokens to tax a delegation deposit, expressed in parts per million * @return Delegation tax percentage in parts per million */ function delegationTaxPercentage() external view override returns (uint32) { return __delegationTaxPercentage; } /** * @notice Getter for delegationPools[_indexer]: * gets the delegation pool structure for a particular indexer. * @param _indexer Address of the indexer for which to query the delegation pool * @return Delegation pool as a DelegationPoolReturn struct */ function delegationPools(address _indexer) external view override returns (DelegationPoolReturn memory) { DelegationPool storage pool = __delegationPools[_indexer]; return DelegationPoolReturn( pool.cooldownBlocks, // Blocks to wait before updating parameters pool.indexingRewardCut, // in PPM pool.queryFeeCut, // in PPM pool.updatedAtBlock, // Block when the pool was last updated pool.tokens, // Total tokens as pool reserves pool.shares // Total shares minted in the pool ); } /** * @notice Getter for rewardsDestination[_indexer]: * returns the address where the indexer's rewards are sent. * @param _indexer The indexer address for which to query the rewards destination * @return The address where the indexer's rewards are sent, zero if none is set in which case rewards are re-staked */ function rewardsDestination(address _indexer) external view override returns (address) { return __rewardsDestination[_indexer]; } /** * @notice Getter for assetHolders[_maybeAssetHolder]: * returns true if the address is an asset holder, i.e. an entity that can collect * query fees into the Staking contract. * @param _maybeAssetHolder The address that may or may not be an asset holder * @return True if the address is an asset holder */ function assetHolders(address _maybeAssetHolder) external view override returns (bool) { return __assetHolders[_maybeAssetHolder]; } /** * @notice Getter for operatorAuth[_indexer][_maybeOperator]: * returns true if the operator is authorized to operate on behalf of the indexer. * @param _indexer The indexer address for which to query authorization * @param _maybeOperator The address that may or may not be an operator * @return True if the operator is authorized to operate on behalf of the indexer */ function operatorAuth(address _indexer, address _maybeOperator) external view override returns (bool) { return __operatorAuth[_indexer][_maybeOperator]; } /** * @notice Getter for subgraphAllocations[_subgraphDeploymentId]: * returns the amount of tokens allocated to a subgraph deployment. * @param _subgraphDeploymentId The subgraph deployment for which to query the allocations * @return The amount of tokens allocated to the subgraph deployment */ function subgraphAllocations(bytes32 _subgraphDeploymentId) external view override returns (uint256) { return __subgraphAllocations[_subgraphDeploymentId]; } /** * @notice Getter for slashers[_maybeSlasher]: * returns true if the address is a slasher, i.e. an entity that can slash indexers * @param _maybeSlasher Address for which to check the slasher role * @return True if the address is a slasher */ function slashers(address _maybeSlasher) external view override returns (bool) { return __slashers[_maybeSlasher]; } /** * @notice Getter for minimumIndexerStake: the minimum * amount of GRT that an indexer needs to stake. * @return Minimum indexer stake in GRT */ function minimumIndexerStake() external view override returns (uint256) { return __minimumIndexerStake; } /** * @notice Getter for thawingPeriod: the time in blocks an * indexer needs to wait to unstake tokens. * @return Thawing period in blocks */ function thawingPeriod() external view override returns (uint32) { return __thawingPeriod; } /** * @notice Getter for curationPercentage: the percentage of * query fees that are distributed to curators. * @return Curation percentage in parts per million */ function curationPercentage() external view override returns (uint32) { return __curationPercentage; } /** * @notice Getter for protocolPercentage: the percentage of * query fees that are burned as protocol fees. * @return Protocol percentage in parts per million */ function protocolPercentage() external view override returns (uint32) { return __protocolPercentage; } /** * @notice Getter for maxAllocationEpochs: the maximum time in epochs * that an allocation can be open before anyone is allowed to close it. This * also caps the effective allocation when sending the allocation's query fees * to the rebate pool. * @return Maximum allocation period in epochs */ function maxAllocationEpochs() external view override returns (uint32) { return __maxAllocationEpochs; } /** * @notice Getter for the numerator of the rebates alpha parameter * @return Alpha numerator */ function alphaNumerator() external view override returns (uint32) { return __alphaNumerator; } /** * @notice Getter for the denominator of the rebates alpha parameter * @return Alpha denominator */ function alphaDenominator() external view override returns (uint32) { return __alphaDenominator; } /** * @notice Getter for the numerator of the rebates lambda parameter * @return Lambda numerator */ function lambdaNumerator() external view override returns (uint32) { return __lambdaNumerator; } /** * @notice Getter for the denominator of the rebates lambda parameter * @return Lambda denominator */ function lambdaDenominator() external view override returns (uint32) { return __lambdaDenominator; } /** * @notice Getter for stakes[_indexer]: * gets the stake information for an indexer as a Stakes.Indexer struct. * @param _indexer Indexer address for which to query the stake information * @return Stake information for the specified indexer, as a Stakes.Indexer struct */ function stakes(address _indexer) external view override returns (Stakes.Indexer memory) { return __stakes[_indexer]; } /** * @notice Getter for allocations[_allocationID]: * gets an allocation's information as an IStakingData.Allocation struct. * @param _allocationID Allocation ID for which to query the allocation information * @return The specified allocation, as an IStakingData.Allocation struct */ function allocations(address _allocationID) external view override returns (IStakingData.Allocation memory) { return __allocations[_allocationID]; } /** * @notice Return whether the delegator has delegated to the indexer. * @param _indexer Address of the indexer where funds have been delegated * @param _delegator Address of the delegator * @return True if delegator has tokens delegated to the indexer */ function isDelegator(address _indexer, address _delegator) public view override returns (bool) { return __delegationPools[_indexer].delegators[_delegator].shares > 0; } /** * @notice Returns amount of delegated tokens ready to be withdrawn after unbonding period. * @param _delegation Delegation of tokens from delegator to indexer * @return Amount of tokens to withdraw */ function getWithdraweableDelegatedTokens(Delegation memory _delegation) public view override returns (uint256) { // There must be locked tokens and period passed uint256 currentEpoch = epochManager().currentEpoch(); if (_delegation.tokensLockedUntil > 0 && currentEpoch >= _delegation.tokensLockedUntil) { return _delegation.tokensLocked; } return 0; } /** * @dev Internal: Set a delegation tax percentage to burn when delegated funds are deposited. * @param _percentage Percentage of delegated tokens to burn as delegation tax */ function _setDelegationTaxPercentage(uint32 _percentage) private { // Must be within 0% to 100% (inclusive) require(_percentage <= MAX_PPM, ">percentage"); __delegationTaxPercentage = _percentage; emit ParameterUpdated("delegationTaxPercentage"); } /** * @dev Internal: Set the delegation ratio. * If set to 10 it means the indexer can use up to 10x the indexer staked amount * from their delegated tokens * @param _delegationRatio Delegation capacity multiplier */ function _setDelegationRatio(uint32 _delegationRatio) private { __delegationRatio = _delegationRatio; emit ParameterUpdated("delegationRatio"); } /** * @dev Internal: Set the time in blocks an indexer needs to wait to change delegation parameters. * @param _blocks Number of blocks to set the delegation parameters cooldown period */ function _setDelegationParametersCooldown(uint32 _blocks) private { __delegationParametersCooldown = _blocks; emit ParameterUpdated("delegationParametersCooldown"); } /** * @dev Internal: Set the period for undelegation of stake from indexer. * @param _delegationUnbondingPeriod Period in epochs to wait for token withdrawals after undelegating */ function _setDelegationUnbondingPeriod(uint32 _delegationUnbondingPeriod) private { require(_delegationUnbondingPeriod > 0, "!delegationUnbondingPeriod"); __delegationUnbondingPeriod = _delegationUnbondingPeriod; emit ParameterUpdated("delegationUnbondingPeriod"); } /** * @dev Delegate tokens to an indexer. * @param _delegator Address of the delegator * @param _indexer Address of the indexer to delegate tokens to * @param _tokens Amount of tokens to delegate * @return Amount of shares issued of the delegation pool */ function _delegate( address _delegator, address _indexer, uint256 _tokens ) private returns (uint256) { // Only delegate a non-zero amount of tokens require(_tokens > 0, "!tokens"); // Only delegate to non-empty address require(_indexer != address(0), "!indexer"); // Only delegate to staked indexer require(__stakes[_indexer].tokensStaked > 0, "!stake"); // Get the delegation pool of the indexer DelegationPool storage pool = __delegationPools[_indexer]; Delegation storage delegation = pool.delegators[_delegator]; // Collect delegation tax uint256 delegationTax = _collectTax(graphToken(), _tokens, __delegationTaxPercentage); uint256 delegatedTokens = _tokens.sub(delegationTax); // Calculate shares to issue uint256 shares = (pool.tokens == 0) ? delegatedTokens : delegatedTokens.mul(pool.shares).div(pool.tokens); require(shares > 0, "!shares"); // Update the delegation pool pool.tokens = pool.tokens.add(delegatedTokens); pool.shares = pool.shares.add(shares); // Update the individual delegation delegation.shares = delegation.shares.add(shares); emit StakeDelegated(_indexer, _delegator, delegatedTokens, shares); return shares; } /** * @dev Undelegate tokens from an indexer. * @param _delegator Address of the delegator * @param _indexer Address of the indexer where tokens had been delegated * @param _shares Amount of shares to return and undelegate tokens * @return Amount of tokens returned for the shares of the delegation pool */ function _undelegate( address _delegator, address _indexer, uint256 _shares ) private returns (uint256) { // Can only undelegate a non-zero amount of shares require(_shares > 0, "!shares"); // Get the delegation pool of the indexer DelegationPool storage pool = __delegationPools[_indexer]; Delegation storage delegation = pool.delegators[_delegator]; // Delegator need to have enough shares in the pool to undelegate require(delegation.shares >= _shares, "!shares-avail"); // Withdraw tokens if available if (getWithdraweableDelegatedTokens(delegation) > 0) { _withdrawDelegated(_delegator, _indexer, address(0)); } // Calculate tokens to get in exchange for the shares uint256 tokens = _shares.mul(pool.tokens).div(pool.shares); // Update the delegation pool pool.tokens = pool.tokens.sub(tokens); pool.shares = pool.shares.sub(_shares); // Update the delegation delegation.shares = delegation.shares.sub(_shares); delegation.tokensLocked = delegation.tokensLocked.add(tokens); delegation.tokensLockedUntil = epochManager().currentEpoch().add( __delegationUnbondingPeriod ); emit StakeDelegatedLocked( _indexer, _delegator, tokens, _shares, delegation.tokensLockedUntil ); return tokens; } /** * @dev Withdraw delegated tokens once the unbonding period has passed. * @param _delegator Delegator that is withdrawing tokens * @param _indexer Withdraw available tokens delegated to indexer * @param _delegateToIndexer Re-delegate to indexer address if non-zero, withdraw if zero address * @return Amount of tokens withdrawn or re-delegated */ function _withdrawDelegated( address _delegator, address _indexer, address _delegateToIndexer ) private returns (uint256) { // Get the delegation pool of the indexer DelegationPool storage pool = __delegationPools[_indexer]; Delegation storage delegation = pool.delegators[_delegator]; // Validation uint256 tokensToWithdraw = getWithdraweableDelegatedTokens(delegation); require(tokensToWithdraw > 0, "!tokens"); // Reset lock delegation.tokensLocked = 0; delegation.tokensLockedUntil = 0; emit StakeDelegatedWithdrawn(_indexer, _delegator, tokensToWithdraw); // -- Interactions -- if (_delegateToIndexer != address(0)) { // Re-delegate tokens to a new indexer _delegate(_delegator, _delegateToIndexer, tokensToWithdraw); } else { // Return tokens to the delegator TokenUtils.pushTokens(graphToken(), _delegator, tokensToWithdraw); } return tokensToWithdraw; } /** * @dev Collect tax to burn for an amount of tokens. * @param _graphToken Token to burn * @param _tokens Total tokens received used to calculate the amount of tax to collect * @param _percentage Percentage of tokens to burn as tax * @return Amount of tax charged */ function _collectTax( IGraphToken _graphToken, uint256 _tokens, uint256 _percentage ) private returns (uint256) { uint256 tax = uint256(_percentage).mul(_tokens).div(MAX_PPM); TokenUtils.burnTokens(_graphToken, tax); // Burn tax if any return tax; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a % b); } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { 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"); return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { 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, reverting 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) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a % b; } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.7.6; import { Managed } from "../governance/Managed.sol"; import { IStakingData } from "./IStakingData.sol"; import { Stakes } from "./libs/Stakes.sol"; /** * @title StakingV1Storage * @notice This contract holds all the storage variables for the Staking contract, version 1 * @dev Note that we use a double underscore prefix for variable names; this prefix identifies * variables that used to be public but are now internal, getters can be found on StakingExtension.sol. */ // solhint-disable-next-line max-states-count contract StakingV1Storage is Managed { // -- Staking -- /// @dev Minimum amount of tokens an indexer needs to stake uint256 internal __minimumIndexerStake; /// @dev Time in blocks to unstake uint32 internal __thawingPeriod; // in blocks /// @dev Percentage of fees going to curators /// Parts per million. (Allows for 4 decimal points, 999,999 = 99.9999%) uint32 internal __curationPercentage; /// @dev Percentage of fees burned as protocol fee /// Parts per million. (Allows for 4 decimal points, 999,999 = 99.9999%) uint32 internal __protocolPercentage; /// @dev Period for allocation to be finalized uint32 private __DEPRECATED_channelDisputeEpochs; /// @dev Maximum allocation time uint32 internal __maxAllocationEpochs; /// @dev Rebate alpha numerator // Originally used for Cobb-Douglas rebates, now used for exponential rebates uint32 internal __alphaNumerator; /// @dev Rebate alpha denominator // Originally used for Cobb-Douglas rebates, now used for exponential rebates uint32 internal __alphaDenominator; /// @dev Indexer stakes : indexer => Stake mapping(address => Stakes.Indexer) internal __stakes; /// @dev Allocations : allocationID => Allocation mapping(address => IStakingData.Allocation) internal __allocations; /// @dev Subgraph Allocations: subgraphDeploymentID => tokens mapping(bytes32 => uint256) internal __subgraphAllocations; // Rebate pools : epoch => Pool mapping(uint256 => uint256) private __DEPRECATED_rebates; // -- Slashing -- /// @dev List of addresses allowed to slash stakes mapping(address => bool) internal __slashers; // -- Delegation -- /// @dev Set the delegation capacity multiplier defined by the delegation ratio /// If delegation ratio is 100, and an Indexer has staked 5 GRT, /// then they can use up to 500 GRT from the delegated stake uint32 internal __delegationRatio; /// @dev Time in blocks an indexer needs to wait to change delegation parameters uint32 internal __delegationParametersCooldown; /// @dev Time in epochs a delegator needs to wait to withdraw delegated stake uint32 internal __delegationUnbondingPeriod; // in epochs /// @dev Percentage of tokens to tax a delegation deposit /// Parts per million. (Allows for 4 decimal points, 999,999 = 99.9999%) uint32 internal __delegationTaxPercentage; /// @dev Delegation pools : indexer => DelegationPool mapping(address => IStakingData.DelegationPool) internal __delegationPools; // -- Operators -- /// @dev Operator auth : indexer => operator => is authorized mapping(address => mapping(address => bool)) internal __operatorAuth; // -- Asset Holders -- /// @dev Allowed AssetHolders that can collect query fees: assetHolder => is allowed mapping(address => bool) internal __assetHolders; } /** * @title StakingV2Storage * @notice This contract holds all the storage variables for the Staking contract, version 2 * @dev Note that we use a double underscore prefix for variable names; this prefix identifies * variables that used to be public but are now internal, getters can be found on StakingExtension.sol. */ contract StakingV2Storage is StakingV1Storage { /// @dev Destination of accrued rewards : beneficiary => rewards destination mapping(address => address) internal __rewardsDestination; } /** * @title StakingV3Storage * @notice This contract holds all the storage variables for the base Staking contract, version 3. */ contract StakingV3Storage is StakingV2Storage { /// @dev Address of the counterpart Staking contract on L1/L2 address internal counterpartStakingAddress; /// @dev Address of the StakingExtension implementation address internal extensionImpl; } /** * @title StakingV4Storage * @notice This contract holds all the storage variables for the base Staking contract, version 4. * @dev Note that it includes a storage gap - if adding future versions, make sure to move the gap * to the new version and reduce the size of the gap accordingly. */ contract StakingV4Storage is StakingV3Storage { // Additional rebate parameters for exponential rebates uint32 internal __lambdaNumerator; uint32 internal __lambdaDenominator; /// @dev Gap to allow adding variables in future upgrades (since L1Staking and L2Staking can have their own storage as well) uint256[50] private __gap; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.6.12 <0.8.0; pragma abicoder v2; import { IStakingData } from "./IStakingData.sol"; import { Stakes } from "./libs/Stakes.sol"; /** * @title Interface for the StakingExtension contract * @dev This interface defines the events and functions implemented * in the StakingExtension contract, which is used to extend the functionality * of the Staking contract while keeping it within the 24kB mainnet size limit. * In particular, this interface includes delegation functions and various storage * getters. */ interface IStakingExtension is IStakingData { /** * @dev DelegationPool struct as returned by delegationPools(), since * the original DelegationPool in IStakingData.sol contains a nested mapping. */ struct DelegationPoolReturn { uint32 cooldownBlocks; // Blocks to wait before updating parameters uint32 indexingRewardCut; // in PPM uint32 queryFeeCut; // in PPM uint256 updatedAtBlock; // Block when the pool was last updated uint256 tokens; // Total tokens as pool reserves uint256 shares; // Total shares minted in the pool } /** * @dev Emitted when `delegator` delegated `tokens` to the `indexer`, the delegator * gets `shares` for the delegation pool proportionally to the tokens staked. */ event StakeDelegated( address indexed indexer, address indexed delegator, uint256 tokens, uint256 shares ); /** * @dev Emitted when `delegator` undelegated `tokens` from `indexer`. * Tokens get locked for withdrawal after a period of time. */ event StakeDelegatedLocked( address indexed indexer, address indexed delegator, uint256 tokens, uint256 shares, uint256 until ); /** * @dev Emitted when `delegator` withdrew delegated `tokens` from `indexer`. */ event StakeDelegatedWithdrawn( address indexed indexer, address indexed delegator, uint256 tokens ); /** * @dev Emitted when `indexer` was slashed for a total of `tokens` amount. * Tracks `reward` amount of tokens given to `beneficiary`. */ event StakeSlashed( address indexed indexer, uint256 tokens, uint256 reward, address beneficiary ); /** * @dev Emitted when `caller` set `slasher` address as `allowed` to slash stakes. */ event SlasherUpdate(address indexed caller, address indexed slasher, bool allowed); /** * @notice Set the delegation ratio. * If set to 10 it means the indexer can use up to 10x the indexer staked amount * from their delegated tokens * @dev This function is only callable by the governor * @param _delegationRatio Delegation capacity multiplier */ function setDelegationRatio(uint32 _delegationRatio) external; /** * @notice Set the minimum time in blocks an indexer needs to wait to change delegation parameters. * Indexers can set a custom amount time for their own cooldown, but it must be greater than this. * @dev This function is only callable by the governor * @param _blocks Number of blocks to set the delegation parameters cooldown period */ function setDelegationParametersCooldown(uint32 _blocks) external; /** * @notice Set the time, in epochs, a Delegator needs to wait to withdraw tokens after undelegating. * @dev This function is only callable by the governor * @param _delegationUnbondingPeriod Period in epochs to wait for token withdrawals after undelegating */ function setDelegationUnbondingPeriod(uint32 _delegationUnbondingPeriod) external; /** * @notice Set a delegation tax percentage to burn when delegated funds are deposited. * @dev This function is only callable by the governor * @param _percentage Percentage of delegated tokens to burn as delegation tax, expressed in parts per million */ function setDelegationTaxPercentage(uint32 _percentage) external; /** * @notice Set or unset an address as allowed slasher. * @dev This function can only be called by the governor. * @param _slasher Address of the party allowed to slash indexers * @param _allowed True if slasher is allowed */ function setSlasher(address _slasher, bool _allowed) external; /** * @notice Delegate tokens to an indexer. * @param _indexer Address of the indexer to which tokens are delegated * @param _tokens Amount of tokens to delegate * @return Amount of shares issued from the delegation pool */ function delegate(address _indexer, uint256 _tokens) external returns (uint256); /** * @notice Undelegate tokens from an indexer. Tokens will be locked for the unbonding period. * @param _indexer Address of the indexer to which tokens had been delegated * @param _shares Amount of shares to return and undelegate tokens * @return Amount of tokens returned for the shares of the delegation pool */ function undelegate(address _indexer, uint256 _shares) external returns (uint256); /** * @notice Withdraw undelegated tokens once the unbonding period has passed, and optionally * re-delegate to a new indexer. * @param _indexer Withdraw available tokens delegated to indexer * @param _newIndexer Re-delegate to indexer address if non-zero, withdraw if zero address */ function withdrawDelegated(address _indexer, address _newIndexer) external returns (uint256); /** * @notice Slash the indexer stake. Delegated tokens are not subject to slashing. * @dev Can only be called by the slasher role. * @param _indexer Address of indexer to slash * @param _tokens Amount of tokens to slash from the indexer stake * @param _reward Amount of reward tokens to send to a beneficiary * @param _beneficiary Address of a beneficiary to receive a reward for the slashing */ function slash( address _indexer, uint256 _tokens, uint256 _reward, address _beneficiary ) external; /** * @notice Return the delegation from a delegator to an indexer. * @param _indexer Address of the indexer where funds have been delegated * @param _delegator Address of the delegator * @return Delegation data */ function getDelegation(address _indexer, address _delegator) external view returns (Delegation memory); /** * @notice Return whether the delegator has delegated to the indexer. * @param _indexer Address of the indexer where funds have been delegated * @param _delegator Address of the delegator * @return True if delegator has tokens delegated to the indexer */ function isDelegator(address _indexer, address _delegator) external view returns (bool); /** * @notice Returns amount of delegated tokens ready to be withdrawn after unbonding period. * @param _delegation Delegation of tokens from delegator to indexer * @return Amount of tokens to withdraw */ function getWithdraweableDelegatedTokens(Delegation memory _delegation) external view returns (uint256); /** * @notice Getter for the delegationRatio, i.e. the delegation capacity multiplier: * If delegation ratio is 100, and an Indexer has staked 5 GRT, * then they can use up to 500 GRT from the delegated stake * @return Delegation ratio */ function delegationRatio() external view returns (uint32); /** * @notice Getter for delegationParametersCooldown: * Minimum time in blocks an indexer needs to wait to change delegation parameters * @return Delegation parameters cooldown in blocks */ function delegationParametersCooldown() external view returns (uint32); /** * @notice Getter for delegationUnbondingPeriod: * Time in epochs a delegator needs to wait to withdraw delegated stake * @return Delegation unbonding period in epochs */ function delegationUnbondingPeriod() external view returns (uint32); /** * @notice Getter for delegationTaxPercentage: * Percentage of tokens to tax a delegation deposit, expressed in parts per million * @return Delegation tax percentage in parts per million */ function delegationTaxPercentage() external view returns (uint32); /** * @notice Getter for delegationPools[_indexer]: * gets the delegation pool structure for a particular indexer. * @param _indexer Address of the indexer for which to query the delegation pool * @return Delegation pool as a DelegationPoolReturn struct */ function delegationPools(address _indexer) external view returns (DelegationPoolReturn memory); /** * @notice Getter for operatorAuth[_indexer][_maybeOperator]: * returns true if the operator is authorized to operate on behalf of the indexer. * @param _indexer The indexer address for which to query authorization * @param _maybeOperator The address that may or may not be an operator * @return True if the operator is authorized to operate on behalf of the indexer */ function operatorAuth(address _indexer, address _maybeOperator) external view returns (bool); /** * @notice Getter for rewardsDestination[_indexer]: * returns the address where the indexer's rewards are sent. * @param _indexer The indexer address for which to query the rewards destination * @return The address where the indexer's rewards are sent, zero if none is set in which case rewards are re-staked */ function rewardsDestination(address _indexer) external view returns (address); /** * @notice Getter for assetHolders[_maybeAssetHolder]: * returns true if the address is an asset holder, i.e. an entity that can collect * query fees into the Staking contract. * @param _maybeAssetHolder The address that may or may not be an asset holder * @return True if the address is an asset holder */ function assetHolders(address _maybeAssetHolder) external view returns (bool); /** * @notice Getter for subgraphAllocations[_subgraphDeploymentId]: * returns the amount of tokens allocated to a subgraph deployment. * @param _subgraphDeploymentId The subgraph deployment for which to query the allocations * @return The amount of tokens allocated to the subgraph deployment */ function subgraphAllocations(bytes32 _subgraphDeploymentId) external view returns (uint256); /** * @notice Getter for slashers[_maybeSlasher]: * returns true if the address is a slasher, i.e. an entity that can slash indexers * @param _maybeSlasher Address for which to check the slasher role * @return True if the address is a slasher */ function slashers(address _maybeSlasher) external view returns (bool); /** * @notice Getter for minimumIndexerStake: the minimum * amount of GRT that an indexer needs to stake. * @return Minimum indexer stake in GRT */ function minimumIndexerStake() external view returns (uint256); /** * @notice Getter for thawingPeriod: the time in blocks an * indexer needs to wait to unstake tokens. * @return Thawing period in blocks */ function thawingPeriod() external view returns (uint32); /** * @notice Getter for curationPercentage: the percentage of * query fees that are distributed to curators. * @return Curation percentage in parts per million */ function curationPercentage() external view returns (uint32); /** * @notice Getter for protocolPercentage: the percentage of * query fees that are burned as protocol fees. * @return Protocol percentage in parts per million */ function protocolPercentage() external view returns (uint32); /** * @notice Getter for maxAllocationEpochs: the maximum time in epochs * that an allocation can be open before anyone is allowed to close it. This * also caps the effective allocation when sending the allocation's query fees * to the rebate pool. * @return Maximum allocation period in epochs */ function maxAllocationEpochs() external view returns (uint32); /** * @notice Getter for the numerator of the rebates alpha parameter * @return Alpha numerator */ function alphaNumerator() external view returns (uint32); /** * @notice Getter for the denominator of the rebates alpha parameter * @return Alpha denominator */ function alphaDenominator() external view returns (uint32); /** * @notice Getter for the numerator of the rebates lambda parameter * @return Lambda numerator */ function lambdaNumerator() external view returns (uint32); /** * @notice Getter for the denominator of the rebates lambda parameter * @return Lambda denominator */ function lambdaDenominator() external view returns (uint32); /** * @notice Getter for stakes[_indexer]: * gets the stake information for an indexer as a Stakes.Indexer struct. * @param _indexer Indexer address for which to query the stake information * @return Stake information for the specified indexer, as a Stakes.Indexer struct */ function stakes(address _indexer) external view returns (Stakes.Indexer memory); /** * @notice Getter for allocations[_allocationID]: * gets an allocation's information as an IStakingData.Allocation struct. * @param _allocationID Allocation ID for which to query the allocation information * @return The specified allocation, as an IStakingData.Allocation struct */ function allocations(address _allocationID) external view returns (IStakingData.Allocation memory); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.7.6; import "../token/IGraphToken.sol"; library TokenUtils { /** * @dev Pull tokens from an address to this contract. * @param _graphToken Token to transfer * @param _from Address sending the tokens * @param _amount Amount of tokens to transfer */ function pullTokens( IGraphToken _graphToken, address _from, uint256 _amount ) internal { if (_amount > 0) { require(_graphToken.transferFrom(_from, address(this), _amount), "!transfer"); } } /** * @dev Push tokens from this contract to a receiving address. * @param _graphToken Token to transfer * @param _to Address receiving the tokens * @param _amount Amount of tokens to transfer */ function pushTokens( IGraphToken _graphToken, address _to, uint256 _amount ) internal { if (_amount > 0) { require(_graphToken.transfer(_to, _amount), "!transfer"); } } /** * @dev Burn tokens held by this contract. * @param _graphToken Token to burn * @param _amount Amount of tokens to burn */ function burnTokens(IGraphToken _graphToken, uint256 _amount) internal { if (_amount > 0) { _graphToken.burn(_amount); } } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.7.6; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; interface IGraphToken is IERC20 { // -- Mint and Burn -- function burn(uint256 amount) external; function burnFrom(address _from, uint256 amount) external; function mint(address _to, uint256 _amount) external; // -- Mint Admin -- function addMinter(address _account) external; function removeMinter(address _account) external; function renounceMinter() external; function isMinter(address _account) external view returns (bool); // -- Permit -- function permit( address _owner, address _spender, uint256 _value, uint256 _deadline, uint8 _v, bytes32 _r, bytes32 _s ) external; // -- Allowance -- function increaseAllowance(address spender, uint256 addedValue) external returns (bool); function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.7.6; import { IGraphProxy } from "./IGraphProxy.sol"; /** * @title Graph Upgradeable * @dev This contract is intended to be inherited from upgradeable contracts. */ abstract contract GraphUpgradeable { /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Check if the caller is the proxy admin. */ modifier onlyProxyAdmin(IGraphProxy _proxy) { require(msg.sender == _proxy.admin(), "Caller must be the proxy admin"); _; } /** * @dev Check if the caller is the implementation. */ modifier onlyImpl() { require(msg.sender == _implementation(), "Only implementation"); _; } /** * @dev Returns the current implementation. * @return impl Address of the current implementation */ function _implementation() internal view returns (address impl) { bytes32 slot = IMPLEMENTATION_SLOT; // solhint-disable-next-line no-inline-assembly assembly { impl := sload(slot) } } /** * @notice Accept to be an implementation of proxy. * @param _proxy Proxy to accept */ function acceptProxy(IGraphProxy _proxy) external onlyProxyAdmin(_proxy) { _proxy.acceptUpgrade(); } /** * @notice Accept to be an implementation of proxy and then call a function from the new * implementation as specified by `_data`, which should be an encoded function call. This is * useful to initialize new storage variables in the proxied contract. * @param _proxy Proxy to accept * @param _data Calldata for the initialization function call (including selector) */ function acceptProxyAndCall(IGraphProxy _proxy, bytes calldata _data) external onlyProxyAdmin(_proxy) { _proxy.acceptUpgradeAndCall(_data); } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.7.6; pragma abicoder v2; import "@openzeppelin/contracts/math/SafeMath.sol"; import "./MathUtils.sol"; /** * @title A collection of data structures and functions to manage the Indexer Stake state. * Used for low-level state changes, require() conditions should be evaluated * at the caller function scope. */ library Stakes { using SafeMath for uint256; using Stakes for Stakes.Indexer; struct Indexer { uint256 tokensStaked; // Tokens on the indexer stake (staked by the indexer) uint256 tokensAllocated; // Tokens used in allocations uint256 tokensLocked; // Tokens locked for withdrawal subject to thawing period uint256 tokensLockedUntil; // Block when locked tokens can be withdrawn } /** * @dev Deposit tokens to the indexer stake. * @param stake Stake data * @param _tokens Amount of tokens to deposit */ function deposit(Stakes.Indexer storage stake, uint256 _tokens) internal { stake.tokensStaked = stake.tokensStaked.add(_tokens); } /** * @dev Release tokens from the indexer stake. * @param stake Stake data * @param _tokens Amount of tokens to release */ function release(Stakes.Indexer storage stake, uint256 _tokens) internal { stake.tokensStaked = stake.tokensStaked.sub(_tokens); } /** * @dev Allocate tokens from the main stack to a SubgraphDeployment. * @param stake Stake data * @param _tokens Amount of tokens to allocate */ function allocate(Stakes.Indexer storage stake, uint256 _tokens) internal { stake.tokensAllocated = stake.tokensAllocated.add(_tokens); } /** * @dev Unallocate tokens from a SubgraphDeployment back to the main stack. * @param stake Stake data * @param _tokens Amount of tokens to unallocate */ function unallocate(Stakes.Indexer storage stake, uint256 _tokens) internal { stake.tokensAllocated = stake.tokensAllocated.sub(_tokens); } /** * @dev Lock tokens until a thawing period pass. * @param stake Stake data * @param _tokens Amount of tokens to unstake * @param _period Period in blocks that need to pass before withdrawal */ function lockTokens( Stakes.Indexer storage stake, uint256 _tokens, uint256 _period ) internal { // Take into account period averaging for multiple unstake requests uint256 lockingPeriod = _period; if (stake.tokensLocked > 0) { lockingPeriod = MathUtils.weightedAverage( MathUtils.diffOrZero(stake.tokensLockedUntil, block.number), // Remaining thawing period stake.tokensLocked, // Weighted by remaining unstaked tokens _period, // Thawing period _tokens // Weighted by new tokens to unstake ); } // Update balances stake.tokensLocked = stake.tokensLocked.add(_tokens); stake.tokensLockedUntil = block.number.add(lockingPeriod); } /** * @dev Unlock tokens. * @param stake Stake data * @param _tokens Amount of tokens to unkock */ function unlockTokens(Stakes.Indexer storage stake, uint256 _tokens) internal { stake.tokensLocked = stake.tokensLocked.sub(_tokens); if (stake.tokensLocked == 0) { stake.tokensLockedUntil = 0; } } /** * @dev Take all tokens out from the locked stake for withdrawal. * @param stake Stake data * @return Amount of tokens being withdrawn */ function withdrawTokens(Stakes.Indexer storage stake) internal returns (uint256) { // Calculate tokens that can be released uint256 tokensToWithdraw = stake.tokensWithdrawable(); if (tokensToWithdraw > 0) { // Reset locked tokens stake.unlockTokens(tokensToWithdraw); // Decrease indexer stake stake.release(tokensToWithdraw); } return tokensToWithdraw; } /** * @dev Return the amount of tokens used in allocations and locked for withdrawal. * @param stake Stake data * @return Token amount */ function tokensUsed(Stakes.Indexer memory stake) internal pure returns (uint256) { return stake.tokensAllocated.add(stake.tokensLocked); } /** * @dev Return the amount of tokens staked not considering the ones that are already going * through the thawing period or are ready for withdrawal. We call it secure stake because * it is not subject to change by a withdraw call from the indexer. * @param stake Stake data * @return Token amount */ function tokensSecureStake(Stakes.Indexer memory stake) internal pure returns (uint256) { return stake.tokensStaked.sub(stake.tokensLocked); } /** * @dev Tokens free balance on the indexer stake that can be used for any purpose. * Any token that is allocated cannot be used as well as tokens that are going through the * thawing period or are withdrawable * Calc: tokensStaked - tokensAllocated - tokensLocked * @param stake Stake data * @return Token amount */ function tokensAvailable(Stakes.Indexer memory stake) internal pure returns (uint256) { return stake.tokensAvailableWithDelegation(0); } /** * @dev Tokens free balance on the indexer stake that can be used for allocations. * This function accepts a parameter for extra delegated capacity that takes into * account delegated tokens * @param stake Stake data * @param _delegatedCapacity Amount of tokens used from delegators to calculate availability * @return Token amount */ function tokensAvailableWithDelegation(Stakes.Indexer memory stake, uint256 _delegatedCapacity) internal pure returns (uint256) { uint256 tokensCapacity = stake.tokensStaked.add(_delegatedCapacity); uint256 _tokensUsed = stake.tokensUsed(); // If more tokens are used than the current capacity, the indexer is overallocated. // This means the indexer doesn't have available capacity to create new allocations. // We can reach this state when the indexer has funds allocated and then any // of these conditions happen: // - The delegationCapacity ratio is reduced. // - The indexer stake is slashed. // - A delegator removes enough stake. if (_tokensUsed > tokensCapacity) { // Indexer stake is over allocated: return 0 to avoid stake to be used until // the overallocation is restored by staking more tokens, unallocating tokens // or using more delegated funds return 0; } return tokensCapacity.sub(_tokensUsed); } /** * @dev Tokens available for withdrawal after thawing period. * @param stake Stake data * @return Token amount */ function tokensWithdrawable(Stakes.Indexer memory stake) internal view returns (uint256) { // No tokens to withdraw before locking period if (stake.tokensLockedUntil == 0 || block.number < stake.tokensLockedUntil) { return 0; } return stake.tokensLocked; } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.6.12 <0.8.0; /** * @title Staking Data interface * @dev This interface defines some structures used by the Staking contract. */ interface IStakingData { /** * @dev Allocate GRT tokens for the purpose of serving queries of a subgraph deployment * An allocation is created in the allocate() function and closed in closeAllocation() */ struct Allocation { address indexer; bytes32 subgraphDeploymentID; uint256 tokens; // Tokens allocated to a SubgraphDeployment uint256 createdAtEpoch; // Epoch when it was created uint256 closedAtEpoch; // Epoch when it was closed uint256 collectedFees; // Collected fees for the allocation uint256 __DEPRECATED_effectiveAllocation; // Effective allocation when closed uint256 accRewardsPerAllocatedToken; // Snapshot used for reward calc uint256 distributedRebates; // Collected rebates that have been rebated } // -- Delegation Data -- /** * @dev Delegation pool information. One per indexer. */ struct DelegationPool { uint32 cooldownBlocks; // Blocks to wait before updating parameters uint32 indexingRewardCut; // in PPM uint32 queryFeeCut; // in PPM uint256 updatedAtBlock; // Block when the pool was last updated uint256 tokens; // Total tokens as pool reserves uint256 shares; // Total shares minted in the pool mapping(address => Delegation) delegators; // Mapping of delegator => Delegation } /** * @dev Individual delegation data of a delegator in a pool. */ struct Delegation { uint256 shares; // Shares owned by a delegator in the pool uint256 tokensLocked; // Tokens locked for undelegation uint256 tokensLockedUntil; // Block when locked tokens can be withdrawn } /** * @dev Rebates parameters. Used to avoid stack too deep errors in Staking initialize function. */ struct RebatesParameters { uint32 alphaNumerator; uint32 alphaDenominator; uint32 lambdaNumerator; uint32 lambdaDenominator; } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.7.6; import "@openzeppelin/contracts/math/SafeMath.sol"; /** * @title MathUtils Library * @notice A collection of functions to perform math operations */ library MathUtils { using SafeMath for uint256; /** * @dev Calculates the weighted average of two values pondering each of these * values based on configured weights. The contribution of each value N is * weightN/(weightA + weightB). * @param valueA The amount for value A * @param weightA The weight to use for value A * @param valueB The amount for value B * @param weightB The weight to use for value B */ function weightedAverage( uint256 valueA, uint256 weightA, uint256 valueB, uint256 weightB ) internal pure returns (uint256) { return valueA.mul(weightA).add(valueB.mul(weightB)).div(weightA.add(weightB)); } /** * @dev Returns the minimum of two numbers. */ function min(uint256 x, uint256 y) internal pure returns (uint256) { return x <= y ? x : y; } /** * @dev Returns the difference between two numbers or zero if negative. */ function diffOrZero(uint256 x, uint256 y) internal pure returns (uint256) { return (x > y) ? x.sub(y) : 0; } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.7.6; import { IController } from "./IController.sol"; import { ICuration } from "../curation/ICuration.sol"; import { IEpochManager } from "../epochs/IEpochManager.sol"; import { IRewardsManager } from "../rewards/IRewardsManager.sol"; import { IStaking } from "../staking/IStaking.sol"; import { IStakingBase } from "../staking/IStakingBase.sol"; import { IGraphToken } from "../token/IGraphToken.sol"; import { ITokenGateway } from "../arbitrum/ITokenGateway.sol"; import { IGNS } from "../discovery/IGNS.sol"; import { IManaged } from "./IManaged.sol"; /** * @title Graph Managed contract * @dev The Managed contract provides an interface to interact with the Controller. * It also provides local caching for contract addresses. This mechanism relies on calling the * public `syncAllContracts()` function whenever a contract changes in the controller. * * Inspired by Livepeer: * https://github.com/livepeer/protocol/blob/streamflow/contracts/Controller.sol */ abstract contract Managed is IManaged { // -- State -- /// Controller that manages this contract IController public override controller; /// @dev Cache for the addresses of the contracts retrieved from the controller mapping(bytes32 => address) private _addressCache; /// @dev Gap for future storage variables uint256[10] private __gap; // Immutables bytes32 private immutable CURATION = keccak256("Curation"); bytes32 private immutable EPOCH_MANAGER = keccak256("EpochManager"); bytes32 private immutable REWARDS_MANAGER = keccak256("RewardsManager"); bytes32 private immutable STAKING = keccak256("Staking"); bytes32 private immutable GRAPH_TOKEN = keccak256("GraphToken"); bytes32 private immutable GRAPH_TOKEN_GATEWAY = keccak256("GraphTokenGateway"); bytes32 private immutable GNS = keccak256("GNS"); // -- Events -- /// Emitted when a contract parameter has been updated event ParameterUpdated(string param); /// Emitted when the controller address has been set event SetController(address controller); /// Emitted when contract with `nameHash` is synced to `contractAddress`. event ContractSynced(bytes32 indexed nameHash, address contractAddress); // -- Modifiers -- /** * @dev Revert if the controller is paused or partially paused */ function _notPartialPaused() internal view { require(!controller.paused(), "Paused"); require(!controller.partialPaused(), "Partial-paused"); } /** * @dev Revert if the controller is paused */ function _notPaused() internal view virtual { require(!controller.paused(), "Paused"); } /** * @dev Revert if the caller is not the governor */ function _onlyGovernor() internal view { require(msg.sender == controller.getGovernor(), "Only Controller governor"); } /** * @dev Revert if the caller is not the Controller */ function _onlyController() internal view { require(msg.sender == address(controller), "Caller must be Controller"); } /** * @dev Revert if the controller is paused or partially paused */ modifier notPartialPaused() { _notPartialPaused(); _; } /** * @dev Revert if the controller is paused */ modifier notPaused() { _notPaused(); _; } /** * @dev Revert if the caller is not the Controller */ modifier onlyController() { _onlyController(); _; } /** * @dev Revert if the caller is not the governor */ modifier onlyGovernor() { _onlyGovernor(); _; } // -- Functions -- /** * @dev Initialize a Managed contract * @param _controller Address for the Controller that manages this contract */ function _initialize(address _controller) internal { _setController(_controller); } /** * @notice Set Controller. Only callable by current controller. * @param _controller Controller contract address */ function setController(address _controller) external override onlyController { _setController(_controller); } /** * @dev Set controller. * @param _controller Controller contract address */ function _setController(address _controller) internal { require(_controller != address(0), "Controller must be set"); controller = IController(_controller); emit SetController(_controller); } /** * @dev Return Curation interface * @return Curation contract registered with Controller */ function curation() internal view returns (ICuration) { return ICuration(_resolveContract(CURATION)); } /** * @dev Return EpochManager interface * @return Epoch manager contract registered with Controller */ function epochManager() internal view returns (IEpochManager) { return IEpochManager(_resolveContract(EPOCH_MANAGER)); } /** * @dev Return RewardsManager interface * @return Rewards manager contract registered with Controller */ function rewardsManager() internal view returns (IRewardsManager) { return IRewardsManager(_resolveContract(REWARDS_MANAGER)); } /** * @dev Return Staking interface * @return Staking contract registered with Controller */ function staking() internal view returns (IStaking) { return IStaking(_resolveContract(STAKING)); } /** * @dev Return GraphToken interface * @return Graph token contract registered with Controller */ function graphToken() internal view returns (IGraphToken) { return IGraphToken(_resolveContract(GRAPH_TOKEN)); } /** * @dev Return GraphTokenGateway (L1 or L2) interface * @return Graph token gateway contract registered with Controller */ function graphTokenGateway() internal view returns (ITokenGateway) { return ITokenGateway(_resolveContract(GRAPH_TOKEN_GATEWAY)); } /** * @dev Return GNS (L1 or L2) interface. * @return Address of the GNS contract registered with Controller, as an IGNS interface. */ function gns() internal view returns (IGNS) { return IGNS(_resolveContract(GNS)); } /** * @dev Resolve a contract address from the cache or the Controller if not found. * @param _nameHash keccak256 hash of the contract name * @return Address of the contract */ function _resolveContract(bytes32 _nameHash) internal view returns (address) { address contractAddress = _addressCache[_nameHash]; if (contractAddress == address(0)) { contractAddress = controller.getContractProxy(_nameHash); } return contractAddress; } /** * @dev Cache a contract address from the Controller registry. * @param _nameHash keccak256 hash of the name of the contract to sync into the cache */ function _syncContract(bytes32 _nameHash) internal { address contractAddress = controller.getContractProxy(_nameHash); if (_addressCache[_nameHash] != contractAddress) { _addressCache[_nameHash] = contractAddress; emit ContractSynced(_nameHash, contractAddress); } } /** * @notice Sync protocol contract addresses from the Controller registry * @dev This function will cache all the contracts using the latest addresses * Anyone can call the function whenever a Proxy contract change in the * controller to ensure the protocol is using the latest version */ function syncAllContracts() external override { _syncContract(CURATION); _syncContract(EPOCH_MANAGER); _syncContract(REWARDS_MANAGER); _syncContract(STAKING); _syncContract(GRAPH_TOKEN); _syncContract(GRAPH_TOKEN_GATEWAY); _syncContract(GNS); } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.6.12 <0.8.0; interface IController { function getGovernor() external view returns (address); // -- Registry -- function setContractProxy(bytes32 _id, address _contractAddress) external; function unsetContractProxy(bytes32 _id) external; function updateController(bytes32 _id, address _controller) external; function getContractProxy(bytes32 _id) external view returns (address); // -- Pausing -- function setPartialPaused(bool _partialPaused) external; function setPaused(bool _paused) external; function setPauseGuardian(address _newPauseGuardian) external; function paused() external view returns (bool); function partialPaused() external view returns (bool); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.7.6; /** * @title Curation Interface * @dev Interface for the Curation contract (and L2Curation too) */ interface ICuration { // -- Configuration -- /** * @notice Update the default reserve ratio to `_defaultReserveRatio` * @param _defaultReserveRatio Reserve ratio (in PPM) */ function setDefaultReserveRatio(uint32 _defaultReserveRatio) external; /** * @notice Update the minimum deposit amount needed to intialize a new subgraph * @param _minimumCurationDeposit Minimum amount of tokens required deposit */ function setMinimumCurationDeposit(uint256 _minimumCurationDeposit) external; /** * @notice Set the curation tax percentage to charge when a curator deposits GRT tokens. * @param _percentage Curation tax percentage charged when depositing GRT tokens */ function setCurationTaxPercentage(uint32 _percentage) external; /** * @notice Set the master copy to use as clones for the curation token. * @param _curationTokenMaster Address of implementation contract to use for curation tokens */ function setCurationTokenMaster(address _curationTokenMaster) external; // -- Curation -- /** * @notice Deposit Graph Tokens in exchange for signal of a SubgraphDeployment curation pool. * @param _subgraphDeploymentID Subgraph deployment pool from where to mint signal * @param _tokensIn Amount of Graph Tokens to deposit * @param _signalOutMin Expected minimum amount of signal to receive * @return Amount of signal minted * @return Amount of curation tax burned */ function mint( bytes32 _subgraphDeploymentID, uint256 _tokensIn, uint256 _signalOutMin ) external returns (uint256, uint256); /** * @notice Burn _signal from the SubgraphDeployment curation pool * @param _subgraphDeploymentID SubgraphDeployment the curator is returning signal * @param _signalIn Amount of signal to return * @param _tokensOutMin Expected minimum amount of tokens to receive * @return Tokens returned */ function burn( bytes32 _subgraphDeploymentID, uint256 _signalIn, uint256 _tokensOutMin ) external returns (uint256); /** * @notice Assign Graph Tokens collected as curation fees to the curation pool reserve. * @param _subgraphDeploymentID SubgraphDeployment where funds should be allocated as reserves * @param _tokens Amount of Graph Tokens to add to reserves */ function collect(bytes32 _subgraphDeploymentID, uint256 _tokens) external; // -- Getters -- /** * @notice Check if any GRT tokens are deposited for a SubgraphDeployment. * @param _subgraphDeploymentID SubgraphDeployment to check if curated * @return True if curated, false otherwise */ function isCurated(bytes32 _subgraphDeploymentID) external view returns (bool); /** * @notice Get the amount of signal a curator has in a curation pool. * @param _curator Curator owning the signal tokens * @param _subgraphDeploymentID Subgraph deployment curation pool * @return Amount of signal owned by a curator for the subgraph deployment */ function getCuratorSignal(address _curator, bytes32 _subgraphDeploymentID) external view returns (uint256); /** * @notice Get the amount of signal in a curation pool. * @param _subgraphDeploymentID Subgraph deployment curation poool * @return Amount of signal minted for the subgraph deployment */ function getCurationPoolSignal(bytes32 _subgraphDeploymentID) external view returns (uint256); /** * @notice Get the amount of token reserves in a curation pool. * @param _subgraphDeploymentID Subgraph deployment curation poool * @return Amount of token reserves in the curation pool */ function getCurationPoolTokens(bytes32 _subgraphDeploymentID) external view returns (uint256); /** * @notice Calculate amount of signal that can be bought with tokens in a curation pool. * This function considers and excludes the deposit tax. * @param _subgraphDeploymentID Subgraph deployment to mint signal * @param _tokensIn Amount of tokens used to mint signal * @return Amount of signal that can be bought * @return Amount of tokens that will be burned as curation tax */ function tokensToSignal(bytes32 _subgraphDeploymentID, uint256 _tokensIn) external view returns (uint256, uint256); /** * @notice Calculate number of tokens to get when burning signal from a curation pool. * @param _subgraphDeploymentID Subgraph deployment to burn signal * @param _signalIn Amount of signal to burn * @return Amount of tokens to get for the specified amount of signal */ function signalToTokens(bytes32 _subgraphDeploymentID, uint256 _signalIn) external view returns (uint256); /** * @notice Tax charged when curators deposit funds. * Parts per million. (Allows for 4 decimal points, 999,999 = 99.9999%) * @return Curation tax percentage expressed in PPM */ function curationTaxPercentage() external view returns (uint32); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.7.6; interface IEpochManager { // -- Configuration -- function setEpochLength(uint256 _epochLength) external; // -- Epochs function runEpoch() external; // -- Getters -- function isCurrentEpochRun() external view returns (bool); function blockNum() external view returns (uint256); function blockHash(uint256 _block) external view returns (bytes32); function currentEpoch() external view returns (uint256); function currentEpochBlock() external view returns (uint256); function currentEpochBlockSinceStart() external view returns (uint256); function epochsSince(uint256 _epoch) external view returns (uint256); function epochsSinceUpdate() external view returns (uint256); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.7.6; interface IRewardsManager { /** * @dev Stores accumulated rewards and snapshots related to a particular SubgraphDeployment. */ struct Subgraph { uint256 accRewardsForSubgraph; uint256 accRewardsForSubgraphSnapshot; uint256 accRewardsPerSignalSnapshot; uint256 accRewardsPerAllocatedToken; } // -- Config -- function setIssuancePerBlock(uint256 _issuancePerBlock) external; function setMinimumSubgraphSignal(uint256 _minimumSubgraphSignal) external; // -- Denylist -- function setSubgraphAvailabilityOracle(address _subgraphAvailabilityOracle) external; function setDenied(bytes32 _subgraphDeploymentID, bool _deny) external; function setDeniedMany(bytes32[] calldata _subgraphDeploymentID, bool[] calldata _deny) external; function isDenied(bytes32 _subgraphDeploymentID) external view returns (bool); // -- Getters -- function getNewRewardsPerSignal() external view returns (uint256); function getAccRewardsPerSignal() external view returns (uint256); function getAccRewardsForSubgraph(bytes32 _subgraphDeploymentID) external view returns (uint256); function getAccRewardsPerAllocatedToken(bytes32 _subgraphDeploymentID) external view returns (uint256, uint256); function getRewards(address _allocationID) external view returns (uint256); // -- Updates -- function updateAccRewardsPerSignal() external returns (uint256); function takeRewards(address _allocationID) external returns (uint256); // -- Hooks -- function onSubgraphSignalUpdate(bytes32 _subgraphDeploymentID) external returns (uint256); function onSubgraphAllocationUpdate(bytes32 _subgraphDeploymentID) external returns (uint256); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.6.12 <0.8.0; pragma abicoder v2; import { IStakingBase } from "./IStakingBase.sol"; import { IStakingExtension } from "./IStakingExtension.sol"; import { IMulticall } from "../base/IMulticall.sol"; import { IManaged } from "../governance/IManaged.sol"; /** * @title Interface for the Staking contract * @notice This is the interface that should be used when interacting with the Staking contract. * @dev Note that Staking doesn't actually inherit this interface. This is because of * the custom setup of the Staking contract where part of the functionality is implemented * in a separate contract (StakingExtension) to which calls are delegated through the fallback function. */ interface IStaking is IStakingBase, IStakingExtension, IMulticall, IManaged { // Nothing to see here }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.6.12 <0.8.0; pragma abicoder v2; import { IStakingData } from "./IStakingData.sol"; /** * @title Base interface for the Staking contract. * @dev This interface includes only what's implemented in the base Staking contract. * It does not include the L1 and L2 specific functionality. It also does not include * several functions that are implemented in the StakingExtension contract, and are called * via delegatecall through the fallback function. See IStaking.sol for an interface * that includes the full functionality. */ interface IStakingBase is IStakingData { /** * @dev Emitted when `indexer` stakes `tokens` amount. */ event StakeDeposited(address indexed indexer, uint256 tokens); /** * @dev Emitted when `indexer` unstaked and locked `tokens` amount until `until` block. */ event StakeLocked(address indexed indexer, uint256 tokens, uint256 until); /** * @dev Emitted when `indexer` withdrew `tokens` staked. */ event StakeWithdrawn(address indexed indexer, uint256 tokens); /** * @dev Emitted when `indexer` allocated `tokens` amount to `subgraphDeploymentID` * during `epoch`. * `allocationID` indexer derived address used to identify the allocation. * `metadata` additional information related to the allocation. */ event AllocationCreated( address indexed indexer, bytes32 indexed subgraphDeploymentID, uint256 epoch, uint256 tokens, address indexed allocationID, bytes32 metadata ); /** * @dev Emitted when `indexer` close an allocation in `epoch` for `allocationID`. * An amount of `tokens` get unallocated from `subgraphDeploymentID`. * This event also emits the POI (proof of indexing) submitted by the indexer. * `isPublic` is true if the sender was someone other than the indexer. */ event AllocationClosed( address indexed indexer, bytes32 indexed subgraphDeploymentID, uint256 epoch, uint256 tokens, address indexed allocationID, address sender, bytes32 poi, bool isPublic ); /** * @dev Emitted when `indexer` collects a rebate on `subgraphDeploymentID` for `allocationID`. * `epoch` is the protocol epoch the rebate was collected on * The rebate is for `tokens` amount which are being provided by `assetHolder`; `queryFees` * is the amount up for rebate after `curationFees` are distributed and `protocolTax` is burnt. * `queryRebates` is the amount distributed to the `indexer` with `delegationFees` collected * and sent to the delegation pool. */ event RebateCollected( address assetHolder, address indexed indexer, bytes32 indexed subgraphDeploymentID, address indexed allocationID, uint256 epoch, uint256 tokens, uint256 protocolTax, uint256 curationFees, uint256 queryFees, uint256 queryRebates, uint256 delegationRewards ); /** * @dev Emitted when `indexer` update the delegation parameters for its delegation pool. */ event DelegationParametersUpdated( address indexed indexer, uint32 indexingRewardCut, uint32 queryFeeCut, uint32 cooldownBlocks ); /** * @dev Emitted when `caller` set `assetHolder` address as `allowed` to send funds * to staking contract. */ event AssetHolderUpdate(address indexed caller, address indexed assetHolder, bool allowed); /** * @dev Emitted when `indexer` set `operator` access. */ event SetOperator(address indexed indexer, address indexed operator, bool allowed); /** * @dev Emitted when `indexer` set an address to receive rewards. */ event SetRewardsDestination(address indexed indexer, address indexed destination); /** * @dev Emitted when `extensionImpl` was set as the address of the StakingExtension contract * to which extended functionality is delegated. */ event ExtensionImplementationSet(address indexed extensionImpl); /** * @dev Possible states an allocation can be. * States: * - Null = indexer == address(0) * - Active = not Null && tokens > 0 * - Closed = Active && closedAtEpoch != 0 */ enum AllocationState { Null, Active, Closed } /** * @notice Initialize this contract. * @param _controller Address of the controller that manages this contract * @param _minimumIndexerStake Minimum amount of tokens that an indexer must stake * @param _thawingPeriod Number of blocks that tokens get locked after unstaking * @param _protocolPercentage Percentage of query fees that are burned as protocol fee (in PPM) * @param _curationPercentage Percentage of query fees that are given to curators (in PPM) * @param _maxAllocationEpochs The maximum number of epochs that an allocation can be active * @param _delegationUnbondingPeriod The period in epochs that tokens get locked after undelegating * @param _delegationRatio The ratio between an indexer's own stake and the delegation they can use * @param _rebatesParameters Alpha and lambda parameters for rebates function * @param _extensionImpl Address of the StakingExtension implementation */ function initialize( address _controller, uint256 _minimumIndexerStake, uint32 _thawingPeriod, uint32 _protocolPercentage, uint32 _curationPercentage, uint32 _maxAllocationEpochs, uint32 _delegationUnbondingPeriod, uint32 _delegationRatio, RebatesParameters calldata _rebatesParameters, address _extensionImpl ) external; /** * @notice Set the address of the StakingExtension implementation. * @dev This function can only be called by the governor. * @param _extensionImpl Address of the StakingExtension implementation */ function setExtensionImpl(address _extensionImpl) external; /** * @notice Set the address of the counterpart (L1 or L2) staking contract. * @dev This function can only be called by the governor. * @param _counterpart Address of the counterpart staking contract in the other chain, without any aliasing. */ function setCounterpartStakingAddress(address _counterpart) external; /** * @notice Set the minimum stake needed to be an Indexer * @dev This function can only be called by the governor. * @param _minimumIndexerStake Minimum amount of tokens that an indexer must stake */ function setMinimumIndexerStake(uint256 _minimumIndexerStake) external; /** * @notice Set the number of blocks that tokens get locked after unstaking * @dev This function can only be called by the governor. * @param _thawingPeriod Number of blocks that tokens get locked after unstaking */ function setThawingPeriod(uint32 _thawingPeriod) external; /** * @notice Set the curation percentage of query fees sent to curators. * @dev This function can only be called by the governor. * @param _percentage Percentage of query fees sent to curators */ function setCurationPercentage(uint32 _percentage) external; /** * @notice Set a protocol percentage to burn when collecting query fees. * @dev This function can only be called by the governor. * @param _percentage Percentage of query fees to burn as protocol fee */ function setProtocolPercentage(uint32 _percentage) external; /** * @notice Set the max time allowed for indexers to allocate on a subgraph * before others are allowed to close the allocation. * @dev This function can only be called by the governor. * @param _maxAllocationEpochs Allocation duration limit in epochs */ function setMaxAllocationEpochs(uint32 _maxAllocationEpochs) external; /** * @notice Set the rebate parameters * @dev This function can only be called by the governor. * @param _alphaNumerator Numerator of `alpha` * @param _alphaDenominator Denominator of `alpha` * @param _lambdaNumerator Numerator of `lambda` * @param _lambdaDenominator Denominator of `lambda` */ function setRebateParameters( uint32 _alphaNumerator, uint32 _alphaDenominator, uint32 _lambdaNumerator, uint32 _lambdaDenominator ) external; /** * @notice Set an address as allowed asset holder. * @dev This function can only be called by the governor. * @param _assetHolder Address of allowed source for state channel funds * @param _allowed True if asset holder is allowed */ function setAssetHolder(address _assetHolder, bool _allowed) external; /** * @notice Authorize or unauthorize an address to be an operator for the caller. * @param _operator Address to authorize or unauthorize * @param _allowed Whether the operator is authorized or not */ function setOperator(address _operator, bool _allowed) external; /** * @notice Deposit tokens on the indexer's stake. * The amount staked must be over the minimumIndexerStake. * @param _tokens Amount of tokens to stake */ function stake(uint256 _tokens) external; /** * @notice Deposit tokens on the Indexer stake, on behalf of the Indexer. * The amount staked must be over the minimumIndexerStake. * @param _indexer Address of the indexer * @param _tokens Amount of tokens to stake */ function stakeTo(address _indexer, uint256 _tokens) external; /** * @notice Unstake tokens from the indexer stake, lock them until the thawing period expires. * @dev NOTE: The function accepts an amount greater than the currently staked tokens. * If that happens, it will try to unstake the max amount of tokens it can. * The reason for this behaviour is to avoid time conditions while the transaction * is in flight. * @param _tokens Amount of tokens to unstake */ function unstake(uint256 _tokens) external; /** * @notice Withdraw indexer tokens once the thawing period has passed. */ function withdraw() external; /** * @notice Set the destination where to send rewards for an indexer. * @param _destination Rewards destination address. If set to zero, rewards will be restaked */ function setRewardsDestination(address _destination) external; /** * @notice Set the delegation parameters for the caller. * @param _indexingRewardCut Percentage of indexing rewards left for the indexer * @param _queryFeeCut Percentage of query fees left for the indexer * @param _cooldownBlocks Period that need to pass to update delegation parameters */ function setDelegationParameters( uint32 _indexingRewardCut, uint32 _queryFeeCut, uint32 _cooldownBlocks ) external; /** * @notice Allocate available tokens to a subgraph deployment. * @param _subgraphDeploymentID ID of the SubgraphDeployment where tokens will be allocated * @param _tokens Amount of tokens to allocate * @param _allocationID The allocation identifier * @param _metadata IPFS hash for additional information about the allocation * @param _proof A 65-bytes Ethereum signed message of `keccak256(indexerAddress,allocationID)` */ function allocate( bytes32 _subgraphDeploymentID, uint256 _tokens, address _allocationID, bytes32 _metadata, bytes calldata _proof ) external; /** * @notice Allocate available tokens to a subgraph deployment from and indexer's stake. * The caller must be the indexer or the indexer's operator. * @param _indexer Indexer address to allocate funds from. * @param _subgraphDeploymentID ID of the SubgraphDeployment where tokens will be allocated * @param _tokens Amount of tokens to allocate * @param _allocationID The allocation identifier * @param _metadata IPFS hash for additional information about the allocation * @param _proof A 65-bytes Ethereum signed message of `keccak256(indexerAddress,allocationID)` */ function allocateFrom( address _indexer, bytes32 _subgraphDeploymentID, uint256 _tokens, address _allocationID, bytes32 _metadata, bytes calldata _proof ) external; /** * @notice Close an allocation and free the staked tokens. * To be eligible for rewards a proof of indexing must be presented. * Presenting a bad proof is subject to slashable condition. * To opt out of rewards set _poi to 0x0 * @param _allocationID The allocation identifier * @param _poi Proof of indexing submitted for the allocated period */ function closeAllocation(address _allocationID, bytes32 _poi) external; /** * @notice Collect query fees from state channels and assign them to an allocation. * Funds received are only accepted from a valid sender. * @dev To avoid reverting on the withdrawal from channel flow this function will: * 1) Accept calls with zero tokens. * 2) Accept calls after an allocation passed the dispute period, in that case, all * the received tokens are burned. * @param _tokens Amount of tokens to collect * @param _allocationID Allocation where the tokens will be assigned */ function collect(uint256 _tokens, address _allocationID) external; /** * @notice Return true if operator is allowed for indexer. * @param _operator Address of the operator * @param _indexer Address of the indexer * @return True if operator is allowed for indexer, false otherwise */ function isOperator(address _operator, address _indexer) external view returns (bool); /** * @notice Getter that returns if an indexer has any stake. * @param _indexer Address of the indexer * @return True if indexer has staked tokens */ function hasStake(address _indexer) external view returns (bool); /** * @notice Get the total amount of tokens staked by the indexer. * @param _indexer Address of the indexer * @return Amount of tokens staked by the indexer */ function getIndexerStakedTokens(address _indexer) external view returns (uint256); /** * @notice Get the total amount of tokens available to use in allocations. * This considers the indexer stake and delegated tokens according to delegation ratio * @param _indexer Address of the indexer * @return Amount of tokens available to allocate including delegation */ function getIndexerCapacity(address _indexer) external view returns (uint256); /** * @notice Return the allocation by ID. * @param _allocationID Address used as allocation identifier * @return Allocation data */ function getAllocation(address _allocationID) external view returns (Allocation memory); /** * @notice Return the current state of an allocation * @param _allocationID Allocation identifier * @return AllocationState enum with the state of the allocation */ function getAllocationState(address _allocationID) external view returns (AllocationState); /** * @notice Return if allocationID is used. * @param _allocationID Address used as signer by the indexer for an allocation * @return True if allocationID already used */ function isAllocation(address _allocationID) external view returns (bool); /** * @notice Return the total amount of tokens allocated to subgraph. * @param _subgraphDeploymentID Deployment ID for the subgraph * @return Total tokens allocated to subgraph */ function getSubgraphAllocatedTokens(bytes32 _subgraphDeploymentID) external view returns (uint256); }
// SPDX-License-Identifier: Apache-2.0 /* * Copyright 2020, Offchain Labs, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Originally copied from: * https://github.com/OffchainLabs/arbitrum/tree/e3a6307ad8a2dc2cad35728a2a9908cfd8dd8ef9/packages/arb-bridge-peripherals * * MODIFIED from Offchain Labs' implementation: * - Changed solidity version to 0.7.6 ([email protected]) * */ pragma solidity ^0.7.6; interface ITokenGateway { /// @notice event deprecated in favor of DepositInitiated and WithdrawalInitiated // event OutboundTransferInitiated( // address token, // address indexed _from, // address indexed _to, // uint256 indexed _transferId, // uint256 _amount, // bytes _data // ); /// @notice event deprecated in favor of DepositFinalized and WithdrawalFinalized // event InboundTransferFinalized( // address token, // address indexed _from, // address indexed _to, // uint256 indexed _transferId, // uint256 _amount, // bytes _data // ); function outboundTransfer( address _token, address _to, uint256 _amount, uint256 _maxGas, uint256 _gasPriceBid, bytes calldata _data ) external payable returns (bytes memory); function finalizeInboundTransfer( address _token, address _from, address _to, uint256 _amount, bytes calldata _data ) external payable; /** * @notice Calculate the address used when bridging an ERC20 token * @dev the L1 and L2 address oracles may not always be in sync. * For example, a custom token may have been registered but not deployed or the contract self destructed. * @param l1ERC20 address of L1 token * @return L2 address of a bridged ERC20 token */ function calculateL2TokenAddress(address l1ERC20) external view returns (address); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.7.6; /** * @title Interface for GNS */ interface IGNS { // -- Pool -- /** * @dev The SubgraphData struct holds information about subgraphs * and their signal; both nSignal (i.e. name signal at the GNS level) * and vSignal (i.e. version signal at the Curation contract level) */ struct SubgraphData { uint256 vSignal; // The token of the subgraph-deployment bonding curve uint256 nSignal; // The token of the subgraph bonding curve mapping(address => uint256) curatorNSignal; bytes32 subgraphDeploymentID; uint32 reserveRatioDeprecated; // Ratio for the bonding curve, always 1 in PPM, deprecated. bool disabled; uint256 withdrawableGRT; } /** * @dev The LegacySubgraphKey struct holds the account and sequence ID * used to generate subgraph IDs in legacy subgraphs. */ struct LegacySubgraphKey { address account; uint256 accountSeqID; } // -- Configuration -- /** * @notice Approve curation contract to pull funds. */ function approveAll() external; /** * @notice Set the owner fee percentage. This is used to prevent a subgraph owner to drain all * the name curators tokens while upgrading or deprecating and is configurable in parts per million. * @param _ownerTaxPercentage Owner tax percentage */ function setOwnerTaxPercentage(uint32 _ownerTaxPercentage) external; // -- Publishing -- /** * @notice Allows a graph account to set a default name * @param _graphAccount Account that is setting its name * @param _nameSystem Name system account already has ownership of a name in * @param _nameIdentifier The unique identifier that is used to identify the name in the system * @param _name The name being set as default */ function setDefaultName( address _graphAccount, uint8 _nameSystem, bytes32 _nameIdentifier, string calldata _name ) external; /** * @notice Allows a subgraph owner to update the metadata of a subgraph they have published * @param _subgraphID Subgraph ID * @param _subgraphMetadata IPFS hash for the subgraph metadata */ function updateSubgraphMetadata(uint256 _subgraphID, bytes32 _subgraphMetadata) external; /** * @notice Publish a new subgraph. * @param _subgraphDeploymentID Subgraph deployment for the subgraph * @param _versionMetadata IPFS hash for the subgraph version metadata * @param _subgraphMetadata IPFS hash for the subgraph metadata */ function publishNewSubgraph( bytes32 _subgraphDeploymentID, bytes32 _versionMetadata, bytes32 _subgraphMetadata ) external; /** * @notice Publish a new version of an existing subgraph. * @param _subgraphID Subgraph ID * @param _subgraphDeploymentID Subgraph deployment ID of the new version * @param _versionMetadata IPFS hash for the subgraph version metadata */ function publishNewVersion( uint256 _subgraphID, bytes32 _subgraphDeploymentID, bytes32 _versionMetadata ) external; /** * @notice Deprecate a subgraph. The bonding curve is destroyed, the vSignal is burned, and the GNS * contract holds the GRT from burning the vSignal, which all curators can withdraw manually. * Can only be done by the subgraph owner. * @param _subgraphID Subgraph ID */ function deprecateSubgraph(uint256 _subgraphID) external; // -- Curation -- /** * @notice Deposit GRT into a subgraph and mint signal. * @param _subgraphID Subgraph ID * @param _tokensIn The amount of tokens the nameCurator wants to deposit * @param _nSignalOutMin Expected minimum amount of name signal to receive */ function mintSignal( uint256 _subgraphID, uint256 _tokensIn, uint256 _nSignalOutMin ) external; /** * @notice Burn signal for a subgraph and return the GRT. * @param _subgraphID Subgraph ID * @param _nSignal The amount of nSignal the nameCurator wants to burn * @param _tokensOutMin Expected minimum amount of tokens to receive */ function burnSignal( uint256 _subgraphID, uint256 _nSignal, uint256 _tokensOutMin ) external; /** * @notice Move subgraph signal from sender to `_recipient` * @param _subgraphID Subgraph ID * @param _recipient Address to send the signal to * @param _amount The amount of nSignal to transfer */ function transferSignal( uint256 _subgraphID, address _recipient, uint256 _amount ) external; /** * @notice Withdraw tokens from a deprecated subgraph. * When the subgraph is deprecated, any curator can call this function and * withdraw the GRT they are entitled for its original deposit * @param _subgraphID Subgraph ID */ function withdraw(uint256 _subgraphID) external; // -- Getters -- /** * @notice Return the owner of a subgraph. * @param _tokenID Subgraph ID * @return Owner address */ function ownerOf(uint256 _tokenID) external view returns (address); /** * @notice Return the total signal on the subgraph. * @param _subgraphID Subgraph ID * @return Total signal on the subgraph */ function subgraphSignal(uint256 _subgraphID) external view returns (uint256); /** * @notice Return the total tokens on the subgraph at current value. * @param _subgraphID Subgraph ID * @return Total tokens on the subgraph */ function subgraphTokens(uint256 _subgraphID) external view returns (uint256); /** * @notice Calculate subgraph signal to be returned for an amount of tokens. * @param _subgraphID Subgraph ID * @param _tokensIn Tokens being exchanged for subgraph signal * @return Amount of subgraph signal and curation tax */ function tokensToNSignal(uint256 _subgraphID, uint256 _tokensIn) external view returns ( uint256, uint256, uint256 ); /** * @notice Calculate tokens returned for an amount of subgraph signal. * @param _subgraphID Subgraph ID * @param _nSignalIn Subgraph signal being exchanged for tokens * @return Amount of tokens returned for an amount of subgraph signal */ function nSignalToTokens(uint256 _subgraphID, uint256 _nSignalIn) external view returns (uint256, uint256); /** * @notice Calculate subgraph signal to be returned for an amount of subgraph deployment signal. * @param _subgraphID Subgraph ID * @param _vSignalIn Amount of subgraph deployment signal to exchange for subgraph signal * @return Amount of subgraph signal that can be bought */ function vSignalToNSignal(uint256 _subgraphID, uint256 _vSignalIn) external view returns (uint256); /** * @notice Calculate subgraph deployment signal to be returned for an amount of subgraph signal. * @param _subgraphID Subgraph ID * @param _nSignalIn Subgraph signal being exchanged for subgraph deployment signal * @return Amount of subgraph deployment signal that can be returned */ function nSignalToVSignal(uint256 _subgraphID, uint256 _nSignalIn) external view returns (uint256); /** * @notice Get the amount of subgraph signal a curator has. * @param _subgraphID Subgraph ID * @param _curator Curator address * @return Amount of subgraph signal owned by a curator */ function getCuratorSignal(uint256 _subgraphID, address _curator) external view returns (uint256); /** * @notice Return whether a subgraph is published. * @param _subgraphID Subgraph ID * @return Return true if subgraph is currently published */ function isPublished(uint256 _subgraphID) external view returns (bool); /** * @notice Return whether a subgraph is a legacy subgraph (created before subgraph NFTs). * @param _subgraphID Subgraph ID * @return Return true if subgraph is a legacy subgraph */ function isLegacySubgraph(uint256 _subgraphID) external view returns (bool); /** * @notice Returns account and sequence ID for a legacy subgraph (created before subgraph NFTs). * @param _subgraphID Subgraph ID * @return account Account that created the subgraph (or 0 if it's not a legacy subgraph) * @return seqID Sequence number for the subgraph */ function getLegacySubgraphKey(uint256 _subgraphID) external view returns (address account, uint256 seqID); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.7.6; import { IController } from "./IController.sol"; /** * @title Managed Interface * @dev Interface for contracts that can be managed by a controller. */ interface IManaged { /** * @notice Set the controller that manages this contract * @dev Only the current controller can set a new controller * @param _controller Address of the new controller */ function setController(address _controller) external; /** * @notice Sync protocol contract addresses from the Controller registry * @dev This function will cache all the contracts using the latest addresses. * Anyone can call the function whenever a Proxy contract change in the * controller to ensure the protocol is using the latest version. */ function syncAllContracts() external; /** * @notice Get the Controller that manages this contract * @return The Controller as an IController interface */ function controller() external view returns (IController); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.7.6; pragma abicoder v2; /** * @title Multicall interface * @notice Enables calling multiple methods in a single call to the contract */ interface IMulticall { /** * @notice Call multiple functions in the current contract and return the data from all of them if they all succeed * @param data The encoded function data for each of the calls to make to this contract * @return results The results from each of the calls passed in via data */ function multicall(bytes[] calldata data) external returns (bytes[] memory results); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @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: GPL-2.0-or-later pragma solidity ^0.7.6; interface IGraphProxy { function admin() external returns (address); function setAdmin(address _newAdmin) external; function implementation() external returns (address); function pendingImplementation() external returns (address); function upgradeTo(address _newImplementation) external; function acceptUpgrade() external; function acceptUpgradeAndCall(bytes calldata data) external; }
{ "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"nameHash","type":"bytes32"},{"indexed":false,"internalType":"address","name":"contractAddress","type":"address"}],"name":"ContractSynced","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"param","type":"string"}],"name":"ParameterUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"controller","type":"address"}],"name":"SetController","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"slasher","type":"address"},{"indexed":false,"internalType":"bool","name":"allowed","type":"bool"}],"name":"SlasherUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"indexer","type":"address"},{"indexed":true,"internalType":"address","name":"delegator","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokens","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"StakeDelegated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"indexer","type":"address"},{"indexed":true,"internalType":"address","name":"delegator","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokens","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"until","type":"uint256"}],"name":"StakeDelegatedLocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"indexer","type":"address"},{"indexed":true,"internalType":"address","name":"delegator","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokens","type":"uint256"}],"name":"StakeDelegatedWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"indexer","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokens","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"},{"indexed":false,"internalType":"address","name":"beneficiary","type":"address"}],"name":"StakeSlashed","type":"event"},{"inputs":[{"internalType":"contract IGraphProxy","name":"_proxy","type":"address"}],"name":"acceptProxy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IGraphProxy","name":"_proxy","type":"address"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"acceptProxyAndCall","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_allocationID","type":"address"}],"name":"allocations","outputs":[{"components":[{"internalType":"address","name":"indexer","type":"address"},{"internalType":"bytes32","name":"subgraphDeploymentID","type":"bytes32"},{"internalType":"uint256","name":"tokens","type":"uint256"},{"internalType":"uint256","name":"createdAtEpoch","type":"uint256"},{"internalType":"uint256","name":"closedAtEpoch","type":"uint256"},{"internalType":"uint256","name":"collectedFees","type":"uint256"},{"internalType":"uint256","name":"__DEPRECATED_effectiveAllocation","type":"uint256"},{"internalType":"uint256","name":"accRewardsPerAllocatedToken","type":"uint256"},{"internalType":"uint256","name":"distributedRebates","type":"uint256"}],"internalType":"struct IStakingData.Allocation","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"alphaDenominator","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"alphaNumerator","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_maybeAssetHolder","type":"address"}],"name":"assetHolders","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"controller","outputs":[{"internalType":"contract IController","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"curationPercentage","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_indexer","type":"address"},{"internalType":"uint256","name":"_tokens","type":"uint256"}],"name":"delegate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"delegationParametersCooldown","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_indexer","type":"address"}],"name":"delegationPools","outputs":[{"components":[{"internalType":"uint32","name":"cooldownBlocks","type":"uint32"},{"internalType":"uint32","name":"indexingRewardCut","type":"uint32"},{"internalType":"uint32","name":"queryFeeCut","type":"uint32"},{"internalType":"uint256","name":"updatedAtBlock","type":"uint256"},{"internalType":"uint256","name":"tokens","type":"uint256"},{"internalType":"uint256","name":"shares","type":"uint256"}],"internalType":"struct IStakingExtension.DelegationPoolReturn","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"delegationRatio","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"delegationTaxPercentage","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"delegationUnbondingPeriod","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_indexer","type":"address"},{"internalType":"address","name":"_delegator","type":"address"}],"name":"getDelegation","outputs":[{"components":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"uint256","name":"tokensLocked","type":"uint256"},{"internalType":"uint256","name":"tokensLockedUntil","type":"uint256"}],"internalType":"struct IStakingData.Delegation","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"uint256","name":"tokensLocked","type":"uint256"},{"internalType":"uint256","name":"tokensLockedUntil","type":"uint256"}],"internalType":"struct IStakingData.Delegation","name":"_delegation","type":"tuple"}],"name":"getWithdraweableDelegatedTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_delegationUnbondingPeriod","type":"uint32"},{"internalType":"uint32","name":"_cooldownBlocks","type":"uint32"},{"internalType":"uint32","name":"_delegationRatio","type":"uint32"},{"internalType":"uint32","name":"_delegationTaxPercentage","type":"uint32"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_indexer","type":"address"},{"internalType":"address","name":"_delegator","type":"address"}],"name":"isDelegator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lambdaDenominator","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lambdaNumerator","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxAllocationEpochs","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minimumIndexerStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_indexer","type":"address"},{"internalType":"address","name":"_maybeOperator","type":"address"}],"name":"operatorAuth","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolPercentage","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_indexer","type":"address"}],"name":"rewardsDestination","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_controller","type":"address"}],"name":"setController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_blocks","type":"uint32"}],"name":"setDelegationParametersCooldown","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_delegationRatio","type":"uint32"}],"name":"setDelegationRatio","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_percentage","type":"uint32"}],"name":"setDelegationTaxPercentage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_delegationUnbondingPeriod","type":"uint32"}],"name":"setDelegationUnbondingPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_slasher","type":"address"},{"internalType":"bool","name":"_allowed","type":"bool"}],"name":"setSlasher","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_indexer","type":"address"},{"internalType":"uint256","name":"_tokens","type":"uint256"},{"internalType":"uint256","name":"_reward","type":"uint256"},{"internalType":"address","name":"_beneficiary","type":"address"}],"name":"slash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_maybeSlasher","type":"address"}],"name":"slashers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_indexer","type":"address"}],"name":"stakes","outputs":[{"components":[{"internalType":"uint256","name":"tokensStaked","type":"uint256"},{"internalType":"uint256","name":"tokensAllocated","type":"uint256"},{"internalType":"uint256","name":"tokensLocked","type":"uint256"},{"internalType":"uint256","name":"tokensLockedUntil","type":"uint256"}],"internalType":"struct Stakes.Indexer","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_subgraphDeploymentId","type":"bytes32"}],"name":"subgraphAllocations","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"syncAllContracts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"thawingPeriod","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_indexer","type":"address"},{"internalType":"uint256","name":"_shares","type":"uint256"}],"name":"undelegate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_indexer","type":"address"},{"internalType":"address","name":"_newIndexer","type":"address"}],"name":"withdrawDelegated","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6101606040527fe6876326c1291dfcbbd3864a6816d698cd591defc7aa2153d7f9c4c04016c89f6080527fc713c3df6d14cdf946460395d09af88993ee2b948b1a808161494e32c5f6706360a0527f966f1e8d8d8014e05f6ec4a57138da9be1f7c5a7f802928a18072f7c5318076160c0527f1df41cd916959d1163dc8f0671a666ea8a3e434c13e40faef527133b5d16703460e0527f45fc200c7e4544e457d3c5709bfe0d520442c30bbcbdaede89e8d4a4bbc19247610100527fd362cac9cb75c10d67bcc0b7eeb0b1ef48bb5420b556c092d4fd7f758816fcf0610120527f39605a6c26a173774ca666c67ef70cf491880e5d3d6d0ca66ec0a31034f15ea36101405234801561011057600080fd5b5060805160a05160c05160e05161010051610120516101405161289f61016e60003980610dda525080610db1525080610d88528061122e525080610d5f525080610d36525080610d0d52806114ec525080610ce4525061289f6000f3fe608060405234801561001057600080fd5b506004361061023d5760003560e01c806392eefe9b1161013b578063ce853613116100b8578063e76fede61161007c578063e76fede6146104b7578063f2485bf2146104ca578063f77c4791146104d2578063f8b80a92146104da578063fb765938146104ed5761023d565b8063ce85361314610479578063d6866ea514610481578063e2e9465614610489578063e6aeb7961461049c578063e6dc5a1c146104a45761023d565b8063b1468f52116100ff578063b1468f521461043b578063b6846e471461044e578063b87fcbff14610456578063bfdfa7af14610469578063cdc747dd146104715761023d565b806392eefe9b146103e75780639ce7abe5146103fa578063a0e119291461040d578063a2594d8214610420578063a26b90f2146104335761023d565b806352348080116101c95780637203ca781161018d5780637203ca781461038f5780637ef82070146103af57806385b52ad0146103b75780638a7ff87d146103bf57806392511c8f146103c75761023d565b8063523480801461031657806352a9039c146103295780635e9a63921461034957806369d33c2f1461035c5780636b535d7e1461036f5761023d565b806316934fc41161021057806316934fc4146102b35780631dd42f60146102d35780634b8a9b8e146102e85780634d99dd16146102f057806351a60b02146103035761023d565b8063026e402b1461024257806309da07f71461026b578063130bea571461028057806315049a5a14610293575b600080fd5b610255610250366004612244565b6104f5565b60405161026291906127b6565b60405180910390f35b610273610527565b6040516102629190612802565b61025561028e366004612350565b61053a565b6102a66102a13660046121db565b6105eb565b604051610262919061276a565b6102c66102c13660046121bf565b610646565b604051610262919061278b565b6102e66102e13660046123bd565b61069c565b005b6102736106b0565b6102556102fe366004612244565b6106c3565b6102556103113660046121db565b6106df565b6102e6610324366004612213565b6106f4565b61033c6103373660046121bf565b61078d565b60405161026291906126b2565b6102e66103573660046123bd565b61081a565b6102e661036a3660046123d7565b61082b565b61038261037d3660046121bf565b6108b8565b604051610262919061243e565b6103a261039d3660046121bf565b6108d6565b604051610262919061242a565b6102736108f4565b610273610907565b61027361091b565b6103da6103d53660046121bf565b61092f565b604051610262919061271a565b6102e66103f53660046121bf565b6109ab565b6102e66104083660046122d0565b6109bc565b61038261041b3660046121db565b610b12565b6102e661042e3660046121bf565b610b43565b610273610c5e565b6102556104493660046122b8565b610c71565b610273610c83565b6103826104643660046121bf565b610c96565b610273610cb4565b610273610cc0565b610273610ccc565b6102e6610cdf565b6103826104973660046121db565b610e00565b610273610e2e565b6102e66104b23660046123bd565b610e41565b6102e66104c536600461226f565b610e52565b610255611080565b6103a2611086565b6102e66104e83660046123bd565b611095565b6102736110a6565b60006104ff6110b9565b3361051261050b611227565b8285611257565b61051d818585611324565b9150505b92915050565b601954600160a01b900463ffffffff1690565b6000806105456114e5565b6001600160a01b031663766718086040518163ffffffff1660e01b815260040160206040518083038186803b15801561057d57600080fd5b505afa158015610591573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105b591906123a5565b9050600083604001511180156105cf575082604001518110155b156105e057505060208101516105e6565b60009150505b919050565b6105f36120c2565b506001600160a01b03918216600090815260146020908152604080832093909416825260049092018252829020825160608101845281548152600182015492810192909252600201549181019190915290565b61064e6120e3565b506001600160a01b03166000908152600e6020908152604091829020825160808101845281548152600182015492810192909252600281015492820192909252600390910154606082015290565b6106a4611510565b6106ad816115e4565b50565b601954600160c01b900463ffffffff1690565b60006106cd6110b9565b6106d8338484611620565b9392505050565b60006106e961182b565b6106d83384846118de565b6106fc611510565b6001600160a01b03821661072b5760405162461bcd60e51b815260040161072290612449565b60405180910390fd5b6001600160a01b03821660008181526012602052604090819020805460ff19168415151790555133907f87ea6771e87d96ce16dbe8eda64da9473733e4c1c568baf8ae47256c5bd765e99061078190859061243e565b60405180910390a35050565b61079561210b565b506001600160a01b039081166000908152600f6020908152604091829020825161012081018452815490941684526001810154918401919091526002810154918301919091526003810154606083015260048101546080830152600581015460a0830152600681015460c0830152600781015460e08301526008015461010082015290565b610822611510565b6106ad816119ef565b610833611a54565b6001600160a01b0316336001600160a01b03161461088e576040805162461bcd60e51b815260206004820152601360248201527227b7363c9034b6b83632b6b2b73a30ba34b7b760691b604482015290519081900360640190fd5b610897846119ef565b6108a083611a79565b6108a9826115e4565b6108b281611ab5565b50505050565b6001600160a01b031660009081526016602052604090205460ff1690565b6001600160a01b039081166000908152601760205260409020541690565b600d54600160a01b900463ffffffff1690565b600d54640100000000900463ffffffff1690565b601354640100000000900463ffffffff1690565b610937612163565b506001600160a01b0316600090815260146020908152604091829020825160c081018452815463ffffffff80821683526401000000008204811694830194909452600160401b900490921692820192909252600182015460608201526002820154608082015260039091015460a082015290565b6109b3611b18565b6106ad81611b77565b82806001600160a01b031663f851a4406040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156109f857600080fd5b505af1158015610a0c573d6000803e3d6000fd5b505050506040513d6020811015610a2257600080fd5b50516001600160a01b03163314610a80576040805162461bcd60e51b815260206004820152601e60248201527f43616c6c6572206d757374206265207468652070726f78792061646d696e0000604482015290519081900360640190fd5b60405163623faf6160e01b8152602060048201908152602482018490526001600160a01b0386169163623faf619186918691908190604401848480828437600081840152601f19601f8201169050808301925050509350505050600060405180830381600087803b158015610af457600080fd5b505af1158015610b08573d6000803e3d6000fd5b5050505050505050565b6001600160a01b03918216600090815260146020908152604080832093909416825260049092019091522054151590565b80806001600160a01b031663f851a4406040518163ffffffff1660e01b8152600401602060405180830381600087803b158015610b7f57600080fd5b505af1158015610b93573d6000803e3d6000fd5b505050506040513d6020811015610ba957600080fd5b50516001600160a01b03163314610c07576040805162461bcd60e51b815260206004820152601e60248201527f43616c6c6572206d757374206265207468652070726f78792061646d696e0000604482015290519081900360640190fd5b816001600160a01b03166359fc20bb6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610c4257600080fd5b505af1158015610c56573d6000803e3d6000fd5b505050505050565b600d54600160401b900463ffffffff1690565b60009081526010602052604090205490565b601354600160401b900463ffffffff1690565b6001600160a01b031660009081526012602052604090205460ff1690565b60135463ffffffff1690565b600d5463ffffffff1690565b600d54600160c01b900463ffffffff1690565b610d087f0000000000000000000000000000000000000000000000000000000000000000611c1f565b610d317f0000000000000000000000000000000000000000000000000000000000000000611c1f565b610d5a7f0000000000000000000000000000000000000000000000000000000000000000611c1f565b610d837f0000000000000000000000000000000000000000000000000000000000000000611c1f565b610dac7f0000000000000000000000000000000000000000000000000000000000000000611c1f565b610dd57f0000000000000000000000000000000000000000000000000000000000000000611c1f565b610dfe7f0000000000000000000000000000000000000000000000000000000000000000611c1f565b565b6001600160a01b03918216600090815260156020908152604080832093909416825291909152205460ff1690565b601354600160601b900463ffffffff1690565b610e49611510565b6106ad81611ab5565b3360009081526012602052604090205460ff161515600114610e865760405162461bcd60e51b815260040161072290612449565b610e8e6110b9565b6001600160a01b0384166000908152600e6020526040902083610ec35760405162461bcd60e51b815260040161072290612548565b82841015610ee35760405162461bcd60e51b81526004016107229061268b565b8054610f015760405162461bcd60e51b81526004016107229061266b565b8054841115610f225760405162461bcd60e51b815260040161072290612592565b6001600160a01b038216610f485760405162461bcd60e51b81526004016107229061246b565b60408051608081018252825481526001830154602082015260028301549181019190915260038201546060820152610f7f90611d21565b84118015610f91575060008160020154115b15610fff576000610fde610fd783604051806080016040529081600082015481526020016001820154815260200160028201548152602001600382015481525050611d21565b8690611d2d565b90506000610ff0828460020154611d8a565b9050610ffc8382611da1565b50505b6110098185611dc6565b6000611013611227565b9050611028816110238787611d2d565b611dd8565b611033818486611e24565b856001600160a01b03167ff2717be2f27d9d2d7d265e42dc556e40d2d9aeaba02f49c5286030f30c0571f3868686604051611070939291906127cd565b60405180910390a2505050505050565b600c5490565b6000546001600160a01b031681565b61109d611510565b6106ad81611a79565b600d54600160801b900463ffffffff1690565b60008054906101000a90046001600160a01b03166001600160a01b0316635c975abb6040518163ffffffff1660e01b815260040160206040518083038186803b15801561110557600080fd5b505afa158015611119573d6000803e3d6000fd5b505050506040513d602081101561112f57600080fd5b50511561116c576040805162461bcd60e51b815260206004820152600660248201526514185d5cd95960d21b604482015290519081900360640190fd5b60008054906101000a90046001600160a01b03166001600160a01b0316632e292fc76040518163ffffffff1660e01b815260040160206040518083038186803b1580156111b857600080fd5b505afa1580156111cc573d6000803e3d6000fd5b505050506040513d60208110156111e257600080fd5b505115610dfe576040805162461bcd60e51b815260206004820152600e60248201526d14185c9d1a585b0b5c185d5cd95960921b604482015290519081900360640190fd5b60006112527f0000000000000000000000000000000000000000000000000000000000000000611e81565b905090565b801561131f57604080516323b872dd60e01b81526001600160a01b038481166004830152306024830152604482018490529151918516916323b872dd916064808201926020929091908290030181600087803b1580156112b657600080fd5b505af11580156112ca573d6000803e3d6000fd5b505050506040513d60208110156112e057600080fd5b505161131f576040805162461bcd60e51b815260206004820152600960248201526810ba3930b739b332b960b91b604482015290519081900360640190fd5b505050565b60008082116113455760405162461bcd60e51b815260040161072290612548565b6001600160a01b03831661136b5760405162461bcd60e51b8152600401610722906124c8565b6001600160a01b0383166000908152600e60205260409020546113a05760405162461bcd60e51b81526004016107229061266b565b6001600160a01b0380841660009081526014602090815260408083209388168352600484019091528120906113ed6113d6611227565b6013548790600160601b900463ffffffff16611f1d565b905060006113fb8683611d2d565b90506000846002015460001461143557611430856002015461142a876003015485611f4590919063ffffffff16565b90611f9e565b611437565b815b9050600081116114595760405162461bcd60e51b8152600401610722906125ee565b60028501546114689083612005565b6002860155600385015461147c9082612005565b6003860155835461148d9082612005565b84556040516001600160a01b03808b1691908a16907fcd0366dce5247d874ffc60a762aa7abbb82c1695bbb171609c1b8861e279eb73906114d190869086906127bf565b60405180910390a398975050505050505050565b60006112527f0000000000000000000000000000000000000000000000000000000000000000611e81565b60008054906101000a90046001600160a01b03166001600160a01b0316634fc07d756040518163ffffffff1660e01b815260040160206040518083038186803b15801561155c57600080fd5b505afa158015611570573d6000803e3d6000fd5b505050506040513d602081101561158657600080fd5b50516001600160a01b03163314610dfe576040805162461bcd60e51b815260206004820152601860248201527f4f6e6c7920436f6e74726f6c6c657220676f7665726e6f720000000000000000604482015290519081900360640190fd5b6013805463ffffffff191663ffffffff83161790556040516000805160206128298339815191529061161590612569565b60405180910390a150565b60008082116116415760405162461bcd60e51b8152600401610722906125ee565b6001600160a01b0380841660009081526014602090815260408083209388168352600484019091529020805484111561168c5760405162461bcd60e51b8152600401610722906124ea565b6040805160608101825282548152600183015460208201526002830154918101919091526000906116bc9061053a565b11156116d0576116ce868660006118de565b505b60006116f1836003015461142a856002015488611f4590919063ffffffff16565b60028401549091506117039082611d2d565b600284015560038301546117179086611d2d565b600384015581546117289086611d2d565b825560018201546117399082612005565b60018301556013546117d090600160401b900463ffffffff1661175a6114e5565b6001600160a01b031663766718086040518163ffffffff1660e01b815260040160206040518083038186803b15801561179257600080fd5b505afa1580156117a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117ca91906123a5565b90612005565b600283018190556040516001600160a01b03808a1692908916917f0430183f84d9c4502386d499da806543dee1d9de83c08b01e39a6d2116c43b25916118199186918b916127ec565b60405180910390a39695505050505050565b60008054906101000a90046001600160a01b03166001600160a01b0316635c975abb6040518163ffffffff1660e01b815260040160206040518083038186803b15801561187757600080fd5b505afa15801561188b573d6000803e3d6000fd5b505050506040513d60208110156118a157600080fd5b505115610dfe576040805162461bcd60e51b815260206004820152600660248201526514185d5cd95960d21b604482015290519081900360640190fd5b6001600160a01b038083166000908152601460209081526040808320938716835260048401825280832081516060810183528154815260018201549381019390935260028101549183019190915291929190839061193b9061053a565b90506000811161195d5760405162461bcd60e51b815260040161072290612548565b60006001830181905560028301556040516001600160a01b0380891691908816907f1b2e7737e043c5cf1b587ceb4daeb7ae00148b9bda8f79f1093eead08f141952906119ab9085906127b6565b60405180910390a36001600160a01b038516156119d3576119cd878683611324565b506119e5565b6119e56119de611227565b8883611e24565b9695505050505050565b60008163ffffffff1611611a155760405162461bcd60e51b8152600401610722906125b7565b601380546bffffffff00000000000000001916600160401b63ffffffff8416021790556040516000805160206128298339815191529061161590612511565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6013805467ffffffff00000000191664010000000063ffffffff841602179055604051600080516020612829833981519152906116159061260f565b620f424063ffffffff82161115611ade5760405162461bcd60e51b815260040161072290612646565b6013805463ffffffff60601b1916600160601b63ffffffff8416021790556040516000805160206128298339815191529061161590612491565b6000546001600160a01b03163314610dfe576040805162461bcd60e51b815260206004820152601960248201527f43616c6c6572206d75737420626520436f6e74726f6c6c657200000000000000604482015290519081900360640190fd5b6001600160a01b038116611bcb576040805162461bcd60e51b815260206004820152601660248201527510dbdb9d1c9bdb1b195c881b5d5cdd081899481cd95d60521b604482015290519081900360640190fd5b600080546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f4ff638452bbf33c012645d18ae6f05515ff5f2d1dfb0cece8cbf018c60903f709181900360200190a150565b6000805460408051637bb20d2f60e11b81526004810185905290516001600160a01b039092169163f7641a5e91602480820192602092909190829003018186803b158015611c6c57600080fd5b505afa158015611c80573d6000803e3d6000fd5b505050506040513d6020811015611c9657600080fd5b50516000838152600160205260409020549091506001600160a01b03808316911614611d1d5760008281526001602090815260409182902080546001600160a01b0319166001600160a01b0385169081179091558251908152915184927fd0e7a942b1fc38c411c4f53d153ba14fd24542a6a35ebacd9b6afca1a154e20692908290030190a25b5050565b6000610521828261205f565b600082821115611d84576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b600081831115611d9a57816106d8565b5090919050565b6002820154611db09082611d2d565b60028301819055611d1d57600060038301555050565b8154611dd29082611d2d565b90915550565b8015611d1d57816001600160a01b03166342966c68826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015610c4257600080fd5b801561131f57826001600160a01b031663a9059cbb83836040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156112b657600080fd5b6000818152600160205260408120546001600160a01b0316806105215760005460408051637bb20d2f60e11b81526004810186905290516001600160a01b039092169163f7641a5e91602480820192602092909190829003018186803b158015611eea57600080fd5b505afa158015611efe573d6000803e3d6000fd5b505050506040513d6020811015611f1457600080fd5b50519392505050565b600080611f31620f424061142a8587611f45565b9050611f3d8582611dd8565b949350505050565b600082611f5457506000610521565b82820282848281611f6157fe5b04146106d85760405162461bcd60e51b81526004018080602001828103825260218152602001806128496021913960400191505060405180910390fd5b6000808211611ff4576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b818381611ffd57fe5b049392505050565b6000828201838110156106d8576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b815160009081906120709084612005565b9050600061207d856120a5565b90508181111561209257600092505050610521565b61209c8282611d2d565b95945050505050565b60006105218260400151836020015161200590919063ffffffff16565b60405180606001604052806000815260200160008152602001600081525090565b6040518060800160405280600081526020016000815260200160008152602001600081525090565b60405180610120016040528060006001600160a01b0316815260200160008019168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040518060c00160405280600063ffffffff168152602001600063ffffffff168152602001600063ffffffff1681526020016000815260200160008152602001600081525090565b803563ffffffff811681146105e657600080fd5b6000602082840312156121d0578081fd5b81356106d881612813565b600080604083850312156121ed578081fd5b82356121f881612813565b9150602083013561220881612813565b809150509250929050565b60008060408385031215612225578182fd5b823561223081612813565b915060208301358015158114612208578182fd5b60008060408385031215612256578182fd5b823561226181612813565b946020939093013593505050565b60008060008060808587031215612284578182fd5b843561228f81612813565b9350602085013592506040850135915060608501356122ad81612813565b939692955090935050565b6000602082840312156122c9578081fd5b5035919050565b6000806000604084860312156122e4578283fd5b83356122ef81612813565b9250602084013567ffffffffffffffff8082111561230b578384fd5b818601915086601f83011261231e578384fd5b81358181111561232c578485fd5b87602082850101111561233d578485fd5b6020830194508093505050509250925092565b600060608284031215612361578081fd5b6040516060810181811067ffffffffffffffff8211171561237e57fe5b80604052508235815260208301356020820152604083013560408201528091505092915050565b6000602082840312156123b6578081fd5b5051919050565b6000602082840312156123ce578081fd5b6106d8826121ab565b600080600080608085870312156123ec578384fd5b6123f5856121ab565b9350612403602086016121ab565b9250612411604086016121ab565b915061241f606086016121ab565b905092959194509250565b6001600160a01b0391909116815260200190565b901515815260200190565b60208082526008908201526710b9b630b9b432b960c11b604082015260600190565b6020808252600c908201526b2162656e656669636961727960a01b604082015260600190565b60208082526017908201527f64656c65676174696f6e54617850657263656e74616765000000000000000000604082015260600190565b60208082526008908201526710b4b73232bc32b960c11b604082015260600190565b6020808252600d908201526c085cda185c995ccb585d985a5b609a1b604082015260600190565b60208082526019908201527f64656c65676174696f6e556e626f6e64696e67506572696f6400000000000000604082015260600190565b60208082526007908201526621746f6b656e7360c81b604082015260600190565b6020808252600f908201526e64656c65676174696f6e526174696f60881b604082015260600190565b6020808252600b908201526a736c6173683e7374616b6560a81b604082015260600190565b6020808252601a908201527f2164656c65676174696f6e556e626f6e64696e67506572696f64000000000000604082015260600190565b6020808252600790820152662173686172657360c81b604082015260600190565b6020808252601c908201527f64656c65676174696f6e506172616d6574657273436f6f6c646f776e00000000604082015260600190565b6020808252600b908201526a3e70657263656e7461676560a81b604082015260600190565b602080825260069082015265217374616b6560d01b604082015260600190565b6020808252600d908201526c0e4caeec2e4c8e67ce6d8c2e6d609b1b604082015260600190565b81516001600160a01b031681526020808301519082015260408083015190820152606080830151908201526080808301519082015260a0828101519082015260c0808301519082015260e0808301519082015261010091820151918101919091526101200190565b600060c08201905063ffffffff80845116835280602085015116602084015280604085015116604084015250606083015160608301526080830151608083015260a083015160a083015292915050565b81518152602080830151908201526040918201519181019190915260600190565b8151815260208083015190820152604080830151908201526060918201519181019190915260800190565b90815260200190565b918252602082015260400190565b92835260208301919091526001600160a01b0316604082015260600190565b9283526020830191909152604082015260600190565b63ffffffff91909116815260200190565b6001600160a01b03811681146106ad57600080fdfe96d5a4b4edf1cefd0900c166d64447f8da1d01d1861a6a60894b5b82a2c15c3c536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a26469706673582212203cd17ff3f2a4eed9880a80869627b8a2ac7177f564cd84b9c98c45314cbe93ec64736f6c63430007060033
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061023d5760003560e01c806392eefe9b1161013b578063ce853613116100b8578063e76fede61161007c578063e76fede6146104b7578063f2485bf2146104ca578063f77c4791146104d2578063f8b80a92146104da578063fb765938146104ed5761023d565b8063ce85361314610479578063d6866ea514610481578063e2e9465614610489578063e6aeb7961461049c578063e6dc5a1c146104a45761023d565b8063b1468f52116100ff578063b1468f521461043b578063b6846e471461044e578063b87fcbff14610456578063bfdfa7af14610469578063cdc747dd146104715761023d565b806392eefe9b146103e75780639ce7abe5146103fa578063a0e119291461040d578063a2594d8214610420578063a26b90f2146104335761023d565b806352348080116101c95780637203ca781161018d5780637203ca781461038f5780637ef82070146103af57806385b52ad0146103b75780638a7ff87d146103bf57806392511c8f146103c75761023d565b8063523480801461031657806352a9039c146103295780635e9a63921461034957806369d33c2f1461035c5780636b535d7e1461036f5761023d565b806316934fc41161021057806316934fc4146102b35780631dd42f60146102d35780634b8a9b8e146102e85780634d99dd16146102f057806351a60b02146103035761023d565b8063026e402b1461024257806309da07f71461026b578063130bea571461028057806315049a5a14610293575b600080fd5b610255610250366004612244565b6104f5565b60405161026291906127b6565b60405180910390f35b610273610527565b6040516102629190612802565b61025561028e366004612350565b61053a565b6102a66102a13660046121db565b6105eb565b604051610262919061276a565b6102c66102c13660046121bf565b610646565b604051610262919061278b565b6102e66102e13660046123bd565b61069c565b005b6102736106b0565b6102556102fe366004612244565b6106c3565b6102556103113660046121db565b6106df565b6102e6610324366004612213565b6106f4565b61033c6103373660046121bf565b61078d565b60405161026291906126b2565b6102e66103573660046123bd565b61081a565b6102e661036a3660046123d7565b61082b565b61038261037d3660046121bf565b6108b8565b604051610262919061243e565b6103a261039d3660046121bf565b6108d6565b604051610262919061242a565b6102736108f4565b610273610907565b61027361091b565b6103da6103d53660046121bf565b61092f565b604051610262919061271a565b6102e66103f53660046121bf565b6109ab565b6102e66104083660046122d0565b6109bc565b61038261041b3660046121db565b610b12565b6102e661042e3660046121bf565b610b43565b610273610c5e565b6102556104493660046122b8565b610c71565b610273610c83565b6103826104643660046121bf565b610c96565b610273610cb4565b610273610cc0565b610273610ccc565b6102e6610cdf565b6103826104973660046121db565b610e00565b610273610e2e565b6102e66104b23660046123bd565b610e41565b6102e66104c536600461226f565b610e52565b610255611080565b6103a2611086565b6102e66104e83660046123bd565b611095565b6102736110a6565b60006104ff6110b9565b3361051261050b611227565b8285611257565b61051d818585611324565b9150505b92915050565b601954600160a01b900463ffffffff1690565b6000806105456114e5565b6001600160a01b031663766718086040518163ffffffff1660e01b815260040160206040518083038186803b15801561057d57600080fd5b505afa158015610591573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105b591906123a5565b9050600083604001511180156105cf575082604001518110155b156105e057505060208101516105e6565b60009150505b919050565b6105f36120c2565b506001600160a01b03918216600090815260146020908152604080832093909416825260049092018252829020825160608101845281548152600182015492810192909252600201549181019190915290565b61064e6120e3565b506001600160a01b03166000908152600e6020908152604091829020825160808101845281548152600182015492810192909252600281015492820192909252600390910154606082015290565b6106a4611510565b6106ad816115e4565b50565b601954600160c01b900463ffffffff1690565b60006106cd6110b9565b6106d8338484611620565b9392505050565b60006106e961182b565b6106d83384846118de565b6106fc611510565b6001600160a01b03821661072b5760405162461bcd60e51b815260040161072290612449565b60405180910390fd5b6001600160a01b03821660008181526012602052604090819020805460ff19168415151790555133907f87ea6771e87d96ce16dbe8eda64da9473733e4c1c568baf8ae47256c5bd765e99061078190859061243e565b60405180910390a35050565b61079561210b565b506001600160a01b039081166000908152600f6020908152604091829020825161012081018452815490941684526001810154918401919091526002810154918301919091526003810154606083015260048101546080830152600581015460a0830152600681015460c0830152600781015460e08301526008015461010082015290565b610822611510565b6106ad816119ef565b610833611a54565b6001600160a01b0316336001600160a01b03161461088e576040805162461bcd60e51b815260206004820152601360248201527227b7363c9034b6b83632b6b2b73a30ba34b7b760691b604482015290519081900360640190fd5b610897846119ef565b6108a083611a79565b6108a9826115e4565b6108b281611ab5565b50505050565b6001600160a01b031660009081526016602052604090205460ff1690565b6001600160a01b039081166000908152601760205260409020541690565b600d54600160a01b900463ffffffff1690565b600d54640100000000900463ffffffff1690565b601354640100000000900463ffffffff1690565b610937612163565b506001600160a01b0316600090815260146020908152604091829020825160c081018452815463ffffffff80821683526401000000008204811694830194909452600160401b900490921692820192909252600182015460608201526002820154608082015260039091015460a082015290565b6109b3611b18565b6106ad81611b77565b82806001600160a01b031663f851a4406040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156109f857600080fd5b505af1158015610a0c573d6000803e3d6000fd5b505050506040513d6020811015610a2257600080fd5b50516001600160a01b03163314610a80576040805162461bcd60e51b815260206004820152601e60248201527f43616c6c6572206d757374206265207468652070726f78792061646d696e0000604482015290519081900360640190fd5b60405163623faf6160e01b8152602060048201908152602482018490526001600160a01b0386169163623faf619186918691908190604401848480828437600081840152601f19601f8201169050808301925050509350505050600060405180830381600087803b158015610af457600080fd5b505af1158015610b08573d6000803e3d6000fd5b5050505050505050565b6001600160a01b03918216600090815260146020908152604080832093909416825260049092019091522054151590565b80806001600160a01b031663f851a4406040518163ffffffff1660e01b8152600401602060405180830381600087803b158015610b7f57600080fd5b505af1158015610b93573d6000803e3d6000fd5b505050506040513d6020811015610ba957600080fd5b50516001600160a01b03163314610c07576040805162461bcd60e51b815260206004820152601e60248201527f43616c6c6572206d757374206265207468652070726f78792061646d696e0000604482015290519081900360640190fd5b816001600160a01b03166359fc20bb6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610c4257600080fd5b505af1158015610c56573d6000803e3d6000fd5b505050505050565b600d54600160401b900463ffffffff1690565b60009081526010602052604090205490565b601354600160401b900463ffffffff1690565b6001600160a01b031660009081526012602052604090205460ff1690565b60135463ffffffff1690565b600d5463ffffffff1690565b600d54600160c01b900463ffffffff1690565b610d087fe6876326c1291dfcbbd3864a6816d698cd591defc7aa2153d7f9c4c04016c89f611c1f565b610d317fc713c3df6d14cdf946460395d09af88993ee2b948b1a808161494e32c5f67063611c1f565b610d5a7f966f1e8d8d8014e05f6ec4a57138da9be1f7c5a7f802928a18072f7c53180761611c1f565b610d837f1df41cd916959d1163dc8f0671a666ea8a3e434c13e40faef527133b5d167034611c1f565b610dac7f45fc200c7e4544e457d3c5709bfe0d520442c30bbcbdaede89e8d4a4bbc19247611c1f565b610dd57fd362cac9cb75c10d67bcc0b7eeb0b1ef48bb5420b556c092d4fd7f758816fcf0611c1f565b610dfe7f39605a6c26a173774ca666c67ef70cf491880e5d3d6d0ca66ec0a31034f15ea3611c1f565b565b6001600160a01b03918216600090815260156020908152604080832093909416825291909152205460ff1690565b601354600160601b900463ffffffff1690565b610e49611510565b6106ad81611ab5565b3360009081526012602052604090205460ff161515600114610e865760405162461bcd60e51b815260040161072290612449565b610e8e6110b9565b6001600160a01b0384166000908152600e6020526040902083610ec35760405162461bcd60e51b815260040161072290612548565b82841015610ee35760405162461bcd60e51b81526004016107229061268b565b8054610f015760405162461bcd60e51b81526004016107229061266b565b8054841115610f225760405162461bcd60e51b815260040161072290612592565b6001600160a01b038216610f485760405162461bcd60e51b81526004016107229061246b565b60408051608081018252825481526001830154602082015260028301549181019190915260038201546060820152610f7f90611d21565b84118015610f91575060008160020154115b15610fff576000610fde610fd783604051806080016040529081600082015481526020016001820154815260200160028201548152602001600382015481525050611d21565b8690611d2d565b90506000610ff0828460020154611d8a565b9050610ffc8382611da1565b50505b6110098185611dc6565b6000611013611227565b9050611028816110238787611d2d565b611dd8565b611033818486611e24565b856001600160a01b03167ff2717be2f27d9d2d7d265e42dc556e40d2d9aeaba02f49c5286030f30c0571f3868686604051611070939291906127cd565b60405180910390a2505050505050565b600c5490565b6000546001600160a01b031681565b61109d611510565b6106ad81611a79565b600d54600160801b900463ffffffff1690565b60008054906101000a90046001600160a01b03166001600160a01b0316635c975abb6040518163ffffffff1660e01b815260040160206040518083038186803b15801561110557600080fd5b505afa158015611119573d6000803e3d6000fd5b505050506040513d602081101561112f57600080fd5b50511561116c576040805162461bcd60e51b815260206004820152600660248201526514185d5cd95960d21b604482015290519081900360640190fd5b60008054906101000a90046001600160a01b03166001600160a01b0316632e292fc76040518163ffffffff1660e01b815260040160206040518083038186803b1580156111b857600080fd5b505afa1580156111cc573d6000803e3d6000fd5b505050506040513d60208110156111e257600080fd5b505115610dfe576040805162461bcd60e51b815260206004820152600e60248201526d14185c9d1a585b0b5c185d5cd95960921b604482015290519081900360640190fd5b60006112527f45fc200c7e4544e457d3c5709bfe0d520442c30bbcbdaede89e8d4a4bbc19247611e81565b905090565b801561131f57604080516323b872dd60e01b81526001600160a01b038481166004830152306024830152604482018490529151918516916323b872dd916064808201926020929091908290030181600087803b1580156112b657600080fd5b505af11580156112ca573d6000803e3d6000fd5b505050506040513d60208110156112e057600080fd5b505161131f576040805162461bcd60e51b815260206004820152600960248201526810ba3930b739b332b960b91b604482015290519081900360640190fd5b505050565b60008082116113455760405162461bcd60e51b815260040161072290612548565b6001600160a01b03831661136b5760405162461bcd60e51b8152600401610722906124c8565b6001600160a01b0383166000908152600e60205260409020546113a05760405162461bcd60e51b81526004016107229061266b565b6001600160a01b0380841660009081526014602090815260408083209388168352600484019091528120906113ed6113d6611227565b6013548790600160601b900463ffffffff16611f1d565b905060006113fb8683611d2d565b90506000846002015460001461143557611430856002015461142a876003015485611f4590919063ffffffff16565b90611f9e565b611437565b815b9050600081116114595760405162461bcd60e51b8152600401610722906125ee565b60028501546114689083612005565b6002860155600385015461147c9082612005565b6003860155835461148d9082612005565b84556040516001600160a01b03808b1691908a16907fcd0366dce5247d874ffc60a762aa7abbb82c1695bbb171609c1b8861e279eb73906114d190869086906127bf565b60405180910390a398975050505050505050565b60006112527fc713c3df6d14cdf946460395d09af88993ee2b948b1a808161494e32c5f67063611e81565b60008054906101000a90046001600160a01b03166001600160a01b0316634fc07d756040518163ffffffff1660e01b815260040160206040518083038186803b15801561155c57600080fd5b505afa158015611570573d6000803e3d6000fd5b505050506040513d602081101561158657600080fd5b50516001600160a01b03163314610dfe576040805162461bcd60e51b815260206004820152601860248201527f4f6e6c7920436f6e74726f6c6c657220676f7665726e6f720000000000000000604482015290519081900360640190fd5b6013805463ffffffff191663ffffffff83161790556040516000805160206128298339815191529061161590612569565b60405180910390a150565b60008082116116415760405162461bcd60e51b8152600401610722906125ee565b6001600160a01b0380841660009081526014602090815260408083209388168352600484019091529020805484111561168c5760405162461bcd60e51b8152600401610722906124ea565b6040805160608101825282548152600183015460208201526002830154918101919091526000906116bc9061053a565b11156116d0576116ce868660006118de565b505b60006116f1836003015461142a856002015488611f4590919063ffffffff16565b60028401549091506117039082611d2d565b600284015560038301546117179086611d2d565b600384015581546117289086611d2d565b825560018201546117399082612005565b60018301556013546117d090600160401b900463ffffffff1661175a6114e5565b6001600160a01b031663766718086040518163ffffffff1660e01b815260040160206040518083038186803b15801561179257600080fd5b505afa1580156117a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117ca91906123a5565b90612005565b600283018190556040516001600160a01b03808a1692908916917f0430183f84d9c4502386d499da806543dee1d9de83c08b01e39a6d2116c43b25916118199186918b916127ec565b60405180910390a39695505050505050565b60008054906101000a90046001600160a01b03166001600160a01b0316635c975abb6040518163ffffffff1660e01b815260040160206040518083038186803b15801561187757600080fd5b505afa15801561188b573d6000803e3d6000fd5b505050506040513d60208110156118a157600080fd5b505115610dfe576040805162461bcd60e51b815260206004820152600660248201526514185d5cd95960d21b604482015290519081900360640190fd5b6001600160a01b038083166000908152601460209081526040808320938716835260048401825280832081516060810183528154815260018201549381019390935260028101549183019190915291929190839061193b9061053a565b90506000811161195d5760405162461bcd60e51b815260040161072290612548565b60006001830181905560028301556040516001600160a01b0380891691908816907f1b2e7737e043c5cf1b587ceb4daeb7ae00148b9bda8f79f1093eead08f141952906119ab9085906127b6565b60405180910390a36001600160a01b038516156119d3576119cd878683611324565b506119e5565b6119e56119de611227565b8883611e24565b9695505050505050565b60008163ffffffff1611611a155760405162461bcd60e51b8152600401610722906125b7565b601380546bffffffff00000000000000001916600160401b63ffffffff8416021790556040516000805160206128298339815191529061161590612511565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6013805467ffffffff00000000191664010000000063ffffffff841602179055604051600080516020612829833981519152906116159061260f565b620f424063ffffffff82161115611ade5760405162461bcd60e51b815260040161072290612646565b6013805463ffffffff60601b1916600160601b63ffffffff8416021790556040516000805160206128298339815191529061161590612491565b6000546001600160a01b03163314610dfe576040805162461bcd60e51b815260206004820152601960248201527f43616c6c6572206d75737420626520436f6e74726f6c6c657200000000000000604482015290519081900360640190fd5b6001600160a01b038116611bcb576040805162461bcd60e51b815260206004820152601660248201527510dbdb9d1c9bdb1b195c881b5d5cdd081899481cd95d60521b604482015290519081900360640190fd5b600080546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f4ff638452bbf33c012645d18ae6f05515ff5f2d1dfb0cece8cbf018c60903f709181900360200190a150565b6000805460408051637bb20d2f60e11b81526004810185905290516001600160a01b039092169163f7641a5e91602480820192602092909190829003018186803b158015611c6c57600080fd5b505afa158015611c80573d6000803e3d6000fd5b505050506040513d6020811015611c9657600080fd5b50516000838152600160205260409020549091506001600160a01b03808316911614611d1d5760008281526001602090815260409182902080546001600160a01b0319166001600160a01b0385169081179091558251908152915184927fd0e7a942b1fc38c411c4f53d153ba14fd24542a6a35ebacd9b6afca1a154e20692908290030190a25b5050565b6000610521828261205f565b600082821115611d84576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b600081831115611d9a57816106d8565b5090919050565b6002820154611db09082611d2d565b60028301819055611d1d57600060038301555050565b8154611dd29082611d2d565b90915550565b8015611d1d57816001600160a01b03166342966c68826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015610c4257600080fd5b801561131f57826001600160a01b031663a9059cbb83836040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156112b657600080fd5b6000818152600160205260408120546001600160a01b0316806105215760005460408051637bb20d2f60e11b81526004810186905290516001600160a01b039092169163f7641a5e91602480820192602092909190829003018186803b158015611eea57600080fd5b505afa158015611efe573d6000803e3d6000fd5b505050506040513d6020811015611f1457600080fd5b50519392505050565b600080611f31620f424061142a8587611f45565b9050611f3d8582611dd8565b949350505050565b600082611f5457506000610521565b82820282848281611f6157fe5b04146106d85760405162461bcd60e51b81526004018080602001828103825260218152602001806128496021913960400191505060405180910390fd5b6000808211611ff4576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b818381611ffd57fe5b049392505050565b6000828201838110156106d8576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b815160009081906120709084612005565b9050600061207d856120a5565b90508181111561209257600092505050610521565b61209c8282611d2d565b95945050505050565b60006105218260400151836020015161200590919063ffffffff16565b60405180606001604052806000815260200160008152602001600081525090565b6040518060800160405280600081526020016000815260200160008152602001600081525090565b60405180610120016040528060006001600160a01b0316815260200160008019168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040518060c00160405280600063ffffffff168152602001600063ffffffff168152602001600063ffffffff1681526020016000815260200160008152602001600081525090565b803563ffffffff811681146105e657600080fd5b6000602082840312156121d0578081fd5b81356106d881612813565b600080604083850312156121ed578081fd5b82356121f881612813565b9150602083013561220881612813565b809150509250929050565b60008060408385031215612225578182fd5b823561223081612813565b915060208301358015158114612208578182fd5b60008060408385031215612256578182fd5b823561226181612813565b946020939093013593505050565b60008060008060808587031215612284578182fd5b843561228f81612813565b9350602085013592506040850135915060608501356122ad81612813565b939692955090935050565b6000602082840312156122c9578081fd5b5035919050565b6000806000604084860312156122e4578283fd5b83356122ef81612813565b9250602084013567ffffffffffffffff8082111561230b578384fd5b818601915086601f83011261231e578384fd5b81358181111561232c578485fd5b87602082850101111561233d578485fd5b6020830194508093505050509250925092565b600060608284031215612361578081fd5b6040516060810181811067ffffffffffffffff8211171561237e57fe5b80604052508235815260208301356020820152604083013560408201528091505092915050565b6000602082840312156123b6578081fd5b5051919050565b6000602082840312156123ce578081fd5b6106d8826121ab565b600080600080608085870312156123ec578384fd5b6123f5856121ab565b9350612403602086016121ab565b9250612411604086016121ab565b915061241f606086016121ab565b905092959194509250565b6001600160a01b0391909116815260200190565b901515815260200190565b60208082526008908201526710b9b630b9b432b960c11b604082015260600190565b6020808252600c908201526b2162656e656669636961727960a01b604082015260600190565b60208082526017908201527f64656c65676174696f6e54617850657263656e74616765000000000000000000604082015260600190565b60208082526008908201526710b4b73232bc32b960c11b604082015260600190565b6020808252600d908201526c085cda185c995ccb585d985a5b609a1b604082015260600190565b60208082526019908201527f64656c65676174696f6e556e626f6e64696e67506572696f6400000000000000604082015260600190565b60208082526007908201526621746f6b656e7360c81b604082015260600190565b6020808252600f908201526e64656c65676174696f6e526174696f60881b604082015260600190565b6020808252600b908201526a736c6173683e7374616b6560a81b604082015260600190565b6020808252601a908201527f2164656c65676174696f6e556e626f6e64696e67506572696f64000000000000604082015260600190565b6020808252600790820152662173686172657360c81b604082015260600190565b6020808252601c908201527f64656c65676174696f6e506172616d6574657273436f6f6c646f776e00000000604082015260600190565b6020808252600b908201526a3e70657263656e7461676560a81b604082015260600190565b602080825260069082015265217374616b6560d01b604082015260600190565b6020808252600d908201526c0e4caeec2e4c8e67ce6d8c2e6d609b1b604082015260600190565b81516001600160a01b031681526020808301519082015260408083015190820152606080830151908201526080808301519082015260a0828101519082015260c0808301519082015260e0808301519082015261010091820151918101919091526101200190565b600060c08201905063ffffffff80845116835280602085015116602084015280604085015116604084015250606083015160608301526080830151608083015260a083015160a083015292915050565b81518152602080830151908201526040918201519181019190915260600190565b8151815260208083015190820152604080830151908201526060918201519181019190915260800190565b90815260200190565b918252602082015260400190565b92835260208301919091526001600160a01b0316604082015260600190565b9283526020830191909152604082015260600190565b63ffffffff91909116815260200190565b6001600160a01b03811681146106ad57600080fdfe96d5a4b4edf1cefd0900c166d64447f8da1d01d1861a6a60894b5b82a2c15c3c536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a26469706673582212203cd17ff3f2a4eed9880a80869627b8a2ac7177f564cd84b9c98c45314cbe93ec64736f6c63430007060033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 27 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.