FTM Price: $0.5207 (+5.19%)
 

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Claim1069524272025-03-21 19:19:0714 hrs ago1742584747IN
0xE0B70875...923A3389A
0 FTM0.001953836.81921632
Claim1069524032025-03-21 19:18:3914 hrs ago1742584719IN
0xE0B70875...923A3389A
0 FTM0.001953836.81921632
Claim1069523822025-03-21 19:18:1614 hrs ago1742584696IN
0xE0B70875...923A3389A
0 FTM0.001953836.81921632
Claim1069523532025-03-21 19:17:4914 hrs ago1742584669IN
0xE0B70875...923A3389A
0 FTM0.001953836.81921632
Claim1069456162025-03-21 16:38:4417 hrs ago1742575124IN
0xE0B70875...923A3389A
0 FTM0.002300928.03060222
Claim1069455962025-03-21 16:38:1217 hrs ago1742575092IN
0xE0B70875...923A3389A
0 FTM0.002300928.03060222
Claim1069060622025-03-20 20:56:4136 hrs ago1742504201IN
0xE0B70875...923A3389A
0 FTM0.0072063716.59338946
Claim1069060532025-03-20 20:56:2736 hrs ago1742504187IN
0xE0B70875...923A3389A
0 FTM0.0072061716.59338946
Claim1069042932025-03-20 20:00:3937 hrs ago1742500839IN
0xE0B70875...923A3389A
0 FTM0.0053044518
Claim1068901322025-03-20 14:10:5943 hrs ago1742479859IN
0xE0B70875...923A3389A
0 FTM0.002062847
Claim1068742492025-03-20 8:29:192 days ago1742459359IN
0xE0B70875...923A3389A
0 FTM0.000884073
Claim1068711762025-03-20 7:11:482 days ago1742454708IN
0xE0B70875...923A3389A
0 FTM0.000566752
Claim1068687062025-03-20 6:08:052 days ago1742450885IN
0xE0B70875...923A3389A
0 FTM0.000589382
Claim1068686402025-03-20 6:06:562 days ago1742450816IN
0xE0B70875...923A3389A
0 FTM0.00060612
Claim1068625772025-03-20 3:24:072 days ago1742441047IN
0xE0B70875...923A3389A
0 FTM0.00060612
Claim1068577002025-03-20 1:12:472 days ago1742433167IN
0xE0B70875...923A3389A
0 FTM0.000701292.5
Claim1068572622025-03-20 1:02:142 days ago1742432534IN
0xE0B70875...923A3389A
0 FTM0.000884073
Claim1068494922025-03-19 22:23:232 days ago1742423003IN
0xE0B70875...923A3389A
0 FTM0.00071962
Claim1068375492025-03-19 18:14:372 days ago1742408077IN
0xE0B70875...923A3389A
0 FTM0.000293771.02366
Claim1068375252025-03-19 18:13:552 days ago1742408035IN
0xE0B70875...923A3389A
0 FTM0.000408671.023808
Claim1068364412025-03-19 17:50:012 days ago1742406601IN
0xE0B70875...923A3389A
0 FTM0.000589382
Claim1067877692025-03-18 16:35:393 days ago1742315739IN
0xE0B70875...923A3389A
0 FTM0.000566782
Claim1067762792025-03-18 10:51:143 days ago1742295074IN
0xE0B70875...923A3389A
0 FTM0.00073022.5
Claim1066701442025-03-16 20:49:185 days ago1742158158IN
0xE0B70875...923A3389A
0 FTM0.000778372.5
Claim1065510052025-03-15 0:41:407 days ago1741999300IN
0xE0B70875...923A3389A
0 FTM0.000768282.59167061
View all transactions

Latest 1 internal transaction

Parent Transaction Hash Block From To
649651832023-07-01 8:51:25630 days ago1688201485  Contract Creation0 FTM
Loading...
Loading

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0x82D862D1...e99A9E339
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
RewardsDistributor

Compiler Version
v0.8.13+commit.abaa5c0e

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, GNU AGPLv3 license

Contract Source Code (Solidity)

/**
 *Submitted for verification at ftmscan.com on 2023-06-30
*/

// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;


// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                // Solidity will revert if denominator == 0, unlike the div opcode on its own.
                // The surrounding unchecked block does not change this fact.
                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1, "Math: mulDiv overflow");

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10 ** 64) {
                value /= 10 ** 64;
                result += 64;
            }
            if (value >= 10 ** 32) {
                value /= 10 ** 32;
                result += 32;
            }
            if (value >= 10 ** 16) {
                value /= 10 ** 16;
                result += 16;
            }
            if (value >= 10 ** 8) {
                value /= 10 ** 8;
                result += 8;
            }
            if (value >= 10 ** 4) {
                value /= 10 ** 4;
                result += 4;
            }
            if (value >= 10 ** 2) {
                value /= 10 ** 2;
                result += 2;
            }
            if (value >= 10 ** 1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256, rounded down, of a positive value.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
        }
    }
}


interface IERC20 {
    function totalSupply() external view returns (uint256);
    function transfer(address recipient, uint amount) external returns (bool);
    function decimals() external view returns (uint8);
    function symbol() external view returns (string memory);
    function balanceOf(address) external view returns (uint);
    function transferFrom(address sender, address recipient, uint amount) external returns (bool);
    function allowance(address owner, address spender) external view returns (uint);
    function approve(address spender, uint value) external returns (bool);

    event Transfer(address indexed from, address indexed to, uint value);
    event Approval(address indexed owner, address indexed spender, uint value);
}


interface IRewardsDistributor {
    function checkpoint_token() external;
    function checkpoint_total_supply() external;
}



interface IVotingEscrow {

    struct Point {
        int128 bias;
        int128 slope; // # -dweight / dt
        uint256 ts;
        uint256 blk; // block
    }

    function token() external view returns (address);
    function team() external returns (address);
    function epoch() external view returns (uint);
    function point_history(uint loc) external view returns (Point memory);
    function user_point_history(uint tokenId, uint loc) external view returns (Point memory);
    function user_point_epoch(uint tokenId) external view returns (uint);

    function ownerOf(uint) external view returns (address);
    function isApprovedOrOwner(address, uint) external view returns (bool);
    function transferFrom(address, address, uint) external;

    function voting(uint tokenId) external;
    function abstain(uint tokenId) external;
    function attach(uint tokenId) external;
    function detach(uint tokenId) external;

    function checkpoint() external;
    function deposit_for(uint tokenId, uint value) external;
    function create_lock_for(uint, uint, address) external returns (uint);

    function balanceOfNFT(uint) external view returns (uint);
    function totalSupply() external view returns (uint);
}


/*

@title Curve Fee Distribution modified for ve(3,3) emissions
@author Curve Finance, andrecronje
@license MIT

*/

