APE Price: $1.12 (-3.63%)

Contract

0xB3B9c7170C51b1ffF01251e54aA7607b86a1762f

Overview

APE Balance

Apechain LogoApechain LogoApechain Logo0 APE

APE Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Deposit With Dis...83281952025-01-17 17:52:4713 hrs ago1737136367IN
0xB3B9c717...b86a1762f
3 APE0.0099189225.42069
Deposit81392662025-01-14 1:35:244 days ago1736818524IN
0xB3B9c717...b86a1762f
103.81 APE0.0027780725.42069
Deposit81208602025-01-13 18:52:504 days ago1736794370IN
0xB3B9c717...b86a1762f
42 APE0.003125825.42069
Deposit81207872025-01-13 18:51:264 days ago1736794286IN
0xB3B9c717...b86a1762f
42 APE0.003125825.42069
Deposit81206262025-01-13 18:48:334 days ago1736794113IN
0xB3B9c717...b86a1762f
42 APE0.003125825.42069
Deposit81041462025-01-13 13:53:094 days ago1736776389IN
0xB3B9c717...b86a1762f
93 APE0.003125825.42069
Deposit80233172025-01-12 5:53:106 days ago1736661190IN
0xB3B9c717...b86a1762f
100 APE0.0031258225.42069
Deposit With Dis...80191052025-01-12 3:58:376 days ago1736654317IN
0xB3B9c717...b86a1762f
2,000 APE0.0099183125.42069
Deposit79439882025-01-11 3:21:407 days ago1736565700IN
0xB3B9c717...b86a1762f
1,000 APE0.0027780725.42069
Deposit78359142025-01-09 19:06:018 days ago1736449561IN
0xB3B9c717...b86a1762f
830 APE0.0031258225.42069
Deposit With Dis...77920692025-01-09 1:58:069 days ago1736387886IN
0xB3B9c717...b86a1762f
18.1 APE0.0098477225.42069
Deposit77728442025-01-08 18:46:299 days ago1736361989IN
0xB3B9c717...b86a1762f
200 APE0.0027780725.42069
Deposit77348832025-01-08 2:56:0310 days ago1736304963IN
0xB3B9c717...b86a1762f
10 APE0.0031258225.42069
Deposit76891562025-01-07 11:15:0210 days ago1736248502IN
0xB3B9c717...b86a1762f
15 APE0.0027780725.42069
Deposit76856472025-01-07 9:08:3810 days ago1736240918IN
0xB3B9c717...b86a1762f
778 APE0.0027780725.42069
Deposit76078442025-01-05 20:42:5712 days ago1736109777IN
0xB3B9c717...b86a1762f
72 APE0.0027778225.42069
Deposit75698062025-01-05 3:12:1513 days ago1736046735IN
0xB3B9c717...b86a1762f
200 APE0.0027780725.42069
Deposit75463282025-01-04 15:58:2513 days ago1736006305IN
0xB3B9c717...b86a1762f
400 APE0.0031258225.42069
Deposit With Dis...75346472025-01-04 8:25:2913 days ago1735979129IN
0xB3B9c717...b86a1762f
1 APE0.0099189225.42069
Deposit75343182025-01-04 8:05:4513 days ago1735977945IN
0xB3B9c717...b86a1762f
1.4 APE0.0031258225.42069
Deposit With Dis...75342952025-01-04 8:04:3413 days ago1735977874IN
0xB3B9c717...b86a1762f
2 APE0.0098471325.42069
Deposit75275772025-01-04 3:17:5514 days ago1735960675IN
0xB3B9c717...b86a1762f
10,000 APE0.0027780725.42069
Deposit74966742025-01-03 15:32:5214 days ago1735918372IN
0xB3B9c717...b86a1762f
21.5 APE0.0027780425.42069
Deposit74893952025-01-03 11:21:2714 days ago1735903287IN
0xB3B9c717...b86a1762f
8.5 APE0.003125825.42069
Deposit74884162025-01-03 10:50:5014 days ago1735901450IN
0xB3B9c717...b86a1762f
318 APE0.0031258225.42069
View all transactions

