false
true
0

Contract Address Details

0xc8B4d7d885D41826CB46376676638449332aeA87

Contract Name
SunPLSOracleV2
Creator
0x062449–5ac4c9 at 0x2700bc–3f53d4
Balance
0 PLS ( )
Tokens
Fetching tokens...
Transactions
121 Transactions
Transfers
0 Transfers
Gas Used
7,334,040
Last Balance Update
26314713
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
This contract has been verified via Sourcify. View contract in Sourcify repository
Contract name:
SunPLSOracleV2




Optimization enabled
true
Compiler version
v0.8.20+commit.a1b79de6




Optimization runs
200
EVM Version
shanghai




Verified at
2026-03-12T00:46:16.181846Z

Constructor Arguments

000000000000000000000000ca46e01f4bf6938e8d8b8d22a570ffe96e9f0b19000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a2700000000000000000000000004b37fa64a8d73a37d636608e5f6f8e5ce1541aa

Arg [0] (address) : 0xca46e01f4bf6938e8d8b8d22a570ffe96e9f0b19
Arg [1] (address) : 0xa1077a294dde1b09bb078844df40758a5d0f9a27
Arg [2] (address) : 0x04b37fa64a8d73a37d636608e5f6f8e5ce1541aa

              

SunPulse_Oracle.sol

// SPDX-License-Identifier: CC-BY-NC-SA-4.0
pragma solidity ^0.8.20;

/**
 * ╔══════════════════════════════════════════════════════════════════════╗
 * ║         SunPLS Oracle v1.2 — ELITE TEAM6                             ║
 * ║         Single-Pair TWAP Oracle for PulseChain                       ║
 * ║                                                                      ║
 * ║   Reads SunPLS/WPLS pair from PulseX                                 ║
 * ║                                                                      ║
 * ║   PRICE DIRECTION: WPLS per SunPLS (1e18 scale)                      ║
 * ║   Example: 100_000e18 = 1 SunPLS costs 100,000 PLS                   ║
 * ║   This matches Controller's R (also WPLS per SunPLS)                 ║
 * ║   ε = |P - R| / R is meaningful only when P and R share units        ║
 * ║                                                                      ║
 * ║   UNISWAP V2 CUMULATIVE PRICE DIRECTION:                             ║
 * ║   price0Cumulative = token1/token0 (in Q112 fixed point)             ║
 * ║   price1Cumulative = token0/token1 (in Q112 fixed point)             ║
 * ║   When wplsIsToken0: we want WPLS/SunPLS = token0/token1             ║
 * ║     → use price1CumulativeLast                                       ║
 * ║   When wplsIsToken1: we want WPLS/SunPLS = token1/token0             ║
 * ║     → use price0CumulativeLast                                       ║
 * ║                                                                      ║
 * ║   ANTI-MANIPULATION:                                                 ║
 * ║   • TWAP (60s window) for manipulation resistance                    ║
 * ║   • Creeping: deviations >5% require 3 confirmations + 10% step      ║
 * ║   • Candidate tolerance band: rolling TWAP windows naturally produce ║
 * ║     slightly different values each call. Confirmations now accumulate║
 * ║     if the new reading is within 1% of pendingPrice, preventing      ║
 * ║     legitimate large moves from stalling indefinitely.               ║
 * ║   • Flash loan defense: MIN_TWAP_INTERVAL between updates            ║
 * ║   • Bootstrap from live reserves (no magic number starting price)    ║
 * ║                                                                      ║
 * ║   CHANGELOG v1.2:                                                    ║
 * ║   • Fixed creeping confirmation stall on large legitimate moves.     ║
 * ║     Previously: confirmations required newPrice == pendingPrice      ║
 * ║     (exact equality). Rolling TWAP windows produce fractionally      ║
 * ║     different values each call (e.g. 40.1e18, 40.2e18, 40.15e18),    ║
 * ║     causing confirmations to reset to 1 on every call. A sustained   ║
 * ║     PLS pump could leave the oracle permanently stuck tracking a     ║
 * ║     stale price, forcing indefinite Controller Mode B/C degradation. ║
 * ║     Fix: CANDIDATE_TOLERANCE_BPS = 100 (1%) tolerance band. Any      ║
 * ║     new TWAP reading within 1% of pendingPrice counts as the same    ║
 * ║     candidate and increments confirmations. Genuine reversals (>1%   ║
 * ║     away from pendingPrice) still reset the counter. pendingPrice    ║
 * ║     updates to the latest reading within the band so it tracks the   ║
 * ║     rolling TWAP accurately.                                         ║
 * ║                                                                      ║
 * ║   CHANGELOG v1.1:                                                    ║
 * ║   • Split lastUpdateTimestamp (call gate) from lastPriceTimestamp    ║
 * ║     (when lastPrice last actually changed). isHealthy() and peek()   ║
 * ║     now use lastPriceTimestamp so health/staleness signals are       ║
 * ║     accurate even during creep confirmation accumulation.            ║
 * ║                                                                      ║
 * ║   Dev:     ELITE TEAM6                                               ║
 * ║   License: CC-BY-NC-SA-4.0 | Immutable After Launch                  ║
 * ╚══════════════════════════════════════════════════════════════════════╝
 *
 * ═══════════════════════════════════════════════════════════════════════
 *                   CREEPING MECHANISM — HOW IT WORKS
 * ═══════════════════════════════════════════════════════════════════════
 *
 * Small moves (≤5%): accepted immediately every call.
 *
 * Large moves (>5%): require confirmation before creeping:
 *
 *   1. First reading above threshold → pendingPrice = newPrice, confirmations = 1
 *   2. Subsequent readings within 1% of pendingPrice → confirmations++
 *      pendingPrice updates to latest reading (tracks rolling TWAP)
 *   3. Reading >1% away from pendingPrice → genuine reversal detected,
 *      pendingPrice = newPrice, confirmations = 1 (fresh start)
 *   4. Once confirmations >= MAX_CONFIRMATIONS (3):
 *      → creep lastPrice by CREEP_STEP_BPS (10%) toward pendingPrice
 *      → reset confirmation state
 *      → repeat until lastPrice converges to pendingPrice
 *
 * Example — PLS pumps 40%:
 *   Call 1: TWAP = 140e18. Deviation 40% > 5%. pending=140e18, conf=1
 *   Call 2: TWAP = 140.2e18. Within 1% of 140e18. pending=140.2e18, conf=2
 *   Call 3: TWAP = 139.9e18. Within 1% of 140.2e18. pending=139.9e18, conf=3
 *   → Creep: lastPrice moves 10% toward 139.9e18
 *   Repeat until converged. Total time: ~(40/10) × 3 × 60s = ~12 minutes.
 *
 * ═══════════════════════════════════════════════════════════════════════
 */

