S Price: $0.558294 (-7.39%)

Contract

0x0361a173dC338c32E57079b2c51cEf36f8A982f1

Overview

S Balance

Sonic LogoSonic LogoSonic Logo0 S

S Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Set Depositor22068232025-01-01 23:37:3085 days ago1735774650IN
0x0361a173...6f8A982f1
0 S0.000029611.1

Parent Transaction Hash Block From To
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
veArcDistributor

Compiler Version
v0.8.22+commit.4fc1097e

Optimization Enabled:
Yes with 10000 runs

Other Settings:
paris EvmVersion
File 1 of 4 : veArcDistributor.sol
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.22;

import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {IVotingEscrow} from "./interfaces/IVotingEscrow.sol";

/*

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

*/

contract veArcDistributor {

    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;
        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;
    }
}

File 2 of 4 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @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);
}

File 3 of 4 : Math.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @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);
        }
    }
}

File 4 of 4 : IVotingEscrow.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.22;

interface IVotingEscrow {

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

    function user_point_epoch(uint tokenId) external view returns (uint);
    function epoch() external view returns (uint);
    function user_point_history(uint tokenId, uint loc) external view returns (Point memory);
    function point_history(uint loc) external view returns (Point memory);
    function checkpoint() external;
    function deposit_for(uint tokenId, uint value) external;
    function token() external view returns (address);
    function user_point_history__ts(uint tokenId, uint idx) external view returns (uint);
    function locked__end(uint _tokenId) external view returns (uint);
    function locked__amount(uint _tokenId) external view returns (uint);
    function approve(address spender, uint tokenId) external;
    function balanceOfNFT(uint) external view returns (uint);
    function isApprovedOrOwner(address, uint) external view returns (bool);
    function ownerOf(uint) external view returns (address);
    function transferFrom(address, address, uint) external;
    function totalSupply() external view returns (uint);
    function supply() external view returns (uint);
    function create_lock_for(uint, uint, address) external returns (uint);
    function lockVote(uint tokenId) external;
    function isVoteExpired(uint tokenId) external view returns (bool);
    function voteExpiry(uint _tokenId) external view returns (uint);
    function attach(uint tokenId) external;
    function detach(uint tokenId) external;
    function voting(uint tokenId) external;
    function abstain(uint tokenId) external;
    function voted(uint tokenId) external view returns (bool);
    function withdraw(uint tokenId) external;
    function create_lock(uint value, uint duration) external returns (uint);
    function setVoter(address voter) external;
    function balanceOf(address owner) external view returns (uint);
    function safeTransferFrom(address from, address to, uint tokenId) external;
    function burn(uint _tokenId) external;
    function setAdmin(address _admin) external;
    function setArtProxy(address _proxy) external;
}