Latest 25 internal transactions (View All)

Parent Transaction Hash Block From To
83281952025-01-17 17:52:4713 hrs ago1737136367
0xB3B9c717...b86a1762f
3 APE
81392662025-01-14 1:35:244 days ago1736818524
0xB3B9c717...b86a1762f
103.81 APE
81208602025-01-13 18:52:504 days ago1736794370
0xB3B9c717...b86a1762f
42 APE
81207872025-01-13 18:51:264 days ago1736794286
0xB3B9c717...b86a1762f
42 APE
81206262025-01-13 18:48:334 days ago1736794113
0xB3B9c717...b86a1762f
42 APE
81041462025-01-13 13:53:094 days ago1736776389
0xB3B9c717...b86a1762f
93 APE
80233172025-01-12 5:53:106 days ago1736661190
0xB3B9c717...b86a1762f
100 APE
80191052025-01-12 3:58:376 days ago1736654317
0xB3B9c717...b86a1762f
2,000 APE
79439882025-01-11 3:21:407 days ago1736565700
0xB3B9c717...b86a1762f
1,000 APE
78359142025-01-09 19:06:018 days ago1736449561
0xB3B9c717...b86a1762f
830 APE
77920692025-01-09 1:58:069 days ago1736387886
0xB3B9c717...b86a1762f
18.1 APE
77728442025-01-08 18:46:299 days ago1736361989
0xB3B9c717...b86a1762f
200 APE
77348832025-01-08 2:56:0310 days ago1736304963
0xB3B9c717...b86a1762f
10 APE
76891562025-01-07 11:15:0210 days ago1736248502
0xB3B9c717...b86a1762f
15 APE
76856472025-01-07 9:08:3810 days ago1736240918
0xB3B9c717...b86a1762f
778 APE
76078442025-01-05 20:42:5712 days ago1736109777
0xB3B9c717...b86a1762f
72 APE
75698062025-01-05 3:12:1513 days ago1736046735
0xB3B9c717...b86a1762f
200 APE
75463282025-01-04 15:58:2513 days ago1736006305
0xB3B9c717...b86a1762f
400 APE
75346472025-01-04 8:25:2913 days ago1735979129
0xB3B9c717...b86a1762f
1 APE
75343182025-01-04 8:05:4513 days ago1735977945
0xB3B9c717...b86a1762f
1.4 APE
75342952025-01-04 8:04:3413 days ago1735977874
0xB3B9c717...b86a1762f
2 APE
75275772025-01-04 3:17:5514 days ago1735960675
0xB3B9c717...b86a1762f
10,000 APE
74966742025-01-03 15:32:5214 days ago1735918372
0xB3B9c717...b86a1762f
21.5 APE
74893952025-01-03 11:21:2714 days ago1735903287
0xB3B9c717...b86a1762f
8.5 APE
74884162025-01-03 10:50:5014 days ago1735901450
0xB3B9c717...b86a1762f
318 APE
View All Internal Transactions

Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
NativeDepositor

Compiler Version
v0.8.23+commit.f704f362

Optimization Enabled:
Yes with 800 runs

Other Settings:
paris EvmVersion
File 1 of 9 : NativeDepositor.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

import "../interfaces/IGTokenExtended.sol";
import "../interfaces/IWETH9.sol";
import "../interfaces/IGeneralErrors.sol";

import "../libraries/ChainUtils.sol";

/**
 * @dev GToken depositor helper. Accepts native tokens, wraps them and deposits them for msg.sender
 */