interface IUniswapV2Pair {
    function token0() external view returns (address);
    function token1() external view returns (address);
    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
    function price0CumulativeLast() external view returns (uint256);
    function price1CumulativeLast() external view returns (uint256);
}

contract SunPLSOracleV2 {

    // ─────────────────────────────────────────────────────────────────────
    // Immutables
    // ─────────────────────────────────────────────────────────────────────

    IUniswapV2Pair public immutable pair;
    address        public immutable wpls;
    address        public immutable sunpls;

    /// @notice True if WPLS is token0. Determines which accumulator to use.
    bool public immutable wplsIsToken0;

    // ─────────────────────────────────────────────────────────────────────
    // Constants
    // ─────────────────────────────────────────────────────────────────────

    uint256 public constant PRECISION              = 1e18;

    /// @notice Instant-accept threshold: deviations ≤ 5% accepted immediately
    uint256 public constant MAX_DEVIATION_BPS      = 500;

    /// @notice Minimum seconds between oracle calls — flash loan defense
    uint256 public constant MIN_TWAP_INTERVAL      = 60;

    /// @notice Oracle considered unhealthy if lastPrice not changed within this window
    uint256 public constant MAX_PRICE_AGE          = 300;

    /// @notice Confirmations before a large deviation is accepted (via creep)
    uint8   private constant MAX_CONFIRMATIONS     = 3;

    /// @notice Each creep step moves 10% toward the confirmed price
    uint16  private constant CREEP_STEP_BPS        = 1000;

    /// @notice v1.2: Tolerance band for creep candidate matching.
    ///         Rolling TWAP windows naturally produce fractionally different
    ///         values each call. A new reading within 1% of pendingPrice
    ///         is treated as the same candidate and increments confirmations.
    ///         Genuine reversals (deviation > 1% from pendingPrice) reset.
    uint16  private constant CANDIDATE_TOLERANCE_BPS = 100;

    // ─────────────────────────────────────────────────────────────────────
    // State
    // ─────────────────────────────────────────────────────────────────────

    /// @notice Last accepted price in WPLS per SunPLS (1e18 scale)
    uint256 public lastPrice;

    /// @notice Timestamp of last oracle CALL (used as rate-limit gate).
    ///         Advanced on every _updateIfNeeded() invocation regardless
    ///         of whether lastPrice changed. Do not use for staleness checks.
    uint256 public lastUpdateTimestamp;

    /// @notice Timestamp of last actual lastPrice CHANGE (accepted or creep step).
    ///         Used by isHealthy() and peek() for accurate staleness signals.
    ///         Only advances when lastPrice is written.
    uint256 public lastPriceTimestamp;

    /// @notice Cumulative price snapshot for TWAP (Q112 scale)
    uint256 private priceCumulativeLast;

    /// @notice Pair's blockTimestamp at last TWAP snapshot (seconds, wraps at uint32 max)
    uint32  private blockTimestampLast;

    /// @notice Price awaiting creep confirmation (tracks latest reading in the band)
    uint256 private pendingPrice;

    /// @notice Confirmations accumulated for pendingPrice
    uint8   private confirmations;

    // ─────────────────────────────────────────────────────────────────────
    // Events
    // ─────────────────────────────────────────────────────────────────────

    event PriceUpdated(uint256 price, uint256 timestamp, bool creeping);

    // ─────────────────────────────────────────────────────────────────────
    // Constructor
    // ─────────────────────────────────────────────────────────────────────

    /**
     * @param _pair   PulseX SunPLS/WPLS pair — must have liquidity at deploy
     * @param _wpls   WPLS token address
     * @param _sunpls SunPLS token address
     *
     * @dev Bootstraps lastPrice from live reserves so the oracle starts
     *      at the real market price. The pool must be seeded before this
     *      contract is deployed.
     */
    constructor(address _pair, address _wpls, address _sunpls) {
        require(
            _pair   != address(0) &&
            _wpls   != address(0) &&
            _sunpls != address(0),
            "Zero address"
        );

        pair   = IUniswapV2Pair(_pair);
        wpls   = _wpls;
        sunpls = _sunpls;

        // Verify both tokens are in the pair
        address t0 = IUniswapV2Pair(_pair).token0();
        address t1 = IUniswapV2Pair(_pair).token1();
        bool _wplsIsToken0 = (t0 == _wpls);
        require(_wplsIsToken0 || t1 == _wpls,    "Pair missing WPLS");
        require(t0 == _sunpls  || t1 == _sunpls, "Pair missing SunPLS");
        wplsIsToken0 = _wplsIsToken0;

        // Seed cumulative accumulator
        (, , uint32 ts) = IUniswapV2Pair(_pair).getReserves();
        blockTimestampLast  = ts;
        priceCumulativeLast = _wplsIsToken0
            ? IUniswapV2Pair(_pair).price1CumulativeLast()
            : IUniswapV2Pair(_pair).price0CumulativeLast();

        // Bootstrap from live spot price — pool must have liquidity
        (uint112 r0, uint112 r1,) = IUniswapV2Pair(_pair).getReserves();
        require(r0 > 0 && r1 > 0, "Pool has no liquidity at deploy");

        uint256 initialPrice = _wplsIsToken0
            ? (uint256(r0) * PRECISION) / uint256(r1)
            : (uint256(r1) * PRECISION) / uint256(r0);

        require(initialPrice > 0, "Zero initial price");
        lastPrice           = initialPrice;
        lastUpdateTimestamp = block.timestamp;
        lastPriceTimestamp  = block.timestamp;
    }

    // ─────────────────────────────────────────────────────────────────────
    // External interface — Controller + Vault compatible
    // ─────────────────────────────────────────────────────────────────────

    /**
     * @notice Update oracle and return current price.
     *         Called by Controller each epoch and Vault on mint/liquidate.
     */
    function update() external returns (uint256 price, uint256 timestamp) {
        return _updateIfNeeded();
    }

    /**
     * @notice Read current price without mutating state.
     *         Returns lastPriceTimestamp — the time lastPrice last changed.
     *         Vault uses this for staleness: block.timestamp - ts <= MAX_ORACLE_STALENESS.
     *         Using lastPriceTimestamp here (not lastUpdateTimestamp) ensures the vault's
     *         staleness check reflects actual price age, not just last call time.
     */
    function peek() external view returns (uint256 price, uint256 timestamp) {
        return (lastPrice, lastPriceTimestamp);
    }

    /**
     * @notice True if lastPrice has changed within 2 × MAX_PRICE_AGE.
     *         Uses lastPriceTimestamp so health accurately reflects price
     *         freshness, not just whether update() was recently called.
     */
    function isHealthy() external view returns (bool) {
        return (block.timestamp - lastPriceTimestamp) < (MAX_PRICE_AGE * 2);
    }

    // ─────────────────────────────────────────────────────────────────────
    // Internal — update logic
    // ─────────────────────────────────────────────────────────────────────

    function _updateIfNeeded() internal returns (uint256, uint256) {
        // Rate-limit gate: MIN_TWAP_INTERVAL between oracle calls.
        // Uses lastUpdateTimestamp (call time) not lastPriceTimestamp (price time)
        // so the gate works regardless of whether the last call changed the price.
        if (block.timestamp - lastUpdateTimestamp < MIN_TWAP_INTERVAL) {
            return (lastPrice, lastPriceTimestamp);
        }

        (uint112 r0, uint112 r1, uint32 tsPair) = pair.getReserves();
        require(r0 > 0 && r1 > 0, "No liquidity");

        uint32 elapsed = uint32(block.timestamp) - blockTimestampLast;

        uint256 newPrice;
        if (elapsed < MIN_TWAP_INTERVAL) {
            newPrice = _spotPrice(r0, r1);
        } else {
            newPrice = _twapPrice(r0, r1, tsPair, elapsed);
        }

        // Advance call gate timestamp BEFORE applying creep so the rate-limit
        // applies even if _applyCreepingOrAccept doesn't change lastPrice.
        lastUpdateTimestamp = block.timestamp;

        _applyCreepingOrAccept(newPrice);
        return (lastPrice, lastPriceTimestamp);
    }

    /**
     * @dev Spot price: WPLS per SunPLS from current reserves.
     */
    function _spotPrice(uint112 r0, uint112 r1) internal view returns (uint256) {
        return wplsIsToken0
            ? (uint256(r0) * PRECISION) / uint256(r1)
            : (uint256(r1) * PRECISION) / uint256(r0);
    }

    /**
     * @dev TWAP price: WPLS per SunPLS from cumulative accumulators.
     */
    function _twapPrice(
        uint112 r0,
        uint112 r1,
        uint32  tsPair,
        uint32  elapsed
    ) internal returns (uint256) {
        uint256 cumulative = wplsIsToken0
            ? pair.price1CumulativeLast()
            : pair.price0CumulativeLast();

        unchecked {
            uint32 gapSinceSync = uint32(block.timestamp) - tsPair;
            if (gapSinceSync > 0) {
                uint256 instantQ112 = wplsIsToken0
                    ? (uint256(r0) << 112) / uint256(r1)
                    : (uint256(r1) << 112) / uint256(r0);
                cumulative += instantQ112 * gapSinceSync;
            }
        }

        uint256 diff = cumulative - priceCumulativeLast;
        uint256 twap = (diff * PRECISION) / (uint256(elapsed) << 112);

        priceCumulativeLast = cumulative;
        blockTimestampLast  = uint32(block.timestamp);

        return twap;
    }

    /**
     * @dev Accept price immediately if deviation ≤ MAX_DEVIATION_BPS.
     *      For larger moves: accumulate MAX_CONFIRMATIONS using a tolerance
     *      band, then creep CREEP_STEP_BPS (10%) toward the confirmed price.
     *
     * v1.2 CHANGE — candidate matching:
     *      Old: confirmations++ only if newPrice == pendingPrice (exact).
     *      New: confirmations++ if newPrice is within CANDIDATE_TOLERANCE_BPS
     *           (1%) of pendingPrice. pendingPrice updates to newPrice so it
     *           tracks the rolling TWAP within the band.
     *
     *      Why: TWAP windows roll forward each call, producing slightly
     *      different values (e.g. 140.1e18 vs 140.2e18) even for a sustained
     *      price. Exact equality never accumulates. The 1% band is tight enough
     *      to reject genuine reversals while wide enough to absorb TWAP drift.
     *
     *      lastPriceTimestamp is ONLY updated when lastPrice actually changes.
     *      lastUpdateTimestamp is updated by _updateIfNeeded() before this call.
     */
    function _applyCreepingOrAccept(uint256 newPrice) internal {
        if (lastPrice == 0) {
            lastPrice          = newPrice;
            lastPriceTimestamp = block.timestamp;
            emit PriceUpdated(newPrice, block.timestamp, false);
            return;
        }

        uint256 diff         = newPrice > lastPrice ? newPrice - lastPrice : lastPrice - newPrice;
        uint256 deviationBps = (diff * 10_000) / lastPrice;

        if (deviationBps <= MAX_DEVIATION_BPS) {
            // Small move — accept immediately, clear pending state
            lastPrice          = newPrice;
            lastPriceTimestamp = block.timestamp;
            confirmations      = 0;
            pendingPrice       = 0;
            emit PriceUpdated(newPrice, block.timestamp, false);
            return;
        }

        // Large move — check if newPrice is within tolerance band of pendingPrice
        // v1.2: tolerance band replaces exact equality check
        bool sameCandidate = false;
        if (pendingPrice > 0) {
            uint256 candidateDiff = newPrice > pendingPrice
                ? newPrice - pendingPrice
                : pendingPrice - newPrice;
            sameCandidate = (candidateDiff * 10_000) / pendingPrice <= CANDIDATE_TOLERANCE_BPS;
        }

        if (sameCandidate) {
            // Within 1% of current candidate — count as confirmation.
            // Update pendingPrice to latest reading so it tracks TWAP drift.
            pendingPrice = newPrice;
            confirmations++;
        } else {
            // Genuine new candidate (reversal or first reading) — reset
            pendingPrice  = newPrice;
            confirmations = 1;
        }

        if (confirmations >= MAX_CONFIRMATIONS) {
            // Creep 10% toward confirmed price
            uint256 step = pendingPrice > lastPrice
                ? ((pendingPrice - lastPrice) * CREEP_STEP_BPS) / 10_000
                : ((lastPrice - pendingPrice) * CREEP_STEP_BPS) / 10_000;

            lastPrice = pendingPrice > lastPrice
                ? lastPrice + step
                : lastPrice - step;

            // Price changed — update price timestamp
            lastPriceTimestamp = block.timestamp;

            confirmations = 0;
            pendingPrice  = 0;
            emit PriceUpdated(lastPrice, block.timestamp, true);
        }

        // NOTE: lastUpdateTimestamp already advanced in _updateIfNeeded().
        // We do NOT touch it here. During confirmation accumulation, lastPrice
        // is unchanged and lastPriceTimestamp correctly remains stale.
    }

    // ─────────────────────────────────────────────────────────────────────
    // View helpers
    // ─────────────────────────────────────────────────────────────────────

    /// @notice Current spot price from reserves (no state change).
    function getSpotPrice() external view returns (uint256) {
        (uint112 r0, uint112 r1,) = pair.getReserves();
        if (r0 == 0 || r1 == 0) return lastPrice;
        return _spotPrice(r0, r1);
    }

    /// @notice Oracle configuration for on-chain verification.
    function getConfig()
        external
        view
        returns (
            address pairAddress,
            address wplsAddress,
            address sunplsAddress,
            bool    wplsIsToken0Flag,
            uint256 maxDeviationBps,
            uint256 minTwapInterval,
            uint256 maxPriceAge,
            uint256 candidateToleranceBps
        )
    {
        return (
            address(pair),
            wpls,
            sunpls,
            wplsIsToken0,
            MAX_DEVIATION_BPS,
            MIN_TWAP_INTERVAL,
            MAX_PRICE_AGE,
            CANDIDATE_TOLERANCE_BPS
        );
    }

    /// @notice Creeping state for dashboards and monitoring.
    function getCreepingState()
        external
        view
        returns (
            uint256 pending,
            uint8   confirmCount,
            bool    isCreeping
        )
    {
        return (pendingPrice, confirmations, pendingPrice > 0);
    }
}
        