contract RewardsDistributor is IRewardsDistributor {

    event CheckpointToken(
        uint time,
        uint tokens
    );

    event Claimed(
        uint tokenId,
        uint amount,
        uint claim_epoch,
        uint max_epoch
    );

    uint constant WEEK = 7 * 86400;

    uint public start_time;
    uint public time_cursor;
    mapping(uint => uint) public time_cursor_of;
    mapping(uint => uint) public user_epoch_of;

    uint public last_token_time;
    uint[1000000000000000] public tokens_per_week;

    address public voting_escrow;
    address public token;
    uint public token_last_balance;

    uint[1000000000000000] public ve_supply;

    address public depositor;

    constructor(address _voting_escrow) {
        uint _t = block.timestamp / WEEK * WEEK;
        start_time = _t;
        last_token_time = _t;
        time_cursor = _t;
        address _token = IVotingEscrow(_voting_escrow).token();
        token = _token;
        voting_escrow = _voting_escrow;
        depositor = msg.sender;
        require(IERC20(_token).approve(_voting_escrow, type(uint).max));
    }

    function timestamp() external view returns (uint) {
        return block.timestamp / WEEK * WEEK;
    }

    function _checkpoint_token() internal {
        uint token_balance = IERC20(token).balanceOf(address(this));
        uint to_distribute = token_balance - token_last_balance;
        token_last_balance = token_balance;

        uint t = last_token_time;
        uint since_last = block.timestamp - t;
        last_token_time = block.timestamp;
        uint this_week = t / WEEK * WEEK;
        uint next_week = 0;

        for (uint i = 0; i < 20; i++) {
            next_week = this_week + WEEK;
            if (block.timestamp < next_week) {
                if (since_last == 0 && block.timestamp == t) {
                    tokens_per_week[this_week] += to_distribute;
                } else {
                    tokens_per_week[this_week] += to_distribute * (block.timestamp - t) / since_last;
                }
                break;
            } else {
                if (since_last == 0 && next_week == t) {
                    tokens_per_week[this_week] += to_distribute;
                } else {
                    tokens_per_week[this_week] += to_distribute * (next_week - t) / since_last;
                }
            }
            t = next_week;
            this_week = next_week;
        }
        emit CheckpointToken(block.timestamp, to_distribute);
    }

    function checkpoint_token() external {
        assert(msg.sender == depositor);
        _checkpoint_token();
    }

    function _find_timestamp_epoch(address ve, uint _timestamp) internal view returns (uint) {
        uint _min = 0;
        uint _max = IVotingEscrow(ve).epoch();
        for (uint i = 0; i < 128; i++) {
            if (_min >= _max) break;
            uint _mid = (_min + _max + 2) / 2;
            IVotingEscrow.Point memory pt = IVotingEscrow(ve).point_history(_mid);
            if (pt.ts <= _timestamp) {
                _min = _mid;
            } else {
                _max = _mid - 1;
            }
        }
        return _min;
    }

    function _find_timestamp_user_epoch(address ve, uint tokenId, uint _timestamp, uint max_user_epoch) internal view returns (uint) {
        uint _min = 0;
        uint _max = max_user_epoch;
        for (uint i = 0; i < 128; i++) {
            if (_min >= _max) break;
            uint _mid = (_min + _max + 2) / 2;
            IVotingEscrow.Point memory pt = IVotingEscrow(ve).user_point_history(tokenId, _mid);
            if (pt.ts <= _timestamp) {
                _min = _mid;
            } else {
                _max = _mid -1;
            }
        }
        return _min;
    }

    function ve_for_at(uint _tokenId, uint _timestamp) external view returns (uint) {
        address ve = voting_escrow;
        uint max_user_epoch = IVotingEscrow(ve).user_point_epoch(_tokenId);
        uint epoch = _find_timestamp_user_epoch(ve, _tokenId, _timestamp, max_user_epoch);
        IVotingEscrow.Point memory pt = IVotingEscrow(ve).user_point_history(_tokenId, epoch);
        return Math.max(uint(int256(pt.bias - pt.slope * (int128(int256(_timestamp - pt.ts))))), 0);
    }

    function _checkpoint_total_supply() internal {
        address ve = voting_escrow;
        uint t = time_cursor;
        uint rounded_timestamp = block.timestamp / WEEK * WEEK;
        IVotingEscrow(ve).checkpoint();

        for (uint i = 0; i < 20; i++) {
            if (t > rounded_timestamp) {
                break;
            } else {
                uint epoch = _find_timestamp_epoch(ve, t);
                IVotingEscrow.Point memory pt = IVotingEscrow(ve).point_history(epoch);
                int128 dt = 0;
                if (t > pt.ts) {
                    dt = int128(int256(t - pt.ts));
                }
                ve_supply[t] = Math.max(uint(int256(pt.bias - pt.slope * dt)), 0);
            }
            t += WEEK;
        }
        time_cursor = t;
    }

    function checkpoint_total_supply() external {
        _checkpoint_total_supply();
    }

    function _claim(uint _tokenId, address ve, uint _last_token_time) internal returns (uint) {
        uint user_epoch = 0;
        uint to_distribute = 0;

        uint max_user_epoch = IVotingEscrow(ve).user_point_epoch(_tokenId);
        uint _start_time = start_time;

        if (max_user_epoch == 0) return 0;

        uint week_cursor = time_cursor_of[_tokenId];
        if (week_cursor == 0) {
            user_epoch = _find_timestamp_user_epoch(ve, _tokenId, _start_time, max_user_epoch);
        } else {
            user_epoch = user_epoch_of[_tokenId];
        }

        if (user_epoch == 0) user_epoch = 1;

        IVotingEscrow.Point memory user_point = IVotingEscrow(ve).user_point_history(_tokenId, user_epoch);

        if (week_cursor == 0) week_cursor = (user_point.ts + WEEK - 1) / WEEK * WEEK;
        if (week_cursor >= last_token_time) return 0;
        if (week_cursor < _start_time) week_cursor = _start_time;

        IVotingEscrow.Point memory old_user_point;

        for (uint i = 0; i < 50; i++) {
            if (week_cursor >= _last_token_time) break;

            if (week_cursor >= user_point.ts && user_epoch <= max_user_epoch) {
                user_epoch += 1;
                old_user_point = user_point;
                if (user_epoch > max_user_epoch) {
                    user_point = IVotingEscrow.Point(0,0,0,0);
                } else {
                    user_point = IVotingEscrow(ve).user_point_history(_tokenId, user_epoch);
                }
            } else {
                int128 dt = int128(int256(week_cursor - old_user_point.ts));
                uint balance_of = Math.max(uint(int256(old_user_point.bias - dt * old_user_point.slope)), 0);
                if (balance_of == 0 && user_epoch > max_user_epoch) break;
                if (balance_of != 0) {
                    to_distribute += balance_of * tokens_per_week[week_cursor] / ve_supply[week_cursor];
                }
                week_cursor += WEEK;
            }
        }

        user_epoch = Math.min(max_user_epoch, user_epoch - 1);
        user_epoch_of[_tokenId] = user_epoch;
        time_cursor_of[_tokenId] = week_cursor;

        emit Claimed(_tokenId, to_distribute, user_epoch, max_user_epoch);

        return to_distribute;
    }

    function _claimable(uint _tokenId, address ve, uint _last_token_time) internal view returns (uint) {
        uint user_epoch = 0;
        uint to_distribute = 0;

        uint max_user_epoch = IVotingEscrow(ve).user_point_epoch(_tokenId);
        uint _start_time = start_time;

        if (max_user_epoch == 0) return 0;

        uint week_cursor = time_cursor_of[_tokenId];
        if (week_cursor == 0) {
            user_epoch = _find_timestamp_user_epoch(ve, _tokenId, _start_time, max_user_epoch);
        } else {
            user_epoch = user_epoch_of[_tokenId];
        }

        if (user_epoch == 0) user_epoch = 1;

        IVotingEscrow.Point memory user_point = IVotingEscrow(ve).user_point_history(_tokenId, user_epoch);

        if (week_cursor == 0) week_cursor = (user_point.ts + WEEK - 1) / WEEK * WEEK;
        if (week_cursor >= last_token_time) return 0;
        if (week_cursor < _start_time) week_cursor = _start_time;

        IVotingEscrow.Point memory old_user_point;

        for (uint i = 0; i < 50; i++) {
            if (week_cursor >= _last_token_time) break;

            if (week_cursor >= user_point.ts && user_epoch <= max_user_epoch) {
                user_epoch += 1;
                old_user_point = user_point;
                if (user_epoch > max_user_epoch) {
                    user_point = IVotingEscrow.Point(0,0,0,0);
                } else {
                    user_point = IVotingEscrow(ve).user_point_history(_tokenId, user_epoch);
                }
            } else {
                int128 dt = int128(int256(week_cursor - old_user_point.ts));
                uint balance_of = Math.max(uint(int256(old_user_point.bias - dt * old_user_point.slope)), 0);
                if (balance_of == 0 && user_epoch > max_user_epoch) break;
                if (balance_of != 0) {
                    to_distribute += balance_of * tokens_per_week[week_cursor] / ve_supply[week_cursor];
                }
                week_cursor += WEEK;
            }
        }

        return to_distribute;
    }

    function claimable(uint _tokenId) external view returns (uint) {
        uint _last_token_time = last_token_time / WEEK * WEEK;
        return _claimable(_tokenId, voting_escrow, _last_token_time);
    }

    function claim(uint _tokenId) external returns (uint) {
        if (block.timestamp >= time_cursor) _checkpoint_total_supply();
        uint _last_token_time = last_token_time;
        _last_token_time = _last_token_time / WEEK * WEEK;
        uint amount = _claim(_tokenId, voting_escrow, _last_token_time);
        if (amount != 0) {
            IVotingEscrow(voting_escrow).deposit_for(_tokenId, amount);
            token_last_balance -= amount;
        }
        return amount;
    }

    function claim_many(uint[] memory _tokenIds) external returns (bool) {
        if (block.timestamp >= time_cursor) _checkpoint_total_supply();
        uint _last_token_time = last_token_time;
        _last_token_time = _last_token_time / WEEK * WEEK;
        address _voting_escrow = voting_escrow;
        uint total = 0;

        for (uint i = 0; i < _tokenIds.length; i++) {
            uint _tokenId = _tokenIds[i];
            if (_tokenId == 0) break;
            uint amount = _claim(_tokenId, _voting_escrow, _last_token_time);
            if (amount != 0) {
                IVotingEscrow(_voting_escrow).deposit_for(_tokenId, amount);
                total += amount;
            }
        }
        if (total != 0) {
            token_last_balance -= total;
        }

        return true;
    }

    // Once off event on contract initialize
    function setDepositor(address _depositor) external {
        require(msg.sender == depositor);
        depositor = _depositor;
    }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_voting_escrow","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokens","type":"uint256"}],"name":"CheckpointToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"claim_epoch","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"max_epoch","type":"uint256"}],"name":"Claimed","type":"event"},{"inputs":[],"name":"checkpoint_token","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"checkpoint_total_supply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"claim","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"claim_many","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"claimable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"depositor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"last_token_time","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_depositor","type":"address"}],"name":"setDepositor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"start_time","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"time_cursor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"time_cursor_of","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"timestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token_last_balance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokens_per_week","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"user_epoch_of","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"ve_for_at","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"ve_supply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"voting_escrow","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101215760003560e01c8063834ee417116100ad578063d4dafba811610071578063d4dafba81461024a578063dfe050311461025d578063edf5999714610276578063f2c098b714610289578063fc0c546a1461029c57600080fd5b8063834ee417146101ed578063b21ed502146101f6578063b80777ea146101fe578063c7c4ff4614610206578063d1d58b251461023757600080fd5b8063379607f5116100f4578063379607f514610194578063486d25fe146101a757806368809889146101c75780637f58e8f8146101da578063811a40fe146101e357600080fd5b8063127dcbd31461012657806316aea5c0146101425780631f1db0431461016257806322b04bfc14610185575b600080fd5b61012f60015481565b6040519081526020015b60405180910390f35b61012f610150366004611566565b60036020526000908152604090205481565b6101756101703660046115c6565b6102b5565b6040519015158152602001610139565b61012f66038d7ea4c680075481565b61012f6101a2366004611566565b6103fb565b61012f6101b5366004611566565b60026020526000908152604090205481565b61012f6101d536600461166c565b6104e5565b61012f60045481565b6101eb610628565b005b61012f60005481565b6101eb610652565b61012f61065a565b66071afd498d00085461021f906001600160a01b031681565b6040516001600160a01b039091168152602001610139565b61012f610245366004611566565b610679565b61012f610258366004611566565b6106b9565b66038d7ea4c680055461021f906001600160a01b031681565b61012f610284366004611566565b6106dc565b6101eb61029736600461168e565b6106f2565b66038d7ea4c680065461021f906001600160a01b031681565b600060015442106102c8576102c8610737565b60045462093a806102d981836116cd565b6102e391906116ef565b66038d7ea4c68005549091506001600160a01b03166000805b85518110156103cb5760008682815181106103195761031961170e565b602002602001015190508060000361033157506103cb565b600061033e8286886108da565b905080156103b657604051631dd33fc560e31b815260048101839052602481018290526001600160a01b0386169063ee99fe2890604401600060405180830381600087803b15801561038f57600080fd5b505af11580156103a3573d6000803e3d6000fd5b5050505080846103b39190611724565b93505b505080806103c39061173c565b9150506102fc565b5080156103f0578066038d7ea4c6800760008282546103ea9190611755565b90915550505b506001949350505050565b6000600154421061040e5761040e610737565b60045462093a8061041f81836116cd565b61042991906116ef565b66038d7ea4c680055490915060009061044d9085906001600160a01b0316846108da565b905080156104de5766038d7ea4c6800554604051631dd33fc560e31b815260048101869052602481018390526001600160a01b039091169063ee99fe2890604401600060405180830381600087803b1580156104a857600080fd5b505af11580156104bc573d6000803e3d6000fd5b505050508066038d7ea4c6800760008282546104d89190611755565b90915550505b9392505050565b66038d7ea4c680055460405163391044d760e21b8152600481018490526000916001600160a01b0316908290829063e441135c90602401602060405180830381865afa158015610539573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061055d919061176c565b9050600061056d83878785610cfe565b6040516309bb79ed60e11b815260048101889052602481018290529091506000906001600160a01b03851690631376f3da90604401608060405180830381865afa1580156105bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105e3919061179c565b905061061d8160400151876105f89190611755565b8260200151610607919061180e565b825161061391906118ac565b600f0b6000610df2565b979650505050505050565b66071afd498d0008546001600160a01b03163314610648576106486118fc565b610650610e08565b565b610650610737565b600062093a8061066a81426116cd565b61067491906116ef565b905090565b60008062093a808060045461068e91906116cd565b61069891906116ef565b66038d7ea4c68005549091506104de9084906001600160a01b031683611065565b66038d7ea4c680088166038d7ea4c6800081106106d557600080fd5b0154905081565b60058166038d7ea4c6800081106106d557600080fd5b66071afd498d0008546001600160a01b0316331461070f57600080fd5b66071afd498d000880546001600160a01b0319166001600160a01b0392909216919091179055565b66038d7ea4c68005546001546001600160a01b0390911690600062093a8061075f81426116cd565b61076991906116ef565b9050826001600160a01b031663c2c4c5c16040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156107a657600080fd5b505af11580156107ba573d6000803e3d6000fd5b5050505060005b60148110156108d2578183116108d25760006107dd8585611402565b60405163d1febfb960e01b8152600481018290529091506000906001600160a01b0387169063d1febfb990602401608060405180830381865afa158015610828573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061084c919061179c565b90506000816040015186111561086e57604082015161086b9087611755565b90505b61088d818360200151610881919061180e565b835161061391906118ac565b66038d7ea4c680088766038d7ea4c6800081106108ac576108ac61170e565b01555050506108be62093a8084611724565b9250806108ca8161173c565b9150506107c1565b505060015550565b60405163391044d760e21b8152600481018490526000908190819081906001600160a01b0387169063e441135c90602401602060405180830381865afa158015610928573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061094c919061176c565b600080549192508290036109675760009450505050506104de565b600088815260026020526040812054908190036109915761098a888a8486610cfe565b94506109a3565b60008981526003602052604090205494505b846000036109b057600194505b6040516309bb79ed60e11b8152600481018a9052602481018690526000906001600160a01b038a1690631376f3da90604401608060405180830381865afa1580156109ff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a23919061179c565b905081600003610a685762093a8080600162093a808460400151610a479190611724565b610a519190611755565b610a5b91906116cd565b610a6591906116ef565b91505b6004548210610a8057600096505050505050506104de565b82821015610a8c578291505b6040805160808101825260008082526020820181905291810182905260608101829052905b6032811015610c735789841015610c735782604001518410158015610ad65750858811155b15610b9c57610ae6600189611724565b975082915085881115610b255760405180608001604052806000600f0b81526020016000600f0b81526020016000815260200160008152509250610c61565b6040516309bb79ed60e11b8152600481018d9052602481018990526001600160a01b038c1690631376f3da90604401608060405180830381865afa158015610b71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b95919061179c565b9250610c61565b6000826040015185610bae9190611755565b90506000610bd1846020015183610bc5919061180e565b855161061391906118ac565b905080158015610be05750878a115b15610bec575050610c73565b8015610c4f5766038d7ea4c680088666038d7ea4c680008110610c1157610c1161170e565b015460058766038d7ea4c680008110610c2c57610c2c61170e565b0154610c3890836116ef565b610c4291906116cd565b610c4c908a611724565b98505b610c5c62093a8087611724565b955050505b80610c6b8161173c565b915050610ab1565b50610c8885610c8360018a611755565b611557565b60008c8152600360209081526040808320849055600282529182902086905581518e8152908101899052908101829052606081018790529097507fcae2990aa9af8eb1c64713b7eddb3a80bf18e49a94a13fe0d0002b5d61d58f009060800160405180910390a150939998505050505050505050565b60008082815b6080811015610de65781831015610de65760006002610d238486611724565b610d2e906002611724565b610d3891906116cd565b6040516309bb79ed60e11b8152600481018a9052602481018290529091506000906001600160a01b038b1690631376f3da90604401608060405180830381865afa158015610d8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dae919061179c565b905087816040015111610dc357819450610dd1565b610dce600183611755565b93505b50508080610dde9061173c565b915050610d04565b50909695505050505050565b6000818311610e0157816104de565b5090919050565b66038d7ea4c68006546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015610e57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e7b919061176c565b9050600066038d7ea4c680075482610e939190611755565b66038d7ea4c680078390556004549091506000610eb08242611755565b426004559050600062093a80610ec681856116cd565b610ed091906116ef565b90506000805b601481101561102357610eec62093a8084611724565b915081421015610f755783158015610f0357508442145b15610f3d578560058466038d7ea4c680008110610f2257610f2261170e565b016000828254610f329190611724565b909155506110239050565b83610f488642611755565b610f5290886116ef565b610f5c91906116cd565b60058466038d7ea4c680008110610f2257610f2261170e565b83158015610f8257508482145b15610fbc578560058466038d7ea4c680008110610fa157610fa161170e565b016000828254610fb19190611724565b9091555061100a9050565b83610fc78684611755565b610fd190886116ef565b610fdb91906116cd565b60058466038d7ea4c680008110610ff457610ff461170e565b0160008282546110049190611724565b90915550505b819450819250808061101b9061173c565b915050610ed6565b5060408051428152602081018790527fce749457b74e10f393f2c6b1ce4261b78791376db5a3f501477a809f03f500d6910160405180910390a1505050505050565b60405163391044d760e21b8152600481018490526000908190819081906001600160a01b0387169063e441135c90602401602060405180830381865afa1580156110b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110d7919061176c565b600080549192508290036110f25760009450505050506104de565b6000888152600260205260408120549081900361111c57611115888a8486610cfe565b945061112e565b60008981526003602052604090205494505b8460000361113b57600194505b6040516309bb79ed60e11b8152600481018a9052602481018690526000906001600160a01b038a1690631376f3da90604401608060405180830381865afa15801561118a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111ae919061179c565b9050816000036111f35762093a8080600162093a8084604001516111d29190611724565b6111dc9190611755565b6111e691906116cd565b6111f091906116ef565b91505b600454821061120b57600096505050505050506104de565b82821015611217578291505b6040805160808101825260008082526020820181905291810182905260608101829052905b60328110156113f257898410156113f257826040015184101580156112615750858811155b1561132757611271600189611724565b9750829150858811156112b05760405180608001604052806000600f0b81526020016000600f0b815260200160008152602001600081525092506113e0565b6040516309bb79ed60e11b8152600481018d9052602481018990526001600160a01b038c1690631376f3da90604401608060405180830381865afa1580156112fc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611320919061179c565b92506113e0565b60008260400151856113399190611755565b90506000611350846020015183610bc5919061180e565b90508015801561135f5750878a115b1561136b5750506113f2565b80156113ce5766038d7ea4c680088666038d7ea4c6800081106113905761139061170e565b015460058766038d7ea4c6800081106113ab576113ab61170e565b01546113b790836116ef565b6113c191906116cd565b6113cb908a611724565b98505b6113db62093a8087611724565b955050505b806113ea8161173c565b91505061123c565b50949a9950505050505050505050565b600080600090506000846001600160a01b031663900cf0cf6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611449573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061146d919061176c565b905060005b608081101561154d578183101561154d57600060026114918486611724565b61149c906002611724565b6114a691906116cd565b60405163d1febfb960e01b8152600481018290529091506000906001600160a01b0389169063d1febfb990602401608060405180830381865afa1580156114f1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611515919061179c565b90508681604001511161152a57819450611538565b611535600183611755565b93505b505080806115459061173c565b915050611472565b5090949350505050565b6000818310610e0157816104de565b60006020828403121561157857600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156115be576115be61157f565b604052919050565b600060208083850312156115d957600080fd5b823567ffffffffffffffff808211156115f157600080fd5b818501915085601f83011261160557600080fd5b8135818111156116175761161761157f565b8060051b9150611628848301611595565b818152918301840191848101908884111561164257600080fd5b938501935b8385101561166057843582529385019390850190611647565b98975050505050505050565b6000806040838503121561167f57600080fd5b50508035926020909101359150565b6000602082840312156116a057600080fd5b81356001600160a01b03811681146104de57600080fd5b634e487b7160e01b600052601160045260246000fd5b6000826116ea57634e487b7160e01b600052601260045260246000fd5b500490565b6000816000190483118215151615611709576117096116b7565b500290565b634e487b7160e01b600052603260045260246000fd5b60008219821115611737576117376116b7565b500190565b60006001820161174e5761174e6116b7565b5060010190565b600082821015611767576117676116b7565b500390565b60006020828403121561177e57600080fd5b5051919050565b8051600f81900b811461179757600080fd5b919050565b6000608082840312156117ae57600080fd5b6040516080810181811067ffffffffffffffff821117156117d1576117d161157f565b6040526117dd83611785565b81526117eb60208401611785565b602082015260408301516040820152606083015160608201528091505092915050565b600081600f0b83600f0b60016001607f1b0360008213600084138383048511828216161561183e5761183e6116b7565b6f7fffffffffffffffffffffffffffffff19600085128281168783058712161561186a5761186a6116b7565b60008712925085820587128484161615611886576118866116b7565b8585058712818416161561189c5761189c6116b7565b5050509290910295945050505050565b600081600f0b83600f0b600081128160016001607f1b0319018312811516156118d7576118d76116b7565b8160016001607f1b030183138116156118f2576118f26116b7565b5090039392505050565b634e487b7160e01b600052600160045260246000fdfea2646970667358221220df39fa4149f6a026a6d05b7f018116456ad78482d46afe7b6da486093c631dbd64736f6c634300080d0033

Deployed Bytecode Sourcemap

15427:11456:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15760:23;;;;;;;;;160:25:1;;;148:2;133:18;15760:23:0;;;;;;;;15840:42;;;;;;:::i;:::-;;;;;;;;;;;;;;25865:826;;;;;;:::i;:::-;;:::i;:::-;;;1909:14:1;;1902:22;1884:41;;1872:2;1857:18;25865:826:0;1744:187:1;16041:30:0;;;;;;25359:498;;;;;;:::i;:::-;;:::i;15790:43::-;;;;;;:::i;:::-;;;;;;;;;;;;;;19304:492;;;;;;:::i;:::-;;:::i;15891:27::-;;;;;;18011:117;;;:::i;:::-;;15731:22;;;;;;20617:89;;;:::i;16585:105::-;;;:::i;16128:24::-;;;;;-1:-1:-1;;;;;16128:24:0;;;;;;-1:-1:-1;;;;;2353:32:1;;;2335:51;;2323:2;2308:18;16128:24:0;2189:203:1;25145:206:0;;;;;;:::i;:::-;;:::i;16080:39::-;;;;;;:::i;:::-;;:::i;15979:28::-;;;;;-1:-1:-1;;;;;15979:28:0;;;15925:45;;;;;;:::i;:::-;;:::i;26745:135::-;;;;;;:::i;:::-;;:::i;16014:20::-;;;;;-1:-1:-1;;;;;16014:20:0;;;25865:826;25928:4;25968:11;;25949:15;:30;25945:62;;25981:26;:24;:26::i;:::-;26042:15;;15713:9;26087:23;15713:9;26042:15;26087:23;:::i;:::-;:30;;;;:::i;:::-;26153:13;;26068:49;;-1:-1:-1;;;;;;26153:13:0;26128:22;;26204:376;26225:9;:16;26221:1;:20;26204:376;;;26263:13;26279:9;26289:1;26279:12;;;;;;;;:::i;:::-;;;;;;;26263:28;;26310:8;26322:1;26310:13;26306:24;;26325:5;;;26306:24;26345:11;26359:50;26366:8;26376:14;26392:16;26359:6;:50::i;:::-;26345:64;-1:-1:-1;26428:11:0;;26424:145;;26460:59;;-1:-1:-1;;;26460:59:0;;;;;3521:25:1;;;3562:18;;;3555:34;;;-1:-1:-1;;;;;26460:41:0;;;;;3494:18:1;;26460:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26547:6;26538:15;;;;;:::i;:::-;;;26424:145;26248:332;;26243:3;;;;;:::i;:::-;;;;26204:376;;;-1:-1:-1;26594:10:0;;26590:70;;26643:5;26621:18;;:27;;;;;;;:::i;:::-;;;;-1:-1:-1;;26590:70:0;-1:-1:-1;26679:4:0;;25865:826;-1:-1:-1;;;;25865:826:0:o;25359:498::-;25407:4;25447:11;;25428:15;:30;25424:62;;25460:26;:24;:26::i;:::-;25521:15;;15713:9;25566:23;15713:9;25521:15;25566:23;:::i;:::-;:30;;;;:::i;:::-;25638:13;;25547:49;;-1:-1:-1;25607:11:0;;25621:49;;25628:8;;-1:-1:-1;;;;;25638:13:0;25547:49;25621:6;:49::i;:::-;25607:63;-1:-1:-1;25685:11:0;;25681:145;;25727:13;;25713:58;;-1:-1:-1;;;25713:58:0;;;;;3521:25:1;;;3562:18;;;3555:34;;;-1:-1:-1;;;;;25727:13:0;;;;25713:40;;3494:18:1;;25713:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25808:6;25786:18;;:28;;;;;;;:::i;:::-;;;;-1:-1:-1;;25681:145:0;25843:6;25359:498;-1:-1:-1;;;25359:498:0:o;19304:492::-;19408:13;;19454:44;;-1:-1:-1;;;19454:44:0;;;;;160:25:1;;;19378:4:0;;-1:-1:-1;;;;;19408:13:0;;19378:4;;19408:13;;19454:34;;133:18:1;;19454:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;19432:66;;19509:10;19522:68;19549:2;19553:8;19563:10;19575:14;19522:26;:68::i;:::-;19633:53;;-1:-1:-1;;;19633:53:0;;;;;3521:25:1;;;3562:18;;;3555:34;;;19509:81:0;;-1:-1:-1;19601:29:0;;-1:-1:-1;;;;;19633:36:0;;;;;3494:18:1;;19633:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;19601:85;;19704:84;19774:2;:5;;;19761:10;:18;;;;:::i;:::-;19735:2;:8;;;:47;;;;:::i;:::-;19725:7;;:57;;;;:::i;:::-;19718:65;;19786:1;19704:8;:84::i;:::-;19697:91;19304:492;-1:-1:-1;;;;;;;19304:492:0:o;18011:117::-;18080:9;;-1:-1:-1;;;;;18080:9:0;18066:10;:23;18059:31;;;;:::i;:::-;18101:19;:17;:19::i;:::-;18011:117::o;20617:89::-;20672:26;:24;:26::i;16585:105::-;16629:4;15713:9;16653:22;15713:9;16653:15;:22;:::i;:::-;:29;;;;:::i;:::-;16646:36;;16585:105;:::o;25145:206::-;25202:4;25219:21;15713:9;;25243:15;;:22;;;;:::i;:::-;:29;;;;:::i;:::-;25311:13;;25219:53;;-1:-1:-1;25290:53:0;;25301:8;;-1:-1:-1;;;;;25311:13:0;25219:53;25290:10;:53::i;16080:39::-;;;;;;;;;;;;;;;-1:-1:-1;16080:39:0;:::o;15925:45::-;;;;;;;;;;;26745:135;26829:9;;-1:-1:-1;;;;;26829:9:0;26815:10;:23;26807:32;;;;;;26850:9;:22;;-1:-1:-1;;;;;;26850:22:0;-1:-1:-1;;;;;26850:22:0;;;;;;;;;;26745:135::o;19804:805::-;19873:13;;;19906:11;-1:-1:-1;;;;;19873:13:0;;;;19860:10;15713:9;19953:22;15713:9;19953:15;:22;:::i;:::-;:29;;;;:::i;:::-;19928:54;;20007:2;-1:-1:-1;;;;;19993:28:0;;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20041:6;20036:540;20057:2;20053:1;:6;20036:540;;;20089:17;20085:1;:21;20127:5;20081:460;20173:10;20186:28;20208:2;20212:1;20186:21;:28::i;:::-;20265:38;;-1:-1:-1;;;20265:38:0;;;;;160:25:1;;;20173:41:0;;-1:-1:-1;20233:29:0;;-1:-1:-1;;;;;20265:31:0;;;;;133:18:1;;20265:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;20233:70;;20322:9;20362:2;:5;;;20358:1;:9;20354:88;;;20415:5;;;;20411:9;;:1;:9;:::i;:::-;20392:30;;20354:88;20475:50;20517:2;20506;:8;;;:13;;;;:::i;:::-;20496:7;;:23;;;;:::i;20475:50::-;20460:9;20470:1;20460:12;;;;;;;:::i;:::-;;:65;-1:-1:-1;;;20555:9:0;15713;20555;;:::i;:::-;;-1:-1:-1;20061:3:0;;;;:::i;:::-;;;;20036:540;;;-1:-1:-1;;20586:11:0;:15;-1:-1:-1;19804:805:0:o;20714:2323::-;20902:44;;-1:-1:-1;;;20902:44:0;;;;;160:25:1;;;20798:4:0;;;;;;;;-1:-1:-1;;;;;20902:34:0;;;;;133:18:1;;20902:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;20957:16;20976:10;;20880:66;;-1:-1:-1;21003:19:0;;;20999:33;;21031:1;21024:8;;;;;;;;20999:33;21045:16;21064:24;;;:14;:24;;;;;;;21103:16;;;21099:200;;21149:69;21176:2;21180:8;21190:11;21203:14;21149:26;:69::i;:::-;21136:82;;21099:200;;;21264:23;;;;:13;:23;;;;;;;-1:-1:-1;21099:200:0;21315:10;21329:1;21315:15;21311:35;;21345:1;21332:14;;21311:35;21399:58;;-1:-1:-1;;;21399:58:0;;;;;3521:25:1;;;3562:18;;;3555:34;;;21359:37:0;;-1:-1:-1;;;;;21399:36:0;;;;;3494:18:1;;21399:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;21359:98;;21474:11;21489:1;21474:16;21470:76;;15713:9;;21530:1;15713:9;21507:10;:13;;;:20;;;;:::i;:::-;:24;;;;:::i;:::-;21506:33;;;;:::i;:::-;:40;;;;:::i;:::-;21492:54;;21470:76;21576:15;;21561:11;:30;21557:44;;21600:1;21593:8;;;;;;;;;;21557:44;21630:11;21616;:25;21612:56;;;21657:11;21643:25;;21612:56;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21735:1022:0;21756:2;21752:1;:6;21735:1022;;;21799:16;21784:11;:31;21780:42;21817:5;21780:42;21858:10;:13;;;21843:11;:28;;:60;;;;;21889:14;21875:10;:28;;21843:60;21839:907;;;21924:15;21938:1;21924:15;;:::i;:::-;;;21975:10;21958:27;;22021:14;22008:10;:27;22004:237;;;22073:28;;;;;;;;22093:1;22073:28;;;;;;22095:1;22073:28;;;;;;22097:1;22073:28;;;;22099:1;22073:28;;;22060:41;;21839:907;;22004:237;22163:58;;-1:-1:-1;;;22163:58:0;;;;;3521:25:1;;;3562:18;;;3555:34;;;-1:-1:-1;;;;;22163:36:0;;;;;3494:18:1;;22163:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;22150:71;;21839:907;;;22281:9;22321:14;:17;;;22307:11;:31;;;;:::i;:::-;22281:59;;22359:15;22377:74;22425:14;:20;;;22420:2;:25;;;;:::i;:::-;22398:19;;:47;;;;:::i;22377:74::-;22359:92;-1:-1:-1;22474:15:0;;:46;;;;;22506:14;22493:10;:27;22474:46;22470:57;;;22522:5;;;;22470:57;22550:15;;22546:147;;22651:9;22661:11;22651:22;;;;;;;:::i;:::-;;;22620:15;22636:11;22620:28;;;;;;;:::i;:::-;;;22607:41;;:10;:41;:::i;:::-;:66;;;;:::i;:::-;22590:83;;;;:::i;:::-;;;22546:147;22711:19;15713:9;22711:19;;:::i;:::-;;;22262:484;;21839:907;21760:3;;;;:::i;:::-;;;;21735:1022;;;-1:-1:-1;22782:40:0;22791:14;22807;22820:1;22807:10;:14;:::i;:::-;22782:8;:40::i;:::-;22833:23;;;;:13;:23;;;;;;;;:36;;;22880:14;:24;;;;;;:38;;;22936:60;;6501:25:1;;;6542:18;;;6535:34;;;6585:18;;;6578:34;;;6643:2;6628:18;;6621:34;;;22833:36:0;;-1:-1:-1;22936:60:0;;6488:3:1;6473:19;22936:60:0;;;;;;;-1:-1:-1;23016:13:0;;20714:2323;-1:-1:-1;;;;;;;;;20714:2323:0:o;18699:597::-;18822:4;;18875:14;18822:4;18900:367;18921:3;18917:1;:7;18900:367;;;18958:4;18950;:12;18946:23;18964:5;18946:23;18984:9;19016:1;18997:11;19004:4;18997;:11;:::i;:::-;:15;;19011:1;18997:15;:::i;:::-;18996:21;;;;:::i;:::-;19064:51;;-1:-1:-1;;;19064:51:0;;;;;3521:25:1;;;3562:18;;;3555:34;;;18984:33:0;;-1:-1:-1;19032:29:0;;-1:-1:-1;;;;;19064:36:0;;;;;3494:18:1;;19064:51:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;19032:83;;19143:10;19134:2;:5;;;:19;19130:126;;19181:4;19174:11;;19130:126;;;19233:7;19239:1;19233:4;:7;:::i;:::-;19226:14;;19130:126;18931:336;;18926:3;;;;;:::i;:::-;;;;18900:367;;;-1:-1:-1;19284:4:0;;18699:597;-1:-1:-1;;;;;;18699:597:0:o;433:106::-;491:7;522:1;518;:5;:13;;530:1;518:13;;;-1:-1:-1;526:1:0;;511:20;-1:-1:-1;433:106:0:o;16698:1305::-;16775:5;;16768:38;;-1:-1:-1;;;16768:38:0;;16800:4;16768:38;;;2335:51:1;16747:18:0;;-1:-1:-1;;;;;16775:5:0;;16768:23;;2308:18:1;;16768:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;16747:59;;16817:18;16854;;16838:13;:34;;;;:::i;:::-;16883:18;:34;;;16939:15;;16817:55;;-1:-1:-1;16930:6:0;16983:19;16939:15;16983;:19;:::i;:::-;17031:15;17013;:33;16965:37;-1:-1:-1;17057:14:0;15713:9;17074:8;15713:9;17074:1;:8;:::i;:::-;:15;;;;:::i;:::-;17057:32;;17100:14;17136:6;17131:802;17152:2;17148:1;:6;17131:802;;;17188:16;15713:9;17188;:16;:::i;:::-;17176:28;;17241:9;17223:15;:27;17219:639;;;17275:15;;:39;;;;;17313:1;17294:15;:20;17275:39;17271:260;;;17369:13;17339:15;17355:9;17339:26;;;;;;;:::i;:::-;;;:43;;;;;;;:::i;:::-;;;;-1:-1:-1;17549:5:0;;-1:-1:-1;17549:5:0;17271:260;17501:10;17478:19;17496:1;17478:15;:19;:::i;:::-;17461:37;;:13;:37;:::i;:::-;:50;;;;:::i;:::-;17431:15;17447:9;17431:26;;;;;;;:::i;17219:639::-;17599:15;;:33;;;;;17631:1;17618:9;:14;17599:33;17595:248;;;17687:13;17657:15;17673:9;17657:26;;;;;;;:::i;:::-;;;:43;;;;;;;:::i;:::-;;;;-1:-1:-1;17595:248:0;;-1:-1:-1;17595:248:0;;17813:10;17796:13;17808:1;17796:9;:13;:::i;:::-;17779:31;;:13;:31;:::i;:::-;:44;;;;:::i;:::-;17749:15;17765:9;17749:26;;;;;;;:::i;:::-;;;:74;;;;;;;:::i;:::-;;;;-1:-1:-1;;17595:248:0;17876:9;17872:13;;17912:9;17900:21;;17156:3;;;;;:::i;:::-;;;;17131:802;;;-1:-1:-1;17948:47:0;;;17964:15;3521:25:1;;3577:2;3562:18;;3555:34;;;17948:47:0;;3494:18:1;17948:47:0;;;;;;;16736:1267;;;;;;16698:1305::o;23045:2092::-;23242:44;;-1:-1:-1;;;23242:44:0;;;;;160:25:1;;;23138:4:0;;;;;;;;-1:-1:-1;;;;;23242:34:0;;;;;133:18:1;;23242:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;23297:16;23316:10;;23220:66;;-1:-1:-1;23343:19:0;;;23339:33;;23371:1;23364:8;;;;;;;;23339:33;23385:16;23404:24;;;:14;:24;;;;;;;23443:16;;;23439:200;;23489:69;23516:2;23520:8;23530:11;23543:14;23489:26;:69::i;:::-;23476:82;;23439:200;;;23604:23;;;;:13;:23;;;;;;;-1:-1:-1;23439:200:0;23655:10;23669:1;23655:15;23651:35;;23685:1;23672:14;;23651:35;23739:58;;-1:-1:-1;;;23739:58:0;;;;;3521:25:1;;;3562:18;;;3555:34;;;23699:37:0;;-1:-1:-1;;;;;23739:36:0;;;;;3494:18:1;;23739:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;23699:98;;23814:11;23829:1;23814:16;23810:76;;15713:9;;23870:1;15713:9;23847:10;:13;;;:20;;;;:::i;:::-;:24;;;;:::i;:::-;23846:33;;;;:::i;:::-;:40;;;;:::i;:::-;23832:54;;23810:76;23916:15;;23901:11;:30;23897:44;;23940:1;23933:8;;;;;;;;;;23897:44;23970:11;23956;:25;23952:56;;;23997:11;23983:25;;23952:56;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24075:1022:0;24096:2;24092:1;:6;24075:1022;;;24139:16;24124:11;:31;24120:42;24157:5;24120:42;24198:10;:13;;;24183:11;:28;;:60;;;;;24229:14;24215:10;:28;;24183:60;24179:907;;;24264:15;24278:1;24264:15;;:::i;:::-;;;24315:10;24298:27;;24361:14;24348:10;:27;24344:237;;;24413:28;;;;;;;;24433:1;24413:28;;;;;;24435:1;24413:28;;;;;;24437:1;24413:28;;;;24439:1;24413:28;;;24400:41;;24179:907;;24344:237;24503:58;;-1:-1:-1;;;24503:58:0;;;;;3521:25:1;;;3562:18;;;3555:34;;;-1:-1:-1;;;;;24503:36:0;;;;;3494:18:1;;24503:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;24490:71;;24179:907;;;24621:9;24661:14;:17;;;24647:11;:31;;;;:::i;:::-;24621:59;;24699:15;24717:74;24765:14;:20;;;24760:2;:25;;;;:::i;24717:74::-;24699:92;-1:-1:-1;24814:15:0;;:46;;;;;24846:14;24833:10;:27;24814:46;24810:57;;;24862:5;;;;24810:57;24890:15;;24886:147;;24991:9;25001:11;24991:22;;;;;;;:::i;:::-;;;24960:15;24976:11;24960:28;;;;;;;:::i;:::-;;;24947:41;;:10;:41;:::i;:::-;:66;;;;:::i;:::-;24930:83;;;;:::i;:::-;;;24886:147;25051:19;15713:9;25051:19;;:::i;:::-;;;24602:484;;24179:907;24100:3;;;;:::i;:::-;;;;24075:1022;;;-1:-1:-1;25116:13:0;;23045:2092;-1:-1:-1;;;;;;;;;;23045:2092:0:o;18136:555::-;18219:4;18236:9;18248:1;18236:13;;18260:9;18286:2;-1:-1:-1;;;;;18272:23:0;;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;18260:37;;18313:6;18308:354;18329:3;18325:1;:7;18308:354;;;18366:4;18358;:12;18354:23;18372:5;18354:23;18392:9;18424:1;18405:11;18412:4;18405;:11;:::i;:::-;:15;;18419:1;18405:15;:::i;:::-;18404:21;;;;:::i;:::-;18472:37;;-1:-1:-1;;;18472:37:0;;;;;160:25:1;;;18392:33:0;;-1:-1:-1;18440:29:0;;-1:-1:-1;;;;;18472:31:0;;;;;133:18:1;;18472:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;18440:69;;18537:10;18528:2;:5;;;:19;18524:127;;18575:4;18568:11;;18524:127;;;18627:8;18634:1;18627:4;:8;:::i;:::-;18620:15;;18524:127;18339:323;;18334:3;;;;;:::i;:::-;;;;18308:354;;;-1:-1:-1;18679:4:0;;18136:555;-1:-1:-1;;;;18136:555:0:o;615:106::-;673:7;704:1;700;:5;:13;;712:1;700:13;;196:180:1;255:6;308:2;296:9;287:7;283:23;279:32;276:52;;;324:1;321;314:12;276:52;-1:-1:-1;347:23:1;;196:180;-1:-1:-1;196:180:1:o;381:127::-;442:10;437:3;433:20;430:1;423:31;473:4;470:1;463:15;497:4;494:1;487:15;513:275;584:2;578:9;649:2;630:13;;-1:-1:-1;;626:27:1;614:40;;684:18;669:34;;705:22;;;666:62;663:88;;;731:18;;:::i;:::-;767:2;760:22;513:275;;-1:-1:-1;513:275:1:o;793:946::-;877:6;908:2;951;939:9;930:7;926:23;922:32;919:52;;;967:1;964;957:12;919:52;1007:9;994:23;1036:18;1077:2;1069:6;1066:14;1063:34;;;1093:1;1090;1083:12;1063:34;1131:6;1120:9;1116:22;1106:32;;1176:7;1169:4;1165:2;1161:13;1157:27;1147:55;;1198:1;1195;1188:12;1147:55;1234:2;1221:16;1256:2;1252;1249:10;1246:36;;;1262:18;;:::i;:::-;1308:2;1305:1;1301:10;1291:20;;1331:28;1355:2;1351;1347:11;1331:28;:::i;:::-;1393:15;;;1463:11;;;1459:20;;;1424:12;;;;1491:19;;;1488:39;;;1523:1;1520;1513:12;1488:39;1547:11;;;;1567:142;1583:6;1578:3;1575:15;1567:142;;;1649:17;;1637:30;;1600:12;;;;1687;;;;1567:142;;;1728:5;793:946;-1:-1:-1;;;;;;;;793:946:1:o;1936:248::-;2004:6;2012;2065:2;2053:9;2044:7;2040:23;2036:32;2033:52;;;2081:1;2078;2071:12;2033:52;-1:-1:-1;;2104:23:1;;;2174:2;2159:18;;;2146:32;;-1:-1:-1;1936:248:1:o;2397:286::-;2456:6;2509:2;2497:9;2488:7;2484:23;2480:32;2477:52;;;2525:1;2522;2515:12;2477:52;2551:23;;-1:-1:-1;;;;;2603:31:1;;2593:42;;2583:70;;2649:1;2646;2639:12;2688:127;2749:10;2744:3;2740:20;2737:1;2730:31;2780:4;2777:1;2770:15;2804:4;2801:1;2794:15;2820:217;2860:1;2886;2876:132;;2930:10;2925:3;2921:20;2918:1;2911:31;2965:4;2962:1;2955:15;2993:4;2990:1;2983:15;2876:132;-1:-1:-1;3022:9:1;;2820:217::o;3042:168::-;3082:7;3148:1;3144;3140:6;3136:14;3133:1;3130:21;3125:1;3118:9;3111:17;3107:45;3104:71;;;3155:18;;:::i;:::-;-1:-1:-1;3195:9:1;;3042:168::o;3215:127::-;3276:10;3271:3;3267:20;3264:1;3257:31;3307:4;3304:1;3297:15;3331:4;3328:1;3321:15;3600:128;3640:3;3671:1;3667:6;3664:1;3661:13;3658:39;;;3677:18;;:::i;:::-;-1:-1:-1;3713:9:1;;3600:128::o;3733:135::-;3772:3;3793:17;;;3790:43;;3813:18;;:::i;:::-;-1:-1:-1;3860:1:1;3849:13;;3733:135::o;3873:125::-;3913:4;3941:1;3938;3935:8;3932:34;;;3946:18;;:::i;:::-;-1:-1:-1;3983:9:1;;3873:125::o;4003:184::-;4073:6;4126:2;4114:9;4105:7;4101:23;4097:32;4094:52;;;4142:1;4139;4132:12;4094:52;-1:-1:-1;4165:16:1;;4003:184;-1:-1:-1;4003:184:1:o;4192:166::-;4270:13;;4323:2;4312:21;;;4302:32;;4292:60;;4348:1;4345;4338:12;4292:60;4192:166;;;:::o;4363:664::-;4455:6;4508:3;4496:9;4487:7;4483:23;4479:33;4476:53;;;4525:1;4522;4515:12;4476:53;4558:2;4552:9;4600:3;4592:6;4588:16;4670:6;4658:10;4655:22;4634:18;4622:10;4619:34;4616:62;4613:88;;;4681:18;;:::i;:::-;4717:2;4710:22;4756:39;4785:9;4756:39;:::i;:::-;4748:6;4741:55;4829:48;4873:2;4862:9;4858:18;4829:48;:::i;:::-;4824:2;4816:6;4812:15;4805:73;4932:2;4921:9;4917:18;4911:25;4906:2;4898:6;4894:15;4887:50;4991:2;4980:9;4976:18;4970:25;4965:2;4957:6;4953:15;4946:50;5015:6;5005:16;;;4363:664;;;;:::o;5032:698::-;5071:7;5119:1;5115:2;5104:17;5156:1;5152:2;5141:17;-1:-1:-1;;;;;5239:1:1;5234:3;5230:11;5269:1;5264:3;5260:11;5316:3;5312:2;5308:12;5303:3;5300:21;5295:2;5291;5287:11;5283:39;5280:65;;;5325:18;;:::i;:::-;-1:-1:-1;;5431:1:1;5422:11;;5449;;;5471:13;;;5462:23;;5445:41;5442:67;;;5489:18;;:::i;:::-;5537:1;5532:3;5528:11;5518:21;;5586:3;5582:2;5577:13;5572:3;5568:23;5563:2;5559;5555:11;5551:41;5548:67;;;5595:18;;:::i;:::-;5662:3;5658:2;5653:13;5648:3;5644:23;5639:2;5635;5631:11;5627:41;5624:67;;;5671:18;;:::i;:::-;-1:-1:-1;;;5711:13:1;;;;;5032:698;-1:-1:-1;;;;;5032:698:1:o;5735:398::-;5774:4;5819:1;5815:2;5804:17;5856:1;5852:2;5841:17;5886:1;5881:3;5877:11;5970:3;-1:-1:-1;;;;;5929:39:1;5925:49;5920:3;5916:59;5911:2;5904:10;5900:76;5897:102;;;5979:18;;:::i;:::-;6068:3;-1:-1:-1;;;;;6028:44:1;6023:3;6019:54;6015:2;6011:63;6008:89;;;6077:18;;:::i;:::-;-1:-1:-1;6114:13:1;;;5735:398;-1:-1:-1;;;5735:398:1:o;6138:127::-;6199:10;6194:3;6190:20;6187:1;6180:31;6230:4;6227:1;6220:15;6254:4;6251:1;6244:15

Swarm Source

ipfs://df39fa4149f6a026a6d05b7f018116456ad78482d46afe7b6da486093c631dbd

Block Transaction Gas Used Reward
view all blocks produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
[ Download: CSV Export  ]
[ 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.