contract NativeDepositor {
    receive() external payable {}

    function validateRequest(
        IGTokenExtended _gToken,
        uint256 _value,
        address _receiver
    ) public view returns (address asset) {
        if (address(_gToken) == address(0) || _receiver == address(0)) revert IGeneralErrors.ZeroAddress();
        if (_value == 0) revert IGeneralErrors.ZeroValue();

        asset = _gToken.asset();

        if (!ChainUtils.isWrappedNativeToken(asset)) revert IGeneralErrors.InvalidAddress();
    }

    /**
     * @dev Accepts native payment, wraps native token and deposits value for `_receiver`
     * @param _gToken the gToken address
     * @param _receiver the address receiving the gTokens
     */
    function deposit(IGTokenExtended _gToken, address _receiver) external payable returns (uint256 shares) {
        IWETH9 asset = IWETH9(validateRequest(_gToken, msg.value, _receiver));

        asset.deposit{value: msg.value}();
        asset.approve(address(_gToken), msg.value);

        return _gToken.deposit(msg.value, _receiver);
    }

    /**
     * @dev Accepts native payment, wraps native token and deposits value for `_receiver` with discount and lock
     * @param _gToken the gToken address
     * @param _lockDuration the duration of the lock
     * @param _receiver the address receiving the gTokens
     */
    function depositWithDiscountAndLock(
        IGTokenExtended _gToken,
        uint256 _lockDuration,
        address _receiver
    ) external payable returns (uint256 shares) {
        IWETH9 asset = IWETH9(validateRequest(_gToken, msg.value, _receiver));

        asset.deposit{value: msg.value}();
        asset.approve(address(_gToken), msg.value);

        return _gToken.depositWithDiscountAndLock(msg.value, _lockDuration, _receiver);
    }
}

File 2 of 9 : 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 3 of 9 : IArbSys.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

/**
 * @dev Interface for Arbitrum special l2 functions
 */
interface IArbSys {
    function arbBlockNumber() external view returns (uint256);
}

File 4 of 9 : IGeneralErrors.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

/**
 * @dev Interface for errors potentially used in all libraries (general names)
 */
interface IGeneralErrors {
    error InitError();
    error InvalidAddresses();
    error InvalidAddress();
    error InvalidInputLength();
    error InvalidCollateralIndex();
    error WrongParams();
    error WrongLength();
    error WrongOrder();
    error WrongIndex();
    error BlockOrder();
    error Overflow();
    error ZeroAddress();
    error ZeroValue();
    error AlreadyExists();
    error DoesntExist();
    error Paused();
    error BelowMin();
    error AboveMax();
    error NotAuthorized();
    error WrongTradeType();
    error WrongOrderType();
    error InsufficientBalance();
    error UnsupportedChain();
}

File 5 of 9 : IGToken.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

/**
 * @dev Interface for GToken contract
 */
interface IGToken {
    struct GnsPriceProvider {
        address addr;
        bytes signature;
    }

    struct LockedDeposit {
        address owner;
        uint256 shares; // collateralConfig.precision
        uint256 assetsDeposited; // collateralConfig.precision
        uint256 assetsDiscount; // collateralConfig.precision
        uint256 atTimestamp; // timestamp
        uint256 lockDuration; // timestamp
    }

    struct ContractAddresses {
        address asset;
        address owner; // 2-week timelock contract
        address manager; // 3-day timelock contract
        address admin; // bypasses timelock, access to emergency functions
        address gnsToken;
        address lockedDepositNft;
        address pnlHandler;
        address openTradesPnlFeed;
        GnsPriceProvider gnsPriceProvider;
    }

    struct Meta {
        string name;
        string symbol;
    }

    function manager() external view returns (address);

    function admin() external view returns (address);

    function currentEpoch() external view returns (uint256);

    function currentEpochStart() external view returns (uint256);

    function currentEpochPositiveOpenPnl() external view returns (uint256);

    function updateAccPnlPerTokenUsed(
        uint256 prevPositiveOpenPnl,
        uint256 newPositiveOpenPnl
    ) external returns (uint256);

    function getLockedDeposit(uint256 depositId) external view returns (LockedDeposit memory);

    function sendAssets(uint256 assets, address receiver) external;

    function receiveAssets(uint256 assets, address user) external;

    function distributeReward(uint256 assets) external;

    function tvl() external view returns (uint256);

    function marketCap() external view returns (uint256);

    function shareToAssetsPrice() external view returns (uint256);