Compiler Settings

{"remappings":[],"optimizer":{"runs":200,"enabled":true},"metadata":{"bytecodeHash":"ipfs"},"libraries":{},"evmVersion":"shanghai","compilationTarget":{"SunPulse_Oracle.sol":"SunPLSOracleV2"}}
              

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_pair","internalType":"address"},{"type":"address","name":"_wpls","internalType":"address"},{"type":"address","name":"_sunpls","internalType":"address"}]},{"type":"event","name":"PriceUpdated","inputs":[{"type":"uint256","name":"price","internalType":"uint256","indexed":false},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false},{"type":"bool","name":"creeping","internalType":"bool","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MAX_DEVIATION_BPS","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MAX_PRICE_AGE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MIN_TWAP_INTERVAL","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"PRECISION","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"pairAddress","internalType":"address"},{"type":"address","name":"wplsAddress","internalType":"address"},{"type":"address","name":"sunplsAddress","internalType":"address"},{"type":"bool","name":"wplsIsToken0Flag","internalType":"bool"},{"type":"uint256","name":"maxDeviationBps","internalType":"uint256"},{"type":"uint256","name":"minTwapInterval","internalType":"uint256"},{"type":"uint256","name":"maxPriceAge","internalType":"uint256"},{"type":"uint256","name":"candidateToleranceBps","internalType":"uint256"}],"name":"getConfig","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"pending","internalType":"uint256"},{"type":"uint8","name":"confirmCount","internalType":"uint8"},{"type":"bool","name":"isCreeping","internalType":"bool"}],"name":"getCreepingState","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getSpotPrice","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isHealthy","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lastPrice","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lastPriceTimestamp","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lastUpdateTimestamp","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IUniswapV2Pair"}],"name":"pair","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"price","internalType":"uint256"},{"type":"uint256","name":"timestamp","internalType":"uint256"}],"name":"peek","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"sunpls","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"price","internalType":"uint256"},{"type":"uint256","name":"timestamp","internalType":"uint256"}],"name":"update","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"wpls","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"wplsIsToken0","inputs":[]}]
              

