false
true
0

Contract Address Details

0x411d2fDdbD944894E8aAa3c4b5563B66C5dC6346

Token
Perpetual Bitcoin (PB)
Creator
0xbad37b–e7b055 at 0xb8cb1d–54dbd8
Balance
0 PLS ( )
Tokens
Fetching tokens...
Transactions
117 Transactions
Transfers
1 Transfers
Gas Used
4,841,022
Last Balance Update
26425651
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 partially verified via Sourcify. View contract in Sourcify repository
Contract name:
PB




Optimization enabled
true
Compiler version
v0.8.24+commit.e11b9ed9




Optimization runs
1
EVM Version
shanghai




Verified at
2026-04-07T20:56:33.061482Z

contracts/PB.sol

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

/**
 * @title PB - Perpetual Bitcoin Liquid Token
 * @notice ERC20: 21M supply, 3.69% liquid (users), 96.31% locked (PBc).
 * SECURITY: Only Vault can receive PB from swaps (prevents direct pair.swap()).
 */

// By 0xBE369

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

contract PB is IERC20, ReentrancyGuard {
    string public constant name = "Perpetual Bitcoin";
    string public constant symbol = "PB";
    uint8 public constant decimals = 18;
    uint256 public constant totalSupply = 21_000_000e18;
    string public constant logoURI = "https://azure-rational-salmon-152.mypinata.cloud/ipfs/bafybeiclvfm6pqd4rozhffhewfndebxv3s6f2z5t3xsmirchyda3lg7e54/PB.jpg";
    string public constant website = "https://perpetualbitcoin.io";
    string public constant description = "Perpetual Bitcoin (PB) - Price-based unlock protocol. 21M supply, 3.69% liquid on purchase, 96.31% locked. Visit perpetualbitcoin.io";
    address public immutable DEPLOYER;

    // IMMUTABLE STATE (after lockVault() called)
    address public VAULT;           // Immutable after lockVault()
    bool public vaultLocked;        // Prevents re-locking
    address public PAIR;            // PulseX pair address (set by vault only)

    mapping(address => uint256) public balanceOf;
    mapping(address => mapping(address => uint256)) public allowance;

    constructor() {
        DEPLOYER = msg.sender;
        // VAULT will be set via lockVault() after deployment
    }

    /**
     * @notice Lock VAULT address and mint total supply to Vault
     * Can only be called once by deployer after Vault deployment
     * Mints all 21M PB to Vault at genesis
     */
    function lockVault(address _vault) external {
        require(msg.sender == DEPLOYER, "Only deployer");
        require(!vaultLocked, "Vault already locked");
        require(VAULT == address(0), "Vault already set");
        require(_vault != address(0), "Invalid vault");
        
        VAULT = _vault;
        vaultLocked = true;
        
        // Mint total supply to Vault
        balanceOf[_vault] = totalSupply;
        emit Transfer(address(0), _vault, totalSupply);
    }

    /**
     * @notice Set the PulseX pair address (SECURITY: only vault can call)
     * Used to prevent direct pair.swap() calls - vault is the ONLY source of PB swaps
     * 
     * @param _pair The PulseX pair address
     */
    function setPairAddress(address _pair) external {
        require(msg.sender == VAULT, "Only vault can set pair");
        require(_pair != address(0), "Invalid pair address");
        require(PAIR == address(0), "Pair already set");
        PAIR = _pair;
    }

    /**
     * @notice Transfer PB (standard ERC20)
     * Users can transfer their liquid PB freely - including selling to pair
     * SECURITY: Only vault can receive PB from pair (prevents direct pair.swap())
     */
    function transfer(address to, uint256 amount) external nonReentrant returns (bool) {
        address from = msg.sender;
        require(amount > 0, "Amount must be > 0");
        require(balanceOf[from] >= amount, "Insufficient balance");

        // SECURITY: If pair is trying to send PB to non-vault, DENY
        // This prevents direct pair.swap() calls - all PB must come through vault.buyPBDirect()
        if (from == PAIR && to != VAULT) {
            revert("Go to PerpetualBitcoin.io to 'BUY PB'");
        }

        // Standard ERC20 transfer (no split enforcement)
        balanceOf[from] -= amount;
        balanceOf[to] += amount;
        emit Transfer(from, to, amount);
        return true;
    }

    /**
     * @notice TransferFrom (standard ERC20)
     * Users can trade their PB on DEX (including selling to pair)
     * SECURITY: Only vault can receive PB from pair (prevents direct pair.swap())
     */
    function transferFrom(address from, address to, uint256 amount) external nonReentrant returns (bool) {
        // SECURITY: If pair is trying to get PB to non-vault, DENY
        // This prevents direct pair.swap() calls - all swaps must go through vault
        if (from == PAIR && to != VAULT) {
            revert("Go to PerpetualBitcoin.io to 'BUY PB'");
        }

        uint256 allowed = allowance[from][msg.sender];
        if (allowed != type(uint256).max) {
            require(allowed >= amount, "Allowance exceeded");
            allowance[from][msg.sender] = allowed - amount;
        }

        require(amount > 0, "Amount must be > 0");
        require(balanceOf[from] >= amount, "Insufficient balance");

        // Standard ERC20 transferFrom (no split enforcement)
        balanceOf[from] -= amount;
        balanceOf[to] += amount;
        emit Transfer(from, to, amount);
        return true;
    }

    /**
     * @notice Approve spender (standard ERC20)
     */
    function approve(address spender, uint256 amount) external returns (bool) {
        allowance[msg.sender][spender] = amount;
        emit Approval(msg.sender, spender, amount);
        return true;
    }

    modifier onlyVault() {
        require(vaultLocked, "Vault not locked yet");
        require(msg.sender == VAULT, "Only Vault");
        _;
    }
}
        

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