    function collateralConfig() external view returns (uint128, uint128);

    event ManagerUpdated(address newValue);
    event AdminUpdated(address newValue);
    event PnlHandlerUpdated(address newValue);
    event OpenTradesPnlFeedUpdated(address newValue);
    event GnsPriceProviderUpdated(GnsPriceProvider newValue);
    event WithdrawLockThresholdsPUpdated(uint256[2] newValue);
    event MaxAccOpenPnlDeltaUpdated(uint256 newValue);
    event MaxDailyAccPnlDeltaUpdated(uint256 newValue);
    event MaxSupplyIncreaseDailyPUpdated(uint256 newValue);
    event LossesBurnPUpdated(uint256 newValue);
    event MaxGnsSupplyMintDailyPUpdated(uint256 newValue);
    event MaxDiscountPUpdated(uint256 newValue);
    event MaxDiscountThresholdPUpdated(uint256 newValue);

    event CurrentMaxSupplyUpdated(uint256 newValue);
    event DailyAccPnlDeltaReset();
    event ShareToAssetsPriceUpdated(uint256 newValue);
    event OpenTradesPnlFeedCallFailed();

    event WithdrawRequested(
        address indexed sender,
        address indexed owner,
        uint256 shares,
        uint256 currEpoch,
        uint256 indexed unlockEpoch
    );
    event WithdrawCanceled(
        address indexed sender,
        address indexed owner,
        uint256 shares,
        uint256 currEpoch,
        uint256 indexed unlockEpoch
    );

    event DepositLocked(address indexed sender, address indexed owner, uint256 depositId, LockedDeposit d);
    event DepositUnlocked(
        address indexed sender,
        address indexed receiver,
        address indexed owner,
        uint256 depositId,
        LockedDeposit d
    );

    event RewardDistributed(address indexed sender, uint256 assets);

    event AssetsSent(address indexed sender, address indexed receiver, uint256 assets);
    event AssetsReceived(address indexed sender, address indexed user, uint256 assets, uint256 assetsLessDeplete);

    event Depleted(address indexed sender, uint256 assets, uint256 amountGns);
    event Refilled(address indexed sender, uint256 assets, uint256 amountGns);

    event AccPnlPerTokenUsedUpdated(
        address indexed sender,
        uint256 indexed newEpoch,
        uint256 prevPositiveOpenPnl,
        uint256 newPositiveOpenPnl,
        uint256 newEpochPositiveOpenPnl,
        int256 newAccPnlPerTokenUsed
    );

    error OnlyManager();
    error OnlyTradingPnlHandler();
    error OnlyPnlFeed();
    error AddressZero();
    error PriceZero();
    error ValueZero();
    error BytesZero();
    error NoActiveDiscount();
    error BelowMin();
    error AboveMax();
    error WrongValue();
    error WrongValues();
    error GnsPriceCallFailed();
    error GnsTokenPriceZero();
    error PendingWithdrawal();
    error EndOfEpoch();
    error NotAllowed();
    error NoDiscount();
    error NotUnlocked();
    error NotEnoughAssets();
    error MaxDailyPnl();
    error NotUnderCollateralized();
    error AboveInflationLimit();

    // Ownable
    error OwnableInvalidOwner(address owner);

    // ERC4626
    error ERC4626ExceededMaxDeposit();
    error ERC4626ExceededMaxMint();
    error ERC4626ExceededMaxWithdraw();
    error ERC4626ExceededMaxRedeem();
}

File 6 of 9 : IGTokenExtended.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

import "./IGToken.sol";
/**
 * @dev Extended interface for GToken contract
 */
interface IGTokenExtended is IGToken {
    function asset() external view returns (address);
    function deposit(uint256 assets, address receiver) external returns (uint256);
    function depositWithDiscountAndLock(
        uint256 assets,
        uint256 lockDuration,
        address receiver
    ) external returns (uint256);
}

File 7 of 9 : IWETH9.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

/**
 * @dev Interface for WETH9 token
 */
interface IWETH9 {
    function approve(address spender, uint256 amount) external returns (bool);