Contract Creation Code

0x61010060405234801562000011575f80fd5b506040516200140d3803806200140d8339810160408190526200003491620005b2565b6001600160a01b038316158015906200005557506001600160a01b03821615155b80156200006a57506001600160a01b03811615155b620000ab5760405162461bcd60e51b815260206004820152600c60248201526b5a65726f206164647265737360a01b60448201526064015b60405180910390fd5b6001600160a01b03808416608081905283821660a05290821660c05260408051630dfe168160e01b815290515f9291630dfe16819160048083019260209291908290030181865afa15801562000103573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620001299190620005f9565b90505f846001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000169573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906200018f9190620005f9565b90506001600160a01b03828116908516148080620001be5750846001600160a01b0316826001600160a01b0316145b620002005760405162461bcd60e51b815260206004820152601160248201527050616972206d697373696e672057504c5360781b6044820152606401620000a2565b836001600160a01b0316836001600160a01b03161480620002325750836001600160a01b0316826001600160a01b0316145b620002805760405162461bcd60e51b815260206004820152601360248201527f50616972206d697373696e672053756e504c53000000000000000000000000006044820152606401620000a2565b80151560e0811515815250505f866001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015620002ca573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620002f0919062000633565b6004805463ffffffff191663ffffffff831617905592508391506200037a905057866001600160a01b0316635909c0d56040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200034e573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019062000374919062000685565b620003dd565b866001600160a01b0316635a3d54936040518163ffffffff1660e01b8152600401602060405180830381865afa158015620003b7573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620003dd919062000685565b6003819055505f80886001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa15801562000422573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019062000448919062000633565b50915091505f826001600160701b03161180156200046e57505f816001600160701b0316115b620004bc5760405162461bcd60e51b815260206004820152601f60248201527f506f6f6c20686173206e6f206c6971756964697479206174206465706c6f79006044820152606401620000a2565b5f84620004fe57826001600160701b0316670de0b6b3a7640000836001600160701b0316620004ec91906200069d565b620004f89190620006c7565b62000533565b816001600160701b0316670de0b6b3a7640000846001600160701b03166200052791906200069d565b620005339190620006c7565b90505f81116200057b5760405162461bcd60e51b81526020600482015260126024820152715a65726f20696e697469616c20707269636560701b6044820152606401620000a2565b5f55505042600181905560025550620006e795505050505050565b80516001600160a01b0381168114620005ad575f80fd5b919050565b5f805f60608486031215620005c5575f80fd5b620005d08462000596565b9250620005e06020850162000596565b9150620005f06040850162000596565b90509250925092565b5f602082840312156200060a575f80fd5b620006158262000596565b9392505050565b80516001600160701b0381168114620005ad575f80fd5b5f805f6060848603121562000646575f80fd5b62000651846200061c565b925062000661602085016200061c565b9150604084015163ffffffff811681146200067a575f80fd5b809150509250925092565b5f6020828403121562000696575f80fd5b5051919050565b8082028115828204841417620006c157634e487b7160e01b5f52601160045260245ffd5b92915050565b5f82620006e257634e487b7160e01b5f52601260045260245ffd5b500490565b60805160a05160c05160e051610ca5620007685f395f8181610296015281816102e8015281816105bd01528181610654015261079101525f818161026d015261031f01525f8181610168015261024501525f81816101b80152818161022001528181610368015281816104710152818161067901526106fe0152610ca55ff3fe608060405234801561000f575f80fd5b5060043610610106575f3560e01c8063a2e620451161009e578063c3f909d41161006e578063c3f909d414610212578063d4108e2a146102e3578063dc6a94221461031a578063dc76fabc14610341578063e402080414610349575f80fd5b8063a2e62045146101ab578063a8aa1b31146101b3578063aaf5eb68146101da578063b5d0db7a146101e9575f80fd5b80637de93f93116100d95780637de93f931461015257806391bf279b1461015b578063927ef7fa146101635780639d7f7e86146101a2575f80fd5b8063053f14da1461010a57806314bcec9f1461012557806325c684031461012e57806359e02dd714610137575b5f80fd5b6101125f5481565b6040519081526020015b60405180910390f35b61011260015481565b6101126101f481565b5f546002545b6040805192835260208301919091520161011c565b61011260025481565b610112603c81565b61018a7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161011c565b61011261012c81565b61013d610351565b61018a7f000000000000000000000000000000000000000000000000000000000000000081565b610112670de0b6b3a764000081565b6005546006546040805183815260ff90921660208301529115159181019190915260600161011c565b604080516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811682527f0000000000000000000000000000000000000000000000000000000000000000811660208301527f000000000000000000000000000000000000000000000000000000000000000016918101919091527f0000000000000000000000000000000000000000000000000000000000000000151560608201526101f46080820152603c60a082015261012c60c0820152606460e08201526101000161011c565b61030a7f000000000000000000000000000000000000000000000000000000000000000081565b604051901515815260200161011c565b61018a7f000000000000000000000000000000000000000000000000000000000000000081565b610112610363565b61030a610428565b5f8061035b610449565b915091509091565b5f805f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156103c2573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103e69190610b46565b5091509150816001600160701b03165f148061040957506001600160701b038116155b15610417575f549250505090565b61042182826105ba565b9250505090565b5f61043661012c6002610ba6565b6002546104439042610bbd565b10905090565b5f80603c6001544261045b9190610bbd565b101561046c5750505f546002549091565b5f805f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156104cb573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104ef9190610b46565b9250925092505f836001600160701b031611801561051557505f826001600160701b0316115b6105545760405162461bcd60e51b815260206004820152600c60248201526b4e6f206c697175696469747960a01b604482015260640160405180910390fd5b6004545f906105699063ffffffff1642610bd0565b90505f603c8263ffffffff16101561058c5761058585856105ba565b905061059b565b61059885858585610650565b90505b426001556105a881610878565b5f546002549650965050505050509091565b5f7f000000000000000000000000000000000000000000000000000000000000000061061657826001600160701b0316670de0b6b3a7640000836001600160701b03166106079190610ba6565b6106119190610c08565b610647565b816001600160701b0316670de0b6b3a7640000846001600160701b031661063d9190610ba6565b6106479190610c08565b90505b92915050565b5f807f00000000000000000000000000000000000000000000000000000000000000006106fc577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316635909c0d56040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106d3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106f79190610c27565b61077c565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316635a3d54936040518163ffffffff1660e01b8152600401602060405180830381865afa158015610758573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061077c9190610c27565b90504284900363ffffffff811615610815575f7f00000000000000000000000000000000000000000000000000000000000000006107df57876001600160701b03166070886001600160701b0316901b816107d9576107d9610bf4565b04610806565b866001600160701b03166070896001600160701b0316901b8161080457610804610bf4565b045b63ffffffff8316029290920191505b505f600354826108259190610bbd565b90505f63ffffffff60701b607086901b16610848670de0b6b3a764000084610ba6565b6108529190610c08565b60039390935550506004805463ffffffff19164263ffffffff1617905595945050505050565b5f545f036108cf575f8181554260028190556040805184815260208101929092528101919091527f2c0233f2ee34a876228db2e1c01e39264f7ffd29a8d12ff94b180c31592c7a609060600160405180910390a150565b5f805482116108ea57815f546108e59190610bbd565b6108f6565b5f546108f69083610bbd565b90505f8054826127106109099190610ba6565b6109139190610c08565b90506101f4811161097e575f8381554260028190556006805460ff1916905560058290556040805186815260208101929092528101919091527f2c0233f2ee34a876228db2e1c01e39264f7ffd29a8d12ff94b180c31592c7a609060600160405180910390a1505050565b6005545f90156109d7575f60055485116109a557846005546109a09190610bbd565b6109b2565b6005546109b29086610bbd565b6005549091506064906109c783612710610ba6565b6109d19190610c08565b11159150505b8015610a125760058490556006805460ff16905f6109f483610c3e565b91906101000a81548160ff021916908360ff16021790555050610a25565b60058490556006805460ff191660011790555b600654600360ff90911610610b25575f805460055411610a71576127106103e861ffff166005545f54610a589190610bbd565b610a629190610ba6565b610a6c9190610c08565b610a9e565b6127106103e861ffff165f54600554610a8a9190610bbd565b610a949190610ba6565b610a9e9190610c08565b90505f5460055411610abc57805f54610ab79190610bbd565b610ac9565b805f54610ac99190610c5c565b5f8181554260028190556006805460ff19169055600591909155604080519283526020830191909152600182820152517f2c0233f2ee34a876228db2e1c01e39264f7ffd29a8d12ff94b180c31592c7a609181900360600190a1505b50505050565b80516001600160701b0381168114610b41575f80fd5b919050565b5f805f60608486031215610b58575f80fd5b610b6184610b2b565b9250610b6f60208501610b2b565b9150604084015163ffffffff81168114610b87575f80fd5b809150509250925092565b634e487b7160e01b5f52601160045260245ffd5b808202811582820484141761064a5761064a610b92565b8181038181111561064a5761064a610b92565b63ffffffff828116828216039080821115610bed57610bed610b92565b5092915050565b634e487b7160e01b5f52601260045260245ffd5b5f82610c2257634e487b7160e01b5f52601260045260245ffd5b500490565b5f60208284031215610c37575f80fd5b5051919050565b5f60ff821660ff8103610c5357610c53610b92565b60010192915050565b8082018082111561064a5761064a610b9256fea26469706673582212200938008797e0c07bd92eb28c899f02053a423bb60a8c539bb8d4794dc221934064736f6c63430008140033000000000000000000000000ca46e01f4bf6938e8d8b8d22a570ffe96e9f0b19000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a2700000000000000000000000004b37fa64a8d73a37d636608e5f6f8e5ce1541aa

