Source Code
Overview
MATIC Balance
0 MATIC
Token Holdings
More Info
ContractCreator:
Multichain Info
N/A
Latest 21 from a total of 21 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
Increase Gauge | 26286865 | 687 days ago | IN | 0 MATIC | 0.00079867 | ||||
Increase Gauge | 26286859 | 687 days ago | IN | 0 MATIC | 0.00074465 | ||||
Deposit | 26286856 | 687 days ago | IN | 0 MATIC | 0.00062672 | ||||
Increase Gauge | 26286687 | 687 days ago | IN | 0 MATIC | 0.00015148 | ||||
Increase Gauge | 26286686 | 687 days ago | IN | 0 MATIC | 0.00016312 | ||||
Deposit | 26286678 | 687 days ago | IN | 0 MATIC | 0.00062983 | ||||
Increase Gauge | 26276515 | 688 days ago | IN | 0 MATIC | 0.00011978 | ||||
Increase Gauge | 26276514 | 688 days ago | IN | 0 MATIC | 0.00012701 | ||||
Deposit | 26276481 | 688 days ago | IN | 0 MATIC | 0.00008164 | ||||
Withdraw | 26276477 | 688 days ago | IN | 0 MATIC | 0.00006926 | ||||
Deposit | 26276326 | 688 days ago | IN | 0 MATIC | 0.00009522 | ||||
Decrease Gauge | 26276291 | 688 days ago | IN | 0 MATIC | 0.00011946 | ||||
Decrease Gauge | 26276270 | 688 days ago | IN | 0 MATIC | 0.0001203 | ||||
Withdraw | 26218509 | 692 days ago | IN | 0 MATIC | 0.00014218 | ||||
Increase Gauge | 26217496 | 692 days ago | IN | 0 MATIC | 0.00020932 | ||||
Deposit | 26217491 | 692 days ago | IN | 0 MATIC | 0.00010607 | ||||
Increase Gauge | 26217471 | 692 days ago | IN | 0 MATIC | 0.00022259 | ||||
Deposit | 26217464 | 692 days ago | IN | 0 MATIC | 0.00019125 | ||||
Add Gauge | 26205368 | 693 days ago | IN | 0 MATIC | 0.00017868 | ||||
Add Gauge | 26205366 | 693 days ago | IN | 0 MATIC | 0.00428838 | ||||
0x60806040 | 26123131 | 699 days ago | IN | Create: GaugeController | 0 MATIC | 0.00745218 |
Loading...
Loading
Contract Name:
GaugeController
Compiler Version
v0.8.6+commit.11564f7e
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity)
/** *Submitted for verification at mumbai.polygonscan.com on 2022-04-28 */ // SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.6; /** * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such 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. * * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing * all math on `uint256` and `int256` and then downcasting. */ library ExtendedSafeCastLib { /** * @dev Returns the downcasted uint104 from uint256, reverting on * overflow (when the input is greater than largest uint104). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 104 bits */ function toUint104(uint256 _value) internal pure returns (uint104) { require(_value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits"); return uint104(_value); } /** * @dev Returns the downcasted uint208 from uint256, reverting on * overflow (when the input is greater than largest uint208). * * Counterpart to Solidity's `uint208` operator. * * Requirements: * * - input must fit into 208 bits */ function toUint208(uint256 _value) internal pure returns (uint208) { require(_value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits"); return uint208(_value); } /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits */ function toUint224(uint256 _value) internal pure returns (uint224) { require(_value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits"); return uint224(_value); } } /// @title OverflowSafeComparatorLib library to share comparator functions between contracts /// @dev Code taken from Uniswap V3 Oracle.sol: https://github.com/Uniswap/v3-core/blob/3e88af408132fc957e3e406f65a0ce2b1ca06c3d/contracts/libraries/Oracle.sol /// @author PoolTogether Inc. library OverflowSafeComparatorLib { /// @notice 32-bit timestamps comparator. /// @dev safe for 0 or 1 overflows, `_a` and `_b` must be chronologically before or equal to time. /// @param _a A comparison timestamp from which to determine the relative position of `_timestamp`. /// @param _b Timestamp to compare against `_a`. /// @param _timestamp A timestamp truncated to 32 bits. /// @return bool Whether `_a` is chronologically < `_b`. function lt( uint32 _a, uint32 _b, uint32 _timestamp ) internal pure returns (bool) { // No need to adjust if there hasn't been an overflow if (_a <= _timestamp && _b <= _timestamp) return _a < _b; uint256 aAdjusted = _a > _timestamp ? _a : _a + 2**32; uint256 bAdjusted = _b > _timestamp ? _b : _b + 2**32; return aAdjusted < bAdjusted; } /// @notice 32-bit timestamps comparator. /// @dev safe for 0 or 1 overflows, `_a` and `_b` must be chronologically before or equal to time. /// @param _a A comparison timestamp from which to determine the relative position of `_timestamp`. /// @param _b Timestamp to compare against `_a`. /// @param _timestamp A timestamp truncated to 32 bits. /// @return bool Whether `_a` is chronologically <= `_b`. function lte( uint32 _a, uint32 _b, uint32 _timestamp ) internal pure returns (bool) { // No need to adjust if there hasn't been an overflow if (_a <= _timestamp && _b <= _timestamp) return _a <= _b; uint256 aAdjusted = _a > _timestamp ? _a : _a + 2**32; uint256 bAdjusted = _b > _timestamp ? _b : _b + 2**32; return aAdjusted <= bAdjusted; } /// @notice 32-bit timestamp subtractor /// @dev safe for 0 or 1 overflows, where `_a` and `_b` must be chronologically before or equal to time /// @param _a The subtraction left operand /// @param _b The subtraction right operand /// @param _timestamp The current time. Expected to be chronologically after both. /// @return The difference between a and b, adjusted for overflow function checkedSub( uint32 _a, uint32 _b, uint32 _timestamp ) internal pure returns (uint32) { // No need to adjust if there hasn't been an overflow if (_a <= _timestamp && _b <= _timestamp) return _a - _b; uint256 aAdjusted = _a > _timestamp ? _a : _a + 2**32; uint256 bAdjusted = _b > _timestamp ? _b : _b + 2**32; return uint32(aAdjusted - bAdjusted); } } library RingBufferLib { /** * @notice Returns wrapped TWAB index. * @dev In order to navigate the TWAB circular buffer, we need to use the modulo operator. * @dev For example, if `_index` is equal to 32 and the TWAB circular buffer is of `_cardinality` 32, * it will return 0 and will point to the first element of the array. * @param _index Index used to navigate through the TWAB circular buffer. * @param _cardinality TWAB buffer cardinality. * @return TWAB index. */ function wrap(uint256 _index, uint256 _cardinality) internal pure returns (uint256) { return _index % _cardinality; } /** * @notice Computes the negative offset from the given index, wrapped by the cardinality. * @dev We add `_cardinality` to `_index` to be able to offset even if `_amount` is superior to `_cardinality`. * @param _index The index from which to offset * @param _amount The number of indices to offset. This is subtracted from the given index. * @param _cardinality The number of elements in the ring buffer * @return Offsetted index. */ function offset( uint256 _index, uint256 _amount, uint256 _cardinality ) internal pure returns (uint256) { return wrap(_index + _cardinality - _amount, _cardinality); } /// @notice Returns the index of the last recorded TWAB /// @param _nextIndex The next available twab index. This will be recorded to next. /// @param _cardinality The cardinality of the TWAB history. /// @return The index of the last recorded TWAB function newestIndex(uint256 _nextIndex, uint256 _cardinality) internal pure returns (uint256) { if (_cardinality == 0) { return 0; } return wrap(_nextIndex + _cardinality - 1, _cardinality); } /// @notice Computes the ring buffer index that follows the given one, wrapped by cardinality /// @param _index The index to increment /// @param _cardinality The number of elements in the Ring Buffer /// @return The next index relative to the given index. Will wrap around to 0 if the next index == cardinality function nextIndex(uint256 _index, uint256 _cardinality) internal pure returns (uint256) { return wrap(_index + 1, _cardinality); } } // OpenZeppelin Contracts v4.4.1 (utils/math/SafeCast.sol) /** * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such 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. * * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing * all math on `uint256` and `int256` and then downcasting. */ library SafeCast { /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits */ function toUint224(uint256 value) internal pure returns (uint224) { require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits"); return uint224(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits */ function toUint128(uint256 value) internal pure returns (uint128) { require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits"); return uint128(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits */ function toUint96(uint256 value) internal pure returns (uint96) { require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits"); return uint96(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits */ function toUint64(uint256 value) internal pure returns (uint64) { require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits"); return uint64(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits */ function toUint32(uint256 value) internal pure returns (uint32) { require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits"); return uint32(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits */ function toUint16(uint256 value) internal pure returns (uint16) { require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits"); return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits. */ function toUint8(uint256 value) internal pure returns (uint8) { require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits"); return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. */ function toUint256(int256 value) internal pure returns (uint256) { require(value >= 0, "SafeCast: value must be positive"); return uint256(value); } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v3.1._ */ function toInt128(int256 value) internal pure returns (int128) { require(value >= type(int128).min && value <= type(int128).max, "SafeCast: value doesn't fit in 128 bits"); return int128(value); } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v3.1._ */ function toInt64(int256 value) internal pure returns (int64) { require(value >= type(int64).min && value <= type(int64).max, "SafeCast: value doesn't fit in 64 bits"); return int64(value); } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v3.1._ */ function toInt32(int256 value) internal pure returns (int32) { require(value >= type(int32).min && value <= type(int32).max, "SafeCast: value doesn't fit in 32 bits"); return int32(value); } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v3.1._ */ function toInt16(int256 value) internal pure returns (int16) { require(value >= type(int16).min && value <= type(int16).max, "SafeCast: value doesn't fit in 16 bits"); return int16(value); } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits. * * _Available since v3.1._ */ function toInt8(int256 value) internal pure returns (int8) { require(value >= type(int8).min && value <= type(int8).max, "SafeCast: value doesn't fit in 8 bits"); return int8(value); } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256"); return int256(value); } } /** * @title Observation Library * @notice This library allows one to store an array of timestamped values and efficiently binary search them. * @dev Largely pulled from Uniswap V3 Oracle.sol: https://github.com/Uniswap/v3-core/blob/c05a0e2c8c08c460fb4d05cfdda30b3ad8deeaac/contracts/libraries/Oracle.sol * @author PoolTogether Inc. */ library ObservationLib { using OverflowSafeComparatorLib for uint32; using SafeCast for uint256; /// @notice The maximum number of observations uint24 public constant MAX_CARDINALITY = 16777215; // 2**24 /** * @notice Observation, which includes an amount and timestamp. * @param amount `amount` at `timestamp`. * @param timestamp Recorded `timestamp`. */ struct Observation { uint224 amount; uint32 timestamp; } /** * @notice Fetches Observations `beforeOrAt` and `atOrAfter` a `_target`, eg: where [`beforeOrAt`, `atOrAfter`] is satisfied. * The result may be the same Observation, or adjacent Observations. * @dev The answer must be contained in the array used when the target is located within the stored Observation. * boundaries: older than the most recent Observation and younger, or the same age as, the oldest Observation. * @dev If `_newestObservationIndex` is less than `_oldestObservationIndex`, it means that we've wrapped around the circular buffer. * So the most recent observation will be at `_oldestObservationIndex + _cardinality - 1`, at the beginning of the circular buffer. * @param _observations List of Observations to search through. * @param _newestObservationIndex Index of the newest Observation. Right side of the circular buffer. * @param _oldestObservationIndex Index of the oldest Observation. Left side of the circular buffer. * @param _target Timestamp at which we are searching the Observation. * @param _cardinality Cardinality of the circular buffer we are searching through. * @param _time Timestamp at which we perform the binary search. * @return beforeOrAt Observation recorded before, or at, the target. * @return atOrAfter Observation recorded at, or after, the target. */ function binarySearch( Observation[MAX_CARDINALITY] storage _observations, uint24 _newestObservationIndex, uint24 _oldestObservationIndex, uint32 _target, uint24 _cardinality, uint32 _time ) internal view returns (Observation memory beforeOrAt, Observation memory atOrAfter) { uint256 leftSide = _oldestObservationIndex; uint256 rightSide = _newestObservationIndex < leftSide ? leftSide + _cardinality - 1 : _newestObservationIndex; uint256 currentIndex; while (true) { // We start our search in the middle of the `leftSide` and `rightSide`. // After each iteration, we narrow down the search to the left or the right side while still starting our search in the middle. currentIndex = (leftSide + rightSide) / 2; beforeOrAt = _observations[uint24(RingBufferLib.wrap(currentIndex, _cardinality))]; uint32 beforeOrAtTimestamp = beforeOrAt.timestamp; // We've landed on an uninitialized timestamp, keep searching higher (more recently). if (beforeOrAtTimestamp == 0) { leftSide = currentIndex + 1; continue; } atOrAfter = _observations[uint24(RingBufferLib.nextIndex(currentIndex, _cardinality))]; bool targetAtOrAfter = beforeOrAtTimestamp.lte(_target, _time); // Check if we've found the corresponding Observation. if (targetAtOrAfter && _target.lte(atOrAfter.timestamp, _time)) { break; } // If `beforeOrAtTimestamp` is greater than `_target`, then we keep searching lower. To the left of the current index. if (!targetAtOrAfter) { rightSide = currentIndex - 1; } else { // Otherwise, we keep searching higher. To the left of the current index. leftSide = currentIndex + 1; } } } } /** * @title PoolTogether V4 TwabLib (Library) * @author PoolTogether Inc Team * @dev Time-Weighted Average Balance Library for ERC20 tokens. * @notice This TwabLib adds on-chain historical lookups to a user(s) time-weighted average balance. Each user is mapped to an Account struct containing the TWAB history (ring bufffer) and ring buffer parameters. Every token.transfer() creates a new TWAB checkpoint. The new TWAB checkpoint is stored in the circular ring buffer, as either a new checkpoint or rewriting a previous checkpoint with new parameters. The TwabLib (using existing blocktimes 1block/15sec) guarantees minimum 7.4 years of search history. */ library TwabLib { using OverflowSafeComparatorLib for uint32; using ExtendedSafeCastLib for uint256; /** * @notice Sets max ring buffer length in the Account.twabs Observation list. As users transfer/mint/burn tickets new Observation checkpoints are recorded. The current max cardinality guarantees a six month minimum, of historical accurate lookups with current estimates of 1 new block every 15 seconds - the of course contain a transfer to trigger an observation write to storage. * @dev The user Account.AccountDetails.cardinality parameter can NOT exceed the max cardinality variable. Preventing "corrupted" ring buffer lookup pointers and new observation checkpoints. The MAX_CARDINALITY in fact guarantees at least 7.4 years of records: If 14 = block time in seconds (2**24) * 14 = 234881024 seconds of history 234881024 / (365 * 24 * 60 * 60) ~= 7.44 years */ uint24 public constant MAX_CARDINALITY = 16777215; // 2**24 /** @notice Struct ring buffer parameters for single user Account * @param balance Current balance for an Account * @param nextTwabIndex Next uninitialized or updatable ring buffer checkpoint storage slot * @param cardinality Current total "initialized" ring buffer checkpoints for single user AccountDetails. Used to set initial boundary conditions for an efficient binary search. */ struct AccountDetails { uint208 balance; uint24 nextTwabIndex; uint24 cardinality; } /// @notice Combines account details with their twab history /// @param details The account details /// @param twabs The history of twabs for this account struct Account { AccountDetails details; ObservationLib.Observation[MAX_CARDINALITY] twabs; } /// @notice Increases an account's balance and records a new twab. /// @param _account The account whose balance will be increased /// @param _amount The amount to increase the balance by /// @param _currentTime The current time /// @return accountDetails The new AccountDetails /// @return twab The user's latest TWAB /// @return isNew Whether the TWAB is new function increaseBalance( Account storage _account, uint208 _amount, uint32 _currentTime ) internal returns ( AccountDetails memory accountDetails, ObservationLib.Observation memory twab, bool isNew ) { AccountDetails memory _accountDetails = _account.details; (accountDetails, twab, isNew) = _nextTwab(_account.twabs, _accountDetails, _currentTime); accountDetails.balance = _accountDetails.balance + _amount; } /** @notice Calculates the next TWAB checkpoint for an account with a decreasing balance. * @dev With Account struct and amount decreasing calculates the next TWAB observable checkpoint. * @param _account Account whose balance will be decreased * @param _amount Amount to decrease the balance by * @param _revertMessage Revert message for insufficient balance * @return accountDetails Updated Account.details struct * @return twab TWAB observation (with decreasing average) * @return isNew Whether TWAB is new or calling twice in the same block */ function decreaseBalance( Account storage _account, uint208 _amount, string memory _revertMessage, uint32 _currentTime ) internal returns ( AccountDetails memory accountDetails, ObservationLib.Observation memory twab, bool isNew ) { AccountDetails memory _accountDetails = _account.details; require(_accountDetails.balance >= _amount, _revertMessage); (accountDetails, twab, isNew) = _nextTwab(_account.twabs, _accountDetails, _currentTime); unchecked { accountDetails.balance -= _amount; } } /** @notice Calculates the average balance held by a user for a given time frame. * @dev Finds the average balance between start and end timestamp epochs. Validates the supplied end time is within the range of elapsed time i.e. less then timestamp of now. * @param _twabs Individual user Observation recorded checkpoints passed as storage pointer * @param _accountDetails User AccountDetails struct loaded in memory * @param _startTime Start of timestamp range as an epoch * @param _endTime End of timestamp range as an epoch * @param _currentTime Block.timestamp * @return Average balance of user held between epoch timestamps start and end */ function getAverageBalanceBetween( ObservationLib.Observation[MAX_CARDINALITY] storage _twabs, AccountDetails memory _accountDetails, uint32 _startTime, uint32 _endTime, uint32 _currentTime ) internal view returns (uint256) { uint32 endTime = _endTime > _currentTime ? _currentTime : _endTime; return _getAverageBalanceBetween(_twabs, _accountDetails, _startTime, endTime, _currentTime); } /// @notice Retrieves the oldest TWAB /// @param _twabs The storage array of twabs /// @param _accountDetails The TWAB account details /// @return index The index of the oldest TWAB in the twabs array /// @return twab The oldest TWAB function oldestTwab( ObservationLib.Observation[MAX_CARDINALITY] storage _twabs, AccountDetails memory _accountDetails ) internal view returns (uint24 index, ObservationLib.Observation memory twab) { index = _accountDetails.nextTwabIndex; twab = _twabs[index]; // If the TWAB is not initialized we go to the beginning of the TWAB circular buffer at index 0 if (twab.timestamp == 0) { index = 0; twab = _twabs[0]; } } /// @notice Retrieves the newest TWAB /// @param _twabs The storage array of twabs /// @param _accountDetails The TWAB account details /// @return index The index of the newest TWAB in the twabs array /// @return twab The newest TWAB function newestTwab( ObservationLib.Observation[MAX_CARDINALITY] storage _twabs, AccountDetails memory _accountDetails ) internal view returns (uint24 index, ObservationLib.Observation memory twab) { index = uint24(RingBufferLib.newestIndex(_accountDetails.nextTwabIndex, MAX_CARDINALITY)); twab = _twabs[index]; } /// @notice Retrieves amount at `_targetTime` timestamp /// @param _twabs List of TWABs to search through. /// @param _accountDetails Accounts details /// @param _targetTime Timestamp at which the reserved TWAB should be for. /// @return uint256 TWAB amount at `_targetTime`. function getBalanceAt( ObservationLib.Observation[MAX_CARDINALITY] storage _twabs, AccountDetails memory _accountDetails, uint32 _targetTime, uint32 _currentTime ) internal view returns (uint256) { uint32 timeToTarget = _targetTime > _currentTime ? _currentTime : _targetTime; return _getBalanceAt(_twabs, _accountDetails, timeToTarget, _currentTime); } /// @notice Calculates the average balance held by a user for a given time frame. /// @param _startTime The start time of the time frame. /// @param _endTime The end time of the time frame. /// @return The average balance that the user held during the time frame. function _getAverageBalanceBetween( ObservationLib.Observation[MAX_CARDINALITY] storage _twabs, AccountDetails memory _accountDetails, uint32 _startTime, uint32 _endTime, uint32 _currentTime ) private view returns (uint256) { (uint24 oldestTwabIndex, ObservationLib.Observation memory oldTwab) = oldestTwab( _twabs, _accountDetails ); (uint24 newestTwabIndex, ObservationLib.Observation memory newTwab) = newestTwab( _twabs, _accountDetails ); ObservationLib.Observation memory startTwab = _calculateTwab( _twabs, _accountDetails, newTwab, oldTwab, newestTwabIndex, oldestTwabIndex, _startTime, _currentTime ); ObservationLib.Observation memory endTwab = _calculateTwab( _twabs, _accountDetails, newTwab, oldTwab, newestTwabIndex, oldestTwabIndex, _endTime, _currentTime ); // Difference in amount / time return (endTwab.amount - startTwab.amount) / OverflowSafeComparatorLib.checkedSub(endTwab.timestamp, startTwab.timestamp, _currentTime); } /** @notice Searches TWAB history and calculate the difference between amount(s)/timestamp(s) to return average balance between the Observations closes to the supplied targetTime. * @param _twabs Individual user Observation recorded checkpoints passed as storage pointer * @param _accountDetails User AccountDetails struct loaded in memory * @param _targetTime Target timestamp to filter Observations in the ring buffer binary search * @param _currentTime Block.timestamp * @return uint256 Time-weighted average amount between two closest observations. */ function _getBalanceAt( ObservationLib.Observation[MAX_CARDINALITY] storage _twabs, AccountDetails memory _accountDetails, uint32 _targetTime, uint32 _currentTime ) private view returns (uint256) { uint24 newestTwabIndex; ObservationLib.Observation memory afterOrAt; ObservationLib.Observation memory beforeOrAt; (newestTwabIndex, beforeOrAt) = newestTwab(_twabs, _accountDetails); // If `_targetTime` is chronologically after the newest TWAB, we can simply return the current balance if (beforeOrAt.timestamp.lte(_targetTime, _currentTime)) { return _accountDetails.balance; } uint24 oldestTwabIndex; // Now, set before to the oldest TWAB (oldestTwabIndex, beforeOrAt) = oldestTwab(_twabs, _accountDetails); // If `_targetTime` is chronologically before the oldest TWAB, we can early return if (_targetTime.lt(beforeOrAt.timestamp, _currentTime)) { return 0; } // Otherwise, we perform the `binarySearch` (beforeOrAt, afterOrAt) = ObservationLib.binarySearch( _twabs, newestTwabIndex, oldestTwabIndex, _targetTime, _accountDetails.cardinality, _currentTime ); // Sum the difference in amounts and divide by the difference in timestamps. // The time-weighted average balance uses time measured between two epoch timestamps as // a constaint on the measurement when calculating the time weighted average balance. return (afterOrAt.amount - beforeOrAt.amount) / OverflowSafeComparatorLib.checkedSub(afterOrAt.timestamp, beforeOrAt.timestamp, _currentTime); } /** @notice Calculates a user TWAB for a target timestamp using the historical TWAB records. The balance is linearly interpolated: amount differences / timestamp differences using the simple (after.amount - before.amount / end.timestamp - start.timestamp) formula. /** @dev Binary search in _calculateTwab fails when searching out of bounds. Thus, before searching we exclude target timestamps out of range of newest/oldest TWAB(s). IF a search is before or after the range we "extrapolate" a Observation from the expected state. * @param _twabs Individual user Observation recorded checkpoints passed as storage pointer * @param _accountDetails User AccountDetails struct loaded in memory * @param _newestTwab Newest TWAB in history (end of ring buffer) * @param _oldestTwab Olderst TWAB in history (end of ring buffer) * @param _newestTwabIndex Pointer in ring buffer to newest TWAB * @param _oldestTwabIndex Pointer in ring buffer to oldest TWAB * @param _targetTimestamp Epoch timestamp to calculate for time (T) in the TWAB * @param _time Block.timestamp * @return accountDetails Updated Account.details struct */ function _calculateTwab( ObservationLib.Observation[MAX_CARDINALITY] storage _twabs, AccountDetails memory _accountDetails, ObservationLib.Observation memory _newestTwab, ObservationLib.Observation memory _oldestTwab, uint24 _newestTwabIndex, uint24 _oldestTwabIndex, uint32 _targetTimestamp, uint32 _time ) private view returns (ObservationLib.Observation memory) { // If `_targetTimestamp` is chronologically after the newest TWAB, we extrapolate a new one if (_newestTwab.timestamp.lt(_targetTimestamp, _time)) { return _computeNextTwab(_newestTwab, _accountDetails.balance, _targetTimestamp); } if (_newestTwab.timestamp == _targetTimestamp) { return _newestTwab; } if (_oldestTwab.timestamp == _targetTimestamp) { return _oldestTwab; } // If `_targetTimestamp` is chronologically before the oldest TWAB, we create a zero twab if (_targetTimestamp.lt(_oldestTwab.timestamp, _time)) { return ObservationLib.Observation({ amount: 0, timestamp: _targetTimestamp }); } // Otherwise, both timestamps must be surrounded by twabs. ( ObservationLib.Observation memory beforeOrAtStart, ObservationLib.Observation memory afterOrAtStart ) = ObservationLib.binarySearch( _twabs, _newestTwabIndex, _oldestTwabIndex, _targetTimestamp, _accountDetails.cardinality, _time ); uint224 heldBalance = (afterOrAtStart.amount - beforeOrAtStart.amount) / OverflowSafeComparatorLib.checkedSub(afterOrAtStart.timestamp, beforeOrAtStart.timestamp, _time); return _computeNextTwab(beforeOrAtStart, heldBalance, _targetTimestamp); } /** * @notice Calculates the next TWAB using the newestTwab and updated balance. * @dev Storage of the TWAB obersation is managed by the calling function and not _computeNextTwab. * @param _currentTwab Newest Observation in the Account.twabs list * @param _currentBalance User balance at time of most recent (newest) checkpoint write * @param _time Current block.timestamp * @return TWAB Observation */ function _computeNextTwab( ObservationLib.Observation memory _currentTwab, uint224 _currentBalance, uint32 _time ) private pure returns (ObservationLib.Observation memory) { // New twab amount = last twab amount (or zero) + (current amount * elapsed seconds) return ObservationLib.Observation({ amount: _currentTwab.amount + _currentBalance * (_time.checkedSub(_currentTwab.timestamp, _time)), timestamp: _time }); } /// @notice Sets a new TWAB Observation at the next available index and returns the new account details. /// @dev Note that if _currentTime is before the last observation timestamp, it appears as an overflow /// @param _twabs The twabs array to insert into /// @param _accountDetails The current account details /// @param _currentTime The current time /// @return accountDetails The new account details /// @return twab The newest twab (may or may not be brand-new) /// @return isNew Whether the newest twab was created by this call function _nextTwab( ObservationLib.Observation[MAX_CARDINALITY] storage _twabs, AccountDetails memory _accountDetails, uint32 _currentTime ) private returns ( AccountDetails memory accountDetails, ObservationLib.Observation memory twab, bool isNew ) { (, ObservationLib.Observation memory _newestTwab) = newestTwab(_twabs, _accountDetails); // if we're in the same block, return if (_newestTwab.timestamp == _currentTime) { return (_accountDetails, _newestTwab, false); } ObservationLib.Observation memory newTwab = _computeNextTwab( _newestTwab, _accountDetails.balance, _currentTime ); _twabs[_accountDetails.nextTwabIndex] = newTwab; AccountDetails memory nextAccountDetails = push(_accountDetails); return (nextAccountDetails, newTwab, true); } /// @notice "Pushes" a new element on the AccountDetails ring buffer, and returns the new AccountDetails /// @param _accountDetails The account details from which to pull the cardinality and next index /// @return The new AccountDetails function push(AccountDetails memory _accountDetails) internal pure returns (AccountDetails memory) { _accountDetails.nextTwabIndex = uint24( RingBufferLib.nextIndex(_accountDetails.nextTwabIndex, MAX_CARDINALITY) ); // Prevent the Account specific cardinality from exceeding the MAX_CARDINALITY. // The ring buffer length is limited by MAX_CARDINALITY. IF the account.cardinality // exceeds the max cardinality, new observations would be incorrectly set or the // observation would be out of "bounds" of the ring buffer. Once reached the // AccountDetails.cardinality will continue to be equal to max cardinality. if (_accountDetails.cardinality < MAX_CARDINALITY) { _accountDetails.cardinality += 1; } return _accountDetails; } } // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol) /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); } interface GaugeControllerInterface { function getScaledAverageGaugeBetween(address _gauge, uint256 _startTime, uint256 _endTime) external view returns (uint256); } contract GaugeController is GaugeControllerInterface { using ExtendedSafeCastLib for uint256; struct GaugeInfo { uint256 weight; } IERC20 public token; address public rewardVault; mapping(address => uint256) public rewards; mapping(address => uint256) public balances; mapping(address => mapping(address => uint256)) public gaugeBalances; // records total voting power in a gauge mapping(address => TwabLib.Account) internal gaugeTwabs; // records scales for gauges. mapping(address => TwabLib.Account) internal gaugeScaleTwabs; constructor ( IERC20 _token, address _rewardVault ) { token = _token; rewardVault = _rewardVault; } function deposit(address _to, uint256 _amount) public { balances[_to] += _amount; token.transferFrom(_to, address(this), _amount); } function withdraw(uint256 _amount) public { balances[msg.sender] -= _amount; token.transfer(msg.sender, _amount); } function increaseGauge(address _gauge, uint256 _amount) public requireGauge(_gauge) { balances[msg.sender] -= _amount; gaugeBalances[msg.sender][_gauge] += _amount; TwabLib.Account storage gaugeTwab = gaugeTwabs[_gauge]; ( TwabLib.AccountDetails memory twabDetails,, ) = TwabLib.increaseBalance(gaugeTwab, _amount.toUint208(), uint32(block.timestamp)); gaugeTwab.details = twabDetails; } function decreaseGauge(address _gauge, uint256 _amount) public requireGauge(_gauge) { balances[msg.sender] += _amount; gaugeBalances[msg.sender][_gauge] -= _amount; TwabLib.Account storage gaugeTwab = gaugeTwabs[_gauge]; ( TwabLib.AccountDetails memory twabDetails,, ) = TwabLib.decreaseBalance(gaugeTwab, _amount.toUint208(), "insuff", uint32(block.timestamp)); gaugeTwab.details = twabDetails; } function addGauge(address _gauge) public { addGaugeWithScale(_gauge, 1 ether); } function addGaugeWithScale(address _gauge, uint256 _scale) public { TwabLib.Account storage gaugeScaleTwab = gaugeScaleTwabs[_gauge]; ( TwabLib.AccountDetails memory twabDetails,, ) = TwabLib.increaseBalance(gaugeScaleTwab, _scale.toUint208(), uint32(block.timestamp)); gaugeScaleTwab.details = twabDetails; } function removeGauge(address _gauge) public { TwabLib.Account storage gaugeScaleTwab = gaugeScaleTwabs[_gauge]; TwabLib.AccountDetails memory twabDetails = gaugeScaleTwab.details; ( twabDetails,, ) = TwabLib.decreaseBalance(gaugeScaleTwab, twabDetails.balance, "insuff", uint32(block.timestamp)); gaugeScaleTwab.details = twabDetails; } function setGaugeScale(address _gauge, uint256 _scale) public { TwabLib.Account storage gaugeScaleTwab = gaugeScaleTwabs[_gauge]; TwabLib.AccountDetails memory twabDetails = gaugeScaleTwab.details; if (twabDetails.balance > _scale) { ( twabDetails,, ) = TwabLib.decreaseBalance(gaugeScaleTwab, twabDetails.balance - _scale.toUint208(), "insuff", uint32(block.timestamp)); } else { ( twabDetails,, ) = TwabLib.increaseBalance(gaugeScaleTwab, _scale.toUint208() - twabDetails.balance, uint32(block.timestamp)); } gaugeScaleTwab.details = twabDetails; } function getGauge(address _gauge) public view returns (uint256) { return gaugeTwabs[_gauge].details.balance; } function getGaugeScale(address _gauge) public view returns (uint256) { return gaugeScaleTwabs[_gauge].details.balance; } function getScaledAverageGaugeBetween(address _gauge, uint256 _startTime, uint256 _endTime) external override view returns (uint256) { uint256 gauge = _getAverageGaugeBetween(_gauge, _startTime, _endTime); uint256 gaugeScale = _getAverageGaugeScaleBetween(_gauge, _startTime, _endTime); return (gauge*gaugeScale) / 1 ether; } function getAverageGaugeBetween(address _gauge, uint256 _startTime, uint256 _endTime) external view returns (uint256) { return _getAverageGaugeBetween(_gauge, _startTime, _endTime); } function getAverageGaugeScaleBetween(address _gauge, uint256 _startTime, uint256 _endTime) external view returns (uint256) { return _getAverageGaugeScaleBetween(_gauge, _startTime, _endTime); } function _getAverageGaugeBetween(address _gauge, uint256 _startTime, uint256 _endTime) internal view returns (uint256) { TwabLib.AccountDetails memory gaugeDetails = gaugeTwabs[_gauge].details; return TwabLib.getAverageBalanceBetween( gaugeTwabs[_gauge].twabs, gaugeDetails, uint32(_startTime), uint32(_endTime), uint32(block.timestamp) ); } function _getAverageGaugeScaleBetween(address _gauge, uint256 _startTime, uint256 _endTime) internal view returns (uint256) { TwabLib.AccountDetails memory gaugeScaleDetails = gaugeScaleTwabs[_gauge].details; return TwabLib.getAverageBalanceBetween( gaugeScaleTwabs[_gauge].twabs, gaugeScaleDetails, uint32(_startTime), uint32(_endTime), uint32(block.timestamp) ); } function isGauge(address _gauge) public view returns (bool) { return gaugeScaleTwabs[_gauge].details.balance > 0; } modifier requireGauge(address _gauge) { require(isGauge(_gauge), "Gauge does not exist"); _; } }
[{"inputs":[{"internalType":"contract IERC20","name":"_token","type":"address"},{"internalType":"address","name":"_rewardVault","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"_gauge","type":"address"}],"name":"addGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gauge","type":"address"},{"internalType":"uint256","name":"_scale","type":"uint256"}],"name":"addGaugeWithScale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_gauge","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"decreaseGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"gaugeBalances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_gauge","type":"address"},{"internalType":"uint256","name":"_startTime","type":"uint256"},{"internalType":"uint256","name":"_endTime","type":"uint256"}],"name":"getAverageGaugeBetween","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_gauge","type":"address"},{"internalType":"uint256","name":"_startTime","type":"uint256"},{"internalType":"uint256","name":"_endTime","type":"uint256"}],"name":"getAverageGaugeScaleBetween","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_gauge","type":"address"}],"name":"getGauge","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_gauge","type":"address"}],"name":"getGaugeScale","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_gauge","type":"address"},{"internalType":"uint256","name":"_startTime","type":"uint256"},{"internalType":"uint256","name":"_endTime","type":"uint256"}],"name":"getScaledAverageGaugeBetween","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_gauge","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"increaseGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gauge","type":"address"}],"name":"isGauge","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_gauge","type":"address"}],"name":"removeGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardVault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_gauge","type":"address"},{"internalType":"uint256","name":"_scale","type":"uint256"}],"name":"setGaugeScale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b5060405162001a4238038062001a42833981016040819052620000349162000066565b600080546001600160a01b039384166001600160a01b03199182161790915560018054929093169116179055620000be565b600080604083850312156200007a57600080fd5b82516200008781620000a5565b60208401519092506200009a81620000a5565b809150509250929050565b6001600160a01b0381168114620000bb57600080fd5b50565b61197480620000ce6000396000f3fe608060405234801561001057600080fd5b50600436106101215760003560e01c80635cf39fbf116100ad578063aa79979b11610071578063aa79979b146102ae578063b14c6986146102d1578063b1c6f0e9146102e4578063fc0c546a14610316578063fd775c541461032957600080fd5b80635cf39fbf1461023057806362b3fdd2146102435780637eec39f0146102565780639da882ac14610288578063a1a2f1201461029b57600080fd5b80633a045145116100f45780633a045145146101b95780633a2c6777146101cc5780633c72026e146101f757806347e7ef241461020a5780634b0ad1cb1461021d57600080fd5b80630700037d146101265780631264f42b1461015957806327e235e3146101845780632e1a7d4d146101a4575b600080fd5b610146610134366004611606565b60026020526000908152604090205481565b6040519081526020015b60405180910390f35b610146610167366004611621565b600460209081526000928352604080842090915290825290205481565b610146610192366004611606565b60036020526000908152604090205481565b6101b76101b23660046116d3565b61033c565b005b6101b76101c7366004611606565b6103e8565b6001546101df906001600160a01b031681565b6040516001600160a01b039091168152602001610150565b61014661020536600461167e565b6104bc565b6101b7610218366004611654565b6104d3565b6101b761022b366004611654565b610591565b61014661023e36600461167e565b6106e1565b6101b7610251366004611654565b610727565b610146610264366004611606565b6001600160a01b03166000908152600660205260409020546001600160d01b031690565b6101b7610296366004611606565b610827565b6101466102a936600461167e565b61083c565b6102c16102bc366004611606565b610849565b6040519015158152602001610150565b6101b76102df366004611654565b61086f565b6101466102f2366004611606565b6001600160a01b03166000908152600560205260409020546001600160d01b031690565b6000546101df906001600160a01b031681565b6101b7610337366004611654565b6108eb565b336000908152600360205260408120805483929061035b9084906118b4565b909155505060005460405163a9059cbb60e01b8152336004820152602481018390526001600160a01b039091169063a9059cbb90604401602060405180830381600087803b1580156103ac57600080fd5b505af11580156103c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103e491906116b1565b5050565b6001600160a01b038116600090815260066020818152604092839020835160608101855281546001600160d01b03811680835262ffffff600160d01b8304811684870152600160e81b9092049091168287015285518087019096529385526534b739bab33360d11b9285019290925292909161046791849190426109ba565b505080518354602083015160409093015162ffffff908116600160e81b026001600160e81b0391909416600160d01b026001600160e81b03199092166001600160d01b03909316929092171716179091555050565b60006104c9848484610a7e565b90505b9392505050565b6001600160a01b038216600090815260036020526040812080548392906104fb9084906117ac565b90915550506000546040516323b872dd60e01b81526001600160a01b03848116600483015230602483015260448201849052909116906323b872dd90606401602060405180830381600087803b15801561055457600080fd5b505af1158015610568573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058c91906116b1565b505050565b8161059b81610849565b6105e35760405162461bcd60e51b815260206004820152601460248201527311d85d59d948191bd95cc81b9bdd08195e1a5cdd60621b60448201526064015b60405180910390fd5b33600090815260036020526040812080548492906106029084906117ac565b90915550503360009081526004602090815260408083206001600160a01b03871684529091528120805484929061063a9084906118b4565b90915550506001600160a01b03831660009081526005602052604081209061068a8261066586610af1565b6040518060400160405280600681526020016534b739bab33360d11b815250426109ba565b505080518354602083015160409093015162ffffff908116600160e81b026001600160e81b0391909416600160d01b026001600160e81b03199092166001600160d01b039093169290921717161790915550505050565b6000806106ef858585610b5e565b905060006106fe868686610a7e565b9050670de0b6b3a7640000610713828461184d565b61071d919061180a565b9695505050505050565b6001600160a01b038216600090815260066020908152604091829020825160608101845281546001600160d01b03811680835262ffffff600160d01b8304811695840195909552600160e81b9091049093169381019390935291908310156107ad576107a28261079685610af1565b8351610665919061186c565b509091506107d59050565b6107cf8282600001516107bf86610af1565b6107c9919061186c565b42610bc8565b50909150505b80518254602083015160409093015162ffffff908116600160e81b026001600160e81b0391909416600160d01b026001600160e81b03199092166001600160d01b039093169290921717161790555050565b61083981670de0b6b3a764000061086f565b50565b60006104c9848484610b5e565b6001600160a01b03166000908152600660205260409020546001600160d01b0316151590565b6001600160a01b038216600090815260066020526040812090610895826107c985610af1565b505080518354602083015160409093015162ffffff908116600160e81b026001600160e81b0391909416600160d01b026001600160e81b03199092166001600160d01b0390931692909217171617909155505050565b816108f581610849565b6109385760405162461bcd60e51b815260206004820152601460248201527311d85d59d948191bd95cc81b9bdd08195e1a5cdd60621b60448201526064016105da565b33600090815260036020526040812080548492906109579084906118b4565b90915550503360009081526004602090815260408083206001600160a01b03871684529091528120805484929061098f9084906117ac565b90915550506001600160a01b03831660009081526005602052604081209061068a826107c986610af1565b604080516060810182526000808252602082018190529181019190915260408051808201909152600080825260208201526040805160608101825287546001600160d01b0380821680845262ffffff600160d01b840481166020860152600160e81b9093049092169383019390935260009287919089161115610a505760405162461bcd60e51b81526004016105da91906116ec565b50610a5f886001018287610c71565b8251999099036001600160d01b03168252909990985095505050505050565b6001600160a01b0383166000818152600660208181526040808420815160608101835281546001600160d01b038116825262ffffff600160d01b8204811683870152600160e81b90910416928101929092529484529190529091610ae89060010182868642610d58565b95945050505050565b60006001600160d01b03821115610b5a5760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20326044820152663038206269747360c81b60648201526084016105da565b5090565b6001600160a01b0383166000818152600560208181526040808420815160608101835281546001600160d01b038116825262ffffff600160d01b8204811683870152600160e81b90910416928101929092529484529190529091610ae89060010182868642610d58565b604080516060810182526000808252602082018190529181019190915260408051808201909152600080825260208201526040805160608101825286546001600160d01b038116825262ffffff600160d01b820481166020840152600160e81b9091041691810191909152600090610c44600188018287610c71565b83519296509094509250610c59908790611741565b6001600160d01b031684525091959094509092509050565b60408051606081018252600080825260208201819052918101919091526040805180820190915260008082526020820152600080610caf8787610d90565b9150508463ffffffff16816020015163ffffffff161415610cd857859350915060009050610d4f565b6000610cf28288600001516001600160d01b031688610e15565b90508088886020015162ffffff1662ffffff8110610d1257610d12611928565b825160209093015163ffffffff16600160e01b026001600160e01b03909316929092179101556000610d4388610e90565b95509093506001925050505b93509350939050565b6000808263ffffffff168463ffffffff1611610d745783610d76565b825b9050610d858787878487610ef8565b979650505050505050565b6000610dac604080518082019091526000808252602082015290565b610dc4836020015162ffffff1662ffffff8016610f94565b9150838262ffffff1662ffffff8110610ddf57610ddf611928565b604080518082019091529101546001600160e01b0381168252600160e01b900463ffffffff166020820152919491935090915050565b60408051808201909152600080825260208201526040518060400160405280610e538660200151858663ffffffff16610fcb9092919063ffffffff16565b610e639063ffffffff168661181e565b8651610e6f919061176c565b6001600160e01b031681526020018363ffffffff1681525090509392505050565b60408051606081018252600080825260208083018290529282015290820151610ec09062ffffff90811690611095565b62ffffff9081166020840152604083015181161015610b5a57600182604001818151610eec919061178e565b62ffffff169052505090565b6000806000610f0788886110a5565b91509150600080610f188a8a610d90565b915091506000610f2e8b8b8487878a8f8e611127565b90506000610f428c8c8588888b8f8f611127565b9050610f57816020015183602001518a610fcb565b63ffffffff1682600001518260000151610f719190611894565b610f7b91906117e4565b6001600160e01b03169c9b505050505050505050505050565b600081610fa357506000610fc5565b610fc26001610fb284866117ac565b610fbc91906118b4565b83611271565b90505b92915050565b60008163ffffffff168463ffffffff1611158015610ff557508163ffffffff168363ffffffff1611155b1561100b5761100483856118cb565b90506104cc565b60008263ffffffff168563ffffffff161161103a5761103563ffffffff86166401000000006117c4565b611042565b8463ffffffff165b64ffffffffff16905060008363ffffffff168563ffffffff161161107a5761107563ffffffff86166401000000006117c4565b611082565b8463ffffffff165b64ffffffffff16905061071d81836118b4565b6000610fc2610fbc8460016117ac565b60006110c1604080518082019091526000808252602082015290565b82602001519150838262ffffff1662ffffff81106110e1576110e1611928565b604080518082019091529101546001600160e01b0381168252600160e01b900463ffffffff166020820181905290915061112057600091508382610ddf565b9250929050565b604080518082019091526000808252602082015261115a8383896020015163ffffffff1661127d9092919063ffffffff16565b1561117e576111778789600001516001600160d01b031685610e15565b9050611265565b8263ffffffff16876020015163ffffffff16141561119d575085611265565b8263ffffffff16866020015163ffffffff1614156111bc575084611265565b6111db8660200151838563ffffffff1661127d9092919063ffffffff16565b156112005750604080518082019091526000815263ffffffff83166020820152611265565b6000806112158b8888888e604001518961134c565b91509150600061122e8260200151846020015187610fcb565b63ffffffff16836000015183600001516112489190611894565b61125291906117e4565b905061125f838288610e15565b93505050505b98975050505050505050565b6000610fc282846118e8565b60008163ffffffff168463ffffffff16111580156112a757508163ffffffff168363ffffffff1611155b156112c2578263ffffffff168463ffffffff161090506104cc565b60008263ffffffff168563ffffffff16116112f1576112ec63ffffffff86166401000000006117c4565b6112f9565b8463ffffffff165b64ffffffffff16905060008363ffffffff168563ffffffff16116113315761132c63ffffffff86166401000000006117c4565b611339565b8463ffffffff165b64ffffffffff1690911095945050505050565b6040805180820190915260008082526020820152604080518082019091526000808252602082015260008662ffffff1690506000818962ffffff1610611397578862ffffff166113b2565b60016113a862ffffff8816846117ac565b6113b291906118b4565b905060005b60026113c383856117ac565b6113cd919061180a565b90508a6113df828962ffffff16611271565b62ffffff1662ffffff81106113f6576113f6611928565b604080518082019091529101546001600160e01b0381168252600160e01b900463ffffffff16602082018190529095508061143e576114368260016117ac565b9350506113b7565b8b61144e838a62ffffff16611095565b62ffffff1662ffffff811061146557611465611928565b604080518082019091529101546001600160e01b038116825263ffffffff600160e01b909104811660208301529095506000906114aa90838116908c908b9061151916565b90508080156114d357506114d38660200151898c63ffffffff166115199092919063ffffffff16565b156114df57505061150b565b806114f6576114ef6001846118b4565b9350611504565b6115018360016117ac565b94505b50506113b7565b505050965096945050505050565b60008163ffffffff168463ffffffff161115801561154357508163ffffffff168363ffffffff1611155b1561155f578263ffffffff168463ffffffff16111590506104cc565b60008263ffffffff168563ffffffff161161158e5761158963ffffffff86166401000000006117c4565b611596565b8463ffffffff165b64ffffffffff16905060008363ffffffff168563ffffffff16116115ce576115c963ffffffff86166401000000006117c4565b6115d6565b8463ffffffff165b64ffffffffff169091111595945050505050565b80356001600160a01b038116811461160157600080fd5b919050565b60006020828403121561161857600080fd5b610fc2826115ea565b6000806040838503121561163457600080fd5b61163d836115ea565b915061164b602084016115ea565b90509250929050565b6000806040838503121561166757600080fd5b611670836115ea565b946020939093013593505050565b60008060006060848603121561169357600080fd5b61169c846115ea565b95602085013595506040909401359392505050565b6000602082840312156116c357600080fd5b815180151581146104cc57600080fd5b6000602082840312156116e557600080fd5b5035919050565b600060208083528351808285015260005b81811015611719578581018301518582016040015282016116fd565b8181111561172b576000604083870101525b50601f01601f1916929092016040019392505050565b60006001600160d01b03828116848216808303821115611763576117636118fc565b01949350505050565b60006001600160e01b03828116848216808303821115611763576117636118fc565b600062ffffff808316818516808303821115611763576117636118fc565b600082198211156117bf576117bf6118fc565b500190565b600064ffffffffff808316818516808303821115611763576117636118fc565b60006001600160e01b03838116806117fe576117fe611912565b92169190910492915050565b60008261181957611819611912565b500490565b60006001600160e01b0382811684821681151582840482111615611844576118446118fc565b02949350505050565b6000816000190483118215151615611867576118676118fc565b500290565b60006001600160d01b038381169083168181101561188c5761188c6118fc565b039392505050565b60006001600160e01b038381169083168181101561188c5761188c6118fc565b6000828210156118c6576118c66118fc565b500390565b600063ffffffff8381169083168181101561188c5761188c6118fc565b6000826118f7576118f7611912565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fdfea2646970667358221220eaa08cae469ef5fc39ede3507ec30d8085833436b83a7c4738188644c54ca4c264736f6c6343000806003300000000000000000000000052acd6a9e9af795cdad99e1dc21fd6491a237b97000000000000000000000000e0f4217390221af47855e094f6e112d43c8698fe
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101215760003560e01c80635cf39fbf116100ad578063aa79979b11610071578063aa79979b146102ae578063b14c6986146102d1578063b1c6f0e9146102e4578063fc0c546a14610316578063fd775c541461032957600080fd5b80635cf39fbf1461023057806362b3fdd2146102435780637eec39f0146102565780639da882ac14610288578063a1a2f1201461029b57600080fd5b80633a045145116100f45780633a045145146101b95780633a2c6777146101cc5780633c72026e146101f757806347e7ef241461020a5780634b0ad1cb1461021d57600080fd5b80630700037d146101265780631264f42b1461015957806327e235e3146101845780632e1a7d4d146101a4575b600080fd5b610146610134366004611606565b60026020526000908152604090205481565b6040519081526020015b60405180910390f35b610146610167366004611621565b600460209081526000928352604080842090915290825290205481565b610146610192366004611606565b60036020526000908152604090205481565b6101b76101b23660046116d3565b61033c565b005b6101b76101c7366004611606565b6103e8565b6001546101df906001600160a01b031681565b6040516001600160a01b039091168152602001610150565b61014661020536600461167e565b6104bc565b6101b7610218366004611654565b6104d3565b6101b761022b366004611654565b610591565b61014661023e36600461167e565b6106e1565b6101b7610251366004611654565b610727565b610146610264366004611606565b6001600160a01b03166000908152600660205260409020546001600160d01b031690565b6101b7610296366004611606565b610827565b6101466102a936600461167e565b61083c565b6102c16102bc366004611606565b610849565b6040519015158152602001610150565b6101b76102df366004611654565b61086f565b6101466102f2366004611606565b6001600160a01b03166000908152600560205260409020546001600160d01b031690565b6000546101df906001600160a01b031681565b6101b7610337366004611654565b6108eb565b336000908152600360205260408120805483929061035b9084906118b4565b909155505060005460405163a9059cbb60e01b8152336004820152602481018390526001600160a01b039091169063a9059cbb90604401602060405180830381600087803b1580156103ac57600080fd5b505af11580156103c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103e491906116b1565b5050565b6001600160a01b038116600090815260066020818152604092839020835160608101855281546001600160d01b03811680835262ffffff600160d01b8304811684870152600160e81b9092049091168287015285518087019096529385526534b739bab33360d11b9285019290925292909161046791849190426109ba565b505080518354602083015160409093015162ffffff908116600160e81b026001600160e81b0391909416600160d01b026001600160e81b03199092166001600160d01b03909316929092171716179091555050565b60006104c9848484610a7e565b90505b9392505050565b6001600160a01b038216600090815260036020526040812080548392906104fb9084906117ac565b90915550506000546040516323b872dd60e01b81526001600160a01b03848116600483015230602483015260448201849052909116906323b872dd90606401602060405180830381600087803b15801561055457600080fd5b505af1158015610568573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058c91906116b1565b505050565b8161059b81610849565b6105e35760405162461bcd60e51b815260206004820152601460248201527311d85d59d948191bd95cc81b9bdd08195e1a5cdd60621b60448201526064015b60405180910390fd5b33600090815260036020526040812080548492906106029084906117ac565b90915550503360009081526004602090815260408083206001600160a01b03871684529091528120805484929061063a9084906118b4565b90915550506001600160a01b03831660009081526005602052604081209061068a8261066586610af1565b6040518060400160405280600681526020016534b739bab33360d11b815250426109ba565b505080518354602083015160409093015162ffffff908116600160e81b026001600160e81b0391909416600160d01b026001600160e81b03199092166001600160d01b039093169290921717161790915550505050565b6000806106ef858585610b5e565b905060006106fe868686610a7e565b9050670de0b6b3a7640000610713828461184d565b61071d919061180a565b9695505050505050565b6001600160a01b038216600090815260066020908152604091829020825160608101845281546001600160d01b03811680835262ffffff600160d01b8304811695840195909552600160e81b9091049093169381019390935291908310156107ad576107a28261079685610af1565b8351610665919061186c565b509091506107d59050565b6107cf8282600001516107bf86610af1565b6107c9919061186c565b42610bc8565b50909150505b80518254602083015160409093015162ffffff908116600160e81b026001600160e81b0391909416600160d01b026001600160e81b03199092166001600160d01b039093169290921717161790555050565b61083981670de0b6b3a764000061086f565b50565b60006104c9848484610b5e565b6001600160a01b03166000908152600660205260409020546001600160d01b0316151590565b6001600160a01b038216600090815260066020526040812090610895826107c985610af1565b505080518354602083015160409093015162ffffff908116600160e81b026001600160e81b0391909416600160d01b026001600160e81b03199092166001600160d01b0390931692909217171617909155505050565b816108f581610849565b6109385760405162461bcd60e51b815260206004820152601460248201527311d85d59d948191bd95cc81b9bdd08195e1a5cdd60621b60448201526064016105da565b33600090815260036020526040812080548492906109579084906118b4565b90915550503360009081526004602090815260408083206001600160a01b03871684529091528120805484929061098f9084906117ac565b90915550506001600160a01b03831660009081526005602052604081209061068a826107c986610af1565b604080516060810182526000808252602082018190529181019190915260408051808201909152600080825260208201526040805160608101825287546001600160d01b0380821680845262ffffff600160d01b840481166020860152600160e81b9093049092169383019390935260009287919089161115610a505760405162461bcd60e51b81526004016105da91906116ec565b50610a5f886001018287610c71565b8251999099036001600160d01b03168252909990985095505050505050565b6001600160a01b0383166000818152600660208181526040808420815160608101835281546001600160d01b038116825262ffffff600160d01b8204811683870152600160e81b90910416928101929092529484529190529091610ae89060010182868642610d58565b95945050505050565b60006001600160d01b03821115610b5a5760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20326044820152663038206269747360c81b60648201526084016105da565b5090565b6001600160a01b0383166000818152600560208181526040808420815160608101835281546001600160d01b038116825262ffffff600160d01b8204811683870152600160e81b90910416928101929092529484529190529091610ae89060010182868642610d58565b604080516060810182526000808252602082018190529181019190915260408051808201909152600080825260208201526040805160608101825286546001600160d01b038116825262ffffff600160d01b820481166020840152600160e81b9091041691810191909152600090610c44600188018287610c71565b83519296509094509250610c59908790611741565b6001600160d01b031684525091959094509092509050565b60408051606081018252600080825260208201819052918101919091526040805180820190915260008082526020820152600080610caf8787610d90565b9150508463ffffffff16816020015163ffffffff161415610cd857859350915060009050610d4f565b6000610cf28288600001516001600160d01b031688610e15565b90508088886020015162ffffff1662ffffff8110610d1257610d12611928565b825160209093015163ffffffff16600160e01b026001600160e01b03909316929092179101556000610d4388610e90565b95509093506001925050505b93509350939050565b6000808263ffffffff168463ffffffff1611610d745783610d76565b825b9050610d858787878487610ef8565b979650505050505050565b6000610dac604080518082019091526000808252602082015290565b610dc4836020015162ffffff1662ffffff8016610f94565b9150838262ffffff1662ffffff8110610ddf57610ddf611928565b604080518082019091529101546001600160e01b0381168252600160e01b900463ffffffff166020820152919491935090915050565b60408051808201909152600080825260208201526040518060400160405280610e538660200151858663ffffffff16610fcb9092919063ffffffff16565b610e639063ffffffff168661181e565b8651610e6f919061176c565b6001600160e01b031681526020018363ffffffff1681525090509392505050565b60408051606081018252600080825260208083018290529282015290820151610ec09062ffffff90811690611095565b62ffffff9081166020840152604083015181161015610b5a57600182604001818151610eec919061178e565b62ffffff169052505090565b6000806000610f0788886110a5565b91509150600080610f188a8a610d90565b915091506000610f2e8b8b8487878a8f8e611127565b90506000610f428c8c8588888b8f8f611127565b9050610f57816020015183602001518a610fcb565b63ffffffff1682600001518260000151610f719190611894565b610f7b91906117e4565b6001600160e01b03169c9b505050505050505050505050565b600081610fa357506000610fc5565b610fc26001610fb284866117ac565b610fbc91906118b4565b83611271565b90505b92915050565b60008163ffffffff168463ffffffff1611158015610ff557508163ffffffff168363ffffffff1611155b1561100b5761100483856118cb565b90506104cc565b60008263ffffffff168563ffffffff161161103a5761103563ffffffff86166401000000006117c4565b611042565b8463ffffffff165b64ffffffffff16905060008363ffffffff168563ffffffff161161107a5761107563ffffffff86166401000000006117c4565b611082565b8463ffffffff165b64ffffffffff16905061071d81836118b4565b6000610fc2610fbc8460016117ac565b60006110c1604080518082019091526000808252602082015290565b82602001519150838262ffffff1662ffffff81106110e1576110e1611928565b604080518082019091529101546001600160e01b0381168252600160e01b900463ffffffff166020820181905290915061112057600091508382610ddf565b9250929050565b604080518082019091526000808252602082015261115a8383896020015163ffffffff1661127d9092919063ffffffff16565b1561117e576111778789600001516001600160d01b031685610e15565b9050611265565b8263ffffffff16876020015163ffffffff16141561119d575085611265565b8263ffffffff16866020015163ffffffff1614156111bc575084611265565b6111db8660200151838563ffffffff1661127d9092919063ffffffff16565b156112005750604080518082019091526000815263ffffffff83166020820152611265565b6000806112158b8888888e604001518961134c565b91509150600061122e8260200151846020015187610fcb565b63ffffffff16836000015183600001516112489190611894565b61125291906117e4565b905061125f838288610e15565b93505050505b98975050505050505050565b6000610fc282846118e8565b60008163ffffffff168463ffffffff16111580156112a757508163ffffffff168363ffffffff1611155b156112c2578263ffffffff168463ffffffff161090506104cc565b60008263ffffffff168563ffffffff16116112f1576112ec63ffffffff86166401000000006117c4565b6112f9565b8463ffffffff165b64ffffffffff16905060008363ffffffff168563ffffffff16116113315761132c63ffffffff86166401000000006117c4565b611339565b8463ffffffff165b64ffffffffff1690911095945050505050565b6040805180820190915260008082526020820152604080518082019091526000808252602082015260008662ffffff1690506000818962ffffff1610611397578862ffffff166113b2565b60016113a862ffffff8816846117ac565b6113b291906118b4565b905060005b60026113c383856117ac565b6113cd919061180a565b90508a6113df828962ffffff16611271565b62ffffff1662ffffff81106113f6576113f6611928565b604080518082019091529101546001600160e01b0381168252600160e01b900463ffffffff16602082018190529095508061143e576114368260016117ac565b9350506113b7565b8b61144e838a62ffffff16611095565b62ffffff1662ffffff811061146557611465611928565b604080518082019091529101546001600160e01b038116825263ffffffff600160e01b909104811660208301529095506000906114aa90838116908c908b9061151916565b90508080156114d357506114d38660200151898c63ffffffff166115199092919063ffffffff16565b156114df57505061150b565b806114f6576114ef6001846118b4565b9350611504565b6115018360016117ac565b94505b50506113b7565b505050965096945050505050565b60008163ffffffff168463ffffffff161115801561154357508163ffffffff168363ffffffff1611155b1561155f578263ffffffff168463ffffffff16111590506104cc565b60008263ffffffff168563ffffffff161161158e5761158963ffffffff86166401000000006117c4565b611596565b8463ffffffff165b64ffffffffff16905060008363ffffffff168563ffffffff16116115ce576115c963ffffffff86166401000000006117c4565b6115d6565b8463ffffffff165b64ffffffffff169091111595945050505050565b80356001600160a01b038116811461160157600080fd5b919050565b60006020828403121561161857600080fd5b610fc2826115ea565b6000806040838503121561163457600080fd5b61163d836115ea565b915061164b602084016115ea565b90509250929050565b6000806040838503121561166757600080fd5b611670836115ea565b946020939093013593505050565b60008060006060848603121561169357600080fd5b61169c846115ea565b95602085013595506040909401359392505050565b6000602082840312156116c357600080fd5b815180151581146104cc57600080fd5b6000602082840312156116e557600080fd5b5035919050565b600060208083528351808285015260005b81811015611719578581018301518582016040015282016116fd565b8181111561172b576000604083870101525b50601f01601f1916929092016040019392505050565b60006001600160d01b03828116848216808303821115611763576117636118fc565b01949350505050565b60006001600160e01b03828116848216808303821115611763576117636118fc565b600062ffffff808316818516808303821115611763576117636118fc565b600082198211156117bf576117bf6118fc565b500190565b600064ffffffffff808316818516808303821115611763576117636118fc565b60006001600160e01b03838116806117fe576117fe611912565b92169190910492915050565b60008261181957611819611912565b500490565b60006001600160e01b0382811684821681151582840482111615611844576118446118fc565b02949350505050565b6000816000190483118215151615611867576118676118fc565b500290565b60006001600160d01b038381169083168181101561188c5761188c6118fc565b039392505050565b60006001600160e01b038381169083168181101561188c5761188c6118fc565b6000828210156118c6576118c66118fc565b500390565b600063ffffffff8381169083168181101561188c5761188c6118fc565b6000826118f7576118f7611912565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fdfea2646970667358221220eaa08cae469ef5fc39ede3507ec30d8085833436b83a7c4738188644c54ca4c264736f6c63430008060033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000052acd6a9e9af795cdad99e1dc21fd6491a237b97000000000000000000000000e0f4217390221af47855e094f6e112d43c8698fe
-----Decoded View---------------
Arg [0] : _token (address): 0x52ACd6a9E9AF795CDaD99E1dc21Fd6491a237b97
Arg [1] : _rewardVault (address): 0xE0F4217390221aF47855E094F6e112D43C8698fE
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 00000000000000000000000052acd6a9e9af795cdad99e1dc21fd6491a237b97
Arg [1] : 000000000000000000000000e0f4217390221af47855e094f6e112d43c8698fe
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.