    function transfer(address to, uint256 amount) external returns (bool);

    function deposit() external payable;

    function withdraw(uint256) external;

    function balanceOf(address account) external view returns (uint256);

    event Approval(address indexed src, address indexed guy, uint256 wad);
    event Transfer(address indexed src, address indexed dst, uint256 wad);
    event Deposit(address indexed dst, uint256 wad);
    event Withdrawal(address indexed src, uint256 wad);
}

File 8 of 9 : IBlockManager_Mock.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

/**
 * @dev Interface for BlockManager_Mock contract (test helper)
 */
interface IBlockManager_Mock {
    function getBlockNumber() external view returns (uint256);
}

File 9 of 9 : ChainUtils.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";

import "../interfaces/IArbSys.sol";
import "../interfaces/IGeneralErrors.sol";
import "../interfaces/mock/IBlockManager_Mock.sol";

/**
 * @dev Chain helpers internal library
 */
library ChainUtils {
    // Supported chains
    uint256 internal constant ARBITRUM_MAINNET = 42161;
    uint256 internal constant ARBITRUM_SEPOLIA = 421614;
    uint256 internal constant POLYGON_MAINNET = 137;
    uint256 internal constant BASE_MAINNET = 8453;
    uint256 internal constant APECHAIN_MAINNET = 33139;
    uint256 internal constant TESTNET = 31337;

    // Wrapped native tokens
    address private constant ARBITRUM_MAINNET_WETH = 0x82aF49447D8a07e3bd95BD0d56f35241523fBab1;
    address private constant ARBITRUM_SEPOLIA_WETH = 0x980B62Da83eFf3D4576C647993b0c1D7faf17c73;
    address private constant POLYGON_MAINNET_WMATIC = 0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270;
    address private constant BASE_MAINNET_WETH = 0x4200000000000000000000000000000000000006;
    address private constant APECHAIN_MAINNET_WAPE = 0x00000000000f7e000644657dC9417b185962645a; // Custom non-rebasing WAPE

    IArbSys private constant ARB_SYS = IArbSys(address(100));

    error Overflow();
    /**
     * @dev Returns the current block number (l2 block for arbitrum)
     */
    function getBlockNumber() internal view returns (uint256) {
        if (block.chainid == ARBITRUM_MAINNET || block.chainid == ARBITRUM_SEPOLIA) {
            return ARB_SYS.arbBlockNumber();
        }

        if (block.chainid == TESTNET) {
            return IBlockManager_Mock(address(420)).getBlockNumber();
        }

        return block.number;
    }

    /**
     * @dev Returns blockNumber converted to uint48
     * @param blockNumber block number to convert
     */
    function getUint48BlockNumber(uint256 blockNumber) internal pure returns (uint48) {
        if (blockNumber > type(uint48).max) revert Overflow();
        return uint48(blockNumber);
    }

    /**
     * @dev Returns the wrapped native token address for the current chain
     */
    function getWrappedNativeToken() internal view returns (address) {
        if (block.chainid == ARBITRUM_MAINNET) {
            return ARBITRUM_MAINNET_WETH;
        }

        if (block.chainid == BASE_MAINNET) {
            return BASE_MAINNET_WETH;
        }

        if (block.chainid == APECHAIN_MAINNET) {
            return APECHAIN_MAINNET_WAPE;
        }

        if (block.chainid == POLYGON_MAINNET) {
            return POLYGON_MAINNET_WMATIC;
        }

        if (block.chainid == ARBITRUM_SEPOLIA) {
            return ARBITRUM_SEPOLIA_WETH;
        }

        if (block.chainid == TESTNET) {
            return address(421);
        }

        return address(0);
    }

    /**
     * @dev Returns whether a token is the wrapped native token for the current chain
     * @param _token token address to check
     */
    function isWrappedNativeToken(address _token) internal view returns (bool) {
        return _token != address(0) && _token == getWrappedNativeToken();
    }

    /**
     * @dev Converts blocks to seconds for the current chain.
     * @dev Important: the result is an estimation and may not be accurate. Use with caution.
     * @param _blocks block count to convert to seconds
     */
    function convertBlocksToSeconds(uint256 _blocks) internal view returns (uint256) {
        uint256 millisecondsPerBlock;

        if (block.chainid == ARBITRUM_MAINNET || block.chainid == ARBITRUM_SEPOLIA) {
            millisecondsPerBlock = 300; // 0.3 seconds per block
        } else if (block.chainid == BASE_MAINNET) {
            millisecondsPerBlock = 2000; // 2 seconds per block
        } else if (block.chainid == POLYGON_MAINNET) {
            millisecondsPerBlock = 2200; // 2.2 seconds per block
        } else if (block.chainid == APECHAIN_MAINNET) {
            millisecondsPerBlock = 12000; // for apescan we use L1 blocktime (12s)
        } else if (block.chainid == TESTNET) {
            millisecondsPerBlock = 1000; // 1 second per block
        } else {
            revert IGeneralErrors.UnsupportedChain();
        }

        return Math.mulDiv(_blocks, millisecondsPerBlock, 1000, Math.Rounding.Up);
    }
}

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