Deployed ByteCode

0x608060405234801561000f575f80fd5b5060043610610106575f3560e01c8063a2e620451161009e578063c3f909d41161006e578063c3f909d414610212578063d4108e2a146102e3578063dc6a94221461031a578063dc76fabc14610341578063e402080414610349575f80fd5b8063a2e62045146101ab578063a8aa1b31146101b3578063aaf5eb68146101da578063b5d0db7a146101e9575f80fd5b80637de93f93116100d95780637de93f931461015257806391bf279b1461015b578063927ef7fa146101635780639d7f7e86146101a2575f80fd5b8063053f14da1461010a57806314bcec9f1461012557806325c684031461012e57806359e02dd714610137575b5f80fd5b6101125f5481565b6040519081526020015b60405180910390f35b61011260015481565b6101126101f481565b5f546002545b6040805192835260208301919091520161011c565b61011260025481565b610112603c81565b61018a7f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a2781565b6040516001600160a01b03909116815260200161011c565b61011261012c81565b61013d610351565b61018a7f000000000000000000000000ca46e01f4bf6938e8d8b8d22a570ffe96e9f0b1981565b610112670de0b6b3a764000081565b6005546006546040805183815260ff90921660208301529115159181019190915260600161011c565b604080516001600160a01b037f000000000000000000000000ca46e01f4bf6938e8d8b8d22a570ffe96e9f0b19811682527f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a27811660208301527f00000000000000000000000004b37fa64a8d73a37d636608e5f6f8e5ce1541aa16918101919091527f0000000000000000000000000000000000000000000000000000000000000000151560608201526101f46080820152603c60a082015261012c60c0820152606460e08201526101000161011c565b61030a7f000000000000000000000000000000000000000000000000000000000000000081565b604051901515815260200161011c565b61018a7f00000000000000000000000004b37fa64a8d73a37d636608e5f6f8e5ce1541aa81565b610112610363565b61030a610428565b5f8061035b610449565b915091509091565b5f805f7f000000000000000000000000ca46e01f4bf6938e8d8b8d22a570ffe96e9f0b196001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156103c2573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103e69190610b46565b5091509150816001600160701b03165f148061040957506001600160701b038116155b15610417575f549250505090565b61042182826105ba565b9250505090565b5f61043661012c6002610ba6565b6002546104439042610bbd565b10905090565b5f80603c6001544261045b9190610bbd565b101561046c5750505f546002549091565b5f805f7f000000000000000000000000ca46e01f4bf6938e8d8b8d22a570ffe96e9f0b196001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156104cb573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104ef9190610b46565b9250925092505f836001600160701b031611801561051557505f826001600160701b0316115b6105545760405162461bcd60e51b815260206004820152600c60248201526b4e6f206c697175696469747960a01b604482015260640160405180910390fd5b6004545f906105699063ffffffff1642610bd0565b90505f603c8263ffffffff16101561058c5761058585856105ba565b905061059b565b61059885858585610650565b90505b426001556105a881610878565b5f546002549650965050505050509091565b5f7f000000000000000000000000000000000000000000000000000000000000000061061657826001600160701b0316670de0b6b3a7640000836001600160701b03166106079190610ba6565b6106119190610c08565b610647565b816001600160701b0316670de0b6b3a7640000846001600160701b031661063d9190610ba6565b6106479190610c08565b90505b92915050565b5f807f00000000000000000000000000000000000000000000000000000000000000006106fc577f000000000000000000000000ca46e01f4bf6938e8d8b8d22a570ffe96e9f0b196001600160a01b0316635909c0d56040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106d3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106f79190610c27565b61077c565b7f000000000000000000000000ca46e01f4bf6938e8d8b8d22a570ffe96e9f0b196001600160a01b0316635a3d54936040518163ffffffff1660e01b8152600401602060405180830381865afa158015610758573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061077c9190610c27565b90504284900363ffffffff811615610815575f7f00000000000000000000000000000000000000000000000000000000000000006107df57876001600160701b03166070886001600160701b0316901b816107d9576107d9610bf4565b04610806565b866001600160701b03166070896001600160701b0316901b8161080457610804610bf4565b045b63ffffffff8316029290920191505b505f600354826108259190610bbd565b90505f63ffffffff60701b607086901b16610848670de0b6b3a764000084610ba6565b6108529190610c08565b60039390935550506004805463ffffffff19164263ffffffff1617905595945050505050565b5f545f036108cf575f8181554260028190556040805184815260208101929092528101919091527f2c0233f2ee34a876228db2e1c01e39264f7ffd29a8d12ff94b180c31592c7a609060600160405180910390a150565b5f805482116108ea57815f546108e59190610bbd565b6108f6565b5f546108f69083610bbd565b90505f8054826127106109099190610ba6565b6109139190610c08565b90506101f4811161097e575f8381554260028190556006805460ff1916905560058290556040805186815260208101929092528101919091527f2c0233f2ee34a876228db2e1c01e39264f7ffd29a8d12ff94b180c31592c7a609060600160405180910390a1505050565b6005545f90156109d7575f60055485116109a557846005546109a09190610bbd565b6109b2565b6005546109b29086610bbd565b6005549091506064906109c783612710610ba6565b6109d19190610c08565b11159150505b8015610a125760058490556006805460ff16905f6109f483610c3e565b91906101000a81548160ff021916908360ff16021790555050610a25565b60058490556006805460ff191660011790555b600654600360ff90911610610b25575f805460055411610a71576127106103e861ffff166005545f54610a589190610bbd565b610a629190610ba6565b610a6c9190610c08565b610a9e565b6127106103e861ffff165f54600554610a8a9190610bbd565b610a949190610ba6565b610a9e9190610c08565b90505f5460055411610abc57805f54610ab79190610bbd565b610ac9565b805f54610ac99190610c5c565b5f8181554260028190556006805460ff19169055600591909155604080519283526020830191909152600182820152517f2c0233f2ee34a876228db2e1c01e39264f7ffd29a8d12ff94b180c31592c7a609181900360600190a1505b50505050565b80516001600160701b0381168114610b41575f80fd5b919050565b5f805f60608486031215610b58575f80fd5b610b6184610b2b565b9250610b6f60208501610b2b565b9150604084015163ffffffff81168114610b87575f80fd5b809150509250925092565b634e487b7160e01b5f52601160045260245ffd5b808202811582820484141761064a5761064a610b92565b8181038181111561064a5761064a610b92565b63ffffffff828116828216039080821115610bed57610bed610b92565b5092915050565b634e487b7160e01b5f52601260045260245ffd5b5f82610c2257634e487b7160e01b5f52601260045260245ffd5b500490565b5f60208284031215610c37575f80fd5b5051919050565b5f60ff821660ff8103610c5357610c53610b92565b60010192915050565b8082018082111561064a5761064a610b9256fea26469706673582212200938008797e0c07bd92eb28c899f02053a423bb60a8c539bb8d4794dc221934064736f6c63430008140033