Settings
{
  "evmVersion": "paris",
  "optimizer": {
    "enabled": true,
    "runs": 10000
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

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"}]

60806040523480156200001157600080fd5b5060405162001e5738038062001e57833981016040819052620000349162000196565b600062093a80620000468142620001c8565b620000529190620001eb565b90508060008190555080600481905550806001819055506000826001600160a01b031663fc0c546a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000aa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000d0919062000196565b66038d7ea4c6800680546001600160a01b038381166001600160a01b0319928316811790935566038d7ea4c6800580549188169183168217905566071afd498d00088054909216331790915560405163095ea7b360e01b8152600481019190915260001960248201529192509063095ea7b3906044016020604051808303816000875af115801562000166573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200018c919062000217565b505050506200023b565b600060208284031215620001a957600080fd5b81516001600160a01b0381168114620001c157600080fd5b9392505050565b600082620001e657634e487b7160e01b600052601260045260246000fd5b500490565b80820281158282048414176200021157634e487b7160e01b600052601160045260246000fd5b92915050565b6000602082840312156200022a57600080fd5b81518015158114620001c157600080fd5b611c0c806200024b6000396000f3fe608060405234801561001057600080fd5b50600436106101515760003560e01c8063834ee417116100cd578063d4dafba811610081578063edf5999711610066578063edf59997146102cd578063f2c098b7146102e0578063fc0c546a146102f357600080fd5b8063d4dafba814610294578063dfe05031146102a757600080fd5b8063b80777ea116100b2578063b80777ea1461022e578063c7c4ff4614610236578063d1d58b251461028157600080fd5b8063834ee4171461021d578063b21ed5021461022657600080fd5b8063379607f511610124578063688098891161010957806368809889146101f75780637f58e8f81461020a578063811a40fe1461021357600080fd5b8063379607f5146101c4578063486d25fe146101d757600080fd5b8063127dcbd31461015657806316aea5c0146101725780631f1db0431461019257806322b04bfc146101b5575b600080fd5b61015f60015481565b6040519081526020015b60405180910390f35b61015f610180366004611825565b60036020526000908152604090205481565b6101a56101a03660046118bc565b610319565b6040519015158152602001610169565b61015f66038d7ea4c680075481565b61015f6101d2366004611825565b610487565b61015f6101e5366004611825565b60026020526000908152604090205481565b61015f610205366004611962565b6105a4565b61015f60045481565b61021b610735565b005b61015f60005481565b61021b61076c565b61015f610774565b66071afd498d00085461025c9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610169565b61015f61028f366004611825565b610793565b61015f6102a2366004611825565b6107e0565b66038d7ea4c680055461025c9073ffffffffffffffffffffffffffffffffffffffff1681565b61015f6102db366004611825565b610803565b61021b6102ee366004611984565b610819565b66038d7ea4c680065461025c9073ffffffffffffffffffffffffffffffffffffffff1681565b6000600154421061032c5761032c610890565b60045462093a8061033d81836119e9565b6103479190611a24565b66038d7ea4c680055490915073ffffffffffffffffffffffffffffffffffffffff166000805b855181101561045757600086828151811061038a5761038a611a3b565b60200260200101519050806000036103a25750610457565b60006103af828688610a69565b9050801561044d576040517fee99fe28000000000000000000000000000000000000000000000000000000008152600481018390526024810182905273ffffffffffffffffffffffffffffffffffffffff86169063ee99fe2890604401600060405180830381600087803b15801561042657600080fd5b505af115801561043a573d6000803e3d6000fd5b50505050808461044a9190611a6a565b93505b505060010161036d565b50801561047c578066038d7ea4c6800760008282546104769190611a7d565b90915550505b506001949350505050565b6000600154421061049a5761049a610890565b60045462093a806104ab81836119e9565b6104b59190611a24565b66038d7ea4c68005549091506000906104e690859073ffffffffffffffffffffffffffffffffffffffff1684610a69565b9050801561059d5766038d7ea4c68005546040517fee99fe28000000000000000000000000000000000000000000000000000000008152600481018690526024810183905273ffffffffffffffffffffffffffffffffffffffff9091169063ee99fe2890604401600060405180830381600087803b15801561056757600080fd5b505af115801561057b573d6000803e3d6000fd5b505050508066038d7ea4c6800760008282546105979190611a7d565b90915550505b9392505050565b66038d7ea4c68005546040517fe441135c0000000000000000000000000000000000000000000000000000000081526004810184905260009173ffffffffffffffffffffffffffffffffffffffff16908290829063e441135c90602401602060405180830381865afa15801561061e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106429190611a90565b9050600061065283878785610ef5565b6040517f1376f3da000000000000000000000000000000000000000000000000000000008152600481018890526024810182905290915060009073ffffffffffffffffffffffffffffffffffffffff851690631376f3da90604401608060405180830381865afa1580156106ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ee9190611ac0565b90506107288160400151876107039190611a7d565b82602001516107129190611b32565b825161071e9190611b59565b600f0b6000611004565b9450505050505b92915050565b66071afd498d00085473ffffffffffffffffffffffffffffffffffffffff16331461076257610762611ba7565b61076a61101a565b565b61076a610890565b600062093a8061078481426119e9565b61078e9190611a24565b905090565b60008062093a80806004546107a891906119e9565b6107b29190611a24565b66038d7ea4c680055490915061059d90849073ffffffffffffffffffffffffffffffffffffffff1683611294565b66038d7ea4c680088166038d7ea4c6800081106107fc57600080fd5b0154905081565b60058166038d7ea4c6800081106107fc57600080fd5b66071afd498d00085473ffffffffffffffffffffffffffffffffffffffff16331461084357600080fd5b66071afd498d000880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b66038d7ea4c680055460015473ffffffffffffffffffffffffffffffffffffffff90911690600062093a806108c581426119e9565b6108cf9190611a24565b90508273ffffffffffffffffffffffffffffffffffffffff1663c2c4c5c16040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561091957600080fd5b505af115801561092d573d6000803e3d6000fd5b5050505060005b6014811015610a6157818311610a615760006109508585611699565b6040517fd1febfb90000000000000000000000000000000000000000000000000000000081526004810182905290915060009073ffffffffffffffffffffffffffffffffffffffff87169063d1febfb990602401608060405180830381865afa1580156109c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109e59190611ac0565b905060008160400151861115610a07576040820151610a049087611a7d565b90505b610a26818360200151610a1a9190611b32565b835161071e9190611b59565b66038d7ea4c680088766038d7ea4c680008110610a4557610a45611a3b565b0155505050610a5762093a8084611a6a565b9250600101610934565b505060015550565b6040517fe441135c0000000000000000000000000000000000000000000000000000000081526004810184905260009081908190819073ffffffffffffffffffffffffffffffffffffffff87169063e441135c90602401602060405180830381865afa158015610add573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b019190611a90565b60008054919250829003610b1c57600094505050505061059d565b60008881526002602052604081205490819003610b4657610b3f888a8486610ef5565b9450610b58565b60008981526003602052604090205494505b84600003610b6557600194505b6040517f1376f3da000000000000000000000000000000000000000000000000000000008152600481018a90526024810186905260009073ffffffffffffffffffffffffffffffffffffffff8a1690631376f3da90604401608060405180830381865afa158015610bda573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bfe9190611ac0565b905081600003610c435762093a8080600162093a808460400151610c229190611a6a565b610c2c9190611a7d565b610c3691906119e9565b610c409190611a24565b91505b6004548210610c5b576000965050505050505061059d565b82821015610c67578291505b6040805160808101825260008082526020820181905291810182905260608101829052905b6032811015610e6a5789841015610e6a5782604001518410158015610cb15750858811155b15610d9d57610cc1600189611a6a565b975082915085881115610d005760405180608001604052806000600f0b81526020016000600f0b81526020016000815260200160008152509250610e62565b6040517f1376f3da000000000000000000000000000000000000000000000000000000008152600481018d90526024810189905273ffffffffffffffffffffffffffffffffffffffff8c1690631376f3da90604401608060405180830381865afa158015610d72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d969190611ac0565b9250610e62565b6000826040015185610daf9190611a7d565b90506000610dd2846020015183610dc69190611b32565b855161071e9190611b59565b905080158015610de15750878a115b15610ded575050610e6a565b8015610e505766038d7ea4c680088666038d7ea4c680008110610e1257610e12611a3b565b015460058766038d7ea4c680008110610e2d57610e2d611a3b565b0154610e399083611a24565b610e4391906119e9565b610e4d908a611a6a565b98505b610e5d62093a8087611a6a565b955050505b600101610c8c565b50610e7f85610e7a60018a611a7d565b611816565b60008c8152600360209081526040808320849055600282529182902086905581518e8152908101899052908101829052606081018790529097507fcae2990aa9af8eb1c64713b7eddb3a80bf18e49a94a13fe0d0002b5d61d58f009060800160405180910390a150939998505050505050505050565b60008082815b6080811015610ff85781831015610ff85760006002610f1a8486611a6a565b610f25906002611a6a565b610f2f91906119e9565b6040517f1376f3da000000000000000000000000000000000000000000000000000000008152600481018a90526024810182905290915060009073ffffffffffffffffffffffffffffffffffffffff8b1690631376f3da90604401608060405180830381865afa158015610fa7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fcb9190611ac0565b905087816040015111610fe057819450610fee565b610feb600183611a7d565b93505b5050600101610efb565b50909695505050505050565b6000818311611013578161059d565b5090919050565b66038d7ea4c68006546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561108f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110b39190611a90565b9050600066038d7ea4c6800754826110cb9190611a7d565b66038d7ea4c6800783905560045490915060006110e88242611a7d565b426004559050600062093a806110fe81856119e9565b6111089190611a24565b90506000805b60148110156112525761112462093a8084611a6a565b9150814210156111ad578315801561113b57508442145b15611175578560058466038d7ea4c68000811061115a5761115a611a3b565b01600082825461116a9190611a6a565b909155506112529050565b836111808642611a7d565b61118a9088611a24565b61119491906119e9565b60058466038d7ea4c68000811061115a5761115a611a3b565b831580156111ba57508482145b156111f4578560058466038d7ea4c6800081106111d9576111d9611a3b565b0160008282546111e99190611a6a565b909155506112429050565b836111ff8684611a7d565b6112099088611a24565b61121391906119e9565b60058466038d7ea4c68000811061122c5761122c611a3b565b01600082825461123c9190611a6a565b90915550505b909350839150819060010161110e565b5060408051428152602081018790527fce749457b74e10f393f2c6b1ce4261b78791376db5a3f501477a809f03f500d6910160405180910390a1505050505050565b6040517fe441135c0000000000000000000000000000000000000000000000000000000081526004810184905260009081908190819073ffffffffffffffffffffffffffffffffffffffff87169063e441135c90602401602060405180830381865afa158015611308573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061132c9190611a90565b6000805491925082900361134757600094505050505061059d565b600088815260026020526040812054908190036113715761136a888a8486610ef5565b9450611383565b60008981526003602052604090205494505b8460000361139057600194505b6040517f1376f3da000000000000000000000000000000000000000000000000000000008152600481018a90526024810186905260009073ffffffffffffffffffffffffffffffffffffffff8a1690631376f3da90604401608060405180830381865afa158015611405573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114299190611ac0565b90508160000361146e5762093a8080600162093a80846040015161144d9190611a6a565b6114579190611a7d565b61146191906119e9565b61146b9190611a24565b91505b6004548210611486576000965050505050505061059d565b82821015611492578291505b6040805160808101825260008082526020820181905291810182905260608101829052905b6032811015611689578984101561168957826040015184101580156114dc5750858811155b156115c8576114ec600189611a6a565b97508291508588111561152b5760405180608001604052806000600f0b81526020016000600f0b81526020016000815260200160008152509250611681565b6040517f1376f3da000000000000000000000000000000000000000000000000000000008152600481018d90526024810189905273ffffffffffffffffffffffffffffffffffffffff8c1690631376f3da90604401608060405180830381865afa15801561159d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115c19190611ac0565b9250611681565b60008260400151856115da9190611a7d565b905060006115f1846020015183610dc69190611b32565b9050801580156116005750878a115b1561160c575050611689565b801561166f5766038d7ea4c680088666038d7ea4c68000811061163157611631611a3b565b015460058766038d7ea4c68000811061164c5761164c611a3b565b01546116589083611a24565b61166291906119e9565b61166c908a611a6a565b98505b61167c62093a8087611a6a565b955050505b6001016114b7565b50949a9950505050505050505050565b6000806000905060008473ffffffffffffffffffffffffffffffffffffffff1663900cf0cf6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117119190611a90565b905060005b608081101561180c578183101561180c57600060026117358486611a6a565b611740906002611a6a565b61174a91906119e9565b6040517fd1febfb90000000000000000000000000000000000000000000000000000000081526004810182905290915060009073ffffffffffffffffffffffffffffffffffffffff89169063d1febfb990602401608060405180830381865afa1580156117bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117df9190611ac0565b9050868160400151116117f457819450611802565b6117ff600183611a7d565b93505b5050600101611716565b5090949350505050565b6000818310611013578161059d565b60006020828403121561183757600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156118b4576118b461183e565b604052919050565b600060208083850312156118cf57600080fd5b823567ffffffffffffffff808211156118e757600080fd5b818501915085601f8301126118fb57600080fd5b81358181111561190d5761190d61183e565b8060051b915061191e84830161186d565b818152918301840191848101908884111561193857600080fd5b938501935b838510156119565784358252938501939085019061193d565b98975050505050505050565b6000806040838503121561197557600080fd5b50508035926020909101359150565b60006020828403121561199657600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461059d57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082611a1f577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b808202811582820484141761072f5761072f6119ba565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8082018082111561072f5761072f6119ba565b8181038181111561072f5761072f6119ba565b600060208284031215611aa257600080fd5b5051919050565b8051600f81900b8114611abb57600080fd5b919050565b600060808284031215611ad257600080fd5b6040516080810181811067ffffffffffffffff82111715611af557611af561183e565b604052611b0183611aa9565b8152611b0f60208401611aa9565b602082015260408301516040820152606083015160608201528091505092915050565b600082600f0b82600f0b0280600f0b9150808214611b5257611b526119ba565b5092915050565b600f82810b9082900b037fffffffffffffffffffffffffffffffff8000000000000000000000000000000081126f7fffffffffffffffffffffffffffffff8213171561072f5761072f6119ba565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fdfea2646970667358221220a95f206ed6e3e0d07b78917375d6c1b46e66a027842695352def56ca5bd1303264736f6c634300081600330000000000000000000000006aca098fa93dad7a872f6dcb989f8b4a3afc3342

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101515760003560e01c8063834ee417116100cd578063d4dafba811610081578063edf5999711610066578063edf59997146102cd578063f2c098b7146102e0578063fc0c546a146102f357600080fd5b8063d4dafba814610294578063dfe05031146102a757600080fd5b8063b80777ea116100b2578063b80777ea1461022e578063c7c4ff4614610236578063d1d58b251461028157600080fd5b8063834ee4171461021d578063b21ed5021461022657600080fd5b8063379607f511610124578063688098891161010957806368809889146101f75780637f58e8f81461020a578063811a40fe1461021357600080fd5b8063379607f5146101c4578063486d25fe146101d757600080fd5b8063127dcbd31461015657806316aea5c0146101725780631f1db0431461019257806322b04bfc146101b5575b600080fd5b61015f60015481565b6040519081526020015b60405180910390f35b61015f610180366004611825565b60036020526000908152604090205481565b6101a56101a03660046118bc565b610319565b6040519015158152602001610169565b61015f66038d7ea4c680075481565b61015f6101d2366004611825565b610487565b61015f6101e5366004611825565b60026020526000908152604090205481565b61015f610205366004611962565b6105a4565b61015f60045481565b61021b610735565b005b61015f60005481565b61021b61076c565b61015f610774565b66071afd498d00085461025c9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610169565b61015f61028f366004611825565b610793565b61015f6102a2366004611825565b6107e0565b66038d7ea4c680055461025c9073ffffffffffffffffffffffffffffffffffffffff1681565b61015f6102db366004611825565b610803565b61021b6102ee366004611984565b610819565b66038d7ea4c680065461025c9073ffffffffffffffffffffffffffffffffffffffff1681565b6000600154421061032c5761032c610890565b60045462093a8061033d81836119e9565b6103479190611a24565b66038d7ea4c680055490915073ffffffffffffffffffffffffffffffffffffffff166000805b855181101561045757600086828151811061038a5761038a611a3b565b60200260200101519050806000036103a25750610457565b60006103af828688610a69565b9050801561044d576040517fee99fe28000000000000000000000000000000000000000000000000000000008152600481018390526024810182905273ffffffffffffffffffffffffffffffffffffffff86169063ee99fe2890604401600060405180830381600087803b15801561042657600080fd5b505af115801561043a573d6000803e3d6000fd5b50505050808461044a9190611a6a565b93505b505060010161036d565b50801561047c578066038d7ea4c6800760008282546104769190611a7d565b90915550505b506001949350505050565b6000600154421061049a5761049a610890565b60045462093a806104ab81836119e9565b6104b59190611a24565b66038d7ea4c68005549091506000906104e690859073ffffffffffffffffffffffffffffffffffffffff1684610a69565b9050801561059d5766038d7ea4c68005546040517fee99fe28000000000000000000000000000000000000000000000000000000008152600481018690526024810183905273ffffffffffffffffffffffffffffffffffffffff9091169063ee99fe2890604401600060405180830381600087803b15801561056757600080fd5b505af115801561057b573d6000803e3d6000fd5b505050508066038d7ea4c6800760008282546105979190611a7d565b90915550505b9392505050565b66038d7ea4c68005546040517fe441135c0000000000000000000000000000000000000000000000000000000081526004810184905260009173ffffffffffffffffffffffffffffffffffffffff16908290829063e441135c90602401602060405180830381865afa15801561061e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106429190611a90565b9050600061065283878785610ef5565b6040517f1376f3da000000000000000000000000000000000000000000000000000000008152600481018890526024810182905290915060009073ffffffffffffffffffffffffffffffffffffffff851690631376f3da90604401608060405180830381865afa1580156106ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ee9190611ac0565b90506107288160400151876107039190611a7d565b82602001516107129190611b32565b825161071e9190611b59565b600f0b6000611004565b9450505050505b92915050565b66071afd498d00085473ffffffffffffffffffffffffffffffffffffffff16331461076257610762611ba7565b61076a61101a565b565b61076a610890565b600062093a8061078481426119e9565b61078e9190611a24565b905090565b60008062093a80806004546107a891906119e9565b6107b29190611a24565b66038d7ea4c680055490915061059d90849073ffffffffffffffffffffffffffffffffffffffff1683611294565b66038d7ea4c680088166038d7ea4c6800081106107fc57600080fd5b0154905081565b60058166038d7ea4c6800081106107fc57600080fd5b66071afd498d00085473ffffffffffffffffffffffffffffffffffffffff16331461084357600080fd5b66071afd498d000880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b66038d7ea4c680055460015473ffffffffffffffffffffffffffffffffffffffff90911690600062093a806108c581426119e9565b6108cf9190611a24565b90508273ffffffffffffffffffffffffffffffffffffffff1663c2c4c5c16040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561091957600080fd5b505af115801561092d573d6000803e3d6000fd5b5050505060005b6014811015610a6157818311610a615760006109508585611699565b6040517fd1febfb90000000000000000000000000000000000000000000000000000000081526004810182905290915060009073ffffffffffffffffffffffffffffffffffffffff87169063d1febfb990602401608060405180830381865afa1580156109c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109e59190611ac0565b905060008160400151861115610a07576040820151610a049087611a7d565b90505b610a26818360200151610a1a9190611b32565b835161071e9190611b59565b66038d7ea4c680088766038d7ea4c680008110610a4557610a45611a3b565b0155505050610a5762093a8084611a6a565b9250600101610934565b505060015550565b6040517fe441135c0000000000000000000000000000000000000000000000000000000081526004810184905260009081908190819073ffffffffffffffffffffffffffffffffffffffff87169063e441135c90602401602060405180830381865afa158015610add573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b019190611a90565b60008054919250829003610b1c57600094505050505061059d565b60008881526002602052604081205490819003610b4657610b3f888a8486610ef5565b9450610b58565b60008981526003602052604090205494505b84600003610b6557600194505b6040517f1376f3da000000000000000000000000000000000000000000000000000000008152600481018a90526024810186905260009073ffffffffffffffffffffffffffffffffffffffff8a1690631376f3da90604401608060405180830381865afa158015610bda573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bfe9190611ac0565b905081600003610c435762093a8080600162093a808460400151610c229190611a6a565b610c2c9190611a7d565b610c3691906119e9565b610c409190611a24565b91505b6004548210610c5b576000965050505050505061059d565b82821015610c67578291505b6040805160808101825260008082526020820181905291810182905260608101829052905b6032811015610e6a5789841015610e6a5782604001518410158015610cb15750858811155b15610d9d57610cc1600189611a6a565b975082915085881115610d005760405180608001604052806000600f0b81526020016000600f0b81526020016000815260200160008152509250610e62565b6040517f1376f3da000000000000000000000000000000000000000000000000000000008152600481018d90526024810189905273ffffffffffffffffffffffffffffffffffffffff8c1690631376f3da90604401608060405180830381865afa158015610d72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d969190611ac0565b9250610e62565b6000826040015185610daf9190611a7d565b90506000610dd2846020015183610dc69190611b32565b855161071e9190611b59565b905080158015610de15750878a115b15610ded575050610e6a565b8015610e505766038d7ea4c680088666038d7ea4c680008110610e1257610e12611a3b565b015460058766038d7ea4c680008110610e2d57610e2d611a3b565b0154610e399083611a24565b610e4391906119e9565b610e4d908a611a6a565b98505b610e5d62093a8087611a6a565b955050505b600101610c8c565b50610e7f85610e7a60018a611a7d565b611816565b60008c8152600360209081526040808320849055600282529182902086905581518e8152908101899052908101829052606081018790529097507fcae2990aa9af8eb1c64713b7eddb3a80bf18e49a94a13fe0d0002b5d61d58f009060800160405180910390a150939998505050505050505050565b60008082815b6080811015610ff85781831015610ff85760006002610f1a8486611a6a565b610f25906002611a6a565b610f2f91906119e9565b6040517f1376f3da000000000000000000000000000000000000000000000000000000008152600481018a90526024810182905290915060009073ffffffffffffffffffffffffffffffffffffffff8b1690631376f3da90604401608060405180830381865afa158015610fa7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fcb9190611ac0565b905087816040015111610fe057819450610fee565b610feb600183611a7d565b93505b5050600101610efb565b50909695505050505050565b6000818311611013578161059d565b5090919050565b66038d7ea4c68006546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561108f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110b39190611a90565b9050600066038d7ea4c6800754826110cb9190611a7d565b66038d7ea4c6800783905560045490915060006110e88242611a7d565b426004559050600062093a806110fe81856119e9565b6111089190611a24565b90506000805b60148110156112525761112462093a8084611a6a565b9150814210156111ad578315801561113b57508442145b15611175578560058466038d7ea4c68000811061115a5761115a611a3b565b01600082825461116a9190611a6a565b909155506112529050565b836111808642611a7d565b61118a9088611a24565b61119491906119e9565b60058466038d7ea4c68000811061115a5761115a611a3b565b831580156111ba57508482145b156111f4578560058466038d7ea4c6800081106111d9576111d9611a3b565b0160008282546111e99190611a6a565b909155506112429050565b836111ff8684611a7d565b6112099088611a24565b61121391906119e9565b60058466038d7ea4c68000811061122c5761122c611a3b565b01600082825461123c9190611a6a565b90915550505b909350839150819060010161110e565b5060408051428152602081018790527fce749457b74e10f393f2c6b1ce4261b78791376db5a3f501477a809f03f500d6910160405180910390a1505050505050565b6040517fe441135c0000000000000000000000000000000000000000000000000000000081526004810184905260009081908190819073ffffffffffffffffffffffffffffffffffffffff87169063e441135c90602401602060405180830381865afa158015611308573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061132c9190611a90565b6000805491925082900361134757600094505050505061059d565b600088815260026020526040812054908190036113715761136a888a8486610ef5565b9450611383565b60008981526003602052604090205494505b8460000361139057600194505b6040517f1376f3da000000000000000000000000000000000000000000000000000000008152600481018a90526024810186905260009073ffffffffffffffffffffffffffffffffffffffff8a1690631376f3da90604401608060405180830381865afa158015611405573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114299190611ac0565b90508160000361146e5762093a8080600162093a80846040015161144d9190611a6a565b6114579190611a7d565b61146191906119e9565b61146b9190611a24565b91505b6004548210611486576000965050505050505061059d565b82821015611492578291505b6040805160808101825260008082526020820181905291810182905260608101829052905b6032811015611689578984101561168957826040015184101580156114dc5750858811155b156115c8576114ec600189611a6a565b97508291508588111561152b5760405180608001604052806000600f0b81526020016000600f0b81526020016000815260200160008152509250611681565b6040517f1376f3da000000000000000000000000000000000000000000000000000000008152600481018d90526024810189905273ffffffffffffffffffffffffffffffffffffffff8c1690631376f3da90604401608060405180830381865afa15801561159d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115c19190611ac0565b9250611681565b60008260400151856115da9190611a7d565b905060006115f1846020015183610dc69190611b32565b9050801580156116005750878a115b1561160c575050611689565b801561166f5766038d7ea4c680088666038d7ea4c68000811061163157611631611a3b565b015460058766038d7ea4c68000811061164c5761164c611a3b565b01546116589083611a24565b61166291906119e9565b61166c908a611a6a565b98505b61167c62093a8087611a6a565b955050505b6001016114b7565b50949a9950505050505050505050565b6000806000905060008473ffffffffffffffffffffffffffffffffffffffff1663900cf0cf6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117119190611a90565b905060005b608081101561180c578183101561180c57600060026117358486611a6a565b611740906002611a6a565b61174a91906119e9565b6040517fd1febfb90000000000000000000000000000000000000000000000000000000081526004810182905290915060009073ffffffffffffffffffffffffffffffffffffffff89169063d1febfb990602401608060405180830381865afa1580156117bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117df9190611ac0565b9050868160400151116117f457819450611802565b6117ff600183611a7d565b93505b5050600101611716565b5090949350505050565b6000818310611013578161059d565b60006020828403121561183757600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156118b4576118b461183e565b604052919050565b600060208083850312156118cf57600080fd5b823567ffffffffffffffff808211156118e757600080fd5b818501915085601f8301126118fb57600080fd5b81358181111561190d5761190d61183e565b8060051b915061191e84830161186d565b818152918301840191848101908884111561193857600080fd5b938501935b838510156119565784358252938501939085019061193d565b98975050505050505050565b6000806040838503121561197557600080fd5b50508035926020909101359150565b60006020828403121561199657600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461059d57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082611a1f577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b808202811582820484141761072f5761072f6119ba565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8082018082111561072f5761072f6119ba565b8181038181111561072f5761072f6119ba565b600060208284031215611aa257600080fd5b5051919050565b8051600f81900b8114611abb57600080fd5b919050565b600060808284031215611ad257600080fd5b6040516080810181811067ffffffffffffffff82111715611af557611af561183e565b604052611b0183611aa9565b8152611b0f60208401611aa9565b602082015260408301516040820152606083015160608201528091505092915050565b600082600f0b82600f0b0280600f0b9150808214611b5257611b526119ba565b5092915050565b600f82810b9082900b037fffffffffffffffffffffffffffffffff8000000000000000000000000000000081126f7fffffffffffffffffffffffffffffff8213171561072f5761072f6119ba565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fdfea2646970667358221220a95f206ed6e3e0d07b78917375d6c1b46e66a027842695352def56ca5bd1303264736f6c63430008160033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000006aca098fa93dad7a872f6dcb989f8b4a3afc3342

-----Decoded View---------------
Arg [0] : _voting_escrow (address): 0x6ACa098fa93DAD7A872F6dcb989F8b4A3aFC3342

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000006aca098fa93dad7a872f6dcb989f8b4a3afc3342


Block Transaction Gas Used Reward
view all blocks ##produced##

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

Validator Index Block Amount
View All Withdrawals

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