Contract Security Audit

Contract ABI

[{"inputs":[],"name":"InvalidAddress","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"inputs":[],"name":"ZeroValue","type":"error"},{"inputs":[{"internalType":"contract IGTokenExtended","name":"_gToken","type":"address"},{"internalType":"address","name":"_receiver","type":"address"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract IGTokenExtended","name":"_gToken","type":"address"},{"internalType":"uint256","name":"_lockDuration","type":"uint256"},{"internalType":"address","name":"_receiver","type":"address"}],"name":"depositWithDiscountAndLock","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract IGTokenExtended","name":"_gToken","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"},{"internalType":"address","name":"_receiver","type":"address"}],"name":"validateRequest","outputs":[{"internalType":"address","name":"asset","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

608060405234801561001057600080fd5b50610666806100206000396000f3fe6080604052600436106100385760003560e01c806323a3a28514610044578063e344c47214610081578063f9609f08146100a257600080fd5b3661003f57005b600080fd5b34801561005057600080fd5b5061006461005f36600461055d565b6100b5565b6040516001600160a01b0390911681526020015b60405180910390f35b61009461008f36600461055d565b6101a4565b604051908152602001610078565b6100946100b036600461059f565b6102fe565b60006001600160a01b03841615806100d457506001600160a01b038216155b156100f25760405163d92e233d60e01b815260040160405180910390fd5b8260000361011357604051637c946ed760e01b815260040160405180910390fd5b836001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610151573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061017591906105d8565b905061018081610450565b61019d5760405163e6c4247b60e01b815260040160405180910390fd5b9392505050565b6000806101b28534856100b5565b9050806001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156101ef57600080fd5b505af1158015610203573d6000803e3d6000fd5b505060405163095ea7b360e01b81526001600160a01b0389811660048301523460248301528516935063095ea7b3925060440190506020604051808303816000875af1158015610257573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061027b91906105f5565b50604051630e8e431160e41b8152346004820152602481018590526001600160a01b03848116604483015286169063e8e43110906064016020604051808303816000875af11580156102d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102f59190610617565b95945050505050565b60008061030c8434856100b5565b9050806001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561034957600080fd5b505af115801561035d573d6000803e3d6000fd5b505060405163095ea7b360e01b81526001600160a01b0388811660048301523460248301528516935063095ea7b3925060440190506020604051808303816000875af11580156103b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d591906105f5565b50604051636e553f6560e01b81523460048201526001600160a01b038481166024830152851690636e553f65906044016020604051808303816000875af1158015610424573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104489190610617565b949350505050565b60006001600160a01b03821615801590610482575061046d610488565b6001600160a01b0316826001600160a01b0316145b92915050565b600061a4b146036104ac57507382af49447d8a07e3bd95bd0d56f35241523fbab190565b61210546036104ce575073420000000000000000000000000000000000000690565b61817346036104eb57506e0f7e000644657dc9417b185962645a90565b6089460361050c5750730d500b1d8e8ef31e21c99d1db9a6444d3adf127090565b62066eee460361052f575073980b62da83eff3d4576c647993b0c1d7faf17c7390565b617a69460361053f57506101a590565b50600090565b6001600160a01b038116811461055a57600080fd5b50565b60008060006060848603121561057257600080fd5b833561057d81610545565b925060208401359150604084013561059481610545565b809150509250925092565b600080604083850312156105b257600080fd5b82356105bd81610545565b915060208301356105cd81610545565b809150509250929050565b6000602082840312156105ea57600080fd5b815161019d81610545565b60006020828403121561060757600080fd5b8151801515811461019d57600080fd5b60006020828403121561062957600080fd5b505191905056fea2646970667358221220e50e7fb9e0d6b8b6b7749d12877532dc43ff93b64952b8252b53b44eb1643dc264736f6c63430008170033

Deployed Bytecode

0x6080604052600436106100385760003560e01c806323a3a28514610044578063e344c47214610081578063f9609f08146100a257600080fd5b3661003f57005b600080fd5b34801561005057600080fd5b5061006461005f36600461055d565b6100b5565b6040516001600160a01b0390911681526020015b60405180910390f35b61009461008f36600461055d565b6101a4565b604051908152602001610078565b6100946100b036600461059f565b6102fe565b60006001600160a01b03841615806100d457506001600160a01b038216155b156100f25760405163d92e233d60e01b815260040160405180910390fd5b8260000361011357604051637c946ed760e01b815260040160405180910390fd5b836001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610151573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061017591906105d8565b905061018081610450565b61019d5760405163e6c4247b60e01b815260040160405180910390fd5b9392505050565b6000806101b28534856100b5565b9050806001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156101ef57600080fd5b505af1158015610203573d6000803e3d6000fd5b505060405163095ea7b360e01b81526001600160a01b0389811660048301523460248301528516935063095ea7b3925060440190506020604051808303816000875af1158015610257573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061027b91906105f5565b50604051630e8e431160e41b8152346004820152602481018590526001600160a01b03848116604483015286169063e8e43110906064016020604051808303816000875af11580156102d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102f59190610617565b95945050505050565b60008061030c8434856100b5565b9050806001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561034957600080fd5b505af115801561035d573d6000803e3d6000fd5b505060405163095ea7b360e01b81526001600160a01b0388811660048301523460248301528516935063095ea7b3925060440190506020604051808303816000875af11580156103b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103d591906105f5565b50604051636e553f6560e01b81523460048201526001600160a01b038481166024830152851690636e553f65906044016020604051808303816000875af1158015610424573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104489190610617565b949350505050565b60006001600160a01b03821615801590610482575061046d610488565b6001600160a01b0316826001600160a01b0316145b92915050565b600061a4b146036104ac57507382af49447d8a07e3bd95bd0d56f35241523fbab190565b61210546036104ce575073420000000000000000000000000000000000000690565b61817346036104eb57506e0f7e000644657dc9417b185962645a90565b6089460361050c5750730d500b1d8e8ef31e21c99d1db9a6444d3adf127090565b62066eee460361052f575073980b62da83eff3d4576c647993b0c1d7faf17c7390565b617a69460361053f57506101a590565b50600090565b6001600160a01b038116811461055a57600080fd5b50565b60008060006060848603121561057257600080fd5b833561057d81610545565b925060208401359150604084013561059481610545565b809150509250925092565b600080604083850312156105b257600080fd5b82356105bd81610545565b915060208301356105cd81610545565b809150509250929050565b6000602082840312156105ea57600080fd5b815161019d81610545565b60006020828403121561060757600080fd5b8151801515811461019d57600080fd5b60006020828403121561062957600080fd5b505191905056fea2646970667358221220e50e7fb9e0d6b8b6b7749d12877532dc43ff93b64952b8252b53b44eb1643dc264736f6c63430008170033

Block Transaction Difficulty 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  ]
[ 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.