/ReentrancyGuard.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be _NOT_ENTERED
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;
    }

    function _nonReentrantAfter() private {
        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
     * `nonReentrant` function in the call stack.
     */
    function _reentrancyGuardEntered() internal view returns (bool) {
        return _status == _ENTERED;
    }
}
          

Compiler Settings

{"viaIR":true,"remappings":[],"optimizer":{"runs":1,"enabled":true},"metadata":{"bytecodeHash":"none"},"libraries":{},"evmVersion":"shanghai","compilationTarget":{"contracts/PB.sol":"PB"}}
              

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[]},{"type":"event","name":"Approval","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":true},{"type":"address","name":"spender","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"DEPLOYER","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"PAIR","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"VAULT","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"allowance","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"approve","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"decimals","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"description","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"lockVault","inputs":[{"type":"address","name":"_vault","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"logoURI","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"name","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setPairAddress","inputs":[{"type":"address","name":"_pair","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"symbol","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalSupply","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transfer","inputs":[{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transferFrom","inputs":[{"type":"address","name":"from","internalType":"address"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"vaultLocked","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"website","inputs":[]}]
              

Contract Creation Code

Verify & Publish
0x60a0806040523461002e5760015f5533608052610c7d90816100338239608051818181610146015261031f0152f35b5f80fdfe6080604081815260049182361015610015575f80fd5b5f3560e01c90816306fdde0314610a3e57508063095ea7b3146109d057806318160ddd146109ab5780631d2005c31461098557806323b872dd14610800578063313ce567146107e5578063411557d1146107bd5780636bb38b28146106ec57806370a08231146106b55780637284e416146105d257806395d89b4114610589578063a22d483214610486578063a519c198146102f9578063a9059cbb14610216578063ace3a8a7146101ee578063beb0a41614610175578063c1b8411a146101325763dd62ed3e146100e5575f80fd5b3461012e578060031936011261012e57602091610100610ad8565b610108610aee565b6001600160a01b039182165f908152928552838320911682528352819020549051908152f35b5f80fd5b503461012e575f36600319011261012e57517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b503461012e575f36600319011261012e578051908181016001600160401b038111838210176101db576101d793508152601b82527a68747470733a2f2f70657270657475616c626974636f696e2e696f60281b60208301525191829182610a91565b0390f35b604184634e487b7160e01b5f525260245ffd5b503461012e575f36600319011261012e5760025490516001600160a01b039091168152602090f35b503461012e578060031936011261012e5761022f610ad8565b6024359061023b610bfc565b610246821515610b6b565b335f52600360205261025d82845f20541015610bac565b6002546001600160a01b03919082163314806102e9575b6102ce5760209450335f5260038552835f20610291848254610b4a565b90551690815f5260038452825f206102aa828254610bef565b905582519081525f80516020610c51833981519152843392a360015f555160018152f35b835162461bcd60e51b8152806102e5818801610b04565b0390fd5b5081600154168282161415610274565b50903461012e5760208060031936011261012e57610315610ad8565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081163303610454576001549160ff8360a01c16610419578183166103e157169283156103ae57506001600160a81b0319168217600160a01b176001555f828152600382528381206a115eec47f6cf7e3500000090819055845190815290915f80516020610c5183398151915291a3005b845162461bcd60e51b8152908101839052600d60248201526c125b9d985b1a59081d985d5b1d609a1b6044820152606490fd5b5050925162461bcd60e51b815291820152601160248201527015985d5b1d08185b1c9958591e481cd95d607a1b604482015260649150fd5b5050925162461bcd60e51b815291820152601460248201527315985d5b1d08185b1c9958591e481b1bd8dad95960621b604482015260649150fd5b5050606492519162461bcd60e51b8352820152600d60248201526c27b7363c903232b83637bcb2b960991b6044820152fd5b50903461012e57602036600319011261012e576104a1610ad8565b6001546001600160a01b039291908316330361054c578216928315610512576002549283166104dc5750506001600160a01b03191617600255005b906020606492519162461bcd60e51b8352820152601060248201526f14185a5c88185b1c9958591e481cd95d60821b6044820152fd5b906020606492519162461bcd60e51b83528201526014602482015273496e76616c69642070616972206164647265737360601b6044820152fd5b835162461bcd60e51b8152602081840152601760248201527627b7363c903b30bab63a1031b0b71039b2ba103830b4b960491b6044820152606490fd5b503461012e575f36600319011261012e578051908181016001600160401b038111838210176101db576101d7935081526002825261282160f11b60208301525191829182610a91565b503461012e575f36600319011261012e5780519060c082016001600160401b038111838210176101db576101d793508152608482527f50657270657475616c20426974636f696e2028504229202d2050726963652d6260208301527f6173656420756e6c6f636b2070726f746f636f6c2e2032314d20737570706c79818301527f2c20332e363925206c6971756964206f6e2070757263686173652c2039362e3360608301527f3125206c6f636b65642e2056697369742070657270657475616c626974636f696080830152636e2e696f60e01b60a08301525191829182610a91565b503461012e57602036600319011261012e576020906001600160a01b036106da610ad8565b165f5260038252805f20549051908152f35b503461012e575f36600319011261012e5780519060a082016001600160401b038111838210176101db576101d793508152607882527f68747470733a2f2f617a7572652d726174696f6e616c2d73616c6d6f6e2d313560208301527f322e6d7970696e6174612e636c6f75642f697066732f62616679626569636c76818301527f666d3670716434726f7a686666686577666e646562787633733666327a35743360608301527778736d69726368796461336c67376535342f50422e6a706760401b60808301525191829182610a91565b503461012e575f36600319011261012e5760015490516001600160a01b039091168152602090f35b503461012e575f36600319011261012e576020905160128152f35b503461012e57606036600319011261012e5761081a610ad8565b91610823610aee565b9260443591610830610bfc565b6002546001600160a01b039283169291908216831480610975575b61095c57825f526020958187928352865f20335f528352865f20545f1981036108e3575b5050915f80516020610c518339815191529261088c861515610b6b565b845f52600383526108a286885f20541015610bac565b845f5260038352865f206108b7878254610b4a565b90551693845f5260038252855f206108d0828254610bef565b90558551908152a360015f555160018152f35b9091925085811061092457915f80516020610c51833981519152939161090a878a95610b4a565b90865f528452875f20335f528452875f205590925f61086f565b865162461bcd60e51b81528083018990526012602482015271105b1b1bddd85b98d948195e18d95959195960721b6044820152606490fd5b845162461bcd60e51b81529081906102e5908201610b04565b508160015416828716141561084b565b503461012e575f36600319011261012e5760209060ff60015460a01c1690519015158152f35b503461012e575f36600319011261012e57602090516a115eec47f6cf7e350000008152f35b503461012e578060031936011261012e576020916109ec610ad8565b9060243590335f528452825f209160018060a01b031691825f52845280835f205582519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925843392a35160018152f35b9190503461012e575f36600319011261012e578181016001600160401b038111838210176101db576101d79350815260118252702832b93832ba3ab0b6102134ba31b7b4b760791b602083015251918291825b602080825282518183018190529093925f5b828110610ac457505060409293505f838284010152601f8019910116010190565b818101860151848201604001528501610aa3565b600435906001600160a01b038216820361012e57565b602435906001600160a01b038216820361012e57565b60809060208152602560208201527f476f20746f2050657270657475616c426974636f696e2e696f20746f20274255604082015264592050422760d81b60608201520190565b91908203918211610b5757565b634e487b7160e01b5f52601160045260245ffd5b15610b7257565b60405162461bcd60e51b81526020600482015260126024820152710416d6f756e74206d757374206265203e20360741b6044820152606490fd5b15610bb357565b60405162461bcd60e51b8152602060048201526014602482015273496e73756666696369656e742062616c616e636560601b6044820152606490fd5b91908201809211610b5757565b60025f5414610c0b5760025f55565b60405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606490fdfeddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa164736f6c6343000818000a

Deployed ByteCode

0x6080604081815260049182361015610015575f80fd5b5f3560e01c90816306fdde0314610a3e57508063095ea7b3146109d057806318160ddd146109ab5780631d2005c31461098557806323b872dd14610800578063313ce567146107e5578063411557d1146107bd5780636bb38b28146106ec57806370a08231146106b55780637284e416146105d257806395d89b4114610589578063a22d483214610486578063a519c198146102f9578063a9059cbb14610216578063ace3a8a7146101ee578063beb0a41614610175578063c1b8411a146101325763dd62ed3e146100e5575f80fd5b3461012e578060031936011261012e57602091610100610ad8565b610108610aee565b6001600160a01b039182165f908152928552838320911682528352819020549051908152f35b5f80fd5b503461012e575f36600319011261012e57517f000000000000000000000000bad37bea31ad0ac692080ea29b04b23a9ee7b0556001600160a01b03168152602090f35b503461012e575f36600319011261012e578051908181016001600160401b038111838210176101db576101d793508152601b82527a68747470733a2f2f70657270657475616c626974636f696e2e696f60281b60208301525191829182610a91565b0390f35b604184634e487b7160e01b5f525260245ffd5b503461012e575f36600319011261012e5760025490516001600160a01b039091168152602090f35b503461012e578060031936011261012e5761022f610ad8565b6024359061023b610bfc565b610246821515610b6b565b335f52600360205261025d82845f20541015610bac565b6002546001600160a01b03919082163314806102e9575b6102ce5760209450335f5260038552835f20610291848254610b4a565b90551690815f5260038452825f206102aa828254610bef565b905582519081525f80516020610c51833981519152843392a360015f555160018152f35b835162461bcd60e51b8152806102e5818801610b04565b0390fd5b5081600154168282161415610274565b50903461012e5760208060031936011261012e57610315610ad8565b6001600160a01b037f000000000000000000000000bad37bea31ad0ac692080ea29b04b23a9ee7b05581163303610454576001549160ff8360a01c16610419578183166103e157169283156103ae57506001600160a81b0319168217600160a01b176001555f828152600382528381206a115eec47f6cf7e3500000090819055845190815290915f80516020610c5183398151915291a3005b845162461bcd60e51b8152908101839052600d60248201526c125b9d985b1a59081d985d5b1d609a1b6044820152606490fd5b5050925162461bcd60e51b815291820152601160248201527015985d5b1d08185b1c9958591e481cd95d607a1b604482015260649150fd5b5050925162461bcd60e51b815291820152601460248201527315985d5b1d08185b1c9958591e481b1bd8dad95960621b604482015260649150fd5b5050606492519162461bcd60e51b8352820152600d60248201526c27b7363c903232b83637bcb2b960991b6044820152fd5b50903461012e57602036600319011261012e576104a1610ad8565b6001546001600160a01b039291908316330361054c578216928315610512576002549283166104dc5750506001600160a01b03191617600255005b906020606492519162461bcd60e51b8352820152601060248201526f14185a5c88185b1c9958591e481cd95d60821b6044820152fd5b906020606492519162461bcd60e51b83528201526014602482015273496e76616c69642070616972206164647265737360601b6044820152fd5b835162461bcd60e51b8152602081840152601760248201527627b7363c903b30bab63a1031b0b71039b2ba103830b4b960491b6044820152606490fd5b503461012e575f36600319011261012e578051908181016001600160401b038111838210176101db576101d7935081526002825261282160f11b60208301525191829182610a91565b503461012e575f36600319011261012e5780519060c082016001600160401b038111838210176101db576101d793508152608482527f50657270657475616c20426974636f696e2028504229202d2050726963652d6260208301527f6173656420756e6c6f636b2070726f746f636f6c2e2032314d20737570706c79818301527f2c20332e363925206c6971756964206f6e2070757263686173652c2039362e3360608301527f3125206c6f636b65642e2056697369742070657270657475616c626974636f696080830152636e2e696f60e01b60a08301525191829182610a91565b503461012e57602036600319011261012e576020906001600160a01b036106da610ad8565b165f5260038252805f20549051908152f35b503461012e575f36600319011261012e5780519060a082016001600160401b038111838210176101db576101d793508152607882527f68747470733a2f2f617a7572652d726174696f6e616c2d73616c6d6f6e2d313560208301527f322e6d7970696e6174612e636c6f75642f697066732f62616679626569636c76818301527f666d3670716434726f7a686666686577666e646562787633733666327a35743360608301527778736d69726368796461336c67376535342f50422e6a706760401b60808301525191829182610a91565b503461012e575f36600319011261012e5760015490516001600160a01b039091168152602090f35b503461012e575f36600319011261012e576020905160128152f35b503461012e57606036600319011261012e5761081a610ad8565b91610823610aee565b9260443591610830610bfc565b6002546001600160a01b039283169291908216831480610975575b61095c57825f526020958187928352865f20335f528352865f20545f1981036108e3575b5050915f80516020610c518339815191529261088c861515610b6b565b845f52600383526108a286885f20541015610bac565b845f5260038352865f206108b7878254610b4a565b90551693845f5260038252855f206108d0828254610bef565b90558551908152a360015f555160018152f35b9091925085811061092457915f80516020610c51833981519152939161090a878a95610b4a565b90865f528452875f20335f528452875f205590925f61086f565b865162461bcd60e51b81528083018990526012602482015271105b1b1bddd85b98d948195e18d95959195960721b6044820152606490fd5b845162461bcd60e51b81529081906102e5908201610b04565b508160015416828716141561084b565b503461012e575f36600319011261012e5760209060ff60015460a01c1690519015158152f35b503461012e575f36600319011261012e57602090516a115eec47f6cf7e350000008152f35b503461012e578060031936011261012e576020916109ec610ad8565b9060243590335f528452825f209160018060a01b031691825f52845280835f205582519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925843392a35160018152f35b9190503461012e575f36600319011261012e578181016001600160401b038111838210176101db576101d79350815260118252702832b93832ba3ab0b6102134ba31b7b4b760791b602083015251918291825b602080825282518183018190529093925f5b828110610ac457505060409293505f838284010152601f8019910116010190565b818101860151848201604001528501610aa3565b600435906001600160a01b038216820361012e57565b602435906001600160a01b038216820361012e57565b60809060208152602560208201527f476f20746f2050657270657475616c426974636f696e2e696f20746f20274255604082015264592050422760d81b60608201520190565b91908203918211610b5757565b634e487b7160e01b5f52601160045260245ffd5b15610b7257565b60405162461bcd60e51b81526020600482015260126024820152710416d6f756e74206d757374206265203e20360741b6044820152606490fd5b15610bb357565b60405162461bcd60e51b8152602060048201526014602482015273496e73756666696369656e742062616c616e636560601b6044820152606490fd5b91908201809211610b5757565b60025f5414610c0b5760025f55565b60405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606490fdfeddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa164736f6c6343000818000a